feat(UI): shortcuts setting UI improved

This commit is contained in:
Fabio Di Stasio 2022-08-09 16:10:08 +02:00
parent 44bb75bc60
commit 49b63bc6f2
15 changed files with 229 additions and 155 deletions

View File

@ -1,7 +1,9 @@
interface ShortcutRecord { interface ShortcutRecord {
event: string; event: string;
keys: Electron.Accelerator[]; keys: Electron.Accelerator[];
description: string; description?: string;
l18nSlug: string;
l18nParam?: string | number;
os: NodeJS.Platform[]; os: NodeJS.Platform[];
} }
@ -10,48 +12,63 @@ const shortcuts: ShortcutRecord[] = [
event: 'open-new-tab', event: 'open-new-tab',
keys: ['CommandOrControl+T'], keys: ['CommandOrControl+T'],
description: 'Open a new query tab', description: 'Open a new query tab',
l18nSlug: 'message.openNewTab',
os: ['darwin', 'linux', 'win32'] os: ['darwin', 'linux', 'win32']
}, },
{ {
event: 'close-tab', event: 'close-tab',
keys: ['CommandOrControl+W'], keys: ['CommandOrControl+W'],
description: 'Close tab', description: 'Close tab',
l18nSlug: 'message.closeTab',
os: ['darwin', 'linux', 'win32'] os: ['darwin', 'linux', 'win32']
}, },
{ {
event: 'next-tab', event: 'next-tab',
keys: ['Alt+CommandOrControl+Right', 'CommandOrControl+PageDown'], keys: ['Alt+CommandOrControl+Right'],
description: 'Next tab', description: 'Next tab',
l18nSlug: 'message.nextTab',
os: ['darwin', 'win32'] os: ['darwin', 'win32']
}, },
{ {
event: 'prev-tab', event: 'prev-tab',
keys: ['Alt+CommandOrControl+Left', 'CommandOrControl+PageUp'], keys: ['Alt+CommandOrControl+Left'],
description: 'Previous tab', description: 'Previous tab',
l18nSlug: 'message.previousTab',
os: ['darwin', 'win32'] os: ['darwin', 'win32']
}, },
{ {
event: 'next-tab', event: 'next-tab',
keys: ['CommandOrControl+PageDown'], keys: ['CommandOrControl+PageDown'],
description: 'Next tab', description: 'Next tab',
os: ['linux'] l18nSlug: 'message.nextTab',
os: ['linux', 'win32']
}, },
{ {
event: 'prev-tab', event: 'prev-tab',
keys: ['CommandOrControl+PageUp'], keys: ['CommandOrControl+PageUp'],
description: 'Previous tab', description: 'Previous tab',
os: ['linux'] l18nSlug: 'message.previousTab',
os: ['linux', 'win32']
}, },
{ {
event: 'open-connections-modal', event: 'open-connections-modal',
keys: ['Shift+CommandOrControl+Space'], keys: ['Shift+CommandOrControl+Space'],
description: 'Show all connections', description: 'Show all connections',
l18nSlug: 'message.allConnections',
os: ['darwin', 'linux', 'win32'] os: ['darwin', 'linux', 'win32']
}, },
{ {
event: 'toggle-console', event: 'toggle-console',
keys: ['CommandOrControl+F12', 'CommandOrControl+`'], keys: ['CommandOrControl+F12'],
description: 'Toggle console', description: 'Toggle console',
l18nSlug: 'message.toggleConsole',
os: ['darwin', 'linux', 'win32']
},
{
event: 'toggle-console',
keys: ['CommandOrControl+`'],
description: 'Toggle console',
l18nSlug: 'message.toggleConsole',
os: ['darwin', 'linux', 'win32'] os: ['darwin', 'linux', 'win32']
} }
]; ];
@ -62,6 +79,8 @@ for (let i = 1; i <= 9; i++) {
event: `select-tab-${i}`, event: `select-tab-${i}`,
keys: [`CommandOrControl+${i}`], keys: [`CommandOrControl+${i}`],
description: `Select tab number ${i}`, description: `Select tab number ${i}`,
l18nSlug: 'message.selectTabNumber',
l18nParam: i,
os: ['darwin', 'linux', 'win32'] os: ['darwin', 'linux', 'win32']
}); });
} }

View File

@ -1,8 +1,9 @@
import { BrowserWindow, globalShortcut } from 'electron'; import { BrowserWindow, globalShortcut } from 'electron';
import * as Store from 'electron-store'; import * as Store from 'electron-store';
import { ShortcutRecord, shortcuts as defaultShortcuts } from 'common/shortcuts'; import { ShortcutRecord, shortcuts } from 'common/shortcuts';
const shortcutsStore = new Store({ name: 'shortcuts' }); const shortcutsStore = new Store({ name: 'shortcuts' });
const isDevelopment = process.env.NODE_ENV !== 'production'; const isDevelopment = process.env.NODE_ENV !== 'production';
const defaultShortcuts = shortcuts.filter(s => s.os.includes(process.platform));
export class ShortcutRegister { export class ShortcutRegister {
private _shortcuts: ShortcutRecord[]; private _shortcuts: ShortcutRecord[];

View File

@ -126,7 +126,7 @@
key="trick" key="trick"
readonly readonly
class="p-absolute" class="p-absolute"
style="width: 1px; height: 1px; opacity: 0" style="width: 1px; height: 1px; opacity: 0;"
type="text" type="text"
> >
<!-- workaround for useFocusTrap $lastFocusable --> <!-- workaround for useFocusTrap $lastFocusable -->
@ -270,89 +270,87 @@ onBeforeUnmount(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.vscroll { .vscroll {
height: 1000px; height: 1000px;
overflow: auto; overflow: auto;
overflow-anchor: none; overflow-anchor: none;
} }
.column-resizable { .column-resizable {
&:hover,
&:hover, &:active {
&:active { resize: horizontal;
resize: horizontal; overflow: hidden;
overflow: hidden; }
}
} }
.table-column-title { .table-column-title {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.sort-icon { .sort-icon {
font-size: 0.7rem; font-size: 0.7rem;
line-height: 1; line-height: 1;
margin-left: 0.2rem; margin-left: 0.2rem;
} }
.modal { .modal {
align-items: flex-start; align-items: flex-start;
.modal-container { .modal-container {
max-width: 75vw; max-width: 75vw;
margin-top: 10vh; margin-top: 10vh;
.modal-body { .modal-body {
height: 80vh; height: 80vh;
} }
} }
} }
.connections-search { .connections-search {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
} }
.connection-block { .connection-block {
cursor: pointer; cursor: pointer;
transition: all .2s; transition: all 0.2s;
border-radius: $border-radius; border-radius: $border-radius;
outline: none; outline: none;
&:focus { &:focus {
box-shadow: 0 0 3px .1rem rgba($primary-color, 80%); box-shadow: 0 0 3px 0.1rem rgba($primary-color, 80%);
} }
&:hover {
.all-connections-buttons {
.all-connections-delete,
.all-connections-pinned,
.all-connections-pin {
opacity: .5;
}
}
}
.all-connections-buttons {
.all-connections-pinned {
opacity: .3;
transition: opacity .2s;
&:hover {
opacity: 1;
}
}
&:hover {
.all-connections-buttons {
.all-connections-delete, .all-connections-delete,
.all-connections-pinned,
.all-connections-pin { .all-connections-pin {
opacity: 0; opacity: 0.5;
transition: opacity .2s;
&:hover {
opacity: 1;
}
} }
} }
}
.all-connections-buttons {
.all-connections-pinned {
opacity: 0.3;
transition: opacity 0.2s;
&:hover {
opacity: 1;
}
}
.all-connections-delete,
.all-connections-pin {
opacity: 0;
transition: opacity 0.2s;
&:hover {
opacity: 1;
}
}
}
} }
</style> </style>

View File

@ -549,10 +549,10 @@ onBeforeUnmount(() => {
.modal-body { .modal-body {
overflow: hidden; overflow: hidden;
.tab-link{ .tab-link {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.panel-body { .panel-body {

View File

@ -1,5 +1,13 @@
<template> <template>
<div class="p-relative"> <div class="p-relative">
<div class="shortcuts-tools pb-2 px-2">
<button class="btn btn-dark btn-sm d-flex ml-2">
<i class="mdi mdi-24px mdi-plus mr-1" /><span>{{ t('message.addShortcut') }}</span>
</button>
<button class="btn btn-dark btn-sm d-flex ml-2">
<i class="mdi mdi-24px mdi-undo mr-1" /><span>{{ t('message.restoreDefaults') }}</span>
</button>
</div>
<div class="container workspace-query-results"> <div class="container workspace-query-results">
<div class="table table-hover"> <div class="table table-hover">
<div class="thead"> <div class="thead">
@ -14,6 +22,7 @@
{{ t('word.key', 2) }} {{ t('word.key', 2) }}
</div> </div>
</div> </div>
<div class="th no-border" />
</div> </div>
</div> </div>
@ -25,9 +34,21 @@
tabindex="0" tabindex="0"
> >
<div class="td py-1"> <div class="td py-1">
{{ shortcut.description }} {{ t(shortcut.l18nSlug, {param: shortcut.l18nParam}) }}
</div>
<div
class="td py-1"
style="border-right: 0;"
v-html="parseKeys(shortcut.keys)"
/>
<div class="td py-1 pr-2">
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 mr-2">
<span>{{ t('word.edit') }}</span><i class="mdi mdi-pencil ml-1" />
</button>
<button class="shortcut-button btn btn-link btn-sm d-flex p-0">
<span>{{ t('word.delete') }}</span><i class="mdi mdi-delete-outline ml-1" />
</button>
</div> </div>
<div class="td py-1" v-html="parseKeys(shortcut.keys)" />
</div> </div>
</div> </div>
</div> </div>
@ -57,9 +78,34 @@ const parseKeys = (keys: {[key: number]: string}[]) => {
).join(', '); ).join(', ');
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.table .td { .table {
border-right: 3px solid; .tr{
border-bottom: 3px solid; .td {
border-right: 3px solid;
border-bottom: 3px solid;
}
&:hover {
.shortcut-button {
opacity: 1;
}
}
.shortcut-button {
font-size: 0.7rem;
height: 1rem;
line-height: 1rem;
display: inline-flex;
align-items: center;
justify-content: center;
opacity: 0;
}
}
}
.shortcuts-tools{
display: flex;
justify-content: flex-end;
} }
</style> </style>

View File

@ -245,7 +245,7 @@ watch(selectedWorkspace, (newVal, oldVal) => {
height: calc(100vh - #{$excluding-size}); height: calc(100vh - #{$excluding-size});
display: flex; display: flex;
flex-direction: column; flex-direction: column;
// justify-content: space-between; // justify-content: space-between;
align-items: center; align-items: center;
padding: 0; padding: 0;
z-index: 9; z-index: 9;
@ -319,7 +319,7 @@ watch(selectedWorkspace, (newVal, oldVal) => {
} }
} }
.settingbar-element-pin{ .settingbar-element-pin {
margin: 0 auto; margin: 0 auto;
&::before { &::before {
@ -327,7 +327,7 @@ watch(selectedWorkspace, (newVal, oldVal) => {
content: "\F0403"; content: "\F0403";
color: $body-font-color-dark; color: $body-font-color-dark;
transform: rotate(45deg); transform: rotate(45deg);
opacity: .25; opacity: 0.25;
bottom: -8px; bottom: -8px;
left: -4px; left: -4px;
position: absolute; position: absolute;

View File

@ -560,7 +560,7 @@ setTimeout(() => {
.connection-panel { .connection-panel {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-bottom: .5rem; margin-bottom: 0.5rem;
margin-top: 1.5rem; margin-top: 1.5rem;
.panel { .panel {

View File

@ -551,7 +551,7 @@ localConnection.value = JSON.parse(JSON.stringify(props.connection));
.connection-panel { .connection-panel {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-bottom: .5rem; margin-bottom: 0.5rem;
margin-top: 1.5rem; margin-top: 1.5rem;
.panel { .panel {

View File

@ -119,61 +119,62 @@ onMounted(() => {
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.query-console-wrapper{ .query-console-wrapper {
width: 100%; width: 100%;
z-index: 9; z-index: 9;
margin-top: auto; margin-top: auto;
position: absolute; position: absolute;
bottom: 0; bottom: 0;
.query-console-resizer{ .query-console-resizer {
height: 4px; height: 4px;
top: -1px; top: -1px;
width: 100%; width: 100%;
cursor: ns-resize; cursor: ns-resize;
position: absolute; position: absolute;
z-index: 99; z-index: 99;
transition: background 0.2s; transition: background 0.2s;
&:hover { &:hover {
background: rgba($primary-color, 50%); background: rgba($primary-color, 50%);
}
}
.query-console {
padding: 0;
padding-bottom: $footer-height;
.query-console-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px;
font-weight: 700;
}
.query-console-body {
overflow: auto;
display: flex;
flex-direction: column;
max-height: 100%;
padding: 0 6px 3px;
.query-console-log {
padding: 1px 3px;
margin: 1px 0;
border-radius: $border-radius;
.query-console-log-sql {
font-size: 95%;
opacity: 0.8;
font-weight: 700;
&:hover {
user-select: text;
}
}
} }
} }
}
.query-console {
padding: 0;
padding-bottom: $footer-height;
.query-console-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px;
font-weight: 700;
}
.query-console-body {
overflow: auto;
display: flex;
flex-direction: column;
max-height: 100%;
padding: 0 6px 3px;
.query-console-log {
padding: 1px 3px;
margin: 1px 0;
border-radius: $border-radius;
.query-console-log-sql {
font-size: 95%;
opacity: .8;
font-weight: 700;
&:hover {
user-select: text;
}
}
}
}
}
} }
</style> </style>

View File

@ -299,7 +299,13 @@ export const enUS = {
allConnections: 'All connections', allConnections: 'All connections',
searchForConnections: 'Search for connections', searchForConnections: 'Search for connections',
disableScratchpad: 'Disable scratchpad', disableScratchpad: 'Disable scratchpad',
reportABug: 'Report a bug' reportABug: 'Report a bug',
nextTab: 'Next tab',
previousTab: 'Previous tab',
selectTabNumber: 'Select tab number {param}',
toggleConsole: 'Toggle console',
addShortcut: 'Add shortcut',
restoreDefaults: 'Restore defaults'
}, },
faker: { faker: {
address: 'Address', address: 'Address',

View File

@ -28,13 +28,14 @@ $settingbar-width: 3rem;
$explorebar-width: 14rem; $explorebar-width: 14rem;
$footer-height: 1.5rem; $footer-height: 1.5rem;
@function get-excluding-size(){ @function get-excluding-size() {
@if $platform == linux{ @if $platform == linux {
@return $footer-height; @return $footer-height;
} }
@else {
@return $footer-height + $titlebar-height; @else {
} @return $footer-height + $titlebar-height;
}
} }
$excluding-size: get-excluding-size(); $excluding-size: get-excluding-size();

View File

@ -362,8 +362,9 @@ option:checked {
.accordion-body { .accordion-body {
max-height: 5000rem !important; max-height: 5000rem !important;
} }
.btn { .btn {
&:focus{ &:focus {
box-shadow: 0 0 3px 1px rgba($primary-color, 90%); box-shadow: 0 0 3px 1px rgba($primary-color, 90%);
} }

View File

@ -256,7 +256,7 @@
} }
} }
.connection-block{ .connection-block {
&:hover { &:hover {
background: $bg-color-light-dark; background: $bg-color-light-dark;
} }
@ -308,13 +308,13 @@
.query-console { .query-console {
border-top: 1px solid #444; border-top: 1px solid #444;
background-color: $bg-color-dark; background-color: $bg-color-dark;
.query-console-log { .query-console-log {
&:hover, &:hover,
&:focus { &:focus {
background: $bg-color-gray; background: $bg-color-gray;
} }
} }
} }
.tile { .tile {

View File

@ -131,13 +131,13 @@
.query-console { .query-console {
border-top: 1px solid darken($bg-color-light-gray, 15%); border-top: 1px solid darken($bg-color-light-gray, 15%);
background-color: $bg-color-light; background-color: $bg-color-light;
.query-console-log { .query-console-log {
&:hover, &:hover,
&:focus { &:focus {
background: $bg-color-light-gray; background: $bg-color-light-gray;
} }
} }
} }
#titlebar { #titlebar {
@ -234,7 +234,7 @@
.table-size { .table-size {
opacity: 0.4; opacity: 0.4;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
@ -290,8 +290,8 @@
background: rgba($bg-color-light-gray, 100%); background: rgba($bg-color-light-gray, 100%);
} }
} }
.connection-block{ .connection-block {
&:hover { &:hover {
background: $bg-color-light-gray; background: $bg-color-light-gray;
} }

View File

@ -2,12 +2,13 @@ import { defineStore } from 'pinia';
import { ipcRenderer } from 'electron'; import { ipcRenderer } from 'electron';
import { i18n, AvailableLocale } from '@/i18n'; import { i18n, AvailableLocale } from '@/i18n';
import * as Store from 'electron-store'; import * as Store from 'electron-store';
import { ShortcutRecord, shortcuts as defaultShortcuts } from 'common/shortcuts'; import { ShortcutRecord, shortcuts } from 'common/shortcuts';
const settingsStore = new Store({ name: 'settings' }); const settingsStore = new Store({ name: 'settings' });
const shortcutsStore = new Store({ name: 'shortcuts' }); const shortcutsStore = new Store({ name: 'shortcuts' });
const isDarkTheme = window.matchMedia('(prefers-color-scheme: dark)'); const isDarkTheme = window.matchMedia('(prefers-color-scheme: dark)');
const defaultAppTheme = isDarkTheme.matches ? 'dark' : 'light'; const defaultAppTheme = isDarkTheme.matches ? 'dark' : 'light';
const defaultEditorTheme = isDarkTheme.matches ? 'twilight' : 'sqlserver'; const defaultEditorTheme = isDarkTheme.matches ? 'twilight' : 'sqlserver';
const defaultShortcuts = shortcuts.filter(s => s.os.includes(process.platform));
export type EditorFontSize = 'small' | 'medium' | 'large'; export type EditorFontSize = 'small' | 'medium' | 'large';
export type ApplicationTheme = 'light' | 'dark'; export type ApplicationTheme = 'light' | 'dark';