Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ export class EntitySettingsHelperTab extends LitElement {

@state() private _submitting = false;

@state() private _dirty = false;

@state() private _componentLoaded?: boolean;

@query("entity-registry-settings-editor")
private _registryEditor?: EntityRegistrySettingsEditor;

private _originalItemJson?: string;

protected firstUpdated(changedProperties: PropertyValues<this>) {
super.firstUpdated(changedProperties);
this._componentLoaded = isComponentLoaded(
Expand Down Expand Up @@ -120,16 +124,28 @@ export class EntitySettingsHelperTab extends LitElement {
</ha-button>
<ha-button
@click=${this._updateItem}
.disabled=${!!this._submitting || !!(this._item && !this._item.name)}
.disabled=${!this._dirty ||
!!this._submitting ||
!!(this._item && !this._item.name)}
>
${this.hass.localize("ui.dialogs.entity_registry.editor.update")}
</ha-button>
</div>
`;
}

private get _isHelperDirty(): boolean {
if (!this._item || !this._originalItemJson) return false;
return JSON.stringify(this._item) !== this._originalItemJson;
}

private _updateDirty() {
this._dirty = (this._registryEditor?.dirty ?? false) || this._isHelperDirty;
}

private _entityRegistryChanged() {
this._error = undefined;
this._updateDirty();
}

private _valueChanged(ev: CustomEvent): void {
Expand All @@ -138,11 +154,15 @@ export class EntitySettingsHelperTab extends LitElement {
}
this._error = undefined;
this._item = ev.detail.value;
this._updateDirty();
}

private async _getItem() {
const items = await HELPERS_CRUD[this.entry.platform].fetch(this.hass!);
this._item = items.find((item) => item.id === this.entry.unique_id) || null;
this._originalItemJson = this._item
? JSON.stringify(this._item)
: undefined;
}

private async _updateItem(): Promise<void> {
Expand Down
69 changes: 69 additions & 0 deletions src/panels/config/entities/entity-registry-settings-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,34 @@ export class EntityRegistrySettingsEditor extends LitElement {

private _deviceClassOptions?: string[][];

private _initialStateJson!: string;

private _lastDirty = false;

private _currentState() {
return {
name: this._name.trim() || null,
icon: this._icon.trim() || null,
entityId: this._entityId.trim(),
areaId: this._areaId ?? null,
labels: this._labels ?? [],
deviceClass: this._deviceClass,
disabledBy: this._disabledBy,
hiddenBy: this._hiddenBy,
unitOfMeasurement: this._unit_of_measurement,
precision: this._precision,
defaultCode: this._defaultCode,
calendarColor: this._calendarColor ?? null,
precipitationUnit: this._precipitation_unit,
pressureUnit: this._pressure_unit,
temperatureUnit: this._temperature_unit,
visibilityUnit: this._visibility_unit,
windSpeedUnit: this._wind_speed_unit,
switchAsDomain: this._switchAsDomain,
switchAsInvert: this._switchAsInvert,
};
}

protected willUpdate(changedProperties: PropertyValues<this>) {
super.willUpdate(changedProperties);
if (
Expand Down Expand Up @@ -274,6 +302,9 @@ export class EntityRegistrySettingsEditor extends LitElement {
this._wind_speed_unit = stateObj?.attributes?.wind_speed_unit;
}

this._initialStateJson = JSON.stringify(this._currentState());
this._lastDirty = false;

const deviceClasses: string[][] = OVERRIDE_DEVICE_CLASSES[domain];

if (!deviceClasses || this._hideDeviceClassOverride(domain)) {
Expand Down Expand Up @@ -372,6 +403,16 @@ export class EntityRegistrySettingsEditor extends LitElement {
this._switchAsDomain = "switch";
this._switchAsInvert = false;
}
this._initialStateJson = JSON.stringify(this._currentState());
this._lastDirty = false;
}

if (this._initialStateJson) {
const dirty = this.dirty;
if (dirty !== this._lastDirty) {
this._lastDirty = dirty;
fireEvent(this, "change");
}
}
}

Expand Down Expand Up @@ -407,6 +448,23 @@ export class EntityRegistrySettingsEditor extends LitElement {
.disabled=${this.disabled}
@input=${this._nameChanged}
>
${this._device
? html`<span slot="hint"
>${this.hass.localize(
"ui.dialogs.entity_registry.editor.device_name_tip",
{
link: html`<button
class="link"
@click=${this._resetNameAndOpenDeviceSettings}
>
${this.hass.localize(
"ui.dialogs.entity_registry.editor.open_device_settings"
)}
</button>`,
}
)}</span
>`
: nothing}
</ha-input>`}
${this.hideIcon
? nothing
Expand Down Expand Up @@ -1060,6 +1118,10 @@ export class EntityRegistrySettingsEditor extends LitElement {
`;
}

public get dirty(): boolean {
return JSON.stringify(this._currentState()) !== this._initialStateJson;
}

public async updateEntry(): Promise<{
close: boolean;
entry: ExtEntityRegistryEntry;
Expand Down Expand Up @@ -1518,6 +1580,13 @@ export class EntityRegistrySettingsEditor extends LitElement {
}
}

private _resetNameAndOpenDeviceSettings() {
this._name = this.entry.name || "";
fireEvent(this, "change");

this._openDeviceSettings();
}

private _openDeviceSettings() {
showDeviceRegistryDetailDialog(this, {
device: this._device!,
Expand Down
9 changes: 8 additions & 1 deletion src/panels/config/entities/entity-registry-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {

@state() private _submitting?: boolean;

@state() private _dirty = false;

@query("entity-registry-settings-editor")
private _registryEditor?: EntityRegistrySettingsEditor;

Expand Down Expand Up @@ -144,7 +146,11 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
>
${this.hass.localize("ui.dialogs.entity_registry.editor.delete")}
</ha-button>
<ha-button @click=${this._updateEntry} .loading=${!!this._submitting}>
<ha-button
@click=${this._updateEntry}
.disabled=${!this._dirty || !!this._submitting}
.loading=${!!this._submitting}
>
${this.hass.localize("ui.dialogs.entity_registry.editor.update")}
</ha-button>
</div>
Expand All @@ -153,6 +159,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {

private _entityRegistryChanged() {
this._error = undefined;
this._dirty = this._registryEditor?.dirty ?? false;
}

private _openDeviceSettings() {
Expand Down
1 change: 1 addition & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1958,6 +1958,7 @@
"entity_disabled": "This entity is disabled.",
"enable_entity": "Enable",
"open_device_settings": "Open device settings",
"device_name_tip": "Consider renaming the device instead to update all its entities at once. {link}",
"switch_as_x_confirm": "This switch will be hidden and a new {domain} will be added. Your existing configurations using the switch will continue to work.",
"switch_as_x_remove_confirm": "This {domain} will be removed and the original switch will be visible again. Your existing configurations using the {domain} will no longer work!",
"switch_as_x_change_confirm": "This {domain_1} will be removed and will be replaced by a new {domain_2}. Your existing configurations using the {domain_1} will no longer work!",
Expand Down
Loading