mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-30 12:46:35 +00:00
Add new backup dialog to choose between automatic and manual (#22895)
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
This commit is contained in:
parent
258a19028b
commit
918fca4d0a
@ -76,6 +76,9 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _dialogClosed() {
|
private _dialogClosed() {
|
||||||
|
if (this._params!.cancel) {
|
||||||
|
this._params!.cancel();
|
||||||
|
}
|
||||||
this._step = undefined;
|
this._step = undefined;
|
||||||
this._formData = undefined;
|
this._formData = undefined;
|
||||||
this._agents = [];
|
this._agents = [];
|
||||||
@ -307,7 +310,7 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
|
|
||||||
// TODO: Fetch all addons
|
// TODO: Fetch all addons
|
||||||
const ALL_ADDONS = [];
|
const ALL_ADDONS = [];
|
||||||
const { slug } = await generateBackup(this.hass, {
|
const { backup_id } = await generateBackup(this.hass, {
|
||||||
name,
|
name,
|
||||||
agent_ids:
|
agent_ids:
|
||||||
agents_mode === "all"
|
agents_mode === "all"
|
||||||
@ -318,7 +321,7 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
addons_included: addons_mode === "all" ? ALL_ADDONS : addons,
|
addons_included: addons_mode === "all" ? ALL_ADDONS : addons,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._params!.submit?.({ slug });
|
this._params!.submit?.({ backup_id });
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
147
src/panels/config/backup/dialogs/dialog-new-backup.ts
Normal file
147
src/panels/config/backup/dialogs/dialog-new-backup.ts
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import { mdiBackupRestore, mdiClose, mdiCogs } from "@mdi/js";
|
||||||
|
import type { CSSResultGroup } from "lit";
|
||||||
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-dialog-header";
|
||||||
|
import "../../../../components/ha-icon-button";
|
||||||
|
import "../../../../components/ha-icon-next";
|
||||||
|
import "../../../../components/ha-md-dialog";
|
||||||
|
import "../../../../components/ha-md-list";
|
||||||
|
import "../../../../components/ha-md-list-item";
|
||||||
|
import "../../../../components/ha-svg-icon";
|
||||||
|
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||||
|
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||||
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import type { NewBackupDialogParams } from "./show-dialog-new-backup";
|
||||||
|
|
||||||
|
@customElement("ha-dialog-new-backup")
|
||||||
|
class DialogNewBackup extends LitElement implements HassDialog {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _opened = false;
|
||||||
|
|
||||||
|
@state() private _params?: NewBackupDialogParams;
|
||||||
|
|
||||||
|
public showDialog(params: NewBackupDialogParams): void {
|
||||||
|
this._opened = true;
|
||||||
|
this._params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
if (this._params!.cancel) {
|
||||||
|
this._params!.cancel();
|
||||||
|
}
|
||||||
|
if (this._opened) {
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
this._opened = false;
|
||||||
|
this._params = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._opened || !this._params) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const heading = "New backup";
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-md-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
aria-labelledby="dialog-box-title"
|
||||||
|
aria-describedby="dialog-box-description"
|
||||||
|
>
|
||||||
|
<ha-dialog-header slot="headline">
|
||||||
|
<ha-icon-button
|
||||||
|
slot="navigationIcon"
|
||||||
|
@click=${this.closeDialog}
|
||||||
|
.label=${this.hass.localize("ui.common.close")}
|
||||||
|
.path=${mdiClose}
|
||||||
|
></ha-icon-button>
|
||||||
|
<span slot="title" id="dialog-light-color-favorite-title">
|
||||||
|
${heading}
|
||||||
|
</span>
|
||||||
|
</ha-dialog-header>
|
||||||
|
<div slot="content">
|
||||||
|
<ha-md-list
|
||||||
|
innerRole="listbox"
|
||||||
|
itemRoles="option"
|
||||||
|
innerAriaLabel=${heading}
|
||||||
|
rootTabbable
|
||||||
|
dialogInitialFocus
|
||||||
|
>
|
||||||
|
<ha-md-list-item @click=${this._automatic} type="button">
|
||||||
|
<ha-svg-icon slot="start" .path=${mdiBackupRestore}></ha-svg-icon>
|
||||||
|
<span slot="headline">Use automatic backup settings</span>
|
||||||
|
<span slot="supporting-text">
|
||||||
|
Trigger a backup using the configured settings for automatic backups
|
||||||
|
</span>
|
||||||
|
<ha-icon-next slot="end"></ha-icon-next>
|
||||||
|
</ha-md-list-item>
|
||||||
|
<ha-md-list-item @click=${this._manual} type="button">
|
||||||
|
<ha-svg-icon slot="start" .path=${mdiCogs}></ha-svg-icon>
|
||||||
|
|
||||||
|
<span slot="headline"> Create a manual backup</span>
|
||||||
|
<span slot="supporting-text">
|
||||||
|
Create a backup with custom settings (e.g. specific add-ons,
|
||||||
|
database, etc.)
|
||||||
|
</span>
|
||||||
|
<ha-icon-next slot="end"></ha-icon-next>
|
||||||
|
</ha-md-list-item>
|
||||||
|
</ha-md-list>
|
||||||
|
</div>
|
||||||
|
</ha-md-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _manual() {
|
||||||
|
this._params!.submit?.("manual");
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _automatic() {
|
||||||
|
this._params!.submit?.("automatic");
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
ha-md-dialog {
|
||||||
|
--dialog-content-padding: 0;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
div[slot="content"] {
|
||||||
|
margin-top: -16px;
|
||||||
|
}
|
||||||
|
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||||
|
ha-md-dialog {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
div[slot="content"] {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-md-list {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
ha-md-list-item {
|
||||||
|
}
|
||||||
|
ha-icon-next {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-dialog-new-backup": DialogNewBackup;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
|
||||||
export interface GenerateBackupDialogParams {
|
export interface GenerateBackupDialogParams {
|
||||||
submit?: (response: { slug: string }) => void;
|
submit?: (response: { backup_id: string }) => void;
|
||||||
cancel?: () => void;
|
cancel?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ export const showGenerateBackupDialog = (
|
|||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
params: GenerateBackupDialogParams
|
params: GenerateBackupDialogParams
|
||||||
) =>
|
) =>
|
||||||
new Promise<{ slug: string } | null>((resolve) => {
|
new Promise<{ backup_id: string } | null>((resolve) => {
|
||||||
const origCancel = params.cancel;
|
const origCancel = params.cancel;
|
||||||
const origSubmit = params.submit;
|
const origSubmit = params.submit;
|
||||||
fireEvent(element, "show-dialog", {
|
fireEvent(element, "show-dialog", {
|
||||||
|
37
src/panels/config/backup/dialogs/show-dialog-new-backup.ts
Normal file
37
src/panels/config/backup/dialogs/show-dialog-new-backup.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export type NewBackupType = "automatic" | "manual";
|
||||||
|
export interface NewBackupDialogParams {
|
||||||
|
submit?: (type: NewBackupType) => void;
|
||||||
|
cancel?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadNewBackupDialog = () => import("./dialog-new-backup");
|
||||||
|
|
||||||
|
export const showNewBackupDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
params: NewBackupDialogParams
|
||||||
|
) =>
|
||||||
|
new Promise<NewBackupType | null>((resolve) => {
|
||||||
|
const origCancel = params.cancel;
|
||||||
|
const origSubmit = params.submit;
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "ha-dialog-new-backup",
|
||||||
|
dialogImport: loadNewBackupDialog,
|
||||||
|
dialogParams: {
|
||||||
|
...params,
|
||||||
|
cancel: () => {
|
||||||
|
resolve(null);
|
||||||
|
if (origCancel) {
|
||||||
|
origCancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit: (response) => {
|
||||||
|
resolve(response);
|
||||||
|
if (origSubmit) {
|
||||||
|
origSubmit(response);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
@ -20,6 +20,7 @@ import "../../../components/ha-icon";
|
|||||||
import "../../../components/ha-icon-next";
|
import "../../../components/ha-icon-next";
|
||||||
import "../../../components/ha-icon-overflow-menu";
|
import "../../../components/ha-icon-overflow-menu";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
|
import { getSignedPath } from "../../../data/auth";
|
||||||
import {
|
import {
|
||||||
fetchBackupInfo,
|
fetchBackupInfo,
|
||||||
getBackupDownloadUrl,
|
getBackupDownloadUrl,
|
||||||
@ -37,10 +38,10 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
|||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import type { HomeAssistant, Route } from "../../../types";
|
import type { HomeAssistant, Route } from "../../../types";
|
||||||
import { brandsUrl } from "../../../util/brands-url";
|
import { brandsUrl } from "../../../util/brands-url";
|
||||||
|
import { fileDownload } from "../../../util/file_download";
|
||||||
import "./components/ha-backup-summary-card";
|
import "./components/ha-backup-summary-card";
|
||||||
import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup";
|
import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup";
|
||||||
import { getSignedPath } from "../../../data/auth";
|
import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup";
|
||||||
import { fileDownload } from "../../../util/file_download";
|
|
||||||
|
|
||||||
@customElement("ha-config-backup-dashboard")
|
@customElement("ha-config-backup-dashboard")
|
||||||
class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
||||||
@ -232,7 +233,7 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
|||||||
?disabled=${this._backingUp}
|
?disabled=${this._backingUp}
|
||||||
.label=${this.hass.localize("ui.panel.config.backup.create_backup")}
|
.label=${this.hass.localize("ui.panel.config.backup.create_backup")}
|
||||||
extended
|
extended
|
||||||
@click=${this._generateBackup}
|
@click=${this._newBackup}
|
||||||
>
|
>
|
||||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||||
</ha-fab>
|
</ha-fab>
|
||||||
@ -251,6 +252,20 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
|||||||
this._backingUp = info.backing_up;
|
this._backingUp = info.backing_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _newBackup(): Promise<void> {
|
||||||
|
const type = await showNewBackupDialog(this, {});
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === "manual") {
|
||||||
|
await this._generateBackup();
|
||||||
|
} else {
|
||||||
|
// Todo: implement trigger automatic backup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _generateBackup(): Promise<void> {
|
private async _generateBackup(): Promise<void> {
|
||||||
const response = await showGenerateBackupDialog(this, {});
|
const response = await showGenerateBackupDialog(this, {});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user