mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 12:26:35 +00:00
Don't allow user to choose cloud if ha settings is not set (#23364)
This commit is contained in:
parent
1f7929bb3d
commit
dc799bf691
@ -1,18 +1,13 @@
|
|||||||
import { mdiHarddisk } from "@mdi/js";
|
import { mdiHarddisk } from "@mdi/js";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||||
import "../../../../components/ha-checkbox";
|
import "../../../../components/ha-checkbox";
|
||||||
import "../../../../components/ha-formfield";
|
import "../../../../components/ha-formfield";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import {
|
import { computeBackupAgentName, isLocalAgent } from "../../../../data/backup";
|
||||||
compareAgents,
|
|
||||||
computeBackupAgentName,
|
|
||||||
isLocalAgent,
|
|
||||||
type BackupAgent,
|
|
||||||
} from "../../../../data/backup";
|
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import { brandsUrl } from "../../../../util/brands-url";
|
import { brandsUrl } from "../../../../util/brands-url";
|
||||||
|
|
||||||
@ -25,22 +20,18 @@ class HaBackupAgentsPicker extends LitElement {
|
|||||||
public disabled = false;
|
public disabled = false;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public agents!: BackupAgent[];
|
public agentIds!: string[];
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public disabledAgents?: string[];
|
public disabledAgentIds?: string[];
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public value!: string[];
|
public value!: string[];
|
||||||
|
|
||||||
private _agentIds = memoizeOne((agents: BackupAgent[]) =>
|
|
||||||
agents.map((agent) => agent.agent_id).sort(compareAgents)
|
|
||||||
);
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="agents">
|
<div class="agents">
|
||||||
${this._agentIds(this.agents).map((agent) => this._renderAgent(agent))}
|
${this.agentIds.map((agent) => this._renderAgent(agent))}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -50,15 +41,15 @@ class HaBackupAgentsPicker extends LitElement {
|
|||||||
const name = computeBackupAgentName(
|
const name = computeBackupAgentName(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
agentId,
|
agentId,
|
||||||
this._agentIds(this.agents)
|
this.agentIds
|
||||||
);
|
);
|
||||||
|
|
||||||
const disabled =
|
const disabled =
|
||||||
this.disabled || this.disabledAgents?.includes(agentId) || false;
|
this.disabled || this.disabledAgentIds?.includes(agentId) || false;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-formfield>
|
<ha-formfield>
|
||||||
<span class="label" slot="label">
|
<span class="label ${classMap({ disabled })}" slot="label">
|
||||||
${isLocalAgent(agentId)
|
${isLocalAgent(agentId)
|
||||||
? html`
|
? html`
|
||||||
<ha-svg-icon .path=${mdiHarddisk} slot="start"> </ha-svg-icon>
|
<ha-svg-icon .path=${mdiHarddisk} slot="start"> </ha-svg-icon>
|
||||||
@ -127,6 +118,12 @@ class HaBackupAgentsPicker extends LitElement {
|
|||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
}
|
}
|
||||||
|
span.disabled {
|
||||||
|
color: var(--disabled-text-color);
|
||||||
|
}
|
||||||
|
span.disabled ha-svg-icon {
|
||||||
|
color: var(--disabled-text-color);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { mdiClose } from "@mdi/js";
|
import { mdiClose } from "@mdi/js";
|
||||||
import type { CSSResultGroup } from "lit";
|
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-alert";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-dialog-header";
|
import "../../../../components/ha-dialog-header";
|
||||||
import "../../../../components/ha-expansion-panel";
|
import "../../../../components/ha-expansion-panel";
|
||||||
@ -17,20 +18,21 @@ import "../../../../components/ha-md-select";
|
|||||||
import "../../../../components/ha-md-select-option";
|
import "../../../../components/ha-md-select-option";
|
||||||
import "../../../../components/ha-textfield";
|
import "../../../../components/ha-textfield";
|
||||||
import type {
|
import type {
|
||||||
BackupAgent,
|
|
||||||
BackupConfig,
|
BackupConfig,
|
||||||
GenerateBackupParams,
|
GenerateBackupParams,
|
||||||
} from "../../../../data/backup";
|
} from "../../../../data/backup";
|
||||||
import {
|
import {
|
||||||
|
CLOUD_AGENT,
|
||||||
|
compareAgents,
|
||||||
fetchBackupAgentsInfo,
|
fetchBackupAgentsInfo,
|
||||||
fetchBackupConfig,
|
fetchBackupConfig,
|
||||||
} from "../../../../data/backup";
|
} from "../../../../data/backup";
|
||||||
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import "../components/ha-backup-agents-picker";
|
|
||||||
import "../components/config/ha-backup-config-data";
|
import "../components/config/ha-backup-config-data";
|
||||||
import type { BackupConfigData } from "../components/config/ha-backup-config-data";
|
import type { BackupConfigData } from "../components/config/ha-backup-config-data";
|
||||||
|
import "../components/ha-backup-agents-picker";
|
||||||
import type { GenerateBackupDialogParams } from "./show-dialog-generate-backup";
|
import type { GenerateBackupDialogParams } from "./show-dialog-generate-backup";
|
||||||
|
|
||||||
type FormData = {
|
type FormData = {
|
||||||
@ -54,13 +56,15 @@ const INITIAL_DATA: FormData = {
|
|||||||
|
|
||||||
const STEPS = ["data", "sync"] as const;
|
const STEPS = ["data", "sync"] as const;
|
||||||
|
|
||||||
|
const DISALLOWED_AGENTS_NO_HA = [CLOUD_AGENT];
|
||||||
|
|
||||||
@customElement("ha-dialog-generate-backup")
|
@customElement("ha-dialog-generate-backup")
|
||||||
class DialogGenerateBackup extends LitElement implements HassDialog {
|
class DialogGenerateBackup extends LitElement implements HassDialog {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@state() private _step?: "data" | "sync";
|
@state() private _step?: "data" | "sync";
|
||||||
|
|
||||||
@state() private _agents: BackupAgent[] = [];
|
@state() private _agentIds: string[] = [];
|
||||||
|
|
||||||
@state() private _backupConfig?: BackupConfig;
|
@state() private _backupConfig?: BackupConfig;
|
||||||
|
|
||||||
@ -74,6 +78,7 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
this._step = STEPS[0];
|
this._step = STEPS[0];
|
||||||
this._formData = INITIAL_DATA;
|
this._formData = INITIAL_DATA;
|
||||||
this._params = _params;
|
this._params = _params;
|
||||||
|
|
||||||
this._fetchAgents();
|
this._fetchAgents();
|
||||||
this._fetchBackupConfig();
|
this._fetchBackupConfig();
|
||||||
}
|
}
|
||||||
@ -84,7 +89,7 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
}
|
}
|
||||||
this._step = undefined;
|
this._step = undefined;
|
||||||
this._formData = undefined;
|
this._formData = undefined;
|
||||||
this._agents = [];
|
this._agentIds = [];
|
||||||
this._backupConfig = undefined;
|
this._backupConfig = undefined;
|
||||||
this._params = undefined;
|
this._params = undefined;
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
@ -92,7 +97,10 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
|
|
||||||
private async _fetchAgents() {
|
private async _fetchAgents() {
|
||||||
const { agents } = await fetchBackupAgentsInfo(this.hass);
|
const { agents } = await fetchBackupAgentsInfo(this.hass);
|
||||||
this._agents = agents;
|
this._agentIds = agents
|
||||||
|
.map((agent) => agent.agent_id)
|
||||||
|
.filter((id) => id !== CLOUD_AGENT || this._params?.cloudStatus.logged_in)
|
||||||
|
.sort(compareAgents);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchBackupConfig() {
|
private async _fetchBackupConfig() {
|
||||||
@ -120,6 +128,32 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
this._step = STEPS[index + 1];
|
this._step = STEPS[index + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected willUpdate(changedProperties: PropertyValues): void {
|
||||||
|
super.willUpdate(changedProperties);
|
||||||
|
|
||||||
|
if (changedProperties.has("_step")) {
|
||||||
|
if (this._step === "sync" && this._formData) {
|
||||||
|
const disallowedAgents = this._disabledAgentIds();
|
||||||
|
if (disallowedAgents.length) {
|
||||||
|
// Remove disallowed agents from the list
|
||||||
|
const agentsIds =
|
||||||
|
this._formData.agents_mode === "all"
|
||||||
|
? this._agentIds
|
||||||
|
: this._formData.agent_ids;
|
||||||
|
|
||||||
|
const filteredAgents = agentsIds.filter(
|
||||||
|
(agentId) => !disallowedAgents.includes(agentId)
|
||||||
|
);
|
||||||
|
this._formData = {
|
||||||
|
...this._formData,
|
||||||
|
agents_mode: "custom",
|
||||||
|
agent_ids: filteredAgents,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this._step || !this._formData) {
|
if (!this._step || !this._formData) {
|
||||||
return nothing;
|
return nothing;
|
||||||
@ -131,6 +165,8 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
const isFirstStep = this._step === STEPS[0];
|
const isFirstStep = this._step === STEPS[0];
|
||||||
const isLastStep = this._step === STEPS[STEPS.length - 1];
|
const isLastStep = this._step === STEPS[STEPS.length - 1];
|
||||||
|
|
||||||
|
const selectedAgents = this._formData.agent_ids;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-md-dialog open disable-cancel-action @closed=${this._dialogClosed}>
|
<ha-md-dialog open disable-cancel-action @closed=${this._dialogClosed}>
|
||||||
<ha-dialog-header slot="headline">
|
<ha-dialog-header slot="headline">
|
||||||
@ -159,7 +195,14 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
? html`<ha-button @click=${this.closeDialog}>Cancel</ha-button>`
|
? html`<ha-button @click=${this.closeDialog}>Cancel</ha-button>`
|
||||||
: nothing}
|
: nothing}
|
||||||
${isLastStep
|
${isLastStep
|
||||||
? html`<ha-button @click=${this._submit}>Create backup</ha-button>`
|
? html`
|
||||||
|
<ha-button
|
||||||
|
@click=${this._submit}
|
||||||
|
.disabled=${!selectedAgents.length}
|
||||||
|
>
|
||||||
|
Create backup
|
||||||
|
</ha-button>
|
||||||
|
`
|
||||||
: html`<ha-button @click=${this._nextStep}>Next</ha-button>`}
|
: html`<ha-button @click=${this._nextStep}>Next</ha-button>`}
|
||||||
</div>
|
</div>
|
||||||
</ha-md-dialog>
|
</ha-md-dialog>
|
||||||
@ -194,6 +237,8 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const disabledAgentIds = this._disabledAgentIds();
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-textfield
|
<ha-textfield
|
||||||
name="name"
|
name="name"
|
||||||
@ -214,8 +259,11 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
@change=${this._selectChanged}
|
@change=${this._selectChanged}
|
||||||
.value=${this._formData.agents_mode}
|
.value=${this._formData.agents_mode}
|
||||||
>
|
>
|
||||||
<ha-md-select-option value="all">
|
<ha-md-select-option
|
||||||
<div slot="headline">All (${this._agents.length})</div>
|
value="all"
|
||||||
|
.disabled=${disabledAgentIds.length}
|
||||||
|
>
|
||||||
|
<div slot="headline">All (${this._agentIds.length})</div>
|
||||||
</ha-md-select-option>
|
</ha-md-select-option>
|
||||||
<ha-md-select-option value="custom">
|
<ha-md-select-option value="custom">
|
||||||
<div slot="headline">Custom</div>
|
<div slot="headline">Custom</div>
|
||||||
@ -223,6 +271,17 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
</ha-md-select>
|
</ha-md-select>
|
||||||
</ha-md-list-item>
|
</ha-md-list-item>
|
||||||
</ha-md-list>
|
</ha-md-list>
|
||||||
|
${disabledAgentIds.length
|
||||||
|
? html`
|
||||||
|
<ha-alert
|
||||||
|
alert-type="info"
|
||||||
|
.title=${"Home Assistant Cloud cannot synchronize"}
|
||||||
|
>
|
||||||
|
Add Home Assistant settings data to synchronize this backup to
|
||||||
|
Home Assistant Cloud.
|
||||||
|
</ha-alert>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
${this._formData.agents_mode === "custom"
|
${this._formData.agents_mode === "custom"
|
||||||
? html`
|
? html`
|
||||||
<ha-expansion-panel .header=${"Locations"} outlined expanded>
|
<ha-expansion-panel .header=${"Locations"} outlined expanded>
|
||||||
@ -230,7 +289,8 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._formData.agent_ids}
|
.value=${this._formData.agent_ids}
|
||||||
@value-changed=${this._agentsChanged}
|
@value-changed=${this._agentsChanged}
|
||||||
.agents=${this._agents}
|
.agentIds=${this._agentIds}
|
||||||
|
.disabledAgentIds=${disabledAgentIds}
|
||||||
></ha-backup-agents-picker>
|
></ha-backup-agents-picker>
|
||||||
</ha-expansion-panel>
|
</ha-expansion-panel>
|
||||||
`
|
`
|
||||||
@ -260,6 +320,16 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _disabledAgentIds() {
|
||||||
|
if (!this._formData) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const allAgents = this._agentIds;
|
||||||
|
return !this._formData.data.include_homeassistant
|
||||||
|
? DISALLOWED_AGENTS_NO_HA.filter((agentId) => allAgents.includes(agentId))
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
|
||||||
private async _submit() {
|
private async _submit() {
|
||||||
if (!this._formData) {
|
if (!this._formData) {
|
||||||
return;
|
return;
|
||||||
@ -269,12 +339,10 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
|
|
||||||
const password = this._backupConfig?.create_backup.password || undefined;
|
const password = this._backupConfig?.create_backup.password || undefined;
|
||||||
|
|
||||||
const ALL_AGENT_IDS = this._agents.map((agent) => agent.agent_id);
|
|
||||||
|
|
||||||
const params: GenerateBackupParams = {
|
const params: GenerateBackupParams = {
|
||||||
name,
|
name,
|
||||||
password,
|
password,
|
||||||
agent_ids: agents_mode === "all" ? ALL_AGENT_IDS : agent_ids,
|
agent_ids: agents_mode === "all" ? this._agentIds : agent_ids,
|
||||||
// We always include homeassistant if we include database
|
// We always include homeassistant if we include database
|
||||||
include_homeassistant:
|
include_homeassistant:
|
||||||
data.include_homeassistant || data.include_database,
|
data.include_homeassistant || data.include_database,
|
||||||
@ -287,6 +355,13 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
params.include_addons = data.include_addons;
|
params.include_addons = data.include_addons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure we don't upload to disallowed agents if we are not including homeassistant
|
||||||
|
if (!params.include_homeassistant) {
|
||||||
|
params.agent_ids = params.agent_ids.filter(
|
||||||
|
(agentId) => !DISALLOWED_AGENTS_NO_HA.includes(agentId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this._params!.submit?.(params);
|
this._params!.submit?.(params);
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
@ -333,6 +408,10 @@ class DialogGenerateBackup extends LitElement implements HassDialog {
|
|||||||
.content {
|
.content {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
ha-alert {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { mdiClose, mdiFolderUpload } from "@mdi/js";
|
|||||||
import type { CSSResultGroup } from "lit";
|
import type { CSSResultGroup } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { keyed } from "lit/directives/keyed";
|
import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-alert";
|
import "../../../../components/ha-alert";
|
||||||
import "../../../../components/ha-dialog-header";
|
import "../../../../components/ha-dialog-header";
|
||||||
@ -11,12 +11,11 @@ import "../../../../components/ha-file-upload";
|
|||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-icon-button";
|
||||||
import "../../../../components/ha-md-dialog";
|
import "../../../../components/ha-md-dialog";
|
||||||
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
||||||
import "../../../../components/ha-md-list";
|
import {
|
||||||
import "../../../../components/ha-md-list-item";
|
CORE_LOCAL_AGENT,
|
||||||
import "../../../../components/ha-md-select";
|
HASSIO_LOCAL_AGENT,
|
||||||
import "../../../../components/ha-md-select-option";
|
uploadBackup,
|
||||||
import type { BackupAgent } from "../../../../data/backup";
|
} from "../../../../data/backup";
|
||||||
import { fetchBackupAgentsInfo, uploadBackup } from "../../../../data/backup";
|
|
||||||
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
@ -27,14 +26,10 @@ import type { UploadBackupDialogParams } from "./show-dialog-upload-backup";
|
|||||||
const SUPPORTED_FORMAT = "application/x-tar";
|
const SUPPORTED_FORMAT = "application/x-tar";
|
||||||
|
|
||||||
type FormData = {
|
type FormData = {
|
||||||
agents_mode: "all" | "custom";
|
|
||||||
agent_ids: string[];
|
|
||||||
file?: File;
|
file?: File;
|
||||||
};
|
};
|
||||||
|
|
||||||
const INITIAL_DATA: FormData = {
|
const INITIAL_DATA: FormData = {
|
||||||
agents_mode: "all",
|
|
||||||
agent_ids: [],
|
|
||||||
file: undefined,
|
file: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,8 +46,6 @@ export class DialogUploadBackup
|
|||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@state() private _agents: BackupAgent[] = [];
|
|
||||||
|
|
||||||
@state() private _formData?: FormData;
|
@state() private _formData?: FormData;
|
||||||
|
|
||||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||||
@ -60,7 +53,6 @@ export class DialogUploadBackup
|
|||||||
public async showDialog(params: UploadBackupDialogParams): Promise<void> {
|
public async showDialog(params: UploadBackupDialogParams): Promise<void> {
|
||||||
this._params = params;
|
this._params = params;
|
||||||
this._formData = INITIAL_DATA;
|
this._formData = INITIAL_DATA;
|
||||||
this._fetchAgents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _dialogClosed() {
|
private _dialogClosed() {
|
||||||
@ -68,7 +60,6 @@ export class DialogUploadBackup
|
|||||||
this._params!.cancel();
|
this._params!.cancel();
|
||||||
}
|
}
|
||||||
this._formData = undefined;
|
this._formData = undefined;
|
||||||
this._agents = [];
|
|
||||||
this._params = undefined;
|
this._params = undefined;
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
@ -77,17 +68,8 @@ export class DialogUploadBackup
|
|||||||
this._dialog?.close();
|
this._dialog?.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchAgents() {
|
|
||||||
const { agents } = await fetchBackupAgentsInfo(this.hass);
|
|
||||||
this._agents = agents;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _formValid() {
|
private _formValid() {
|
||||||
return (
|
return this._formData?.file !== undefined;
|
||||||
this._formData?.file !== undefined &&
|
|
||||||
(this._formData.agents_mode === "all" ||
|
|
||||||
this._formData.agent_ids.length > 0)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
@ -117,44 +99,6 @@ export class DialogUploadBackup
|
|||||||
supports="Supports .tar files"
|
supports="Supports .tar files"
|
||||||
@file-picked=${this._filePicked}
|
@file-picked=${this._filePicked}
|
||||||
></ha-file-upload>
|
></ha-file-upload>
|
||||||
<ha-md-list>
|
|
||||||
<ha-md-list-item>
|
|
||||||
<span slot="headline">Locations</span>
|
|
||||||
<span slot="supporting-text">
|
|
||||||
What locations you want to upload this backup.
|
|
||||||
</span>
|
|
||||||
${keyed(
|
|
||||||
this._agents.length,
|
|
||||||
html`
|
|
||||||
<ha-md-select
|
|
||||||
slot="end"
|
|
||||||
id="agents_mode"
|
|
||||||
@change=${this._selectChanged}
|
|
||||||
.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-md-list-item>
|
|
||||||
</ha-md-list>
|
|
||||||
${this._formData.agents_mode === "custom"
|
|
||||||
? html`
|
|
||||||
<ha-expansion-panel .header=${"Locations"} outlined expanded>
|
|
||||||
<ha-backup-agents-picker
|
|
||||||
.hass=${this.hass}
|
|
||||||
.value=${this._formData.agent_ids}
|
|
||||||
@value-changed=${this._agentsChanged}
|
|
||||||
.agents=${this._agents}
|
|
||||||
></ha-backup-agents-picker>
|
|
||||||
</ha-expansion-panel>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
${this._error
|
${this._error
|
||||||
? html`<ha-alert alertType="error">${this._error}</ha-alert>`
|
? html`<ha-alert alertType="error">${this._error}</ha-alert>`
|
||||||
: nothing}
|
: nothing}
|
||||||
@ -169,21 +113,6 @@ export class DialogUploadBackup
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _selectChanged(ev) {
|
|
||||||
const select = ev.currentTarget;
|
|
||||||
this._formData = {
|
|
||||||
...this._formData!,
|
|
||||||
[select.id]: select.value,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private _agentsChanged(ev) {
|
|
||||||
this._formData = {
|
|
||||||
...this._formData!,
|
|
||||||
agent_ids: ev.detail.value,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _filePicked(ev: CustomEvent<{ files: File[] }>): Promise<void> {
|
private async _filePicked(ev: CustomEvent<{ files: File[] }>): Promise<void> {
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
const file = ev.detail.files[0];
|
const file = ev.detail.files[0];
|
||||||
@ -195,7 +124,7 @@ export class DialogUploadBackup
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _upload() {
|
private async _upload() {
|
||||||
const { file, agent_ids, agents_mode } = this._formData!;
|
const { file } = this._formData!;
|
||||||
if (!file || file.type !== SUPPORTED_FORMAT) {
|
if (!file || file.type !== SUPPORTED_FORMAT) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Unsupported file format",
|
title: "Unsupported file format",
|
||||||
@ -205,14 +134,13 @@ export class DialogUploadBackup
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const agents =
|
const agentIds = isComponentLoaded(this.hass!, "hassio")
|
||||||
agents_mode === "all"
|
? [HASSIO_LOCAL_AGENT]
|
||||||
? this._agents.map((agent) => agent.agent_id)
|
: [CORE_LOCAL_AGENT];
|
||||||
: agent_ids;
|
|
||||||
|
|
||||||
this._uploading = true;
|
this._uploading = true;
|
||||||
try {
|
try {
|
||||||
await uploadBackup(this.hass!, file, agents);
|
await uploadBackup(this.hass!, file, agentIds);
|
||||||
this._params!.submit?.();
|
this._params!.submit?.();
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@ -233,20 +161,6 @@ export class DialogUploadBackup
|
|||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
ha-md-list {
|
|
||||||
background: none;
|
|
||||||
--md-list-item-leading-space: 0;
|
|
||||||
--md-list-item-trailing-space: 0;
|
|
||||||
}
|
|
||||||
ha-md-select {
|
|
||||||
min-width: 210px;
|
|
||||||
}
|
|
||||||
@media all and (max-width: 450px) {
|
|
||||||
ha-md-select {
|
|
||||||
min-width: 160px;
|
|
||||||
width: 160px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import type { GenerateBackupParams } from "../../../../data/backup";
|
import type { GenerateBackupParams } from "../../../../data/backup";
|
||||||
|
import type { CloudStatus } from "../../../../data/cloud";
|
||||||
|
|
||||||
export interface GenerateBackupDialogParams {
|
export interface GenerateBackupDialogParams {
|
||||||
submit?: (response: GenerateBackupParams) => void;
|
submit?: (response: GenerateBackupParams) => void;
|
||||||
cancel?: () => void;
|
cancel?: () => void;
|
||||||
|
cloudStatus: CloudStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadGenerateBackupDialog = () =>
|
export const loadGenerateBackupDialog = () =>
|
||||||
|
@ -363,7 +363,9 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === "manual") {
|
if (type === "manual") {
|
||||||
const params = await showGenerateBackupDialog(this, {});
|
const params = await showGenerateBackupDialog(this, {
|
||||||
|
cloudStatus: this.cloudStatus,
|
||||||
|
});
|
||||||
|
|
||||||
if (!params) {
|
if (!params) {
|
||||||
return;
|
return;
|
||||||
|
@ -110,7 +110,9 @@ class HaConfigBackupOverview extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === "manual") {
|
if (type === "manual") {
|
||||||
const params = await showGenerateBackupDialog(this, {});
|
const params = await showGenerateBackupDialog(this, {
|
||||||
|
cloudStatus: this.cloudStatus,
|
||||||
|
});
|
||||||
|
|
||||||
if (!params) {
|
if (!params) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user