mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 13:57:21 +00:00
Trace fixes (#9192)
* Show sub-conditions * Better show errors in timeline * Add rendered nodes * Fix some rendering issues with sub-conditions in timeline * Improve condition rendering
This commit is contained in:
parent
fd2728c02c
commit
f8e8b5ad18
@ -63,6 +63,8 @@ class HatScriptGraph extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public selected;
|
||||
|
||||
@property() renderedNodes: Record<string, any> = {};
|
||||
|
||||
@property() trackedNodes: Record<string, any> = {};
|
||||
|
||||
private selectNode(config, path) {
|
||||
@ -74,8 +76,9 @@ class HatScriptGraph extends LitElement {
|
||||
private render_trigger(config: Trigger, i: number) {
|
||||
const path = `trigger/${i}`;
|
||||
const tracked = this.trace && path in this.trace.trace;
|
||||
this.renderedNodes[path] = { config, path };
|
||||
if (tracked) {
|
||||
this.trackedNodes[path] = { config, path };
|
||||
this.trackedNodes[path] = this.renderedNodes[path];
|
||||
}
|
||||
return html`
|
||||
<hat-graph-node
|
||||
@ -96,8 +99,9 @@ class HatScriptGraph extends LitElement {
|
||||
const trace = this.trace.trace[path] as ConditionTraceStep[] | undefined;
|
||||
const track_path =
|
||||
trace?.[0].result === undefined ? 0 : trace[0].result.result ? 1 : 2;
|
||||
this.renderedNodes[path] = { config, path };
|
||||
if (trace) {
|
||||
this.trackedNodes[path] = { config, path };
|
||||
this.trackedNodes[path] = this.renderedNodes[path];
|
||||
}
|
||||
return html`
|
||||
<hat-graph
|
||||
@ -172,8 +176,11 @@ class HatScriptGraph extends LitElement {
|
||||
const branch_path = `${path}/choose/${i}`;
|
||||
const track_this =
|
||||
trace !== undefined && trace[0].result?.choice === i;
|
||||
this.renderedNodes[branch_path] = { config, path: branch_path };
|
||||
if (track_this) {
|
||||
this.trackedNodes[branch_path] = { config, path: branch_path };
|
||||
this.trackedNodes[branch_path] = this.renderedNodes[
|
||||
branch_path
|
||||
];
|
||||
}
|
||||
return html`
|
||||
<hat-graph>
|
||||
@ -411,8 +418,9 @@ class HatScriptGraph extends LitElement {
|
||||
|
||||
const type = Object.keys(NODE_TYPES).find((key) => key in node) || "other";
|
||||
const nodeEl = NODE_TYPES[type].bind(this)(node, path);
|
||||
this.renderedNodes[path] = { config: node, path };
|
||||
if (this.trace && path in this.trace.trace) {
|
||||
this.trackedNodes[path] = { config: node, path };
|
||||
this.trackedNodes[path] = this.renderedNodes[path];
|
||||
}
|
||||
return nodeEl;
|
||||
}
|
||||
@ -483,6 +491,7 @@ class HatScriptGraph extends LitElement {
|
||||
|
||||
protected update(changedProps: PropertyValues<this>) {
|
||||
if (changedProps.has("trace")) {
|
||||
this.renderedNodes = {};
|
||||
this.trackedNodes = {};
|
||||
}
|
||||
super.update(changedProps);
|
||||
@ -493,7 +502,7 @@ class HatScriptGraph extends LitElement {
|
||||
|
||||
// Select first node if new trace loaded but no selection given.
|
||||
if (changedProps.has("trace")) {
|
||||
const tracked = this.getTrackedNodes();
|
||||
const tracked = this.trackedNodes;
|
||||
const paths = Object.keys(tracked);
|
||||
|
||||
// If trace changed and we have no or an invalid selection, select first option.
|
||||
@ -509,42 +518,44 @@ class HatScriptGraph extends LitElement {
|
||||
|
||||
if (this.trace) {
|
||||
const sortKeys = Object.keys(this.trace.trace);
|
||||
const keys = Object.keys(this.trackedNodes).sort(
|
||||
const keys = Object.keys(this.renderedNodes).sort(
|
||||
(a, b) => sortKeys.indexOf(a) - sortKeys.indexOf(b)
|
||||
);
|
||||
const sortedTrackedNodes = keys.reduce((obj, key) => {
|
||||
obj[key] = this.trackedNodes[key];
|
||||
return obj;
|
||||
}, {});
|
||||
const sortedTrackedNodes = {};
|
||||
const sortedRenderedNodes = {};
|
||||
for (const key of keys) {
|
||||
sortedRenderedNodes[key] = this.renderedNodes[key];
|
||||
if (key in this.trackedNodes) {
|
||||
sortedTrackedNodes[key] = this.trackedNodes[key];
|
||||
}
|
||||
}
|
||||
this.renderedNodes = sortedRenderedNodes;
|
||||
this.trackedNodes = sortedTrackedNodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getTrackedNodes() {
|
||||
return this.trackedNodes;
|
||||
}
|
||||
|
||||
public previousTrackedNode() {
|
||||
const tracked = this.getTrackedNodes();
|
||||
const nodes = Object.keys(tracked);
|
||||
|
||||
for (let i = nodes.indexOf(this.selected) - 1; i >= 0; i--) {
|
||||
if (tracked[nodes[i]]) {
|
||||
fireEvent(this, "graph-node-selected", tracked[nodes[i]]);
|
||||
break;
|
||||
}
|
||||
const nodes = Object.keys(this.trackedNodes);
|
||||
const prevIndex = nodes.indexOf(this.selected) - 1;
|
||||
if (prevIndex >= 0) {
|
||||
fireEvent(
|
||||
this,
|
||||
"graph-node-selected",
|
||||
this.trackedNodes[nodes[prevIndex]]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public nextTrackedNode() {
|
||||
const tracked = this.getTrackedNodes();
|
||||
const nodes = Object.keys(tracked);
|
||||
for (let i = nodes.indexOf(this.selected) + 1; i < nodes.length; i++) {
|
||||
if (tracked[nodes[i]]) {
|
||||
fireEvent(this, "graph-node-selected", tracked[nodes[i]]);
|
||||
break;
|
||||
}
|
||||
const nodes = Object.keys(this.trackedNodes);
|
||||
const nextIndex = nodes.indexOf(this.selected) + 1;
|
||||
if (nextIndex < nodes.length) {
|
||||
fireEvent(
|
||||
this,
|
||||
"graph-node-selected",
|
||||
this.trackedNodes[nodes[nextIndex]]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,13 +245,15 @@ class ActionRenderer {
|
||||
try {
|
||||
data = getDataFromPath(this.trace.config, path);
|
||||
} catch (err) {
|
||||
this.entries.push(
|
||||
html`Unable to extract path ${path}. Download trace and report as bug`
|
||||
this._renderEntry(
|
||||
path,
|
||||
`Unable to extract path ${path}. Download trace and report as bug`
|
||||
);
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
const isTopLevel = path.split("/").length === 2;
|
||||
const parts = path.split("/");
|
||||
const isTopLevel = parts.length === 2;
|
||||
|
||||
if (!isTopLevel && !actionType) {
|
||||
this._renderEntry(path, path.replace(/\//g, " "));
|
||||
@ -267,7 +269,16 @@ class ActionRenderer {
|
||||
}
|
||||
|
||||
this._renderEntry(path, describeAction(this.hass, data, actionType));
|
||||
return index + 1;
|
||||
|
||||
let i = index + 1;
|
||||
|
||||
for (; i < this.keys.length; i++) {
|
||||
if (this.keys[i].split("/").length === parts.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private _handleTrigger(index: number, triggerStep: TriggerTraceStep): number {
|
||||
@ -303,7 +314,7 @@ class ActionRenderer {
|
||||
// +4: executed sequence
|
||||
|
||||
const choosePath = this.keys[index];
|
||||
const startLevel = choosePath.split("/").length - 1;
|
||||
const startLevel = choosePath.split("/").length;
|
||||
|
||||
const chooseTrace = this._getItem(index)[0] as ChooseActionTraceStep;
|
||||
const defaultExecuted = chooseTrace.result?.choice === "default";
|
||||
|
@ -7,8 +7,8 @@ export const describeCondition = (condition: Condition) => {
|
||||
if (condition.alias) {
|
||||
return condition.alias;
|
||||
}
|
||||
if (condition.condition === "template") {
|
||||
return "Test a template";
|
||||
if (["or", "and", "not"].includes(condition.condition)) {
|
||||
return `multiple conditions using "${condition.condition}"`;
|
||||
}
|
||||
return `${condition.condition} condition`;
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ export interface DeviceAction extends DeviceAutomation {
|
||||
}
|
||||
|
||||
export interface DeviceCondition extends DeviceAutomation {
|
||||
condition: string;
|
||||
condition: "device";
|
||||
}
|
||||
|
||||
export interface DeviceTrigger extends DeviceAutomation {
|
||||
|
@ -38,6 +38,8 @@ export class HaAutomationTracePathDetails extends LitElement {
|
||||
|
||||
@property() public logbookEntries!: LogbookEntry[];
|
||||
|
||||
@property() renderedNodes: Record<string, any> = {};
|
||||
|
||||
@property() public trackedNodes!: Record<string, any>;
|
||||
|
||||
@state() private _view: "config" | "changed_variables" | "logbook" = "config";
|
||||
@ -99,12 +101,12 @@ export class HaAutomationTracePathDetails extends LitElement {
|
||||
const parts: TemplateResult[][] = [];
|
||||
|
||||
let active = false;
|
||||
const childConditionsPrefix = `${this.selected.path}/conditions/`;
|
||||
|
||||
for (const curPath of Object.keys(this.trace.trace)) {
|
||||
// Include all child conditions too
|
||||
// Include all trace results until the next rendered node.
|
||||
// Rendered nodes also include non-chosen choose paths.
|
||||
if (active) {
|
||||
if (!curPath.startsWith(childConditionsPrefix)) {
|
||||
if (curPath in this.renderedNodes) {
|
||||
break;
|
||||
}
|
||||
} else if (curPath === this.selected.path) {
|
||||
@ -129,9 +131,7 @@ export class HaAutomationTracePathDetails extends LitElement {
|
||||
return html`
|
||||
${curPath === this.selected.path
|
||||
? ""
|
||||
: html`<h2>
|
||||
Condition ${curPath.substr(childConditionsPrefix.length)}
|
||||
</h2>`}
|
||||
: html`<h2>${curPath.substr(this.selected.path.length + 1)}</h2>`}
|
||||
${data.length === 1 ? "" : html`<h3>Iteration ${idx + 1}</h3>`}
|
||||
Executed:
|
||||
${formatDateTimeWithSeconds(
|
||||
|
@ -81,9 +81,9 @@ export class HaAutomationTrace extends LitElement {
|
||||
? this.hass.states[this._entityId]
|
||||
: undefined;
|
||||
|
||||
const trackedNodes = this.shadowRoot!.querySelector(
|
||||
"hat-script-graph"
|
||||
)?.getTrackedNodes();
|
||||
const graph = this.shadowRoot!.querySelector("hat-script-graph");
|
||||
const trackedNodes = graph?.trackedNodes;
|
||||
const renderedNodes = graph?.renderedNodes;
|
||||
|
||||
const title = stateObj?.attributes.friendly_name || this._entityId;
|
||||
|
||||
@ -234,6 +234,7 @@ export class HaAutomationTrace extends LitElement {
|
||||
.selected=${this._selected}
|
||||
.logbookEntries=${this._logbookEntries}
|
||||
.trackedNodes=${trackedNodes}
|
||||
.renderedNodes=${renderedNodes}
|
||||
></ha-automation-trace-path-details>
|
||||
`
|
||||
: this._view === "config"
|
||||
@ -442,9 +443,8 @@ export class HaAutomationTrace extends LitElement {
|
||||
|
||||
private _timelinePathPicked(ev) {
|
||||
const path = ev.detail.value;
|
||||
const nodes = this.shadowRoot!.querySelector(
|
||||
"hat-script-graph"
|
||||
)!.getTrackedNodes();
|
||||
const nodes = this.shadowRoot!.querySelector("hat-script-graph")!
|
||||
.trackedNodes;
|
||||
if (nodes[path]) {
|
||||
this._selected = nodes[path];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user