Handle configurations that don't wrap their action sequences in arrays (#8798)

This commit is contained in:
Paulus Schoutsen 2021-04-02 05:45:34 -07:00 committed by GitHub
parent a0b5bc5456
commit 82ad5c103d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 47 deletions

View File

@ -1,5 +1,7 @@
type NonUndefined<T> = T extends undefined ? never : T;
export function ensureArray(value: undefined): undefined;
export function ensureArray<T>(value: T | T[]): T[];
export function ensureArray<T>(value: T | T[]): NonUndefined<T>[];
export function ensureArray(value) {
if (value === undefined || Array.isArray(value)) {
return value;

View File

@ -177,7 +177,7 @@ class HatScriptGraph extends LitElement {
track: trace !== undefined && trace[0].result?.choice === i,
})}
></hat-graph-node>
${branch.sequence.map((action, j) =>
${ensureArray(branch.sequence).map((action, j) =>
this.render_node(action, `${branch_path}/sequence/${j}`)
)}
</hat-graph>
@ -192,7 +192,7 @@ class HatScriptGraph extends LitElement {
trace !== undefined && trace[0].result?.choice === "default",
})}
></hat-graph-node>
${config.default?.map((action, i) =>
${ensureArray(config.default)?.map((action, i) =>
this.render_node(action, `${path}/default/${i}`)
)}
</hat-graph>
@ -319,7 +319,7 @@ class HatScriptGraph extends LitElement {
.badge=${repeats}
></hat-graph-node>
<hat-graph>
${node.repeat.sequence.map((action, i) =>
${ensureArray(node.repeat.sequence).map((action, i) =>
this.render_node(action, `${path}/repeat/sequence/${i}`)
)}
</hat-graph>
@ -421,43 +421,52 @@ class HatScriptGraph extends LitElement {
return this.render_trigger(trigger, i);
}
);
return html`
<hat-graph class="parent">
<div></div>
<hat-graph
branching
id="trigger"
.short=${trigger_nodes.length < 2}
.track_start=${track_path}
.track_end=${track_path}
>
${trigger_nodes}
</hat-graph>
<hat-graph id="condition">
${ensureArray(this.trace.config.condition)?.map((condition, i) =>
this.render_condition(condition!, i)
try {
return html`
<hat-graph class="parent">
<div></div>
<hat-graph
branching
id="trigger"
.short=${trigger_nodes.length < 2}
.track_start=${track_path}
.track_end=${track_path}
>
${trigger_nodes}
</hat-graph>
<hat-graph id="condition">
${ensureArray(this.trace.config.condition)?.map((condition, i) =>
this.render_condition(condition!, i)
)}
</hat-graph>
${ensureArray(this.trace.config.action).map((action, i) =>
this.render_node(action, `action/${i}`)
)}
</hat-graph>
${ensureArray(this.trace.config.action).map((action, i) =>
this.render_node(action, `action/${i}`)
)}
</hat-graph>
<div class="actions">
<mwc-icon-button
.disabled=${paths.length === 0 || paths[0] === this.selected}
@click=${this.previousTrackedNode}
>
<ha-svg-icon .path=${mdiChevronUp}></ha-svg-icon>
</mwc-icon-button>
<mwc-icon-button
.disabled=${paths.length === 0 ||
paths[paths.length - 1] === this.selected}
@click=${this.nextTrackedNode}
>
<ha-svg-icon .path=${mdiChevronDown}></ha-svg-icon>
</mwc-icon-button>
</div>
`;
<div class="actions">
<mwc-icon-button
.disabled=${paths.length === 0 || paths[0] === this.selected}
@click=${this.previousTrackedNode}
>
<ha-svg-icon .path=${mdiChevronUp}></ha-svg-icon>
</mwc-icon-button>
<mwc-icon-button
.disabled=${paths.length === 0 ||
paths[paths.length - 1] === this.selected}
@click=${this.nextTrackedNode}
>
<ha-svg-icon .path=${mdiChevronDown}></ha-svg-icon>
</mwc-icon-button>
</div>
`;
} catch (err) {
return html`
<div class="error">
Error rendering graph. Please download trace and share with the
developers.
</div>
`;
}
}
protected update(changedProps: PropertyValues<this>) {
@ -539,6 +548,10 @@ class HatScriptGraph extends LitElement {
.parent {
margin-left: 8px;
}
.error {
padding: 16px;
max-width: 300px;
}
`;
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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:
<pre>${safeDump(result)}</pre>`
: error
? html`<div class="error">Error: ${error}</div>`
: ""}
${Object.keys(rest).length === 0
? ""
@ -232,6 +235,10 @@ ${safeDump(trace.changed_variables).trimRight()}</pre
pre {
margin: 0;
}
.error {
color: var(--error-color);
}
`,
];
}

View File

@ -469,6 +469,11 @@ export class HaAutomationTrace extends LitElement {
.graph {
border-right: 1px solid var(--divider-color);
overflow-x: auto;
max-width: 50%;
}
:host([narrow]) .graph {
max-width: 100%;
}
.info {