feat: option to change editor theme

This commit is contained in:
Fabio Di Stasio 2020-12-23 18:07:50 +01:00
parent cb1fce6f99
commit a95b8d188c
8 changed files with 211 additions and 24 deletions

View File

@ -31,11 +31,6 @@ jobs:
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1

View File

@ -33,7 +33,7 @@ An application created with minimalism and semplicity in mind, with features in
- Database management (add/edit/delete).
- Full tables management, including indexes and foreign keys.
- Run queries on multiple tabs.
- Query suggestions.
- Query suggestions and auto complete.
- Native dark theme.
- Multi language.
- Secure password storage.
@ -49,8 +49,6 @@ This is a roadmap with major features will come in near future.
- SSL and SSH tunnel support.
- Support for other databases.
- UI/UX improvements.
- Improvements of query editor area.
- Improvements of query suggestions.
- Query history.
- More context menu shortcuts.
- More keyboard shortcuts.

View File

@ -96,8 +96,65 @@
</div>
<div v-if="selectedTab === 'themes'" class="panel-body py-4">
<div class="text-center">
<p>In future releases</p>
<div class="container">
<div class="columns">
<div class="column col-12 h5 mb-2 ">
{{ $t('message.applicationTheme') }}
</div>
<div class="column col-6 c-hand theme-block" :class="{'selected': applicationTheme === 'dark'}">
<img :src="require('@/images/dark.png').default" class="img-responsive img-fit-cover s-rounded">
<div class="theme-name">
<i class="mdi mdi-moon-waning-crescent mdi-48px" />
<div class="h6 mt-4">
{{ $t('word.dark') }}
</div>
</div>
</div>
<div class="column col-6 theme-block disabled" :class="{'selected': applicationTheme === 'light'}">
<div class="theme-name">
<i class="mdi mdi-white-balance-sunny mdi-48px" />
<div class="h6 mt-4">
{{ $t('word.light') }} (Coming)
</div>
</div>
</div>
</div>
<div class="columns mt-4">
<div class="column col-12 h5 mb-2">
{{ $t('message.editorTheme') }}
</div>
<div class="column col-6 h5 mb-4">
<select
v-model="localEditorTheme"
class="form-select"
@change="changeEditorTheme(localEditorTheme)"
>
<optgroup
v-for="group in editorThemes"
:key="group.group"
:label="group.group"
>
<option
v-for="theme in group.themes"
:key="theme.name"
:value="theme.code"
:selected="editorTheme === theme.code"
>
{{ theme.name }}
</option>
</optgroup>
</select>
</div>
<div class="column col-12">
<QueryEditor
:value="exampleQuery"
:workspace="workspace"
:read-only="true"
:height="270"
/>
</div>
</div>
</div>
</div>
@ -127,18 +184,70 @@
import { mapActions, mapGetters } from 'vuex';
import localesNames from '@/i18n/supported-locales';
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate';
import QueryEditor from '@/components/QueryEditor';
const { shell } = require('electron');
export default {
name: 'ModalSettings',
components: {
ModalSettingsUpdate
ModalSettingsUpdate,
QueryEditor
},
data () {
return {
localLocale: null,
localTimeout: null,
selectedTab: 'general'
localEditorTheme: null,
selectedTab: 'general',
editorThemes: [
{
group: this.$t('word.light'),
themes: [
{ code: 'chrome', name: 'Chrome' },
{ code: 'clouds', name: 'Clouds' },
{ code: 'crimson_editor', name: 'Crimson Editor' },
{ code: 'dawn', name: 'Dawn' },
{ code: 'dreamweaver', name: 'Dreamweaver' },
{ code: 'eclupse', name: 'Eclipse' },
{ code: 'github', name: 'GitHub' },
{ code: 'iplastic', name: 'IPlastic' },
{ code: 'solarized_light', name: 'Solarized Light' },
{ code: 'textmate', name: 'TextMate' },
{ code: 'tomorrow', name: 'Tomorrow' },
{ code: 'xcode', name: 'Xcode' },
{ code: 'kuroir', name: 'Kuroir' },
{ code: 'katzenmilch', name: 'KatzenMilch' },
{ code: 'sqlserver', name: 'SQL Server' }
]
},
{
group: this.$t('word.dark'),
themes: [
{ code: 'ambiance', name: 'Ambiance' },
{ code: 'chaos', name: 'Chaos' },
{ code: 'clouds_midnight', name: 'Clouds Midnight' },
{ code: 'dracula', name: 'Dracula' },
{ code: 'cobalt', name: 'Cobalt' },
{ code: 'gruvbox', name: 'Gruvbox' },
{ code: 'gob', name: 'Green on Black' },
{ code: 'idle_fingers', name: 'Idle Fingers' },
{ code: 'kr_theme', name: 'krTheme' },
{ code: 'merbivore', name: 'Merbivore' },
{ code: 'mono_industrial', name: 'Mono Industrial' },
{ code: 'monokai', name: 'Monokai' },
{ code: 'nord_dark', name: 'Nord Dark' },
{ code: 'pastel_on_dark', name: 'Pastel on Dark' },
{ code: 'solarized_dark', name: 'Solarized Dark' },
{ code: 'terminal', name: 'Terminal' },
{ code: 'tomorrow_night', name: 'Tomorrow Night' },
{ code: 'tomorrow_night_blue', name: 'Tomorrow Night Blue' },
{ code: 'tomorrow_night_bright', name: 'Tomorrow Night Bright' },
{ code: 'tomorrow_night_eighties', name: 'Tomorrow Night 80s' },
{ code: 'twilight', name: 'Twilight' },
{ code: 'vibrant_ink', name: 'Vibrant Ink' }
]
}
]
};
},
computed: {
@ -148,7 +257,11 @@ export default {
selectedSettingTab: 'application/selectedSettingTab',
selectedLocale: 'settings/getLocale',
notificationsTimeout: 'settings/getNotificationsTimeout',
updateStatus: 'application/getUpdateStatus'
applicationTheme: 'settings/getApplicationTheme',
editorTheme: 'settings/getEditorTheme',
updateStatus: 'application/getUpdateStatus',
selectedWorkspace: 'workspaces/getSelected',
getWorkspace: 'workspaces/getWorkspace'
}),
locales () {
const locales = [];
@ -159,11 +272,32 @@ export default {
},
hasUpdates () {
return ['available', 'downloading', 'downloaded'].includes(this.updateStatus);
},
workspace () {
return this.getWorkspace(this.selectedWorkspace);
},
exampleQuery () {
return `-- This is an example
SELECT
employee.id,
employee.first_name,
employee.last_name,
SUM(DATEDIFF("SECOND", call.start, call.end)) AS call_duration
FROM call
INNER JOIN employee ON call.employee_id = employee.id
GROUP BY
employee.id,
employee.first_name,
employee.last_name
ORDER BY
employee.id ASC;
`;
}
},
created () {
this.localLocale = this.selectedLocale;
this.localTimeout = this.notificationsTimeout;
this.localEditorTheme = this.editorTheme;
this.selectedTab = this.selectedSettingTab;
window.addEventListener('keydown', this.onKey);
},
@ -174,6 +308,7 @@ export default {
...mapActions({
closeModal: 'application/hideSettingModal',
changeLocale: 'settings/changeLocale',
changeEditorTheme: 'settings/changeEditorTheme',
updateNotificationsTimeout: 'settings/updateNotificationsTimeout'
}),
selectTab (tab) {
@ -205,6 +340,34 @@ export default {
.panel-body {
height: calc(70vh - 70px);
overflow: auto;
.theme-block {
position: relative;
text-align: center;
&.selected {
img {
box-shadow: 0 0 0 3px $primary-color;
}
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
.theme-name {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
top: 0;
height: 100%;
width: 100%;
text-shadow: 0 0 8px #000;
}
}
}
.badge::after {

View File

@ -1,6 +1,10 @@
<template>
<div class="editor-wrapper">
<div ref="editor" class="editor" />
<div
ref="editor"
class="editor"
:style="{height: `${height}px`}"
/>
</div>
</template>
@ -8,15 +12,18 @@
import * as ace from 'ace-builds';
import 'ace-builds/webpack-resolver';
import '../libs/ext-language_tools';
import { mapGetters } from 'vuex';
import Tables from '@/ipc-api/Tables';
export default {
name: 'QueryEditor',
props: {
value: String,
schema: String,
workspace: Object,
schema: { type: String, default: '' },
autoFocus: { type: Boolean, default: false },
workspace: Object
readOnly: { type: Boolean, default: false },
height: { type: Number, default: 200 }
},
data () {
return {
@ -26,6 +33,9 @@ export default {
};
},
computed: {
...mapGetters({
editorTheme: 'settings/getEditorTheme'
}),
tables () {
return this.workspace.structure.filter(schema => schema.name === this.schema)
.reduce((acc, curr) => {
@ -36,7 +46,7 @@ export default {
name: table.name,
comment: table.comment,
type: table.type,
fields: ['TODO']
fields: []
};
});
},
@ -76,13 +86,20 @@ export default {
};
}
},
watch: {
editorTheme () {
if (this.editor)
this.editor.setTheme(`ace/theme/${this.editorTheme}`);
}
},
mounted () {
this.editor = ace.edit(this.$refs.editor, {
mode: `ace/mode/${this.mode}`,
theme: 'ace/theme/twilight',
theme: `ace/theme/${this.editorTheme}`,
value: this.value,
fontSize: '14px',
printMargin: false
printMargin: false,
readOnly: this.readOnly
});
this.editor.setOptions({
@ -157,7 +174,6 @@ export default {
border-bottom: 1px solid #444;
.editor {
height: 200px;
width: 100%;
}
}

View File

@ -193,6 +193,7 @@ export default {
align-items: flex-start;
flex-wrap: nowrap;
overflow: auto;
margin-bottom: 0;
&::-webkit-scrollbar {
width: 2px;

View File

@ -62,7 +62,9 @@ module.exports = {
table: 'Table',
discard: 'Discard',
stay: 'Stay',
author: 'Author'
author: 'Author',
light: 'Light',
dark: 'Dark'
},
message: {
appWelcome: 'Welcome to Antares SQL Client!',
@ -124,7 +126,9 @@ module.exports = {
referenceField: 'Ref. field',
foreignFields: 'Foreign fields',
invalidDefault: 'Invalid default',
onDelete: 'On delete'
onDelete: 'On delete',
applicationTheme: 'Application Theme',
editorTheme: 'Editor Theme'
},
// Date and Time
short: {

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -9,12 +9,16 @@ export default {
state: {
locale: persistentStore.get('locale') || 'en-US',
explorebar_size: persistentStore.get('explorebar_size') || null,
notifications_timeout: persistentStore.get('notifications_timeout') || 5
notifications_timeout: persistentStore.get('notifications_timeout') || 5,
application_theme: persistentStore.get('application_theme') || 'dark',
editor_theme: persistentStore.get('editor_theme') || 'twilight'
},
getters: {
getLocale: state => state.locale,
getExplorebarSize: state => state.explorebar_size,
getNotificationsTimeout: state => state.notifications_timeout
getNotificationsTimeout: state => state.notifications_timeout,
getApplicationTheme: state => state.application_theme,
getEditorTheme: state => state.editor_theme
},
mutations: {
SET_LOCALE (state, locale) {
@ -29,6 +33,9 @@ export default {
SET_EXPLOREBAR_SIZE (state, size) {
state.explorebar_size = size;
persistentStore.set('explorebar_size', state.explorebar_size);
},
SET_EDITOR_THEME (state, theme) {
state.editor_theme = theme;
}
},
actions: {
@ -40,6 +47,9 @@ export default {
},
changeExplorebarSize ({ commit }, size) {
commit('SET_EXPLOREBAR_SIZE', size);
},
changeEditorTheme ({ commit }, theme) {
commit('SET_EDITOR_THEME', theme);
}
}
};