This commit is contained in:
Jan Prochazka 2021-02-26 19:25:35 +01:00
parent a101f21483
commit d9387bef1f
9 changed files with 152 additions and 14 deletions

View File

@ -4,5 +4,16 @@
--dim-left-panel-width: 300px;
--dim-tabs-panel-height: 53px;
--dim-splitter-thickness: 3px;
--dim-content-left: calc(var(--dim-widget-icon-size) + var(--dim-left-panel-width) + var(--dim-splitter-thickness));
--dim-visible-left-panel: 1; /* set from JS */
--dim-content-left: calc(
var(--dim-widget-icon-size) + var(--dim-visible-left-panel) *
(var(--dim-left-panel-width) + var(--dim-splitter-thickness))
);
--dim-visible-toolbar: 1; /* set from JS */
--dim-toolbar-height: 30px;
--dim-header-top: calc(var(--dim-toolbar-height) * var(--dim-visible-toolbar));
--dim-content-top: calc(var(--dim-header-top) + var(--dim-tabs-panel-height));
}

View File

@ -1,10 +1,11 @@
<script lang="ts">
import WidgetContainer from './widgets/WidgetContainer.svelte';
import WidgetIconPanel from './widgets/WidgetIconPanel.svelte';
import { currentTheme, selectedWidget, visibleCommandPalette } from './stores';
import { currentTheme, selectedWidget, visibleCommandPalette, visibleToolbar } from './stores';
import TabsPanel from './widgets/TabsPanel.svelte';
import TabContent from './TabContent.svelte';
import CommandPalette from './commands/CommandPalette.svelte';
import Toolbar from './widgets/Toolbar.svelte';
</script>
<div class={`${$currentTheme} root`}>
@ -28,6 +29,11 @@
<CommandPalette />
</div>
{/if}
{#if $visibleToolbar}
<div class="toolbar">
<Toolbar />
</div>
{/if}
</div>
<style>
@ -37,7 +43,7 @@
.iconbar {
position: fixed;
left: 0;
top: 0;
top: var(--dim-header-top);
bottom: var(--dim-statusbar-height);
width: var(--dim-widget-icon-size);
background: var(--theme-bg-inv-1);
@ -52,7 +58,7 @@
}
.leftpanel {
position: fixed;
top: 0;
top: var(--dim-header-top);
left: var(--dim-widget-icon-size);
bottom: var(--dim-statusbar-height);
width: var(--dim-left-panel-width);
@ -62,7 +68,7 @@
.tabs {
display: flex;
position: fixed;
top: 0;
top: var(--dim-header-top);
left: var(--dim-content-left);
height: var(--dim-tabs-panel-height);
right: 0;
@ -76,7 +82,7 @@
}
.content {
position: fixed;
top: var(--dim-tabs-panel-height);
top: var(--dim-content-top);
left: var(--dim-content-left);
bottom: var(--dim-statusbar-height);
right: 0;
@ -84,7 +90,14 @@
}
.commads {
position: fixed;
top: 0;
top: var(--dim-header-top);
left: var(--dim-widget-icon-size);
}
.toolbar {
position: fixed;
top: 0;
height: var(--dim-toolbar-height);
left: 0;
right: 0;
}
</style>

View File

@ -1,8 +1,12 @@
<script context="module">
registerCommand({
id: 'commandPalette.show',
text: 'Command palette: Show',
category: 'Command palette',
name: 'Show',
keyText: 'F1',
toolbar: true,
showDisabled: true,
icon: 'icon menu',
onClick: () => visibleCommandPalette.set(true),
enabledStore: derived(visibleCommandPalette, $visibleCommandPalette => !$visibleCommandPalette),
});
@ -61,7 +65,7 @@
</div>
{#each filteredItems as command, index}
<div class="command" class:selected={index == selectedIndex} on:click={() => handleCommand(command)}>
<div>{command.text}</div>
<div>{command.category}: {command.name}</div>
{#if command.keyText}
<div class="shortcut">{command.keyText}</div>
{/if}

View File

@ -7,7 +7,8 @@ export interface SubCommand {
export interface GlobalCommand {
id: string;
text: string;
category: string;
name: string;
keyText?: string;
getSubCommands?: () => SubCommand[];
onClick?: Function;
@ -15,6 +16,7 @@ export interface GlobalCommand {
icon?: string;
toolbar?: boolean;
enabled?: boolean;
showDisabled?: boolean;
}
export default function registerCommand(command: GlobalCommand) {

View File

@ -1,6 +1,6 @@
import { currentTheme, extensions } from '../stores';
import { currentTheme, extensions, visibleToolbar } from '../stores';
import registerCommand from './registerCommand';
import { get } from 'svelte/store';
import { derived, get } from 'svelte/store';
import { ThemeDefinition } from 'dbgate-types';
function themeCommand(theme: ThemeDefinition) {
@ -19,6 +19,23 @@ function themeCommand(theme: ThemeDefinition) {
registerCommand({
id: 'theme.changeTheme',
text: 'Theme: Change',
category: 'Theme',
name: 'Change',
getSubCommands: () => get(extensions).themes.map(themeCommand),
});
registerCommand({
id: 'toolbar.show',
category: 'Toolbar',
name: 'Show',
onClick: () => visibleToolbar.set(1),
enabledStore: derived(visibleToolbar, $visibleToolbar => !$visibleToolbar),
});
registerCommand({
id: 'toolbar.hide',
category: 'Toolbar',
name: 'Hide',
onClick: () => visibleToolbar.set(0),
enabledStore: derived(visibleToolbar, $visibleToolbar => $visibleToolbar),
});

View File

@ -3,8 +3,11 @@
registerCommand({
id: 'dataGrid.refresh',
text: 'Data grid: Refresh',
category: 'Data grid',
name: 'Refresh',
keyText: 'F5',
toolbar: true,
icon: 'icon reload',
enabledStore: derived([currentDataGrid], ([grid]) => grid != null),
onClick: () => get(currentDataGrid).refresh(),
});

View File

@ -20,6 +20,10 @@ export function writableWithStorage<T>(defaultValue: T, storageName) {
return res;
}
function subscribeCssVariable(store, transform, cssVariable) {
store.subscribe(value => document.documentElement.style.setProperty(cssVariable, transform(value)));
}
export const selectedWidget = writable('database');
export const openedConnections = writable([]);
export const currentDatabase = writable(null);
@ -29,5 +33,9 @@ export const visibleCommandPalette = writable(false);
export const commands = writable({});
export const currentTheme = writableWithStorage('theme-light', 'currentTheme');
export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid);
export const visibleToolbar = writableWithStorage(1, 'visibleToolbar');
subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel');
subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar');
// export const leftPanelWidth = writable(300);

View File

@ -0,0 +1,23 @@
<script>
import { filter } from 'lodash';
import App from '../App.svelte';
import { commands } from '../stores';
import ToolbarButton from './ToolbarButton.svelte';
</script>
<div class="container">
{#each Object.values($commands).filter(x => (x.enabled || x.showDisabled) && x.toolbar && x.onClick) as command}
<ToolbarButton icon={command.icon} on:click={command.onClick} disabled={!command.enabled}
>{command.name}</ToolbarButton
>
{/each}
</div>
<style>
.container {
display: flex;
user-select: none;
align-items: stretch;
height: var(--dim-toolbar-height);
}
</style>

View File

@ -0,0 +1,57 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import FontIcon from '../icons/FontIcon.svelte';
export let disabled;
export let icon;
const dispatch = createEventDispatcher();
function handleClick(e) {
if (disabled) return;
dispatch('click');
}
</script>
<div class="button" on:click={handleClick} class:disabled>
<div class="inner">
<span class="icon" class:disabled><FontIcon {icon} /></span>
<slot />
</div>
</div>
<style>
.button {
/* padding: 5px 15px; */
padding-left: 15px;
padding-right: 15px;
color: var(--theme-font-1);
border: 0;
border-right: 1px solid var(--theme-border);
align-self: stretch;
display: flex;
}
.button.disabled {
background: var(--theme-bg-2);
color: var(--theme-font-3);
}
.button:hover {
background: var(--theme-bg-2);
}
.button:active:hover {
background: var(--theme-bg-3);
}
.icon {
margin-right: 5px;
color: var(--theme-font-link);
}
.icon.disabled {
color: var(--theme-font-3);
}
.inner {
/* position: relative;
top: 2px; */
white-space: nowrap;
align-self: center;
}
</style>