diff --git a/src/panels/config/core/ha-config-section-general.ts b/src/panels/config/core/ha-config-section-general.ts
new file mode 100644
index 0000000000..97f3552607
--- /dev/null
+++ b/src/panels/config/core/ha-config-section-general.ts
@@ -0,0 +1,313 @@
+import timezones from "google-timezones-json";
+import { css, html, LitElement, TemplateResult } from "lit";
+import { customElement, property, state } from "lit/decorators";
+import { UNIT_C } from "../../../common/const";
+import { stopPropagation } from "../../../common/dom/stop_propagation";
+import { navigate } from "../../../common/navigate";
+import { HaProgressButton } from "../../../components/buttons/ha-progress-button";
+import { currencies } from "../../../components/currency-datalist";
+import "../../../components/ha-formfield";
+import "../../../components/ha-radio";
+import type { HaRadio } from "../../../components/ha-radio";
+import "../../../components/ha-settings-row";
+import { ConfigUpdateValues, saveCoreConfig } from "../../../data/core";
+import { SYMBOL_TO_ISO } from "../../../data/currency";
+import "../../../layouts/hass-subpage";
+import { haStyle } from "../../../resources/styles";
+import type { HomeAssistant } from "../../../types";
+
+@customElement("ha-config-section-general")
+class HaConfigSectionGeneral extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ type: Boolean }) public narrow!: boolean;
+
+ @state() private _submitting = false;
+
+ @state() private _unitSystem?: ConfigUpdateValues["unit_system"];
+
+ @state() private _currency?: string;
+
+ @state() private _name?: string;
+
+ @state() private _elevation?: number;
+
+ @state() private _timeZone?: string;
+
+ protected render(): TemplateResult {
+ const canEdit = ["storage", "default"].includes(
+ this.hass.config.config_source
+ );
+ const disabled = this._submitting || !canEdit;
+ return html`
+
+
+
+
+ ${!canEdit
+ ? html`
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.edit_requires_storage"
+ )}
+
+ `
+ : ""}
+
+
+ ${Object.keys(timezones).map(
+ (tz) =>
+ html`${timezones[tz]}`
+ )}
+
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.elevation_meters"
+ )}
+
+
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.unit_system"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.metric_example"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.unit_system_metric"
+ )}
+
+ `}
+ >
+
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.imperial_example"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.unit_system_imperial"
+ )}
+
+ `}
+ >
+
+
+
+
+
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.edit_location"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.core.section.core.core_config.edit_location_description"
+ )}
+
+ ${this.hass.localize("ui.common.edit")}
+
+
+
+ ${this.hass!.localize("ui.panel.config.zone.detail.update")}
+
+
+
+
+
+ `;
+ }
+
+ protected firstUpdated(): void {
+ this._unitSystem =
+ this.hass.config.unit_system.temperature === UNIT_C
+ ? "metric"
+ : "imperial";
+ this._currency = this.hass.config.currency;
+ this._elevation = this.hass.config.elevation;
+ this._timeZone = this.hass.config.time_zone;
+ this._name = this.hass.config.location_name;
+ }
+
+ private _handleChange(ev) {
+ const target = ev.currentTarget;
+ let value = target.value;
+
+ if (target.name === "currency" && value) {
+ if (value in SYMBOL_TO_ISO) {
+ value = SYMBOL_TO_ISO[value];
+ }
+ }
+
+ this[`_${target.name}`] = value;
+ }
+
+ private _unitSystemChanged(ev: CustomEvent) {
+ this._unitSystem = (ev.target as HaRadio).value as "metric" | "imperial";
+ }
+
+ private async _updateEntry(ev) {
+ const button = ev.target as HaProgressButton;
+ if (button.progress) {
+ return;
+ }
+ button.progress = true;
+
+ try {
+ await saveCoreConfig(this.hass, {
+ currency: this._currency,
+ elevation: Number(this._elevation),
+ unit_system: this._unitSystem,
+ time_zone: this._timeZone,
+ location_name: this._name,
+ });
+ button.actionSuccess();
+ } catch (err: any) {
+ button.actionError();
+ alert(`Error saving config: ${err.message}`);
+ } finally {
+ button.progress = false;
+ }
+ }
+
+ private _editLocation() {
+ navigate("/config/zone");
+ }
+
+ static styles = [
+ haStyle,
+ css`
+ .content {
+ padding: 28px 20px 0;
+ max-width: 1040px;
+ margin: 0 auto;
+ }
+ ha-card {
+ max-width: 500px;
+ margin: 0 auto;
+ height: 100%;
+ justify-content: space-between;
+ flex-direction: column;
+ display: flex;
+ }
+ .card-content {
+ display: flex;
+ justify-content: space-between;
+ flex-direction: column;
+ padding: 16px 16px 0 16px;
+ }
+ .card-actions {
+ text-align: right;
+ height: 48px;
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ margin-top: 16px;
+ }
+ .card-content > * {
+ display: block;
+ margin-top: 16px;
+ }
+ ha-select {
+ display: block;
+ }
+ `,
+ ];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-config-section-general": HaConfigSectionGeneral;
+ }
+}
diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts
index e9e624e7fa..360d7b8ea7 100644
--- a/src/panels/config/ha-panel-config.ts
+++ b/src/panels/config/ha-panel-config.ts
@@ -324,6 +324,13 @@ export const configSections: { [name: string]: PageNavigation[] } = {
iconColor: "#507FfE",
components: ["system_health", "hassio"],
},
+ {
+ path: "/config/general",
+ translationKey: "ui.panel.config.core.caption",
+ iconPath: mdiCog,
+ iconColor: "#653249",
+ core: true,
+ },
],
about: [
{
@@ -462,6 +469,10 @@ class HaPanelConfig extends HassRouterPage {
tag: "ha-config-zone",
load: () => import("./zone/ha-config-zone"),
},
+ general: {
+ tag: "ha-config-section-general",
+ load: () => import("./core/ha-config-section-general"),
+ },
zha: {
tag: "zha-config-dashboard-router",
load: () =>
diff --git a/src/panels/config/zone/dialog-core-zone-detail.ts b/src/panels/config/zone/dialog-core-zone-detail.ts
deleted file mode 100644
index 411be8bf04..0000000000
--- a/src/panels/config/zone/dialog-core-zone-detail.ts
+++ /dev/null
@@ -1,284 +0,0 @@
-import "@material/mwc-button";
-import "@material/mwc-list/mwc-list";
-import "@material/mwc-list/mwc-list-item";
-import timezones from "google-timezones-json";
-import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
-import { customElement, property, state } from "lit/decorators";
-import { UNIT_C } from "../../../common/const";
-import { fireEvent } from "../../../common/dom/fire_event";
-import { stopPropagation } from "../../../common/dom/stop_propagation";
-import { currencies } from "../../../components/currency-datalist";
-import { createCloseHeading } from "../../../components/ha-dialog";
-import "../../../components/ha-formfield";
-import "../../../components/ha-radio";
-import type { HaRadio } from "../../../components/ha-radio";
-import "../../../components/ha-select";
-import "../../../components/ha-textfield";
-import { ConfigUpdateValues, saveCoreConfig } from "../../../data/core";
-import { SYMBOL_TO_ISO } from "../../../data/currency";
-import { haStyleDialog } from "../../../resources/styles";
-import type { HomeAssistant } from "../../../types";
-
-@customElement("dialog-core-zone-detail")
-class DialogZoneDetail extends LitElement {
- @property({ attribute: false }) public hass!: HomeAssistant;
-
- @state() private _submitting = false;
-
- @state() private _open = false;
-
- @state() private _unitSystem?: ConfigUpdateValues["unit_system"];
-
- @state() private _currency?: string;
-
- @state() private _name?: string;
-
- @state() private _elevation?: number;
-
- @state() private _timeZone?: string;
-
- public showDialog(): void {
- this._submitting = false;
- this._unitSystem =
- this.hass.config.unit_system.temperature === UNIT_C
- ? "metric"
- : "imperial";
- this._currency = this.hass.config.currency;
- this._elevation = this.hass.config.elevation;
- this._timeZone = this.hass.config.time_zone;
- this._name = this.hass.config.location_name;
- this._open = true;
- }
-
- public closeDialog(): void {
- this._open = false;
- this._currency = undefined;
- this._elevation = undefined;
- this._timeZone = undefined;
- this._unitSystem = undefined;
- this._name = undefined;
-
- fireEvent(this, "dialog-closed", { dialog: this.localName });
- }
-
- protected render(): TemplateResult {
- const canEdit = ["storage", "default"].includes(
- this.hass.config.config_source
- );
- const disabled = this._submitting || !canEdit;
-
- if (!this._open) {
- return html``;
- }
-
- return html`
-
- ${!canEdit
- ? html`
-
- ${this.hass.localize(
- "ui.panel.config.core.section.core.core_config.edit_requires_storage"
- )}
-
- `
- : ""}
-
-
- ${Object.keys(timezones).map(
- (tz) =>
- html`${timezones[tz]}`
- )}
-
-
-
- ${this.hass.localize(
- "ui.panel.config.core.section.core.core_config.elevation_meters"
- )}
-
-
-
-
- ${this.hass.localize(
- "ui.panel.config.core.section.core.core_config.unit_system"
- )}
-
-
- ${this.hass.localize(
- "ui.panel.config.core.section.core.core_config.metric_example"
- )}
- `}
- >
-
-
-
- ${this.hass.localize(
- "ui.panel.config.core.section.core.core_config.imperial_example"
- )}
- `}
- >
-
-
-
-
-
- ${this.hass!.localize("ui.panel.config.zone.detail.update")}
-
-
- `;
- }
-
- private _handleChange(ev) {
- const target = ev.currentTarget;
- let value = target.value;
-
- if (target.name === "currency" && value) {
- if (value in SYMBOL_TO_ISO) {
- value = SYMBOL_TO_ISO[value];
- }
- }
-
- this[`_${target.name}`] = value;
- }
-
- private _unitSystemChanged(ev: CustomEvent) {
- this._unitSystem = (ev.target as HaRadio).value as "metric" | "imperial";
- }
-
- private async _updateEntry() {
- this._submitting = true;
- try {
- await saveCoreConfig(this.hass, {
- currency: this._currency,
- elevation: Number(this._elevation),
- unit_system: this._unitSystem,
- time_zone: this._timeZone,
- location_name: this._name,
- });
- } catch (err: any) {
- alert(`Error saving config: ${err.message}`);
- } finally {
- this._submitting = false;
- }
-
- this.closeDialog();
- }
-
- static get styles(): CSSResultGroup {
- return [
- haStyleDialog,
- css`
- ha-dialog {
- --mdc-dialog-min-width: 600px;
- }
- @media all and (max-width: 450px), all and (max-height: 500px) {
- ha-dialog {
- --mdc-dialog-min-width: calc(
- 100vw - env(safe-area-inset-right) - env(safe-area-inset-left)
- );
- }
- }
- .card-actions {
- text-align: right;
- }
- ha-dialog > * {
- display: block;
- margin-top: 16px;
- }
- ha-select {
- display: block;
- }
- `,
- ];
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- "dialog-core-zone-detail": DialogZoneDetail;
- }
-}
diff --git a/src/panels/config/zone/ha-config-zone.ts b/src/panels/config/zone/ha-config-zone.ts
index e46ed02abf..cd91aeb472 100644
--- a/src/panels/config/zone/ha-config-zone.ts
+++ b/src/panels/config/zone/ha-config-zone.ts
@@ -46,7 +46,6 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import type { HomeAssistant, Route } from "../../../types";
import "../ha-config-section";
import { configSections } from "../ha-panel-config";
-import { showCoreZoneDetailDialog } from "./show-dialog-core-zone-detail";
import { showZoneDetailDialog } from "./show-dialog-zone-detail";
@customElement("ha-config-zone")
@@ -188,30 +187,26 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
-
- ${stateObject.entity_id === "zone.home"
- ? hass.localize(
- `ui.panel.config.zone.${
- this.narrow
- ? "edit_home_zone_narrow"
- : "edit_home_zone"
- }`
- )
- : hass.localize(
- "ui.panel.config.zone.configured_in_yaml"
- )}
-
+ ${stateObject.entity_id !== "zone.home"
+ ? html`
+
+ ${hass.localize(
+ "ui.panel.config.zone.configured_in_yaml"
+ )}
+
+ `
+ : ""}
`
@@ -397,7 +392,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
});
return;
}
- showCoreZoneDetailDialog(this);
+ navigate("/config/general");
}
private async _createEntry(values: ZoneMutableParams) {
diff --git a/src/panels/config/zone/show-dialog-core-zone-detail.ts b/src/panels/config/zone/show-dialog-core-zone-detail.ts
deleted file mode 100644
index 4bf747169c..0000000000
--- a/src/panels/config/zone/show-dialog-core-zone-detail.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { fireEvent } from "../../../common/dom/fire_event";
-
-export const loadCoreZoneDetailDialog = () =>
- import("./dialog-core-zone-detail");
-
-export const showCoreZoneDetailDialog = (element: HTMLElement): void => {
- fireEvent(element, "show-dialog", {
- dialogTag: "dialog-core-zone-detail",
- dialogImport: loadCoreZoneDetailDialog,
- dialogParams: {},
- });
-};
diff --git a/src/translations/en.json b/src/translations/en.json
index d97778537e..4f4ed026b9 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -314,6 +314,7 @@
"undo": "Undo",
"move": "Move",
"save": "Save",
+ "edit": "Edit",
"submit": "Submit",
"rename": "Rename",
"yes": "Yes",
@@ -1494,7 +1495,9 @@
"metric_example": "Celsius, kilograms",
"find_currency_value": "Find your value",
"save_button": "Save",
- "currency": "Currency"
+ "currency": "Currency",
+ "edit_location": "Edit location",
+ "edit_location_description": "Location can be changed in zone settings"
}
}
}
@@ -2687,6 +2690,7 @@
"create_zone": "Add Zone",
"add_zone": "Add Zone",
"edit_zone": "Edit Zone",
+ "edit_home": "Edit Home",
"confirm_delete": "Are you sure you want to delete this zone?",
"can_not_edit": "Unable to edit zone",
"configured_in_yaml": "Zones configured via configuration.yaml cannot be edited via the UI.",