1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00

Migrate other dialogs to wa (#29610)

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
Aidan Timson
2026-02-13 15:19:48 +00:00
committed by GitHub
parent 8edfd4d5ad
commit 309e60fc4f
9 changed files with 451 additions and 411 deletions

View File

@@ -9,12 +9,13 @@ import { fireEvent } from "../../common/dom/fire_event";
import { haStyleDialog } from "../../resources/styles"; import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
import "../ha-button"; import "../ha-button";
import { createCloseHeading } from "../ha-dialog"; import "../ha-dialog-footer";
import "../ha-icon-button"; import "../ha-icon-button";
import "../ha-list"; import "../ha-list";
import "../ha-list-item"; import "../ha-list-item";
import "../ha-sortable"; import "../ha-sortable";
import "../ha-svg-icon"; import "../ha-svg-icon";
import "../ha-wa-dialog";
import type { import type {
DataTableColumnContainer, DataTableColumnContainer,
DataTableColumnData, DataTableColumnData,
@@ -31,13 +32,20 @@ export class DialogDataTableSettings extends LitElement {
@state() private _hiddenColumns?: string[]; @state() private _hiddenColumns?: string[];
@state() private _open = false;
public showDialog(params: DataTableSettingsDialogParams) { public showDialog(params: DataTableSettingsDialogParams) {
this._params = params; this._params = params;
this._columnOrder = params.columnOrder; this._columnOrder = params.columnOrder;
this._hiddenColumns = params.hiddenColumns; this._hiddenColumns = params.hiddenColumns;
this._open = true;
} }
public closeDialog() { public closeDialog() {
this._open = false;
}
private _dialogClosed() {
this._params = undefined; this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName }); fireEvent(this, "dialog-closed", { dialog: this.localName });
} }
@@ -93,13 +101,11 @@ export class DialogDataTableSettings extends LitElement {
); );
return html` return html`
<ha-dialog <ha-wa-dialog
open .hass=${this.hass}
@closed=${this.closeDialog} .open=${this._open}
.heading=${createCloseHeading( header-title=${localize("ui.components.data-table.settings.header")}
this.hass, @closed=${this._dialogClosed}
localize("ui.components.data-table.settings.header")
)}
> >
<ha-sortable <ha-sortable
@item-moved=${this._columnMoved} @item-moved=${this._columnMoved}
@@ -154,16 +160,18 @@ export class DialogDataTableSettings extends LitElement {
)} )}
</ha-list> </ha-list>
</ha-sortable> </ha-sortable>
<ha-button <ha-dialog-footer slot="footer">
appearance="plain" <ha-button
slot="secondaryAction" slot="secondaryAction"
@click=${this._reset} appearance="plain"
>${localize("ui.components.data-table.settings.restore")}</ha-button @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 slot="primaryAction" @click=${this.closeDialog}>
</ha-button> ${localize("ui.components.data-table.settings.done")}
</ha-dialog> </ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`; `;
} }
@@ -283,22 +291,10 @@ export class DialogDataTableSettings extends LitElement {
return [ return [
haStyleDialog, haStyleDialog,
css` css`
ha-dialog { ha-wa-dialog {
--mdc-dialog-max-width: 500px;
--dialog-z-index: 10; --dialog-z-index: 10;
--dialog-content-padding: 0 8px; --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 { ha-list-item {
--mdc-list-side-padding: 12px; --mdc-list-side-padding: 12px;
overflow: visible; overflow: visible;

View File

@@ -1,8 +1,9 @@
import { mdiAlertCircle, mdiMicrophone, mdiSend } from "@mdi/js"; import { mdiAlertCircle, mdiMicrophone, mdiSend } from "@mdi/js";
import type { PropertyValues, TemplateResult } from "lit"; import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { haStyleScrollbar } from "../resources/styles";
import { supportsFeature } from "../common/entity/supports-feature"; import { supportsFeature } from "../common/entity/supports-feature";
import { import {
runAssistPipeline, runAssistPipeline,
@@ -114,7 +115,7 @@ export class HaAssistChat extends LitElement {
const supportsSTT = this.pipeline?.stt_engine && !this.disableSpeech; const supportsSTT = this.pipeline?.stt_engine && !this.disableSpeech;
return html` return html`
<div class="messages"> <div class="messages ha-scrollbar">
${controlHA ${controlHA
? nothing ? nothing
: html` : html`
@@ -585,154 +586,167 @@ export class HaAssistChat extends LitElement {
return progress; return progress;
} }
static styles = css` static get styles(): CSSResultGroup {
:host { return [
flex: 1; haStyleScrollbar,
display: flex; css`
flex-direction: column; :host {
} flex: 1;
ha-alert { display: flex;
margin-bottom: 8px; flex-direction: column;
} min-height: 0;
ha-textfield { }
display: block; ha-alert {
} margin-bottom: var(--ha-space-2);
.messages { }
flex: 1; ha-textfield {
display: block; display: block;
box-sizing: border-box; }
overflow-y: auto; .messages {
max-height: 100%; flex: 1 1 400px;
display: flex; display: block;
flex-direction: column; box-sizing: border-box;
padding: 0 12px 16px; overflow-y: auto;
} min-height: 0;
.spacer { max-height: 100%;
flex: 1; display: flex;
} flex-direction: column;
.message { padding: 0 var(--ha-space-3) var(--ha-space-4);
font-size: var(--ha-font-size-l); }
clear: both; .input {
max-width: -webkit-fill-available; padding: var(--ha-space-1) var(--ha-space-4) var(--ha-space-6);
overflow-wrap: break-word; }
scroll-margin-top: 24px; .spacer {
margin: 8px 0; flex: 1;
padding: 8px; }
border-radius: var(--ha-border-radius-xl); .message {
} font-size: var(--ha-font-size-l);
@media all and (max-width: 450px), all and (max-height: 500px) { clear: both;
.message { max-width: -webkit-fill-available;
font-size: var(--ha-font-size-l); overflow-wrap: break-word;
} scroll-margin-top: var(--ha-space-6);
} margin: var(--ha-space-2) 0;
.message.user { padding: var(--ha-space-2);
margin-left: 24px; border-radius: var(--ha-border-radius-xl);
margin-inline-start: 24px; }
margin-inline-end: initial; @media all and (max-width: 450px), all and (max-height: 500px) {
align-self: flex-end; .message {
border-bottom-right-radius: 0px; font-size: var(--ha-font-size-l);
--markdown-link-color: var(--text-primary-color); }
background-color: var(--chat-background-color-user, var(--primary-color)); }
color: var(--text-primary-color); .message.user {
direction: var(--direction); margin-left: var(--ha-space-6);
} margin-inline-start: var(--ha-space-6);
.message.hass { margin-inline-end: initial;
margin-right: 24px; align-self: flex-end;
margin-inline-end: 24px; border-bottom-right-radius: 0px;
margin-inline-start: initial; --markdown-link-color: var(--text-primary-color);
align-self: flex-start; background-color: var(
border-bottom-left-radius: 0px; --chat-background-color-user,
background-color: var( var(--primary-color)
--chat-background-color-hass, );
var(--secondary-background-color) color: var(--text-primary-color);
); direction: var(--direction);
}
.message.hass {
margin-right: var(--ha-space-6);
margin-inline-end: var(--ha-space-6);
margin-inline-start: initial;
align-self: flex-start;
border-bottom-left-radius: 0px;
background-color: var(
--chat-background-color-hass,
var(--secondary-background-color)
);
color: var(--primary-text-color); color: var(--primary-text-color);
direction: var(--direction); direction: var(--direction);
} }
.message.error { .message.error {
background-color: var(--error-color); background-color: var(--error-color);
color: var(--text-primary-color); color: var(--text-primary-color);
} }
ha-markdown { ha-markdown {
--markdown-image-border-radius: calc(var(--ha-border-radius-xl) / 2); --markdown-image-border-radius: calc(var(--ha-border-radius-xl) / 2);
--markdown-table-border-color: var(--divider-color); --markdown-table-border-color: var(--divider-color);
--markdown-code-background-color: var(--primary-background-color); --markdown-code-background-color: var(--primary-background-color);
--markdown-code-text-color: var(--primary-text-color); --markdown-code-text-color: var(--primary-text-color);
--markdown-list-indent: 1.15em; --markdown-list-indent: 1.15em;
&:not(:has(ha-markdown-element)) { &:not(:has(ha-markdown-element)) {
min-height: 1lh; min-height: 1lh;
min-width: 1lh; min-width: 1lh;
flex-shrink: 0; flex-shrink: 0;
} }
} }
.bouncer { .bouncer {
width: 48px; width: 48px;
height: 48px; height: 48px;
position: absolute; position: absolute;
} }
.double-bounce1, .double-bounce1,
.double-bounce2 { .double-bounce2 {
width: 48px; width: 48px;
height: 48px; height: 48px;
border-radius: var(--ha-border-radius-circle); border-radius: var(--ha-border-radius-circle);
background-color: var(--primary-color); background-color: var(--primary-color);
opacity: 0.2; opacity: 0.2;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
-webkit-animation: sk-bounce 2s infinite ease-in-out; -webkit-animation: sk-bounce 2s infinite ease-in-out;
animation: sk-bounce 2s infinite ease-in-out; animation: sk-bounce 2s infinite ease-in-out;
} }
.double-bounce2 { .double-bounce2 {
-webkit-animation-delay: -1s; -webkit-animation-delay: -1s;
animation-delay: -1s; animation-delay: -1s;
} }
@-webkit-keyframes sk-bounce { @-webkit-keyframes sk-bounce {
0%, 0%,
100% { 100% {
-webkit-transform: scale(0); -webkit-transform: scale(0);
} }
50% { 50% {
-webkit-transform: scale(1); -webkit-transform: scale(1);
} }
} }
@keyframes sk-bounce { @keyframes sk-bounce {
0%, 0%,
100% { 100% {
transform: scale(0); transform: scale(0);
-webkit-transform: scale(0); -webkit-transform: scale(0);
} }
50% { 50% {
transform: scale(1); transform: scale(1);
-webkit-transform: scale(1); -webkit-transform: scale(1);
} }
} }
.listening-icon { .listening-icon {
position: relative; position: relative;
color: var(--secondary-text-color); color: var(--secondary-text-color);
margin-right: -24px; margin-right: -24px;
margin-inline-end: -24px; margin-inline-end: -24px;
margin-inline-start: initial; margin-inline-start: initial;
direction: var(--direction); direction: var(--direction);
transform: scaleX(var(--scale-direction)); transform: scaleX(var(--scale-direction));
} }
.listening-icon[active] { .listening-icon[active] {
color: var(--primary-color); color: var(--primary-color);
} }
.unsupported { .unsupported {
color: var(--error-color); color: var(--error-color);
position: absolute; position: absolute;
--mdc-icon-size: 16px; --mdc-icon-size: 16px;
right: 5px; right: 5px;
inset-inline-end: 5px; inset-inline-end: 5px;
inset-inline-start: initial; inset-inline-start: initial;
top: 0px; top: 0px;
} }
`; `,
];
}
} }
declare global { declare global {

View File

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

View File

@@ -2,8 +2,9 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-button"; import "../../components/ha-button";
import { createCloseHeading } from "../../components/ha-dialog";
import "../../components/ha-form/ha-form"; import "../../components/ha-form/ha-form";
import "../../components/ha-dialog-footer";
import "../../components/ha-wa-dialog";
import { haStyleDialog } from "../../resources/styles"; import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
import type { HassDialog } from "../make-dialog-manager"; import type { HassDialog } from "../make-dialog-manager";
@@ -20,24 +21,40 @@ export class DialogForm
@state() private _data: FormDialogData = {}; @state() private _data: FormDialogData = {};
@state() private _open = false;
@state() private _closeState?: "canceled" | "submitted";
public async showDialog(params: FormDialogParams): Promise<void> { public async showDialog(params: FormDialogParams): Promise<void> {
this._params = params; this._params = params;
this._data = params.data || {}; this._data = params.data || {};
this._open = true;
} }
public closeDialog() { public closeDialog(): boolean {
this._params = undefined; this._open = false;
this._data = {};
fireEvent(this, "dialog-closed", { dialog: this.localName });
return true; 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 { private _submit(): void {
this._closeState = "submitted";
this._params?.submit?.(this._data); this._params?.submit?.(this._data);
this.closeDialog(); this.closeDialog();
} }
private _cancel(): void { private _cancel(): void {
this._closeState = "canceled";
this._params?.cancel?.(); this._params?.cancel?.();
this.closeDialog(); this.closeDialog();
} }
@@ -52,15 +69,15 @@ export class DialogForm
} }
return html` return html`
<ha-dialog <ha-wa-dialog
open .hass=${this.hass}
scrimClickAction .open=${this._open}
escapeKeyAction header-title=${this._params.title}
.heading=${createCloseHeading(this.hass, this._params.title)} prevent-scrim-close
@closed=${this._cancel} @closed=${this._dialogClosed}
> >
<ha-form <ha-form
dialogInitialFocus autofocus
.hass=${this.hass} .hass=${this.hass}
.computeLabel=${this._params.computeLabel} .computeLabel=${this._params.computeLabel}
.computeHelper=${this._params.computeHelper} .computeHelper=${this._params.computeHelper}
@@ -69,17 +86,19 @@ export class DialogForm
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
> >
</ha-form> </ha-form>
<ha-button <ha-dialog-footer slot="footer">
appearance="plain" <ha-button
@click=${this._cancel} slot="secondaryAction"
slot="secondaryAction" appearance="plain"
> @click=${this._cancel}
${this._params.cancelText || this.hass.localize("ui.common.cancel")} >
</ha-button> ${this._params.cancelText || this.hass.localize("ui.common.cancel")}
<ha-button @click=${this._submit} slot="primaryAction"> </ha-button>
${this._params.submitText || this.hass.localize("ui.common.save")} <ha-button slot="primaryAction" @click=${this._submit}>
</ha-button> ${this._params.submitText || this.hass.localize("ui.common.save")}
</ha-dialog> </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 { storage } from "../../common/decorators/storage";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import "../../components/buttons/ha-progress-button"; import "../../components/buttons/ha-progress-button";
import { createCloseHeading } from "../../components/ha-dialog"; import "../../components/ha-dialog-footer";
import "../../components/ha-textarea"; import "../../components/ha-textarea";
import "../../components/ha-wa-dialog";
import type { HaTextArea } from "../../components/ha-textarea"; import type { HaTextArea } from "../../components/ha-textarea";
import { convertTextToSpeech } from "../../data/tts"; import { convertTextToSpeech } from "../../data/tts";
import { haStyleDialog } from "../../resources/styles"; import { haStyleDialog } from "../../resources/styles";
@@ -19,6 +20,8 @@ export class TTSTryDialog extends LitElement {
@state() private _loadingExample = false; @state() private _loadingExample = false;
@state() private _open = false;
@state() private _params?: TTSTryDialogParams; @state() private _params?: TTSTryDialogParams;
@state() private _valid = false; @state() private _valid = false;
@@ -35,9 +38,14 @@ export class TTSTryDialog extends LitElement {
public showDialog(params: TTSTryDialogParams) { public showDialog(params: TTSTryDialogParams) {
this._params = params; this._params = params;
this._valid = Boolean(this._defaultMessage); this._valid = Boolean(this._defaultMessage);
this._open = true;
} }
public closeDialog() { public closeDialog() {
this._open = false;
}
private _dialogClosed() {
this._params = undefined; this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName }); fireEvent(this, "dialog-closed", { dialog: this.localName });
} }
@@ -61,13 +69,11 @@ export class TTSTryDialog extends LitElement {
return nothing; return nothing;
} }
return html` return html`
<ha-dialog <ha-wa-dialog
open .hass=${this.hass}
@closed=${this.closeDialog} .open=${this._open}
.heading=${createCloseHeading( header-title=${this.hass.localize("ui.dialogs.tts-try.header")}
this.hass, @closed=${this._dialogClosed}
this.hass.localize("ui.dialogs.tts-try.header")
)}
> >
<ha-textarea <ha-textarea
autogrow autogrow
@@ -78,21 +84,23 @@ export class TTSTryDialog extends LitElement {
)} )}
.value=${this._defaultMessage} .value=${this._defaultMessage}
@input=${this._inputChanged} @input=${this._inputChanged}
?dialogInitialFocus=${!this._defaultMessage} ?autofocus=${!this._defaultMessage}
> >
</ha-textarea> </ha-textarea>
<ha-progress-button <ha-dialog-footer slot="footer">
.progress=${this._loadingExample} <ha-progress-button
?dialogInitialFocus=${Boolean(this._defaultMessage)} slot="primaryAction"
slot="primaryAction" .progress=${this._loadingExample}
@click=${this._playExample} ?autofocus=${Boolean(this._defaultMessage)}
.disabled=${!this._valid} @click=${this._playExample}
.iconPath=${mdiPlayCircleOutline} .disabled=${!this._valid}
> .iconPath=${mdiPlayCircleOutline}
${this.hass.localize("ui.dialogs.tts-try.play")} >
</ha-progress-button> ${this.hass.localize("ui.dialogs.tts-try.play")}
</ha-dialog> </ha-progress-button>
</ha-dialog-footer>
</ha-wa-dialog>
`; `;
} }
@@ -153,9 +161,6 @@ export class TTSTryDialog extends LitElement {
static styles = [ static styles = [
haStyleDialog, haStyleDialog,
css` css`
ha-dialog {
--mdc-dialog-max-width: 500px;
}
ha-textarea, ha-textarea,
ha-select { ha-select {
width: 100%; width: 100%;

View File

@@ -2,7 +2,8 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-button"; 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 { HomeAssistant } from "../../types";
import type { UpdateBackupDialogParams } from "./show-update-backup-dialog"; import type { UpdateBackupDialogParams } from "./show-update-backup-dialog";
@@ -12,8 +13,13 @@ class DialogBox extends LitElement {
@state() private _params?: UpdateBackupDialogParams; @state() private _params?: UpdateBackupDialogParams;
@state() private _open = false;
@state() private _closeState?: "canceled" | "submitted";
public async showDialog(params: UpdateBackupDialogParams): Promise<void> { public async showDialog(params: UpdateBackupDialogParams): Promise<void> {
this._params = params; this._params = params;
this._open = true;
} }
protected render() { protected render() {
@@ -22,27 +28,32 @@ class DialogBox extends LitElement {
} }
return html` return html`
<ha-dialog <ha-wa-dialog
open .hass=${this.hass}
@closed=${this._cancel} .open=${this._open}
defaultAction="ignore" header-title=${this.hass.localize("ui.dialogs.update_backup.title")}
.heading=${createCloseHeading( width="small"
this.hass, @closed=${this._dialogClosed}
this.hass.localize("ui.dialogs.update_backup.title")
)}
> >
<p>${this.hass.localize("ui.dialogs.update_backup.text")}</p> <p>${this.hass.localize("ui.dialogs.update_backup.text")}</p>
<ha-button appearance="plain" @click=${this._no} slot="secondaryAction"> <ha-dialog-footer slot="footer">
${this.hass!.localize("ui.common.no")} <ha-button
</ha-button> slot="secondaryAction"
<ha-button @click=${this._yes} slot="primaryAction"> appearance="plain"
${this.hass.localize("ui.dialogs.update_backup.create")} @click=${this._no}
</ha-button> >
</ha-dialog> ${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 { private _no(): void {
this._closeState = "submitted";
if (this._params!.submit) { if (this._params!.submit) {
this._params!.submit(false); this._params!.submit(false);
} }
@@ -50,19 +61,24 @@ class DialogBox extends LitElement {
} }
private _yes(): void { private _yes(): void {
this._closeState = "submitted";
if (this._params!.submit) { if (this._params!.submit) {
this._params!.submit(true); this._params!.submit(true);
} }
this.closeDialog(); this.closeDialog();
} }
private _cancel(): void { public closeDialog(): void {
this._params?.cancel?.(); this._open = false;
this.closeDialog();
} }
public closeDialog(): void { private _dialogClosed(): void {
if (!this._closeState) {
this._params?.cancel?.();
}
this._closeState = undefined;
this._params = undefined; this._params = undefined;
this._open = false;
fireEvent(this, "dialog-closed", { dialog: this.localName }); fireEvent(this, "dialog-closed", { dialog: this.localName });
} }
@@ -71,15 +87,10 @@ class DialogBox extends LitElement {
margin: 0; margin: 0;
color: var(--primary-text-color); color: var(--primary-text-color);
} }
ha-dialog { ha-wa-dialog {
/* Place above other dialogs */ /* Place above other dialogs */
--dialog-z-index: 104; --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 type { CSSResultGroup } from "lit";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; 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 { computeDomain } from "../../common/entity/compute_domain";
import { formatLanguageCode } from "../../common/language/format_language"; import { formatLanguageCode } from "../../common/language/format_language";
import "../../components/chips/ha-assist-chip"; import "../../components/chips/ha-assist-chip";
import "../../components/ha-dialog"; import "../../components/ha-wa-dialog";
import "../../components/ha-dropdown"; import "../../components/ha-dropdown";
import type { HaDropdownSelectEvent } from "../../components/ha-dropdown"; import type { HaDropdownSelectEvent } from "../../components/ha-dropdown";
import "../../components/ha-dropdown-item"; import "../../components/ha-dropdown-item";
@@ -49,6 +49,8 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
@state() private _params?: VoiceAssistantSetupDialogParams; @state() private _params?: VoiceAssistantSetupDialogParams;
@state() private _open = false;
@state() private _step: STEP = STEP.INIT; @state() private _step: STEP = STEP.INIT;
@state() private _assistConfiguration?: AssistSatelliteConfiguration; @state() private _assistConfiguration?: AssistSatelliteConfiguration;
@@ -69,14 +71,15 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
params: VoiceAssistantSetupDialogParams params: VoiceAssistantSetupDialogParams
): Promise<void> { ): Promise<void> {
this._params = params; this._params = params;
this._open = true;
await this._fetchAssistConfiguration(); await this._fetchAssistConfiguration();
this._step = STEP.UPDATE; this._step = STEP.UPDATE;
} }
public async closeDialog(): Promise<void> { public closeDialog(): void {
this.renderRoot.querySelector("ha-dialog")?.close(); this._open = false;
} }
protected willUpdate(changedProps) { protected willUpdate(changedProps) {
@@ -86,6 +89,7 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
} }
private _dialogClosed() { private _dialogClosed() {
this._open = false;
this._params = undefined; this._params = undefined;
this._assistConfiguration = undefined; this._assistConfiguration = undefined;
this._previousSteps = []; this._previousSteps = [];
@@ -133,78 +137,72 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
? this.hass.states[assistSatelliteEntityId] ? this.hass.states[assistSatelliteEntityId]
: undefined; : undefined;
const hideNavigationIcon =
this._step === STEP.LOCAL ||
(this._step === STEP.UPDATE && !this._previousSteps.length);
return html` return html`
<ha-dialog <ha-wa-dialog
open .hass=${this.hass}
.open=${this._open}
header-title="Voice Satellite setup"
prevent-scrim-close
@closed=${this._dialogClosed} @closed=${this._dialogClosed}
.heading=${"Voice Satellite setup"}
hideActions
escapeKeyAction
scrimClickAction
> >
<ha-dialog-header slot="heading"> ${hideNavigationIcon
${this._step === STEP.LOCAL ? html`<span slot="headerNavigationIcon"></span>`
? nothing : this._previousSteps.length
: this._previousSteps.length ? html`<ha-icon-button
? html`<ha-icon-button slot="headerNavigationIcon"
slot="navigationIcon" .label=${this.hass.localize("ui.common.back") ?? "Back"}
.label=${this.hass.localize("ui.common.back") ?? "Back"} .path=${mdiChevronLeft}
.path=${mdiChevronLeft} @click=${this._goToPreviousStep}
@click=${this._goToPreviousStep} ></ha-icon-button>`
></ha-icon-button>` : nothing}
: this._step !== STEP.UPDATE ${this._step === STEP.WAKEWORD || this._step === STEP.AREA
? html`<ha-icon-button ? html`<ha-button
slot="navigationIcon" @click=${this._goToNextStep}
.label=${this.hass.localize("ui.common.close") ?? "Close"} class="skip-btn"
.path=${mdiClose} slot="headerActionItems"
@click=${this.closeDialog} >${this.hass.localize(
></ha-icon-button>` "ui.panel.config.voice_assistants.satellite_wizard.skip"
: nothing} )}</ha-button
${this._step === STEP.WAKEWORD || this._step === STEP.AREA >`
? html`<ha-button : this._step === STEP.PIPELINE
@click=${this._goToNextStep} ? this._language
class="skip-btn" ? html`<ha-dropdown
slot="actionItems" slot="headerActionItems"
>${this.hass.localize( @wa-select=${this._handlePickLanguage}
"ui.panel.config.voice_assistants.satellite_wizard.skip" >
)}</ha-button <ha-assist-chip
>` .label=${formatLanguageCode(
: this._step === STEP.PIPELINE this._language,
? 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,
this.hass.locale this.hass.locale
).map(
(lang) =>
html`<ha-dropdown-item
.value=${lang.id}
.selected=${this._language === lang.id}
>
${lang.primary}
</ha-dropdown-item>`
)} )}
</ha-dropdown>` slot="trigger"
: nothing >
: nothing} <ha-svg-icon
</ha-dialog-header> 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}
.selected=${this._language === lang.id}
>
${lang.primary}
</ha-dropdown-item>`
)}
</ha-dropdown>`
: nothing
: nothing}
<div <div
class="content" class="content"
@next-step=${this._goToNextStep} @next-step=${this._goToNextStep}
@@ -288,7 +286,7 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
></ha-voice-assistant-setup-step-success>` ></ha-voice-assistant-setup-step-success>`
: nothing} : nothing}
</div> </div>
</ha-dialog> </ha-wa-dialog>
`; `;
} }
@@ -373,20 +371,9 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
return [ return [
haStyleDialog, haStyleDialog,
css` css`
ha-dialog { ha-wa-dialog {
--dialog-content-padding: 0; --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) { @media all and (max-width: 450px), all and (max-height: 500px) {
.content { .content {
height: calc(100vh - 56px); height: calc(100vh - 56px);

View File

@@ -14,7 +14,6 @@ import { stopPropagation } from "../../common/dom/stop_propagation";
import "../../components/ha-alert"; import "../../components/ha-alert";
import "../../components/ha-assist-chat"; import "../../components/ha-assist-chat";
import "../../components/ha-button"; import "../../components/ha-button";
import "../../components/ha-dialog";
import "../../components/ha-dialog-header"; import "../../components/ha-dialog-header";
import "../../components/ha-dropdown"; import "../../components/ha-dropdown";
import type { HaDropdownSelectEvent } from "../../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-button";
import "../../components/ha-icon-next"; import "../../components/ha-icon-next";
import "../../components/ha-spinner"; import "../../components/ha-spinner";
import "../../components/ha-wa-dialog";
import type { AssistPipeline } from "../../data/assist_pipeline"; import type { AssistPipeline } from "../../data/assist_pipeline";
import { import {
getAssistPipeline, getAssistPipeline,
@@ -36,7 +36,9 @@ import type { VoiceCommandDialogParams } from "./show-ha-voice-command-dialog";
export class HaVoiceCommandDialog extends LitElement { export class HaVoiceCommandDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@state() private _opened = false; @state() private _open = false;
@state() private _dialogOpen = false;
@state() @state()
@storage({ @storage({
@@ -76,32 +78,36 @@ export class HaVoiceCommandDialog extends LitElement {
} }
this._startListening = params.start_listening; this._startListening = params.start_listening;
this._opened = true; this._dialogOpen = true;
this._open = true;
} }
public async closeDialog(): Promise<void> { public closeDialog(): void {
this._opened = false; this._open = false;
}
private _dialogClosed(): void {
this._dialogOpen = false;
this._pipelines = undefined; this._pipelines = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName }); fireEvent(this, "dialog-closed", { dialog: this.localName });
} }
protected render() { protected render() {
if (!this._opened) { if (!this._dialogOpen) {
return nothing; return nothing;
} }
return html` return html`
<ha-dialog <ha-wa-dialog
open .hass=${this.hass}
@closed=${this.closeDialog} .open=${this._open}
.heading=${this.hass.localize("ui.dialogs.voice_command.title")} @closed=${this._dialogClosed}
flexContent flexcontent
hideactions
> >
<ha-dialog-header slot="heading"> <ha-dialog-header slot="header">
<ha-icon-button <ha-icon-button
slot="navigationIcon" slot="navigationIcon"
dialogAction="cancel" data-dialog="close"
.label=${this.hass.localize("ui.common.close")} .label=${this.hass.localize("ui.common.close")}
.path=${mdiClose} .path=${mdiClose}
></ha-icon-button> ></ha-icon-button>
@@ -189,15 +195,15 @@ export class HaVoiceCommandDialog extends LitElement {
: html`<div class="pipelines-loading"> : html`<div class="pipelines-loading">
<ha-spinner size="large"></ha-spinner> <ha-spinner size="large"></ha-spinner>
</div>`} </div>`}
</ha-dialog> </ha-wa-dialog>
`; `;
} }
protected willUpdate(changedProperties: PropertyValues): void { protected willUpdate(changedProperties: PropertyValues): void {
if ( if (
changedProperties.has("_pipelineId") || changedProperties.has("_pipelineId") ||
(changedProperties.has("_opened") && (changedProperties.has("_open") &&
this._opened === true && this._open === true &&
this._pipelineId) this._pipelineId)
) { ) {
this._getPipeline(); this._getPipeline();
@@ -252,9 +258,7 @@ export class HaVoiceCommandDialog extends LitElement {
return [ return [
haStyleDialog, haStyleDialog,
css` css`
ha-dialog { ha-wa-dialog {
--mdc-dialog-max-width: 500px;
--mdc-dialog-max-height: 500px;
--dialog-content-padding: 0; --dialog-content-padding: 0;
} }
ha-dialog-header a { ha-dialog-header a {
@@ -277,7 +281,7 @@ export class HaVoiceCommandDialog extends LitElement {
margin-inline-start: -9px; margin-inline-start: -9px;
} }
ha-dropdown ha-button { ha-dropdown ha-button {
--ha-button-height: 20px; --ha-button-height: var(--ha-space-5);
} }
ha-dropdown ha-button::part(base) { ha-dropdown ha-button::part(base) {
margin-left: 5px; margin-left: 5px;
@@ -289,15 +293,15 @@ export class HaVoiceCommandDialog extends LitElement {
} }
} }
ha-dropdown ha-button ha-svg-icon { ha-dropdown ha-button ha-svg-icon {
height: 28px; height: var(--ha-space-7);
margin-left: 4px; margin-left: var(--ha-space-1);
margin-inline-start: 4px; margin-inline-start: var(--ha-space-1);
margin-inline-end: initial; margin-inline-end: initial;
direction: var(--direction); direction: var(--direction);
} }
ha-dropdown-item ha-svg-icon { ha-dropdown-item ha-svg-icon {
margin-left: 4px; margin-left: var(--ha-space-1);
margin-inline-start: 4px; margin-inline-start: var(--ha-space-1);
margin-inline-end: initial; margin-inline-end: initial;
direction: var(--direction); direction: var(--direction);
display: block; display: block;
@@ -310,10 +314,6 @@ export class HaVoiceCommandDialog extends LitElement {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
ha-assist-chat {
margin: 0 24px 16px;
min-height: 399px;
}
`, `,
]; ];
} }

View File

@@ -28,8 +28,8 @@ import type {
} from "../components/data-table/ha-data-table"; } from "../components/data-table/ha-data-table";
import { showDataTableSettingsDialog } from "../components/data-table/show-dialog-data-table-settings"; import { showDataTableSettingsDialog } from "../components/data-table/show-dialog-data-table-settings";
import "../components/ha-button"; import "../components/ha-button";
import "../components/ha-dialog"; import "../components/ha-dialog-footer";
import "../components/ha-dialog-header"; import "../components/ha-wa-dialog";
import "../components/ha-dropdown"; import "../components/ha-dropdown";
import "../components/ha-icon-button"; import "../components/ha-icon-button";
import "../components/ha-svg-icon"; import "../components/ha-svg-icon";
@@ -538,44 +538,42 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
<div slot="fab"><slot name="fab"></slot></div> <div slot="fab"><slot name="fab"></slot></div>
</hass-tabs-subpage> </hass-tabs-subpage>
${this.showFilters && !showPane ${this.showFilters && !showPane
? html`<ha-dialog ? html`<ha-wa-dialog
open .hass=${this.hass}
.heading=${localize("ui.components.subpage-data-table.filters")} .open=${true}
width="full"
header-title=${localize("ui.components.subpage-data-table.filters")}
@closed=${this._closeFilters}
> >
<ha-dialog-header slot="heading"> <ha-icon-button
<ha-icon-button slot="headerNavigationIcon"
slot="navigationIcon" .path=${mdiClose}
.path=${mdiClose} @click=${this._closeFilters}
@click=${this._toggleFilters} .label=${localize(
.label=${localize( "ui.components.subpage-data-table.close_filter"
"ui.components.subpage-data-table.close_filter" )}
)} ></ha-icon-button>
></ha-icon-button> ${this.filters
<span slot="title" ? html`<ha-icon-button
>${localize("ui.components.subpage-data-table.filters")}</span slot="headerActionItems"
> @click=${this._clearFilters}
${this.filters .path=${mdiFilterVariantRemove}
? html`<ha-icon-button .label=${localize(
slot="actionItems" "ui.components.subpage-data-table.clear_filter"
@click=${this._clearFilters} )}
.path=${mdiFilterVariantRemove} ></ha-icon-button>`
.label=${localize( : nothing}
"ui.components.subpage-data-table.clear_filter"
)}
></ha-icon-button>`
: nothing}
</ha-dialog-header>
<div class="filter-dialog-content"> <div class="filter-dialog-content">
<slot name="filter-pane"></slot> <slot name="filter-pane"></slot>
</div> </div>
<div slot="primaryAction"> <ha-dialog-footer slot="footer">
<ha-button @click=${this._toggleFilters}> <ha-button slot="primaryAction" @click=${this._closeFilters}>
${localize("ui.components.subpage-data-table.show_results", { ${localize("ui.components.subpage-data-table.show_results", {
number: this.data.length, number: this.data.length,
})} })}
</ha-button> </ha-button>
</div> </ha-dialog-footer>
</ha-dialog>` </ha-wa-dialog>`
: nothing} : nothing}
`; `;
} }
@@ -588,6 +586,10 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
this.showFilters = !this.showFilters; this.showFilters = !this.showFilters;
} }
private _closeFilters = () => {
this.showFilters = false;
};
private _sortingChanged(ev) { private _sortingChanged(ev) {
this._sortDirection = ev.detail.direction; this._sortDirection = ev.detail.direction;
this._sortColumn = this._sortDirection ? ev.detail.column : undefined; this._sortColumn = this._sortDirection ? ev.detail.column : undefined;
@@ -896,13 +898,7 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
--md-assist-chip-trailing-space: 8px; --md-assist-chip-trailing-space: 8px;
} }
ha-dialog { ha-wa-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);
--dialog-content-padding: 0; --dialog-content-padding: 0;
} }