mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 00:06:35 +00:00
Localization bugfixes in config devices/entities/helpers (#18645)
This commit is contained in:
parent
e2e80d1f49
commit
3addfc3548
@ -285,145 +285,143 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
private _columns = memoizeOne((narrow: boolean, showDisabled: boolean) => {
|
private _columns = memoizeOne(
|
||||||
type DeviceItem = ReturnType<
|
(localize: LocalizeFunc, narrow: boolean, showDisabled: boolean) => {
|
||||||
typeof this._devicesAndFilterDomains
|
type DeviceItem = ReturnType<
|
||||||
>["devicesOutput"][number];
|
typeof this._devicesAndFilterDomains
|
||||||
|
>["devicesOutput"][number];
|
||||||
|
|
||||||
const columns: DataTableColumnContainer<DeviceItem> = {
|
const columns: DataTableColumnContainer<DeviceItem> = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (device) =>
|
template: (device) =>
|
||||||
device.domains.length
|
device.domains.length
|
||||||
? html`<img
|
? html`<img
|
||||||
alt=""
|
alt=""
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
src=${brandsUrl({
|
src=${brandsUrl({
|
||||||
domain: device.domains[0],
|
domain: device.domains[0],
|
||||||
type: "icon",
|
type: "icon",
|
||||||
darkOptimized: this.hass.themes?.darkMode,
|
darkOptimized: this.hass.themes?.darkMode,
|
||||||
})}
|
})}
|
||||||
/>`
|
/>`
|
||||||
: "",
|
: "",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (narrow) {
|
if (narrow) {
|
||||||
columns.name = {
|
columns.name = {
|
||||||
title: this.hass.localize("ui.panel.config.devices.data_table.device"),
|
title: localize("ui.panel.config.devices.data_table.device"),
|
||||||
main: true,
|
main: true,
|
||||||
|
sortable: true,
|
||||||
|
filterable: true,
|
||||||
|
direction: "asc",
|
||||||
|
grows: true,
|
||||||
|
template: (device) => html`
|
||||||
|
${device.name}
|
||||||
|
<div class="secondary">${device.area} | ${device.integration}</div>
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
columns.name = {
|
||||||
|
title: localize("ui.panel.config.devices.data_table.device"),
|
||||||
|
main: true,
|
||||||
|
sortable: true,
|
||||||
|
filterable: true,
|
||||||
|
grows: true,
|
||||||
|
direction: "asc",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
columns.manufacturer = {
|
||||||
|
title: localize("ui.panel.config.devices.data_table.manufacturer"),
|
||||||
|
sortable: true,
|
||||||
|
hidden: narrow,
|
||||||
|
filterable: true,
|
||||||
|
width: "15%",
|
||||||
|
};
|
||||||
|
columns.model = {
|
||||||
|
title: localize("ui.panel.config.devices.data_table.model"),
|
||||||
|
sortable: true,
|
||||||
|
hidden: narrow,
|
||||||
|
filterable: true,
|
||||||
|
width: "15%",
|
||||||
|
};
|
||||||
|
columns.area = {
|
||||||
|
title: localize("ui.panel.config.devices.data_table.area"),
|
||||||
|
sortable: true,
|
||||||
|
hidden: narrow,
|
||||||
|
filterable: true,
|
||||||
|
width: "15%",
|
||||||
|
};
|
||||||
|
columns.integration = {
|
||||||
|
title: localize("ui.panel.config.devices.data_table.integration"),
|
||||||
|
sortable: true,
|
||||||
|
hidden: narrow,
|
||||||
|
filterable: true,
|
||||||
|
width: "15%",
|
||||||
|
};
|
||||||
|
columns.battery_entity = {
|
||||||
|
title: localize("ui.panel.config.devices.data_table.battery"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
type: "numeric",
|
||||||
grows: true,
|
width: narrow ? "95px" : "15%",
|
||||||
template: (device) => html`
|
maxWidth: "95px",
|
||||||
${device.name}
|
valueColumn: "battery_level",
|
||||||
<div class="secondary">${device.area} | ${device.integration}</div>
|
template: (device) => {
|
||||||
`,
|
const batteryEntityPair = device.battery_entity;
|
||||||
};
|
const battery =
|
||||||
} else {
|
batteryEntityPair && batteryEntityPair[0]
|
||||||
columns.name = {
|
? this.hass.states[batteryEntityPair[0]]
|
||||||
title: this.hass.localize("ui.panel.config.devices.data_table.device"),
|
: undefined;
|
||||||
main: true,
|
const batteryDomain = battery
|
||||||
sortable: true,
|
? computeStateDomain(battery)
|
||||||
filterable: true,
|
|
||||||
grows: true,
|
|
||||||
direction: "asc",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
columns.manufacturer = {
|
|
||||||
title: this.hass.localize(
|
|
||||||
"ui.panel.config.devices.data_table.manufacturer"
|
|
||||||
),
|
|
||||||
sortable: true,
|
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
|
||||||
width: "15%",
|
|
||||||
};
|
|
||||||
columns.model = {
|
|
||||||
title: this.hass.localize("ui.panel.config.devices.data_table.model"),
|
|
||||||
sortable: true,
|
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
|
||||||
width: "15%",
|
|
||||||
};
|
|
||||||
columns.area = {
|
|
||||||
title: this.hass.localize("ui.panel.config.devices.data_table.area"),
|
|
||||||
sortable: true,
|
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
|
||||||
width: "15%",
|
|
||||||
};
|
|
||||||
columns.integration = {
|
|
||||||
title: this.hass.localize(
|
|
||||||
"ui.panel.config.devices.data_table.integration"
|
|
||||||
),
|
|
||||||
sortable: true,
|
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
|
||||||
width: "15%",
|
|
||||||
};
|
|
||||||
columns.battery_entity = {
|
|
||||||
title: this.hass.localize("ui.panel.config.devices.data_table.battery"),
|
|
||||||
sortable: true,
|
|
||||||
filterable: true,
|
|
||||||
type: "numeric",
|
|
||||||
width: narrow ? "95px" : "15%",
|
|
||||||
maxWidth: "95px",
|
|
||||||
valueColumn: "battery_level",
|
|
||||||
template: (device) => {
|
|
||||||
const batteryEntityPair = device.battery_entity;
|
|
||||||
const battery =
|
|
||||||
batteryEntityPair && batteryEntityPair[0]
|
|
||||||
? this.hass.states[batteryEntityPair[0]]
|
|
||||||
: undefined;
|
|
||||||
const batteryDomain = battery ? computeStateDomain(battery) : undefined;
|
|
||||||
const batteryCharging =
|
|
||||||
batteryEntityPair && batteryEntityPair[1]
|
|
||||||
? this.hass.states[batteryEntityPair[1]]
|
|
||||||
: undefined;
|
: undefined;
|
||||||
|
const batteryCharging =
|
||||||
|
batteryEntityPair && batteryEntityPair[1]
|
||||||
|
? this.hass.states[batteryEntityPair[1]]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return battery &&
|
return battery &&
|
||||||
(batteryDomain === "binary_sensor" || !isNaN(battery.state as any))
|
(batteryDomain === "binary_sensor" || !isNaN(battery.state as any))
|
||||||
? html`
|
? html`
|
||||||
${batteryDomain === "sensor"
|
${batteryDomain === "sensor"
|
||||||
? this.hass.formatEntityState(battery)
|
? this.hass.formatEntityState(battery)
|
||||||
: nothing}
|
: nothing}
|
||||||
<ha-battery-icon
|
<ha-battery-icon
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.batteryStateObj=${battery}
|
.batteryStateObj=${battery}
|
||||||
.batteryChargingStateObj=${batteryCharging}
|
.batteryChargingStateObj=${batteryCharging}
|
||||||
></ha-battery-icon>
|
></ha-battery-icon>
|
||||||
`
|
`
|
||||||
: html`—`;
|
: html`—`;
|
||||||
},
|
},
|
||||||
};
|
|
||||||
if (showDisabled) {
|
|
||||||
columns.disabled_by = {
|
|
||||||
title: "",
|
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.devices.data_table.disabled_by"
|
|
||||||
),
|
|
||||||
type: "icon",
|
|
||||||
template: (device) =>
|
|
||||||
device.disabled_by
|
|
||||||
? html`<div
|
|
||||||
tabindex="0"
|
|
||||||
style="display:inline-block; position: relative;"
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiCancel}></ha-svg-icon>
|
|
||||||
<simple-tooltip animation-delay="0" position="left">
|
|
||||||
${this.hass.localize("ui.panel.config.devices.disabled")}
|
|
||||||
</simple-tooltip>
|
|
||||||
</div>`
|
|
||||||
: "—",
|
|
||||||
};
|
};
|
||||||
|
if (showDisabled) {
|
||||||
|
columns.disabled_by = {
|
||||||
|
title: "",
|
||||||
|
label: localize("ui.panel.config.devices.data_table.disabled_by"),
|
||||||
|
type: "icon",
|
||||||
|
template: (device) =>
|
||||||
|
device.disabled_by
|
||||||
|
? html`<div
|
||||||
|
tabindex="0"
|
||||||
|
style="display:inline-block; position: relative;"
|
||||||
|
>
|
||||||
|
<ha-svg-icon .path=${mdiCancel}></ha-svg-icon>
|
||||||
|
<simple-tooltip animation-delay="0" position="left">
|
||||||
|
${this.hass.localize("ui.panel.config.devices.disabled")}
|
||||||
|
</simple-tooltip>
|
||||||
|
</div>`
|
||||||
|
: "—",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return columns;
|
||||||
}
|
}
|
||||||
return columns;
|
);
|
||||||
});
|
|
||||||
|
|
||||||
public willUpdate(changedProps) {
|
public willUpdate(changedProps) {
|
||||||
if (changedProps.has("_searchParms")) {
|
if (changedProps.has("_searchParms")) {
|
||||||
@ -474,7 +472,11 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
"number",
|
"number",
|
||||||
this._numHiddenDevices
|
this._numHiddenDevices
|
||||||
)}
|
)}
|
||||||
.columns=${this._columns(this.narrow, this._showDisabled)}
|
.columns=${this._columns(
|
||||||
|
this.hass.localize,
|
||||||
|
this.narrow,
|
||||||
|
this._showDisabled
|
||||||
|
)}
|
||||||
.data=${devicesOutput}
|
.data=${devicesOutput}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
@clear-filter=${this._clearFilter}
|
@clear-filter=${this._clearFilter}
|
||||||
|
@ -84,6 +84,7 @@ export interface EntityRow extends StateEntity {
|
|||||||
restored: boolean;
|
restored: boolean;
|
||||||
status: string;
|
status: string;
|
||||||
area?: string;
|
area?: string;
|
||||||
|
localized_platform: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement("ha-config-entities")
|
@customElement("ha-config-entities")
|
||||||
@ -176,12 +177,15 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private _columns = memoize(
|
private _columns = memoize(
|
||||||
(narrow, _language, showDisabled): DataTableColumnContainer<EntityRow> => ({
|
(
|
||||||
|
localize: LocalizeFunc,
|
||||||
|
narrow,
|
||||||
|
_language,
|
||||||
|
showDisabled
|
||||||
|
): DataTableColumnContainer<EntityRow> => ({
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
label: this.hass.localize(
|
label: localize("ui.panel.config.entities.picker.headers.state_icon"),
|
||||||
"ui.panel.config.entities.picker.headers.state_icon"
|
|
||||||
),
|
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (entry) => html`
|
template: (entry) => html`
|
||||||
<ha-state-icon
|
<ha-state-icon
|
||||||
@ -193,9 +197,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
main: true,
|
main: true,
|
||||||
title: this.hass.localize(
|
title: localize("ui.panel.config.entities.picker.headers.name"),
|
||||||
"ui.panel.config.entities.picker.headers.name"
|
|
||||||
),
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
@ -204,47 +206,34 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
? (entry) => html`
|
? (entry) => html`
|
||||||
${entry.name}<br />
|
${entry.name}<br />
|
||||||
<div class="secondary">
|
<div class="secondary">
|
||||||
${entry.entity_id} |
|
${entry.entity_id} | ${entry.localized_platform}
|
||||||
${this.hass.localize(`component.${entry.platform}.title`) ||
|
|
||||||
entry.platform}
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: undefined,
|
: undefined,
|
||||||
},
|
},
|
||||||
entity_id: {
|
entity_id: {
|
||||||
title: this.hass.localize(
|
title: localize("ui.panel.config.entities.picker.headers.entity_id"),
|
||||||
"ui.panel.config.entities.picker.headers.entity_id"
|
|
||||||
),
|
|
||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "25%",
|
width: "25%",
|
||||||
},
|
},
|
||||||
platform: {
|
localized_platform: {
|
||||||
title: this.hass.localize(
|
title: localize("ui.panel.config.entities.picker.headers.integration"),
|
||||||
"ui.panel.config.entities.picker.headers.integration"
|
|
||||||
),
|
|
||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "20%",
|
width: "20%",
|
||||||
template: (entry) =>
|
|
||||||
this.hass.localize(`component.${entry.platform}.title`) ||
|
|
||||||
entry.platform,
|
|
||||||
},
|
},
|
||||||
area: {
|
area: {
|
||||||
title: this.hass.localize(
|
title: localize("ui.panel.config.entities.picker.headers.area"),
|
||||||
"ui.panel.config.entities.picker.headers.area"
|
|
||||||
),
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
},
|
},
|
||||||
disabled_by: {
|
disabled_by: {
|
||||||
title: this.hass.localize(
|
title: localize("ui.panel.config.entities.picker.headers.disabled_by"),
|
||||||
"ui.panel.config.entities.picker.headers.disabled_by"
|
|
||||||
),
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow || !showDisabled,
|
hidden: narrow || !showDisabled,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
@ -257,9 +246,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
title: this.hass.localize(
|
title: localize("ui.panel.config.entities.picker.headers.status"),
|
||||||
"ui.panel.config.entities.picker.headers.status"
|
|
||||||
),
|
|
||||||
type: "icon",
|
type: "icon",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
@ -318,6 +305,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _filteredEntitiesAndDomains = memoize(
|
private _filteredEntitiesAndDomains = memoize(
|
||||||
(
|
(
|
||||||
|
localize: LocalizeFunc,
|
||||||
entities: StateEntity[],
|
entities: StateEntity[],
|
||||||
devices: DeviceRegistryEntry[] | undefined,
|
devices: DeviceRegistryEntry[] | undefined,
|
||||||
areas: AreaRegistryEntry[] | undefined,
|
areas: AreaRegistryEntry[] | undefined,
|
||||||
@ -432,20 +420,16 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
),
|
),
|
||||||
unavailable,
|
unavailable,
|
||||||
restored,
|
restored,
|
||||||
|
localized_platform:
|
||||||
|
localize(`component.${entry.platform}.title`) || entry.platform,
|
||||||
area: area ? area.name : "—",
|
area: area ? area.name : "—",
|
||||||
status: restored
|
status: restored
|
||||||
? this.hass.localize(
|
? localize("ui.panel.config.entities.picker.status.restored")
|
||||||
"ui.panel.config.entities.picker.status.restored"
|
|
||||||
)
|
|
||||||
: unavailable
|
: unavailable
|
||||||
? this.hass.localize(
|
? localize("ui.panel.config.entities.picker.status.unavailable")
|
||||||
"ui.panel.config.entities.picker.status.unavailable"
|
|
||||||
)
|
|
||||||
: entry.disabled_by
|
: entry.disabled_by
|
||||||
? this.hass.localize(
|
? localize("ui.panel.config.entities.picker.status.disabled")
|
||||||
"ui.panel.config.entities.picker.status.disabled"
|
: localize("ui.panel.config.entities.picker.status.ok"),
|
||||||
)
|
|
||||||
: this.hass.localize("ui.panel.config.entities.picker.status.ok"),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +482,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
const { filteredEntities, filteredDomains } =
|
const { filteredEntities, filteredDomains } =
|
||||||
this._filteredEntitiesAndDomains(
|
this._filteredEntitiesAndDomains(
|
||||||
|
this.hass.localize,
|
||||||
this._entities,
|
this._entities,
|
||||||
this._devices,
|
this._devices,
|
||||||
this._areas,
|
this._areas,
|
||||||
@ -526,6 +511,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.tabs=${configSections.devices}
|
.tabs=${configSections.devices}
|
||||||
.columns=${this._columns(
|
.columns=${this._columns(
|
||||||
|
this.hass.localize,
|
||||||
this.narrow,
|
this.narrow,
|
||||||
this.hass.language,
|
this.hass.language,
|
||||||
this._showDisabled
|
this._showDisabled
|
||||||
@ -969,6 +955,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
private _addDevice() {
|
private _addDevice() {
|
||||||
const { filteredConfigEntry, filteredDomains } =
|
const { filteredConfigEntry, filteredDomains } =
|
||||||
this._filteredEntitiesAndDomains(
|
this._filteredEntitiesAndDomains(
|
||||||
|
this.hass.localize,
|
||||||
this._entities!,
|
this._entities!,
|
||||||
this._devices,
|
this._devices,
|
||||||
this._areas,
|
this._areas,
|
||||||
|
@ -158,19 +158,11 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
width: "25%",
|
width: "25%",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
columns.type = {
|
columns.localized_type = {
|
||||||
title: localize("ui.panel.config.helpers.picker.headers.type"),
|
title: localize("ui.panel.config.helpers.picker.headers.type"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
width: "25%",
|
width: "25%",
|
||||||
filterable: true,
|
filterable: true,
|
||||||
template: (helper) =>
|
|
||||||
helper.configEntry
|
|
||||||
? domainToName(localize, helper.type)
|
|
||||||
: html`
|
|
||||||
${localize(
|
|
||||||
`ui.panel.config.helpers.types.${helper.type}` as LocalizeKeys
|
|
||||||
) || helper.type}
|
|
||||||
`,
|
|
||||||
};
|
};
|
||||||
columns.editable = {
|
columns.editable = {
|
||||||
title: "",
|
title: "",
|
||||||
@ -202,6 +194,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _getItems = memoizeOne(
|
private _getItems = memoizeOne(
|
||||||
(
|
(
|
||||||
|
localize: LocalizeFunc,
|
||||||
stateItems: HassEntity[],
|
stateItems: HassEntity[],
|
||||||
entityEntries: Record<string, EntityRegistryEntry>,
|
entityEntries: Record<string, EntityRegistryEntry>,
|
||||||
configEntries: Record<string, ConfigEntry>
|
configEntries: Record<string, ConfigEntry>
|
||||||
@ -248,7 +241,14 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
entity: undefined,
|
entity: undefined,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return [...states, ...entries];
|
return [...states, ...entries].map((item) => ({
|
||||||
|
...item,
|
||||||
|
localized_type: item.configEntry
|
||||||
|
? domainToName(localize, item.type)
|
||||||
|
: localize(
|
||||||
|
`ui.panel.config.helpers.types.${item.type}` as LocalizeKeys
|
||||||
|
) || item.type,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -271,6 +271,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
.tabs=${configSections.devices}
|
.tabs=${configSections.devices}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.narrow, this.hass.localize)}
|
||||||
.data=${this._getItems(
|
.data=${this._getItems(
|
||||||
|
this.hass.localize,
|
||||||
this._stateItems,
|
this._stateItems,
|
||||||
this._entityEntries,
|
this._entityEntries,
|
||||||
this._configEntries
|
this._configEntries
|
||||||
|
Loading…
x
Reference in New Issue
Block a user