diff --git a/build-scripts/gulp/gather-static.js b/build-scripts/gulp/gather-static.js index 3361cf798d..e156c84825 100644 --- a/build-scripts/gulp/gather-static.js +++ b/build-scripts/gulp/gather-static.js @@ -12,8 +12,10 @@ const polyPath = (...parts) => path.resolve(paths.polymer_dir, ...parts); const copyFileDir = (fromFile, toDir) => fs.copySync(fromFile, path.join(toDir, path.basename(fromFile))); -const genStaticPath = (staticDir) => (...parts) => - path.resolve(staticDir, ...parts); +const genStaticPath = + (staticDir) => + (...parts) => + path.resolve(staticDir, ...parts); function copyTranslations(staticDir) { const staticPath = genStaticPath(staticDir); diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index d42c6a7292..3f7cb4375d 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -987,7 +987,7 @@ class HassioAddonInfo extends LitElement { supervisor: this.supervisor, name: this.addon.name, version: this.addon.version_latest, - snapshotParams: { + backupParams: { name: `addon_${this.addon.slug}_${this.addon.version}`, addons: [this.addon.slug], homeassistant: false, diff --git a/hassio/src/snapshots/hassio-snapshots.ts b/hassio/src/backups/hassio-backups.ts similarity index 69% rename from hassio/src/snapshots/hassio-snapshots.ts rename to hassio/src/backups/hassio-backups.ts index 56c527b667..e5e98c7c35 100644 --- a/hassio/src/snapshots/hassio-snapshots.ts +++ b/hassio/src/backups/hassio-backups.ts @@ -25,12 +25,12 @@ import "../../../src/components/ha-button-menu"; import "../../../src/components/ha-fab"; import { extractApiErrorMessage } from "../../../src/data/hassio/common"; import { - fetchHassioSnapshots, + fetchHassioBackups, friendlyFolderName, - HassioSnapshot, - reloadHassioSnapshots, - removeSnapshot, -} from "../../../src/data/hassio/snapshot"; + HassioBackup, + reloadHassioBackups, + removeBackup, +} from "../../../src/data/hassio/backup"; import { Supervisor } from "../../../src/data/supervisor/supervisor"; import { showAlertDialog, @@ -40,14 +40,14 @@ import "../../../src/layouts/hass-tabs-subpage-data-table"; import type { HaTabsSubpageDataTable } from "../../../src/layouts/hass-tabs-subpage-data-table"; import { haStyle } from "../../../src/resources/styles"; import { HomeAssistant, Route } from "../../../src/types"; -import { showHassioCreateSnapshotDialog } from "../dialogs/snapshot/show-dialog-hassio-create-snapshot"; -import { showHassioSnapshotDialog } from "../dialogs/snapshot/show-dialog-hassio-snapshot"; -import { showSnapshotUploadDialog } from "../dialogs/snapshot/show-dialog-snapshot-upload"; +import { showHassioCreateBackupDialog } from "../dialogs/backup/show-dialog-hassio-create-backup"; +import { showHassioBackupDialog } from "../dialogs/backup/show-dialog-hassio-backup"; +import { showBackupUploadDialog } from "../dialogs/backup/show-dialog-backup-upload"; import { supervisorTabs } from "../hassio-tabs"; import { hassioStyle } from "../resources/hassio-style"; -@customElement("hassio-snapshots") -export class HassioSnapshots extends LitElement { +@customElement("hassio-backups") +export class HassioBackups extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public supervisor!: Supervisor; @@ -58,9 +58,9 @@ export class HassioSnapshots extends LitElement { @property({ type: Boolean }) public isWide!: boolean; - @state() private _selectedSnapshots: string[] = []; + @state() private _selectedBackups: string[] = []; - @state() private _snapshots?: HassioSnapshot[] = []; + @state() private _backups?: HassioBackup[] = []; @query("hass-tabs-subpage-data-table", true) private _dataTable!: HaTabsSubpageDataTable; @@ -75,26 +75,26 @@ export class HassioSnapshots extends LitElement { } public async refreshData() { - await reloadHassioSnapshots(this.hass); - await this.fetchSnapshots(); + await reloadHassioBackups(this.hass); + await this.fetchBackups(); } - private _computeSnapshotContent = (snapshot: HassioSnapshot): string => { - if (snapshot.type === "full") { - return this.supervisor.localize("snapshot.full_snapshot"); + private _computeBackupContent = (backup: HassioBackup): string => { + if (backup.type === "full") { + return this.supervisor.localize("backup.full_backup"); } const content: string[] = []; - if (snapshot.content.homeassistant) { + if (backup.content.homeassistant) { content.push("Home Assistant"); } - if (snapshot.content.folders.length !== 0) { - for (const folder of snapshot.content.folders) { + if (backup.content.folders.length !== 0) { + for (const folder of backup.content.folders) { content.push(friendlyFolderName[folder] || folder); } } - if (snapshot.content.addons.length !== 0) { - for (const addon of snapshot.content.addons) { + if (backup.content.addons.length !== 0) { + for (const addon of backup.content.addons) { content.push( this.supervisor.supervisor.addons.find( (entry) => entry.slug === addon @@ -117,16 +117,16 @@ export class HassioSnapshots extends LitElement { private _columns = memoizeOne( (narrow: boolean): DataTableColumnContainer => ({ name: { - title: this.supervisor?.localize("snapshot.name") || "", + title: this.supervisor?.localize("backup.name") || "", sortable: true, filterable: true, grows: true, - template: (entry: string, snapshot: any) => - html`${entry || snapshot.slug} -
${snapshot.secondary}
`, + template: (entry: string, backup: any) => + html`${entry || backup.slug} +
${backup.secondary}
`, }, date: { - title: this.supervisor?.localize("snapshot.created") || "", + title: this.supervisor?.localize("backup.created") || "", width: "15%", direction: "desc", hidden: narrow, @@ -143,10 +143,10 @@ export class HassioSnapshots extends LitElement { }) ); - private _snapshotData = memoizeOne((snapshots: HassioSnapshot[]) => - snapshots.map((snapshot) => ({ - ...snapshot, - secondary: this._computeSnapshotContent(snapshot), + private _backupData = memoizeOne((backups: HassioBackup[]) => + backups.map((backup) => ({ + ...backup, + secondary: this._computeBackupContent(backup), })) ); @@ -160,11 +160,11 @@ export class HassioSnapshots extends LitElement { .hass=${this.hass} .localizeFunc=${this.supervisor.localize} .searchLabel=${this.supervisor.localize("search")} - .noDataText=${this.supervisor.localize("snapshot.no_snapshots")} + .noDataText=${this.supervisor.localize("backup.no_backups")} .narrow=${this.narrow} .route=${this.route} .columns=${this._columns(this.narrow)} - .data=${this._snapshotData(this._snapshots || [])} + .data=${this._backupData(this._backups || [])} id="slug" @row-click=${this._handleRowClicked} @selection-changed=${this._handleSelectionChanged} @@ -187,12 +187,12 @@ export class HassioSnapshots extends LitElement { ${atLeastVersion(this.hass.config.version, 0, 116) ? html` - ${this.supervisor?.localize("snapshot.upload_snapshot")} + ${this.supervisor?.localize("backup.upload_backup")} ` : ""} - ${this._selectedSnapshots.length + ${this._selectedBackups.length ? html`

- ${this.supervisor.localize("snapshot.selected", { - number: this._selectedSnapshots.length, + ${this.supervisor.localize("backup.selected", { + number: this._selectedBackups.length, })}

@@ -212,7 +212,7 @@ export class HassioSnapshots extends LitElement { @click=${this._deleteSelected} class="warning" > - ${this.supervisor.localize("snapshot.delete_selected")} + ${this.supervisor.localize("backup.delete_selected")} ` : html` @@ -224,7 +224,7 @@ export class HassioSnapshots extends LitElement { - ${this.supervisor.localize("snapshot.delete_selected")} + ${this.supervisor.localize("backup.delete_selected")} `}
@@ -233,8 +233,8 @@ export class HassioSnapshots extends LitElement { @@ -249,7 +249,7 @@ export class HassioSnapshots extends LitElement { this.refreshData(); break; case 1: - this._showUploadSnapshotDialog(); + this._showUploadBackupDialog(); break; } } @@ -257,33 +257,33 @@ export class HassioSnapshots extends LitElement { private _handleSelectionChanged( ev: HASSDomEvent ): void { - this._selectedSnapshots = ev.detail.value; + this._selectedBackups = ev.detail.value; } - private _showUploadSnapshotDialog() { - showSnapshotUploadDialog(this, { - showSnapshot: (slug: string) => - showHassioSnapshotDialog(this, { + private _showUploadBackupDialog() { + showBackupUploadDialog(this, { + showBackup: (slug: string) => + showHassioBackupDialog(this, { slug, supervisor: this.supervisor, - onDelete: () => this.fetchSnapshots(), + onDelete: () => this.fetchBackups(), }), - reloadSnapshot: () => this.refreshData(), + reloadBackup: () => this.refreshData(), }); } - private async fetchSnapshots() { - await reloadHassioSnapshots(this.hass); - this._snapshots = await fetchHassioSnapshots(this.hass); + private async fetchBackups() { + await reloadHassioBackups(this.hass); + this._backups = await fetchHassioBackups(this.hass); } private async _deleteSelected() { const confirm = await showConfirmationDialog(this, { - title: this.supervisor.localize("snapshot.delete_snapshot_title"), - text: this.supervisor.localize("snapshot.delete_snapshot_text", { - number: this._selectedSnapshots.length, + title: this.supervisor.localize("backup.delete_backup_title"), + text: this.supervisor.localize("backup.delete_backup_text", { + number: this._selectedBackups.length, }), - confirmText: this.supervisor.localize("snapshot.delete_snapshot_confirm"), + confirmText: this.supervisor.localize("backup.delete_backup_confirm"), }); if (!confirm) { @@ -292,44 +292,44 @@ export class HassioSnapshots extends LitElement { try { await Promise.all( - this._selectedSnapshots.map((slug) => removeSnapshot(this.hass, slug)) + this._selectedBackups.map((slug) => removeBackup(this.hass, slug)) ); } catch (err) { showAlertDialog(this, { - title: this.supervisor.localize("snapshot.failed_to_delete"), + title: this.supervisor.localize("backup.failed_to_delete"), text: extractApiErrorMessage(err), }); return; } - await reloadHassioSnapshots(this.hass); - this._snapshots = await fetchHassioSnapshots(this.hass); + await reloadHassioBackups(this.hass); + this._backups = await fetchHassioBackups(this.hass); this._dataTable.clearSelection(); } private _handleRowClicked(ev: HASSDomEvent) { const slug = ev.detail.id; - showHassioSnapshotDialog(this, { + showHassioBackupDialog(this, { slug, supervisor: this.supervisor, - onDelete: () => this.fetchSnapshots(), + onDelete: () => this.fetchBackups(), }); } - private _createSnapshot() { + private _createBackup() { if (this.supervisor!.info.state !== "running") { showAlertDialog(this, { - title: this.supervisor!.localize("snapshot.could_not_create"), + title: this.supervisor!.localize("backup.could_not_create"), text: this.supervisor!.localize( - "snapshot.create_blocked_not_running", + "backup.create_blocked_not_running", "state", this.supervisor!.info.state ), }); return; } - showHassioCreateSnapshotDialog(this, { + showHassioCreateBackupDialog(this, { supervisor: this.supervisor!, - onCreate: () => this.fetchSnapshots(), + onCreate: () => this.fetchBackups(), }); } @@ -378,6 +378,6 @@ export class HassioSnapshots extends LitElement { declare global { interface HTMLElementTagNameMap { - "hassio-snapshots": HassioSnapshots; + "hassio-backups": HassioBackups; } } diff --git a/hassio/src/components/hassio-card-content.ts b/hassio/src/components/hassio-card-content.ts index d4b9508009..9d5e420b4c 100644 --- a/hassio/src/components/hassio-card-content.ts +++ b/hassio/src/components/hassio-card-content.ts @@ -87,7 +87,7 @@ class HassioCardContent extends LitElement { color: var(--paper-green-400); } ha-svg-icon.hassupdate, - ha-svg-icon.snapshot { + ha-svg-icon.backup { color: var(--paper-item-icon-color); } ha-svg-icon.not_available { diff --git a/hassio/src/components/hassio-upload-snapshot.ts b/hassio/src/components/hassio-upload-backup.ts similarity index 77% rename from hassio/src/components/hassio-upload-snapshot.ts rename to hassio/src/components/hassio-upload-backup.ts index 4677231c85..619e35d4e2 100644 --- a/hassio/src/components/hassio-upload-snapshot.ts +++ b/hassio/src/components/hassio-upload-backup.ts @@ -8,23 +8,20 @@ import "../../../src/components/ha-circular-progress"; import "../../../src/components/ha-file-upload"; import "../../../src/components/ha-svg-icon"; import { extractApiErrorMessage } from "../../../src/data/hassio/common"; -import { - HassioSnapshot, - uploadSnapshot, -} from "../../../src/data/hassio/snapshot"; +import { HassioBackup, uploadBackup } from "../../../src/data/hassio/backup"; import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../../../src/types"; declare global { interface HASSDomEvents { - "snapshot-uploaded": { snapshot: HassioSnapshot }; + "backup-uploaded": { backup: HassioBackup }; } } const MAX_FILE_SIZE = 1 * 1024 * 1024 * 1024; // 1GB -@customElement("hassio-upload-snapshot") -export class HassioUploadSnapshot extends LitElement { +@customElement("hassio-upload-backup") +export class HassioUploadBackup extends LitElement { public hass!: HomeAssistant; @state() public value: string | null = null; @@ -37,7 +34,7 @@ export class HassioUploadSnapshot extends LitElement { .uploading=${this._uploading} .icon=${mdiFolderUpload} accept="application/x-tar" - label="Upload snapshot" + label="Upload backup" @file-picked=${this._uploadFile} auto-open-file-dialog > @@ -49,10 +46,10 @@ export class HassioUploadSnapshot extends LitElement { if (file.size > MAX_FILE_SIZE) { showAlertDialog(this, { - title: "Snapshot file is too big", + title: "Backup file is too big", text: html`The maximum allowed filesize is 1GB.
Have a look here on how to restore it.`, @@ -64,15 +61,15 @@ export class HassioUploadSnapshot extends LitElement { if (!["application/x-tar"].includes(file.type)) { showAlertDialog(this, { title: "Unsupported file format", - text: "Please choose a Home Assistant snapshot file (.tar)", + text: "Please choose a Home Assistant backup file (.tar)", confirmText: "ok", }); return; } this._uploading = true; try { - const snapshot = await uploadSnapshot(this.hass, file); - fireEvent(this, "snapshot-uploaded", { snapshot: snapshot.data }); + const backup = await uploadBackup(this.hass, file); + fireEvent(this, "backup-uploaded", { backup: backup.data }); } catch (err) { showAlertDialog(this, { title: "Upload failed", @@ -87,6 +84,6 @@ export class HassioUploadSnapshot extends LitElement { declare global { interface HTMLElementTagNameMap { - "hassio-upload-snapshot": HassioUploadSnapshot; + "hassio-upload-backup": HassioUploadBackup; } } diff --git a/hassio/src/components/supervisor-snapshot-content.ts b/hassio/src/components/supervisor-backup-content.ts similarity index 76% rename from hassio/src/components/supervisor-snapshot-content.ts rename to hassio/src/components/supervisor-backup-content.ts index b420f00959..ac55733ace 100644 --- a/hassio/src/components/supervisor-snapshot-content.ts +++ b/hassio/src/components/supervisor-backup-content.ts @@ -11,10 +11,10 @@ import "../../../src/components/ha-formfield"; import "../../../src/components/ha-radio"; import type { HaRadio } from "../../../src/components/ha-radio"; import { - HassioFullSnapshotCreateParams, - HassioPartialSnapshotCreateParams, - HassioSnapshotDetail, -} from "../../../src/data/hassio/snapshot"; + HassioFullBackupCreateParams, + HassioPartialBackupCreateParams, + HassioBackupDetail, +} from "../../../src/data/hassio/backup"; import { Supervisor } from "../../../src/data/supervisor/supervisor"; import { PolymerChangedEvent } from "../../../src/polymer-types"; import { HomeAssistant } from "../../../src/types"; @@ -64,17 +64,17 @@ const _computeAddons = (addons): AddonCheckboxItem[] => })) .sort((a, b) => (a.name > b.name ? 1 : -1)); -@customElement("supervisor-snapshot-content") -export class SupervisorSnapshotContent extends LitElement { +@customElement("supervisor-backup-content") +export class SupervisorBackupContent extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property() public localize?: LocalizeFunc; @property({ attribute: false }) public supervisor?: Supervisor; - @property({ attribute: false }) public snapshot?: HassioSnapshotDetail; + @property({ attribute: false }) public backup?: HassioBackupDetail; - @property() public snapshotType: HassioSnapshotDetail["type"] = "full"; + @property() public backupType: HassioBackupDetail["type"] = "full"; @property({ attribute: false }) public folders?: CheckboxItem[]; @@ -82,37 +82,35 @@ export class SupervisorSnapshotContent extends LitElement { @property({ type: Boolean }) public homeAssistant = false; - @property({ type: Boolean }) public snapshotHasPassword = false; + @property({ type: Boolean }) public backupHasPassword = false; @property({ type: Boolean }) public onboarding = false; - @property() public snapshotName = ""; + @property() public backupName = ""; - @property() public snapshotPassword = ""; + @property() public backupPassword = ""; - @property() public confirmSnapshotPassword = ""; + @property() public confirmBackupPassword = ""; public willUpdate(changedProps) { super.willUpdate(changedProps); if (!this.hasUpdated) { this.folders = _computeFolders( - this.snapshot - ? this.snapshot.folders + this.backup + ? this.backup.folders : ["homeassistant", "ssl", "share", "media", "addons/local"] ); this.addons = _computeAddons( - this.snapshot - ? this.snapshot.addons - : this.supervisor?.supervisor.addons + this.backup ? this.backup.addons : this.supervisor?.supervisor.addons ); - this.snapshotType = this.snapshot?.type || "full"; - this.snapshotName = this.snapshot?.name || ""; - this.snapshotHasPassword = this.snapshot?.protected || false; + this.backupType = this.backup?.type || "full"; + this.backupName = this.backup?.name || ""; + this.backupHasPassword = this.backup?.protected || false; } } private _localize = (string: string) => - this.supervisor?.localize(`snapshot.${string}`) || + this.supervisor?.localize(`backup.${string}`) || this.localize!(`ui.panel.page-onboarding.restore.${string}`); protected render(): TemplateResult { @@ -120,64 +118,64 @@ export class SupervisorSnapshotContent extends LitElement { return html``; } const foldersSection = - this.snapshotType === "partial" ? this._getSection("folders") : undefined; + this.backupType === "partial" ? this._getSection("folders") : undefined; const addonsSection = - this.snapshotType === "partial" ? this._getSection("addons") : undefined; + this.backupType === "partial" ? this._getSection("addons") : undefined; return html` - ${this.snapshot + ${this.backup ? html`
- ${this.snapshot.type === "full" - ? this._localize("full_snapshot") - : this._localize("partial_snapshot")} - (${Math.ceil(this.snapshot.size * 10) / 10 + " MB"})
+ ${this.backup.type === "full" + ? this._localize("full_backup") + : this._localize("partial_backup")} + (${Math.ceil(this.backup.size * 10) / 10 + " MB"})
${this.hass - ? formatDateTime(new Date(this.snapshot.date), this.hass.locale) - : this.snapshot.date} + ? formatDateTime(new Date(this.backup.date), this.hass.locale) + : this.backup.date}
` : html` `} - ${!this.snapshot || this.snapshot.type === "full" + ${!this.backup || this.backup.type === "full" ? html`
- ${!this.snapshot + ${!this.backup ? this._localize("type") : this._localize("select_type")}
-
- +
+ - +
` : ""} - ${this.snapshotType === "partial" + ${this.backupType === "partial" ? html`
- ${this.snapshot && this.snapshot.homeassistant + ${this.backup && this.backup.homeassistant ? html` `} > @@ -233,38 +231,38 @@ export class SupervisorSnapshotContent extends LitElement { : ""}
` : ""} - ${this.snapshotType === "partial" && - (!this.snapshot || this.snapshotHasPassword) + ${this.backupType === "partial" && + (!this.backup || this.backupHasPassword) ? html`
` : ""} - ${!this.snapshot + ${!this.backup ? html` ` : ""} - ${this.snapshotHasPassword + ${this.backupHasPassword ? html` - ${!this.snapshot + ${!this.backup ? html` ` @@ -307,7 +305,7 @@ export class SupervisorSnapshotContent extends LitElement { display: block; margin: 0 -14px -16px; } - .snapshot-types { + .backup-types { display: flex; margin-left: -13px; } @@ -317,23 +315,23 @@ export class SupervisorSnapshotContent extends LitElement { `; } - public snapshotDetails(): - | HassioPartialSnapshotCreateParams - | HassioFullSnapshotCreateParams { + public backupDetails(): + | HassioPartialBackupCreateParams + | HassioFullBackupCreateParams { const data: any = {}; - if (!this.snapshot) { - data.name = this.snapshotName || formatDate(new Date(), this.hass.locale); + if (!this.backup) { + data.name = this.backupName || formatDate(new Date(), this.hass.locale); } - if (this.snapshotHasPassword) { - data.password = this.snapshotPassword; - if (!this.snapshot) { - data.confirm_password = this.confirmSnapshotPassword; + if (this.backupHasPassword) { + data.password = this.backupPassword; + if (!this.backup) { + data.confirm_password = this.confirmBackupPassword; } } - if (this.snapshotType === "full") { + if (this.backupType === "full") { return data; } @@ -415,7 +413,7 @@ export class SupervisorSnapshotContent extends LitElement { } private _toggleHasPassword(): void { - this.snapshotHasPassword = !this.snapshotHasPassword; + this.backupHasPassword = !this.backupHasPassword; } private _toggleSection(ev): void { @@ -445,6 +443,6 @@ export class SupervisorSnapshotContent extends LitElement { declare global { interface HTMLElementTagNameMap { - "supervisor-snapshot-content": SupervisorSnapshotContent; + "supervisor-backup-content": SupervisorBackupContent; } } diff --git a/hassio/src/dashboard/hassio-update.ts b/hassio/src/dashboard/hassio-update.ts index 7947a5372c..3b854b1f4e 100644 --- a/hassio/src/dashboard/hassio-update.ts +++ b/hassio/src/dashboard/hassio-update.ts @@ -162,7 +162,7 @@ export class HassioUpdate extends LitElement { supervisor: this.supervisor, name: "Home Assistant Core", version: this.supervisor.core.version_latest, - snapshotParams: { + backupParams: { name: `core_${this.supervisor.core.version}`, folders: ["homeassistant"], homeassistant: true, diff --git a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot-upload.ts b/hassio/src/dialogs/backup/dialog-hassio-backup-upload.ts similarity index 72% rename from hassio/src/dialogs/snapshot/dialog-hassio-snapshot-upload.ts rename to hassio/src/dialogs/backup/dialog-hassio-backup-upload.ts index 1c23944951..93f79446e0 100644 --- a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot-upload.ts +++ b/hassio/src/dialogs/backup/dialog-hassio-backup-upload.ts @@ -6,20 +6,20 @@ import "../../../../src/components/ha-header-bar"; import { HassDialog } from "../../../../src/dialogs/make-dialog-manager"; import { haStyleDialog } from "../../../../src/resources/styles"; import type { HomeAssistant } from "../../../../src/types"; -import "../../components/hassio-upload-snapshot"; -import { HassioSnapshotUploadDialogParams } from "./show-dialog-snapshot-upload"; +import "../../components/hassio-upload-backup"; +import { HassioBackupUploadDialogParams } from "./show-dialog-backup-upload"; -@customElement("dialog-hassio-snapshot-upload") -export class DialogHassioSnapshotUpload +@customElement("dialog-hassio-backup-upload") +export class DialogHassioBackupUpload extends LitElement - implements HassDialog + implements HassDialog { @property({ attribute: false }) public hass!: HomeAssistant; - @state() private _params?: HassioSnapshotUploadDialogParams; + @state() private _params?: HassioBackupUploadDialogParams; public async showDialog( - params: HassioSnapshotUploadDialogParams + params: HassioBackupUploadDialogParams ): Promise { this._params = params; await this.updateComplete; @@ -27,8 +27,8 @@ export class DialogHassioSnapshotUpload public closeDialog(): void { if (this._params && !this._params.onboarding) { - if (this._params.reloadSnapshot) { - this._params.reloadSnapshot(); + if (this._params.reloadBackup) { + this._params.reloadBackup(); } } this._params = undefined; @@ -51,23 +51,23 @@ export class DialogHassioSnapshotUpload >
- Upload snapshot + Upload backup
- + > `; } - private _snapshotUploaded(ev) { - const snapshot = ev.detail.snapshot; - this._params?.showSnapshot(snapshot.slug); + private _backupUploaded(ev) { + const backup = ev.detail.backup; + this._params?.showBackup(backup.slug); this.closeDialog(); } @@ -94,6 +94,6 @@ export class DialogHassioSnapshotUpload declare global { interface HTMLElementTagNameMap { - "dialog-hassio-snapshot-upload": DialogHassioSnapshotUpload; + "dialog-hassio-backup-upload": DialogHassioBackupUpload; } } diff --git a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts b/hassio/src/dialogs/backup/dialog-hassio-backup.ts old mode 100755 new mode 100644 similarity index 63% rename from hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts rename to hassio/src/dialogs/backup/dialog-hassio-backup.ts index 5228488fb0..3c8ddae3d0 --- a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts +++ b/hassio/src/dialogs/backup/dialog-hassio-backup.ts @@ -12,9 +12,9 @@ import "../../../../src/components/ha-svg-icon"; import { getSignedPath } from "../../../../src/data/auth"; import { extractApiErrorMessage } from "../../../../src/data/hassio/common"; import { - fetchHassioSnapshotInfo, - HassioSnapshotDetail, -} from "../../../../src/data/hassio/snapshot"; + fetchHassioBackupInfo, + HassioBackupDetail, +} from "../../../../src/data/hassio/backup"; import { showAlertDialog, showConfirmationDialog, @@ -23,44 +23,45 @@ import { HassDialog } from "../../../../src/dialogs/make-dialog-manager"; import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; import { HomeAssistant } from "../../../../src/types"; import { fileDownload } from "../../../../src/util/file_download"; -import "../../components/supervisor-snapshot-content"; -import type { SupervisorSnapshotContent } from "../../components/supervisor-snapshot-content"; -import { HassioSnapshotDialogParams } from "./show-dialog-hassio-snapshot"; +import "../../components/supervisor-backup-content"; +import type { SupervisorBackupContent } from "../../components/supervisor-backup-content"; +import { HassioBackupDialogParams } from "./show-dialog-hassio-backup"; +import { atLeastVersion } from "../../../../src/common/config/version"; -@customElement("dialog-hassio-snapshot") -class HassioSnapshotDialog +@customElement("dialog-hassio-backup") +class HassioBackupDialog extends LitElement - implements HassDialog + implements HassDialog { @property({ attribute: false }) public hass!: HomeAssistant; @state() private _error?: string; - @state() private _snapshot?: HassioSnapshotDetail; + @state() private _backup?: HassioBackupDetail; - @state() private _dialogParams?: HassioSnapshotDialogParams; + @state() private _dialogParams?: HassioBackupDialogParams; - @state() private _restoringSnapshot = false; + @state() private _restoringBackup = false; - @query("supervisor-snapshot-content") - private _snapshotContent!: SupervisorSnapshotContent; + @query("supervisor-backup-content") + private _backupContent!: SupervisorBackupContent; - public async showDialog(params: HassioSnapshotDialogParams) { - this._snapshot = await fetchHassioSnapshotInfo(this.hass, params.slug); + public async showDialog(params: HassioBackupDialogParams) { + this._backup = await fetchHassioBackupInfo(this.hass, params.slug); this._dialogParams = params; - this._restoringSnapshot = false; + this._restoringBackup = false; } public closeDialog() { - this._snapshot = undefined; + this._backup = undefined; this._dialogParams = undefined; - this._restoringSnapshot = false; + this._restoringBackup = false; this._error = undefined; fireEvent(this, "dialog-closed", { dialog: this.localName }); } protected render(): TemplateResult { - if (!this._dialogParams || !this._snapshot) { + if (!this._dialogParams || !this._backup) { return html``; } return html` @@ -72,26 +73,26 @@ class HassioSnapshotDialog >
- ${this._snapshot.name} + ${this._backup.name}
- ${this._restoringSnapshot + ${this._restoringBackup ? html` ` - : html` - `} + `} ${this._error ? html`

Error: ${this._error}

` : ""} @@ -108,8 +109,8 @@ class HassioSnapshotDialog - Download Snapshot - Delete Snapshot + Download Backup + Delete Backup ` : ""} @@ -150,30 +151,30 @@ class HassioSnapshotDialog } private async _restoreClicked() { - const snapshotDetails = this._snapshotContent.snapshotDetails(); - this._restoringSnapshot = true; - if (this._snapshotContent.snapshotType === "full") { - await this._fullRestoreClicked(snapshotDetails); + const backupDetails = this._backupContent.backupDetails(); + this._restoringBackup = true; + if (this._backupContent.backupType === "full") { + await this._fullRestoreClicked(backupDetails); } else { - await this._partialRestoreClicked(snapshotDetails); + await this._partialRestoreClicked(backupDetails); } - this._restoringSnapshot = false; + this._restoringBackup = false; } - private async _partialRestoreClicked(snapshotDetails) { + private async _partialRestoreClicked(backupDetails) { if ( this._dialogParams?.supervisor !== undefined && this._dialogParams?.supervisor.info.state !== "running" ) { await showAlertDialog(this, { - title: "Could not restore snapshot", - text: `Restoring a snapshot is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`, + title: "Could not restore backup", + text: `Restoring a backup is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`, }); return; } if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want partially to restore this snapshot?", + title: "Are you sure you want partially to restore this backup?", confirmText: "restore", dismissText: "cancel", })) @@ -186,8 +187,12 @@ class HassioSnapshotDialog .callApi( "POST", - `hassio/snapshots/${this._snapshot!.slug}/restore/partial`, - snapshotDetails + `hassio/${ + atLeastVersion(this.hass.config.version, 2021, 9) + ? "backups" + : "snapshots" + }/${this._backup!.slug}/restore/partial`, + backupDetails ) .then( () => { @@ -199,29 +204,29 @@ class HassioSnapshotDialog ); } else { fireEvent(this, "restoring"); - fetch(`/api/hassio/snapshots/${this._snapshot!.slug}/restore/partial`, { + fetch(`/api/hassio/backups/${this._backup!.slug}/restore/partial`, { method: "POST", - body: JSON.stringify(snapshotDetails), + body: JSON.stringify(backupDetails), }); this.closeDialog(); } } - private async _fullRestoreClicked(snapshotDetails) { + private async _fullRestoreClicked(backupDetails) { if ( this._dialogParams?.supervisor !== undefined && this._dialogParams?.supervisor.info.state !== "running" ) { await showAlertDialog(this, { - title: "Could not restore snapshot", - text: `Restoring a snapshot is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`, + title: "Could not restore backup", + text: `Restoring a backup is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`, }); return; } if ( !(await showConfirmationDialog(this, { title: - "Are you sure you want to wipe your system and restore this snapshot?", + "Are you sure you want to wipe your system and restore this backup?", confirmText: "restore", dismissText: "cancel", })) @@ -233,8 +238,12 @@ class HassioSnapshotDialog this.hass .callApi( "POST", - `hassio/snapshots/${this._snapshot!.slug}/restore/full`, - snapshotDetails + `hassio/${ + atLeastVersion(this.hass.config.version, 2021, 9) + ? "backups" + : "snapshots" + }/${this._backup!.slug}/restore/full`, + backupDetails ) .then( () => { @@ -246,9 +255,9 @@ class HassioSnapshotDialog ); } else { fireEvent(this, "restoring"); - fetch(`/api/hassio/snapshots/${this._snapshot!.slug}/restore/full`, { + fetch(`/api/hassio/backups/${this._backup!.slug}/restore/full`, { method: "POST", - body: JSON.stringify(snapshotDetails), + body: JSON.stringify(backupDetails), }); this.closeDialog(); } @@ -257,7 +266,7 @@ class HassioSnapshotDialog private async _deleteClicked() { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this snapshot?", + title: "Are you sure you want to delete this backup?", confirmText: "delete", dismissText: "cancel", })) @@ -267,7 +276,14 @@ class HassioSnapshotDialog this.hass - .callApi("POST", `hassio/snapshots/${this._snapshot!.slug}/remove`) + .callApi( + atLeastVersion(this.hass.config.version, 2021, 9) ? "DELETE" : "POST", + `hassio/${ + atLeastVersion(this.hass.config.version, 2021, 9) + ? "backups" + : "snapshots" + }/${this._backup!.slug}/remove` + ) .then( () => { if (this._dialogParams!.onDelete) { @@ -286,7 +302,11 @@ class HassioSnapshotDialog try { signedPath = await getSignedPath( this.hass, - `/api/hassio/snapshots/${this._snapshot!.slug}/download` + `/api/hassio/${ + atLeastVersion(this.hass.config.version, 2021, 9) + ? "backups" + : "snapshots" + }/${this._backup!.slug}/download` ); } catch (err) { await showAlertDialog(this, { @@ -298,7 +318,7 @@ class HassioSnapshotDialog if (window.location.href.includes("ui.nabu.casa")) { const confirm = await showConfirmationDialog(this, { title: "Potential slow download", - text: "Downloading snapshots over the Nabu Casa URL will take some time, it is recomended to use your local URL instead, do you want to continue?", + text: "Downloading backups over the Nabu Casa URL will take some time, it is recomended to use your local URL instead, do you want to continue?", confirmText: "continue", dismissText: "cancel", }); @@ -310,19 +330,19 @@ class HassioSnapshotDialog fileDownload( this, signedPath.path, - `home_assistant_snapshot_${slugify(this._computeName)}.tar` + `home_assistant_backup_${slugify(this._computeName)}.tar` ); } private get _computeName() { - return this._snapshot - ? this._snapshot.name || this._snapshot.slug - : "Unnamed snapshot"; + return this._backup + ? this._backup.name || this._backup.slug + : "Unnamed backup"; } } declare global { interface HTMLElementTagNameMap { - "dialog-hassio-snapshot": HassioSnapshotDialog; + "dialog-hassio-backup": HassioBackupDialog; } } diff --git a/hassio/src/dialogs/snapshot/dialog-hassio-create-snapshot.ts b/hassio/src/dialogs/backup/dialog-hassio-create-backup.ts old mode 100755 new mode 100644 similarity index 57% rename from hassio/src/dialogs/snapshot/dialog-hassio-create-snapshot.ts rename to hassio/src/dialogs/backup/dialog-hassio-create-backup.ts index dbb7c503c7..06b07c101b --- a/hassio/src/dialogs/snapshot/dialog-hassio-create-snapshot.ts +++ b/hassio/src/dialogs/backup/dialog-hassio-create-backup.ts @@ -6,37 +6,37 @@ import "../../../../src/components/buttons/ha-progress-button"; import { createCloseHeading } from "../../../../src/components/ha-dialog"; import { extractApiErrorMessage } from "../../../../src/data/hassio/common"; import { - createHassioFullSnapshot, - createHassioPartialSnapshot, -} from "../../../../src/data/hassio/snapshot"; + createHassioFullBackup, + createHassioPartialBackup, +} from "../../../../src/data/hassio/backup"; import { showAlertDialog } from "../../../../src/dialogs/generic/show-dialog-box"; import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; import { HomeAssistant } from "../../../../src/types"; -import "../../components/supervisor-snapshot-content"; -import type { SupervisorSnapshotContent } from "../../components/supervisor-snapshot-content"; -import { HassioCreateSnapshotDialogParams } from "./show-dialog-hassio-create-snapshot"; +import "../../components/supervisor-backup-content"; +import type { SupervisorBackupContent } from "../../components/supervisor-backup-content"; +import { HassioCreateBackupDialogParams } from "./show-dialog-hassio-create-backup"; -@customElement("dialog-hassio-create-snapshot") -class HassioCreateSnapshotDialog extends LitElement { +@customElement("dialog-hassio-create-backup") +class HassioCreateBackupDialog extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @state() private _dialogParams?: HassioCreateSnapshotDialogParams; + @state() private _dialogParams?: HassioCreateBackupDialogParams; @state() private _error?: string; - @state() private _creatingSnapshot = false; + @state() private _creatingBackup = false; - @query("supervisor-snapshot-content") - private _snapshotContent!: SupervisorSnapshotContent; + @query("supervisor-backup-content") + private _backupContent!: SupervisorBackupContent; - public showDialog(params: HassioCreateSnapshotDialogParams) { + public showDialog(params: HassioCreateBackupDialogParams) { this._dialogParams = params; - this._creatingSnapshot = false; + this._creatingBackup = false; } public closeDialog() { this._dialogParams = undefined; - this._creatingSnapshot = false; + this._creatingBackup = false; this._error = undefined; fireEvent(this, "dialog-closed", { dialog: this.localName }); } @@ -52,74 +52,74 @@ class HassioCreateSnapshotDialog extends LitElement { @closed=${this.closeDialog} .heading=${createCloseHeading( this.hass, - this._dialogParams.supervisor.localize("snapshot.create_snapshot") + this._dialogParams.supervisor.localize("backup.create_backup") )} > - ${this._creatingSnapshot + ${this._creatingBackup ? html` ` - : html` - `} + `} ${this._error ? html`

Error: ${this._error}

` : ""} ${this._dialogParams.supervisor.localize("common.close")} - ${this._dialogParams.supervisor.localize("snapshot.create")} + ${this._dialogParams.supervisor.localize("backup.create")} `; } - private async _createSnapshot(): Promise { + private async _createBackup(): Promise { if (this._dialogParams!.supervisor.info.state !== "running") { showAlertDialog(this, { title: this._dialogParams!.supervisor.localize( - "snapshot.could_not_create" + "backup.could_not_create" ), text: this._dialogParams!.supervisor.localize( - "snapshot.create_blocked_not_running", + "backup.create_blocked_not_running", "state", this._dialogParams!.supervisor.info.state ), }); return; } - const snapshotDetails = this._snapshotContent.snapshotDetails(); - this._creatingSnapshot = true; + const backupDetails = this._backupContent.backupDetails(); + this._creatingBackup = true; this._error = ""; - if (snapshotDetails.password && !snapshotDetails.password.length) { + if (backupDetails.password && !backupDetails.password.length) { this._error = this._dialogParams!.supervisor.localize( - "snapshot.enter_password" + "backup.enter_password" ); - this._creatingSnapshot = false; + this._creatingBackup = false; return; } if ( - snapshotDetails.password && - snapshotDetails.password !== snapshotDetails.confirm_password + backupDetails.password && + backupDetails.password !== backupDetails.confirm_password ) { this._error = this._dialogParams!.supervisor.localize( - "snapshot.passwords_not_matching" + "backup.passwords_not_matching" ); - this._creatingSnapshot = false; + this._creatingBackup = false; return; } - delete snapshotDetails.confirm_password; + delete backupDetails.confirm_password; try { - if (this._snapshotContent.snapshotType === "full") { - await createHassioFullSnapshot(this.hass, snapshotDetails); + if (this._backupContent.backupType === "full") { + await createHassioFullBackup(this.hass, backupDetails); } else { - await createHassioPartialSnapshot(this.hass, snapshotDetails); + await createHassioPartialBackup(this.hass, backupDetails); } this._dialogParams!.onCreate(); @@ -127,7 +127,7 @@ class HassioCreateSnapshotDialog extends LitElement { } catch (err) { this._error = extractApiErrorMessage(err); } - this._creatingSnapshot = false; + this._creatingBackup = false; } static get styles(): CSSResultGroup { @@ -146,6 +146,6 @@ class HassioCreateSnapshotDialog extends LitElement { declare global { interface HTMLElementTagNameMap { - "dialog-hassio-create-snapshot": HassioCreateSnapshotDialog; + "dialog-hassio-create-backup": HassioCreateBackupDialog; } } diff --git a/hassio/src/dialogs/backup/show-dialog-backup-upload.ts b/hassio/src/dialogs/backup/show-dialog-backup-upload.ts new file mode 100644 index 0000000000..861f192595 --- /dev/null +++ b/hassio/src/dialogs/backup/show-dialog-backup-upload.ts @@ -0,0 +1,19 @@ +import { fireEvent } from "../../../../src/common/dom/fire_event"; +import "./dialog-hassio-backup-upload"; + +export interface HassioBackupUploadDialogParams { + showBackup: (slug: string) => void; + reloadBackup?: () => Promise; + onboarding?: boolean; +} + +export const showBackupUploadDialog = ( + element: HTMLElement, + dialogParams: HassioBackupUploadDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-hassio-backup-upload", + dialogImport: () => import("./dialog-hassio-backup-upload"), + dialogParams, + }); +}; diff --git a/hassio/src/dialogs/snapshot/show-dialog-hassio-snapshot.ts b/hassio/src/dialogs/backup/show-dialog-hassio-backup.ts similarity index 65% rename from hassio/src/dialogs/snapshot/show-dialog-hassio-snapshot.ts rename to hassio/src/dialogs/backup/show-dialog-hassio-backup.ts index fd74e90ea7..39c438e217 100644 --- a/hassio/src/dialogs/snapshot/show-dialog-hassio-snapshot.ts +++ b/hassio/src/dialogs/backup/show-dialog-hassio-backup.ts @@ -2,7 +2,7 @@ import { fireEvent } from "../../../../src/common/dom/fire_event"; import { LocalizeFunc } from "../../../../src/common/translations/localize"; import { Supervisor } from "../../../../src/data/supervisor/supervisor"; -export interface HassioSnapshotDialogParams { +export interface HassioBackupDialogParams { slug: string; onDelete?: () => void; onboarding?: boolean; @@ -10,13 +10,13 @@ export interface HassioSnapshotDialogParams { localize?: LocalizeFunc; } -export const showHassioSnapshotDialog = ( +export const showHassioBackupDialog = ( element: HTMLElement, - dialogParams: HassioSnapshotDialogParams + dialogParams: HassioBackupDialogParams ): void => { fireEvent(element, "show-dialog", { - dialogTag: "dialog-hassio-snapshot", - dialogImport: () => import("./dialog-hassio-snapshot"), + dialogTag: "dialog-hassio-backup", + dialogImport: () => import("./dialog-hassio-backup"), dialogParams, }); }; diff --git a/hassio/src/dialogs/snapshot/show-dialog-hassio-create-snapshot.ts b/hassio/src/dialogs/backup/show-dialog-hassio-create-backup.ts similarity index 52% rename from hassio/src/dialogs/snapshot/show-dialog-hassio-create-snapshot.ts rename to hassio/src/dialogs/backup/show-dialog-hassio-create-backup.ts index 353caf31a2..4fbcf0435c 100644 --- a/hassio/src/dialogs/snapshot/show-dialog-hassio-create-snapshot.ts +++ b/hassio/src/dialogs/backup/show-dialog-hassio-create-backup.ts @@ -1,18 +1,18 @@ import { fireEvent } from "../../../../src/common/dom/fire_event"; import { Supervisor } from "../../../../src/data/supervisor/supervisor"; -export interface HassioCreateSnapshotDialogParams { +export interface HassioCreateBackupDialogParams { supervisor: Supervisor; onCreate: () => void; } -export const showHassioCreateSnapshotDialog = ( +export const showHassioCreateBackupDialog = ( element: HTMLElement, - dialogParams: HassioCreateSnapshotDialogParams + dialogParams: HassioCreateBackupDialogParams ): void => { fireEvent(element, "show-dialog", { - dialogTag: "dialog-hassio-create-snapshot", - dialogImport: () => import("./dialog-hassio-create-snapshot"), + dialogTag: "dialog-hassio-create-backup", + dialogImport: () => import("./dialog-hassio-create-backup"), dialogParams, }); }; diff --git a/hassio/src/dialogs/snapshot/show-dialog-snapshot-upload.ts b/hassio/src/dialogs/snapshot/show-dialog-snapshot-upload.ts deleted file mode 100644 index f6fa98b01d..0000000000 --- a/hassio/src/dialogs/snapshot/show-dialog-snapshot-upload.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { fireEvent } from "../../../../src/common/dom/fire_event"; -import "./dialog-hassio-snapshot-upload"; - -export interface HassioSnapshotUploadDialogParams { - showSnapshot: (slug: string) => void; - reloadSnapshot?: () => Promise; - onboarding?: boolean; -} - -export const showSnapshotUploadDialog = ( - element: HTMLElement, - dialogParams: HassioSnapshotUploadDialogParams -): void => { - fireEvent(element, "show-dialog", { - dialogTag: "dialog-hassio-snapshot-upload", - dialogImport: () => import("./dialog-hassio-snapshot-upload"), - dialogParams, - }); -}; diff --git a/hassio/src/dialogs/update/dialog-supervisor-update.ts b/hassio/src/dialogs/update/dialog-supervisor-update.ts index f6757c1481..03e388de59 100644 --- a/hassio/src/dialogs/update/dialog-supervisor-update.ts +++ b/hassio/src/dialogs/update/dialog-supervisor-update.ts @@ -11,7 +11,7 @@ import { extractApiErrorMessage, ignoreSupervisorError, } from "../../../../src/data/hassio/common"; -import { createHassioPartialSnapshot } from "../../../../src/data/hassio/snapshot"; +import { createHassioPartialBackup } from "../../../../src/data/hassio/backup"; import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; import type { HomeAssistant } from "../../../../src/types"; import { SupervisorDialogSupervisorUpdateParams } from "./show-dialog-update"; @@ -22,9 +22,9 @@ class DialogSupervisorUpdate extends LitElement { @state() private _opened = false; - @state() private _createSnapshot = true; + @state() private _createBackup = true; - @state() private _action: "snapshot" | "update" | null = null; + @state() private _action: "backup" | "update" | null = null; @state() private _error?: string; @@ -41,7 +41,7 @@ class DialogSupervisorUpdate extends LitElement { public closeDialog(): void { this._action = null; - this._createSnapshot = true; + this._createBackup = true; this._error = undefined; this._dialogParams = undefined; fireEvent(this, "dialog-closed", { dialog: this.localName }); @@ -84,20 +84,20 @@ class DialogSupervisorUpdate extends LitElement { ${this._dialogParams.supervisor.localize( - "dialog.update.snapshot" + "dialog.update.backup" )} ${this._dialogParams.supervisor.localize( - "dialog.update.create_snapshot", + "dialog.update.create_backup", "name", this._dialogParams.name )} @@ -123,7 +123,7 @@ class DialogSupervisorUpdate extends LitElement { this._dialogParams.version ) : this._dialogParams.supervisor.localize( - "dialog.update.snapshotting", + "dialog.update.creating_backup", "name", this._dialogParams.name )} @@ -133,17 +133,17 @@ class DialogSupervisorUpdate extends LitElement { `; } - private _toggleSnapshot() { - this._createSnapshot = !this._createSnapshot; + private _toggleBackup() { + this._createBackup = !this._createBackup; } private async _update() { - if (this._createSnapshot) { - this._action = "snapshot"; + if (this._createBackup) { + this._action = "backup"; try { - await createHassioPartialSnapshot( + await createHassioPartialBackup( this.hass, - this._dialogParams!.snapshotParams + this._dialogParams!.backupParams ); } catch (err) { this._error = extractApiErrorMessage(err); diff --git a/hassio/src/dialogs/update/show-dialog-update.ts b/hassio/src/dialogs/update/show-dialog-update.ts index 209243968c..6c3d15cc05 100644 --- a/hassio/src/dialogs/update/show-dialog-update.ts +++ b/hassio/src/dialogs/update/show-dialog-update.ts @@ -5,7 +5,7 @@ export interface SupervisorDialogSupervisorUpdateParams { supervisor: Supervisor; name: string; version: string; - snapshotParams: any; + backupParams: any; updateHandler: () => Promise; } diff --git a/hassio/src/hassio-my-redirect.ts b/hassio/src/hassio-my-redirect.ts index cd38d85d57..6cfb728f1b 100644 --- a/hassio/src/hassio-my-redirect.ts +++ b/hassio/src/hassio-my-redirect.ts @@ -26,7 +26,10 @@ const REDIRECTS: Redirects = { redirect: "/hassio/system", }, supervisor_snapshots: { - redirect: "/hassio/snapshots", + redirect: "/hassio/backups", + }, + supervisor_backups: { + redirect: "/hassio/backups", }, supervisor_store: { redirect: "/hassio/store", diff --git a/hassio/src/hassio-panel-router.ts b/hassio/src/hassio-panel-router.ts index 28d9f24519..bceab08108 100644 --- a/hassio/src/hassio-panel-router.ts +++ b/hassio/src/hassio-panel-router.ts @@ -9,7 +9,7 @@ import "./addon-store/hassio-addon-store"; // Don't codesplit it, that way the dashboard always loads fast. import "./dashboard/hassio-dashboard"; // Don't codesplit the others, because it breaks the UI when pushed to a Pi -import "./snapshots/hassio-snapshots"; +import "./backups/hassio-backups"; import "./system/hassio-system"; @customElement("hassio-panel-router") @@ -23,6 +23,8 @@ class HassioPanelRouter extends HassRouterPage { @property({ type: Boolean }) public narrow!: boolean; protected routerOptions: RouterOptions = { + beforeRender: (page: string) => + page === "snapshots" ? "backups" : undefined, routes: { dashboard: { tag: "hassio-dashboard", @@ -30,8 +32,8 @@ class HassioPanelRouter extends HassRouterPage { store: { tag: "hassio-addon-store", }, - snapshots: { - tag: "hassio-snapshots", + backups: { + tag: "hassio-backups", }, system: { tag: "hassio-system", diff --git a/hassio/src/hassio-router.ts b/hassio/src/hassio-router.ts index 082688399e..3768d26e92 100644 --- a/hassio/src/hassio-router.ts +++ b/hassio/src/hassio-router.ts @@ -23,6 +23,8 @@ class HassioRouter extends HassRouterPage { protected routerOptions: RouterOptions = { // Hass.io has a page with tabs, so we route all non-matching routes to it. defaultPage: "dashboard", + beforeRender: (page: string) => + page === "snapshots" ? "backups" : undefined, initialLoad: () => this._redirectIngress(), showLoading: true, routes: { @@ -30,7 +32,7 @@ class HassioRouter extends HassRouterPage { tag: "hassio-panel", cache: true, }, - snapshots: "dashboard", + backups: "dashboard", store: "dashboard", system: "dashboard", addon: { diff --git a/hassio/src/hassio-tabs.ts b/hassio/src/hassio-tabs.ts index af33a53741..5131b56f0d 100644 --- a/hassio/src/hassio-tabs.ts +++ b/hassio/src/hassio-tabs.ts @@ -13,8 +13,8 @@ export const supervisorTabs: PageNavigation[] = [ iconPath: mdiStore, }, { - translationKey: "panel.snapshots", - path: `/hassio/snapshots`, + translationKey: "panel.backups", + path: `/hassio/backups`, iconPath: mdiBackupRestore, }, { diff --git a/hassio/src/system/hassio-core-info.ts b/hassio/src/system/hassio-core-info.ts index e335a1df78..f749eaade2 100644 --- a/hassio/src/system/hassio-core-info.ts +++ b/hassio/src/system/hassio-core-info.ts @@ -165,7 +165,7 @@ class HassioCoreInfo extends LitElement { supervisor: this.supervisor, name: "Home Assistant Core", version: this.supervisor.core.version_latest, - snapshotParams: { + backupParams: { name: `core_${this.supervisor.core.version}`, folders: ["homeassistant"], homeassistant: true, diff --git a/src/data/hassio/backup.ts b/src/data/hassio/backup.ts new file mode 100644 index 0000000000..69771eb363 --- /dev/null +++ b/src/data/hassio/backup.ts @@ -0,0 +1,233 @@ +import { atLeastVersion } from "../../common/config/version"; +import { HomeAssistant } from "../../types"; +import { hassioApiResultExtractor, HassioResponse } from "./common"; + +export const friendlyFolderName = { + ssl: "SSL", + homeassistant: "Configuration", + "addons/local": "Local add-ons", + media: "Media", + share: "Share", +}; + +interface BackupContent { + homeassistant: boolean; + folders: string[]; + addons: string[]; +} + +export interface HassioBackup { + slug: string; + date: string; + name: string; + type: "full" | "partial"; + protected: boolean; + content: BackupContent; +} + +export interface HassioBackupDetail extends HassioBackup { + size: number; + homeassistant: string; + addons: Array<{ + slug: "ADDON_SLUG"; + name: "NAME"; + version: "INSTALLED_VERSION"; + size: "SIZE_IN_MB"; + }>; + repositories: string[]; + folders: string[]; +} + +export interface HassioFullBackupCreateParams { + name: string; + password?: string; + confirm_password?: string; +} +export interface HassioPartialBackupCreateParams + extends HassioFullBackupCreateParams { + folders?: string[]; + addons?: string[]; + homeassistant?: boolean; +} + +export const fetchHassioBackups = async ( + hass: HomeAssistant +): Promise => { + if (atLeastVersion(hass.config.version, 2021, 2, 4)) { + const data: { + [key: string]: HassioBackup[]; + } = await hass.callWS({ + type: "supervisor/api", + endpoint: `/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }`, + method: "get", + }); + return data[ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + ]; + } + + return hassioApiResultExtractor( + await hass.callApi>( + "GET", + `hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }` + ) + ).snapshots; +}; + +export const fetchHassioBackupInfo = async ( + hass: HomeAssistant, + backup: string +): Promise => { + if (hass) { + if (atLeastVersion(hass.config.version, 2021, 2, 4)) { + return hass.callWS({ + type: "supervisor/api", + endpoint: `/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/${backup}/info`, + method: "get", + }); + } + return hassioApiResultExtractor( + await hass.callApi>( + "GET", + `hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/${backup}/info` + ) + ); + } + // 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; +}; + +export const reloadHassioBackups = async (hass: HomeAssistant) => { + if (atLeastVersion(hass.config.version, 2021, 2, 4)) { + await hass.callWS({ + type: "supervisor/api", + endpoint: `/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/reload`, + method: "post", + }); + return; + } + + await hass.callApi>( + "POST", + `hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/reload` + ); +}; + +export const createHassioFullBackup = async ( + hass: HomeAssistant, + data: HassioFullBackupCreateParams +) => { + if (atLeastVersion(hass.config.version, 2021, 2, 4)) { + await hass.callWS({ + type: "supervisor/api", + endpoint: `/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/new/full`, + method: "post", + timeout: null, + data, + }); + return; + } + await hass.callApi>( + "POST", + `hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/new/full`, + data + ); +}; + +export const removeBackup = async (hass: HomeAssistant, slug: string) => { + if (atLeastVersion(hass.config.version, 2021, 2, 4)) { + await hass.callWS({ + type: "supervisor/api", + endpoint: `/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/${slug}/remove`, + method: "post", + }); + return; + } + await hass.callApi>( + "POST", + `hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/${slug}/remove` + ); +}; + +export const createHassioPartialBackup = async ( + hass: HomeAssistant, + data: HassioPartialBackupCreateParams +) => { + if (atLeastVersion(hass.config.version, 2021, 2, 4)) { + await hass.callWS({ + type: "supervisor/api", + endpoint: `/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/new/partial`, + method: "post", + timeout: null, + data, + }); + return; + } + + await hass.callApi>( + "POST", + `hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/new/partial`, + data + ); +}; + +export const uploadBackup = async ( + hass: HomeAssistant, + file: File +): Promise> => { + const fd = new FormData(); + let resp; + fd.append("file", file); + if (hass) { + resp = await hass.fetchWithAuth( + `/api/hassio/${ + atLeastVersion(hass.config.version, 2021, 9) ? "backups" : "snapshots" + }/new/upload`, + { + method: "POST", + body: fd, + } + ); + } else { + // When called from onboarding we don't have hass + resp = await fetch("/api/hassio/backups/new/upload", { + method: "POST", + body: fd, + }); + } + + if (resp.status === 413) { + throw new Error("Uploaded backup is too large"); + } else if (resp.status !== 200) { + throw new Error(`${resp.status} ${resp.statusText}`); + } + return resp.json(); +}; diff --git a/src/data/hassio/snapshot.ts b/src/data/hassio/snapshot.ts deleted file mode 100644 index 35220e80b6..0000000000 --- a/src/data/hassio/snapshot.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { atLeastVersion } from "../../common/config/version"; -import { HomeAssistant } from "../../types"; -import { hassioApiResultExtractor, HassioResponse } from "./common"; - -export const friendlyFolderName = { - ssl: "SSL", - homeassistant: "Configuration", - "addons/local": "Local add-ons", - media: "Media", - share: "Share", -}; - -interface SnapshotContent { - homeassistant: boolean; - folders: string[]; - addons: string[]; -} - -export interface HassioSnapshot { - slug: string; - date: string; - name: string; - type: "full" | "partial"; - protected: boolean; - content: SnapshotContent; -} - -export interface HassioSnapshotDetail extends HassioSnapshot { - size: number; - homeassistant: string; - addons: Array<{ - slug: "ADDON_SLUG"; - name: "NAME"; - version: "INSTALLED_VERSION"; - size: "SIZE_IN_MB"; - }>; - repositories: string[]; - folders: string[]; -} - -export interface HassioFullSnapshotCreateParams { - name: string; - password?: string; - confirm_password?: string; -} -export interface HassioPartialSnapshotCreateParams - extends HassioFullSnapshotCreateParams { - folders?: string[]; - addons?: string[]; - homeassistant?: boolean; -} - -export const fetchHassioSnapshots = async ( - hass: HomeAssistant -): Promise => { - if (atLeastVersion(hass.config.version, 2021, 2, 4)) { - const data: { snapshots: HassioSnapshot[] } = await hass.callWS({ - type: "supervisor/api", - endpoint: `/snapshots`, - method: "get", - }); - return data.snapshots; - } - - return hassioApiResultExtractor( - await hass.callApi>( - "GET", - "hassio/snapshots" - ) - ).snapshots; -}; - -export const fetchHassioSnapshotInfo = async ( - hass: HomeAssistant, - snapshot: string -): Promise => { - if (hass) { - if (atLeastVersion(hass.config.version, 2021, 2, 4)) { - return hass.callWS({ - type: "supervisor/api", - endpoint: `/snapshots/${snapshot}/info`, - method: "get", - }); - } - return hassioApiResultExtractor( - await hass.callApi>( - "GET", - `hassio/snapshots/${snapshot}/info` - ) - ); - } - // When called from onboarding we don't have hass - const resp = await fetch(`/api/hassio/snapshots/${snapshot}/info`, { - method: "GET", - }); - const data = (await resp.json()).data; - return data; -}; - -export const reloadHassioSnapshots = async (hass: HomeAssistant) => { - if (atLeastVersion(hass.config.version, 2021, 2, 4)) { - await hass.callWS({ - type: "supervisor/api", - endpoint: "/snapshots/reload", - method: "post", - }); - return; - } - - await hass.callApi>("POST", `hassio/snapshots/reload`); -}; - -export const createHassioFullSnapshot = async ( - hass: HomeAssistant, - data: HassioFullSnapshotCreateParams -) => { - if (atLeastVersion(hass.config.version, 2021, 2, 4)) { - await hass.callWS({ - type: "supervisor/api", - endpoint: "/snapshots/new/full", - method: "post", - timeout: null, - data, - }); - return; - } - await hass.callApi>( - "POST", - `hassio/snapshots/new/full`, - data - ); -}; - -export const removeSnapshot = async (hass: HomeAssistant, slug: string) => { - if (atLeastVersion(hass.config.version, 2021, 2, 4)) { - await hass.callWS({ - type: "supervisor/api", - endpoint: `/snapshots/${slug}/remove`, - method: "post", - }); - return; - } - await hass.callApi>( - "POST", - `hassio/snapshots/${slug}/remove` - ); -}; - -export const createHassioPartialSnapshot = async ( - hass: HomeAssistant, - data: HassioPartialSnapshotCreateParams -) => { - if (atLeastVersion(hass.config.version, 2021, 2, 4)) { - await hass.callWS({ - type: "supervisor/api", - endpoint: "/snapshots/new/partial", - method: "post", - timeout: null, - data, - }); - return; - } - - await hass.callApi>( - "POST", - `hassio/snapshots/new/partial`, - data - ); -}; - -export const uploadSnapshot = async ( - hass: HomeAssistant, - file: File -): Promise> => { - const fd = new FormData(); - let resp; - fd.append("file", file); - if (hass) { - resp = await hass.fetchWithAuth("/api/hassio/snapshots/new/upload", { - method: "POST", - body: fd, - }); - } else { - // When called from onboarding we don't have hass - resp = await fetch("/api/hassio/snapshots/new/upload", { - method: "POST", - body: fd, - }); - } - - if (resp.status === 413) { - throw new Error("Uploaded snapshot is too large"); - } else if (resp.status !== 200) { - throw new Error(`${resp.status} ${resp.statusText}`); - } - return resp.json(); -}; diff --git a/src/onboarding/ha-onboarding.ts b/src/onboarding/ha-onboarding.ts index 1d0b571b3e..e06665b300 100644 --- a/src/onboarding/ha-onboarding.ts +++ b/src/onboarding/ha-onboarding.ts @@ -89,13 +89,13 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { ` : ""} ${this._supervisor - ? html` - ` + ` : ""} `; } @@ -170,7 +170,7 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { return this._steps ? this._steps.find((stp) => !stp.done) : undefined; } - private _restoringSnapshot() { + private _restoringBackup() { this._restoring = true; } @@ -183,12 +183,12 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { ].includes(response.installation_type); if (this._supervisor) { // Only load if we have supervisor - import("./onboarding-restore-snapshot"); + import("./onboarding-restore-backup"); } } catch (err) { // eslint-disable-next-line no-console console.error( - "Something went wrong loading onboarding-restore-snapshot", + "Something went wrong loading onboarding-restore-backup", err ); } diff --git a/src/onboarding/onboarding-restore-snapshot.ts b/src/onboarding/onboarding-restore-backup.ts similarity index 80% rename from src/onboarding/onboarding-restore-snapshot.ts rename to src/onboarding/onboarding-restore-backup.ts index ca1afc56eb..bc3c2d4265 100644 --- a/src/onboarding/onboarding-restore-snapshot.ts +++ b/src/onboarding/onboarding-restore-backup.ts @@ -2,8 +2,8 @@ import "@material/mwc-button/mwc-button"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import "../../hassio/src/components/hassio-ansi-to-html"; -import { showHassioSnapshotDialog } from "../../hassio/src/dialogs/snapshot/show-dialog-hassio-snapshot"; -import { showSnapshotUploadDialog } from "../../hassio/src/dialogs/snapshot/show-dialog-snapshot-upload"; +import { showHassioBackupDialog } from "../../hassio/src/dialogs/backup/show-dialog-hassio-backup"; +import { showBackupUploadDialog } from "../../hassio/src/dialogs/backup/show-dialog-backup-upload"; import type { LocalizeFunc } from "../common/translations/localize"; import "../components/ha-card"; import { @@ -21,8 +21,8 @@ declare global { } } -@customElement("onboarding-restore-snapshot") -class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) { +@customElement("onboarding-restore-backup") +class OnboardingRestoreBackup extends ProvideHassLitMixin(LitElement) { @property() public localize!: LocalizeFunc; @property() public language!: string; @@ -42,15 +42,15 @@ class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) { ` : html` - `; } - private _uploadSnapshot(): void { - showSnapshotUploadDialog(this, { - showSnapshot: (slug: string) => this._showSnapshotDialog(slug), + private _uploadBackup(): void { + showBackupUploadDialog(this, { + showBackup: (slug: string) => this._showBackupDialog(slug), onboarding: true, }); } @@ -79,8 +79,8 @@ class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) { } } - private _showSnapshotDialog(slug: string): void { - showHassioSnapshotDialog(this, { + private _showBackupDialog(slug: string): void { + showHassioBackupDialog(this, { slug, onboarding: true, localize: this.localize, @@ -118,6 +118,6 @@ class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) { declare global { interface HTMLElementTagNameMap { - "onboarding-restore-snapshot": OnboardingRestoreSnapshot; + "onboarding-restore-backup": OnboardingRestoreBackup; } } diff --git a/src/panels/config/integrations/integration-panels/zwave/zwave-migration.ts b/src/panels/config/integrations/integration-panels/zwave/zwave-migration.ts index 318744d30b..31df96cffe 100644 --- a/src/panels/config/integrations/integration-panels/zwave/zwave-migration.ts +++ b/src/panels/config/integrations/integration-panels/zwave/zwave-migration.ts @@ -127,8 +127,8 @@ export class ZwaveMigration extends LitElement {

- Please take a backup or a snapshot of your - environment before proceeding. + Please take a backup of your environment before + proceeding.

diff --git a/src/translations/en.json b/src/translations/en.json index 24b363da27..1f4ab1970e 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3700,19 +3700,19 @@ "finish": "Next" }, "restore": { - "description": "Alternatively you can restore from a previous snapshot.", + "description": "Alternatively you can restore from a previous backup.", "in_progress": "Restore in progress", "show_log": "Show full log", "hide_log": "Hide full log", - "full_snapshot": "[%key:supervisor::snapshot::full_snapshot%]", - "partial_snapshot": "[%key:supervisor::snapshot::partial_snapshot%]", - "type": "[%key:supervisor::snapshot::type%]", - "select_type": "[%key:supervisor::snapshot::select_type%]", - "folders": "[%key:supervisor::snapshot::folders%]", - "addons": "[%key:supervisor::snapshot::addons%]", - "password_protection": "[%key:supervisor::snapshot::password_protection%]", - "password": "[%key:supervisor::snapshot::password%]", - "confirm_password": "[%key:supervisor::snapshot::confirm_password%]" + "full_backup": "[%key:supervisor::backup::full_backup%]", + "partial_backup": "[%key:supervisor::backup::partial_backup%]", + "type": "[%key:supervisor::backup::type%]", + "select_type": "[%key:supervisor::backup::select_type%]", + "folders": "[%key:supervisor::backup::folders%]", + "addons": "[%key:supervisor::backup::addons%]", + "password_protection": "[%key:supervisor::backup::password_protection%]", + "password": "[%key:supervisor::backup::password%]", + "confirm_password": "[%key:supervisor::backup::confirm_password%]" } }, "custom": { @@ -3959,7 +3959,7 @@ }, "panel": { "dashboard": "Dashboard", - "snapshots": "Snapshots", + "backups": "Backups", "store": "Add-on Store", "system": "System" }, @@ -4054,43 +4054,32 @@ "ram_usage": "Core RAM Usage" } }, - "snapshot": { - "description": "Snapshots allow you to easily backup and restore all data of your Home Assistant instance.", - "available_snapshots": "Available Snapshots", - "no_snapshots": "You don't have any snapshots yet.", - "create_blocked_not_running": "Creating a snapshot is not possible right now because the system is in {state} state.", - "delete_selected": "Delete selected snapshots", - "delete_snapshot_title": "Delete snapshot", - "delete_snapshot_text": "Do you want to delete {number} {number, plural,\n one {snapshot}\n other {snapshots}\n}?", - "delete_snapshot_confirm": "delete", + "backup": { + "no_backups": "You don't have any backups yet.", + "create_blocked_not_running": "Creating a backup is not possible right now because the system is in {state} state.", + "delete_selected": "Delete selected backups", + "delete_backup_title": "Delete backup", + "delete_backup_text": "Do you want to delete {number} {number, plural,\n one {backup}\n other {backups}\n}?", + "delete_backup_confirm": "delete", "selected": "{number} selected", "failed_to_delete": "Failed to delete", - "could_not_create": "Could not create snapshot", - "upload_snapshot": "Upload snapshot", - "create_snapshot": "Create snapshot", + "could_not_create": "Could not create backup", + "upload_backup": "Upload backup", + "create_backup": "Create backup", "create": "Create", "created": "Created", - "name": "Snapshot name", - "type": "Snapshot type", + "name": "Backup name", + "type": "Backup type", "select_type": "Select what to restore", - "security": "Security", - "full_snapshot": "Full snapshot", - "partial_snapshot": "Partial snapshot", + "full_backup": "Full backup", + "partial_backup": "Partial backup", "addons": "Add-ons", "folders": "Folders", - "password": "Snapshot password", - "confirm_password": "Confirm Snapshot password", + "password": "Backup password", + "confirm_password": "Confirm backup password", "password_protection": "Password protection", - "password_protected": "password protected", "enter_password": "Please enter a password.", - "passwords_not_matching": "The passwords does not match", - "folder": { - "homeassistant": "Home Assistant configuration", - "ssl": "SSL", - "share": "Share", - "media": "Media", - "addons/local": "Local add-ons" - } + "passwords_not_matching": "The passwords does not match" }, "dialog": { "network": { @@ -4133,10 +4122,10 @@ "text": "Do you want to restart the add-on with your changes?" }, "update": { - "snapshot": "Snapshot", - "create_snapshot": "Create a snapshot of {name} before updating", + "backup": "Backup", + "create_backup": "Create a backup of {name} before updating", "updating": "Updating {name} to version {version}", - "snapshotting": "Creating snapshot of {name}" + "creating_backup": "Creating backup of {name}" }, "hardware": { "title": "Hardware",