Added logic for configuration remote backup/restore
This commit is contained in:
parent
7feb972715
commit
8eb5e80821
2 changed files with 131 additions and 7 deletions
|
@ -4,17 +4,41 @@
|
||||||
<h2>Extension Configuration</h2>
|
<h2>Extension Configuration</h2>
|
||||||
<form class="loader" ref="loader" @submit.prevent="loadURL">
|
<form class="loader" ref="loader" @submit.prevent="loadURL">
|
||||||
<div class="loader-head">
|
<div class="loader-head">
|
||||||
|
<div class="left">
|
||||||
Load configuration
|
Load configuration
|
||||||
<input type="radio" id="_file" value="file" v-model="extConfigType" />
|
<input type="radio" id="_file" value="file" v-model="extConfigType" />
|
||||||
<label for="_file">From file</label>
|
<label for="_file">From file</label>
|
||||||
<input type="radio" id="_url" value="url" v-model="extConfigType" />
|
<input type="radio" id="_url" value="url" v-model="extConfigType" />
|
||||||
<label for="_url">From URL</label>
|
<label for="_url">From URL</label>
|
||||||
|
<input type="radio" id="_host" value="host" v-model="extConfigType" />
|
||||||
|
<label for="_host">From device</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right" v-if="Object.keys(hosts).length">
|
||||||
|
<select id="host-selector" v-model="selectedHost">
|
||||||
|
<option disabled :selected="!selectedHost" value="">Backup configuration to a device</option>
|
||||||
|
<option v-for="(host, name) in hosts" :selected="selectedHost === name" :key="name" :value="name">{{ name }}</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="button" :disabled="loading || !selectedHost || savedConfig !== config" @click.stop="backupConfig(selectedHost)">
|
||||||
|
<i class="fas fa-upload" /> Upload
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="loader-body">
|
<div class="loader-body">
|
||||||
<input type="file" name="file" placeholder="Configuration file" accept="application/json, text/x-json, text/plain" @change="uploadFile" v-if="extConfigType === 'file'" />
|
<input type="file" name="file" placeholder="Configuration file" accept="application/json, text/x-json, text/plain" @change="uploadFile" v-if="extConfigType === 'file'" />
|
||||||
<input type="text" name="url" placeholder="Configuration URL" v-model="extURL" v-if="extConfigType === 'url'" />
|
<input type="text" name="url" placeholder="Configuration URL" v-model="extURL" v-if="extConfigType === 'url'" />
|
||||||
<input type="submit" value="Load" v-if="extConfigType === 'url'" />
|
<input type="submit" value="Load" v-if="extConfigType === 'url'" />
|
||||||
|
|
||||||
|
<select id="host-selector" v-model="selectedHost" v-if="extConfigType === 'host'">
|
||||||
|
<option disabled :selected="!selectedHost" value="">Select a device</option>
|
||||||
|
<option v-for="(host, name) in hosts" :selected="selectedHost === name" :key="name" :value="name">{{ name }}</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="button" :disabled="loading || !selectedHost" @click.stop="restoreConfig(selectedHost)" v-if="extConfigType === 'host'">
|
||||||
|
<i class="fas fa-download" /> Restore
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,7 +46,6 @@
|
||||||
<form class="content" ref="content" @submit.prevent="save">
|
<form class="content" ref="content" @submit.prevent="save">
|
||||||
<div class="textarea">
|
<div class="textarea">
|
||||||
<PrismEditor name="text" v-model="config" :code="loading ? 'Loading...' : config" language="js" :emitEvents="true" />
|
<PrismEditor name="text" v-model="config" :code="loading ? 'Loading...' : config" language="js" :emitEvents="true" />
|
||||||
<!-- <textarea name="text" ref="text" v-model="config" v-text="loading ? 'Loading...' : config" @focus="onFocus" :disabled="loading" /> -->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
|
@ -52,6 +75,8 @@ export default {
|
||||||
savedConfig: null,
|
savedConfig: null,
|
||||||
extConfigType: 'file',
|
extConfigType: 'file',
|
||||||
extURL: null,
|
extURL: null,
|
||||||
|
selectedHost: null,
|
||||||
|
hosts: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -65,6 +90,7 @@ export default {
|
||||||
|
|
||||||
async reload() {
|
async reload() {
|
||||||
const config = await this.loadConfig();
|
const config = await this.loadConfig();
|
||||||
|
this.hosts = config.hosts || [];
|
||||||
this.config = JSON.stringify(config, null, ' ');
|
this.config = JSON.stringify(config, null, ' ');
|
||||||
this.savedConfig = this.config;
|
this.savedConfig = this.config;
|
||||||
},
|
},
|
||||||
|
@ -121,6 +147,10 @@ export default {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async restoreConfig(host) {
|
||||||
|
this.config = JSON.stringify(await this.getConfig(host), null, ' ');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
|
@ -176,7 +206,18 @@ $buttons-height: 5em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|
||||||
.loader-head {
|
.loader-head {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
width: 50%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loader-body {
|
.loader-body {
|
||||||
|
@ -197,6 +238,10 @@ $buttons-height: 5em;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- vim:sw=2:ts=2:et: -->
|
<!-- vim:sw=2:ts=2:et: -->
|
||||||
|
|
81
src/utils.js
81
src/utils.js
|
@ -71,11 +71,18 @@ export default {
|
||||||
|
|
||||||
if (Array.isArray(action.args)) {
|
if (Array.isArray(action.args)) {
|
||||||
args = action.args
|
args = action.args
|
||||||
.filter(arg => arg.value && arg.value.length)
|
.filter(arg => arg.value != null && arg.value.length)
|
||||||
.reduce((obj, arg) => {
|
.reduce((obj, arg) => {
|
||||||
obj[arg.name] = arg.value;
|
obj[arg.name] = arg.value;
|
||||||
return obj;
|
return obj;
|
||||||
}, {});
|
}, {});
|
||||||
|
} else {
|
||||||
|
args = Object.entries(args)
|
||||||
|
.filter(([name, value]) => value != null && value.length)
|
||||||
|
.reduce((obj, [name, value]) => {
|
||||||
|
obj[name] = value;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(args).forEach(name => {
|
Object.keys(args).forEach(name => {
|
||||||
|
@ -282,6 +289,78 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async backupConfig(host) {
|
||||||
|
if (typeof host === 'string') {
|
||||||
|
const hosts = await this.getHosts();
|
||||||
|
if (!(host in hosts)) {
|
||||||
|
this.notify(host, 'No such Platypush host');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
host = hosts[host];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
const config = JSON.stringify(await this.loadConfig());
|
||||||
|
const basedir = `\${Config.get("workdir")}/webext`;
|
||||||
|
const filename = `${basedir}/config.json`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.run(
|
||||||
|
{
|
||||||
|
name: 'file.mkdir',
|
||||||
|
args: { directory: basedir },
|
||||||
|
},
|
||||||
|
host
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.run(
|
||||||
|
{
|
||||||
|
name: 'file.write',
|
||||||
|
args: {
|
||||||
|
file: filename,
|
||||||
|
content: config,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
host
|
||||||
|
);
|
||||||
|
|
||||||
|
this.notify(`Configugration successfully backed up to ${host.name}`, 'Backup successful');
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async getConfig(host) {
|
||||||
|
if (typeof host === 'string') {
|
||||||
|
const hosts = await this.getHosts();
|
||||||
|
if (!(host in hosts)) {
|
||||||
|
this.notify(host, 'No such Platypush host');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
host = hosts[host];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
const basedir = `\${Config.get("workdir")}/webext`;
|
||||||
|
const filename = `${basedir}/config.json`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const config = await this.run(
|
||||||
|
{
|
||||||
|
name: 'file.read',
|
||||||
|
args: { file: filename },
|
||||||
|
},
|
||||||
|
host
|
||||||
|
);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
formToHost(form) {
|
formToHost(form) {
|
||||||
return {
|
return {
|
||||||
name: form.name.value,
|
name: form.name.value,
|
||||||
|
|
Loading…
Reference in a new issue