diff --git a/src/common/datetime/format_duration.ts b/src/common/datetime/format_duration.ts index c05c890a39..bc706d034e 100644 --- a/src/common/datetime/format_duration.ts +++ b/src/common/datetime/format_duration.ts @@ -10,7 +10,7 @@ export const formatDuration = (duration: HaDurationData) => { const ms = duration.milliseconds || 0; if (d > 0) { - return `${d} days ${h}:${leftPad(m)}:${leftPad(s)}`; + return `${d} day${d === 1 ? "" : "s"} ${h}:${leftPad(m)}:${leftPad(s)}`; } if (h > 0) { return `${h}:${leftPad(m)}:${leftPad(s)}`; @@ -19,10 +19,10 @@ export const formatDuration = (duration: HaDurationData) => { return `${m}:${leftPad(s)}`; } if (s > 0) { - return `${s} seconds`; + return `${s} second${s === 1 ? "" : "s"}`; } if (ms > 0) { - return `${ms} milliseconds`; + return `${ms} millisecond${ms === 1 ? "" : "s"}`; } return null; }; diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index b123894cad..78cd7ea8e8 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -374,35 +374,35 @@ export const describeCondition = ( if (condition.condition === "or") { const conditions = ensureArray(condition.conditions); - let count = "condition"; - - if (conditions && conditions.length > 0) { - count = `of ${conditions.length} conditions`; + if (!conditions || conditions.length === 0) { + return "Test if any condition matches"; } - - return `Test if any ${count} matches`; + const count = conditions.length; + return `Test if any of ${count} condition${count === 1 ? "" : "s"} matches`; } if (condition.condition === "and") { const conditions = ensureArray(condition.conditions); - const count = - conditions && conditions.length > 0 - ? `${conditions.length} ` - : "multiple"; - - return `Test if ${count} conditions match`; + if (!conditions || conditions.length === 0) { + return "Test if multiple conditions match"; + } + const count = conditions.length; + return `Test if ${count} condition${count === 1 ? "" : "s"} match${ + count === 1 ? "es" : "" + }`; } if (condition.condition === "not") { const conditions = ensureArray(condition.conditions); - const what = - conditions && conditions.length > 0 - ? `none of ${conditions.length} conditions match` - : "no condition matches"; - - return `Test if ${what}`; + if (!conditions || conditions.length === 0) { + return "Test if no condition matches"; + } + if (conditions.length === 1) { + return "Test if 1 condition does not match"; + } + return `Test if none of ${conditions.length} conditions match`; } // State Condition diff --git a/src/data/script.ts b/src/data/script.ts index 06e31c017c..52a3f10f29 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -185,7 +185,7 @@ interface BaseRepeat extends BaseAction { } export interface CountRepeat extends BaseRepeat { - count: number; + count: number | string; } export interface WhileRepeat extends BaseRepeat { diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts index a838d6c19e..163f13e2e0 100644 --- a/src/data/script_i18n.ts +++ b/src/data/script_i18n.ts @@ -231,32 +231,37 @@ export const describeAction = ( if (actionType === "choose") { const config = action as ChooseAction; - return config.choose - ? `Choose between ${ - ensureArray(config.choose).length + (config.default ? 1 : 0) - } actions` - : "Choose an action"; + if (config.choose) { + const numActions = + ensureArray(config.choose).length + (config.default ? 1 : 0); + return `Choose between ${numActions} action${ + numActions === 1 ? "" : "s" + }`; + } + return "Choose an action"; } if (actionType === "repeat") { const config = action as RepeatAction; - return `Repeat an action ${ - "count" in config.repeat ? `${config.repeat.count} times` : "" - }${ - "while" in config.repeat - ? `while ${ensureArray(config.repeat.while) - .map((condition) => describeCondition(condition, hass)) - .join(", ")} is true` - : "until" in config.repeat - ? `until ${ensureArray(config.repeat.until) - .map((condition) => describeCondition(condition, hass)) - .join(", ")} is true` - : "for_each" in config.repeat - ? `for every item: ${ensureArray(config.repeat.for_each) - .map((item) => JSON.stringify(item)) - .join(", ")}` - : "" - }`; + + let base = "Repeat an action"; + if ("count" in config.repeat) { + const count = config.repeat.count; + base += ` ${count} time${Number(count) === 1 ? "" : "s"}`; + } else if ("while" in config.repeat) { + base += ` while ${ensureArray(config.repeat.while) + .map((condition) => describeCondition(condition, hass)) + .join(", ")} is true`; + } else if ("until" in config.repeat) { + base += ` until ${ensureArray(config.repeat.until) + .map((condition) => describeCondition(condition, hass)) + .join(", ")} is true`; + } else if ("for_each" in config.repeat) { + base += ` for every item: ${ensureArray(config.repeat.for_each) + .map((item) => JSON.stringify(item)) + .join(", ")}`; + } + return base; } if (actionType === "check_condition") { @@ -280,7 +285,8 @@ export const describeAction = ( if (actionType === "parallel") { const config = action as ParallelAction; - return `Run ${ensureArray(config.parallel).length} actions in parallel`; + const numActions = ensureArray(config.parallel).length; + return `Run ${numActions} action${numActions === 1 ? "" : "s"} in parallel`; } return actionType;