mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Fix issues with restoring snapshot during onboarding (#9385)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
8a33d174d7
commit
e9b1b3d853
@ -5,6 +5,7 @@ import { customElement, property } from "lit/decorators";
|
|||||||
import { atLeastVersion } from "../../../src/common/config/version";
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import { formatDate } from "../../../src/common/datetime/format_date";
|
import { formatDate } from "../../../src/common/datetime/format_date";
|
||||||
import { formatDateTime } from "../../../src/common/datetime/format_date_time";
|
import { formatDateTime } from "../../../src/common/datetime/format_date_time";
|
||||||
|
import { LocalizeFunc } from "../../../src/common/translations/localize";
|
||||||
import "../../../src/components/ha-checkbox";
|
import "../../../src/components/ha-checkbox";
|
||||||
import "../../../src/components/ha-formfield";
|
import "../../../src/components/ha-formfield";
|
||||||
import "../../../src/components/ha-radio";
|
import "../../../src/components/ha-radio";
|
||||||
@ -67,6 +68,8 @@ const _computeAddons = (addons): AddonCheckboxItem[] =>
|
|||||||
export class SupervisorSnapshotContent extends LitElement {
|
export class SupervisorSnapshotContent extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public localize?: LocalizeFunc;
|
||||||
|
|
||||||
@property({ attribute: false }) public supervisor?: Supervisor;
|
@property({ attribute: false }) public supervisor?: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public snapshot?: HassioSnapshotDetail;
|
@property({ attribute: false }) public snapshot?: HassioSnapshotDetail;
|
||||||
@ -81,6 +84,8 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public snapshotHasPassword = false;
|
@property({ type: Boolean }) public snapshotHasPassword = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public onboarding = false;
|
||||||
|
|
||||||
@property() public snapshotName = "";
|
@property() public snapshotName = "";
|
||||||
|
|
||||||
@property() public snapshotPassword = "";
|
@property() public snapshotPassword = "";
|
||||||
@ -106,8 +111,12 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _localize = (string: string) =>
|
||||||
|
this.supervisor?.localize(`snapshot.${string}`) ||
|
||||||
|
this.localize!(`ui.panel.page-onboarding.restore.${string}`);
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.supervisor) {
|
if (!this.onboarding && !this.supervisor) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
const foldersSection =
|
const foldersSection =
|
||||||
@ -119,14 +128,16 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
${this.snapshot
|
${this.snapshot
|
||||||
? html`<div class="details">
|
? html`<div class="details">
|
||||||
${this.snapshot.type === "full"
|
${this.snapshot.type === "full"
|
||||||
? this.supervisor.localize("snapshot.full_snapshot")
|
? this._localize("full_snapshot")
|
||||||
: this.supervisor.localize("snapshot.partial_snapshot")}
|
: this._localize("partial_snapshot")}
|
||||||
(${Math.ceil(this.snapshot.size * 10) / 10 + " MB"})<br />
|
(${Math.ceil(this.snapshot.size * 10) / 10 + " MB"})<br />
|
||||||
${formatDateTime(new Date(this.snapshot.date), this.hass.locale)}
|
${this.hass
|
||||||
|
? formatDateTime(new Date(this.snapshot.date), this.hass.locale)
|
||||||
|
: this.snapshot.date}
|
||||||
</div>`
|
</div>`
|
||||||
: html`<paper-input
|
: html`<paper-input
|
||||||
name="snapshotName"
|
name="snapshotName"
|
||||||
.label=${this.supervisor.localize("snapshot.name")}
|
.label=${this.supervisor?.localize("snapshot.name") || "Name"}
|
||||||
.value=${this.snapshotName}
|
.value=${this.snapshotName}
|
||||||
@value-changed=${this._handleTextValueChanged}
|
@value-changed=${this._handleTextValueChanged}
|
||||||
>
|
>
|
||||||
@ -134,13 +145,11 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
${!this.snapshot || this.snapshot.type === "full"
|
${!this.snapshot || this.snapshot.type === "full"
|
||||||
? html`<div class="sub-header">
|
? html`<div class="sub-header">
|
||||||
${!this.snapshot
|
${!this.snapshot
|
||||||
? this.supervisor.localize("snapshot.type")
|
? this._localize("type")
|
||||||
: this.supervisor.localize("snapshot.select_type")}
|
: this._localize("select_type")}
|
||||||
</div>
|
</div>
|
||||||
<div class="snapshot-types">
|
<div class="snapshot-types">
|
||||||
<ha-formfield
|
<ha-formfield .label=${this._localize("full_snapshot")}>
|
||||||
.label=${this.supervisor.localize("snapshot.full_snapshot")}
|
|
||||||
>
|
|
||||||
<ha-radio
|
<ha-radio
|
||||||
@change=${this._handleRadioValueChanged}
|
@change=${this._handleRadioValueChanged}
|
||||||
value="full"
|
value="full"
|
||||||
@ -149,9 +158,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
>
|
>
|
||||||
</ha-radio>
|
</ha-radio>
|
||||||
</ha-formfield>
|
</ha-formfield>
|
||||||
<ha-formfield
|
<ha-formfield .label=${this._localize("partial_snapshot")}>
|
||||||
.label=${this.supervisor!.localize("snapshot.partial_snapshot")}
|
|
||||||
>
|
|
||||||
<ha-radio
|
<ha-radio
|
||||||
@change=${this._handleRadioValueChanged}
|
@change=${this._handleRadioValueChanged}
|
||||||
value="partial"
|
value="partial"
|
||||||
@ -188,7 +195,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
? html`
|
? html`
|
||||||
<ha-formfield
|
<ha-formfield
|
||||||
.label=${html`<supervisor-formfield-label
|
.label=${html`<supervisor-formfield-label
|
||||||
.label=${this.supervisor.localize("snapshot.folders")}
|
.label=${this._localize("folders")}
|
||||||
.iconPath=${mdiFolder}
|
.iconPath=${mdiFolder}
|
||||||
>
|
>
|
||||||
</supervisor-formfield-label>`}
|
</supervisor-formfield-label>`}
|
||||||
@ -208,7 +215,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
? html`
|
? html`
|
||||||
<ha-formfield
|
<ha-formfield
|
||||||
.label=${html`<supervisor-formfield-label
|
.label=${html`<supervisor-formfield-label
|
||||||
.label=${this.supervisor.localize("snapshot.addons")}
|
.label=${this._localize("addons")}
|
||||||
.iconPath=${mdiPuzzle}
|
.iconPath=${mdiPuzzle}
|
||||||
>
|
>
|
||||||
</supervisor-formfield-label>`}
|
</supervisor-formfield-label>`}
|
||||||
@ -233,7 +240,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
${!this.snapshot
|
${!this.snapshot
|
||||||
? html`<ha-formfield
|
? html`<ha-formfield
|
||||||
class="password"
|
class="password"
|
||||||
.label=${this.supervisor.localize("snapshot.password_protection")}
|
.label=${this._localize("password_protection")}
|
||||||
>
|
>
|
||||||
<ha-checkbox
|
<ha-checkbox
|
||||||
.checked=${this.snapshotHasPassword}
|
.checked=${this.snapshotHasPassword}
|
||||||
@ -245,7 +252,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
${this.snapshotHasPassword
|
${this.snapshotHasPassword
|
||||||
? html`
|
? html`
|
||||||
<paper-input
|
<paper-input
|
||||||
.label=${this.supervisor.localize("snapshot.password")}
|
.label=${this._localize("password")}
|
||||||
type="password"
|
type="password"
|
||||||
name="snapshotPassword"
|
name="snapshotPassword"
|
||||||
.value=${this.snapshotPassword}
|
.value=${this.snapshotPassword}
|
||||||
@ -254,9 +261,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
</paper-input>
|
</paper-input>
|
||||||
${!this.snapshot
|
${!this.snapshot
|
||||||
? html` <paper-input
|
? html` <paper-input
|
||||||
.label=${this.supervisor.localize(
|
.label=${this.supervisor?.localize("confirm_password")}
|
||||||
"snapshot.confirm_password"
|
|
||||||
)}
|
|
||||||
type="password"
|
type="password"
|
||||||
name="confirmSnapshotPassword"
|
name="confirmSnapshotPassword"
|
||||||
.value=${this.confirmSnapshotPassword}
|
.value=${this.confirmSnapshotPassword}
|
||||||
@ -357,7 +362,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
const addons =
|
const addons =
|
||||||
section === "addons"
|
section === "addons"
|
||||||
? new Map(
|
? new Map(
|
||||||
this.supervisor!.addon.addons.map((item) => [item.slug, item])
|
this.supervisor?.addon.addons.map((item) => [item.slug, item])
|
||||||
)
|
)
|
||||||
: undefined;
|
: undefined;
|
||||||
let checkedItems = 0;
|
let checkedItems = 0;
|
||||||
@ -367,6 +372,7 @@ export class SupervisorSnapshotContent extends LitElement {
|
|||||||
.label=${item.name}
|
.label=${item.name}
|
||||||
.iconPath=${section === "addons" ? mdiPuzzle : mdiFolder}
|
.iconPath=${section === "addons" ? mdiPuzzle : mdiFolder}
|
||||||
.imageUrl=${section === "addons" &&
|
.imageUrl=${section === "addons" &&
|
||||||
|
!this.onboarding &&
|
||||||
atLeastVersion(this.hass.config.version, 0, 105) &&
|
atLeastVersion(this.hass.config.version, 0, 105) &&
|
||||||
addons?.get(item.slug)?.icon
|
addons?.get(item.slug)?.icon
|
||||||
? `/api/hassio/addons/${item.slug}/icon`
|
? `/api/hassio/addons/${item.slug}/icon`
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { ActionDetail } from "@material/mwc-list";
|
import { ActionDetail } from "@material/mwc-list";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import { mdiDotsVertical } from "@mdi/js";
|
import { mdiClose, mdiDotsVertical } from "@mdi/js";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import { slugify } from "../../../../src/common/string/slugify";
|
import { slugify } from "../../../../src/common/string/slugify";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../../src/components/ha-button-menu";
|
import "../../../../src/components/ha-button-menu";
|
||||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
import "../../../../src/components/ha-header-bar";
|
||||||
import "../../../../src/components/ha-svg-icon";
|
import "../../../../src/components/ha-svg-icon";
|
||||||
import { getSignedPath } from "../../../../src/data/auth";
|
import { getSignedPath } from "../../../../src/data/auth";
|
||||||
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||||
@ -67,14 +67,24 @@ class HassioSnapshotDialog
|
|||||||
open
|
open
|
||||||
scrimClickAction
|
scrimClickAction
|
||||||
@closed=${this.closeDialog}
|
@closed=${this.closeDialog}
|
||||||
.heading=${createCloseHeading(this.hass, this._computeName)}
|
.heading=${true}
|
||||||
>
|
>
|
||||||
|
<div slot="heading">
|
||||||
|
<ha-header-bar>
|
||||||
|
<span slot="title">${this._snapshot.name}</span>
|
||||||
|
<mwc-icon-button slot="actionItems" dialogAction="cancel">
|
||||||
|
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
|
||||||
|
</mwc-icon-button>
|
||||||
|
</ha-header-bar>
|
||||||
|
</div>
|
||||||
${this._restoringSnapshot
|
${this._restoringSnapshot
|
||||||
? html` <ha-circular-progress active></ha-circular-progress>`
|
? html` <ha-circular-progress active></ha-circular-progress>`
|
||||||
: html`<supervisor-snapshot-content
|
: html`<supervisor-snapshot-content
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.supervisor=${this._dialogParams.supervisor}
|
.supervisor=${this._dialogParams.supervisor}
|
||||||
.snapshot=${this._snapshot}
|
.snapshot=${this._snapshot}
|
||||||
|
.onboarding=${this._dialogParams.onboarding || false}
|
||||||
|
.localize=${this._dialogParams.localize}
|
||||||
>
|
>
|
||||||
</supervisor-snapshot-content>`}
|
</supervisor-snapshot-content>`}
|
||||||
${this._error ? html`<p class="error">Error: ${this._error}</p>` : ""}
|
${this._error ? html`<p class="error">Error: ${this._error}</p>` : ""}
|
||||||
@ -87,18 +97,20 @@ class HassioSnapshotDialog
|
|||||||
Restore
|
Restore
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
|
|
||||||
<ha-button-menu
|
${!this._dialogParams.onboarding
|
||||||
fixed
|
? html`<ha-button-menu
|
||||||
slot="primaryAction"
|
fixed
|
||||||
@action=${this._handleMenuAction}
|
slot="primaryAction"
|
||||||
@closed=${(ev: Event) => ev.stopPropagation()}
|
@action=${this._handleMenuAction}
|
||||||
>
|
@closed=${(ev: Event) => ev.stopPropagation()}
|
||||||
<mwc-icon-button slot="trigger" alt="menu">
|
>
|
||||||
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
<mwc-icon-button slot="trigger" alt="menu">
|
||||||
</mwc-icon-button>
|
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
||||||
<mwc-list-item>Download Snapshot</mwc-list-item>
|
</mwc-icon-button>
|
||||||
<mwc-list-item class="error">Delete Snapshot</mwc-list-item>
|
<mwc-list-item>Download Snapshot</mwc-list-item>
|
||||||
</ha-button-menu>
|
<mwc-list-item class="error">Delete Snapshot</mwc-list-item>
|
||||||
|
</ha-button-menu>`
|
||||||
|
: ""}
|
||||||
</ha-dialog>
|
</ha-dialog>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -115,6 +127,12 @@ class HassioSnapshotDialog
|
|||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
ha-header-bar {
|
||||||
|
--mdc-theme-on-primary: var(--primary-text-color);
|
||||||
|
--mdc-theme-primary: var(--mdc-theme-surface);
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
|
import { LocalizeFunc } from "../../../../src/common/translations/localize";
|
||||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
|
|
||||||
export interface HassioSnapshotDialogParams {
|
export interface HassioSnapshotDialogParams {
|
||||||
@ -6,6 +7,7 @@ export interface HassioSnapshotDialogParams {
|
|||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
onboarding?: boolean;
|
onboarding?: boolean;
|
||||||
supervisor?: Supervisor;
|
supervisor?: Supervisor;
|
||||||
|
localize?: LocalizeFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const showHassioSnapshotDialog = (
|
export const showHassioSnapshotDialog = (
|
||||||
|
@ -12,7 +12,10 @@ import { HASSDomEvent } from "../common/dom/fire_event";
|
|||||||
import { extractSearchParamsObject } from "../common/url/search-params";
|
import { extractSearchParamsObject } from "../common/url/search-params";
|
||||||
import { subscribeOne } from "../common/util/subscribe-one";
|
import { subscribeOne } from "../common/util/subscribe-one";
|
||||||
import { AuthUrlSearchParams, hassUrl } from "../data/auth";
|
import { AuthUrlSearchParams, hassUrl } from "../data/auth";
|
||||||
import { fetchDiscoveryInformation } from "../data/discovery";
|
import {
|
||||||
|
DiscoveryInformation,
|
||||||
|
fetchDiscoveryInformation,
|
||||||
|
} from "../data/discovery";
|
||||||
import {
|
import {
|
||||||
fetchOnboardingOverview,
|
fetchOnboardingOverview,
|
||||||
OnboardingResponses,
|
OnboardingResponses,
|
||||||
@ -68,6 +71,8 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
|||||||
|
|
||||||
@state() private _steps?: OnboardingStep[];
|
@state() private _steps?: OnboardingStep[];
|
||||||
|
|
||||||
|
@state() private _discoveryInformation?: DiscoveryInformation;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const step = this._curStep()!;
|
const step = this._curStep()!;
|
||||||
|
|
||||||
@ -87,6 +92,7 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
|||||||
? html`<onboarding-restore-snapshot
|
? html`<onboarding-restore-snapshot
|
||||||
.localize=${this.localize}
|
.localize=${this.localize}
|
||||||
.restoring=${this._restoring}
|
.restoring=${this._restoring}
|
||||||
|
.discoveryInformation=${this._discoveryInformation}
|
||||||
@restoring=${this._restoringSnapshot}
|
@restoring=${this._restoringSnapshot}
|
||||||
>
|
>
|
||||||
</onboarding-restore-snapshot>`
|
</onboarding-restore-snapshot>`
|
||||||
|
@ -4,9 +4,12 @@ import { customElement, property } from "lit/decorators";
|
|||||||
import "../../hassio/src/components/hassio-ansi-to-html";
|
import "../../hassio/src/components/hassio-ansi-to-html";
|
||||||
import { showHassioSnapshotDialog } from "../../hassio/src/dialogs/snapshot/show-dialog-hassio-snapshot";
|
import { showHassioSnapshotDialog } from "../../hassio/src/dialogs/snapshot/show-dialog-hassio-snapshot";
|
||||||
import { showSnapshotUploadDialog } from "../../hassio/src/dialogs/snapshot/show-dialog-snapshot-upload";
|
import { showSnapshotUploadDialog } from "../../hassio/src/dialogs/snapshot/show-dialog-snapshot-upload";
|
||||||
import { navigate } from "../common/navigate";
|
|
||||||
import type { LocalizeFunc } from "../common/translations/localize";
|
import type { LocalizeFunc } from "../common/translations/localize";
|
||||||
import "../components/ha-card";
|
import "../components/ha-card";
|
||||||
|
import {
|
||||||
|
DiscoveryInformation,
|
||||||
|
fetchDiscoveryInformation,
|
||||||
|
} from "../data/discovery";
|
||||||
import { makeDialogManager } from "../dialogs/make-dialog-manager";
|
import { makeDialogManager } from "../dialogs/make-dialog-manager";
|
||||||
import { ProvideHassLitMixin } from "../mixins/provide-hass-lit-mixin";
|
import { ProvideHassLitMixin } from "../mixins/provide-hass-lit-mixin";
|
||||||
import { haStyle } from "../resources/styles";
|
import { haStyle } from "../resources/styles";
|
||||||
@ -26,6 +29,9 @@ class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public restoring = false;
|
@property({ type: Boolean }) public restoring = false;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public discoveryInformation?: DiscoveryInformation;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return this.restoring
|
return this.restoring
|
||||||
? html`<ha-card
|
? html`<ha-card
|
||||||
@ -58,13 +64,14 @@ class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) {
|
|||||||
private async _checkRestoreStatus(): Promise<void> {
|
private async _checkRestoreStatus(): Promise<void> {
|
||||||
if (this.restoring) {
|
if (this.restoring) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/hassio/supervisor/info", {
|
const response = await fetchDiscoveryInformation();
|
||||||
method: "GET",
|
|
||||||
});
|
if (
|
||||||
if (response.status === 401) {
|
!this.discoveryInformation ||
|
||||||
// If we get a unauthorized response, the restore is done
|
this.discoveryInformation.uuid !== response.uuid
|
||||||
navigate("/", { replace: true });
|
) {
|
||||||
location.reload();
|
// When the UUID changes, the restore is complete
|
||||||
|
window.location.replace("/");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// We fully expected issues with fetching info untill restore is complete.
|
// We fully expected issues with fetching info untill restore is complete.
|
||||||
@ -76,6 +83,7 @@ class OnboardingRestoreSnapshot extends ProvideHassLitMixin(LitElement) {
|
|||||||
showHassioSnapshotDialog(this, {
|
showHassioSnapshotDialog(this, {
|
||||||
slug,
|
slug,
|
||||||
onboarding: true,
|
onboarding: true,
|
||||||
|
localize: this.localize,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3569,7 +3569,16 @@
|
|||||||
"description": "Alternatively you can restore from a previous snapshot.",
|
"description": "Alternatively you can restore from a previous snapshot.",
|
||||||
"in_progress": "Restore in progress",
|
"in_progress": "Restore in progress",
|
||||||
"show_log": "Show full log",
|
"show_log": "Show full log",
|
||||||
"hide_log": "Hide full log"
|
"hide_log": "Hide full log",
|
||||||
|
"full_snapshot": "[%key:supervisor::snapshot::full_snapshot%]",
|
||||||
|
"partial_snapshot": "[%key:supervisor::snapshot::partial_snapshot%]",
|
||||||
|
"type": "[%key:supervisor::snapshot::type%]",
|
||||||
|
"select_type": "[%key:supervisor::snapshot::select_type%]",
|
||||||
|
"folders": "[%key:supervisor::snapshot::folders%]",
|
||||||
|
"addons": "[%key:supervisor::snapshot::addons%]",
|
||||||
|
"password_protection": "[%key:supervisor::snapshot::password_protection%]",
|
||||||
|
"password": "[%key:supervisor::snapshot::password%]",
|
||||||
|
"confirm_password": "[%key:supervisor::snapshot::confirm_password%]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"custom": {
|
"custom": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user