add db key modal

This commit is contained in:
Jan Prochazka 2022-03-13 22:30:45 +01:00
parent dc34898cd8
commit 5bda092a51
10 changed files with 161 additions and 29 deletions

View File

@ -47,6 +47,7 @@ export interface EngineDriver {
title: string;
defaultPort?: number;
databaseEngineTypes: string[];
supportedKeyTypes: { name: string; label: string }[];
supportsDatabaseUrl?: boolean;
isElectronOnly?: boolean;
showConnectionField?: (field: string, values: any) => boolean;

View File

@ -4,6 +4,7 @@ import { get } from 'svelte/store';
import { ThemeDefinition } from 'dbgate-types';
import ConnectionModal from '../modals/ConnectionModal.svelte';
import AboutModal from '../modals/AboutModal.svelte';
import AddDbKeyModal from '../modals/AddDbKeyModal.svelte';
import SettingsModal from '../settings/SettingsModal.svelte';
import ImportExportModal from '../modals/ImportExportModal.svelte';
import SqlGeneratorModal from '../modals/SqlGeneratorModal.svelte';
@ -217,6 +218,30 @@ registerCommand({
},
});
registerCommand({
id: 'new.dbKey',
category: 'New',
name: 'Key',
toolbar: true,
toolbarName: 'New key',
testEnabled: () => {
const driver = findEngineDriver(get(currentDatabase)?.connection, getExtensions());
return !!get(currentDatabase) && driver?.databaseEngineTypes?.includes('keyvalue');
},
onClick: async () => {
const $currentDatabase = get(currentDatabase);
const connection = _.get($currentDatabase, 'connection') || {};
const database = _.get($currentDatabase, 'name');
const driver = findEngineDriver(get(currentDatabase)?.connection, getExtensions());
showModal(AddDbKeyModal, {
conid: connection._id,
database,
driver,
});
},
});
registerCommand({
id: 'new.markdown',
category: 'New',

View File

@ -19,6 +19,9 @@
const oldIndexRef = createRef(null);
async function loadNextRows() {
if (isLoadedAll) {
return;
}
if (isLoading) {
// console.log('ALREADY LOADING');
loadNextNeeded = true;
@ -79,7 +82,7 @@
header: 'num',
width: '60px',
},
...keyInfo.tableColumns.map(column => ({
...keyInfo.keyType.dbKeyFields.map(column => ({
fieldName: column.name,
header: column.name,
})),

View File

@ -1,13 +1,13 @@
<script lang="ts">
import AceEditor from '../query/AceEditor.svelte';
export let keyInfo;
export let dbKeyFields;
export let item;
export let onChangeItem;
export let onChangeItem = null;
</script>
<div class="props">
{#each keyInfo.tableColumns as column}
{#each dbKeyFields as column}
<div class="colname">{column.name}</div>
<div class="colvalue">
<AceEditor

View File

@ -0,0 +1,58 @@
<script lang="ts">
import FormStyledButton from '../buttons/FormStyledButton.svelte';
import DbKeyItemDetail from '../dbkeyvalue/DbKeyItemDetail.svelte';
import FormProvider from '../forms/FormProvider.svelte';
import SelectField from '../forms/SelectField.svelte';
import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools';
export let conid;
export let database;
export let driver;
export let onConfirm;
let item = {};
let type = driver.supportedKeyTypes[0].name;
const handleSubmit = async () => {
closeCurrentModal();
onConfirm(item);
};
</script>
<FormProvider>
<ModalBase {...$$restProps}>
<svelte:fragment slot="header">Add item</svelte:fragment>
<div class="container">
<SelectField
options={driver.supportedKeyTypes.map(t => ({ value: t.name, label: t.label }))}
value={type}
on:change={e => {
type = e.detail;
}}
/>
<DbKeyItemDetail
dbKeyFields={driver.supportedKeyTypes.find(x => x.name == type).dbKeyFields}
{item}
onChangeItem={value => {
item = value;
}}
/>
</div>
<svelte:fragment slot="footer">
<FormStyledButton value="OK" on:click={e => handleSubmit()} />
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
</svelte:fragment>
</ModalBase>
</FormProvider>
<style>
.container {
display: flex;
height: 30vh;
}
</style>

View File

@ -24,7 +24,7 @@
<div class="container">
<DbKeyItemDetail
{keyInfo}
dbKeyFields={keyInfo.keyType.dbKeyFields}
{item}
onChangeItem={value => {
item = value;

View File

@ -89,8 +89,8 @@
await apiCall('database-connections/call-method', {
conid,
database,
method: keyInfo.addMethod,
args: [keyInfo.key, ...keyInfo.tableColumns.map(col => row[col.name])],
method: keyInfo.keyType.addMethod,
args: [keyInfo.key, ...keyInfo.keyType.dbKeyFields.map(col => row[col.name])],
});
refresh();
},
@ -114,14 +114,14 @@
{#if keyInfo.type == 'string'}
<FormStyledButton value="Save" on:click={saveString} disabled={!editedValue} />
{/if}
{#if keyInfo.addMethod}
{#if keyInfo.keyType?.addMethod && keyInfo.keyType?.showItemList}
<FormStyledButton value="Add item" on:click={() => addItem(keyInfo)} />
{/if}
<FormStyledButton value="Refresh" on:click={refresh} />
</div>
<div class="content">
{#if keyInfo.tableColumns}
{#if keyInfo.keyType?.dbKeyFields && keyInfo.keyType?.showItemList}
<VerticalSplitter>
<svelte:fragment slot="1">
<DbKeyTableControl
@ -134,7 +134,7 @@
/>
</svelte:fragment>
<svelte:fragment slot="2">
<DbKeyItemDetail {keyInfo} item={currentRow} />
<DbKeyItemDetail dbKeyFields={keyInfo.keyType.dbKeyFields} item={currentRow} />
</svelte:fragment>
</VerticalSplitter>
{:else}

View File

@ -1,6 +1,7 @@
<script lang="ts">
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
import InlineButton from '../buttons/InlineButton.svelte';
import runCommand from '../commands/runCommand';
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
import SearchInput from '../elements/SearchInput.svelte';
@ -20,6 +21,9 @@
<SearchBoxWrapper>
<SearchInput placeholder="Search keys" bind:value={filter} />
<CloseSearchButton bind:filter />
<InlineButton on:click={() => runCommand('new.dbKey')} title="Add new key">
<FontIcon icon="icon plus-thick" />
</InlineButton>
<InlineButton on:click={handleRefreshDatabase} title="Refresh key list">
<FontIcon icon="icon refresh" />
</InlineButton>

View File

@ -161,27 +161,29 @@ const driver = {
case 'string':
res.value = await pool.get(key);
break;
case 'list':
res.tableColumns = [{ name: 'value' }];
res.addMethod = 'rpush';
break;
case 'set':
res.tableColumns = [{ name: 'value' }];
res.keyColumn = 'value';
res.addMethod = 'sadd';
break;
case 'zset':
res.tableColumns = [{ name: 'score' }, { name: 'value' }];
res.keyColumn = 'value';
res.addMethod = 'zadd';
break;
case 'hash':
res.tableColumns = [{ name: 'key' }, { name: 'value' }];
res.keyColumn = 'key';
res.addMethod = 'hset';
break;
// case 'list':
// res.tableColumns = [{ name: 'value' }];
// res.addMethod = 'rpush';
// break;
// case 'set':
// res.tableColumns = [{ name: 'value' }];
// res.keyColumn = 'value';
// res.addMethod = 'sadd';
// break;
// case 'zset':
// res.tableColumns = [{ name: 'score' }, { name: 'value' }];
// res.keyColumn = 'value';
// res.addMethod = 'zadd';
// break;
// case 'hash':
// res.tableColumns = [{ name: 'key' }, { name: 'value' }];
// res.keyColumn = 'key';
// res.addMethod = 'hset';
// break;
}
res.keyType = this.supportedKeyTypes.find((x) => x.name == type);
return res;
},

View File

@ -22,6 +22,45 @@ const driver = {
title: 'Redis',
defaultPort: 6379,
databaseEngineTypes: ['keyvalue'],
supportedKeyTypes: [
{
name: 'string',
label: 'String',
dbKeyFields: [{ name: 'value' }],
addMethod: 'set',
},
{
name: 'list',
label: 'List',
dbKeyFields: [{ name: 'value' }],
addMethod: 'rpush',
showItemList: true,
},
{
name: 'set',
label: 'Set',
dbKeyFields: [{ name: 'value' }],
keyColumn: 'value',
addMethod: 'sadd',
showItemList: true,
},
{
name: 'zset',
label: 'Sorted Set',
dbKeyFields: [{ name: 'score' }, { name: 'value' }],
keyColumn: 'value',
addMethod: 'zadd',
showItemList: true,
},
{
name: 'hash',
label: 'Hash',
dbKeyFields: [{ name: 'key' }, { name: 'value' }],
keyColumn: 'key',
addMethod: 'hset',
showItemList: true,
},
],
showConnectionField: (field, values) => {
return ['server', 'port', 'password'].includes(field);