mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 19:26:36 +00:00
Confirmation Dialog (#4053)
* ✨ Add confirmation dialog * ✨ Add confirmation dialog to service calls * 🔨 Change returned value * ✨ Add confirmation dialog to integration remove * ✨ Add to entity registry * ✨ Add to delete card and add translation * ✨ Add to views deletion * 🔨 Remove async * 🔨 Fix min-width for smaller screens * 🔨 Remove async * Fix wrong merge * Update ha-config-entry-page.ts
This commit is contained in:
parent
d4d6b7e2ce
commit
bb73039205
@ -3,6 +3,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import "./ha-progress-button";
|
||||
import { EventsMixin } from "../../mixins/events-mixin";
|
||||
import { showConfirmationDialog } from "../../dialogs/confirmation/show-dialog-confirmation";
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
@ -49,10 +50,7 @@ class HaCallServiceButton extends EventsMixin(PolymerElement) {
|
||||
};
|
||||
}
|
||||
|
||||
buttonTapped() {
|
||||
if (this.confirmation && !window.confirm(this.confirmation)) {
|
||||
return;
|
||||
}
|
||||
callService() {
|
||||
this.progress = true;
|
||||
var el = this;
|
||||
var eventData = {
|
||||
@ -79,6 +77,17 @@ class HaCallServiceButton extends EventsMixin(PolymerElement) {
|
||||
el.fire("hass-service-called", eventData);
|
||||
});
|
||||
}
|
||||
|
||||
buttonTapped() {
|
||||
if (this.confirmation) {
|
||||
showConfirmationDialog(this, {
|
||||
text: this.confirmation,
|
||||
confirm: () => this.callService(),
|
||||
});
|
||||
} else {
|
||||
this.callService();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-call-service-button", HaCallServiceButton);
|
||||
|
107
src/dialogs/confirmation/dialog-confirmation.ts
Normal file
107
src/dialogs/confirmation/dialog-confirmation.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
css,
|
||||
CSSResult,
|
||||
TemplateResult,
|
||||
customElement,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
|
||||
import "../../components/dialog/ha-paper-dialog";
|
||||
import "../../components/ha-switch";
|
||||
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { ConfirmationDialogParams } from "./show-dialog-confirmation";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
|
||||
@customElement("dialog-confirmation")
|
||||
class DialogConfirmation extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() private _params?: ConfirmationDialogParams;
|
||||
|
||||
public async showDialog(params: ConfirmationDialogParams): Promise<void> {
|
||||
this._params = params;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this._params) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-paper-dialog
|
||||
with-backdrop
|
||||
opened
|
||||
@opened-changed="${this._openedChanged}"
|
||||
>
|
||||
<h2>
|
||||
${this._params.title
|
||||
? this._params.title
|
||||
: this.hass.localize("ui.dialogs.confirmation.title")}
|
||||
</h2>
|
||||
<paper-dialog-scrollable>
|
||||
<p>${this._params.text}</p>
|
||||
</paper-dialog-scrollable>
|
||||
<div class="paper-dialog-buttons">
|
||||
<mwc-button @click="${this._dismiss}">
|
||||
${this.hass.localize("ui.dialogs.confirmation.cancel")}
|
||||
</mwc-button>
|
||||
<mwc-button @click="${this._confirm}">
|
||||
${this.hass.localize("ui.dialogs.confirmation.ok")}
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-paper-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _dismiss(): Promise<void> {
|
||||
this._params = undefined;
|
||||
}
|
||||
|
||||
private async _confirm(): Promise<void> {
|
||||
this._params!.confirm();
|
||||
this._dismiss();
|
||||
}
|
||||
|
||||
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
||||
if (!(ev.detail as any).value) {
|
||||
this._params = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-paper-dialog {
|
||||
min-width: 400px;
|
||||
max-width: 500px;
|
||||
}
|
||||
@media (max-width: 400px) {
|
||||
ha-paper-dialog {
|
||||
min-width: initial;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 24px;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.secondary {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-confirmation": DialogConfirmation;
|
||||
}
|
||||
}
|
21
src/dialogs/confirmation/show-dialog-confirmation.ts
Normal file
21
src/dialogs/confirmation/show-dialog-confirmation.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
|
||||
export interface ConfirmationDialogParams {
|
||||
title?: string;
|
||||
text: string;
|
||||
confirm: () => void;
|
||||
}
|
||||
|
||||
export const loadConfirmationDialog = () =>
|
||||
import(/* webpackChunkName: "confirmation" */ "./dialog-confirmation");
|
||||
|
||||
export const showConfirmationDialog = (
|
||||
element: HTMLElement,
|
||||
systemLogDetailParams: ConfirmationDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-confirmation",
|
||||
dialogImport: loadConfirmationDialog,
|
||||
dialogParams: systemLogDetailParams,
|
||||
});
|
||||
};
|
@ -26,6 +26,7 @@ import {
|
||||
updateEntityRegistryEntry,
|
||||
removeEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { showConfirmationDialog } from "../../../dialogs/confirmation/show-dialog-confirmation";
|
||||
|
||||
class DialogEntityRegistryDetail extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -139,7 +140,7 @@ class DialogEntityRegistryDetail extends LitElement {
|
||||
<div class="paper-dialog-buttons">
|
||||
<mwc-button
|
||||
class="warning"
|
||||
@click="${this._deleteEntry}"
|
||||
@click="${this._confirmDeleteEntry}"
|
||||
.disabled=${this._submitting}
|
||||
>
|
||||
${this.hass.localize(
|
||||
@ -186,22 +187,6 @@ class DialogEntityRegistryDetail extends LitElement {
|
||||
}
|
||||
|
||||
private async _deleteEntry(): Promise<void> {
|
||||
if (
|
||||
!confirm(
|
||||
`${this.hass.localize(
|
||||
"ui.panel.config.entity_registry.editor.confirm_delete"
|
||||
)}
|
||||
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entity_registry.editor.confirm_delete2",
|
||||
"platform",
|
||||
this._platform
|
||||
)}`
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._submitting = true;
|
||||
|
||||
try {
|
||||
@ -212,6 +197,20 @@ ${this.hass.localize(
|
||||
}
|
||||
}
|
||||
|
||||
private _confirmDeleteEntry(): void {
|
||||
showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.entity_registry.editor.confirm_delete"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.entity_registry.editor.confirm_delete2",
|
||||
"platform",
|
||||
this._platform
|
||||
),
|
||||
confirm: () => this._deleteEntry(),
|
||||
});
|
||||
}
|
||||
|
||||
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
||||
if (!(ev.detail as any).value) {
|
||||
this._params = undefined;
|
||||
|
@ -17,6 +17,7 @@ import { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||
import { AreaRegistryEntry } from "../../../../data/area_registry";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { showConfigEntrySystemOptionsDialog } from "../../../../dialogs/config-entry-system-options/show-dialog-config-entry-system-options";
|
||||
import { showConfirmationDialog } from "../../../../dialogs/confirmation/show-dialog-confirmation";
|
||||
|
||||
class HaConfigEntryPage extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -110,7 +111,7 @@ class HaConfigEntryPage extends LitElement {
|
||||
"integration",
|
||||
configEntry.title
|
||||
)}
|
||||
@click=${this._removeEntry}
|
||||
@click=${this._confirmRemoveEntry}
|
||||
></paper-icon-button>
|
||||
|
||||
<div class="content">
|
||||
@ -159,17 +160,16 @@ class HaConfigEntryPage extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _removeEntry() {
|
||||
if (
|
||||
!confirm(
|
||||
this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.delete_confirm"
|
||||
)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
private _confirmRemoveEntry() {
|
||||
showConfirmationDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.delete_confirm"
|
||||
),
|
||||
confirm: () => this._removeEntry(),
|
||||
});
|
||||
}
|
||||
|
||||
private _removeEntry() {
|
||||
deleteConfigEntry(this.hass, this.configEntryId).then((result) => {
|
||||
fireEvent(this, "hass-reload-entries");
|
||||
if (result.require_restart) {
|
||||
|
@ -165,7 +165,7 @@ export class HuiCardOptions extends LitElement {
|
||||
}
|
||||
|
||||
private _deleteCard(): void {
|
||||
confDeleteCard(this.lovelace!, this.path!);
|
||||
confDeleteCard(this, this.hass!, this.lovelace!, this.path!);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,22 @@
|
||||
import { Lovelace } from "../types";
|
||||
import { deleteCard } from "./config-util";
|
||||
import { showConfirmationDialog } from "../../../dialogs/confirmation/show-dialog-confirmation";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
export async function confDeleteCard(
|
||||
element: HTMLElement,
|
||||
hass: HomeAssistant,
|
||||
lovelace: Lovelace,
|
||||
path: [number, number]
|
||||
): Promise<void> {
|
||||
if (!confirm("Are you sure you want to delete this card?")) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await lovelace.saveConfig(deleteCard(lovelace.config, path));
|
||||
} catch (err) {
|
||||
alert(`Deleting failed: ${err.message}`);
|
||||
}
|
||||
showConfirmationDialog(element, {
|
||||
text: hass.localize("ui.panel.lovelace.cards.confirm_delete"),
|
||||
confirm: async () => {
|
||||
try {
|
||||
await lovelace.saveConfig(deleteCard(lovelace.config, path));
|
||||
} catch (err) {
|
||||
alert(`Deleting failed: ${err.message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import { processEditorEntities } from "../process-editor-entities";
|
||||
import { navigate } from "../../../../common/navigate";
|
||||
import { Lovelace } from "../../types";
|
||||
import { deleteView, addView, replaceView } from "../config-util";
|
||||
import { showConfirmationDialog } from "../../../../dialogs/confirmation/show-dialog-confirmation";
|
||||
|
||||
@customElement("hui-edit-view")
|
||||
export class HuiEditView extends LitElement {
|
||||
@ -145,7 +146,7 @@ export class HuiEditView extends LitElement {
|
||||
<div class="paper-dialog-buttons">
|
||||
${this.viewIndex !== undefined
|
||||
? html`
|
||||
<mwc-button class="delete" @click="${this._delete}">
|
||||
<mwc-button class="delete" @click="${this._deleteConfirm}">
|
||||
${this.hass!.localize(
|
||||
"ui.panel.lovelace.editor.edit_view.delete"
|
||||
)}
|
||||
@ -171,17 +172,6 @@ export class HuiEditView extends LitElement {
|
||||
}
|
||||
|
||||
private async _delete(): Promise<void> {
|
||||
if (this._cards && this._cards.length > 0) {
|
||||
alert(
|
||||
"You can't delete a view that has cards in it. Remove the cards first."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm("Are you sure you want to delete this view?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.lovelace!.saveConfig(
|
||||
deleteView(this.lovelace!.config, this.viewIndex!)
|
||||
@ -193,6 +183,18 @@ export class HuiEditView extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _deleteConfirm(): void {
|
||||
if (this._cards && this._cards.length > 0) {
|
||||
alert(this.hass!.localize("ui.panel.lovelace.views.existing_cards"));
|
||||
return;
|
||||
}
|
||||
|
||||
showConfirmationDialog(this, {
|
||||
text: this.hass!.localize("ui.panel.lovelace.views.confirm_delete"),
|
||||
confirm: () => this._delete(),
|
||||
});
|
||||
}
|
||||
|
||||
private async _resizeDialog(): Promise<void> {
|
||||
await this.updateComplete;
|
||||
fireEvent(this._dialog as HTMLElement, "iron-resize");
|
||||
|
@ -546,6 +546,11 @@
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"confirmation": {
|
||||
"cancel": "Cancel",
|
||||
"ok": "OK",
|
||||
"title": "Are you sure?"
|
||||
},
|
||||
"more_info_control": {
|
||||
"script": {
|
||||
"last_action": "Last Action"
|
||||
@ -1354,6 +1359,7 @@
|
||||
},
|
||||
"lovelace": {
|
||||
"cards": {
|
||||
"confirm_delete": "Are you sure you want to delete this card?",
|
||||
"empty_state": {
|
||||
"title": "Welcome Home",
|
||||
"no_devices": "This page allows you to control your devices, however it looks like you have no devices set up yet. Head to the integrations page to get started.",
|
||||
@ -1374,6 +1380,10 @@
|
||||
"more_info": "Show more-info: {name}"
|
||||
}
|
||||
},
|
||||
"views": {
|
||||
"confirm_delete": "Are you sure you want to delete this view?",
|
||||
"existing_cards": "You can't delete a view that has cards in it. Remove the cards first."
|
||||
},
|
||||
"menu": {
|
||||
"configure_ui": "Configure UI",
|
||||
"unused_entities": "Unused entities",
|
||||
|
Loading…
x
Reference in New Issue
Block a user