From 3bea09f161e077077308b704f1d3404e8706da8b Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 17 Oct 2024 16:43:42 +0200 Subject: [PATCH] Use undo notification instead of confirmation dialog for cards and badges --- .../components/hui-badge-edit-mode.ts | 8 +-- src/panels/lovelace/editor/delete-badge.ts | 27 ++++++++++ src/panels/lovelace/editor/delete-card.ts | 49 ++++++------------- src/panels/lovelace/sections/hui-section.ts | 9 +++- src/panels/lovelace/views/hui-view.ts | 27 ++++++++-- src/util/toast-deleted-success.ts | 3 +- 6 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 src/panels/lovelace/editor/delete-badge.ts diff --git a/src/panels/lovelace/components/hui-badge-edit-mode.ts b/src/panels/lovelace/components/hui-badge-edit-mode.ts index 2614344085..ab14234385 100644 --- a/src/panels/lovelace/components/hui-badge-edit-mode.ts +++ b/src/panels/lovelace/components/hui-badge-edit-mode.ts @@ -199,14 +199,14 @@ export class HuiBadgeEditMode extends LitElement { this._cutBadge(); break; case 4: - this._deleteBadge(); + this._deleteBadge(true); break; } } private _cutBadge(): void { this._copyBadge(); - this._deleteBadge(); + this._deleteBadge(false); } private _copyBadge(): void { @@ -231,8 +231,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 { diff --git a/src/panels/lovelace/editor/delete-badge.ts b/src/panels/lovelace/editor/delete-badge.ts new file mode 100644 index 0000000000..8431202337 --- /dev/null +++ b/src/panels/lovelace/editor/delete-badge.ts @@ -0,0 +1,27 @@ +import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; +import { HomeAssistant } from "../../../types"; +import { showDeletedToastWithUndo } from "../../../util/toast-deleted-success"; +import { Lovelace } from "../types"; +import { deleteBadge } from "./config-util"; +import { LovelaceCardPath } from "./lovelace-path"; + +export async function deleteBadgeWithUndo( + element: HTMLElement, + hass: HomeAssistant, + lovelace: Lovelace, + path: LovelaceCardPath +): Promise { + try { + const oldConfig = lovelace.config; + const newConfig = deleteBadge(oldConfig, path); + const action = async () => { + lovelace.saveConfig(oldConfig); + }; + await lovelace.saveConfig(newConfig); + showDeletedToastWithUndo(element, hass, action); + } catch (err: any) { + showAlertDialog(element, { + text: `Deleting failed: ${err.message}`, + }); + } +} diff --git a/src/panels/lovelace/editor/delete-card.ts b/src/panels/lovelace/editor/delete-card.ts index f3264bc023..9cc179b7a4 100644 --- a/src/panels/lovelace/editor/delete-card.ts +++ b/src/panels/lovelace/editor/delete-card.ts @@ -1,44 +1,27 @@ import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../../../types"; -import { showDeleteSuccessToast } from "../../../util/toast-deleted-success"; +import { showDeletedToastWithUndo } from "../../../util/toast-deleted-success"; import { Lovelace } from "../types"; -import { showDeleteCardDialog } from "./card-editor/show-delete-card-dialog"; -import { deleteCard, insertCard } from "./config-util"; -import { - LovelaceCardPath, - findLovelaceContainer, - getLovelaceContainerPath, - parseLovelaceCardPath, -} from "./lovelace-path"; +import { deleteCard } from "./config-util"; +import { LovelaceCardPath } from "./lovelace-path"; -export async function confDeleteCard( +export async function deleteCardWithUndo( element: HTMLElement, hass: HomeAssistant, lovelace: Lovelace, path: LovelaceCardPath ): Promise { - const containerPath = getLovelaceContainerPath(path); - const { cardIndex } = parseLovelaceCardPath(path); - const containerConfig = findLovelaceContainer(lovelace.config, containerPath); - if ("strategy" in containerConfig) { - throw new Error("Deleting cards in a strategy is not supported."); + try { + const oldConfig = lovelace.config; + const newConfig = deleteCard(oldConfig, path); + const action = async () => { + await lovelace.saveConfig(oldConfig); + }; + await lovelace.saveConfig(newConfig); + showDeletedToastWithUndo(element, hass, action); + } catch (err: any) { + showAlertDialog(element, { + text: `Deleting failed: ${err.message}`, + }); } - const cardConfig = containerConfig.cards![cardIndex]; - showDeleteCardDialog(element, { - cardConfig, - deleteCard: async () => { - try { - const newLovelace = deleteCard(lovelace.config, path); - await lovelace.saveConfig(newLovelace); - const action = async () => { - await lovelace.saveConfig(insertCard(newLovelace, path, cardConfig)); - }; - showDeleteSuccessToast(element, hass!, action); - } catch (err: any) { - showAlertDialog(element, { - text: `Deleting failed: ${err.message}`, - }); - } - }, - }); } diff --git a/src/panels/lovelace/sections/hui-section.ts b/src/panels/lovelace/sections/hui-section.ts index 07dc7a78f8..27c733952b 100644 --- a/src/panels/lovelace/sections/hui-section.ts +++ b/src/panels/lovelace/sections/hui-section.ts @@ -21,7 +21,7 @@ import { createSectionElement } from "../create-element/create-section-element"; import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog"; import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog"; import { deleteCard } from "../editor/config-util"; -import { confDeleteCard } from "../editor/delete-card"; +import { deleteCardWithUndo } from "../editor/delete-card"; import { parseLovelaceCardPath } from "../editor/lovelace-path"; import { generateLovelaceSectionStrategy } from "../strategies/get-strategy"; import type { Lovelace } from "../types"; @@ -258,7 +258,12 @@ export class HuiSection extends ReactiveElement { ev.stopPropagation(); if (!this.lovelace) return; if (ev.detail.confirm) { - confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path); + deleteCardWithUndo( + this._layoutElement!, + this.hass!, + this.lovelace, + ev.detail.path + ); } else { const newLovelace = deleteCard(this.lovelace!.config, ev.detail.path); this.lovelace.saveConfig(newLovelace); diff --git a/src/panels/lovelace/views/hui-view.ts b/src/panels/lovelace/views/hui-view.ts index cdbb6b31c5..da07025ce3 100644 --- a/src/panels/lovelace/views/hui-view.ts +++ b/src/panels/lovelace/views/hui-view.ts @@ -26,7 +26,8 @@ import { showEditBadgeDialog } from "../editor/badge-editor/show-edit-badge-dial import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog"; import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog"; import { deleteBadge, deleteCard } from "../editor/config-util"; -import { confDeleteCard } from "../editor/delete-card"; +import { deleteBadgeWithUndo } from "../editor/delete-badge"; +import { deleteCardWithUndo } from "../editor/delete-card"; import { LovelaceCardPath, parseLovelaceCardPath, @@ -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; @@ -322,8 +323,14 @@ export class HUIView extends ReactiveElement { }); }); this._layoutElement.addEventListener("ll-delete-card", (ev) => { + if (!this.lovelace) return; if (ev.detail.confirm) { - confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path); + deleteCardWithUndo( + this._layoutElement!, + this.hass!, + this.lovelace!, + ev.detail.path + ); } else { const newLovelace = deleteCard(this.lovelace!.config, ev.detail.path); this.lovelace.saveConfig(newLovelace); @@ -346,8 +353,18 @@ 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 (!this.lovelace) return; + if (ev.detail.confirm) { + deleteBadgeWithUndo( + this._layoutElement!, + this.hass!, + this.lovelace!, + ev.detail.path + ); + } else { + const newLovelace = deleteBadge(this.lovelace!.config, ev.detail.path); + this.lovelace.saveConfig(newLovelace); + } }); } diff --git a/src/util/toast-deleted-success.ts b/src/util/toast-deleted-success.ts index 046e099fec..312c003dae 100644 --- a/src/util/toast-deleted-success.ts +++ b/src/util/toast-deleted-success.ts @@ -2,13 +2,14 @@ import { ShowToastParams } from "../managers/notification-manager"; import { HomeAssistant } from "../types"; import { showToast } from "./toast"; -export const showDeleteSuccessToast = ( +export const showDeletedToastWithUndo = ( el: HTMLElement, hass: HomeAssistant, action?: () => void ) => { const toastParams: ShowToastParams = { message: hass!.localize("ui.common.successfully_deleted"), + duration: 8000, }; if (action) {