mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Update entity settings, combine basic editor with normal editor (#16297)
This commit is contained in:
parent
8c06712ab7
commit
19c9486351
@ -14,8 +14,9 @@ import { customElement, property, query } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { HomeAssistant } from "../types";
|
||||
import "./ha-list-item";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-list-item";
|
||||
import "./ha-textfield";
|
||||
import type { HaTextField } from "./ha-textfield";
|
||||
|
||||
registerStyles(
|
||||
|
@ -52,18 +52,17 @@ export class HaSettingsRow extends LitElement {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.body > .secondary {
|
||||
font-family: var(--paper-font-body1_-_font-family);
|
||||
-webkit-font-smoothing: var(
|
||||
--paper-font-body1_-_-webkit-font-smoothing
|
||||
);
|
||||
font-size: var(--paper-font-body1_-_font-size);
|
||||
font-weight: var(--paper-font-body1_-_font-weight);
|
||||
line-height: var(--paper-font-body1_-_line-height);
|
||||
|
||||
color: var(
|
||||
--paper-item-body-secondary-color,
|
||||
var(--secondary-text-color)
|
||||
display: block;
|
||||
padding-top: 4px;
|
||||
font-family: var(
|
||||
--mdc-typography-body2-font-family,
|
||||
var(--mdc-typography-font-family, Roboto, sans-serif)
|
||||
);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: var(--mdc-typography-body2-font-size, 0.875rem);
|
||||
font-weight: var(--mdc-typography-body2-font-weight, 400);
|
||||
line-height: normal;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.body[two-line] {
|
||||
min-height: calc(
|
||||
|
@ -3,8 +3,8 @@ import {
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
nothing,
|
||||
PropertyValues,
|
||||
} from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../../../../common/config/is_component_loaded";
|
||||
@ -28,8 +28,9 @@ import "../../../helpers/forms/ha-input_select-form";
|
||||
import "../../../helpers/forms/ha-input_text-form";
|
||||
import "../../../helpers/forms/ha-schedule-form";
|
||||
import "../../../helpers/forms/ha-timer-form";
|
||||
import "../../entity-registry-basic-editor";
|
||||
import type { HaEntityRegistryBasicEditor } from "../../entity-registry-basic-editor";
|
||||
import "../../../voice-assistants/entity-voice-settings";
|
||||
import "../../entity-registry-settings-editor";
|
||||
import type { EntityRegistrySettingsEditor } from "../../entity-registry-settings-editor";
|
||||
|
||||
@customElement("entity-settings-helper-tab")
|
||||
export class EntityRegistrySettingsHelper extends LitElement {
|
||||
@ -45,8 +46,8 @@ export class EntityRegistrySettingsHelper extends LitElement {
|
||||
|
||||
@state() private _componentLoaded?: boolean;
|
||||
|
||||
@query("ha-registry-basic-editor")
|
||||
private _registryEditor?: HaEntityRegistryBasicEditor;
|
||||
@query("entity-registry-settings-editor")
|
||||
private _registryEditor?: EntityRegistrySettingsEditor;
|
||||
|
||||
protected firstUpdated(changedProperties: PropertyValues) {
|
||||
super.firstUpdated(changedProperties);
|
||||
@ -75,7 +76,9 @@ export class EntityRegistrySettingsHelper extends LitElement {
|
||||
const stateObj = this.hass.states[this.entry.entity_id];
|
||||
return html`
|
||||
<div class="form">
|
||||
${this._error ? html` <div class="error">${this._error}</div> ` : ""}
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: ""}
|
||||
${!this._componentLoaded
|
||||
? this.hass.localize(
|
||||
"ui.dialogs.helper_settings.platform_not_loaded",
|
||||
@ -93,10 +96,14 @@ export class EntityRegistrySettingsHelper extends LitElement {
|
||||
})}
|
||||
</span>
|
||||
`}
|
||||
<ha-registry-basic-editor
|
||||
<entity-registry-settings-editor
|
||||
.hass=${this.hass}
|
||||
.entry=${this.entry}
|
||||
></ha-registry-basic-editor>
|
||||
.disabled=${this._submitting}
|
||||
@change=${this._entityRegistryChanged}
|
||||
hideName
|
||||
hideIcon
|
||||
></entity-registry-settings-editor>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<mwc-button
|
||||
@ -117,6 +124,10 @@ export class EntityRegistrySettingsHelper extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _entityRegistryChanged() {
|
||||
this._error = undefined;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
this._error = undefined;
|
||||
this._item = ev.detail.value;
|
||||
@ -137,7 +148,7 @@ export class EntityRegistrySettingsHelper extends LitElement {
|
||||
this._item
|
||||
);
|
||||
}
|
||||
await this._registryEditor?.updateEntry();
|
||||
await this._registryEditor!.updateEntry();
|
||||
fireEvent(this, "close-dialog");
|
||||
} catch (err: any) {
|
||||
this._error = err.message || "Unknown error";
|
||||
|
@ -1,376 +0,0 @@
|
||||
import "@material/mwc-formfield/mwc-formfield";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiPencil } from "@mdi/js";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, PropertyValues, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stringCompare } from "../../../common/string/compare";
|
||||
import "../../../components/ha-area-picker";
|
||||
import "../../../components/ha-expansion-panel";
|
||||
import "../../../components/ha-radio";
|
||||
import "../../../components/ha-switch";
|
||||
import "../../../components/ha-textfield";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../data/device_registry";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
EntityRegistryEntryUpdateParams,
|
||||
ExtEntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { showAliasesDialog } from "../../../dialogs/aliases/show-dialog-aliases";
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
|
||||
@customElement("ha-registry-basic-editor")
|
||||
export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public entry!: ExtEntityRegistryEntry;
|
||||
|
||||
@state() private _origEntityId!: string;
|
||||
|
||||
@state() private _entityId!: string;
|
||||
|
||||
@state() private _areaId?: string | null;
|
||||
|
||||
@state() private _disabledBy!: EntityRegistryEntry["disabled_by"];
|
||||
|
||||
@state() private _hiddenBy!: string | null;
|
||||
|
||||
private _deviceLookup?: Record<string, DeviceRegistryEntry>;
|
||||
|
||||
@state() private _device?: DeviceRegistryEntry;
|
||||
|
||||
@state() private _submitting = false;
|
||||
|
||||
private _handleAliasesClicked(ev: CustomEvent) {
|
||||
if (ev.detail.index !== 0) return;
|
||||
const stateObj = this.hass.states[this.entry.entity_id];
|
||||
const name =
|
||||
(stateObj && computeStateName(stateObj)) || this.entry.entity_id;
|
||||
|
||||
showAliasesDialog(this, {
|
||||
name,
|
||||
aliases: this.entry!.aliases,
|
||||
updateAliases: async (aliases: string[]) => {
|
||||
const result = await updateEntityRegistryEntry(
|
||||
this.hass,
|
||||
this.entry.entity_id,
|
||||
{ aliases }
|
||||
);
|
||||
fireEvent(this, "entity-entry-updated", result.entity_entry);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public async updateEntry(): Promise<void> {
|
||||
this._submitting = true;
|
||||
const params: Partial<EntityRegistryEntryUpdateParams> = {
|
||||
new_entity_id: this._entityId.trim(),
|
||||
area_id: this._areaId || null,
|
||||
};
|
||||
if (
|
||||
this.entry.disabled_by !== this._disabledBy &&
|
||||
(this._disabledBy === null || this._disabledBy === "user")
|
||||
) {
|
||||
params.disabled_by = this._disabledBy;
|
||||
}
|
||||
if (
|
||||
this.entry.hidden_by !== this._hiddenBy &&
|
||||
(this._hiddenBy === null || this._hiddenBy === "user")
|
||||
) {
|
||||
params.hidden_by = this._hiddenBy;
|
||||
}
|
||||
try {
|
||||
const result = await updateEntityRegistryEntry(
|
||||
this.hass!,
|
||||
this._origEntityId,
|
||||
params
|
||||
);
|
||||
if (result.require_restart) {
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.enabled_restart_confirm"
|
||||
),
|
||||
});
|
||||
}
|
||||
if (result.reload_delay) {
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.enabled_delay_confirm",
|
||||
"delay",
|
||||
result.reload_delay
|
||||
),
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
this._submitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
||||
this._deviceLookup = {};
|
||||
for (const device of devices) {
|
||||
this._deviceLookup[device.id] = device;
|
||||
}
|
||||
if (!this._device && this.entry.device_id) {
|
||||
this._device = this._deviceLookup[this.entry.device_id];
|
||||
}
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues) {
|
||||
super.updated(changedProperties);
|
||||
if (!changedProperties.has("entry")) {
|
||||
return;
|
||||
}
|
||||
if (this.entry) {
|
||||
this._origEntityId = this.entry.entity_id;
|
||||
this._entityId = this.entry.entity_id;
|
||||
this._disabledBy = this.entry.disabled_by;
|
||||
this._hiddenBy = this.entry.hidden_by;
|
||||
this._areaId = this.entry.area_id;
|
||||
this._device =
|
||||
this.entry.device_id && this._deviceLookup
|
||||
? this._deviceLookup[this.entry.device_id]
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (
|
||||
!this.hass ||
|
||||
!this.entry ||
|
||||
this.entry.entity_id !== this._origEntityId
|
||||
) {
|
||||
return nothing;
|
||||
}
|
||||
const invalidDomainUpdate =
|
||||
computeDomain(this._entityId.trim()) !==
|
||||
computeDomain(this.entry.entity_id);
|
||||
|
||||
return html`
|
||||
<ha-textfield
|
||||
error-message="Domain needs to stay the same"
|
||||
.value=${this._entityId}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.entity_id"
|
||||
)}
|
||||
.invalid=${invalidDomainUpdate}
|
||||
.disabled=${this._submitting}
|
||||
@input=${this._entityIdChanged}
|
||||
></ha-textfield>
|
||||
<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._areaId || undefined}
|
||||
.placeholder=${this._device?.area_id || undefined}
|
||||
@value-changed=${this._areaPicked}
|
||||
></ha-area-picker>
|
||||
|
||||
<ha-expansion-panel
|
||||
.header=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.advanced"
|
||||
)}
|
||||
outlined
|
||||
>
|
||||
<div class="label">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.entity_status"
|
||||
)}:
|
||||
</div>
|
||||
<div class="secondary">
|
||||
${this._disabledBy && this._disabledBy !== "user"
|
||||
? this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.enabled_cause",
|
||||
"cause",
|
||||
this.hass.localize(
|
||||
`config_entry.disabled_by.${this._disabledBy}`
|
||||
)
|
||||
)
|
||||
: ""}
|
||||
</div>
|
||||
<div class="row">
|
||||
<mwc-formfield
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.enabled_label"
|
||||
)}
|
||||
>
|
||||
<ha-radio
|
||||
name="hiddendisabled"
|
||||
value="enabled"
|
||||
.checked=${!this._hiddenBy && !this._disabledBy}
|
||||
.disabled=${!!this._device?.disabled_by ||
|
||||
(this._disabledBy !== null &&
|
||||
!(
|
||||
this._disabledBy === "user" ||
|
||||
this._disabledBy === "integration"
|
||||
))}
|
||||
@change=${this._viewStatusChanged}
|
||||
></ha-radio>
|
||||
</mwc-formfield>
|
||||
<mwc-formfield
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.hidden_label"
|
||||
)}
|
||||
>
|
||||
<ha-radio
|
||||
name="hiddendisabled"
|
||||
value="hidden"
|
||||
.checked=${this._hiddenBy !== null}
|
||||
.disabled=${!!this._device?.disabled_by ||
|
||||
(this._disabledBy !== null &&
|
||||
!(
|
||||
this._disabledBy === "user" ||
|
||||
this._disabledBy === "integration"
|
||||
))}
|
||||
@change=${this._viewStatusChanged}
|
||||
></ha-radio>
|
||||
</mwc-formfield>
|
||||
<mwc-formfield
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.disabled_label"
|
||||
)}
|
||||
>
|
||||
<ha-radio
|
||||
name="hiddendisabled"
|
||||
value="disabled"
|
||||
.checked=${this._disabledBy !== null}
|
||||
.disabled=${!!this._device?.disabled_by ||
|
||||
(this._disabledBy !== null &&
|
||||
!(
|
||||
this._disabledBy === "user" ||
|
||||
this._disabledBy === "integration"
|
||||
))}
|
||||
@change=${this._viewStatusChanged}
|
||||
></ha-radio>
|
||||
</mwc-formfield>
|
||||
</div>
|
||||
|
||||
${this._disabledBy !== null
|
||||
? html`
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.enabled_description"
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: this._hiddenBy !== null
|
||||
? html`
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.hidden_description"
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<div class="label">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.aliases_section"
|
||||
)}
|
||||
</div>
|
||||
<mwc-list class="aliases" @action=${this._handleAliasesClicked}>
|
||||
<mwc-list-item .twoline=${this.entry.aliases.length > 0} hasMeta>
|
||||
<span>
|
||||
${this.entry.aliases.length > 0
|
||||
? this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.configured_aliases",
|
||||
{ count: this.entry.aliases.length }
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.no_aliases"
|
||||
)}
|
||||
</span>
|
||||
<span slot="secondary">
|
||||
${[...this.entry.aliases]
|
||||
.sort((a, b) => stringCompare(a, b, this.hass.locale.language))
|
||||
.join(", ")}
|
||||
</span>
|
||||
<ha-svg-icon slot="meta" .path=${mdiPencil}></ha-svg-icon>
|
||||
</mwc-list-item>
|
||||
</mwc-list>
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.aliases_description"
|
||||
)}
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
`;
|
||||
}
|
||||
|
||||
private _areaPicked(ev: CustomEvent) {
|
||||
this._areaId = ev.detail.value;
|
||||
}
|
||||
|
||||
private _entityIdChanged(ev): void {
|
||||
this._entityId = ev.target.value;
|
||||
}
|
||||
|
||||
private _viewStatusChanged(ev: CustomEvent): void {
|
||||
switch ((ev.target as any).value) {
|
||||
case "enabled":
|
||||
this._disabledBy = null;
|
||||
this._hiddenBy = null;
|
||||
break;
|
||||
case "disabled":
|
||||
this._disabledBy = "user";
|
||||
this._hiddenBy = null;
|
||||
break;
|
||||
case "hidden":
|
||||
this._hiddenBy = "user";
|
||||
this._disabledBy = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-switch {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.row {
|
||||
margin-top: 8px;
|
||||
color: var(--primary-text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.secondary {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
ha-textfield {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
ha-expansion-panel {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.label {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.aliases {
|
||||
border-radius: 4px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
--mdc-icon-button-size: 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-registry-basic-editor": HaEntityRegistryBasicEditor;
|
||||
}
|
||||
}
|
1199
src/panels/config/entities/entity-registry-settings-editor.ts
Normal file
1199
src/panels/config/entities/entity-registry-settings-editor.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1041,7 +1041,7 @@
|
||||
"enabled_label": "Enabled",
|
||||
"disabled_label": "Disabled",
|
||||
"enabled_cause": "Cannot change status. Disabled by {cause}.",
|
||||
"hidden_label": "Hidden",
|
||||
"visible_label": "Visible",
|
||||
"hidden_cause": "Hidden by {cause}.",
|
||||
"device_disabled": "The device of this entity is disabled.",
|
||||
"entity_disabled": "This entity is disabled.",
|
||||
@ -1056,12 +1056,11 @@
|
||||
"confirm_delete": "Are you sure you want to delete this entity?",
|
||||
"update": "Update",
|
||||
"note": "Note: This might not work yet with all integrations.",
|
||||
"advanced": "Advanced settings",
|
||||
"area": "Set entity area only",
|
||||
"area_note": "By default the entities of a device are in the same area as the device. If you change the area of this entity, it will no longer follow the area of the device.",
|
||||
"follow_device_area": "Follow device area",
|
||||
"change_device_area": "Change device area",
|
||||
"use_device_area": "Use device area",
|
||||
"change_device_settings": "You can {link} in the device settings",
|
||||
"change_device_area_link": "change the device area",
|
||||
"configure_state": "{integration} options",
|
||||
"configure_state_secondary": "Specific options for {integration}",
|
||||
"stream": {
|
||||
"preload_stream": "Preload camera stream",
|
||||
"preload_stream_description": "This keeps the camera stream open in the background so it shows quicker. Warning! This is device intensive.",
|
||||
@ -1076,10 +1075,7 @@
|
||||
"stream_orientation_7": "Rotate right and flip",
|
||||
"stream_orientation_8": "Rotate right"
|
||||
},
|
||||
"aliases_section": "Aliases",
|
||||
"no_aliases": "No configured aliases",
|
||||
"configured_aliases": "{count} configured {count, plural,\n one {alias}\n other {aliases}\n}",
|
||||
"aliases_description": "Aliases are alternative names used in voice assistants to refer to this entity."
|
||||
"no_aliases": "Configure aliases and expose settings for voice assistants"
|
||||
}
|
||||
},
|
||||
"voice-settings": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user