From fd32efac3575b65c8d28b04be169bbef2f37ba3b Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Thu, 19 Dec 2024 17:34:04 +0100
Subject: [PATCH] Simplify fetching logic
---
.../config/backup/ha-config-backup-backups.ts | 112 ++------------
.../backup/ha-config-backup-locations.ts | 138 ------------------
.../backup/ha-config-backup-overview.ts | 65 +++------
.../backup/ha-config-backup-settings.ts | 102 ++++---------
src/panels/config/backup/ha-config-backup.ts | 68 ++++++++-
5 files changed, 124 insertions(+), 361 deletions(-)
delete mode 100644 src/panels/config/backup/ha-config-backup-locations.ts
diff --git a/src/panels/config/backup/ha-config-backup-backups.ts b/src/panels/config/backup/ha-config-backup-backups.ts
index 2d00aed0fa79..d095f4d46e10 100644
--- a/src/panels/config/backup/ha-config-backup-backups.ts
+++ b/src/panels/config/backup/ha-config-backup-backups.ts
@@ -6,14 +6,14 @@ import {
mdiPlus,
mdiUpload,
} from "@mdi/js";
-import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
+import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one";
import { relativeTime } from "../../../common/datetime/relative_time";
import { storage } from "../../../common/decorators/storage";
-import type { HASSDomEvent } from "../../../common/dom/fire_event";
+import { fireEvent, type HASSDomEvent } from "../../../common/dom/fire_event";
import { computeDomain } from "../../../common/entity/compute_domain";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import { navigate } from "../../../common/navigate";
@@ -36,11 +36,8 @@ import "../../../components/ha-svg-icon";
import { getSignedPath } from "../../../data/auth";
import type { BackupConfig, BackupContent } from "../../../data/backup";
import {
- compareAgents,
computeBackupAgentName,
deleteBackup,
- fetchBackupConfig,
- fetchBackupInfo,
generateBackup,
generateBackupWithAutomaticSettings,
getBackupDownloadUrl,
@@ -48,10 +45,6 @@ import {
isLocalAgent,
} from "../../../data/backup";
import type { ManagerStateEvent } from "../../../data/backup_manager";
-import {
- DEFAULT_MANAGER_STATE,
- subscribeBackupEvents,
-} from "../../../data/backup_manager";
import type { CloudStatus } from "../../../data/cloud";
import { extractApiErrorMessage } from "../../../data/hassio/common";
import {
@@ -66,7 +59,6 @@ import type { HomeAssistant, Route } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
import { bytesToString } from "../../../util/bytes-to-string";
import { fileDownload } from "../../../util/file_download";
-import { showToast } from "../../../util/toast";
import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup";
import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup";
import { showUploadBackupDialog } from "./dialogs/show-dialog-upload-backup";
@@ -89,13 +81,13 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public route!: Route;
- @state() private _manager: ManagerStateEvent = DEFAULT_MANAGER_STATE;
+ @property() private manager!: ManagerStateEvent;
- @state() private _backups: BackupContent[] = [];
+ @property() private backups: BackupContent[] = [];
- @state() private _selected: string[] = [];
+ @property() private config?: BackupConfig;
- @state() private _config?: BackupConfig;
+ @state() private _selected: string[] = [];
@storage({ key: "backups-table-grouping", state: false, subscribe: false })
private _activeGrouping?: string = "formatted_type";
@@ -107,8 +99,6 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
})
private _activeCollapsed: string[] = [];
- private _subscribed?: Promise<() => void>;
-
@query("hass-tabs-subpage-data-table", true)
private _dataTable!: HaTabsSubpageDataTable;
@@ -251,7 +241,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
protected render(): TemplateResult {
const backupInProgress =
- "state" in this._manager && this._manager.state === "in_progress";
+ "state" in this.manager && this.manager.state === "in_progress";
return html`
unsub());
- this._subscribed = undefined;
- }
- }
-
- private async _subscribeEvents() {
- this._unsubscribeEvents();
- if (!this.isConnected) {
- return;
- }
-
- this._subscribed = subscribeBackupEvents(this.hass!, (event) => {
- this._manager = event;
- if ("state" in event) {
- if (event.state === "completed" || event.state === "failed") {
- this._fetchBackupInfo();
- }
- if (event.state === "failed") {
- let message = "";
- switch (this._manager.manager_state) {
- case "create_backup":
- message = "Failed to create backup";
- break;
- case "restore_backup":
- message = "Failed to restore backup";
- break;
- case "receive_backup":
- message = "Failed to upload backup";
- break;
- }
- if (message) {
- showToast(this, { message });
- }
- }
- }
- });
- }
-
- protected firstUpdated(changedProps: PropertyValues) {
- super.firstUpdated(changedProps);
- this._fetchBackupInfo();
- this._subscribeEvents();
- this._fetchBackupConfig();
- }
-
- public connectedCallback() {
- super.connectedCallback();
- if (this.hasUpdated) {
- this._fetchBackupInfo();
- this._subscribeEvents();
- }
- }
-
- public disconnectedCallback(): void {
- super.disconnectedCallback();
- this._unsubscribeEvents();
- }
-
- private async _fetchBackupInfo() {
- const info = await fetchBackupInfo(this.hass);
- this._backups = info.backups.map((backup) => ({
- ...backup,
- agent_ids: backup.agent_ids?.sort(compareAgents),
- failed_agent_ids: backup.failed_agent_ids?.sort(compareAgents),
- }));
- }
-
- private async _fetchBackupConfig() {
- const { config } = await fetchBackupConfig(this.hass);
- this._config = config;
- }
-
private get _needsOnboarding() {
- return !this._config?.create_backup.password;
+ return !this.config?.create_backup.password;
}
private async _uploadBackup(ev) {
@@ -438,7 +354,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
}
private async _newBackup(): Promise {
- const config = this._config!;
+ const config = this.config!;
const type = await showNewBackupDialog(this, { config });
@@ -454,12 +370,12 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
}
await generateBackup(this.hass, params);
- await this._fetchBackupInfo();
+ fireEvent(this, "ha-refresh-backup-info");
return;
}
if (type === "automatic") {
await generateBackupWithAutomaticSettings(this.hass);
- await this._fetchBackupInfo();
+ fireEvent(this, "ha-refresh-backup-info");
}
}
@@ -490,7 +406,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
}
await deleteBackup(this.hass, backup.backup_id);
- this._fetchBackupInfo();
+ fireEvent(this, "ha-refresh-backup-info");
}
private async _deleteSelected() {
@@ -516,7 +432,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
});
return;
}
- await this._fetchBackupInfo();
+ fireEvent(this, "ha-refresh-backup-info");
this._dataTable.clearSelection();
}
diff --git a/src/panels/config/backup/ha-config-backup-locations.ts b/src/panels/config/backup/ha-config-backup-locations.ts
deleted file mode 100644
index 80312f30c219..000000000000
--- a/src/panels/config/backup/ha-config-backup-locations.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import type { TemplateResult } from "lit";
-import { css, html, LitElement } from "lit";
-import { customElement, property, state } from "lit/decorators";
-import "../../../components/ha-card";
-import "../../../components/ha-icon-next";
-import "../../../components/ha-md-list";
-import "../../../components/ha-md-list-item";
-import type { BackupAgent } from "../../../data/backup";
-import { fetchBackupAgentsInfo } from "../../../data/backup";
-import "../../../layouts/hass-subpage";
-import type { HomeAssistant } from "../../../types";
-import { brandsUrl } from "../../../util/brands-url";
-import { domainToName } from "../../../data/integration";
-
-@customElement("ha-config-backup-locations")
-class HaConfigBackupLocations extends LitElement {
- @property({ attribute: false }) public hass!: HomeAssistant;
-
- @property({ type: Boolean }) public narrow = false;
-
- @state() private _agents: BackupAgent[] = [];
-
- protected firstUpdated(changedProps) {
- super.firstUpdated(changedProps);
- this._fetchAgents();
- }
-
- protected render(): TemplateResult {
- return html`
-
-
-
-
-
- ${this._agents.length > 0
- ? html`
-
- ${this._agents.map((agent) => {
- const [domain, name] = agent.agent_id.split(".");
- const domainName = domainToName(
- this.hass.localize,
- domain
- );
- return html`
-
-
- ${domainName}: ${name}
-
-
- `;
- })}
-
- `
- : html`
No sync agents configured
`}
-
-
-
-
- `;
- }
-
- private async _fetchAgents() {
- const data = await fetchBackupAgentsInfo(this.hass);
- this._agents = data.agents;
- }
-
- static styles = css`
- .content {
- padding: 28px 20px 0;
- max-width: 690px;
- margin: 0 auto;
- gap: 24px;
- display: flex;
- flex-direction: column;
- }
-
- .header .title {
- font-size: 22px;
- font-style: normal;
- font-weight: 400;
- line-height: 28px;
- color: var(--primary-text-color);
- margin: 0;
- margin-bottom: 8px;
- }
-
- .header .description {
- font-size: 14px;
- font-style: normal;
- font-weight: 400;
- line-height: 20px;
- letter-spacing: 0.25px;
- color: var(--secondary-text-color);
- margin: 0;
- }
-
- ha-md-list {
- background: none;
- }
- ha-md-list-item img {
- width: 48px;
- }
- .card-content {
- padding: 0;
- }
- `;
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- "ha-config-backup-locations": HaConfigBackupLocations;
- }
-}
diff --git a/src/panels/config/backup/ha-config-backup-overview.ts b/src/panels/config/backup/ha-config-backup-overview.ts
index 44b196736469..afa203244fd9 100644
--- a/src/panels/config/backup/ha-config-backup-overview.ts
+++ b/src/panels/config/backup/ha-config-backup-overview.ts
@@ -1,7 +1,8 @@
import { mdiDotsVertical, mdiPlus, mdiUpload } from "@mdi/js";
-import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
+import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
-import { customElement, property, state } from "lit/decorators";
+import { customElement, property } from "lit/decorators";
+import { fireEvent } from "../../../common/dom/fire_event";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import "../../../components/ha-button";
import "../../../components/ha-button-menu";
@@ -13,8 +14,6 @@ import "../../../components/ha-icon-overflow-menu";
import "../../../components/ha-list-item";
import "../../../components/ha-svg-icon";
import {
- fetchBackupConfig,
- fetchBackupInfo,
generateBackup,
generateBackupWithAutomaticSettings,
type BackupConfig,
@@ -50,29 +49,11 @@ class HaConfigBackupOverview extends LitElement {
@property({ attribute: false }) public manager!: ManagerStateEvent;
- @state() private _backups: BackupContent[] = [];
+ @property({ attribute: false }) public backups: BackupContent[] = [];
- @state() private _fetching = false;
+ @property({ attribute: false }) public fetching = false;
- @state() private _config?: BackupConfig;
-
- protected firstUpdated(changedProps: PropertyValues) {
- super.firstUpdated(changedProps);
- this._fetching = true;
- Promise.all([this._fetchBackupInfo(), this._fetchBackupConfig()]).finally(
- () => {
- this._fetching = false;
- }
- );
- }
-
- public connectedCallback() {
- super.connectedCallback();
- if (this.hasUpdated) {
- this._fetchBackupInfo();
- this._fetchBackupConfig();
- }
- }
+ @property({ attribute: false }) public config?: BackupConfig;
private async _uploadBackup(ev) {
if (!shouldHandleRequestSelectedEvent(ev)) {
@@ -96,19 +77,9 @@ class HaConfigBackupOverview extends LitElement {
return;
}
- this._fetchBackupConfig();
+ fireEvent(this, "ha-refresh-backup-config");
await generateBackupWithAutomaticSettings(this.hass);
- await this._fetchBackupInfo();
- }
-
- private async _fetchBackupInfo() {
- const info = await fetchBackupInfo(this.hass);
- this._backups = info.backups;
- }
-
- private async _fetchBackupConfig() {
- const { config } = await fetchBackupConfig(this.hass);
- this._config = config;
+ fireEvent(this, "ha-refresh-backup-info");
}
private async _newBackup(): Promise {
@@ -117,11 +88,11 @@ class HaConfigBackupOverview extends LitElement {
return;
}
- if (!this._config) {
+ if (!this.config) {
return;
}
- const config = this._config;
+ const config = this.config;
const type = await showNewBackupDialog(this, { config });
@@ -137,17 +108,17 @@ class HaConfigBackupOverview extends LitElement {
}
await generateBackup(this.hass, params);
- await this._fetchBackupInfo();
+ fireEvent(this, "ha-refresh-backup-info");
return;
}
if (type === "automatic") {
await generateBackupWithAutomaticSettings(this.hass);
- await this._fetchBackupInfo();
+ fireEvent(this, "ha-refresh-backup-info");
}
}
private get _needsOnboarding() {
- return !this._config?.create_backup.password;
+ return !this.config?.create_backup.password;
}
protected render(): TemplateResult {
@@ -186,7 +157,7 @@ class HaConfigBackupOverview extends LitElement {
>
`
- : this._fetching
+ : this.fetching
? html`
`}
${!this._needsOnboarding
? html`
`
: nothing}
diff --git a/src/panels/config/backup/ha-config-backup-settings.ts b/src/panels/config/backup/ha-config-backup-settings.ts
index ffb4c2719041..0c02e27f3c74 100644
--- a/src/panels/config/backup/ha-config-backup-settings.ts
+++ b/src/panels/config/backup/ha-config-backup-settings.ts
@@ -1,17 +1,12 @@
import { css, html, LitElement, nothing } from "lit";
-import { customElement, property, state } from "lit/decorators";
+import { customElement, property } from "lit/decorators";
import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-button";
import "../../../components/ha-card";
import "../../../components/ha-icon-next";
import "../../../components/ha-password-field";
-import "../../../components/ha-settings-row";
import type { BackupConfig } from "../../../data/backup";
-import {
- BackupScheduleState,
- fetchBackupConfig,
- updateBackupConfig,
-} from "../../../data/backup";
+import { updateBackupConfig } from "../../../data/backup";
import type { CloudStatus } from "../../../data/cloud";
import "../../../layouts/hass-subpage";
import type { HomeAssistant } from "../../../types";
@@ -21,27 +16,7 @@ import type { BackupConfigData } from "./components/config/ha-backup-config-data
import "./components/config/ha-backup-config-encryption-key";
import "./components/config/ha-backup-config-schedule";
import type { BackupConfigSchedule } from "./components/config/ha-backup-config-schedule";
-
-const INITIAL_BACKUP_CONFIG: BackupConfig = {
- create_backup: {
- agent_ids: [],
- include_folders: [],
- include_database: true,
- include_addons: [],
- include_all_addons: true,
- password: null,
- name: null,
- },
- retention: {
- copies: 3,
- days: null,
- },
- schedule: {
- state: BackupScheduleState.DAILY,
- },
- last_attempted_automatic_backup: null,
- last_completed_automatic_backup: null,
-};
+import { fireEvent } from "../../../common/dom/fire_event";
@customElement("ha-config-backup-settings")
class HaConfigBackupSettings extends LitElement {
@@ -51,22 +26,10 @@ class HaConfigBackupSettings extends LitElement {
@property({ type: Boolean }) public narrow = false;
- @state() private _backupConfig: BackupConfig = INITIAL_BACKUP_CONFIG;
-
- protected willUpdate(changedProps) {
- super.willUpdate(changedProps);
- if (!this.hasUpdated) {
- this._fetchData();
- }
- }
-
- private async _fetchData() {
- const { config } = await fetchBackupConfig(this.hass);
- this._backupConfig = config;
- }
+ @property({ attribute: false }) public config?: BackupConfig;
protected render() {
- if (!this._backupConfig) {
+ if (!this.config) {
return nothing;
}
@@ -87,7 +50,7 @@ class HaConfigBackupSettings extends LitElement {
@@ -113,7 +76,7 @@ class HaConfigBackupSettings extends LitElement {
@@ -130,7 +93,7 @@ class HaConfigBackupSettings extends LitElement {
@@ -142,8 +105,8 @@ class HaConfigBackupSettings extends LitElement {
private _scheduleConfigChanged(ev) {
const value = ev.detail.value as BackupConfigSchedule;
- this._backupConfig = {
- ...this._backupConfig,
+ this.config = {
+ ...this.config!,
schedule: value.schedule,
retention: value.retention,
};
@@ -156,7 +119,7 @@ class HaConfigBackupSettings extends LitElement {
include_all_addons,
include_database,
include_folders,
- } = this._backupConfig.create_backup;
+ } = this.config!.create_backup;
return {
include_homeassistant: true,
@@ -169,10 +132,10 @@ class HaConfigBackupSettings extends LitElement {
private _dataConfigChanged(ev) {
const data = ev.detail.value as BackupConfigData;
- this._backupConfig = {
- ...this._backupConfig,
+ this.config = {
+ ...this.config!,
create_backup: {
- ...this._backupConfig.create_backup,
+ ...this.config!.create_backup,
include_database: data.include_database,
include_folders: data.include_folders || null,
include_all_addons: data.include_all_addons,
@@ -184,10 +147,10 @@ class HaConfigBackupSettings extends LitElement {
private _agentsConfigChanged(ev) {
const agents = ev.detail.value as string[];
- this._backupConfig = {
- ...this._backupConfig,
+ this.config = {
+ ...this.config!,
create_backup: {
- ...this._backupConfig.create_backup,
+ ...this.config!.create_backup,
agent_ids: agents,
},
};
@@ -196,10 +159,10 @@ class HaConfigBackupSettings extends LitElement {
private _encryptionKeyChanged(ev) {
const password = ev.detail.value as string;
- this._backupConfig = {
- ...this._backupConfig,
+ this.config = {
+ ...this.config!,
create_backup: {
- ...this._backupConfig.create_backup,
+ ...this.config!.create_backup,
password: password,
},
};
@@ -211,16 +174,17 @@ class HaConfigBackupSettings extends LitElement {
private async _save() {
await updateBackupConfig(this.hass, {
create_backup: {
- agent_ids: this._backupConfig.create_backup.agent_ids,
- include_folders: this._backupConfig.create_backup.include_folders ?? [],
- include_database: this._backupConfig.create_backup.include_database,
- include_addons: this._backupConfig.create_backup.include_addons ?? [],
- include_all_addons: this._backupConfig.create_backup.include_all_addons,
- password: this._backupConfig.create_backup.password,
+ agent_ids: this.config!.create_backup.agent_ids,
+ include_folders: this.config!.create_backup.include_folders ?? [],
+ include_database: this.config!.create_backup.include_database,
+ include_addons: this.config!.create_backup.include_addons ?? [],
+ include_all_addons: this.config!.create_backup.include_all_addons,
+ password: this.config!.create_backup.password,
},
- retention: this._backupConfig.retention,
- schedule: this._backupConfig.schedule.state,
+ retention: this.config!.retention,
+ schedule: this.config!.schedule.state,
});
+ fireEvent(this, "ha-refresh-backup-config");
}
static styles = css`
@@ -233,14 +197,6 @@ class HaConfigBackupSettings extends LitElement {
flex-direction: column;
margin-bottom: 24px;
}
- ha-settings-row {
- --settings-row-prefix-display: flex;
- padding: 0;
- }
- ha-settings-row > ha-svg-icon {
- align-self: center;
- margin-inline-end: 16px;
- }
.alert {
--mdc-theme-primary: var(--error-color);
}
diff --git a/src/panels/config/backup/ha-config-backup.ts b/src/panels/config/backup/ha-config-backup.ts
index 230004feb49a..bf8be4d454d1 100644
--- a/src/panels/config/backup/ha-config-backup.ts
+++ b/src/panels/config/backup/ha-config-backup.ts
@@ -15,6 +15,19 @@ import type { HomeAssistant } from "../../../types";
import { showToast } from "../../../util/toast";
import "./ha-config-backup-backups";
import "./ha-config-backup-overview";
+import type { BackupConfig, BackupContent } from "../../../data/backup";
+import {
+ compareAgents,
+ fetchBackupConfig,
+ fetchBackupInfo,
+} from "../../../data/backup";
+
+declare global {
+ interface HASSDomEvents {
+ "ha-refresh-backup-info": undefined;
+ "ha-refresh-backup-config": undefined;
+ }
+}
@customElement("ha-config-backup")
class HaConfigBackup extends SubscribeMixin(HassRouterPage) {
@@ -26,6 +39,51 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) {
@state() private _manager: ManagerStateEvent = DEFAULT_MANAGER_STATE;
+ @state() private _backups: BackupContent[] = [];
+
+ @state() private _fetching = false;
+
+ @state() private _config?: BackupConfig;
+
+ protected firstUpdated(changedProps: PropertyValues) {
+ super.firstUpdated(changedProps);
+ this._fetching = true;
+ Promise.all([this._fetchBackupInfo(), this._fetchBackupConfig()]).finally(
+ () => {
+ this._fetching = false;
+ }
+ );
+
+ this.addEventListener("ha-refresh-backup-info", () => {
+ this._fetchBackupInfo();
+ });
+ this.addEventListener("ha-refresh-backup-config", () => {
+ this._fetchBackupConfig();
+ });
+ }
+
+ public connectedCallback() {
+ super.connectedCallback();
+ if (this.hasUpdated) {
+ this._fetchBackupInfo();
+ this._fetchBackupConfig();
+ }
+ }
+
+ private async _fetchBackupInfo() {
+ const info = await fetchBackupInfo(this.hass);
+ this._backups = info.backups.map((backup) => ({
+ ...backup,
+ agent_ids: backup.agent_ids?.sort(compareAgents),
+ failed_agent_ids: backup.failed_agent_ids?.sort(compareAgents),
+ }));
+ }
+
+ private async _fetchBackupConfig() {
+ const { config } = await fetchBackupConfig(this.hass);
+ this._config = config;
+ }
+
protected routerOptions: RouterOptions = {
defaultPage: "overview",
routes: {
@@ -41,10 +99,6 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) {
tag: "ha-config-backup-details",
load: () => import("./ha-config-backup-details"),
},
- locations: {
- tag: "ha-config-backup-locations",
- load: () => import("./ha-config-backup-locations"),
- },
settings: {
tag: "ha-config-backup-settings",
load: () => import("./ha-config-backup-settings"),
@@ -58,7 +112,11 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) {
pageEl.narrow = this.narrow;
pageEl.cloudStatus = this.cloudStatus;
pageEl.manager = this._manager;
+ pageEl.backups = this._backups;
+ pageEl.config = this._config;
+ pageEl.fetching = this._fetching;
+ pageEl.addEventListener("reload", () => {});
if (
(!changedProps || changedProps.has("route")) &&
this._currentPage === "details"
@@ -73,7 +131,7 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) {
this._manager = event;
if ("state" in event) {
if (event.state === "completed" || event.state === "failed") {
- // this._fetchBackupInfo();
+ this._fetchBackupInfo();
}
if (event.state === "failed") {
let message = "";