mirror of
https://github.com/home-assistant/frontend.git
synced 2026-05-23 01:27:07 +00:00
Compare commits
3 Commits
dev
...
add-to-target-ui
| Author | SHA1 | Date | |
|---|---|---|---|
| 73e05237a4 | |||
| 6137d7ffff | |||
| 625324846f |
@@ -51,25 +51,59 @@ interface ActionDefinition {
|
||||
icon: string;
|
||||
}
|
||||
|
||||
const ADD_TO_TARGET_PLACEHOLDER = "__HA_ADD_TO_TARGET__";
|
||||
|
||||
export const ADD_TO_ACTION_ICONS: Record<AddToActionKey, string> = {
|
||||
automation_trigger: "mdi:robot-outline",
|
||||
automation_condition: "mdi:playlist-check",
|
||||
automation_action: "mdi:play-circle-outline",
|
||||
script_action: "mdi:script-text-outline",
|
||||
scene: "mdi:palette",
|
||||
};
|
||||
|
||||
export const DEFAULT_ACTION_DEFS: ActionDefinition[] = [
|
||||
{
|
||||
translation_key: "automation_trigger",
|
||||
icon: "mdi:robot-outline",
|
||||
icon: ADD_TO_ACTION_ICONS.automation_trigger,
|
||||
},
|
||||
{
|
||||
translation_key: "automation_condition",
|
||||
icon: "mdi:playlist-check",
|
||||
icon: ADD_TO_ACTION_ICONS.automation_condition,
|
||||
},
|
||||
{
|
||||
translation_key: "automation_action",
|
||||
icon: "mdi:play-circle-outline",
|
||||
icon: ADD_TO_ACTION_ICONS.automation_action,
|
||||
},
|
||||
{
|
||||
translation_key: "script_action",
|
||||
icon: "mdi:script-text-outline",
|
||||
icon: ADD_TO_ACTION_ICONS.script_action,
|
||||
},
|
||||
];
|
||||
|
||||
export const getAddToActionLabel = (
|
||||
localize: LocalizeFunc,
|
||||
key: AddToActionKey,
|
||||
target: string
|
||||
): string =>
|
||||
localize(`ui.dialogs.more_info_control.add_to.actions.${key}`, { target });
|
||||
|
||||
export const getAddToActionLabelParts = (
|
||||
localize: LocalizeFunc,
|
||||
key: AddToActionKey
|
||||
): [string, string] => {
|
||||
const label = getAddToActionLabel(localize, key, ADD_TO_TARGET_PLACEHOLDER);
|
||||
const placeholderIndex = label.indexOf(ADD_TO_TARGET_PLACEHOLDER);
|
||||
|
||||
if (placeholderIndex === -1) {
|
||||
return [label, ""];
|
||||
}
|
||||
|
||||
return [
|
||||
label.slice(0, placeholderIndex),
|
||||
label.slice(placeholderIndex + ADD_TO_TARGET_PLACEHOLDER.length),
|
||||
];
|
||||
};
|
||||
|
||||
export const getDefaultAddToActions = (
|
||||
states: HomeAssistant["states"],
|
||||
localize: LocalizeFunc,
|
||||
@@ -81,14 +115,12 @@ export const getDefaultAddToActions = (
|
||||
type: "default",
|
||||
key: def.translation_key,
|
||||
enabled: true,
|
||||
name: localize(
|
||||
`ui.dialogs.more_info_control.add_to.actions.${def.translation_key}`,
|
||||
{
|
||||
target:
|
||||
states[entityId] !== undefined
|
||||
? formatEntityName(states[entityId], undefined)
|
||||
: entityId,
|
||||
}
|
||||
name: getAddToActionLabel(
|
||||
localize,
|
||||
def.translation_key,
|
||||
states[entityId] !== undefined
|
||||
? formatEntityName(states[entityId], undefined)
|
||||
: entityId
|
||||
),
|
||||
icon: def.icon,
|
||||
})
|
||||
|
||||
@@ -5,17 +5,17 @@ import "../../components/ha-icon";
|
||||
import "../../components/ha-spinner";
|
||||
import "../../components/item/ha-list-item-button";
|
||||
import "../../components/list/ha-list-base";
|
||||
import type { HaListItemButton } from "../../components/item/ha-list-item-button";
|
||||
import "../../panels/config/automation/target/ha-automation-target-badge";
|
||||
import { showToast } from "../../util/toast";
|
||||
|
||||
import type { HASSDomCurrentTargetEvent } from "../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import {
|
||||
type EntityAddToAction,
|
||||
type AddToActionKey,
|
||||
type EntityAddToActions,
|
||||
addToActionHandler,
|
||||
getDefaultAddToActions,
|
||||
getAddToActionLabelParts,
|
||||
} from "./add-to";
|
||||
|
||||
@customElement("ha-more-info-add-to")
|
||||
@@ -65,14 +65,18 @@ export class HaMoreInfoAddTo extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async _actionSelected(
|
||||
ev: HASSDomCurrentTargetEvent<
|
||||
HaListItemButton & {
|
||||
action: EntityAddToAction;
|
||||
}
|
||||
>
|
||||
) {
|
||||
const action = ev.currentTarget.action;
|
||||
private async _actionSelected(ev: Event) {
|
||||
const item = ev.currentTarget as HTMLElement;
|
||||
const actions =
|
||||
item.dataset.actionSource === "external"
|
||||
? this._externalActions
|
||||
: this._defaultActions;
|
||||
const action = actions[Number(item.dataset.actionIndex)];
|
||||
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!action.enabled) {
|
||||
return;
|
||||
}
|
||||
@@ -110,16 +114,25 @@ export class HaMoreInfoAddTo extends LitElement {
|
||||
addToActionHandler(action.key, { entity_id: this.entityId });
|
||||
}
|
||||
|
||||
private _renderActionItems(actions: EntityAddToActions) {
|
||||
private _renderActionItems(
|
||||
actions: EntityAddToActions,
|
||||
source: "default" | "external"
|
||||
) {
|
||||
return actions.map(
|
||||
(action) => html`
|
||||
(action, index) => html`
|
||||
<ha-list-item-button
|
||||
aria-label=${action.name}
|
||||
data-action-index=${index}
|
||||
data-action-source=${source}
|
||||
.disabled=${!action.enabled}
|
||||
.action=${action}
|
||||
@click=${this._actionSelected}
|
||||
>
|
||||
<ha-icon slot="start" .icon=${action.icon}></ha-icon>
|
||||
<span slot="headline">${action.name}</span>
|
||||
<span slot="headline" class="action-label">
|
||||
${action.type === "default"
|
||||
? this._renderDefaultActionLabel(action.key)
|
||||
: action.name}
|
||||
</span>
|
||||
${action.description
|
||||
? html`<span slot="supporting-text">${action.description}</span>`
|
||||
: nothing}
|
||||
@@ -128,6 +141,30 @@ export class HaMoreInfoAddTo extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private _renderDefaultActionLabel(key: AddToActionKey) {
|
||||
const [beforeTarget, afterTarget] = getAddToActionLabelParts(
|
||||
this.hass.localize,
|
||||
key
|
||||
);
|
||||
|
||||
return html`${beforeTarget}${this._renderTarget()}${afterTarget}`;
|
||||
}
|
||||
|
||||
private _renderTarget() {
|
||||
return html`<ha-automation-target-badge
|
||||
target-type="entity"
|
||||
.targetId=${this.entityId}
|
||||
.label=${this._targetLabel}
|
||||
></ha-automation-target-badge>`;
|
||||
}
|
||||
|
||||
private get _targetLabel(): string {
|
||||
const stateObj = this.hass.states[this.entityId];
|
||||
return stateObj
|
||||
? this.hass.formatEntityName(stateObj, undefined)
|
||||
: this.entityId;
|
||||
}
|
||||
|
||||
protected async firstUpdated() {
|
||||
await this._loadActions();
|
||||
this._loading = false;
|
||||
@@ -154,7 +191,7 @@ export class HaMoreInfoAddTo extends LitElement {
|
||||
|
||||
return html`
|
||||
<ha-list-base>
|
||||
${this._renderActionItems(this._defaultActions)}
|
||||
${this._renderActionItems(this._defaultActions, "default")}
|
||||
</ha-list-base>
|
||||
${this._externalActions.length
|
||||
? html`
|
||||
@@ -164,7 +201,7 @@ export class HaMoreInfoAddTo extends LitElement {
|
||||
)}
|
||||
</h2>
|
||||
<ha-list-base>
|
||||
${this._renderActionItems(this._externalActions)}
|
||||
${this._renderActionItems(this._externalActions, "external")}
|
||||
</ha-list-base>
|
||||
`
|
||||
: nothing}
|
||||
@@ -197,6 +234,13 @@ export class HaMoreInfoAddTo extends LitElement {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--ha-space-1);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
} from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
@@ -21,7 +20,7 @@ import type { LabelRegistryEntry } from "../../../../data/label/label_registry";
|
||||
import { haStyleScrollbar } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { AddAutomationElementListItem } from "../add-automation-element-dialog";
|
||||
import { getTargetIcon } from "../target/get_target_icon";
|
||||
import "../target/ha-automation-target-badge";
|
||||
|
||||
type Target = [string, string | undefined, string | undefined];
|
||||
|
||||
@@ -108,7 +107,10 @@ export class HaAutomationAddItems extends LitElement {
|
||||
items,
|
||||
(item) => item.key,
|
||||
(item) => html`
|
||||
<ha-list-item-button .value=${item.key} @click=${this._selected}>
|
||||
<ha-list-item-button
|
||||
data-value=${item.key}
|
||||
@click=${this._selected}
|
||||
>
|
||||
<div slot="headline" class=${this.target ? "item-headline" : ""}>
|
||||
${item.name}${this._renderTarget(this.target)}
|
||||
</div>
|
||||
@@ -154,33 +156,22 @@ export class HaAutomationAddItems extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderTarget = memoizeOne((target?: Target) => {
|
||||
private _renderTarget(target?: Target) {
|
||||
if (!target) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`<div class="selected-target">
|
||||
${getTargetIcon(
|
||||
{
|
||||
entities: this.hass.entities,
|
||||
devices: this.hass.devices,
|
||||
areas: this.hass.areas,
|
||||
floors: this.hass.floors,
|
||||
},
|
||||
this.hass.states,
|
||||
target[0],
|
||||
target[1],
|
||||
this.configEntryLookup,
|
||||
this.getLabel
|
||||
)}
|
||||
<div class="label">${target[2]}</div>
|
||||
</div>`;
|
||||
});
|
||||
return html`<ha-automation-target-badge
|
||||
.targetType=${target[0]}
|
||||
.targetId=${target[1]}
|
||||
.label=${target[2]}
|
||||
></ha-automation-target-badge>`;
|
||||
}
|
||||
|
||||
private _selected(ev) {
|
||||
const item = ev.currentTarget;
|
||||
const item = ev.currentTarget as HTMLElement;
|
||||
fireEvent(this, "value-changed", {
|
||||
value: item.value,
|
||||
value: item.dataset.value,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -301,42 +292,6 @@ export class HaAutomationAddItems extends LitElement {
|
||||
ha-svg-icon.plus {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.selected-target {
|
||||
display: inline-flex;
|
||||
gap: var(--ha-space-1);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: var(--ha-border-radius-md);
|
||||
background: var(--ha-color-fill-neutral-normal-resting);
|
||||
padding: 0 var(--ha-space-2) 0 var(--ha-space-1);
|
||||
border: var(--ha-border-width-sm) solid
|
||||
var(--ha-color-border-neutral-quiet);
|
||||
color: var(--ha-color-on-neutral-normal);
|
||||
overflow: hidden;
|
||||
}
|
||||
.selected-target .label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.selected-target ha-icon,
|
||||
.selected-target ha-svg-icon,
|
||||
.selected-target ha-domain-icon {
|
||||
display: flex;
|
||||
padding: var(--ha-space-1) 0;
|
||||
}
|
||||
|
||||
.selected-target ha-floor-icon {
|
||||
display: flex;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
align-items: center;
|
||||
}
|
||||
.selected-target ha-domain-icon {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiAlert, mdiCodeBraces, mdiShape } from "@mdi/js";
|
||||
import { css, html, LitElement, nothing, type TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { transform } from "../../../../common/decorators/transform";
|
||||
import { isTemplate } from "../../../../common/string/has-template";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import type { ConfigEntry } from "../../../../data/config_entries";
|
||||
import {
|
||||
configEntriesContext,
|
||||
internationalizationContext,
|
||||
labelsContext,
|
||||
registriesContext,
|
||||
statesContext,
|
||||
} from "../../../../data/context";
|
||||
import type { LabelRegistryEntry } from "../../../../data/label/label_registry";
|
||||
import type { TargetType } from "../../../../data/target";
|
||||
import { getTargetIcon } from "./get_target_icon";
|
||||
import { getTargetText } from "./get_target_text";
|
||||
|
||||
const TARGET_TYPES = ["entity", "device", "area", "label", "floor"] as const;
|
||||
|
||||
const isTargetType = (targetType: string): targetType is TargetType =>
|
||||
TARGET_TYPES.includes(targetType as TargetType);
|
||||
|
||||
@customElement("ha-automation-target-badge")
|
||||
export class HaAutomationTargetBadge extends LitElement {
|
||||
@property({ attribute: "target-type" })
|
||||
public targetType!: string;
|
||||
|
||||
@property({ attribute: "target-id" })
|
||||
public targetId?: string;
|
||||
|
||||
@property()
|
||||
public label?: string;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public warning = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public error = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public interactive = false;
|
||||
|
||||
@property({ attribute: false })
|
||||
public countTemplate: unknown = nothing;
|
||||
|
||||
@state()
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: registriesContext, subscribe: true })
|
||||
private _registries!: ContextType<typeof registriesContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: labelsContext, subscribe: true })
|
||||
private _labelRegistry!: LabelRegistryEntry[];
|
||||
|
||||
@state()
|
||||
@consume({ context: configEntriesContext, subscribe: true })
|
||||
@transform<ConfigEntry[], Record<string, ConfigEntry>>({
|
||||
transformer: function (value) {
|
||||
return value
|
||||
? Object.fromEntries(value.map((entry) => [entry.entry_id, entry]))
|
||||
: undefined;
|
||||
},
|
||||
})
|
||||
private _configEntryLookup?: Record<string, ConfigEntry>;
|
||||
|
||||
@consume({ context: statesContext, subscribe: true })
|
||||
private _states!: ContextType<typeof statesContext>;
|
||||
|
||||
protected render() {
|
||||
const { icon, label, warning } = this._targetInfo();
|
||||
|
||||
return html`<div
|
||||
class=${classMap({
|
||||
target: true,
|
||||
warning,
|
||||
error: this.error,
|
||||
interactive: this.interactive,
|
||||
})}
|
||||
>
|
||||
${icon}
|
||||
<div class="label">${label}${this.countTemplate}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
private _targetInfo(): {
|
||||
icon: TemplateResult | typeof nothing;
|
||||
label: string;
|
||||
warning: boolean;
|
||||
} {
|
||||
const targetId = this.targetId;
|
||||
|
||||
if (!targetId) {
|
||||
return {
|
||||
icon: nothing,
|
||||
label: this.label || "",
|
||||
warning: this.warning,
|
||||
};
|
||||
}
|
||||
|
||||
let iconPath: string | undefined;
|
||||
let label = this.label;
|
||||
let warning = this.warning;
|
||||
|
||||
if (!isTargetType(this.targetType)) {
|
||||
return {
|
||||
icon: nothing,
|
||||
label: label || targetId,
|
||||
warning,
|
||||
};
|
||||
}
|
||||
|
||||
if (this.targetType === "entity" && ["all", "none"].includes(targetId)) {
|
||||
iconPath = mdiShape;
|
||||
label = this._i18n.localize(
|
||||
`ui.panel.config.automation.editor.target_summary.${targetId as "all" | "none"}_entities`
|
||||
);
|
||||
} else if (isTemplate(targetId)) {
|
||||
iconPath = mdiCodeBraces;
|
||||
label = this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.target_summary.template"
|
||||
);
|
||||
} else if (!this._checkTargetExists(targetId)) {
|
||||
iconPath = mdiAlert;
|
||||
label = label || this._targetText(this.targetType, targetId);
|
||||
warning = true;
|
||||
} else {
|
||||
label = label || this._targetText(this.targetType, targetId);
|
||||
}
|
||||
|
||||
const icon = iconPath
|
||||
? html`<ha-svg-icon .path=${iconPath}></ha-svg-icon>`
|
||||
: getTargetIcon(
|
||||
this._registries,
|
||||
this._states,
|
||||
this.targetType,
|
||||
targetId,
|
||||
this._configEntryLookup || {},
|
||||
this._getLabel
|
||||
);
|
||||
|
||||
return {
|
||||
icon,
|
||||
label: label || targetId,
|
||||
warning,
|
||||
};
|
||||
}
|
||||
|
||||
private _targetText(targetType: TargetType, targetId: string): string {
|
||||
return getTargetText(
|
||||
this._registries,
|
||||
this._states,
|
||||
this._i18n.localize,
|
||||
targetType,
|
||||
targetId,
|
||||
this._getLabel
|
||||
);
|
||||
}
|
||||
|
||||
private _getLabel = (id: string) =>
|
||||
this._labelRegistry?.find(({ label_id }) => label_id === id);
|
||||
|
||||
private _checkTargetExists(targetId: string): boolean {
|
||||
if (this.targetType === "floor") {
|
||||
return !!this._registries.floors[targetId];
|
||||
}
|
||||
if (this.targetType === "area") {
|
||||
return !!this._registries.areas[targetId];
|
||||
}
|
||||
if (this.targetType === "device") {
|
||||
return !!this._registries.devices[targetId];
|
||||
}
|
||||
if (this.targetType === "entity") {
|
||||
return !!this._states[targetId];
|
||||
}
|
||||
return !!this._getLabel(targetId);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: inline-flex;
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.target {
|
||||
display: inline-flex;
|
||||
gap: var(--ha-space-1);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: var(--ha-border-radius-md);
|
||||
background: var(--ha-color-fill-neutral-normal-resting);
|
||||
padding: 0 var(--ha-space-2) 0 var(--ha-space-1);
|
||||
color: var(--ha-color-on-neutral-normal);
|
||||
border: var(--ha-border-width-sm) solid
|
||||
var(--ha-color-border-neutral-quiet);
|
||||
overflow: hidden;
|
||||
height: 32px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
.label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.target ha-icon,
|
||||
.target ha-svg-icon,
|
||||
.target ha-domain-icon {
|
||||
display: flex;
|
||||
padding: var(--ha-space-1) 0;
|
||||
}
|
||||
|
||||
.target ha-floor-icon {
|
||||
display: flex;
|
||||
height: 32px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.target.interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.target.interactive:hover {
|
||||
background: var(--ha-color-fill-neutral-normal-hover);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-automation-target-badge": HaAutomationTargetBadge;
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,10 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import {
|
||||
mdiPalette,
|
||||
mdiPlayCircleOutline,
|
||||
mdiPlaylistCheck,
|
||||
mdiRobotOutline,
|
||||
mdiScriptTextOutline,
|
||||
} from "@mdi/js";
|
||||
import { computeDeviceNameDisplay } from "../../../../common/entity/compute_device_name";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-adaptive-dialog";
|
||||
import "../../../../components/ha-icon";
|
||||
import "../../../../components/ha-list";
|
||||
import "../../../../components/ha-list-item";
|
||||
import "../../../../components/ha-spinner";
|
||||
@@ -38,10 +32,14 @@ import { showScriptEditor } from "../../../../data/script";
|
||||
import type { SceneEntities } from "../../../../data/scene";
|
||||
import { showSceneEditor } from "../../../../data/scene";
|
||||
import {
|
||||
ADD_TO_ACTION_ICONS,
|
||||
addToActionHandler,
|
||||
type AddToActionKey,
|
||||
getAddToActionLabel,
|
||||
getAddToActionLabelParts,
|
||||
} from "../../../../dialogs/more-info/add-to";
|
||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||
import "../../automation/target/ha-automation-target-badge";
|
||||
import type { DeviceAddToDialogParams } from "./show-dialog-device-add-to";
|
||||
|
||||
@customElement("dialog-device-add-to")
|
||||
@@ -151,11 +149,7 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
if (!this._params) {
|
||||
return nothing;
|
||||
}
|
||||
const deviceName = computeDeviceNameDisplay(
|
||||
this._params.device,
|
||||
this._i18n.localize,
|
||||
this._states
|
||||
);
|
||||
const deviceName = this._deviceName;
|
||||
|
||||
return html`
|
||||
<h3 class="section-header">
|
||||
@@ -169,39 +163,51 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
data-type="automation_trigger"
|
||||
@click=${this._handleNewAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiRobotOutline}></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.automation_trigger",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"automation_trigger",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.automation_trigger}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("automation_trigger")}
|
||||
</ha-list-item>
|
||||
<ha-list-item
|
||||
graphic="icon"
|
||||
data-type="automation_condition"
|
||||
@click=${this._handleNewAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiPlaylistCheck}></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.automation_condition",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"automation_condition",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.automation_condition}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("automation_condition")}
|
||||
</ha-list-item>
|
||||
<ha-list-item
|
||||
graphic="icon"
|
||||
data-type="automation_action"
|
||||
@click=${this._handleNewAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiPlayCircleOutline}
|
||||
></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.automation_action",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"automation_action",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.automation_action}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("automation_action")}
|
||||
</ha-list-item>
|
||||
</ha-list>
|
||||
<h3 class="section-header">
|
||||
@@ -213,15 +219,17 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
data-type="script_action"
|
||||
@click=${this._handleNewAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiScriptTextOutline}
|
||||
></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.script_action",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"script_action",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.script_action}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("script_action")}
|
||||
</ha-list-item>
|
||||
</ha-list>
|
||||
${this._renderSceneSection(deviceName)}
|
||||
@@ -242,11 +250,7 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const deviceName = computeDeviceNameDisplay(
|
||||
this._params.device,
|
||||
this._i18n.localize,
|
||||
this._states
|
||||
);
|
||||
const deviceName = this._deviceName;
|
||||
|
||||
const hasTriggers = Boolean(this._triggers?.length);
|
||||
const hasConditions = Boolean(this._conditions?.length);
|
||||
@@ -279,15 +283,17 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
data-type="trigger"
|
||||
@click=${this._handleLegacyAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiRobotOutline}
|
||||
></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.automation_trigger",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"automation_trigger",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.automation_trigger}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("automation_trigger")}
|
||||
</ha-list-item>
|
||||
`
|
||||
: nothing}
|
||||
@@ -298,15 +304,17 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
data-type="condition"
|
||||
@click=${this._handleLegacyAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiPlaylistCheck}
|
||||
></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.automation_condition",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"automation_condition",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.automation_condition}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("automation_condition")}
|
||||
</ha-list-item>
|
||||
`
|
||||
: nothing}
|
||||
@@ -317,15 +325,17 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
data-type="automation_action"
|
||||
@click=${this._handleLegacyAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiPlayCircleOutline}
|
||||
></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.automation_action",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"automation_action",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.automation_action}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("automation_action")}
|
||||
</ha-list-item>
|
||||
`
|
||||
: nothing}
|
||||
@@ -351,15 +361,17 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
data-type="script_action"
|
||||
@click=${this._handleLegacyAction}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiScriptTextOutline}
|
||||
></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.script_action",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"script_action",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon
|
||||
slot="graphic"
|
||||
.icon=${ADD_TO_ACTION_ICONS.script_action}
|
||||
></ha-icon>
|
||||
${this._renderActionLabel("script_action")}
|
||||
</ha-list-item>
|
||||
</ha-list>
|
||||
`
|
||||
@@ -390,17 +402,48 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
graphic="icon"
|
||||
@click=${this._handleCreateScene}
|
||||
data-dialog="close"
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiPalette}></ha-svg-icon>
|
||||
${this._i18n.localize(
|
||||
"ui.dialogs.more_info_control.add_to.actions.scene",
|
||||
{ target: deviceName }
|
||||
aria-label=${getAddToActionLabel(
|
||||
this._i18n.localize,
|
||||
"scene",
|
||||
deviceName
|
||||
)}
|
||||
>
|
||||
<ha-icon slot="graphic" .icon=${ADD_TO_ACTION_ICONS.scene}></ha-icon>
|
||||
${this._renderActionLabel("scene")}
|
||||
</ha-list-item>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderActionLabel(key: AddToActionKey) {
|
||||
const [beforeTarget, afterTarget] = getAddToActionLabelParts(
|
||||
this._i18n.localize,
|
||||
key
|
||||
);
|
||||
|
||||
return html`<span class="action-label">
|
||||
${beforeTarget}${this._renderDeviceTarget()}${afterTarget}
|
||||
</span>`;
|
||||
}
|
||||
|
||||
private _renderDeviceTarget() {
|
||||
return html`<ha-automation-target-badge
|
||||
target-type="device"
|
||||
.targetId=${this._params?.device.id}
|
||||
.label=${this._deviceName}
|
||||
></ha-automation-target-badge>`;
|
||||
}
|
||||
|
||||
private get _deviceName(): string {
|
||||
return this._params
|
||||
? computeDeviceNameDisplay(
|
||||
this._params.device,
|
||||
this._i18n.localize,
|
||||
this._states
|
||||
)
|
||||
: "";
|
||||
}
|
||||
|
||||
private _handleNewAction(ev: Event) {
|
||||
if (!this._params) {
|
||||
return;
|
||||
@@ -477,6 +520,13 @@ export class DialogDeviceAddTo extends LitElement {
|
||||
font-weight: var(--ha-font-weight-medium);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.action-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--ha-space-1);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user