mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 06:46:35 +00:00
Add core country and language settings (#14478)
This commit is contained in:
parent
ee6f97b802
commit
92d022747b
@ -112,7 +112,7 @@
|
|||||||
"google-timezones-json": "^1.0.2",
|
"google-timezones-json": "^1.0.2",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"hls.js": "^1.2.5",
|
"hls.js": "^1.2.5",
|
||||||
"home-assistant-js-websocket": "^8.0.0",
|
"home-assistant-js-websocket": "^8.0.1",
|
||||||
"idb-keyval": "^5.1.3",
|
"idb-keyval": "^5.1.3",
|
||||||
"intl-messageformat": "^9.9.1",
|
"intl-messageformat": "^9.9.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
273
src/components/country-datalist.ts
Normal file
273
src/components/country-datalist.ts
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
export const countries = [
|
||||||
|
"AD",
|
||||||
|
"AE",
|
||||||
|
"AF",
|
||||||
|
"AG",
|
||||||
|
"AI",
|
||||||
|
"AL",
|
||||||
|
"AM",
|
||||||
|
"AO",
|
||||||
|
"AQ",
|
||||||
|
"AR",
|
||||||
|
"AS",
|
||||||
|
"AT",
|
||||||
|
"AU",
|
||||||
|
"AW",
|
||||||
|
"AX",
|
||||||
|
"AZ",
|
||||||
|
"BA",
|
||||||
|
"BB",
|
||||||
|
"BD",
|
||||||
|
"BE",
|
||||||
|
"BF",
|
||||||
|
"BG",
|
||||||
|
"BH",
|
||||||
|
"BI",
|
||||||
|
"BJ",
|
||||||
|
"BL",
|
||||||
|
"BM",
|
||||||
|
"BN",
|
||||||
|
"BO",
|
||||||
|
"BQ",
|
||||||
|
"BR",
|
||||||
|
"BS",
|
||||||
|
"BT",
|
||||||
|
"BV",
|
||||||
|
"BW",
|
||||||
|
"BY",
|
||||||
|
"BZ",
|
||||||
|
"CA",
|
||||||
|
"CC",
|
||||||
|
"CD",
|
||||||
|
"CF",
|
||||||
|
"CG",
|
||||||
|
"CH",
|
||||||
|
"CI",
|
||||||
|
"CK",
|
||||||
|
"CL",
|
||||||
|
"CM",
|
||||||
|
"CN",
|
||||||
|
"CO",
|
||||||
|
"CR",
|
||||||
|
"CU",
|
||||||
|
"CV",
|
||||||
|
"CW",
|
||||||
|
"CX",
|
||||||
|
"CY",
|
||||||
|
"CZ",
|
||||||
|
"DE",
|
||||||
|
"DJ",
|
||||||
|
"DK",
|
||||||
|
"DM",
|
||||||
|
"DO",
|
||||||
|
"DZ",
|
||||||
|
"EC",
|
||||||
|
"EE",
|
||||||
|
"EG",
|
||||||
|
"EH",
|
||||||
|
"ER",
|
||||||
|
"ES",
|
||||||
|
"ET",
|
||||||
|
"FI",
|
||||||
|
"FJ",
|
||||||
|
"FK",
|
||||||
|
"FM",
|
||||||
|
"FO",
|
||||||
|
"FR",
|
||||||
|
"GA",
|
||||||
|
"GB",
|
||||||
|
"GD",
|
||||||
|
"GE",
|
||||||
|
"GF",
|
||||||
|
"GG",
|
||||||
|
"GH",
|
||||||
|
"GI",
|
||||||
|
"GL",
|
||||||
|
"GM",
|
||||||
|
"GN",
|
||||||
|
"GP",
|
||||||
|
"GQ",
|
||||||
|
"GR",
|
||||||
|
"GS",
|
||||||
|
"GT",
|
||||||
|
"GU",
|
||||||
|
"GW",
|
||||||
|
"GY",
|
||||||
|
"HK",
|
||||||
|
"HM",
|
||||||
|
"HN",
|
||||||
|
"HR",
|
||||||
|
"HT",
|
||||||
|
"HU",
|
||||||
|
"ID",
|
||||||
|
"IE",
|
||||||
|
"IL",
|
||||||
|
"IM",
|
||||||
|
"IN",
|
||||||
|
"IO",
|
||||||
|
"IQ",
|
||||||
|
"IR",
|
||||||
|
"IS",
|
||||||
|
"IT",
|
||||||
|
"JE",
|
||||||
|
"JM",
|
||||||
|
"JO",
|
||||||
|
"JP",
|
||||||
|
"KE",
|
||||||
|
"KG",
|
||||||
|
"KH",
|
||||||
|
"KI",
|
||||||
|
"KM",
|
||||||
|
"KN",
|
||||||
|
"KP",
|
||||||
|
"KR",
|
||||||
|
"KW",
|
||||||
|
"KY",
|
||||||
|
"KZ",
|
||||||
|
"LA",
|
||||||
|
"LB",
|
||||||
|
"LC",
|
||||||
|
"LI",
|
||||||
|
"LK",
|
||||||
|
"LR",
|
||||||
|
"LS",
|
||||||
|
"LT",
|
||||||
|
"LU",
|
||||||
|
"LV",
|
||||||
|
"LY",
|
||||||
|
"MA",
|
||||||
|
"MC",
|
||||||
|
"MD",
|
||||||
|
"ME",
|
||||||
|
"MF",
|
||||||
|
"MG",
|
||||||
|
"MH",
|
||||||
|
"MK",
|
||||||
|
"ML",
|
||||||
|
"MM",
|
||||||
|
"MN",
|
||||||
|
"MO",
|
||||||
|
"MP",
|
||||||
|
"MQ",
|
||||||
|
"MR",
|
||||||
|
"MS",
|
||||||
|
"MT",
|
||||||
|
"MU",
|
||||||
|
"MV",
|
||||||
|
"MW",
|
||||||
|
"MX",
|
||||||
|
"MY",
|
||||||
|
"MZ",
|
||||||
|
"NA",
|
||||||
|
"NC",
|
||||||
|
"NE",
|
||||||
|
"NF",
|
||||||
|
"NG",
|
||||||
|
"NI",
|
||||||
|
"NL",
|
||||||
|
"NO",
|
||||||
|
"NP",
|
||||||
|
"NR",
|
||||||
|
"NU",
|
||||||
|
"NZ",
|
||||||
|
"OM",
|
||||||
|
"PA",
|
||||||
|
"PE",
|
||||||
|
"PF",
|
||||||
|
"PG",
|
||||||
|
"PH",
|
||||||
|
"PK",
|
||||||
|
"PL",
|
||||||
|
"PM",
|
||||||
|
"PN",
|
||||||
|
"PR",
|
||||||
|
"PS",
|
||||||
|
"PT",
|
||||||
|
"PW",
|
||||||
|
"PY",
|
||||||
|
"QA",
|
||||||
|
"RE",
|
||||||
|
"RO",
|
||||||
|
"RS",
|
||||||
|
"RU",
|
||||||
|
"RW",
|
||||||
|
"SA",
|
||||||
|
"SB",
|
||||||
|
"SC",
|
||||||
|
"SD",
|
||||||
|
"SE",
|
||||||
|
"SG",
|
||||||
|
"SH",
|
||||||
|
"SI",
|
||||||
|
"SJ",
|
||||||
|
"SK",
|
||||||
|
"SL",
|
||||||
|
"SM",
|
||||||
|
"SN",
|
||||||
|
"SO",
|
||||||
|
"SR",
|
||||||
|
"SS",
|
||||||
|
"ST",
|
||||||
|
"SV",
|
||||||
|
"SX",
|
||||||
|
"SY",
|
||||||
|
"SZ",
|
||||||
|
"TC",
|
||||||
|
"TD",
|
||||||
|
"TF",
|
||||||
|
"TG",
|
||||||
|
"TH",
|
||||||
|
"TJ",
|
||||||
|
"TK",
|
||||||
|
"TL",
|
||||||
|
"TM",
|
||||||
|
"TN",
|
||||||
|
"TO",
|
||||||
|
"TR",
|
||||||
|
"TT",
|
||||||
|
"TV",
|
||||||
|
"TW",
|
||||||
|
"TZ",
|
||||||
|
"UA",
|
||||||
|
"UG",
|
||||||
|
"UM",
|
||||||
|
"US",
|
||||||
|
"UY",
|
||||||
|
"UZ",
|
||||||
|
"VA",
|
||||||
|
"VC",
|
||||||
|
"VE",
|
||||||
|
"VG",
|
||||||
|
"VI",
|
||||||
|
"VN",
|
||||||
|
"VU",
|
||||||
|
"WF",
|
||||||
|
"WS",
|
||||||
|
"YE",
|
||||||
|
"YT",
|
||||||
|
"ZA",
|
||||||
|
"ZM",
|
||||||
|
"ZW",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const countryDisplayNames =
|
||||||
|
Intl && "DisplayNames" in Intl
|
||||||
|
? new Intl.DisplayNames(undefined, {
|
||||||
|
type: "region",
|
||||||
|
fallback: "code",
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
export const createCountryListEl = () => {
|
||||||
|
const list = document.createElement("datalist");
|
||||||
|
list.id = "countries";
|
||||||
|
for (const country of countries) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = country;
|
||||||
|
option.innerText = countryDisplayNames
|
||||||
|
? countryDisplayNames.of(country)!
|
||||||
|
: country;
|
||||||
|
list.appendChild(option);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
@ -158,13 +158,23 @@ export const currencies = [
|
|||||||
"ZWL",
|
"ZWL",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const currencyDisplayNames =
|
||||||
|
Intl && "DisplayNames" in Intl
|
||||||
|
? new Intl.DisplayNames(undefined, {
|
||||||
|
type: "currency",
|
||||||
|
fallback: "code",
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
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 currencies) {
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.value = currency;
|
option.value = currency;
|
||||||
option.innerHTML = currency;
|
option.innerText = currencyDisplayNames
|
||||||
|
? currencyDisplayNames.of(currency)!
|
||||||
|
: currency;
|
||||||
list.appendChild(option);
|
list.appendChild(option);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { TextFieldBase } from "@material/mwc-textfield/mwc-textfield-base";
|
import { TextFieldBase } from "@material/mwc-textfield/mwc-textfield-base";
|
||||||
import { styles } from "@material/mwc-textfield/mwc-textfield.css";
|
import { styles } from "@material/mwc-textfield/mwc-textfield.css";
|
||||||
import { TemplateResult, html, PropertyValues, css } from "lit";
|
import { TemplateResult, html, PropertyValues, css } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property, query } from "lit/decorators";
|
||||||
|
|
||||||
@customElement("ha-textfield")
|
@customElement("ha-textfield")
|
||||||
export class HaTextField extends TextFieldBase {
|
export class HaTextField extends TextFieldBase {
|
||||||
@ -17,6 +17,8 @@ export class HaTextField extends TextFieldBase {
|
|||||||
|
|
||||||
@property() public autocomplete?: string;
|
@property() public autocomplete?: string;
|
||||||
|
|
||||||
|
@query("input") public formElement!: HTMLInputElement;
|
||||||
|
|
||||||
override updated(changedProperties: PropertyValues) {
|
override updated(changedProperties: PropertyValues) {
|
||||||
super.updated(changedProperties);
|
super.updated(changedProperties);
|
||||||
if (
|
if (
|
||||||
|
15
src/components/language-datalist.ts
Normal file
15
src/components/language-datalist.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
export const createLanguageListEl = (hass: HomeAssistant) => {
|
||||||
|
const list = document.createElement("datalist");
|
||||||
|
list.id = "languages";
|
||||||
|
for (const [language, metadata] of Object.entries(
|
||||||
|
hass.translationMetadata.translations
|
||||||
|
)) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = language;
|
||||||
|
option.innerText = metadata.nativeName;
|
||||||
|
list.appendChild(option);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
@ -133,11 +133,11 @@ export class HaMap extends ReactiveElement {
|
|||||||
if (
|
if (
|
||||||
!changedProps.has("darkMode") &&
|
!changedProps.has("darkMode") &&
|
||||||
(!changedProps.has("hass") ||
|
(!changedProps.has("hass") ||
|
||||||
(oldHass && oldHass.themes.darkMode === this.hass.themes.darkMode))
|
(oldHass && oldHass.themes?.darkMode === this.hass.themes?.darkMode))
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const darkMode = this.darkMode ?? this.hass.themes.darkMode;
|
const darkMode = this.darkMode ?? this.hass.themes?.darkMode;
|
||||||
this.shadowRoot!.getElementById("map")!.classList.toggle("dark", darkMode);
|
this.shadowRoot!.getElementById("map")!.classList.toggle("dark", darkMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ export const createTimezoneListEl = () => {
|
|||||||
Object.keys(timezones).forEach((key) => {
|
Object.keys(timezones).forEach((key) => {
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.value = key;
|
option.value = key;
|
||||||
option.innerHTML = timezones[key];
|
option.innerText = timezones[key];
|
||||||
list.appendChild(option);
|
list.appendChild(option);
|
||||||
});
|
});
|
||||||
return list;
|
return list;
|
||||||
|
@ -11,6 +11,8 @@ export interface ConfigUpdateValues {
|
|||||||
external_url?: string | null;
|
external_url?: string | null;
|
||||||
internal_url?: string | null;
|
internal_url?: string | null;
|
||||||
currency?: string | null;
|
currency?: string | null;
|
||||||
|
country?: string | null;
|
||||||
|
language?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CheckConfigResult {
|
export interface CheckConfigResult {
|
||||||
|
@ -32,4 +32,6 @@ export const demoConfig: HassConfig = {
|
|||||||
internal_url: "http://homeassistant.local:8123",
|
internal_url: "http://homeassistant.local:8123",
|
||||||
external_url: null,
|
external_url: null,
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
|
language: "en",
|
||||||
|
country: "NL",
|
||||||
};
|
};
|
||||||
|
@ -131,21 +131,6 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
|||||||
if (window.innerWidth > 450) {
|
if (window.innerWidth > 450) {
|
||||||
import("./particles");
|
import("./particles");
|
||||||
}
|
}
|
||||||
if (matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
applyThemesOnElement(
|
|
||||||
document.documentElement,
|
|
||||||
{
|
|
||||||
default_theme: "default",
|
|
||||||
default_dark_theme: null,
|
|
||||||
themes: {},
|
|
||||||
darkMode: true,
|
|
||||||
theme: "default",
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
@ -154,10 +139,25 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
|||||||
document.querySelector("html")!.setAttribute("lang", this.language!);
|
document.querySelector("html")!.setAttribute("lang", this.language!);
|
||||||
}
|
}
|
||||||
if (changedProps.has("hass")) {
|
if (changedProps.has("hass")) {
|
||||||
this.hassChanged(
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
this.hass!,
|
this.hassChanged(this.hass!, oldHass);
|
||||||
changedProps.get("hass") as HomeAssistant | undefined
|
if (oldHass?.themes !== this.hass!.themes) {
|
||||||
);
|
if (matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
|
applyThemesOnElement(
|
||||||
|
document.documentElement,
|
||||||
|
{
|
||||||
|
default_theme: "default",
|
||||||
|
default_dark_theme: null,
|
||||||
|
themes: {},
|
||||||
|
darkMode: true,
|
||||||
|
theme: "default",
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
import type { PaperInputElement } from "@polymer/paper-input/paper-input";
|
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
@ -25,6 +23,11 @@ import type { HomeAssistant } from "../types";
|
|||||||
import "../components/ha-radio";
|
import "../components/ha-radio";
|
||||||
import "../components/ha-formfield";
|
import "../components/ha-formfield";
|
||||||
import type { HaRadio } from "../components/ha-radio";
|
import type { HaRadio } from "../components/ha-radio";
|
||||||
|
import type { HaTextField } from "../components/ha-textfield";
|
||||||
|
import "../components/ha-textfield";
|
||||||
|
import { getLocalLanguage } from "../util/common-translation";
|
||||||
|
import { createCountryListEl } from "../components/country-datalist";
|
||||||
|
import { createLanguageListEl } from "../components/language-datalist";
|
||||||
|
|
||||||
const amsterdam: [number, number] = [52.3731339, 4.8903147];
|
const amsterdam: [number, number] = [52.3731339, 4.8903147];
|
||||||
const mql = matchMedia("(prefers-color-scheme: dark)");
|
const mql = matchMedia("(prefers-color-scheme: dark)");
|
||||||
@ -50,6 +53,10 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
|
|
||||||
@state() private _timeZone?: string;
|
@state() private _timeZone?: string;
|
||||||
|
|
||||||
|
@state() private _language?: ConfigUpdateValues["language"];
|
||||||
|
|
||||||
|
@state() private _country?: ConfigUpdateValues["country"];
|
||||||
|
|
||||||
@query("ha-locations-editor", true) private map!: HaLocationsEditor;
|
@query("ha-locations-editor", true) private map!: HaLocationsEditor;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@ -62,15 +69,15 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<paper-input
|
<ha-textfield
|
||||||
.label=${this.onboardingLocalize(
|
.label=${this.onboardingLocalize(
|
||||||
"ui.panel.page-onboarding.core-config.location_name"
|
"ui.panel.page-onboarding.core-config.location_name"
|
||||||
)}
|
)}
|
||||||
name="name"
|
name="name"
|
||||||
.disabled=${this._working}
|
.disabled=${this._working}
|
||||||
.value=${this._nameValue}
|
.value=${this._nameValue}
|
||||||
@value-changed=${this._handleChange}
|
@change=${this._handleChange}
|
||||||
></paper-input>
|
></ha-textfield>
|
||||||
|
|
||||||
<div class="middle-text">
|
<div class="middle-text">
|
||||||
<p>
|
<p>
|
||||||
@ -105,19 +112,42 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<paper-input
|
<ha-textfield
|
||||||
|
class="flex"
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.core.section.core.core_config.country"
|
||||||
|
)}
|
||||||
|
name="country"
|
||||||
|
.disabled=${this._working}
|
||||||
|
.value=${this._countryValue}
|
||||||
|
@change=${this._handleChange}
|
||||||
|
></ha-textfield>
|
||||||
|
|
||||||
|
<ha-textfield
|
||||||
|
class="flex"
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.core.section.core.core_config.language"
|
||||||
|
)}
|
||||||
|
name="language"
|
||||||
|
.disabled=${this._working}
|
||||||
|
.value=${this._languageValue}
|
||||||
|
@change=${this._handleChange}
|
||||||
|
></ha-textfield>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ha-textfield
|
||||||
class="flex"
|
class="flex"
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.core.section.core.core_config.time_zone"
|
"ui.panel.config.core.section.core.core_config.time_zone"
|
||||||
)}
|
)}
|
||||||
name="timeZone"
|
name="timeZone"
|
||||||
list="timezones"
|
|
||||||
.disabled=${this._working}
|
.disabled=${this._working}
|
||||||
.value=${this._timeZoneValue}
|
.value=${this._timeZoneValue}
|
||||||
@value-changed=${this._handleChange}
|
@change=${this._handleChange}
|
||||||
></paper-input>
|
></ha-textfield>
|
||||||
|
|
||||||
<paper-input
|
<ha-textfield
|
||||||
class="flex"
|
class="flex"
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.core.section.core.core_config.elevation"
|
"ui.panel.config.core.section.core.core_config.elevation"
|
||||||
@ -126,14 +156,14 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
type="number"
|
type="number"
|
||||||
.disabled=${this._working}
|
.disabled=${this._working}
|
||||||
.value=${this._elevationValue}
|
.value=${this._elevationValue}
|
||||||
@value-changed=${this._handleChange}
|
@change=${this._handleChange}
|
||||||
>
|
>
|
||||||
<span slot="suffix">
|
<span slot="suffix">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.core.section.core.core_config.elevation_meters"
|
"ui.panel.config.core.section.core.core_config.elevation_meters"
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</paper-input>
|
</ha-textfield>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -197,17 +227,16 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<paper-input
|
<ha-textfield
|
||||||
class="flex"
|
class="flex"
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.core.section.core.core_config.currency"
|
"ui.panel.config.core.section.core.core_config.currency"
|
||||||
)}
|
)}
|
||||||
name="currency"
|
name="currency"
|
||||||
list="currencies"
|
|
||||||
.disabled=${this._working}
|
.disabled=${this._working}
|
||||||
.value=${this._currencyValue}
|
.value=${this._currencyValue}
|
||||||
@value-changed=${this._handleChange}
|
@change=${this._handleChange}
|
||||||
></paper-input>
|
></ha-textfield>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -224,7 +253,7 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => this.shadowRoot!.querySelector("paper-input")!.focus(),
|
() => this.shadowRoot!.querySelector("ha-textfield")!.focus(),
|
||||||
100
|
100
|
||||||
);
|
);
|
||||||
this.addEventListener("keypress", (ev) => {
|
this.addEventListener("keypress", (ev) => {
|
||||||
@ -234,13 +263,35 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
});
|
});
|
||||||
const tzInput = this.shadowRoot!.querySelector(
|
const tzInput = this.shadowRoot!.querySelector(
|
||||||
"[name=timeZone]"
|
"[name=timeZone]"
|
||||||
) as PaperInputElement;
|
) as HaTextField;
|
||||||
tzInput.inputElement.appendChild(createTimezoneListEl());
|
tzInput.updateComplete.then(() => {
|
||||||
|
tzInput.shadowRoot!.appendChild(createTimezoneListEl());
|
||||||
|
tzInput.formElement.setAttribute("list", "timezones");
|
||||||
|
});
|
||||||
|
|
||||||
const cInput = this.shadowRoot!.querySelector(
|
const curInput = this.shadowRoot!.querySelector(
|
||||||
"[name=currency]"
|
"[name=currency]"
|
||||||
) as PaperInputElement;
|
) as HaTextField;
|
||||||
cInput.inputElement.appendChild(createCurrencyListEl());
|
curInput.updateComplete.then(() => {
|
||||||
|
curInput.shadowRoot!.appendChild(createCurrencyListEl());
|
||||||
|
curInput.formElement.setAttribute("list", "currencies");
|
||||||
|
});
|
||||||
|
|
||||||
|
const countryInput = this.shadowRoot!.querySelector(
|
||||||
|
"[name=country]"
|
||||||
|
) as HaTextField;
|
||||||
|
countryInput.updateComplete.then(() => {
|
||||||
|
countryInput.shadowRoot!.appendChild(createCountryListEl());
|
||||||
|
countryInput.formElement.setAttribute("list", "countries");
|
||||||
|
});
|
||||||
|
|
||||||
|
const langInput = this.shadowRoot!.querySelector(
|
||||||
|
"[name=language]"
|
||||||
|
) as HaTextField;
|
||||||
|
langInput.updateComplete.then(() => {
|
||||||
|
langInput.shadowRoot!.appendChild(createLanguageListEl(this.hass));
|
||||||
|
langInput.formElement.setAttribute("list", "languages");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _nameValue() {
|
private get _nameValue() {
|
||||||
@ -260,7 +311,15 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _timeZoneValue() {
|
private get _timeZoneValue() {
|
||||||
return this._timeZone;
|
return this._timeZone || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _languageValue() {
|
||||||
|
return this._language || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _countryValue() {
|
||||||
|
return this._country || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _unitSystemValue() {
|
private get _unitSystemValue() {
|
||||||
@ -283,7 +342,7 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private _handleChange(ev: PolymerChangedEvent<string>) {
|
private _handleChange(ev: PolymerChangedEvent<string>) {
|
||||||
const target = ev.currentTarget as PaperInputElement;
|
const target = ev.currentTarget as HaTextField;
|
||||||
|
|
||||||
let value = target.value;
|
let value = target.value;
|
||||||
|
|
||||||
@ -335,6 +394,10 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
if (values.currency) {
|
if (values.currency) {
|
||||||
this._currency = values.currency;
|
this._currency = values.currency;
|
||||||
}
|
}
|
||||||
|
if (values.country) {
|
||||||
|
this._country = values.country;
|
||||||
|
}
|
||||||
|
this._language = getLocalLanguage();
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
alert(`Failed to detect location information: ${err.message}`);
|
alert(`Failed to detect location information: ${err.message}`);
|
||||||
} finally {
|
} finally {
|
||||||
@ -355,6 +418,8 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
unit_system: this._unitSystemValue,
|
unit_system: this._unitSystemValue,
|
||||||
time_zone: this._timeZoneValue || "UTC",
|
time_zone: this._timeZoneValue || "UTC",
|
||||||
currency: this._currencyValue || "EUR",
|
currency: this._currencyValue || "EUR",
|
||||||
|
country: this._countryValue,
|
||||||
|
language: this._languageValue,
|
||||||
});
|
});
|
||||||
const result = await onboardCoreConfigStep(this.hass);
|
const result = await onboardCoreConfigStep(this.hass);
|
||||||
fireEvent(this, "onboarding-step", {
|
fireEvent(this, "onboarding-step", {
|
||||||
@ -380,6 +445,10 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ha-textfield {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
ha-locations-editor {
|
ha-locations-editor {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
@ -389,7 +458,11 @@ class OnboardingCoreConfig extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.middle-text {
|
.middle-text {
|
||||||
margin: 24px 0;
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row > * {
|
.row > * {
|
||||||
|
@ -8,7 +8,14 @@ import { stopPropagation } from "../../../common/dom/stop_propagation";
|
|||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
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 { currencies } from "../../../components/currency-datalist";
|
import {
|
||||||
|
countries,
|
||||||
|
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";
|
||||||
@ -36,6 +43,10 @@ class HaConfigSectionGeneral extends LitElement {
|
|||||||
|
|
||||||
@state() private _currency?: string;
|
@state() private _currency?: string;
|
||||||
|
|
||||||
|
@state() private _language?: string;
|
||||||
|
|
||||||
|
@state() private _country?: string | null;
|
||||||
|
|
||||||
@state() private _name?: string;
|
@state() private _name?: string;
|
||||||
|
|
||||||
@state() private _elevation?: number;
|
@state() private _elevation?: number;
|
||||||
@ -179,7 +190,9 @@ class HaConfigSectionGeneral extends LitElement {
|
|||||||
${currencies.map(
|
${currencies.map(
|
||||||
(currency) =>
|
(currency) =>
|
||||||
html`<mwc-list-item .value=${currency}
|
html`<mwc-list-item .value=${currency}
|
||||||
>${currency}</mwc-list-item
|
>${currencyDisplayNames
|
||||||
|
? currencyDisplayNames.of(currency)
|
||||||
|
: currency}</mwc-list-item
|
||||||
>`
|
>`
|
||||||
)}</ha-select
|
)}</ha-select
|
||||||
>
|
>
|
||||||
@ -193,6 +206,48 @@ class HaConfigSectionGeneral extends LitElement {
|
|||||||
)}</a
|
)}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<ha-select
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.core.section.core.core_config.country"
|
||||||
|
)}
|
||||||
|
name="country"
|
||||||
|
fixedMenuPosition
|
||||||
|
naturalMenuWidth
|
||||||
|
.disabled=${disabled}
|
||||||
|
.value=${this._country}
|
||||||
|
@closed=${stopPropagation}
|
||||||
|
@change=${this._handleChange}
|
||||||
|
>
|
||||||
|
${countries.map(
|
||||||
|
(country) =>
|
||||||
|
html`<mwc-list-item .value=${country}
|
||||||
|
>${countryDisplayNames
|
||||||
|
? countryDisplayNames.of(country)
|
||||||
|
: country}</mwc-list-item
|
||||||
|
>`
|
||||||
|
)}</ha-select
|
||||||
|
>
|
||||||
|
<ha-select
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.core.section.core.core_config.language"
|
||||||
|
)}
|
||||||
|
name="language"
|
||||||
|
fixedMenuPosition
|
||||||
|
naturalMenuWidth
|
||||||
|
.disabled=${disabled}
|
||||||
|
.value=${this._language}
|
||||||
|
@closed=${stopPropagation}
|
||||||
|
@change=${this._handleChange}
|
||||||
|
>
|
||||||
|
${Object.entries(
|
||||||
|
this.hass.translationMetadata.translations
|
||||||
|
).map(
|
||||||
|
([code, metadata]) =>
|
||||||
|
html`<mwc-list-item .value=${code}
|
||||||
|
>${metadata.nativeName}</mwc-list-item
|
||||||
|
>`
|
||||||
|
)}</ha-select
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
${this.narrow
|
${this.narrow
|
||||||
? html`
|
? html`
|
||||||
@ -240,6 +295,8 @@ class HaConfigSectionGeneral extends LitElement {
|
|||||||
? "metric"
|
? "metric"
|
||||||
: "us_customary";
|
: "us_customary";
|
||||||
this._currency = this.hass.config.currency;
|
this._currency = this.hass.config.currency;
|
||||||
|
this._country = this.hass.config.country;
|
||||||
|
this._language = this.hass.config.language;
|
||||||
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;
|
||||||
@ -291,6 +348,8 @@ class HaConfigSectionGeneral extends LitElement {
|
|||||||
unit_system: this._unitSystem,
|
unit_system: this._unitSystem,
|
||||||
time_zone: this._timeZone,
|
time_zone: this._timeZone,
|
||||||
location_name: this._name,
|
location_name: this._name,
|
||||||
|
language: this._language,
|
||||||
|
country: this._country,
|
||||||
...locationConfig,
|
...locationConfig,
|
||||||
});
|
});
|
||||||
button.actionSuccess();
|
button.actionSuccess();
|
||||||
|
@ -1654,6 +1654,8 @@
|
|||||||
"elevation": "Elevation",
|
"elevation": "Elevation",
|
||||||
"elevation_meters": "meters",
|
"elevation_meters": "meters",
|
||||||
"time_zone": "Time Zone",
|
"time_zone": "Time Zone",
|
||||||
|
"language": "Language",
|
||||||
|
"country": "Country",
|
||||||
"unit_system": "Unit System",
|
"unit_system": "Unit System",
|
||||||
"unit_system_us_customary": "US customary",
|
"unit_system_us_customary": "US customary",
|
||||||
"unit_system_metric": "Metric",
|
"unit_system_metric": "Metric",
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -9419,7 +9419,7 @@ fsevents@^1.2.7:
|
|||||||
gulp-zopfli-green: ^3.0.1
|
gulp-zopfli-green: ^3.0.1
|
||||||
hammerjs: ^2.0.8
|
hammerjs: ^2.0.8
|
||||||
hls.js: ^1.2.5
|
hls.js: ^1.2.5
|
||||||
home-assistant-js-websocket: ^8.0.0
|
home-assistant-js-websocket: ^8.0.1
|
||||||
html-minifier: ^4.0.0
|
html-minifier: ^4.0.0
|
||||||
husky: ^8.0.1
|
husky: ^8.0.1
|
||||||
idb-keyval: ^5.1.3
|
idb-keyval: ^5.1.3
|
||||||
@ -9492,10 +9492,10 @@ fsevents@^1.2.7:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"home-assistant-js-websocket@npm:^8.0.0":
|
"home-assistant-js-websocket@npm:^8.0.1":
|
||||||
version: 8.0.0
|
version: 8.0.1
|
||||||
resolution: "home-assistant-js-websocket@npm:8.0.0"
|
resolution: "home-assistant-js-websocket@npm:8.0.1"
|
||||||
checksum: 55fecd70e10ab3c74b4c6c78dbf11d56e22e9799e050096a24c74c3844c48d458f42f43c353b9b050d49acecb323a137df8667428206a07a426f030d339a42e7
|
checksum: e8b2204d58b2b1fbdf26ca1ad196fcc02ec5d18e6d867179f27246a9f2d4fe5f91de9dbbe7b82806c19dcb0af0e2b77fb48d393668b5c8c0844c201a16832023
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user