mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-18 07:56:44 +01:00
920 lines
27 KiB
TypeScript
920 lines
27 KiB
TypeScript
import "@home-assistant/webawesome/dist/components/divider/divider";
|
|
import { consume } from "@lit/context";
|
|
import {
|
|
mdiAppleKeyboardCommand,
|
|
mdiArrowDown,
|
|
mdiArrowUp,
|
|
mdiContentCopy,
|
|
mdiContentCut,
|
|
mdiDelete,
|
|
mdiDotsVertical,
|
|
mdiFlask,
|
|
mdiPlayCircleOutline,
|
|
mdiPlaylistEdit,
|
|
mdiPlusCircleMultipleOutline,
|
|
mdiRenameBox,
|
|
mdiStopCircleOutline,
|
|
} from "@mdi/js";
|
|
import deepClone from "deep-clone-simple";
|
|
import type { HassServiceTarget } from "home-assistant-js-websocket";
|
|
import { dump } from "js-yaml";
|
|
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
|
import { LitElement, css, html, nothing } from "lit";
|
|
import { customElement, property, query, state } from "lit/decorators";
|
|
import { classMap } from "lit/directives/class-map";
|
|
import memoizeOne from "memoize-one";
|
|
import { ensureArray } from "../../../../common/array/ensure-array";
|
|
import { storage } from "../../../../common/decorators/storage";
|
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
|
import { preventDefaultStopPropagation } from "../../../../common/dom/prevent_default_stop_propagation";
|
|
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
|
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
|
|
import { handleStructError } from "../../../../common/structs/handle-errors";
|
|
import { copyToClipboard } from "../../../../common/util/copy-clipboard";
|
|
import "../../../../components/ha-automation-row";
|
|
import type { HaAutomationRow } from "../../../../components/ha-automation-row";
|
|
import "../../../../components/ha-card";
|
|
import "../../../../components/ha-condition-icon";
|
|
import "../../../../components/ha-dropdown";
|
|
import "../../../../components/ha-dropdown-item";
|
|
import "../../../../components/ha-expansion-panel";
|
|
import "../../../../components/ha-icon-button";
|
|
import type {
|
|
AutomationClipboard,
|
|
Condition,
|
|
ConditionSidebarConfig,
|
|
PlatformCondition,
|
|
} from "../../../../data/automation";
|
|
import { isCondition, testCondition } from "../../../../data/automation";
|
|
import { describeCondition } from "../../../../data/automation_i18n";
|
|
import type { ConditionDescriptions } from "../../../../data/condition";
|
|
import { CONDITION_BUILDING_BLOCKS } from "../../../../data/condition";
|
|
import { validateConfig } from "../../../../data/config";
|
|
import { fullEntitiesContext } from "../../../../data/context";
|
|
import type { DeviceCondition } from "../../../../data/device/device_automation";
|
|
import type { EntityRegistryEntry } from "../../../../data/entity/entity_registry";
|
|
import {
|
|
showAlertDialog,
|
|
showPromptDialog,
|
|
} from "../../../../dialogs/generic/show-dialog-box";
|
|
import type { HomeAssistant } from "../../../../types";
|
|
import { isMac } from "../../../../util/is_mac";
|
|
import { showToast } from "../../../../util/toast";
|
|
import "../ha-automation-editor-warning";
|
|
import { overflowStyles, rowStyles } from "../styles";
|
|
import "../target/ha-automation-row-targets";
|
|
import "./ha-automation-condition-editor";
|
|
import type HaAutomationConditionEditor from "./ha-automation-condition-editor";
|
|
import "./types/ha-automation-condition-and";
|
|
import "./types/ha-automation-condition-device";
|
|
import "./types/ha-automation-condition-not";
|
|
import "./types/ha-automation-condition-numeric_state";
|
|
import "./types/ha-automation-condition-or";
|
|
import "./types/ha-automation-condition-state";
|
|
import "./types/ha-automation-condition-sun";
|
|
import "./types/ha-automation-condition-template";
|
|
import "./types/ha-automation-condition-time";
|
|
import "./types/ha-automation-condition-trigger";
|
|
import "./types/ha-automation-condition-zone";
|
|
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
|
|
|
export interface ConditionElement extends LitElement {
|
|
condition: Condition;
|
|
expandAll?: () => void;
|
|
collapseAll?: () => void;
|
|
}
|
|
|
|
@customElement("ha-automation-condition-row")
|
|
export default class HaAutomationConditionRow extends LitElement {
|
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
|
|
@property({ attribute: false }) public condition!: Condition;
|
|
|
|
@property({ type: Boolean }) public disabled = false;
|
|
|
|
@property({ type: Boolean }) public root = false;
|
|
|
|
@property({ type: Boolean }) public first?: boolean;
|
|
|
|
@property({ type: Boolean }) public last?: boolean;
|
|
|
|
@property({ type: Boolean }) public narrow = false;
|
|
|
|
@property({ type: Boolean }) public highlight?: boolean;
|
|
|
|
@property({ type: Boolean, attribute: "sort-selected" })
|
|
public sortSelected = false;
|
|
|
|
@state() private _collapsed = true;
|
|
|
|
@state() private _isNew = false;
|
|
|
|
@state() private _warnings?: string[];
|
|
|
|
@property({ attribute: false })
|
|
public conditionDescriptions: ConditionDescriptions = {};
|
|
|
|
@property({ type: Boolean, attribute: "sidebar" })
|
|
public optionsInSidebar = false;
|
|
|
|
@storage({
|
|
key: "automationClipboard",
|
|
state: false,
|
|
subscribe: true,
|
|
storage: "sessionStorage",
|
|
})
|
|
public _clipboard?: AutomationClipboard;
|
|
|
|
@state() private _yamlMode = false;
|
|
|
|
@state() private _testing = false;
|
|
|
|
@state() private _testingResult?: boolean;
|
|
|
|
@state() private _selected = false;
|
|
|
|
@state()
|
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
|
_entityReg: EntityRegistryEntry[] = [];
|
|
|
|
@query("ha-automation-condition-editor")
|
|
public conditionEditor?: HaAutomationConditionEditor;
|
|
|
|
@query("ha-automation-row")
|
|
private _automationRowElement?: HaAutomationRow;
|
|
|
|
get selected() {
|
|
return this._selected;
|
|
}
|
|
|
|
private _renderOverflowLabel(label: string, shortcut?: TemplateResult) {
|
|
return html`
|
|
<div class="overflow-label">
|
|
${label}
|
|
${this.optionsInSidebar && !this.narrow
|
|
? shortcut ||
|
|
html`<span
|
|
class="shortcut-placeholder ${isMac ? "mac" : ""}"
|
|
></span>`
|
|
: nothing}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
private _renderRow() {
|
|
const descriptionHasTarget =
|
|
"target" in (this.conditionDescriptions[this.condition.condition] || {});
|
|
|
|
const target = descriptionHasTarget
|
|
? (this.condition as PlatformCondition).target
|
|
: "device_id" in this.condition &&
|
|
(this.condition as DeviceCondition).device_id
|
|
? { device_id: [(this.condition as DeviceCondition).device_id] }
|
|
: undefined;
|
|
|
|
return html`
|
|
<ha-condition-icon
|
|
slot="leading-icon"
|
|
.hass=${this.hass}
|
|
.condition=${this.condition.condition}
|
|
></ha-condition-icon>
|
|
<h3 slot="header">
|
|
${capitalizeFirstLetter(
|
|
describeCondition(this.condition, this.hass, this._entityReg)
|
|
)}
|
|
${target !== undefined || (descriptionHasTarget && !this._isNew)
|
|
? this._renderTargets(target, descriptionHasTarget && !this._isNew)
|
|
: nothing}
|
|
</h3>
|
|
|
|
<slot name="icons" slot="icons"></slot>
|
|
|
|
<ha-dropdown
|
|
slot="icons"
|
|
@click=${preventDefaultStopPropagation}
|
|
@keydown=${stopPropagation}
|
|
@wa-select=${this._handleDropdownSelect}
|
|
placement="bottom-end"
|
|
>
|
|
<ha-icon-button
|
|
slot="trigger"
|
|
.label=${this.hass.localize("ui.common.menu")}
|
|
.path=${mdiDotsVertical}
|
|
>
|
|
</ha-icon-button>
|
|
|
|
<ha-dropdown-item value="test">
|
|
<ha-svg-icon slot="icon" .path=${mdiFlask}></ha-svg-icon>
|
|
${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.test"
|
|
)
|
|
)}
|
|
</ha-dropdown-item>
|
|
<ha-dropdown-item value="rename" .disabled=${this.disabled}>
|
|
<ha-svg-icon slot="icon" .path=${mdiRenameBox}></ha-svg-icon>
|
|
${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.rename"
|
|
)
|
|
)}
|
|
</ha-dropdown-item>
|
|
|
|
<wa-divider></wa-divider>
|
|
|
|
<ha-dropdown-item value="duplicate" .disabled=${this.disabled}>
|
|
<ha-svg-icon
|
|
slot="icon"
|
|
.path=${mdiPlusCircleMultipleOutline}
|
|
></ha-svg-icon>
|
|
${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
"ui.panel.config.automation.editor.actions.duplicate"
|
|
)
|
|
)}
|
|
</ha-dropdown-item>
|
|
|
|
<ha-dropdown-item value="copy" .disabled=${this.disabled}>
|
|
<ha-svg-icon slot="icon" .path=${mdiContentCopy}></ha-svg-icon
|
|
>${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
"ui.panel.config.automation.editor.triggers.copy"
|
|
),
|
|
html`<span class="shortcut">
|
|
<span
|
|
>${isMac
|
|
? html`<ha-svg-icon
|
|
.path=${mdiAppleKeyboardCommand}
|
|
></ha-svg-icon>`
|
|
: this.hass.localize(
|
|
"ui.panel.config.automation.editor.ctrl"
|
|
)}</span
|
|
>
|
|
<span>+</span>
|
|
<span>C</span>
|
|
</span>`
|
|
)}
|
|
</ha-dropdown-item>
|
|
|
|
<ha-dropdown-item value="cut" .disabled=${this.disabled}>
|
|
<ha-svg-icon slot="icon" .path=${mdiContentCut}></ha-svg-icon
|
|
>${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
"ui.panel.config.automation.editor.triggers.cut"
|
|
),
|
|
html`<span class="shortcut">
|
|
<span
|
|
>${isMac
|
|
? html`<ha-svg-icon
|
|
.path=${mdiAppleKeyboardCommand}
|
|
></ha-svg-icon>`
|
|
: this.hass.localize(
|
|
"ui.panel.config.automation.editor.ctrl"
|
|
)}</span
|
|
>
|
|
<span>+</span>
|
|
<span>X</span>
|
|
</span>`
|
|
)}
|
|
</ha-dropdown-item>
|
|
|
|
${!this.optionsInSidebar
|
|
? html`
|
|
<ha-dropdown-item
|
|
value="move_up"
|
|
.disabled=${this.disabled || !!this.first}
|
|
>
|
|
${this.hass.localize(
|
|
"ui.panel.config.automation.editor.move_up"
|
|
)}
|
|
<ha-svg-icon slot="icon" .path=${mdiArrowUp}></ha-svg-icon
|
|
></ha-dropdown-item>
|
|
<ha-dropdown-item
|
|
value="move_down"
|
|
.disabled=${this.disabled || !!this.last}
|
|
>
|
|
${this.hass.localize(
|
|
"ui.panel.config.automation.editor.move_down"
|
|
)}
|
|
<ha-svg-icon slot="icon" .path=${mdiArrowDown}></ha-svg-icon
|
|
></ha-dropdown-item>
|
|
`
|
|
: nothing}
|
|
|
|
<ha-dropdown-item value="toggle_yaml_mode">
|
|
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
|
|
${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
`ui.panel.config.automation.editor.edit_${!this._yamlMode ? "yaml" : "ui"}`
|
|
)
|
|
)}
|
|
</ha-dropdown-item>
|
|
|
|
<wa-divider></wa-divider>
|
|
|
|
<ha-dropdown-item value="disable" .disabled=${this.disabled}>
|
|
<ha-svg-icon
|
|
slot="icon"
|
|
.path=${this.condition.enabled === false
|
|
? mdiPlayCircleOutline
|
|
: mdiStopCircleOutline}
|
|
></ha-svg-icon>
|
|
|
|
${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
`ui.panel.config.automation.editor.actions.${this.condition.enabled === false ? "enable" : "disable"}`
|
|
)
|
|
)}
|
|
</ha-dropdown-item>
|
|
<ha-dropdown-item
|
|
variant="danger"
|
|
value="delete"
|
|
.disabled=${this.disabled}
|
|
>
|
|
<ha-svg-icon
|
|
class="warning"
|
|
slot="icon"
|
|
.path=${mdiDelete}
|
|
></ha-svg-icon>
|
|
${this._renderOverflowLabel(
|
|
this.hass.localize(
|
|
"ui.panel.config.automation.editor.actions.delete"
|
|
),
|
|
html`<span class="shortcut">
|
|
<span
|
|
>${isMac
|
|
? html`<ha-svg-icon
|
|
.path=${mdiAppleKeyboardCommand}
|
|
></ha-svg-icon>`
|
|
: this.hass.localize(
|
|
"ui.panel.config.automation.editor.ctrl"
|
|
)}</span
|
|
>
|
|
<span>+</span>
|
|
<span
|
|
>${this.hass.localize(
|
|
"ui.panel.config.automation.editor.del"
|
|
)}</span
|
|
>
|
|
</span>`
|
|
)}
|
|
</ha-dropdown-item>
|
|
</ha-dropdown>
|
|
${!this.optionsInSidebar
|
|
? html`${this._warnings
|
|
? html`<ha-automation-editor-warning
|
|
.localize=${this.hass.localize}
|
|
.warnings=${this._warnings}
|
|
>
|
|
</ha-automation-editor-warning>`
|
|
: nothing}
|
|
<ha-automation-condition-editor
|
|
.hass=${this.hass}
|
|
.condition=${this.condition}
|
|
.description=${this.conditionDescriptions[
|
|
this.condition.condition
|
|
]}
|
|
.disabled=${this.disabled}
|
|
.yamlMode=${this._yamlMode}
|
|
.uiSupported=${this._uiSupported(
|
|
this._getType(this.condition, this.conditionDescriptions)
|
|
)}
|
|
.narrow=${this.narrow}
|
|
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
|
></ha-automation-condition-editor>`
|
|
: nothing}
|
|
`;
|
|
}
|
|
|
|
protected render() {
|
|
if (!this.condition) {
|
|
return nothing;
|
|
}
|
|
|
|
return html`
|
|
<ha-card
|
|
outlined
|
|
class=${classMap({
|
|
selected: this._selected,
|
|
"building-block":
|
|
this.optionsInSidebar &&
|
|
CONDITION_BUILDING_BLOCKS.includes(this.condition.condition) &&
|
|
!this._collapsed,
|
|
})}
|
|
>
|
|
${this.condition.enabled === false
|
|
? html`
|
|
<div class="disabled-bar">
|
|
${this.hass.localize(
|
|
"ui.panel.config.automation.editor.actions.disabled"
|
|
)}
|
|
</div>
|
|
`
|
|
: nothing}
|
|
${this.optionsInSidebar
|
|
? html`<ha-automation-row
|
|
.disabled=${this.condition.enabled === false}
|
|
.leftChevron=${CONDITION_BUILDING_BLOCKS.includes(
|
|
this.condition.condition
|
|
)}
|
|
.collapsed=${this._collapsed}
|
|
.selected=${this._selected}
|
|
.highlight=${this.highlight}
|
|
.buildingBlock=${CONDITION_BUILDING_BLOCKS.includes(
|
|
this.condition.condition
|
|
)}
|
|
.sortSelected=${this.sortSelected}
|
|
@click=${this._toggleSidebar}
|
|
@toggle-collapsed=${this._toggleCollapse}
|
|
>${this._renderRow()}</ha-automation-row
|
|
>`
|
|
: html`
|
|
<ha-expansion-panel left-chevron>
|
|
${this._renderRow()}
|
|
</ha-expansion-panel>
|
|
`}
|
|
<div
|
|
class="testing ${classMap({
|
|
active: this._testing,
|
|
pass: this._testingResult === true,
|
|
error: this._testingResult === false,
|
|
})}"
|
|
>
|
|
${this._testingResult === undefined
|
|
? nothing
|
|
: this.hass.localize(
|
|
`ui.panel.config.automation.editor.conditions.testing_${
|
|
this._testingResult ? "pass" : "error"
|
|
}`
|
|
)}
|
|
</div>
|
|
</ha-card>
|
|
|
|
${this.optionsInSidebar &&
|
|
CONDITION_BUILDING_BLOCKS.includes(this.condition.condition)
|
|
? html`<ha-automation-condition-editor
|
|
class=${this._collapsed ? "hidden" : ""}
|
|
.hass=${this.hass}
|
|
.condition=${this.condition}
|
|
.disabled=${this.disabled}
|
|
.uiSupported=${this._uiSupported(
|
|
this._getType(this.condition, this.conditionDescriptions)
|
|
)}
|
|
indent
|
|
.selected=${this._selected}
|
|
.narrow=${this.narrow}
|
|
@value-changed=${this._onValueChange}
|
|
></ha-automation-condition-editor>`
|
|
: nothing}
|
|
`;
|
|
}
|
|
|
|
private _renderTargets = memoizeOne(
|
|
(target?: HassServiceTarget, targetRequired = false) =>
|
|
html`<ha-automation-row-targets
|
|
.hass=${this.hass}
|
|
.target=${target}
|
|
.targetRequired=${targetRequired}
|
|
></ha-automation-row-targets>`
|
|
);
|
|
|
|
protected firstUpdated(changedProperties: PropertyValues): void {
|
|
super.firstUpdated(changedProperties);
|
|
|
|
if (this.root) {
|
|
this._collapsed = false;
|
|
}
|
|
}
|
|
|
|
protected willUpdate(changedProperties) {
|
|
// on yaml toggle --> clear warnings
|
|
if (changedProperties.has("yamlMode")) {
|
|
this._warnings = undefined;
|
|
}
|
|
}
|
|
|
|
private _onValueChange(event: CustomEvent) {
|
|
// reload sidebar if sort, deleted,... happend
|
|
if (this._selected && this.optionsInSidebar) {
|
|
this.openSidebar(event.detail.value);
|
|
}
|
|
}
|
|
|
|
private _setClipboard() {
|
|
this._clipboard = {
|
|
...this._clipboard,
|
|
condition: deepClone(this.condition),
|
|
};
|
|
copyToClipboard(dump(this.condition));
|
|
}
|
|
|
|
private _onDisable = () => {
|
|
const enabled = !(this.condition.enabled ?? true);
|
|
const value = { ...this.condition, enabled };
|
|
fireEvent(this, "value-changed", { value });
|
|
|
|
if (this._selected && this.optionsInSidebar) {
|
|
this.openSidebar(value); // refresh sidebar
|
|
}
|
|
|
|
if (this._yamlMode && !this.optionsInSidebar) {
|
|
this.conditionEditor?.yamlEditor?.setValue(value);
|
|
}
|
|
};
|
|
|
|
private _onDelete = () => {
|
|
fireEvent(this, "value-changed", { value: null });
|
|
if (this._selected) {
|
|
fireEvent(this, "close-sidebar");
|
|
}
|
|
|
|
showToast(this, {
|
|
message: this.hass.localize("ui.common.successfully_deleted"),
|
|
duration: 4000,
|
|
action: {
|
|
text: this.hass.localize("ui.common.undo"),
|
|
action: () => {
|
|
fireEvent(window, "undo-change");
|
|
},
|
|
},
|
|
});
|
|
};
|
|
|
|
private _switchUiMode() {
|
|
this._yamlMode = false;
|
|
}
|
|
|
|
private _switchYamlMode() {
|
|
this._yamlMode = true;
|
|
}
|
|
|
|
private _testCondition = async () => {
|
|
if (this._testing) {
|
|
return;
|
|
}
|
|
this._testingResult = undefined;
|
|
this._testing = true;
|
|
const condition = this.condition;
|
|
requestAnimationFrame(() => {
|
|
// @ts-ignore is supported in all browsers except firefox
|
|
if (this.scrollIntoViewIfNeeded) {
|
|
// @ts-ignore is supported in all browsers except firefox
|
|
this.scrollIntoViewIfNeeded();
|
|
return;
|
|
}
|
|
this.scrollIntoView();
|
|
});
|
|
|
|
try {
|
|
const validateResult = await validateConfig(this.hass, {
|
|
conditions: condition,
|
|
});
|
|
|
|
// Abort if condition changed.
|
|
if (this.condition !== condition) {
|
|
this._testing = false;
|
|
return;
|
|
}
|
|
|
|
if (!validateResult.conditions.valid) {
|
|
showAlertDialog(this, {
|
|
title: this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.invalid_condition"
|
|
),
|
|
text: validateResult.conditions.error,
|
|
});
|
|
this._testing = false;
|
|
return;
|
|
}
|
|
|
|
let result: { result: boolean };
|
|
try {
|
|
result = await testCondition(this.hass, condition);
|
|
} catch (err: any) {
|
|
if (this.condition !== condition) {
|
|
this._testing = false;
|
|
return;
|
|
}
|
|
|
|
showAlertDialog(this, {
|
|
title: this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.test_failed"
|
|
),
|
|
text: err.message,
|
|
});
|
|
this._testing = false;
|
|
return;
|
|
}
|
|
|
|
this._testingResult = result.result;
|
|
} finally {
|
|
setTimeout(() => {
|
|
this._testing = false;
|
|
}, 2500);
|
|
}
|
|
};
|
|
|
|
private _renameCondition = async (): Promise<void> => {
|
|
const alias = await showPromptDialog(this, {
|
|
title: this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.change_alias"
|
|
),
|
|
inputLabel: this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.alias"
|
|
),
|
|
inputType: "string",
|
|
placeholder: capitalizeFirstLetter(
|
|
describeCondition(this.condition, this.hass, this._entityReg, true)
|
|
),
|
|
defaultValue: this.condition.alias,
|
|
confirmText: this.hass.localize("ui.common.submit"),
|
|
});
|
|
if (alias !== null) {
|
|
const value = { ...this.condition };
|
|
if (alias === "") {
|
|
delete value.alias;
|
|
} else {
|
|
value.alias = alias;
|
|
}
|
|
fireEvent(this, "value-changed", {
|
|
value,
|
|
});
|
|
|
|
if (this._selected && this.optionsInSidebar) {
|
|
this.openSidebar(value); // refresh sidebar
|
|
} else if (this._yamlMode) {
|
|
this.conditionEditor?.yamlEditor?.setValue(value);
|
|
}
|
|
}
|
|
};
|
|
|
|
private _duplicateCondition = () => {
|
|
fireEvent(this, "duplicate");
|
|
};
|
|
|
|
private _insertAfter = (value: Condition | Condition[]) => {
|
|
if (ensureArray(value).some((val) => !isCondition(val))) {
|
|
return false;
|
|
}
|
|
fireEvent(this, "insert-after", { value });
|
|
return true;
|
|
};
|
|
|
|
private _copyCondition = () => {
|
|
this._setClipboard();
|
|
showToast(this, {
|
|
message: this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.copied_to_clipboard"
|
|
),
|
|
duration: 2000,
|
|
});
|
|
};
|
|
|
|
private _cutCondition = () => {
|
|
this._setClipboard();
|
|
fireEvent(this, "value-changed", { value: null });
|
|
if (this._selected) {
|
|
fireEvent(this, "close-sidebar");
|
|
}
|
|
showToast(this, {
|
|
message: this.hass.localize(
|
|
"ui.panel.config.automation.editor.conditions.cut_to_clipboard"
|
|
),
|
|
duration: 2000,
|
|
});
|
|
};
|
|
|
|
private _moveUp = () => {
|
|
fireEvent(this, "move-up");
|
|
};
|
|
|
|
private _moveDown = () => {
|
|
fireEvent(this, "move-down");
|
|
};
|
|
|
|
private _toggleYamlMode = (item?: HTMLElement) => {
|
|
if (this._yamlMode) {
|
|
this._switchUiMode();
|
|
} else {
|
|
this._switchYamlMode();
|
|
}
|
|
|
|
if (!this.optionsInSidebar) {
|
|
this.expand();
|
|
} else if (item) {
|
|
this.openSidebar();
|
|
}
|
|
};
|
|
|
|
public expand() {
|
|
if (this.optionsInSidebar) {
|
|
this._collapsed = false;
|
|
return;
|
|
}
|
|
|
|
this.updateComplete.then(() => {
|
|
this.shadowRoot!.querySelector("ha-expansion-panel")!.expanded = true;
|
|
});
|
|
}
|
|
|
|
public collapse() {
|
|
this._collapsed = true;
|
|
}
|
|
|
|
public expandAll() {
|
|
this.expand();
|
|
|
|
this.conditionEditor?.expandAll();
|
|
}
|
|
|
|
public collapseAll() {
|
|
this.collapse();
|
|
|
|
this.conditionEditor?.collapseAll();
|
|
}
|
|
|
|
private _handleUiModeNotAvailable(ev: CustomEvent) {
|
|
this._warnings = handleStructError(this.hass, ev.detail).warnings;
|
|
if (!this._yamlMode) {
|
|
this._yamlMode = true;
|
|
}
|
|
}
|
|
|
|
private _toggleSidebar(ev: Event) {
|
|
ev?.stopPropagation();
|
|
|
|
if (this._selected) {
|
|
fireEvent(this, "request-close-sidebar");
|
|
return;
|
|
}
|
|
this.openSidebar();
|
|
}
|
|
|
|
public markAsNew(): void {
|
|
this._isNew = true;
|
|
}
|
|
|
|
public openSidebar(condition?: Condition): void {
|
|
const sidebarCondition = condition || this.condition;
|
|
fireEvent(this, "open-sidebar", {
|
|
save: (value) => {
|
|
fireEvent(this, "value-changed", { value });
|
|
},
|
|
close: (focus?: boolean) => {
|
|
this._selected = false;
|
|
this._isNew = false;
|
|
fireEvent(this, "close-sidebar");
|
|
if (focus) {
|
|
this.focus();
|
|
}
|
|
},
|
|
rename: () => {
|
|
this._renameCondition();
|
|
},
|
|
toggleYamlMode: () => {
|
|
this._toggleYamlMode();
|
|
this.openSidebar();
|
|
},
|
|
disable: this._onDisable,
|
|
delete: this._onDelete,
|
|
duplicate: this._duplicateCondition,
|
|
insertAfter: this._insertAfter,
|
|
copy: this._copyCondition,
|
|
cut: this._cutCondition,
|
|
test: this._testCondition,
|
|
config: sidebarCondition,
|
|
uiSupported: this._uiSupported(
|
|
this._getType(sidebarCondition, this.conditionDescriptions)
|
|
),
|
|
description: this.conditionDescriptions[sidebarCondition.condition],
|
|
yamlMode: this._yamlMode,
|
|
} satisfies ConditionSidebarConfig);
|
|
this._selected = true;
|
|
this._collapsed = false;
|
|
|
|
if (this.narrow) {
|
|
window.setTimeout(() => {
|
|
this.scrollIntoView({
|
|
block: "start",
|
|
behavior: "smooth",
|
|
});
|
|
}, 180); // duration of transition of added padding for bottom sheet
|
|
}
|
|
}
|
|
|
|
private _getType = memoizeOne(
|
|
(condition: Condition, conditionDescriptions: ConditionDescriptions) => {
|
|
if (condition.condition in conditionDescriptions) {
|
|
return "platform";
|
|
}
|
|
|
|
return condition.condition;
|
|
}
|
|
);
|
|
|
|
private _uiSupported = memoizeOne(
|
|
(type: string) =>
|
|
customElements.get(`ha-automation-condition-${type}`) !== undefined
|
|
);
|
|
|
|
private _toggleCollapse() {
|
|
if (!this._collapsed) {
|
|
this._isNew = false;
|
|
}
|
|
this._collapsed = !this._collapsed;
|
|
}
|
|
|
|
public focus() {
|
|
this._automationRowElement?.focus();
|
|
}
|
|
|
|
private _handleDropdownSelect(ev: HaDropdownSelectEvent) {
|
|
ev.stopPropagation();
|
|
const action = ev.detail?.item?.value;
|
|
|
|
if (!action) {
|
|
return;
|
|
}
|
|
|
|
switch (action) {
|
|
case "test":
|
|
this._testCondition();
|
|
break;
|
|
case "rename":
|
|
this._renameCondition();
|
|
break;
|
|
case "duplicate":
|
|
this._duplicateCondition();
|
|
break;
|
|
case "copy":
|
|
this._copyCondition();
|
|
break;
|
|
case "cut":
|
|
this._cutCondition();
|
|
break;
|
|
case "move_up":
|
|
this._moveUp();
|
|
break;
|
|
case "move_down":
|
|
this._moveDown();
|
|
break;
|
|
case "toggle_yaml_mode":
|
|
this._toggleYamlMode(ev.target as HTMLElement);
|
|
break;
|
|
case "disable":
|
|
this._onDisable();
|
|
break;
|
|
case "delete":
|
|
this._onDelete();
|
|
break;
|
|
}
|
|
}
|
|
|
|
static get styles(): CSSResultGroup {
|
|
return [
|
|
rowStyles,
|
|
overflowStyles,
|
|
css`
|
|
.testing {
|
|
position: absolute;
|
|
top: 0px;
|
|
right: 0px;
|
|
left: 0px;
|
|
text-transform: uppercase;
|
|
font-size: var(--ha-font-size-m);
|
|
font-weight: var(--ha-font-weight-bold);
|
|
background-color: var(--divider-color, #e0e0e0);
|
|
color: var(--text-primary-color);
|
|
max-height: 0px;
|
|
overflow: hidden;
|
|
transition: max-height 0.3s;
|
|
text-align: center;
|
|
border-top-right-radius: var(
|
|
--ha-card-border-radius,
|
|
var(--ha-border-radius-lg)
|
|
);
|
|
border-top-left-radius: var(
|
|
--ha-card-border-radius,
|
|
var(--ha-border-radius-lg)
|
|
);
|
|
}
|
|
.testing.active {
|
|
max-height: 100px;
|
|
}
|
|
.testing.error {
|
|
background-color: var(--accent-color);
|
|
}
|
|
.testing.pass {
|
|
background-color: var(--success-color);
|
|
}
|
|
`,
|
|
];
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"ha-automation-condition-row": HaAutomationConditionRow;
|
|
}
|
|
}
|