263 lines
7.7 KiB
JavaScript
263 lines
7.7 KiB
JavaScript
import '@polymer/paper-button/paper-button.js';
|
|
import '@polymer/paper-card/paper-card.js';
|
|
import '@polymer/paper-checkbox/paper-checkbox.js';
|
|
import '@polymer/paper-input/paper-input.js';
|
|
import '@polymer/paper-radio-button/paper-radio-button.js';
|
|
import '@polymer/paper-radio-group/paper-radio-group.js';
|
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
|
|
import '../../src/components/hassio-card-content.js';
|
|
import '../../src/resources/hassio-style.js';
|
|
import '../../src/util/hass-mixins.js';
|
|
|
|
class HassioSnapshots extends window.hassMixins.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">
|
|
<paper-button disabled="[[creatingSnapshot]]" on-click="_createSnapshot">Create</paper-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 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: [],
|
|
},
|
|
installedAddons: {
|
|
type: Array,
|
|
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' ? 'mdi:package-variant-closed' : 'mdi:package-variant';
|
|
}
|
|
|
|
_snapshotClicked(ev) {
|
|
this.snapshotSlug = ev.model.snapshot.slug;
|
|
}
|
|
|
|
_fullSelected(type) {
|
|
return type === 'full';
|
|
}
|
|
|
|
_snapshotDeletedChanged(snapshotDeleted) {
|
|
if (snapshotDeleted) {
|
|
this._updateSnapshots();
|
|
this.snapshotDeleted = false;
|
|
}
|
|
}
|
|
|
|
refreshData() {
|
|
this.hass.callApi('post', 'hassio/snapshots/reload')
|
|
.then(() => {
|
|
this._updateSnapshots();
|
|
});
|
|
}
|
|
}
|
|
|
|
customElements.define('hassio-snapshots', HassioSnapshots);
|