Sort language, country, currency (#14500)

This commit is contained in:
Bram Kragten 2022-12-01 13:38:50 +01:00 committed by GitHub
parent dfc461ce05
commit 4190ff5a2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 54 deletions

View File

@ -1,4 +1,7 @@
export const countries = [ import memoizeOne from "memoize-one";
import { caseInsensitiveStringCompare } from "../common/string/compare";
export const COUNTRIES = [
"AD", "AD",
"AE", "AE",
"AF", "AF",
@ -250,23 +253,31 @@ export const countries = [
"ZW", "ZW",
]; ];
export const countryDisplayNames = export const getCountryOptions = memoizeOne((language?: string) => {
Intl && "DisplayNames" in Intl const countryDisplayNames =
? new Intl.DisplayNames(undefined, { Intl && "DisplayNames" in Intl
type: "region", ? new Intl.DisplayNames(language, {
fallback: "code", type: "region",
}) fallback: "code",
: undefined; })
: undefined;
const options = COUNTRIES.map((country) => ({
value: country,
label: countryDisplayNames ? countryDisplayNames.of(country)! : country,
}));
options.sort((a, b) => caseInsensitiveStringCompare(a.label, b.label));
return options;
});
export const createCountryListEl = () => { export const createCountryListEl = () => {
const list = document.createElement("datalist"); const list = document.createElement("datalist");
list.id = "countries"; list.id = "countries";
for (const country of countries) { const options = getCountryOptions();
for (const country of options) {
const option = document.createElement("option"); const option = document.createElement("option");
option.value = country; option.value = country.value;
option.innerText = countryDisplayNames option.innerText = country.label;
? countryDisplayNames.of(country)!
: country;
list.appendChild(option); list.appendChild(option);
} }
return list; return list;

View File

@ -1,4 +1,7 @@
export const currencies = [ import memoizeOne from "memoize-one";
import { caseInsensitiveStringCompare } from "../common/string/compare";
export const CURRENCIES = [
"AED", "AED",
"AFN", "AFN",
"ALL", "ALL",
@ -158,23 +161,29 @@ export const currencies = [
"ZWL", "ZWL",
]; ];
export const currencyDisplayNames = export const getCurrencyOptions = memoizeOne((language?: string) => {
Intl && "DisplayNames" in Intl const currencyDisplayNames =
? new Intl.DisplayNames(undefined, { Intl && "DisplayNames" in Intl
type: "currency", ? new Intl.DisplayNames(language, {
fallback: "code", type: "currency",
}) fallback: "code",
: undefined; })
: undefined;
const options = CURRENCIES.map((currency) => ({
value: currency,
label: currencyDisplayNames ? currencyDisplayNames.of(currency)! : currency,
}));
options.sort((a, b) => caseInsensitiveStringCompare(a.label, b.label));
return options;
});
export const createCurrencyListEl = () => { export const createCurrencyListEl = () => {
const list = document.createElement("datalist"); const list = document.createElement("datalist");
list.id = "currencies"; list.id = "currencies";
for (const currency of currencies) { for (const currency of getCurrencyOptions()) {
const option = document.createElement("option"); const option = document.createElement("option");
option.value = currency; option.value = currency.value;
option.innerText = currencyDisplayNames option.innerText = currency.label;
? currencyDisplayNames.of(currency)!
: currency;
list.appendChild(option); list.appendChild(option);
} }
return list; return list;

View File

@ -6,16 +6,11 @@ import memoizeOne from "memoize-one";
import { UNIT_C } from "../../../common/const"; import { UNIT_C } from "../../../common/const";
import { stopPropagation } from "../../../common/dom/stop_propagation"; import { stopPropagation } from "../../../common/dom/stop_propagation";
import { navigate } from "../../../common/navigate"; import { navigate } from "../../../common/navigate";
import { caseInsensitiveStringCompare } from "../../../common/string/compare";
import "../../../components/buttons/ha-progress-button"; import "../../../components/buttons/ha-progress-button";
import type { HaProgressButton } from "../../../components/buttons/ha-progress-button"; import type { HaProgressButton } from "../../../components/buttons/ha-progress-button";
import { import { getCountryOptions } from "../../../components/country-datalist";
countries, import { getCurrencyOptions } from "../../../components/currency-datalist";
countryDisplayNames,
} from "../../../components/country-datalist";
import {
currencies,
currencyDisplayNames,
} from "../../../components/currency-datalist";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-formfield"; import "../../../components/ha-formfield";
import "../../../components/ha-radio"; import "../../../components/ha-radio";
@ -55,6 +50,8 @@ class HaConfigSectionGeneral extends LitElement {
@state() private _location?: [number, number]; @state() private _location?: [number, number];
@state() private _languages?: { value: string; label: string }[];
protected render(): TemplateResult { protected render(): TemplateResult {
const canEdit = ["storage", "default"].includes( const canEdit = ["storage", "default"].includes(
this.hass.config.config_source this.hass.config.config_source
@ -187,13 +184,11 @@ class HaConfigSectionGeneral extends LitElement {
@closed=${stopPropagation} @closed=${stopPropagation}
@change=${this._handleChange} @change=${this._handleChange}
> >
${currencies.map( ${getCurrencyOptions(this.hass.locale.language).map(
(currency) => ({ value, label }) =>
html`<mwc-list-item .value=${currency} html`<mwc-list-item .value=${value}>
>${currencyDisplayNames ${label}
? currencyDisplayNames.of(currency) </mwc-list-item>`
: currency}</mwc-list-item
>`
)}</ha-select )}</ha-select
> >
<a <a
@ -218,13 +213,11 @@ class HaConfigSectionGeneral extends LitElement {
@closed=${stopPropagation} @closed=${stopPropagation}
@change=${this._handleChange} @change=${this._handleChange}
> >
${countries.map( ${getCountryOptions(this.hass.locale.language).map(
(country) => ({ value, label }) =>
html`<mwc-list-item .value=${country} html`<mwc-list-item .value=${value}>
>${countryDisplayNames ${label}
? countryDisplayNames.of(country) </mwc-list-item>`
: country}</mwc-list-item
>`
)}</ha-select )}</ha-select
> >
<ha-select <ha-select
@ -239,12 +232,10 @@ class HaConfigSectionGeneral extends LitElement {
@closed=${stopPropagation} @closed=${stopPropagation}
@change=${this._handleChange} @change=${this._handleChange}
> >
${Object.entries( ${this._languages?.map(
this.hass.translationMetadata.translations ({ value, label }) =>
).map( html`<mwc-list-item .value=${value}
([code, metadata]) => >${label}</mwc-list-item
html`<mwc-list-item .value=${code}
>${metadata.nativeName}</mwc-list-item
>` >`
)}</ha-select )}</ha-select
> >
@ -300,6 +291,21 @@ class HaConfigSectionGeneral extends LitElement {
this._elevation = this.hass.config.elevation; this._elevation = this.hass.config.elevation;
this._timeZone = this.hass.config.time_zone; this._timeZone = this.hass.config.time_zone;
this._name = this.hass.config.location_name; this._name = this.hass.config.location_name;
this._computeLanguages();
}
private _computeLanguages() {
if (!this.hass.translationMetadata?.translations) {
return;
}
this._languages = Object.entries(this.hass.translationMetadata.translations)
.sort((a, b) =>
caseInsensitiveStringCompare(a[1].nativeName, b[1].nativeName)
)
.map(([value, metaData]) => ({
value,
label: metaData.nativeName,
}));
} }
private _handleChange(ev) { private _handleChange(ev) {