mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +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/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 {
|
||||
<paper-checkbox checked="{{restoreHass}}">
|
||||
Home Assistant [[snapshot.homeassistant]]
|
||||
</paper-checkbox>
|
||||
<template is="dom-if" if="[[snapshot.addons.length]]">
|
||||
<template is="dom-if" if="[[_folders.length]]">
|
||||
<div>Folders:</div>
|
||||
<template is="dom-repeat" items="[[snapshot.folders]]">
|
||||
<template is="dom-repeat" items="[[_folders]]">
|
||||
<paper-checkbox checked="{{item.checked}}">
|
||||
[[item.name]]
|
||||
</paper-checkbox>
|
||||
</template>
|
||||
</template>
|
||||
<template is="dom-if" if="[[snapshot.addons.length]]">
|
||||
<template is="dom-if" if="[[_addons.length]]">
|
||||
<div>Add-ons:</div>
|
||||
<paper-dialog-scrollable>
|
||||
<template
|
||||
is="dom-repeat"
|
||||
items="[[snapshot.addons]]"
|
||||
sort="_sortAddons"
|
||||
>
|
||||
<template is="dom-repeat" items="[[_addons]]" sort="_sortAddons">
|
||||
<paper-checkbox checked="{{item.checked}}">
|
||||
[[item.name]] <span class="details">([[item.version]])</span>
|
||||
</paper-checkbox>
|
||||
@ -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: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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<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