mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Simplify create automation from device dialog (#22190)
* Simplify automation dialog * Fix translations * Auto expand trigger action and condition * Improve wording * Expand all * Remove unused translations
This commit is contained in:
parent
fe0fb2382a
commit
faf872bfb8
@ -8,6 +8,7 @@ import { Context, HomeAssistant } from "../types";
|
|||||||
import { BlueprintInput } from "./blueprint";
|
import { BlueprintInput } from "./blueprint";
|
||||||
import { DeviceCondition, DeviceTrigger } from "./device_automation";
|
import { DeviceCondition, DeviceTrigger } from "./device_automation";
|
||||||
import { Action, MODES, migrateAutomationAction } from "./script";
|
import { Action, MODES, migrateAutomationAction } from "./script";
|
||||||
|
import { createSearchParam } from "../common/url/search-params";
|
||||||
|
|
||||||
export const AUTOMATION_DEFAULT_MODE: (typeof MODES)[number] = "single";
|
export const AUTOMATION_DEFAULT_MODE: (typeof MODES)[number] = "single";
|
||||||
export const AUTOMATION_DEFAULT_MAX = 10;
|
export const AUTOMATION_DEFAULT_MAX = 10;
|
||||||
@ -462,9 +463,13 @@ export const flattenTriggers = (
|
|||||||
return flatTriggers;
|
return flatTriggers;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showAutomationEditor = (data?: Partial<AutomationConfig>) => {
|
export const showAutomationEditor = (
|
||||||
|
data?: Partial<AutomationConfig>,
|
||||||
|
expanded?: boolean
|
||||||
|
) => {
|
||||||
initialAutomationEditorData = data;
|
initialAutomationEditorData = data;
|
||||||
navigate("/config/automation/edit/new");
|
const params = expanded ? `?${createSearchParam({ expanded: "1" })}` : "";
|
||||||
|
navigate(`/config/automation/edit/new${params}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const duplicateAutomation = (config: AutomationConfig) => {
|
export const duplicateAutomation = (config: AutomationConfig) => {
|
||||||
|
@ -28,6 +28,7 @@ import {
|
|||||||
} from "./automation";
|
} from "./automation";
|
||||||
import { BlueprintInput } from "./blueprint";
|
import { BlueprintInput } from "./blueprint";
|
||||||
import { computeObjectId } from "../common/entity/compute_object_id";
|
import { computeObjectId } from "../common/entity/compute_object_id";
|
||||||
|
import { createSearchParam } from "../common/url/search-params";
|
||||||
|
|
||||||
export const MODES = ["single", "restart", "queued", "parallel"] as const;
|
export const MODES = ["single", "restart", "queued", "parallel"] as const;
|
||||||
export const MODES_MAX = ["queued", "parallel"] as const;
|
export const MODES_MAX = ["queued", "parallel"] as const;
|
||||||
@ -347,9 +348,13 @@ export const getScriptStateConfig = (hass: HomeAssistant, entity_id: string) =>
|
|||||||
entity_id,
|
entity_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const showScriptEditor = (data?: Partial<ScriptConfig>) => {
|
export const showScriptEditor = (
|
||||||
|
data?: Partial<ScriptConfig>,
|
||||||
|
expanded?: boolean
|
||||||
|
) => {
|
||||||
inititialScriptEditorData = data;
|
inititialScriptEditorData = data;
|
||||||
navigate("/config/script/edit/new");
|
const params = expanded ? `?${createSearchParam({ expanded: "1" })}` : "";
|
||||||
|
navigate(`/config/script/edit/new${params}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getScriptEditorInitData = () => {
|
export const getScriptEditorInitData = () => {
|
||||||
|
@ -156,6 +156,15 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public expandAll() {
|
||||||
|
const rows = this.shadowRoot!.querySelectorAll<HaAutomationActionRow>(
|
||||||
|
"ha-automation-action-row"
|
||||||
|
)!;
|
||||||
|
rows.forEach((row) => {
|
||||||
|
row.expand();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _addActionDialog() {
|
private _addActionDialog() {
|
||||||
showAddAutomationElementDialog(this, {
|
showAddAutomationElementDialog(this, {
|
||||||
type: "action",
|
type: "action",
|
||||||
|
@ -106,6 +106,15 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public expandAll() {
|
||||||
|
const rows = this.shadowRoot!.querySelectorAll<HaAutomationConditionRow>(
|
||||||
|
"ha-automation-condition-row"
|
||||||
|
)!;
|
||||||
|
rows.forEach((row) => {
|
||||||
|
row.expand();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private get nested() {
|
private get nested() {
|
||||||
return this.path !== undefined;
|
return this.path !== undefined;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import { mdiHelpCircle } from "@mdi/js";
|
import { mdiHelpCircle } from "@mdi/js";
|
||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
nothing,
|
||||||
|
PropertyValues,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { ensureArray } from "../../../common/array/ensure-array";
|
import { ensureArray } from "../../../common/array/ensure-array";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
@ -21,6 +28,14 @@ import { documentationUrl } from "../../../util/documentation-url";
|
|||||||
import "./action/ha-automation-action";
|
import "./action/ha-automation-action";
|
||||||
import "./condition/ha-automation-condition";
|
import "./condition/ha-automation-condition";
|
||||||
import "./trigger/ha-automation-trigger";
|
import "./trigger/ha-automation-trigger";
|
||||||
|
import type HaAutomationTrigger from "./trigger/ha-automation-trigger";
|
||||||
|
import type HaAutomationAction from "./action/ha-automation-action";
|
||||||
|
import type HaAutomationCondition from "./condition/ha-automation-condition";
|
||||||
|
import {
|
||||||
|
extractSearchParam,
|
||||||
|
removeSearchParam,
|
||||||
|
} from "../../../common/url/search-params";
|
||||||
|
import { constructUrlCurrentPath } from "../../../common/url/construct-url";
|
||||||
|
|
||||||
@customElement("manual-automation-editor")
|
@customElement("manual-automation-editor")
|
||||||
export class HaManualAutomationEditor extends LitElement {
|
export class HaManualAutomationEditor extends LitElement {
|
||||||
@ -36,6 +51,31 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public stateObj?: HassEntity;
|
@property({ attribute: false }) public stateObj?: HassEntity;
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps: PropertyValues): void {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const expanded = extractSearchParam("expanded");
|
||||||
|
if (expanded === "1") {
|
||||||
|
this._clearParam("expanded");
|
||||||
|
const items = this.shadowRoot!.querySelectorAll<
|
||||||
|
HaAutomationTrigger | HaAutomationCondition | HaAutomationAction
|
||||||
|
>("ha-automation-trigger, ha-automation-condition, ha-automation-action");
|
||||||
|
|
||||||
|
items.forEach((el) => {
|
||||||
|
el.updateComplete.then(() => {
|
||||||
|
el.expandAll();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _clearParam(param: string) {
|
||||||
|
window.history.replaceState(
|
||||||
|
null,
|
||||||
|
"",
|
||||||
|
constructUrlCurrentPath(removeSearchParam(param))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
${this.stateObj?.state === "off"
|
${this.stateObj?.state === "off"
|
||||||
|
@ -179,6 +179,15 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public expandAll() {
|
||||||
|
const rows = this.shadowRoot!.querySelectorAll<HaAutomationTriggerRow>(
|
||||||
|
"ha-automation-trigger-row"
|
||||||
|
)!;
|
||||||
|
rows.forEach((row) => {
|
||||||
|
row.expand();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _getKey(action: Trigger) {
|
private _getKey(action: Trigger) {
|
||||||
if (!this._triggerKeys.has(action)) {
|
if (!this._triggerKeys.has(action)) {
|
||||||
this._triggerKeys.set(action, Math.random().toString());
|
this._triggerKeys.set(action, Math.random().toString());
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { customElement } from "lit/decorators";
|
|
||||||
import {
|
|
||||||
DeviceAction,
|
|
||||||
localizeDeviceAutomationAction,
|
|
||||||
} from "../../../../data/device_automation";
|
|
||||||
import { HaDeviceAutomationCard } from "./ha-device-automation-card";
|
|
||||||
|
|
||||||
@customElement("ha-device-actions-card")
|
|
||||||
export class HaDeviceActionsCard extends HaDeviceAutomationCard<DeviceAction> {
|
|
||||||
readonly type = "action";
|
|
||||||
|
|
||||||
readonly headerKey = "ui.panel.config.devices.automation.actions.caption";
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(localizeDeviceAutomationAction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"ha-device-actions-card": HaDeviceActionsCard;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
import { css, html, LitElement, nothing } from "lit";
|
|
||||||
import { property, state } from "lit/decorators";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
|
||||||
import "../../../../components/chips/ha-assist-chip";
|
|
||||||
import "../../../../components/chips/ha-chip-set";
|
|
||||||
import { showAutomationEditor } from "../../../../data/automation";
|
|
||||||
import {
|
|
||||||
DeviceAction,
|
|
||||||
DeviceAutomation,
|
|
||||||
} from "../../../../data/device_automation";
|
|
||||||
import { EntityRegistryEntry } from "../../../../data/entity_registry";
|
|
||||||
import { showScriptEditor } from "../../../../data/script";
|
|
||||||
import { buttonLinkStyle } from "../../../../resources/styles";
|
|
||||||
import { HomeAssistant } from "../../../../types";
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HASSDomEvents {
|
|
||||||
"entry-selected": undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class HaDeviceAutomationCard<
|
|
||||||
T extends DeviceAutomation,
|
|
||||||
> extends LitElement {
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
||||||
|
|
||||||
@property() public deviceId?: string;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public script = false;
|
|
||||||
|
|
||||||
@property({ attribute: false }) public automations: T[] = [];
|
|
||||||
|
|
||||||
@property({ attribute: false }) entityReg?: EntityRegistryEntry[];
|
|
||||||
|
|
||||||
@state() public _showSecondary = false;
|
|
||||||
|
|
||||||
abstract headerKey: Parameters<typeof this.hass.localize>[0];
|
|
||||||
|
|
||||||
abstract type: "action" | "condition" | "trigger";
|
|
||||||
|
|
||||||
private _localizeDeviceAutomation: (
|
|
||||||
hass: HomeAssistant,
|
|
||||||
entityRegistry: EntityRegistryEntry[],
|
|
||||||
automation: T
|
|
||||||
) => string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
localizeDeviceAutomation: HaDeviceAutomationCard<T>["_localizeDeviceAutomation"]
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
this._localizeDeviceAutomation = localizeDeviceAutomation;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected shouldUpdate(changedProps): boolean {
|
|
||||||
if (changedProps.has("deviceId") || changedProps.has("automations")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
|
||||||
if (!oldHass || oldHass.language !== this.hass.language) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render() {
|
|
||||||
if (this.automations.length === 0 || !this.entityReg) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
const automations = this._showSecondary
|
|
||||||
? this.automations
|
|
||||||
: this.automations.filter(
|
|
||||||
(automation) => automation.metadata?.secondary === false
|
|
||||||
);
|
|
||||||
return html`
|
|
||||||
<h3>${this.hass.localize(this.headerKey)}</h3>
|
|
||||||
<div class="content">
|
|
||||||
<ha-chip-set>
|
|
||||||
${automations.map(
|
|
||||||
(automation, idx) => html`
|
|
||||||
<ha-assist-chip
|
|
||||||
filled
|
|
||||||
.index=${idx}
|
|
||||||
@click=${this._handleAutomationClicked}
|
|
||||||
class=${automation.metadata?.secondary ? "secondary" : ""}
|
|
||||||
.label=${this._localizeDeviceAutomation(
|
|
||||||
this.hass,
|
|
||||||
this.entityReg!,
|
|
||||||
automation
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
</ha-assist-chip>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</ha-chip-set>
|
|
||||||
${!this._showSecondary && automations.length < this.automations.length
|
|
||||||
? html`<button class="link" @click=${this._toggleSecondary}>
|
|
||||||
Show ${this.automations.length - automations.length} more...
|
|
||||||
</button>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggleSecondary() {
|
|
||||||
this._showSecondary = !this._showSecondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleAutomationClicked(ev: CustomEvent) {
|
|
||||||
const automation = { ...this.automations[(ev.currentTarget as any).index] };
|
|
||||||
if (!automation) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete automation.metadata;
|
|
||||||
if (this.script) {
|
|
||||||
showScriptEditor({ sequence: [automation as DeviceAction] });
|
|
||||||
fireEvent(this, "entry-selected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const data = {};
|
|
||||||
data[this.type] = [automation];
|
|
||||||
showAutomationEditor(data);
|
|
||||||
fireEvent(this, "entry-selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = [
|
|
||||||
buttonLinkStyle,
|
|
||||||
css`
|
|
||||||
h3 {
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
.secondary {
|
|
||||||
--ha-assist-chip-filled-container-color: rgba(
|
|
||||||
var(--rgb-primary-text-color),
|
|
||||||
0.07
|
|
||||||
);
|
|
||||||
}
|
|
||||||
button.link {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,8 +1,18 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import {
|
||||||
import { CSSResultGroup, html, LitElement, nothing } from "lit";
|
mdiAbTesting,
|
||||||
|
mdiGestureTap,
|
||||||
|
mdiPencilOutline,
|
||||||
|
mdiRoomService,
|
||||||
|
} from "@mdi/js";
|
||||||
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-dialog";
|
import { shouldHandleRequestSelectedEvent } from "../../../../common/mwc/handle-request-selected-event";
|
||||||
|
import { createCloseHeading } from "../../../../components/ha-dialog";
|
||||||
|
import {
|
||||||
|
AutomationConfig,
|
||||||
|
showAutomationEditor,
|
||||||
|
} from "../../../../data/automation";
|
||||||
import {
|
import {
|
||||||
DeviceAction,
|
DeviceAction,
|
||||||
DeviceCondition,
|
DeviceCondition,
|
||||||
@ -12,11 +22,9 @@ import {
|
|||||||
fetchDeviceTriggers,
|
fetchDeviceTriggers,
|
||||||
sortDeviceAutomations,
|
sortDeviceAutomations,
|
||||||
} from "../../../../data/device_automation";
|
} from "../../../../data/device_automation";
|
||||||
import { haStyleDialog } from "../../../../resources/styles";
|
import { ScriptConfig, showScriptEditor } from "../../../../data/script";
|
||||||
|
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import "./ha-device-actions-card";
|
|
||||||
import "./ha-device-conditions-card";
|
|
||||||
import "./ha-device-triggers-card";
|
|
||||||
import { DeviceAutomationDialogParams } from "./show-dialog-device-automation";
|
import { DeviceAutomationDialogParams } from "./show-dialog-device-automation";
|
||||||
|
|
||||||
@customElement("dialog-device-automation")
|
@customElement("dialog-device-automation")
|
||||||
@ -77,75 +85,184 @@ export class DialogDeviceAutomation extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleRowClick = (ev) => {
|
||||||
|
if (!shouldHandleRequestSelectedEvent(ev) || !this._params) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const type = (ev.currentTarget as any).type;
|
||||||
|
const isScript = this._params.script;
|
||||||
|
|
||||||
|
this.closeDialog();
|
||||||
|
|
||||||
|
if (isScript) {
|
||||||
|
const newScript = {} as ScriptConfig;
|
||||||
|
if (type === "action") {
|
||||||
|
newScript.sequence = [this._actions[0]];
|
||||||
|
}
|
||||||
|
showScriptEditor(newScript, true);
|
||||||
|
} else {
|
||||||
|
const newAutomation = {} as AutomationConfig;
|
||||||
|
if (type === "trigger") {
|
||||||
|
newAutomation.triggers = [this._triggers[0]];
|
||||||
|
}
|
||||||
|
if (type === "condition") {
|
||||||
|
newAutomation.conditions = [this._conditions[0]];
|
||||||
|
}
|
||||||
|
if (type === "action") {
|
||||||
|
newAutomation.actions = [this._actions[0]];
|
||||||
|
}
|
||||||
|
showAutomationEditor(newAutomation, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this._params) {
|
if (!this._params) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mode = this._params.script ? "script" : "automation";
|
||||||
|
|
||||||
|
const title = this.hass.localize(`ui.panel.config.devices.${mode}.create`, {
|
||||||
|
type: this.hass.localize(
|
||||||
|
`ui.panel.config.devices.type.${
|
||||||
|
this._params.device.entry_type || "device"
|
||||||
|
}`
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
|
hideActions
|
||||||
@closed=${this.closeDialog}
|
@closed=${this.closeDialog}
|
||||||
.heading=${this.hass.localize(
|
.heading=${createCloseHeading(this.hass, title)}
|
||||||
`ui.panel.config.devices.${
|
|
||||||
this._params.script ? "script" : "automation"
|
|
||||||
}.create`,
|
|
||||||
{
|
|
||||||
type: this.hass.localize(
|
|
||||||
`ui.panel.config.devices.type.${
|
|
||||||
this._params.device.entry_type || "device"
|
|
||||||
}`
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<div @entry-selected=${this.closeDialog}>
|
<mwc-list
|
||||||
|
innerRole="listbox"
|
||||||
|
itemRoles="option"
|
||||||
|
innerAriaLabel="Create new automation"
|
||||||
|
rootTabbable
|
||||||
|
dialogInitialFocus
|
||||||
|
>
|
||||||
|
${this._triggers.length
|
||||||
|
? html`
|
||||||
|
<ha-list-item
|
||||||
|
hasmeta
|
||||||
|
twoline
|
||||||
|
graphic="icon"
|
||||||
|
.type=${"trigger"}
|
||||||
|
@request-selected=${this._handleRowClick}
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiGestureTap}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.devices.automation.triggers.title`
|
||||||
|
)}
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.devices.automation.triggers.description`
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<ha-icon-next slot="meta"></ha-icon-next>
|
||||||
|
</ha-list-item>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${this._conditions.length
|
||||||
|
? html`
|
||||||
|
<ha-list-item
|
||||||
|
hasmeta
|
||||||
|
twoline
|
||||||
|
graphic="icon"
|
||||||
|
.type=${"condition"}
|
||||||
|
@request-selected=${this._handleRowClick}
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiAbTesting}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.devices.automation.conditions.title`
|
||||||
|
)}
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.devices.automation.conditions.description`
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<ha-icon-next slot="meta"></ha-icon-next>
|
||||||
|
</ha-list-item>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${this._actions.length
|
||||||
|
? html`
|
||||||
|
<ha-list-item
|
||||||
|
hasmeta
|
||||||
|
twoline
|
||||||
|
graphic="icon"
|
||||||
|
.type=${"action"}
|
||||||
|
@request-selected=${this._handleRowClick}
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiRoomService}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.devices.${mode}.actions.title`
|
||||||
|
)}
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.devices.${mode}.actions.description`
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<ha-icon-next slot="meta"></ha-icon-next>
|
||||||
|
</ha-list-item>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
${this._triggers.length ||
|
${this._triggers.length ||
|
||||||
this._conditions.length ||
|
this._conditions.length ||
|
||||||
this._actions.length
|
this._actions.length
|
||||||
? html`
|
? html`<li divider role="separator"></li>`
|
||||||
${this._triggers.length
|
: nothing}
|
||||||
? html`
|
<ha-list-item
|
||||||
<ha-device-triggers-card
|
hasmeta
|
||||||
.hass=${this.hass}
|
twoline
|
||||||
.automations=${this._triggers}
|
graphic="icon"
|
||||||
.entityReg=${this._params.entityReg}
|
@request-selected=${this._handleRowClick}
|
||||||
></ha-device-triggers-card>
|
>
|
||||||
`
|
<ha-svg-icon slot="graphic" .path=${mdiPencilOutline}></ha-svg-icon>
|
||||||
: ""}
|
${this.hass.localize(`ui.panel.config.devices.${mode}.new.title`)}
|
||||||
${this._conditions.length
|
<span slot="secondary">
|
||||||
? html`
|
${this.hass.localize(
|
||||||
<ha-device-conditions-card
|
`ui.panel.config.devices.${mode}.new.description`
|
||||||
.hass=${this.hass}
|
|
||||||
.automations=${this._conditions}
|
|
||||||
.entityReg=${this._params.entityReg}
|
|
||||||
></ha-device-conditions-card>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this._actions.length
|
|
||||||
? html`
|
|
||||||
<ha-device-actions-card
|
|
||||||
.hass=${this.hass}
|
|
||||||
.automations=${this._actions}
|
|
||||||
.script=${this._params.script}
|
|
||||||
.entityReg=${this._params.entityReg}
|
|
||||||
></ha-device-actions-card>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
`
|
|
||||||
: this.hass.localize(
|
|
||||||
"ui.panel.config.devices.automation.no_device_automations"
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</span>
|
||||||
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
<ha-icon-next slot="meta"></ha-icon-next>
|
||||||
${this.hass.localize("ui.common.close")}
|
</ha-list-item>
|
||||||
</mwc-button>
|
</mwc-list>
|
||||||
</ha-dialog>
|
</ha-dialog>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return haStyleDialog;
|
return [
|
||||||
|
haStyle,
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
ha-dialog {
|
||||||
|
--dialog-content-padding: 0;
|
||||||
|
--mdc-dialog-max-height: 60vh;
|
||||||
|
}
|
||||||
|
@media all and (min-width: 550px) {
|
||||||
|
ha-dialog {
|
||||||
|
--mdc-dialog-min-width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ha-icon-next {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { customElement } from "lit/decorators";
|
|
||||||
import {
|
|
||||||
DeviceCondition,
|
|
||||||
localizeDeviceAutomationCondition,
|
|
||||||
} from "../../../../data/device_automation";
|
|
||||||
import { HaDeviceAutomationCard } from "./ha-device-automation-card";
|
|
||||||
|
|
||||||
@customElement("ha-device-conditions-card")
|
|
||||||
export class HaDeviceConditionsCard extends HaDeviceAutomationCard<DeviceCondition> {
|
|
||||||
readonly type = "condition";
|
|
||||||
|
|
||||||
readonly headerKey = "ui.panel.config.devices.automation.conditions.caption";
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(localizeDeviceAutomationCondition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"ha-device-conditions-card": HaDeviceConditionsCard;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import { customElement } from "lit/decorators";
|
|
||||||
import {
|
|
||||||
DeviceTrigger,
|
|
||||||
localizeDeviceAutomationTrigger,
|
|
||||||
} from "../../../../data/device_automation";
|
|
||||||
import { HaDeviceAutomationCard } from "./ha-device-automation-card";
|
|
||||||
|
|
||||||
@customElement("ha-device-triggers-card")
|
|
||||||
export class HaDeviceTriggersCard extends HaDeviceAutomationCard<DeviceTrigger> {
|
|
||||||
readonly type = "trigger";
|
|
||||||
|
|
||||||
readonly headerKey = "ui.panel.config.devices.automation.triggers.caption";
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(localizeDeviceAutomationTrigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"ha-device-triggers-card": HaDeviceTriggersCard;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,20 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import { mdiHelpCircle } from "@mdi/js";
|
import { mdiHelpCircle } from "@mdi/js";
|
||||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
import {
|
||||||
|
CSSResultGroup,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, query } from "lit/decorators";
|
import { customElement, property, query } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { constructUrlCurrentPath } from "../../../common/url/construct-url";
|
||||||
|
import {
|
||||||
|
extractSearchParam,
|
||||||
|
removeSearchParam,
|
||||||
|
} from "../../../common/url/search-params";
|
||||||
import { nestedArrayMove } from "../../../common/util/array-move";
|
import { nestedArrayMove } from "../../../common/util/array-move";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
@ -12,6 +24,7 @@ import { haStyle } from "../../../resources/styles";
|
|||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import { documentationUrl } from "../../../util/documentation-url";
|
import { documentationUrl } from "../../../util/documentation-url";
|
||||||
import "../automation/action/ha-automation-action";
|
import "../automation/action/ha-automation-action";
|
||||||
|
import type HaAutomationAction from "../automation/action/ha-automation-action";
|
||||||
import "./ha-script-fields";
|
import "./ha-script-fields";
|
||||||
import type HaScriptFields from "./ha-script-fields";
|
import type HaScriptFields from "./ha-script-fields";
|
||||||
|
|
||||||
@ -58,6 +71,31 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps: PropertyValues): void {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const expanded = extractSearchParam("expanded");
|
||||||
|
if (expanded === "1") {
|
||||||
|
this._clearParam("expanded");
|
||||||
|
const items = this.shadowRoot!.querySelectorAll<HaAutomationAction>(
|
||||||
|
"ha-automation-action"
|
||||||
|
);
|
||||||
|
|
||||||
|
items.forEach((el) => {
|
||||||
|
el.updateComplete.then(() => {
|
||||||
|
el.expandAll();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _clearParam(param: string) {
|
||||||
|
window.history.replaceState(
|
||||||
|
null,
|
||||||
|
"",
|
||||||
|
constructUrlCurrentPath(removeSearchParam(param))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
${this.config.description
|
${this.config.description
|
||||||
|
@ -4039,18 +4039,25 @@
|
|||||||
"unknown_automation": "Unknown automation",
|
"unknown_automation": "Unknown automation",
|
||||||
"create": "Create automation with {type}",
|
"create": "Create automation with {type}",
|
||||||
"create_disable": "Can't create automation with disabled {type}",
|
"create_disable": "Can't create automation with disabled {type}",
|
||||||
|
"new": {
|
||||||
|
"title": "Create new automation",
|
||||||
|
"description": "Start with an empty automation from scratch"
|
||||||
|
},
|
||||||
"triggers": {
|
"triggers": {
|
||||||
"caption": "Do something when…",
|
"title": "Use device as trigger",
|
||||||
|
"description": "When something happens to the device",
|
||||||
"no_triggers": "No triggers",
|
"no_triggers": "No triggers",
|
||||||
"unknown_trigger": "Unknown trigger"
|
"unknown_trigger": "Unknown trigger"
|
||||||
},
|
},
|
||||||
"conditions": {
|
"conditions": {
|
||||||
"caption": "Only do something if…",
|
"title": "Use device as condition",
|
||||||
|
"description": "Only if a condition is met for the device",
|
||||||
"no_conditions": "No conditions",
|
"no_conditions": "No conditions",
|
||||||
"unknown_condition": "Unknown condition"
|
"unknown_condition": "Unknown condition"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"caption": "When something is triggered…",
|
"title": "Use device as action",
|
||||||
|
"description": "Do something on the device",
|
||||||
"no_actions": "No actions",
|
"no_actions": "No actions",
|
||||||
"unknown_action": "Unknown action"
|
"unknown_action": "Unknown action"
|
||||||
},
|
},
|
||||||
@ -4061,7 +4068,15 @@
|
|||||||
"scripts": "scripts",
|
"scripts": "scripts",
|
||||||
"no_scripts": "No scripts",
|
"no_scripts": "No scripts",
|
||||||
"create": "Create script with {type}",
|
"create": "Create script with {type}",
|
||||||
"create_disable": "Can't create script with disabled {type}"
|
"create_disable": "Can't create script with disabled {type}",
|
||||||
|
"new": {
|
||||||
|
"title": "Create new script",
|
||||||
|
"description": "Start with an empty script from scratch"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Use device as action",
|
||||||
|
"description": "Do something on this device."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"scene": {
|
"scene": {
|
||||||
"scenes_heading": "Scenes",
|
"scenes_heading": "Scenes",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user