Revive automation row overflow menu (#27093)

This commit is contained in:
Wendelin
2025-09-22 16:46:35 +02:00
committed by GitHub
parent 1e2d144d26
commit 95a0fe335f
13 changed files with 881 additions and 474 deletions

View File

@@ -1,6 +1,7 @@
import { consume } from "@lit/context"; import { consume } from "@lit/context";
import { import {
mdiAlertCircleCheck, mdiAlertCircleCheck,
mdiAppleKeyboardCommand,
mdiArrowDown, mdiArrowDown,
mdiArrowUp, mdiArrowUp,
mdiContentCopy, mdiContentCopy,
@@ -16,7 +17,7 @@ import {
} from "@mdi/js"; } from "@mdi/js";
import deepClone from "deep-clone-simple"; import deepClone from "deep-clone-simple";
import { dump } from "js-yaml"; import { dump } from "js-yaml";
import type { PropertyValues } from "lit"; import type { PropertyValues, TemplateResult } from "lit";
import { LitElement, html, nothing } from "lit"; import { LitElement, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
@@ -73,9 +74,10 @@ import {
showPromptDialog, showPromptDialog,
} from "../../../../dialogs/generic/show-dialog-box"; } from "../../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac";
import { showToast } from "../../../../util/toast"; import { showToast } from "../../../../util/toast";
import "../ha-automation-editor-warning"; import "../ha-automation-editor-warning";
import { rowStyles } from "../styles"; import { overflowStyles, rowStyles } from "../styles";
import "./ha-automation-action-editor"; import "./ha-automation-action-editor";
import type HaAutomationActionEditor from "./ha-automation-action-editor"; import type HaAutomationActionEditor from "./ha-automation-action-editor";
import "./types/ha-automation-action-choose"; import "./types/ha-automation-action-choose";
@@ -225,6 +227,20 @@ export default class HaAutomationActionRow extends LitElement {
} }
} }
private _renderOverflowLabel(label: string, shortcut?: TemplateResult) {
return html`
<div class="overflow-label">
${label}
${this.optionsInSidebar && !this.narrow
? shortcut ||
html`<span
class="shortcut-placeholder ${isMac ? "mac" : ""}"
></span>`
: nothing}
</div>
`;
}
private _renderRow() { private _renderRow() {
const type = getAutomationActionType(this.action); const type = getAutomationActionType(this.action);
@@ -272,8 +288,8 @@ export default class HaAutomationActionRow extends LitElement {
)} )}
</ha-tooltip>` </ha-tooltip>`
: nothing} : nothing}
${!this.optionsInSidebar
? html`<ha-md-button-menu <ha-md-button-menu
quick quick
slot="icons" slot="icons"
@click=${preventDefaultStopPropagation} @click=${preventDefaultStopPropagation}
@@ -290,62 +306,102 @@ export default class HaAutomationActionRow extends LitElement {
></ha-icon-button> ></ha-icon-button>
<ha-md-menu-item .clickAction=${this._runAction}> <ha-md-menu-item .clickAction=${this._runAction}>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.run"
)}
<ha-svg-icon slot="start" .path=${mdiPlay}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiPlay}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize("ui.panel.config.automation.editor.actions.run")
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._renameAction} .clickAction=${this._renameAction}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.rename"
)}
<ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.rename"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider> <ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._duplicateAction} .clickAction=${this._duplicateAction}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${mdiPlusCircleMultipleOutline} .path=${mdiPlusCircleMultipleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._copyAction} .clickAction=${this._copyAction}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.copy"
)}
<ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.copy"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span>C</span>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._cutAction} .clickAction=${this._cutAction}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.cut"
)}
<ha-svg-icon slot="start" .path=${mdiContentCut}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiContentCut}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.cut"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span>X</span>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
${!this.optionsInSidebar
? html`
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._moveUp} .clickAction=${this._moveUp}
.disabled=${this.disabled || !!this.first} .disabled=${this.disabled || !!this.first}
> >
${this.hass.localize("ui.panel.config.automation.editor.move_up")} ${this.hass.localize(
"ui.panel.config.automation.editor.move_up"
)}
<ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon <ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon
></ha-md-menu-item> ></ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._moveDown} .clickAction=${this._moveDown}
.disabled=${this.disabled || !!this.last} .disabled=${this.disabled || !!this.last}
@@ -355,15 +411,19 @@ export default class HaAutomationActionRow extends LitElement {
)} )}
<ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon <ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon
></ha-md-menu-item> ></ha-md-menu-item>
`
: nothing}
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._toggleYamlMode} .clickAction=${this._toggleYamlMode}
.disabled=${!this._uiModeAvailable || !!this._warnings} .disabled=${!this._uiModeAvailable || !!this._warnings}
> >
${this.hass.localize(
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
)}
<ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider> <ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
@@ -372,36 +432,56 @@ export default class HaAutomationActionRow extends LitElement {
.clickAction=${this._onDisable} .clickAction=${this._onDisable}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.action.enabled === false
? this.hass.localize(
"ui.panel.config.automation.editor.actions.enable"
)
: this.hass.localize(
"ui.panel.config.automation.editor.actions.disable"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${this.action.enabled === false .path=${this.action.enabled === false
? mdiPlayCircleOutline ? mdiPlayCircleOutline
: mdiStopCircleOutline} : mdiStopCircleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
`ui.panel.config.automation.editor.actions.${this.action.enabled === false ? "enable" : "disable"}`
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
class="warning" class="warning"
.clickAction=${this._onDelete} .clickAction=${this._onDelete}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
<ha-svg-icon <ha-svg-icon
class="warning" class="warning"
slot="start" slot="start"
.path=${mdiDelete} .path=${mdiDelete}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span
>${this.hass.localize(
"ui.panel.config.automation.editor.del"
)}</span
>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
</ha-md-button-menu>` </ha-md-button-menu>
: nothing}
${!this.optionsInSidebar ${!this.optionsInSidebar
? html`${this._warnings ? html`${this._warnings
? html`<ha-automation-editor-warning ? html`<ha-automation-editor-warning
@@ -680,7 +760,7 @@ export default class HaAutomationActionRow extends LitElement {
fireEvent(this, "move-down"); fireEvent(this, "move-down");
}; };
private _toggleYamlMode = () => { private _toggleYamlMode = (item?: HTMLElement) => {
if (this._yamlMode) { if (this._yamlMode) {
this._switchUiMode(); this._switchUiMode();
} else { } else {
@@ -689,6 +769,8 @@ export default class HaAutomationActionRow extends LitElement {
if (!this.optionsInSidebar) { if (!this.optionsInSidebar) {
this.expand(); this.expand();
} else if (item) {
this.openSidebar();
} }
}; };
@@ -804,7 +886,7 @@ export default class HaAutomationActionRow extends LitElement {
this._automationRowElement?.focus(); this._automationRowElement?.focus();
} }
static styles = rowStyles; static styles = [rowStyles, overflowStyles];
} }
declare global { declare global {

View File

@@ -1,5 +1,6 @@
import { consume } from "@lit/context"; import { consume } from "@lit/context";
import { import {
mdiAppleKeyboardCommand,
mdiArrowDown, mdiArrowDown,
mdiArrowUp, mdiArrowUp,
mdiContentCopy, mdiContentCopy,
@@ -15,7 +16,7 @@ import {
} from "@mdi/js"; } from "@mdi/js";
import deepClone from "deep-clone-simple"; import deepClone from "deep-clone-simple";
import { dump } from "js-yaml"; import { dump } from "js-yaml";
import type { CSSResultGroup, PropertyValues } from "lit"; import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
@@ -56,9 +57,10 @@ import {
showPromptDialog, showPromptDialog,
} from "../../../../dialogs/generic/show-dialog-box"; } from "../../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac";
import { showToast } from "../../../../util/toast"; import { showToast } from "../../../../util/toast";
import "../ha-automation-editor-warning"; import "../ha-automation-editor-warning";
import { rowStyles } from "../styles"; import { overflowStyles, rowStyles } from "../styles";
import "./ha-automation-condition-editor"; import "./ha-automation-condition-editor";
import type HaAutomationConditionEditor from "./ha-automation-condition-editor"; import type HaAutomationConditionEditor from "./ha-automation-condition-editor";
import "./types/ha-automation-condition-and"; import "./types/ha-automation-condition-and";
@@ -162,6 +164,20 @@ export default class HaAutomationConditionRow extends LitElement {
return this._selected; return this._selected;
} }
private _renderOverflowLabel(label: string, shortcut?: TemplateResult) {
return html`
<div class="overflow-label">
${label}
${this.optionsInSidebar && !this.narrow
? shortcut ||
html`<span
class="shortcut-placeholder ${isMac ? "mac" : ""}"
></span>`
: nothing}
</div>
`;
}
private _renderRow() { private _renderRow() {
return html` return html`
<ha-svg-icon <ha-svg-icon
@@ -177,8 +193,7 @@ export default class HaAutomationConditionRow extends LitElement {
<slot name="icons" slot="icons"></slot> <slot name="icons" slot="icons"></slot>
${!this.optionsInSidebar <ha-md-button-menu
? html`<ha-md-button-menu
quick quick
slot="icons" slot="icons"
@click=${preventDefaultStopPropagation} @click=${preventDefaultStopPropagation}
@@ -196,19 +211,23 @@ export default class HaAutomationConditionRow extends LitElement {
</ha-icon-button> </ha-icon-button>
<ha-md-menu-item .clickAction=${this._testCondition}> <ha-md-menu-item .clickAction=${this._testCondition}>
${this.hass.localize(
"ui.panel.config.automation.editor.conditions.test"
)}
<ha-svg-icon slot="start" .path=${mdiFlask}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiFlask}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.conditions.test"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._renameCondition} .clickAction=${this._renameCondition}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.conditions.rename"
)}
<ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.conditions.rename"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider> <ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
@@ -217,43 +236,80 @@ export default class HaAutomationConditionRow extends LitElement {
.clickAction=${this._duplicateCondition} .clickAction=${this._duplicateCondition}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${mdiPlusCircleMultipleOutline} .path=${mdiPlusCircleMultipleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._copyCondition} .clickAction=${this._copyCondition}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize( <ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon
>${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.copy" "ui.panel.config.automation.editor.triggers.copy"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span>C</span>
</span>`
)} )}
<ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon>
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._cutCondition} .clickAction=${this._cutCondition}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize( <ha-svg-icon slot="start" .path=${mdiContentCut}></ha-svg-icon
>${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.cut" "ui.panel.config.automation.editor.triggers.cut"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span>X</span>
</span>`
)} )}
<ha-svg-icon slot="start" .path=${mdiContentCut}></ha-svg-icon>
</ha-md-menu-item> </ha-md-menu-item>
${!this.optionsInSidebar
? html`
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._moveUp} .clickAction=${this._moveUp}
.disabled=${this.disabled || this.first} .disabled=${this.disabled || this.first}
> >
${this.hass.localize("ui.panel.config.automation.editor.move_up")} ${this.hass.localize(
"ui.panel.config.automation.editor.move_up"
)}
<ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon <ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon
></ha-md-menu-item> ></ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._moveDown} .clickAction=${this._moveDown}
.disabled=${this.disabled || this.last} .disabled=${this.disabled || this.last}
@@ -263,16 +319,16 @@ export default class HaAutomationConditionRow extends LitElement {
)} )}
<ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon <ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon
></ha-md-menu-item> ></ha-md-menu-item>
`
: nothing}
<ha-md-menu-item <ha-md-menu-item .clickAction=${this._toggleYamlMode}>
.clickAction=${this._toggleYamlMode}
.disabled=${this._uiSupported(this.condition.condition) ||
!!this._warnings}
>
${this.hass.localize(
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
)}
<ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider> <ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
@@ -281,36 +337,54 @@ export default class HaAutomationConditionRow extends LitElement {
.clickAction=${this._onDisable} .clickAction=${this._onDisable}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.condition.enabled === false
? this.hass.localize(
"ui.panel.config.automation.editor.actions.enable"
)
: this.hass.localize(
"ui.panel.config.automation.editor.actions.disable"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${this.condition.enabled === false .path=${this.condition.enabled === false
? mdiPlayCircleOutline ? mdiPlayCircleOutline
: mdiStopCircleOutline} : mdiStopCircleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
`ui.panel.config.automation.editor.actions.${this.condition.enabled === false ? "enable" : "disable"}`
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
class="warning" class="warning"
.clickAction=${this._onDelete} .clickAction=${this._onDelete}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
<ha-svg-icon <ha-svg-icon
class="warning" class="warning"
slot="start" slot="start"
.path=${mdiDelete} .path=${mdiDelete}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span
>${this.hass.localize(
"ui.panel.config.automation.editor.del"
)}</span
>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
</ha-md-button-menu>` </ha-md-button-menu>
: nothing}
${!this.optionsInSidebar ${!this.optionsInSidebar
? html`${this._warnings ? html`${this._warnings
? html`<ha-automation-editor-warning ? html`<ha-automation-editor-warning
@@ -490,9 +564,9 @@ export default class HaAutomationConditionRow extends LitElement {
this._testing = true; this._testing = true;
const condition = this.condition; const condition = this.condition;
requestAnimationFrame(() => { requestAnimationFrame(() => {
// @ts-ignore is supported in all browsers expect firefox // @ts-ignore is supported in all browsers except firefox
if (this.scrollIntoViewIfNeeded) { if (this.scrollIntoViewIfNeeded) {
// @ts-ignore is supported in all browsers expect firefox // @ts-ignore is supported in all browsers except firefox
this.scrollIntoViewIfNeeded(); this.scrollIntoViewIfNeeded();
return; return;
} }
@@ -626,7 +700,7 @@ export default class HaAutomationConditionRow extends LitElement {
fireEvent(this, "move-down"); fireEvent(this, "move-down");
}; };
private _toggleYamlMode = () => { private _toggleYamlMode = (item?: HTMLElement) => {
if (this._yamlMode) { if (this._yamlMode) {
this._switchUiMode(); this._switchUiMode();
} else { } else {
@@ -635,6 +709,8 @@ export default class HaAutomationConditionRow extends LitElement {
if (!this.optionsInSidebar) { if (!this.optionsInSidebar) {
this.expand(); this.expand();
} else if (item) {
this.openSidebar();
} }
}; };
@@ -742,6 +818,7 @@ export default class HaAutomationConditionRow extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
rowStyles, rowStyles,
overflowStyles,
css` css`
.testing { .testing {
position: absolute; position: absolute;

View File

@@ -1,5 +1,6 @@
import { consume } from "@lit/context"; import { consume } from "@lit/context";
import { import {
mdiAppleKeyboardCommand,
mdiArrowDown, mdiArrowDown,
mdiArrowUp, mdiArrowUp,
mdiDelete, mdiDelete,
@@ -7,7 +8,7 @@ import {
mdiPlusCircleMultipleOutline, mdiPlusCircleMultipleOutline,
mdiRenameBox, mdiRenameBox,
} from "@mdi/js"; } from "@mdi/js";
import type { CSSResultGroup } from "lit"; import type { CSSResultGroup, TemplateResult } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
@@ -37,11 +38,17 @@ import {
showPromptDialog, showPromptDialog,
} from "../../../../dialogs/generic/show-dialog-box"; } from "../../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac";
import "../action/ha-automation-action"; import "../action/ha-automation-action";
import type HaAutomationAction from "../action/ha-automation-action"; import type HaAutomationAction from "../action/ha-automation-action";
import "../condition/ha-automation-condition"; import "../condition/ha-automation-condition";
import type HaAutomationCondition from "../condition/ha-automation-condition"; import type HaAutomationCondition from "../condition/ha-automation-condition";
import { editorStyles, indentStyle, rowStyles } from "../styles"; import {
editorStyles,
indentStyle,
overflowStyles,
rowStyles,
} from "../styles";
@customElement("ha-automation-option-row") @customElement("ha-automation-option-row")
export default class HaAutomationOptionRow extends LitElement { export default class HaAutomationOptionRow extends LitElement {
@@ -119,6 +126,20 @@ export default class HaAutomationOptionRow extends LitElement {
return str; return str;
} }
private _renderOverflowLabel(label: string, shortcut?: TemplateResult) {
return html`
<div class="overflow-label">
${label}
${this.optionsInSidebar && !this.narrow
? shortcut ||
html`<span
class="shortcut-placeholder ${isMac ? "mac" : ""}"
></span>`
: nothing}
</div>
`;
}
private _renderRow() { private _renderRow() {
return html` return html`
<h3 slot="header"> <h3 slot="header">
@@ -134,7 +155,7 @@ export default class HaAutomationOptionRow extends LitElement {
<slot name="icons" slot="icons"></slot> <slot name="icons" slot="icons"></slot>
${this.option && !this.optionsInSidebar ${this.option
? html` ? html`
<ha-md-button-menu <ha-md-button-menu
quick quick
@@ -156,58 +177,92 @@ export default class HaAutomationOptionRow extends LitElement {
@click=${this._renameOption} @click=${this._renameOption}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.rename"
)}
<ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.rename"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
@click=${this._duplicateOption} @click=${this._duplicateOption}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${mdiPlusCircleMultipleOutline} .path=${mdiPlusCircleMultipleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
${!this.optionsInSidebar
? html`
<ha-md-menu-item <ha-md-menu-item
@click=${this._moveUp} .clickAction=${this._moveUp}
.disabled=${this.disabled || this.first} .disabled=${this.disabled || !!this.first}
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.move_up" "ui.panel.config.automation.editor.move_up"
)} )}
<ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon> <ha-svg-icon
</ha-md-menu-item> slot="start"
.path=${mdiArrowUp}
></ha-svg-icon
></ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
@click=${this._moveDown} .clickAction=${this._moveDown}
.disabled=${this.disabled || this.last} .disabled=${this.disabled || !!this.last}
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.move_down" "ui.panel.config.automation.editor.move_down"
)} )}
<ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon> <ha-svg-icon
</ha-md-menu-item> slot="start"
.path=${mdiArrowDown}
></ha-svg-icon
></ha-md-menu-item>
`
: nothing}
<ha-md-menu-item <ha-md-menu-item
@click=${this._removeOption} @click=${this._removeOption}
class="warning" class="warning"
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
)}
<ha-svg-icon <ha-svg-icon
class="warning" class="warning"
slot="start" slot="start"
.path=${mdiDelete} .path=${mdiDelete}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span
>${this.hass.localize(
"ui.panel.config.automation.editor.del"
)}</span
>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
</ha-md-button-menu> </ha-md-button-menu>
` `
@@ -459,6 +514,7 @@ export default class HaAutomationOptionRow extends LitElement {
return [ return [
rowStyles, rowStyles,
editorStyles, editorStyles,
overflowStyles,
indentStyle, indentStyle,
css` css`
li[role="separator"] { li[role="separator"] {

View File

@@ -26,7 +26,7 @@ import { isMac } from "../../../../util/is_mac";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { getAutomationActionType } from "../action/ha-automation-action-row"; import { getAutomationActionType } from "../action/ha-automation-action-row";
import { getRepeatType } from "../action/types/ha-automation-action-repeat"; import { getRepeatType } from "../action/types/ha-automation-action-repeat";
import { sidebarEditorStyles } from "../styles"; import { overflowStyles, sidebarEditorStyles } from "../styles";
import "../trigger/ha-automation-trigger-editor"; import "../trigger/ha-automation-trigger-editor";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@@ -324,7 +324,7 @@ export default class HaAutomationSidebarAction extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
static styles = sidebarEditorStyles; static styles = [sidebarEditorStyles, overflowStyles];
} }
declare global { declare global {

View File

@@ -27,7 +27,7 @@ import { isMac } from "../../../../util/is_mac";
import { showAlertDialog } from "../../../lovelace/custom-card-helpers"; import { showAlertDialog } from "../../../lovelace/custom-card-helpers";
import "../condition/ha-automation-condition-editor"; import "../condition/ha-automation-condition-editor";
import type HaAutomationConditionEditor from "../condition/ha-automation-condition-editor"; import type HaAutomationConditionEditor from "../condition/ha-automation-condition-editor";
import { sidebarEditorStyles } from "../styles"; import { overflowStyles, sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-condition") @customElement("ha-automation-sidebar-condition")
@@ -364,6 +364,7 @@ export default class HaAutomationSidebarCondition extends LitElement {
} finally { } finally {
setTimeout(() => { setTimeout(() => {
this._testing = false; this._testing = false;
this._testingResult = undefined;
}, 2500); }, 2500);
} }
}; };
@@ -402,6 +403,7 @@ export default class HaAutomationSidebarCondition extends LitElement {
static styles = [ static styles = [
sidebarEditorStyles, sidebarEditorStyles,
overflowStyles,
css` css`
ha-automation-sidebar-card { ha-automation-sidebar-card {
position: relative; position: relative;

View File

@@ -10,7 +10,7 @@ import type { OptionSidebarConfig } from "../../../../data/automation";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac"; import { isMac } from "../../../../util/is_mac";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { sidebarEditorStyles } from "../styles"; import { overflowStyles, sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-option") @customElement("ha-automation-sidebar-option")
@@ -127,7 +127,7 @@ export default class HaAutomationSidebarOption extends LitElement {
</ha-automation-sidebar-card>`; </ha-automation-sidebar-card>`;
} }
static styles = sidebarEditorStyles; static styles = [sidebarEditorStyles, overflowStyles];
} }
declare global { declare global {

View File

@@ -8,7 +8,7 @@ import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac"; import { isMac } from "../../../../util/is_mac";
import "../../script/ha-script-field-editor"; import "../../script/ha-script-field-editor";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { sidebarEditorStyles } from "../styles"; import { overflowStyles, sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-script-field") @customElement("ha-automation-sidebar-script-field")
@@ -153,7 +153,7 @@ export default class HaAutomationSidebarScriptField extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
static styles = sidebarEditorStyles; static styles = [sidebarEditorStyles, overflowStyles];
} }
declare global { declare global {

View File

@@ -3,7 +3,6 @@ import {
mdiContentCopy, mdiContentCopy,
mdiContentCut, mdiContentCut,
mdiDelete, mdiDelete,
mdiIdentifier,
mdiPlayCircleOutline, mdiPlayCircleOutline,
mdiPlaylistEdit, mdiPlaylistEdit,
mdiPlusCircleMultipleOutline, mdiPlusCircleMultipleOutline,
@@ -19,7 +18,7 @@ import type { TriggerSidebarConfig } from "../../../../data/automation";
import { isTriggerList } from "../../../../data/trigger"; import { isTriggerList } from "../../../../data/trigger";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac"; import { isMac } from "../../../../util/is_mac";
import { sidebarEditorStyles } from "../styles"; import { overflowStyles, sidebarEditorStyles } from "../styles";
import "../trigger/ha-automation-trigger-editor"; import "../trigger/ha-automation-trigger-editor";
import type HaAutomationTriggerEditor from "../trigger/ha-automation-trigger-editor"; import type HaAutomationTriggerEditor from "../trigger/ha-automation-trigger-editor";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@@ -40,8 +39,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
@property({ attribute: "sidebar-key" }) public sidebarKey?: string; @property({ attribute: "sidebar-key" }) public sidebarKey?: string;
@state() private _requestShowId = false;
@state() private _warnings?: string[]; @state() private _warnings?: string[];
@query(".sidebar-editor") @query(".sidebar-editor")
@@ -49,7 +46,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
protected willUpdate(changedProperties) { protected willUpdate(changedProperties) {
if (changedProperties.has("config")) { if (changedProperties.has("config")) {
this._requestShowId = false;
this._warnings = undefined; this._warnings = undefined;
if (this.config) { if (this.config) {
this.yamlMode = this.config.yamlMode; this.yamlMode = this.config.yamlMode;
@@ -103,23 +99,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span> <span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
</div> </div>
</ha-md-menu-item> </ha-md-menu-item>
${!this.yamlMode &&
!("id" in this.config.config) &&
!this._requestShowId
? html`<ha-md-menu-item
slot="menu-items"
.clickAction=${this._showTriggerId}
.disabled=${this.disabled || type === "list"}
>
<ha-svg-icon slot="start" .path=${mdiIdentifier}></ha-svg-icon>
<div class="overflow-label">
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.edit_id"
)}
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
</div>
</ha-md-menu-item>`
: nothing}
<ha-md-divider <ha-md-divider
slot="menu-items" slot="menu-items"
@@ -270,7 +249,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
@value-changed=${this._valueChangedSidebar} @value-changed=${this._valueChangedSidebar}
@yaml-changed=${this._yamlChangedSidebar} @yaml-changed=${this._yamlChangedSidebar}
.uiSupported=${this.config.uiSupported} .uiSupported=${this.config.uiSupported}
.showId=${this._requestShowId}
.yamlMode=${this.yamlMode} .yamlMode=${this.yamlMode}
.disabled=${this.disabled} .disabled=${this.disabled}
@ui-mode-not-available=${this._handleUiModeNotAvailable} @ui-mode-not-available=${this._handleUiModeNotAvailable}
@@ -313,11 +291,7 @@ export default class HaAutomationSidebarTrigger extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
private _showTriggerId = () => { static styles = [sidebarEditorStyles, overflowStyles];
this._requestShowId = true;
};
static styles = sidebarEditorStyles;
} }
declare global { declare global {

View File

@@ -238,6 +238,9 @@ export const sidebarEditorStyles = css`
.description { .description {
padding-top: 16px; padding-top: 16px;
} }
`;
export const overflowStyles = css`
.overflow-label { .overflow-label {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@@ -27,8 +27,6 @@ export default class HaAutomationTriggerEditor extends LitElement {
@property({ type: Boolean, attribute: "supported" }) public uiSupported = @property({ type: Boolean, attribute: "supported" }) public uiSupported =
false; false;
@property({ type: Boolean, attribute: "show-id" }) public showId = false;
@property({ type: Boolean, attribute: "sidebar" }) public inSidebar = false; @property({ type: Boolean, attribute: "sidebar" }) public inSidebar = false;
@query("ha-yaml-editor") public yamlEditor?: HaYamlEditor; @query("ha-yaml-editor") public yamlEditor?: HaYamlEditor;
@@ -37,7 +35,6 @@ export default class HaAutomationTriggerEditor extends LitElement {
const type = isTriggerList(this.trigger) ? "list" : this.trigger.trigger; const type = isTriggerList(this.trigger) ? "list" : this.trigger.trigger;
const yamlMode = this.yamlMode || !this.uiSupported; const yamlMode = this.yamlMode || !this.uiSupported;
const showId = "id" in this.trigger || this.showId;
return html` return html`
<div <div
@@ -73,19 +70,23 @@ export default class HaAutomationTriggerEditor extends LitElement {
></ha-yaml-editor> ></ha-yaml-editor>
` `
: html` : html`
${showId && !isTriggerList(this.trigger) ${!isTriggerList(this.trigger)
? html` ? html`
<ha-textfield <ha-textfield
.label=${this.hass.localize( .label=${`${this.hass.localize(
"ui.panel.config.automation.editor.triggers.id" "ui.panel.config.automation.editor.triggers.id"
)} )} (${this.hass.localize(
"ui.panel.config.automation.editor.triggers.optional"
)})`}
.value=${this.trigger.id || ""} .value=${this.trigger.id || ""}
.disabled=${this.disabled} .disabled=${this.disabled}
@change=${this._idChanged} @change=${this._idChanged}
> .helper=${this.hass.localize(
</ha-textfield> "ui.panel.config.automation.editor.triggers.id_helper"
)}
></ha-textfield>
` `
: ""} : nothing}
<div @value-changed=${this._onUiChanged}> <div @value-changed=${this._onUiChanged}>
${dynamicElement(`ha-automation-trigger-${type}`, { ${dynamicElement(`ha-automation-trigger-${type}`, {
hass: this.hass, hass: this.hass,

View File

@@ -1,12 +1,13 @@
import { consume } from "@lit/context"; import { consume } from "@lit/context";
import { import {
mdiAppleKeyboardCommand,
mdiArrowDown, mdiArrowDown,
mdiArrowUp, mdiArrowUp,
mdiContentCopy, mdiContentCopy,
mdiContentCut, mdiContentCut,
mdiDelete, mdiDelete,
mdiDotsVertical, mdiDotsVertical,
mdiIdentifier, mdiInformation,
mdiPlayCircleOutline, mdiPlayCircleOutline,
mdiPlaylistEdit, mdiPlaylistEdit,
mdiPlusCircleMultipleOutline, mdiPlusCircleMultipleOutline,
@@ -15,7 +16,7 @@ import {
} from "@mdi/js"; } from "@mdi/js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket"; import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import { dump } from "js-yaml"; import { dump } from "js-yaml";
import type { CSSResultGroup, PropertyValues } from "lit"; import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
@@ -38,6 +39,7 @@ import "../../../../components/ha-icon-button";
import "../../../../components/ha-md-button-menu"; import "../../../../components/ha-md-button-menu";
import "../../../../components/ha-md-divider"; import "../../../../components/ha-md-divider";
import "../../../../components/ha-md-menu-item"; import "../../../../components/ha-md-menu-item";
import "../../../../components/ha-svg-icon";
import type { import type {
AutomationClipboard, AutomationClipboard,
Trigger, Trigger,
@@ -55,9 +57,10 @@ import {
showPromptDialog, showPromptDialog,
} from "../../../../dialogs/generic/show-dialog-box"; } from "../../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { isMac } from "../../../../util/is_mac";
import { showToast } from "../../../../util/toast"; import { showToast } from "../../../../util/toast";
import "../ha-automation-editor-warning"; import "../ha-automation-editor-warning";
import { rowStyles } from "../styles"; import { overflowStyles, rowStyles } from "../styles";
import "./ha-automation-trigger-editor"; import "./ha-automation-trigger-editor";
import type HaAutomationTriggerEditor from "./ha-automation-trigger-editor"; import type HaAutomationTriggerEditor from "./ha-automation-trigger-editor";
import "./types/ha-automation-trigger-calendar"; import "./types/ha-automation-trigger-calendar";
@@ -133,8 +136,6 @@ export default class HaAutomationTriggerRow extends LitElement {
@state() private _selected = false; @state() private _selected = false;
@state() private _requestShowId = false;
@state() private _warnings?: string[]; @state() private _warnings?: string[];
@property({ type: Boolean }) public narrow = false; @property({ type: Boolean }) public narrow = false;
@@ -163,6 +164,20 @@ export default class HaAutomationTriggerRow extends LitElement {
private _triggerUnsub?: Promise<UnsubscribeFunc>; private _triggerUnsub?: Promise<UnsubscribeFunc>;
private _renderOverflowLabel(label: string, shortcut?: TemplateResult) {
return html`
<div class="overflow-label">
${label}
${this.optionsInSidebar && !this.narrow
? shortcut ||
html`<span
class="shortcut-placeholder ${isMac ? "mac" : ""}"
></span>`
: nothing}
</div>
`;
}
private _renderRow() { private _renderRow() {
const type = this._getType(this.trigger); const type = this._getType(this.trigger);
@@ -182,8 +197,7 @@ export default class HaAutomationTriggerRow extends LitElement {
<slot name="icons" slot="icons"></slot> <slot name="icons" slot="icons"></slot>
${!this.optionsInSidebar <ha-md-button-menu
? html`<ha-md-button-menu
quick quick
slot="icons" slot="icons"
@click=${preventDefaultStopPropagation} @click=${preventDefaultStopPropagation}
@@ -202,20 +216,12 @@ export default class HaAutomationTriggerRow extends LitElement {
.clickAction=${this._renameTrigger} .clickAction=${this._renameTrigger}
.disabled=${this.disabled || type === "list"} .disabled=${this.disabled || type === "list"}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.rename"
)}
<ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon>
</ha-md-menu-item> ${this._renderOverflowLabel(
this.hass.localize(
<ha-md-menu-item "ui.panel.config.automation.editor.triggers.rename"
.clickAction=${this._showTriggerId} )
.disabled=${this.disabled || type === "list"}
>
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.edit_id"
)} )}
<ha-svg-icon slot="start" .path=${mdiIdentifier}></ha-svg-icon>
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider> <ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
@@ -224,61 +230,103 @@ export default class HaAutomationTriggerRow extends LitElement {
.clickAction=${this._duplicateTrigger} .clickAction=${this._duplicateTrigger}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.duplicate"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${mdiPlusCircleMultipleOutline} .path=${mdiPlusCircleMultipleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._copyTrigger} .clickAction=${this._copyTrigger}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.copy"
)}
<ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.copy"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span>C</span>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._cutTrigger} .clickAction=${this._cutTrigger}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.cut"
)}
<ha-svg-icon slot="start" .path=${mdiContentCut}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiContentCut}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.triggers.cut"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span>X</span>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
${!this.optionsInSidebar
? html`
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._moveUp} .clickAction=${this._moveUp}
.disabled=${this.disabled || this.first} .disabled=${this.disabled || !!this.first}
> >
${this.hass.localize("ui.panel.config.automation.editor.move_up")} ${this.hass.localize(
"ui.panel.config.automation.editor.move_up"
)}
<ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon <ha-svg-icon slot="start" .path=${mdiArrowUp}></ha-svg-icon
></ha-md-menu-item> ></ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._moveDown} .clickAction=${this._moveDown}
.disabled=${this.disabled || this.last} .disabled=${this.disabled || !!this.last}
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.move_down" "ui.panel.config.automation.editor.move_down"
)} )}
<ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon <ha-svg-icon slot="start" .path=${mdiArrowDown}></ha-svg-icon
></ha-md-menu-item> ></ha-md-menu-item>
`
: nothing}
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._toggleYamlMode} .clickAction=${this._toggleYamlMode}
.disabled=${!supported || !!this._warnings} .disabled=${!supported || !!this._warnings}
> >
${this.hass.localize(
`ui.panel.config.automation.editor.edit_${!yamlMode ? "yaml" : "ui"}`
)}
<ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon> <ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
`ui.panel.config.automation.editor.edit_${!yamlMode ? "yaml" : "ui"}`
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider> <ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
@@ -287,37 +335,54 @@ export default class HaAutomationTriggerRow extends LitElement {
.clickAction=${this._onDisable} .clickAction=${this._onDisable}
.disabled=${this.disabled || type === "list"} .disabled=${this.disabled || type === "list"}
> >
${"enabled" in this.trigger && this.trigger.enabled === false
? this.hass.localize(
"ui.panel.config.automation.editor.actions.enable"
)
: this.hass.localize(
"ui.panel.config.automation.editor.actions.disable"
)}
<ha-svg-icon <ha-svg-icon
slot="start" slot="start"
.path=${"enabled" in this.trigger && .path=${"enabled" in this.trigger && this.trigger.enabled === false
this.trigger.enabled === false
? mdiPlayCircleOutline ? mdiPlayCircleOutline
: mdiStopCircleOutline} : mdiStopCircleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
`ui.panel.config.automation.editor.actions.${"enabled" in this.trigger && this.trigger.enabled === false ? "enable" : "disable"}`
)
)}
</ha-md-menu-item> </ha-md-menu-item>
<ha-md-menu-item <ha-md-menu-item
.clickAction=${this._onDelete} .clickAction=${this._onDelete}
class="warning" class="warning"
.disabled=${this.disabled} .disabled=${this.disabled}
> >
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
<ha-svg-icon <ha-svg-icon
class="warning" class="warning"
slot="start" slot="start"
.path=${mdiDelete} .path=${mdiDelete}
></ha-svg-icon> ></ha-svg-icon>
${this._renderOverflowLabel(
this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
),
html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span
>${this.hass.localize(
"ui.panel.config.automation.editor.del"
)}</span
>
</span>`
)}
</ha-md-menu-item> </ha-md-menu-item>
</ha-md-button-menu>` </ha-md-button-menu>
: nothing}
${!this.optionsInSidebar ${!this.optionsInSidebar
? html`${this._warnings ? html`${this._warnings
? html`<ha-automation-editor-warning ? html`<ha-automation-editor-warning
@@ -331,7 +396,6 @@ export default class HaAutomationTriggerRow extends LitElement {
.trigger=${this.trigger} .trigger=${this.trigger}
.disabled=${this.disabled} .disabled=${this.disabled}
.yamlMode=${this._yamlMode} .yamlMode=${this._yamlMode}
.showId=${this._requestShowId}
.uiSupported=${supported} .uiSupported=${supported}
@ui-mode-not-available=${this._handleUiModeNotAvailable} @ui-mode-not-available=${this._handleUiModeNotAvailable}
></ha-automation-trigger-editor>` ></ha-automation-trigger-editor>`
@@ -380,6 +444,7 @@ export default class HaAutomationTriggerRow extends LitElement {
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.triggers.triggered" "ui.panel.config.automation.editor.triggers.triggered"
)} )}
<ha-svg-icon .path=${mdiInformation}></ha-svg-icon>
</div> </div>
</ha-card> </ha-card>
`; `;
@@ -630,14 +695,6 @@ export default class HaAutomationTriggerRow extends LitElement {
} }
}; };
private _showTriggerId = () => {
this._requestShowId = true;
if (!this.optionsInSidebar) {
this.expand();
}
};
private _duplicateTrigger = () => { private _duplicateTrigger = () => {
fireEvent(this, "duplicate"); fireEvent(this, "duplicate");
}; };
@@ -682,7 +739,7 @@ export default class HaAutomationTriggerRow extends LitElement {
fireEvent(this, "move-down"); fireEvent(this, "move-down");
}; };
private _toggleYamlMode = () => { private _toggleYamlMode = (item?: HTMLElement) => {
if (this._yamlMode) { if (this._yamlMode) {
this._switchUiMode(); this._switchUiMode();
} else { } else {
@@ -691,6 +748,8 @@ export default class HaAutomationTriggerRow extends LitElement {
if (!this.optionsInSidebar) { if (!this.optionsInSidebar) {
this.expand(); this.expand();
} else if (item) {
this.openSidebar();
} }
}; };
@@ -716,6 +775,7 @@ export default class HaAutomationTriggerRow extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
rowStyles, rowStyles,
overflowStyles,
css` css`
.triggered { .triggered {
cursor: pointer; cursor: pointer;
@@ -740,9 +800,20 @@ export default class HaAutomationTriggerRow extends LitElement {
--ha-card-border-radius, --ha-card-border-radius,
var(--ha-border-radius-lg) var(--ha-border-radius-lg)
); );
display: flex;
justify-content: center;
align-items: center;
gap: 4px;
line-height: 1;
padding: 0;
} }
.triggered ha-svg-icon {
--mdc-icon-size: 16px;
}
.triggered.active { .triggered.active {
max-height: 100px; max-height: 100px;
padding: 4px;
} }
.triggered:hover { .triggered:hover {
opacity: 0.8; opacity: 0.8;

View File

@@ -1,19 +1,30 @@
import {
mdiAppleKeyboardCommand,
mdiDelete,
mdiDotsVertical,
mdiPlaylistEdit,
} from "@mdi/js";
import type { CSSResultGroup } from "lit"; import type { CSSResultGroup } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { preventDefaultStopPropagation } from "../../../common/dom/prevent_default_stop_propagation";
import { stopPropagation } from "../../../common/dom/stop_propagation";
import type { LocalizeKeys } from "../../../common/translations/localize"; import type { LocalizeKeys } from "../../../common/translations/localize";
import "../../../components/ha-automation-row"; import "../../../components/ha-automation-row";
import type { HaAutomationRow } from "../../../components/ha-automation-row"; import type { HaAutomationRow } from "../../../components/ha-automation-row";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-md-button-menu";
import "../../../components/ha-md-menu-item";
import type { ScriptFieldSidebarConfig } from "../../../data/automation"; import type { ScriptFieldSidebarConfig } from "../../../data/automation";
import type { Field } from "../../../data/script"; import type { Field } from "../../../data/script";
import { SELECTOR_SELECTOR_BUILDING_BLOCKS } from "../../../data/selector/selector_selector"; import { SELECTOR_SELECTOR_BUILDING_BLOCKS } from "../../../data/selector/selector_selector";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { indentStyle } from "../automation/styles"; import { isMac } from "../../../util/is_mac";
import { indentStyle, overflowStyles } from "../automation/styles";
import "./ha-script-field-selector-editor"; import "./ha-script-field-selector-editor";
import type HaScriptFieldSelectorEditor from "./ha-script-field-selector-editor"; import type HaScriptFieldSelectorEditor from "./ha-script-field-selector-editor";
@@ -66,6 +77,64 @@ export default class HaScriptFieldRow extends LitElement {
.highlight=${this.highlight} .highlight=${this.highlight}
@delete-row=${this._onDelete} @delete-row=${this._onDelete}
> >
<ha-md-button-menu
quick
slot="icons"
@click=${preventDefaultStopPropagation}
@keydown=${stopPropagation}
@closed=${stopPropagation}
positioning="fixed"
anchor-corner="end-end"
menu-corner="start-end"
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-md-menu-item .clickAction=${this._toggleYamlMode}>
<ha-svg-icon slot="start" .path=${mdiPlaylistEdit}></ha-svg-icon>
<div class="overflow-label">
${this.hass.localize(
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
)}
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
</div>
</ha-md-menu-item>
<ha-md-menu-item
.clickAction=${this._onDelete}
.disabled=${this.disabled}
class="warning"
>
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
<div class="overflow-label">
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
${!this.narrow
? html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span
>${this.hass.localize(
"ui.panel.config.automation.editor.del"
)}</span
>
</span>`
: nothing}
</div>
</ha-md-menu-item>
</ha-md-button-menu>
<h3 slot="header">${this.key}</h3> <h3 slot="header">${this.key}</h3>
<slot name="icons" slot="icons"></slot> <slot name="icons" slot="icons"></slot>
@@ -97,6 +166,71 @@ export default class HaScriptFieldRow extends LitElement {
"ui.panel.config.script.editor.field.selector" "ui.panel.config.script.editor.field.selector"
)} )}
</h3> </h3>
<ha-md-button-menu
quick
slot="icons"
@click=${preventDefaultStopPropagation}
@keydown=${stopPropagation}
@closed=${stopPropagation}
positioning="fixed"
anchor-corner="end-end"
menu-corner="start-end"
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-md-menu-item
.clickAction=${this._toggleYamlMode}
selector-row
>
<ha-svg-icon
slot="start"
.path=${mdiPlaylistEdit}
></ha-svg-icon>
<div class="overflow-label">
${this.hass.localize(
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
)}
<span
class="shortcut-placeholder ${isMac ? "mac" : ""}"
></span>
</div>
</ha-md-menu-item>
<ha-md-menu-item
.clickAction=${this._onDelete}
.disabled=${this.disabled}
class="warning"
>
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
<div class="overflow-label">
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
${!this.narrow
? html`<span class="shortcut">
<span
>${isMac
? html`<ha-svg-icon
slot="start"
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize(
"ui.panel.config.automation.editor.ctrl"
)}</span
>
<span>+</span>
<span
>${this.hass.localize(
"ui.panel.config.automation.editor.del"
)}</span
>
</span>`
: nothing}
</div>
</ha-md-menu-item>
</ha-md-button-menu>
</ha-automation-row> </ha-automation-row>
</ha-card> </ha-card>
${typeof this.field.selector === "object" && ${typeof this.field.selector === "object" &&
@@ -243,8 +377,12 @@ export default class HaScriptFieldRow extends LitElement {
} }
} }
private _toggleYamlMode = () => { private _toggleYamlMode = (item?: HTMLElement) => {
this._yamlMode = !this._yamlMode; this._yamlMode = !this._yamlMode;
if (item) {
this.openSidebar(item.hasAttribute("selector-row"));
}
}; };
private _onDelete = () => { private _onDelete = () => {
@@ -279,6 +417,7 @@ export default class HaScriptFieldRow extends LitElement {
return [ return [
haStyle, haStyle,
indentStyle, indentStyle,
overflowStyles,
css` css`
.disabled { .disabled {
opacity: 0.5; opacity: 0.5;

View File

@@ -3883,6 +3883,8 @@
"add": "Add trigger", "add": "Add trigger",
"search": "Search trigger", "search": "Search trigger",
"id": "Trigger ID", "id": "Trigger ID",
"id_helper": "Helps identify each run based on which trigger fired.",
"optional": "Optional",
"edit_id": "Edit ID", "edit_id": "Edit ID",
"duplicate": "[%key:ui::common::duplicate%]", "duplicate": "[%key:ui::common::duplicate%]",
"re_order": "Re-order", "re_order": "Re-order",
@@ -4287,7 +4289,7 @@
}, },
"trigger": { "trigger": {
"label": "Triggered by", "label": "Triggered by",
"no_triggers": "No triggers have an ID set. Use the three-dot menu on a trigger and select Edit ID to assign one.", "no_triggers": "There are no triggers with ID's set in this automation. Edit a trigger and give it a Trigger ID name.",
"id": "Trigger", "id": "Trigger",
"description": { "description": {
"picker": "If the automation has been triggered by a specific trigger.", "picker": "If the automation has been triggered by a specific trigger.",