mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 03:36:44 +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 "./ha-progress-button";
|
||||||
import { EventsMixin } from "../../mixins/events-mixin";
|
import { EventsMixin } from "../../mixins/events-mixin";
|
||||||
|
import { showConfirmationDialog } from "../../dialogs/confirmation/show-dialog-confirmation";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin EventsMixin
|
* @appliesMixin EventsMixin
|
||||||
@ -49,10 +50,7 @@ class HaCallServiceButton extends EventsMixin(PolymerElement) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonTapped() {
|
callService() {
|
||||||
if (this.confirmation && !window.confirm(this.confirmation)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.progress = true;
|
this.progress = true;
|
||||||
var el = this;
|
var el = this;
|
||||||
var eventData = {
|
var eventData = {
|
||||||
@ -79,6 +77,17 @@ class HaCallServiceButton extends EventsMixin(PolymerElement) {
|
|||||||
el.fire("hass-service-called", eventData);
|
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);
|
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,
|
updateEntityRegistryEntry,
|
||||||
removeEntityRegistryEntry,
|
removeEntityRegistryEntry,
|
||||||
} from "../../../data/entity_registry";
|
} from "../../../data/entity_registry";
|
||||||
|
import { showConfirmationDialog } from "../../../dialogs/confirmation/show-dialog-confirmation";
|
||||||
|
|
||||||
class DialogEntityRegistryDetail extends LitElement {
|
class DialogEntityRegistryDetail extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@ -139,7 +140,7 @@ class DialogEntityRegistryDetail extends LitElement {
|
|||||||
<div class="paper-dialog-buttons">
|
<div class="paper-dialog-buttons">
|
||||||
<mwc-button
|
<mwc-button
|
||||||
class="warning"
|
class="warning"
|
||||||
@click="${this._deleteEntry}"
|
@click="${this._confirmDeleteEntry}"
|
||||||
.disabled=${this._submitting}
|
.disabled=${this._submitting}
|
||||||
>
|
>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
@ -186,22 +187,6 @@ class DialogEntityRegistryDetail extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _deleteEntry(): Promise<void> {
|
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;
|
this._submitting = true;
|
||||||
|
|
||||||
try {
|
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 {
|
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
||||||
if (!(ev.detail as any).value) {
|
if (!(ev.detail as any).value) {
|
||||||
this._params = undefined;
|
this._params = undefined;
|
||||||
|
@ -17,6 +17,7 @@ import { DeviceRegistryEntry } from "../../../../data/device_registry";
|
|||||||
import { AreaRegistryEntry } from "../../../../data/area_registry";
|
import { AreaRegistryEntry } from "../../../../data/area_registry";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { showConfigEntrySystemOptionsDialog } from "../../../../dialogs/config-entry-system-options/show-dialog-config-entry-system-options";
|
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 {
|
class HaConfigEntryPage extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@ -110,7 +111,7 @@ class HaConfigEntryPage extends LitElement {
|
|||||||
"integration",
|
"integration",
|
||||||
configEntry.title
|
configEntry.title
|
||||||
)}
|
)}
|
||||||
@click=${this._removeEntry}
|
@click=${this._confirmRemoveEntry}
|
||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -159,17 +160,16 @@ class HaConfigEntryPage extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _removeEntry() {
|
private _confirmRemoveEntry() {
|
||||||
if (
|
showConfirmationDialog(this, {
|
||||||
!confirm(
|
text: this.hass.localize(
|
||||||
this.hass.localize(
|
"ui.panel.config.integrations.config_entry.delete_confirm"
|
||||||
"ui.panel.config.integrations.config_entry.delete_confirm"
|
),
|
||||||
)
|
confirm: () => this._removeEntry(),
|
||||||
)
|
});
|
||||||
) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private _removeEntry() {
|
||||||
deleteConfigEntry(this.hass, this.configEntryId).then((result) => {
|
deleteConfigEntry(this.hass, this.configEntryId).then((result) => {
|
||||||
fireEvent(this, "hass-reload-entries");
|
fireEvent(this, "hass-reload-entries");
|
||||||
if (result.require_restart) {
|
if (result.require_restart) {
|
||||||
|
@ -165,7 +165,7 @@ export class HuiCardOptions extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _deleteCard(): void {
|
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 { Lovelace } from "../types";
|
||||||
import { deleteCard } from "./config-util";
|
import { deleteCard } from "./config-util";
|
||||||
|
import { showConfirmationDialog } from "../../../dialogs/confirmation/show-dialog-confirmation";
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
|
||||||
export async function confDeleteCard(
|
export async function confDeleteCard(
|
||||||
|
element: HTMLElement,
|
||||||
|
hass: HomeAssistant,
|
||||||
lovelace: Lovelace,
|
lovelace: Lovelace,
|
||||||
path: [number, number]
|
path: [number, number]
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!confirm("Are you sure you want to delete this card?")) {
|
showConfirmationDialog(element, {
|
||||||
return;
|
text: hass.localize("ui.panel.lovelace.cards.confirm_delete"),
|
||||||
}
|
confirm: async () => {
|
||||||
try {
|
try {
|
||||||
await lovelace.saveConfig(deleteCard(lovelace.config, path));
|
await lovelace.saveConfig(deleteCard(lovelace.config, path));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert(`Deleting failed: ${err.message}`);
|
alert(`Deleting failed: ${err.message}`);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import { processEditorEntities } from "../process-editor-entities";
|
|||||||
import { navigate } from "../../../../common/navigate";
|
import { navigate } from "../../../../common/navigate";
|
||||||
import { Lovelace } from "../../types";
|
import { Lovelace } from "../../types";
|
||||||
import { deleteView, addView, replaceView } from "../config-util";
|
import { deleteView, addView, replaceView } from "../config-util";
|
||||||
|
import { showConfirmationDialog } from "../../../../dialogs/confirmation/show-dialog-confirmation";
|
||||||
|
|
||||||
@customElement("hui-edit-view")
|
@customElement("hui-edit-view")
|
||||||
export class HuiEditView extends LitElement {
|
export class HuiEditView extends LitElement {
|
||||||
@ -145,7 +146,7 @@ export class HuiEditView extends LitElement {
|
|||||||
<div class="paper-dialog-buttons">
|
<div class="paper-dialog-buttons">
|
||||||
${this.viewIndex !== undefined
|
${this.viewIndex !== undefined
|
||||||
? html`
|
? html`
|
||||||
<mwc-button class="delete" @click="${this._delete}">
|
<mwc-button class="delete" @click="${this._deleteConfirm}">
|
||||||
${this.hass!.localize(
|
${this.hass!.localize(
|
||||||
"ui.panel.lovelace.editor.edit_view.delete"
|
"ui.panel.lovelace.editor.edit_view.delete"
|
||||||
)}
|
)}
|
||||||
@ -171,17 +172,6 @@ export class HuiEditView extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _delete(): Promise<void> {
|
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 {
|
try {
|
||||||
await this.lovelace!.saveConfig(
|
await this.lovelace!.saveConfig(
|
||||||
deleteView(this.lovelace!.config, this.viewIndex!)
|
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> {
|
private async _resizeDialog(): Promise<void> {
|
||||||
await this.updateComplete;
|
await this.updateComplete;
|
||||||
fireEvent(this._dialog as HTMLElement, "iron-resize");
|
fireEvent(this._dialog as HTMLElement, "iron-resize");
|
||||||
|
@ -546,6 +546,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dialogs": {
|
"dialogs": {
|
||||||
|
"confirmation": {
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"ok": "OK",
|
||||||
|
"title": "Are you sure?"
|
||||||
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
"script": {
|
"script": {
|
||||||
"last_action": "Last Action"
|
"last_action": "Last Action"
|
||||||
@ -1354,6 +1359,7 @@
|
|||||||
},
|
},
|
||||||
"lovelace": {
|
"lovelace": {
|
||||||
"cards": {
|
"cards": {
|
||||||
|
"confirm_delete": "Are you sure you want to delete this card?",
|
||||||
"empty_state": {
|
"empty_state": {
|
||||||
"title": "Welcome Home",
|
"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.",
|
"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}"
|
"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": {
|
"menu": {
|
||||||
"configure_ui": "Configure UI",
|
"configure_ui": "Configure UI",
|
||||||
"unused_entities": "Unused entities",
|
"unused_entities": "Unused entities",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user