Improve ensureArray and use it in tracing (#8785)

* Improve ensureArray and use it in tracing

* Fix typing

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Bram Kragten 2021-04-01 22:33:47 +02:00 committed by GitHub
parent 401064d3c8
commit deca6f03ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 55 deletions

View File

@ -1,6 +1,8 @@
export const ensureArray = (value?: any) => {
if (!value || Array.isArray(value)) {
export function ensureArray(value: undefined): undefined;
export function ensureArray<T>(value: T | T[]): T[];
export function ensureArray(value) {
if (value === undefined || Array.isArray(value)) {
return value;
}
return [value];
};
}

View File

@ -125,35 +125,41 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
return html``;
}
return html`<div class="mdc-chip-set items">
${ensureArray(this.value?.area_id)?.map((area_id) => {
const area = this._areas![area_id];
return this._renderChip(
"area_id",
area_id,
area?.name || area_id,
undefined,
mdiSofa
);
})}
${ensureArray(this.value?.device_id)?.map((device_id) => {
const device = this._devices![device_id];
return this._renderChip(
"device_id",
device_id,
device ? computeDeviceName(device, this.hass) : device_id,
undefined,
mdiDevices
);
})}
${ensureArray(this.value?.entity_id)?.map((entity_id) => {
const entity = this.hass.states[entity_id];
return this._renderChip(
"entity_id",
entity_id,
entity ? computeStateName(entity) : entity_id,
entity ? stateIcon(entity) : undefined
);
})}
${this.value?.area_id
? ensureArray(this.value.area_id).map((area_id) => {
const area = this._areas![area_id];
return this._renderChip(
"area_id",
area_id,
area?.name || area_id,
undefined,
mdiSofa
);
})
: ""}
${this.value?.device_id
? ensureArray(this.value.device_id).map((device_id) => {
const device = this._devices![device_id];
return this._renderChip(
"device_id",
device_id,
device ? computeDeviceName(device, this.hass) : device_id,
undefined,
mdiDevices
);
})
: ""}
${this.value?.entity_id
? ensureArray(this.value.entity_id).map((entity_id) => {
const entity = this.hass.states[entity_id];
return this._renderChip(
"entity_id",
entity_id,
entity ? computeStateName(entity) : entity_id,
entity ? stateIcon(entity) : undefined
);
})
: ""}
</div>
${this._renderPicker()}
<div class="mdc-chip-set">

View File

@ -48,6 +48,7 @@ import {
WaitAction,
WaitForTriggerAction,
} from "../../data/script";
import { ensureArray } from "../../common/ensure-array";
declare global {
interface HASSDomEvents {
@ -412,16 +413,14 @@ class HatScriptGraph extends LitElement {
const manual_triggered = this.trace && "trigger" in this.trace.trace;
let track_path = manual_triggered ? undefined : [0];
const trigger_nodes = (Array.isArray(this.trace.config.trigger)
? this.trace.config.trigger
: [this.trace.config.trigger]
).map((trigger, i) => {
if (this.trace && `trigger/${i}` in this.trace.trace) {
track_path = [i];
const trigger_nodes = ensureArray(this.trace.config.trigger).map(
(trigger, i) => {
if (this.trace && `trigger/${i}` in this.trace.trace) {
track_path = [i];
}
return this.render_trigger(trigger, i);
}
return this.render_trigger(trigger, i);
});
);
return html`
<hat-graph class="parent">
<div></div>
@ -435,16 +434,13 @@ class HatScriptGraph extends LitElement {
${trigger_nodes}
</hat-graph>
<hat-graph id="condition">
${(!this.trace.config.condition ||
Array.isArray(this.trace.config.condition)
? this.trace.config.condition
: [this.trace.config.condition]
)?.map((condition, i) => this.render_condition(condition, i))}
${ensureArray(this.trace.config.condition)?.map((condition, i) =>
this.render_condition(condition!, i)
)}
</hat-graph>
${(Array.isArray(this.trace.config.action)
? this.trace.config.action
: [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}`)
)}
</hat-graph>
<div class="actions">
<mwc-icon-button

View File

@ -77,7 +77,7 @@ export interface WaitAction {
export interface WaitForTriggerAction {
alias?: string;
wait_for_trigger: Trigger[];
wait_for_trigger: Trigger | Trigger[];
timeout?: number;
continue_on_timeout?: boolean;
}

View File

@ -1,4 +1,5 @@
import secondsToDuration from "../common/datetime/seconds_to_duration";
import { ensureArray } from "../common/ensure-array";
import { computeStateName } from "../common/entity/compute_state_name";
import { HomeAssistant } from "../types";
import { Condition } from "./automation";
@ -111,7 +112,7 @@ export const describeAction = <T extends ActionType>(
if (actionType === "wait_for_trigger") {
const config = action as WaitForTriggerAction;
return `Wait for ${config.wait_for_trigger
return `Wait for ${ensureArray(config.wait_for_trigger)
.map((trigger) => describeTrigger(trigger))
.join(", ")}`;
}

View File

@ -1,6 +1,6 @@
import { strStartsWith } from "../common/string/starts-with";
import { HomeAssistant, Context } from "../types";
import { AutomationConfig } from "./automation";
import { ManualAutomationConfig } from "./automation";
interface BaseTraceStep {
path: string;
@ -86,7 +86,7 @@ export interface AutomationTrace {
export interface AutomationTraceExtended extends AutomationTrace {
trace: Record<string, ActionTraceStep[]>;
context: Context;
config: AutomationConfig;
config: ManualAutomationConfig;
error?: string;
}
@ -138,7 +138,7 @@ export const loadTraceContexts = (
});
export const getDataFromPath = (
config: AutomationConfig,
config: ManualAutomationConfig,
path: string
): any => {
const parts = path.split("/").reverse();