diff --git a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts b/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts
index a784ec21a4..6ced46ca76 100644
--- a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts
+++ b/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts
@@ -11,18 +11,51 @@ import { getSignedPath } from "../../../../src/auth/data";
import "../../../../src/resources/ha-style";
import "../../../../src/components/dialog/ha-paper-dialog";
import { customElement } from "lit-element";
-import { HomeAssistant } from "../../../../src/types";
import { PaperDialogElement } from "@polymer/paper-dialog";
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")
class HassioSnapshotDialog extends PolymerElement {
- public hass!: HomeAssistant;
- protected error?: string;
- private snapshot?: any;
- private dialogParams?: HassioSnapshotDialogParams;
- private restoreHass!: boolean;
- private snapshotPassword!: string;
+ // Commented out because it breaks Polymer! Kept around for when we migrate
+ // to Lit. Now just putting ts-ignore everywhere because we need this out.
+ // Sorry future developer.
+ // public hass!: HomeAssistant;
+ // protected error?: string;
+ // private snapshot?: any;
+ // private dialogParams?: HassioSnapshotDialogParams;
+ // private restoreHass!: boolean;
+ // private snapshotPassword!: string;
static get template() {
return html`
@@ -89,22 +122,18 @@ class HassioSnapshotDialog extends PolymerElement {
Home Assistant [[snapshot.homeassistant]]
-
+
Folders:
-
+
[[item.name]]
-
+
Add-ons:
-
+
[[item.name]] ([[item.version]])
@@ -151,7 +180,10 @@ class HassioSnapshotDialog extends PolymerElement {
static get properties() {
return {
hass: Object,
+ dialogParams: Object,
snapshot: Object,
+ _folders: Object,
+ _addons: Object,
restoreHass: {
type: Boolean,
value: true,
@@ -161,49 +193,16 @@ class HassioSnapshotDialog extends PolymerElement {
};
}
- public showDialog(params: HassioSnapshotDialogParams) {
- this.dialogParams = params;
- this.hass.callApi("GET", `hassio/snapshots/${params.slug}/info`).then(
- (info: any) => {
- info.data.folders = this._computeFolders(info.data.folders);
- info.data.addons = this._computeAddons(info.data.addons);
- this.setProperties({ snapshot: info.data });
- (this.$.dialog as PaperDialogElement).open();
- },
- () => {
- 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,
- });
- }
- 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,
- }));
+ public async showDialog(params: HassioSnapshotDialogParams) {
+ // @ts-ignore
+ const snapshot = await fetchHassioSnapshotInfo(this.hass, params.slug);
+ this.setProperties({
+ dialogParams: params,
+ snapshot,
+ _folders: _computeFolders(snapshot.folders),
+ _addons: _computeAddons(snapshot.addons),
+ });
+ (this.$.dialog as PaperDialogElement).open();
}
protected _isFullSnapshot(type) {
@@ -214,26 +213,32 @@ class HassioSnapshotDialog extends PolymerElement {
if (!confirm("Are you sure you want to restore this snapshot?")) {
return;
}
- const addons = this.snapshot.addons
+ // @ts-ignore
+ const addons = this._addons
.filter((addon) => addon.checked)
.map((addon) => addon.slug);
- const folders = this.snapshot.folders
+ // @ts-ignore
+ const folders = this._folders
.filter((folder) => folder.checked)
.map((folder) => folder.slug);
const data = {
+ // @ts-ignore
homeassistant: this.restoreHass,
addons,
folders,
};
+ // @ts-ignore
if (this.snapshot.protected) {
// @ts-ignore
data.password = this.snapshotPassword;
}
+ // @ts-ignore
this.hass
.callApi(
"POST",
+ // @ts-ignore
`hassio/snapshots/${this.dialogParams!.slug}/restore/partial`,
data
)
@@ -243,6 +248,7 @@ class HassioSnapshotDialog extends PolymerElement {
(this.$.dialog as PaperDialogElement).close();
},
(error) => {
+ // @ts-ignore
this.error = error.body.message;
}
);
@@ -252,12 +258,19 @@ class HassioSnapshotDialog extends PolymerElement {
if (!confirm("Are you sure you want to restore this snapshot?")) {
return;
}
+ // @ts-ignore
const data = this.snapshot.protected
- ? { password: this.snapshotPassword }
+ ? {
+ password:
+ // @ts-ignore
+ this.snapshotPassword,
+ }
: undefined;
+ // @ts-ignore
this.hass
.callApi(
"POST",
+ // @ts-ignore
`hassio/snapshots/${this.dialogParams!.slug}/restore/full`,
data
)
@@ -267,6 +280,7 @@ class HassioSnapshotDialog extends PolymerElement {
(this.$.dialog as PaperDialogElement).close();
},
(error) => {
+ // @ts-ignore
this.error = error.body.message;
}
);
@@ -276,14 +290,18 @@ class HassioSnapshotDialog extends PolymerElement {
if (!confirm("Are you sure you want to delete this snapshot?")) {
return;
}
+ // @ts-ignore
this.hass
+ // @ts-ignore
.callApi("POST", `hassio/snapshots/${this.dialogParams!.slug}/remove`)
.then(
() => {
(this.$.dialog as PaperDialogElement).close();
+ // @ts-ignore
this.dialogParams!.onDelete();
},
(error) => {
+ // @ts-ignore
this.error = error.body.message;
}
);
@@ -293,13 +311,16 @@ class HassioSnapshotDialog extends PolymerElement {
let signedPath;
try {
signedPath = await getSignedPath(
+ // @ts-ignore
this.hass,
+ // @ts-ignore
`/api/hassio/snapshots/${this.dialogParams!.slug}/download`
);
} catch (err) {
alert(`Error: ${err.message}`);
return;
}
+ // @ts-ignore
const name = this._computeName(this.snapshot).replace(/[^a-z0-9]+/gi, "_");
const a = document.createElement("a");
a.href = signedPath.path;
@@ -310,7 +331,7 @@ class HassioSnapshotDialog extends PolymerElement {
}
protected _computeName(snapshot) {
- return snapshot.name || snapshot.slug;
+ return snapshot ? snapshot.name || snapshot.slug : "Unnamed snapshot";
}
protected _computeType(type) {
@@ -337,8 +358,12 @@ class HassioSnapshotDialog extends PolymerElement {
}
protected _dialogClosed() {
- this.dialogParams = undefined;
- this.snapshot = undefined;
+ this.setProperties({
+ dialogParams: undefined,
+ snapshot: undefined,
+ _addons: [],
+ _folders: [],
+ });
}
}
diff --git a/hassio/src/hassio-tabs-router.ts b/hassio/src/hassio-tabs-router.ts
index 11726c8c36..53f9b16def 100644
--- a/hassio/src/hassio-tabs-router.ts
+++ b/hassio/src/hassio-tabs-router.ts
@@ -7,6 +7,10 @@ import { PolymerElement } from "@polymer/polymer";
import { HomeAssistant } from "../../src/types";
// Don't codesplit it, that way the dashboard always loads fast.
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 {
HassioSupervisorInfo,
HassioHostInfo,
@@ -27,15 +31,12 @@ class HassioTabsRouter extends HassRouterPage {
},
snapshots: {
tag: "hassio-snapshots",
- load: () => import("./snapshots/hassio-snapshots"),
},
store: {
tag: "hassio-addon-store",
- load: () => import("./addon-store/hassio-addon-store"),
},
system: {
tag: "hassio-system",
- load: () => import("./system/hassio-system"),
},
},
};
diff --git a/hassio/webpack.config.js b/hassio/webpack.config.js
index 1a8936d771..022bbb563c 100644
--- a/hassio/webpack.config.js
+++ b/hassio/webpack.config.js
@@ -31,11 +31,7 @@ module.exports = {
},
],
},
- optimization: {
- ...webpackBase.optimization(latestBuild),
- // Try #4323432 to get hass.io to wrk on es5
- concatenateModules: false,
- },
+ optimization: webpackBase.optimization(latestBuild),
plugins: [
new webpack.DefinePlugin({
__DEV__: JSON.stringify(!isProdBuild),
diff --git a/src/data/hassio.ts b/src/data/hassio.ts
index 3066bf31cf..ab3b840df3 100644
--- a/src/data/hassio.ts
+++ b/src/data/hassio.ts
@@ -110,6 +110,19 @@ export interface HassioSnapshot {
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 {
name: string;
password?: string;
@@ -191,3 +204,14 @@ export const createHassioPartialSnapshot = (
hass: HomeAssistant,
data: HassioPartialSnapshotCreateParams
) => hass.callApi("POST", "hassio/snapshots/new/partial", data);
+
+export const fetchHassioSnapshotInfo = (
+ hass: HomeAssistant,
+ snapshot: string
+) =>
+ hass
+ .callApi>(
+ "GET",
+ `hassio/snapshots/${snapshot}/info`
+ )
+ .then(hassioApiResultExtractor);