mirror of https://github.com/Lissy93/dashy.git
🔀 Merge pull request #129 from Lissy93/FIX/missing-translations
[FIX] - Adds missing translations + small UI fixes Fixes #123 Fixes #126 Fixes #127
This commit is contained in:
commit
8668621ca8
|
@ -1,8 +1,15 @@
|
|||
# Changelog
|
||||
|
||||
## 🌐 1.5.5 - Adds Missing Translations + Small UI Issues [PR #129](https://github.com/Lissy93/dashy/pull/129)
|
||||
- Adds missing translations to several UI elements, Re: #126
|
||||
- Fixes login translations not being picked up on page load, Re: #127
|
||||
- Fixes small text overflow glitch in config icon, Re: #123
|
||||
- Several small UI improvements: height of config editor, scrollbar on theme dropdown, page height, white-on-white on material theme, etc
|
||||
- Adds an action to auto-assign reviewer based on ./.github/CODEOWNERS file
|
||||
|
||||
## 🐳 1.5.4 - Docker ARM Support [PR #122](https://github.com/Lissy93/dashy/pull/122)
|
||||
- Adds Docker files for `arm64v8` and `arm32v7` in order to support Raspberry Pi and other modern ARM-based devices
|
||||
- Publishes these images on DockerHub and sets up a workflow to submit a new container every time a release is made
|
||||
- Adds a Dockerfile for `arm64v8` and `arm32v7`, to support Raspberry Pi and other modern ARM-based devices
|
||||
- Sets up automated workflow to publish ARM containers to DockerHub after every new release
|
||||
- Adds documentation for running Dashy on RPi/ ARM-based devices, Re: #117
|
||||
|
||||
## 🩹 1.5.3 - UI Quick Fix [PR #121](https://github.com/Lissy93/dashy/pull/121)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# Uses the .github/OWNERS file to assign appropriate reviewers to PRs
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
autolabeler-codeowners:
|
||||
runs-on: ubuntu-latest
|
||||
name: Assign Reviewers
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Uses owners file to assign appropriate reviews to PR
|
||||
uses: pratikmallya/autolabeler-codeowners@releases/v1
|
||||
with:
|
||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -71,7 +71,7 @@
|
|||
<!-- readme: contributors -end -->
|
||||
|
||||
## Helpful Users
|
||||
<!-- readme: EVOTk,shadowking001,turnrye,Robert-Ernst,MilesTEG1,Niklashere -start -->
|
||||
<!-- readme: EVOTk,shadowking001,turnrye,Robert-Ernst,Niklashere,evroon,MilesTEG1 -start -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
|
@ -152,7 +152,7 @@
|
|||
This app definitely wouldn't have been quite so possible without the making use of the following package and components. Full credit and big kudos to their respective authors, who've done an amazing job in building and maintaining them. For a full breakdown of dependency licenses, please see [Legal](https://github.com/Lissy93/dashy/blob/master/.github/LEGAL.md)
|
||||
|
||||
##### Core
|
||||
At it's core, the application uses [Vue.js](https://github.com/vuejs/vue), as well as it's services. Styling is done with [SCSS](https://github.com/sass/sass), JavaScript is currently [Babel](https://github.com/babel/babel), (but I am in the process of converting to [TypeScript](https://github.com/Microsoft/TypeScript)), linting is done with [ESLint](https://github.com/eslint/eslint), the config is defined in [YAML](https://github.com/yaml/yaml), and there is a simple [Node.js](https://github.com/nodejs/node) server to serve up the static app.
|
||||
At it's core, the application uses [Vue.js](https://github.com/vuejs/vue), as well as it's services. Styling is done with [SCSS](https://github.com/sass/sass), JavaScript is currently [Babel](https://github.com/babel/babel), (but I am in the process of converting to [TypeScript](https://github.com/Microsoft/TypeScript)). Linting is done with [ESLint](https://github.com/eslint/eslint) and [Prettier](https://prettier.io/), both following the [AirBnB Styleguide](https://github.com/airbnb/javascript). The config is defined in [YAML](https://github.com/yaml/yaml), and there is a simple [Node.js](https://github.com/nodejs/node) server to serve up the static app and the optional API endpoints.
|
||||
|
||||
##### Utilities
|
||||
- [`crypto-js`](https://github.com/brix/crypto-js) - Encryption implementations by @evanvosberg and community `MIT`
|
||||
|
@ -176,7 +176,7 @@ At it's core, the application uses [Vue.js](https://github.com/vuejs/vue), as we
|
|||
Although the app is purely frontend, there is an optional cloud backup and restore feature. This is built as a serverless function on [Cloudflare workers](https://workers.cloudflare.com/) using [KV](https://developers.cloudflare.com/workers/runtime-apis/kv) and [web crypto](https://developers.cloudflare.com/workers/runtime-apis/web-crypto)
|
||||
|
||||
##### External Services
|
||||
The 1-Click deploy demo uses [Play-with-Docker Labs](https://play-with-docker.com/). Code is hosted on [GitHub](https://github.com), Docker image is hosted on [DockerHub](https://hub.docker.com/), and the demos are hosted on [Netlify](https://www.netlify.com/).
|
||||
The 1-Click deploy demo uses [Play-with-Docker Labs](https://play-with-docker.com/). Code is hosted on [GitHub](https://github.com), Docker images are hosted on [DockerHub](https://hub.docker.com/), and the demos are hosted on [Netlify](https://www.netlify.com/).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Dashy",
|
||||
"version": "1.5.4",
|
||||
"version": "1.5.5",
|
||||
"license": "MIT",
|
||||
"main": "server",
|
||||
"scripts": {
|
||||
|
@ -22,7 +22,6 @@
|
|||
"body-parser": "^1.19.0",
|
||||
"connect": "^3.7.0",
|
||||
"crypto-js": "^4.0.0",
|
||||
"highlight.js": "^11.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prismjs": "^1.24.1",
|
||||
|
|
|
@ -17,7 +17,13 @@
|
|||
"remember-me-never": "Never",
|
||||
"remember-me-hour": "4 Hours",
|
||||
"remember-me-day": "1 Day",
|
||||
"remember-me-week": "1 Week"
|
||||
"remember-me-week": "1 Week",
|
||||
"error-missing-username": "Missing Username",
|
||||
"error-missing-password": "Missing Password",
|
||||
"error-incorrect-username": "User not found",
|
||||
"error-incorrect-password": "Incorrect Password",
|
||||
"success-message": "Logging in...",
|
||||
"logout-message": "Logged Out"
|
||||
},
|
||||
"config": {
|
||||
"main-tab": "Config",
|
||||
|
@ -59,7 +65,9 @@
|
|||
"item-size-small": "Small",
|
||||
"item-size-medium": "Medium",
|
||||
"item-size-large": "Large",
|
||||
"config-launcher-label": "Config"
|
||||
"config-launcher-label": "Config",
|
||||
"config-launcher-tooltip": "Update Configuration",
|
||||
"sign-out-tooltip": "Sign Out"
|
||||
},
|
||||
"updates": {
|
||||
"app-version-note": "Dashy version",
|
||||
|
|
|
@ -79,9 +79,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import yaml from 'highlight.js/lib/languages/yaml';
|
||||
import 'highlight.js/styles/mono-blue.css';
|
||||
|
||||
import JsonToYaml from '@/utils/JsonToYaml';
|
||||
import { localStorageKeys, modalNames } from '@/utils/defaults';
|
||||
|
@ -179,20 +176,11 @@ export default {
|
|||
element.click();
|
||||
document.body.removeChild(element);
|
||||
},
|
||||
/* Highlights the YAML config in View config tab */
|
||||
initiateStntaxHighlighter() {
|
||||
hljs.registerLanguage('yaml', yaml);
|
||||
const highlighted = hljs.highlight(this.jsonParser(this.config), { language: 'yaml' }).value;
|
||||
document.getElementById('conf-yaml').innerHTML = highlighted;
|
||||
},
|
||||
getLanguage() {
|
||||
const lang = getUsersLanguage();
|
||||
return lang ? `${lang.flag} ${lang.name}` : '';
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initiateStntaxHighlighter();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<v-jsoneditor
|
||||
v-model="jsonData"
|
||||
:options="options"
|
||||
height="500px"
|
||||
/>
|
||||
<!-- Options raido, and save button -->
|
||||
<div class="save-options">
|
||||
|
@ -293,6 +292,10 @@ div.save-options {
|
|||
}
|
||||
}
|
||||
|
||||
.jsoneditor-container.min-box {
|
||||
height: 58vh;
|
||||
}
|
||||
|
||||
.jsoneditor, .jsoneditor-menu {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="display-options">
|
||||
<IconLogout @click="logout()" v-tooltip="tooltip('Sign Out')"
|
||||
<IconLogout @click="logout()" v-tooltip="tooltip($t('settings.sign-out-tooltip'))"
|
||||
class="layout-icon" tabindex="-2" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@ export default {
|
|||
methods: {
|
||||
logout() {
|
||||
registerLogout();
|
||||
this.$toasted.show('Logged Out');
|
||||
this.$toasted.show(this.$t('login.logout-message'));
|
||||
setTimeout(() => {
|
||||
location.reload(true); // eslint-disable-line no-restricted-globals
|
||||
}, 500);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<span>{{ $t('settings.config-launcher-label') }}</span>
|
||||
<div class="config-buttons">
|
||||
<IconSpanner @click="showEditor()" tabindex="-2"
|
||||
v-tooltip="tooltip('Update configuration')" />
|
||||
v-tooltip="tooltip($t('settings.config-launcher-tooltip'))" />
|
||||
</div>
|
||||
|
||||
<!-- Modal containing all the configuration options -->
|
||||
|
@ -73,6 +73,7 @@ export default {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
color: var(--settings-text-color);
|
||||
min-width: 3.2rem;
|
||||
svg {
|
||||
path {
|
||||
fill: var(--settings-text-color);
|
||||
|
|
|
@ -37,7 +37,6 @@ import ItemSizeSelector from '@/components/Settings/ItemSizeSelector';
|
|||
import AppButtons from '@/components/Settings/AppButtons';
|
||||
import KeyboardShortcutInfo from '@/components/Settings/KeyboardShortcutInfo';
|
||||
import AppInfoModal from '@/components/Configuration/AppInfoModal';
|
||||
import { logout as registerLogout } from '@/utils/Auth';
|
||||
import IconOpen from '@/assets/interface-icons/config-open-settings.svg';
|
||||
import IconClose from '@/assets/interface-icons/config-close.svg';
|
||||
import {
|
||||
|
@ -88,13 +87,6 @@ export default {
|
|||
getInitialTheme() {
|
||||
return this.appConfig.theme || '';
|
||||
},
|
||||
logout() {
|
||||
registerLogout();
|
||||
this.$toasted.show('Logged Out');
|
||||
setTimeout(() => {
|
||||
location.reload(true); // eslint-disable-line no-restricted-globals
|
||||
}, 100);
|
||||
},
|
||||
isUserLoggedIn() {
|
||||
return !!localStorage[localStorageKeys.USERNAME];
|
||||
},
|
||||
|
@ -199,25 +191,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
svg.logout-icon {
|
||||
path {
|
||||
fill: var(--settings-text-color);
|
||||
}
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
margin: 0.35rem 0.2rem;
|
||||
padding: 0.2rem;
|
||||
text-align: center;
|
||||
background: var(--background);
|
||||
border: 1px solid var(--settings-text-color);;
|
||||
border-radius: var(--curve-factor);
|
||||
cursor: pointer;
|
||||
&:hover, &.selected {
|
||||
background: var(--settings-text-color);
|
||||
path { fill: var(--background); }
|
||||
}
|
||||
}
|
||||
|
||||
@include tablet {
|
||||
section {
|
||||
display: block;
|
||||
|
|
|
@ -126,6 +126,7 @@ export default {
|
|||
<style lang="scss">
|
||||
|
||||
@import 'vue-select/src/scss/vue-select.scss';
|
||||
@import '@/styles/style-helpers.scss';
|
||||
|
||||
.theme-dropdown {
|
||||
div.vs__dropdown-toggle {
|
||||
|
@ -146,10 +147,13 @@ export default {
|
|||
}
|
||||
ul.vs__dropdown-menu {
|
||||
width: auto;
|
||||
background: var(--background);
|
||||
z-index: 5;
|
||||
max-width: 13rem;
|
||||
overflow-x: hidden;
|
||||
@extend .scroll-bar;
|
||||
background: var(--background);
|
||||
border-radius: var(--curve-factor);
|
||||
border-top: 1px solid var(--settings-text-color);
|
||||
}
|
||||
li.vs__dropdown-option--highlight {
|
||||
background: var(--settings-text-color);
|
||||
|
|
|
@ -498,7 +498,7 @@ html[data-theme='material'] {
|
|||
--nav-link-border-color: #0c4eba;
|
||||
--settings-text-color: #363636;
|
||||
--config-code-color: #363636;
|
||||
--config-settings-background: #fff;
|
||||
--config-settings-background: #f5f5f5;
|
||||
--config-settings-color: #473f3f;
|
||||
--heading-text-color: #fff;
|
||||
--curve-factor: 4px;
|
||||
|
@ -508,6 +508,11 @@ html[data-theme='material'] {
|
|||
--footer-text-color: #f5f5f5cc;
|
||||
// --login-form-background-secondary: #f5f5f5cc;
|
||||
--context-menu-secondary-color: #f5f5f5;
|
||||
--transparent-white-50: #00000080;
|
||||
|
||||
div.jsoneditor div.jsoneditor-menu {
|
||||
background: #5c90eb !important;
|
||||
}
|
||||
|
||||
header {
|
||||
background: #4285f4;
|
||||
|
|
|
@ -43,24 +43,24 @@ export const isLoggedIn = (users) => {
|
|||
* @param {String[]} users An array of valid user objects
|
||||
* @returns {Object} An object containing a boolean result and a message
|
||||
*/
|
||||
export const checkCredentials = (username, pass, users) => {
|
||||
let response;
|
||||
export const checkCredentials = (username, pass, users, messages) => {
|
||||
let response; // Will store an object containing boolean and message
|
||||
if (!username) {
|
||||
response = { correct: false, msg: 'Missing Username' };
|
||||
response = { correct: false, msg: messages.missingUsername };
|
||||
} else if (!pass) {
|
||||
response = { correct: false, msg: 'Missing Password' };
|
||||
response = { correct: false, msg: messages.missingPassword };
|
||||
} else {
|
||||
users.forEach((user) => {
|
||||
if (user.user.toLowerCase() === username.toLowerCase()) {
|
||||
if (user.user.toLowerCase() === username.toLowerCase()) { // User found
|
||||
if (user.hash.toLowerCase() === sha256(pass).toString().toLowerCase()) {
|
||||
response = { correct: true, msg: 'Logging in...' };
|
||||
} else {
|
||||
response = { correct: false, msg: 'Incorrect Password' };
|
||||
response = { correct: true, msg: messages.successMsg }; // Password is correct
|
||||
} else { // User found, but password is not a match
|
||||
response = { correct: false, msg: messages.incorrectPassword };
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return response || { correct: false, msg: 'User not found' };
|
||||
return response || { correct: false, msg: messages.incorrectUsername };
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -218,7 +218,7 @@ export default {
|
|||
padding-bottom: 1px;
|
||||
background: var(--background);
|
||||
// min-height: calc(100vh - 126px);
|
||||
min-height: calc(100vh - var(--footer-height));
|
||||
min-height: calc(99.9vh - var(--footer-height));
|
||||
}
|
||||
|
||||
/* Outside container wrapping the item groups*/
|
||||
|
|
|
@ -40,6 +40,10 @@ import { checkCredentials, login } from '@/utils/Auth';
|
|||
|
||||
export default {
|
||||
name: 'login',
|
||||
components: {
|
||||
Button,
|
||||
Input,
|
||||
},
|
||||
props: {
|
||||
appConfig: Object,
|
||||
},
|
||||
|
@ -50,23 +54,41 @@ export default {
|
|||
message: '',
|
||||
status: 'waiting', // wating, error, success
|
||||
timeout: { label: this.$t('login.remember-me-never'), time: 0 },
|
||||
dropDownMenu: [ // Data for timeout dropdown menu, translated label + value in ms
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* Data for timeout dropdown menu, translated label + value in ms */
|
||||
dropDownMenu() {
|
||||
return [
|
||||
{ label: this.$t('login.remember-me-never'), time: 0 },
|
||||
{ label: this.$t('login.remember-me-hour'), time: 14400 * 1000 },
|
||||
{ label: this.$t('login.remember-me-day'), time: 86400 * 1000 },
|
||||
{ label: this.$t('login.remember-me-week'), time: 604800 * 1000 },
|
||||
],
|
||||
};
|
||||
},
|
||||
components: {
|
||||
Button,
|
||||
Input,
|
||||
];
|
||||
},
|
||||
/* Translations for login response messages */
|
||||
responseMessages() {
|
||||
return {
|
||||
missingUsername: this.$t('login.error-missing-username'),
|
||||
missingPassword: this.$t('login.error-missing-password'),
|
||||
incorrectUsername: this.$t('login.error-incorrect-username'),
|
||||
incorrectPassword: this.$t('login.error-incorrect-password'),
|
||||
successMsg: this.$t('login.success-message'),
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/* Checks form is filled in, then initiates the login, and redirects to /home */
|
||||
submitLogin() {
|
||||
// Use selected timeout, if available,else revedrt to zero
|
||||
const timeout = this.timeout ? this.timeout.time : 0;
|
||||
const response = checkCredentials(this.username, this.password, this.appConfig.auth || []);
|
||||
// Check users credentials
|
||||
const response = checkCredentials(
|
||||
this.username,
|
||||
this.password,
|
||||
this.appConfig.auth || [], // All users
|
||||
this.responseMessages, // Translated response messages
|
||||
);
|
||||
this.message = response.msg; // Show error or success message to the user
|
||||
this.status = response.correct ? 'success' : 'error';
|
||||
if (response.correct) { // Yay, credentials were correct :)
|
||||
|
@ -76,7 +98,7 @@ export default {
|
|||
}, 250);
|
||||
}
|
||||
},
|
||||
/* Since we don't have the Theme setter at this point, we must manually set users theme */
|
||||
/* Since Theme setter isn't loaded at this point, we must manually get and apply users theme */
|
||||
setTheme() {
|
||||
const theme = localStorage[localStorageKeys.THEME] || Defaults.theme;
|
||||
document.getElementsByTagName('html')[0].setAttribute('data-theme', theme);
|
||||
|
|
|
@ -5045,11 +5045,6 @@ highlight.js@^10.7.1:
|
|||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
|
||||
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
|
||||
|
||||
highlight.js@^11.0.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.1.0.tgz#0198f7326e64ddfbea5f76b00e84ab542cf24ae8"
|
||||
integrity sha512-X9VVhYKHQPPuwffO8jk4bP/FVj+ibNCy3HxZZNDXFtJrq4O5FdcdCDRIkDis5MiMnjh7UwEdHgRZJcHFYdzDdA==
|
||||
|
||||
hmac-drbg@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
|
|
Loading…
Reference in New Issue