diff --git a/src/panels/config/backup/components/ha-backup-config-data.ts b/src/panels/config/backup/components/ha-backup-config-data.ts
index 66834351c141..99ec42c05478 100644
--- a/src/panels/config/backup/components/ha-backup-config-data.ts
+++ b/src/panels/config/backup/components/ha-backup-config-data.ts
@@ -84,7 +84,7 @@ class HaBackupConfigData extends LitElement {
];
}
- private getData = memoizeOne((value?: BackupConfigData): FormData => {
+ private _getData = memoizeOne((value?: BackupConfigData): FormData => {
if (!value) {
return INITIAL_FORM_DATA;
}
@@ -111,7 +111,7 @@ class HaBackupConfigData extends LitElement {
};
});
- private setData(data: FormData) {
+ private _setData(data: FormData) {
const hasSelfCreatedAddons = data.addons.includes(SELF_CREATED_ADDONS_NAME);
const include_folders = [
@@ -140,7 +140,7 @@ class HaBackupConfigData extends LitElement {
}
protected render() {
- const data = this.getData(this.value);
+ const data = this._getData(this.value);
const isHassio = isComponentLoaded(this.hass, "hassio");
@@ -263,8 +263,8 @@ class HaBackupConfigData extends LitElement {
private _switchChanged(ev: Event) {
const target = ev.currentTarget as HaSwitch;
- const data = this.getData(this.value);
- this.setData({
+ const data = this._getData(this.value);
+ this._setData({
...data,
[target.id]: target.checked,
});
@@ -273,8 +273,8 @@ class HaBackupConfigData extends LitElement {
private _selectChanged(ev: Event) {
const target = ev.currentTarget as HaMdSelect;
- const data = this.getData(this.value);
- this.setData({
+ const data = this._getData(this.value);
+ this._setData({
...data,
[target.id]: target.value,
});
@@ -284,8 +284,8 @@ class HaBackupConfigData extends LitElement {
private _addonsChanged(ev: CustomEvent) {
ev.stopPropagation();
const addons = ev.detail.value;
- const data = this.getData(this.value);
- this.setData({
+ const data = this._getData(this.value);
+ this._setData({
...data,
addons,
});
diff --git a/src/panels/config/backup/dialogs/dialog-backup-onboarding.ts b/src/panels/config/backup/dialogs/dialog-backup-onboarding.ts
new file mode 100644
index 000000000000..b3b6a23e31fc
--- /dev/null
+++ b/src/panels/config/backup/dialogs/dialog-backup-onboarding.ts
@@ -0,0 +1,448 @@
+import { mdiClose, mdiDownload, mdiKey } from "@mdi/js";
+import type { CSSResultGroup } from "lit";
+import { LitElement, css, html, nothing } from "lit";
+import { customElement, property, query, state } from "lit/decorators";
+import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
+import { fireEvent } from "../../../../common/dom/fire_event";
+import "../../../../components/ha-button";
+import "../../../../components/ha-dialog-header";
+import "../../../../components/ha-icon-button";
+import "../../../../components/ha-icon-button-prev";
+import "../../../../components/ha-md-dialog";
+import type { HaMdDialog } from "../../../../components/ha-md-dialog";
+import "../../../../components/ha-md-list";
+import "../../../../components/ha-md-list-item";
+import "../../../../components/ha-password-field";
+import "../../../../components/ha-svg-icon";
+import type {
+ BackupConfig,
+ BackupMutableConfig,
+} from "../../../../data/backup";
+import {
+ BackupScheduleState,
+ generateEncryptionKey,
+ updateBackupConfig,
+} from "../../../../data/backup";
+import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
+import { haStyle, haStyleDialog } from "../../../../resources/styles";
+import type { HomeAssistant } from "../../../../types";
+import { fileDownload } from "../../../../util/file_download";
+import { showToast } from "../../../../util/toast";
+import "../components/ha-backup-config-agents";
+import "../components/ha-backup-config-data";
+import type { BackupConfigData } from "../components/ha-backup-config-data";
+import "../components/ha-backup-config-schedule";
+import type { BackupConfigSchedule } from "../components/ha-backup-config-schedule";
+import type { SetBackupEncryptionKeyDialogParams } from "./show-dialog-set-backup-encryption-key";
+
+const STEPS = ["new_key", "save_key", "schedule", "data", "locations"] as const;
+
+type Step = (typeof STEPS)[number];
+
+const INITIAL_CONFIG: BackupConfig = {
+ create_backup: {
+ agent_ids: [],
+ include_addons: null,
+ include_all_addons: false,
+ include_database: true,
+ include_folders: null,
+ name: null,
+ password: null,
+ },
+ retention: {
+ copies: 3,
+ days: null,
+ },
+ schedule: {
+ state: BackupScheduleState.DAILY,
+ },
+ last_automatic_backup: null,
+};
+
+@customElement("ha-dialog-backup-onboarding")
+class DialogSetBackupEncryptionKey extends LitElement implements HassDialog {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @state() private _opened = false;
+
+ @state() private _step?: Step;
+
+ @state() private _params?: SetBackupEncryptionKeyDialogParams;
+
+ @query("ha-md-dialog") private _dialog!: HaMdDialog;
+
+ @state() private _config?: BackupConfig;
+
+ private _suggestedEncryptionKey?: string;
+
+ public showDialog(params: SetBackupEncryptionKeyDialogParams): void {
+ this._params = params;
+ this._step = STEPS[0];
+ this._config = INITIAL_CONFIG;
+ this._opened = true;
+ this._suggestedEncryptionKey = generateEncryptionKey();
+ }
+
+ public closeDialog(): void {
+ if (this._params!.cancel) {
+ this._params!.cancel();
+ }
+ if (this._opened) {
+ fireEvent(this, "dialog-closed", { dialog: this.localName });
+ }
+ this._opened = false;
+ this._step = undefined;
+ this._config = undefined;
+ this._params = undefined;
+ this._suggestedEncryptionKey = undefined;
+ }
+
+ private async _done() {
+ if (!this._config) {
+ return;
+ }
+
+ const params: BackupMutableConfig = {
+ create_backup: {
+ password: this._config.create_backup.password,
+ include_database: this._config.create_backup.include_database,
+ agent_ids: this._config.create_backup.agent_ids,
+ },
+ schedule: this._config.schedule.state,
+ retention: this._config.retention,
+ };
+
+ if (isComponentLoaded(this.hass, "hassio")) {
+ params.create_backup!.include_folders =
+ this._config.create_backup.include_folders || [];
+ params.create_backup!.include_all_addons =
+ this._config.create_backup.include_all_addons;
+ params.create_backup!.include_addons =
+ this._config.create_backup.include_addons || [];
+ }
+
+ try {
+ await updateBackupConfig(this.hass, params);
+
+ this._params?.submit!(true);
+ this._dialog.close();
+ } catch (err) {
+ // eslint-disable-next-line no-console
+ console.error(err);
+ showToast(this, { message: "Failed to save backup configuration" });
+ }
+ }
+
+ private _previousStep() {
+ const index = STEPS.indexOf(this._step!);
+ if (index === 0) {
+ return;
+ }
+ this._step = STEPS[index - 1];
+ }
+
+ private _nextStep() {
+ const index = STEPS.indexOf(this._step!);
+ if (index === STEPS.length - 1) {
+ return;
+ }
+ this._step = STEPS[index + 1];
+ }
+
+ protected render() {
+ if (!this._opened || !this._params) {
+ return nothing;
+ }
+
+ const isLastStep = this._step === STEPS[STEPS.length - 1];
+ const isFirstStep = this._step === STEPS[0];
+
+ return html`
+
+ All your backups are encrypted to keep your data private and secure. + You need this encryption key to restore any backup. +
++ It’s important that you don’t lose this encryption key. We recommend + to save this key somewhere secure. As you can only restore your data + with the backup encryption key. +
++ Let Home Assistant take care of your backups by creating a scheduled + backup that also removes older copies. +
++ Choose what data to include in your backups. You can always change + this later. +
++ Home Assistant will upload to these locations when this backup + strategy is used. You can use all locations for custom backups. +
+