mirror of
https://github.com/Lissy93/dashy.git
synced 2025-07-31 01:24:42 +02:00
✨ Implements save to disk functionality
This commit is contained in:
parent
6bdc4fe313
commit
7cda6651c0
@ -30,12 +30,14 @@
|
|||||||
<CancelIcon />
|
<CancelIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
:click="saveLocally"
|
||||||
v-tooltip="tooltip($t('interactive-editor.menu.save-locally-tooltip'))"
|
v-tooltip="tooltip($t('interactive-editor.menu.save-locally-tooltip'))"
|
||||||
>
|
>
|
||||||
{{ $t('interactive-editor.menu.save-locally-btn') }}
|
{{ $t('interactive-editor.menu.save-locally-btn') }}
|
||||||
<SaveLocallyIcon />
|
<SaveLocallyIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
:click="writeToDisk"
|
||||||
v-tooltip="tooltip($t('interactive-editor.menu.save-disk-tooltip'))"
|
v-tooltip="tooltip($t('interactive-editor.menu.save-disk-tooltip'))"
|
||||||
>
|
>
|
||||||
{{ $t('interactive-editor.menu.save-disk-btn') }}
|
{{ $t('interactive-editor.menu.save-disk-btn') }}
|
||||||
@ -69,11 +71,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import jsYaml from 'js-yaml';
|
||||||
|
import ProgressBar from 'rsup-progress';
|
||||||
|
|
||||||
import Button from '@/components/FormElements/Button';
|
import Button from '@/components/FormElements/Button';
|
||||||
import StoreKeys from '@/utils/StoreMutations';
|
import StoreKeys from '@/utils/StoreMutations';
|
||||||
import { modalNames } from '@/utils/defaults';
|
|
||||||
import EditPageInfo from '@/components/InteractiveEditor/EditPageInfo';
|
import EditPageInfo from '@/components/InteractiveEditor/EditPageInfo';
|
||||||
import EditAppConfig from '@/components/InteractiveEditor/EditAppConfig';
|
import EditAppConfig from '@/components/InteractiveEditor/EditAppConfig';
|
||||||
|
import { modalNames, localStorageKeys, serviceEndpoints } from '@/utils/defaults';
|
||||||
|
import ErrorHandler, { InfoHandler } from '@/utils/ErrorHandler';
|
||||||
|
|
||||||
import SaveLocallyIcon from '@/assets/interface-icons/interactive-editor-save-locally.svg';
|
import SaveLocallyIcon from '@/assets/interface-icons/interactive-editor-save-locally.svg';
|
||||||
import SaveToDiskIcon from '@/assets/interface-icons/interactive-editor-save-disk.svg';
|
import SaveToDiskIcon from '@/assets/interface-icons/interactive-editor-save-disk.svg';
|
||||||
@ -95,6 +102,18 @@ export default {
|
|||||||
PageInfoIcon,
|
PageInfoIcon,
|
||||||
EditAppConfig,
|
EditAppConfig,
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
config() {
|
||||||
|
return this.$store.state.config;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
saveSuccess: undefined,
|
||||||
|
responseText: '',
|
||||||
|
progress: new ProgressBar({ color: 'var(--progress-bar)' }),
|
||||||
|
};
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
reset() {
|
reset() {
|
||||||
this.$store.dispatch(StoreKeys.INITIALIZE_CONFIG);
|
this.$store.dispatch(StoreKeys.INITIALIZE_CONFIG);
|
||||||
@ -115,6 +134,58 @@ export default {
|
|||||||
tooltip(content) {
|
tooltip(content) {
|
||||||
return { content, trigger: 'hover focus', delay: 250 };
|
return { content, trigger: 'hover focus', delay: 250 };
|
||||||
},
|
},
|
||||||
|
showToast(message, success) {
|
||||||
|
this.$toasted.show(message, { className: `toast-${success ? 'success' : 'error'}` });
|
||||||
|
},
|
||||||
|
carefullyClearLocalStorage() {
|
||||||
|
localStorage.removeItem(localStorageKeys.PAGE_INFO);
|
||||||
|
localStorage.removeItem(localStorageKeys.APP_CONFIG);
|
||||||
|
localStorage.removeItem(localStorageKeys.CONF_SECTIONS);
|
||||||
|
},
|
||||||
|
saveLocally() {
|
||||||
|
const data = this.config;
|
||||||
|
localStorage.setItem(localStorageKeys.CONF_SECTIONS, JSON.stringify(data.sections));
|
||||||
|
localStorage.setItem(localStorageKeys.PAGE_INFO, JSON.stringify(data.pageInfo));
|
||||||
|
localStorage.setItem(localStorageKeys.APP_CONFIG, JSON.stringify(data.appConfig));
|
||||||
|
if (data.appConfig.theme) {
|
||||||
|
localStorage.setItem(localStorageKeys.THEME, data.appConfig.theme);
|
||||||
|
}
|
||||||
|
InfoHandler('Config has succesfully been saved in browser storage', 'Config Update');
|
||||||
|
this.showToast(this.$t('config-editor.success-msg-local'), true);
|
||||||
|
},
|
||||||
|
writeToDisk() {
|
||||||
|
// 1. Convert JSON into YAML
|
||||||
|
const yamlOptions = {};
|
||||||
|
const yaml = jsYaml.dump(this.config, yamlOptions);
|
||||||
|
// 2. Prepare the request
|
||||||
|
const baseUrl = process.env.VUE_APP_DOMAIN || window.location.origin;
|
||||||
|
const endpoint = `${baseUrl}${serviceEndpoints.save}`;
|
||||||
|
const headers = { 'Content-Type': 'text/plain' };
|
||||||
|
const body = { config: yaml, timestamp: new Date() };
|
||||||
|
const request = axios.post(endpoint, body, headers);
|
||||||
|
// 3. Make the request, and handle response
|
||||||
|
this.progress.start();
|
||||||
|
request.then((response) => {
|
||||||
|
this.saveSuccess = response.data.success || false;
|
||||||
|
this.responseText = response.data.message;
|
||||||
|
if (this.saveSuccess) {
|
||||||
|
this.carefullyClearLocalStorage();
|
||||||
|
this.showToast(this.$t('config-editor.success-msg-disk'), true);
|
||||||
|
} else {
|
||||||
|
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
|
||||||
|
}
|
||||||
|
InfoHandler('Config has been written to disk succesfully', 'Config Update');
|
||||||
|
this.progress.end();
|
||||||
|
this.$store.commit(StoreKeys.SET_EDIT_MODE, false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.saveSuccess = false;
|
||||||
|
this.responseText = error;
|
||||||
|
this.showToast(error, false);
|
||||||
|
ErrorHandler(`Failed to save config. ${error}`);
|
||||||
|
this.progress.end();
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -108,20 +108,9 @@ export default {
|
|||||||
if (colCount > 8) colCount = 8;
|
if (colCount > 8) colCount = 8;
|
||||||
return colCount;
|
return colCount;
|
||||||
},
|
},
|
||||||
/* Combines sections from config file, with those in local storage */
|
|
||||||
allSections() {
|
|
||||||
// If the user has stored sections in local storage, return those
|
|
||||||
const localSections = localStorage[localStorageKeys.CONF_SECTIONS];
|
|
||||||
if (localSections) {
|
|
||||||
const json = JSON.parse(localSections);
|
|
||||||
if (json.length >= 1) return json;
|
|
||||||
}
|
|
||||||
// Otherwise, return the usuall data from conf.yml
|
|
||||||
return this.sections;
|
|
||||||
},
|
|
||||||
/* Return all sections, that match users search term */
|
/* Return all sections, that match users search term */
|
||||||
filteredTiles() {
|
filteredTiles() {
|
||||||
const sections = this.singleSectionView || this.allSections;
|
const sections = this.singleSectionView || this.sections;
|
||||||
return sections.filter((section) => this.filterTiles(section.items, this.searchValue));
|
return sections.filter((section) => this.filterTiles(section.items, this.searchValue));
|
||||||
},
|
},
|
||||||
/* Updates layout (when button clicked), and saves in local storage */
|
/* Updates layout (when button clicked), and saves in local storage */
|
||||||
@ -176,11 +165,11 @@ export default {
|
|||||||
this.$store.commit('SET_MODAL_OPEN', modalState);
|
this.$store.commit('SET_MODAL_OPEN', modalState);
|
||||||
},
|
},
|
||||||
/* If on sub-route, and section exists, then return only that section */
|
/* If on sub-route, and section exists, then return only that section */
|
||||||
findSingleSection: (allSectios, sectionTitle) => {
|
findSingleSection: (allSections, sectionTitle) => {
|
||||||
if (!sectionTitle) return undefined;
|
if (!sectionTitle) return undefined;
|
||||||
let sectionToReturn;
|
let sectionToReturn;
|
||||||
const parse = (section) => section.replace(' ', '-').toLowerCase().trim();
|
const parse = (section) => section.replace(' ', '-').toLowerCase().trim();
|
||||||
allSectios.forEach((section) => {
|
allSections.forEach((section) => {
|
||||||
if (parse(sectionTitle) === parse(section.name)) {
|
if (parse(sectionTitle) === parse(section.name)) {
|
||||||
sectionToReturn = [section];
|
sectionToReturn = [section];
|
||||||
}
|
}
|
||||||
@ -209,8 +198,8 @@ export default {
|
|||||||
/* Checks if any sections or items use icons from a given CDN */
|
/* Checks if any sections or items use icons from a given CDN */
|
||||||
checkIfIconLibraryNeeded(prefix) {
|
checkIfIconLibraryNeeded(prefix) {
|
||||||
let isNeeded = false;
|
let isNeeded = false;
|
||||||
if (!this.allSections) return false;
|
if (!this.sections) return false;
|
||||||
this.allSections.forEach((section) => {
|
this.sections.forEach((section) => {
|
||||||
if (section.icon && section.icon.includes(prefix)) isNeeded = true;
|
if (section.icon && section.icon.includes(prefix)) isNeeded = true;
|
||||||
section.items.forEach((item) => {
|
section.items.forEach((item) => {
|
||||||
if (item.icon && item.icon.includes(prefix)) isNeeded = true;
|
if (item.icon && item.icon.includes(prefix)) isNeeded = true;
|
||||||
@ -249,10 +238,10 @@ export default {
|
|||||||
},
|
},
|
||||||
/* Returns true if there is more than 1 sub-result visible during searching */
|
/* Returns true if there is more than 1 sub-result visible during searching */
|
||||||
checkIfResults() {
|
checkIfResults() {
|
||||||
if (!this.allSections) return false;
|
if (!this.sections) return false;
|
||||||
else {
|
else {
|
||||||
let itemsFound = true;
|
let itemsFound = true;
|
||||||
this.allSections.forEach((section) => {
|
this.sections.forEach((section) => {
|
||||||
if (this.filterTiles(section.items, this.searchValue).length > 0) itemsFound = false;
|
if (this.filterTiles(section.items, this.searchValue).length > 0) itemsFound = false;
|
||||||
});
|
});
|
||||||
return itemsFound;
|
return itemsFound;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user