mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-14 21:06:34 +00:00
Link to traces from logbook entries (#8659)
Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
This commit is contained in:
parent
ef31bce5ee
commit
593e5ac79c
@ -72,6 +72,20 @@ export const loadAutomationTraces = (
|
|||||||
automation_id,
|
automation_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type AutomationTraceContexts = Record<
|
||||||
|
string,
|
||||||
|
{ run_id: string; automation_id: string }
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const loadAutomationTraceContexts = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
automation_id?: string
|
||||||
|
): Promise<AutomationTraceContexts> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "automation/trace/contexts",
|
||||||
|
automation_id,
|
||||||
|
});
|
||||||
|
|
||||||
export const getDataFromPath = (
|
export const getDataFromPath = (
|
||||||
config: AutomationConfig,
|
config: AutomationConfig,
|
||||||
path: string
|
path: string
|
||||||
|
@ -16,6 +16,7 @@ export interface LogbookEntry {
|
|||||||
icon?: string;
|
icon?: string;
|
||||||
source?: string;
|
source?: string;
|
||||||
domain?: string;
|
domain?: string;
|
||||||
|
context_id?: string;
|
||||||
context_user_id?: string;
|
context_user_id?: string;
|
||||||
context_event_type?: string;
|
context_event_type?: string;
|
||||||
context_domain?: string;
|
context_domain?: string;
|
||||||
|
@ -9,10 +9,15 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||||
|
import { closeDialog } from "../make-dialog-manager";
|
||||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||||
import { throttle } from "../../common/util/throttle";
|
import { throttle } from "../../common/util/throttle";
|
||||||
import "../../components/ha-circular-progress";
|
import "../../components/ha-circular-progress";
|
||||||
import "../../components/state-history-charts";
|
import "../../components/state-history-charts";
|
||||||
|
import {
|
||||||
|
AutomationTraceContexts,
|
||||||
|
loadAutomationTraceContexts,
|
||||||
|
} from "../../data/automation_debug";
|
||||||
import { getLogbookData, LogbookEntry } from "../../data/logbook";
|
import { getLogbookData, LogbookEntry } from "../../data/logbook";
|
||||||
import "../../panels/logbook/ha-logbook";
|
import "../../panels/logbook/ha-logbook";
|
||||||
import { haStyle, haStyleScrollbar } from "../../resources/styles";
|
import { haStyle, haStyleScrollbar } from "../../resources/styles";
|
||||||
@ -26,6 +31,8 @@ export class MoreInfoLogbook extends LitElement {
|
|||||||
|
|
||||||
@internalProperty() private _logbookEntries?: LogbookEntry[];
|
@internalProperty() private _logbookEntries?: LogbookEntry[];
|
||||||
|
|
||||||
|
@internalProperty() private _traceContexts?: AutomationTraceContexts;
|
||||||
|
|
||||||
@internalProperty() private _persons = {};
|
@internalProperty() private _persons = {};
|
||||||
|
|
||||||
private _lastLogbookDate?: Date;
|
private _lastLogbookDate?: Date;
|
||||||
@ -63,6 +70,7 @@ export class MoreInfoLogbook extends LitElement {
|
|||||||
relative-time
|
relative-time
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.entries=${this._logbookEntries}
|
.entries=${this._logbookEntries}
|
||||||
|
.traceContexts=${this._traceContexts}
|
||||||
.userIdToName=${this._persons}
|
.userIdToName=${this._persons}
|
||||||
></ha-logbook>
|
></ha-logbook>
|
||||||
`
|
`
|
||||||
@ -75,6 +83,11 @@ export class MoreInfoLogbook extends LitElement {
|
|||||||
|
|
||||||
protected firstUpdated(): void {
|
protected firstUpdated(): void {
|
||||||
this._fetchPersonNames();
|
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 {
|
protected updated(changedProps: PropertyValues): void {
|
||||||
@ -115,17 +128,21 @@ export class MoreInfoLogbook extends LitElement {
|
|||||||
this._lastLogbookDate ||
|
this._lastLogbookDate ||
|
||||||
new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
|
new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const newEntries = await getLogbookData(
|
const [newEntries, traceContexts] = await Promise.all([
|
||||||
this.hass,
|
getLogbookData(
|
||||||
lastDate.toISOString(),
|
this.hass,
|
||||||
now.toISOString(),
|
lastDate.toISOString(),
|
||||||
this.entityId,
|
now.toISOString(),
|
||||||
true
|
this.entityId,
|
||||||
);
|
true
|
||||||
|
),
|
||||||
|
loadAutomationTraceContexts(this.hass),
|
||||||
|
]);
|
||||||
this._logbookEntries = this._logbookEntries
|
this._logbookEntries = this._logbookEntries
|
||||||
? [...newEntries, ...this._logbookEntries]
|
? [...newEntries, ...this._logbookEntries]
|
||||||
: newEntries;
|
: newEntries;
|
||||||
this._lastLogbookDate = now;
|
this._lastLogbookDate = now;
|
||||||
|
this._traceContexts = traceContexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _fetchPersonNames() {
|
private _fetchPersonNames() {
|
||||||
|
@ -22,6 +22,7 @@ import { computeRTL, emitRTLDirection } from "../../common/util/compute_rtl";
|
|||||||
import "../../components/entity/state-badge";
|
import "../../components/entity/state-badge";
|
||||||
import "../../components/ha-circular-progress";
|
import "../../components/ha-circular-progress";
|
||||||
import "../../components/ha-relative-time";
|
import "../../components/ha-relative-time";
|
||||||
|
import { AutomationTraceContexts } from "../../data/automation_debug";
|
||||||
import { LogbookEntry } from "../../data/logbook";
|
import { LogbookEntry } from "../../data/logbook";
|
||||||
import { haStyle, haStyleScrollbar } from "../../resources/styles";
|
import { haStyle, haStyleScrollbar } from "../../resources/styles";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
@ -32,6 +33,9 @@ class HaLogbook extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public userIdToName = {};
|
@property({ attribute: false }) public userIdToName = {};
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public traceContexts: AutomationTraceContexts = {};
|
||||||
|
|
||||||
@property({ attribute: false }) public entries: LogbookEntry[] = [];
|
@property({ attribute: false }) public entries: LogbookEntry[] = [];
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "narrow" })
|
@property({ type: Boolean, attribute: "narrow" })
|
||||||
@ -55,12 +59,16 @@ class HaLogbook extends LitElement {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@restoreScroll(".container") private _savedScrollPos?: number;
|
@restoreScroll(".container") private _savedScrollPos?: number;
|
||||||
|
|
||||||
protected shouldUpdate(changedProps: PropertyValues) {
|
protected shouldUpdate(changedProps: PropertyValues<this>) {
|
||||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
const languageChanged =
|
const languageChanged =
|
||||||
oldHass === undefined || oldHass.language !== this.hass.language;
|
oldHass === undefined || oldHass.language !== this.hass.language;
|
||||||
|
|
||||||
return changedProps.has("entries") || languageChanged;
|
return (
|
||||||
|
changedProps.has("entries") ||
|
||||||
|
changedProps.has("traceContexts") ||
|
||||||
|
languageChanged
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(_changedProps: PropertyValues) {
|
protected updated(_changedProps: PropertyValues) {
|
||||||
@ -204,6 +212,22 @@ class HaLogbook extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.datetime=${item.when}
|
.datetime=${item.when}
|
||||||
></ha-relative-time>
|
></ha-relative-time>
|
||||||
|
${item.domain === "automation" &&
|
||||||
|
item.context_id! in this.traceContexts
|
||||||
|
? html`
|
||||||
|
-
|
||||||
|
<a
|
||||||
|
href=${`/config/automation/trace/${
|
||||||
|
this.traceContexts[item.context_id!].automation_id
|
||||||
|
}?run_id=${
|
||||||
|
this.traceContexts[item.context_id!].run_id
|
||||||
|
}`}
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.components.logbook.show_trace"
|
||||||
|
)}</a
|
||||||
|
>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -280,6 +304,10 @@ class HaLogbook extends LitElement {
|
|||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.secondary a {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
.date {
|
.date {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
@ -17,6 +17,7 @@ import "../../components/ha-date-range-picker";
|
|||||||
import type { DateRangePickerRanges } from "../../components/ha-date-range-picker";
|
import type { DateRangePickerRanges } from "../../components/ha-date-range-picker";
|
||||||
import "../../components/ha-icon-button";
|
import "../../components/ha-icon-button";
|
||||||
import "../../components/ha-menu-button";
|
import "../../components/ha-menu-button";
|
||||||
|
import { AutomationTraceContexts, loadAutomationTraceContexts } from "../../data/automation_debug";
|
||||||
import {
|
import {
|
||||||
clearLogbookCache,
|
clearLogbookCache,
|
||||||
getLogbookData,
|
getLogbookData,
|
||||||
@ -35,9 +36,6 @@ export class HaPanelLogbook extends LitElement {
|
|||||||
|
|
||||||
@property({ reflect: true, type: Boolean }) narrow!: boolean;
|
@property({ reflect: true, type: Boolean }) narrow!: boolean;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
private _userIdToName = {};
|
|
||||||
|
|
||||||
@property() _startDate: Date;
|
@property() _startDate: Date;
|
||||||
|
|
||||||
@property() _endDate: Date;
|
@property() _endDate: Date;
|
||||||
@ -54,6 +52,10 @@ export class HaPanelLogbook extends LitElement {
|
|||||||
|
|
||||||
private _fetchUserDone?: Promise<unknown>;
|
private _fetchUserDone?: Promise<unknown>;
|
||||||
|
|
||||||
|
@internalProperty() private _userIdToName = {};
|
||||||
|
|
||||||
|
@internalProperty() private _traceContexts: AutomationTraceContexts = {};
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -128,6 +130,7 @@ export class HaPanelLogbook extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.entries=${this._entries}
|
.entries=${this._entries}
|
||||||
.userIdToName=${this._userIdToName}
|
.userIdToName=${this._userIdToName}
|
||||||
|
.traceContexts=${this._traceContexts}
|
||||||
virtualize
|
virtualize
|
||||||
></ha-logbook>
|
></ha-logbook>
|
||||||
`}
|
`}
|
||||||
@ -181,7 +184,7 @@ export class HaPanelLogbook extends LitElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues<this>) {
|
||||||
if (
|
if (
|
||||||
changedProps.has("_startDate") ||
|
changedProps.has("_startDate") ||
|
||||||
changedProps.has("_endDate") ||
|
changedProps.has("_endDate") ||
|
||||||
@ -257,19 +260,19 @@ export class HaPanelLogbook extends LitElement {
|
|||||||
|
|
||||||
private async _getData() {
|
private async _getData() {
|
||||||
this._isLoading = true;
|
this._isLoading = true;
|
||||||
const [entries] = await Promise.all([
|
const [entries, traceContexts] = await Promise.all([
|
||||||
getLogbookData(
|
getLogbookData(
|
||||||
this.hass,
|
this.hass,
|
||||||
this._startDate.toISOString(),
|
this._startDate.toISOString(),
|
||||||
this._endDate.toISOString(),
|
this._endDate.toISOString(),
|
||||||
this._entityId
|
this._entityId
|
||||||
),
|
),
|
||||||
|
loadAutomationTraceContexts(this.hass),
|
||||||
this._fetchUserDone,
|
this._fetchUserDone,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Fixed in TS 3.9 but upgrade out of scope for this PR.
|
|
||||||
// @ts-ignore
|
|
||||||
this._entries = entries;
|
this._entries = entries;
|
||||||
|
this._traceContexts = traceContexts;
|
||||||
this._isLoading = false;
|
this._isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +300,7 @@
|
|||||||
"entries_not_found": "No logbook entries found.",
|
"entries_not_found": "No logbook entries found.",
|
||||||
"by": "by",
|
"by": "by",
|
||||||
"by_service": "by service",
|
"by_service": "by service",
|
||||||
|
"show_trace": "Show trace",
|
||||||
"messages": {
|
"messages": {
|
||||||
"was_away": "was detected away",
|
"was_away": "was detected away",
|
||||||
"was_at_state": "was detected at {state}",
|
"was_at_state": "was detected at {state}",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user