Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add confirm dialog when deleting a badge #22398

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/panels/lovelace/components/hui-badge-edit-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
104 changes: 104 additions & 0 deletions src/panels/lovelace/editor/badge-editor/hui-dialog-delete-badge.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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,
});
};
4 changes: 2 additions & 2 deletions src/panels/lovelace/editor/config-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
47 changes: 47 additions & 0 deletions src/panels/lovelace/editor/delete-badge.ts
Original file line number Diff line number Diff line change
@@ -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}`,
});
}
},
});
}
11 changes: 8 additions & 3 deletions src/panels/lovelace/views/hui-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"]>;
Expand Down Expand Up @@ -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);
}
});
}

Expand Down
5 changes: 4 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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}''?",
Expand Down Expand Up @@ -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.",
Expand Down
Loading