diff --git a/src/data/automation_debug.ts b/src/data/automation_debug.ts index 01251bb0d3..2257d1e6bc 100644 --- a/src/data/automation_debug.ts +++ b/src/data/automation_debug.ts @@ -72,6 +72,20 @@ export const loadAutomationTraces = ( automation_id, }); +export type AutomationTraceContexts = Record< + string, + { run_id: string; automation_id: string } +>; + +export const loadAutomationTraceContexts = ( + hass: HomeAssistant, + automation_id?: string +): Promise => + hass.callWS({ + type: "automation/trace/contexts", + automation_id, + }); + export const getDataFromPath = ( config: AutomationConfig, path: string diff --git a/src/data/logbook.ts b/src/data/logbook.ts index 50a3eec209..27dd865df9 100644 --- a/src/data/logbook.ts +++ b/src/data/logbook.ts @@ -16,6 +16,7 @@ export interface LogbookEntry { icon?: string; source?: string; domain?: string; + context_id?: string; context_user_id?: string; context_event_type?: string; context_domain?: string; diff --git a/src/dialogs/more-info/ha-more-info-logbook.ts b/src/dialogs/more-info/ha-more-info-logbook.ts index 107636a7c0..56919a3001 100644 --- a/src/dialogs/more-info/ha-more-info-logbook.ts +++ b/src/dialogs/more-info/ha-more-info-logbook.ts @@ -9,10 +9,15 @@ import { TemplateResult, } from "lit-element"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; +import { closeDialog } from "../make-dialog-manager"; import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { throttle } from "../../common/util/throttle"; import "../../components/ha-circular-progress"; import "../../components/state-history-charts"; +import { + AutomationTraceContexts, + loadAutomationTraceContexts, +} from "../../data/automation_debug"; import { getLogbookData, LogbookEntry } from "../../data/logbook"; import "../../panels/logbook/ha-logbook"; import { haStyle, haStyleScrollbar } from "../../resources/styles"; @@ -26,6 +31,8 @@ export class MoreInfoLogbook extends LitElement { @internalProperty() private _logbookEntries?: LogbookEntry[]; + @internalProperty() private _traceContexts?: AutomationTraceContexts; + @internalProperty() private _persons = {}; private _lastLogbookDate?: Date; @@ -63,6 +70,7 @@ export class MoreInfoLogbook extends LitElement { relative-time .hass=${this.hass} .entries=${this._logbookEntries} + .traceContexts=${this._traceContexts} .userIdToName=${this._persons} > ` @@ -75,6 +83,11 @@ export class MoreInfoLogbook extends LitElement { protected firstUpdated(): void { this._fetchPersonNames(); + this.addEventListener("click", (ev) => { + if ((ev.composedPath()[0] as HTMLElement).tagName === "A") { + setTimeout(() => closeDialog("ha-more-info-dialog"), 500); + } + }); } protected updated(changedProps: PropertyValues): void { @@ -115,17 +128,21 @@ export class MoreInfoLogbook extends LitElement { this._lastLogbookDate || new Date(new Date().getTime() - 24 * 60 * 60 * 1000); const now = new Date(); - const newEntries = await getLogbookData( - this.hass, - lastDate.toISOString(), - now.toISOString(), - this.entityId, - true - ); + const [newEntries, traceContexts] = await Promise.all([ + getLogbookData( + this.hass, + lastDate.toISOString(), + now.toISOString(), + this.entityId, + true + ), + loadAutomationTraceContexts(this.hass), + ]); this._logbookEntries = this._logbookEntries ? [...newEntries, ...this._logbookEntries] : newEntries; this._lastLogbookDate = now; + this._traceContexts = traceContexts; } private _fetchPersonNames() { diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts index 29e90f80a7..2b5b23814c 100644 --- a/src/panels/logbook/ha-logbook.ts +++ b/src/panels/logbook/ha-logbook.ts @@ -22,6 +22,7 @@ import { computeRTL, emitRTLDirection } from "../../common/util/compute_rtl"; import "../../components/entity/state-badge"; import "../../components/ha-circular-progress"; import "../../components/ha-relative-time"; +import { AutomationTraceContexts } from "../../data/automation_debug"; import { LogbookEntry } from "../../data/logbook"; import { haStyle, haStyleScrollbar } from "../../resources/styles"; import { HomeAssistant } from "../../types"; @@ -32,6 +33,9 @@ class HaLogbook extends LitElement { @property({ attribute: false }) public userIdToName = {}; + @property({ attribute: false }) + public traceContexts: AutomationTraceContexts = {}; + @property({ attribute: false }) public entries: LogbookEntry[] = []; @property({ type: Boolean, attribute: "narrow" }) @@ -55,12 +59,16 @@ class HaLogbook extends LitElement { // @ts-ignore @restoreScroll(".container") private _savedScrollPos?: number; - protected shouldUpdate(changedProps: PropertyValues) { + protected shouldUpdate(changedProps: PropertyValues) { const oldHass = changedProps.get("hass") as HomeAssistant | undefined; const languageChanged = oldHass === undefined || oldHass.language !== this.hass.language; - return changedProps.has("entries") || languageChanged; + return ( + changedProps.has("entries") || + changedProps.has("traceContexts") || + languageChanged + ); } protected updated(_changedProps: PropertyValues) { @@ -204,6 +212,22 @@ class HaLogbook extends LitElement { .hass=${this.hass} .datetime=${item.when} > + ${item.domain === "automation" && + item.context_id! in this.traceContexts + ? html` + - + ${this.hass.localize( + "ui.components.logbook.show_trace" + )} + ` + : ""} @@ -280,6 +304,10 @@ class HaLogbook extends LitElement { line-height: 1.7; } + .secondary a { + color: var(--secondary-text-color); + } + .date { margin: 8px 0; padding: 0 16px; diff --git a/src/panels/logbook/ha-panel-logbook.ts b/src/panels/logbook/ha-panel-logbook.ts index f9054ff86e..c71365a320 100644 --- a/src/panels/logbook/ha-panel-logbook.ts +++ b/src/panels/logbook/ha-panel-logbook.ts @@ -17,6 +17,7 @@ import "../../components/ha-date-range-picker"; import type { DateRangePickerRanges } from "../../components/ha-date-range-picker"; import "../../components/ha-icon-button"; import "../../components/ha-menu-button"; +import { AutomationTraceContexts, loadAutomationTraceContexts } from "../../data/automation_debug"; import { clearLogbookCache, getLogbookData, @@ -35,9 +36,6 @@ export class HaPanelLogbook extends LitElement { @property({ reflect: true, type: Boolean }) narrow!: boolean; - @property({ attribute: false }) - private _userIdToName = {}; - @property() _startDate: Date; @property() _endDate: Date; @@ -54,6 +52,10 @@ export class HaPanelLogbook extends LitElement { private _fetchUserDone?: Promise; + @internalProperty() private _userIdToName = {}; + + @internalProperty() private _traceContexts: AutomationTraceContexts = {}; + public constructor() { super(); @@ -128,6 +130,7 @@ export class HaPanelLogbook extends LitElement { .hass=${this.hass} .entries=${this._entries} .userIdToName=${this._userIdToName} + .traceContexts=${this._traceContexts} virtualize > `} @@ -181,7 +184,7 @@ export class HaPanelLogbook extends LitElement { }; } - protected updated(changedProps: PropertyValues) { + protected updated(changedProps: PropertyValues) { if ( changedProps.has("_startDate") || changedProps.has("_endDate") || @@ -257,19 +260,19 @@ export class HaPanelLogbook extends LitElement { private async _getData() { this._isLoading = true; - const [entries] = await Promise.all([ + const [entries, traceContexts] = await Promise.all([ getLogbookData( this.hass, this._startDate.toISOString(), this._endDate.toISOString(), this._entityId ), + loadAutomationTraceContexts(this.hass), this._fetchUserDone, ]); - // Fixed in TS 3.9 but upgrade out of scope for this PR. - // @ts-ignore this._entries = entries; + this._traceContexts = traceContexts; this._isLoading = false; } diff --git a/src/translations/en.json b/src/translations/en.json index c523f09742..18bbf6ab91 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -300,6 +300,7 @@ "entries_not_found": "No logbook entries found.", "by": "by", "by_service": "by service", + "show_trace": "Show trace", "messages": { "was_away": "was detected away", "was_at_state": "was detected at {state}",