1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-14 23:18:21 +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 type { HomeAssistant } from "../../types";
import "../ha-button";
import { createCloseHeading } from "../ha-dialog";
import "../ha-dialog-footer";
import "../ha-icon-button";
import "../ha-list";
import "../ha-list-item";
import "../ha-sortable";
import "../ha-svg-icon";
import "../ha-wa-dialog";
import type {
DataTableColumnContainer,
DataTableColumnData,
@@ -31,13 +32,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 });
}
@@ -93,13 +101,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}
@@ -154,16 +160,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>
`;
}
@@ -283,22 +291,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

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

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

@@ -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,15 @@ 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}
prevent-scrim-close
@closed=${this._dialogClosed}
>
<ha-form
dialogInitialFocus
autofocus
.hass=${this.hass}
.computeLabel=${this._params.computeLabel}
.computeHelper=${this._params.computeHelper}
@@ -69,17 +86,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,72 @@ 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"
prevent-scrim-close
@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}
.selected=${this._language === lang.id}
>
${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}
.selected=${this._language === lang.id}
>
${lang.primary}
</ha-dropdown-item>`
)}
</ha-dropdown>`
: nothing
: nothing}
<div
class="content"
@next-step=${this._goToNextStep}
@@ -288,7 +286,7 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
></ha-voice-assistant-setup-step-success>`
: nothing}
</div>
</ha-dialog>
</ha-wa-dialog>
`;
}
@@ -373,20 +371,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 {
@@ -277,7 +281,7 @@ export class HaVoiceCommandDialog extends LitElement {
margin-inline-start: -9px;
}
ha-dropdown ha-button {
--ha-button-height: 20px;
--ha-button-height: var(--ha-space-5);
}
ha-dropdown ha-button::part(base) {
margin-left: 5px;
@@ -289,15 +293,15 @@ export class HaVoiceCommandDialog extends LitElement {
}
}
ha-dropdown ha-button ha-svg-icon {
height: 28px;
margin-left: 4px;
margin-inline-start: 4px;
height: var(--ha-space-7);
margin-left: var(--ha-space-1);
margin-inline-start: var(--ha-space-1);
margin-inline-end: initial;
direction: var(--direction);
}
ha-dropdown-item ha-svg-icon {
margin-left: 4px;
margin-inline-start: 4px;
margin-left: var(--ha-space-1);
margin-inline-start: var(--ha-space-1);
margin-inline-end: initial;
direction: var(--direction);
display: block;
@@ -310,10 +314,6 @@ export class HaVoiceCommandDialog extends LitElement {
display: flex;
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";
import { showDataTableSettingsDialog } from "../components/data-table/show-dialog-data-table-settings";
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-icon-button";
import "../components/ha-svg-icon";
@@ -538,44 +538,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}
`;
}
@@ -588,6 +586,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;
@@ -896,13 +898,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;
}