Sort strings by locale language (#14533)

This commit is contained in:
Jaroslav Hanslík 2022-12-28 14:25:45 +01:00 committed by GitHub
parent 1198f983aa
commit e926091e54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 231 additions and 79 deletions

View File

@ -29,7 +29,9 @@ class HassioAddonRepositoryEl extends LitElement {
if (filter) {
return filterAndSort(addons, filter);
}
return addons.sort((a, b) => caseInsensitiveStringCompare(a.name, b.name));
return addons.sort((a, b) =>
caseInsensitiveStringCompare(a.name, b.name, this.hass.locale.language)
);
});
protected render(): TemplateResult {

View File

@ -35,7 +35,13 @@ class HassioAddons extends LitElement {
</ha-card>
`
: this.supervisor.addon.addons
.sort((a, b) => caseInsensitiveStringCompare(a.name, b.name))
.sort((a, b) =>
caseInsensitiveStringCompare(
a.name,
b.name,
this.hass.locale.language
)
)
.map(
(addon) => html`
<ha-card

View File

@ -15,7 +15,12 @@ import { HomeAssistant } from "../../../../src/types";
import { HassioHardwareDialogParams } from "./show-dialog-hassio-hardware";
const _filterDevices = memoizeOne(
(showAdvanced: boolean, hardware: HassioHardwareInfo, filter: string) =>
(
showAdvanced: boolean,
hardware: HassioHardwareInfo,
filter: string,
language: string
) =>
hardware.devices
.filter(
(device) =>
@ -28,7 +33,7 @@ const _filterDevices = memoizeOne(
.toLocaleLowerCase()
.includes(filter))
)
.sort((a, b) => stringCompare(a.name, b.name))
.sort((a, b) => stringCompare(a.name, b.name, language))
);
@customElement("dialog-hassio-hardware")
@ -56,7 +61,8 @@ class HassioHardwareDialog extends LitElement {
const devices = _filterDevices(
this.hass.userData?.showAdvanced || false,
this._dialogParams.hardware,
(this._filter || "").toLowerCase()
(this._filter || "").toLowerCase(),
this.hass.locale.language
);
return html`

View File

@ -68,7 +68,9 @@ class HassioRepositoriesDialog extends LitElement {
repo.slug !== "a0d7b954" && // Home Assistant Community Add-ons
repo.slug !== "5c53de3b" // The ESPHome repository
)
.sort((a, b) => caseInsensitiveStringCompare(a.name, b.name))
.sort((a, b) =>
caseInsensitiveStringCompare(a.name, b.name, this.hass.locale.language)
)
);
private _filteredUsedRepositories = memoizeOne(

View File

@ -1,4 +1,15 @@
export const stringCompare = (a: string, b: string) => {
import memoizeOne from "memoize-one";
const collator = memoizeOne(
(language: string | undefined) => new Intl.Collator(language)
);
const caseInsensitiveCollator = memoizeOne(
(language: string | undefined) =>
new Intl.Collator(language, { sensitivity: "accent" })
);
const fallbackStringCompare = (a: string, b: string) => {
if (a < b) {
return -1;
}
@ -9,5 +20,28 @@ export const stringCompare = (a: string, b: string) => {
return 0;
};
export const caseInsensitiveStringCompare = (a: string, b: string) =>
stringCompare(a.toLowerCase(), b.toLowerCase());
export const stringCompare = (
a: string,
b: string,
language: string | undefined = undefined
) => {
// @ts-ignore
if (Intl?.Collator) {
return collator(language).compare(a, b);
}
return fallbackStringCompare(a, b);
};
export const caseInsensitiveStringCompare = (
a: string,
b: string,
language: string | undefined = undefined
) => {
// @ts-ignore
if (Intl?.Collator) {
return caseInsensitiveCollator(language).compare(a, b);
}
return fallbackStringCompare(a.toLowerCase(), b.toLowerCase());
};

View File

@ -266,14 +266,16 @@ export const getCountryOptions = memoizeOne((language?: string) => {
value: country,
label: countryDisplayNames ? countryDisplayNames.of(country)! : country,
}));
options.sort((a, b) => caseInsensitiveStringCompare(a.label, b.label));
options.sort((a, b) =>
caseInsensitiveStringCompare(a.label, b.label, language)
);
return options;
});
export const createCountryListEl = () => {
export const createCountryListEl = (language?: string) => {
const list = document.createElement("datalist");
list.id = "countries";
const options = getCountryOptions();
const options = getCountryOptions(language);
for (const country of options) {
const option = document.createElement("option");
option.value = country.value;

View File

@ -173,14 +173,16 @@ export const getCurrencyOptions = memoizeOne((language?: string) => {
value: currency,
label: currencyDisplayNames ? currencyDisplayNames.of(currency)! : currency,
}));
options.sort((a, b) => caseInsensitiveStringCompare(a.label, b.label));
options.sort((a, b) =>
caseInsensitiveStringCompare(a.label, b.label, language)
);
return options;
});
export const createCurrencyListEl = () => {
export const createCurrencyListEl = (language: string) => {
const list = document.createElement("datalist");
list.id = "currencies";
for (const currency of getCurrencyOptions()) {
for (const currency of getCurrencyOptions(language)) {
const option = document.createElement("option");
option.value = currency.value;
option.innerText = currency.label;

View File

@ -189,7 +189,8 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
.sort((a, b) =>
stringCompare(
devicesByArea[a].name || "",
devicesByArea[b].name || ""
devicesByArea[b].name || "",
this.hass.locale.language
)
)
.map((key) => devicesByArea[key]);

View File

@ -231,7 +231,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
return outputDevices;
}
return outputDevices.sort((a, b) =>
stringCompare(a.name || "", b.name || "")
stringCompare(a.name || "", b.name || "", this.hass.locale.language)
);
}
);

View File

@ -174,7 +174,8 @@ export class HaEntityPicker extends LitElement {
.sort((entityA, entityB) =>
caseInsensitiveStringCompare(
entityA.friendly_name,
entityB.friendly_name
entityB.friendly_name,
this.hass.locale.language
)
);
}
@ -205,7 +206,8 @@ export class HaEntityPicker extends LitElement {
.sort((entityA, entityB) =>
caseInsensitiveStringCompare(
entityA.friendly_name,
entityB.friendly_name
entityB.friendly_name,
this.hass.locale.language
)
);

View File

@ -177,7 +177,9 @@ export class HaStatisticPicker extends LitElement {
}
if (output.length > 1) {
output.sort((a, b) => stringCompare(a.name || "", b.name || ""));
output.sort((a, b) =>
stringCompare(a.name || "", b.name || "", this.hass.locale.language)
);
}
output.push({

View File

@ -80,7 +80,9 @@ class HaAddonPicker extends LitElement {
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
this._addons = addonsInfo.addons
.filter((addon) => addon.version)
.sort((a, b) => stringCompare(a.name, b.name));
.sort((a, b) =>
stringCompare(a.name, b.name, this.hass.locale.language)
);
} else {
showAlertDialog(this, {
title: this.hass.localize(

View File

@ -46,7 +46,9 @@ class HaBluePrintPicker extends LitElement {
...(blueprint as Blueprint).metadata,
path,
}));
return result.sort((a, b) => stringCompare(a.name, b.name));
return result.sort((a, b) =>
stringCompare(a.name, b.name, this.hass!.locale.language)
);
});
protected render(): TemplateResult {

View File

@ -121,7 +121,8 @@ class HaConfigEntryPicker extends LitElement {
.sort((conf1, conf2) =>
caseInsensitiveStringCompare(
conf1.localized_domain_name + conf1.title,
conf2.localized_domain_name + conf2.title
conf2.localized_domain_name + conf2.title,
this.hass.locale.language
)
);
});

View File

@ -87,7 +87,8 @@ const panelSorter = (
reverseSort: string[],
defaultPanel: string,
a: PanelInfo,
b: PanelInfo
b: PanelInfo,
language: string
) => {
const indexA = reverseSort.indexOf(a.url_path);
const indexB = reverseSort.indexOf(b.url_path);
@ -97,13 +98,14 @@ const panelSorter = (
}
return -1;
}
return defaultPanelSorter(defaultPanel, a, b);
return defaultPanelSorter(defaultPanel, a, b, language);
};
const defaultPanelSorter = (
defaultPanel: string,
a: PanelInfo,
b: PanelInfo
b: PanelInfo,
language: string
) => {
// Put all the Lovelace at the top.
const aLovelace = a.component_name === "lovelace";
@ -117,7 +119,7 @@ const defaultPanelSorter = (
}
if (aLovelace && bLovelace) {
return stringCompare(a.title!, b.title!);
return stringCompare(a.title!, b.title!, language);
}
if (aLovelace && !bLovelace) {
return -1;
@ -139,7 +141,7 @@ const defaultPanelSorter = (
return 1;
}
// both not built in, sort by title
return stringCompare(a.title!, b.title!);
return stringCompare(a.title!, b.title!, language);
};
const computePanels = memoizeOne(
@ -147,7 +149,8 @@ const computePanels = memoizeOne(
panels: HomeAssistant["panels"],
defaultPanel: HomeAssistant["defaultPanel"],
panelsOrder: string[],
hiddenPanels: string[]
hiddenPanels: string[],
locale: HomeAssistant["locale"]
): [PanelInfo[], PanelInfo[]] => {
if (!panels) {
return [[], []];
@ -171,8 +174,12 @@ const computePanels = memoizeOne(
const reverseSort = [...panelsOrder].reverse();
beforeSpacer.sort((a, b) => panelSorter(reverseSort, defaultPanel, a, b));
afterSpacer.sort((a, b) => panelSorter(reverseSort, defaultPanel, a, b));
beforeSpacer.sort((a, b) =>
panelSorter(reverseSort, defaultPanel, a, b, locale.language)
);
afterSpacer.sort((a, b) =>
panelSorter(reverseSort, defaultPanel, a, b, locale.language)
);
return [beforeSpacer, afterSpacer];
}
@ -374,7 +381,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
this.hass.panels,
this.hass.defaultPanel,
this._panelOrder,
this._hiddenPanels
this._hiddenPanels,
this.hass.locale
);
// Show the supervisor as beeing part of configuration

View File

@ -30,7 +30,9 @@ class HaUserPicker extends LitElement {
return users
.filter((user) => !user.system_generated)
.sort((a, b) => stringCompare(a.name, b.name));
.sort((a, b) =>
stringCompare(a.name, b.name, this.hass!.locale.language)
);
});
protected render(): TemplateResult {

View File

@ -123,9 +123,12 @@ export const subscribeDeviceRegistry = (
onChange
);
export const sortDeviceRegistryByName = (entries: DeviceRegistryEntry[]) =>
export const sortDeviceRegistryByName = (
entries: DeviceRegistryEntry[],
language: string
) =>
entries.sort((entry1, entry2) =>
caseInsensitiveStringCompare(entry1.name || "", entry2.name || "")
caseInsensitiveStringCompare(entry1.name || "", entry2.name || "", language)
);
export const getDeviceEntityLookup = (

View File

@ -164,9 +164,12 @@ export const subscribeEntityRegistry = (
onChange
);
export const sortEntityRegistryByName = (entries: EntityRegistryEntry[]) =>
export const sortEntityRegistryByName = (
entries: EntityRegistryEntry[],
language: string
) =>
entries.sort((entry1, entry2) =>
caseInsensitiveStringCompare(entry1.name || "", entry2.name || "")
caseInsensitiveStringCompare(entry1.name || "", entry2.name || "", language)
);
export const entityRegistryById = memoizeOne(

View File

@ -68,7 +68,10 @@ export const updateReleaseNotes = (hass: HomeAssistant, entityId: string) =>
entity_id: entityId,
});
export const filterUpdateEntities = (entities: HassEntities) =>
export const filterUpdateEntities = (
entities: HassEntities,
language?: string
) =>
(
Object.values(entities).filter(
(entity) => computeStateDomain(entity) === "update"
@ -94,7 +97,8 @@ export const filterUpdateEntities = (entities: HassEntities) =>
}
return caseInsensitiveStringCompare(
a.attributes.title || a.attributes.friendly_name || "",
b.attributes.title || b.attributes.friendly_name || ""
b.attributes.title || b.attributes.friendly_name || "",
language
);
});
@ -110,7 +114,7 @@ export const checkForEntityUpdates = async (
element: HTMLElement,
hass: HomeAssistant
) => {
const entities = filterUpdateEntities(hass.states).map(
const entities = filterUpdateEntities(hass.states, hass.locale.language).map(
(entity) => entity.entity_id
);

View File

@ -484,7 +484,11 @@ export class QuickBar extends LitElement {
};
})
.sort((a, b) =>
caseInsensitiveStringCompare(a.primaryText, b.primaryText)
caseInsensitiveStringCompare(
a.primaryText,
b.primaryText,
this.hass.locale.language
)
);
}
@ -494,7 +498,11 @@ export class QuickBar extends LitElement {
...this._generateServerControlCommands(),
...(await this._generateNavigationCommands()),
].sort((a, b) =>
caseInsensitiveStringCompare(a.strings.join(" "), b.strings.join(" "))
caseInsensitiveStringCompare(
a.strings.join(" "),
b.strings.join(" "),
this.hass.locale.language
)
);
}

View File

@ -271,7 +271,9 @@ class OnboardingCoreConfig extends LitElement {
"[name=currency]"
) as HaTextField;
curInput.updateComplete.then(() => {
curInput.shadowRoot!.appendChild(createCurrencyListEl());
curInput.shadowRoot!.appendChild(
createCurrencyListEl(this.hass.locale.language)
);
curInput.formElement.setAttribute("list", "currencies");
});
@ -279,7 +281,9 @@ class OnboardingCoreConfig extends LitElement {
"[name=country]"
) as HaTextField;
countryInput.updateComplete.then(() => {
countryInput.shadowRoot!.appendChild(createCountryListEl());
countryInput.shadowRoot!.appendChild(
createCountryListEl(this.hass.locale.language)
);
countryInput.formElement.setAttribute("list", "countries");
});

View File

@ -117,7 +117,7 @@ class OnboardingIntegrations extends LitElement {
}
);
const content = [...entries, ...discovered]
.sort((a, b) => stringCompare(a[0], b[0]))
.sort((a, b) => stringCompare(a[0], b[0], this.hass.locale.language))
.map((item) => item[1]);
return html`

View File

@ -192,13 +192,13 @@ class HaConfigAreaPage extends SubscribeMixin(LitElement) {
devices.forEach((entry) => {
entry.name = computeDeviceName(entry, this.hass);
});
sortDeviceRegistryByName(devices);
sortDeviceRegistryByName(devices, this.hass.locale.language);
}
if (entities) {
entities.forEach((entry) => {
entry.name = computeEntityRegistryName(this.hass, entry);
});
sortEntityRegistryByName(entities);
sortEntityRegistryByName(entities, this.hass.locale.language);
}
// Group entities by domain
@ -507,7 +507,11 @@ class HaConfigAreaPage extends SubscribeMixin(LitElement) {
}
});
groupedEntities.sort((entry1, entry2) =>
caseInsensitiveStringCompare(entry1.name!, entry2.name!)
caseInsensitiveStringCompare(
entry1.name!,
entry2.name!,
this.hass.locale.language
)
);
}
if (relatedEntityIds?.length) {
@ -521,7 +525,11 @@ class HaConfigAreaPage extends SubscribeMixin(LitElement) {
}
});
relatedEntities.sort((entry1, entry2) =>
caseInsensitiveStringCompare(entry1.name!, entry2.name!)
caseInsensitiveStringCompare(
entry1.name!,
entry2.name!,
this.hass.locale.language
)
);
}

View File

@ -299,7 +299,7 @@ export default class HaAutomationAction extends LitElement {
icon,
] as [string, string, string]
)
.sort((a, b) => stringCompare(a[1], b[1]))
.sort((a, b) => stringCompare(a[1], b[1], this.hass.locale.language))
);
static get styles(): CSSResultGroup {

View File

@ -66,7 +66,7 @@ export class HaConditionAction extends LitElement implements ActionElement {
icon,
] as [string, string, string]
)
.sort((a, b) => stringCompare(a[1], b[1]))
.sort((a, b) => stringCompare(a[1], b[1], this.hass.locale.language))
);
private _conditionChanged(ev: CustomEvent) {

View File

@ -328,7 +328,7 @@ export default class HaAutomationCondition extends LitElement {
icon,
] as [string, string, string]
)
.sort((a, b) => stringCompare(a[1], b[1]))
.sort((a, b) => stringCompare(a[1], b[1], this.hass.locale.language))
);
static get styles(): CSSResultGroup {

View File

@ -302,7 +302,7 @@ export default class HaAutomationTrigger extends LitElement {
icon,
] as [string, string, string]
)
.sort((a, b) => stringCompare(a[1], b[1]))
.sort((a, b) => stringCompare(a[1], b[1], this.hass.locale.language))
);
static get styles(): CSSResultGroup {

View File

@ -54,7 +54,11 @@ export class HaTagTrigger extends LitElement implements TriggerElement {
private async _fetchTags() {
this._tags = (await fetchTags(this.hass)).sort((a, b) =>
caseInsensitiveStringCompare(a.name || a.id, b.name || b.id)
caseInsensitiveStringCompare(
a.name || a.id,
b.name || b.id,
this.hass.locale.language
)
);
}

View File

@ -349,7 +349,8 @@ class CloudAlexa extends SubscribeMixin(LitElement) {
const stateB = this.hass.states[b.entity_id];
return stringCompare(
stateA ? computeStateName(stateA) : a.entity_id,
stateB ? computeStateName(stateB) : b.entity_id
stateB ? computeStateName(stateB) : b.entity_id,
this.hass.locale.language
);
});
this._entities = entities;

View File

@ -402,7 +402,8 @@ class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
const stateB = this.hass.states[b.entity_id];
return stringCompare(
stateA ? computeStateName(stateA) : a.entity_id,
stateB ? computeStateName(stateB) : b.entity_id
stateB ? computeStateName(stateB) : b.entity_id,
this.hass.locale.language
);
});
this._entities = entities;

View File

@ -304,7 +304,11 @@ class HaConfigSectionGeneral extends LitElement {
}
this._languages = Object.entries(this.hass.translationMetadata.translations)
.sort((a, b) =>
caseInsensitiveStringCompare(a[1].nativeName, b[1].nativeName)
caseInsensitiveStringCompare(
a[1].nativeName,
b[1].nativeName,
this.hass.locale.language
)
)
.map(([value, metaData]) => ({
value,

View File

@ -31,7 +31,8 @@ export class HaDeviceViaDevicesCard extends LitElement {
.sort((d1, d2) =>
caseInsensitiveStringCompare(
computeDeviceName(d1, this.hass),
computeDeviceName(d2, this.hass)
computeDeviceName(d2, this.hass),
this.hass.locale.language
)
)
);

View File

@ -157,7 +157,8 @@ export class HaConfigDevicePage extends LitElement {
.sort((ent1, ent2) =>
stringCompare(
ent1.stateName || `zzz${ent1.entity_id}`,
ent2.stateName || `zzz${ent2.entity_id}`
ent2.stateName || `zzz${ent2.entity_id}`,
this.hass.locale.language
)
)
);

View File

@ -1191,7 +1191,9 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
domain: entry,
label: domainToName(localize, entry),
}))
.sort((a, b) => stringCompare(a.label, b.label))
.sort((a, b) =>
stringCompare(a.label, b.label, this.hass.locale.language)
)
);
private _deviceClassesSorted = memoizeOne(
@ -1203,7 +1205,9 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
`ui.dialogs.entity_registry.editor.device_classes.${domain}.${entry}`
),
}))
.sort((a, b) => stringCompare(a.label, b.label))
.sort((a, b) =>
stringCompare(a.label, b.label, this.hass.locale.language)
)
);
static get styles(): CSSResultGroup {

View File

@ -20,7 +20,12 @@ import { haStyle, haStyleDialog } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types";
const _filterDevices = memoizeOne(
(showAdvanced: boolean, hardware: HassioHardwareInfo, filter: string) =>
(
showAdvanced: boolean,
hardware: HassioHardwareInfo,
filter: string,
language: string
) =>
hardware.devices
.filter(
(device) =>
@ -33,7 +38,7 @@ const _filterDevices = memoizeOne(
.toLocaleLowerCase()
.includes(filter))
)
.sort((a, b) => stringCompare(a.name, b.name))
.sort((a, b) => stringCompare(a.name, b.name, language))
);
@customElement("ha-dialog-hardware-available")
@ -70,7 +75,8 @@ class DialogHardwareAvailable extends LitElement implements HassDialog {
const devices = _filterDevices(
this.hass.userData?.showAdvanced || false,
this._hardware,
(this._filter || "").toLowerCase()
(this._filter || "").toLowerCase(),
this.hass.locale.language
);
return html`

View File

@ -147,7 +147,13 @@ class AddIntegrationDialog extends LitElement {
is_built_in: true,
is_add: true,
}))
.sort((a, b) => caseInsensitiveStringCompare(a.name, b.name));
.sort((a, b) =>
caseInsensitiveStringCompare(
a.name,
b.name,
this.hass.locale.language
)
);
const integrations: IntegrationListItem[] = [];
const yamlIntegrations: IntegrationListItem[] = [];
@ -242,7 +248,11 @@ class AddIntegrationDialog extends LitElement {
return [
...addDeviceRows,
...integrations.sort((a, b) =>
caseInsensitiveStringCompare(a.name || "", b.name || "")
caseInsensitiveStringCompare(
a.name || "",
b.name || "",
this.hass.locale.language
)
),
];
}

View File

@ -230,7 +230,8 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
(conf1, conf2) =>
caseInsensitiveStringCompare(
conf1.localized_domain_name + conf1.title,
conf2.localized_domain_name + conf2.title
conf2.localized_domain_name + conf2.title,
this.hass.locale.language
)
);
},

View File

@ -121,7 +121,8 @@ class HaDomainIntegrations extends LitElement {
}
return caseInsensitiveStringCompare(
a[1].name || domainToName(this.hass.localize, a[0]),
b[1].name || domainToName(this.hass.localize, b[0])
b[1].name || domainToName(this.hass.localize, b[0]),
this.hass.locale.language
);
})
.map(

View File

@ -50,7 +50,8 @@ class ZHADeviceCard extends SubscribeMixin(LitElement) {
.sort((ent1, ent2) =>
stringCompare(
ent1.stateName || `zzz${ent1.entity_id}`,
ent2.stateName || `zzz${ent2.entity_id}`
ent2.stateName || `zzz${ent2.entity_id}`,
this.hass.locale.language
)
)
);

View File

@ -230,7 +230,9 @@ export class HaConfigLovelaceDashboards extends LitElement {
result.push(
...dashboards
.sort((a, b) => stringCompare(a.title, b.title))
.sort((a, b) =>
stringCompare(a.title, b.title, this.hass.locale.language)
)
.map((dashboard) => ({
filename: "",
...dashboard,
@ -342,7 +344,12 @@ export class HaConfigLovelaceDashboards extends LitElement {
createDashboard: async (values: LovelaceDashboardCreateParams) => {
const created = await createDashboard(this.hass!, values);
this._dashboards = this._dashboards!.concat(created).sort(
(res1, res2) => stringCompare(res1.url_path, res2.url_path)
(res1, res2) =>
stringCompare(
res1.url_path,
res2.url_path,
this.hass.locale.language
)
);
},
updateDashboard: async (values) => {

View File

@ -143,7 +143,7 @@ export class HaConfigLovelaceRescources extends LitElement {
createResource: async (values) => {
const created = await createResource(this.hass!, values);
this._resources = this._resources!.concat(created).sort((res1, res2) =>
stringCompare(res1.url, res2.url)
stringCompare(res1.url, res2.url, this.hass!.locale.language)
);
loadLovelaceResources([created], this.hass!.auth.data.hassUrl);
},

View File

@ -156,10 +156,10 @@ class HaConfigPerson extends LitElement {
const personData = await fetchPersons(this.hass!);
this._storageItems = personData.storage.sort((ent1, ent2) =>
stringCompare(ent1.name, ent2.name)
stringCompare(ent1.name, ent2.name, this.hass!.locale.language)
);
this._configItems = personData.config.sort((ent1, ent2) =>
stringCompare(ent1.name, ent2.name)
stringCompare(ent1.name, ent2.name, this.hass!.locale.language)
);
this._openDialogIfPersonSpecifiedInRoute();
}
@ -221,7 +221,8 @@ class HaConfigPerson extends LitElement {
createEntry: async (values) => {
const created = await createPerson(this.hass!, values);
this._storageItems = this._storageItems!.concat(created).sort(
(ent1, ent2) => stringCompare(ent1.name, ent2.name)
(ent1, ent2) =>
stringCompare(ent1.name, ent2.name, this.hass!.locale.language)
);
},
updateEntry: async (values) => {

View File

@ -296,7 +296,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
private async _fetchData() {
this._storageItems = (await fetchZones(this.hass!)).sort((ent1, ent2) =>
stringCompare(ent1.name, ent2.name)
stringCompare(ent1.name, ent2.name, this.hass!.locale.language)
);
this._getStates();
}
@ -411,7 +411,8 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
private async _createEntry(values: ZoneMutableParams) {
const created = await createZone(this.hass!, values);
this._storageItems = this._storageItems!.concat(created).sort(
(ent1, ent2) => stringCompare(ent1.name, ent2.name)
(ent1, ent2) =>
stringCompare(ent1.name, ent2.name, this.hass!.locale.language)
);
if (this.narrow) {
return;

View File

@ -58,7 +58,9 @@ class EventsList extends EventsMixin(LocalizeMixin(PolymerElement)) {
connectedCallback() {
super.connectedCallback();
this.hass.callApi("GET", "events").then((events) => {
this.events = events.sort((e1, e2) => stringCompare(e1.event, e2.event));
this.events = events.sort((e1, e2) =>
stringCompare(e1.event, e2.event, this.hass.locale.language)
);
});
}

View File

@ -42,7 +42,9 @@ export class HuiViewVisibilityEditor extends LitElement {
@state() private _visible!: boolean | ShowViewConfig[];
private _sortedUsers = memoizeOne((users: User[]) =>
users.sort((a, b) => stringCompare(a.name, b.name))
users.sort((a, b) =>
stringCompare(a.name, b.name, this.hass.locale.language)
)
);
protected firstUpdated(changedProps: PropertyValues) {