Compare commits

...

2 Commits

Author SHA1 Message Date
Aidan Timson
a11a6a1a23 Remove profile and todo dialogs from shared migration 2026-02-05 15:46:30 +00:00
Aidan Timson
ff8673834b Migrate shared dialog(s) to wa 2026-02-05 15:43:06 +00:00
11 changed files with 438 additions and 375 deletions

View File

@@ -9,10 +9,11 @@ import { fireEvent } from "../../common/dom/fire_event";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
import "../ha-button";
import { createCloseHeading } from "../ha-dialog";
import "../ha-dialog-footer";
import "../ha-list";
import "../ha-list-item";
import "../ha-sortable";
import "../ha-wa-dialog";
import type {
DataTableColumnContainer,
DataTableColumnData,
@@ -29,13 +30,20 @@ export class DialogDataTableSettings extends LitElement {
@state() private _hiddenColumns?: string[];
@state() private _open = false;
public showDialog(params: DataTableSettingsDialogParams) {
this._params = params;
this._columnOrder = params.columnOrder;
this._hiddenColumns = params.hiddenColumns;
this._open = true;
}
public closeDialog() {
this._open = false;
}
private _dialogClosed() {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -91,13 +99,11 @@ export class DialogDataTableSettings extends LitElement {
);
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${createCloseHeading(
this.hass,
localize("ui.components.data-table.settings.header")
)}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${localize("ui.components.data-table.settings.header")}
@closed=${this._dialogClosed}
>
<ha-sortable
@item-moved=${this._columnMoved}
@@ -152,16 +158,18 @@ export class DialogDataTableSettings extends LitElement {
)}
</ha-list>
</ha-sortable>
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._reset}
>${localize("ui.components.data-table.settings.restore")}</ha-button
>
<ha-button slot="primaryAction" @click=${this.closeDialog}>
${localize("ui.components.data-table.settings.done")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._reset}
>${localize("ui.components.data-table.settings.restore")}</ha-button
>
<ha-button slot="primaryAction" @click=${this.closeDialog}>
${localize("ui.components.data-table.settings.done")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -281,22 +289,10 @@ export class DialogDataTableSettings extends LitElement {
return [
haStyleDialog,
css`
ha-dialog {
--mdc-dialog-max-width: 500px;
ha-wa-dialog {
--dialog-z-index: 10;
--dialog-content-padding: 0 8px;
}
@media all and (max-width: 451px) {
ha-dialog {
--vertical-align-dialog: flex-start;
--dialog-surface-margin-top: 250px;
--ha-dialog-border-radius: var(--ha-border-radius-4xl)
var(--ha-border-radius-4xl) var(--ha-border-radius-square)
var(--ha-border-radius-square);
--mdc-dialog-min-height: calc(100% - 250px);
--mdc-dialog-max-height: calc(100% - 250px);
}
}
ha-list-item {
--mdc-list-side-padding: 12px;
overflow: visible;

View File

@@ -7,8 +7,9 @@ import { nextRender } from "../common/util/render-status";
import { haStyleDialog } from "../resources/styles";
import type { HomeAssistant } from "../types";
import type { DatePickerDialogParams } from "./ha-date-input";
import "./ha-dialog";
import "./ha-button";
import "./ha-dialog-footer";
import "./ha-wa-dialog";
@customElement("ha-dialog-date-picker")
export class HaDialogDatePicker extends LitElement {
@@ -22,6 +23,8 @@ export class HaDialogDatePicker extends LitElement {
@state() private _params?: DatePickerDialogParams;
@state() private _open = false;
@state() private _value?: string;
public async showDialog(params: DatePickerDialogParams): Promise<void> {
@@ -30,9 +33,14 @@ export class HaDialogDatePicker extends LitElement {
await nextRender();
this._params = params;
this._value = params.value;
this._open = true;
}
public closeDialog() {
this._open = false;
}
private _dialogClosed() {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -41,7 +49,12 @@ export class HaDialogDatePicker extends LitElement {
if (!this._params) {
return nothing;
}
return html`<ha-dialog open @closed=${this.closeDialog}>
return html`<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
width="small"
@closed=${this._dialogClosed}
>
<app-datepicker
.value=${this._value}
.min=${this._params.min}
@@ -50,35 +63,36 @@ export class HaDialogDatePicker extends LitElement {
@datepicker-value-updated=${this._valueChanged}
.firstDayOfWeek=${this._params.firstWeekday}
></app-datepicker>
${this._params.canClear
? html`<ha-button
slot="secondaryAction"
@click=${this._clear}
variant="danger"
appearance="plain"
>
${this.hass.localize("ui.dialogs.date-picker.clear")}
</ha-button>`
: nothing}
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._setToday}
>
${this.hass.localize("ui.dialogs.date-picker.today")}
</ha-button>
<ha-button
appearance="plain"
slot="primaryAction"
dialogaction="cancel"
class="cancel-btn"
>
${this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._setValue}>
${this.hass.localize("ui.common.ok")}
</ha-button>
</ha-dialog>`;
<ha-dialog-footer slot="footer">
${this._params.canClear
? html`<ha-button
slot="secondaryAction"
@click=${this._clear}
variant="danger"
appearance="plain"
>
${this.hass.localize("ui.dialogs.date-picker.clear")}
</ha-button>`
: nothing}
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this._setToday}
>
${this.hass.localize("ui.dialogs.date-picker.today")}
</ha-button>
<ha-button
appearance="plain"
slot="secondaryAction"
@click=${this.closeDialog}
>
${this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._setValue}>
${this.hass.localize("ui.common.ok")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>`;
}
private _valueChanged(ev: CustomEvent) {
@@ -108,9 +122,8 @@ export class HaDialogDatePicker extends LitElement {
static styles = [
haStyleDialog,
css`
ha-dialog {
ha-wa-dialog {
--dialog-content-padding: 0;
--justify-action-buttons: space-between;
}
app-datepicker {
--app-datepicker-accent-color: var(--primary-color);
@@ -129,11 +142,6 @@ export class HaDialogDatePicker extends LitElement {
app-datepicker::part(body) {
direction: ltr;
}
@media all and (min-width: 450px) {
ha-dialog {
--mdc-dialog-min-width: 300px;
}
}
@media all and (max-width: 450px), all and (max-height: 500px) {
app-datepicker {
width: 100%;

View File

@@ -6,8 +6,7 @@ import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import type { HASSDomEvent } from "../../common/dom/fire_event";
import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-dialog";
import "../../components/ha-dialog-header";
import "../../components/ha-wa-dialog";
import "../../components/ha-icon-button";
import type { DataEntryFlowStep } from "../../data/data_entry_flow";
import {
@@ -64,6 +63,8 @@ class DataEntryFlowDialog extends LitElement {
private _instance = instance;
@state() private _open = false;
@state() private _step:
| DataEntryFlowStep
| undefined
@@ -77,6 +78,7 @@ class DataEntryFlowDialog extends LitElement {
public async showDialog(params: DataEntryFlowDialogParams): Promise<void> {
this._params = params;
this._instance = instance++;
this._open = true;
const curInstance = this._instance;
let step: DataEntryFlowStep;
@@ -146,6 +148,17 @@ class DataEntryFlowDialog extends LitElement {
}
public closeDialog() {
if (!this._params) {
return;
}
if (!this._open) {
this._dialogClosed();
return;
}
this._open = false;
}
private _dialogClosed(): void {
if (!this._params) {
return;
}
@@ -174,6 +187,7 @@ class DataEntryFlowDialog extends LitElement {
this._unsubDataEntryFlowProgress();
this._unsubDataEntryFlowProgress = undefined;
}
this._open = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -289,56 +303,51 @@ class DataEntryFlowDialog extends LitElement {
const dialogSubtitle = this._getDialogSubtitle();
return html`
<ha-dialog
open
@closed=${this.closeDialog}
scrimClickAction
escapeKeyAction
hideActions
.heading=${dialogTitle || true}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
@closed=${this._dialogClosed}
>
<ha-dialog-header slot="heading">
<ha-icon-button
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
dialogAction="close"
slot="navigationIcon"
></ha-icon-button>
<ha-icon-button
slot="headerNavigationIcon"
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
data-dialog="close"
></ha-icon-button>
<div
slot="title"
class="dialog-title${this._step?.type === "form" ? " form" : ""}"
title=${dialogTitle}
>
${dialogTitle}
</div>
<div
slot="headerTitle"
class="dialog-title${this._step?.type === "form" ? " form" : ""}"
title=${dialogTitle}
>
${dialogTitle}
</div>
${dialogSubtitle
? html` <div slot="subtitle">${dialogSubtitle}</div>`
: nothing}
${showDocumentationLink && !this._loading && this._step
? html`
<a
slot="actionItems"
class="help"
href=${this._params.manifest!.is_built_in
? documentationUrl(
this.hass,
`/integrations/${this._params.manifest!.domain}`
)
: this._params.manifest!.documentation}
target="_blank"
rel="noreferrer noopener"
${dialogSubtitle
? html` <div slot="headerSubtitle">${dialogSubtitle}</div>`
: nothing}
${showDocumentationLink && !this._loading && this._step
? html`
<a
slot="headerActionItems"
class="help"
href=${this._params.manifest!.is_built_in
? documentationUrl(
this.hass,
`/integrations/${this._params.manifest!.domain}`
)
: this._params.manifest!.documentation}
target="_blank"
rel="noreferrer noopener"
>
<ha-icon-button
.label=${this.hass.localize("ui.common.help")}
.path=${mdiHelpCircle}
>
<ha-icon-button
.label=${this.hass.localize("ui.common.help")}
.path=${mdiHelpCircle}
>
</ha-icon-button
></a>
`
: nothing}
</ha-dialog-header>
</ha-icon-button
></a>
`
: nothing}
<div>
${this._loading || this._step === null
? html`
@@ -417,7 +426,7 @@ class DataEntryFlowDialog extends LitElement {
`}
`}
</div>
</ha-dialog>
</ha-wa-dialog>
`;
}
@@ -551,7 +560,7 @@ class DataEntryFlowDialog extends LitElement {
return [
haStyleDialog,
css`
ha-dialog {
ha-wa-dialog {
--dialog-content-padding: 0;
}
.dialog-title {

View File

@@ -2,11 +2,11 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-bottom-sheet";
import { createCloseHeading } from "../../components/ha-dialog";
import "../../components/ha-icon";
import "../../components/ha-md-list";
import "../../components/ha-md-list-item";
import "../../components/ha-svg-icon";
import "../../components/ha-wa-dialog";
import type { HomeAssistant } from "../../types";
import type { HassDialog } from "../make-dialog-manager";
import type { ListItemsDialogParams } from "./show-list-items-dialog";
@@ -20,8 +20,16 @@ export class ListItemsDialog
@state() private _params?: ListItemsDialogParams;
@state() private _open = false;
public async showDialog(params: ListItemsDialogParams): Promise<void> {
this._params = params;
this._open = true;
}
public closeDialog(_historyState?: any): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
@@ -33,7 +41,7 @@ export class ListItemsDialog
const item = (ev.currentTarget as any).item;
if (!item) return;
item.action();
this._dialogClosed();
this.closeDialog();
}
protected render() {
@@ -83,26 +91,30 @@ export class ListItemsDialog
if (this._params.mode === "bottom-sheet") {
return html`
<ha-bottom-sheet placement="bottom" open @closed=${this._dialogClosed}>
<ha-bottom-sheet
placement="bottom"
.open=${this._open}
@closed=${this._dialogClosed}
>
${content}
</ha-bottom-sheet>
`;
}
return html`
<ha-dialog
open
.heading=${createCloseHeading(this.hass, this._params.title ?? " ")}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this._params.title ?? " "}
@closed=${this._dialogClosed}
hideActions
>
${content}
</ha-dialog>
</ha-wa-dialog>
`;
}
static styles = css`
ha-dialog {
ha-wa-dialog {
/* Place above other dialogs */
--dialog-z-index: 104;
--dialog-content-padding: 0;

View File

@@ -5,8 +5,9 @@ import { ifDefined } from "lit/directives/if-defined";
import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-button";
import "../../components/ha-control-button";
import { createCloseHeading } from "../../components/ha-dialog";
import "../../components/ha-dialog-footer";
import "../../components/ha-textfield";
import "../../components/ha-wa-dialog";
import type { HaTextField } from "../../components/ha-textfield";
import type { HomeAssistant } from "../../types";
import type { HassDialog } from "../make-dialog-manager";
@@ -36,34 +37,51 @@ export class DialogEnterCode
@state() private _dialogParams?: EnterCodeDialogParams;
@state() private _open = false;
@query("#code") private _input?: HaTextField;
@state() private _showClearButton = false;
@state() private _narrow = false;
private _closeAction?: "submit" | "cancel";
public async showDialog(dialogParams: EnterCodeDialogParams): Promise<void> {
this._dialogParams = dialogParams;
this._open = true;
this._showClearButton = false;
this._closeAction = undefined;
this._narrow = matchMedia(
"all and (max-width: 450px), all and (max-height: 500px)"
).matches;
await this.updateComplete;
}
public closeDialog() {
public closeDialog(): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
if (!this._closeAction) {
this._dialogParams?.cancel?.();
}
this._dialogParams = undefined;
this._showClearButton = false;
this._closeAction = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true;
}
private _submit(): void {
this._dialogParams?.submit?.(this._input?.value ?? "");
this._closeAction = "submit";
this.closeDialog();
}
private _cancel(): void {
this._dialogParams?.cancel?.();
this._closeAction = "cancel";
this.closeDialog();
}
@@ -93,15 +111,16 @@ export class DialogEnterCode
if (isText) {
return html`
<ha-dialog
open
@closed=${this._cancel}
.heading=${this._dialogParams.title ??
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this._dialogParams.title ??
this.hass.localize("ui.dialogs.enter_code.title")}
@closed=${this._dialogClosed}
>
<ha-textfield
class="input"
?dialogInitialFocus=${!this._narrow}
?autofocus=${!this._narrow}
id="code"
.label=${this.hass.localize("ui.dialogs.enter_code.input_label")}
type="password"
@@ -110,31 +129,30 @@ export class DialogEnterCode
pattern=${ifDefined(this._dialogParams.codePattern)}
inputmode="text"
></ha-textfield>
<ha-button
appearance="plain"
slot="secondaryAction"
dialogAction="cancel"
>
${this._dialogParams.cancelText ??
this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button @click=${this._submit} slot="primaryAction">
${this._dialogParams.submitText ??
this.hass.localize("ui.common.submit")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this._dialogParams.cancelText ??
this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._submit}>
${this._dialogParams.submitText ??
this.hass.localize("ui.common.submit")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
return html`
<ha-dialog
open
.heading=${createCloseHeading(
this.hass,
this._dialogParams.title ?? "Enter code"
)}
@closed=${this._cancel}
hideActions
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this._dialogParams.title ?? "Enter code"}
@closed=${this._dialogClosed}
>
<div class="container">
<ha-textfield
@@ -143,7 +161,7 @@ export class DialogEnterCode
.label=${this.hass.localize("ui.dialogs.enter_code.input_label")}
type="password"
inputmode="numeric"
?dialogInitialFocus=${!this._narrow}
?autofocus=${!this._narrow}
></ha-textfield>
<div class="keypad">
${BUTTONS.map((value) =>
@@ -183,12 +201,12 @@ export class DialogEnterCode
)}
</div>
</div>
</ha-dialog>
</ha-wa-dialog>
`;
}
static styles = css`
ha-dialog {
ha-wa-dialog {
/* Place above other dialogs */
--dialog-z-index: 104;
}

View File

@@ -2,8 +2,9 @@ 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-form/ha-form";
import "../../components/ha-dialog-footer";
import "../../components/ha-wa-dialog";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
import type { HassDialog } from "../make-dialog-manager";
@@ -20,24 +21,40 @@ export class DialogForm
@state() private _data: FormDialogData = {};
@state() private _open = false;
@state() private _closeState?: "canceled" | "submitted";
public async showDialog(params: FormDialogParams): Promise<void> {
this._params = params;
this._data = params.data || {};
this._open = true;
}
public closeDialog() {
this._params = undefined;
this._data = {};
fireEvent(this, "dialog-closed", { dialog: this.localName });
public closeDialog(): boolean {
this._open = false;
return true;
}
private _dialogClosed(): void {
if (!this._closeState) {
this._params?.cancel?.();
}
this._closeState = undefined;
this._params = undefined;
this._data = {};
this._open = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
private _submit(): void {
this._closeState = "submitted";
this._params?.submit?.(this._data);
this.closeDialog();
}
private _cancel(): void {
this._closeState = "canceled";
this._params?.cancel?.();
this.closeDialog();
}
@@ -52,15 +69,14 @@ export class DialogForm
}
return html`
<ha-dialog
open
scrimClickAction
escapeKeyAction
.heading=${createCloseHeading(this.hass, this._params.title)}
@closed=${this._cancel}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this._params.title}
@closed=${this._dialogClosed}
>
<ha-form
dialogInitialFocus
autofocus
.hass=${this.hass}
.computeLabel=${this._params.computeLabel}
.computeHelper=${this._params.computeHelper}
@@ -69,17 +85,19 @@ export class DialogForm
@value-changed=${this._valueChanged}
>
</ha-form>
<ha-button
appearance="plain"
@click=${this._cancel}
slot="secondaryAction"
>
${this._params.cancelText || this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button @click=${this._submit} slot="primaryAction">
${this._params.submitText || this.hass.localize("ui.common.save")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._cancel}
>
${this._params.cancelText || this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._submit}>
${this._params.submitText || this.hass.localize("ui.common.save")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}

View File

@@ -4,8 +4,9 @@ import { customElement, property, query, state } from "lit/decorators";
import { storage } from "../../common/decorators/storage";
import { fireEvent } from "../../common/dom/fire_event";
import "../../components/buttons/ha-progress-button";
import { createCloseHeading } from "../../components/ha-dialog";
import "../../components/ha-dialog-footer";
import "../../components/ha-textarea";
import "../../components/ha-wa-dialog";
import type { HaTextArea } from "../../components/ha-textarea";
import { convertTextToSpeech } from "../../data/tts";
import { haStyleDialog } from "../../resources/styles";
@@ -19,6 +20,8 @@ export class TTSTryDialog extends LitElement {
@state() private _loadingExample = false;
@state() private _open = false;
@state() private _params?: TTSTryDialogParams;
@state() private _valid = false;
@@ -35,9 +38,14 @@ export class TTSTryDialog extends LitElement {
public showDialog(params: TTSTryDialogParams) {
this._params = params;
this._valid = Boolean(this._defaultMessage);
this._open = true;
}
public closeDialog() {
this._open = false;
}
private _dialogClosed() {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -61,13 +69,11 @@ export class TTSTryDialog extends LitElement {
return nothing;
}
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${createCloseHeading(
this.hass,
this.hass.localize("ui.dialogs.tts-try.header")
)}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this.hass.localize("ui.dialogs.tts-try.header")}
@closed=${this._dialogClosed}
>
<ha-textarea
autogrow
@@ -78,21 +84,23 @@ export class TTSTryDialog extends LitElement {
)}
.value=${this._defaultMessage}
@input=${this._inputChanged}
?dialogInitialFocus=${!this._defaultMessage}
?autofocus=${!this._defaultMessage}
>
</ha-textarea>
<ha-progress-button
.progress=${this._loadingExample}
?dialogInitialFocus=${Boolean(this._defaultMessage)}
slot="primaryAction"
@click=${this._playExample}
.disabled=${!this._valid}
.iconPath=${mdiPlayCircleOutline}
>
${this.hass.localize("ui.dialogs.tts-try.play")}
</ha-progress-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-progress-button
slot="primaryAction"
.progress=${this._loadingExample}
?autofocus=${Boolean(this._defaultMessage)}
@click=${this._playExample}
.disabled=${!this._valid}
.iconPath=${mdiPlayCircleOutline}
>
${this.hass.localize("ui.dialogs.tts-try.play")}
</ha-progress-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -153,9 +161,6 @@ export class TTSTryDialog extends LitElement {
static styles = [
haStyleDialog,
css`
ha-dialog {
--mdc-dialog-max-width: 500px;
}
ha-textarea,
ha-select {
width: 100%;

View File

@@ -2,7 +2,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 { HomeAssistant } from "../../types";
import type { UpdateBackupDialogParams } from "./show-update-backup-dialog";
@@ -12,8 +13,13 @@ class DialogBox extends LitElement {
@state() private _params?: UpdateBackupDialogParams;
@state() private _open = false;
@state() private _closeState?: "canceled" | "submitted";
public async showDialog(params: UpdateBackupDialogParams): Promise<void> {
this._params = params;
this._open = true;
}
protected render() {
@@ -22,27 +28,32 @@ class DialogBox extends LitElement {
}
return html`
<ha-dialog
open
@closed=${this._cancel}
defaultAction="ignore"
.heading=${createCloseHeading(
this.hass,
this.hass.localize("ui.dialogs.update_backup.title")
)}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title=${this.hass.localize("ui.dialogs.update_backup.title")}
width="small"
@closed=${this._dialogClosed}
>
<p>${this.hass.localize("ui.dialogs.update_backup.text")}</p>
<ha-button appearance="plain" @click=${this._no} slot="secondaryAction">
${this.hass!.localize("ui.common.no")}
</ha-button>
<ha-button @click=${this._yes} slot="primaryAction">
${this.hass.localize("ui.dialogs.update_backup.create")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this._no}
>
${this.hass!.localize("ui.common.no")}
</ha-button>
<ha-button slot="primaryAction" @click=${this._yes}>
${this.hass.localize("ui.dialogs.update_backup.create")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
private _no(): void {
this._closeState = "submitted";
if (this._params!.submit) {
this._params!.submit(false);
}
@@ -50,19 +61,24 @@ class DialogBox extends LitElement {
}
private _yes(): void {
this._closeState = "submitted";
if (this._params!.submit) {
this._params!.submit(true);
}
this.closeDialog();
}
private _cancel(): void {
this._params?.cancel?.();
this.closeDialog();
public closeDialog(): void {
this._open = false;
}
public closeDialog(): void {
private _dialogClosed(): void {
if (!this._closeState) {
this._params?.cancel?.();
}
this._closeState = undefined;
this._params = undefined;
this._open = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -71,15 +87,10 @@ class DialogBox extends LitElement {
margin: 0;
color: var(--primary-text-color);
}
ha-dialog {
ha-wa-dialog {
/* Place above other dialogs */
--dialog-z-index: 104;
}
@media all and (min-width: 600px) {
ha-dialog {
--mdc-dialog-min-width: 400px;
}
}
`;
}

View File

@@ -1,4 +1,4 @@
import { mdiChevronLeft, mdiClose, mdiMenuDown } from "@mdi/js";
import { mdiChevronLeft, mdiMenuDown } from "@mdi/js";
import type { CSSResultGroup } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
@@ -7,7 +7,7 @@ import { fireEvent } from "../../common/dom/fire_event";
import { computeDomain } from "../../common/entity/compute_domain";
import { formatLanguageCode } from "../../common/language/format_language";
import "../../components/chips/ha-assist-chip";
import "../../components/ha-dialog";
import "../../components/ha-wa-dialog";
import "../../components/ha-dropdown";
import type { HaDropdownSelectEvent } from "../../components/ha-dropdown";
import "../../components/ha-dropdown-item";
@@ -49,6 +49,8 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
@state() private _params?: VoiceAssistantSetupDialogParams;
@state() private _open = false;
@state() private _step: STEP = STEP.INIT;
@state() private _assistConfiguration?: AssistSatelliteConfiguration;
@@ -69,14 +71,15 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
params: VoiceAssistantSetupDialogParams
): Promise<void> {
this._params = params;
this._open = true;
await this._fetchAssistConfiguration();
this._step = STEP.UPDATE;
}
public async closeDialog(): Promise<void> {
this.renderRoot.querySelector("ha-dialog")?.close();
public closeDialog(): void {
this._open = false;
}
protected willUpdate(changedProps) {
@@ -86,6 +89,7 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
}
private _dialogClosed() {
this._open = false;
this._params = undefined;
this._assistConfiguration = undefined;
this._previousSteps = [];
@@ -133,78 +137,71 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
? this.hass.states[assistSatelliteEntityId]
: undefined;
const hideNavigationIcon =
this._step === STEP.LOCAL ||
(this._step === STEP.UPDATE && !this._previousSteps.length);
return html`
<ha-dialog
open
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
header-title="Voice Satellite setup"
@closed=${this._dialogClosed}
.heading=${"Voice Satellite setup"}
hideActions
escapeKeyAction
scrimClickAction
>
<ha-dialog-header slot="heading">
${this._step === STEP.LOCAL
? nothing
: this._previousSteps.length
? html`<ha-icon-button
slot="navigationIcon"
.label=${this.hass.localize("ui.common.back") ?? "Back"}
.path=${mdiChevronLeft}
@click=${this._goToPreviousStep}
></ha-icon-button>`
: this._step !== STEP.UPDATE
? html`<ha-icon-button
slot="navigationIcon"
.label=${this.hass.localize("ui.common.close") ?? "Close"}
.path=${mdiClose}
@click=${this.closeDialog}
></ha-icon-button>`
: nothing}
${this._step === STEP.WAKEWORD || this._step === STEP.AREA
? html`<ha-button
@click=${this._goToNextStep}
class="skip-btn"
slot="actionItems"
>${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.skip"
)}</ha-button
>`
: this._step === STEP.PIPELINE
? this._language
? html`<ha-dropdown
slot="actionItems"
@wa-select=${this._handlePickLanguage}
>
<ha-assist-chip
.label=${formatLanguageCode(
this._language,
this.hass.locale
)}
slot="trigger"
>
<ha-svg-icon
slot="trailing-icon"
.path=${mdiMenuDown}
></ha-svg-icon
></ha-assist-chip>
${getLanguageOptions(
this._languages,
false,
false,
${hideNavigationIcon
? html`<span slot="headerNavigationIcon"></span>`
: this._previousSteps.length
? html`<ha-icon-button
slot="headerNavigationIcon"
.label=${this.hass.localize("ui.common.back") ?? "Back"}
.path=${mdiChevronLeft}
@click=${this._goToPreviousStep}
></ha-icon-button>`
: nothing}
${this._step === STEP.WAKEWORD || this._step === STEP.AREA
? html`<ha-button
@click=${this._goToNextStep}
class="skip-btn"
slot="headerActionItems"
>${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.skip"
)}</ha-button
>`
: this._step === STEP.PIPELINE
? this._language
? html`<ha-dropdown
slot="headerActionItems"
@wa-select=${this._handlePickLanguage}
>
<ha-assist-chip
.label=${formatLanguageCode(
this._language,
this.hass.locale
).map(
(lang) =>
html`<ha-dropdown-item
.value=${lang.id}
class=${this._language === lang.id ? "selected" : ""}
>
${lang.primary}
</ha-dropdown-item>`
)}
</ha-dropdown>`
: nothing
: nothing}
</ha-dialog-header>
slot="trigger"
>
<ha-svg-icon
slot="trailing-icon"
.path=${mdiMenuDown}
></ha-svg-icon
></ha-assist-chip>
${getLanguageOptions(
this._languages,
false,
false,
this.hass.locale
).map(
(lang) =>
html`<ha-dropdown-item
.value=${lang.id}
class=${this._language === lang.id ? "selected" : ""}
>
${lang.primary}
</ha-dropdown-item>`
)}
</ha-dropdown>`
: nothing
: nothing}
<div
class="content"
@next-step=${this._goToNextStep}
@@ -288,7 +285,7 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
></ha-voice-assistant-setup-step-success>`
: nothing}
</div>
</ha-dialog>
</ha-wa-dialog>
`;
}
@@ -373,20 +370,9 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
return [
haStyleDialog,
css`
ha-dialog {
ha-wa-dialog {
--dialog-content-padding: 0;
}
@media all and (min-width: 450px) and (min-height: 500px) {
ha-dialog {
--mdc-dialog-min-width: 560px;
--mdc-dialog-max-width: 560px;
--mdc-dialog-min-width: min(560px, 95vw);
--mdc-dialog-max-width: min(560px, 95vw);
}
}
ha-dialog-header {
height: 56px;
}
@media all and (max-width: 450px), all and (max-height: 500px) {
.content {
height: calc(100vh - 56px);

View File

@@ -14,7 +14,6 @@ import { stopPropagation } from "../../common/dom/stop_propagation";
import "../../components/ha-alert";
import "../../components/ha-assist-chat";
import "../../components/ha-button";
import "../../components/ha-dialog";
import "../../components/ha-dialog-header";
import "../../components/ha-dropdown";
import type { HaDropdownSelectEvent } from "../../components/ha-dropdown";
@@ -22,6 +21,7 @@ import "../../components/ha-dropdown-item";
import "../../components/ha-icon-button";
import "../../components/ha-icon-next";
import "../../components/ha-spinner";
import "../../components/ha-wa-dialog";
import type { AssistPipeline } from "../../data/assist_pipeline";
import {
getAssistPipeline,
@@ -36,7 +36,9 @@ import type { VoiceCommandDialogParams } from "./show-ha-voice-command-dialog";
export class HaVoiceCommandDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@state() private _opened = false;
@state() private _open = false;
@state() private _dialogOpen = false;
@state()
@storage({
@@ -76,32 +78,36 @@ export class HaVoiceCommandDialog extends LitElement {
}
this._startListening = params.start_listening;
this._opened = true;
this._dialogOpen = true;
this._open = true;
}
public async closeDialog(): Promise<void> {
this._opened = false;
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._dialogOpen = false;
this._pipelines = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
protected render() {
if (!this._opened) {
if (!this._dialogOpen) {
return nothing;
}
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${this.hass.localize("ui.dialogs.voice_command.title")}
flexContent
hideactions
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
@closed=${this._dialogClosed}
flexcontent
>
<ha-dialog-header slot="heading">
<ha-dialog-header slot="header">
<ha-icon-button
slot="navigationIcon"
dialogAction="cancel"
data-dialog="close"
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
></ha-icon-button>
@@ -189,15 +195,15 @@ export class HaVoiceCommandDialog extends LitElement {
: html`<div class="pipelines-loading">
<ha-spinner size="large"></ha-spinner>
</div>`}
</ha-dialog>
</ha-wa-dialog>
`;
}
protected willUpdate(changedProperties: PropertyValues): void {
if (
changedProperties.has("_pipelineId") ||
(changedProperties.has("_opened") &&
this._opened === true &&
(changedProperties.has("_open") &&
this._open === true &&
this._pipelineId)
) {
this._getPipeline();
@@ -252,9 +258,7 @@ export class HaVoiceCommandDialog extends LitElement {
return [
haStyleDialog,
css`
ha-dialog {
--mdc-dialog-max-width: 500px;
--mdc-dialog-max-height: 500px;
ha-wa-dialog {
--dialog-content-padding: 0;
}
ha-dialog-header a {

View File

@@ -27,8 +27,8 @@ import type {
SortingDirection,
} from "../components/data-table/ha-data-table";
import { showDataTableSettingsDialog } from "../components/data-table/show-dialog-data-table-settings";
import "../components/ha-dialog";
import "../components/ha-dialog-header";
import "../components/ha-dialog-footer";
import "../components/ha-wa-dialog";
import "../components/ha-dropdown";
import type { HaDropdownSelectEvent } from "../components/ha-dropdown";
import "../components/ha-dropdown-item";
@@ -535,44 +535,42 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
<div slot="fab"><slot name="fab"></slot></div>
</hass-tabs-subpage>
${this.showFilters && !showPane
? html`<ha-dialog
open
.heading=${localize("ui.components.subpage-data-table.filters")}
? html`<ha-wa-dialog
.hass=${this.hass}
.open=${true}
width="full"
header-title=${localize("ui.components.subpage-data-table.filters")}
@closed=${this._closeFilters}
>
<ha-dialog-header slot="heading">
<ha-icon-button
slot="navigationIcon"
.path=${mdiClose}
@click=${this._toggleFilters}
.label=${localize(
"ui.components.subpage-data-table.close_filter"
)}
></ha-icon-button>
<span slot="title"
>${localize("ui.components.subpage-data-table.filters")}</span
>
${this.filters
? html`<ha-icon-button
slot="actionItems"
@click=${this._clearFilters}
.path=${mdiFilterVariantRemove}
.label=${localize(
"ui.components.subpage-data-table.clear_filter"
)}
></ha-icon-button>`
: nothing}
</ha-dialog-header>
<ha-icon-button
slot="headerNavigationIcon"
.path=${mdiClose}
@click=${this._closeFilters}
.label=${localize(
"ui.components.subpage-data-table.close_filter"
)}
></ha-icon-button>
${this.filters
? html`<ha-icon-button
slot="headerActionItems"
@click=${this._clearFilters}
.path=${mdiFilterVariantRemove}
.label=${localize(
"ui.components.subpage-data-table.clear_filter"
)}
></ha-icon-button>`
: nothing}
<div class="filter-dialog-content">
<slot name="filter-pane"></slot>
</div>
<div slot="primaryAction">
<ha-button @click=${this._toggleFilters}>
<ha-dialog-footer slot="footer">
<ha-button slot="primaryAction" @click=${this._closeFilters}>
${localize("ui.components.subpage-data-table.show_results", {
number: this.data.length,
})}
</ha-button>
</div>
</ha-dialog>`
</ha-dialog-footer>
</ha-wa-dialog>`
: nothing}
`;
}
@@ -585,6 +583,10 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
this.showFilters = !this.showFilters;
}
private _closeFilters = () => {
this.showFilters = false;
};
private _sortingChanged(ev) {
this._sortDirection = ev.detail.direction;
this._sortColumn = this._sortDirection ? ev.detail.column : undefined;
@@ -893,13 +895,7 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
--md-assist-chip-trailing-space: 8px;
}
ha-dialog {
--mdc-dialog-min-width: 100vw;
--mdc-dialog-max-width: 100vw;
--mdc-dialog-min-height: 100%;
--mdc-dialog-max-height: 100%;
--vertical-align-dialog: flex-end;
--ha-dialog-border-radius: var(--ha-border-radius-square);
ha-wa-dialog {
--dialog-content-padding: 0;
}