🌐 Translations for app config, json editor, rebuild dialog and css dialog

This commit is contained in:
Alicia Sykes 2021-07-24 14:18:48 +01:00
parent 921af8def1
commit ef3468e2fb
5 changed files with 144 additions and 64 deletions

View File

@ -19,6 +19,68 @@
"remember-me-day": "1 Day", "remember-me-day": "1 Day",
"remember-me-week": "1 Week" "remember-me-week": "1 Week"
}, },
"config": {
"main-tab": "Config",
"view-config-tab": "View Config",
"edit-config-tab": "Edit Config",
"custom-css-tab": "Custom Styles",
"heading": "Configuration Options",
"download-config-button": "Download Config",
"edit-config-button": "Edit Config",
"edit-css-button": "Edit Custom CSS",
"cloud-sync-button": "Enable Cloud Sync",
"edit-cloud-sync-button": "Edit Cloud Sync",
"rebuild-app-button": "Rebuild Application",
"reset-settings-button": "Reset Local Settings",
"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.",
"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-l3": "Are you sure you want to proceed?",
"data-cleared-msg": "Data cleared successfully",
"actions-label": "Actions",
"copy-config-label": "Copy Config",
"data-copied-msg": "Config has been copied to clipboard",
"reset-config-label": "Reset Config",
"css-save-btn": "Save Changes",
"css-note-label": "Note",
"css-note-l1": "You will need to refresh the page for your changes to take effect.",
"css-note-l2": "Styles overrides are only stored locally, so it is recommended to make a copy of your CSS.",
"css-note-l3": "To remove all custom styles, delete the contents and hit Save Changes"
},
"config-editor": {
"save-location-label": "Save Location",
"location-local-label": "Apply Locally",
"location-disk-label": "Write Changes to Config File",
"save-button": "Save Changes",
"valid-label": "Config is Valid",
"status-success-msg": "Task Complete",
"status-fail-msg": "Task Failed",
"success-msg-disk": "Config file written to disk successfully",
"success-msg-local": "Local changes saved successfully",
"success-note-l1": "The app should rebuild automatically.",
"success-note-l2": "This may take up to a minute.",
"success-note-l3": "You will need to refresh the page for changes to take effect.",
"error-msg-save-mode": "Please select a Save Mode: Local or File",
"error-msg-cannot-save": "An error occurred saving config",
"error-msg-bad-json": "Error in JSON, possibly malformed",
"warning-msg-validation": "Validation Warning"
},
"app-rebuild": {
"title": "Rebuild Application",
"rebuild-note-l1": "A rebuild is required for changes written to the conf.yml file to take effect.",
"rebuild-note-l2": "This should happen automatically, but if it hasn't, you can manually trigger it here.",
"rebuild-note-l3": "This is not required for modifications stored locally.",
"rebuild-button": "Start Build",
"rebuilding-status-1": "Building...",
"rebuilding-status-2": "This may take a few minutes",
"error-permission": "You do no have permission to trigger this action",
"success-msg": "Build completed succesfully",
"fail-msg": "Build operation failed",
"reload-note": "A page reload is now required for changes to take effect",
"reload-button": "Reload Page"
},
"cloud-sync": { "cloud-sync": {
"title": "Cloud Backup & Restore", "title": "Cloud Backup & Restore",
"intro-l1": "Cloud backup and restore is an optional feature, that enables you to upload your config to the internet, and then restore it on any other device or instance of Dashy.", "intro-l1": "Cloud backup and restore is an optional feature, that enables you to upload your config to the internet, and then restore it on any other device or instance of Dashy.",

View File

@ -1,67 +1,69 @@
<template> <template>
<Tabs :navAuto="true" name="Add Item" ref="tabView"> <Tabs :navAuto="true" name="Add Item" ref="tabView">
<TabItem name="Config" class="main-tab"> <TabItem :name="$t('config.main-tab')" class="main-tab">
<div class="main-options-container"> <div class="main-options-container">
<h2>Configuration Options</h2> <h2>Configuration Options</h2>
<a class="hyperlink-wrapper" @click="downloadConfigFile('conf.yml', yaml)"> <a class="hyperlink-wrapper" @click="downloadConfigFile('conf.yml', yaml)">
<button class="config-button center"> <button class="config-button center">
<DownloadIcon class="button-icon"/> <DownloadIcon class="button-icon"/>
Download Config {{ $t('config.download-config-button') }}
</button> </button>
</a> </a>
<button class="config-button center" @click="() => navigateToTab(2)"> <button class="config-button center" @click="() => navigateToTab(2)">
<EditIcon class="button-icon"/> <EditIcon class="button-icon"/>
Edit Config {{ $t('config.edit-config-button') }}
</button> </button>
<button class="config-button center" @click="() => navigateToTab(3)"> <button class="config-button center" @click="() => navigateToTab(3)">
<CustomCssIcon class="button-icon"/> <CustomCssIcon class="button-icon"/>
Edit Custom CSS {{ $t('config.edit-css-button') }}
</button> </button>
<button class="config-button center" @click="openCloudSync()"> <button class="config-button center" @click="openCloudSync()">
<CloudIcon class="button-icon"/> <CloudIcon class="button-icon"/>
{{backupId ? 'Edit Cloud Sync' : 'Enable Cloud Sync'}} {{backupId ? $t('config.edit-cloud-sync-button') : $t('config.cloud-sync-button') }}
</button> </button>
<button class="config-button center" @click="openRebuildAppModal()"> <button class="config-button center" @click="openRebuildAppModal()">
<RebuildIcon class="button-icon"/> <RebuildIcon class="button-icon"/>
Rebuild Application {{ $t('config.rebuild-app-button') }}
</button> </button>
<button class="config-button center" @click="resetLocalSettings()"> <button class="config-button center" @click="resetLocalSettings()">
<DeleteIcon class="button-icon"/> <DeleteIcon class="button-icon"/>
Reset Local Settings {{ $t('config.reset-settings-button') }}
</button> </button>
<button class="config-button center" @click="openAboutModal()"> <button class="config-button center" @click="openAboutModal()">
<IconAbout class="button-icon" /> <IconAbout class="button-icon" />
App Info {{ $t('config.app-info-button') }}
</button> </button>
<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">Dashy version {{ appVersion }}</p> <p class="app-version">{{ $t('config.app-version-note') }} {{ appVersion }}</p>
<div class="config-note"> <div class="config-note">
<span> <span>{{ $t('config.backup-note') }}</span>
It is recommend to make a backup of your conf.yml file before making changes.
</span>
</div> </div>
</div> </div>
<!-- Rebuild App Modal --> <!-- Rebuild App Modal -->
<RebuildApp /> <RebuildApp />
</TabItem> </TabItem>
<TabItem name="View Config" class="code-container"> <TabItem :name="$t('config.view-config-tab')" class="code-container">
<pre id="conf-yaml">{{yaml}}</pre> <pre id="conf-yaml">{{yaml}}</pre>
<div class="yaml-action-buttons"> <div class="yaml-action-buttons">
<h2>Actions</h2> <h2>{{ $t('config.actions-label') }}</h2>
<a class="yaml-button download" @click="downloadConfigFile('conf.yml', yaml)"> <a class="yaml-button download" @click="downloadConfigFile('conf.yml', yaml)">
Download Config {{ $t('config.download-config-button') }}
</a>
<a class="yaml-button copy" @click="copyConfigToClipboard()">
{{ $t('config.copy-config-label') }}
</a>
<a class="yaml-button reset" @click="resetLocalSettings()">
{{ $t('config.reset-config-label') }}
</a> </a>
<a class="yaml-button copy" @click="copyConfigToClipboard()">Copy Config</a>
<a class="yaml-button reset" @click="resetLocalSettings()">Reset Config</a>
</div> </div>
</TabItem> </TabItem>
<TabItem name="Edit Config"> <TabItem :name="$t('config.edit-config-tab')">
<JsonEditor :config="config" /> <JsonEditor :config="config" />
</TabItem> </TabItem>
<TabItem name="Custom Styles"> <TabItem :name="$t('config.custom-css-tab')">
<CustomCssEditor :config="config" initialCss="hello" /> <CustomCssEditor :config="config" />
</TabItem> </TabItem>
</Tabs> </Tabs>
</template> </template>
@ -135,18 +137,16 @@ export default {
}, },
copyConfigToClipboard() { copyConfigToClipboard() {
navigator.clipboard.writeText(this.jsonParser(this.config)); navigator.clipboard.writeText(this.jsonParser(this.config));
// event.target.textContent = 'Copied to clipboard'; this.$toasted.show(this.$t('config.data-copied-msg'));
}, },
/* Checks that the user is sure, then resets site-wide local storage, and reloads page */ /* Checks that the user is sure, then resets site-wide local storage, and reloads page */
resetLocalSettings() { resetLocalSettings() {
const msg = 'This will remove all user settings from local storage, ' const msg = `${this.$t('config.reset-config-msg-l1')
+ 'but won\'t effect your \'conf.yml\' file. ' }${this.$t('config.reset-config-msg-l2')}\n\n${this.$t('config.reset-config-msg-l3')}`;
+ 'It is recommend to make a backup of your modified YAML settings first.\n\n'
+ 'Are you sure you want to proceed?';
const isTheUserSure = confirm(msg); // eslint-disable-line no-alert, no-restricted-globals const isTheUserSure = confirm(msg); // eslint-disable-line no-alert, no-restricted-globals
if (isTheUserSure) { if (isTheUserSure) {
localStorage.clear(); localStorage.clear();
this.$toasted.show('Data cleared succesfully'); this.$toasted.show(this.$t('config.data-cleared-msg'));
setTimeout(() => { setTimeout(() => {
location.reload(true); // eslint-disable-line no-restricted-globals location.reload(true); // eslint-disable-line no-restricted-globals
}, 1900); }, 1900);
@ -162,11 +162,15 @@ export default {
element.click(); element.click();
document.body.removeChild(element); 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;
},
}, },
mounted() { mounted() {
hljs.registerLanguage('yaml', yaml); this.initiateStntaxHighlighter();
const highlighted = hljs.highlight(this.jsonParser(this.config), { language: 'yaml' }).value;
document.getElementById('conf-yaml').innerHTML = highlighted;
}, },
}; };
</script> </script>

View File

@ -1,11 +1,10 @@
<template> <template>
<div class="css-editor-outer"> <div class="css-editor-outer">
<prism-editor class="my-editor" v-model="customCss" :highlight="highlighter" line-numbers /> <prism-editor class="my-editor" v-model="customCss" :highlight="highlighter" line-numbers />
<button class="save-button" @click="save()">Save Changes</button> <button class="save-button" @click="save()">{{ $t('config.css-save-btn') }}</button>
<p class="quick-note"> <p class="quick-note">
<b>Note</b>: You will need to refresh the page for your changes to take effect. <b>{{ $t('config.css-note-label') }}:</b>
Styles overides are only stored locally, so it is reccomended to make a copy of your CSS. {{ $t('config.css-note-l1') }} {{ $t('config.css-note-l2') }} {{ $t('config.css-note-l3') }}
To remove all custom styles, delete the contents and hit Save Changes
</p> </p>
<CustomThemeMaker :themeToEdit="currentTheme" class="color-config" /> <CustomThemeMaker :themeToEdit="currentTheme" class="color-config" />
</div> </div>

View File

@ -8,19 +8,25 @@
/> />
<!-- Options raido, and save button --> <!-- Options raido, and save button -->
<div class="save-options"> <div class="save-options">
<span class="save-option-title">Save Location:</span> <span class="save-option-title">{{ $t('config-editor.save-location-label') }}:</span>
<div class="option"> <div class="option">
<input type="radio" id="local" value="local" <input type="radio" id="local" value="local"
v-model="saveMode" class="radio-option" :disabled="!allowWriteToDisk" /> v-model="saveMode" class="radio-option" :disabled="!allowWriteToDisk" />
<label for="local" class="save-option-label">Apply Locally</label> <label for="local" class="save-option-label">
{{ $t('config-editor.location-local-label') }}
</label>
</div> </div>
<div class="option"> <div class="option">
<input type="radio" id="file" value="file" v-model="saveMode" class="radio-option" <input type="radio" id="file" value="file" v-model="saveMode" class="radio-option"
:disabled="!allowWriteToDisk" /> :disabled="!allowWriteToDisk" />
<label for="file" class="save-option-label">Write Changes to Config File</label> <label for="file" class="save-option-label">
{{ $t('config-editor.location-disk-label') }}
</label>
</div> </div>
</div> </div>
<button :class="`save-button ${!isValid ? 'err' : ''}`" @click="save()">Save Changes</button> <button :class="`save-button ${!isValid ? 'err' : ''}`" @click="save()">
{{ $t('config-editor.save-button') }}
</button>
<!-- List validation warnings --> <!-- List validation warnings -->
<p class="errors"> <p class="errors">
<ul> <ul>
@ -28,24 +34,23 @@
{{error.msg}} {{error.msg}}
</li> </li>
<li v-if="errorMessages.length < 1" class="type-valid"> <li v-if="errorMessages.length < 1" class="type-valid">
Config is Valid {{ $t('config-editor.valid-label') }}
</li> </li>
</ul> </ul>
</p> </p>
<!-- Information notes --> <!-- Information notes -->
<p v-if="saveSuccess !== undefined" <p v-if="saveSuccess !== undefined"
:class="`response-output status-${saveSuccess ? 'success' : 'fail'}`"> :class="`response-output status-${saveSuccess ? 'success' : 'fail'}`">
{{saveSuccess ? 'Task Complete' : 'Task Failed'}} {{saveSuccess
? $t('config-editor.status-success-msg') : $t('config-editor.status-fail-msg') }}
</p> </p>
<p class="response-output">{{ responseText }}</p> <p class="response-output">{{ responseText }}</p>
<p v-if="saveSuccess" class="response-output"> <p v-if="saveSuccess" class="response-output">
The app should rebuild automatically. {{ $t('config-editor.success-note-l1') }}
This may take up to a minute. {{ $t('config-editor.success-note-l2') }}
You will need to refresh the page for changes to take effect. {{ $t('config-editor.success-note-l3') }}
</p>
<p class="note">
It is recommend to backup your existing confiruration before making any changes.
</p> </p>
<p class="note">{{ $t('config.backup-note') }}</p>
</div> </div>
</template> </template>
@ -103,7 +108,7 @@ export default {
} else if (this.saveMode === 'file') { } else if (this.saveMode === 'file') {
this.writeConfigToDisk(); this.writeConfigToDisk();
} else { } else {
this.$toasted.show('Please select a Save Mode: Local or File'); this.$toasted.show(this.$t('config-editor.error-msg-save-mode'));
} }
}, },
writeConfigToDisk() { writeConfigToDisk() {
@ -121,9 +126,9 @@ export default {
this.responseText = response.data.message; this.responseText = response.data.message;
if (this.saveSuccess) { if (this.saveSuccess) {
this.carefullyClearLocalStorage(); this.carefullyClearLocalStorage();
this.showToast('Config file written to disk succesfully', true); this.showToast(this.$t('config-editor.success-msg-disk'), true);
} else { } else {
this.showToast('An error occurred saving config', false); this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
} }
}) })
.catch((error) => { .catch((error) => {
@ -146,7 +151,7 @@ export default {
if (data.appConfig.theme) { if (data.appConfig.theme) {
localStorage.setItem(localStorageKeys.THEME, data.appConfig.theme); localStorage.setItem(localStorageKeys.THEME, data.appConfig.theme);
} }
this.showToast('Changes saved succesfully', true); this.showToast(this.$t('config-editor.success-msg-local'), true);
}, },
carefullyClearLocalStorage() { carefullyClearLocalStorage() {
localStorage.removeItem(localStorageKeys.PAGE_INFO); localStorage.removeItem(localStorageKeys.PAGE_INFO);
@ -160,7 +165,8 @@ export default {
case 'validation': case 'validation':
errorMessages.push({ errorMessages.push({
type: 'validation', type: 'validation',
msg: `Validatation Warning: ${error.error.keyword} ${error.error.message}`, msg: `${this.$t('config-editor.warning-msg-validation')}: `
+ `${error.error.keyword} ${error.error.message}`,
}); });
break; break;
case 'error': case 'error':
@ -172,7 +178,7 @@ export default {
default: default:
errorMessages.push({ errorMessages.push({
type: 'editor', type: 'editor',
msg: 'Error in JSON', msg: this.$t('config-editor.error-msg-bad-json'),
}); });
break; break;
} }

View File

@ -2,35 +2,41 @@
<modal :name="modalName" :resizable="true" width="50%" height="60%" classes="dashy-modal"> <modal :name="modalName" :resizable="true" width="50%" height="60%" classes="dashy-modal">
<div class="rebuild-app-container"> <div class="rebuild-app-container">
<!-- Title, intro and start button --> <!-- Title, intro and start button -->
<h3 class="rebuild-app-title">Rebuild Application</h3> <h3 class="rebuild-app-title">{{ $t('app-rebuild.title') }}</h3>
<p> <p>
A rebuild is required for changes written to the conf.yml file to take effect. {{ $t('app-rebuild.rebuild-note-l1') }}
This should happen automatically, but if it hasn't, you can manually trigger it here.<br> {{ $t('app-rebuild.rebuild-note-l2') }}<br>
This is not required for modifications stored locally. {{ $t('app-rebuild.rebuild-note-l3') }}
</p> </p>
<Button :click="startBuild" :disabled="loading || !allowRebuild" :disallow="!allowRebuild"> <Button :click="startBuild" :disabled="loading || !allowRebuild" :disallow="!allowRebuild">
<template v-slot:text>{{ loading ? 'Building...' : 'Start Build' }}</template> <template v-slot:text>
{{ loading ? $t('app-rebuild.rebuilding-status-1') : $t('app-rebuild.rebuild-button') }}
</template>
<template v-slot:icon><RebuildIcon /></template> <template v-slot:icon><RebuildIcon /></template>
</Button> </Button>
<div v-if="!allowRebuild"> <div v-if="!allowRebuild">
<p class="disallow-rebuild-msg">You do no have permission to trigger this action</p> <p class="disallow-rebuild-msg">{{ $t('app-rebuild.error-permission') }}</p>
</div> </div>
<!-- Loading animation and text (shown while build is happening) --> <!-- Loading animation and text (shown while build is happening) -->
<div v-if="loading" class="loader-info"> <div v-if="loading" class="loader-info">
<LoadingAnimation class="loader" /> <LoadingAnimation class="loader" />
<p class="loading-message">This may take a few minutes...</p> <p class="loading-message">{{ $t('app-rebuild.rebuilding-status-2') }}...</p>
</div> </div>
<!-- Build response, and next actions (shown after build is done) --> <!-- Build response, and next actions (shown after build is done) -->
<div class="rebuild-response" v-if="success !== undefined"> <div class="rebuild-response" v-if="success !== undefined">
<p v-if="success" class="response-status success"> Build completed succesfully</p> <p v-if="success" class="response-status success">
<p v-else class="response-status failure"> Build operation failed</p> {{ $t('app-rebuild.success-msg') }}
</p>
<p v-else class="response-status failure">
{{ $t('app-rebuild.fail-msg') }}
</p>
<pre class="output"><code>{{ output || error }}</code></pre> <pre class="output"><code>{{ output || error }}</code></pre>
<p class="rebuild-message">{{ message }}</p> <p class="rebuild-message">{{ message }}</p>
<p v-if="success" class="rebuild-message"> <p v-if="success" class="rebuild-message">
A page reload is now required for changes to take effect {{ $t('app-rebuild.reload-note') }}
</p> </p>
<Button :click="refreshPage" v-if="success"> <Button :click="refreshPage" v-if="success">
<template v-slot:text>Reload Page</template> <template v-slot:text>{{ $t('app-rebuild.reload-button') }}</template>
<template v-slot:icon><ReloadIcon /></template> <template v-slot:icon><ReloadIcon /></template>
</Button> </Button>
</div> </div>
@ -65,6 +71,7 @@ export default {
allowRebuild: true, allowRebuild: true,
}), }),
methods: { methods: {
/* Calls to the rebuild endpoint, to kickoff the app build */
startBuild() { startBuild() {
const baseUrl = process.env.VUE_APP_DOMAIN || window.location.origin; const baseUrl = process.env.VUE_APP_DOMAIN || window.location.origin;
const endpoint = `${baseUrl}/config-manager/rebuild`; const endpoint = `${baseUrl}/config-manager/rebuild`;
@ -77,6 +84,7 @@ export default {
this.finished({ success: false, error }); this.finished({ success: false, error });
}); });
}, },
/* Called when rebuild is complete, updates UI with either success or fail message */
finished(responseData) { finished(responseData) {
this.loading = false; this.loading = false;
if (responseData) { if (responseData) {
@ -89,7 +97,8 @@ export default {
this.error = error; this.error = error;
} }
this.$toasted.show( this.$toasted.show(
(this.success ? '✅ Build Completed Succesfully' : '❌ Build Failed'), (this.success
? `${this.$t('app-rebuild.success-msg')}` : `${this.$t('app-rebuild.fail-msg')}`),
{ className: `toast-${this.success ? 'success' : 'error'}` }, { className: `toast-${this.success ? 'success' : 'error'}` },
); );
}, },