mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-10 10:56:34 +00:00
Improve onboarding backup restore (#23340)
* Improve onboarding backup restore * Fix onboarding backup restore * Fix restoring value in onboarding-restore-backup
This commit is contained in:
parent
f1f53b9f24
commit
37aa2bd869
@ -1,7 +1,7 @@
|
||||
import { mdiFolderUpload } from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import "../../../src/components/ha-circular-progress";
|
||||
import "../../../src/components/ha-file-upload";
|
||||
@ -10,10 +10,12 @@ import { uploadBackup } from "../../../src/data/hassio/backup";
|
||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
||||
import type { HomeAssistant } from "../../../src/types";
|
||||
import type { LocalizeFunc } from "../../../src/common/translations/localize";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"backup-uploaded": { backup: HassioBackup };
|
||||
"backup-cleared": void;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +23,8 @@ declare global {
|
||||
export class HassioUploadBackup extends LitElement {
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public localize?: LocalizeFunc;
|
||||
|
||||
@state() public value: string | null = null;
|
||||
|
||||
@state() private _uploading = false;
|
||||
@ -32,13 +36,26 @@ export class HassioUploadBackup extends LitElement {
|
||||
.uploading=${this._uploading}
|
||||
.icon=${mdiFolderUpload}
|
||||
accept="application/x-tar"
|
||||
label="Upload backup"
|
||||
supports="Supports .TAR files"
|
||||
.label=${this.localize?.(
|
||||
"ui.panel.page-onboarding.restore.upload_backup"
|
||||
) || "Upload backup"}
|
||||
.supports=${this.localize?.(
|
||||
"ui.panel.page-onboarding.restore.upload_supports"
|
||||
) || "Supports .TAR files"}
|
||||
.secondary=${this.localize?.(
|
||||
"ui.panel.page-onboarding.restore.upload_drop"
|
||||
) || "Or drop your file here"}
|
||||
@file-picked=${this._uploadFile}
|
||||
@files-cleared=${this._clear}
|
||||
></ha-file-upload>
|
||||
`;
|
||||
}
|
||||
|
||||
private _clear() {
|
||||
this.value = null;
|
||||
fireEvent(this, "backup-cleared");
|
||||
}
|
||||
|
||||
private async _uploadFile(ev) {
|
||||
const file = ev.detail.files[0];
|
||||
|
||||
|
@ -65,7 +65,7 @@ const _computeAddons = (addons): AddonCheckboxItem[] =>
|
||||
|
||||
@customElement("supervisor-backup-content")
|
||||
export class SupervisorBackupContent extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public localize?: LocalizeFunc;
|
||||
|
||||
@ -186,12 +186,13 @@ export class SupervisorBackupContent extends LitElement {
|
||||
.iconPath=${mdiHomeAssistant}
|
||||
.version=${this.backup
|
||||
? this.backup.homeassistant
|
||||
: this.hass.config.version}
|
||||
: this.hass?.config.version}
|
||||
>
|
||||
</supervisor-formfield-label>`}
|
||||
>
|
||||
<ha-checkbox
|
||||
.checked=${this.homeAssistant}
|
||||
.checked=${this.onboarding || this.homeAssistant}
|
||||
.disabled=${this.onboarding}
|
||||
@change=${this._toggleHomeAssistant}
|
||||
>
|
||||
</ha-checkbox>
|
||||
@ -334,7 +335,7 @@ export class SupervisorBackupContent extends LitElement {
|
||||
| HassioFullBackupCreateParams {
|
||||
const data: any = {};
|
||||
|
||||
if (!this.backup) {
|
||||
if (!this.backup && this.hass) {
|
||||
data.name =
|
||||
this.backupName ||
|
||||
formatDate(new Date(), this.hass.locale, this.hass.config);
|
||||
@ -364,7 +365,9 @@ export class SupervisorBackupContent extends LitElement {
|
||||
if (folders?.length) {
|
||||
data.folders = folders;
|
||||
}
|
||||
data.homeassistant = this.homeAssistant;
|
||||
|
||||
// onboarding needs at least homeassistant to restore
|
||||
data.homeassistant = this.onboarding || this.homeAssistant;
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -386,6 +389,7 @@ export class SupervisorBackupContent extends LitElement {
|
||||
.iconPath=${section === "addons" ? mdiPuzzle : mdiFolder}
|
||||
.imageUrl=${section === "addons" &&
|
||||
!this.onboarding &&
|
||||
this.hass &&
|
||||
atLeastVersion(this.hass.config.version, 0, 105) &&
|
||||
addons?.get(item.slug)?.icon
|
||||
? `/api/hassio/addons/${item.slug}/icon`
|
||||
|
@ -8,9 +8,11 @@ import { atLeastVersion } from "../../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../../src/common/dom/stop_propagation";
|
||||
import { slugify } from "../../../../src/common/string/slugify";
|
||||
import "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-md-dialog";
|
||||
import "../../../../src/components/ha-dialog-header";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-button";
|
||||
import "../../../../src/components/ha-button-menu";
|
||||
import "../../../../src/components/ha-header-bar";
|
||||
import "../../../../src/components/ha-icon-button";
|
||||
@ -19,6 +21,7 @@ import type { HassioBackupDetail } from "../../../../src/data/hassio/backup";
|
||||
import {
|
||||
fetchHassioBackupInfo,
|
||||
removeBackup,
|
||||
restoreBackup,
|
||||
} from "../../../../src/data/hassio/backup";
|
||||
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||
import {
|
||||
@ -33,6 +36,7 @@ import "../../components/supervisor-backup-content";
|
||||
import type { SupervisorBackupContent } from "../../components/supervisor-backup-content";
|
||||
import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup";
|
||||
import type { BackupOrRestoreKey } from "../../util/translations";
|
||||
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
||||
|
||||
@customElement("dialog-hassio-backup")
|
||||
class HassioBackupDialog
|
||||
@ -52,13 +56,20 @@ class HassioBackupDialog
|
||||
@query("supervisor-backup-content")
|
||||
private _backupContent!: SupervisorBackupContent;
|
||||
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
|
||||
public async showDialog(dialogParams: HassioBackupDialogParams) {
|
||||
this._backup = await fetchHassioBackupInfo(this.hass, dialogParams.slug);
|
||||
this._dialogParams = dialogParams;
|
||||
this._backup = await fetchHassioBackupInfo(this.hass, dialogParams.slug);
|
||||
if (!this._backup) {
|
||||
this._error = this._localize("no_backup_found");
|
||||
} else if (this._dialogParams.onboarding && !this._backup.homeassistant) {
|
||||
this._error = this._localize("restore_no_home_assistant");
|
||||
}
|
||||
this._restoringBackup = false;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
private _dialogClosed(): void {
|
||||
this._backup = undefined;
|
||||
this._dialogParams = undefined;
|
||||
this._restoringBackup = false;
|
||||
@ -66,6 +77,10 @@ class HassioBackupDialog
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._dialog?.close();
|
||||
}
|
||||
|
||||
private _localize(key: BackupOrRestoreKey) {
|
||||
return (
|
||||
this._dialogParams!.supervisor?.localize(`backup.${key}`) ||
|
||||
@ -78,100 +93,80 @@ class HassioBackupDialog
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
<ha-dialog
|
||||
<ha-md-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${this._backup.name}
|
||||
.disableCancelAction=${!this._error}
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<div slot="heading">
|
||||
<ha-header-bar>
|
||||
<span slot="title">${this._backup.name}</span>
|
||||
<ha-icon-button
|
||||
.label=${this._localize("close")}
|
||||
.path=${mdiClose}
|
||||
slot="actionItems"
|
||||
dialogAction="cancel"
|
||||
></ha-icon-button>
|
||||
</ha-header-bar>
|
||||
<ha-dialog-header slot="headline">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
.label=${this._localize("close")}
|
||||
.path=${mdiClose}
|
||||
@click=${this.closeDialog}
|
||||
.disabled=${this._restoringBackup}
|
||||
></ha-icon-button>
|
||||
<span slot="title" .title=${this._backup.name}
|
||||
>${this._backup.name}</span
|
||||
>
|
||||
${!this._dialogParams.onboarding && this._dialogParams.supervisor
|
||||
? html`<ha-button-menu
|
||||
slot="actionItems"
|
||||
fixed
|
||||
@action=${this._handleMenuAction}
|
||||
@closed=${stopPropagation}
|
||||
>
|
||||
<ha-icon-button
|
||||
.label=${this._dialogParams.supervisor.localize(
|
||||
"backup.more_actions"
|
||||
)}
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item
|
||||
>${this._dialogParams.supervisor.localize(
|
||||
"backup.download_backup"
|
||||
)}</mwc-list-item
|
||||
>
|
||||
<mwc-list-item class="error"
|
||||
>${this._dialogParams.supervisor.localize(
|
||||
"backup.delete_backup_title"
|
||||
)}</mwc-list-item
|
||||
>
|
||||
</ha-button-menu>`
|
||||
: nothing}
|
||||
</ha-dialog-header>
|
||||
<div slot="content">
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: this._restoringBackup
|
||||
? html`<div class="loading">
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>`
|
||||
: html`
|
||||
<supervisor-backup-content
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this._dialogParams.supervisor}
|
||||
.backup=${this._backup}
|
||||
.onboarding=${this._dialogParams.onboarding || false}
|
||||
.localize=${this._dialogParams.localize}
|
||||
dialogInitialFocus
|
||||
>
|
||||
</supervisor-backup-content>
|
||||
`}
|
||||
</div>
|
||||
${this._restoringBackup
|
||||
? html`<ha-circular-progress indeterminate></ha-circular-progress>`
|
||||
: html`
|
||||
<supervisor-backup-content
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this._dialogParams.supervisor}
|
||||
.backup=${this._backup}
|
||||
.onboarding=${this._dialogParams.onboarding || false}
|
||||
.localize=${this._dialogParams.localize}
|
||||
dialogInitialFocus
|
||||
>
|
||||
</supervisor-backup-content>
|
||||
`}
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: nothing}
|
||||
|
||||
<mwc-button
|
||||
.disabled=${this._restoringBackup}
|
||||
slot="secondaryAction"
|
||||
@click=${this._restoreClicked}
|
||||
>
|
||||
${this._localize("restore")}
|
||||
</mwc-button>
|
||||
|
||||
${!this._dialogParams.onboarding && this._dialogParams.supervisor
|
||||
? html`<ha-button-menu
|
||||
fixed
|
||||
slot="primaryAction"
|
||||
@action=${this._handleMenuAction}
|
||||
@closed=${stopPropagation}
|
||||
>
|
||||
<ha-icon-button
|
||||
.label=${this._dialogParams.supervisor.localize(
|
||||
"backup.more_actions"
|
||||
)}
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item
|
||||
>${this._dialogParams.supervisor.localize(
|
||||
"backup.download_backup"
|
||||
)}</mwc-list-item
|
||||
>
|
||||
<mwc-list-item class="error"
|
||||
>${this._dialogParams.supervisor.localize(
|
||||
"backup.delete_backup_title"
|
||||
)}</mwc-list-item
|
||||
>
|
||||
</ha-button-menu>`
|
||||
: nothing}
|
||||
</ha-dialog>
|
||||
<div slot="actions">
|
||||
<ha-button
|
||||
.disabled=${this._restoringBackup || !!this._error}
|
||||
@click=${this._restoreClicked}
|
||||
>
|
||||
${this._localize("restore")}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
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<ActionDetail>) {
|
||||
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;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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<void> => {
|
||||
if (hass) {
|
||||
await hass.callApi<HassioResponse<{ job_id: string }>>(
|
||||
"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),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -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`<h1>
|
||||
${this.localize("ui.panel.page-onboarding.restore.in_progress")}
|
||||
</h1>
|
||||
<ha-alert alert-type="info">
|
||||
${this.localize("ui.panel.page-onboarding.restore.in_progress")}
|
||||
</ha-alert>
|
||||
<onboarding-loading></onboarding-loading>`
|
||||
: html` <h1>
|
||||
${this.localize("ui.panel.page-onboarding.restore.header")}
|
||||
</h1>
|
||||
<hassio-upload-backup
|
||||
@backup-uploaded=${this._backupUploaded}
|
||||
@backup-cleared=${this._backupCleared}
|
||||
.hass=${this.hass}
|
||||
.localize=${this.localize}
|
||||
></hassio-upload-backup>`}
|
||||
<div class="footer">
|
||||
<mwc-button @click=${this._back} .disabled=${this._restoring}>
|
||||
<ha-button @click=${this._back} .disabled=${this._restoring}>
|
||||
${this.localize("ui.panel.page-onboarding.back")}
|
||||
</mwc-button>
|
||||
</div> `;
|
||||
</ha-button>
|
||||
${this._backupSlug
|
||||
? html`<ha-button
|
||||
@click=${this._showBackupDialog}
|
||||
.disabled=${this._restoring}
|
||||
>
|
||||
${this.localize("ui.panel.page-onboarding.restore.restore")}
|
||||
</ha-button>`
|
||||
: nothing}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
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<void> {
|
||||
@ -73,13 +95,18 @@ class OnboardingRestoreBackup extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _showBackupDialog(slug: string): void {
|
||||
private _scheduleCheckRestoreStatus(): void {
|
||||
setTimeout(() => this._checkRestoreStatus(), 1000);
|
||||
}
|
||||
|
||||
private _showBackupDialog(): void {
|
||||
showHassioBackupDialog(this, {
|
||||
slug,
|
||||
slug: this._backupSlug!,
|
||||
onboarding: true,
|
||||
localize: this.localize,
|
||||
onRestoring: () => {
|
||||
this._restoring = true;
|
||||
this._scheduleCheckRestoreStatus();
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -97,8 +124,9 @@ class OnboardingRestoreBackup extends LitElement {
|
||||
width: 100%;
|
||||
}
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -7587,7 +7587,10 @@
|
||||
"restore": {
|
||||
"header": "Restore a backup",
|
||||
"in_progress": "Restore in progress",
|
||||
"failed": "Restore failed",
|
||||
"upload_backup": "[%key:supervisor::backup::upload_backup%]",
|
||||
"upload_supports": "Supports .TAR files",
|
||||
"upload_drop": "[%key:ui::components::file-upload::secondary%]",
|
||||
"show_log": "Show full log",
|
||||
"hide_log": "Hide full log",
|
||||
"full_backup": "[%key:supervisor::backup::full_backup%]",
|
||||
@ -7601,12 +7604,17 @@
|
||||
"password": "[%key:supervisor::backup::password%]",
|
||||
"confirm_password": "[%key:supervisor::backup::confirm_password%]",
|
||||
"confirm_restore_partial_backup_title": "[%key:supervisor::backup::confirm_restore_partial_backup_title%]",
|
||||
"confirm_restore_partial_backup_text": "[%key:supervisor::backup::confirm_restore_partial_backup_text%]",
|
||||
"confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again and you see the login screen. If it fails it will bring you back to the onboarding.",
|
||||
"confirm_restore_full_backup_title": "[%key:supervisor::backup::confirm_restore_full_backup_title%]",
|
||||
"confirm_restore_full_backup_text": "[%key:supervisor::backup::confirm_restore_full_backup_text%]",
|
||||
"confirm_restore_full_backup_text": "Your entire system will be wiped and the backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again and you see the login screen. If it fails it will bring you back to the onboarding.",
|
||||
"restore": "[%key:supervisor::backup::restore%]",
|
||||
"close": "[%key:ui::common::close%]",
|
||||
"cancel": "[%key:ui::common::cancel%]"
|
||||
"cancel": "[%key:ui::common::cancel%]",
|
||||
"retry": "Retry",
|
||||
"restore_start_failed": "[%key:supervisor::backup::restore_start_failed%]",
|
||||
"no_backup_found": "[%key:supervisor::backup::no_backup_found%]",
|
||||
"restore_no_home_assistant": "[%key:supervisor::backup::restore_no_home_assistant%]",
|
||||
"unnamed_backup": "[%key:supervisor::backup::unnamed_backup%]"
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
@ -8092,16 +8100,16 @@
|
||||
"addons": "Add-ons",
|
||||
"folders": "Folders",
|
||||
"size": "Size",
|
||||
"password": "Backup password",
|
||||
"confirm_password": "Confirm backup password",
|
||||
"password": "Backup encryption key",
|
||||
"confirm_password": "Confirm encryption key",
|
||||
"password_protection": "Password protection",
|
||||
"enter_password": "Please enter a password.",
|
||||
"passwords_not_matching": "The passwords does not match",
|
||||
"backup_already_running": "A backup or restore is already running. Creating a new backup is currently not possible, try again later.",
|
||||
"confirm_restore_partial_backup_title": "Restore partial backup",
|
||||
"confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min.",
|
||||
"confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.",
|
||||
"confirm_restore_full_backup_title": "Restore full backup",
|
||||
"confirm_restore_full_backup_text": "Your entire system will be wiped and the backup will be restored. Depending on the size of the backup, this can take up to 45 min.",
|
||||
"confirm_restore_full_backup_text": "Your entire system will be wiped and the backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.",
|
||||
"confirm_delete_title": "Delete backup",
|
||||
"confirm_delete_text": "This backup will be permanently deleted and cannot be restored later.",
|
||||
"restore": "Restore",
|
||||
@ -8111,7 +8119,11 @@
|
||||
"download": "Download",
|
||||
"more_actions": "More actions",
|
||||
"remote_download_title": "Potentially slow download",
|
||||
"remote_download_text": "You are accessing Home Assistant via remote access. Downloading backups over the Nabu Casa URL will take some time. If you are at home, cancel this dialog and enter your local URL, such as 'http://homeassistant.local:8123'"
|
||||
"remote_download_text": "You are accessing Home Assistant via remote access. Downloading backups over the Nabu Casa URL will take some time. If you are at home, cancel this dialog and enter your local URL, such as 'http://homeassistant.local:8123'",
|
||||
"restore_start_failed": "Failed to start restore. Unknown error.",
|
||||
"no_backup_found": "No backup found.",
|
||||
"restore_no_home_assistant": "Backup does not contain Home Assistant data. To restore Home Assistant you need a backup of Home Assistant core.",
|
||||
"unnamed_backup": "Unnamed backup"
|
||||
},
|
||||
"dialog": {
|
||||
"network": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user