Merge branch 'master' of github.com:Lissy93/dashy into DOCS/updates-to-docs

This commit is contained in:
Alicia Sykes 2021-07-25 17:55:32 +01:00
commit 8183d1a7d9
11 changed files with 175 additions and 10 deletions

View File

@ -20,4 +20,5 @@
- [ ] There are no (new) build warnings or errors - [ ] There are no (new) build warnings or errors
- [ ] _(If a new config option is added)_ Attribute is outlined in the schema and documented - [ ] _(If a new config option is added)_ Attribute is outlined in the schema and documented
- [ ] _(If a new dependency is added)_ Package is essential, and has been checked out for security or performance - [ ] _(If a new dependency is added)_ Package is essential, and has been checked out for security or performance
- [ ] Bumps version, if new feature added

View File

@ -71,6 +71,7 @@ To disallow any changes from being written to disk via the UI config editor, set
**`customCss`** | `string` | _Optional_ | Raw CSS that will be applied to the page. This can also be set from the UI. Please minify it first. **`customCss`** | `string` | _Optional_ | Raw CSS that will be applied to the page. This can also be set from the UI. Please minify it first.
**`hideComponents`** | `object` | _Optional_ | A list of key page components (header, footer, search, settings, etc) that are present by default, but can be removed using this option. See [`appConfig.hideComponents`](#appconfighideComponents-optional) **`hideComponents`** | `object` | _Optional_ | A list of key page components (header, footer, search, settings, etc) that are present by default, but can be removed using this option. See [`appConfig.hideComponents`](#appconfighideComponents-optional)
**`allowConfigEdit`** | `boolean` | _Optional_ | Should prevent / allow the user to write configuration changes to the conf.yml from the UI. When set to `false`, the user can only apply changes locally using the config editor within the app, whereas if set to `true` then changes can be written to disk directly through the UI. Defaults to `true`. Note that if authentication is enabled, the user must be of type `admin` in order to apply changes globally. **`allowConfigEdit`** | `boolean` | _Optional_ | Should prevent / allow the user to write configuration changes to the conf.yml from the UI. When set to `false`, the user can only apply changes locally using the config editor within the app, whereas if set to `true` then changes can be written to disk directly through the UI. Defaults to `true`. Note that if authentication is enabled, the user must be of type `admin` in order to apply changes globally.
**`disableUpdateChecks`** | `boolean` | _Optional_ | If set to true, Dashy will not check for updates. Defaults to `false`.
**`disableServiceWorker`** | `boolean` | _Optional_ | Service workers cache web applications to improve load times and offer basic offline functionality, and are enabled by default in Dashy. The service worker can sometimes cause older content to be cached, requiring the app to be hard-refreshed. If you do not want SW functionality, or are having issues with caching, set this property to `true` to disable all service workers. **`disableServiceWorker`** | `boolean` | _Optional_ | Service workers cache web applications to improve load times and offer basic offline functionality, and are enabled by default in Dashy. The service worker can sometimes cause older content to be cached, requiring the app to be hard-refreshed. If you do not want SW functionality, or are having issues with caching, set this property to `true` to disable all service workers.
**`disableContextMenu`** | `boolean` | _Optional_ | If set to `true`, the custom right-click context menu will be disabled. Defaults to `false`. **`disableContextMenu`** | `boolean` | _Optional_ | If set to `true`, the custom right-click context menu will be disabled. Defaults to `false`.

View File

@ -1,6 +1,6 @@
{ {
"name": "Dashy", "name": "Dashy",
"version": "1.4.2", "version": "1.4.4",
"license": "MIT", "license": "MIT",
"main": "server", "main": "server",
"scripts": { "scripts": {
@ -11,7 +11,7 @@
"pm2-start": "npx pm2 start server.js", "pm2-start": "npx pm2 start server.js",
"build-watch": "vue-cli-service build --watch --mode production", "build-watch": "vue-cli-service build --watch --mode production",
"build-and-start": "npm-run-all --parallel build-watch start", "build-and-start": "npm-run-all --parallel build-watch start",
"validate-config": "node src/utils/ConfigValidator", "validate-config": "node services/config-validator",
"health-check": "node services/healthcheck" "health-check": "node services/healthcheck"
}, },
"dependencies": { "dependencies": {

View File

@ -13,12 +13,15 @@ const dns = require('dns');
const os = require('os'); const os = require('os');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
/* Kick of some basic checks */
require('./services/update-checker'); // Checks if there are any updates available, prints message
require('./services/config-validator'); // Include and kicks off the config file validation script
/* Include helper functions and route handlers */ /* Include helper functions and route handlers */
const pingUrl = require('./services/ping'); // Used by the status check feature, to ping services const pingUrl = require('./services/ping'); // Used by the status check feature, to ping services
const saveConfig = require('./services/save-config'); // Saves users new conf.yml to file-system const saveConfig = require('./services/save-config'); // Saves users new conf.yml to file-system
const printMessage = require('./services/print-message'); // Function to print welcome msg on start const printMessage = require('./services/print-message'); // Function to print welcome msg on start
const rebuild = require('./services/rebuild-app'); // A script to programmatically trigger a build const rebuild = require('./services/rebuild-app'); // A script to programmatically trigger a build
require('./src/utils/ConfigValidator'); // Include and kicks off the config file validation script
/* Checks if app is running within a container, from env var */ /* Checks if app is running within a container, from env var */
const isDocker = !!process.env.IS_DOCKER; const isDocker = !!process.env.IS_DOCKER;

View File

@ -4,14 +4,16 @@ const Ajv = require('ajv');
const yaml = require('js-yaml'); const yaml = require('js-yaml');
const fs = require('fs'); const fs = require('fs');
const schema = require('./ConfigSchema.json'); const schema = require('../src/utils/ConfigSchema.json');
/* Tell AJV to use strict mode, and report all errors */
const validatorOptions = { const validatorOptions = {
strict: true, strict: true,
allowUnionTypes: true, allowUnionTypes: true,
allErrors: true, allErrors: true,
}; };
/* Initiate AJV validator */
const ajv = new Ajv(validatorOptions); const ajv = new Ajv(validatorOptions);
/* Message printed when validation was successful */ /* Message printed when validation was successful */
@ -58,13 +60,13 @@ const validate = (config) => {
try { try {
const config = yaml.load(fs.readFileSync('./public/conf.yml', 'utf8')); const config = yaml.load(fs.readFileSync('./public/conf.yml', 'utf8'));
validate(config); validate(config);
} catch (e) { } catch (e) { // Something went very wrong...
setIsValidVariable(false); setIsValidVariable(false);
console.log(bigError()); console.log(bigError());
console.log('Please ensure that your config file is present, ' console.log('Please ensure that your config file is present, '
+ 'has the correct access rights and is parsable. ' + 'has the correct access rights and is parsable. '
+ 'If this warning persists, it may be an issue with the ' + 'If this warning persists, it may be an issue with the '
+ 'validator function. Please raise an issue, and include the following stack trace:\n'); + 'validator function. Please raise an issue, and include the following stack trace:\n');
console.warn('\x1b[33mStack Trace for ConfigValidators.js:\x1b[0m\n', e); console.warn('\x1b[33mStack Trace for config-validator.js:\x1b[0m\n', e);
console.log('\n\n'); console.log('\n\n');
} }

View File

@ -0,0 +1,28 @@
const axios = require('axios').default;
const currentVersion = require('../package.json').version;
const packageUrl = 'https://raw.githubusercontent.com/Lissy93/dashy/master/package.json';
const makeMsg = (latestVersion) => {
const parse = (version) => parseInt(version.replaceAll('.', ''), 10);
const difference = parse(latestVersion) - parse(currentVersion);
let msg = '';
if (difference <= 0) {
msg = '\x1b[1m\x1b[32m✅ Dashy is Up-to-Date\x1b[0m\n';
} else {
msg = `\x1b[103m\x1b[34m${new Array(27).fill('━').join('')}\x1b[0m\n`
+ `\x1b[103m\x1b[34m⚠ Update Available: ${latestVersion} \x1b[0m\n`
+ `\x1b[103m\x1b[34m${new Array(27).fill('━').join('')}\x1b[0m\n`;
}
return msg;
};
axios.get(packageUrl).then((response) => {
if (response && response.data && response.data.version) {
console.log(`\nUsing Dashy V-${currentVersion}. Update Check Complete`);
console.log(makeMsg(response.data.version));
}
}).catch(() => {
console.log('Unable to check for updates');
});

View File

@ -34,7 +34,6 @@
"change-language-button": "Change App Language", "change-language-button": "Change App Language",
"reset-settings-button": "Reset Local Settings", "reset-settings-button": "Reset Local Settings",
"app-info-button": "App Info", "app-info-button": "App Info",
"app-version-note": "Dashy version",
"backup-note": "It is recommend to make a backup of your configuration before making changes.", "backup-note": "It is recommend to make a backup of your configuration before making changes.",
"reset-config-msg-l1": "This will remove all user settings from local storage, but won't effect your 'conf.yml' file.", "reset-config-msg-l1": "This will remove all user settings from local storage, but won't effect your 'conf.yml' file.",
"reset-config-msg-l2": "You should first backup any changes you've made locally, if you want to use them in the future.", "reset-config-msg-l2": "You should first backup any changes you've made locally, if you want to use them in the future.",
@ -62,6 +61,13 @@
"item-size-large": "Large", "item-size-large": "Large",
"config-launcher-label": "Config" "config-launcher-label": "Config"
}, },
"updates": {
"app-version-note": "Dashy version",
"up-to-date": "Up-to-Date",
"out-of-date": "Update Available",
"unsupported-version-l1": "You are using an unsupported version of Dashy",
"unsupported-version-l2": "For the best experience, and recent security patches, please update to"
},
"language-switcher": { "language-switcher": {
"title": "Change Application Language", "title": "Change Application Language",
"dropdown-label": "Select a Language", "dropdown-label": "Select a Language",

View File

@ -2,8 +2,9 @@
<modal :name="modalName" :resizable="true" width="40%" height="60%" classes="dashy-modal"> <modal :name="modalName" :resizable="true" width="40%" height="60%" classes="dashy-modal">
<div class="about-modal"> <div class="about-modal">
<router-link to="/about"> <router-link to="/about">
<h2>Dashy V{{ appVersion }}</h2> <h2>Dashy</h2>
</router-link> </router-link>
<AppVersion />
<h3>Service Worker Status</h3> <h3>Service Worker Status</h3>
<code v-html="serviceWorkerInfo">{{ serviceWorkerInfo }}</code> <code v-html="serviceWorkerInfo">{{ serviceWorkerInfo }}</code>
<br> <br>
@ -39,10 +40,14 @@
</template> </template>
<script> <script>
import AppVersion from '@/components/Configuration/AppVersion';
import { modalNames, sessionStorageKeys } from '@/utils/defaults'; import { modalNames, sessionStorageKeys } from '@/utils/defaults';
export default { export default {
name: 'AppInfoModal', name: 'AppInfoModal',
components: {
AppVersion,
},
data() { data() {
return { return {
modalName: modalNames.ABOUT_APP, modalName: modalNames.ABOUT_APP,

View File

@ -0,0 +1,112 @@
<template>
<div class="app-version">
<!-- Current Version -->
<p>
{{ $t('updates.app-version-note') }} {{ appVersion }}
</p>
<div v-if="checksEnabled">
<!-- Results haven't come in yet, either still checking, or error -->
<p v-if="!finished">
{{ error ? 'Error checking for updates.' : 'Chcekcing for Updates...' }}
</p>
<!-- App is up-to-date -->
<p v-if="finished && isUpToDate" class="up-to-date">
{{ $t('updates.up-to-date') }}
</p>
<!-- An update is available, but not too out-of-date -->
<p v-else-if="finished && !veryOutOfDate" class="update-availible">
{{ $t('updates.out-of-date') }}: <b>{{ latestVersion }}</b>
</p>
<!-- Update available, app is VERY out of date, show some additional info -->
<p v-else-if="finished && veryOutOfDate" class="big-update-availible">
{{ $t('updates.out-of-date') }}: <b>{{ latestVersion }}</b>
<span class="please-update">
{{ $t('updates.unsupported-version-l1') }}.<br>
{{ $t('updates.unsupported-version-2') }} {{ latestVersion }}
</span>
</p>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'AppInfoModal',
inject: ['config'],
data() {
return {
appVersion: process.env.VUE_APP_VERSION, // Current version, from package.json
latestVersion: '', // Will store latest version, when request returns
checksEnabled: true, // Should we check for updates
isUpToDate: true, // Is current version === latest version
veryOutOfDate: false, // If the app is more than 5 versions out of date
finished: false, // Set to true when request is done
error: false, // Set to true if checkig fails
};
},
mounted() {
const appConfig = this.config.appConfig || {};
if (!this.appVersion || (appConfig && appConfig.disableUpdateChecks)) {
// Either current version isn't found, or user disabled checks
this.checksEnabled = false;
} else {
this.checkVersion(); // Trigger the check
}
},
methods: {
/* Gets the apps latest version from Dashy's git repo */
checkVersion() {
const packageUrl = 'https://raw.githubusercontent.com/Lissy93/dashy/master/package.json';
axios.get(packageUrl).then((response) => {
if (response && response.data && response.data.version) {
this.latestVersion = response.data.version;
this.isUpToDate = this.checkIfUpToDate(this.appVersion, this.latestVersion);
this.finished = true;
}
}).catch(() => {
this.error = true;
});
},
/* Compares the current version, with the package.json version */
checkIfUpToDate(currentVersion, latestVersion) {
const parse = (version) => parseInt(version.replaceAll('.', ''), 10);
const difference = parse(latestVersion) - parse(currentVersion);
if (difference > 5) this.veryOutOfDate = true;
return difference <= 0;
},
},
};
</script>
<style scoped lang="scss">
div.app-version {
color: var(--settings-text-color);
text-align: center;
p {
margin: 0.5rem auto;
color: var(--transparent-white-50);
cursor: default;
&.up-to-date {
color: var(--success);
font-weight: bold;
opacity: 0.8;
}
&.update-availible {
color: var(--warning);
opacity: 0.8;
}
&.big-update-availible {
color: var(--danger);
.please-update {
font-size: 0.8rem;
color: var(--danger);
display: block;
}
}
}
}
</style>

View File

@ -40,8 +40,8 @@
<p class="small-screen-note" style="display: none;"> <p class="small-screen-note" style="display: none;">
You are using a very small screen, and some screens in this menu may not be optimal You are using a very small screen, and some screens in this menu may not be optimal
</p> </p>
<p class="app-version">{{ $t('config.app-version-note') }} {{ appVersion }}</p>
<p class="language">{{ getLanguage() }}</p> <p class="language">{{ getLanguage() }}</p>
<AppVersion />
<div class="config-note"> <div class="config-note">
<span>{{ $t('config.backup-note') }}</span> <span>{{ $t('config.backup-note') }}</span>
</div> </div>
@ -74,7 +74,6 @@
</template> </template>
<script> <script>
import hljs from 'highlight.js/lib/core'; import hljs from 'highlight.js/lib/core';
import yaml from 'highlight.js/lib/languages/yaml'; import yaml from 'highlight.js/lib/languages/yaml';
import 'highlight.js/styles/mono-blue.css'; import 'highlight.js/styles/mono-blue.css';
@ -85,6 +84,7 @@ import { getUsersLanguage } from '@/utils/ConfigHelpers';
import JsonEditor from '@/components/Configuration/JsonEditor'; import JsonEditor from '@/components/Configuration/JsonEditor';
import CustomCssEditor from '@/components/Configuration/CustomCss'; import CustomCssEditor from '@/components/Configuration/CustomCss';
import RebuildApp from '@/components/Configuration/RebuildApp'; import RebuildApp from '@/components/Configuration/RebuildApp';
import AppVersion from '@/components/Configuration/AppVersion';
import DownloadIcon from '@/assets/interface-icons/config-download-file.svg'; import DownloadIcon from '@/assets/interface-icons/config-download-file.svg';
import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg'; import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg';
@ -102,6 +102,7 @@ export default {
jsonParser: JsonToYaml, jsonParser: JsonToYaml,
backupId: localStorage[localStorageKeys.BACKUP_ID] || '', backupId: localStorage[localStorageKeys.BACKUP_ID] || '',
appVersion: process.env.VUE_APP_VERSION, appVersion: process.env.VUE_APP_VERSION,
latestVersion: '',
}; };
}, },
props: { props: {
@ -119,6 +120,7 @@ export default {
JsonEditor, JsonEditor,
CustomCssEditor, CustomCssEditor,
RebuildApp, RebuildApp,
AppVersion,
DownloadIcon, DownloadIcon,
DeleteIcon, DeleteIcon,
EditIcon, EditIcon,

View File

@ -244,6 +244,11 @@
"type": "boolean", "type": "boolean",
"default": false, "default": false,
"description": "If set to true, custom right-click context menu will be disabled" "description": "If set to true, custom right-click context menu will be disabled"
},
"disableUpdateChecks": {
"type": "boolean",
"default": false,
"description": "Prevents Dashy from checking for updates"
} }
}, },
"additionalProperties": false "additionalProperties": false