Refactor DbKeyDetailTab and related components to handle item changes

This commit is contained in:
Stela Augustinova
2025-12-23 14:22:31 +01:00
parent 4c12ee3b14
commit 7281ee1565
6 changed files with 177 additions and 16 deletions

View File

@@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import _ from 'lodash'; import _ from 'lodash';
import { onMount } from 'svelte';
import TextField from '../forms/TextField.svelte'; import TextField from '../forms/TextField.svelte';
import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte'; import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte';
import FontIcon from '../icons/FontIcon.svelte'; import FontIcon from '../icons/FontIcon.svelte';
@@ -46,6 +45,12 @@
function addRecord() { function addRecord() {
records = [...records, { key: '', value: '', ttl: '' }]; records = [...records, { key: '', value: '', ttl: '' }];
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
} }
</script> </script>
@@ -82,6 +87,12 @@
<div class="delete-wrapper col-1"> <div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => { <button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index); records = records.filter((_, idx) => idx !== index);
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
}}> }}>
<FontIcon icon="icon delete" /> <FontIcon icon="icon delete" />
</button> </button>

View File

@@ -38,6 +38,12 @@
function addRecord() { function addRecord() {
records = [...records, { value: '' }]; records = [...records, { value: '' }];
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
} }
</script> </script>
@@ -56,6 +62,12 @@
<div class="delete-wrapper col-1"> <div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => { <button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index); records = records.filter((_, idx) => idx !== index);
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
}}> }}>
<FontIcon icon="icon delete" /> <FontIcon icon="icon delete" />
</button> </button>

View File

@@ -38,6 +38,12 @@
function addRecord() { function addRecord() {
records = [...records, { value: '' }]; records = [...records, { value: '' }];
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
} }
</script> </script>
@@ -56,6 +62,12 @@
<div class="delete-wrapper col-1"> <div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => { <button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index); records = records.filter((_, idx) => idx !== index);
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
}}> }}>
<FontIcon icon="icon delete" /> <FontIcon icon="icon delete" />
</button> </button>

View File

@@ -43,6 +43,12 @@
function addRecord() { function addRecord() {
records = [...records, { id: '', value: '' }]; records = [...records, { id: '', value: '' }];
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
} }
</script> </script>
@@ -71,6 +77,12 @@
<div class="delete-wrapper col-1"> <div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => { <button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index); records = records.filter((_, idx) => idx !== index);
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
}}> }}>
<FontIcon icon="icon delete" /> <FontIcon icon="icon delete" />
</button> </button>

View File

@@ -43,6 +43,12 @@
function addRecord() { function addRecord() {
records = [...records, { member: '', score: '' }]; records = [...records, { member: '', score: '' }];
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
} }
</script> </script>
@@ -70,6 +76,12 @@
<div class="delete-wrapper col-1"> <div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => { <button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index); records = records.filter((_, idx) => idx !== index);
if (onChangeItem) {
onChangeItem({
...item,
records: records,
});
}
}}> }}>
<FontIcon icon="icon delete" /> <FontIcon icon="icon delete" />
</button> </button>

View File

@@ -44,6 +44,8 @@
import ToolStripContainer from '../buttons/ToolStripContainer.svelte'; import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
import ToolStripButton from '../buttons/ToolStripButton.svelte'; import ToolStripButton from '../buttons/ToolStripButton.svelte';
import type { ChangeSetRedis, ChangeSetRedisType } from 'dbgate-datalib'; import type { ChangeSetRedis, ChangeSetRedisType } from 'dbgate-datalib';
import useEditorData from '../query/useEditorData';
import { onDestroy } from 'svelte';
export let tabid; export let tabid;
export let conid; export let conid;
@@ -63,11 +65,37 @@
let currentRow; let currentRow;
let showAddForm = false; let showAddForm = false;
let previousKey = null;
$: key = $activeDbKeysStore[`${conid}:${database}`]; $: key = $activeDbKeysStore[`${conid}:${database}`];
let refreshToken = 0; let refreshToken = 0;
const { editorState, editorValue, setEditorData } = useEditorData({
tabid,
onInitialData: value => {
if (value && value.changes) {
changeSetRedis = value;
}
},
});
let changeSetRedis: ChangeSetRedis = { changes: [] }; let changeSetRedis: ChangeSetRedis = { changes: [] };
$: if ($editorValue && $editorValue.changes) {
changeSetRedis = $editorValue;
}
$: if (changeSetRedis && changeSetRedis.changes) {
setEditorData(changeSetRedis);
}
$: if (key !== previousKey && previousKey !== null && changeSetRedis.changes.length > 0) {
setEditorData(changeSetRedis);
previousKey = key;
} else if (key !== previousKey) {
previousKey = key;
}
$: hasChanges = changeSetRedis.changes.length > 0; $: hasChanges = changeSetRedis.changes.length > 0;
$: changeTab(tabid, tab => ({ $: changeTab(tabid, tab => ({
@@ -75,6 +103,12 @@
title: getKeyText(key), title: getKeyText(key),
})); }));
onDestroy(() => {
if (changeSetRedis && changeSetRedis.changes && changeSetRedis.changes.length > 0) {
setEditorData(changeSetRedis);
}
});
function handleChangeTtl(keyInfo) { function handleChangeTtl(keyInfo) {
showModal(InputTextModal, { showModal(InputTextModal, {
value: keyInfo.ttl, value: keyInfo.ttl,
@@ -197,8 +231,35 @@
return keyInfo.value; return keyInfo.value;
} }
function getExistingInserts(keyInfo) {
const existingChange = changeSetRedis.changes.find(
c => c.key === keyInfo.key && c.type === keyInfo.type
);
if (!existingChange || !existingChange.inserts) {
return null;
}
// @ts-ignore
const records = existingChange.inserts.map(insert => {
if (keyInfo.type === 'hash') {
return { key: insert.key || '', value: insert.value || '', ttl: insert.ttl ? String(insert.ttl) : '' };
} else if (keyInfo.type === 'list' || keyInfo.type === 'set') {
return { value: insert.value || '' };
} else if (keyInfo.type === 'zset') {
return { member: insert.member || '', score: insert.score ? String(insert.score) : '' };
} else if (keyInfo.type === 'stream') {
return { id: insert.id || '', value: insert.value || '' };
}
return insert;
});
return { records };
}
function refresh() { function refresh() {
changeSetRedis = { changes: [] }; changeSetRedis = { changes: [] };
setEditorData({ changes: [] });
refreshToken += 1; refreshToken += 1;
} }
@@ -210,6 +271,7 @@
changeSet: changeSetRedis, changeSet: changeSetRedis,
}); });
changeSetRedis = { changes: [] }; changeSetRedis = { changes: [] };
setEditorData({ changes: [] });
refreshToken += 1; refreshToken += 1;
} }
</script> </script>
@@ -252,51 +314,91 @@
{#if keyInfo.type === 'list'} {#if keyInfo.type === 'list'}
<DbKeyValueListEdit <DbKeyValueListEdit
dbKeyFields={keyInfo.keyType.dbKeyFields} dbKeyFields={keyInfo.keyType.dbKeyFields}
item={null} item={getExistingInserts(keyInfo)}
keyColumn={null} keyColumn={null}
onChangeItem={item => { onChangeItem={item => {
console.log('Add item:', item); if (item && item.records && item.records.length > 0) {
showAddForm = false; const existingChange = changeSetRedis.changes.find(
c => c.key === keyInfo.key && c.type === keyInfo.type
);
// @ts-ignore
const listChange = existingChange || { key: keyInfo.key, type: 'list', inserts: [], updates: [], deletes: [] };
// @ts-ignore
listChange.inserts = item.records.filter(r => r.value.trim() !== '').map(r => ({ value: r.value }));
addOrUpdateChange(listChange);
}
}} }}
/> />
{:else if keyInfo.type === 'hash'} {:else if keyInfo.type === 'hash'}
<DbKeyValueHashEdit <DbKeyValueHashEdit
dbKeyFields={keyInfo.keyType.dbKeyFields} dbKeyFields={keyInfo.keyType.dbKeyFields}
item={null} item={getExistingInserts(keyInfo)}
keyColumn={null} keyColumn={null}
onChangeItem={item => { onChangeItem={item => {
console.log('Add item:', item); if (item && item.records && item.records.length > 0) {
showAddForm = false; const existingChange = changeSetRedis.changes.find(
c => c.key === keyInfo.key && c.type === keyInfo.type
);
// @ts-ignore
const hashChange = existingChange || { key: keyInfo.key, type: 'hash', inserts: [], updates: [], deletes: [] };
// @ts-ignore
hashChange.inserts = item.records.filter(r => r.key.trim() !== '' && r.value.trim() !== '').map(r => ({ key: r.key, value: r.value, ttl: r.ttl ? parseInt(r.ttl) : undefined }));
addOrUpdateChange(hashChange);
}
}} }}
/> />
{:else if keyInfo.type === 'zset'} {:else if keyInfo.type === 'zset'}
<DbKeyValueZSetEdit <DbKeyValueZSetEdit
dbKeyFields={keyInfo.keyType.dbKeyFields} dbKeyFields={keyInfo.keyType.dbKeyFields}
item={null} item={getExistingInserts(keyInfo)}
keyColumn={null} keyColumn={null}
onChangeItem={item => { onChangeItem={item => {
console.log('Add item:', item); if (item && item.records && item.records.length > 0) {
showAddForm = false; const existingChange = changeSetRedis.changes.find(
c => c.key === keyInfo.key && c.type === keyInfo.type
);
// @ts-ignore
const zsetChange = existingChange || { key: keyInfo.key, type: 'zset', inserts: [], updates: [], deletes: [] };
// @ts-ignore
zsetChange.inserts = item.records.filter(r => r.member.trim() !== '' && r.score.trim() !== '').map(r => ({ member: r.member, score: parseFloat(r.score) }));
addOrUpdateChange(zsetChange);
}
}} }}
/> />
{:else if keyInfo.type === 'set'} {:else if keyInfo.type === 'set'}
<DbKeyValueSetEdit <DbKeyValueSetEdit
dbKeyFields={keyInfo.keyType.dbKeyFields} dbKeyFields={keyInfo.keyType.dbKeyFields}
item={null} item={getExistingInserts(keyInfo)}
keyColumn={null} keyColumn={null}
onChangeItem={item => { onChangeItem={item => {
console.log('Add item:', item); if (item && item.records && item.records.length > 0) {
showAddForm = false; const existingChange = changeSetRedis.changes.find(
c => c.key === keyInfo.key && c.type === keyInfo.type
);
// @ts-ignore
const setChange = existingChange || { key: keyInfo.key, type: 'set', inserts: [], updates: [], deletes: [] };
// @ts-ignore
setChange.inserts = item.records.filter(r => r.value.trim() !== '').map(r => ({ value: r.value }));
addOrUpdateChange(setChange);
}
}} }}
/> />
{:else if keyInfo.type === 'stream'} {:else if keyInfo.type === 'stream'}
<DbKeyValueStreamEdit <DbKeyValueStreamEdit
dbKeyFields={keyInfo.keyType.dbKeyFields} dbKeyFields={keyInfo.keyType.dbKeyFields}
item={null} item={getExistingInserts(keyInfo)}
keyColumn={null} keyColumn={null}
onChangeItem={item => { onChangeItem={item => {
console.log('Add item:', item); if (item && item.records && item.records.length > 0) {
showAddForm = false; const existingChange = changeSetRedis.changes.find(
c => c.key === keyInfo.key && c.type === keyInfo.type
);
// @ts-ignore
const streamChange = existingChange || { key: keyInfo.key, type: 'stream', inserts: [], updates: [], deletes: [] };
// @ts-ignore
streamChange.inserts = item.records.filter(r => r.value.trim() !== '').map(r => ({ id: r.id.trim() || '*', value: r.value }));
addOrUpdateChange(streamChange);
}
}} }}
/> />
{/if} {/if}