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