diff --git a/packages/api/src/controllers/config.js b/packages/api/src/controllers/config.js index 16f9efae5..088af6656 100644 --- a/packages/api/src/controllers/config.js +++ b/packages/api/src/controllers/config.js @@ -1,3 +1,10 @@ +const fs = require('fs-extra'); +const path = require('path'); +const { datadir } = require('../utility/directories'); +const hasPermission = require('../utility/hasPermission'); +const socket = require('../utility/socket'); +const _ = require('lodash'); + const currentVersion = require('../currentVersion'); const platformInfo = require('../utility/platformInfo'); @@ -37,5 +44,30 @@ module.exports = { async platformInfo() { return platformInfo; }, - + + getSettings_meta: 'get', + async getSettings() { + try { + return JSON.parse(await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' })); + } catch (err) { + return {}; + } + }, + + updateSettings_meta: 'post', + async updateSettings(values) { + if (!hasPermission(`settings/change`)) return false; + const oldSettings = await this.getSettings(); + try { + const updated = { + ...oldSettings, + ...values, + }; + await fs.writeFile(path.join(datadir(), 'settings.json'), JSON.stringify(updated, undefined, 2)); + socket.emitChanged(`settings-changed`); + return updated; + } catch (err) { + return false; + } + }, }; diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index 71f8b5f58..c32108695 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -15,6 +15,7 @@ import { openElectronFile } from '../utility/openElectronFile'; import { getDefaultFileFormat } from '../plugins/fileformats'; import { getCurrentConfig, getCurrentDatabase } from '../stores'; import './recentDatabaseSwitch'; +import hasPermission from '../utility/hasPermission'; const electron = getElectron(); @@ -203,19 +204,21 @@ registerCommand({ }), }); -registerCommand({ - id: 'settings.commands', - category: 'Settings', - name: 'Keyboard shortcuts', - onClick: () => { - openNewTab({ - title: 'Keyboard Shortcuts', - icon: 'icon keyboard', - tabComponent: 'CommandListTab', - props: {}, - }); - }, -}); +if (hasPermission('settings/change')) { + registerCommand({ + id: 'settings.commands', + category: 'Settings', + name: 'Keyboard shortcuts', + onClick: () => { + openNewTab({ + title: 'Keyboard Shortcuts', + icon: 'icon keyboard', + tabComponent: 'CommandListTab', + props: {}, + }); + }, + }); +} export function registerFileCommands({ idPrefix, diff --git a/packages/web/src/modals/CommandModal.svelte b/packages/web/src/modals/CommandModal.svelte index e8ce63d5e..876171619 100644 --- a/packages/web/src/modals/CommandModal.svelte +++ b/packages/web/src/modals/CommandModal.svelte @@ -10,7 +10,8 @@ import FormSubmit from '../forms/FormSubmit.svelte'; import FormTextField from '../forms/FormTextField.svelte'; import FontIcon from '../icons/FontIcon.svelte'; - import { customKeyboardShortcuts } from '../stores'; + import { commandsSettings } from '../stores'; + import axiosInstance from '../utility/axiosInstance'; import KeyboardModal from './KeyboardModal.svelte'; import ModalBase from './ModalBase.svelte'; import { closeCurrentModal, showModal } from './modalTools'; @@ -41,13 +42,15 @@ value="OK" on:click={e => { closeCurrentModal(); - customKeyboardShortcuts.update(list => ({ - ...list, - [command.id]: { - keyText: e.detail.keyText, - customKeyboardShortcut: true, + axiosInstance.post('config/update-settings', { + commands: { + ...$commandsSettings, + [command.id]: { + keyText: e.detail.keyText, + customKeyboardShortcut: true, + }, }, - })); + }); }} /> { closeCurrentModal(); - customKeyboardShortcuts.update(list => _.omit(list, [command.id])); + axiosInstance.post('config/update-settings', { + commands: _.omit($commandsSettings, [command.id]), + }); }} /> diff --git a/packages/web/src/modals/DropDownMenu.svelte b/packages/web/src/modals/DropDownMenu.svelte index 982ae6922..6227ec72c 100644 --- a/packages/web/src/modals/DropDownMenu.svelte +++ b/packages/web/src/modals/DropDownMenu.svelte @@ -30,9 +30,12 @@ const command = commands[item.command]; if (command) { return { - text: command.name, + text: command.menuName || command.toolbarName || command.name, keyText: command.keyText || command.keyTextFromGroup, - onClick: command.onClick, + onClick: () => { + if (command.getSubCommands) visibleCommandPalette.set(command); + else if (command.onClick) command.onClick(); + }, disabled: !command.enabled, hideDisabled: item.hideDisabled, }; @@ -48,7 +51,7 @@ import clickOutside from '../utility/clickOutside'; import { createEventDispatcher } from 'svelte'; import { onMount } from 'svelte'; - import { commands, commandsCustomized } from '../stores'; + import { commandsCustomized, visibleCommandPalette } from '../stores'; import { extractMenuItems } from '../utility/contextMenu'; export let items; diff --git a/packages/web/src/stores.ts b/packages/web/src/stores.ts index 16f4cde4e..f80416050 100644 --- a/packages/web/src/stores.ts +++ b/packages/web/src/stores.ts @@ -3,7 +3,7 @@ import { ExtensionsDirectory } from 'dbgate-types'; import invalidateCommands from './commands/invalidateCommands'; import getElectron from './utility/getElectron'; import { GlobalCommand } from './commands/registerCommand'; -import { useConfig } from './utility/metadataLoaders'; +import { useConfig, useSettings } from './utility/metadataLoaders'; import _ from 'lodash'; interface TabDefinition { @@ -41,15 +41,15 @@ export const currentTheme = writableWithStorage('theme-light', 'currentTheme'); export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid); export const activeTab = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)); export const recentDatabases = writableWithStorage([], 'recentDatabases'); -export const customKeyboardShortcuts = writableWithStorage({}, 'customKeyboardShortcuts'); +export const commandsSettings = derived(useSettings(), (config: any) => (config || {}).commands || {}); export const allResultsInOneTabDefault = writableWithStorage(false, 'allResultsInOneTabDefault'); export const commandsCustomized = derived( - [commands, customKeyboardShortcuts], - ([$commands, $customKeyboardShortcuts]) => + [commands, commandsSettings], + ([$commands, $commandsSettings]) => _.mapValues($commands, (v, k) => ({ // @ts-ignore ...v, - ...$customKeyboardShortcuts[k], + ...$commandsSettings[k], })) ); diff --git a/packages/web/src/utility/metadataLoaders.ts b/packages/web/src/utility/metadataLoaders.ts index e8fb11d7f..0ed32ae78 100644 --- a/packages/web/src/utility/metadataLoaders.ts +++ b/packages/web/src/utility/metadataLoaders.ts @@ -40,6 +40,12 @@ const configLoader = () => ({ reloadTrigger: 'config-changed', }); +const settingsLoader = () => ({ + url: 'config/get-settings', + params: {}, + reloadTrigger: 'settings-changed', +}); + const platformInfoLoader = () => ({ url: 'config/platform-info', params: {}, @@ -333,6 +339,13 @@ export function useConfig() { return useCore(configLoader, {}); } +export function getSettings() { + return getCore(settingsLoader, {}); +} +export function useSettings() { + return useCore(settingsLoader, {}); +} + export function getPlatformInfo() { return getCore(platformInfoLoader, {}); } diff --git a/packages/web/src/widgets/WidgetIconPanel.svelte b/packages/web/src/widgets/WidgetIconPanel.svelte index 9af34a2a9..a84469bba 100644 --- a/packages/web/src/widgets/WidgetIconPanel.svelte +++ b/packages/web/src/widgets/WidgetIconPanel.svelte @@ -59,7 +59,7 @@ const rect = domSettings.getBoundingClientRect(); const left = rect.right; const top = rect.top; - const items = [{ command: 'settings.commands' }]; + const items = [{ command: 'settings.commands' }, { command: 'theme.changeTheme' }]; currentDropDownMenu.set({ left, top, items }); }