From 27884b9a54ac52505ca854a4dd44fa9806397112 Mon Sep 17 00:00:00 2001 From: Zack Barett Date: Wed, 27 Apr 2022 00:12:44 -0500 Subject: [PATCH] Move Restart to Overflow and yaml config advanced (#12446) * Move Restart to Overflow and yaml config advanced * Move around YAML Config page * Move to developer tools * Make card actions * Update Translations --- .../core/ha-config-system-navigation.ts | 34 +++ src/panels/config/ha-panel-config.ts | 13 - .../ha-config-server-control.ts | 269 ------------------ .../developer-tools/developer-tools-router.ts | 4 + .../ha-panel-developer-tools.ts | 3 + .../developer-yaml-config.ts | 240 ++++++++++++++++ src/translations/en.json | 192 +++++++------ 7 files changed, 379 insertions(+), 376 deletions(-) delete mode 100644 src/panels/config/server_control/ha-config-server-control.ts create mode 100644 src/panels/developer-tools/yaml_configuration/developer-yaml-config.ts diff --git a/src/panels/config/core/ha-config-system-navigation.ts b/src/panels/config/core/ha-config-system-navigation.ts index ad5edab63f..b9f9ff955a 100644 --- a/src/panels/config/core/ha-config-system-navigation.ts +++ b/src/panels/config/core/ha-config-system-navigation.ts @@ -1,9 +1,12 @@ +import { ActionDetail } from "@material/mwc-list"; +import { mdiDotsVertical } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { canShowPage } from "../../../common/config/can_show_page"; import "../../../components/ha-card"; import "../../../components/ha-navigation-list"; import { CloudStatus } from "../../../data/cloud"; +import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import "../../../layouts/hass-subpage"; import { haStyle } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; @@ -38,6 +41,22 @@ class HaConfigSystemNavigation extends LitElement { back-path="/config" .header=${this.hass.localize("ui.panel.config.dashboard.system.main")} > + + + + ${this.hass.localize( + "ui.panel.config.system_dashboard.restart_homeassistant" + )} + + ) { + switch (ev.detail.index) { + case 0: + showConfirmationDialog(this, { + text: this.hass.localize( + "ui.panel.config.system_dashboard.confirm_restart" + ), + confirm: () => { + this.hass.callService("homeassistant", "restart"); + }, + }); + break; + } + } + static get styles(): CSSResultGroup { return [ haStyle, diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts index 360d7b8ea7..5c7b11a2fc 100644 --- a/src/panels/config/ha-panel-config.ts +++ b/src/panels/config/ha-panel-config.ts @@ -20,7 +20,6 @@ import { mdiPuzzle, mdiRobot, mdiScriptText, - mdiServer, mdiShape, mdiSofa, mdiTools, @@ -255,14 +254,6 @@ export const configSections: { [name: string]: PageNavigation[] } = { }, ], general: [ - { - component: "server_control", - path: "/config/server_control", - translationKey: "ui.panel.config.server_control.caption", - iconPath: mdiServer, - iconColor: "#4A5963", - core: true, - }, { path: "/config/updates", translationKey: "ui.panel.config.updates.caption", @@ -445,10 +436,6 @@ class HaPanelConfig extends HassRouterPage { tag: "ha-config-helpers", load: () => import("./helpers/ha-config-helpers"), }, - server_control: { - tag: "ha-config-server-control", - load: () => import("./server_control/ha-config-server-control"), - }, storage: { tag: "ha-config-section-storage", load: () => import("./storage/ha-config-section-storage"), diff --git a/src/panels/config/server_control/ha-config-server-control.ts b/src/panels/config/server_control/ha-config-server-control.ts deleted file mode 100644 index 9bf4a8a728..0000000000 --- a/src/panels/config/server_control/ha-config-server-control.ts +++ /dev/null @@ -1,269 +0,0 @@ -import "@material/mwc-button"; -import "@polymer/app-layout/app-header/app-header"; -import "@polymer/app-layout/app-toolbar/app-toolbar"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { componentsWithService } from "../../../common/config/components_with_service"; -import "../../../components/buttons/ha-call-service-button"; -import "../../../components/ha-card"; -import { checkCoreConfig } from "../../../data/core"; -import { domainToName } from "../../../data/integration"; -import "../../../layouts/hass-subpage"; -import "../../../layouts/hass-tabs-subpage"; -import { haStyle } from "../../../resources/styles"; -import { HomeAssistant, Route } from "../../../types"; -import "../ha-config-section"; - -@customElement("ha-config-server-control") -export class HaConfigServerControl extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property({ type: Boolean }) public isWide!: boolean; - - @property({ type: Boolean }) public narrow!: boolean; - - @property({ attribute: false }) public route!: Route; - - @property({ type: Boolean }) public showAdvanced!: boolean; - - @state() private _validating = false; - - @state() private _reloadableDomains: string[] = []; - - private _validateLog = ""; - - private _isValid: boolean | null = null; - - protected updated(changedProperties) { - const oldHass = changedProperties.get("hass"); - if ( - changedProperties.has("hass") && - (!oldHass || oldHass.config.components !== this.hass.config.components) - ) { - this._reloadableDomains = componentsWithService( - this.hass, - "reload" - ).sort(); - } - } - - protected render(): TemplateResult { - return html` - -
- ${this.showAdvanced - ? html` - -
- ${this.hass.localize( - "ui.panel.config.server_control.section.validation.introduction" - )} - ${!this._validateLog - ? html` -
- ${!this._validating - ? html` - ${this._isValid - ? html`
- ${this.hass.localize( - "ui.panel.config.server_control.section.validation.valid" - )} -
` - : ""} - - ${this.hass.localize( - "ui.panel.config.server_control.section.validation.check_config" - )} - - ` - : html` - - `} -
- ` - : html` -
- - ${this.hass.localize( - "ui.panel.config.server_control.section.validation.invalid" - )} - - - ${this.hass.localize( - "ui.panel.config.server_control.section.validation.check_config" - )} - -
-
- ${this._validateLog} -
- `} -
-
- ` - : ""} - - -
- ${this.hass.localize( - "ui.panel.config.server_control.section.server_management.introduction" - )} -
-
- ${this.hass.localize( - "ui.panel.config.server_control.section.server_management.restart" - )} - -
-
- - ${this.showAdvanced - ? html` - -
- ${this.hass.localize( - "ui.panel.config.server_control.section.reloading.introduction" - )} -
-
- ${this.hass.localize( - "ui.panel.config.server_control.section.reloading.core" - )} - -
- ${this._reloadableDomains.map( - (domain) => - html` -
- ${this.hass.localize( - `ui.panel.config.server_control.section.reloading.${domain}` - ) || - this.hass.localize( - "ui.panel.config.server_control.section.reloading.reload", - "domain", - domainToName(this.hass.localize, domain) - )} - -
- ` - )} -
- ` - : ""} -
-
- `; - } - - private async _validateConfig() { - this._validating = true; - this._validateLog = ""; - this._isValid = null; - - const configCheck = await checkCoreConfig(this.hass); - this._validating = false; - this._isValid = configCheck.result === "valid"; - - if (configCheck.errors) { - this._validateLog = configCheck.errors; - } - } - - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - .validate-container { - height: 140px; - } - - .validate-result { - color: var(--success-color); - font-weight: 500; - margin-bottom: 1em; - } - - .config-invalid { - margin: 1em 0; - } - - .config-invalid .text { - color: var(--error-color); - font-weight: 500; - } - - .config-invalid mwc-button { - float: right; - } - - .validate-log { - white-space: pre-line; - direction: ltr; - } - - .content { - padding: 28px 20px 0; - max-width: 1040px; - margin: 0 auto; - } - - ha-card { - margin-top: 24px; - } - `, - ]; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-config-server-control": HaConfigServerControl; - } -} diff --git a/src/panels/developer-tools/developer-tools-router.ts b/src/panels/developer-tools/developer-tools-router.ts index 308a1cc348..7fc389ae84 100644 --- a/src/panels/developer-tools/developer-tools-router.ts +++ b/src/panels/developer-tools/developer-tools-router.ts @@ -41,6 +41,10 @@ class DeveloperToolsRouter extends HassRouterPage { tag: "developer-tools-statistics", load: () => import("./statistics/developer-tools-statistics"), }, + yaml: { + tag: "developer-yaml-config", + load: () => import("./yaml_configuration/developer-yaml-config"), + }, }, }; diff --git a/src/panels/developer-tools/ha-panel-developer-tools.ts b/src/panels/developer-tools/ha-panel-developer-tools.ts index a3c1c7a897..cc8e80500c 100644 --- a/src/panels/developer-tools/ha-panel-developer-tools.ts +++ b/src/panels/developer-tools/ha-panel-developer-tools.ts @@ -67,6 +67,9 @@ class PanelDeveloperTools extends LitElement { "ui.panel.developer-tools.tabs.statistics.title" )} + + ${this.hass.localize("ui.panel.developer-tools.tabs.yaml.title")} + + +
+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.validation.introduction" + )} + ${!this._validateLog + ? html` +
+ ${!this._validating + ? html` + ${this._isValid + ? html`
+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.validation.valid" + )} +
` + : ""} + ` + : html` + + `} +
+ ` + : html` +
+ + ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.validation.invalid" + )} + + + ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.validation.check_config" + )} + +
+
+ ${this._validateLog} +
+ `} +
+
+ + ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.validation.check_config" + )} + + + ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.server_management.restart" + )} + +
+
+ +
+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.reloading.introduction" + )} +
+
+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.reloading.core" + )} + +
+ ${this._reloadableDomains.map( + (domain) => + html` +
+ ${this.hass.localize( + `ui.panel.developer-tools.tabs.yaml.section.reloading.${domain}` + ) || + this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.reloading.reload", + "domain", + domainToName(this.hass.localize, domain) + )} + +
+ ` + )} +
+ + `; + } + + private async _validateConfig() { + this._validating = true; + this._validateLog = ""; + this._isValid = null; + + const configCheck = await checkCoreConfig(this.hass); + this._validating = false; + this._isValid = configCheck.result === "valid"; + + if (configCheck.errors) { + this._validateLog = configCheck.errors; + } + } + + private _restart() { + showConfirmationDialog(this, { + text: this.hass.localize( + "ui.panel.developer-tools.tabs.yaml.section.server_management.confirm_restart" + ), + confirmText: this.hass!.localize("ui.common.leave"), + dismissText: this.hass!.localize("ui.common.stay"), + confirm: () => { + this.hass.callService("homeassistant", "restart"); + }, + }); + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + .validate-container { + height: 140px; + } + + .validate-result { + color: var(--success-color); + font-weight: 500; + margin-bottom: 1em; + } + + .config-invalid { + margin: 1em 0; + } + + .config-invalid .text { + color: var(--error-color); + font-weight: 500; + } + + .validate-log { + white-space: pre-line; + direction: ltr; + } + + .content { + padding: 28px 20px 0; + max-width: 1040px; + margin: 0 auto; + } + + ha-card { + margin-top: 24px; + } + + .card-actions { + display: flex; + justify-content: space-between; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "developer-yaml-config": DeveloperYamlConfig; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index 412bbd4272..fcc5dab6be 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -625,43 +625,43 @@ "quick-bar": { "commands": { "reload": { - "reload": "[%key:ui::panel::config::server_control::section::reloading::reload%]", - "core": "[%key:ui::panel::config::server_control::section::reloading::core%]", - "group": "[%key:ui::panel::config::server_control::section::reloading::group%]", - "automation": "[%key:ui::panel::config::server_control::section::reloading::automation%]", - "script": "[%key:ui::panel::config::server_control::section::reloading::script%]", - "scene": "[%key:ui::panel::config::server_control::section::reloading::scene%]", - "person": "[%key:ui::panel::config::server_control::section::reloading::person%]", - "zone": "[%key:ui::panel::config::server_control::section::reloading::zone%]", - "input_boolean": "[%key:ui::panel::config::server_control::section::reloading::input_boolean%]", - "input_text": "[%key:ui::panel::config::server_control::section::reloading::input_text%]", - "input_number": "[%key:ui::panel::config::server_control::section::reloading::input_number%]", - "input_datetime": "[%key:ui::panel::config::server_control::section::reloading::input_datetime%]", - "input_select": "[%key:ui::panel::config::server_control::section::reloading::input_select%]", - "template": "[%key:ui::panel::config::server_control::section::reloading::template%]", - "universal": "[%key:ui::panel::config::server_control::section::reloading::universal%]", - "rest": "[%key:ui::panel::config::server_control::section::reloading::rest%]", - "command_line": "[%key:ui::panel::config::server_control::section::reloading::command_line%]", - "filter": "[%key:ui::panel::config::server_control::section::reloading::filter%]", - "statistics": "[%key:ui::panel::config::server_control::section::reloading::statistics%]", - "generic": "[%key:ui::panel::config::server_control::section::reloading::generic%]", - "generic_thermostat": "[%key:ui::panel::config::server_control::section::reloading::generic_thermostat%]", - "homekit": "[%key:ui::panel::config::server_control::section::reloading::homekit%]", - "min_max": "[%key:ui::panel::config::server_control::section::reloading::min_max%]", - "history_stats": "[%key:ui::panel::config::server_control::section::reloading::history_stats%]", - "trend": "[%key:ui::panel::config::server_control::section::reloading::trend%]", - "ping": "[%key:ui::panel::config::server_control::section::reloading::ping%]", - "filesize": "[%key:ui::panel::config::server_control::section::reloading::filesize%]", - "telegram": "[%key:ui::panel::config::server_control::section::reloading::telegram%]", - "smtp": "[%key:ui::panel::config::server_control::section::reloading::smtp%]", - "mqtt": "[%key:ui::panel::config::server_control::section::reloading::mqtt%]", - "rpi_gpio": "[%key:ui::panel::config::server_control::section::reloading::rpi_gpio%]", - "themes": "[%key:ui::panel::config::server_control::section::reloading::themes%]" + "reload": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::reload%]", + "core": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::core%]", + "group": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::group%]", + "automation": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::automation%]", + "script": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::script%]", + "scene": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::scene%]", + "person": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::person%]", + "zone": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::zone%]", + "input_boolean": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::input_boolean%]", + "input_text": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::input_text%]", + "input_number": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::input_number%]", + "input_datetime": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::input_datetime%]", + "input_select": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::input_select%]", + "template": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::template%]", + "universal": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::universal%]", + "rest": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::rest%]", + "command_line": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::command_line%]", + "filter": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::filter%]", + "statistics": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::statistics%]", + "generic": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::generic%]", + "generic_thermostat": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::generic_thermostat%]", + "homekit": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::homekit%]", + "min_max": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::min_max%]", + "history_stats": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::history_stats%]", + "trend": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::trend%]", + "ping": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::ping%]", + "filesize": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::filesize%]", + "telegram": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::telegram%]", + "smtp": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::smtp%]", + "mqtt": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::mqtt%]", + "rpi_gpio": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::rpi_gpio%]", + "themes": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::themes%]" }, "server_control": { "perform_action": "{action} server", - "restart": "[%key:ui::panel::config::server_control::section::server_management::restart%]", - "stop": "[%key:ui::panel::config::server_control::section::server_management::stop%]" + "restart": "[%key:ui::panel::developer-tools::tabs::yaml::section::server_management::restart%]", + "stop": "[%key:ui::panel::developer-tools::tabs::yaml::section::server_management::stop%]" }, "types": { "reload": "Reload", @@ -687,7 +687,7 @@ "users": "[%key:ui::panel::config::users::caption%]", "info": "[%key:ui::panel::config::info::caption%]", "blueprint": "[%key:ui::panel::config::blueprint::caption%]", - "server_control": "[%key:ui::panel::config::server_control::caption%]" + "server_control": "[%key:ui::panel::developer-tools::tabs::yaml::title%]" } }, "filter_placeholder": "Entity Filter", @@ -1667,65 +1667,6 @@ } } }, - "server_control": { - "caption": "Server Controls", - "description": "Validate and restart the Home Assistant server", - "section": { - "validation": { - "heading": "Configuration validation", - "introduction": "Validate your configuration if you recently made some changes to your configuration and want to make sure that it is all valid.", - "check_config": "Check configuration", - "valid": "Configuration valid!", - "invalid": "Configuration invalid" - }, - "reloading": { - "heading": "YAML configuration reloading", - "introduction": "Some parts of Home Assistant can reload without requiring a restart. Clicking one of the options below will unload their current YAML configuration and load the new one.", - "reload": "{domain}", - "core": "Location & customizations", - "group": "Groups, group entities, and notify services", - "automation": "Automations", - "script": "Scripts", - "scene": "Scenes", - "person": "People", - "zone": "Zones", - "input_boolean": "Input booleans", - "input_button": "Input buttons", - "input_text": "Input texts", - "input_number": "Input numbers", - "input_datetime": "Input date times", - "input_select": "Input selects", - "template": "Template entities", - "universal": "Universal media player entities", - "rest": "Rest entities and notify services", - "command_line": "Command line entities", - "filter": "Filter entities", - "statistics": "Statistics entities", - "generic": "Generic IP camera entities", - "generic_thermostat": "Generic thermostat entities", - "homekit": "HomeKit", - "min_max": "Min/max entities", - "history_stats": "History stats entities", - "trend": "Trend entities", - "ping": "Ping binary sensor entities", - "filesize": "File size entities", - "telegram": "Telegram notify services", - "smtp": "SMTP notify services", - "mqtt": "Manually configured MQTT entities", - "rpi_gpio": "Raspberry Pi GPIO entities", - "timer": "Timers", - "themes": "Themes" - }, - "server_management": { - "heading": "Home Assistant", - "introduction": "Restarting Home Assistant will stop your dashboard and automations. After the reboot, each configuration will be reloaded.", - "restart": "Restart", - "confirm_restart": "Are you sure you want to restart Home Assistant?", - "stop": "Stop", - "confirm_stop": "Are you sure you want to stop Home Assistant?" - } - } - }, "automation": { "caption": "Automations", "description": "Create custom behavior rules for your home", @@ -3221,6 +3162,10 @@ "ram_usage": "Memory Usage", "core_stats": "Core Stats", "supervisor_stats": "Supervisor Stats" + }, + "system_dashboard": { + "confirm_restart": "Are you sure you want to restart Home Assistant?", + "restart_homeassistant": "Restart Home Assistant" } }, "lovelace": { @@ -4200,6 +4145,65 @@ } }, "adjust_sum": "Adjust sum" + }, + "yaml": { + "title": "YAML Configuration", + "section": { + "validation": { + "heading": "Configuration validation", + "introduction": "Validate your configuration if you recently made some changes to your configuration and want to make sure that it is all valid.", + "check_config": "Check configuration", + "valid": "Configuration valid!", + "invalid": "Configuration invalid" + }, + "reloading": { + "heading": "YAML configuration reloading", + "introduction": "Some parts of Home Assistant can reload without requiring a restart. Clicking one of the options below will unload their current YAML configuration and load the new one.", + "reload": "{domain}", + "core": "Location & customizations", + "group": "Groups, group entities, and notify services", + "automation": "Automations", + "script": "Scripts", + "scene": "Scenes", + "person": "People", + "zone": "Zones", + "input_boolean": "Input booleans", + "input_button": "Input buttons", + "input_text": "Input texts", + "input_number": "Input numbers", + "input_datetime": "Input date times", + "input_select": "Input selects", + "template": "Template entities", + "universal": "Universal media player entities", + "rest": "Rest entities and notify services", + "command_line": "Command line entities", + "filter": "Filter entities", + "statistics": "Statistics entities", + "generic": "Generic IP camera entities", + "generic_thermostat": "Generic thermostat entities", + "homekit": "HomeKit", + "min_max": "Min/max entities", + "history_stats": "History stats entities", + "trend": "Trend entities", + "ping": "Ping binary sensor entities", + "filesize": "File size entities", + "telegram": "Telegram notify services", + "smtp": "SMTP notify services", + "mqtt": "Manually configured MQTT entities", + "rpi_gpio": "Raspberry Pi GPIO entities", + "timer": "Timers", + "themes": "Themes" + }, + "server_management": { + "heading": "Home Assistant", + "introduction": "Restarting Home Assistant will stop your dashboard and automations. After the reboot, each configuration will be reloaded.", + "restart": "Restart", + "restart_home_assistant": "Restart Home Assistant", + "confirm_restart": "Are you sure you want to restart Home Assistant?", + "stop": "Stop", + "confirm_stop": "Are you sure you want to stop Home Assistant?" + } + } } } },