* Hassio snapshot download, upload * some improvements * Remove event * Remove upload stuff * Feedback * Make downloads as suggested * More updates * Add tooltips
273 lines
8.1 KiB
HTML
273 lines
8.1 KiB
HTML
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
|
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
|
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
|
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
|
<link rel='import' href='../../bower_components/paper-radio-group/paper-radio-group.html'>
|
|
<link rel='import' href='../../bower_components/paper-radio-button/paper-radio-button.html'>
|
|
<link rel='import' href='../../bower_components/paper-checkbox/paper-checkbox.html'>
|
|
|
|
<link rel='import' href='../../src/util/hass-mixins.html'>
|
|
|
|
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
|
<link rel='import' href='../../src/resources/hassio-style.html'>
|
|
|
|
<dom-module id="hassio-snapshots">
|
|
<template>
|
|
<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>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<script>
|
|
class HassioSnapshots extends window.hassMixins.EventsMixin(Polymer.Element) {
|
|
static get is() { return 'hassio-snapshots'; }
|
|
|
|
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(HassioSnapshots.is, HassioSnapshots);
|
|
</script>
|