mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
Add target error badge if target is missing (#30352)
* Add target error badge if target is missing * Don't show for newly added items
This commit is contained in:
@@ -185,6 +185,8 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
|
||||
@state() private _collapsed = true;
|
||||
|
||||
@state() private _isNew = false;
|
||||
|
||||
@state() private _warnings?: string[];
|
||||
|
||||
@query("ha-automation-action-editor")
|
||||
@@ -237,12 +239,13 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
private _renderRow() {
|
||||
const type = getAutomationActionType(this.action);
|
||||
|
||||
const target =
|
||||
type === "service" && "target" in this.action
|
||||
? (this.action as ServiceAction).target
|
||||
: type === "device_id" && (this.action as DeviceAction).device_id
|
||||
? { device_id: (this.action as DeviceAction).device_id }
|
||||
: undefined;
|
||||
const actionHasTarget = type === "service" && "target" in this.action;
|
||||
|
||||
const target = actionHasTarget
|
||||
? (this.action as ServiceAction).target
|
||||
: type === "device_id" && (this.action as DeviceAction).device_id
|
||||
? { device_id: (this.action as DeviceAction).device_id }
|
||||
: undefined;
|
||||
|
||||
return html`
|
||||
${type === "service" && "action" in this.action && this.action.action
|
||||
@@ -265,7 +268,9 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
${capitalizeFirstLetter(
|
||||
describeAction(this.hass, this._entityReg, this.action)
|
||||
)}
|
||||
${target ? this._renderTargets(target) : nothing}
|
||||
${target !== undefined || (actionHasTarget && !this._isNew)
|
||||
? this._renderTargets(target, actionHasTarget && !this._isNew)
|
||||
: nothing}
|
||||
${type !== "condition" &&
|
||||
(this.action as NonConditionAction).continue_on_error === true
|
||||
? html`<ha-svg-icon
|
||||
@@ -575,10 +580,11 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
}
|
||||
|
||||
private _renderTargets = memoizeOne(
|
||||
(target?: HassServiceTarget) =>
|
||||
(target?: HassServiceTarget, targetRequired = false) =>
|
||||
html`<ha-automation-row-targets
|
||||
.hass=${this.hass}
|
||||
.target=${target}
|
||||
.targetRequired=${targetRequired}
|
||||
></ha-automation-row-targets>`
|
||||
);
|
||||
|
||||
@@ -812,6 +818,10 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
this.openSidebar();
|
||||
}
|
||||
|
||||
public markAsNew(): void {
|
||||
this._isNew = true;
|
||||
}
|
||||
|
||||
public openSidebar(action?: Action): void {
|
||||
const sidebarAction = action ?? this.action;
|
||||
const actionType = getAutomationActionType(sidebarAction);
|
||||
@@ -822,6 +832,7 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
},
|
||||
close: (focus?: boolean) => {
|
||||
this._selected = false;
|
||||
this._isNew = false;
|
||||
fireEvent(this, "close-sidebar");
|
||||
if (focus) {
|
||||
this.focus();
|
||||
@@ -901,6 +912,9 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
);
|
||||
|
||||
private _toggleCollapse() {
|
||||
if (!this._collapsed) {
|
||||
this._isNew = false;
|
||||
}
|
||||
this._collapsed = !this._collapsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ export default class HaAutomationAction extends AutomationSortableListMixin<Acti
|
||||
|
||||
if (mode === "new") {
|
||||
row.expand();
|
||||
row.markAsNew();
|
||||
}
|
||||
|
||||
if (!this.optionsInSidebar) {
|
||||
|
||||
@@ -107,6 +107,8 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
|
||||
@state() private _collapsed = true;
|
||||
|
||||
@state() private _isNew = false;
|
||||
|
||||
@state() private _warnings?: string[];
|
||||
|
||||
@property({ attribute: false })
|
||||
@@ -160,13 +162,15 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
}
|
||||
|
||||
private _renderRow() {
|
||||
const target =
|
||||
"target" in (this.conditionDescriptions[this.condition.condition] || {})
|
||||
? (this.condition as PlatformCondition).target
|
||||
: "device_id" in this.condition &&
|
||||
(this.condition as DeviceCondition).device_id
|
||||
? { device_id: [(this.condition as DeviceCondition).device_id] }
|
||||
: undefined;
|
||||
const descriptionHasTarget =
|
||||
"target" in (this.conditionDescriptions[this.condition.condition] || {});
|
||||
|
||||
const target = descriptionHasTarget
|
||||
? (this.condition as PlatformCondition).target
|
||||
: "device_id" in this.condition &&
|
||||
(this.condition as DeviceCondition).device_id
|
||||
? { device_id: [(this.condition as DeviceCondition).device_id] }
|
||||
: undefined;
|
||||
|
||||
return html`
|
||||
<ha-condition-icon
|
||||
@@ -178,7 +182,9 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
${capitalizeFirstLetter(
|
||||
describeCondition(this.condition, this.hass, this._entityReg)
|
||||
)}
|
||||
${target ? this._renderTargets(target) : nothing}
|
||||
${target !== undefined || (descriptionHasTarget && !this._isNew)
|
||||
? this._renderTargets(target, descriptionHasTarget && !this._isNew)
|
||||
: nothing}
|
||||
</h3>
|
||||
|
||||
<slot name="icons" slot="icons"></slot>
|
||||
@@ -464,10 +470,11 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
}
|
||||
|
||||
private _renderTargets = memoizeOne(
|
||||
(target?: HassServiceTarget) =>
|
||||
(target?: HassServiceTarget, targetRequired = false) =>
|
||||
html`<ha-automation-row-targets
|
||||
.hass=${this.hass}
|
||||
.target=${target}
|
||||
.targetRequired=${targetRequired}
|
||||
></ha-automation-row-targets>`
|
||||
);
|
||||
|
||||
@@ -743,6 +750,10 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
this.openSidebar();
|
||||
}
|
||||
|
||||
public markAsNew(): void {
|
||||
this._isNew = true;
|
||||
}
|
||||
|
||||
public openSidebar(condition?: Condition): void {
|
||||
const sidebarCondition = condition || this.condition;
|
||||
fireEvent(this, "open-sidebar", {
|
||||
@@ -751,6 +762,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
},
|
||||
close: (focus?: boolean) => {
|
||||
this._selected = false;
|
||||
this._isNew = false;
|
||||
fireEvent(this, "close-sidebar");
|
||||
if (focus) {
|
||||
this.focus();
|
||||
@@ -806,6 +818,9 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
);
|
||||
|
||||
private _toggleCollapse() {
|
||||
if (!this._collapsed) {
|
||||
this._isNew = false;
|
||||
}
|
||||
this._collapsed = !this._collapsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ export default class HaAutomationCondition extends AutomationSortableListMixin<C
|
||||
|
||||
if (mode === "new") {
|
||||
row.expand();
|
||||
row.markAsNew();
|
||||
}
|
||||
|
||||
if (!this.optionsInSidebar) {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { consume } from "@lit/context";
|
||||
import {
|
||||
mdiAlert,
|
||||
mdiAlertOctagon,
|
||||
mdiCodeBraces,
|
||||
mdiFormatListBulleted,
|
||||
mdiShape,
|
||||
} from "@mdi/js";
|
||||
import type { HassServiceTarget } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, type nothing, type TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing, type TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { ensureArray } from "../../../../common/array/ensure-array";
|
||||
import { transform } from "../../../../common/decorators/transform";
|
||||
import { isTemplate } from "../../../../common/string/has-template";
|
||||
@@ -35,6 +37,9 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public target?: HassServiceTarget;
|
||||
|
||||
@property({ attribute: false })
|
||||
public targetRequired = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: HomeAssistant["localize"];
|
||||
@@ -73,13 +78,16 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
protected render() {
|
||||
const length = Object.keys(this.target || {}).length;
|
||||
if (!length) {
|
||||
return html`<span class="target">
|
||||
<div class="label">
|
||||
${this.localize(
|
||||
"ui.panel.config.automation.editor.target_summary.no_target"
|
||||
)}
|
||||
</div>
|
||||
</span>`;
|
||||
return this._renderTargetBadge(
|
||||
this.targetRequired
|
||||
? html`<ha-svg-icon .path=${mdiAlertOctagon}></ha-svg-icon>`
|
||||
: nothing,
|
||||
this.localize(
|
||||
"ui.panel.config.automation.editor.target_summary.no_target"
|
||||
),
|
||||
false,
|
||||
this.targetRequired
|
||||
);
|
||||
}
|
||||
const totalLength = Object.values(this.target || {}).reduce(
|
||||
(acc, val) => acc + ensureArray(val).length,
|
||||
@@ -154,9 +162,10 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
private _renderTargetBadge(
|
||||
icon: TemplateResult | typeof nothing,
|
||||
label: string,
|
||||
alert = false
|
||||
warning = false,
|
||||
error = false
|
||||
) {
|
||||
return html`<div class="target ${alert ? "alert" : ""}">
|
||||
return html`<div class=${classMap({ target: true, warning, error })}>
|
||||
${icon}
|
||||
<div class="label">${label}</div>
|
||||
</div>`;
|
||||
@@ -230,10 +239,14 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
overflow: hidden;
|
||||
height: 32px;
|
||||
}
|
||||
.target.alert {
|
||||
.target.warning {
|
||||
background: var(--ha-color-fill-warning-normal-resting);
|
||||
color: var(--ha-color-on-warning-normal);
|
||||
}
|
||||
.target.error {
|
||||
background: var(--ha-color-fill-danger-normal-resting);
|
||||
color: var(--ha-color-on-danger-normal);
|
||||
}
|
||||
.target .label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -145,6 +145,8 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
|
||||
@state() private _selected = false;
|
||||
|
||||
@state() private _isNew = false;
|
||||
|
||||
@state() private _warnings?: string[];
|
||||
|
||||
@property({ attribute: false })
|
||||
@@ -197,14 +199,16 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
|
||||
const yamlMode = this._yamlMode || !supported;
|
||||
|
||||
const target =
|
||||
const descriptionHasTarget =
|
||||
type === "platform" &&
|
||||
"target" in
|
||||
this.triggerDescriptions[(this.trigger as PlatformTrigger).trigger]
|
||||
? (this.trigger as PlatformTrigger).target
|
||||
: type === "device" && (this.trigger as DeviceTrigger).device_id
|
||||
? { device_id: (this.trigger as DeviceTrigger).device_id }
|
||||
: undefined;
|
||||
this.triggerDescriptions[(this.trigger as PlatformTrigger).trigger];
|
||||
|
||||
const target = descriptionHasTarget
|
||||
? (this.trigger as PlatformTrigger).target
|
||||
: type === "device" && (this.trigger as DeviceTrigger).device_id
|
||||
? { device_id: (this.trigger as DeviceTrigger).device_id }
|
||||
: undefined;
|
||||
|
||||
return html`
|
||||
${type === "list"
|
||||
@@ -220,7 +224,9 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
></ha-trigger-icon>`}
|
||||
<h3 slot="header">
|
||||
${describeTrigger(this.trigger, this.hass, this._entityReg)}
|
||||
${target ? this._renderTargets(target) : nothing}
|
||||
${target !== undefined || (descriptionHasTarget && !this._isNew)
|
||||
? this._renderTargets(target, descriptionHasTarget && !this._isNew)
|
||||
: nothing}
|
||||
</h3>
|
||||
|
||||
<slot name="icons" slot="icons"></slot>
|
||||
@@ -446,7 +452,10 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
: nothing}${this._renderRow()}</ha-automation-row
|
||||
>`
|
||||
: html`
|
||||
<ha-expansion-panel left-chevron>
|
||||
<ha-expansion-panel
|
||||
left-chevron
|
||||
@expanded-changed=${this._expansionPanelChanged}
|
||||
>
|
||||
${this._renderRow()}
|
||||
</ha-expansion-panel>
|
||||
`}
|
||||
@@ -467,10 +476,11 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
}
|
||||
|
||||
private _renderTargets = memoizeOne(
|
||||
(target?: HassServiceTarget) =>
|
||||
(target?: HassServiceTarget, targetRequired = false) =>
|
||||
html`<ha-automation-row-targets
|
||||
.hass=${this.hass}
|
||||
.target=${target}
|
||||
.targetRequired=${targetRequired}
|
||||
></ha-automation-row-targets>`
|
||||
);
|
||||
|
||||
@@ -576,6 +586,16 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
this.openSidebar();
|
||||
}
|
||||
|
||||
public markAsNew(): void {
|
||||
this._isNew = true;
|
||||
}
|
||||
|
||||
private _expansionPanelChanged(ev: CustomEvent) {
|
||||
if (!ev.detail.expanded) {
|
||||
this._isNew = false;
|
||||
}
|
||||
}
|
||||
|
||||
public openSidebar(trigger?: Trigger): void {
|
||||
trigger = trigger || this.trigger;
|
||||
fireEvent(this, "open-sidebar", {
|
||||
@@ -584,6 +604,7 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
},
|
||||
close: (focus?: boolean) => {
|
||||
this._selected = false;
|
||||
this._isNew = false;
|
||||
fireEvent(this, "close-sidebar");
|
||||
if (focus) {
|
||||
this.focus();
|
||||
|
||||
@@ -252,6 +252,7 @@ export default class HaAutomationTrigger extends AutomationSortableListMixin<Tri
|
||||
row.expand();
|
||||
row.focus();
|
||||
}
|
||||
row.markAsNew();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user