mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-03 08:13:57 +00:00
add db key modal
This commit is contained in:
1
packages/types/engines.d.ts
vendored
1
packages/types/engines.d.ts
vendored
@@ -47,6 +47,7 @@ export interface EngineDriver {
|
|||||||
title: string;
|
title: string;
|
||||||
defaultPort?: number;
|
defaultPort?: number;
|
||||||
databaseEngineTypes: string[];
|
databaseEngineTypes: string[];
|
||||||
|
supportedKeyTypes: { name: string; label: string }[];
|
||||||
supportsDatabaseUrl?: boolean;
|
supportsDatabaseUrl?: boolean;
|
||||||
isElectronOnly?: boolean;
|
isElectronOnly?: boolean;
|
||||||
showConnectionField?: (field: string, values: any) => boolean;
|
showConnectionField?: (field: string, values: any) => boolean;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { get } from 'svelte/store';
|
|||||||
import { ThemeDefinition } from 'dbgate-types';
|
import { ThemeDefinition } from 'dbgate-types';
|
||||||
import ConnectionModal from '../modals/ConnectionModal.svelte';
|
import ConnectionModal from '../modals/ConnectionModal.svelte';
|
||||||
import AboutModal from '../modals/AboutModal.svelte';
|
import AboutModal from '../modals/AboutModal.svelte';
|
||||||
|
import AddDbKeyModal from '../modals/AddDbKeyModal.svelte';
|
||||||
import SettingsModal from '../settings/SettingsModal.svelte';
|
import SettingsModal from '../settings/SettingsModal.svelte';
|
||||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||||
import SqlGeneratorModal from '../modals/SqlGeneratorModal.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({
|
registerCommand({
|
||||||
id: 'new.markdown',
|
id: 'new.markdown',
|
||||||
category: 'New',
|
category: 'New',
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
const oldIndexRef = createRef(null);
|
const oldIndexRef = createRef(null);
|
||||||
|
|
||||||
async function loadNextRows() {
|
async function loadNextRows() {
|
||||||
|
if (isLoadedAll) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
// console.log('ALREADY LOADING');
|
// console.log('ALREADY LOADING');
|
||||||
loadNextNeeded = true;
|
loadNextNeeded = true;
|
||||||
@@ -79,7 +82,7 @@
|
|||||||
header: 'num',
|
header: 'num',
|
||||||
width: '60px',
|
width: '60px',
|
||||||
},
|
},
|
||||||
...keyInfo.tableColumns.map(column => ({
|
...keyInfo.keyType.dbKeyFields.map(column => ({
|
||||||
fieldName: column.name,
|
fieldName: column.name,
|
||||||
header: column.name,
|
header: column.name,
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import AceEditor from '../query/AceEditor.svelte';
|
import AceEditor from '../query/AceEditor.svelte';
|
||||||
|
|
||||||
export let keyInfo;
|
export let dbKeyFields;
|
||||||
export let item;
|
export let item;
|
||||||
export let onChangeItem;
|
export let onChangeItem = null;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="props">
|
<div class="props">
|
||||||
{#each keyInfo.tableColumns as column}
|
{#each dbKeyFields as column}
|
||||||
<div class="colname">{column.name}</div>
|
<div class="colname">{column.name}</div>
|
||||||
<div class="colvalue">
|
<div class="colvalue">
|
||||||
<AceEditor
|
<AceEditor
|
||||||
|
|||||||
58
packages/web/src/modals/AddDbKeyModal.svelte
Normal file
58
packages/web/src/modals/AddDbKeyModal.svelte
Normal 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>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<DbKeyItemDetail
|
<DbKeyItemDetail
|
||||||
{keyInfo}
|
dbKeyFields={keyInfo.keyType.dbKeyFields}
|
||||||
{item}
|
{item}
|
||||||
onChangeItem={value => {
|
onChangeItem={value => {
|
||||||
item = value;
|
item = value;
|
||||||
|
|||||||
@@ -89,8 +89,8 @@
|
|||||||
await apiCall('database-connections/call-method', {
|
await apiCall('database-connections/call-method', {
|
||||||
conid,
|
conid,
|
||||||
database,
|
database,
|
||||||
method: keyInfo.addMethod,
|
method: keyInfo.keyType.addMethod,
|
||||||
args: [keyInfo.key, ...keyInfo.tableColumns.map(col => row[col.name])],
|
args: [keyInfo.key, ...keyInfo.keyType.dbKeyFields.map(col => row[col.name])],
|
||||||
});
|
});
|
||||||
refresh();
|
refresh();
|
||||||
},
|
},
|
||||||
@@ -114,14 +114,14 @@
|
|||||||
{#if keyInfo.type == 'string'}
|
{#if keyInfo.type == 'string'}
|
||||||
<FormStyledButton value="Save" on:click={saveString} disabled={!editedValue} />
|
<FormStyledButton value="Save" on:click={saveString} disabled={!editedValue} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if keyInfo.addMethod}
|
{#if keyInfo.keyType?.addMethod && keyInfo.keyType?.showItemList}
|
||||||
<FormStyledButton value="Add item" on:click={() => addItem(keyInfo)} />
|
<FormStyledButton value="Add item" on:click={() => addItem(keyInfo)} />
|
||||||
{/if}
|
{/if}
|
||||||
<FormStyledButton value="Refresh" on:click={refresh} />
|
<FormStyledButton value="Refresh" on:click={refresh} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{#if keyInfo.tableColumns}
|
{#if keyInfo.keyType?.dbKeyFields && keyInfo.keyType?.showItemList}
|
||||||
<VerticalSplitter>
|
<VerticalSplitter>
|
||||||
<svelte:fragment slot="1">
|
<svelte:fragment slot="1">
|
||||||
<DbKeyTableControl
|
<DbKeyTableControl
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="2">
|
<svelte:fragment slot="2">
|
||||||
<DbKeyItemDetail {keyInfo} item={currentRow} />
|
<DbKeyItemDetail dbKeyFields={keyInfo.keyType.dbKeyFields} item={currentRow} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</VerticalSplitter>
|
</VerticalSplitter>
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
|
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
|
||||||
import InlineButton from '../buttons/InlineButton.svelte';
|
import InlineButton from '../buttons/InlineButton.svelte';
|
||||||
|
import runCommand from '../commands/runCommand';
|
||||||
|
|
||||||
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
||||||
import SearchInput from '../elements/SearchInput.svelte';
|
import SearchInput from '../elements/SearchInput.svelte';
|
||||||
@@ -20,6 +21,9 @@
|
|||||||
<SearchBoxWrapper>
|
<SearchBoxWrapper>
|
||||||
<SearchInput placeholder="Search keys" bind:value={filter} />
|
<SearchInput placeholder="Search keys" bind:value={filter} />
|
||||||
<CloseSearchButton bind: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">
|
<InlineButton on:click={handleRefreshDatabase} title="Refresh key list">
|
||||||
<FontIcon icon="icon refresh" />
|
<FontIcon icon="icon refresh" />
|
||||||
</InlineButton>
|
</InlineButton>
|
||||||
|
|||||||
@@ -161,27 +161,29 @@ const driver = {
|
|||||||
case 'string':
|
case 'string':
|
||||||
res.value = await pool.get(key);
|
res.value = await pool.get(key);
|
||||||
break;
|
break;
|
||||||
case 'list':
|
// case 'list':
|
||||||
res.tableColumns = [{ name: 'value' }];
|
// res.tableColumns = [{ name: 'value' }];
|
||||||
res.addMethod = 'rpush';
|
// res.addMethod = 'rpush';
|
||||||
break;
|
// break;
|
||||||
case 'set':
|
// case 'set':
|
||||||
res.tableColumns = [{ name: 'value' }];
|
// res.tableColumns = [{ name: 'value' }];
|
||||||
res.keyColumn = 'value';
|
// res.keyColumn = 'value';
|
||||||
res.addMethod = 'sadd';
|
// res.addMethod = 'sadd';
|
||||||
break;
|
// break;
|
||||||
case 'zset':
|
// case 'zset':
|
||||||
res.tableColumns = [{ name: 'score' }, { name: 'value' }];
|
// res.tableColumns = [{ name: 'score' }, { name: 'value' }];
|
||||||
res.keyColumn = 'value';
|
// res.keyColumn = 'value';
|
||||||
res.addMethod = 'zadd';
|
// res.addMethod = 'zadd';
|
||||||
break;
|
// break;
|
||||||
case 'hash':
|
// case 'hash':
|
||||||
res.tableColumns = [{ name: 'key' }, { name: 'value' }];
|
// res.tableColumns = [{ name: 'key' }, { name: 'value' }];
|
||||||
res.keyColumn = 'key';
|
// res.keyColumn = 'key';
|
||||||
res.addMethod = 'hset';
|
// res.addMethod = 'hset';
|
||||||
break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.keyType = this.supportedKeyTypes.find((x) => x.name == type);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,45 @@ const driver = {
|
|||||||
title: 'Redis',
|
title: 'Redis',
|
||||||
defaultPort: 6379,
|
defaultPort: 6379,
|
||||||
databaseEngineTypes: ['keyvalue'],
|
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) => {
|
showConnectionField: (field, values) => {
|
||||||
return ['server', 'port', 'password'].includes(field);
|
return ['server', 'port', 'password'].includes(field);
|
||||||
|
|||||||
Reference in New Issue
Block a user