mirror of
https://github.com/home-assistant/frontend.git
synced 2026-06-12 03:13:25 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d36d35467 |
@@ -181,6 +181,7 @@ export const DirtyStateProviderMixin =
|
||||
|
||||
/**
|
||||
* Whether any slice's current value differs from its baseline.
|
||||
* This passes the protected getter to the consuming class.
|
||||
*/
|
||||
public get isDirtyState(): boolean {
|
||||
return this._dirtyStateContext.isDirty;
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { consume } from "@lit/context";
|
||||
import { mdiContentSave } from "@mdi/js";
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, html, nothing, type CSSResultGroup } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-markdown";
|
||||
import type { BlueprintAutomationConfig } from "../../../data/automation";
|
||||
import { fetchBlueprints } from "../../../data/blueprint";
|
||||
import {
|
||||
dirtyStateContext,
|
||||
type DirtyStateContext,
|
||||
} from "../../../data/context/dirty-state";
|
||||
import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor";
|
||||
import { saveFabStyles } from "./styles";
|
||||
|
||||
@@ -19,7 +24,9 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor {
|
||||
|
||||
@property({ type: Boolean }) public saving = false;
|
||||
|
||||
@property({ type: Boolean }) public dirty = false;
|
||||
@consume({ context: dirtyStateContext, subscribe: true })
|
||||
@state()
|
||||
private _dirtyState?: DirtyStateContext;
|
||||
|
||||
protected get _config(): BlueprintAutomationConfig {
|
||||
return this.config;
|
||||
@@ -58,7 +65,7 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor {
|
||||
<ha-button
|
||||
slot="fab"
|
||||
size="l"
|
||||
class=${this.dirty ? "dirty" : ""}
|
||||
class=${this._dirtyState?.isDirty ? "dirty" : ""}
|
||||
.disabled=${this.saving}
|
||||
@click=${this._saveAutomation}
|
||||
>
|
||||
|
||||
@@ -421,7 +421,6 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.saving=${this.saving}
|
||||
.dirty=${this.dirty}
|
||||
@value-changed=${this._valueChanged}
|
||||
@save-automation=${this._handleSaveAutomation}
|
||||
></blueprint-automation-editor>
|
||||
@@ -434,7 +433,6 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
.stateObj=${stateObj}
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.dirty=${this.dirty}
|
||||
.saving=${this.saving}
|
||||
@value-changed=${this._valueChanged}
|
||||
@save-automation=${this._handleSaveAutomation}
|
||||
@@ -554,7 +552,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
<ha-button
|
||||
slot="fab"
|
||||
size="l"
|
||||
class=${this.dirty ? "dirty" : ""}
|
||||
class=${this.isDirtyState ? "dirty" : ""}
|
||||
.disabled=${this.saving}
|
||||
@click=${this._handleSaveAutomation}
|
||||
>
|
||||
@@ -602,7 +600,6 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
!this.entityId
|
||||
) {
|
||||
const initData = getAutomationEditorInitData();
|
||||
this.dirty = !!initData;
|
||||
let baseConfig: Partial<AutomationConfig> = { description: "" };
|
||||
if (!initData || !("use_blueprint" in initData)) {
|
||||
baseConfig = {
|
||||
@@ -617,6 +614,8 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
...baseConfig,
|
||||
...(initData ? normalizeAutomationConfig(initData) : initData),
|
||||
} as AutomationConfig;
|
||||
this._initDirtyTracking({ type: "deep" }, baseConfig as AutomationConfig);
|
||||
this._updateDirtyState(this.config);
|
||||
this.currentEntityId = undefined;
|
||||
this.readOnly = false;
|
||||
}
|
||||
@@ -624,10 +623,10 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
if (changedProps.has("entityId") && this.entityId) {
|
||||
getAutomationStateConfig(this.hass, this.entityId).then((c) => {
|
||||
this.config = normalizeAutomationConfig(c.config);
|
||||
this._initDirtyTracking({ type: "deep" }, this.config);
|
||||
this._checkValidation();
|
||||
});
|
||||
this.currentEntityId = this.entityId;
|
||||
this.dirty = false;
|
||||
this.readOnly = true;
|
||||
}
|
||||
|
||||
@@ -690,7 +689,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
if (this.readOnly) {
|
||||
return;
|
||||
}
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
this.errors = undefined;
|
||||
}
|
||||
|
||||
@@ -762,7 +761,6 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this.dirty = true;
|
||||
if (!ev.detail.isValid) {
|
||||
this.yamlErrors = ev.detail.errorMsg;
|
||||
return;
|
||||
@@ -772,11 +770,12 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
id: this.config?.id,
|
||||
...normalizeAutomationConfig(ev.detail.value),
|
||||
};
|
||||
this._updateDirtyState(this.config!);
|
||||
this.errors = undefined;
|
||||
}
|
||||
|
||||
protected async confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (!this.dirty) {
|
||||
if (!this.isDirtyState) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -787,7 +786,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
this.requestUpdate();
|
||||
|
||||
const id = this.automationId || String(Date.now());
|
||||
@@ -901,7 +900,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
@@ -918,7 +917,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
config: this.config!,
|
||||
updateConfig: (config) => {
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(config);
|
||||
this.requestUpdate();
|
||||
resolve();
|
||||
},
|
||||
@@ -1009,7 +1008,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
}
|
||||
}
|
||||
|
||||
this.dirty = false;
|
||||
this._markDirtyStateClean();
|
||||
} catch (errors: any) {
|
||||
this.errors = errors.body?.message || errors.error || errors.body;
|
||||
showEditorToast(this, {
|
||||
@@ -1068,7 +1067,7 @@ export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationCo
|
||||
private _applyUndoRedo(config: AutomationConfig) {
|
||||
this._manualEditor?.triggerCloseSidebar();
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
}
|
||||
|
||||
private _undo() {
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
showConfirmationDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import { DirtyStateProviderMixin } from "../../../mixins/dirty-state-provider-mixin";
|
||||
import type { Constructor, HomeAssistant, Route } from "../../../types";
|
||||
import type { EntityRegistryUpdate } from "./automation-save-dialog/show-dialog-automation-save";
|
||||
|
||||
@@ -87,7 +88,9 @@ export interface EditorDomainHooks<TConfig> {
|
||||
export const AutomationScriptEditorMixin = <TConfig extends BaseEditorConfig>(
|
||||
superClass: Constructor<LitElement>
|
||||
) => {
|
||||
class AutomationScriptEditorClass extends superClass {
|
||||
class AutomationScriptEditorClass extends DirtyStateProviderMixin<TConfig>()(
|
||||
superClass
|
||||
) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
@@ -102,8 +105,6 @@ export const AutomationScriptEditorMixin = <TConfig extends BaseEditorConfig>(
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
entityRegistry?: EntityRegistryEntry[];
|
||||
|
||||
@state() protected dirty = false;
|
||||
|
||||
@state() protected errors?: string;
|
||||
|
||||
@state() protected yamlErrors?: string;
|
||||
@@ -217,7 +218,9 @@ export const AutomationScriptEditorMixin = <TConfig extends BaseEditorConfig>(
|
||||
|
||||
protected takeControlSave() {
|
||||
this.readOnly = false;
|
||||
this.dirty = true;
|
||||
// Force dirty: set baseline to null so current config always differs
|
||||
this._initDirtyTracking({ type: "deep" }, null as unknown as TConfig);
|
||||
this._updateDirtyState(this.config!);
|
||||
this.blueprintConfig = undefined;
|
||||
}
|
||||
|
||||
@@ -237,10 +240,6 @@ export const AutomationScriptEditorMixin = <TConfig extends BaseEditorConfig>(
|
||||
}
|
||||
};
|
||||
|
||||
protected get isDirty() {
|
||||
return this.dirty;
|
||||
}
|
||||
|
||||
protected async promptDiscardChanges() {
|
||||
return this.confirmUnsavedChanged();
|
||||
}
|
||||
@@ -259,9 +258,9 @@ export const AutomationScriptEditorMixin = <TConfig extends BaseEditorConfig>(
|
||||
const domain = hooks.domain;
|
||||
try {
|
||||
const config = await hooks.fetchFileConfig(this.hass, id);
|
||||
this.dirty = false;
|
||||
this.readOnly = false;
|
||||
this.config = hooks.normalizeConfig(config);
|
||||
this._initDirtyTracking({ type: "deep" }, this.config);
|
||||
hooks.checkValidation();
|
||||
} catch (err: any) {
|
||||
if (err.status_code !== 404) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { consume } from "@lit/context";
|
||||
import { mdiContentSave } from "@mdi/js";
|
||||
import {
|
||||
html,
|
||||
@@ -19,6 +20,10 @@ import "../../../components/ha-button";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-markdown";
|
||||
import type { SidebarConfig } from "../../../data/automation";
|
||||
import {
|
||||
dirtyStateContext,
|
||||
type DirtyStateContext,
|
||||
} from "../../../data/context/dirty-state";
|
||||
import type {
|
||||
Constructor,
|
||||
HomeAssistant,
|
||||
@@ -46,7 +51,13 @@ export const ManualEditorMixin = <TConfig>(
|
||||
|
||||
@property({ attribute: false }) public config!: TConfig;
|
||||
|
||||
@property({ attribute: false }) public dirty = false;
|
||||
@consume({ context: dirtyStateContext, subscribe: true })
|
||||
@state()
|
||||
private _dirtyState?: DirtyStateContext;
|
||||
|
||||
protected get dirty(): boolean {
|
||||
return this._dirtyState?.isDirty ?? false;
|
||||
}
|
||||
|
||||
@state() protected pastedConfig?: TConfig;
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ import {
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import { DirtyStateProviderMixin } from "../../../mixins/dirty-state-provider-mixin";
|
||||
import { KeyboardShortcutMixin } from "../../../mixins/keyboard-shortcut-mixin";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
@@ -97,8 +98,8 @@ interface DeviceEntities {
|
||||
type DeviceEntitiesLookup = Record<string, string[]>;
|
||||
|
||||
@customElement("ha-scene-editor")
|
||||
export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
KeyboardShortcutMixin(LitElement)
|
||||
export class HaSceneEditor extends DirtyStateProviderMixin<number>()(
|
||||
PreventUnsavedMixin(KeyboardShortcutMixin(LitElement))
|
||||
) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -112,10 +113,10 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
|
||||
@property({ attribute: false }) public scenes!: SceneEntity[];
|
||||
|
||||
@state() private _dirty = false;
|
||||
|
||||
@state() private _errors?: string;
|
||||
|
||||
private _sceneRevision = 0;
|
||||
|
||||
@state() private _yamlErrors?: string;
|
||||
|
||||
@state() private _config?: SceneConfig;
|
||||
@@ -322,7 +323,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
.disabled=${this._saving}
|
||||
@click=${this._saveScene}
|
||||
class=${classMap({
|
||||
dirty: this._dirty || !this.sceneId,
|
||||
dirty: this.isDirty || !this.sceneId,
|
||||
saving: this._saving,
|
||||
})}
|
||||
>
|
||||
@@ -641,7 +642,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
|
||||
if (changedProps.has("sceneId") && !this.sceneId && this.hass) {
|
||||
this._dirty = false;
|
||||
this._sceneRevision = 0;
|
||||
const initData = getSceneEditorInitData();
|
||||
this._config = {
|
||||
name: this.hass.localize("ui.panel.config.scene.editor.default_name"),
|
||||
@@ -656,9 +657,13 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
category: "",
|
||||
};
|
||||
}
|
||||
this._dirty =
|
||||
this._initDirtyTracking({ type: "shallow" }, 0);
|
||||
if (
|
||||
initData !== undefined &&
|
||||
(initData.areaId !== undefined || initData.config !== undefined);
|
||||
(initData.areaId !== undefined || initData.config !== undefined)
|
||||
) {
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
}
|
||||
}
|
||||
|
||||
if (changedProps.has("_entityRegistryEntries")) {
|
||||
@@ -816,7 +821,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
|
||||
private async _enterLiveMode() {
|
||||
if (this._dirty) {
|
||||
if (this.isDirty) {
|
||||
const result = await showConfirmationDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.scene.editor.enter_live_mode_unsaved"
|
||||
@@ -850,13 +855,13 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this._dirty = true;
|
||||
if (!ev.detail.isValid) {
|
||||
this._yamlErrors = ev.detail.errorMsg;
|
||||
return;
|
||||
}
|
||||
this._yamlErrors = undefined;
|
||||
this._config = ev.detail.value;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
this._errors = undefined;
|
||||
}
|
||||
|
||||
@@ -911,7 +916,8 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
(entity: SceneEntity) => entity.attributes.id === this.sceneId
|
||||
);
|
||||
|
||||
this._dirty = false;
|
||||
this._sceneRevision = 0;
|
||||
this._initDirtyTracking({ type: "shallow" }, 0);
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
@@ -960,7 +966,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
this._entities = [...this._entities, entityId];
|
||||
this._single_entities.push(entityId);
|
||||
this._storeState(entityId);
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
}
|
||||
|
||||
private _deleteEntity(ev: Event) {
|
||||
@@ -978,7 +984,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
if (this._config!.metadata) {
|
||||
delete this._config!.metadata[deleteEntityId];
|
||||
}
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
}
|
||||
|
||||
private _pickDevice(device_id: string) {
|
||||
@@ -994,7 +1000,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
deviceEntities.forEach((entityId) => {
|
||||
this._storeState(entityId);
|
||||
});
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
}
|
||||
|
||||
private _devicePicked(ev: CustomEvent) {
|
||||
@@ -1018,7 +1024,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
delete this._config!.entities[entityId];
|
||||
});
|
||||
}
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
}
|
||||
|
||||
private _stateChanged(event: HassEvent) {
|
||||
@@ -1026,7 +1032,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
event.context.id !== this._activateContextId &&
|
||||
this._entities.includes(event.data.entity_id)
|
||||
) {
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1072,7 +1078,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
|
||||
private async _confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (this._dirty) {
|
||||
if (this.isDirty) {
|
||||
return showConfirmationDialog(this, {
|
||||
title: this.hass!.localize(
|
||||
"ui.panel.config.scene.editor.unsaved_confirm_title"
|
||||
@@ -1239,7 +1245,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
this._markDirtyStateClean();
|
||||
if (isNewScene) {
|
||||
navigate(`/config/scene/edit/${id}`, { replace: true });
|
||||
}
|
||||
@@ -1294,7 +1300,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
updateConfig: async (newConfig, entityRegistryUpdate) => {
|
||||
this._config = newConfig;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
@@ -1313,7 +1319,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
updateConfig: async (newConfig, entityRegistryUpdate) => {
|
||||
this._config = newConfig;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this._updateDirtyState(++this._sceneRevision);
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
@@ -1322,10 +1328,6 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
});
|
||||
}
|
||||
|
||||
protected get isDirty() {
|
||||
return this._dirty;
|
||||
}
|
||||
|
||||
protected async promptDiscardChanges() {
|
||||
return this._confirmUnsavedChanged();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import { consume } from "@lit/context";
|
||||
import { mdiContentSave } from "@mdi/js";
|
||||
import { css, html, nothing, type CSSResultGroup } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-markdown";
|
||||
import { fetchBlueprints } from "../../../data/blueprint";
|
||||
import {
|
||||
dirtyStateContext,
|
||||
type DirtyStateContext,
|
||||
} from "../../../data/context/dirty-state";
|
||||
import type { BlueprintScriptConfig } from "../../../data/script";
|
||||
import { saveFabStyles } from "../automation/styles";
|
||||
import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor";
|
||||
@@ -15,7 +20,9 @@ export class HaBlueprintScriptEditor extends HaBlueprintGenericEditor {
|
||||
|
||||
@property({ type: Boolean }) public saving = false;
|
||||
|
||||
@property({ type: Boolean }) public dirty = false;
|
||||
@consume({ context: dirtyStateContext, subscribe: true })
|
||||
@state()
|
||||
private _dirtyState?: DirtyStateContext;
|
||||
|
||||
protected get _config(): BlueprintScriptConfig {
|
||||
return this.config;
|
||||
@@ -35,7 +42,7 @@ export class HaBlueprintScriptEditor extends HaBlueprintGenericEditor {
|
||||
<ha-button
|
||||
slot="fab"
|
||||
size="l"
|
||||
class=${this.dirty ? "dirty" : ""}
|
||||
class=${this._dirtyState?.isDirty ? "dirty" : ""}
|
||||
.disabled=${this.saving}
|
||||
@click=${this._saveScript}
|
||||
>
|
||||
|
||||
@@ -377,7 +377,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.saving=${this.saving}
|
||||
.dirty=${this.dirty}
|
||||
@value-changed=${this._valueChanged}
|
||||
@save-script=${this._handleSaveScript}
|
||||
></blueprint-script-editor>
|
||||
@@ -389,7 +388,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.isWide=${this.isWide}
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.dirty=${this.dirty}
|
||||
.saving=${this.saving}
|
||||
@value-changed=${this._valueChanged}
|
||||
@editor-save=${this._handleSaveScript}
|
||||
@@ -470,7 +468,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
<ha-button
|
||||
slot="fab"
|
||||
size="l"
|
||||
class=${!this.readOnly && this.dirty ? "dirty" : ""}
|
||||
class=${!this.readOnly && this.isDirtyState ? "dirty" : ""}
|
||||
.disabled=${this.saving}
|
||||
@click=${this._handleSaveScript}
|
||||
>
|
||||
@@ -522,7 +520,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
if (changedProps.has("scriptId") && !this.scriptId && this.hass) {
|
||||
const initData = getScriptEditorInitData();
|
||||
this.dirty = !!initData;
|
||||
const baseConfig: Partial<ScriptConfig> = {};
|
||||
if (!initData || !("use_blueprint" in initData)) {
|
||||
baseConfig.sequence = [];
|
||||
@@ -531,12 +528,15 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
...baseConfig,
|
||||
...initData,
|
||||
} as ScriptConfig;
|
||||
this._initDirtyTracking({ type: "deep" }, baseConfig as ScriptConfig);
|
||||
this._updateDirtyState(this.config);
|
||||
this.readOnly = false;
|
||||
}
|
||||
|
||||
if (changedProps.has("entityId") && this.entityId) {
|
||||
getScriptStateConfig(this.hass, this.entityId).then((c) => {
|
||||
this.config = normalizeScriptConfig(c.config);
|
||||
this._initDirtyTracking({ type: "deep" }, this.config);
|
||||
this._checkValidation();
|
||||
});
|
||||
const regEntry = this.entityRegistry?.find(
|
||||
@@ -546,7 +546,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
this.scriptId = regEntry.unique_id;
|
||||
}
|
||||
this.currentEntityId = this.entityId;
|
||||
this.dirty = false;
|
||||
this.readOnly = true;
|
||||
}
|
||||
}
|
||||
@@ -582,7 +581,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
this.config = ev.detail.value;
|
||||
this.errors = undefined;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config!);
|
||||
}
|
||||
|
||||
private async _runScript() {
|
||||
@@ -669,7 +668,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
|
||||
this._manualEditor?.addFields();
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config!);
|
||||
}
|
||||
|
||||
private _preprocessYaml() {
|
||||
@@ -678,18 +677,18 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this.dirty = true;
|
||||
if (!ev.detail.isValid) {
|
||||
this.yamlErrors = ev.detail.errorMsg;
|
||||
return;
|
||||
}
|
||||
this.yamlErrors = undefined;
|
||||
this.config = ev.detail.value;
|
||||
this._updateDirtyState(this.config!);
|
||||
this.errors = undefined;
|
||||
}
|
||||
|
||||
protected async confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (!this.dirty) {
|
||||
if (!this.isDirtyState) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -700,7 +699,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
this.requestUpdate();
|
||||
|
||||
const id = this.scriptId || String(Date.now());
|
||||
@@ -815,7 +814,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
@@ -834,7 +833,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
config: this.config!,
|
||||
updateConfig: (config) => {
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(config);
|
||||
this.requestUpdate();
|
||||
resolve();
|
||||
},
|
||||
@@ -930,7 +929,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
}
|
||||
|
||||
this.dirty = false;
|
||||
this._markDirtyStateClean();
|
||||
} catch (errors: any) {
|
||||
this.errors = errors.body?.message || errors.error || errors.body;
|
||||
showEditorToast(this, {
|
||||
@@ -980,7 +979,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
private _applyUndoRedo(config: ScriptConfig) {
|
||||
this._manualEditor?.triggerCloseSidebar();
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
this._updateDirtyState(this.config);
|
||||
}
|
||||
|
||||
private _undo() {
|
||||
|
||||
Reference in New Issue
Block a user