Compare commits

...

1 Commits

Author SHA1 Message Date
Aidan Timson
c726ce0f6a Migrate lovelace dialog(s) to wa 2026-02-05 15:45:06 +00:00
14 changed files with 657 additions and 713 deletions

View File

@@ -6,10 +6,11 @@ import { cache } from "lit/directives/cache";
import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-tab-group";
import "../../../../components/ha-tab-group-tab";
import "../../../../components/ha-wa-dialog";
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
import { haStyleDialog } from "../../../../resources/styles";
@@ -41,6 +42,8 @@ export class HuiCreateDialogBadge
@state() private _params?: CreateBadgeDialogParams;
@state() private _open = false;
@state() private _containerConfig!: LovelaceViewConfig;
@state() private _selectedEntities: string[] = [];
@@ -60,14 +63,20 @@ export class HuiCreateDialogBadge
}
this._containerConfig = containerConfig;
this._open = true;
}
public closeDialog(): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
this._open = false;
this._params = undefined;
this._currTab = "badge";
this._selectedEntities = [];
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected render() {
@@ -83,18 +92,18 @@ export class HuiCreateDialogBadge
: this.hass!.localize("ui.panel.lovelace.editor.edit_badge.pick_badge");
return html`
<ha-dialog
open
scrimClickAction
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
@keydown=${this._ignoreKeydown}
@closed=${this._cancel}
.heading=${title}
@closed=${this._dialogClosed}
class=${classMap({ table: this._currTab === "entity" })}
>
<ha-dialog-header show-border slot="heading">
<ha-dialog-header show-border slot="header">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
@click=${this._cancel}
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
@@ -104,7 +113,6 @@ export class HuiCreateDialogBadge
slot="nav"
.active=${this._currTab === "badge"}
panel="badge"
dialogInitialFocus
>
${this.hass!.localize(
"ui.panel.lovelace.editor.badge_picker.by_badge"
@@ -124,6 +132,7 @@ export class HuiCreateDialogBadge
this._currTab === "badge"
? html`
<hui-badge-picker
autofocus
.suggestedBadges=${this._params.suggestedBadges}
.lovelace=${this._params.lovelaceConfig}
.hass=${this.hass}
@@ -140,19 +149,23 @@ export class HuiCreateDialogBadge
`
)}
<div slot="primaryAction">
<ha-button appearance="plain" @click=${this._cancel}>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
${this._selectedEntities.length
? html`
<ha-button @click=${this._suggestBadges}>
<ha-button slot="primaryAction" @click=${this._suggestBadges}>
${this.hass!.localize("ui.common.continue")}
</ha-button>
`
: ""}
</div>
</ha-dialog>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -164,36 +177,14 @@ export class HuiCreateDialogBadge
return [
haStyleDialog,
css`
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
--mdc-dialog-max-height: 100%;
height: 100%;
}
}
@media all and (min-width: 850px) {
ha-dialog {
--mdc-dialog-min-width: 845px;
}
}
ha-dialog {
--mdc-dialog-max-width: 845px;
ha-wa-dialog {
--dialog-content-padding: 2px 24px 20px 24px;
--dialog-z-index: 6;
}
ha-dialog.table {
ha-wa-dialog.table {
--dialog-content-padding: 0;
}
@media (min-width: 1200px) {
ha-dialog {
--mdc-dialog-max-width: calc(100vw - 32px);
--mdc-dialog-min-width: 1000px;
}
}
ha-tab-group-tab {
flex: 1;
}

View File

@@ -6,8 +6,8 @@ import { customElement, property, query, state } from "lit/decorators";
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
import { fireEvent } from "../../../../common/dom/fire_event";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import "../../../../components/ha-icon-button";
import "../../../../components/ha-spinner";
import "../../../../components/ha-button";
@@ -61,6 +61,8 @@ export class HuiDialogEditBadge
@state() private _params?: EditBadgeDialogParams;
@state() private _open = false;
@state() private _badgeConfig?: LovelaceBadgeConfig;
@state() private _containerConfig!: LovelaceViewConfig;
@@ -86,6 +88,7 @@ export class HuiDialogEditBadge
this._params = params;
this._GUImode = true;
this._guiModeAvailable = true;
this._open = true;
const containerConfig = findLovelaceContainer(
params.lovelaceConfig,
@@ -113,20 +116,25 @@ export class HuiDialogEditBadge
}
public closeDialog(): boolean {
this._isEscapeEnabled = true;
window.removeEventListener("dialog-closed", this._enableEscapeKeyClose);
window.removeEventListener("hass-more-info", this._disableEscapeKeyClose);
if (this._dirty) {
this._confirmCancel();
return false;
}
this._open = false;
return true;
}
private _dialogClosed(): void {
this._open = false;
this._isEscapeEnabled = true;
window.removeEventListener("dialog-closed", this._enableEscapeKeyClose);
window.removeEventListener("hass-more-info", this._disableEscapeKeyClose);
this._params = undefined;
this._badgeConfig = undefined;
this._error = undefined;
this._documentationURL = undefined;
this._dirty = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected updated(changedProps: PropertyValues): void {
@@ -197,48 +205,46 @@ export class HuiDialogEditBadge
}
return html`
<ha-dialog
open
scrimClickAction
.escapeKeyAction=${this._isEscapeEnabled ? undefined : ""}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
?prevent-scrim-close=${!this._isEscapeEnabled}
@keydown=${this._ignoreKeydown}
@closed=${this._cancel}
@closed=${this._dialogClosed}
@opened=${this._opened}
.heading=${heading}
>
<ha-dialog-header slot="heading">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
<span slot="title" @click=${this._enlarge}>${heading}</span>
${this._documentationURL !== undefined
? html`
<a
slot="actionItems"
href=${this._documentationURL}
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
dir=${computeRTLDirection(this.hass)}
>
<ha-icon-button .path=${mdiHelpCircle}></ha-icon-button>
</a>
`
: nothing}
</ha-dialog-header>
<ha-icon-button
slot="headerNavigationIcon"
@click=${this._cancel}
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
<span slot="headerTitle" @click=${this._enlarge}>${heading}</span>
${this._documentationURL !== undefined
? html`
<a
slot="headerActionItems"
href=${this._documentationURL}
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
dir=${computeRTLDirection(this.hass)}
>
<ha-icon-button .path=${mdiHelpCircle}></ha-icon-button>
</a>
`
: nothing}
<div class="content">
<div class="element-editor">
<hui-badge-element-editor
autofocus
.hass=${this.hass}
.lovelace=${this._params.lovelaceConfig}
.value=${this._badgeConfig}
@config-changed=${this._handleConfigChanged}
@GUImode-changed=${this._handleGUIModeChanged}
@editor-save=${this._save}
dialogInitialFocus
></hui-badge-element-editor>
</div>
<div class="element-preview">
@@ -258,44 +264,45 @@ export class HuiDialogEditBadge
: ``}
</div>
</div>
${this._badgeConfig !== undefined
? html`
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._toggleMode}
.disabled=${!this._guiModeAvailable}
class="gui-mode-button"
>
${this.hass!.localize(
!this._badgeEditorEl || this._GUImode
? "ui.panel.lovelace.editor.edit_badge.show_code_editor"
: "ui.panel.lovelace.editor.edit_badge.show_visual_editor"
)}
</ha-button>
`
: nothing}
<ha-button
appearance="plain"
slot="primaryAction"
@click=${this._cancel}
dialogInitialFocus
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
${this._badgeConfig !== undefined && this._dirty
? html`
<ha-button
slot="primaryAction"
?disabled=${!this._canSave || this._saving}
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize("ui.common.save")}
</ha-button>
`
: nothing}
</ha-dialog>
<ha-dialog-footer slot="footer">
${this._badgeConfig !== undefined
? html`
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._toggleMode}
.disabled=${!this._guiModeAvailable}
class="gui-mode-button"
>
${this.hass!.localize(
!this._badgeEditorEl || this._GUImode
? "ui.panel.lovelace.editor.edit_badge.show_code_editor"
: "ui.panel.lovelace.editor.edit_badge.show_visual_editor"
)}
</ha-button>
`
: nothing}
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
${this._badgeConfig !== undefined && this._dirty
? html`
<ha-button
slot="primaryAction"
?disabled=${!this._canSave || this._saving}
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize("ui.common.save")}
</ha-button>
`
: nothing}
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -407,10 +414,8 @@ export class HuiDialogEditBadge
--code-mirror-max-height: calc(100vh - 176px);
}
ha-dialog {
--mdc-dialog-max-width: 100px;
ha-wa-dialog {
--dialog-z-index: 6;
--mdc-dialog-max-width: 90vw;
--dialog-content-padding: 24px 12px;
}
@@ -421,12 +426,6 @@ export class HuiDialogEditBadge
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
height: 100%;
--mdc-dialog-max-height: 100%;
--dialog-surface-top: 0px;
--mdc-dialog-max-width: 100vw;
}
.content {
width: 100%;
max-width: 100%;
@@ -495,12 +494,7 @@ export class HuiDialogEditBadge
margin-inline-end: auto;
margin-inline-start: initial;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
ha-dialog-header a {
ha-wa-dialog a[slot="headerActionItems"] {
color: inherit;
text-decoration: none;
}

View File

@@ -5,6 +5,8 @@ import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-yaml-editor";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
import type { LovelaceBadgeConfig } from "../../../../data/lovelace/config/badge";
@@ -24,6 +26,8 @@ export class HuiDialogSuggestBadge extends LitElement {
@state() private _params?: SuggestBadgeDialogParams;
@state() private _open = false;
@state() private _badgeConfig?: LovelaceBadgeConfig[];
@state() private _saving = false;
@@ -33,6 +37,7 @@ export class HuiDialogSuggestBadge extends LitElement {
public showDialog(params: SuggestBadgeDialogParams): void {
this._params = params;
this._badgeConfig = params.badgeConfig;
this._open = true;
if (!Object.isFrozen(this._badgeConfig)) {
this._badgeConfig = deepFreeze(this._badgeConfig);
}
@@ -42,6 +47,11 @@ export class HuiDialogSuggestBadge extends LitElement {
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._open = false;
this._params = undefined;
this._badgeConfig = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
@@ -71,13 +81,14 @@ export class HuiDialogSuggestBadge extends LitElement {
return nothing;
}
return html`
<ha-dialog
open
scrimClickAction
@closed=${this.closeDialog}
.heading=${this.hass!.localize(
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
header-title=${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_badge.header"
)}
@closed=${this._dialogClosed}
>
<div>
${this._renderPreview()}
@@ -92,30 +103,32 @@ export class HuiDialogSuggestBadge extends LitElement {
`
: nothing}
</div>
<ha-button
appearance="plain"
slot="primaryAction"
@click=${this.closeDialog}
dialogInitialFocus
>
${this._params.yaml
? this.hass!.localize("ui.common.close")
: this.hass!.localize("ui.common.cancel")}
</ha-button>
${!this._params.yaml
? html`
<ha-button
slot="primaryAction"
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_badge.add"
)}
</ha-button>
`
: nothing}
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this.closeDialog}
autofocus
>
${this._params.yaml
? this.hass!.localize("ui.common.close")
: this.hass!.localize("ui.common.cancel")}
</ha-button>
${!this._params.yaml
? html`
<ha-button
slot="primaryAction"
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_badge.add"
)}
</ha-button>
`
: nothing}
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -123,20 +136,7 @@ export class HuiDialogSuggestBadge extends LitElement {
return [
haStyleDialog,
css`
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
max-height: 100%;
height: 100%;
}
}
@media all and (min-width: 850px) {
ha-dialog {
width: 845px;
}
}
ha-dialog {
max-width: 845px;
ha-wa-dialog {
--dialog-z-index: 6;
}
.hidden {

View File

@@ -4,13 +4,13 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { cache } from "lit/directives/cache";
import { classMap } from "lit/directives/class-map";
import { ifDefined } from "lit/directives/if-defined";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-tab-group";
import "../../../../components/ha-tab-group-tab";
import "../../../../components/ha-wa-dialog";
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
import { isStrategySection } from "../../../../data/lovelace/config/section";
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
@@ -51,6 +51,8 @@ export class HuiCreateDialogCard
@state() private _params?: CreateCardDialogParams;
@state() private _open = false;
@state() private _containerConfig!:
| LovelaceViewConfig
| LovelaceSectionConfig;
@@ -78,14 +80,20 @@ export class HuiCreateDialogCard
}
this._containerConfig = containerConfig;
this._open = true;
}
public closeDialog(): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
this._open = false;
this._params = undefined;
this._currTab = "card";
this._selectedEntities = [];
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected render() {
@@ -101,18 +109,18 @@ export class HuiCreateDialogCard
: this.hass!.localize("ui.panel.lovelace.editor.edit_card.pick_card");
return html`
<ha-dialog
open
scrimClickAction
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
@keydown=${this._ignoreKeydown}
@closed=${this._cancel}
.heading=${title}
@closed=${this._dialogClosed}
class=${classMap({ table: this._currTab === "entity" })}
>
<ha-dialog-header show-border slot="heading">
<ha-dialog-header show-border slot="header">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
@click=${this._cancel}
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
@@ -123,7 +131,7 @@ export class HuiCreateDialogCard
slot="nav"
.active=${this._currTab === "card"}
panel="card"
dialogInitialFocus=${ifDefined(this._narrow ? "" : undefined)}
?autofocus=${this._narrow}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.cardpicker.by_card"
@@ -143,7 +151,7 @@ export class HuiCreateDialogCard
this._currTab === "card"
? html`
<hui-card-picker
dialogInitialFocus=${ifDefined(this._narrow ? undefined : "")}
?autofocus=${!this._narrow}
.suggestedCards=${this._params.suggestedCards}
.lovelace=${this._params.lovelaceConfig}
.hass=${this.hass}
@@ -160,19 +168,23 @@ export class HuiCreateDialogCard
`
)}
<div slot="primaryAction">
<ha-button appearance="plain" @click=${this._cancel}>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
${this._selectedEntities.length
? html`
<ha-button @click=${this._suggestCards}>
<ha-button slot="primaryAction" @click=${this._suggestCards}>
${this.hass!.localize("ui.common.continue")}
</ha-button>
`
: ""}
</div>
</ha-dialog>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -184,34 +196,14 @@ export class HuiCreateDialogCard
return [
haStyleDialog,
css`
@media all and (min-width: 850px) {
ha-dialog {
--mdc-dialog-min-width: 845px;
--mdc-dialog-min-height: calc(
100vh - var(--ha-space-18) - var(--safe-area-inset-y)
);
--mdc-dialog-max-height: calc(
100vh - var(--ha-space-18) - var(--safe-area-inset-y)
);
}
}
ha-dialog {
--mdc-dialog-max-width: 845px;
ha-wa-dialog {
--dialog-content-padding: 0 24px 20px 24px;
--dialog-z-index: 6;
}
ha-dialog.table {
ha-wa-dialog.table {
--dialog-content-padding: 0;
}
@media (min-width: 1200px) {
ha-dialog {
--mdc-dialog-max-width: calc(100vw - 32px);
--mdc-dialog-min-width: 1000px;
}
}
ha-tab-group-tab {
flex: 1;
}

View File

@@ -8,6 +8,8 @@ import { haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";
import "../../cards/hui-card";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import type { DeleteCardDialogParams } from "./show-delete-card-dialog";
@customElement("hui-dialog-delete-card")
@@ -16,17 +18,25 @@ export class HuiDialogDeleteCard extends LitElement {
@state() private _params?: DeleteCardDialogParams;
@state() private _open = false;
@state() private _cardConfig?: LovelaceCardConfig;
public async showDialog(params: DeleteCardDialogParams): Promise<void> {
this._params = params;
this._cardConfig = params.cardConfig;
this._open = true;
if (!Object.isFrozen(this._cardConfig)) {
this._cardConfig = deepFreeze(this._cardConfig);
}
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._open = false;
this._params = undefined;
this._cardConfig = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
@@ -38,10 +48,13 @@ export class HuiDialogDeleteCard extends LitElement {
}
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${this.hass.localize("ui.panel.lovelace.cards.confirm_delete")}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this.hass.localize(
"ui.panel.lovelace.cards.confirm_delete"
)}
@closed=${this._dialogClosed}
>
<div>
${this._cardConfig
@@ -56,18 +69,24 @@ export class HuiDialogDeleteCard extends LitElement {
`
: ""}
</div>
<ha-button
appearance="plain"
slot="primaryAction"
@click=${this.closeDialog}
dialogInitialFocus
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" class="warning" @click=${this._delete}>
${this.hass!.localize("ui.common.delete")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this.closeDialog}
autofocus
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button
slot="primaryAction"
class="warning"
@click=${this._delete}
>
${this.hass!.localize("ui.common.delete")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}

View File

@@ -9,8 +9,8 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import "../../../../components/ha-spinner";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import "../../../../components/ha-icon-button";
import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
@@ -60,6 +60,8 @@ export class HuiDialogEditCard
@state() private _params?: EditCardDialogParams;
@state() private _open = false;
@state() private _cardConfig?: LovelaceCardConfig;
@state() private _sectionConfig?: LovelaceSectionConfig;
@@ -83,6 +85,7 @@ export class HuiDialogEditCard
this._params = params;
this._GUImode = true;
this._guiModeAvailable = true;
this._open = true;
this._sectionConfig = this._params.sectionConfig;
@@ -100,13 +103,18 @@ export class HuiDialogEditCard
this._confirmCancel();
return false;
}
this._open = false;
return true;
}
private _dialogClosed(): void {
this._open = false;
this._params = undefined;
this._cardConfig = undefined;
this._error = undefined;
this._documentationURL = undefined;
this._dirty = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected updated(changedProps: PropertyValues): void {
@@ -157,41 +165,39 @@ export class HuiDialogEditCard
}
return html`
<ha-dialog
open
scrimClickAction
escapeKeyAction
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
@keydown=${this._ignoreKeydown}
@closed=${this._cancel}
@closed=${this._dialogClosed}
@opened=${this._opened}
.heading=${heading}
>
<ha-dialog-header slot="heading">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
<span slot="title" @click=${this._enlarge}>${heading}</span>
${this._documentationURL !== undefined
? html`
<a
slot="actionItems"
href=${this._documentationURL}
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
dir=${computeRTLDirection(this.hass)}
>
<ha-icon-button .path=${mdiHelpCircle}></ha-icon-button>
</a>
`
: nothing}
</ha-dialog-header>
<ha-icon-button
slot="headerNavigationIcon"
@click=${this._cancel}
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
<span slot="headerTitle" @click=${this._enlarge}>${heading}</span>
${this._documentationURL !== undefined
? html`
<a
slot="headerActionItems"
href=${this._documentationURL}
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
dir=${computeRTLDirection(this.hass)}
>
<ha-icon-button .path=${mdiHelpCircle}></ha-icon-button>
</a>
`
: nothing}
<div class="content">
<div class="element-editor">
<hui-card-element-editor
autofocus
.showVisibilityTab=${this._cardConfig.type !== "conditional"}
.sectionConfig=${this._sectionConfig}
.hass=${this.hass}
@@ -200,7 +206,6 @@ export class HuiDialogEditCard
@config-changed=${this._handleConfigChanged}
@GUImode-changed=${this._handleGUIModeChanged}
@editor-save=${this._save}
dialogInitialFocus
></hui-card-element-editor>
</div>
<div class="element-preview">
@@ -226,34 +231,35 @@ export class HuiDialogEditCard
: ``}
</div>
</div>
${this._cardConfig !== undefined
? html`
<ha-button
slot="secondaryAction"
@click=${this._toggleMode}
.disabled=${!this._guiModeAvailable}
class="gui-mode-button"
appearance="plain"
>
${this.hass!.localize(
!this._cardEditorEl || this._GUImode
? "ui.panel.lovelace.editor.edit_card.show_code_editor"
: "ui.panel.lovelace.editor.edit_card.show_visual_editor"
)}
</ha-button>
`
: ""}
<div slot="primaryAction" @click=${this._save}>
<ha-dialog-footer slot="footer">
${this._cardConfig !== undefined
? html`
<ha-button
slot="secondaryAction"
@click=${this._toggleMode}
.disabled=${!this._guiModeAvailable}
class="gui-mode-button"
appearance="plain"
>
${this.hass!.localize(
!this._cardEditorEl || this._GUImode
? "ui.panel.lovelace.editor.edit_card.show_code_editor"
: "ui.panel.lovelace.editor.edit_card.show_visual_editor"
)}
</ha-button>
`
: ""}
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._cancel}
dialogInitialFocus
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
${this._cardConfig !== undefined && this._dirty
? html`
<ha-button
slot="primaryAction"
?disabled=${!this._canSave}
@click=${this._save}
.loading=${this._saving}
@@ -262,8 +268,8 @@ export class HuiDialogEditCard
</ha-button>
`
: ``}
</div>
</ha-dialog>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -383,10 +389,8 @@ export class HuiDialogEditCard
--code-mirror-max-height: calc(100vh - 176px);
}
ha-dialog {
--mdc-dialog-max-width: 100px;
ha-wa-dialog {
--dialog-z-index: 6;
--mdc-dialog-max-width: 90vw;
--dialog-content-padding: 24px 12px;
}
@@ -397,12 +401,6 @@ export class HuiDialogEditCard
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
height: 100%;
--mdc-dialog-max-height: 100%;
--dialog-surface-top: 0px;
--mdc-dialog-max-width: 100vw;
}
.content {
width: 100%;
max-width: 100%;
@@ -498,20 +496,10 @@ export class HuiDialogEditCard
margin-inline-end: auto;
margin-inline-start: initial;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
ha-dialog-header a {
ha-wa-dialog a[slot="headerActionItems"] {
color: inherit;
text-decoration: none;
}
[slot="primaryAction"] {
gap: var(--ha-space-2);
display: flex;
}
`,
];
}

View File

@@ -5,6 +5,8 @@ import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-button";
import "../../../../components/ha-yaml-editor";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import "../../../../components/ha-spinner";
import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
@@ -30,6 +32,8 @@ export class HuiDialogSuggestCard extends LitElement {
@state() private _params?: SuggestCardDialogParams;
@state() private _open = false;
@state() private _cardConfig?: LovelaceCardConfig[];
@state() private _sectionConfig?: LovelaceSectionConfig;
@@ -42,6 +46,7 @@ export class HuiDialogSuggestCard extends LitElement {
this._params = params;
this._cardConfig = params.cardConfig;
this._sectionConfig = params.sectionConfig;
this._open = true;
if (!Object.isFrozen(this._cardConfig)) {
this._cardConfig = deepFreeze(this._cardConfig);
}
@@ -54,6 +59,11 @@ export class HuiDialogSuggestCard extends LitElement {
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._open = false;
this._params = undefined;
this._cardConfig = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
@@ -107,13 +117,14 @@ export class HuiDialogSuggestCard extends LitElement {
return nothing;
}
return html`
<ha-dialog
open
scrimClickAction
@closed=${this.closeDialog}
.heading=${this.hass!.localize(
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
header-title=${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_card.header"
)}
@closed=${this._dialogClosed}
>
<div>
${this._renderPreview()}
@@ -128,44 +139,46 @@ export class HuiDialogSuggestCard extends LitElement {
`
: nothing}
</div>
<ha-button
slot="secondaryAction"
@click=${this.closeDialog}
appearance="plain"
dialogInitialFocus
>
${this._params.yaml
? this.hass!.localize("ui.common.close")
: this.hass!.localize("ui.common.cancel")}
</ha-button>
${!this._params.yaml
? html`
${!(this._sectionConfig && this._viewSupportsSection)
? html`
<ha-button
appearance="plain"
slot="primaryAction"
@click=${this._pickCard}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_card.create_own"
)}
</ha-button>
`
: nothing}
<ha-button
slot="primaryAction"
.disabled=${this._saving}
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_card.add"
)}
</ha-button>
`
: nothing}
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
@click=${this.closeDialog}
appearance="plain"
autofocus
>
${this._params.yaml
? this.hass!.localize("ui.common.close")
: this.hass!.localize("ui.common.cancel")}
</ha-button>
${!this._params.yaml
? html`
${!(this._sectionConfig && this._viewSupportsSection)
? html`
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._pickCard}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_card.create_own"
)}
</ha-button>
`
: nothing}
<ha-button
slot="primaryAction"
.disabled=${this._saving}
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.suggest_card.add"
)}
</ha-button>
`
: nothing}
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -173,20 +186,7 @@ export class HuiDialogSuggestCard extends LitElement {
return [
haStyleDialog,
css`
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
max-height: 100%;
height: 100%;
}
}
@media all and (min-width: 850px) {
ha-dialog {
width: 845px;
}
}
ha-dialog {
max-width: 845px;
ha-wa-dialog {
--dialog-z-index: 6;
}
.hidden {

View File

@@ -1,17 +1,13 @@
import {
mdiAccountHardHat,
mdiClose,
mdiDotsVertical,
mdiPlaylistEdit,
} from "@mdi/js";
import { mdiAccountHardHat, mdiDotsVertical, mdiPlaylistEdit } from "@mdi/js";
import type { CSSResultGroup } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import type { HASSDomEvent } from "../../../../../common/dom/fire_event";
import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-button";
import "../../../../../components/ha-dialog";
import "../../../../../components/ha-dialog-header";
import "../../../../../components/ha-dialog-footer";
import "../../../../../components/ha-wa-dialog";
import "../../../../../components/ha-dropdown";
import "../../../../../components/ha-dropdown-item";
import "../../../../../components/ha-icon-button";
@@ -42,6 +38,8 @@ class DialogDashboardStrategyEditor extends LitElement {
@state() private _guiModeAvailable? = true;
@state() private _open = false;
@query("hui-dashboard-strategy-element-editor")
private _strategyEditorEl?: HuiDashboardStrategyElementEditor;
@@ -50,10 +48,15 @@ class DialogDashboardStrategyEditor extends LitElement {
): Promise<void> {
this._params = params;
this._strategyConfig = params.config.strategy;
this._open = true;
await this.updateComplete;
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._params = undefined;
this._strategyConfig = undefined;
this._guiModeAvailable = true;
@@ -73,10 +76,6 @@ class DialogDashboardStrategyEditor extends LitElement {
this._guiModeAvailable = ev.detail.guiModeAvailable;
}
private _opened() {
this._strategyEditorEl?.focusYamlEditor();
}
private async _save(): Promise<void> {
await this._params!.saveConfig({
...this._params!.config,
@@ -136,52 +135,40 @@ class DialogDashboardStrategyEditor extends LitElement {
);
return html`
<ha-dialog
open
@closed=${this.closeDialog}
scrimClickAction
escapeKeyAction
@opened=${this._opened}
.heading=${title || "-"}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${title || "-"}
header-subtitle=${ifDefined(this._params.title)}
width="large"
@closed=${this._dialogClosed}
>
<ha-dialog-header slot="heading">
<ha-dropdown
placement="bottom-end"
slot="headerActionItems"
@wa-select=${this._handleAction}
>
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<span slot="title" .title=${title}>${title}</span>
${this._params.title
? html`<span slot="subtitle">${this._params.title}</span>`
: nothing}
<ha-dropdown
placement="bottom-end"
slot="actionItems"
@wa-select=${this._handleAction}
<ha-dropdown-item
value="toggle-mode"
.disabled=${!this._guiModeAvailable && !this._GUImode}
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-dropdown-item
value="toggle-mode"
.disabled=${!this._guiModeAvailable && !this._GUImode}
>
${this.hass!.localize(
`ui.panel.lovelace.editor.edit_view.edit_${!this._GUImode ? "ui" : "yaml"}`
)}
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
</ha-dropdown-item>
<ha-dropdown-item value="take-control">
${this.hass.localize(
"ui.panel.lovelace.editor.strategy-editor.take_control"
)}
<ha-svg-icon slot="icon" .path=${mdiAccountHardHat}></ha-svg-icon>
</ha-dropdown-item>
</ha-dropdown>
</ha-dialog-header>
${this.hass!.localize(
`ui.panel.lovelace.editor.edit_view.edit_${!this._GUImode ? "ui" : "yaml"}`
)}
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
</ha-dropdown-item>
<ha-dropdown-item value="take-control">
${this.hass.localize(
"ui.panel.lovelace.editor.strategy-editor.take_control"
)}
<ha-svg-icon slot="icon" .path=${mdiAccountHardHat}></ha-svg-icon>
</ha-dropdown-item>
</ha-dropdown>
<div class="content">
<hui-dashboard-strategy-element-editor
.hass=${this.hass}
@@ -189,29 +176,31 @@ class DialogDashboardStrategyEditor extends LitElement {
.value=${config}
@config-changed=${this._handleConfigChanged}
@GUImode-changed=${this._handleGUIModeChanged}
dialogInitialFocus
autofocus
></hui-dashboard-strategy-element-editor>
</div>
<ha-button
variant="danger"
appearance="plain"
@click=${this._delete}
slot="secondaryAction"
>
${this.hass!.localize("ui.common.delete")}
</ha-button>
<ha-button
appearance="plain"
@click=${this._cancel}
slot="primaryAction"
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button @click=${this._save} slot="primaryAction">
${this.hass!.localize("ui.common.save")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
variant="danger"
appearance="plain"
@click=${this._delete}
>
${this.hass!.localize("ui.common.delete")}
</ha-button>
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._save}>
${this.hass!.localize("ui.common.save")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -220,34 +209,8 @@ class DialogDashboardStrategyEditor extends LitElement {
haStyleDialog,
haStyleDialogFixedTop,
css`
ha-dialog {
ha-wa-dialog {
--dialog-content-padding: 0 24px;
--mdc-dialog-min-width: min(
640px,
calc(100vw - var(--safe-area-inset-x))
);
--mdc-dialog-max-width: min(
640px,
calc(100vw - var(--safe-area-inset-x))
);
--mdc-dialog-max-height: calc(
100vh - var(--ha-space-20) - var(--safe-area-inset-y)
);
}
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
height: 100%;
--dialog-surface-top: 0px;
--mdc-dialog-min-width: 100vw;
--mdc-dialog-max-width: 100vw;
--mdc-dialog-min-height: 100vh;
--mdc-dialog-min-height: 100svh;
--mdc-dialog-max-height: 100vh;
--mdc-dialog-max-height: 100svh;
--dialog-content-padding: 8px;
}
}
`,
];

View File

@@ -3,7 +3,8 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-button";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
import { haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";
@@ -21,16 +22,23 @@ export class HuiCreateDialogHeaderFooter
@state() private _params?: CreateHeaderFooterDialogParams;
@state() private _open = false;
public async showDialog(
params: CreateHeaderFooterDialogParams
): Promise<void> {
this._params = params;
this._open = true;
}
public closeDialog(): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected render() {
@@ -39,22 +47,20 @@ export class HuiCreateDialogHeaderFooter
}
return html`
<ha-dialog
open
scrimClickAction
.heading=${createCloseHeading(
this.hass,
this.hass!.localize(
`ui.panel.lovelace.editor.header-footer.choose_header_footer`,
{
type: this.hass!.localize(
`ui.panel.lovelace.editor.header-footer.${this._params.type}`
),
}
)
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this.hass!.localize(
`ui.panel.lovelace.editor.header-footer.choose_header_footer`,
{
type: this.hass!.localize(
`ui.panel.lovelace.editor.header-footer.${this._params.type}`
),
}
)}
width="medium"
@keydown=${this._ignoreKeydown}
@closed=${this._cancel}
@closed=${this._dialogClosed}
>
<div class="elements">
${headerFooterElements.map(
@@ -67,7 +73,7 @@ export class HuiCreateDialogHeaderFooter
.type=${headerFooter.type}
@click=${this._handleHeaderFooterPicked}
@keyDown=${this._handleHeaderFooterPicked}
dialogInitialFocus
?autofocus=${index === 0}
>
<ha-svg-icon .path=${headerFooter.icon}></ha-svg-icon>
<div .id=${"card-name-" + index} role="none presentation">
@@ -79,12 +85,16 @@ export class HuiCreateDialogHeaderFooter
`
)}
</div>
<div slot="primaryAction">
<ha-button @click=${this._cancel}>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
</div>
</ha-dialog>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -129,22 +139,7 @@ export class HuiCreateDialogHeaderFooter
return [
haStyleDialog,
css`
@media all and (max-width: 450px), all and (max-height: 500px) {
/* overrule the ha-style-dialog max-height on small screens */
ha-dialog {
--mdc-dialog-max-height: 100%;
height: 100%;
}
}
@media all and (min-width: 850px) {
ha-dialog {
--mdc-dialog-min-width: 550px;
}
}
ha-dialog {
--mdc-dialog-max-width: 550px;
ha-wa-dialog {
--dialog-content-padding: 2px 24px 20px 24px;
--dialog-z-index: 6;
}

View File

@@ -1,11 +1,11 @@
import { mdiClose, mdiHelpCircle } from "@mdi/js";
import { mdiHelpCircle } from "@mdi/js";
import type { CSSResultGroup } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-button";
import "../../../components/ha-dialog";
import "../../../components/ha-dialog-header";
import "../../../components/ha-dialog-footer";
import "../../../components/ha-wa-dialog";
import "../../../components/ha-formfield";
import "../../../components/ha-icon-button";
import "../../../components/ha-switch";
@@ -30,6 +30,8 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
@state() private _saving: boolean;
@state() private _open = false;
public constructor() {
super();
this._saving = false;
@@ -38,12 +40,17 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
public showDialog(params: SaveDialogParams): void {
this._params = params;
this._emptyConfig = false;
this._open = true;
}
public closeDialog(): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected render() {
@@ -55,34 +62,25 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
"ui.panel.lovelace.editor.save_config.header"
);
return html`
<ha-dialog
open
scrimClickAction
escapeKeyAction
@closed=${this._close}
.heading=${heading}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${heading}
width="medium"
@closed=${this._dialogClosed}
>
<ha-dialog-header slot="heading">
<a
href=${documentationUrl(this.hass!, "/lovelace/")}
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
slot="headerActionItems"
>
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
.label=${this.hass!.localize("ui.common.close")}
.path=${mdiClose}
.path=${mdiHelpCircle}
.label=${this.hass!.localize("ui.common.help")}
></ha-icon-button>
<span slot="title">${heading}</span>
<a
href=${documentationUrl(this.hass!, "/lovelace/")}
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
target="_blank"
rel="noreferrer"
slot="actionItems"
>
<ha-icon-button
.path=${mdiHelpCircle}
.label=${this.hass!.localize("ui.common.help")}
></ha-icon-button>
</a>
</ha-dialog-header>
</a>
<div>
<p>
${this.hass!.localize("ui.panel.lovelace.editor.save_config.para")}
@@ -103,7 +101,7 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
<ha-switch
.checked=${this._emptyConfig}
@change=${this._emptyConfigChanged}
dialogInitialFocus
autofocus
></ha-switch
></ha-formfield>
`
@@ -126,47 +124,44 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
<ha-yaml-editor
.hass=${this.hass}
.defaultValue=${this._params!.lovelace.config}
dialogInitialFocus
autofocus
></ha-yaml-editor>
`}
</div>
${this._params.mode === "storage"
? html`
<ha-button
appearance="plain"
slot="primaryAction"
@click=${this.closeDialog}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button
slot="primaryAction"
@click=${this._saveConfig}
.loading=${this._saving}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.save_config.save"
)}
</ha-button>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this.closeDialog}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button
slot="primaryAction"
@click=${this._saveConfig}
.loading=${this._saving}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.save_config.save"
)}
</ha-button>
</ha-dialog-footer>
`
: html`
<ha-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass!.localize(
"ui.panel.lovelace.editor.save_config.close"
)}</ha-button
>
<ha-dialog-footer slot="footer">
<ha-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass!.localize(
"ui.panel.lovelace.editor.save_config.close"
)}
</ha-button>
</ha-dialog-footer>
`}
</ha-dialog>
</ha-wa-dialog>
`;
}
private _close(ev?: Event) {
if (ev) {
ev.stopPropagation();
}
this.closeDialog();
}
private _emptyConfigChanged(ev) {
this._emptyConfig = ev.target.checked;
}
@@ -196,11 +191,11 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
return [
haStyleDialog,
css`
ha-dialog {
ha-wa-dialog {
--dialog-content-padding: 0 24px 24px 24px;
}
ha-dialog-header a {
ha-wa-dialog [slot="headerActionItems"] {
color: inherit;
text-decoration: none;
}

View File

@@ -11,8 +11,9 @@ import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../../common/dom/fire_event";
import { stopPropagation } from "../../../../common/dom/stop_propagation";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import "../../../../components/ha-icon-button";
@@ -67,6 +68,8 @@ export class HuiDialogEditSection
@state() private _currTab: (typeof TABS)[number] = TABS[0];
@state() private _open = false;
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
protected updated(changedProperties: PropertyValues) {
@@ -80,6 +83,7 @@ export class HuiDialogEditSection
public async showDialog(params: EditSectionDialogParams): Promise<void> {
this._params = params;
this._open = true;
this.lovelace = params.lovelace;
@@ -93,12 +97,16 @@ export class HuiDialogEditSection
}
public closeDialog() {
this._open = false;
return true;
}
private _dialogClosed(): void {
this._params = undefined;
this._yamlMode = false;
this._config = undefined;
this._currTab = TABS[0];
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
protected render() {
@@ -116,7 +124,7 @@ export class HuiDialogEditSection
content = html`
<ha-yaml-editor
.hass=${this.hass}
dialogInitialFocus
autofocus
@value-changed=${this._viewYamlChanged}
></ha-yaml-editor>
`;
@@ -147,20 +155,20 @@ export class HuiDialogEditSection
}
return html`
<ha-dialog
open
scrimClickAction
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
@keydown=${this._ignoreKeydown}
@closed=${this._cancel}
.heading=${heading}
@closed=${this._dialogClosed}
class=${classMap({
"yaml-mode": this._yamlMode,
})}
>
<ha-dialog-header show-border slot="heading">
<ha-dialog-header show-border slot="header">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
@click=${this._cancel}
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
@@ -213,18 +221,20 @@ export class HuiDialogEditSection
: nothing}
</ha-dialog-header>
${content}
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._save}>
${this.hass!.localize("ui.common.save")}
</ha-button>
</ha-dialog>
<ha-button slot="primaryAction" @click=${this._save}>
${this.hass!.localize("ui.common.save")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -417,7 +427,7 @@ export class HuiDialogEditSection
haStyleDialog,
haStyleDialogFixedTop,
css`
ha-dialog.yaml-mode {
ha-wa-dialog.yaml-mode {
--dialog-content-padding: 0;
}
ha-tab-group-tab {
@@ -427,11 +437,6 @@ export class HuiDialogEditSection
width: 100%;
justify-content: center;
}
@media all and (min-width: 600px) {
ha-dialog {
--mdc-dialog-min-width: 600px;
}
}
`,
];
}

View File

@@ -4,11 +4,12 @@ import { customElement, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-alert";
import "../../../../components/ha-button";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-icon";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-list";
import "../../../../components/ha-radio-list-item";
import "../../../../components/ha-select";
import "../../../../components/ha-wa-dialog";
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
import { fetchConfig } from "../../../../data/lovelace/config/types";
import { isStrategyView } from "../../../../data/lovelace/config/view";
@@ -41,16 +42,23 @@ export class HuiDialogSelectView extends LitElement {
@state() private _selectedViewIdx = 0;
@state() private _open = false;
public showDialog(params: SelectViewDialogParams): void {
this._config = params.lovelaceConfig;
this._urlPath = params.urlPath;
this._params = params;
this._open = true;
if (this._params.allowDashboardChange) {
this._getDashboards();
}
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -63,14 +71,13 @@ export class HuiDialogSelectView extends LitElement {
const defaultPanel = getDefaultPanelUrlPath(this.hass);
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${createCloseHeading(
this.hass,
this._params.header ||
this.hass.localize("ui.panel.lovelace.editor.select_view.header")
)}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this._params.header ||
this.hass.localize("ui.panel.lovelace.editor.select_view.header")}
width="medium"
@closed=${this._dialogClosed}
>
${this._params.allowDashboardChange
? html`<ha-select
@@ -80,6 +87,7 @@ export class HuiDialogSelectView extends LitElement {
.disabled=${!this._dashboards.length}
.value=${this._urlPath || defaultPanel}
@selected=${this._dashboardChanged}
autofocus
.options=${this._dashboards
.map((dashboard) => ({
value: dashboard.url_path,
@@ -93,7 +101,6 @@ export class HuiDialogSelectView extends LitElement {
? 1
: a.label.localeCompare(b.label)
)}
dialogInitialFocus
>
</ha-select>`
: nothing}
@@ -107,7 +114,7 @@ export class HuiDialogSelectView extends LitElement {
>`
: this._config.views.length > 1
? html`
<ha-list dialogInitialFocus>
<ha-list>
${this._config.views.map((view, idx) => {
const isStrategy = isStrategyView(view);
@@ -121,6 +128,8 @@ export class HuiDialogSelectView extends LitElement {
.selected=${this._selectedViewIdx === idx}
.disabled=${isStrategy &&
!this._params?.includeStrategyViews}
?autofocus=${idx === 0 &&
!this._params!.allowDashboardChange}
>
<span>
${view.title}${isStrategy
@@ -135,22 +144,23 @@ export class HuiDialogSelectView extends LitElement {
</ha-list>
`
: nothing}
<ha-button
slot="primaryAction"
@click=${this.closeDialog}
dialogInitialFocus
appearance="plain"
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button
slot="primaryAction"
.disabled=${!this._config || (this._config.views || []).length < 1}
@click=${this._selectView}
>
${this._params.actionLabel || this.hass!.localize("ui.common.move")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
@click=${this.closeDialog}
appearance="plain"
>
${this.hass!.localize("ui.common.cancel")}
</ha-button>
<ha-button
slot="primaryAction"
.disabled=${!this._config || (this._config.views || []).length < 1}
@click=${this._selectView}
>
${this._params.actionLabel || this.hass!.localize("ui.common.move")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}

View File

@@ -14,8 +14,9 @@ import { navigate } from "../../../../common/navigate";
import { deepEqual } from "../../../../common/util/deep-equal";
import "../../../../components/ha-alert";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import "../../../../components/ha-spinner";
@@ -85,6 +86,8 @@ export class HuiDialogEditView extends LitElement {
@state() private _currentType = getViewType();
@state() private _open = false;
get _type(): string {
return getViewType(this._config);
}
@@ -100,6 +103,7 @@ export class HuiDialogEditView extends LitElement {
public showDialog(params: EditViewDialogParams): void {
this._params = params;
this._open = true;
if (this._params.viewIndex === undefined) {
this._config = {
@@ -123,6 +127,10 @@ export class HuiDialogEditView extends LitElement {
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._params = undefined;
this._config = {};
this._yamlMode = false;
@@ -153,7 +161,7 @@ export class HuiDialogEditView extends LitElement {
content = html`
<ha-yaml-editor
.hass=${this.hass}
dialogInitialFocus
autofocus
@value-changed=${this._viewYamlChanged}
></ha-yaml-editor>
`;
@@ -200,20 +208,19 @@ export class HuiDialogEditView extends LitElement {
this._config?.sections?.length;
return html`
<ha-dialog
open
scrimClickAction
escapeKeyAction
@closed=${this.closeDialog}
.heading=${this._viewConfigTitle}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="large"
@closed=${this._dialogClosed}
class=${classMap({
"yaml-mode": this._yamlMode,
})}
>
<ha-dialog-header show-border slot="heading">
<ha-dialog-header show-border slot="header">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
@click=${this.closeDialog}
.label=${this.hass!.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
@@ -290,37 +297,39 @@ export class HuiDialogEditView extends LitElement {
: nothing}
</ha-dialog-header>
${content}
${this._params.viewIndex !== undefined
? html`
<ha-button
variant="danger"
appearance="plain"
slot="secondaryAction"
@click=${this._deleteConfirm}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.edit_view.delete"
)}
</ha-button>
`
: nothing}
<ha-button
class="save"
slot="primaryAction"
?disabled=${!this._config ||
this._saving ||
!this._dirty ||
!this._valid ||
convertToSection ||
convertNotSupported}
@click=${this._save}
>
${this._saving
? html`<ha-spinner size="small" aria-label="Saving"></ha-spinner>`
<ha-dialog-footer slot="footer">
${this._params.viewIndex !== undefined
? html`
<ha-button
slot="secondaryAction"
variant="danger"
appearance="plain"
@click=${this._deleteConfirm}
>
${this.hass!.localize(
"ui.panel.lovelace.editor.edit_view.delete"
)}
</ha-button>
`
: nothing}
${this.hass!.localize("ui.common.save")}</ha-button
>
</ha-dialog>
<ha-button
class="save"
slot="primaryAction"
?disabled=${!this._config ||
this._saving ||
!this._dirty ||
!this._valid ||
convertToSection ||
convertNotSupported}
@click=${this._save}
>
${this._saving
? html`<ha-spinner size="small" aria-label="Saving"></ha-spinner>`
: nothing}
${this.hass!.localize("ui.common.save")}</ha-button
>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -634,7 +643,7 @@ export class HuiDialogEditView extends LitElement {
haStyleDialog,
haStyleDialogFixedTop,
css`
ha-dialog.yaml-mode {
ha-wa-dialog.yaml-mode {
--dialog-content-padding: 0;
}
h2 {
@@ -676,12 +685,6 @@ export class HuiDialogEditView extends LitElement {
left: 50%;
transform: translate(-50%, -50%);
}
@media all and (min-width: 600px) {
ha-dialog {
--mdc-dialog-min-width: 600px;
}
}
`,
];
}

View File

@@ -1,4 +1,4 @@
import { mdiClose, mdiDotsVertical, mdiPlaylistEdit } from "@mdi/js";
import { mdiDotsVertical, mdiPlaylistEdit } from "@mdi/js";
import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
@@ -6,8 +6,8 @@ import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../../common/dom/fire_event";
import { deepEqual } from "../../../../common/util/deep-equal";
import "../../../../components/ha-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-wa-dialog";
import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import "../../../../components/ha-spinner";
@@ -40,6 +40,8 @@ export class HuiDialogEditViewHeader extends LitElement {
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
@state() private _open = false;
protected updated(changedProperties: PropertyValues) {
if (this._yamlMode && changedProperties.has("_yamlMode")) {
const config = {
@@ -54,9 +56,14 @@ export class HuiDialogEditViewHeader extends LitElement {
this._dirty = false;
this._config = this._params.config;
this._open = true;
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._params = undefined;
this._config = undefined;
this._yamlMode = false;
@@ -76,7 +83,7 @@ export class HuiDialogEditViewHeader extends LitElement {
content = html`
<ha-yaml-editor
.hass=${this.hass}
dialogInitialFocus
autofocus
@value-changed=${this._viewYamlChanged}
></ha-yaml-editor>
`;
@@ -95,52 +102,45 @@ export class HuiDialogEditViewHeader extends LitElement {
);
return html`
<ha-dialog
open
scrimClickAction
escapeKeyAction
@closed=${this.closeDialog}
.heading=${title}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${title}
width="large"
@closed=${this._dialogClosed}
class=${classMap({
"yaml-mode": this._yamlMode,
})}
>
<ha-dialog-header show-border slot="heading">
<ha-dropdown
slot="headerActionItems"
placement="bottom-end"
@wa-select=${this._handleAction}
>
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
.label=${this.hass!.localize("ui.common.close")}
.path=${mdiClose}
slot="trigger"
.label=${this.hass!.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<h2 slot="title">${title}</h2>
<ha-dropdown
slot="actionItems"
placement="bottom-end"
@wa-select=${this._handleAction}
>
<ha-icon-button
slot="trigger"
.label=${this.hass!.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-dropdown-item value="toggle-mode">
${this.hass!.localize(
`ui.panel.lovelace.editor.edit_view_header.edit_${!this._yamlMode ? "yaml" : "ui"}`
)}
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
</ha-dropdown-item>
</ha-dropdown>
</ha-dialog-header>
<ha-dropdown-item value="toggle-mode">
${this.hass!.localize(
`ui.panel.lovelace.editor.edit_view_header.edit_${!this._yamlMode ? "yaml" : "ui"}`
)}
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
</ha-dropdown-item>
</ha-dropdown>
${content}
<ha-button
slot="primaryAction"
.disabled=${!this._config || this._saving || !this._dirty}
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize("ui.common.save")}</ha-button
>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="primaryAction"
.disabled=${!this._config || this._saving || !this._dirty}
@click=${this._save}
.loading=${this._saving}
>
${this.hass!.localize("ui.common.save")}</ha-button
>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -198,20 +198,9 @@ export class HuiDialogEditViewHeader extends LitElement {
haStyleDialog,
haStyleDialogFixedTop,
css`
ha-dialog.yaml-mode {
ha-wa-dialog.yaml-mode {
--dialog-content-padding: 0;
}
h2 {
margin: 0;
font-size: inherit;
font-weight: inherit;
}
@media all and (min-width: 600px) {
ha-dialog {
--mdc-dialog-min-width: 600px;
}
}
`,
];
}