mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Use expansion panel for dashboard conditions (#18380)
This commit is contained in:
parent
d94f7c90c0
commit
33e0c691c7
@ -8,10 +8,12 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
|||||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
|
import "../../../../components/ha-expansion-panel";
|
||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-icon-button";
|
||||||
import "../../../../components/ha-list-item";
|
import "../../../../components/ha-list-item";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import "../../../../components/ha-yaml-editor";
|
import "../../../../components/ha-yaml-editor";
|
||||||
|
import "../../../../components/ha-alert";
|
||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import { ICON_CONDITION } from "../../common/icon-condition";
|
import { ICON_CONDITION } from "../../common/icon-condition";
|
||||||
@ -19,7 +21,7 @@ import { Condition, LegacyCondition } from "../../common/validate-condition";
|
|||||||
import type { LovelaceConditionEditorConstructor } from "./types";
|
import type { LovelaceConditionEditorConstructor } from "./types";
|
||||||
|
|
||||||
@customElement("ha-card-condition-editor")
|
@customElement("ha-card-condition-editor")
|
||||||
export default class HaCardConditionEditor extends LitElement {
|
export class HaCardConditionEditor extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) condition!: Condition | LegacyCondition;
|
@property({ attribute: false }) condition!: Condition | LegacyCondition;
|
||||||
@ -39,6 +41,12 @@ export default class HaCardConditionEditor extends LitElement {
|
|||||||
) as LovelaceConditionEditorConstructor | undefined;
|
) as LovelaceConditionEditorConstructor | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public expand() {
|
||||||
|
this.updateComplete.then(() => {
|
||||||
|
this.shadowRoot!.querySelector("ha-expansion-panel")!.expanded = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected willUpdate(changedProperties: PropertyValues): void {
|
protected willUpdate(changedProperties: PropertyValues): void {
|
||||||
if (changedProperties.has("condition")) {
|
if (changedProperties.has("condition")) {
|
||||||
this._condition = {
|
this._condition = {
|
||||||
@ -75,110 +83,130 @@ export default class HaCardConditionEditor extends LitElement {
|
|||||||
if (!condition) return nothing;
|
if (!condition) return nothing;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="header">
|
<ha-card outlined>
|
||||||
<ha-svg-icon
|
<ha-expansion-panel leftChevron>
|
||||||
class="icon"
|
<h3 slot="header">
|
||||||
.path=${ICON_CONDITION[condition.condition]}
|
|
||||||
></ha-svg-icon>
|
|
||||||
<span class="title">
|
|
||||||
${this.hass.localize(
|
|
||||||
`ui.panel.lovelace.editor.condition-editor.condition.${condition.condition}.label`
|
|
||||||
) || condition.condition}
|
|
||||||
</span>
|
|
||||||
<ha-button-menu
|
|
||||||
slot="icons"
|
|
||||||
@action=${this._handleAction}
|
|
||||||
@click=${preventDefault}
|
|
||||||
@closed=${stopPropagation}
|
|
||||||
fixed
|
|
||||||
.corner=${"BOTTOM_END"}
|
|
||||||
.menuCorner=${"END"}
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
slot="trigger"
|
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
|
||||||
.path=${mdiDotsVertical}
|
|
||||||
>
|
|
||||||
</ha-icon-button>
|
|
||||||
|
|
||||||
<ha-list-item graphic="icon" .disabled=${!this._uiAvailable}>
|
|
||||||
${this.hass.localize("ui.panel.lovelace.editor.edit_card.edit_ui")}
|
|
||||||
${!this._yamlMode
|
|
||||||
? html`
|
|
||||||
<ha-svg-icon
|
|
||||||
class="selected_menu_item"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiCheck}
|
|
||||||
></ha-svg-icon>
|
|
||||||
`
|
|
||||||
: ``}
|
|
||||||
</ha-list-item>
|
|
||||||
|
|
||||||
<ha-list-item graphic="icon">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.lovelace.editor.edit_card.edit_yaml"
|
|
||||||
)}
|
|
||||||
${this._yamlMode
|
|
||||||
? html`
|
|
||||||
<ha-svg-icon
|
|
||||||
class="selected_menu_item"
|
|
||||||
slot="graphic"
|
|
||||||
.path=${mdiCheck}
|
|
||||||
></ha-svg-icon>
|
|
||||||
`
|
|
||||||
: ``}
|
|
||||||
</ha-list-item>
|
|
||||||
|
|
||||||
<li divider role="separator"></li>
|
|
||||||
|
|
||||||
<ha-list-item class="warning" graphic="icon">
|
|
||||||
${this.hass!.localize("ui.common.delete")}
|
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
class="warning"
|
class="condition-icon"
|
||||||
slot="graphic"
|
.path=${ICON_CONDITION[condition.condition]}
|
||||||
.path=${mdiDelete}
|
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-list-item>
|
${
|
||||||
</ha-button-menu>
|
this.hass.localize(
|
||||||
</div>
|
`ui.panel.lovelace.editor.condition-editor.condition.${condition.condition}.label`
|
||||||
${!this._uiAvailable
|
) || condition.condition
|
||||||
? html`
|
}
|
||||||
<ha-alert
|
</h3>
|
||||||
alert-type="warning"
|
<ha-button-menu
|
||||||
.title=${this.hass.localize(
|
slot="icons"
|
||||||
"ui.errors.config.editor_not_supported"
|
@action=${this._handleAction}
|
||||||
)}
|
@click=${preventDefault}
|
||||||
|
@closed=${stopPropagation}
|
||||||
|
fixed
|
||||||
|
.corner=${"BOTTOM_END"}
|
||||||
|
.menuCorner=${"END"}
|
||||||
>
|
>
|
||||||
${this._uiWarnings!.length > 0 &&
|
<ha-icon-button
|
||||||
this._uiWarnings![0] !== undefined
|
slot="trigger"
|
||||||
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
|
.path=${mdiDotsVertical}
|
||||||
|
>
|
||||||
|
</ha-icon-button>
|
||||||
|
|
||||||
|
<ha-list-item graphic="icon" .disabled=${!this._uiAvailable}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_card.edit_ui"
|
||||||
|
)}
|
||||||
|
${
|
||||||
|
!this._yamlMode
|
||||||
|
? html`
|
||||||
|
<ha-svg-icon
|
||||||
|
class="selected_menu_item"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiCheck}
|
||||||
|
></ha-svg-icon>
|
||||||
|
`
|
||||||
|
: ``
|
||||||
|
}
|
||||||
|
</ha-list-item>
|
||||||
|
|
||||||
|
<ha-list-item graphic="icon">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_card.edit_yaml"
|
||||||
|
)}
|
||||||
|
${
|
||||||
|
this._yamlMode
|
||||||
|
? html`
|
||||||
|
<ha-svg-icon
|
||||||
|
class="selected_menu_item"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiCheck}
|
||||||
|
></ha-svg-icon>
|
||||||
|
`
|
||||||
|
: ``
|
||||||
|
}
|
||||||
|
</ha-list-item>
|
||||||
|
|
||||||
|
<li divider role="separator"></li>
|
||||||
|
|
||||||
|
<ha-list-item class="warning" graphic="icon">
|
||||||
|
${this.hass!.localize("ui.common.delete")}
|
||||||
|
<ha-svg-icon
|
||||||
|
class="warning"
|
||||||
|
slot="graphic"
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</ha-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
</div>
|
||||||
|
${
|
||||||
|
!this._uiAvailable
|
||||||
|
? html`
|
||||||
|
<ha-alert
|
||||||
|
alert-type="warning"
|
||||||
|
.title=${this.hass.localize(
|
||||||
|
"ui.errors.config.editor_not_supported"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
${this._uiWarnings!.length > 0 &&
|
||||||
|
this._uiWarnings![0] !== undefined
|
||||||
|
? html`
|
||||||
|
<ul>
|
||||||
|
${this._uiWarnings!.map(
|
||||||
|
(warning) => html`<li>${warning}</li>`
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.errors.config.edit_in_yaml_supported"
|
||||||
|
)}
|
||||||
|
</ha-alert>
|
||||||
|
`
|
||||||
|
: nothing
|
||||||
|
}
|
||||||
|
<div class="content">
|
||||||
|
${
|
||||||
|
this._yamlMode
|
||||||
? html`
|
? html`
|
||||||
<ul>
|
<ha-yaml-editor
|
||||||
${this._uiWarnings!.map(
|
.hass=${this.hass}
|
||||||
(warning) => html`<li>${warning}</li>`
|
.defaultValue=${this.condition}
|
||||||
)}
|
@value-changed=${this._onYamlChange}
|
||||||
</ul>
|
></ha-yaml-editor>
|
||||||
`
|
`
|
||||||
: nothing}
|
: html`
|
||||||
${this.hass.localize("ui.errors.config.edit_in_yaml_supported")}
|
${dynamicElement(
|
||||||
</ha-alert>
|
`ha-card-condition-${condition.condition}`,
|
||||||
`
|
{
|
||||||
: nothing}
|
hass: this.hass,
|
||||||
<div class="content">
|
condition: condition,
|
||||||
${this._yamlMode
|
}
|
||||||
? html`
|
)}
|
||||||
<ha-yaml-editor
|
`
|
||||||
.hass=${this.hass}
|
}
|
||||||
.defaultValue=${this.condition}
|
</div>
|
||||||
@value-changed=${this._onYamlChange}
|
</ha-expansion-panel>
|
||||||
></ha-yaml-editor>
|
</ha-card>
|
||||||
`
|
|
||||||
: html`
|
|
||||||
${dynamicElement(`ha-card-condition-${condition.condition}`, {
|
|
||||||
hass: this.hass,
|
|
||||||
condition: condition,
|
|
||||||
})}
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,27 +240,39 @@ export default class HaCardConditionEditor extends LitElement {
|
|||||||
static styles = [
|
static styles = [
|
||||||
haStyle,
|
haStyle,
|
||||||
css`
|
css`
|
||||||
.header {
|
ha-button-menu {
|
||||||
display: flex;
|
--mdc-theme-text-primary-on-background: var(--primary-text-color);
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
}
|
||||||
.header span {
|
|
||||||
flex: 1;
|
ha-expansion-panel {
|
||||||
font-size: 16px;
|
--expansion-panel-summary-padding: 0 0 0 8px;
|
||||||
|
--expansion-panel-content-padding: 0;
|
||||||
|
}
|
||||||
|
.condition-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 870px) {
|
||||||
|
.condition-icon {
|
||||||
|
display: inline-block;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
opacity: 0.9;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
.header .icon {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
.selected_menu_item {
|
.selected_menu_item {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
li[role="separator"] {
|
.disabled {
|
||||||
border-bottom-color: var(--divider-color);
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { mdiPlus } from "@mdi/js";
|
import { mdiPlus } from "@mdi/js";
|
||||||
import { CSSResultGroup, LitElement, css, html } from "lit";
|
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||||
|
import "../../../../components/ha-alert";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-list-item";
|
import "../../../../components/ha-list-item";
|
||||||
import type { HaSelect } from "../../../../components/ha-select";
|
import type { HaSelect } from "../../../../components/ha-select";
|
||||||
@ -11,6 +12,7 @@ import type { HomeAssistant } from "../../../../types";
|
|||||||
import { ICON_CONDITION } from "../../common/icon-condition";
|
import { ICON_CONDITION } from "../../common/icon-condition";
|
||||||
import { Condition, LegacyCondition } from "../../common/validate-condition";
|
import { Condition, LegacyCondition } from "../../common/validate-condition";
|
||||||
import "./ha-card-condition-editor";
|
import "./ha-card-condition-editor";
|
||||||
|
import type { HaCardConditionEditor } from "./ha-card-condition-editor";
|
||||||
import { LovelaceConditionEditorConstructor } from "./types";
|
import { LovelaceConditionEditorConstructor } from "./types";
|
||||||
import "./types/ha-card-condition-numeric_state";
|
import "./types/ha-card-condition-numeric_state";
|
||||||
import "./types/ha-card-condition-screen";
|
import "./types/ha-card-condition-screen";
|
||||||
@ -33,22 +35,54 @@ export class HaCardConditionsEditor extends LitElement {
|
|||||||
| LegacyCondition
|
| LegacyCondition
|
||||||
)[];
|
)[];
|
||||||
|
|
||||||
|
private _focusLastConditionOnChange = false;
|
||||||
|
|
||||||
|
protected firstUpdated() {
|
||||||
|
// Expand the condition if there is only one
|
||||||
|
if (this.conditions.length === 1) {
|
||||||
|
const row = this.shadowRoot!.querySelector<HaCardConditionEditor>(
|
||||||
|
"ha-card-condition-editor"
|
||||||
|
)!;
|
||||||
|
row.updateComplete.then(() => {
|
||||||
|
row.expand();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProperties: PropertyValues) {
|
||||||
|
if (!changedProperties.has("conditions")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._focusLastConditionOnChange) {
|
||||||
|
this._focusLastConditionOnChange = false;
|
||||||
|
const row = this.shadowRoot!.querySelector<HaCardConditionEditor>(
|
||||||
|
"ha-card-condition-editor:last-of-type"
|
||||||
|
)!;
|
||||||
|
row.updateComplete.then(() => {
|
||||||
|
row.expand();
|
||||||
|
row.scrollIntoView();
|
||||||
|
row.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="conditions">
|
<div class="conditions">
|
||||||
${this.hass!.localize(
|
<ha-alert alert-type="info">
|
||||||
"ui.panel.lovelace.editor.condition-editor.explanation"
|
${this.hass!.localize(
|
||||||
)}
|
"ui.panel.lovelace.editor.condition-editor.explanation"
|
||||||
|
)}
|
||||||
|
</ha-alert>
|
||||||
${this.conditions.map(
|
${this.conditions.map(
|
||||||
(cond, idx) => html`
|
(cond, idx) => html`
|
||||||
<div class="condition">
|
<ha-card-condition-editor
|
||||||
<ha-card-condition-editor
|
.index=${idx}
|
||||||
.index=${idx}
|
@value-changed=${this._conditionChanged}
|
||||||
@value-changed=${this._conditionChanged}
|
.hass=${this.hass}
|
||||||
.hass=${this.hass}
|
.condition=${cond}
|
||||||
.condition=${cond}
|
></ha-card-condition-editor>
|
||||||
></ha-card-condition-editor>
|
|
||||||
</div>
|
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
@ -99,6 +133,7 @@ export class HaCardConditionsEditor extends LitElement {
|
|||||||
? { ...elClass.defaultConfig }
|
? { ...elClass.defaultConfig }
|
||||||
: { condition: condition }
|
: { condition: condition }
|
||||||
);
|
);
|
||||||
|
this._focusLastConditionOnChange = true;
|
||||||
fireEvent(this, "value-changed", { value: conditions });
|
fireEvent(this, "value-changed", { value: conditions });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,15 +158,14 @@ export class HaCardConditionsEditor extends LitElement {
|
|||||||
mwc-tab-bar {
|
mwc-tab-bar {
|
||||||
border-bottom: 1px solid var(--divider-color);
|
border-bottom: 1px solid var(--divider-color);
|
||||||
}
|
}
|
||||||
.conditions {
|
ha-alert {
|
||||||
margin-top: 8px;
|
display: block;
|
||||||
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
.condition {
|
ha-card-condition-editor {
|
||||||
margin-top: 8px;
|
display: block;
|
||||||
border: 1px solid var(--divider-color);
|
margin-top: 12px;
|
||||||
}
|
scroll-margin-top: 48px;
|
||||||
.condition .content {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
}
|
||||||
ha-button-menu {
|
ha-button-menu {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user