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

Migrate app store dialogs to wa, standardise registry actions (#29542)

* Migrate config-apps dialog(s) to wa

* Apply suggestions from code review

Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>

* Use standard buttons

* Use back action

* Remove extra close action

---------

Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
This commit is contained in:
Aidan Timson
2026-02-11 09:34:53 +00:00
committed by GitHub
parent 1d1e05dbdf
commit 938cc6a1a1
2 changed files with 103 additions and 109 deletions

View File

@@ -1,14 +1,15 @@
import { mdiDelete, mdiPlus } from "@mdi/js";
import { mdiDelete } from "@mdi/js";
import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators";
import "../../../../../components/ha-button";
import { createCloseHeading } from "../../../../../components/ha-dialog";
import "../../../../../components/ha-dialog-footer";
import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-icon-button-prev";
import "../../../../../components/ha-settings-row";
import "../../../../../components/ha-svg-icon";
import "../../../../../components/ha-wa-dialog";
import { extractApiErrorMessage } from "../../../../../data/hassio/common";
import {
addHassioDockerRegistry,
@@ -18,6 +19,7 @@ import {
import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box";
import { haStyle, haStyleDialog } from "../../../../../resources/styles";
import type { HomeAssistant } from "../../../../../types";
import { fireEvent } from "../../../../../common/dom/fire_event";
const SCHEMA = [
{
@@ -52,99 +54,101 @@ class AppsRegistriesDialog extends LitElement {
password?: string;
} = {};
@state() private _opened = false;
@state() private _open = false;
@state() private _addingRegistry = false;
protected render(): TemplateResult {
return html`
<ha-dialog
.open=${this._opened}
@closed=${this.closeDialog}
scrimClickAction
escapeKeyAction
hideActions
.heading=${createCloseHeading(
this.hass,
this._addingRegistry
? this.hass.localize(
"ui.panel.config.apps.dialog.registries.title_add"
)
: this.hass.localize(
"ui.panel.config.apps.dialog.registries.title_manage"
)
)}
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
@closed=${this._dialogClosed}
header-title=${this._addingRegistry
? this.hass.localize(
"ui.panel.config.apps.dialog.registries.title_add"
)
: this.hass.localize(
"ui.panel.config.apps.dialog.registries.title_manage"
)}
>
${this._addingRegistry
? html`
<ha-icon-button-prev
slot="headerNavigationIcon"
@click=${this._stopAddingRegistry}
></ha-icon-button-prev>
`
: ""}
${this._addingRegistry
? html`
<ha-form
autofocus
.data=${this._input}
.schema=${SCHEMA}
@value-changed=${this._valueChanged}
.computeLabel=${this._computeLabel}
dialogInitialFocus
></ha-form>
<div class="action">
`
: html`${this._registries?.length
? this._registries.map(
(entry) => html`
<ha-settings-row class="registry">
<span slot="heading"> ${entry.registry} </span>
<span slot="description">
${this.hass.localize(
"ui.panel.config.apps.dialog.registries.username"
)}:
${entry.username}
</span>
<ha-icon-button
.entry=${entry}
.label=${this.hass.localize(
"ui.panel.config.apps.dialog.registries.remove"
)}
.path=${mdiDelete}
@click=${this._removeRegistry}
></ha-icon-button>
</ha-settings-row>
`
)
: html`
<ha-alert>
${this.hass.localize(
"ui.panel.config.apps.dialog.registries.no_registries"
)}
</ha-alert>
`}`}
<ha-dialog-footer slot="footer">
${this._addingRegistry
? html`
<ha-button
slot="primaryAction"
?disabled=${Boolean(
!this._input.registry ||
!this._input.username ||
!this._input.password
)}
@click=${this._addNewRegistry}
appearance="filled"
size="small"
>
<ha-svg-icon slot="start" .path=${mdiPlus}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.apps.dialog.registries.add_registry"
)}
</ha-button>
</div>
`
: html`${this._registries?.length
? this._registries.map(
(entry) => html`
<ha-settings-row class="registry">
<span slot="heading"> ${entry.registry} </span>
<span slot="description">
${this.hass.localize(
"ui.panel.config.apps.dialog.registries.username"
)}:
${entry.username}
</span>
<ha-icon-button
.entry=${entry}
.label=${this.hass.localize(
"ui.panel.config.apps.dialog.registries.remove"
)}
.path=${mdiDelete}
@click=${this._removeRegistry}
></ha-icon-button>
</ha-settings-row>
`
)
: html`
<ha-alert>
${this.hass.localize(
"ui.panel.config.apps.dialog.registries.no_registries"
)}
</ha-alert>
`}
<div class="action">
`
: html`
<ha-button
slot="primaryAction"
@click=${this._addRegistry}
dialogInitialFocus
appearance="filled"
size="small"
autofocus
>
<ha-svg-icon slot="start" .path=${mdiPlus}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.apps.dialog.registries.add_new_registry"
)}
</ha-button>
</div> `}
</ha-dialog>
`}
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -158,24 +162,20 @@ class AppsRegistriesDialog extends LitElement {
}
public async showDialog(): Promise<void> {
this._opened = true;
this._open = true;
this._input = {};
await this._loadRegistries();
await this.updateComplete;
}
public closeDialog(): void {
this._addingRegistry = false;
this._opened = false;
this._input = {};
this._open = false;
}
public focus(): void {
this.updateComplete.then(() =>
(
this.shadowRoot?.querySelector("[dialogInitialFocus]") as HTMLElement
)?.focus()
);
private _dialogClosed(): void {
this._open = false;
this._stopAddingRegistry();
fireEvent(this, "dialog-closed");
}
private async _loadRegistries(): Promise<void> {
@@ -190,6 +190,11 @@ class AppsRegistriesDialog extends LitElement {
this._addingRegistry = true;
}
private _stopAddingRegistry(): void {
this._addingRegistry = false;
this._input = {};
}
private async _addNewRegistry(): Promise<void> {
const data = {};
data[this._input.registry!] = {
@@ -200,8 +205,7 @@ class AppsRegistriesDialog extends LitElement {
try {
await addHassioDockerRegistry(this.hass, data);
await this._loadRegistries();
this._addingRegistry = false;
this._input = {};
this._stopAddingRegistry();
} catch (err: any) {
showAlertDialog(this, {
title: this.hass.localize(
@@ -238,12 +242,6 @@ class AppsRegistriesDialog extends LitElement {
border-radius: var(--ha-border-radius-sm);
margin-top: 4px;
}
.action {
margin-top: 24px;
width: 100%;
display: flex;
justify-content: flex-end;
}
ha-icon-button {
color: var(--error-color);
margin-right: -10px;

View File

@@ -7,7 +7,7 @@ import { fireEvent } from "../../../../../common/dom/fire_event";
import { caseInsensitiveStringCompare } from "../../../../../common/string/compare";
import "../../../../../components/ha-alert";
import "../../../../../components/ha-button";
import { createCloseHeading } from "../../../../../components/ha-dialog";
import "../../../../../components/ha-dialog-footer";
import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-md-list";
import "../../../../../components/ha-md-list-item";
@@ -15,6 +15,7 @@ import "../../../../../components/ha-svg-icon";
import "../../../../../components/ha-textfield";
import type { HaTextField } from "../../../../../components/ha-textfield";
import "../../../../../components/ha-tooltip";
import "../../../../../components/ha-wa-dialog";
import type {
HassioAddonInfo,
HassioAddonsInfo,
@@ -42,7 +43,7 @@ class AppsRepositoriesDialog extends LitElement {
@state() private _addon?: HassioAddonsInfo;
@state() private _opened = false;
@state() private _open = false;
@state() private _processing = false;
@@ -51,16 +52,22 @@ class AppsRepositoriesDialog extends LitElement {
public async showDialog(dialogParams: RepositoryDialogParams): Promise<void> {
this._dialogParams = dialogParams;
this._addon = dialogParams.addon;
this._opened = true;
this._open = true;
await this._loadData();
await this.updateComplete;
}
public closeDialog(): void {
this._open = false;
}
private _dialogClosed(): void {
this._dialogParams?.closeCallback?.();
this._dialogParams = undefined;
this._opened = false;
this._addon = undefined;
this._open = false;
this._error = "";
fireEvent(this, "dialog-closed");
}
private _filteredRepositories = memoizeOne((repos: HassioAddonRepository[]) =>
@@ -97,14 +104,12 @@ class AppsRepositoriesDialog extends LitElement {
this._addon.addons
);
return html`
<ha-dialog
.open=${this._opened}
@closed=${this.closeDialog}
scrimClickAction
escapeKeyAction
.heading=${createCloseHeading(
this.hass,
this.hass.localize("ui.panel.config.apps.dialog.repositories.title")
<ha-wa-dialog
.hass=${this.hass}
.open=${this._open}
@closed=${this._dialogClosed}
header-title=${this.hass.localize(
"ui.panel.config.apps.dialog.repositories.title"
)}
>
${this._error
@@ -161,7 +166,7 @@ class AppsRepositoriesDialog extends LitElement {
"ui.panel.config.apps.dialog.repositories.add"
)}
@keydown=${this._handleKeyAdd}
dialogInitialFocus
autofocus
></ha-textfield>
<ha-button
.loading=${this._processing}
@@ -176,10 +181,12 @@ class AppsRepositoriesDialog extends LitElement {
</ha-button>
</div>
</div>
<ha-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.common.close")}
</ha-button>
</ha-dialog>
<ha-dialog-footer slot="footer">
<ha-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.common.close")}
</ha-button>
</ha-dialog-footer>
</ha-wa-dialog>
`;
}
@@ -188,9 +195,6 @@ class AppsRepositoriesDialog extends LitElement {
haStyle,
haStyleDialog,
css`
ha-dialog.button-left {
--justify-action-buttons: flex-start;
}
.form {
color: var(--primary-text-color);
}
@@ -215,14 +219,6 @@ class AppsRepositoriesDialog extends LitElement {
];
}
public focus() {
this.updateComplete.then(() =>
(
this.shadowRoot?.querySelector("[dialogInitialFocus]") as HTMLElement
)?.focus()
);
}
private _handleKeyAdd(ev: KeyboardEvent) {
ev.stopPropagation();
if (ev.key !== "Enter") {