diff --git a/src/common/ensure-array.ts b/src/common/ensure-array.ts index 4290c040c1..cdc9ea89ed 100644 --- a/src/common/ensure-array.ts +++ b/src/common/ensure-array.ts @@ -1,5 +1,7 @@ +type NonUndefined = T extends undefined ? never : T; + export function ensureArray(value: undefined): undefined; -export function ensureArray(value: T | T[]): T[]; +export function ensureArray(value: T | T[]): NonUndefined[]; export function ensureArray(value) { if (value === undefined || Array.isArray(value)) { return value; diff --git a/src/components/trace/hat-script-graph.ts b/src/components/trace/hat-script-graph.ts index 7a5e04cac7..0fef57b294 100644 --- a/src/components/trace/hat-script-graph.ts +++ b/src/components/trace/hat-script-graph.ts @@ -177,7 +177,7 @@ class HatScriptGraph extends LitElement { track: trace !== undefined && trace[0].result?.choice === i, })} > - ${branch.sequence.map((action, j) => + ${ensureArray(branch.sequence).map((action, j) => this.render_node(action, `${branch_path}/sequence/${j}`) )} @@ -192,7 +192,7 @@ class HatScriptGraph extends LitElement { trace !== undefined && trace[0].result?.choice === "default", })} > - ${config.default?.map((action, i) => + ${ensureArray(config.default)?.map((action, i) => this.render_node(action, `${path}/default/${i}`) )} @@ -319,7 +319,7 @@ class HatScriptGraph extends LitElement { .badge=${repeats} > - ${node.repeat.sequence.map((action, i) => + ${ensureArray(node.repeat.sequence).map((action, i) => this.render_node(action, `${path}/repeat/sequence/${i}`) )} @@ -421,43 +421,52 @@ class HatScriptGraph extends LitElement { return this.render_trigger(trigger, i); } ); - return html` - -
- - ${trigger_nodes} - - - ${ensureArray(this.trace.config.condition)?.map((condition, i) => - this.render_condition(condition!, i) + try { + return html` + +
+ + ${trigger_nodes} + + + ${ensureArray(this.trace.config.condition)?.map((condition, i) => + this.render_condition(condition!, i) + )} + + ${ensureArray(this.trace.config.action).map((action, i) => + this.render_node(action, `action/${i}`) )}
- ${ensureArray(this.trace.config.action).map((action, i) => - this.render_node(action, `action/${i}`) - )} -
-
- - - - - - -
- `; +
+ + + + + + +
+ `; + } catch (err) { + return html` +
+ Error rendering graph. Please download trace and share with the + developers. +
+ `; + } } protected update(changedProps: PropertyValues) { @@ -539,6 +548,10 @@ class HatScriptGraph extends LitElement { .parent { margin-left: 8px; } + .error { + padding: 16px; + max-width: 300px; + } `; } } diff --git a/src/data/automation.ts b/src/data/automation.ts index d137f76600..21bd303a62 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -23,9 +23,9 @@ export interface ManualAutomationConfig { id?: string; alias?: string; description?: string; - trigger: Trigger[]; - condition?: Condition[]; - action: Action[]; + trigger: Trigger | Trigger[]; + condition?: Condition | Condition[]; + action: Action | Action[]; mode?: typeof MODES[number]; max?: number; max_exceeded?: @@ -161,7 +161,7 @@ export type Trigger = export interface LogicalCondition { condition: "and" | "not" | "or"; alias?: string; - conditions: Condition[]; + conditions: Condition | Condition[]; } export interface StateCondition { diff --git a/src/data/script.ts b/src/data/script.ts index b9cea29528..096835a49d 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -22,7 +22,7 @@ export interface ScriptEntity extends HassEntityBase { export interface ScriptConfig { alias: string; - sequence: Action[]; + sequence: Action | Action[]; icon?: string; mode?: typeof MODES[number]; max?: number; @@ -89,7 +89,7 @@ export interface RepeatAction { interface BaseRepeat { alias?: string; - sequence: Action[]; + sequence: Action | Action[]; } export interface CountRepeat extends BaseRepeat { @@ -107,13 +107,13 @@ export interface UntilRepeat extends BaseRepeat { export interface ChooseActionChoice { alias?: string; conditions: string | Condition[]; - sequence: Action[]; + sequence: Action | Action[]; } export interface ChooseAction { alias?: string; choose: ChooseActionChoice[]; - default?: Action[]; + default?: Action | Action[]; } export interface VariablesAction { diff --git a/src/panels/config/automation/trace/ha-automation-trace-path-details.ts b/src/panels/config/automation/trace/ha-automation-trace-path-details.ts index aa893efc49..b27edf9814 100644 --- a/src/panels/config/automation/trace/ha-automation-trace-path-details.ts +++ b/src/panels/config/automation/trace/ha-automation-trace-path-details.ts @@ -105,6 +105,7 @@ export class HaAutomationTracePathDetails extends LitElement { path, timestamp, result, + error, changed_variables, ...rest } = trace as any; @@ -116,6 +117,8 @@ export class HaAutomationTracePathDetails extends LitElement { ${result ? html`Result:
${safeDump(result)}
` + : error + ? html`
Error: ${error}
` : ""} ${Object.keys(rest).length === 0 ? "" @@ -232,6 +235,10 @@ ${safeDump(trace.changed_variables).trimRight()}