Update Add and Edit area dialog (#17711)

This commit is contained in:
Simon Lamon 2023-09-26 22:41:02 +02:00 committed by GitHub
parent cbd424ff5a
commit 0b6813d9dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 264 deletions

View File

@ -1,137 +0,0 @@
import "@material/mwc-button/mwc-button";
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-alert";
import "../../components/ha-dialog";
import { haStyle, haStyleDialog } from "../../resources/styles";
import { HomeAssistant } from "../../types";
import { AliasesDialogParams } from "./show-dialog-aliases";
import "../../components/ha-aliases-editor";
@customElement("dialog-aliases")
class DialogAliases extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@state() private _error?: string;
@state() private _params?: AliasesDialogParams;
@state() private _aliases!: string[];
@state() private _submitting = false;
public async showDialog(params: AliasesDialogParams): Promise<void> {
this._params = params;
this._error = undefined;
this._aliases =
this._params.aliases?.length > 0
? [...this._params.aliases].sort()
: [""];
await this.updateComplete;
}
public closeDialog(): void {
this._error = "";
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
protected render() {
if (!this._params) {
return nothing;
}
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${this.hass.localize("ui.dialogs.aliases.heading", {
name: this._params.name,
})}
>
<div>
${this._error
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
: ""}
<ha-aliases-editor
.hass=${this.hass}
.aliases=${this._aliases}
@value-changed=${this._aliasesChanged}
></ha-aliases-editor>
</div>
<mwc-button
slot="secondaryAction"
@click=${this.closeDialog}
.disabled=${this._submitting}
>
${this.hass.localize("ui.common.cancel")}
</mwc-button>
<mwc-button
slot="primaryAction"
@click=${this._updateAliases}
.disabled=${this._submitting}
>
${this.hass.localize("ui.dialogs.aliases.save")}
</mwc-button>
</ha-dialog>
`;
}
private _aliasesChanged(ev: CustomEvent): void {
this._aliases = ev.detail.value;
}
private async _updateAliases(): Promise<void> {
this._submitting = true;
const noEmptyAliases = this._aliases
.map((alias) => alias.trim())
.filter((alias) => alias);
try {
await this._params!.updateAliases(noEmptyAliases);
this.closeDialog();
} catch (err: any) {
this._error =
err.message || this.hass.localize("ui.dialogs.aliases.unknown_error");
} finally {
this._submitting = false;
}
}
static get styles(): CSSResultGroup {
return [
haStyle,
haStyleDialog,
css`
.row {
margin-bottom: 8px;
}
ha-textfield {
display: block;
}
ha-icon-button {
display: block;
}
mwc-button {
margin-left: 8px;
}
#alias_input {
margin-top: 8px;
}
.alias {
border: 1px solid var(--divider-color);
border-radius: 4px;
margin-top: 4px;
--mdc-icon-button-size: 24px;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"dialog-aliases": DialogAliases;
}
}

View File

@ -1,20 +0,0 @@
import { fireEvent } from "../../common/dom/fire_event";
export interface AliasesDialogParams {
name: string;
aliases: string[];
updateAliases: (aliases: string[]) => Promise<unknown>;
}
export const loadAliasesDialog = () => import("./dialog-aliases");
export const showAliasesDialog = (
element: HTMLElement,
aliasesParams: AliasesDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-aliases",
dialogImport: loadAliasesDialog,
dialogParams: aliasesParams,
});
};

View File

@ -1,21 +1,19 @@
import "@material/mwc-button";
import "@material/mwc-list/mwc-list";
import { mdiPencil } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { property, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
import { stringCompare } from "../../../common/string/compare";
import "../../../components/ha-alert";
import { createCloseHeading } from "../../../components/ha-dialog";
import "../../../components/ha-picture-upload";
import type { HaPictureUpload } from "../../../components/ha-picture-upload";
import "../../../components/ha-textfield";
import { AreaRegistryEntryMutableParams } from "../../../data/area_registry";
import { showAliasesDialog } from "../../../dialogs/aliases/show-dialog-aliases";
import { CropOptions } from "../../../dialogs/image-cropper-dialog/show-image-cropper-dialog";
import { ValueChangedEvent, HomeAssistant } from "../../../types";
import { haStyleDialog } from "../../../resources/styles";
import { AreaRegistryDetailDialogParams } from "./show-dialog-area-registry-detail";
import "../../../components/ha-aliases-editor";
const cropOptions: CropOptions = {
round: false,
@ -69,8 +67,8 @@ class DialogAreaDetail extends LitElement {
.heading=${createCloseHeading(
this.hass,
entry
? entry.name
: this.hass.localize("ui.panel.config.areas.editor.default_name")
? this.hass.localize("ui.panel.config.areas.editor.update_area")
: this.hass.localize("ui.panel.config.areas.editor.create_area")
)}
>
<div>
@ -80,14 +78,16 @@ class DialogAreaDetail extends LitElement {
<div class="form">
${entry
? html`
<div>
${this.hass.localize(
"ui.panel.config.areas.editor.area_id"
)}:
${entry.area_id}
</div>
<ha-settings-row>
<span slot="heading">
${this.hass.localize(
"ui.panel.config.areas.editor.area_id"
)}
</span>
<span slot="description"> ${entry.area_id} </span>
</ha-settings-row>
`
: ""}
: nothing}
<ha-textfield
.value=${this._name}
@ -108,75 +108,40 @@ class DialogAreaDetail extends LitElement {
@change=${this._pictureChanged}
></ha-picture-upload>
<div class="label">
<h3 class="header">
${this.hass.localize(
"ui.panel.config.areas.editor.aliases_section"
)}
</div>
<mwc-list class="aliases" @action=${this._handleAliasesClicked}>
<mwc-list-item .twoline=${this._aliases.length > 0} hasMeta>
<span>
${this._aliases.length > 0
? this.hass.localize(
"ui.panel.config.areas.editor.configured_aliases",
{ count: this._aliases.length }
)
: this.hass.localize(
"ui.panel.config.areas.editor.no_aliases"
)}
</span>
<span slot="secondary">
${[...this._aliases]
.sort((a, b) =>
stringCompare(a, b, this.hass.locale.language)
)
.join(", ")}
</span>
<ha-svg-icon slot="meta" .path=${mdiPencil}></ha-svg-icon>
</mwc-list-item>
</mwc-list>
<div class="secondary">
</h3>
<p class="description">
${this.hass.localize(
"ui.panel.config.areas.editor.aliases_description"
)}
</div>
</p>
<ha-aliases-editor
.hass=${this.hass}
.aliases=${this._aliases}
@value-changed=${this._aliasesChanged}
></ha-aliases-editor>
</div>
</div>
${entry
? html`
<mwc-button
slot="secondaryAction"
class="warning"
@click=${this._deleteEntry}
.disabled=${this._submitting}
>
${this.hass.localize("ui.panel.config.areas.editor.delete")}
</mwc-button>
`
: nothing}
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.common.cancel")}
</mwc-button>
<mwc-button
slot="primaryAction"
@click=${this._updateEntry}
.disabled=${nameInvalid || this._submitting}
>
${entry
? this.hass.localize("ui.panel.config.areas.editor.update")
: this.hass.localize("ui.panel.config.areas.editor.create")}
? this.hass.localize("ui.common.save")
: this.hass.localize("ui.common.add")}
</mwc-button>
</ha-dialog>
`;
}
private _handleAliasesClicked() {
showAliasesDialog(this, {
name: this._name,
aliases: this._aliases,
updateAliases: async (aliases: string[]) => {
this._aliases = aliases;
},
});
}
private _isNameValid() {
return this._name.trim() !== "";
}
@ -214,15 +179,8 @@ class DialogAreaDetail extends LitElement {
}
}
private async _deleteEntry() {
this._submitting = true;
try {
if (await this._params!.removeEntry!()) {
this.closeDialog();
}
} finally {
this._submitting = false;
}
private _aliasesChanged(ev: CustomEvent): void {
this._aliases = ev.detail.value;
}
static get styles(): CSSResultGroup {

View File

@ -1,6 +1,6 @@
import "@material/mwc-button";
import "@material/mwc-list";
import { mdiImagePlus, mdiPencil } from "@mdi/js";
import { mdiDelete, mdiDotsVertical, mdiImagePlus, mdiPencil } from "@mdi/js";
import {
HassEntity,
UnsubscribeFunc,
@ -246,13 +246,32 @@ class HaConfigAreaPage extends SubscribeMixin(LitElement) {
.narrow=${this.narrow}
.header=${area.name}
>
<ha-icon-button
.path=${mdiPencil}
.entry=${area}
@click=${this._showSettings}
slot="toolbar-icon"
.label=${this.hass.localize("ui.panel.config.areas.edit_settings")}
></ha-icon-button>
<ha-button-menu slot="toolbar-icon">
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<mwc-list-item
graphic="icon"
.entry=${area}
@click=${this._showSettings}
>
${this.hass.localize("ui.panel.config.areas.edit_settings")}
<ha-svg-icon slot="graphic" .path=${mdiPencil}> </ha-svg-icon>
</mwc-list-item>
<mwc-list-item
class="warning"
graphic="icon"
@click=${this._deleteConfirm}
>
${this.hass.localize("ui.panel.config.areas.editor.delete")}
<ha-svg-icon class="warning" slot="graphic" .path=${mdiDelete}>
</ha-svg-icon>
</mwc-list-item>
</ha-button-menu>
<div class="container">
<div class="column">
@ -634,31 +653,25 @@ class HaConfigAreaPage extends SubscribeMixin(LitElement) {
entry,
updateEntry: async (values) =>
updateAreaRegistryEntry(this.hass!, entry!.area_id, values),
removeEntry: async () => {
if (
!(await showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.config.areas.delete.confirmation_title",
{ name: entry!.name }
),
text: this.hass.localize(
"ui.panel.config.areas.delete.confirmation_text"
),
dismissText: this.hass.localize("ui.common.cancel"),
confirmText: this.hass.localize("ui.common.delete"),
destructive: true,
}))
) {
return false;
}
});
}
try {
await deleteAreaRegistryEntry(this.hass!, entry!.area_id);
afterNextRender(() => history.back());
return true;
} catch (err: any) {
return false;
}
private async _deleteConfirm() {
const area = this._area(this.areaId, this._areas);
showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.config.areas.delete.confirmation_title",
{ name: area!.name }
),
text: this.hass.localize(
"ui.panel.config.areas.delete.confirmation_text"
),
dismissText: this.hass.localize("ui.common.cancel"),
confirmText: this.hass.localize("ui.common.delete"),
destructive: true,
confirm: async () => {
await deleteAreaRegistryEntry(this.hass!, area!.area_id);
afterNextRender(() => history.back());
},
});
}

View File

@ -10,7 +10,6 @@ export interface AreaRegistryDetailDialogParams {
updateEntry?: (
updates: Partial<AreaRegistryEntryMutableParams>
) => Promise<unknown>;
removeEntry?: () => Promise<boolean>;
}
export const loadAreaRegistryDetailDialog = () =>

View File

@ -294,6 +294,7 @@
"undo": "Undo",
"move": "Move",
"save": "Save",
"add": "Add",
"edit": "Edit",
"submit": "Submit",
"rename": "Rename",
@ -1665,10 +1666,9 @@
"create_area": "Create Area"
},
"editor": {
"default_name": "New area",
"create_area": "Create area",
"update_area": "Update area",
"delete": "Delete",
"update": "Update",
"create": "Create",
"name": "Name",
"name_required": "Name is required",
"area_id": "Area ID",