Add confirm dialog when deleting a badge

This commit is contained in:
Paul Bottein 2024-10-16 14:56:38 +02:00
parent 4d9e9aaead
commit 282710dacd
No known key found for this signature in database
7 changed files with 190 additions and 10 deletions

View File

@ -180,14 +180,14 @@ export class HuiBadgeEditMode extends LitElement {
this._cutBadge();
break;
case 3:
this._deleteBadge();
this._deleteBadge(true);
break;
}
}
private _cutBadge(): void {
this._copyBadge();
this._deleteBadge();
this._deleteBadge(false);
}
private _copyBadge(): void {
@ -220,8 +220,8 @@ export class HuiBadgeEditMode extends LitElement {
fireEvent(this, "ll-edit-badge", { path: this.path! });
}
private _deleteBadge(): void {
fireEvent(this, "ll-delete-badge", { path: this.path! });
private _deleteBadge(confirm: boolean): void {
fireEvent(this, "ll-delete-badge", { path: this.path!, confirm });
}
static get styles(): CSSResultGroup {

View File

@ -0,0 +1,104 @@
import deepFreeze from "deep-freeze";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import type { LovelaceBadgeConfig } from "../../../../data/lovelace/config/badge";
import { haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";
import "../../badges/hui-badge";
import type { DeleteBadgeDialogParams } from "./show-delete-badge-dialog";
@customElement("hui-dialog-delete-badge")
export class HuiDialogDeleteBadge extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@state() private _params?: DeleteBadgeDialogParams;
@state() private _badgeConfig?: LovelaceBadgeConfig;
public async showDialog(params: DeleteBadgeDialogParams): Promise<void> {
this._params = params;
this._badgeConfig = params.badgeConfig;
if (!Object.isFrozen(this._badgeConfig)) {
this._badgeConfig = deepFreeze(this._badgeConfig);
}
}
public closeDialog(): void {
this._params = undefined;
this._badgeConfig = 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.panel.lovelace.badges.confirm_delete"
)}
>
<div>
${this._badgeConfig
? html`
<div class="element-preview">
<hui-badge
.hass=${this.hass}
.config=${this._badgeConfig}
preview
></hui-badge>
</div>
`
: ""}
</div>
<mwc-button
slot="secondaryAction"
@click=${this.closeDialog}
dialogInitialFocus
>
${this.hass!.localize("ui.common.cancel")}
</mwc-button>
<mwc-button slot="primaryAction" class="warning" @click=${this._delete}>
${this.hass!.localize("ui.common.delete")}
</mwc-button>
</ha-dialog>
`;
}
static get styles(): CSSResultGroup {
return [
haStyleDialog,
css`
.element-preview {
position: relative;
max-width: 500px;
display: block;
width: 100%;
display: flex;
}
hui-badge {
margin: 4px auto;
}
`,
];
}
private _delete(): void {
if (!this._params?.deleteBadge) {
return;
}
this._params.deleteBadge();
this.closeDialog();
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-dialog-delete-badge": HuiDialogDeleteBadge;
}
}

View File

@ -0,0 +1,21 @@
import { fireEvent } from "../../../../common/dom/fire_event";
import { LovelaceBadgeConfig } from "../../../../data/lovelace/config/badge";
export interface DeleteBadgeDialogParams {
deleteBadge: () => void;
badgeConfig?: LovelaceBadgeConfig;
}
export const importDeleteBadgeDialog = () =>
import("./hui-dialog-delete-badge");
export const showDeleteBadgeDialog = (
element: HTMLElement,
deleteBadgeDialogParams: DeleteBadgeDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "hui-dialog-delete-badge",
dialogImport: importDeleteBadgeDialog,
dialogParams: deleteBadgeDialogParams,
});
};

View File

@ -372,13 +372,13 @@ export const deleteBadge = (
config: LovelaceConfig,
path: LovelaceCardPath
): LovelaceConfig => {
const { cardIndex } = parseLovelaceCardPath(path);
const { cardIndex: badgeIndex } = parseLovelaceCardPath(path);
const containerPath = getLovelaceContainerPath(path);
const badges = findLovelaceItems("badges", config, containerPath);
const newBadges = (badges ?? []).filter(
(_origConf, ind) => ind !== cardIndex
(_origConf, ind) => ind !== badgeIndex
);
const newConfig = updateLovelaceItems(

View File

@ -0,0 +1,47 @@
import { ensureBadgeConfig } from "../../../data/lovelace/config/badge";
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
import { HomeAssistant } from "../../../types";
import { showDeleteSuccessToast } from "../../../util/toast-deleted-success";
import { Lovelace } from "../types";
import { showDeleteBadgeDialog } from "./badge-editor/show-delete-badge-dialog";
import { deleteBadge, insertBadge } from "./config-util";
import {
LovelaceCardPath,
findLovelaceItems,
getLovelaceContainerPath,
parseLovelaceCardPath,
} from "./lovelace-path";
export async function confDeleteBadge(
element: HTMLElement,
hass: HomeAssistant,
lovelace: Lovelace,
path: LovelaceCardPath
): Promise<void> {
const { cardIndex: badgeIndex } = parseLovelaceCardPath(path);
const containerPath = getLovelaceContainerPath(path);
const badges = findLovelaceItems("badges", lovelace.config, containerPath);
const badgeConfig = ensureBadgeConfig(badges![badgeIndex]);
showDeleteBadgeDialog(element, {
badgeConfig,
deleteBadge: async () => {
try {
const newLovelace = deleteBadge(lovelace.config, path);
await lovelace.saveConfig(newLovelace);
const action = async () => {
await lovelace.saveConfig(
insertBadge(newLovelace, path, badgeConfig)
);
};
showDeleteSuccessToast(element, hass!, action);
} catch (err: any) {
showAlertDialog(element, {
text: `Deleting failed: ${err.message}`,
});
}
},
});
}

View File

@ -37,6 +37,7 @@ import { generateLovelaceViewStrategy } from "../strategies/get-strategy";
import type { Lovelace } from "../types";
import { DEFAULT_VIEW_LAYOUT, PANEL_VIEW_LAYOUT } from "./const";
import { showCreateBadgeDialog } from "../editor/badge-editor/show-create-badge-dialog";
import { confDeleteBadge } from "../editor/delete-badge";
declare global {
// for fire event
@ -46,7 +47,7 @@ declare global {
"ll-delete-card": { path: LovelaceCardPath; confirm: boolean };
"ll-create-badge": undefined;
"ll-edit-badge": { path: LovelaceCardPath };
"ll-delete-badge": { path: LovelaceCardPath };
"ll-delete-badge": { path: LovelaceCardPath; confirm: boolean };
}
interface HTMLElementEventMap {
"ll-create-card": HASSDomEvent<HASSDomEvents["ll-create-card"]>;
@ -348,8 +349,12 @@ export class HUIView extends ReactiveElement {
});
});
this._layoutElement.addEventListener("ll-delete-badge", (ev) => {
const newLovelace = deleteBadge(this.lovelace!.config, ev.detail.path);
this.lovelace.saveConfig(newLovelace);
if (ev.detail.confirm) {
confDeleteBadge(this, this.hass!, this.lovelace!, ev.detail.path);
} else {
const newLovelace = deleteBadge(this.lovelace!.config, ev.detail.path);
this.lovelace.saveConfig(newLovelace);
}
});
}

View File

@ -5360,7 +5360,7 @@
}
},
"cards": {
"confirm_delete": "Are you sure you want to delete this card?",
"confirm_delete": "Delete card?",
"show_more_info": "Show more information",
"actions": {
"action_confirmation": "Are you sure you want to run action ''{action}''?",
@ -5496,6 +5496,9 @@
"default_heading": "Kitchen"
}
},
"badges": {
"confirm_delete": "Delete badge?"
},
"unused_entities": {
"title": "Unused entities",
"available_entities": "These are the entities that you have available, but are not in your dashboard yet.",