Always allow reorder for triggers, conditions, actions and options (#19574)
* Move up and down action to overflow menu * Always enable reorder mode on desktop * Use media query helper
This commit is contained in:
parent
568e9ebc38
commit
64fc58ddd2
|
@ -32,7 +32,6 @@ import {
|
||||||
expandDeviceTarget,
|
expandDeviceTarget,
|
||||||
Selector,
|
Selector,
|
||||||
} from "../data/selector";
|
} from "../data/selector";
|
||||||
import { ReorderModeMixin } from "../state/reorder-mode-mixin";
|
|
||||||
import { HomeAssistant, ValueChangedEvent } from "../types";
|
import { HomeAssistant, ValueChangedEvent } from "../types";
|
||||||
import { documentationUrl } from "../util/documentation-url";
|
import { documentationUrl } from "../util/documentation-url";
|
||||||
import "./ha-checkbox";
|
import "./ha-checkbox";
|
||||||
|
@ -77,7 +76,7 @@ interface ExtHassService extends Omit<HassService, "fields"> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement("ha-service-control")
|
@customElement("ha-service-control")
|
||||||
export class HaServiceControl extends ReorderModeMixin(LitElement) {
|
export class HaServiceControl extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public value?: {
|
@property({ attribute: false }) public value?: {
|
||||||
|
@ -441,7 +440,6 @@ export class HaServiceControl extends ReorderModeMixin(LitElement) {
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>`
|
></ha-entity-picker>`
|
||||||
: ""}
|
: ""}
|
||||||
${this._renderReorderModeAlert()}
|
|
||||||
${shouldRenderServiceDataYaml
|
${shouldRenderServiceDataYaml
|
||||||
? html`<ha-yaml-editor
|
? html`<ha-yaml-editor
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
@ -522,34 +520,6 @@ export class HaServiceControl extends ReorderModeMixin(LitElement) {
|
||||||
})}`;
|
})}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderReorderModeAlert() {
|
|
||||||
if (!this._reorderMode.active) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
<ha-alert
|
|
||||||
class="re-order"
|
|
||||||
alert-type="info"
|
|
||||||
.title=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.title"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.description_all"
|
|
||||||
)}
|
|
||||||
<ha-button slot="action" @click=${this._exitReOrderMode}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.exit"
|
|
||||||
)}
|
|
||||||
</ha-button>
|
|
||||||
</ha-alert>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _exitReOrderMode() {
|
|
||||||
this._reorderMode.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _localizeValueCallback = (key: string) => {
|
private _localizeValueCallback = (key: string) => {
|
||||||
if (!this._value?.service) {
|
if (!this._value?.service) {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import {
|
import {
|
||||||
mdiAlertCircleCheck,
|
mdiAlertCircleCheck,
|
||||||
|
mdiArrowDown,
|
||||||
|
mdiArrowUp,
|
||||||
mdiCheck,
|
mdiCheck,
|
||||||
mdiContentCopy,
|
mdiContentCopy,
|
||||||
mdiContentCut,
|
mdiContentCut,
|
||||||
|
@ -12,7 +14,6 @@ import {
|
||||||
mdiPlay,
|
mdiPlay,
|
||||||
mdiPlayCircleOutline,
|
mdiPlayCircleOutline,
|
||||||
mdiRenameBox,
|
mdiRenameBox,
|
||||||
mdiSort,
|
|
||||||
mdiStopCircleOutline,
|
mdiStopCircleOutline,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
|
@ -34,9 +35,9 @@ import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||||
import "../../../../components/ha-alert";
|
import "../../../../components/ha-alert";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
import "../../../../components/ha-service-icon";
|
|
||||||
import "../../../../components/ha-expansion-panel";
|
import "../../../../components/ha-expansion-panel";
|
||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-icon-button";
|
||||||
|
import "../../../../components/ha-service-icon";
|
||||||
import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
|
import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
|
||||||
import { ACTION_ICONS, YAML_ONLY_ACTION_TYPES } from "../../../../data/action";
|
import { ACTION_ICONS, YAML_ONLY_ACTION_TYPES } from "../../../../data/action";
|
||||||
import { AutomationClipboard } from "../../../../data/automation";
|
import { AutomationClipboard } from "../../../../data/automation";
|
||||||
|
@ -56,10 +57,6 @@ import {
|
||||||
showPromptDialog,
|
showPromptDialog,
|
||||||
} from "../../../../dialogs/generic/show-dialog-box";
|
} from "../../../../dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../state/reorder-mode-mixin";
|
|
||||||
import type { HomeAssistant, ItemPath } from "../../../../types";
|
import type { HomeAssistant, ItemPath } from "../../../../types";
|
||||||
import { showToast } from "../../../../util/toast";
|
import { showToast } from "../../../../util/toast";
|
||||||
import "./types/ha-automation-action-activate_scene";
|
import "./types/ha-automation-action-activate_scene";
|
||||||
|
@ -73,10 +70,10 @@ import "./types/ha-automation-action-parallel";
|
||||||
import "./types/ha-automation-action-play_media";
|
import "./types/ha-automation-action-play_media";
|
||||||
import "./types/ha-automation-action-repeat";
|
import "./types/ha-automation-action-repeat";
|
||||||
import "./types/ha-automation-action-service";
|
import "./types/ha-automation-action-service";
|
||||||
|
import "./types/ha-automation-action-set_conversation_response";
|
||||||
import "./types/ha-automation-action-stop";
|
import "./types/ha-automation-action-stop";
|
||||||
import "./types/ha-automation-action-wait_for_trigger";
|
import "./types/ha-automation-action-wait_for_trigger";
|
||||||
import "./types/ha-automation-action-wait_template";
|
import "./types/ha-automation-action-wait_template";
|
||||||
import "./types/ha-automation-action-set_conversation_response";
|
|
||||||
|
|
||||||
export const getType = (action: Action | undefined) => {
|
export const getType = (action: Action | undefined) => {
|
||||||
if (!action) {
|
if (!action) {
|
||||||
|
@ -131,10 +128,12 @@ export default class HaAutomationActionRow extends LitElement {
|
||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) public hideMenu = false;
|
|
||||||
|
|
||||||
@property({ type: Array }) public path?: ItemPath;
|
@property({ type: Array }) public path?: ItemPath;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public first?: boolean;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public last?: boolean;
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "automationClipboard",
|
key: "automationClipboard",
|
||||||
state: false,
|
state: false,
|
||||||
|
@ -147,10 +146,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
@state()
|
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@state() private _uiModeAvailable = true;
|
@state() private _uiModeAvailable = true;
|
||||||
|
@ -189,17 +184,17 @@ export default class HaAutomationActionRow extends LitElement {
|
||||||
const type = getType(this.action);
|
const type = getType(this.action);
|
||||||
const yamlMode = this._yamlMode;
|
const yamlMode = this._yamlMode;
|
||||||
|
|
||||||
const noReorderModeAvailable = this._reorderMode === undefined;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card outlined>
|
<ha-card outlined>
|
||||||
${this.action.enabled === false
|
${this.action.enabled === false
|
||||||
? html`<div class="disabled-bar">
|
? html`
|
||||||
${this.hass.localize(
|
<div class="disabled-bar">
|
||||||
"ui.panel.config.automation.editor.actions.disabled"
|
${this.hass.localize(
|
||||||
)}
|
"ui.panel.config.automation.editor.actions.disabled"
|
||||||
</div>`
|
)}
|
||||||
: ""}
|
</div>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
<ha-expansion-panel leftChevron>
|
<ha-expansion-panel leftChevron>
|
||||||
<h3 slot="header">
|
<h3 slot="header">
|
||||||
${type === "service" &&
|
${type === "service" &&
|
||||||
|
@ -220,6 +215,7 @@ export default class HaAutomationActionRow extends LitElement {
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<slot name="icons" slot="icons"></slot>
|
<slot name="icons" slot="icons"></slot>
|
||||||
|
|
||||||
${type !== "condition" &&
|
${type !== "condition" &&
|
||||||
(this.action as NonConditionAction).continue_on_error === true
|
(this.action as NonConditionAction).continue_on_error === true
|
||||||
? html`<div slot="icons">
|
? html`<div slot="icons">
|
||||||
|
@ -231,146 +227,134 @@ export default class HaAutomationActionRow extends LitElement {
|
||||||
</simple-tooltip>
|
</simple-tooltip>
|
||||||
</div> `
|
</div> `
|
||||||
: nothing}
|
: nothing}
|
||||||
${this.hideMenu
|
|
||||||
? ""
|
|
||||||
: html`
|
|
||||||
<ha-button-menu
|
|
||||||
slot="icons"
|
|
||||||
@action=${this._handleAction}
|
|
||||||
@click=${preventDefault}
|
|
||||||
fixed
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
slot="trigger"
|
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
|
||||||
.path=${mdiDotsVertical}
|
|
||||||
></ha-icon-button>
|
|
||||||
<mwc-list-item graphic="icon">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.actions.run"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiPlay}></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<ha-button-menu
|
||||||
${this.hass.localize(
|
slot="icons"
|
||||||
"ui.panel.config.automation.editor.actions.rename"
|
@action=${this._handleAction}
|
||||||
)}
|
@click=${preventDefault}
|
||||||
<ha-svg-icon
|
fixed
|
||||||
slot="graphic"
|
>
|
||||||
.path=${mdiRenameBox}
|
<ha-icon-button
|
||||||
></ha-svg-icon>
|
slot="trigger"
|
||||||
</mwc-list-item>
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
<mwc-list-item
|
.path=${mdiDotsVertical}
|
||||||
graphic="icon"
|
></ha-icon-button>
|
||||||
.disabled=${this.disabled}
|
<mwc-list-item graphic="icon">
|
||||||
class=${classMap({ hidden: noReorderModeAvailable })}
|
${this.hass.localize(
|
||||||
>
|
"ui.panel.config.automation.editor.actions.run"
|
||||||
${this.hass.localize(
|
)}
|
||||||
"ui.panel.config.automation.editor.actions.re_order"
|
<ha-svg-icon slot="graphic" .path=${mdiPlay}></ha-svg-icon>
|
||||||
)}
|
</mwc-list-item>
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiSort}></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.rename"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiRenameBox}></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<li divider role="separator"></li>
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.actions.duplicate"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiContentDuplicate}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.copy"
|
"ui.panel.config.automation.editor.actions.duplicate"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
slot="graphic"
|
slot="graphic"
|
||||||
.path=${mdiContentCopy}
|
.path=${mdiContentDuplicate}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.cut"
|
"ui.panel.config.automation.editor.triggers.copy"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon slot="graphic" .path=${mdiContentCopy}></ha-svg-icon>
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${mdiContentCut}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.cut"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiContentCut}></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item
|
<mwc-list-item
|
||||||
.disabled=${!this._uiModeAvailable}
|
graphic="icon"
|
||||||
graphic="icon"
|
.disabled=${this.disabled || this.first}
|
||||||
>
|
>
|
||||||
${this.hass.localize(
|
${this.hass.localize("ui.panel.config.automation.editor.move_up")}
|
||||||
"ui.panel.config.automation.editor.edit_ui"
|
<ha-svg-icon slot="graphic" .path=${mdiArrowUp}></ha-svg-icon
|
||||||
)}
|
></mwc-list-item>
|
||||||
${!yamlMode
|
|
||||||
? html`<ha-svg-icon
|
|
||||||
class="selected_menu_item"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiCheck}
|
|
||||||
></ha-svg-icon>`
|
|
||||||
: ``}
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item
|
<mwc-list-item
|
||||||
.disabled=${!this._uiModeAvailable}
|
graphic="icon"
|
||||||
graphic="icon"
|
.disabled=${this.disabled || this.last}
|
||||||
>
|
>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.edit_yaml"
|
"ui.panel.config.automation.editor.move_down"
|
||||||
)}
|
)}
|
||||||
${yamlMode
|
<ha-svg-icon slot="graphic" .path=${mdiArrowDown}></ha-svg-icon
|
||||||
? html`<ha-svg-icon
|
></mwc-list-item>
|
||||||
class="selected_menu_item"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiCheck}
|
|
||||||
></ha-svg-icon>`
|
|
||||||
: ``}
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<li divider role="separator"></li>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item .disabled=${!this._uiModeAvailable} graphic="icon">
|
||||||
${this.action.enabled === false
|
${this.hass.localize("ui.panel.config.automation.editor.edit_ui")}
|
||||||
? this.hass.localize(
|
${!yamlMode
|
||||||
"ui.panel.config.automation.editor.actions.enable"
|
? html`<ha-svg-icon
|
||||||
)
|
class="selected_menu_item"
|
||||||
: this.hass.localize(
|
slot="graphic"
|
||||||
"ui.panel.config.automation.editor.actions.disable"
|
.path=${mdiCheck}
|
||||||
)}
|
></ha-svg-icon>`
|
||||||
<ha-svg-icon
|
: ``}
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${this.action.enabled === false
|
|
||||||
? mdiPlayCircleOutline
|
<mwc-list-item .disabled=${!this._uiModeAvailable} graphic="icon">
|
||||||
: mdiStopCircleOutline}
|
${this.hass.localize(
|
||||||
></ha-svg-icon>
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
</mwc-list-item>
|
)}
|
||||||
<mwc-list-item
|
${yamlMode
|
||||||
class="warning"
|
? html`<ha-svg-icon
|
||||||
graphic="icon"
|
class="selected_menu_item"
|
||||||
.disabled=${this.disabled}
|
slot="graphic"
|
||||||
>
|
.path=${mdiCheck}
|
||||||
${this.hass.localize(
|
></ha-svg-icon>`
|
||||||
"ui.panel.config.automation.editor.actions.delete"
|
: ``}
|
||||||
)}
|
</mwc-list-item>
|
||||||
<ha-svg-icon
|
|
||||||
class="warning"
|
<li divider role="separator"></li>
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiDelete}
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
></ha-svg-icon>
|
${this.action.enabled === false
|
||||||
</mwc-list-item>
|
? this.hass.localize(
|
||||||
</ha-button-menu>
|
"ui.panel.config.automation.editor.actions.enable"
|
||||||
`}
|
)
|
||||||
|
: this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.disable"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${this.action.enabled === false
|
||||||
|
? mdiPlayCircleOutline
|
||||||
|
: mdiStopCircleOutline}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
<mwc-list-item
|
||||||
|
class="warning"
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.delete"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
class="warning"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
|
@ -453,30 +437,33 @@ export default class HaAutomationActionRow extends LitElement {
|
||||||
await this._renameAction();
|
await this._renameAction();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this._reorderMode?.enter();
|
fireEvent(this, "duplicate");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
fireEvent(this, "duplicate");
|
this._setClipboard();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
this._setClipboard();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
this._setClipboard();
|
this._setClipboard();
|
||||||
fireEvent(this, "value-changed", { value: null });
|
fireEvent(this, "value-changed", { value: null });
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
fireEvent(this, "move-up");
|
||||||
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
fireEvent(this, "move-down");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
this._switchUiMode();
|
this._switchUiMode();
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 8:
|
||||||
this._switchYamlMode();
|
this._switchYamlMode();
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 9:
|
||||||
this._onDisable();
|
this._onDisable();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 10:
|
||||||
this._onDelete();
|
this._onDelete();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
import { consume } from "@lit-labs/context";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import { mdiArrowDown, mdiArrowUp, mdiDrag, mdiPlus } from "@mdi/js";
|
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
|
import {
|
||||||
|
CSSResultGroup,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nestedArrayMove } from "../../../../common/util/array-move";
|
import { nestedArrayMove } from "../../../../common/util/array-move";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-sortable";
|
import "../../../../components/ha-sortable";
|
||||||
|
@ -13,10 +20,6 @@ import "../../../../components/ha-svg-icon";
|
||||||
import { getService, isService } from "../../../../data/action";
|
import { getService, isService } from "../../../../data/action";
|
||||||
import type { AutomationClipboard } from "../../../../data/automation";
|
import type { AutomationClipboard } from "../../../../data/automation";
|
||||||
import { Action } from "../../../../data/script";
|
import { Action } from "../../../../data/script";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../state/reorder-mode-mixin";
|
|
||||||
import { HomeAssistant, ItemPath } from "../../../../types";
|
import { HomeAssistant, ItemPath } from "../../../../types";
|
||||||
import {
|
import {
|
||||||
PASTE_VALUE,
|
PASTE_VALUE,
|
||||||
|
@ -37,9 +40,7 @@ export default class HaAutomationAction extends LitElement {
|
||||||
|
|
||||||
@property({ attribute: false }) public actions!: Action[];
|
@property({ attribute: false }) public actions!: Action[];
|
||||||
|
|
||||||
@state()
|
@state() private _showReorder: boolean = false;
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "automationClipboard",
|
key: "automationClipboard",
|
||||||
|
@ -53,6 +54,21 @@ export default class HaAutomationAction extends LitElement {
|
||||||
|
|
||||||
private _actionKeys = new WeakMap<Action, string>();
|
private _actionKeys = new WeakMap<Action, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private get nested() {
|
private get nested() {
|
||||||
return this.path !== undefined;
|
return this.path !== undefined;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +77,7 @@ export default class HaAutomationAction extends LitElement {
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
.disabled=${!this._reorderMode?.active}
|
.disabled=${!this._showReorder}
|
||||||
@item-moved=${this._actionMoved}
|
@item-moved=${this._actionMoved}
|
||||||
group="actions"
|
group="actions"
|
||||||
.path=${this.path}
|
.path=${this.path}
|
||||||
|
@ -74,44 +90,28 @@ export default class HaAutomationAction extends LitElement {
|
||||||
<ha-automation-action-row
|
<ha-automation-action-row
|
||||||
.path=${[...(this.path ?? []), idx]}
|
.path=${[...(this.path ?? []), idx]}
|
||||||
.index=${idx}
|
.index=${idx}
|
||||||
|
.first=${idx === 0}
|
||||||
|
.last=${idx === this.actions.length - 1}
|
||||||
.action=${action}
|
.action=${action}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.hideMenu=${Boolean(this._reorderMode?.active)}
|
|
||||||
@duplicate=${this._duplicateAction}
|
@duplicate=${this._duplicateAction}
|
||||||
|
@move-down=${this._moveDown}
|
||||||
|
@move-up=${this._moveUp}
|
||||||
@value-changed=${this._actionChanged}
|
@value-changed=${this._actionChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
>
|
>
|
||||||
${this._reorderMode?.active
|
${this._showReorder
|
||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_up"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowUp}
|
|
||||||
@click=${this._moveUp}
|
|
||||||
.disabled=${idx === 0}
|
|
||||||
></ha-icon-button>
|
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_down"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowDown}
|
|
||||||
@click=${this._moveDown}
|
|
||||||
.disabled=${idx === this.actions.length - 1}
|
|
||||||
></ha-icon-button>
|
|
||||||
<div class="handle" slot="icons">
|
<div class="handle" slot="icons">
|
||||||
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</ha-automation-action-row>
|
</ha-automation-action-row>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ha-sortable>
|
</ha-sortable>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
|
@ -281,7 +281,7 @@ export default class HaAutomationAction extends LitElement {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.handle {
|
.handle {
|
||||||
padding: 12px;
|
padding: 12px 4px;
|
||||||
cursor: move; /* fallback if grab cursor is unsupported */
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,21 @@ import {
|
||||||
mdiDrag,
|
mdiDrag,
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
mdiRenameBox,
|
mdiRenameBox,
|
||||||
mdiSort,
|
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
|
import {
|
||||||
|
CSSResultGroup,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../../common/dom/media_query";
|
||||||
import { capitalizeFirstLetter } from "../../../../../common/string/capitalize-first-letter";
|
import { capitalizeFirstLetter } from "../../../../../common/string/capitalize-first-letter";
|
||||||
import "../../../../../components/ha-button";
|
import "../../../../../components/ha-button";
|
||||||
import "../../../../../components/ha-button-menu";
|
import "../../../../../components/ha-button-menu";
|
||||||
|
@ -37,10 +43,6 @@ import {
|
||||||
showPromptDialog,
|
showPromptDialog,
|
||||||
} from "../../../../../dialogs/generic/show-dialog-box";
|
} from "../../../../../dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../../../../resources/styles";
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../../state/reorder-mode-mixin";
|
|
||||||
import { HomeAssistant, ItemPath } from "../../../../../types";
|
import { HomeAssistant, ItemPath } from "../../../../../types";
|
||||||
import { ActionElement } from "../ha-automation-action-row";
|
import { ActionElement } from "../ha-automation-action-row";
|
||||||
|
|
||||||
|
@ -64,12 +66,25 @@ export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
@state()
|
@state() private _showReorder: boolean = false;
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
private _expandLast = false;
|
private _expandLast = false;
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public static get defaultConfig() {
|
public static get defaultConfig() {
|
||||||
return { choose: [{ conditions: [], sequence: [] }] };
|
return { choose: [{ conditions: [], sequence: [] }] };
|
||||||
}
|
}
|
||||||
|
@ -104,12 +119,10 @@ export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
protected render() {
|
protected render() {
|
||||||
const action = this.action;
|
const action = this.action;
|
||||||
|
|
||||||
const noReorderModeAvailable = this._reorderMode === undefined;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
.disabled=${!this._reorderMode?.active}
|
.disabled=${!this._showReorder}
|
||||||
group="choose-options"
|
group="choose-options"
|
||||||
.path=${[...(this.path ?? []), "choose"]}
|
.path=${[...(this.path ?? []), "choose"]}
|
||||||
>
|
>
|
||||||
|
@ -135,103 +148,89 @@ export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
? ""
|
? ""
|
||||||
: this._getDescription(option))}
|
: this._getDescription(option))}
|
||||||
</h3>
|
</h3>
|
||||||
${this._reorderMode?.active
|
${this._showReorder
|
||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_up"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowUp}
|
|
||||||
@click=${this._moveUp}
|
|
||||||
.disabled=${idx === 0}
|
|
||||||
></ha-icon-button>
|
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_down"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowDown}
|
|
||||||
@click=${this._moveDown}
|
|
||||||
.disabled=${idx ===
|
|
||||||
ensureArray(this.action.choose).length - 1}
|
|
||||||
></ha-icon-button>
|
|
||||||
<div class="handle" slot="icons">
|
<div class="handle" slot="icons">
|
||||||
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: html`
|
: nothing}
|
||||||
<ha-button-menu
|
|
||||||
slot="icons"
|
|
||||||
.idx=${idx}
|
|
||||||
@action=${this._handleAction}
|
|
||||||
@click=${preventDefault}
|
|
||||||
fixed
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
slot="trigger"
|
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
|
||||||
.path=${mdiDotsVertical}
|
|
||||||
></ha-icon-button>
|
|
||||||
<mwc-list-item
|
|
||||||
graphic="icon"
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.actions.rename"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiRenameBox}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
<mwc-list-item
|
|
||||||
graphic="icon"
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
class=${classMap({
|
|
||||||
hidden: noReorderModeAvailable,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.actions.re_order"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiSort}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item
|
<ha-button-menu
|
||||||
graphic="icon"
|
slot="icons"
|
||||||
.disabled=${this.disabled}
|
.idx=${idx}
|
||||||
>
|
@action=${this._handleAction}
|
||||||
${this.hass.localize(
|
@click=${preventDefault}
|
||||||
"ui.panel.config.automation.editor.actions.duplicate"
|
fixed
|
||||||
)}
|
>
|
||||||
<ha-svg-icon
|
<ha-icon-button
|
||||||
slot="graphic"
|
slot="trigger"
|
||||||
.path=${mdiContentDuplicate}
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
></ha-svg-icon>
|
.path=${mdiDotsVertical}
|
||||||
</mwc-list-item>
|
></ha-icon-button>
|
||||||
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.rename"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiRenameBox}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.duplicate"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiContentDuplicate}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
|
<mwc-list-item
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled || idx === 0}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.move_up"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiArrowUp}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
|
<mwc-list-item
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled ||
|
||||||
|
idx === ensureArray(this.action.choose).length - 1}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.move_down"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiArrowDown}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
|
<mwc-list-item
|
||||||
|
class="warning"
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
class="warning"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
|
||||||
<mwc-list-item
|
|
||||||
class="warning"
|
|
||||||
graphic="icon"
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon
|
|
||||||
class="warning"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiDelete}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
</ha-button-menu>
|
|
||||||
`}
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h4>
|
<h4>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
|
@ -324,12 +323,15 @@ export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
await this._renameAction(ev);
|
await this._renameAction(ev);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this._reorderMode?.enter();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this._duplicateOption(ev);
|
this._duplicateOption(ev);
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
this._moveUp(ev);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
this._moveDown(ev);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
this._removeOption(ev);
|
this._removeOption(ev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -433,13 +435,13 @@ export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _moveUp(ev) {
|
private _moveUp(ev) {
|
||||||
const index = (ev.target as any).index;
|
const index = (ev.target as any).idx;
|
||||||
const newIndex = index - 1;
|
const newIndex = index - 1;
|
||||||
this._move(index, newIndex);
|
this._move(index, newIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _moveDown(ev) {
|
private _moveDown(ev) {
|
||||||
const index = (ev.target as any).index;
|
const index = (ev.target as any).idx;
|
||||||
const newIndex = index + 1;
|
const newIndex = index + 1;
|
||||||
this._move(index, newIndex);
|
this._move(index, newIndex);
|
||||||
}
|
}
|
||||||
|
@ -537,7 +539,7 @@ export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
padding: 0 16px 16px 16px;
|
padding: 0 16px 16px 16px;
|
||||||
}
|
}
|
||||||
.handle {
|
.handle {
|
||||||
padding: 12px;
|
padding: 12px 4px;
|
||||||
cursor: move; /* fallback if grab cursor is unsupported */
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { nestedArrayMove } from "../../../common/util/array-move";
|
import { nestedArrayMove } from "../../../common/util/array-move";
|
||||||
|
@ -18,12 +18,11 @@ import {
|
||||||
fetchBlueprints,
|
fetchBlueprints,
|
||||||
} from "../../../data/blueprint";
|
} from "../../../data/blueprint";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { ReorderModeMixin } from "../../../state/reorder-mode-mixin";
|
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
import "../ha-config-section";
|
||||||
|
|
||||||
@customElement("blueprint-automation-editor")
|
@customElement("blueprint-automation-editor")
|
||||||
export class HaBlueprintAutomationEditor extends ReorderModeMixin(LitElement) {
|
export class HaBlueprintAutomationEditor extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ type: Boolean }) public isWide = false;
|
@property({ type: Boolean }) public isWide = false;
|
||||||
|
@ -78,7 +77,6 @@ export class HaBlueprintAutomationEditor extends ReorderModeMixin(LitElement) {
|
||||||
${this.config.description
|
${this.config.description
|
||||||
? html`<p class="description">${this.config.description}</p>`
|
? html`<p class="description">${this.config.description}</p>`
|
||||||
: ""}
|
: ""}
|
||||||
${this._renderReorderModeAlert()}
|
|
||||||
<ha-card
|
<ha-card
|
||||||
outlined
|
outlined
|
||||||
class="blueprint"
|
class="blueprint"
|
||||||
|
@ -173,34 +171,6 @@ export class HaBlueprintAutomationEditor extends ReorderModeMixin(LitElement) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderReorderModeAlert() {
|
|
||||||
if (!this._reorderMode.active) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
<ha-alert
|
|
||||||
class="re-order"
|
|
||||||
alert-type="info"
|
|
||||||
.title=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.title"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.description_all"
|
|
||||||
)}
|
|
||||||
<ha-button slot="action" @click=${this._exitReOrderMode}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.exit"
|
|
||||||
)}
|
|
||||||
</ha-button>
|
|
||||||
</ha-alert>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _exitReOrderMode() {
|
|
||||||
this._reorderMode.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _getBlueprints() {
|
private async _getBlueprints() {
|
||||||
this._blueprints = await fetchBlueprints(this.hass, "automation");
|
this._blueprints = await fetchBlueprints(this.hass, "automation");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { consume } from "@lit-labs/context";
|
||||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import {
|
import {
|
||||||
|
mdiArrowDown,
|
||||||
|
mdiArrowUp,
|
||||||
mdiCheck,
|
mdiCheck,
|
||||||
mdiContentCopy,
|
mdiContentCopy,
|
||||||
mdiContentCut,
|
mdiContentCut,
|
||||||
|
@ -11,7 +13,6 @@ import {
|
||||||
mdiFlask,
|
mdiFlask,
|
||||||
mdiPlayCircleOutline,
|
mdiPlayCircleOutline,
|
||||||
mdiRenameBox,
|
mdiRenameBox,
|
||||||
mdiSort,
|
|
||||||
mdiStopCircleOutline,
|
mdiStopCircleOutline,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
|
@ -41,10 +42,6 @@ import {
|
||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import { HomeAssistant, ItemPath } from "../../../../types";
|
import { HomeAssistant, ItemPath } from "../../../../types";
|
||||||
import "./ha-automation-condition-editor";
|
import "./ha-automation-condition-editor";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../state/reorder-mode-mixin";
|
|
||||||
|
|
||||||
export interface ConditionElement extends LitElement {
|
export interface ConditionElement extends LitElement {
|
||||||
condition: Condition;
|
condition: Condition;
|
||||||
|
@ -83,12 +80,14 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||||
|
|
||||||
@property({ attribute: false }) public condition!: Condition;
|
@property({ attribute: false }) public condition!: Condition;
|
||||||
|
|
||||||
@property({ type: Boolean }) public hideMenu = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@property({ type: Array }) public path?: ItemPath;
|
@property({ type: Array }) public path?: ItemPath;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public first?: boolean;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public last?: boolean;
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "automationClipboard",
|
key: "automationClipboard",
|
||||||
state: false,
|
state: false,
|
||||||
|
@ -109,25 +108,21 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
@state()
|
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.condition) {
|
if (!this.condition) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const noReorderModeAvailable = this._reorderMode === undefined;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card outlined>
|
<ha-card outlined>
|
||||||
${this.condition.enabled === false
|
${this.condition.enabled === false
|
||||||
? html`<div class="disabled-bar">
|
? html`
|
||||||
${this.hass.localize(
|
<div class="disabled-bar">
|
||||||
"ui.panel.config.automation.editor.actions.disabled"
|
${this.hass.localize(
|
||||||
)}
|
"ui.panel.config.automation.editor.actions.disabled"
|
||||||
</div>`
|
)}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
: ""}
|
: ""}
|
||||||
|
|
||||||
<ha-expansion-panel leftChevron>
|
<ha-expansion-panel leftChevron>
|
||||||
|
@ -142,142 +137,135 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<slot name="icons" slot="icons"></slot>
|
<slot name="icons" slot="icons"></slot>
|
||||||
${this.hideMenu
|
|
||||||
? ""
|
|
||||||
: html`
|
|
||||||
<ha-button-menu
|
|
||||||
slot="icons"
|
|
||||||
@action=${this._handleAction}
|
|
||||||
@click=${preventDefault}
|
|
||||||
fixed
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
slot="trigger"
|
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
|
||||||
.path=${mdiDotsVertical}
|
|
||||||
>
|
|
||||||
</ha-icon-button>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon">
|
<ha-button-menu
|
||||||
${this.hass.localize(
|
slot="icons"
|
||||||
"ui.panel.config.automation.editor.conditions.test"
|
@action=${this._handleAction}
|
||||||
)}
|
@click=${preventDefault}
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiFlask}></ha-svg-icon>
|
fixed
|
||||||
</mwc-list-item>
|
>
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<ha-icon-button
|
||||||
${this.hass.localize(
|
slot="trigger"
|
||||||
"ui.panel.config.automation.editor.conditions.rename"
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
)}
|
.path=${mdiDotsVertical}
|
||||||
<ha-svg-icon
|
>
|
||||||
slot="graphic"
|
</ha-icon-button>
|
||||||
.path=${mdiRenameBox}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item
|
<mwc-list-item graphic="icon">
|
||||||
graphic="icon"
|
${this.hass.localize(
|
||||||
.disabled=${this.disabled}
|
"ui.panel.config.automation.editor.conditions.test"
|
||||||
class=${classMap({ hidden: noReorderModeAvailable })}
|
)}
|
||||||
>
|
<ha-svg-icon slot="graphic" .path=${mdiFlask}></ha-svg-icon>
|
||||||
${this.hass.localize(
|
</mwc-list-item>
|
||||||
"ui.panel.config.automation.editor.conditions.re_order"
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
)}
|
${this.hass.localize(
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiSort}></ha-svg-icon>
|
"ui.panel.config.automation.editor.conditions.rename"
|
||||||
</mwc-list-item>
|
)}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiRenameBox}></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<li divider role="separator"></li>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.actions.duplicate"
|
"ui.panel.config.automation.editor.actions.duplicate"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
slot="graphic"
|
slot="graphic"
|
||||||
.path=${mdiContentDuplicate}
|
.path=${mdiContentDuplicate}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.copy"
|
"ui.panel.config.automation.editor.triggers.copy"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon slot="graphic" .path=${mdiContentCopy}></ha-svg-icon>
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${mdiContentCopy}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.cut"
|
"ui.panel.config.automation.editor.triggers.cut"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon slot="graphic" .path=${mdiContentCut}></ha-svg-icon>
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${mdiContentCut}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<mwc-list-item
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled || this.first}
|
||||||
|
>
|
||||||
|
${this.hass.localize("ui.panel.config.automation.editor.move_up")}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiArrowUp}></ha-svg-icon
|
||||||
|
></mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon">
|
<mwc-list-item
|
||||||
${this.hass.localize(
|
graphic="icon"
|
||||||
"ui.panel.config.automation.editor.edit_ui"
|
.disabled=${this.disabled || this.last}
|
||||||
)}
|
>
|
||||||
${!this._yamlMode
|
${this.hass.localize(
|
||||||
? html`<ha-svg-icon
|
"ui.panel.config.automation.editor.move_down"
|
||||||
class="selected_menu_item"
|
)}
|
||||||
slot="graphic"
|
<ha-svg-icon slot="graphic" .path=${mdiArrowDown}></ha-svg-icon
|
||||||
.path=${mdiCheck}
|
></mwc-list-item>
|
||||||
></ha-svg-icon>`
|
|
||||||
: ``}
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon">
|
<li divider role="separator"></li>
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.edit_yaml"
|
|
||||||
)}
|
|
||||||
${this._yamlMode
|
|
||||||
? html`<ha-svg-icon
|
|
||||||
class="selected_menu_item"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiCheck}
|
|
||||||
></ha-svg-icon>`
|
|
||||||
: ``}
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<mwc-list-item graphic="icon">
|
||||||
|
${this.hass.localize("ui.panel.config.automation.editor.edit_ui")}
|
||||||
|
${!this._yamlMode
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
class="selected_menu_item"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiCheck}
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: ``}
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon">
|
||||||
${this.condition.enabled === false
|
${this.hass.localize(
|
||||||
? this.hass.localize(
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
"ui.panel.config.automation.editor.actions.enable"
|
)}
|
||||||
)
|
${this._yamlMode
|
||||||
: this.hass.localize(
|
? html`<ha-svg-icon
|
||||||
"ui.panel.config.automation.editor.actions.disable"
|
class="selected_menu_item"
|
||||||
)}
|
slot="graphic"
|
||||||
<ha-svg-icon
|
.path=${mdiCheck}
|
||||||
slot="graphic"
|
></ha-svg-icon>`
|
||||||
.path=${this.condition.enabled === false
|
: ``}
|
||||||
? mdiPlayCircleOutline
|
</mwc-list-item>
|
||||||
: mdiStopCircleOutline}
|
|
||||||
></ha-svg-icon>
|
<li divider role="separator"></li>
|
||||||
</mwc-list-item>
|
|
||||||
<mwc-list-item
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
class="warning"
|
${this.condition.enabled === false
|
||||||
graphic="icon"
|
? this.hass.localize(
|
||||||
.disabled=${this.disabled}
|
"ui.panel.config.automation.editor.actions.enable"
|
||||||
>
|
)
|
||||||
${this.hass.localize(
|
: this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.actions.delete"
|
"ui.panel.config.automation.editor.actions.disable"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
class="warning"
|
slot="graphic"
|
||||||
slot="graphic"
|
.path=${this.condition.enabled === false
|
||||||
.path=${mdiDelete}
|
? mdiPlayCircleOutline
|
||||||
></ha-svg-icon>
|
: mdiStopCircleOutline}
|
||||||
</mwc-list-item>
|
></ha-svg-icon>
|
||||||
</ha-button-menu>
|
</mwc-list-item>
|
||||||
`}
|
<mwc-list-item
|
||||||
|
class="warning"
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.delete"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
class="warning"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
|
@ -359,30 +347,33 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||||
await this._renameCondition();
|
await this._renameCondition();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this._reorderMode?.enter();
|
fireEvent(this, "duplicate");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
fireEvent(this, "duplicate");
|
this._setClipboard();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
this._setClipboard();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
this._setClipboard();
|
this._setClipboard();
|
||||||
fireEvent(this, "value-changed", { value: null });
|
fireEvent(this, "value-changed", { value: null });
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
fireEvent(this, "move-up");
|
||||||
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
fireEvent(this, "move-down");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
this._switchUiMode();
|
this._switchUiMode();
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 8:
|
||||||
this._switchYamlMode();
|
this._switchYamlMode();
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 9:
|
||||||
this._onDisable();
|
this._onDisable();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 10:
|
||||||
this._onDelete();
|
this._onDelete();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { consume } from "@lit-labs/context";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import { mdiArrowDown, mdiArrowUp, mdiDrag, mdiPlus } from "@mdi/js";
|
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
|
@ -13,6 +12,7 @@ import { customElement, property, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nestedArrayMove } from "../../../../common/util/array-move";
|
import { nestedArrayMove } from "../../../../common/util/array-move";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
|
@ -22,10 +22,6 @@ import type {
|
||||||
AutomationClipboard,
|
AutomationClipboard,
|
||||||
Condition,
|
Condition,
|
||||||
} from "../../../../data/automation";
|
} from "../../../../data/automation";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../state/reorder-mode-mixin";
|
|
||||||
import type { HomeAssistant, ItemPath } from "../../../../types";
|
import type { HomeAssistant, ItemPath } from "../../../../types";
|
||||||
import {
|
import {
|
||||||
PASTE_VALUE,
|
PASTE_VALUE,
|
||||||
|
@ -44,9 +40,7 @@ export default class HaAutomationCondition extends LitElement {
|
||||||
|
|
||||||
@property({ type: Array }) public path?: ItemPath;
|
@property({ type: Array }) public path?: ItemPath;
|
||||||
|
|
||||||
@state()
|
@state() private _showReorder: boolean = false;
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "automationClipboard",
|
key: "automationClipboard",
|
||||||
|
@ -60,6 +54,21 @@ export default class HaAutomationCondition extends LitElement {
|
||||||
|
|
||||||
private _conditionKeys = new WeakMap<Condition, string>();
|
private _conditionKeys = new WeakMap<Condition, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues) {
|
protected updated(changedProperties: PropertyValues) {
|
||||||
if (!changedProperties.has("conditions")) {
|
if (!changedProperties.has("conditions")) {
|
||||||
return;
|
return;
|
||||||
|
@ -108,7 +117,7 @@ export default class HaAutomationCondition extends LitElement {
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
.disabled=${!this._reorderMode?.active}
|
.disabled=${!this._showReorder}
|
||||||
@item-moved=${this._conditionMoved}
|
@item-moved=${this._conditionMoved}
|
||||||
group="conditions"
|
group="conditions"
|
||||||
.path=${this.path}
|
.path=${this.path}
|
||||||
|
@ -121,42 +130,24 @@ export default class HaAutomationCondition extends LitElement {
|
||||||
<ha-automation-condition-row
|
<ha-automation-condition-row
|
||||||
.path=${[...(this.path ?? []), idx]}
|
.path=${[...(this.path ?? []), idx]}
|
||||||
.index=${idx}
|
.index=${idx}
|
||||||
|
.first=${idx === 0}
|
||||||
|
.last=${idx === this.conditions.length - 1}
|
||||||
.totalConditions=${this.conditions.length}
|
.totalConditions=${this.conditions.length}
|
||||||
.condition=${cond}
|
.condition=${cond}
|
||||||
.hideMenu=${Boolean(this._reorderMode?.active)}
|
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
@duplicate=${this._duplicateCondition}
|
@duplicate=${this._duplicateCondition}
|
||||||
@move-condition=${this._move}
|
@move-down=${this._moveDown}
|
||||||
|
@move-up=${this._moveUp}
|
||||||
@value-changed=${this._conditionChanged}
|
@value-changed=${this._conditionChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
>
|
>
|
||||||
${this._reorderMode?.active
|
${this._showReorder
|
||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_up"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowUp}
|
|
||||||
@click=${this._moveUp}
|
|
||||||
.disabled=${idx === 0}
|
|
||||||
></ha-icon-button>
|
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_down"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowDown}
|
|
||||||
@click=${this._moveDown}
|
|
||||||
.disabled=${idx === this.conditions.length - 1}
|
|
||||||
></ha-icon-button>
|
|
||||||
<div class="handle" slot="icons">
|
<div class="handle" slot="icons">
|
||||||
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</ha-automation-condition-row>
|
</ha-automation-condition-row>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
@ -315,7 +306,7 @@ export default class HaAutomationCondition extends LitElement {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.handle {
|
.handle {
|
||||||
padding: 12px;
|
padding: 12px 4px;
|
||||||
cursor: move; /* fallback if grab cursor is unsupported */
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,8 @@ declare global {
|
||||||
};
|
};
|
||||||
"ui-mode-not-available": Error;
|
"ui-mode-not-available": Error;
|
||||||
duplicate: undefined;
|
duplicate: undefined;
|
||||||
"re-order": undefined;
|
"move-down": undefined;
|
||||||
|
"move-up": undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
} from "../../../data/automation";
|
} from "../../../data/automation";
|
||||||
import { Action } from "../../../data/script";
|
import { Action } from "../../../data/script";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { ReorderModeMixin } from "../../../state/reorder-mode-mixin";
|
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import { documentationUrl } from "../../../util/documentation-url";
|
import { documentationUrl } from "../../../util/documentation-url";
|
||||||
import "./action/ha-automation-action";
|
import "./action/ha-automation-action";
|
||||||
|
@ -24,7 +23,7 @@ import "./condition/ha-automation-condition";
|
||||||
import "./trigger/ha-automation-trigger";
|
import "./trigger/ha-automation-trigger";
|
||||||
|
|
||||||
@customElement("manual-automation-editor")
|
@customElement("manual-automation-editor")
|
||||||
export class HaManualAutomationEditor extends ReorderModeMixin(LitElement) {
|
export class HaManualAutomationEditor extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ type: Boolean }) public isWide = false;
|
@property({ type: Boolean }) public isWide = false;
|
||||||
|
@ -94,7 +93,6 @@ export class HaManualAutomationEditor extends ReorderModeMixin(LitElement) {
|
||||||
)}
|
)}
|
||||||
</p>`
|
</p>`
|
||||||
: nothing}
|
: nothing}
|
||||||
${this._renderReorderModeAlert("triggers")}
|
|
||||||
|
|
||||||
<ha-automation-trigger
|
<ha-automation-trigger
|
||||||
role="region"
|
role="region"
|
||||||
|
@ -137,7 +135,6 @@ export class HaManualAutomationEditor extends ReorderModeMixin(LitElement) {
|
||||||
)}
|
)}
|
||||||
</p>`
|
</p>`
|
||||||
: nothing}
|
: nothing}
|
||||||
${this._renderReorderModeAlert("conditions")}
|
|
||||||
|
|
||||||
<ha-automation-condition
|
<ha-automation-condition
|
||||||
role="region"
|
role="region"
|
||||||
|
@ -178,7 +175,6 @@ export class HaManualAutomationEditor extends ReorderModeMixin(LitElement) {
|
||||||
)}
|
)}
|
||||||
</p>`
|
</p>`
|
||||||
: nothing}
|
: nothing}
|
||||||
${this._renderReorderModeAlert("actions")}
|
|
||||||
|
|
||||||
<ha-automation-action
|
<ha-automation-action
|
||||||
role="region"
|
role="region"
|
||||||
|
@ -194,34 +190,6 @@ export class HaManualAutomationEditor extends ReorderModeMixin(LitElement) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderReorderModeAlert(type: "conditions" | "actions" | "triggers") {
|
|
||||||
if (!this._reorderMode.active) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
<ha-alert
|
|
||||||
class="re-order"
|
|
||||||
alert-type="info"
|
|
||||||
.title=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.title"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
`ui.panel.config.automation.editor.re_order_mode.description_${type}`
|
|
||||||
)}
|
|
||||||
<ha-button slot="action" @click=${this._exitReOrderMode}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.exit"
|
|
||||||
)}
|
|
||||||
</ha-button>
|
|
||||||
</ha-alert>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _exitReOrderMode() {
|
|
||||||
this._reorderMode.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _triggerChanged(ev: CustomEvent): void {
|
private _triggerChanged(ev: CustomEvent): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { consume } from "@lit-labs/context";
|
||||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import {
|
import {
|
||||||
|
mdiArrowDown,
|
||||||
|
mdiArrowUp,
|
||||||
mdiCheck,
|
mdiCheck,
|
||||||
mdiContentCopy,
|
mdiContentCopy,
|
||||||
mdiContentCut,
|
mdiContentCut,
|
||||||
|
@ -11,7 +13,6 @@ import {
|
||||||
mdiIdentifier,
|
mdiIdentifier,
|
||||||
mdiPlayCircleOutline,
|
mdiPlayCircleOutline,
|
||||||
mdiRenameBox,
|
mdiRenameBox,
|
||||||
mdiSort,
|
|
||||||
mdiStopCircleOutline,
|
mdiStopCircleOutline,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
|
@ -53,6 +54,7 @@ import {
|
||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant, ItemPath } from "../../../../types";
|
import type { HomeAssistant, ItemPath } from "../../../../types";
|
||||||
import "./types/ha-automation-trigger-calendar";
|
import "./types/ha-automation-trigger-calendar";
|
||||||
|
import "./types/ha-automation-trigger-conversation";
|
||||||
import "./types/ha-automation-trigger-device";
|
import "./types/ha-automation-trigger-device";
|
||||||
import "./types/ha-automation-trigger-event";
|
import "./types/ha-automation-trigger-event";
|
||||||
import "./types/ha-automation-trigger-geo_location";
|
import "./types/ha-automation-trigger-geo_location";
|
||||||
|
@ -60,7 +62,6 @@ import "./types/ha-automation-trigger-homeassistant";
|
||||||
import "./types/ha-automation-trigger-mqtt";
|
import "./types/ha-automation-trigger-mqtt";
|
||||||
import "./types/ha-automation-trigger-numeric_state";
|
import "./types/ha-automation-trigger-numeric_state";
|
||||||
import "./types/ha-automation-trigger-persistent_notification";
|
import "./types/ha-automation-trigger-persistent_notification";
|
||||||
import "./types/ha-automation-trigger-conversation";
|
|
||||||
import "./types/ha-automation-trigger-state";
|
import "./types/ha-automation-trigger-state";
|
||||||
import "./types/ha-automation-trigger-sun";
|
import "./types/ha-automation-trigger-sun";
|
||||||
import "./types/ha-automation-trigger-tag";
|
import "./types/ha-automation-trigger-tag";
|
||||||
|
@ -69,10 +70,6 @@ import "./types/ha-automation-trigger-time";
|
||||||
import "./types/ha-automation-trigger-time_pattern";
|
import "./types/ha-automation-trigger-time_pattern";
|
||||||
import "./types/ha-automation-trigger-webhook";
|
import "./types/ha-automation-trigger-webhook";
|
||||||
import "./types/ha-automation-trigger-zone";
|
import "./types/ha-automation-trigger-zone";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../state/reorder-mode-mixin";
|
|
||||||
|
|
||||||
export interface TriggerElement extends LitElement {
|
export interface TriggerElement extends LitElement {
|
||||||
trigger: Trigger;
|
trigger: Trigger;
|
||||||
|
@ -108,12 +105,14 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||||
|
|
||||||
@property({ attribute: false }) public trigger!: Trigger;
|
@property({ attribute: false }) public trigger!: Trigger;
|
||||||
|
|
||||||
@property({ type: Boolean }) public hideMenu = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@property({ type: Array }) public path?: ItemPath;
|
@property({ type: Array }) public path?: ItemPath;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public first?: boolean;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public last?: boolean;
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@state() private _yamlMode = false;
|
@state() private _yamlMode = false;
|
||||||
|
@ -138,17 +137,11 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
@state()
|
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
private _triggerUnsub?: Promise<UnsubscribeFunc>;
|
private _triggerUnsub?: Promise<UnsubscribeFunc>;
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.trigger) return nothing;
|
if (!this.trigger) return nothing;
|
||||||
|
|
||||||
const noReorderModeAvailable = this._reorderMode === undefined;
|
|
||||||
|
|
||||||
const supported =
|
const supported =
|
||||||
customElements.get(`ha-automation-trigger-${this.trigger.platform}`) !==
|
customElements.get(`ha-automation-trigger-${this.trigger.platform}`) !==
|
||||||
undefined;
|
undefined;
|
||||||
|
@ -165,7 +158,7 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
|
|
||||||
<ha-expansion-panel leftChevron>
|
<ha-expansion-panel leftChevron>
|
||||||
<h3 slot="header">
|
<h3 slot="header">
|
||||||
|
@ -177,145 +170,136 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<slot name="icons" slot="icons"></slot>
|
<slot name="icons" slot="icons"></slot>
|
||||||
${this.hideMenu
|
|
||||||
? ""
|
|
||||||
: html`
|
|
||||||
<ha-button-menu
|
|
||||||
slot="icons"
|
|
||||||
@action=${this._handleAction}
|
|
||||||
@click=${preventDefault}
|
|
||||||
fixed
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
slot="trigger"
|
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
|
||||||
.path=${mdiDotsVertical}
|
|
||||||
></ha-icon-button>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<ha-button-menu
|
||||||
${this.hass.localize(
|
slot="icons"
|
||||||
"ui.panel.config.automation.editor.triggers.rename"
|
@action=${this._handleAction}
|
||||||
)}
|
@click=${preventDefault}
|
||||||
<ha-svg-icon
|
fixed
|
||||||
slot="graphic"
|
>
|
||||||
.path=${mdiRenameBox}
|
<ha-icon-button
|
||||||
></ha-svg-icon>
|
slot="trigger"
|
||||||
</mwc-list-item>
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
|
.path=${mdiDotsVertical}
|
||||||
|
></ha-icon-button>
|
||||||
|
|
||||||
<mwc-list-item
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
graphic="icon"
|
${this.hass.localize(
|
||||||
.disabled=${this.disabled}
|
"ui.panel.config.automation.editor.triggers.rename"
|
||||||
class=${classMap({ hidden: noReorderModeAvailable })}
|
)}
|
||||||
>
|
<ha-svg-icon slot="graphic" .path=${mdiRenameBox}></ha-svg-icon>
|
||||||
${this.hass.localize(
|
</mwc-list-item>
|
||||||
"ui.panel.config.automation.editor.triggers.re_order"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiSort}></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.edit_id"
|
"ui.panel.config.automation.editor.triggers.edit_id"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon slot="graphic" .path=${mdiIdentifier}></ha-svg-icon>
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${mdiIdentifier}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<li divider role="separator"></li>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.duplicate"
|
"ui.panel.config.automation.editor.triggers.duplicate"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
slot="graphic"
|
slot="graphic"
|
||||||
.path=${mdiContentDuplicate}
|
.path=${mdiContentDuplicate}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.copy"
|
"ui.panel.config.automation.editor.triggers.copy"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon slot="graphic" .path=${mdiContentCopy}></ha-svg-icon>
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${mdiContentCopy}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.cut"
|
"ui.panel.config.automation.editor.triggers.cut"
|
||||||
)}
|
)}
|
||||||
<ha-svg-icon
|
<ha-svg-icon slot="graphic" .path=${mdiContentCut}></ha-svg-icon>
|
||||||
slot="graphic"
|
</mwc-list-item>
|
||||||
.path=${mdiContentCut}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<mwc-list-item
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled || this.first}
|
||||||
|
>
|
||||||
|
${this.hass.localize("ui.panel.config.automation.editor.move_up")}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiArrowUp}></ha-svg-icon
|
||||||
|
></mwc-list-item>
|
||||||
|
|
||||||
<mwc-list-item .disabled=${!supported} graphic="icon">
|
<mwc-list-item
|
||||||
${this.hass.localize(
|
graphic="icon"
|
||||||
"ui.panel.config.automation.editor.edit_ui"
|
.disabled=${this.disabled || this.last}
|
||||||
)}
|
>
|
||||||
${!yamlMode
|
${this.hass.localize(
|
||||||
? html`<ha-svg-icon
|
"ui.panel.config.automation.editor.move_down"
|
||||||
class="selected_menu_item"
|
)}
|
||||||
slot="graphic"
|
<ha-svg-icon slot="graphic" .path=${mdiArrowDown}></ha-svg-icon
|
||||||
.path=${mdiCheck}
|
></mwc-list-item>
|
||||||
></ha-svg-icon>`
|
|
||||||
: ``}
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<mwc-list-item .disabled=${!supported} graphic="icon">
|
<li divider role="separator"></li>
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.edit_yaml"
|
|
||||||
)}
|
|
||||||
${yamlMode
|
|
||||||
? html`<ha-svg-icon
|
|
||||||
class="selected_menu_item"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiCheck}
|
|
||||||
></ha-svg-icon>`
|
|
||||||
: ``}
|
|
||||||
</mwc-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
<mwc-list-item .disabled=${!supported} graphic="icon">
|
||||||
|
${this.hass.localize("ui.panel.config.automation.editor.edit_ui")}
|
||||||
|
${!yamlMode
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
class="selected_menu_item"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiCheck}
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: ``}
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
|
<mwc-list-item .disabled=${!supported} graphic="icon">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
|
)}
|
||||||
|
${yamlMode
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
class="selected_menu_item"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiCheck}
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: ``}
|
||||||
|
</mwc-list-item>
|
||||||
|
|
||||||
|
<li divider role="separator"></li>
|
||||||
|
|
||||||
|
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
||||||
|
${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
|
||||||
|
slot="graphic"
|
||||||
|
.path=${this.trigger.enabled === false
|
||||||
|
? mdiPlayCircleOutline
|
||||||
|
: mdiStopCircleOutline}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
<mwc-list-item
|
||||||
|
class="warning"
|
||||||
|
graphic="icon"
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.delete"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon
|
||||||
|
class="warning"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</mwc-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
|
||||||
<mwc-list-item graphic="icon" .disabled=${this.disabled}>
|
|
||||||
${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
|
|
||||||
slot="graphic"
|
|
||||||
.path=${this.trigger.enabled === false
|
|
||||||
? mdiPlayCircleOutline
|
|
||||||
: mdiStopCircleOutline}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
<mwc-list-item
|
|
||||||
class="warning"
|
|
||||||
graphic="icon"
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.actions.delete"
|
|
||||||
)}
|
|
||||||
<ha-svg-icon
|
|
||||||
class="warning"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiDelete}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-list-item>
|
|
||||||
</ha-button-menu>
|
|
||||||
`}
|
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
"card-content": true,
|
"card-content": true,
|
||||||
|
@ -496,34 +480,37 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||||
await this._renameTrigger();
|
await this._renameTrigger();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this._reorderMode?.enter();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this._requestShowId = true;
|
this._requestShowId = true;
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 2:
|
||||||
fireEvent(this, "duplicate");
|
fireEvent(this, "duplicate");
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
this._setClipboard();
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
this._setClipboard();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
this._setClipboard();
|
this._setClipboard();
|
||||||
fireEvent(this, "value-changed", { value: null });
|
fireEvent(this, "value-changed", { value: null });
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
fireEvent(this, "move-up");
|
||||||
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
fireEvent(this, "move-down");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
this._switchUiMode();
|
this._switchUiMode();
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 8:
|
||||||
this._switchYamlMode();
|
this._switchYamlMode();
|
||||||
this.expand();
|
this.expand();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 9:
|
||||||
this._onDisable();
|
this._onDisable();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 10:
|
||||||
this._onDelete();
|
this._onDelete();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
import { consume } from "@lit-labs/context";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import { mdiArrowDown, mdiArrowUp, mdiDrag, mdiPlus } from "@mdi/js";
|
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
|
import {
|
||||||
|
CSSResultGroup,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nestedArrayMove } from "../../../../common/util/array-move";
|
import { nestedArrayMove } from "../../../../common/util/array-move";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
import "../../../../components/ha-sortable";
|
import "../../../../components/ha-sortable";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import { AutomationClipboard, Trigger } from "../../../../data/automation";
|
import { AutomationClipboard, Trigger } from "../../../../data/automation";
|
||||||
import {
|
|
||||||
ReorderMode,
|
|
||||||
reorderModeContext,
|
|
||||||
} from "../../../../state/reorder-mode-mixin";
|
|
||||||
import { HomeAssistant, ItemPath } from "../../../../types";
|
import { HomeAssistant, ItemPath } from "../../../../types";
|
||||||
import {
|
import {
|
||||||
PASTE_VALUE,
|
PASTE_VALUE,
|
||||||
|
@ -34,9 +37,7 @@ export default class HaAutomationTrigger extends LitElement {
|
||||||
|
|
||||||
@property({ type: Array }) public path?: ItemPath;
|
@property({ type: Array }) public path?: ItemPath;
|
||||||
|
|
||||||
@state()
|
@state() private _showReorder: boolean = false;
|
||||||
@consume({ context: reorderModeContext, subscribe: true })
|
|
||||||
private _reorderMode?: ReorderMode;
|
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "automationClipboard",
|
key: "automationClipboard",
|
||||||
|
@ -50,6 +51,21 @@ export default class HaAutomationTrigger extends LitElement {
|
||||||
|
|
||||||
private _triggerKeys = new WeakMap<Trigger, string>();
|
private _triggerKeys = new WeakMap<Trigger, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private get nested() {
|
private get nested() {
|
||||||
return this.path !== undefined;
|
return this.path !== undefined;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +74,7 @@ export default class HaAutomationTrigger extends LitElement {
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
.disabled=${!this._reorderMode?.active}
|
.disabled=${!this._showReorder}
|
||||||
@item-moved=${this._triggerMoved}
|
@item-moved=${this._triggerMoved}
|
||||||
group="triggers"
|
group="triggers"
|
||||||
.path=${this.path}
|
.path=${this.path}
|
||||||
|
@ -71,40 +87,23 @@ export default class HaAutomationTrigger extends LitElement {
|
||||||
<ha-automation-trigger-row
|
<ha-automation-trigger-row
|
||||||
.path=${[...(this.path ?? []), idx]}
|
.path=${[...(this.path ?? []), idx]}
|
||||||
.index=${idx}
|
.index=${idx}
|
||||||
|
.first=${idx === 0}
|
||||||
|
.last=${idx === this.triggers.length - 1}
|
||||||
.trigger=${trg}
|
.trigger=${trg}
|
||||||
.hideMenu=${Boolean(this._reorderMode?.active)}
|
|
||||||
@duplicate=${this._duplicateTrigger}
|
@duplicate=${this._duplicateTrigger}
|
||||||
|
@move-down=${this._moveDown}
|
||||||
|
@move-up=${this._moveUp}
|
||||||
@value-changed=${this._triggerChanged}
|
@value-changed=${this._triggerChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
>
|
>
|
||||||
${this._reorderMode?.active
|
${this._showReorder
|
||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_up"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowUp}
|
|
||||||
@click=${this._moveUp}
|
|
||||||
.disabled=${idx === 0}
|
|
||||||
></ha-icon-button>
|
|
||||||
<ha-icon-button
|
|
||||||
.index=${idx}
|
|
||||||
slot="icons"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.move_down"
|
|
||||||
)}
|
|
||||||
.path=${mdiArrowDown}
|
|
||||||
@click=${this._moveDown}
|
|
||||||
.disabled=${idx === this.triggers.length - 1}
|
|
||||||
></ha-icon-button>
|
|
||||||
<div class="handle" slot="icons">
|
<div class="handle" slot="icons">
|
||||||
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</ha-automation-trigger-row>
|
</ha-automation-trigger-row>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
@ -256,7 +255,7 @@ export default class HaAutomationTrigger extends LitElement {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.handle {
|
.handle {
|
||||||
padding: 12px;
|
padding: 12px 4px;
|
||||||
cursor: move; /* fallback if grab cursor is unsupported */
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { nestedArrayMove } from "../../../common/util/array-move";
|
import { nestedArrayMove } from "../../../common/util/array-move";
|
||||||
|
@ -18,10 +18,9 @@ import { BlueprintScriptConfig } from "../../../data/script";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
import "../ha-config-section";
|
||||||
import { ReorderModeMixin } from "../../../state/reorder-mode-mixin";
|
|
||||||
|
|
||||||
@customElement("blueprint-script-editor")
|
@customElement("blueprint-script-editor")
|
||||||
export class HaBlueprintScriptEditor extends ReorderModeMixin(LitElement) {
|
export class HaBlueprintScriptEditor extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ type: Boolean }) public isWide = false;
|
@property({ type: Boolean }) public isWide = false;
|
||||||
|
@ -57,7 +56,6 @@ export class HaBlueprintScriptEditor extends ReorderModeMixin(LitElement) {
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
</ha-alert>`
|
</ha-alert>`
|
||||||
: ""}
|
: ""}
|
||||||
${this._renderReorderModeAlert()}
|
|
||||||
<ha-card
|
<ha-card
|
||||||
outlined
|
outlined
|
||||||
class="blueprint"
|
class="blueprint"
|
||||||
|
@ -151,34 +149,6 @@ export class HaBlueprintScriptEditor extends ReorderModeMixin(LitElement) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderReorderModeAlert() {
|
|
||||||
if (!this._reorderMode.active) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
<ha-alert
|
|
||||||
class="re-order"
|
|
||||||
alert-type="info"
|
|
||||||
.title=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.title"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.description_all"
|
|
||||||
)}
|
|
||||||
<ha-button slot="action" @click=${this._exitReOrderMode}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.exit"
|
|
||||||
)}
|
|
||||||
</ha-button>
|
|
||||||
</ha-alert>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _exitReOrderMode() {
|
|
||||||
this._reorderMode.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _getBlueprints() {
|
private async _getBlueprints() {
|
||||||
this._blueprints = await fetchBlueprints(this.hass, "script");
|
this._blueprints = await fetchBlueprints(this.hass, "script");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import { Action, Fields, ScriptConfig } from "../../../data/script";
|
import { Action, Fields, ScriptConfig } from "../../../data/script";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { ReorderModeMixin } from "../../../state/reorder-mode-mixin";
|
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import { documentationUrl } from "../../../util/documentation-url";
|
import { documentationUrl } from "../../../util/documentation-url";
|
||||||
import "../automation/action/ha-automation-action";
|
import "../automation/action/ha-automation-action";
|
||||||
|
@ -16,7 +15,7 @@ import "./ha-script-fields";
|
||||||
import type HaScriptFields from "./ha-script-fields";
|
import type HaScriptFields from "./ha-script-fields";
|
||||||
|
|
||||||
@customElement("manual-script-editor")
|
@customElement("manual-script-editor")
|
||||||
export class HaManualScriptEditor extends ReorderModeMixin(LitElement) {
|
export class HaManualScriptEditor extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ type: Boolean }) public isWide = false;
|
@property({ type: Boolean }) public isWide = false;
|
||||||
|
@ -120,8 +119,6 @@ export class HaManualScriptEditor extends ReorderModeMixin(LitElement) {
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${this._renderReorderModeAlert()}
|
|
||||||
|
|
||||||
<ha-automation-action
|
<ha-automation-action
|
||||||
role="region"
|
role="region"
|
||||||
aria-labelledby="sequence-heading"
|
aria-labelledby="sequence-heading"
|
||||||
|
@ -136,34 +133,6 @@ export class HaManualScriptEditor extends ReorderModeMixin(LitElement) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderReorderModeAlert() {
|
|
||||||
if (!this._reorderMode.active) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
<ha-alert
|
|
||||||
class="re-order"
|
|
||||||
alert-type="info"
|
|
||||||
.title=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.title"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.description_all"
|
|
||||||
)}
|
|
||||||
<ha-button slot="action" @click=${this._exitReOrderMode}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.re_order_mode.exit"
|
|
||||||
)}
|
|
||||||
</ha-button>
|
|
||||||
</ha-alert>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _exitReOrderMode() {
|
|
||||||
this._reorderMode.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _fieldsChanged(ev: CustomEvent): void {
|
private _fieldsChanged(ev: CustomEvent): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
import { ContextProvider, createContext } from "@lit-labs/context";
|
|
||||||
import { LitElement } from "lit";
|
|
||||||
import { Constructor } from "../types";
|
|
||||||
|
|
||||||
export type ReorderMode = {
|
|
||||||
active: boolean;
|
|
||||||
enter: () => void;
|
|
||||||
exit: () => void;
|
|
||||||
};
|
|
||||||
export const reorderModeContext = createContext<ReorderMode>("reorder-mode");
|
|
||||||
|
|
||||||
export const ReorderModeMixin = <T extends Constructor<LitElement>>(
|
|
||||||
superClass: T
|
|
||||||
) =>
|
|
||||||
class extends superClass {
|
|
||||||
private _reorderModeProvider = new ContextProvider(this, {
|
|
||||||
context: reorderModeContext,
|
|
||||||
initialValue: {
|
|
||||||
active: false,
|
|
||||||
enter: () => {
|
|
||||||
this._reorderModeProvider.setValue({
|
|
||||||
...this._reorderModeProvider.value,
|
|
||||||
active: true,
|
|
||||||
});
|
|
||||||
this.requestUpdate("_reorderMode");
|
|
||||||
},
|
|
||||||
exit: () => {
|
|
||||||
this._reorderModeProvider.setValue({
|
|
||||||
...this._reorderModeProvider.value,
|
|
||||||
active: false,
|
|
||||||
});
|
|
||||||
this.requestUpdate("_reorderMode");
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
get _reorderMode() {
|
|
||||||
return this._reorderModeProvider.value;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -2446,15 +2446,6 @@
|
||||||
"automation_settings": "Automation settings",
|
"automation_settings": "Automation settings",
|
||||||
"move_up": "Move up",
|
"move_up": "Move up",
|
||||||
"move_down": "Move down",
|
"move_down": "Move down",
|
||||||
"re_order": "Re-order",
|
|
||||||
"re_order_mode": {
|
|
||||||
"title": "Re-order mode",
|
|
||||||
"description_triggers": "You are in re-order mode, you can re-order your triggers.",
|
|
||||||
"description_conditions": "You are in re-order mode, you can re-order your conditions.",
|
|
||||||
"description_actions": "You are in re-order mode, you can re-order your actions.",
|
|
||||||
"description_all": "You are in re-order mode, you can re-order your triggers, conditions and actions.",
|
|
||||||
"exit": "Exit"
|
|
||||||
},
|
|
||||||
"description": {
|
"description": {
|
||||||
"label": "Description",
|
"label": "Description",
|
||||||
"placeholder": "Optional description",
|
"placeholder": "Optional description",
|
||||||
|
|
Loading…
Reference in New Issue