mirror of https://github.com/Lissy93/dashy.git
🎨 Update to read + write conf from store
This commit is contained in:
parent
06dd8ed525
commit
618ab1c439
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<div class="cloud-backup-restore-wrapper">
|
||||
<!-- Intro text -->
|
||||
<div class="section intro">
|
||||
<h2>{{ $t('cloud-sync.title') }}</h2>
|
||||
<p class="intro">
|
||||
|
@ -11,6 +12,7 @@
|
|||
<a href="https://github.com/Lissy93/dashy/blob/master/docs/backup-restore.md">docs</a>
|
||||
</p>
|
||||
</div>
|
||||
<!-- Create or update a backup form -->
|
||||
<div class="section backup-section">
|
||||
<h3 v-if="backupId">{{ $t('cloud-sync.backup-title-setup') }}</h3>
|
||||
<h3 v-else>{{ $t('cloud-sync.backup-title-setup') }}</h3>
|
||||
|
@ -23,11 +25,9 @@
|
|||
type="password"
|
||||
/>
|
||||
<Button :click="checkPass">
|
||||
<template v-slot:text>
|
||||
{{backupId
|
||||
? $t('cloud-sync.backup-button-update') : $t('cloud-sync.backup-button-setup')}}
|
||||
</template>
|
||||
<template v-slot:icon><IconBackup /></template>
|
||||
{{backupId
|
||||
? $t('cloud-sync.backup-button-update') : $t('cloud-sync.backup-button-setup')}}
|
||||
<IconBackup />
|
||||
</Button>
|
||||
<div class="results-view" v-if="backupId">
|
||||
<span class="backup-id-label">{{ $t('cloud-sync.backup-id-label') }}: </span>
|
||||
|
@ -35,6 +35,7 @@
|
|||
<span class="backup-id-note">{{ $t('cloud-sync.backup-id-note') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Restore from backup form -->
|
||||
<div class="section restore-section">
|
||||
<h3>{{ $t('cloud-sync.restore-title') }}</h3>
|
||||
<Input
|
||||
|
@ -49,32 +50,38 @@
|
|||
type="password"
|
||||
/>
|
||||
<Button :click="restoreBackup">
|
||||
<template v-slot:text>{{ $t('cloud-sync.restore-button') }}</template>
|
||||
<template v-slot:icon><IconRestore /></template>
|
||||
{{ $t('cloud-sync.restore-button') }}
|
||||
<IconRestore />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// Import libraries
|
||||
import sha256 from 'crypto-js/sha256';
|
||||
import ProgressBar from 'rsup-progress';
|
||||
// Import form elements
|
||||
import Button from '@/components/FormElements/Button';
|
||||
import Input from '@/components/FormElements/Input';
|
||||
import IconBackup from '@/assets/interface-icons/config-backup.svg';
|
||||
import IconRestore from '@/assets/interface-icons/config-restore.svg';
|
||||
// Import utils and constants
|
||||
import StoreKeys from '@/utils/StoreMutations';
|
||||
import { backup, update, restore } from '@/utils/CloudBackup';
|
||||
import { localStorageKeys } from '@/utils/defaults';
|
||||
import { InfoHandler, WarningInfoHandler } from '@/utils/ErrorHandler';
|
||||
// Import Icons
|
||||
import IconBackup from '@/assets/interface-icons/config-backup.svg';
|
||||
import IconRestore from '@/assets/interface-icons/config-restore.svg';
|
||||
|
||||
export default {
|
||||
name: 'CloudBackupRestore',
|
||||
props: {
|
||||
config: Object,
|
||||
computed: {
|
||||
config() { // Users config from store
|
||||
return this.$store.state.config;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
return { // Store current form data (temp)
|
||||
backupPassword: '',
|
||||
restorePassword: '',
|
||||
restoreCode: '',
|
||||
|
@ -82,36 +89,26 @@ export default {
|
|||
progress: new ProgressBar({ color: 'var(--progress-bar)' }),
|
||||
};
|
||||
},
|
||||
components: {
|
||||
components: { // UI components / icons
|
||||
Button,
|
||||
Input,
|
||||
IconBackup,
|
||||
IconRestore,
|
||||
},
|
||||
methods: {
|
||||
/* Make request to server-side, then either show error, or proceed to restore */
|
||||
restoreBackup() {
|
||||
this.progress.start();
|
||||
restore(this.restoreCode, this.restorePassword)
|
||||
.then((response) => {
|
||||
this.restoreFromBackup(response, this.restoreCode);
|
||||
this.applyRestoredData(response, this.restoreCode);
|
||||
this.progress.end();
|
||||
}).catch((msg) => {
|
||||
this.showErrorMsg(msg);
|
||||
this.progress.end();
|
||||
});
|
||||
},
|
||||
checkPass() {
|
||||
const savedHash = localStorage[localStorageKeys.BACKUP_HASH] || undefined;
|
||||
if (!this.backupPassword) {
|
||||
this.showErrorMsg(this.$t('cloud-sync.backup-missing-password'));
|
||||
} else if (!savedHash) {
|
||||
this.makeBackup();
|
||||
} else if (savedHash === this.makeHash(this.backupPassword)) {
|
||||
this.makeUpdate();
|
||||
} else {
|
||||
this.showErrorMsg(this.$t('cloud-sync.backup-error-password'));
|
||||
}
|
||||
},
|
||||
/* Send request to backup server, to upload a new backup */
|
||||
makeBackup() {
|
||||
this.progress.start();
|
||||
backup(this.config, this.backupPassword)
|
||||
|
@ -127,6 +124,7 @@ export default {
|
|||
this.progress.end();
|
||||
});
|
||||
},
|
||||
/* Send request to backup server, to update an existing backup */
|
||||
makeUpdate() {
|
||||
this.progress.start();
|
||||
update(this.config, this.backupPassword, this.backupId)
|
||||
|
@ -142,17 +140,36 @@ export default {
|
|||
this.progress.end();
|
||||
});
|
||||
},
|
||||
restoreFromBackup(config, backupId) {
|
||||
/* For create / update a backup- checks pass is valid, then calls makeBackup */
|
||||
checkPass() {
|
||||
const savedHash = localStorage[localStorageKeys.BACKUP_HASH] || undefined;
|
||||
if (!this.backupPassword) {
|
||||
this.showErrorMsg(this.$t('cloud-sync.backup-missing-password'));
|
||||
} else if (!savedHash) {
|
||||
this.makeBackup();
|
||||
} else if (savedHash === this.makeHash(this.backupPassword)) {
|
||||
this.makeUpdate();
|
||||
} else {
|
||||
this.showErrorMsg(this.$t('cloud-sync.backup-error-password'));
|
||||
}
|
||||
},
|
||||
/* When restored data is revieved, then save to local storage, and apply it in state */
|
||||
applyRestoredData(config, backupId) {
|
||||
// Store restored data in local storage
|
||||
localStorage.setItem(localStorageKeys.CONF_SECTIONS, JSON.stringify(config.sections));
|
||||
localStorage.setItem(localStorageKeys.APP_CONFIG, JSON.stringify(config.appConfig));
|
||||
localStorage.setItem(localStorageKeys.PAGE_INFO, JSON.stringify(config.pageInfo));
|
||||
if (config.appConfig.theme) {
|
||||
localStorage.setItem(localStorageKeys.THEME, config.appConfig.theme);
|
||||
}
|
||||
// Save hashed token in local storage
|
||||
this.setBackupIdLocally(backupId, this.restorePassword);
|
||||
// Update the current state
|
||||
this.$store.commit(StoreKeys.SET_CONFIG, config);
|
||||
// Show success message
|
||||
this.showSuccessMsg(this.$t('cloud-sync.restore-success-msg'));
|
||||
setTimeout(() => { location.reload(); }, 1500); // eslint-disable-line no-restricted-globals
|
||||
},
|
||||
/* After backup/ update is made, then replace 'Make Backup' with 'Update Backup' */
|
||||
updateUiAfterBackup(backupId, isUpdate = false) {
|
||||
this.setBackupIdLocally(backupId, this.backupPassword);
|
||||
this.showSuccessMsg(
|
||||
|
@ -160,17 +177,21 @@ export default {
|
|||
);
|
||||
this.backupPassword = '';
|
||||
},
|
||||
/* If the server returns a warning, then show to user and log it */
|
||||
showErrorMsg(errorMsg) {
|
||||
WarningInfoHandler(errorMsg, 'Cloud Backup');
|
||||
this.$toasted.show(errorMsg, { className: 'toast-error' });
|
||||
},
|
||||
/* When server returns success message, then show to user and log it */
|
||||
showSuccessMsg(msg) {
|
||||
InfoHandler(msg, 'Cloud Backup');
|
||||
this.$toasted.show(msg, { className: 'toast-success' });
|
||||
},
|
||||
/* Call to hash function, to hash the users chosen/ entered password */
|
||||
makeHash(pass) {
|
||||
return sha256(pass).toString();
|
||||
},
|
||||
/* After backup is applied, hash the backup ID, and save in browser storage */
|
||||
setBackupIdLocally(backupId, pass) {
|
||||
this.backupId = backupId;
|
||||
const hash = this.makeHash(pass);
|
||||
|
@ -185,49 +206,48 @@ export default {
|
|||
@import '@/styles/style-helpers.scss';
|
||||
div.cloud-backup-restore-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
text-align: center;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
background: var(--config-settings-background);
|
||||
color: var(--config-settings-color);
|
||||
color: var(--cloud-backup-color);
|
||||
background: var(--cloud-backup-background);
|
||||
@extend .scroll-bar;
|
||||
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: fit-content;
|
||||
margin: 0 auto 1rem auto;
|
||||
padding: 0 0.5rem 1rem 0.5rem;
|
||||
&:first-child {
|
||||
border-bottom: 1px dashed var(--config-settings-color);
|
||||
}
|
||||
&.intro {
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
a {
|
||||
color: var(--config-settings-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h2 { font-size: 2rem; }
|
||||
h3 { font-size: 1.6rem; }
|
||||
/* Text styling */
|
||||
h2, h3 { font-size: 1.6rem; }
|
||||
p.intro {
|
||||
text-align: left;
|
||||
font-size: 1rem;
|
||||
margin: 0.25rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
/* Main sections */
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: fit-content;
|
||||
margin: 0 auto 1rem auto;
|
||||
padding: 0 0.5rem 1rem 0.5rem;
|
||||
}
|
||||
/* Intro section */
|
||||
.section.intro {
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
border-bottom: 1px dashed var(--cloud-backup-color);
|
||||
a { color: var(--cloud-backup-color); }
|
||||
}
|
||||
}
|
||||
|
||||
/* Container to show backup ID result from server */
|
||||
div.results-view {
|
||||
width: 16rem;
|
||||
margin: 0.5rem auto;
|
||||
padding: 0.5rem 0.75rem;
|
||||
box-sizing: border-box;
|
||||
border: 1px dashed var(--config-settings-color);
|
||||
border: 1px dashed var(--cloud-backup-color);
|
||||
border-radius: var(--curve-factor);
|
||||
text-align: left;
|
||||
.backup-id-label, .backup-id-value {
|
||||
|
@ -245,21 +265,18 @@ export default {
|
|||
|
||||
/* Overide form element colors, so that config menu can be themed by user */
|
||||
input, button {
|
||||
color: var(--config-settings-color);
|
||||
border: 1px solid var(--config-settings-color);
|
||||
color: var(--cloud-backup-color);
|
||||
border: 1px solid var(--cloud-backup-color);
|
||||
background: none;
|
||||
width: 16rem;
|
||||
}
|
||||
input:focus {
|
||||
box-shadow: 1px 1px 6px var(--config-settings-color);
|
||||
box-shadow: 1px 1px 6px var(--cloud-backup-color);
|
||||
}
|
||||
button:hover {
|
||||
color: var(--config-settings-background);
|
||||
border: 1px solid var(--config-settings-background);
|
||||
background: var(--config-settings-color);
|
||||
}
|
||||
h2, h3 {
|
||||
margin: 1rem;
|
||||
color: var(--cloud-backup-background);
|
||||
border: 1px solid var(--cloud-backup-background);
|
||||
background: var(--cloud-backup-color);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue