mirror of
https://github.com/Lissy93/dashy.git
synced 2024-08-16 17:40:24 +03:00
Adds code editor for user to specify custom CSS
This commit is contained in:
parent
0edf235178
commit
35289df0d9
@ -95,10 +95,10 @@ All fields are optional, unless otherwise stated.
|
||||
- `backgroundImg` - String: Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load
|
||||
- `enableFontAwesome` - Boolean: Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
|
||||
- `fontAwesomeKey` - String: If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`)
|
||||
- `customCss` - String: Raw CSS that will be applied to the page. Please minify it first.
|
||||
- `theme`- String: The default theme for first load (you can change this later from the UI)
|
||||
- `cssThemes` - String[]: An array of custom theme names which can be used in the theme switcher dropdown - _See **theming** below_
|
||||
- `externalStyleSheet` - String or String[] - Either a URL to an external stylesheet or an array or URLs, which can be applied as themes within the UI
|
||||
- `customCss` - String: Raw CSS that will be applied to the page. Please minify it first.
|
||||
|
||||
**`sections`** - Section[]: (required) An array of sections - _See **`section`** below_
|
||||
|
||||
@ -182,8 +182,9 @@ This wouldn't have been quite so possible without the following components, kudo
|
||||
- [`vue-material-tabs`](https://github.com/jairoblatt/vue-material-tabs) - Tab view component by @jairoblatt `MIT`
|
||||
- [`VJsoneditor`](https://github.com/yansenlei/VJsoneditor) - Interactive JSON editor component by @yansenlei `MIT`
|
||||
- Forked from [`JsonEditor`](https://github.com/josdejong/jsoneditor) by @josdejong `Apache-2.0 License`
|
||||
- Using [`ajv`](https://github.com/ajv-validator/ajv) `MIT` JSON schema Validator and [`ace`](https://github.com/ajaxorg/ace) `BSD` code editor
|
||||
- [`vue-toasted`](https://github.com/shakee93/vue-toasted) - Toast notification component by @shakee93 `MIT`
|
||||
- [`vue-prism-editor`](https://github.com/koca/vue-prism-editor) - Lightweight code editor by @koca `MIT`
|
||||
- Forked from [`prism.js`](https://github.com/PrismJS/prism) `MIT`
|
||||
|
||||
Utils:
|
||||
- [`crypto-js`](https://github.com/brix/crypto-js) - Encryption implementations by @evanvosberg and community `MIT`
|
||||
|
@ -12,6 +12,7 @@
|
||||
"connect": "^3.7.0",
|
||||
"crypto-js": "^4.0.0",
|
||||
"highlight.js": "^11.0.0",
|
||||
"prismjs": "^1.23.0",
|
||||
"register-service-worker": "^1.6.2",
|
||||
"remedial": "^1.0.8",
|
||||
"serve-static": "^1.14.1",
|
||||
@ -21,6 +22,7 @@
|
||||
"vue-cli-plugin-yaml": "^1.0.2",
|
||||
"vue-js-modal": "^2.0.0-rc.6",
|
||||
"vue-material-tabs": "^0.0.7",
|
||||
"vue-prism-editor": "^1.2.2",
|
||||
"vue-router": "^3.0.3",
|
||||
"vue-select": "^3.11.2",
|
||||
"vue-toasted": "^1.1.28"
|
||||
|
1
src/assets/interface-icons/config-custom-css.svg
Normal file
1
src/assets/interface-icons/config-custom-css.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="css3-alt" class="svg-inline--fa fa-css3-alt fa-w-12" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"></path></svg>
|
After Width: | Height: | Size: 473 B |
@ -17,6 +17,10 @@
|
||||
<MetaDataIcon class="button-icon"/>
|
||||
Edit Meta Data
|
||||
</button>
|
||||
<button class="config-button center" @click="goToCustomCss()">
|
||||
<CustomCssIcon class="button-icon"/>
|
||||
Edit Custom CSS
|
||||
</button>
|
||||
<button class="config-button center" @click="openCloudSync()">
|
||||
<CloudIcon class="button-icon"/>
|
||||
{{backupId ? 'Edit Cloud Sync' : 'Enable Cloud Sync'}}
|
||||
@ -70,6 +74,7 @@ import DownloadIcon from '@/assets/interface-icons/config-download-file.svg';
|
||||
import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg';
|
||||
import EditIcon from '@/assets/interface-icons/config-edit-json.svg';
|
||||
import MetaDataIcon from '@/assets/interface-icons/config-meta-data.svg';
|
||||
import CustomCssIcon from '@/assets/interface-icons/config-custom-css.svg';
|
||||
import CloudIcon from '@/assets/interface-icons/cloud-backup-restore.svg';
|
||||
|
||||
export default {
|
||||
@ -97,6 +102,7 @@ export default {
|
||||
EditIcon,
|
||||
CloudIcon,
|
||||
MetaDataIcon,
|
||||
CustomCssIcon,
|
||||
},
|
||||
methods: {
|
||||
/* Seletcs the edit tab of the tab view */
|
||||
@ -108,6 +114,10 @@ export default {
|
||||
const itemToSelect = this.$refs.tabView.navItems[3];
|
||||
this.$refs.tabView.activeTabItem({ tabItem: itemToSelect, byUser: true });
|
||||
},
|
||||
goToCustomCss() {
|
||||
const itemToSelect = this.$refs.tabView.navItems[4];
|
||||
this.$refs.tabView.activeTabItem({ tabItem: itemToSelect, byUser: true });
|
||||
},
|
||||
openCloudSync() {
|
||||
this.$modal.show(modalNames.CLOUD_BACKUP);
|
||||
},
|
||||
|
@ -1,11 +1,17 @@
|
||||
<template>
|
||||
<div class="json-editor-outer">
|
||||
<textarea v-model="customCss"></textarea>
|
||||
<prism-editor class="my-editor" v-model="customCss" :highlight="highlighter" line-numbers />
|
||||
<button class="save-button" @click="save()">Save Changes</button>
|
||||
<p>Note, you will need to refresh the page for your changes to take effect</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { PrismEditor } from 'vue-prism-editor';
|
||||
import { highlight, languages } from 'prismjs/components/prism-core';
|
||||
import 'prismjs/components/prism-css';
|
||||
import 'prismjs/themes/prism-funky.css';
|
||||
import 'vue-prism-editor/dist/prismeditor.min.css';
|
||||
|
||||
import { localStorageKeys } from '@/utils/defaults';
|
||||
|
||||
@ -14,18 +20,21 @@ export default {
|
||||
props: {
|
||||
config: Object,
|
||||
},
|
||||
components: {
|
||||
PrismEditor,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
customCss: this.config.appConfig.customCss || '',
|
||||
customCss: this.config.appConfig.customCss || '\n\n\n\n\n',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
validate() {
|
||||
return true;
|
||||
validate(css) {
|
||||
return css.match(/((?:^\s*)([\w#.@*,:\-.:>,*\s]+)\s*{(?:[\s]*)((?:[A-Za-z\- \s]+[:]\s*['"0-9\w .,/()\-!%]+;?)*)*\s*}(?:\s*))/gmi);
|
||||
},
|
||||
save() {
|
||||
let msg = '';
|
||||
if (this.validate()) {
|
||||
if (this.validate(this.customCss)) {
|
||||
const appConfig = { ...this.config.appConfig };
|
||||
appConfig.customCss = this.customCss;
|
||||
localStorage.setItem(localStorageKeys.APP_CONFIG, JSON.stringify(appConfig));
|
||||
@ -42,6 +51,9 @@ export default {
|
||||
style.textContent = cleanedCss;
|
||||
document.head.append(style);
|
||||
},
|
||||
highlighter(code) {
|
||||
return highlight(code, languages.css);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -64,4 +76,13 @@ button.save-button {
|
||||
}
|
||||
}
|
||||
|
||||
.prism-editor-wrapper {
|
||||
min-height: 200px;
|
||||
border: 1px solid var(--transparent-70);
|
||||
border-radius: var(--curve-factor);
|
||||
width: 90%;
|
||||
margin: 0.5rem auto;
|
||||
background: var(--transparent-50);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -5,7 +5,6 @@ import VModal from 'vue-js-modal'; // Modal component
|
||||
import VSelect from 'vue-select'; // Select dropdown component
|
||||
import VTabs from 'vue-material-tabs'; // Tab view component, used on the config page
|
||||
import Toasted from 'vue-toasted'; // Toast component, used to show confirmation notifications
|
||||
|
||||
import { toastedOptions } from './utils/defaults';
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
|
@ -37,7 +37,6 @@ const encodeGetParams = p => Object.entries(p).map(kv => kv.map(encodeURICompone
|
||||
/* Restores the backup */
|
||||
export const restore = (backupId, password) => {
|
||||
const params = encodeGetParams({ backupId, subHash: makeSubHash(password) });
|
||||
console.log(makeSubHash(password));
|
||||
const url = `${ENDPOINT}/?${params}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get(url).then((response) => {
|
||||
|
@ -2,6 +2,7 @@ module.exports = {
|
||||
chainWebpack: config => {
|
||||
config.module.rules.delete('svg');
|
||||
},
|
||||
|
||||
configureWebpack: {
|
||||
module: {
|
||||
rules: [
|
||||
@ -9,4 +10,11 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
pwa: {
|
||||
name: 'Dashy',
|
||||
themeColor: '#00CCB4',
|
||||
msTileColor: '#0b1021',
|
||||
manifestCrossorigin: 'use-credentials',
|
||||
},
|
||||
};
|
||||
|
48
yarn.lock
48
yarn.lock
@ -2563,6 +2563,15 @@ cli-width@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
|
||||
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
|
||||
clipboard@^2.0.0:
|
||||
version "2.0.8"
|
||||
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba"
|
||||
integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==
|
||||
dependencies:
|
||||
good-listener "^1.2.2"
|
||||
select "^1.1.2"
|
||||
tiny-emitter "^2.0.0"
|
||||
|
||||
clipboardy@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290"
|
||||
@ -3255,6 +3264,11 @@ delayed-stream@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
delegate@^3.1.2:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
|
||||
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
@ -4434,6 +4448,13 @@ globby@^9.2.0:
|
||||
pify "^4.0.1"
|
||||
slash "^2.0.0"
|
||||
|
||||
good-listener@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
|
||||
integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
|
||||
dependencies:
|
||||
delegate "^3.1.2"
|
||||
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||
@ -4565,6 +4586,11 @@ highlight.js@^10.7.1:
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360"
|
||||
integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==
|
||||
|
||||
highlight.js@^11.0.0:
|
||||
version "11.0.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.0.0.tgz#e22ac9ca45edc4f87a2187685d591a108ceb8449"
|
||||
integrity sha512-ByaTMfsSuoqerTwemOgpIhfULEIaK52JJYhky/sK7/Yqc0+t7Uh5DHay9vIC94YXSupnQ1Vqfc9VXrYP4eXW3Q==
|
||||
|
||||
hmac-drbg@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
@ -7069,6 +7095,13 @@ pretty-error@^2.0.2:
|
||||
lodash "^4.17.20"
|
||||
renderkid "^2.0.4"
|
||||
|
||||
prismjs@^1.23.0:
|
||||
version "1.23.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
|
||||
integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==
|
||||
optionalDependencies:
|
||||
clipboard "^2.0.0"
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
@ -7643,6 +7676,11 @@ select-hose@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
|
||||
|
||||
select@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
|
||||
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
|
||||
|
||||
selfsigned@^1.10.8:
|
||||
version "1.10.8"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
|
||||
@ -8383,6 +8421,11 @@ timsort@^0.3.0:
|
||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||
|
||||
tiny-emitter@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
@ -8852,6 +8895,11 @@ vue-material-tabs@^0.0.7:
|
||||
resolved "https://registry.yarnpkg.com/vue-material-tabs/-/vue-material-tabs-0.0.7.tgz#5f3fa04ad35384af68582f7c89ad4cecac89207b"
|
||||
integrity sha512-02X5paTksYKrGvSRpMdkctRO9qhvJFD5VEGxd0xjOX4sYz6mZSAez0Z/+aYf7Z5ziY+eJ9dMQmxaLn9DVKQRJw==
|
||||
|
||||
vue-prism-editor@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-prism-editor/-/vue-prism-editor-1.2.2.tgz#023cfd4329848f191aac851f2f5e6c7a8c2e059f"
|
||||
integrity sha512-Lq2VgVygTx3Whn/tC8gD4m1ajA4lzSyCTqPLZA1Dq/ErbBaZA93FWRblwCoDR7AD2nXhGWuiTzb5ih3guzB7DA==
|
||||
|
||||
vue-resize@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-1.0.1.tgz#c120bed4e09938771d622614f57dbcf58a5147ee"
|
||||
|
Loading…
Reference in New Issue
Block a user