Automation editor: New choose default styles and style fixes (#26708)

Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
This commit is contained in:
Wendelin
2025-08-27 13:20:25 +02:00
committed by GitHub
parent 673ca8ba4b
commit 22966485c7
21 changed files with 467 additions and 585 deletions

View File

@@ -89,12 +89,12 @@ export class HaActionSelector extends SubscribeMixin(LitElement) {
static styles = css` static styles = css`
ha-automation-action { ha-automation-action {
display: block; display: block;
margin-bottom: 16px;
} }
label { label {
display: block; display: block;
margin-bottom: 4px; margin-bottom: 4px;
font-weight: var(--ha-font-weight-medium); font-weight: var(--ha-font-weight-medium);
color: var(--secondary-text-color);
} }
`; `;
} }

View File

@@ -53,6 +53,7 @@ export class HaConditionSelector extends LitElement {
display: block; display: block;
margin-bottom: 4px; margin-bottom: 4px;
font-weight: var(--ha-font-weight-medium); font-weight: var(--ha-font-weight-medium);
color: var(--secondary-text-color);
} }
`; `;
} }

View File

@@ -607,6 +607,7 @@ export interface OptionSidebarConfig extends BaseSidebarConfig {
close: () => void; close: () => void;
rename: () => void; rename: () => void;
duplicate: () => void; duplicate: () => void;
defaultOption?: boolean;
} }
export interface ScriptFieldSidebarConfig extends BaseSidebarConfig { export interface ScriptFieldSidebarConfig extends BaseSidebarConfig {

View File

@@ -24,6 +24,7 @@ import {
VIRTUAL_ACTIONS, VIRTUAL_ACTIONS,
showAddAutomationElementDialog, showAddAutomationElementDialog,
} from "../show-add-automation-element-dialog"; } from "../show-add-automation-element-dialog";
import { automationRowsStyles } from "../styles";
import type HaAutomationActionRow from "./ha-automation-action-row"; import type HaAutomationActionRow from "./ha-automation-action-row";
import { getAutomationActionType } from "./ha-automation-action-row"; import { getAutomationActionType } from "./ha-automation-action-row";
@@ -89,7 +90,7 @@ export default class HaAutomationAction extends LitElement {
@item-added=${this._actionAdded} @item-added=${this._actionAdded}
@item-removed=${this._actionRemoved} @item-removed=${this._actionRemoved}
> >
<div class="actions"> <div class="rows">
${repeat( ${repeat(
this.actions, this.actions,
(action) => this._getKey(action), (action) => this._getKey(action),
@@ -335,44 +336,14 @@ export default class HaAutomationAction extends LitElement {
}); });
} }
static styles = css` static styles = [
.actions { automationRowsStyles,
padding: 16px 0 16px 16px; css`
margin: -16px; :host([root]) .rows {
display: flex; padding-right: 8px;
flex-direction: column; }
gap: 16px; `,
} ];
:host([root]) .actions {
padding-right: 8px;
}
.sortable-ghost {
background: none;
border-radius: var(--ha-card-border-radius, var(--ha-border-radius-lg));
}
.sortable-drag {
background: none;
}
ha-automation-action-row {
display: block;
scroll-margin-top: 48px;
}
.handle {
padding: 12px;
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
}
.handle ha-svg-icon {
pointer-events: none;
height: 24px;
}
.buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
order: 1;
}
`;
} }
declare global { declare global {

View File

@@ -1,15 +1,16 @@
import { type CSSResultGroup, LitElement, css, html } from "lit"; import { type CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } 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";
import "../../../../../components/ha-button";
import type { Action, ChooseAction, Option } from "../../../../../data/script"; import type { Action, ChooseAction, Option } from "../../../../../data/script";
import { haStyle } from "../../../../../resources/styles"; import { haStyle } from "../../../../../resources/styles";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import "../../option/ha-automation-option"; import "../../option/ha-automation-option";
import type HaAutomationOption from "../../option/ha-automation-option"; import type HaAutomationOption from "../../option/ha-automation-option";
import "../../option/ha-automation-option-row";
import type HaAutomationOptionRow from "../../option/ha-automation-option-row";
import { indentStyle } from "../../styles";
import "../ha-automation-action"; import "../ha-automation-action";
import type HaAutomationAction from "../ha-automation-action";
import type { ActionElement } from "../ha-automation-action-row"; import type { ActionElement } from "../ha-automation-action-row";
@customElement("ha-automation-action-choose") @customElement("ha-automation-action-choose")
@@ -28,7 +29,8 @@ export class HaChooseAction extends LitElement implements ActionElement {
@query("ha-automation-option") private _optionElement?: HaAutomationOption; @query("ha-automation-option") private _optionElement?: HaAutomationOption;
@query("ha-automation-action") private _actionElement?: HaAutomationAction; @query("ha-automation-option-row")
private _defaultOptionRowElement?: HaAutomationOptionRow;
public static get defaultConfig(): ChooseAction { public static get defaultConfig(): ChooseAction {
return { choose: [{ conditions: [], sequence: [] }] }; return { choose: [{ conditions: [], sequence: [] }] };
@@ -47,42 +49,29 @@ export class HaChooseAction extends LitElement implements ActionElement {
.hass=${this.hass} .hass=${this.hass}
.narrow=${this.narrow} .narrow=${this.narrow}
.optionsInSidebar=${this.indent} .optionsInSidebar=${this.indent}
.showDefaultActions=${this._showDefault || !!action.default}
@show-default-actions=${this._addDefault}
></ha-automation-option> ></ha-automation-option>
${this._showDefault || action.default ${this._showDefault || action.default
? html` ? html`
<h4> <ha-automation-option-row
${this.hass.localize( .defaultActions=${(ensureArray(action.default) || []) as Action[]}
"ui.panel.config.automation.editor.actions.type.choose.default"
)}:
</h4>
<ha-automation-action
.actions=${ensureArray(action.default) || []}
.disabled=${this.disabled}
@value-changed=${this._defaultChanged}
.hass=${this.hass}
.narrow=${this.narrow} .narrow=${this.narrow}
.disabled=${this.disabled}
.hass=${this.hass}
.optionsInSidebar=${this.indent} .optionsInSidebar=${this.indent}
></ha-automation-action> @value-changed=${this._defaultChanged}
></ha-automation-option-row>
` `
: html` : nothing}
<div class="link-button-row">
<button
class="link"
@click=${this._addDefault}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.add_default"
)}
</button>
</div>
`}
`; `;
} }
private _addDefault() { private async _addDefault() {
this._showDefault = true; this._showDefault = true;
await this._defaultOptionRowElement?.updateComplete;
this._defaultOptionRowElement?.expand();
} }
private _optionsChanged(ev: CustomEvent) { private _optionsChanged(ev: CustomEvent) {
@@ -112,20 +101,26 @@ export class HaChooseAction extends LitElement implements ActionElement {
public expandAll() { public expandAll() {
this._optionElement?.expandAll(); this._optionElement?.expandAll();
this._actionElement?.expandAll(); this._defaultOptionRowElement?.expandAll();
} }
public collapseAll() { public collapseAll() {
this._optionElement?.collapseAll(); this._optionElement?.collapseAll();
this._actionElement?.collapseAll(); this._defaultOptionRowElement?.collapseAll();
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
haStyle, haStyle,
indentStyle,
css` css`
.link-button-row { ha-automation-option-row {
padding: 14px 14px 0 14px; display: block;
margin-top: 24px;
}
h3 {
font-size: inherit;
font-weight: inherit;
} }
`, `,
]; ];

View File

@@ -1,12 +1,6 @@
import type { CSSResultGroup } from "lit"; import type { CSSResultGroup } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { import { customElement, property, query, queryAll } from "lit/decorators";
customElement,
property,
query,
queryAll,
state,
} from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-textfield"; import "../../../../../components/ha-textfield";
import type { Action, IfAction } from "../../../../../data/script"; import type { Action, IfAction } from "../../../../../data/script";
@@ -30,8 +24,6 @@ export class HaIfAction extends LitElement implements ActionElement {
@property({ type: Boolean }) public indent = false; @property({ type: Boolean }) public indent = false;
@state() private _showElse = false;
@query("ha-automation-condition") @query("ha-automation-condition")
private _conditionElement?: HaAutomationCondition; private _conditionElement?: HaAutomationCondition;
@@ -49,11 +41,11 @@ export class HaIfAction extends LitElement implements ActionElement {
const action = this.action; const action = this.action;
return html` return html`
<h3> <h4>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.if.if" "ui.panel.config.automation.editor.actions.type.if.if"
)}*: )}:
</h3> </h4>
<ha-automation-condition <ha-automation-condition
.conditions=${action.if ?? []} .conditions=${action.if ?? []}
.disabled=${this.disabled} .disabled=${this.disabled}
@@ -63,11 +55,11 @@ export class HaIfAction extends LitElement implements ActionElement {
.optionsInSidebar=${this.indent} .optionsInSidebar=${this.indent}
></ha-automation-condition> ></ha-automation-condition>
<h3> <h4>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.if.then" "ui.panel.config.automation.editor.actions.type.if.then"
)}*: )}:
</h3> </h4>
<ha-automation-action <ha-automation-action
.actions=${action.then ?? []} .actions=${action.then ?? []}
.disabled=${this.disabled} .disabled=${this.disabled}
@@ -76,40 +68,22 @@ export class HaIfAction extends LitElement implements ActionElement {
.narrow=${this.narrow} .narrow=${this.narrow}
.optionsInSidebar=${this.indent} .optionsInSidebar=${this.indent}
></ha-automation-action> ></ha-automation-action>
${this._showElse || action.else <h4>
? html` ${this.hass.localize(
<h3> "ui.panel.config.automation.editor.actions.type.if.else"
${this.hass.localize( )}:
"ui.panel.config.automation.editor.actions.type.if.else" </h4>
)}: <ha-automation-action
</h3> .actions=${action.else || []}
<ha-automation-action .disabled=${this.disabled}
.actions=${action.else || []} @value-changed=${this._elseChanged}
.disabled=${this.disabled} .hass=${this.hass}
@value-changed=${this._elseChanged} .narrow=${this.narrow}
.hass=${this.hass} .optionsInSidebar=${this.indent}
.narrow=${this.narrow} ></ha-automation-action>
.optionsInSidebar=${this.indent}
></ha-automation-action>
`
: html`<div class="link-button-row">
<button
class="link"
@click=${this._addElse}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.if.add_else"
)}
</button>
</div>`}
`; `;
} }
private _addElse() {
this._showElse = true;
}
private _ifChanged(ev: CustomEvent) { private _ifChanged(ev: CustomEvent) {
ev.stopPropagation(); ev.stopPropagation();
const value = ev.detail.value as Condition[]; const value = ev.detail.value as Condition[];
@@ -134,7 +108,6 @@ export class HaIfAction extends LitElement implements ActionElement {
private _elseChanged(ev: CustomEvent) { private _elseChanged(ev: CustomEvent) {
ev.stopPropagation(); ev.stopPropagation();
this._showElse = true;
const elseAction = ev.detail.value as Action[]; const elseAction = ev.detail.value as Action[];
const newValue: IfAction = { const newValue: IfAction = {
...this.action, ...this.action,
@@ -160,8 +133,12 @@ export class HaIfAction extends LitElement implements ActionElement {
return [ return [
haStyle, haStyle,
css` css`
.link-button-row { h4 {
padding: 14px; color: var(--secondary-text-color);
margin-bottom: 8px;
}
h4:first-child {
margin-top: 0;
} }
`, `,
]; ];

View File

@@ -133,6 +133,7 @@ export default class HaAutomationConditionEditor extends LitElement {
margin-right: 0; margin-right: 0;
padding: 0; padding: 0;
border-left: none; border-left: none;
border-bottom: none;
} }
`, `,
]; ];

View File

@@ -1,7 +1,7 @@
import { mdiDrag, mdiPlus } from "@mdi/js"; import { mdiDrag, mdiPlus } from "@mdi/js";
import deepClone from "deep-clone-simple"; import deepClone from "deep-clone-simple";
import type { PropertyValues } from "lit"; import type { PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, queryAll, state } from "lit/decorators"; import { customElement, property, queryAll, state } from "lit/decorators";
import { repeat } from "lit/directives/repeat"; import { repeat } from "lit/directives/repeat";
import { storage } from "../../../../common/decorators/storage"; import { storage } from "../../../../common/decorators/storage";
@@ -22,6 +22,7 @@ import {
PASTE_VALUE, PASTE_VALUE,
showAddAutomationElementDialog, showAddAutomationElementDialog,
} from "../show-add-automation-element-dialog"; } from "../show-add-automation-element-dialog";
import { automationRowsStyles } from "../styles";
import "./ha-automation-condition-row"; import "./ha-automation-condition-row";
import type HaAutomationConditionRow from "./ha-automation-condition-row"; import type HaAutomationConditionRow from "./ha-automation-condition-row";
@@ -151,7 +152,7 @@ export default class HaAutomationCondition extends LitElement {
@item-added=${this._conditionAdded} @item-added=${this._conditionAdded}
@item-removed=${this._conditionRemoved} @item-removed=${this._conditionRemoved}
> >
<div class="conditions"> <div class="rows">
${repeat( ${repeat(
this.conditions.filter((c) => typeof c === "object"), this.conditions.filter((c) => typeof c === "object"),
(condition) => this._getKey(condition), (condition) => this._getKey(condition),
@@ -354,44 +355,14 @@ export default class HaAutomationCondition extends LitElement {
}); });
} }
static styles = css` static styles = [
.conditions { automationRowsStyles,
padding: 16px 0 16px 16px; css`
margin: -16px; :host([root]) .rows {
display: flex; padding-right: 8px;
flex-direction: column; }
gap: 16px; `,
} ];
:host([root]) .conditions {
padding-right: 8px;
}
.sortable-ghost {
background: none;
border-radius: var(--ha-card-border-radius, var(--ha-border-radius-lg));
}
.sortable-drag {
background: none;
}
ha-automation-condition-row {
display: block;
scroll-margin-top: 48px;
}
.handle {
padding: 12px;
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
}
.handle ha-svg-icon {
pointer-events: none;
height: 24px;
}
.buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
order: 1;
}
`;
} }
declare global { declare global {

View File

@@ -50,7 +50,7 @@ import "./condition/ha-automation-condition";
import type HaAutomationCondition from "./condition/ha-automation-condition"; import type HaAutomationCondition from "./condition/ha-automation-condition";
import "./ha-automation-sidebar"; import "./ha-automation-sidebar";
import { showPasteReplaceDialog } from "./paste-replace-dialog/show-dialog-paste-replace"; import { showPasteReplaceDialog } from "./paste-replace-dialog/show-dialog-paste-replace";
import { saveFabStyles } from "./styles"; import { manualEditorStyles, saveFabStyles } from "./styles";
import "./trigger/ha-automation-trigger"; import "./trigger/ha-automation-trigger";
const baseConfigStruct = object({ const baseConfigStruct = object({
@@ -266,7 +266,12 @@ export class HaManualAutomationEditor extends LitElement {
protected render() { protected render() {
return html` return html`
<div class="split-view"> <div
class=${classMap({
"split-view": true,
"sidebar-hidden": !this._sidebarConfig,
})}
>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content">${this._renderContent()}</div> <div class="content">${this._renderContent()}</div>
<ha-fab <ha-fab
@@ -283,7 +288,6 @@ export class HaManualAutomationEditor extends LitElement {
<ha-automation-sidebar <ha-automation-sidebar
class=${classMap({ class=${classMap({
sidebar: true, sidebar: true,
hidden: !this._sidebarConfig,
overlay: !this.isWide && !this.narrow, overlay: !this.isWide && !this.narrow,
rtl: computeRTL(this.hass), rtl: computeRTL(this.hass),
})} })}
@@ -619,81 +623,8 @@ export class HaManualAutomationEditor extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
saveFabStyles, saveFabStyles,
manualEditorStyles,
css` css`
:host {
display: block;
}
.split-view {
display: flex;
flex-direction: row;
height: 100%;
position: relative;
gap: 16px;
}
.content-wrapper {
position: relative;
flex: 6;
}
.content {
padding: 32px 16px 64px 0;
height: calc(100vh - 153px);
height: calc(100dvh - 153px);
overflow-y: auto;
overflow-x: hidden;
}
.sidebar {
padding: 12px 0;
flex: 4;
height: calc(100vh - 81px);
height: calc(100dvh - 81px);
width: 40%;
}
.sidebar.hidden {
border-color: transparent;
border-width: 0;
overflow: hidden;
flex: 0;
visibility: hidden;
}
.sidebar.overlay {
position: fixed;
bottom: 8px;
right: 8px;
height: calc(100% - 70px);
padding: 0;
z-index: 5;
box-shadow: -8px 0 16px rgba(0, 0, 0, 0.2);
}
.sidebar.overlay.rtl {
right: unset;
left: 8px;
}
@media all and (max-width: 870px) {
.split-view {
gap: 0;
margin-right: -8px;
}
.sidebar {
height: 0;
width: 0;
flex: 0;
}
}
.sidebar.overlay.hidden {
width: 0;
}
.description {
margin: 0;
}
p { p {
margin-top: 0; margin-top: 0;
} }
@@ -711,9 +642,6 @@ export class HaManualAutomationEditor extends LitElement {
flex: 1; flex: 1;
margin-bottom: 8px; margin-bottom: 8px;
} }
.header a {
color: var(--secondary-text-color);
}
.header .small { .header .small {
font-size: small; font-size: small;
font-weight: var(--ha-font-weight-normal); font-weight: var(--ha-font-weight-normal);

View File

@@ -46,7 +46,9 @@ import { editorStyles, indentStyle, rowStyles } from "../styles";
export default class HaAutomationOptionRow extends LitElement { export default class HaAutomationOptionRow extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public option!: Option; @property({ attribute: false }) public option?: Option;
@property({ attribute: false }) public defaultActions?: Action[];
@property({ type: Boolean }) public narrow = false; @property({ type: Boolean }) public narrow = false;
@@ -85,7 +87,7 @@ export default class HaAutomationOptionRow extends LitElement {
} }
private _getDescription() { private _getDescription() {
const conditions = ensureArray<Condition | string>(this.option.conditions); const conditions = ensureArray<Condition | string>(this.option!.conditions);
if (!conditions || conditions.length === 0) { if (!conditions || conditions.length === 0) {
return this.hass.localize( return this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.no_conditions" "ui.panel.config.automation.editor.actions.type.choose.no_conditions"
@@ -109,89 +111,102 @@ export default class HaAutomationOptionRow extends LitElement {
private _renderRow() { private _renderRow() {
return html` return html`
<h3 slot="header"> <h3 slot="header">
${this.hass.localize( ${this.option
"ui.panel.config.automation.editor.actions.type.choose.option", ? `${this.hass.localize(
{ number: this.index + 1 } "ui.panel.config.automation.editor.actions.type.choose.option",
)}: { number: this.index + 1 }
${this.option.alias || (this._expanded ? "" : this._getDescription())} )}: ${this.option.alias || (this._expanded ? "" : this._getDescription())}`
: this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.default"
)}
</h3> </h3>
<slot name="icons" slot="icons"></slot> <slot name="icons" slot="icons"></slot>
<ha-md-button-menu ${this.option
slot="icons" ? html`
@click=${preventDefaultStopPropagation} <ha-md-button-menu
@closed=${stopPropagation} slot="icons"
@keydown=${stopPropagation} @click=${preventDefaultStopPropagation}
positioning="fixed" @closed=${stopPropagation}
> @keydown=${stopPropagation}
<ha-icon-button positioning="fixed"
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
${!this.optionsInSidebar
? html`
<ha-md-menu-item
@click=${this._renameOption}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.rename"
)}
<ha-svg-icon slot="graphic" .path=${mdiRenameBox}></ha-svg-icon>
</ha-md-menu-item>
<ha-md-menu-item
@click=${this._duplicateOption}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon
slot="graphic"
.path=${mdiContentDuplicate}
></ha-svg-icon>
</ha-md-menu-item>
`
: nothing}
<ha-md-menu-item
@click=${this._moveUp}
.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>
</ha-md-menu-item>
<ha-md-menu-item
@click=${this._moveDown}
.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>
</ha-md-menu-item>
${!this.optionsInSidebar
? html`<ha-md-menu-item
@click=${this._removeOption}
class="warning"
.disabled=${this.disabled}
> >
${this.hass.localize( <ha-icon-button
"ui.panel.config.automation.editor.actions.type.choose.remove_option" slot="trigger"
)} .label=${this.hass.localize("ui.common.menu")}
<ha-svg-icon .path=${mdiDotsVertical}
class="warning" ></ha-icon-button>
slot="graphic"
.path=${mdiDelete}
></ha-svg-icon>
</ha-md-menu-item>`
: nothing}
</ha-md-button-menu>
${!this.optionsInSidebar
? html`
<ha-md-menu-item
@click=${this._renameOption}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.rename"
)}
<ha-svg-icon
slot="graphic"
.path=${mdiRenameBox}
></ha-svg-icon>
</ha-md-menu-item>
<ha-md-menu-item
@click=${this._duplicateOption}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon
slot="graphic"
.path=${mdiContentDuplicate}
></ha-svg-icon>
</ha-md-menu-item>
`
: nothing}
<ha-md-menu-item
@click=${this._moveUp}
.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>
</ha-md-menu-item>
<ha-md-menu-item
@click=${this._moveDown}
.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>
</ha-md-menu-item>
${!this.optionsInSidebar
? html`<ha-md-menu-item
@click=${this._removeOption}
class="warning"
.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>
</ha-md-menu-item>`
: nothing}
</ha-md-button-menu>
`
: nothing}
${!this.optionsInSidebar ? this._renderContent() : nothing} ${!this.optionsInSidebar ? this._renderContent() : nothing}
`; `;
} }
@@ -202,29 +217,39 @@ export default class HaAutomationOptionRow extends LitElement {
"card-content": true, "card-content": true,
indent: this.optionsInSidebar, indent: this.optionsInSidebar,
selected: this._selected, selected: this._selected,
hidden: this._collapsed, hidden: this.optionsInSidebar && this._collapsed,
})} })}
> >
<h4 class="conditions"> ${this.option
${this.hass.localize( ? html`
"ui.panel.config.automation.editor.actions.type.choose.conditions" <h4 class="top">
)}: ${this.hass.localize(
</h4> "ui.panel.config.automation.editor.actions.type.choose.conditions"
<ha-automation-condition )}:
.conditions=${ensureArray<string | Condition>(this.option.conditions)} </h4>
.disabled=${this.disabled} <ha-automation-condition
.hass=${this.hass} .conditions=${ensureArray<string | Condition>(
.narrow=${this.narrow} this.option.conditions
@value-changed=${this._conditionChanged} )}
.optionsInSidebar=${this.optionsInSidebar} .disabled=${this.disabled}
></ha-automation-condition> .hass=${this.hass}
<h4 class="actions"> .narrow=${this.narrow}
@value-changed=${this._conditionChanged}
.optionsInSidebar=${this.optionsInSidebar}
></ha-automation-condition>
`
: nothing}
<h4 class=${this.option ? "" : "top"}>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.sequence" "ui.panel.config.automation.editor.actions.type.choose.sequence"
)}: )}:
</h4> </h4>
<ha-automation-action <ha-automation-action
.actions=${ensureArray(this.option.sequence) || []} .actions=${(this.option
? ensureArray(this.option.sequence) || []
: this.defaultActions
? ensureArray(this.defaultActions) || []
: []) as Action[]}
.disabled=${this.disabled} .disabled=${this.disabled}
.hass=${this.hass} .hass=${this.hass}
.narrow=${this.narrow} .narrow=${this.narrow}
@@ -235,7 +260,7 @@ export default class HaAutomationOptionRow extends LitElement {
} }
protected render() { protected render() {
if (!this.option) return nothing; if (!this.option && !this.defaultActions) return nothing;
return html` return html`
<ha-card outlined class=${this._selected ? "selected" : ""}> <ha-card outlined class=${this._selected ? "selected" : ""}>
@@ -307,7 +332,7 @@ export default class HaAutomationOptionRow extends LitElement {
), ),
inputType: "string", inputType: "string",
placeholder: capitalizeFirstLetter(this._getDescription()), placeholder: capitalizeFirstLetter(this._getDescription()),
defaultValue: this.option.alias, defaultValue: this.option!.alias,
confirmText: this.hass.localize("ui.common.submit"), confirmText: this.hass.localize("ui.common.submit"),
}); });
if (alias !== null) { if (alias !== null) {
@@ -333,6 +358,9 @@ export default class HaAutomationOptionRow extends LitElement {
} }
private _actionChanged(ev: CustomEvent) { private _actionChanged(ev: CustomEvent) {
if (this.defaultActions) {
return;
}
ev.stopPropagation(); ev.stopPropagation();
const actions = ev.detail.value as Action[]; const actions = ev.detail.value as Action[];
const value = { ...this.option, sequence: actions }; const value = { ...this.option, sequence: actions };
@@ -364,6 +392,7 @@ export default class HaAutomationOptionRow extends LitElement {
toggleYamlMode: () => false, // no yaml mode for options toggleYamlMode: () => false, // no yaml mode for options
delete: this._removeOption, delete: this._removeOption,
duplicate: this._duplicateOption, duplicate: this._duplicateOption,
defaultOption: !!this.defaultActions,
} satisfies OptionSidebarConfig); } satisfies OptionSidebarConfig);
this._selected = true; this._selected = true;
this._collapsed = false; this._collapsed = false;
@@ -418,12 +447,14 @@ export default class HaAutomationOptionRow extends LitElement {
li[role="separator"] { li[role="separator"] {
border-bottom-color: var(--divider-color); border-bottom-color: var(--divider-color);
} }
h4.conditions { h4 {
margin-top: 0; color: var(--ha-color-text-secondary);
}
h4 {
margin-bottom: 8px; margin-bottom: 8px;
} }
h4.actions { h4.top {
margin-bottom: 8px; margin-top: 0;
} }
`, `,
]; ];

View File

@@ -1,7 +1,7 @@
import { mdiDrag, mdiPlus } from "@mdi/js"; import { mdiDrag, mdiPlus } from "@mdi/js";
import deepClone from "deep-clone-simple"; import deepClone from "deep-clone-simple";
import type { PropertyValues } from "lit"; import type { PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, html, nothing } from "lit";
import { customElement, property, queryAll, state } from "lit/decorators"; import { customElement, property, queryAll, state } from "lit/decorators";
import { repeat } from "lit/directives/repeat"; import { repeat } from "lit/directives/repeat";
import { storage } from "../../../../common/decorators/storage"; import { storage } from "../../../../common/decorators/storage";
@@ -14,6 +14,7 @@ import "../../../../components/ha-svg-icon";
import type { AutomationClipboard } from "../../../../data/automation"; import type { AutomationClipboard } from "../../../../data/automation";
import type { Option } from "../../../../data/script"; import type { Option } from "../../../../data/script";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { automationRowsStyles } from "../styles";
import "./ha-automation-option-row"; import "./ha-automation-option-row";
import type HaAutomationOptionRow from "./ha-automation-option-row"; import type HaAutomationOptionRow from "./ha-automation-option-row";
@@ -30,6 +31,9 @@ export default class HaAutomationOption extends LitElement {
@property({ type: Boolean, attribute: "sidebar" }) public optionsInSidebar = @property({ type: Boolean, attribute: "sidebar" }) public optionsInSidebar =
false; false;
@property({ type: Boolean, attribute: "show-default" })
public showDefaultActions = false;
@state() private _showReorder = false; @state() private _showReorder = false;
@state() @state()
@@ -75,7 +79,7 @@ export default class HaAutomationOption extends LitElement {
@item-added=${this._optionAdded} @item-added=${this._optionAdded}
@item-removed=${this._optionRemoved} @item-removed=${this._optionRemoved}
> >
<div class="options"> <div class="rows">
${repeat( ${repeat(
this.options, this.options,
(option) => this._getKey(option), (option) => this._getKey(option),
@@ -117,6 +121,19 @@ export default class HaAutomationOption extends LitElement {
"ui.panel.config.automation.editor.actions.type.choose.add_option" "ui.panel.config.automation.editor.actions.type.choose.add_option"
)} )}
</ha-button> </ha-button>
${!this.showDefaultActions
? html`<ha-button
appearance="plain"
size="small"
.disabled=${this.disabled}
@click=${this._showDefaultActions}
>
<ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.add_default"
)}
</ha-button>`
: nothing}
</div> </div>
</div> </div>
</ha-sortable> </ha-sortable>
@@ -248,45 +265,19 @@ export default class HaAutomationOption extends LitElement {
}); });
} }
static styles = css` private _showDefaultActions = () => {
.options { fireEvent(this, "show-default-actions");
padding: 16px 0 16px 16px; };
margin: -16px;
display: flex; static styles = automationRowsStyles;
flex-direction: column;
gap: 16px;
}
.sortable-ghost {
background: none;
border-radius: var(--ha-card-border-radius, var(--ha-border-radius-lg));
}
.sortable-drag {
background: none;
}
ha-automation-option-row {
display: block;
scroll-margin-top: 48px;
}
.handle {
padding: 12px;
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
}
.handle ha-svg-icon {
pointer-events: none;
height: 24px;
}
.buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
order: 1;
}
`;
} }
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
"ha-automation-option": HaAutomationOption; "ha-automation-option": HaAutomationOption;
} }
interface HASSDomEvents {
"show-default-actions": undefined;
}
} }

View File

@@ -9,7 +9,7 @@ import {
mdiRenameBox, mdiRenameBox,
mdiStopCircleOutline, mdiStopCircleOutline,
} from "@mdi/js"; } from "@mdi/js";
import { css, html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { handleStructError } from "../../../../common/structs/handle-errors"; import { handleStructError } from "../../../../common/structs/handle-errors";
@@ -23,6 +23,7 @@ import type { HomeAssistant } from "../../../../types";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { getAutomationActionType } from "../action/ha-automation-action-row"; import { getAutomationActionType } from "../action/ha-automation-action-row";
import { getRepeatType } from "../action/types/ha-automation-action-repeat"; import { getRepeatType } from "../action/types/ha-automation-action-repeat";
import { sidebarEditorStyles } from "../styles";
import "../trigger/ha-automation-trigger-editor"; import "../trigger/ha-automation-trigger-editor";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@@ -223,14 +224,7 @@ export default class HaAutomationSidebarAction extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
static styles = css` static styles = sidebarEditorStyles;
.sidebar-editor {
padding-top: 64px;
}
.description {
padding-top: 16px;
}
`;
} }
declare global { declare global {

View File

@@ -9,7 +9,7 @@ import {
mdiRenameBox, mdiRenameBox,
mdiStopCircleOutline, mdiStopCircleOutline,
} from "@mdi/js"; } from "@mdi/js";
import { css, html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { handleStructError } from "../../../../common/structs/handle-errors"; import { handleStructError } from "../../../../common/structs/handle-errors";
@@ -18,6 +18,7 @@ import { CONDITION_BUILDING_BLOCKS } from "../../../../data/condition";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import "../condition/ha-automation-condition-editor"; import "../condition/ha-automation-condition-editor";
import type HaAutomationConditionEditor from "../condition/ha-automation-condition-editor"; import type HaAutomationConditionEditor from "../condition/ha-automation-condition-editor";
import { sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-condition") @customElement("ha-automation-sidebar-condition")
@@ -211,14 +212,7 @@ export default class HaAutomationSidebarCondition extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
static styles = css` static styles = sidebarEditorStyles;
.sidebar-editor {
padding-top: 64px;
}
.description {
padding-top: 16px;
}
`;
} }
declare global { declare global {

View File

@@ -1,9 +1,10 @@
import { mdiContentDuplicate, mdiDelete, mdiRenameBox } from "@mdi/js"; import { mdiContentDuplicate, mdiDelete, mdiRenameBox } from "@mdi/js";
import { css, html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, query } from "lit/decorators";
import type { OptionSidebarConfig } from "../../../../data/automation"; import type { OptionSidebarConfig } from "../../../../data/automation";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-option") @customElement("ha-automation-sidebar-option")
@@ -29,11 +30,11 @@ export default class HaAutomationSidebarOption extends LitElement {
); );
const title = this.hass.localize( const title = this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.option_label" `ui.panel.config.automation.editor.actions.type.choose.${this.config.defaultOption ? "default_" : ""}option_label`
); );
const description = this.hass.localize( const description = this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.option_description" `ui.panel.config.automation.editor.actions.type.choose.${this.config.defaultOption ? "default_" : ""}option_description`
); );
return html`<ha-automation-sidebar-card return html`<ha-automation-sidebar-card
@@ -43,55 +44,56 @@ export default class HaAutomationSidebarOption extends LitElement {
> >
<span slot="title">${title}</span> <span slot="title">${title}</span>
<span slot="subtitle">${subtitle}</span> <span slot="subtitle">${subtitle}</span>
<ha-md-menu-item ${this.config.defaultOption
slot="menu-items" ? html`<span slot="overflow-menu"></span>`
.clickAction=${this.config.rename} : html`
.disabled=${!!disabled} <ha-md-menu-item
> slot="menu-items"
${this.hass.localize( .clickAction=${this.config.rename}
"ui.panel.config.automation.editor.triggers.rename" .disabled=${!!disabled}
)} >
<ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon> ${this.hass.localize(
</ha-md-menu-item> "ui.panel.config.automation.editor.triggers.rename"
)}
<ha-svg-icon slot="start" .path=${mdiRenameBox}></ha-svg-icon>
</ha-md-menu-item>
<ha-md-menu-item
slot="menu-items"
@click=${this.config.duplicate}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon
slot="graphic"
.path=${mdiContentDuplicate}
></ha-svg-icon>
</ha-md-menu-item>
<ha-md-divider
slot="menu-items"
role="separator"
tabindex="-1"
></ha-md-divider>
<ha-md-menu-item
slot="menu-items"
.clickAction=${this.config.delete}
.disabled=${this.disabled}
class="warning"
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
)}
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
</ha-md-menu-item>
`}
<ha-md-menu-item
slot="menu-items"
@click=${this.config.duplicate}
.disabled=${this.disabled}
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.duplicate"
)}
<ha-svg-icon slot="graphic" .path=${mdiContentDuplicate}></ha-svg-icon>
</ha-md-menu-item>
<ha-md-divider
slot="menu-items"
role="separator"
tabindex="-1"
></ha-md-divider>
<ha-md-menu-item
slot="menu-items"
.clickAction=${this.config.delete}
.disabled=${this.disabled}
class="warning"
>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
)}
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
</ha-md-menu-item>
<div class="description">${description}</div> <div class="description">${description}</div>
</ha-automation-sidebar-card>`; </ha-automation-sidebar-card>`;
} }
static styles = css` static styles = sidebarEditorStyles;
.sidebar-editor {
padding-top: 64px;
}
.description {
padding-top: 16px;
}
`;
} }
declare global { declare global {

View File

@@ -1,5 +1,5 @@
import { mdiDelete, mdiPlaylistEdit } from "@mdi/js"; import { mdiDelete, mdiPlaylistEdit } from "@mdi/js";
import { css, html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import type { LocalizeKeys } from "../../../../common/translations/localize"; import type { LocalizeKeys } from "../../../../common/translations/localize";
@@ -7,6 +7,7 @@ import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import "../../script/ha-script-field-selector-editor"; import "../../script/ha-script-field-selector-editor";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-script-field-selector") @customElement("ha-automation-sidebar-script-field-selector")
@@ -119,11 +120,7 @@ export default class HaAutomationSidebarScriptFieldSelector extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
static styles = css` static styles = sidebarEditorStyles;
.sidebar-editor {
padding-top: 64px;
}
`;
} }
declare global { declare global {

View File

@@ -1,11 +1,12 @@
import { mdiDelete, mdiPlaylistEdit } from "@mdi/js"; import { mdiDelete, mdiPlaylistEdit } from "@mdi/js";
import { css, html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import type { ScriptFieldSidebarConfig } from "../../../../data/automation"; import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import "../../script/ha-script-field-editor"; import "../../script/ha-script-field-editor";
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor"; import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
import { sidebarEditorStyles } from "../styles";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@customElement("ha-automation-sidebar-script-field") @customElement("ha-automation-sidebar-script-field")
@@ -113,11 +114,7 @@ export default class HaAutomationSidebarScriptField extends LitElement {
fireEvent(this, "toggle-yaml-mode"); fireEvent(this, "toggle-yaml-mode");
}; };
static styles = css` static styles = sidebarEditorStyles;
.sidebar-editor {
padding-top: 64px;
}
`;
} }
declare global { declare global {

View File

@@ -9,13 +9,14 @@ import {
mdiRenameBox, mdiRenameBox,
mdiStopCircleOutline, mdiStopCircleOutline,
} from "@mdi/js"; } from "@mdi/js";
import { css, html, LitElement, nothing } from "lit"; import { html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { handleStructError } from "../../../../common/structs/handle-errors"; import { handleStructError } from "../../../../common/structs/handle-errors";
import type { TriggerSidebarConfig } from "../../../../data/automation"; import type { TriggerSidebarConfig } from "../../../../data/automation";
import { isTriggerList } from "../../../../data/trigger"; import { isTriggerList } from "../../../../data/trigger";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { sidebarEditorStyles } from "../styles";
import "../trigger/ha-automation-trigger-editor"; import "../trigger/ha-automation-trigger-editor";
import type HaAutomationTriggerEditor from "../trigger/ha-automation-trigger-editor"; import type HaAutomationTriggerEditor from "../trigger/ha-automation-trigger-editor";
import "./ha-automation-sidebar-card"; import "./ha-automation-sidebar-card";
@@ -227,11 +228,7 @@ export default class HaAutomationSidebarTrigger extends LitElement {
this._requestShowId = true; this._requestShowId = true;
}; };
static styles = css` static styles = sidebarEditorStyles;
.sidebar-editor {
padding-top: 64px;
}
`;
} }
declare global { declare global {

View File

@@ -104,3 +104,133 @@ export const saveFabStyles = css`
bottom: 16px; bottom: 16px;
} }
`; `;
export const manualEditorStyles = css`
:host {
display: block;
}
.split-view {
display: flex;
flex-direction: row;
height: 100%;
position: relative;
gap: 16px;
}
.split-view.sidebar-hidden {
gap: 0;
}
.content-wrapper {
position: relative;
flex: 6;
}
.content {
padding: 32px 16px 64px 0;
height: calc(100vh - 153px);
height: calc(100dvh - 153px);
overflow-y: auto;
overflow-x: hidden;
}
.sidebar {
padding: 12px 0;
flex: 4;
height: calc(100vh - 81px);
height: calc(100dvh - 81px);
width: 40%;
}
.split-view.sidebar-hidden .sidebar {
border-color: transparent;
border-width: 0;
overflow: hidden;
flex: 0;
visibility: hidden;
}
.sidebar.overlay {
position: fixed;
bottom: 8px;
right: 8px;
height: calc(100% - 70px);
padding: 0;
z-index: 5;
box-shadow: -8px 0 16px rgba(0, 0, 0, 0.2);
}
.sidebar.overlay.rtl {
right: unset;
left: 8px;
}
@media all and (max-width: 870px) {
.split-view {
gap: 0;
margin-right: -8px;
}
.sidebar {
height: 0;
width: 0;
flex: 0;
}
}
.split-view.sidebar-hidden .sidebar.overlay {
width: 0;
}
.description {
margin: 0;
}
.header a {
color: var(--secondary-text-color);
}
`;
export const automationRowsStyles = css`
.rows {
padding: 16px 0 16px 16px;
margin: -16px;
margin-right: -20px;
display: flex;
flex-direction: column;
gap: 16px;
}
.sortable-ghost {
background: none;
border-radius: var(--ha-card-border-radius, var(--ha-border-radius-lg));
}
.sortable-drag {
background: none;
}
ha-automation-action-row {
display: block;
scroll-margin-top: 48px;
}
.handle {
padding: 12px;
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
}
.handle ha-svg-icon {
pointer-events: none;
height: 24px;
}
.buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
order: 1;
}
`;
export const sidebarEditorStyles = css`
.sidebar-editor {
display: block;
padding-top: 16px;
}
.description {
padding-top: 16px;
}
`;

View File

@@ -1,7 +1,7 @@
import { mdiDrag, mdiPlus } from "@mdi/js"; import { mdiDrag, mdiPlus } from "@mdi/js";
import deepClone from "deep-clone-simple"; import deepClone from "deep-clone-simple";
import type { PropertyValues } from "lit"; import type { PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { repeat } from "lit/directives/repeat"; import { repeat } from "lit/directives/repeat";
import { storage } from "../../../../common/decorators/storage"; import { storage } from "../../../../common/decorators/storage";
@@ -23,6 +23,7 @@ import {
PASTE_VALUE, PASTE_VALUE,
showAddAutomationElementDialog, showAddAutomationElementDialog,
} from "../show-add-automation-element-dialog"; } from "../show-add-automation-element-dialog";
import { automationRowsStyles } from "../styles";
import "./ha-automation-trigger-row"; import "./ha-automation-trigger-row";
import type HaAutomationTriggerRow from "./ha-automation-trigger-row"; import type HaAutomationTriggerRow from "./ha-automation-trigger-row";
@@ -85,7 +86,7 @@ export default class HaAutomationTrigger extends LitElement {
@item-added=${this._triggerAdded} @item-added=${this._triggerAdded}
@item-removed=${this._triggerRemoved} @item-removed=${this._triggerRemoved}
> >
<div class="triggers"> <div class="rows">
${repeat( ${repeat(
this.triggers, this.triggers,
(trigger) => this._getKey(trigger), (trigger) => this._getKey(trigger),
@@ -195,10 +196,11 @@ export default class HaAutomationTrigger extends LitElement {
} }
public expandAll() { public expandAll() {
const rows = this.shadowRoot!.querySelectorAll<HaAutomationTriggerRow>( const triggerRows =
"ha-automation-trigger-row" this.shadowRoot!.querySelectorAll<HaAutomationTriggerRow>(
)!; "ha-automation-trigger-row"
rows.forEach((row) => { )!;
triggerRows.forEach((row) => {
row.expand(); row.expand();
}); });
} }
@@ -300,44 +302,14 @@ export default class HaAutomationTrigger extends LitElement {
}); });
} }
static styles = css` static styles = [
.triggers { automationRowsStyles,
padding: 16px 0 16px 16px; css`
margin: -16px; :host([root]) .rows {
display: flex; padding-right: 8px;
flex-direction: column; }
gap: 16px; `,
} ];
:host([root]) .triggers {
padding-right: 8px;
}
.sortable-ghost {
background: none;
border-radius: var(--ha-card-border-radius, var(--ha-border-radius-lg));
}
.sortable-drag {
background: none;
}
ha-automation-trigger-row {
display: block;
scroll-margin-top: 48px;
}
.handle {
padding: 12px;
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
}
.handle ha-svg-icon {
pointer-events: none;
height: 24px;
}
.buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
order: 1;
}
`;
} }
declare global { declare global {

View File

@@ -39,7 +39,7 @@ import "../automation/action/ha-automation-action";
import type HaAutomationAction from "../automation/action/ha-automation-action"; import type HaAutomationAction from "../automation/action/ha-automation-action";
import "../automation/ha-automation-sidebar"; import "../automation/ha-automation-sidebar";
import { showPasteReplaceDialog } from "../automation/paste-replace-dialog/show-dialog-paste-replace"; import { showPasteReplaceDialog } from "../automation/paste-replace-dialog/show-dialog-paste-replace";
import { saveFabStyles } from "../automation/styles"; import { manualEditorStyles, saveFabStyles } from "../automation/styles";
import "./ha-script-fields"; import "./ha-script-fields";
import type HaScriptFields from "./ha-script-fields"; import type HaScriptFields from "./ha-script-fields";
@@ -194,7 +194,12 @@ export class HaManualScriptEditor extends LitElement {
protected render() { protected render() {
return html` return html`
<div class="split-view"> <div
class=${classMap({
"split-view": true,
"sidebar-hidden": !this._sidebarConfig,
})}
>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content">${this._renderContent()}</div> <div class="content">${this._renderContent()}</div>
<ha-fab <ha-fab
@@ -211,7 +216,6 @@ export class HaManualScriptEditor extends LitElement {
<ha-automation-sidebar <ha-automation-sidebar
class=${classMap({ class=${classMap({
sidebar: true, sidebar: true,
hidden: !this._sidebarConfig,
overlay: !this.isWide, overlay: !this.isWide,
rtl: computeRTL(this.hass), rtl: computeRTL(this.hass),
})} })}
@@ -504,79 +508,8 @@ export class HaManualScriptEditor extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
saveFabStyles, saveFabStyles,
manualEditorStyles,
css` css`
:host {
display: block;
}
.split-view {
display: flex;
flex-direction: row;
height: 100%;
position: relative;
gap: 16px;
}
.content-wrapper {
position: relative;
flex: 6;
}
.content {
padding: 32px 16px 64px 0;
height: calc(100vh - 153px);
height: calc(100dvh - 153px);
overflow-y: auto;
overflow-x: hidden;
}
.sidebar {
padding: 12px 0;
flex: 4;
height: calc(100vh - 81px);
height: calc(100dvh - 81px);
width: 40%;
}
.sidebar.hidden {
border-color: transparent;
border-width: 0;
overflow: hidden;
flex: 0;
visibility: hidden;
}
.sidebar.overlay {
position: fixed;
bottom: 0;
right: 0;
height: calc(100% - 64px);
padding: 0;
z-index: 5;
}
.sidebar.overlay.rtl {
right: unset;
left: 8px;
}
@media all and (max-width: 870px) {
.split-view {
gap: 0;
margin-right: -8px;
}
.sidebar {
height: 0;
width: 0;
flex: 0;
}
}
.sidebar.overlay.hidden {
width: 0;
}
.description {
margin: 0;
}
.header { .header {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -589,9 +522,6 @@ export class HaManualScriptEditor extends LitElement {
font-weight: var(--ha-font-weight-normal); font-weight: var(--ha-font-weight-normal);
flex: 1; flex: 1;
} }
.header a {
color: var(--secondary-text-color);
}
`, `,
]; ];
} }

View File

@@ -4472,7 +4472,9 @@
"no_conditions": "[%key:ui::panel::config::devices::automation::conditions::no_conditions%]", "no_conditions": "[%key:ui::panel::config::devices::automation::conditions::no_conditions%]",
"sequence": "Actions", "sequence": "Actions",
"option_label": "Option", "option_label": "Option",
"default_option_label": "Default actions",
"option_description": "Choose actions based on conditions", "option_description": "Choose actions based on conditions",
"default_option_description": "Optional actions to run if no other options match",
"description": { "description": {
"picker": "Choose what to do based on conditions (Similar to If-then, but more powerful).", "picker": "Choose what to do based on conditions (Similar to If-then, but more powerful).",
"full": "Choose {number, plural,\n one {an option}\n other{between {number} options}\n}", "full": "Choose {number, plural,\n one {an option}\n other{between {number} options}\n}",