mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
parent
5b861bb4c6
commit
4d2390daf4
@ -26,21 +26,15 @@ class HassioIngressView extends LitElement {
|
|||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
if (!this._addon) {
|
if (!this._addon) {
|
||||||
return html`
|
return html`
|
||||||
<hass-loading-screen rootnav></hass-loading-screen>
|
<hass-loading-screen></hass-loading-screen>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const iframe = html`
|
return html`
|
||||||
<iframe src=${this._addon.ingress_url}></iframe>
|
<hass-subpage .header=${this._addon.name} hassio>
|
||||||
|
<iframe src=${this._addon.ingress_url}></iframe>
|
||||||
|
</hass-subpage>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return location.search === "?kiosk"
|
|
||||||
? iframe
|
|
||||||
: html`
|
|
||||||
<hass-subpage .header=${this._addon.name} hassio root>
|
|
||||||
${iframe}
|
|
||||||
</hass-subpage>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
|
@ -1,316 +0,0 @@
|
|||||||
import "@material/mwc-button";
|
|
||||||
import "@polymer/paper-card/paper-card";
|
|
||||||
import "@polymer/paper-checkbox/paper-checkbox";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
import "@polymer/paper-radio-button/paper-radio-button";
|
|
||||||
import "@polymer/paper-radio-group/paper-radio-group";
|
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
|
|
||||||
import "../components/hassio-card-content";
|
|
||||||
import "../resources/hassio-style";
|
|
||||||
import EventsMixin from "../../../src/mixins/events-mixin";
|
|
||||||
|
|
||||||
import { showHassioSnapshotDialog } from "../dialogs/snapshot/show-dialog-hassio-snapshot";
|
|
||||||
|
|
||||||
class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|
||||||
static get template() {
|
|
||||||
return html`
|
|
||||||
<style include="ha-style hassio-style">
|
|
||||||
paper-radio-group {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
paper-radio-button {
|
|
||||||
padding: 0 0 2px 2px;
|
|
||||||
}
|
|
||||||
paper-radio-button,
|
|
||||||
paper-checkbox,
|
|
||||||
paper-input[type="password"] {
|
|
||||||
display: block;
|
|
||||||
margin: 4px 0 4px 48px;
|
|
||||||
}
|
|
||||||
.pointer {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="content">
|
|
||||||
<div class="card-group">
|
|
||||||
<div class="title">
|
|
||||||
Create snapshot
|
|
||||||
<div class="description">
|
|
||||||
Snapshots allow you to easily backup and restore all data of your
|
|
||||||
Hass.io instance.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<paper-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<paper-input
|
|
||||||
autofocus=""
|
|
||||||
label="Name"
|
|
||||||
value="{{snapshotName}}"
|
|
||||||
></paper-input>
|
|
||||||
Type:
|
|
||||||
<paper-radio-group selected="{{snapshotType}}">
|
|
||||||
<paper-radio-button name="full">
|
|
||||||
Full snapshot
|
|
||||||
</paper-radio-button>
|
|
||||||
<paper-radio-button name="partial">
|
|
||||||
Partial snapshot
|
|
||||||
</paper-radio-button>
|
|
||||||
</paper-radio-group>
|
|
||||||
<template is="dom-if" if="[[!_fullSelected(snapshotType)]]">
|
|
||||||
Folders:
|
|
||||||
<template is="dom-repeat" items="[[folderList]]">
|
|
||||||
<paper-checkbox checked="{{item.checked}}">
|
|
||||||
[[item.name]]
|
|
||||||
</paper-checkbox>
|
|
||||||
</template>
|
|
||||||
Add-ons:
|
|
||||||
<template
|
|
||||||
is="dom-repeat"
|
|
||||||
items="[[addonList]]"
|
|
||||||
sort="_sortAddons"
|
|
||||||
>
|
|
||||||
<paper-checkbox checked="{{item.checked}}">
|
|
||||||
[[item.name]]
|
|
||||||
</paper-checkbox>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
Security:
|
|
||||||
<paper-checkbox checked="{{snapshotHasPassword}}"
|
|
||||||
>Password protection</paper-checkbox
|
|
||||||
>
|
|
||||||
<template is="dom-if" if="[[snapshotHasPassword]]">
|
|
||||||
<paper-input
|
|
||||||
label="Password"
|
|
||||||
type="password"
|
|
||||||
value="{{snapshotPassword}}"
|
|
||||||
></paper-input>
|
|
||||||
</template>
|
|
||||||
<template is="dom-if" if="[[error]]">
|
|
||||||
<p class="error">[[error]]</p>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="card-actions">
|
|
||||||
<mwc-button
|
|
||||||
disabled="[[creatingSnapshot]]"
|
|
||||||
on-click="_createSnapshot"
|
|
||||||
>Create</mwc-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</paper-card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-group">
|
|
||||||
<div class="title">Available snapshots</div>
|
|
||||||
<template is="dom-if" if="[[!snapshots.length]]">
|
|
||||||
<paper-card>
|
|
||||||
<div class="card-content">You don't have any snapshots yet.</div>
|
|
||||||
</paper-card>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
is="dom-repeat"
|
|
||||||
items="[[snapshots]]"
|
|
||||||
as="snapshot"
|
|
||||||
sort="_sortSnapshots"
|
|
||||||
>
|
|
||||||
<paper-card class="pointer" on-click="_snapshotClicked">
|
|
||||||
<div class="card-content">
|
|
||||||
<hassio-card-content
|
|
||||||
hass="[[hass]]"
|
|
||||||
title="[[_computeName(snapshot)]]"
|
|
||||||
description="[[_computeDetails(snapshot)]]"
|
|
||||||
datetime="[[snapshot.date]]"
|
|
||||||
icon="[[_computeIcon(snapshot.type)]]"
|
|
||||||
icon-class="snapshot"
|
|
||||||
></hassio-card-content>
|
|
||||||
</div>
|
|
||||||
</paper-card>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
hass: Object,
|
|
||||||
snapshotName: {
|
|
||||||
type: String,
|
|
||||||
value: "",
|
|
||||||
},
|
|
||||||
snapshotPassword: {
|
|
||||||
type: String,
|
|
||||||
value: "",
|
|
||||||
},
|
|
||||||
snapshotHasPassword: Boolean,
|
|
||||||
snapshotType: {
|
|
||||||
type: String,
|
|
||||||
value: "full",
|
|
||||||
},
|
|
||||||
snapshots: {
|
|
||||||
type: Array,
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
supervisorInfo: Object,
|
|
||||||
installedAddons: {
|
|
||||||
type: Array,
|
|
||||||
computed: "_computeAddons(supervisorInfo)",
|
|
||||||
observer: "_installedAddonsChanged",
|
|
||||||
},
|
|
||||||
addonList: Array,
|
|
||||||
folderList: {
|
|
||||||
type: Array,
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
slug: "homeassistant",
|
|
||||||
name: "Home Assistant configuration",
|
|
||||||
checked: true,
|
|
||||||
},
|
|
||||||
{ slug: "ssl", name: "SSL", checked: true },
|
|
||||||
{ slug: "share", name: "Share", checked: true },
|
|
||||||
{ slug: "addons/local", name: "Local add-ons", checked: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
snapshotSlug: {
|
|
||||||
type: String,
|
|
||||||
notify: true,
|
|
||||||
},
|
|
||||||
snapshotDeleted: {
|
|
||||||
type: Boolean,
|
|
||||||
notify: true,
|
|
||||||
observer: "_snapshotDeletedChanged",
|
|
||||||
},
|
|
||||||
creatingSnapshot: Boolean,
|
|
||||||
dialogOpened: Boolean,
|
|
||||||
error: String,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
super.ready();
|
|
||||||
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
|
|
||||||
this._updateSnapshots();
|
|
||||||
}
|
|
||||||
|
|
||||||
_apiCalled(ev) {
|
|
||||||
if (ev.detail.success) {
|
|
||||||
this._updateSnapshots();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateSnapshots() {
|
|
||||||
this.hass.callApi("get", "hassio/snapshots").then(
|
|
||||||
(result) => {
|
|
||||||
this.snapshots = result.data.snapshots;
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
this.error = error.message;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_createSnapshot() {
|
|
||||||
this.error = "";
|
|
||||||
if (this.snapshotHasPassword && !this.snapshotPassword.length) {
|
|
||||||
this.error = "Please enter a password.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.creatingSnapshot = true;
|
|
||||||
let name = this.snapshotName;
|
|
||||||
if (!name.length) {
|
|
||||||
name = new Date().toLocaleDateString(navigator.language, {
|
|
||||||
weekday: "long",
|
|
||||||
year: "numeric",
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let data;
|
|
||||||
let path;
|
|
||||||
if (this.snapshotType === "full") {
|
|
||||||
data = { name: name };
|
|
||||||
path = "hassio/snapshots/new/full";
|
|
||||||
} else {
|
|
||||||
const addons = this.addonList
|
|
||||||
.filter((addon) => addon.checked)
|
|
||||||
.map((addon) => addon.slug);
|
|
||||||
const folders = this.folderList
|
|
||||||
.filter((folder) => folder.checked)
|
|
||||||
.map((folder) => folder.slug);
|
|
||||||
|
|
||||||
data = { name: name, folders: folders, addons: addons };
|
|
||||||
path = "hassio/snapshots/new/partial";
|
|
||||||
}
|
|
||||||
if (this.snapshotHasPassword) {
|
|
||||||
data.password = this.snapshotPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.hass.callApi("post", path, data).then(
|
|
||||||
() => {
|
|
||||||
this.creatingSnapshot = false;
|
|
||||||
this.fire("hass-api-called", { success: true });
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
this.creatingSnapshot = false;
|
|
||||||
this.error = error.message;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_installedAddonsChanged(addons) {
|
|
||||||
this.addonList = addons.map((addon) => ({
|
|
||||||
slug: addon.slug,
|
|
||||||
name: addon.name,
|
|
||||||
checked: true,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
_sortAddons(a, b) {
|
|
||||||
return a.name < b.name ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sortSnapshots(a, b) {
|
|
||||||
return a.date < b.date ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeName(snapshot) {
|
|
||||||
return snapshot.name || snapshot.slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeDetails(snapshot) {
|
|
||||||
const type =
|
|
||||||
snapshot.type === "full" ? "Full snapshot" : "Partial snapshot";
|
|
||||||
return snapshot.protected ? `${type}, password protected` : type;
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeIcon(type) {
|
|
||||||
return type === "full"
|
|
||||||
? "hassio:package-variant-closed"
|
|
||||||
: "hassio:package-variant";
|
|
||||||
}
|
|
||||||
|
|
||||||
_snapshotClicked(ev) {
|
|
||||||
showHassioSnapshotDialog(this, {
|
|
||||||
slug: ev.model.snapshot.slug,
|
|
||||||
onDelete: () => this._updateSnapshots(),
|
|
||||||
});
|
|
||||||
this.snapshotSlug = ev.model.snapshot.slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fullSelected(type) {
|
|
||||||
return type === "full";
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshData() {
|
|
||||||
this.hass.callApi("post", "hassio/snapshots/reload").then(() => {
|
|
||||||
this._updateSnapshots();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeAddons(supervisorInfo) {
|
|
||||||
return supervisorInfo.addons;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("hassio-snapshots", HassioSnapshots);
|
|
363
hassio/src/snapshots/hassio-snapshots.ts
Normal file
363
hassio/src/snapshots/hassio-snapshots.ts
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
import {
|
||||||
|
LitElement,
|
||||||
|
TemplateResult,
|
||||||
|
html,
|
||||||
|
CSSResultArray,
|
||||||
|
css,
|
||||||
|
property,
|
||||||
|
PropertyValues,
|
||||||
|
customElement,
|
||||||
|
} from "lit-element";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-checkbox/paper-checkbox";
|
||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-radio-button/paper-radio-button";
|
||||||
|
import "@polymer/paper-radio-group/paper-radio-group";
|
||||||
|
|
||||||
|
import "../components/hassio-card-content";
|
||||||
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
|
|
||||||
|
import { showHassioSnapshotDialog } from "../dialogs/snapshot/show-dialog-hassio-snapshot";
|
||||||
|
import { HomeAssistant } from "../../../src/types";
|
||||||
|
import {
|
||||||
|
HassioSnapshot,
|
||||||
|
HassioSupervisorInfo,
|
||||||
|
fetchHassioSnapshots,
|
||||||
|
reloadHassioSnapshots,
|
||||||
|
HassioFullSnapshotCreateParams,
|
||||||
|
HassioPartialSnapshotCreateParams,
|
||||||
|
createHassioFullSnapshot,
|
||||||
|
createHassioPartialSnapshot,
|
||||||
|
} from "../../../src/data/hassio";
|
||||||
|
import { PolymerChangedEvent } from "../../../src/polymer-types";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
|
|
||||||
|
// Not duplicate, used for typing
|
||||||
|
// tslint:disable-next-line
|
||||||
|
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||||
|
// tslint:disable-next-line
|
||||||
|
import { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-group";
|
||||||
|
// tslint:disable-next-line
|
||||||
|
import { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox";
|
||||||
|
|
||||||
|
interface CheckboxItem {
|
||||||
|
slug: string;
|
||||||
|
name: string;
|
||||||
|
checked: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement("hassio-snapshots")
|
||||||
|
class HassioSnapshots extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public supervisorInfo!: HassioSupervisorInfo;
|
||||||
|
@property() private _snapshotName = "";
|
||||||
|
@property() private _snapshotPassword = "";
|
||||||
|
@property() private _snapshotHasPassword = false;
|
||||||
|
@property() private _snapshotType: HassioSnapshot["type"] = "full";
|
||||||
|
@property() private _snapshots?: HassioSnapshot[] = [];
|
||||||
|
@property() private _addonList: CheckboxItem[] = [];
|
||||||
|
@property() private _folderList: CheckboxItem[] = [
|
||||||
|
{
|
||||||
|
slug: "homeassistant",
|
||||||
|
name: "Home Assistant configuration",
|
||||||
|
checked: true,
|
||||||
|
},
|
||||||
|
{ slug: "ssl", name: "SSL", checked: true },
|
||||||
|
{ slug: "share", name: "Share", checked: true },
|
||||||
|
{ slug: "addons/local", name: "Local add-ons", checked: true },
|
||||||
|
];
|
||||||
|
@property() private _creatingSnapshot = false;
|
||||||
|
@property() private _error = "";
|
||||||
|
|
||||||
|
public async refreshData() {
|
||||||
|
await reloadHassioSnapshots(this.hass);
|
||||||
|
await this._updateSnapshots();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
return html`
|
||||||
|
<div class="content">
|
||||||
|
<div class="card-group">
|
||||||
|
<div class="title">
|
||||||
|
Create snapshot
|
||||||
|
<div class="description">
|
||||||
|
Snapshots allow you to easily backup and restore all data of your
|
||||||
|
Hass.io instance.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<paper-card>
|
||||||
|
<div class="card-content">
|
||||||
|
<paper-input
|
||||||
|
autofocus
|
||||||
|
label="Name"
|
||||||
|
name="snapshotName"
|
||||||
|
.value=${this._snapshotName}
|
||||||
|
@value-changed=${this._handleTextValueChanged}
|
||||||
|
></paper-input>
|
||||||
|
Type:
|
||||||
|
<paper-radio-group
|
||||||
|
name="snapshotType"
|
||||||
|
.selected=${this._snapshotType}
|
||||||
|
@selected-changed=${this._handleRadioValueChanged}
|
||||||
|
>
|
||||||
|
<paper-radio-button name="full">
|
||||||
|
Full snapshot
|
||||||
|
</paper-radio-button>
|
||||||
|
<paper-radio-button name="partial">
|
||||||
|
Partial snapshot
|
||||||
|
</paper-radio-button>
|
||||||
|
</paper-radio-group>
|
||||||
|
${this._snapshotType === "full"
|
||||||
|
? undefined
|
||||||
|
: html`
|
||||||
|
Folders:
|
||||||
|
${this._folderList.map(
|
||||||
|
(folder, idx) => html`
|
||||||
|
<paper-checkbox
|
||||||
|
.idx=${idx}
|
||||||
|
.checked=${folder.checked}
|
||||||
|
@checked-changed=${this._folderChecked}
|
||||||
|
>
|
||||||
|
${folder.name}
|
||||||
|
</paper-checkbox>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
Add-ons:
|
||||||
|
${this._addonList.map(
|
||||||
|
(addon, idx) => html`
|
||||||
|
<paper-checkbox
|
||||||
|
.idx=${idx}
|
||||||
|
.checked="{{item.checked}}"
|
||||||
|
@checked-changed=${this._addonChecked}
|
||||||
|
>
|
||||||
|
${addon.name}
|
||||||
|
</paper-checkbox>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
`}
|
||||||
|
Security:
|
||||||
|
<paper-checkbox
|
||||||
|
name="snapshotHasPassword"
|
||||||
|
.checked=${this._snapshotHasPassword}
|
||||||
|
@checked-changed=${this._handleCheckboxValueChanged}
|
||||||
|
>
|
||||||
|
Password protection
|
||||||
|
</paper-checkbox>
|
||||||
|
${this._snapshotHasPassword
|
||||||
|
? html`
|
||||||
|
<paper-input
|
||||||
|
label="Password"
|
||||||
|
type="password"
|
||||||
|
name="snapshotPassword"
|
||||||
|
.value=${this._snapshotPassword}
|
||||||
|
@value-changed=${this._handleTextValueChanged}
|
||||||
|
></paper-input>
|
||||||
|
`
|
||||||
|
: undefined}
|
||||||
|
${this._error !== ""
|
||||||
|
? html`
|
||||||
|
<p class="error">${this._error}</p>
|
||||||
|
`
|
||||||
|
: undefined}
|
||||||
|
</div>
|
||||||
|
<div class="card-actions">
|
||||||
|
<mwc-button
|
||||||
|
.disabled=${this._creatingSnapshot}
|
||||||
|
@click=${this._createSnapshot}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</mwc-button>
|
||||||
|
</div>
|
||||||
|
</paper-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-group">
|
||||||
|
<div class="title">Available snapshots</div>
|
||||||
|
${this._snapshots === undefined
|
||||||
|
? undefined
|
||||||
|
: this._snapshots.length === 0
|
||||||
|
? html`
|
||||||
|
<paper-card>
|
||||||
|
<div class="card-content">
|
||||||
|
You don't have any snapshots yet.
|
||||||
|
</div>
|
||||||
|
</paper-card>
|
||||||
|
`
|
||||||
|
: this._snapshots.map(
|
||||||
|
(snapshot) => html`
|
||||||
|
<paper-card
|
||||||
|
class="pointer"
|
||||||
|
.snapshot=${snapshot}
|
||||||
|
@click=${this._snapshotClicked}
|
||||||
|
>
|
||||||
|
<div class="card-content">
|
||||||
|
<hassio-card-content
|
||||||
|
.hass=${this.hass}
|
||||||
|
.title=${snapshot.name || snapshot.slug}
|
||||||
|
.description=${this._computeDetails(snapshot)}
|
||||||
|
.datetime=${snapshot.date}
|
||||||
|
.icon=${snapshot.type === "full"
|
||||||
|
? "hassio:package-variant-closed"
|
||||||
|
: "hassio:package-variant"}
|
||||||
|
.
|
||||||
|
.icon-class="snapshot"
|
||||||
|
></hassio-card-content>
|
||||||
|
</div>
|
||||||
|
</paper-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
this._updateSnapshots();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps: PropertyValues) {
|
||||||
|
if (changedProps.has("supervisorInfo")) {
|
||||||
|
this._addonList = this.supervisorInfo.addons
|
||||||
|
.map((addon) => ({
|
||||||
|
slug: addon.slug,
|
||||||
|
name: addon.name,
|
||||||
|
checked: true,
|
||||||
|
}))
|
||||||
|
.sort((a, b) => (a.name < b.name ? -1 : 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleTextValueChanged(ev: PolymerChangedEvent<string>) {
|
||||||
|
const input = ev.currentTarget as PaperInputElement;
|
||||||
|
this[`_${input.name}`] = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCheckboxValueChanged(ev) {
|
||||||
|
const input = ev.currentTarget as PaperCheckboxElement;
|
||||||
|
this[`_${input.name}`] = input.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleRadioValueChanged(ev: PolymerChangedEvent<string>) {
|
||||||
|
const input = ev.currentTarget as PaperRadioGroupElement;
|
||||||
|
this[`_${input.getAttribute("name")}`] = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _folderChecked(ev) {
|
||||||
|
const { idx, checked } = ev.currentTarget!;
|
||||||
|
this._folderList = this._folderList.map((folder, curIdx) =>
|
||||||
|
curIdx === idx ? { ...folder, checked } : folder
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addonChecked(ev) {
|
||||||
|
const { idx, checked } = ev.currentTarget!;
|
||||||
|
this._addonList = this._addonList.map((addon, curIdx) =>
|
||||||
|
curIdx === idx ? { ...addon, checked } : addon
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _updateSnapshots() {
|
||||||
|
try {
|
||||||
|
this._snapshots = await fetchHassioSnapshots(this.hass);
|
||||||
|
this._snapshots.sort((a, b) => (a.date < b.date ? 1 : -1));
|
||||||
|
} catch (err) {
|
||||||
|
this._error = err.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _createSnapshot() {
|
||||||
|
this._error = "";
|
||||||
|
if (this._snapshotHasPassword && !this._snapshotPassword.length) {
|
||||||
|
this._error = "Please enter a password.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._creatingSnapshot = true;
|
||||||
|
await this.updateComplete;
|
||||||
|
|
||||||
|
const name =
|
||||||
|
this._snapshotName ||
|
||||||
|
new Date().toLocaleDateString(navigator.language, {
|
||||||
|
weekday: "long",
|
||||||
|
year: "numeric",
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this._snapshotType === "full") {
|
||||||
|
const data: HassioFullSnapshotCreateParams = { name };
|
||||||
|
if (this._snapshotHasPassword) {
|
||||||
|
data.password = this._snapshotPassword;
|
||||||
|
}
|
||||||
|
await createHassioFullSnapshot(this.hass, data);
|
||||||
|
} else {
|
||||||
|
const addons = this._addonList
|
||||||
|
.filter((addon) => addon.checked)
|
||||||
|
.map((addon) => addon.slug);
|
||||||
|
const folders = this._folderList
|
||||||
|
.filter((folder) => folder.checked)
|
||||||
|
.map((folder) => folder.slug);
|
||||||
|
|
||||||
|
const data: HassioPartialSnapshotCreateParams = {
|
||||||
|
name,
|
||||||
|
folders,
|
||||||
|
addons,
|
||||||
|
};
|
||||||
|
if (this._snapshotHasPassword) {
|
||||||
|
data.password = this._snapshotPassword;
|
||||||
|
}
|
||||||
|
await createHassioPartialSnapshot(this.hass, data);
|
||||||
|
}
|
||||||
|
this._updateSnapshots();
|
||||||
|
fireEvent(this, "hass-api-called", { success: true, response: null });
|
||||||
|
} catch (err) {
|
||||||
|
this._error = err.message;
|
||||||
|
} finally {
|
||||||
|
this._creatingSnapshot = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeDetails(snapshot: HassioSnapshot) {
|
||||||
|
const type =
|
||||||
|
snapshot.type === "full" ? "Full snapshot" : "Partial snapshot";
|
||||||
|
return snapshot.protected ? `${type}, password protected` : type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _snapshotClicked(ev) {
|
||||||
|
showHassioSnapshotDialog(this, {
|
||||||
|
slug: ev.currentTarget!.snapshot.slug,
|
||||||
|
onDelete: () => this._updateSnapshots(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultArray {
|
||||||
|
return [
|
||||||
|
hassioStyle,
|
||||||
|
css`
|
||||||
|
paper-radio-group {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
paper-radio-button {
|
||||||
|
padding: 0 0 2px 2px;
|
||||||
|
}
|
||||||
|
paper-radio-button,
|
||||||
|
paper-checkbox,
|
||||||
|
paper-input[type="password"] {
|
||||||
|
display: block;
|
||||||
|
margin: 4px 0 4px 48px;
|
||||||
|
}
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hassio-snapshots": HassioSnapshots;
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
...webpackBase.optimization(latestBuild),
|
...webpackBase.optimization(latestBuild),
|
||||||
|
// Try #4323432 to get hass.io to wrk on es5
|
||||||
concatenateModules: false,
|
concatenateModules: false,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -102,6 +102,25 @@ export type HassioHomeAssistantInfo = any;
|
|||||||
export type HassioSupervisorInfo = any;
|
export type HassioSupervisorInfo = any;
|
||||||
export type HassioHostInfo = any;
|
export type HassioHostInfo = any;
|
||||||
|
|
||||||
|
export interface HassioSnapshot {
|
||||||
|
slug: string;
|
||||||
|
date: string;
|
||||||
|
name: string;
|
||||||
|
type: "full" | "partial";
|
||||||
|
protected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HassioFullSnapshotCreateParams {
|
||||||
|
name: string;
|
||||||
|
password?: string;
|
||||||
|
}
|
||||||
|
export interface HassioPartialSnapshotCreateParams {
|
||||||
|
name: string;
|
||||||
|
folders: string[];
|
||||||
|
addons: string[];
|
||||||
|
password?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const hassioApiResultExtractor = <T>(response: HassioResponse<T>) =>
|
const hassioApiResultExtractor = <T>(response: HassioResponse<T>) =>
|
||||||
response.data;
|
response.data;
|
||||||
|
|
||||||
@ -116,9 +135,7 @@ export const createHassioSession = async (hass: HomeAssistant) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const reloadHassioAddons = (hass: HomeAssistant) =>
|
export const reloadHassioAddons = (hass: HomeAssistant) =>
|
||||||
hass
|
hass.callApi<unknown>("POST", `hassio/addons/reload`);
|
||||||
.callApi<HassioResponse<unknown>>("POST", `hassio/addons/reload`)
|
|
||||||
.then(hassioApiResultExtractor);
|
|
||||||
|
|
||||||
export const fetchHassioAddonsInfo = (hass: HomeAssistant) =>
|
export const fetchHassioAddonsInfo = (hass: HomeAssistant) =>
|
||||||
hass
|
hass
|
||||||
@ -153,3 +170,24 @@ export const fetchHassioHomeAssistantInfo = (hass: HomeAssistant) =>
|
|||||||
"hassio/homeassistant/info"
|
"hassio/homeassistant/info"
|
||||||
)
|
)
|
||||||
.then(hassioApiResultExtractor);
|
.then(hassioApiResultExtractor);
|
||||||
|
|
||||||
|
export const fetchHassioSnapshots = (hass: HomeAssistant) =>
|
||||||
|
hass
|
||||||
|
.callApi<HassioResponse<{ snapshots: HassioSnapshot[] }>>(
|
||||||
|
"GET",
|
||||||
|
"hassio/snapshots"
|
||||||
|
)
|
||||||
|
.then((resp) => resp.data.snapshots);
|
||||||
|
|
||||||
|
export const reloadHassioSnapshots = (hass: HomeAssistant) =>
|
||||||
|
hass.callApi<unknown>("POST", `hassio/snapshots/reload`);
|
||||||
|
|
||||||
|
export const createHassioFullSnapshot = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
data: HassioFullSnapshotCreateParams
|
||||||
|
) => hass.callApi<unknown>("POST", "hassio/snapshots/new/full", data);
|
||||||
|
|
||||||
|
export const createHassioPartialSnapshot = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
data: HassioPartialSnapshotCreateParams
|
||||||
|
) => hass.callApi<unknown>("POST", "hassio/snapshots/new/partial", data);
|
||||||
|
@ -28,5 +28,9 @@ declare global {
|
|||||||
"hass-notification": {
|
"hass-notification": {
|
||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
"hass-api-called": {
|
||||||
|
success: boolean;
|
||||||
|
response: unknown;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user