Prevent leaving the editor if there are unsaved changes

This commit is contained in:
Jan-Philipp Benecke 2024-12-05 19:49:27 +01:00 committed by Bram Kragten
parent 0582b8430d
commit 91777d45b0
4 changed files with 90 additions and 4 deletions

View File

@ -0,0 +1,55 @@
import type { LitElement } from "lit";
import type { Constructor } from "../types";
import { isNavigationClick } from "../common/dom/is-navigation-click";
import { navigate } from "../common/navigate";
export const PreventUnsavedMixin = <T extends Constructor<LitElement>>(
superClass: T
) =>
class extends superClass {
private _handleClick = async (e: MouseEvent) => {
const href = isNavigationClick(e);
if (!href) {
return;
}
e.preventDefault();
const result = await this.promptDiscardChanges();
if (result) {
navigate(href);
}
};
private _handleUnload = (e: BeforeUnloadEvent) => {
if (this.isDirty()) {
e.preventDefault();
}
};
public connectedCallback(): void {
super.connectedCallback();
document.body.addEventListener("mousedown", this._handleClick, {
capture: true,
});
window.addEventListener("beforeunload", this._handleUnload);
}
public disconnectedCallback(): void {
super.disconnectedCallback();
document.body.removeEventListener("click", this._handleClick, {
capture: true,
});
window.removeEventListener("beforeunload", this._handleUnload);
}
protected isDirty(): boolean {
return false;
}
protected async promptDiscardChanges(): Promise<boolean> {
return true;
}
};

View File

@ -64,6 +64,7 @@ import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-a
import { showAutomationRenameDialog } from "./automation-rename-dialog/show-dialog-automation-rename";
import "./blueprint-automation-editor";
import "./manual-automation-editor";
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
declare global {
interface HTMLElementTagNameMap {
@ -82,7 +83,9 @@ declare global {
}
}
export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
export class HaAutomationEditor extends PreventUnsavedMixin(
KeyboardShortcutMixin(LitElement)
) {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public automationId: string | null = null;
@ -847,6 +850,14 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
};
}
protected isDirty() {
return this._dirty;
}
protected async promptDiscardChanges() {
return this.confirmUnsavedChanged();
}
static get styles(): CSSResultGroup {
return [
haStyle,

View File

@ -77,6 +77,7 @@ import { haStyle } from "../../../resources/styles";
import type { HomeAssistant, Route } from "../../../types";
import { showToast } from "../../../util/toast";
import "../ha-config-section";
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
interface DeviceEntities {
id: string;
@ -89,8 +90,8 @@ interface DeviceEntitiesLookup {
}
@customElement("ha-scene-editor")
export class HaSceneEditor extends SubscribeMixin(
KeyboardShortcutMixin(LitElement)
export class HaSceneEditor extends PreventUnsavedMixin(
SubscribeMixin(KeyboardShortcutMixin(LitElement))
) {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -1225,6 +1226,14 @@ export class HaSceneEditor extends SubscribeMixin(
});
}
protected isDirty() {
return this._dirty;
}
protected async promptDiscardChanges() {
return this.confirmUnsavedChanged();
}
static get styles(): CSSResultGroup {
return [
haStyle,

View File

@ -57,8 +57,11 @@ import "./blueprint-script-editor";
import "./manual-script-editor";
import type { HaManualScriptEditor } from "./manual-script-editor";
import { substituteBlueprint } from "../../../data/blueprint";
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
export class HaScriptEditor extends PreventUnsavedMixin(
KeyboardShortcutMixin(LitElement)
) {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public scriptId: string | null = null;
@ -813,6 +816,14 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
};
}
protected isDirty() {
return this._dirty;
}
protected async promptDiscardChanges() {
return this.confirmUnsavedChanged();
}
static get styles(): CSSResultGroup {
return [
haStyle,