mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-02 22:17:48 +00:00
Create generate backup dialog (#22866)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
be6ecefb9e
commit
d9cd428bf4
104
src/panels/config/backup/components/ha-backup-agents-select.ts
Normal file
104
src/panels/config/backup/components/ha-backup-agents-select.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { css, html, LitElement } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-checkbox";
|
||||||
|
import "../../../../components/ha-formfield";
|
||||||
|
import type { BackupAgent } from "../../../../data/backup";
|
||||||
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import { brandsUrl } from "../../../../util/brands-url";
|
||||||
|
import { domainToName } from "../../../../data/integration";
|
||||||
|
|
||||||
|
@customElement("ha-backup-agents-select")
|
||||||
|
class HaBackupAgentsSelect extends LitElement {
|
||||||
|
@property({ attribute: false })
|
||||||
|
public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ type: Boolean })
|
||||||
|
public disabled = false;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public agents!: BackupAgent[];
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public disabledAgents?: string[];
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public value!: string[];
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div class="agents">
|
||||||
|
${this.agents.map((agent) => this._renderAgent(agent))}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderAgent(agent: BackupAgent) {
|
||||||
|
const [domain, name] = agent.agent_id.split(".");
|
||||||
|
const domainName = domainToName(this.hass.localize, domain);
|
||||||
|
return html`
|
||||||
|
<ha-formfield>
|
||||||
|
<span class="label" slot="label">
|
||||||
|
<img
|
||||||
|
.src=${brandsUrl({
|
||||||
|
domain,
|
||||||
|
type: "icon",
|
||||||
|
useFallback: true,
|
||||||
|
darkOptimized: this.hass.themes?.darkMode,
|
||||||
|
})}
|
||||||
|
crossorigin="anonymous"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
alt=""
|
||||||
|
slot="start"
|
||||||
|
/>
|
||||||
|
${domainName}: ${name}</span
|
||||||
|
>
|
||||||
|
<ha-checkbox
|
||||||
|
.checked=${this.value.includes(agent.agent_id)}
|
||||||
|
.value=${agent.agent_id}
|
||||||
|
.disabled=${this.disabled ||
|
||||||
|
this.disabledAgents?.includes(agent.agent_id)}
|
||||||
|
@change=${this._checkboxChanged}
|
||||||
|
></ha-checkbox>
|
||||||
|
</ha-formfield>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _checkboxChanged(ev: Event) {
|
||||||
|
const checkbox = ev.target as HTMLInputElement;
|
||||||
|
const value = checkbox.value;
|
||||||
|
const index = this.value.indexOf(value);
|
||||||
|
if (checkbox.checked && index === -1) {
|
||||||
|
this.value = [...this.value, value];
|
||||||
|
} else if (!checkbox.checked && index !== -1) {
|
||||||
|
this.value = [
|
||||||
|
...this.value.slice(0, index),
|
||||||
|
...this.value.slice(index + 1),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
fireEvent(this, "value-changed", { value: this.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
img {
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
.agents {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-backup-agents-select": HaBackupAgentsSelect;
|
||||||
|
}
|
||||||
|
}
|
372
src/panels/config/backup/dialogs/dialog-generate-backup.ts
Normal file
372
src/panels/config/backup/dialogs/dialog-generate-backup.ts
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
import {
|
||||||
|
mdiChartBox,
|
||||||
|
mdiClose,
|
||||||
|
mdiCog,
|
||||||
|
mdiFolder,
|
||||||
|
mdiPlayBoxMultiple,
|
||||||
|
} from "@mdi/js";
|
||||||
|
import type { CSSResultGroup } from "lit";
|
||||||
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-button";
|
||||||
|
import "../../../../components/ha-dialog-header";
|
||||||
|
import "../../../../components/ha-expansion-panel";
|
||||||
|
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-select";
|
||||||
|
import "../../../../components/ha-md-select-option";
|
||||||
|
import "../../../../components/ha-settings-row";
|
||||||
|
import "../../../../components/ha-svg-icon";
|
||||||
|
import "../../../../components/ha-switch";
|
||||||
|
import "../../../../components/ha-textfield";
|
||||||
|
import type { BackupAgent } from "../../../../data/backup";
|
||||||
|
import { fetchBackupAgentsInfo, generateBackup } from "../../../../data/backup";
|
||||||
|
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||||
|
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||||
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import "../components/ha-backup-agents-select";
|
||||||
|
import type { GenerateBackupDialogParams } from "./show-dialog-generate-backup";
|
||||||
|
|
||||||
|
type FormData = {
|
||||||
|
name: string;
|
||||||
|
history: boolean;
|
||||||
|
media: boolean;
|
||||||
|
share: boolean;
|
||||||
|
addons_mode: "all" | "custom";
|
||||||
|
addons: string[];
|
||||||
|
agents_mode: "all" | "custom";
|
||||||
|
agents: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const INITIAL_FORM_DATA: FormData = {
|
||||||
|
name: "",
|
||||||
|
history: true,
|
||||||
|
media: false,
|
||||||
|
share: false,
|
||||||
|
addons_mode: "all",
|
||||||
|
addons: [],
|
||||||
|
agents_mode: "all",
|
||||||
|
agents: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const STEPS = ["data", "sync"] as const;
|
||||||
|
|
||||||
|
@customElement("ha-dialog-generate-backup")
|
||||||
|
class DialogGenerateBackup extends LitElement implements HassDialog {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _formData?: FormData;
|
||||||
|
|
||||||
|
@state() private _step?: "data" | "sync";
|
||||||
|
|
||||||
|
@state() private _agents: BackupAgent[] = [];
|
||||||
|
|
||||||
|
@state() private _params?: GenerateBackupDialogParams;
|
||||||
|
|
||||||
|
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||||
|
|
||||||
|
public showDialog(_params: GenerateBackupDialogParams): void {
|
||||||
|
this._step = STEPS[0];
|
||||||
|
this._formData = INITIAL_FORM_DATA;
|
||||||
|
this._params = _params;
|
||||||
|
this._fetchAgents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _dialogClosed() {
|
||||||
|
this._step = undefined;
|
||||||
|
this._formData = undefined;
|
||||||
|
this._agents = [];
|
||||||
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchAgents() {
|
||||||
|
const { agents } = await fetchBackupAgentsInfo(this.hass);
|
||||||
|
this._agents = agents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._dialog?.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
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._step || !this._formData) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dialogTitle =
|
||||||
|
this._step === "sync" ? "Synchronization" : "Backup data";
|
||||||
|
|
||||||
|
const isFirstStep = this._step === STEPS[0];
|
||||||
|
const isLastStep = this._step === STEPS[STEPS.length - 1];
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-md-dialog open disable-cancel-action @closed=${this._dialogClosed}>
|
||||||
|
<ha-dialog-header slot="headline">
|
||||||
|
${isFirstStep
|
||||||
|
? html`
|
||||||
|
<ha-icon-button
|
||||||
|
slot="navigationIcon"
|
||||||
|
.label=${this.hass.localize("ui.dialogs.generic.close")}
|
||||||
|
.path=${mdiClose}
|
||||||
|
@click=${this.closeDialog}
|
||||||
|
></ha-icon-button>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<ha-icon-button-prev
|
||||||
|
slot="navigationIcon"
|
||||||
|
@click=${this._previousStep}
|
||||||
|
></ha-icon-button-prev>
|
||||||
|
`}
|
||||||
|
<span slot="title" .title=${dialogTitle}> ${dialogTitle} </span>
|
||||||
|
</ha-dialog-header>
|
||||||
|
<div slot="content" class="content">
|
||||||
|
${this._step === "data" ? this._renderData() : this._renderSync()}
|
||||||
|
</div>
|
||||||
|
<div slot="actions">
|
||||||
|
${isFirstStep
|
||||||
|
? html`<ha-button @click=${this.closeDialog}>Cancel</ha-button>`
|
||||||
|
: nothing}
|
||||||
|
${isLastStep
|
||||||
|
? html`<ha-button @click=${this._submit}>Create backup</ha-button>`
|
||||||
|
: html`<ha-button @click=${this._nextStep}>Next</ha-button>`}
|
||||||
|
</div>
|
||||||
|
</ha-md-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderData() {
|
||||||
|
if (!this._formData) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<ha-settings-row>
|
||||||
|
<ha-svg-icon slot="prefix" .path=${mdiCog}></ha-svg-icon>
|
||||||
|
<span slot="heading">Home Assistant settings</span>
|
||||||
|
<span slot="description">
|
||||||
|
With these settings you are able to restore your system.
|
||||||
|
</span>
|
||||||
|
<ha-switch disabled checked></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
<ha-settings-row>
|
||||||
|
<ha-svg-icon slot="prefix" .path=${mdiChartBox}></ha-svg-icon>
|
||||||
|
<span slot="heading">History</span>
|
||||||
|
<span slot="description">For example of your energy dashboard.</span>
|
||||||
|
<ha-switch
|
||||||
|
id="history"
|
||||||
|
name="history"
|
||||||
|
@change=${this._switchChanged}
|
||||||
|
.checked=${this._formData.history}
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
<ha-settings-row>
|
||||||
|
<ha-svg-icon slot="prefix" .path=${mdiPlayBoxMultiple}></ha-svg-icon>
|
||||||
|
<span slot="heading">Media</span>
|
||||||
|
<span slot="description">
|
||||||
|
Folder that is often used for advanced or older configurations.
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
id="media"
|
||||||
|
name="media"
|
||||||
|
@change=${this._switchChanged}
|
||||||
|
.checked=${this._formData.media}
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
<ha-settings-row>
|
||||||
|
<ha-svg-icon slot="prefix" .path=${mdiFolder}></ha-svg-icon>
|
||||||
|
<span slot="heading">Share folder</span>
|
||||||
|
<span slot="description">
|
||||||
|
Folder that is often used for advanced or older configurations.
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
id="share"
|
||||||
|
name="share"
|
||||||
|
@change=${this._switchChanged}
|
||||||
|
.checked=${this._formData.share}
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderSync() {
|
||||||
|
if (!this._formData) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<ha-textfield
|
||||||
|
name="name"
|
||||||
|
.label=${"Backup name"}
|
||||||
|
.value=${this._formData.name}
|
||||||
|
@change=${this._nameChanged}
|
||||||
|
>
|
||||||
|
</ha-textfield>
|
||||||
|
<ha-settings-row>
|
||||||
|
<span slot="heading">Locations</span>
|
||||||
|
<span slot="description">
|
||||||
|
What locations you want to automatically backup to.
|
||||||
|
</span>
|
||||||
|
<ha-md-select
|
||||||
|
@change=${this._agentModeChanged}
|
||||||
|
.value=${this._formData.agents_mode}
|
||||||
|
>
|
||||||
|
<ha-md-select-option value="all">
|
||||||
|
<div slot="headline">All (${this._agents.length})</div>
|
||||||
|
</ha-md-select-option>
|
||||||
|
<ha-md-select-option value="custom">
|
||||||
|
<div slot="headline">Custom</div>
|
||||||
|
</ha-md-select-option>
|
||||||
|
</ha-md-select>
|
||||||
|
</ha-settings-row>
|
||||||
|
${this._formData.agents_mode === "custom"
|
||||||
|
? html`
|
||||||
|
<ha-expansion-panel .header=${"Location"} outlined expanded>
|
||||||
|
<ha-backup-agents-select
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${this._formData.agents}
|
||||||
|
@value-changed=${this._agentsChanged}
|
||||||
|
.agents=${this._agents}
|
||||||
|
></ha-backup-agents-select>
|
||||||
|
</ha-expansion-panel>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _agentModeChanged(ev) {
|
||||||
|
const select = ev.currentTarget;
|
||||||
|
this._formData = {
|
||||||
|
...this._formData!,
|
||||||
|
agents_mode: select.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _agentsChanged(ev) {
|
||||||
|
this._formData = {
|
||||||
|
...this._formData!,
|
||||||
|
agents: ev.detail.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _switchChanged(ev) {
|
||||||
|
const _switch = ev.currentTarget;
|
||||||
|
this._formData = {
|
||||||
|
...this._formData!,
|
||||||
|
[_switch.id]: _switch.checked,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _nameChanged(ev) {
|
||||||
|
this._formData = {
|
||||||
|
...this._formData!,
|
||||||
|
name: ev.target.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _submit() {
|
||||||
|
if (!this._formData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
addons,
|
||||||
|
addons_mode,
|
||||||
|
agents,
|
||||||
|
agents_mode,
|
||||||
|
history,
|
||||||
|
media,
|
||||||
|
name,
|
||||||
|
share,
|
||||||
|
} = this._formData;
|
||||||
|
|
||||||
|
const folders: string[] = [];
|
||||||
|
if (media) {
|
||||||
|
folders.push("media");
|
||||||
|
}
|
||||||
|
if (share) {
|
||||||
|
folders.push("share");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Fetch all addons
|
||||||
|
const ALL_ADDONS = [];
|
||||||
|
const { slug } = await generateBackup(this.hass, {
|
||||||
|
name,
|
||||||
|
agent_ids:
|
||||||
|
agents_mode === "all"
|
||||||
|
? this._agents.map((agent) => agent.agent_id)
|
||||||
|
: agents,
|
||||||
|
database_included: history,
|
||||||
|
folders_included: folders,
|
||||||
|
addons_included: addons_mode === "all" ? ALL_ADDONS : addons,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._params!.submit?.({ slug });
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
--dialog-content-overflow: visible;
|
||||||
|
}
|
||||||
|
ha-md-dialog {
|
||||||
|
--dialog-content-padding: 24px;
|
||||||
|
}
|
||||||
|
ha-settings-row {
|
||||||
|
--settings-row-prefix-display: flex;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
ha-settings-row > ha-svg-icon {
|
||||||
|
align-self: center;
|
||||||
|
margin-inline-end: 16px;
|
||||||
|
}
|
||||||
|
ha-settings-row > ha-md-select {
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
ha-settings-row > ha-md-select > span {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
ha-settings-row > ha-md-select-option {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
ha-textfield {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-dialog-generate-backup": DialogGenerateBackup;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export interface GenerateBackupDialogParams {
|
||||||
|
submit?: (response: { slug: string }) => void;
|
||||||
|
cancel?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadGenerateBackupDialog = () =>
|
||||||
|
import("./dialog-generate-backup");
|
||||||
|
|
||||||
|
export const showGenerateBackupDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
params: GenerateBackupDialogParams
|
||||||
|
) =>
|
||||||
|
new Promise<{ slug: string } | null>((resolve) => {
|
||||||
|
const origCancel = params.cancel;
|
||||||
|
const origSubmit = params.submit;
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "ha-dialog-generate-backup",
|
||||||
|
dialogImport: loadGenerateBackupDialog,
|
||||||
|
dialogParams: {
|
||||||
|
...params,
|
||||||
|
cancel: () => {
|
||||||
|
resolve(null);
|
||||||
|
if (origCancel) {
|
||||||
|
origCancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit: (response) => {
|
||||||
|
resolve(response);
|
||||||
|
if (origSubmit) {
|
||||||
|
origSubmit(response);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
@ -22,22 +22,22 @@ import "../../../components/ha-icon-overflow-menu";
|
|||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import {
|
import {
|
||||||
fetchBackupInfo,
|
fetchBackupInfo,
|
||||||
generateBackup,
|
|
||||||
removeBackup,
|
removeBackup,
|
||||||
type BackupContent,
|
type BackupContent,
|
||||||
} from "../../../data/backup";
|
} from "../../../data/backup";
|
||||||
import { extractApiErrorMessage } from "../../../data/hassio/common";
|
import { extractApiErrorMessage } from "../../../data/hassio/common";
|
||||||
|
import {
|
||||||
|
showAlertDialog,
|
||||||
|
showConfirmationDialog,
|
||||||
|
} from "../../../dialogs/generic/show-dialog-box";
|
||||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||||
import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage-data-table";
|
import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage-data-table";
|
||||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
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 {
|
|
||||||
showAlertDialog,
|
|
||||||
showConfirmationDialog,
|
|
||||||
} from "../../lovelace/custom-card-helpers";
|
|
||||||
import "./components/ha-backup-summary-card";
|
import "./components/ha-backup-summary-card";
|
||||||
|
import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup";
|
||||||
|
|
||||||
@customElement("ha-config-backup-dashboard")
|
@customElement("ha-config-backup-dashboard")
|
||||||
class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
||||||
@ -244,21 +244,10 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _generateBackup(): Promise<void> {
|
private async _generateBackup(): Promise<void> {
|
||||||
const confirm = await showConfirmationDialog(this, {
|
const response = await showGenerateBackupDialog(this, {});
|
||||||
title: this.hass.localize("ui.panel.config.backup.create.title"),
|
|
||||||
text: this.hass.localize("ui.panel.config.backup.create.description"),
|
|
||||||
confirmText: this.hass.localize("ui.panel.config.backup.create.confirm"),
|
|
||||||
});
|
|
||||||
if (!confirm) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
if (!response) {
|
||||||
await generateBackup(this.hass, {
|
return;
|
||||||
agent_ids: ["backup.local"],
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
showAlertDialog(this, { text: (err as Error).message });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._fetchBackupInfo();
|
await this._fetchBackupInfo();
|
||||||
|
@ -10,6 +10,7 @@ import { fetchBackupAgentsInfo } from "../../../data/backup";
|
|||||||
import "../../../layouts/hass-subpage";
|
import "../../../layouts/hass-subpage";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import { brandsUrl } from "../../../util/brands-url";
|
import { brandsUrl } from "../../../util/brands-url";
|
||||||
|
import { domainToName } from "../../../data/integration";
|
||||||
|
|
||||||
@customElement("ha-config-backup-locations")
|
@customElement("ha-config-backup-locations")
|
||||||
class HaConfigBackupLocations extends LitElement {
|
class HaConfigBackupLocations extends LitElement {
|
||||||
@ -47,9 +48,10 @@ class HaConfigBackupLocations extends LitElement {
|
|||||||
<ha-md-list>
|
<ha-md-list>
|
||||||
${this._agents.map((agent) => {
|
${this._agents.map((agent) => {
|
||||||
const [domain, name] = agent.agent_id.split(".");
|
const [domain, name] = agent.agent_id.split(".");
|
||||||
const domainName =
|
const domainName = domainToName(
|
||||||
this.hass.localize(`component.${domain}.title`) ||
|
this.hass.localize,
|
||||||
domain;
|
domain
|
||||||
|
);
|
||||||
return html`
|
return html`
|
||||||
<ha-md-list-item
|
<ha-md-list-item
|
||||||
type="link"
|
type="link"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user