settings WIP

This commit is contained in:
Jan Prochazka
2022-02-26 13:08:01 +01:00
parent 2b61c8a21f
commit 9267ca326f
12 changed files with 191 additions and 58 deletions

View File

@@ -30,14 +30,14 @@ try {
initialConfig = {}; initialConfig = {};
} }
let settingsJson = {}; // let settingsJson = {};
try { // try {
const datadir = path.join(os.homedir(), 'dbgate-data'); // const datadir = path.join(os.homedir(), 'dbgate-data');
settingsJson = JSON.parse(fs.readFileSync(path.join(datadir, 'settings.json'), { encoding: 'utf-8' })); // settingsJson = JSON.parse(fs.readFileSync(path.join(datadir, 'settings.json'), { encoding: 'utf-8' }));
} catch (err) { // } catch (err) {
console.log('Error loading settings.json:', err.message); // console.log('Error loading settings.json:', err.message);
settingsJson = {}; // settingsJson = {};
} // }
// Keep a global reference of the window object, if you don't, the window will // Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected. // be closed automatically when the JavaScript object is garbage collected.
@@ -199,7 +199,10 @@ function createWindow() {
mainMenu = buildMenu(); mainMenu = buildMenu();
mainWindow.setMenu(mainMenu); mainWindow.setMenu(mainMenu);
function loadMainWindow() { async function loadMainWindow() {
const settings = await main.configController.getSettings();
console.log(settings);
const startUrl = const startUrl =
process.env.ELECTRON_START_URL || process.env.ELECTRON_START_URL ||
url.format({ url.format({

View File

@@ -5,21 +5,24 @@ const { datadir } = require('../utility/directories');
const hasPermission = require('../utility/hasPermission'); const hasPermission = require('../utility/hasPermission');
const socket = require('../utility/socket'); const socket = require('../utility/socket');
const _ = require('lodash'); const _ = require('lodash');
const AsyncLock = require('async-lock');
const currentVersion = require('../currentVersion'); const currentVersion = require('../currentVersion');
const platformInfo = require('../utility/platformInfo'); const platformInfo = require('../utility/platformInfo');
const connections = require('../controllers/connections'); const connections = require('../controllers/connections');
module.exports = { const lock = new AsyncLock();
settingsValue: {},
async _init() { module.exports = {
try { // settingsValue: {},
this.settingsValue = JSON.parse(await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' }));
} catch (err) { // async _init() {
this.settingsValue = {}; // try {
} // this.settingsValue = JSON.parse(await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' }));
}, // } catch (err) {
// this.settingsValue = {};
// }
// },
get_meta: true, get_meta: true,
async get() { async get() {
@@ -40,24 +43,33 @@ module.exports = {
getSettings_meta: true, getSettings_meta: true,
async getSettings() { async getSettings() {
return this.settingsValue; try {
return JSON.parse(await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' }));
} catch (err) {
return {};
}
}, },
updateSettings_meta: true, updateSettings_meta: true,
async updateSettings(values) { async updateSettings(values) {
if (!hasPermission(`settings/change`)) return false; if (!hasPermission(`settings/change`)) return false;
const res = await lock.acquire('update', async () => {
const currentValue = await this.getSettings();
try { try {
const updated = { const updated = {
...this.settingsValue, ...currentValue,
...values, ...values,
}; };
await fs.writeFile(path.join(datadir(), 'settings.json'), JSON.stringify(updated, undefined, 2)); await fs.writeFile(path.join(datadir(), 'settings.json'), JSON.stringify(updated, undefined, 2));
this.settingsValue = updated; // this.settingsValue = updated;
socket.emitChanged(`settings-changed`); socket.emitChanged(`settings-changed`);
return updated; return updated;
} catch (err) { } catch (err) {
return false; return false;
} }
});
return res;
}, },
changelog_meta: true, changelog_meta: true,

View File

@@ -110,7 +110,7 @@ module.exports = {
msgtype: 'connect', msgtype: 'connect',
connection: { ...connection, database }, connection: { ...connection, database },
structure: lastClosed ? lastClosed.structure : null, structure: lastClosed ? lastClosed.structure : null,
globalSettings: config.settingsValue, globalSettings: await config.getSettings(),
}); });
return newOpened; return newOpened;
}, },

View File

@@ -69,7 +69,7 @@ module.exports = {
if (newOpened.disconnected) return; if (newOpened.disconnected) return;
this.close(conid, false); this.close(conid, false);
}); });
subprocess.send({ msgtype: 'connect', ...connection, globalSettings: config.settingsValue }); subprocess.send({ msgtype: 'connect', ...connection, globalSettings: await config.getSettings() });
return newOpened; return newOpened;
}); });
return res; return res;

View File

@@ -145,4 +145,4 @@ function initializeElectronSender(electronSender) {
socket.setElectronSender(electronSender); socket.setElectronSender(electronSender);
} }
module.exports = { start, useAllControllers, initializeElectronSender }; module.exports = { start, useAllControllers, initializeElectronSender, configController: config };

View File

@@ -0,0 +1,23 @@
<script lang="ts">
import { getFormContext } from './FormProviderCore.svelte';
import SettingsCheckboxFieldRaw from './SettingsCheckboxFieldRaw.svelte';
export let label;
export let name;
export let disabled = false;
export let templateProps = {};
const { template, setFieldValue, values } = getFormContext();
</script>
<svelte:component
this={template}
on:change
type="checkbox"
{label}
{disabled}
{...templateProps}
labelProps={disabled ? { disabled: true } : { onClick: () => setFieldValue(name, !$values[name]) }}
>
<SettingsCheckboxFieldRaw {name} {...$$restProps} {disabled} />
</svelte:component>

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import CheckboxField from './CheckboxField.svelte';
import { apiCall } from '../utility/api';
import _ from 'lodash';
import { useSettings } from '../utility/metadataLoaders';
export let name;
export let defaultValue;
const settings = useSettings();
function handleChange(e) {
apiCall('config/update-settings', { [name]: e.target['checked'] });
}
</script>
<CheckboxField {...$$restProps} checked={($settings || {})[name] ?? defaultValue} on:change={handleChange} on:change />

View File

@@ -0,0 +1,42 @@
<script lang="ts" context="module">
import { getContext, setContext } from 'svelte';
const contextKey = 'formProviderContextKey';
export function getFormContext(): any {
return getContext(contextKey);
}
</script>
<script lang="ts">
import FormFieldTemplateLarge from './FormFieldTemplateLarge.svelte';
import createRef from '../utility/createRef';
import { apiCall } from '../utility/api';
import { useSettings } from '../utility/metadataLoaders';
import { derived } from 'svelte/store';
export let template = FormFieldTemplateLarge;
const settings = useSettings();
const values = derived(settings, $settings => {
if (!$settings) {
return {};
}
return $settings;
});
const setFieldValue = (name, value) => {
apiCall('config/update-settings', { [name]: value });
};
const context = {
values,
template,
setFieldValue,
submitActionRef: createRef(null),
};
setContext(contextKey, context);
</script>
<slot />

View File

@@ -0,0 +1,15 @@
<script lang="ts">
import { getFormContext } from './FormProviderCore.svelte';
import SettingsTextFieldRaw from './SettingsTextFieldRaw.svelte';
export let label;
export let name;
export let templateProps = {};
export let focused = false;
const { template } = getFormContext();
</script>
<svelte:component this={template} type="text" {label} {...templateProps}>
<SettingsTextFieldRaw {name} {...$$restProps} {focused} />
</svelte:component>

View File

@@ -0,0 +1,18 @@
<script lang="ts">
import { apiCall } from '../utility/api';
import { useSettings } from '../utility/metadataLoaders';
import TextField from './TextField.svelte';
export let name;
export let defaultValue;
const settings = useSettings();
function handleChange(e) {
apiCall('config/update-settings', { [name]: e.target['value'] });
}
</script>
<TextField {...$$restProps} value={($settings || {})[name] ?? defaultValue} on:input={handleChange} />

View File

@@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import _ from 'lodash'; import _ from 'lodash';
import FormStyledButton from '../buttons/FormStyledButton.svelte';
import FormButton from '../forms/FormButton.svelte'; import FormButton from '../forms/FormButton.svelte';
import FormCheckboxField from '../forms/FormCheckboxField.svelte'; import FormCheckboxField from '../forms/FormCheckboxField.svelte';
@@ -10,6 +11,9 @@
import FormSubmit from '../forms/FormSubmit.svelte'; import FormSubmit from '../forms/FormSubmit.svelte';
import FormTextField from '../forms/FormTextField.svelte'; import FormTextField from '../forms/FormTextField.svelte';
import FormValues from '../forms/FormValues.svelte'; import FormValues from '../forms/FormValues.svelte';
import SettingsCheckboxField from '../forms/SettingsCheckboxField.svelte';
import SettingsFormProvider from '../forms/SettingsFormProvider.svelte';
import SettingsTextField from '../forms/SettingsTextField.svelte';
import ModalBase from '../modals/ModalBase.svelte'; import ModalBase from '../modals/ModalBase.svelte';
import { closeCurrentModal } from '../modals/modalTools'; import { closeCurrentModal } from '../modals/modalTools';
@@ -19,36 +23,34 @@
import getElectron from '../utility/getElectron'; import getElectron from '../utility/getElectron';
import { showSnackbarInfo } from '../utility/snackbar'; import { showSnackbarInfo } from '../utility/snackbar';
function handleOk(e) { // function handleOk(e) {
apiCall( // apiCall(
'config/update-settings', // 'config/update-settings',
_.omitBy(e.detail, (v, k) => k.startsWith(':')) // _.omitBy(e.detail, (v, k) => k.startsWith(':'))
); // );
visibleToolbar.set(!!e.detail[':visibleToolbar']); // visibleToolbar.set(!!e.detail[':visibleToolbar']);
if (electron && !getTitleBarVisibility() != !!e.detail[':useNativeMenu']) { // if (electron && !getTitleBarVisibility() != !!e.detail[':useNativeMenu']) {
electron.send('set-use-native-menu', !!e.detail[':useNativeMenu']); // electron.send('set-use-native-menu', !!e.detail[':useNativeMenu']);
showSnackbarInfo('Native menu settings will be applied after app restart'); // showSnackbarInfo('Native menu settings will be applied after app restart');
} // }
closeCurrentModal(); // closeCurrentModal();
} // }
const electron = getElectron(); const electron = getElectron();
</script> </script>
<FormProvider <SettingsFormProvider>
initialValues={{
...getCurrentSettings(),
':visibleToolbar': getVisibleToolbar(),
':useNativeMenu': !getTitleBarVisibility(),
}}
>
<ModalBase {...$$restProps}> <ModalBase {...$$restProps}>
<div slot="header">Settings</div> <div slot="header">Settings</div>
<FormValues let:values> <FormValues let:values>
{#if electron} {#if electron}
<div class="heading">Appearance</div> <div class="heading">Appearance</div>
<FormCheckboxField name=":useNativeMenu" label="Use system native menu" /> <FormCheckboxField
name="app.useNativeMenu"
label="Use system native menu"
on:change={() => showSnackbarInfo('Native menu settings will be applied after app restart')}
/>
{/if} {/if}
<div class="heading">Data grid</div> <div class="heading">Data grid</div>
@@ -58,6 +60,7 @@
defaultValue="100" defaultValue="100"
/> />
<FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} />
<!-- <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> -->
<FormCheckboxField name="dataGrid.thousandsSeparator" label="Use thousands separator for numbers" /> <FormCheckboxField name="dataGrid.thousandsSeparator" label="Use thousands separator for numbers" />
@@ -76,11 +79,11 @@
</FormValues> </FormValues>
<div slot="footer"> <div slot="footer">
<FormSubmit value="OK" on:click={handleOk} /> <!-- <FormSubmit value="OK" on:click={handleOk} /> -->
<FormButton value="Cancel" on:click={closeCurrentModal} /> <FormStyledButton value="Close" on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>
</FormProvider> </SettingsFormProvider>
<style> <style>
.heading { .heading {

View File

@@ -67,7 +67,7 @@
const rect = domSettings.getBoundingClientRect(); const rect = domSettings.getBoundingClientRect();
const left = rect.right; const left = rect.right;
const top = rect.bottom; const top = rect.bottom;
const items = [{ command: 'settings.commands' }, { command: 'theme.changeTheme' }, { command: 'settings.show' }]; const items = [{ command: 'settings.show' }, { command: 'theme.changeTheme' }, { command: 'settings.commands' }];
currentDropDownMenu.set({ left, top, items }); currentDropDownMenu.set({ left, top, items });
} }