From 1795fd56b7ee894833d9f1ad83ebd7906d1a5721 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 1 Jun 2021 19:28:03 +0200 Subject: [PATCH 1/8] Don't rotate chart axis labels (#9329) --- src/components/state-history-chart-line.js | 3 +++ src/components/state-history-chart-timeline.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/components/state-history-chart-line.js b/src/components/state-history-chart-line.js index 412ca18e75..dc767fb45c 100644 --- a/src/components/state-history-chart-line.js +++ b/src/components/state-history-chart-line.js @@ -377,7 +377,10 @@ class StateHistoryChartLine extends LocalizeMixin(PolymerElement) { major: { fontStyle: "bold", }, + source: "auto", + sampleSize: 5, autoSkipPadding: 20, + maxRotation: 0, }, }, ], diff --git a/src/components/state-history-chart-timeline.js b/src/components/state-history-chart-timeline.js index 23f0a91e7d..fa29388da3 100644 --- a/src/components/state-history-chart-timeline.js +++ b/src/components/state-history-chart-timeline.js @@ -236,7 +236,9 @@ class StateHistoryChartTimeline extends LocalizeMixin(PolymerElement) { major: { fontStyle: "bold", }, + sampleSize: 5, autoSkipPadding: 50, + maxRotation: 0, }, categoryPercentage: undefined, barPercentage: undefined, From bc5bd3544865e83ded3f6d8ea208fe0688899e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 1 Jun 2021 20:12:54 +0200 Subject: [PATCH 2/8] Filter adapters with information from the Supervisor (#9322) Co-authored-by: Bram Kragten --- src/panels/config/core/ha-config-network.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/panels/config/core/ha-config-network.ts b/src/panels/config/core/ha-config-network.ts index 6793673711..bded44d3d5 100644 --- a/src/panels/config/core/ha-config-network.ts +++ b/src/panels/config/core/ha-config-network.ts @@ -9,13 +9,14 @@ import { } from "lit"; import { customElement, property, state } from "lit/decorators"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; -import "../../../components/ha-network"; import "../../../components/ha-card"; import "../../../components/ha-checkbox"; +import "../../../components/ha-network"; import "../../../components/ha-settings-row"; +import { fetchNetworkInfo } from "../../../data/hassio/network"; import { - NetworkConfig, getNetworkConfig, + NetworkConfig, setNetworkConfig, } from "../../../data/network"; import { haStyle } from "../../../resources/styles"; @@ -73,7 +74,19 @@ class ConfigNetwork extends LitElement { private async _load() { this._error = undefined; try { - this._networkConfig = await getNetworkConfig(this.hass); + const coreNetwork = await getNetworkConfig(this.hass); + if (isComponentLoaded(this.hass, "hassio")) { + const supervisorNetwork = await fetchNetworkInfo(this.hass); + const interfaces = new Set( + supervisorNetwork.interfaces.map((int) => int.interface) + ); + if (interfaces.size) { + coreNetwork.adapters = coreNetwork.adapters.filter((adapter) => + interfaces.has(adapter.name) + ); + } + } + this._networkConfig = coreNetwork; } catch (err) { this._error = err.message || err; } From 8a1eab7ceb20e6f165ed4e7f835d3eed9b6d660c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 1 Jun 2021 20:51:30 +0200 Subject: [PATCH 3/8] Cleanup virtualizer styles (#9327) --- src/components/data-table/ha-data-table.ts | 10 ++++------ src/dialogs/quick-bar/ha-quick-bar.ts | 12 ------------ src/panels/logbook/ha-logbook.ts | 8 -------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index 0811669c51..c7c2927c33 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -246,7 +246,7 @@ export class HaDataTable extends LitElement { aria-rowcount=${this._filteredData.length + 1} style=${styleMap({ height: this.autoHeight - ? `${(this._filteredData.length || 1) * 53 + 57}px` + ? `${(this._filteredData.length || 1) * 53 + 53}px` : `calc(100% - ${this._headerHeight}px)`, })} > @@ -919,13 +919,11 @@ export class HaDataTable extends LitElement { color: var(--secondary-text-color); } .scroller { - display: flex; - position: relative; - contain: strict; height: calc(100% - 57px); } - .mdc-data-table__table:not(.auto-height) .scroller { - overflow: auto; + + .mdc-data-table__table.auto-height .scroller { + overflow-y: hidden !important; } .grows { flex-grow: 1; diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts index 5b39620c92..e98c2375f0 100644 --- a/src/dialogs/quick-bar/ha-quick-bar.ts +++ b/src/dialogs/quick-bar/ha-quick-bar.ts @@ -638,18 +638,6 @@ export class QuickBar extends LitElement { margin-left: 8px; } - .uni-virtualizer-host { - display: block; - position: relative; - contain: strict; - overflow: auto; - height: 100%; - } - - .uni-virtualizer-host > * { - box-sizing: border-box; - } - mwc-list-item { width: 100%; } diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts index 3c62b1c3af..1a8d6864bc 100644 --- a/src/panels/logbook/ha-logbook.ts +++ b/src/panels/logbook/ha-logbook.ts @@ -353,15 +353,7 @@ class HaLogbook extends LitElement { } :host([virtualize]) .container { - display: block; - position: relative; - contain: strict; height: 100%; - overflow: auto; - } - - .container > * { - box-sizing: border-box; } .narrow .entry { From 038199c4478afe5c7032494cffaa229f2fde6f25 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 1 Jun 2021 20:53:45 +0200 Subject: [PATCH 4/8] Change the type of debounce, use arrow functions (#9328) --- src/common/entity/domain_icon.ts | 4 +--- src/common/util/debounce.ts | 26 +++++++++++--------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/common/entity/domain_icon.ts b/src/common/entity/domain_icon.ts index 836c5024dc..adfb8873b4 100644 --- a/src/common/entity/domain_icon.ts +++ b/src/common/entity/domain_icon.ts @@ -89,8 +89,6 @@ export const domainIcon = ( } // eslint-disable-next-line - console.warn( - "Unable to find icon for domain " + domain + " (" + stateObj + ")" - ); + console.warn(`Unable to find icon for domain ${domain}`); return DEFAULT_DOMAIN_ICON; }; diff --git a/src/common/util/debounce.ts b/src/common/util/debounce.ts index 557d596540..70aaddf2e0 100644 --- a/src/common/util/debounce.ts +++ b/src/common/util/debounce.ts @@ -4,29 +4,25 @@ // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. -// eslint-disable-next-line: ban-types -export const debounce = unknown>( - func: T, - wait, + +export const debounce = ( + func: (...args: T) => void, + wait: number, immediate = false -): T => { - let timeout; - // @ts-ignore - return function (...args) { - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-this-alias - const context = this; +) => { + let timeout: number | undefined; + return (...args: T): void => { const later = () => { - timeout = null; + timeout = undefined; if (!immediate) { - func.apply(context, args); + func(...args); } }; const callNow = immediate && !timeout; clearTimeout(timeout); - timeout = setTimeout(later, wait); + timeout = window.setTimeout(later, wait); if (callNow) { - func.apply(context, args); + func(...args); } }; }; From cc1c5e45b2b94983990fc370e00eb2569b43fbe2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 1 Jun 2021 21:03:00 +0200 Subject: [PATCH 5/8] Display error when enabling/disabling config entries (#9325) --- src/data/config_entries.ts | 8 ++-- .../config/devices/ha-config-device-page.ts | 43 +++++++++++++++++-- .../integrations/ha-integration-card.ts | 27 +++++++++++- src/translations/en.json | 2 + 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 8e4de41a9e..6bc9b8242d 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -52,13 +52,15 @@ export const reloadConfigEntry = (hass: HomeAssistant, configEntryId: string) => require_restart: boolean; }>("POST", `config/config_entries/entry/${configEntryId}/reload`); +export interface DisableConfigEntryResult { + require_restart: boolean; +} + export const disableConfigEntry = ( hass: HomeAssistant, configEntryId: string ) => - hass.callWS<{ - require_restart: boolean; - }>({ + hass.callWS({ type: "config_entries/disable", entry_id: configEntryId, disabled_by: "user", diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 3e2cdcfd4e..5ace01bdcb 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -11,7 +11,11 @@ import { slugify } from "../../../common/string/slugify"; import "../../../components/entity/ha-battery-icon"; import "../../../components/ha-icon-next"; import { AreaRegistryEntry } from "../../../data/area_registry"; -import { ConfigEntry, disableConfigEntry } from "../../../data/config_entries"; +import { + ConfigEntry, + disableConfigEntry, + DisableConfigEntryResult, +} from "../../../data/config_entries"; import { computeDeviceName, DeviceRegistryEntry, @@ -25,7 +29,10 @@ import { } from "../../../data/entity_registry"; import { SceneEntities, showSceneEditor } from "../../../data/scene"; import { findRelated, RelatedResult } from "../../../data/search"; -import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; +import { + showAlertDialog, + showConfirmationDialog, +} from "../../../dialogs/generic/show-dialog-box"; import "../../../layouts/hass-error-screen"; import "../../../layouts/hass-tabs-subpage"; import { haStyle } from "../../../resources/styles"; @@ -671,13 +678,41 @@ export class HaConfigDevicePage extends LitElement { dismissText: this.hass.localize("ui.common.no"), })) ) { - disableConfigEntry(this.hass, cnfg_entry); + let result: DisableConfigEntryResult; + try { + // eslint-disable-next-line no-await-in-loop + result = await disableConfigEntry(this.hass, cnfg_entry); + } catch (err) { + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.integrations.config_entry.disable_error" + ), + text: err.message, + }); + return; + } + if (result.require_restart) { + showAlertDialog(this, { + text: this.hass.localize( + "ui.panel.config.integrations.config_entry.disable_restart_confirm" + ), + }); + } delete updates.disabled_by; } } } } - await updateDeviceRegistryEntry(this.hass, this.deviceId, updates); + try { + await updateDeviceRegistryEntry(this.hass, this.deviceId, updates); + } catch (err) { + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.devices.update_device_error" + ), + text: err.message, + }); + } if ( !oldDeviceName || diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 4e2a103c48..bfd3421d08 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -18,6 +18,7 @@ import { ConfigEntry, deleteConfigEntry, disableConfigEntry, + DisableConfigEntryResult, enableConfigEntry, reloadConfigEntry, updateConfigEntry, @@ -487,7 +488,18 @@ export class HaIntegrationCard extends LitElement { if (!confirmed) { return; } - const result = await disableConfigEntry(this.hass, entryId); + let result: DisableConfigEntryResult; + try { + result = await disableConfigEntry(this.hass, entryId); + } catch (err) { + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.integrations.config_entry.disable_error" + ), + text: err.message, + }); + return; + } if (result.require_restart) { showAlertDialog(this, { text: this.hass.localize( @@ -503,7 +515,18 @@ export class HaIntegrationCard extends LitElement { private async _enableIntegration(configEntry: ConfigEntry) { const entryId = configEntry.entry_id; - const result = await enableConfigEntry(this.hass, entryId); + let result: DisableConfigEntryResult; + try { + result = await enableConfigEntry(this.hass, entryId); + } catch (err) { + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.integrations.config_entry.disable_error" + ), + text: err.message, + }); + return; + } if (result.require_restart) { showAlertDialog(this, { diff --git a/src/translations/en.json b/src/translations/en.json index dae343b3c2..458e140bc3 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1975,6 +1975,7 @@ "confirm_rename_entity_ids": "Do you also want to rename the entity IDs of your entities?", "confirm_rename_entity_ids_warning": "This will not change any configuration (like automations, scripts, scenes, dashboards) that is currently using these entities! You will have to update them yourself to use the new entity IDs!", "confirm_disable_config_entry": "There are no more devices for the config entry {entry_name}, do you want to instead disable the config entry?", + "update_device_error": "Updating the device failed", "disabled": "Disabled", "data_table": { "device": "Device", @@ -2163,6 +2164,7 @@ "reload_restart_confirm": "Restart Home Assistant to finish reloading this integration", "disable_restart_confirm": "Restart Home Assistant to finish disabling this integration", "enable_restart_confirm": "Restart Home Assistant to finish enabling this integration", + "disable_error": "Enabling or disabling of the integration failed", "manuf": "by {manufacturer}", "hub": "Connected via", "firmware": "Firmware: {version}", From acd5e1c081e7f2aab32dfc47d49376fb2e18a901 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 1 Jun 2021 21:12:00 +0200 Subject: [PATCH 6/8] Fix back button too wide on mobile (#9333) --- src/layouts/hass-tabs-subpage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index ea691e1766..552f29544c 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -229,7 +229,7 @@ class HassTabsSubpage extends LitElement { color: var(--sidebar-text-color); text-decoration: none; } - :host([narrow]) .toolbar a { + .bottom-bar a { width: 25%; } From 9d0b20adce19cab8c64e8f02740a37e327f133f4 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 1 Jun 2021 12:22:25 -0700 Subject: [PATCH 7/8] Add support for system options v2 (#9332) * Add support for system options v2 * Update src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts Co-authored-by: Bram Kragten * Update dialog-config-entry-system-options.ts Co-authored-by: Bram Kragten --- gallery/src/demos/demo-integration-card.ts | 11 ++---- src/data/config_entries.ts | 35 ++++++------------- .../dialog-config-entry-system-options.ts | 28 +++++++-------- .../integrations/ha-integration-card.ts | 4 +-- .../integrations/ha-integration-header.ts | 2 +- 5 files changed, 28 insertions(+), 52 deletions(-) diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index 97e581f2cc..4f5162c176 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -31,10 +31,8 @@ const createConfigEntry = ( supports_options: false, supports_unload: true, disabled_by: null, - system_options: { - disable_new_entities: false, - disable_polling: false, - }, + pref_disable_new_entities: false, + pref_disable_polling: false, reason: null, ...override, }); @@ -68,10 +66,7 @@ const optionsFlowEntry = createConfigEntry("Options Flow", { supports_options: true, }); const disabledPollingEntry = createConfigEntry("Disabled Polling", { - system_options: { - disable_new_entities: false, - disable_polling: true, - }, + pref_disable_polling: true, }); const setupErrorEntry = createConfigEntry("Setup Error", { state: "setup_error", diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 6bc9b8242d..e83c0498d3 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -14,19 +14,18 @@ export interface ConfigEntry { | "failed_unload"; supports_options: boolean; supports_unload: boolean; - system_options: ConfigEntrySystemOptions; + pref_disable_new_entities: boolean; + pref_disable_polling: boolean; disabled_by: "user" | null; reason: string | null; } -export interface ConfigEntryMutableParams { - title: string; -} - -export interface ConfigEntrySystemOptions { - disable_new_entities: boolean; - disable_polling: boolean; -} +export type ConfigEntryMutableParams = Partial< + Pick< + ConfigEntry, + "title" | "pref_disable_new_entities" | "pref_disable_polling" + > +>; export const getConfigEntries = (hass: HomeAssistant) => hass.callApi("GET", "config/config_entries/entry"); @@ -34,9 +33,9 @@ export const getConfigEntries = (hass: HomeAssistant) => export const updateConfigEntry = ( hass: HomeAssistant, configEntryId: string, - updatedValues: Partial + updatedValues: ConfigEntryMutableParams ) => - hass.callWS({ + hass.callWS<{ require_restart: boolean; config_entry: ConfigEntry }>({ type: "config_entries/update", entry_id: configEntryId, ...updatedValues, @@ -74,17 +73,3 @@ export const enableConfigEntry = (hass: HomeAssistant, configEntryId: string) => entry_id: configEntryId, disabled_by: null, }); - -export const updateConfigEntrySystemOptions = ( - hass: HomeAssistant, - configEntryId: string, - params: Partial -) => - hass.callWS<{ - require_restart: boolean; - system_options: ConfigEntrySystemOptions; - }>({ - type: "config_entries/system_options/update", - entry_id: configEntryId, - ...params, - }); diff --git a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts index 92cac06fef..37d49e0a8a 100644 --- a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts +++ b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts @@ -7,7 +7,10 @@ import "../../components/ha-dialog"; import "../../components/ha-formfield"; import "../../components/ha-switch"; import type { HaSwitch } from "../../components/ha-switch"; -import { updateConfigEntrySystemOptions } from "../../data/config_entries"; +import { + ConfigEntryMutableParams, + updateConfigEntry, +} from "../../data/config_entries"; import { haStyleDialog } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; import { showAlertDialog } from "../generic/show-dialog-box"; @@ -32,8 +35,8 @@ class DialogConfigEntrySystemOptions extends LitElement { ): Promise { this._params = params; this._error = undefined; - this._disableNewEntities = params.entry.system_options.disable_new_entities; - this._disablePolling = params.entry.system_options.disable_polling; + this._disableNewEntities = params.entry.pref_disable_new_entities; + this._disablePolling = params.entry.pref_disable_polling; } public closeDialog(): void { @@ -147,14 +150,14 @@ class DialogConfigEntrySystemOptions extends LitElement { private async _updateEntry(): Promise { this._submitting = true; - const data: Parameters[2] = { - disable_new_entities: this._disableNewEntities, + const data: ConfigEntryMutableParams = { + pref_disable_new_entities: this._disableNewEntities, }; if (this._allowUpdatePolling()) { - data.disable_polling = this._disablePolling; + data.pref_disable_polling = this._disablePolling; } try { - const result = await updateConfigEntrySystemOptions( + const result = await updateConfigEntry( this.hass, this._params!.entry.entry_id, data @@ -166,15 +169,8 @@ class DialogConfigEntrySystemOptions extends LitElement { ), }); } - const curEntry = this._params!.entry; - this._params!.entryUpdated({ - ...curEntry, - system_options: { - ...curEntry.system_options, - ...data, - }, - }); - this._params = undefined; + this._params!.entryUpdated(result.config_entry); + this.closeDialog(); } catch (err) { this._error = err.message || "Unknown error"; } finally { diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index bfd3421d08..85663de87d 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -590,10 +590,10 @@ export class HaIntegrationCard extends LitElement { if (newName === null) { return; } - const newEntry = await updateConfigEntry(this.hass, configEntry.entry_id, { + const result = await updateConfigEntry(this.hass, configEntry.entry_id, { title: newName, }); - fireEvent(this, "entry-updated", { entry: newEntry }); + fireEvent(this, "entry-updated", { entry: result.config_entry }); } static get styles(): CSSResultGroup { diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts index d18ba01670..de6932d1a5 100644 --- a/src/panels/config/integrations/ha-integration-header.ts +++ b/src/panels/config/integrations/ha-integration-header.ts @@ -63,7 +63,7 @@ export class HaIntegrationHeader extends LitElement { ]); } - if (this.configEntry?.system_options.disable_polling) { + if (this.configEntry?.pref_disable_polling) { icons.push([ mdiSyncOff, this.hass.localize( From 2a30b55a43d10fd842119158657547154ae0538a Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 1 Jun 2021 21:30:51 +0200 Subject: [PATCH 8/8] Bumped version to 20210601.1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 32ad5f3e1a..972990e191 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20210601.0", + version="20210601.1", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors",