mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 03:06:41 +00:00
Fix hassio
This commit is contained in:
parent
cbe5355d38
commit
fe73213643
@ -11,18 +11,51 @@ import { getSignedPath } from "../../../../src/auth/data";
|
|||||||
import "../../../../src/resources/ha-style";
|
import "../../../../src/resources/ha-style";
|
||||||
import "../../../../src/components/dialog/ha-paper-dialog";
|
import "../../../../src/components/dialog/ha-paper-dialog";
|
||||||
import { customElement } from "lit-element";
|
import { customElement } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
|
||||||
import { PaperDialogElement } from "@polymer/paper-dialog";
|
import { PaperDialogElement } from "@polymer/paper-dialog";
|
||||||
import { HassioSnapshotDialogParams } from "./show-dialog-hassio-snapshot";
|
import { HassioSnapshotDialogParams } from "./show-dialog-hassio-snapshot";
|
||||||
|
import { fetchHassioSnapshotInfo } from "../../../../src/data/hassio";
|
||||||
|
|
||||||
|
const _computeFolders = (folders) => {
|
||||||
|
const list: Array<{ slug: string; name: string; checked: boolean }> = [];
|
||||||
|
if (folders.includes("homeassistant")) {
|
||||||
|
list.push({
|
||||||
|
slug: "homeassistant",
|
||||||
|
name: "Home Assistant configuration",
|
||||||
|
checked: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (folders.includes("ssl")) {
|
||||||
|
list.push({ slug: "ssl", name: "SSL", checked: true });
|
||||||
|
}
|
||||||
|
if (folders.includes("share")) {
|
||||||
|
list.push({ slug: "share", name: "Share", checked: true });
|
||||||
|
}
|
||||||
|
if (folders.includes("addons/local")) {
|
||||||
|
list.push({ slug: "addons/local", name: "Local add-ons", checked: true });
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
const _computeAddons = (addons) => {
|
||||||
|
return addons.map((addon) => ({
|
||||||
|
slug: addon.slug,
|
||||||
|
name: addon.name,
|
||||||
|
version: addon.version,
|
||||||
|
checked: true,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("dialog-hassio-snapshot")
|
@customElement("dialog-hassio-snapshot")
|
||||||
class HassioSnapshotDialog extends PolymerElement {
|
class HassioSnapshotDialog extends PolymerElement {
|
||||||
public hass!: HomeAssistant;
|
// Commented out because it breaks Polymer! Kept around for when we migrate
|
||||||
protected error?: string;
|
// to Lit. Now just putting ts-ignore everywhere because we need this out.
|
||||||
private snapshot?: any;
|
// Sorry future developer.
|
||||||
private dialogParams?: HassioSnapshotDialogParams;
|
// public hass!: HomeAssistant;
|
||||||
private restoreHass!: boolean;
|
// protected error?: string;
|
||||||
private snapshotPassword!: string;
|
// private snapshot?: any;
|
||||||
|
// private dialogParams?: HassioSnapshotDialogParams;
|
||||||
|
// private restoreHass!: boolean;
|
||||||
|
// private snapshotPassword!: string;
|
||||||
|
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
@ -89,22 +122,18 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
<paper-checkbox checked="{{restoreHass}}">
|
<paper-checkbox checked="{{restoreHass}}">
|
||||||
Home Assistant [[snapshot.homeassistant]]
|
Home Assistant [[snapshot.homeassistant]]
|
||||||
</paper-checkbox>
|
</paper-checkbox>
|
||||||
<template is="dom-if" if="[[snapshot.addons.length]]">
|
<template is="dom-if" if="[[_folders.length]]">
|
||||||
<div>Folders:</div>
|
<div>Folders:</div>
|
||||||
<template is="dom-repeat" items="[[snapshot.folders]]">
|
<template is="dom-repeat" items="[[_folders]]">
|
||||||
<paper-checkbox checked="{{item.checked}}">
|
<paper-checkbox checked="{{item.checked}}">
|
||||||
[[item.name]]
|
[[item.name]]
|
||||||
</paper-checkbox>
|
</paper-checkbox>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template is="dom-if" if="[[snapshot.addons.length]]">
|
<template is="dom-if" if="[[_addons.length]]">
|
||||||
<div>Add-ons:</div>
|
<div>Add-ons:</div>
|
||||||
<paper-dialog-scrollable>
|
<paper-dialog-scrollable>
|
||||||
<template
|
<template is="dom-repeat" items="[[_addons]]" sort="_sortAddons">
|
||||||
is="dom-repeat"
|
|
||||||
items="[[snapshot.addons]]"
|
|
||||||
sort="_sortAddons"
|
|
||||||
>
|
|
||||||
<paper-checkbox checked="{{item.checked}}">
|
<paper-checkbox checked="{{item.checked}}">
|
||||||
[[item.name]] <span class="details">([[item.version]])</span>
|
[[item.name]] <span class="details">([[item.version]])</span>
|
||||||
</paper-checkbox>
|
</paper-checkbox>
|
||||||
@ -151,7 +180,10 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: Object,
|
hass: Object,
|
||||||
|
dialogParams: Object,
|
||||||
snapshot: Object,
|
snapshot: Object,
|
||||||
|
_folders: Object,
|
||||||
|
_addons: Object,
|
||||||
restoreHass: {
|
restoreHass: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: true,
|
value: true,
|
||||||
@ -161,49 +193,16 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public showDialog(params: HassioSnapshotDialogParams) {
|
public async showDialog(params: HassioSnapshotDialogParams) {
|
||||||
this.dialogParams = params;
|
// @ts-ignore
|
||||||
this.hass.callApi("GET", `hassio/snapshots/${params.slug}/info`).then(
|
const snapshot = await fetchHassioSnapshotInfo(this.hass, params.slug);
|
||||||
(info: any) => {
|
this.setProperties({
|
||||||
info.data.folders = this._computeFolders(info.data.folders);
|
dialogParams: params,
|
||||||
info.data.addons = this._computeAddons(info.data.addons);
|
snapshot,
|
||||||
this.setProperties({ snapshot: info.data });
|
_folders: _computeFolders(snapshot.folders),
|
||||||
(this.$.dialog as PaperDialogElement).open();
|
_addons: _computeAddons(snapshot.addons),
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.dialogParams = undefined;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected _computeFolders(folders) {
|
|
||||||
const list: Array<{ slug: string; name: string; checked: boolean }> = [];
|
|
||||||
if (folders.includes("homeassistant")) {
|
|
||||||
list.push({
|
|
||||||
slug: "homeassistant",
|
|
||||||
name: "Home Assistant configuration",
|
|
||||||
checked: true,
|
|
||||||
});
|
});
|
||||||
}
|
(this.$.dialog as PaperDialogElement).open();
|
||||||
if (folders.includes("ssl")) {
|
|
||||||
list.push({ slug: "ssl", name: "SSL", checked: true });
|
|
||||||
}
|
|
||||||
if (folders.includes("share")) {
|
|
||||||
list.push({ slug: "share", name: "Share", checked: true });
|
|
||||||
}
|
|
||||||
if (folders.includes("addons/local")) {
|
|
||||||
list.push({ slug: "addons/local", name: "Local add-ons", checked: true });
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected _computeAddons(addons) {
|
|
||||||
return addons.map((addon) => ({
|
|
||||||
slug: addon.slug,
|
|
||||||
name: addon.name,
|
|
||||||
version: addon.version,
|
|
||||||
checked: true,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _isFullSnapshot(type) {
|
protected _isFullSnapshot(type) {
|
||||||
@ -214,26 +213,32 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
if (!confirm("Are you sure you want to restore this snapshot?")) {
|
if (!confirm("Are you sure you want to restore this snapshot?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const addons = this.snapshot.addons
|
// @ts-ignore
|
||||||
|
const addons = this._addons
|
||||||
.filter((addon) => addon.checked)
|
.filter((addon) => addon.checked)
|
||||||
.map((addon) => addon.slug);
|
.map((addon) => addon.slug);
|
||||||
const folders = this.snapshot.folders
|
// @ts-ignore
|
||||||
|
const folders = this._folders
|
||||||
.filter((folder) => folder.checked)
|
.filter((folder) => folder.checked)
|
||||||
.map((folder) => folder.slug);
|
.map((folder) => folder.slug);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
// @ts-ignore
|
||||||
homeassistant: this.restoreHass,
|
homeassistant: this.restoreHass,
|
||||||
addons,
|
addons,
|
||||||
folders,
|
folders,
|
||||||
};
|
};
|
||||||
|
// @ts-ignore
|
||||||
if (this.snapshot.protected) {
|
if (this.snapshot.protected) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
data.password = this.snapshotPassword;
|
data.password = this.snapshotPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
this.hass
|
this.hass
|
||||||
.callApi(
|
.callApi(
|
||||||
"POST",
|
"POST",
|
||||||
|
// @ts-ignore
|
||||||
`hassio/snapshots/${this.dialogParams!.slug}/restore/partial`,
|
`hassio/snapshots/${this.dialogParams!.slug}/restore/partial`,
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
@ -243,6 +248,7 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
(this.$.dialog as PaperDialogElement).close();
|
(this.$.dialog as PaperDialogElement).close();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
// @ts-ignore
|
||||||
this.error = error.body.message;
|
this.error = error.body.message;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -252,12 +258,19 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
if (!confirm("Are you sure you want to restore this snapshot?")) {
|
if (!confirm("Are you sure you want to restore this snapshot?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// @ts-ignore
|
||||||
const data = this.snapshot.protected
|
const data = this.snapshot.protected
|
||||||
? { password: this.snapshotPassword }
|
? {
|
||||||
|
password:
|
||||||
|
// @ts-ignore
|
||||||
|
this.snapshotPassword,
|
||||||
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
// @ts-ignore
|
||||||
this.hass
|
this.hass
|
||||||
.callApi(
|
.callApi(
|
||||||
"POST",
|
"POST",
|
||||||
|
// @ts-ignore
|
||||||
`hassio/snapshots/${this.dialogParams!.slug}/restore/full`,
|
`hassio/snapshots/${this.dialogParams!.slug}/restore/full`,
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
@ -267,6 +280,7 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
(this.$.dialog as PaperDialogElement).close();
|
(this.$.dialog as PaperDialogElement).close();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
// @ts-ignore
|
||||||
this.error = error.body.message;
|
this.error = error.body.message;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -276,14 +290,18 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
if (!confirm("Are you sure you want to delete this snapshot?")) {
|
if (!confirm("Are you sure you want to delete this snapshot?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// @ts-ignore
|
||||||
this.hass
|
this.hass
|
||||||
|
// @ts-ignore
|
||||||
.callApi("POST", `hassio/snapshots/${this.dialogParams!.slug}/remove`)
|
.callApi("POST", `hassio/snapshots/${this.dialogParams!.slug}/remove`)
|
||||||
.then(
|
.then(
|
||||||
() => {
|
() => {
|
||||||
(this.$.dialog as PaperDialogElement).close();
|
(this.$.dialog as PaperDialogElement).close();
|
||||||
|
// @ts-ignore
|
||||||
this.dialogParams!.onDelete();
|
this.dialogParams!.onDelete();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
// @ts-ignore
|
||||||
this.error = error.body.message;
|
this.error = error.body.message;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -293,13 +311,16 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
let signedPath;
|
let signedPath;
|
||||||
try {
|
try {
|
||||||
signedPath = await getSignedPath(
|
signedPath = await getSignedPath(
|
||||||
|
// @ts-ignore
|
||||||
this.hass,
|
this.hass,
|
||||||
|
// @ts-ignore
|
||||||
`/api/hassio/snapshots/${this.dialogParams!.slug}/download`
|
`/api/hassio/snapshots/${this.dialogParams!.slug}/download`
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert(`Error: ${err.message}`);
|
alert(`Error: ${err.message}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// @ts-ignore
|
||||||
const name = this._computeName(this.snapshot).replace(/[^a-z0-9]+/gi, "_");
|
const name = this._computeName(this.snapshot).replace(/[^a-z0-9]+/gi, "_");
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
a.href = signedPath.path;
|
a.href = signedPath.path;
|
||||||
@ -310,7 +331,7 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _computeName(snapshot) {
|
protected _computeName(snapshot) {
|
||||||
return snapshot.name || snapshot.slug;
|
return snapshot ? snapshot.name || snapshot.slug : "Unnamed snapshot";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _computeType(type) {
|
protected _computeType(type) {
|
||||||
@ -337,8 +358,12 @@ class HassioSnapshotDialog extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _dialogClosed() {
|
protected _dialogClosed() {
|
||||||
this.dialogParams = undefined;
|
this.setProperties({
|
||||||
this.snapshot = undefined;
|
dialogParams: undefined,
|
||||||
|
snapshot: undefined,
|
||||||
|
_addons: [],
|
||||||
|
_folders: [],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ import { PolymerElement } from "@polymer/polymer";
|
|||||||
import { HomeAssistant } from "../../src/types";
|
import { HomeAssistant } from "../../src/types";
|
||||||
// Don't codesplit it, that way the dashboard always loads fast.
|
// Don't codesplit it, that way the dashboard always loads fast.
|
||||||
import "./dashboard/hassio-dashboard";
|
import "./dashboard/hassio-dashboard";
|
||||||
|
// Don't codesplit the others, because it breaks the UI when pushed to a Pi
|
||||||
|
import "./snapshots/hassio-snapshots";
|
||||||
|
import "./addon-store/hassio-addon-store";
|
||||||
|
import "./system/hassio-system";
|
||||||
import {
|
import {
|
||||||
HassioSupervisorInfo,
|
HassioSupervisorInfo,
|
||||||
HassioHostInfo,
|
HassioHostInfo,
|
||||||
@ -27,15 +31,12 @@ class HassioTabsRouter extends HassRouterPage {
|
|||||||
},
|
},
|
||||||
snapshots: {
|
snapshots: {
|
||||||
tag: "hassio-snapshots",
|
tag: "hassio-snapshots",
|
||||||
load: () => import("./snapshots/hassio-snapshots"),
|
|
||||||
},
|
},
|
||||||
store: {
|
store: {
|
||||||
tag: "hassio-addon-store",
|
tag: "hassio-addon-store",
|
||||||
load: () => import("./addon-store/hassio-addon-store"),
|
|
||||||
},
|
},
|
||||||
system: {
|
system: {
|
||||||
tag: "hassio-system",
|
tag: "hassio-system",
|
||||||
load: () => import("./system/hassio-system"),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -31,11 +31,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: webpackBase.optimization(latestBuild),
|
||||||
...webpackBase.optimization(latestBuild),
|
|
||||||
// Try #4323432 to get hass.io to wrk on es5
|
|
||||||
concatenateModules: false,
|
|
||||||
},
|
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
__DEV__: JSON.stringify(!isProdBuild),
|
__DEV__: JSON.stringify(!isProdBuild),
|
||||||
|
@ -110,6 +110,19 @@ export interface HassioSnapshot {
|
|||||||
protected: boolean;
|
protected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HassioSnapshotDetail extends HassioSnapshot {
|
||||||
|
size: string;
|
||||||
|
homeassistant: string;
|
||||||
|
addons: Array<{
|
||||||
|
slug: "ADDON_SLUG";
|
||||||
|
name: "NAME";
|
||||||
|
version: "INSTALLED_VERSION";
|
||||||
|
size: "SIZE_IN_MB";
|
||||||
|
}>;
|
||||||
|
repositories: string[];
|
||||||
|
folders: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface HassioFullSnapshotCreateParams {
|
export interface HassioFullSnapshotCreateParams {
|
||||||
name: string;
|
name: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
@ -191,3 +204,14 @@ export const createHassioPartialSnapshot = (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
data: HassioPartialSnapshotCreateParams
|
data: HassioPartialSnapshotCreateParams
|
||||||
) => hass.callApi<unknown>("POST", "hassio/snapshots/new/partial", data);
|
) => hass.callApi<unknown>("POST", "hassio/snapshots/new/partial", data);
|
||||||
|
|
||||||
|
export const fetchHassioSnapshotInfo = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
snapshot: string
|
||||||
|
) =>
|
||||||
|
hass
|
||||||
|
.callApi<HassioResponse<HassioSnapshotDetail>>(
|
||||||
|
"GET",
|
||||||
|
`hassio/snapshots/${snapshot}/info`
|
||||||
|
)
|
||||||
|
.then(hassioApiResultExtractor);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user