mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
Supervisor backup update config (#24990)
This commit is contained in:
parent
c8e46bd239
commit
e3122e8e4d
21
src/data/supervisor/update.ts
Normal file
21
src/data/supervisor/update.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import type { HomeAssistant } from "../../types";
|
||||
|
||||
export interface SupervisorUpdateConfig {
|
||||
add_on_backup_before_update: boolean;
|
||||
add_on_backup_retain_copies?: number;
|
||||
core_backup_before_update: boolean;
|
||||
}
|
||||
|
||||
export const getSupervisorUpdateConfig = async (hass: HomeAssistant) =>
|
||||
hass.callWS<SupervisorUpdateConfig>({
|
||||
type: "hassio/update/config/info",
|
||||
});
|
||||
|
||||
export const updateSupervisorUpdateConfig = async (
|
||||
hass: HomeAssistant,
|
||||
config: Partial<SupervisorUpdateConfig>
|
||||
) =>
|
||||
hass.callWS({
|
||||
type: "hassio/update/config/update",
|
||||
...config,
|
||||
});
|
@ -207,7 +207,7 @@ export const computeUpdateStateDisplay = (
|
||||
return hass.formatEntityState(stateObj);
|
||||
};
|
||||
|
||||
type UpdateType = "addon" | "home_assistant" | "generic";
|
||||
export type UpdateType = "addon" | "home_assistant" | "generic";
|
||||
|
||||
export const getUpdateType = (
|
||||
stateObj: UpdateEntity,
|
||||
|
@ -1,26 +1,27 @@
|
||||
import "@material/mwc-linear-progress/mwc-linear-progress";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { BINARY_STATE_OFF } from "../../../common/const";
|
||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-checkbox";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-faded";
|
||||
import "../../../components/ha-formfield";
|
||||
import "../../../components/ha-markdown";
|
||||
import "../../../components/ha-md-list";
|
||||
import "../../../components/ha-md-list-item";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-switch";
|
||||
import type { HaSwitch } from "../../../components/ha-switch";
|
||||
import type { BackupConfig } from "../../../data/backup";
|
||||
import { fetchBackupConfig } from "../../../data/backup";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import type { EntitySources } from "../../../data/entity_sources";
|
||||
import { fetchEntitySourcesWithCache } from "../../../data/entity_sources";
|
||||
import type { UpdateEntity } from "../../../data/update";
|
||||
import { getSupervisorUpdateConfig } from "../../../data/supervisor/update";
|
||||
import type { UpdateEntity, UpdateType } from "../../../data/update";
|
||||
import {
|
||||
getUpdateType,
|
||||
UpdateEntityFeature,
|
||||
@ -44,11 +45,38 @@ class MoreInfoUpdate extends LitElement {
|
||||
|
||||
@state() private _backupConfig?: BackupConfig;
|
||||
|
||||
@state() private _createBackup = false;
|
||||
|
||||
@state() private _entitySources?: EntitySources;
|
||||
|
||||
private async _fetchBackupConfig() {
|
||||
const { config } = await fetchBackupConfig(this.hass);
|
||||
this._backupConfig = config;
|
||||
try {
|
||||
const { config } = await fetchBackupConfig(this.hass);
|
||||
this._backupConfig = config;
|
||||
} catch (err) {
|
||||
// ignore error, because user will get a manual backup option
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
private async _fetchUpdateBackupConfig(type: UpdateType) {
|
||||
try {
|
||||
const config = await getSupervisorUpdateConfig(this.hass);
|
||||
|
||||
if (type === "home_assistant") {
|
||||
this._createBackup = config.core_backup_before_update;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === "addon") {
|
||||
this._createBackup = config.add_on_backup_before_update;
|
||||
}
|
||||
} catch (err) {
|
||||
// ignore error, because user can still set the config
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
private async _fetchEntitySources() {
|
||||
@ -256,7 +284,8 @@ class MoreInfoUpdate extends LitElement {
|
||||
: nothing}
|
||||
<ha-switch
|
||||
slot="end"
|
||||
id="create-backup"
|
||||
.checked=${this._createBackup}
|
||||
@change=${this._createBackupChanged}
|
||||
.disabled=${updateIsInstalling(this.stateObj)}
|
||||
></ha-switch>
|
||||
</ha-md-list-item>
|
||||
@ -319,6 +348,12 @@ class MoreInfoUpdate extends LitElement {
|
||||
if (supportsFeature(this.stateObj!, UpdateEntityFeature.BACKUP)) {
|
||||
this._fetchEntitySources().then(() => {
|
||||
const type = getUpdateType(this.stateObj!, this._entitySources!);
|
||||
if (
|
||||
isComponentLoaded(this.hass, "hassio") &&
|
||||
["home_assistant", "addon"].includes(type)
|
||||
) {
|
||||
this._fetchUpdateBackupConfig(type);
|
||||
}
|
||||
if (type === "home_assistant") {
|
||||
this._fetchBackupConfig();
|
||||
}
|
||||
@ -347,13 +382,7 @@ class MoreInfoUpdate extends LitElement {
|
||||
if (!supportsFeature(this.stateObj!, UpdateEntityFeature.BACKUP)) {
|
||||
return false;
|
||||
}
|
||||
const createBackupSwitch = this.shadowRoot?.getElementById(
|
||||
"create-backup"
|
||||
) as HaSwitch;
|
||||
if (createBackupSwitch) {
|
||||
return createBackupSwitch.checked;
|
||||
}
|
||||
return false;
|
||||
return this._createBackup;
|
||||
}
|
||||
|
||||
private _handleInstall(): void {
|
||||
@ -375,6 +404,10 @@ class MoreInfoUpdate extends LitElement {
|
||||
this.hass.callService("update", "install", installData);
|
||||
}
|
||||
|
||||
private _createBackupChanged(ev) {
|
||||
this._createBackup = ev.target.checked;
|
||||
}
|
||||
|
||||
private _handleSkip(): void {
|
||||
if (this.stateObj!.attributes.auto_update) {
|
||||
showAlertDialog(this, {
|
||||
|
@ -0,0 +1,132 @@
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import "../../../../../components/ha-md-list";
|
||||
import "../../../../../components/ha-md-list-item";
|
||||
import "../../../../../components/ha-md-select";
|
||||
import type { HaMdSelect } from "../../../../../components/ha-md-select";
|
||||
import "../../../../../components/ha-md-select-option";
|
||||
import "../../../../../components/ha-md-textfield";
|
||||
import type { HaMdTextfield } from "../../../../../components/ha-md-textfield";
|
||||
import type { SupervisorUpdateConfig } from "../../../../../data/supervisor/update";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
|
||||
const MIN_RETENTION_VALUE = 1;
|
||||
|
||||
@customElement("ha-backup-config-addon")
|
||||
class HaBackupConfigAddon extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
public supervisorUpdateConfig?: SupervisorUpdateConfig;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.backup.schedule.update_preference.label`
|
||||
)}
|
||||
</span>
|
||||
<span slot="supporting-text">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.backup.schedule.update_preference.supporting_text`
|
||||
)}
|
||||
</span>
|
||||
<ha-md-select
|
||||
slot="end"
|
||||
@change=${this._updatePreferenceChanged}
|
||||
.value=${this.supervisorUpdateConfig?.add_on_backup_before_update?.toString() ||
|
||||
"false"}
|
||||
>
|
||||
<ha-md-select-option value="false">
|
||||
<div slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.schedule.update_preference.skip_backups"
|
||||
)}
|
||||
</div>
|
||||
</ha-md-select-option>
|
||||
<ha-md-select-option value="true">
|
||||
<div slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.schedule.update_preference.backup_before_update"
|
||||
)}
|
||||
</div>
|
||||
</ha-md-select-option>
|
||||
</ha-md-select>
|
||||
</ha-md-list-item>
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">
|
||||
${this.hass.localize(`ui.panel.config.backup.schedule.retention`)}
|
||||
</span>
|
||||
<span slot="supporting-text">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.backup.settings.addon_update_backup.retention_description`
|
||||
)}
|
||||
</span>
|
||||
<ha-md-textfield
|
||||
slot="end"
|
||||
@change=${this._backupRetentionChanged}
|
||||
.value=${this.supervisorUpdateConfig?.add_on_backup_retain_copies?.toString() ||
|
||||
"1"}
|
||||
type="number"
|
||||
.min=${MIN_RETENTION_VALUE.toString()}
|
||||
step="1"
|
||||
>
|
||||
</ha-md-textfield>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
`;
|
||||
}
|
||||
|
||||
private _updatePreferenceChanged(ev) {
|
||||
ev.stopPropagation();
|
||||
const target = ev.currentTarget as HaMdSelect;
|
||||
const add_on_backup_before_update = target.value === "true";
|
||||
fireEvent(this, "update-config-changed", {
|
||||
value: {
|
||||
add_on_backup_before_update,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _backupRetentionChanged(ev) {
|
||||
const target = ev.currentTarget as HaMdTextfield;
|
||||
const add_on_backup_retain_copies = Number(target.value);
|
||||
if (add_on_backup_retain_copies >= MIN_RETENTION_VALUE) {
|
||||
fireEvent(this, "update-config-changed", {
|
||||
value: {
|
||||
add_on_backup_retain_copies,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-md-list {
|
||||
background: none;
|
||||
--md-list-item-leading-space: 0;
|
||||
--md-list-item-trailing-space: 0;
|
||||
}
|
||||
ha-md-list-item {
|
||||
--md-item-overflow: visible;
|
||||
}
|
||||
ha-md-select {
|
||||
min-width: 210px;
|
||||
}
|
||||
@media all and (max-width: 450px) {
|
||||
ha-md-select {
|
||||
min-width: 160px;
|
||||
width: 160px;
|
||||
--md-filled-field-content-space: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-backup-config-addon": HaBackupConfigAddon;
|
||||
}
|
||||
}
|
@ -2,9 +2,13 @@ import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { formatTime } from "../../../../../common/datetime/format_time";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { clamp } from "../../../../../common/number/clamp";
|
||||
import "../../../../../components/ha-checkbox";
|
||||
import type { HaCheckbox } from "../../../../../components/ha-checkbox";
|
||||
import "../../../../../components/ha-expansion-panel";
|
||||
import "../../../../../components/ha-formfield";
|
||||
import "../../../../../components/ha-md-list";
|
||||
import "../../../../../components/ha-md-list-item";
|
||||
import "../../../../../components/ha-md-select";
|
||||
@ -12,6 +16,8 @@ import type { HaMdSelect } from "../../../../../components/ha-md-select";
|
||||
import "../../../../../components/ha-md-select-option";
|
||||
import "../../../../../components/ha-md-textfield";
|
||||
import "../../../../../components/ha-switch";
|
||||
import "../../../../../components/ha-time-input";
|
||||
import "../../../../../components/ha-tip";
|
||||
import type { BackupConfig, BackupDay } from "../../../../../data/backup";
|
||||
import {
|
||||
BACKUP_DAYS,
|
||||
@ -20,13 +26,8 @@ import {
|
||||
DEFAULT_OPTIMIZED_BACKUP_START_TIME,
|
||||
sortWeekdays,
|
||||
} from "../../../../../data/backup";
|
||||
import type { SupervisorUpdateConfig } from "../../../../../data/supervisor/update";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import "../../../../../components/ha-time-input";
|
||||
import "../../../../../components/ha-tip";
|
||||
import "../../../../../components/ha-expansion-panel";
|
||||
import "../../../../../components/ha-checkbox";
|
||||
import "../../../../../components/ha-formfield";
|
||||
import { formatTime } from "../../../../../common/datetime/format_time";
|
||||
import { documentationUrl } from "../../../../../util/documentation-url";
|
||||
|
||||
export type BackupConfigSchedule = Pick<BackupConfig, "schedule" | "retention">;
|
||||
@ -116,6 +117,11 @@ class HaBackupConfigSchedule extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public value?: BackupConfigSchedule;
|
||||
|
||||
@property({ type: Boolean }) public supervisor = false;
|
||||
|
||||
@property({ attribute: false })
|
||||
public supervisorUpdateConfig?: SupervisorUpdateConfig;
|
||||
|
||||
@state() private _retentionPreset?: RetentionPreset;
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues): void {
|
||||
@ -333,6 +339,44 @@ class HaBackupConfigSchedule extends LitElement {
|
||||
: nothing}
|
||||
`
|
||||
: nothing}
|
||||
${this.supervisor
|
||||
? html`
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.backup.schedule.update_preference.label`
|
||||
)}
|
||||
</span>
|
||||
<span slot="supporting-text">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.backup.schedule.update_preference.supporting_text`
|
||||
)}
|
||||
</span>
|
||||
<ha-md-select
|
||||
slot="end"
|
||||
@change=${this._updatePreferenceChanged}
|
||||
.value=${this.supervisorUpdateConfig?.core_backup_before_update?.toString() ||
|
||||
"false"}
|
||||
>
|
||||
<ha-md-select-option value="false">
|
||||
<div slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.schedule.update_preference.skip_backups"
|
||||
)}
|
||||
</div>
|
||||
</ha-md-select-option>
|
||||
<ha-md-select-option value="true">
|
||||
<div slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.schedule.update_preference.backup_before_update"
|
||||
)}
|
||||
</div>
|
||||
</ha-md-select-option>
|
||||
</ha-md-select>
|
||||
</ha-md-list-item>
|
||||
`
|
||||
: nothing}
|
||||
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">
|
||||
${this.hass.localize(`ui.panel.config.backup.schedule.retention`)}
|
||||
@ -488,6 +532,17 @@ class HaBackupConfigSchedule extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _updatePreferenceChanged(ev) {
|
||||
ev.stopPropagation();
|
||||
const target = ev.currentTarget as HaMdSelect;
|
||||
const core_backup_before_update = target.value === "true";
|
||||
fireEvent(this, "update-config-changed", {
|
||||
value: {
|
||||
core_backup_before_update,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _retentionPresetChanged(ev) {
|
||||
ev.stopPropagation();
|
||||
const target = ev.currentTarget as HaMdSelect;
|
||||
@ -614,4 +669,10 @@ declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-backup-config-schedule": HaBackupConfigSchedule;
|
||||
}
|
||||
|
||||
interface HASSDomEvents {
|
||||
"update-config-changed": {
|
||||
value: Partial<SupervisorUpdateConfig>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -7,20 +7,27 @@ import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import { nextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-password-field";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type { BackupAgent, BackupConfig } from "../../../data/backup";
|
||||
import { updateBackupConfig } from "../../../data/backup";
|
||||
import type { CloudStatus } from "../../../data/cloud";
|
||||
import {
|
||||
getSupervisorUpdateConfig,
|
||||
updateSupervisorUpdateConfig,
|
||||
type SupervisorUpdateConfig,
|
||||
} from "../../../data/supervisor/update";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import "./components/config/ha-backup-config-addon";
|
||||
import "./components/config/ha-backup-config-agents";
|
||||
import "./components/config/ha-backup-config-data";
|
||||
import type { BackupConfigData } from "./components/config/ha-backup-config-data";
|
||||
@ -28,7 +35,6 @@ import "./components/config/ha-backup-config-encryption-key";
|
||||
import "./components/config/ha-backup-config-schedule";
|
||||
import type { BackupConfigSchedule } from "./components/config/ha-backup-config-schedule";
|
||||
import { showLocalBackupLocationDialog } from "./dialogs/show-dialog-local-backup-location";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
|
||||
@customElement("ha-config-backup-settings")
|
||||
class HaConfigBackupSettings extends LitElement {
|
||||
@ -44,11 +50,19 @@ class HaConfigBackupSettings extends LitElement {
|
||||
|
||||
@state() private _config?: BackupConfig;
|
||||
|
||||
@state() private _supervisorUpdateConfig?: SupervisorUpdateConfig;
|
||||
|
||||
@state() private _supervisorUpdateConfigError?: string;
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues): void {
|
||||
super.willUpdate(changedProperties);
|
||||
if (changedProperties.has("config") && !this._config) {
|
||||
this._config = this.config;
|
||||
}
|
||||
|
||||
if (!this.hasUpdated && isComponentLoaded(this.hass, "hassio")) {
|
||||
this._getSupervisorUpdateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public connectedCallback(): void {
|
||||
@ -58,6 +72,21 @@ class HaConfigBackupSettings extends LitElement {
|
||||
this._config = this.config;
|
||||
}
|
||||
|
||||
private async _getSupervisorUpdateConfig() {
|
||||
try {
|
||||
this._supervisorUpdateConfig = await getSupervisorUpdateConfig(this.hass);
|
||||
} catch (err: any) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
this._supervisorUpdateConfigError = this.hass.localize(
|
||||
"ui.panel.config.backup.settings.addon_update_backup.error_load",
|
||||
{
|
||||
error: err?.message || err,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async _scrollToSection() {
|
||||
const hash = window.location.hash.substring(1);
|
||||
if (
|
||||
@ -145,9 +174,17 @@ class HaConfigBackupSettings extends LitElement {
|
||||
"ui.panel.config.backup.settings.schedule.description"
|
||||
)}
|
||||
</p>
|
||||
${this._supervisorUpdateConfigError
|
||||
? html`<ha-alert alert-type="error">
|
||||
${this._supervisorUpdateConfigError}
|
||||
</ha-alert>`
|
||||
: nothing}
|
||||
<ha-backup-config-schedule
|
||||
.hass=${this.hass}
|
||||
.value=${this._config}
|
||||
.supervisor=${supervisor}
|
||||
.supervisorUpdateConfig=${this._supervisorUpdateConfig}
|
||||
@update-config-changed=${this._supervisorUpdateConfigChanged}
|
||||
@value-changed=${this._scheduleConfigChanged}
|
||||
></ha-backup-config-schedule>
|
||||
</div>
|
||||
@ -230,6 +267,38 @@ class HaConfigBackupSettings extends LitElement {
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-card>
|
||||
${supervisor
|
||||
? html` <ha-card>
|
||||
<div class="card-header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.settings.addon_update_backup.title"
|
||||
)}
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.settings.addon_update_backup.description"
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.settings.addon_update_backup.local_only"
|
||||
)}
|
||||
</p>
|
||||
${this._supervisorUpdateConfigError
|
||||
? html`<ha-alert alert-type="error">
|
||||
${this._supervisorUpdateConfigError}
|
||||
</ha-alert>`
|
||||
: nothing}
|
||||
<ha-backup-config-addon
|
||||
.hass=${this.hass}
|
||||
.supervisorUpdateConfig=${this._supervisorUpdateConfig}
|
||||
@update-config-changed=${this
|
||||
._supervisorUpdateConfigChanged}
|
||||
></ha-backup-config-addon>
|
||||
</div>
|
||||
</ha-card>`
|
||||
: nothing}
|
||||
<ha-card>
|
||||
<div class="card-header">
|
||||
${this.hass.localize(
|
||||
@ -262,6 +331,15 @@ class HaConfigBackupSettings extends LitElement {
|
||||
showLocalBackupLocationDialog(this, {});
|
||||
}
|
||||
|
||||
private async _supervisorUpdateConfigChanged(ev) {
|
||||
const config = ev.detail.value as SupervisorUpdateConfig;
|
||||
this._supervisorUpdateConfig = {
|
||||
...this._supervisorUpdateConfig!,
|
||||
...config,
|
||||
};
|
||||
this._debounceSaveSupervisorUpdateConfig();
|
||||
}
|
||||
|
||||
private _scheduleConfigChanged(ev) {
|
||||
const value = ev.detail.value as BackupConfigSchedule;
|
||||
this._config = {
|
||||
@ -328,6 +406,32 @@ class HaConfigBackupSettings extends LitElement {
|
||||
this._debounceSave();
|
||||
}
|
||||
|
||||
private _debounceSaveSupervisorUpdateConfig = debounce(
|
||||
() => this._saveSupervisorUpdateConfig(),
|
||||
500
|
||||
);
|
||||
|
||||
private async _saveSupervisorUpdateConfig() {
|
||||
if (!this._supervisorUpdateConfig) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await updateSupervisorUpdateConfig(
|
||||
this.hass,
|
||||
this._supervisorUpdateConfig
|
||||
);
|
||||
} catch (err: any) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
this._supervisorUpdateConfigError = this.hass.localize(
|
||||
"ui.panel.config.backup.settings.addon_update_backup.error_save",
|
||||
{
|
||||
error: err?.message || err?.toString(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private _debounceSave = debounce(() => this._save(), 500);
|
||||
|
||||
private async _save() {
|
||||
@ -350,6 +454,12 @@ class HaConfigBackupSettings extends LitElement {
|
||||
ha-card {
|
||||
scroll-margin-top: 16px;
|
||||
}
|
||||
p {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
p.error {
|
||||
color: var(--error-color);
|
||||
}
|
||||
.content {
|
||||
padding: 28px 20px 0;
|
||||
max-width: 690px;
|
||||
|
@ -2520,6 +2520,12 @@
|
||||
"retention_units": {
|
||||
"copies": "backups",
|
||||
"days": "days"
|
||||
},
|
||||
"update_preference": {
|
||||
"label": "Backup preference when updating",
|
||||
"supporting_text": "This can be adjusted each time",
|
||||
"skip_backups": "Skip backups",
|
||||
"backup_before_update": "Backup before update"
|
||||
}
|
||||
},
|
||||
"encryption_key": {
|
||||
@ -2699,6 +2705,14 @@
|
||||
"encryption_key": {
|
||||
"title": "Encryption key",
|
||||
"description": "Keep this encryption key in a safe place, as you will need it to access your backup, allowing it to be restored. Download it as an emergency kit file and store it somewhere safe. Encryption keeps your backups private and secure."
|
||||
},
|
||||
"addon_update_backup": {
|
||||
"title": "Add-on update backups",
|
||||
"description": "Creates a backup of your add-on and its data. That way you can keep around the previous version of the add-on, so you can always roll back to it if needed.",
|
||||
"local_only": "This backup is only saved on this system.",
|
||||
"retention_description": "Prevent your system from filling up with old versions.",
|
||||
"error_load": "Error loading supervisor update config: {error}",
|
||||
"error_save": "Error saving supervisor update config: {error}"
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user