-
- ${this._backup.name}
-
-
+
+
+ ${this._backup.name}
+ ${!this._dialogParams.onboarding && this._dialogParams.supervisor
+ ? html`
+
+ ${this._dialogParams.supervisor.localize(
+ "backup.download_backup"
+ )}
+ ${this._dialogParams.supervisor.localize(
+ "backup.delete_backup_title"
+ )}
+ `
+ : nothing}
+
+
+ ${this._error
+ ? html`
${this._error}`
+ : this._restoringBackup
+ ? html`
+
+
`
+ : html`
+
+
+ `}
- ${this._restoringBackup
- ? html`
`
- : html`
-
-
- `}
- ${this._error
- ? html`
${this._error}`
- : nothing}
-
-
- ${this._localize("restore")}
-
-
- ${!this._dialogParams.onboarding && this._dialogParams.supervisor
- ? html`
-
- ${this._dialogParams.supervisor.localize(
- "backup.download_backup"
- )}
- ${this._dialogParams.supervisor.localize(
- "backup.delete_backup_title"
- )}
- `
- : nothing}
-
+
+
+ ${this._localize("restore")}
+
+
+
`;
}
- static get styles(): CSSResultGroup {
- return [
- haStyle,
- haStyleDialog,
- css`
- ha-circular-progress {
- display: block;
- text-align: center;
- }
- ha-header-bar {
- --mdc-theme-on-primary: var(--primary-text-color);
- --mdc-theme-primary: var(--mdc-theme-surface);
- flex-shrink: 0;
- display: block;
- }
- ha-icon-button {
- color: var(--secondary-text-color);
- }
- `,
- ];
- }
-
private _handleMenuAction(ev: CustomEvent
) {
switch (ev.detail.index) {
case 0:
@@ -184,18 +179,9 @@ class HassioBackupDialog
}
private async _restoreClicked() {
- const backupDetails = this._backupContent.backupDetails();
this._restoringBackup = true;
- this._dialogParams?.onRestoring?.();
- if (this._backupContent.backupType === "full") {
- await this._fullRestoreClicked(backupDetails);
- } else {
- await this._partialRestoreClicked(backupDetails);
- }
- this._restoringBackup = false;
- }
+ const backupDetails = this._backupContent.backupDetails();
- private async _partialRestoreClicked(backupDetails) {
const supervisor = this._dialogParams?.supervisor;
if (supervisor !== undefined && supervisor.info.state !== "running") {
await showAlertDialog(this, {
@@ -204,91 +190,45 @@ class HassioBackupDialog
state: supervisor.info.state,
}),
});
+ this._restoringBackup = false;
return;
}
if (
!(await showConfirmationDialog(this, {
- title: this._localize("confirm_restore_partial_backup_title"),
- text: this._localize("confirm_restore_partial_backup_text"),
+ title: this._localize(
+ this._backupContent.backupType === "full"
+ ? "confirm_restore_full_backup_title"
+ : "confirm_restore_partial_backup_title"
+ ),
+ text: this._localize(
+ this._backupContent.backupType === "full"
+ ? "confirm_restore_full_backup_text"
+ : "confirm_restore_partial_backup_text"
+ ),
confirmText: this._localize("restore"),
dismissText: this._localize("cancel"),
}))
) {
+ this._restoringBackup = false;
return;
}
- if (!this._dialogParams?.onboarding) {
- try {
- await this.hass!.callApi(
- "POST",
-
- `hassio/${
- atLeastVersion(this.hass!.config.version, 2021, 9)
- ? "backups"
- : "snapshots"
- }/${this._backup!.slug}/restore/partial`,
- backupDetails
- );
- this.closeDialog();
- } catch (error: any) {
- this._error = error.body.message;
- }
- } else {
- this._dialogParams?.onRestoring?.();
- await fetch(`/api/hassio/backups/${this._backup!.slug}/restore/partial`, {
- method: "POST",
- body: JSON.stringify(backupDetails),
- });
- this.closeDialog();
- }
- }
-
- private async _fullRestoreClicked(backupDetails) {
- const supervisor = this._dialogParams?.supervisor;
- if (supervisor !== undefined && supervisor.info.state !== "running") {
- await showAlertDialog(this, {
- title: supervisor.localize("backup.could_not_restore"),
- text: supervisor.localize("backup.restore_blocked_not_running", {
- state: supervisor.info.state,
- }),
- });
- return;
- }
- if (
- !(await showConfirmationDialog(this, {
- title: this._localize("confirm_restore_full_backup_title"),
- text: this._localize("confirm_restore_full_backup_text"),
- confirmText: this._localize("restore"),
- dismissText: this._localize("cancel"),
- }))
- ) {
- return;
- }
-
- if (!this._dialogParams?.onboarding) {
- this.hass!.callApi(
- "POST",
- `hassio/${
- atLeastVersion(this.hass!.config.version, 2021, 9)
- ? "backups"
- : "snapshots"
- }/${this._backup!.slug}/restore/full`,
- backupDetails
- ).then(
- () => {
- this.closeDialog();
- },
- (error) => {
- this._error = error.body.message;
- }
+ try {
+ await restoreBackup(
+ this.hass,
+ this._backupContent.backupType,
+ this._backup!.slug,
+ backupDetails,
+ !!this.hass && atLeastVersion(this.hass.config.version, 2021, 9)
);
- } else {
+
this._dialogParams?.onRestoring?.();
- fetch(`/api/hassio/backups/${this._backup!.slug}/restore/full`, {
- method: "POST",
- body: JSON.stringify(backupDetails),
- });
this.closeDialog();
+ } catch (error: any) {
+ this._error =
+ error?.body?.message || this._localize("restore_start_failed");
+ } finally {
+ this._restoringBackup = false;
}
}
@@ -361,7 +301,36 @@ class HassioBackupDialog
private get _computeName() {
return this._backup
? this._backup.name || this._backup.slug
- : "Unnamed backup";
+ : this._localize("unnamed_backup");
+ }
+
+ static get styles(): CSSResultGroup {
+ return [
+ haStyle,
+ haStyleDialog,
+ css`
+ ha-circular-progress {
+ display: block;
+ text-align: center;
+ }
+ ha-header-bar {
+ --mdc-theme-on-primary: var(--primary-text-color);
+ --mdc-theme-primary: var(--mdc-theme-surface);
+ flex-shrink: 0;
+ display: block;
+ }
+ ha-icon-button {
+ color: var(--secondary-text-color);
+ }
+ .loading {
+ width: 100%;
+ display: flex;
+ height: 100%;
+ justify-content: center;
+ align-items: center;
+ }
+ `,
+ ];
}
}
diff --git a/src/components/ha-file-upload.ts b/src/components/ha-file-upload.ts
index 3c8eb6c775..7b588d09b0 100644
--- a/src/components/ha-file-upload.ts
+++ b/src/components/ha-file-upload.ts
@@ -15,6 +15,7 @@ import { bytesToString } from "../util/bytes-to-string";
declare global {
interface HASSDomEvents {
"file-picked": { files: File[] };
+ "files-cleared": void;
}
}
@@ -216,6 +217,7 @@ export class HaFileUpload extends LitElement {
this._input!.value = "";
this.value = undefined;
fireEvent(this, "change");
+ fireEvent(this, "files-cleared");
}
static get styles() {
diff --git a/src/data/hassio/backup.ts b/src/data/hassio/backup.ts
index f2f3abe1e1..8a88e1a5b9 100644
--- a/src/data/hassio/backup.ts
+++ b/src/data/hassio/backup.ts
@@ -1,5 +1,6 @@
import { atLeastVersion } from "../../common/config/version";
import type { HomeAssistant } from "../../types";
+import { handleFetchPromise } from "../../util/hass-call-api";
import type { HassioResponse } from "./common";
import { hassioApiResultExtractor } from "./common";
@@ -105,11 +106,13 @@ export const fetchHassioBackupInfo = async (
);
}
// When called from onboarding we don't have hass
- const resp = await fetch(`/api/hassio/backups/${backup}/info`, {
- method: "GET",
- });
- const data = (await resp.json()).data;
- return data;
+ return hassioApiResultExtractor(
+ await handleFetchPromise(
+ fetch(`/api/hassio/backups/${backup}/info`, {
+ method: "GET",
+ })
+ )
+ );
};
export const reloadHassioBackups = async (hass: HomeAssistant) => {
@@ -236,3 +239,26 @@ export const uploadBackup = async (
}
return resp.json();
};
+
+export const restoreBackup = async (
+ hass: HomeAssistant | undefined,
+ type: HassioBackupDetail["type"],
+ backupSlug: string,
+ backupDetails: HassioPartialBackupCreateParams | HassioFullBackupCreateParams,
+ useSnapshotUrl: boolean
+): Promise => {
+ if (hass) {
+ await hass.callApi>(
+ "POST",
+ `hassio/${useSnapshotUrl ? "snapshots" : "backups"}/${backupSlug}/restore/${type}`,
+ backupDetails
+ );
+ } else {
+ await handleFetchPromise(
+ fetch(`/api/hassio/backups/${backupSlug}/restore/${type}`, {
+ method: "POST",
+ body: JSON.stringify(backupDetails),
+ })
+ );
+ }
+};
diff --git a/src/onboarding/onboarding-restore-backup.ts b/src/onboarding/onboarding-restore-backup.ts
index 7832cb44ad..a02f51ff7c 100644
--- a/src/onboarding/onboarding-restore-backup.ts
+++ b/src/onboarding/onboarding-restore-backup.ts
@@ -1,12 +1,13 @@
-import "@material/mwc-button/mwc-button";
import type { CSSResultGroup, TemplateResult } from "lit";
-import { css, html, LitElement } from "lit";
+import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { showHassioBackupDialog } from "../../hassio/src/dialogs/backup/show-dialog-hassio-backup";
import "../../hassio/src/components/hassio-upload-backup";
import type { LocalizeFunc } from "../common/translations/localize";
import "../components/ha-ansi-to-html";
import "../components/ha-card";
+import "../components/ha-alert";
+import "../components/ha-button";
import { fetchInstallationType } from "../data/onboarding";
import type { HomeAssistant } from "../types";
import "./onboarding-loading";
@@ -16,32 +17,49 @@ import { navigate } from "../common/navigate";
@customElement("onboarding-restore-backup")
class OnboardingRestoreBackup extends LitElement {
- @property({ attribute: false }) public hass!: HomeAssistant;
+ @property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) public localize!: LocalizeFunc;
@property() public language!: string;
- @state() public _restoring = false;
+ @state() private _restoring = false;
+
+ @state() private _backupSlug?: string;
protected render(): TemplateResult {
- return html`${this._restoring
+ return html`
+ ${this._restoring
? html`
${this.localize("ui.panel.page-onboarding.restore.in_progress")}
+
+ ${this.localize("ui.panel.page-onboarding.restore.in_progress")}
+
`
: html`
${this.localize("ui.panel.page-onboarding.restore.header")}
`}
`;
+
+ ${this._backupSlug
+ ? html`
+ ${this.localize("ui.panel.page-onboarding.restore.restore")}
+ `
+ : nothing}
+
+ `;
}
private _back(): void {
@@ -50,12 +68,16 @@ class OnboardingRestoreBackup extends LitElement {
private _backupUploaded(ev) {
const backup = ev.detail.backup;
- this._showBackupDialog(backup.slug);
+ this._backupSlug = backup.slug;
+ this._showBackupDialog();
+ }
+
+ private _backupCleared() {
+ this._backupSlug = undefined;
}
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
- setInterval(() => this._checkRestoreStatus(), 1000);
}
private async _checkRestoreStatus(): Promise