Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Interactive Config Editor #298

Merged
merged 102 commits into from
Oct 30, 2021
Merged
Changes from 1 commit
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
19ba9dc
:globe_with_meridians: Remove the word 'Open' from context menu
Lissy93 Oct 16, 2021
b9b9c30
:construction: Lays ground-work for the Edit Item modal form
Lissy93 Oct 16, 2021
8c3a8e9
:wrench: Support history-mode routing on Netlify
Lissy93 Oct 16, 2021
7a817c1
:zap: Generate and append a unique ID to each item
Lissy93 Oct 16, 2021
685d559
Merge branch 'master' of github.com:Lissy93/dashy into FEATURE/intera…
Lissy93 Oct 16, 2021
36cea32
:alien: Add getter to return specific item
Lissy93 Oct 16, 2021
716bb74
:paperclip: Adds option for description by input
Lissy93 Oct 16, 2021
677f0ee
:construction: Able to display form data from schema
Lissy93 Oct 16, 2021
f1fc013
:construction: You can now save items to VueX store, neat!
Lissy93 Oct 16, 2021
532d5e1
:memo: Adds solutions for when config not updating
Lissy93 Oct 16, 2021
b1e7ce2
:construction: You can now add more items, neat!
Lissy93 Oct 16, 2021
6ef2023
:bento: Adds icons for add + remove fields
Lissy93 Oct 16, 2021
307d371
:memo: Updates URL to TypeForm survey
Lissy93 Oct 17, 2021
8d84dbd
:construction: Adding and removing of all form items
Lissy93 Oct 17, 2021
b78db37
:sparkles: A drop-down select form component
Lissy93 Oct 17, 2021
3a3a26c
:green_heart: Remove duplicate style
Lissy93 Oct 17, 2021
71a0194
:sparkles: Made a radio-button component
Lissy93 Oct 17, 2021
5aefbb2
:construction: Now displays different input fields, dependeing on dat…
Lissy93 Oct 17, 2021
159748e
:sparkles: Show banner when in edit mode
Lissy93 Oct 17, 2021
08da96d
:zap: Adds mutation key for INITIALIZE_CONFIG
Lissy93 Oct 17, 2021
ef57a5b
:construction: Started on the save config banner
Lissy93 Oct 17, 2021
31a2d74
:zap: Turn on edit mode and close, then show banner on hompage when e…
Lissy93 Oct 17, 2021
e6bb509
:bento: Adds icons for the interactive config editor
Lissy93 Oct 18, 2021
6f0ee82
:iphone: Responsive mobile-support for form elements
Lissy93 Oct 18, 2021
0390613
:construction: Adds responsivness, translations, icons and layout to …
Lissy93 Oct 18, 2021
8a4f437
:lipstick: Creates configurable CSS variables for new config editor
Lissy93 Oct 18, 2021
1ed55b4
:art: Apply local style vars for embeded form elements, and adds in-c…
Lissy93 Oct 18, 2021
37e49ae
:see_no_evil: Perform deep copy of config, to reset pointers
Lissy93 Oct 18, 2021
cd40bb1
:zap: Fixes value not updating on form init
Lissy93 Oct 19, 2021
da7717b
:sparkles: Builds a modal for exporting config to file or clipboard
Lissy93 Oct 21, 2021
0585294
➕ Adds dependency, vue-json-tree-view for viewing config
Lissy93 Oct 21, 2021
68cd036
:globe_with_meridians: Adds new EN translations for editing, exportin…
Lissy93 Oct 21, 2021
4894778
:zap: Adds ExportConfigMenu to Home view
Lissy93 Oct 21, 2021
b90301e
:lipstick: Adds CSS for disabled SVG button option
Lissy93 Oct 21, 2021
7d0647f
:lipstick: Adds CSS option for tooltip to have higher z-index
Lissy93 Oct 21, 2021
4fe3d5c
:construction: Adds option for Move and Delete item, plus translations
Lissy93 Oct 21, 2021
fbbc5e0
:heavy_plus_sign: Imports Vue-JSON-tree component
Lissy93 Oct 21, 2021
269e6a9
:bento: Adds icons for editing, moving items
Lissy93 Oct 21, 2021
2876357
:fire: Replaces old export code, with new export modal
Lissy93 Oct 21, 2021
6f92779
:sparkles: Adds an option to enable edit mode, in settings
Lissy93 Oct 21, 2021
a48024e
:memo: Adds docs for Dashy remote access
Lissy93 Oct 21, 2021
8147f40
:sparkles: Adds ability to edit pageInfo through the UI
Lissy93 Oct 23, 2021
b1a7fce
:art: Move interactive-editor styles into own stylesheet
Lissy93 Oct 23, 2021
e6f3cae
:card_file_box: Update order and descriptors in schema for appConfig …
Lissy93 Oct 23, 2021
89737ff
:sparkles: Implements UI editor form for appConfig
Lissy93 Oct 23, 2021
e5d9463
:memo: Adds info for custom domain and remote access into Management …
Lissy93 Oct 23, 2021
e78bd07
:arrows_counterclockwise: Rebased from master
Lissy93 Oct 23, 2021
87bf926
:zap: If in edit mode, open item-edit instead of launching, onclick
Lissy93 Oct 23, 2021
0a00c9b
:nut_and_bolt: Adds updateSection functionality to store
Lissy93 Oct 24, 2021
fecd1c6
:sparkles: Builds edit section form and functionality
Lissy93 Oct 24, 2021
64bd506
:zap: Display a different tooltip, depending on if in edit mode
Lissy93 Oct 24, 2021
e0a7cbd
:zap: Adds index to section itterator, for editing
Lissy93 Oct 24, 2021
4667642
:zap: Refactors console-out into own function
Lissy93 Oct 24, 2021
7ac233e
:globe_with_meridians: Change stucture of context menu
Lissy93 Oct 24, 2021
d377289
:sparkles: Adds context menu for more options on Settings
Lissy93 Oct 24, 2021
51bcd23
:globe_with_meridians: Updates translation keys
Lissy93 Oct 24, 2021
f5965a7
:sparkles: Adds edit title button next to page title
Lissy93 Oct 24, 2021
640e605
:globe_with_meridians: Add translations for edit mode tooltip
Lissy93 Oct 24, 2021
df03046
:sparkles: Adds functionality for navigating to single-section view
Lissy93 Oct 24, 2021
9d36114
:construction: Creates copy part of move item
Lissy93 Oct 24, 2021
f4053d9
:convenience_store: Adds copy_item action to store
Lissy93 Oct 24, 2021
9bec26d
:art: Adds store and modal keys for move item
Lissy93 Oct 24, 2021
16e649c
:art: Update Input to accept Number or Text
Lissy93 Oct 24, 2021
91956d8
:zap: Convert hotkey value to Number
Lissy93 Oct 24, 2021
f450094
:card_file_box: Adds descriptors to schema
Lissy93 Oct 24, 2021
f398a37
:construction: Working on interactive editor, commiting to switch com…
Lissy93 Oct 24, 2021
31e172b
:sparkles: Implements move, copy and delete item, and delete section …
Lissy93 Oct 25, 2021
06d08a8
:sparkles: Implements Add new Item functionality
Lissy93 Oct 25, 2021
b882a38
:construction: WIP, redo layout and size, to use VueX state
Lissy93 Oct 25, 2021
70ebce4
:arrows_clockwise: Merge branch 'master' of github.com:Lissy93/dashy …
Lissy93 Oct 26, 2021
6bdc4fe
:zap: Reusable save/cancel buttons for new config editors
Lissy93 Oct 26, 2021
7cda665
:sparkles: Implements save to disk functionality
Lissy93 Oct 26, 2021
26f464f
:lipstick: Interactive editor style updates for Material Themes
Lissy93 Oct 26, 2021
2190b6e
:zap: Improved regex for url validation
Lissy93 Oct 26, 2021
4b29180
:art: Minor imprvments to code structure
Lissy93 Oct 26, 2021
3e7eae2
:globe_with_meridians: Updates structure for context menu in French t…
Lissy93 Oct 26, 2021
dde5b36
:bookmark: Bumps to 1.8.9 and updates changelog
Lissy93 Oct 26, 2021
016dfb1
:green_heart: Fixes CI
Lissy93 Oct 26, 2021
f999183
Update fr for interactive-editor
EVOTk Oct 27, 2021
793ada1
🌐 Update fr for interactive-editor
EVOTk Oct 27, 2021
dcdd101
🔀 Merge pull request #299 from EVOTk/interactive-editor-fr
Lissy93 Oct 27, 2021
08072f1
:zap: Adds info log for interactive-editor to store
Lissy93 Oct 27, 2021
b3b84c6
:card_file_box: Updates shcema title and description attributes
Lissy93 Oct 27, 2021
f135de5
:adhesive_bandage: Removes trailing curly brace
Lissy93 Oct 27, 2021
c7e6047
:lipstick: Min width for select dropdown
Lissy93 Oct 27, 2021
06dd8ed
:art: Use schema title attribute if available and fixed position save…
Lissy93 Oct 27, 2021
618ab1c
:art: Update to read + write conf from store
Lissy93 Oct 27, 2021
a19b8b8
:art: Updates data state for custom CSS
Lissy93 Oct 27, 2021
2facae3
:sparkles: Adds live preview mode to JSON editor
Lissy93 Oct 28, 2021
e4ea1c8
:zap: Radio button component accepts object input for options
Lissy93 Oct 28, 2021
229e67a
:zap: Updates key names
Lissy93 Oct 28, 2021
beb532b
:sparkles: Add new section functionality
Lissy93 Oct 29, 2021
a237ec0
:convenience_store: Adds setup / update section to store
Lissy93 Oct 29, 2021
f624dba
:exclamation: Adds status message keys to error handler
Lissy93 Oct 29, 2021
e6a6075
:zap: Add attribute for isNew to section form, to determine if editin…
Lissy93 Oct 29, 2021
fb13f84
:no_mouth: what am i doing with my life...
Lissy93 Oct 29, 2021
160f72e
:lipstick: Improved styling variables for config editor
Lissy93 Oct 29, 2021
e556445
:globe_with_meridians: Preview changes button, and Add section title
Lissy93 Oct 30, 2021
6f3570e
:convenience_store: Adds custom theme options to store
Lissy93 Oct 30, 2021
513b1cd
:fire: Remove no-longer needed prop attrs
Lissy93 Oct 30, 2021
168e52c
:zap: Item size and layout are now managed by store
Lissy93 Oct 30, 2021
785695b
:zap: Updates method of getting initial theme
Lissy93 Oct 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
🎨 Update to read + write conf from store
  • Loading branch information
Lissy93 committed Oct 27, 2021
commit 618ab1c439eb0249a89699e53e46e98858d796bc
137 changes: 77 additions & 60 deletions src/components/Configuration/CloudBackupRestore.vue
Original file line number Diff line number Diff line change
@@ -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">
Expand All @@ -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>
Expand All @@ -23,18 +25,17 @@
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>
<pre class="backup-id-value">{{ backupId }}</pre>
<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
Expand All @@ -49,69 +50,65 @@
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: '',
backupId: localStorage[localStorageKeys.BACKUP_ID] || '',
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)
Expand All @@ -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)
Expand All @@ -142,35 +140,58 @@ 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(
`${isUpdate ? 'Update' : 'Backup'} ${this.$t('cloud-sync.backup-success-msg')}`,
);
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);
Expand All @@ -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;

/* 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;
&: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; }
p.intro {
text-align: left;
font-size: 1rem;
margin: 0.25rem;
padding: 0.25rem;
/* 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 {
Expand All @@ -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>