From d387f19a311b3ed4bddadd814a535b244abdab88 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 18 Feb 2025 14:02:53 +0100 Subject: [PATCH] Backup tweaks (#24165) * Backup tweaks * Show progress in fab * Revert unused changes --------- Co-authored-by: Wendelin --- src/data/backup.ts | 9 ++++- .../config/ha-backup-config-agents.ts | 2 +- .../config/backup/ha-config-backup-backups.ts | 24 ++++++++++-- .../backup/ha-config-backup-overview.ts | 37 ++++++++++++++++++- .../backup/ha-config-backup-settings.ts | 33 ++++++++++++++++- src/panels/config/backup/ha-config-backup.ts | 10 ++--- src/translations/en.json | 5 ++- 7 files changed, 106 insertions(+), 14 deletions(-) diff --git a/src/data/backup.ts b/src/data/backup.ts index 54424f0b21..b65ce73611 100644 --- a/src/data/backup.ts +++ b/src/data/backup.ts @@ -12,6 +12,7 @@ import type { HomeAssistant } from "../types"; import { fileDownload } from "../util/file_download"; import { domainToName } from "./integration"; import type { FrontendLocaleData } from "./translation"; +import type { BackupManagerState, ManagerStateEvent } from "./backup_manager"; import checkValidDate from "../common/datetime/check_valid_date"; import { handleFetchPromise } from "../util/hass-call-api"; @@ -130,7 +131,13 @@ export interface BackupContentExtended extends BackupContent, BackupData {} export interface BackupInfo { backups: BackupContent[]; - backing_up: boolean; + agent_errors: Record; + last_attempted_automatic_backup: string | null; + last_completed_automatic_backup: string | null; + last_non_idle_event: ManagerStateEvent | null; + next_automatic_backup: string | null; + next_automatic_backup_additional: boolean; + state: BackupManagerState; } export interface BackupDetails { diff --git a/src/panels/config/backup/components/config/ha-backup-config-agents.ts b/src/panels/config/backup/components/config/ha-backup-config-agents.ts index 4444e917a2..687321f7c5 100644 --- a/src/panels/config/backup/components/config/ha-backup-config-agents.ts +++ b/src/panels/config/backup/components/config/ha-backup-config-agents.ts @@ -4,6 +4,7 @@ import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { fireEvent } from "../../../../../common/dom/fire_event"; import { computeDomain } from "../../../../../common/entity/compute_domain"; +import { navigate } from "../../../../../common/navigate"; import "../../../../../components/ha-icon-button"; import "../../../../../components/ha-md-list"; import "../../../../../components/ha-md-list-item"; @@ -22,7 +23,6 @@ import { import type { CloudStatus } from "../../../../../data/cloud"; import type { HomeAssistant } from "../../../../../types"; import { brandsUrl } from "../../../../../util/brands-url"; -import { navigate } from "../../../../../common/navigate"; const DEFAULT_AGENTS = []; diff --git a/src/panels/config/backup/ha-config-backup-backups.ts b/src/panels/config/backup/ha-config-backup-backups.ts index 6caa2190af..9690a89f9b 100644 --- a/src/panels/config/backup/ha-config-backup-backups.ts +++ b/src/panels/config/backup/ha-config-backup-backups.ts @@ -8,7 +8,7 @@ import { mdiUpload, } from "@mdi/js"; import type { CSSResultGroup, TemplateResult } from "lit"; -import { html, LitElement, nothing } from "lit"; +import { css, html, LitElement, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; @@ -27,6 +27,7 @@ import type { } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-button"; import "../../../components/ha-button-menu"; +import "../../../components/ha-circular-progress"; import "../../../components/ha-fab"; import "../../../components/ha-filter-states"; import "../../../components/ha-icon"; @@ -460,7 +461,17 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { extended @click=${this._newBackup} > - + ${backupInProgress + ? html`
+ +
` + : html``} ` : nothing} @@ -605,7 +616,14 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) { } static get styles(): CSSResultGroup { - return haStyle; + return [ + haStyle, + css` + ha-circular-progress { + --md-sys-color-primary: var(--mdc-theme-on-secondary); + } + `, + ]; } } diff --git a/src/panels/config/backup/ha-config-backup-overview.ts b/src/panels/config/backup/ha-config-backup-overview.ts index 8d23b61b66..e9c75d935f 100644 --- a/src/panels/config/backup/ha-config-backup-overview.ts +++ b/src/panels/config/backup/ha-config-backup-overview.ts @@ -8,6 +8,7 @@ import "../../../components/ha-button"; import "../../../components/ha-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-fab"; +import "../../../components/ha-circular-progress"; import "../../../components/ha-icon"; import "../../../components/ha-icon-next"; import "../../../components/ha-icon-overflow-menu"; @@ -17,8 +18,10 @@ import type { BackupAgent, BackupConfig, BackupContent, + BackupInfo, } from "../../../data/backup"; import { + computeBackupAgentName, generateBackup, generateBackupWithAutomaticSettings, } from "../../../data/backup"; @@ -50,6 +53,8 @@ class HaConfigBackupOverview extends LitElement { @property({ attribute: false }) public manager!: ManagerStateEvent; + @property({ attribute: false }) public info?: BackupInfo; + @property({ attribute: false }) public backups: BackupContent[] = []; @property({ attribute: false }) public fetching = false; @@ -151,6 +156,26 @@ class HaConfigBackupOverview extends LitElement {
+ ${this.info && Object.keys(this.info.agent_errors).length + ? html`${Object.entries(this.info.agent_errors).map( + ([agentId, error]) => + html` + ${error} + ` + )}` + : nothing} ${backupInProgress ? html` - + ${backupInProgress + ? html`
+ +
` + : html``} `; @@ -231,6 +263,9 @@ class HaConfigBackupOverview extends LitElement { padding-left: 0; padding-right: 0; } + ha-circular-progress { + --md-sys-color-primary: var(--mdc-theme-on-secondary); + } `, ]; } diff --git a/src/panels/config/backup/ha-config-backup-settings.ts b/src/panels/config/backup/ha-config-backup-settings.ts index d7bb4266da..e841b872aa 100644 --- a/src/panels/config/backup/ha-config-backup-settings.ts +++ b/src/panels/config/backup/ha-config-backup-settings.ts @@ -1,4 +1,4 @@ -import { mdiDotsVertical, mdiHarddisk } from "@mdi/js"; +import { mdiDotsVertical, mdiHarddisk, mdiOpenInNew } from "@mdi/js"; import type { PropertyValues } from "lit"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -28,6 +28,7 @@ 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"; import { showLocalBackupLocationDialog } from "./dialogs/show-dialog-local-backup-location"; +import { documentationUrl } from "../../../util/documentation-url"; @customElement("ha-config-backup-settings") class HaConfigBackupSettings extends LitElement { @@ -98,6 +99,8 @@ class HaConfigBackupSettings extends LitElement { return nothing; } + const supervisor = isComponentLoaded(this.hass, "hassio"); + return html` - ${isComponentLoaded(this.hass, "hassio") + ${supervisor ? html` +
@@ -342,6 +368,9 @@ class HaConfigBackupSettings extends LitElement { .card-content { padding-bottom: 0; } + a { + text-decoration: none; + } `; } diff --git a/src/panels/config/backup/ha-config-backup.ts b/src/panels/config/backup/ha-config-backup.ts index b488058b58..d61eb33a36 100644 --- a/src/panels/config/backup/ha-config-backup.ts +++ b/src/panels/config/backup/ha-config-backup.ts @@ -4,7 +4,7 @@ import { customElement, property, state } from "lit/decorators"; import type { BackupAgent, BackupConfig, - BackupContent, + BackupInfo, } from "../../../data/backup"; import { compareAgents, @@ -44,7 +44,7 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) { @state() private _manager: ManagerStateEvent = DEFAULT_MANAGER_STATE; - @state() private _backups: BackupContent[] = []; + @state() private _info?: BackupInfo; @state() private _agents: BackupAgent[] = []; @@ -87,8 +87,7 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) { } private async _fetchBackupInfo() { - const info = await fetchBackupInfo(this.hass); - this._backups = info.backups; + this._info = await fetchBackupInfo(this.hass); } private async _fetchBackupConfig() { @@ -134,7 +133,8 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) { pageEl.narrow = this.narrow; pageEl.cloudStatus = this.cloudStatus; pageEl.manager = this._manager; - pageEl.backups = this._backups; + pageEl.info = this._info; + pageEl.backups = this._info?.backups || []; pageEl.config = this._config; pageEl.agents = this._agents; pageEl.fetching = this._fetching; diff --git a/src/translations/en.json b/src/translations/en.json index b4c1a39732..0afa5e133b 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2512,6 +2512,7 @@ "menu": { "upload_backup": "Upload backup" }, + "agent_error": "Error in location {name}", "new_backup": "Backup now", "onboarding": { "title": "Set up backups", @@ -2650,7 +2651,9 @@ "title": "Locations", "description": "Your backup will be stored on these locations when this default backup is created. You can use all locations for custom backups.", "no_location": "No location selected", - "no_location_description": "You have to select at least one location to create a backup." + "no_location_description": "You have to select at least one location to create a backup.", + "more_locations": "Explore more locations", + "manage_network_storage": "Manage network storage" }, "encryption_key": { "title": "Encryption key",