Added delete functionality for list, hash, set, zset and stream fields.

This commit is contained in:
Stela Augustinova
2025-12-23 09:05:04 +01:00
parent 7ff84a9932
commit 4c12ee3b14
10 changed files with 239 additions and 24 deletions

View File

@@ -10,7 +10,7 @@
<div class="props">
{#each dbKeyFields as column}
<DbKeyValueDetail
value={item && item[column.name]}
value={item && item[column.name] != null ? String(item[column.name]) : ''}
columnTitle={_.startCase(column.name)}
onChangeValue={onChangeItem && !column.readOnly
? value => {

View File

@@ -39,8 +39,6 @@
<style>
.props {
flex: 1;
display: flex;
flex-direction: row;
gap: 10px;
padding: 10px;
overflow: hidden;
@@ -49,8 +47,6 @@
.field-wrapper {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
overflow: hidden;
max-height: 100px;
}

View File

@@ -34,7 +34,7 @@
<div class="editor-wrapper">
<AceEditor
readOnly={!onChangeValue}
{value}
value={value != null ? String(value) : ''}
mode={keyType === 'JSON' ? 'json' : undefined}
on:input={e => {
onChangeValue?.(e.detail);

View File

@@ -1,5 +1,6 @@
<script lang="ts">
import _ from 'lodash';
import { onMount } from 'svelte';
import TextField from '../forms/TextField.svelte';
import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte';
import FontIcon from '../icons/FontIcon.svelte';
@@ -10,6 +11,16 @@
export let keyColumn = null;
let records = [{ key: '', value: '', ttl: '' }];
let lastItem = null;
$: if (item !== lastItem) {
if (item?.records && Array.isArray(item.records)) {
records = [...item.records];
} else if (!item) {
records = [{ key: '', value: '', ttl: '' }];
}
lastItem = item;
}
$: console.log('DbKeyItemEdit', { item, dbKeyFields, keyColumn, onChangeItem: !!onChangeItem });
@@ -50,7 +61,7 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="field-wrapper col-7">
<div class="field-wrapper col-6">
<FormFieldTemplateLarge label="Value" type="text" noMargin>
<TextField
value={record.value}
@@ -68,6 +79,13 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index);
}}>
<FontIcon icon="icon delete" />
</button>
</div>
</div>
{/each}
@@ -91,6 +109,7 @@
display: flex;
flex-direction: row;
gap: 10px;
align-items: center;
}
.field-wrapper {
@@ -100,6 +119,27 @@
flex-direction: column;
}
.delete-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button {
background: none;
border: none;
padding: 0;
cursor: pointer;
color: var(--theme-font-3);
transition: color 0.2s;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.add-button-wrapper {
display: flex;
justify-content: flex-end;

View File

@@ -10,6 +10,16 @@
export let keyColumn = null;
let records = [{ value: '' }];
let lastItem = null;
$: if (item !== lastItem) {
if (item?.records && Array.isArray(item.records)) {
records = [...item.records];
} else if (!item) {
records = [{ value: '' }];
}
lastItem = item;
}
$: console.log('DbKeyValueListEdit', { item, dbKeyFields, keyColumn, onChangeItem: !!onChangeItem });
@@ -34,7 +44,7 @@
<div class="container">
{#each records as record, index}
<div class="props flex">
<div class="field-wrapper col-12">
<div class="field-wrapper col-11">
<FormFieldTemplateLarge label="Value" type="text" noMargin>
<TextField
value={record.value}
@@ -43,6 +53,13 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index);
}}>
<FontIcon icon="icon delete" />
</button>
</div>
</div>
{/each}
@@ -75,6 +92,31 @@
flex-direction: column;
}
.delete-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button {
background: none;
border: none;
padding: 0;
cursor: pointer;
color: var(--theme-font-3);
transition: color 0.2s;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button:hover {
color: var(--theme-font-hover);
}
.add-button-wrapper {
display: flex;
justify-content: flex-end;

View File

@@ -10,6 +10,16 @@
export let keyColumn = null;
let records = [{ value: '' }];
let lastItem = null;
$: if (item !== lastItem) {
if (item?.records && Array.isArray(item.records)) {
records = [...item.records];
} else if (!item) {
records = [{ value: '' }];
}
lastItem = item;
}
$: console.log('DbKeyValueSetEdit', { item, dbKeyFields, keyColumn, onChangeItem: !!onChangeItem });
@@ -34,7 +44,7 @@
<div class="container">
{#each records as record, index}
<div class="props flex">
<div class="field-wrapper col-12">
<div class="field-wrapper col-11">
<FormFieldTemplateLarge label="Value" type="text" noMargin>
<TextField
value={record.value}
@@ -43,6 +53,13 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index);
}}>
<FontIcon icon="icon delete" />
</button>
</div>
</div>
{/each}
@@ -75,6 +92,31 @@
flex-direction: column;
}
.delete-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button {
background: none;
border: none;
padding: 0;
cursor: pointer;
color: var(--theme-font-3);
transition: color 0.2s;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button:hover {
color: var(--theme-font-hover);
}
.add-button-wrapper {
display: flex;
justify-content: flex-end;

View File

@@ -10,6 +10,16 @@
export let keyColumn = null;
let records = [{ id: '', value: '' }];
let lastItem = null;
$: if (item !== lastItem) {
if (item?.records && Array.isArray(item.records)) {
records = [...item.records];
} else if (!item) {
records = [{ id: '', value: '' }];
}
lastItem = item;
}
$: console.log('DbKeyValueStreamEdit', { item, dbKeyFields, keyColumn, onChangeItem: !!onChangeItem });
@@ -49,7 +59,7 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="field-wrapper col-9">
<div class="field-wrapper col-8">
<FormFieldTemplateLarge label="Value" type="text" noMargin>
<TextField
value={record.value}
@@ -58,6 +68,13 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index);
}}>
<FontIcon icon="icon delete" />
</button>
</div>
</div>
{/each}
@@ -90,6 +107,31 @@
flex-direction: column;
}
.delete-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button {
background: none;
border: none;
padding: 0;
cursor: pointer;
color: var(--theme-font-3);
transition: color 0.2s;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button:hover {
color: var(--theme-font-hover);
}
.add-button-wrapper {
display: flex;
justify-content: flex-end;

View File

@@ -10,6 +10,16 @@
export let keyColumn = null;
let records = [{ member: '', score: '' }];
let lastItem = null;
$: if (item !== lastItem) {
if (item?.records && Array.isArray(item.records)) {
records = [...item.records];
} else if (!item) {
records = [{ member: '', score: '' }];
}
lastItem = item;
}
$: console.log('DbKeyValueZSetEdit', { item, dbKeyFields, keyColumn, onChangeItem: !!onChangeItem });
@@ -39,7 +49,7 @@
<div class="container">
{#each records as record, index}
<div class="props flex">
<div class="field-wrapper col-8">
<div class="field-wrapper col-7">
<FormFieldTemplateLarge label="Member" type="text" noMargin>
<TextField
value={record.member}
@@ -57,6 +67,13 @@
/>
</FormFieldTemplateLarge>
</div>
<div class="delete-wrapper col-1">
<button class="delete-button" on:click={() => {
records = records.filter((_, idx) => idx !== index);
}}>
<FontIcon icon="icon delete" />
</button>
</div>
</div>
{/each}
@@ -89,6 +106,31 @@
flex-direction: column;
}
.delete-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button {
background: none;
border: none;
padding: 0;
cursor: pointer;
color: var(--theme-font-3);
transition: color 0.2s;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.delete-button:hover {
color: var(--theme-font-hover);
}
.add-button-wrapper {
display: flex;
justify-content: flex-end;

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import FormStyledButton from '../buttons/FormStyledButton.svelte';
import DbKeyItemDetail from '../dbkeyvalue/DbKeyItemDetail.svelte';
import DbKeyValueHashEdit from '../dbkeyvalue/DbKeyValueHashEdit.svelte';
import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte';
import FormProvider from '../forms/FormProvider.svelte';
@@ -53,6 +54,15 @@
/>
</FormFieldTemplateLarge>
{#if type === 'hash'}
<DbKeyValueHashEdit
dbKeyFields={driver.supportedKeyTypes.find(x => x.name == type).dbKeyFields}
{item}
onChangeItem={value => {
item = value;
}}
/>
{:else}
<DbKeyItemDetail
dbKeyFields={driver.supportedKeyTypes.find(x => x.name == type).dbKeyFields}
{item}
@@ -60,6 +70,7 @@
item = value;
}}
/>
{/if}
</div>
<svelte:fragment slot="footer">

View File

@@ -165,7 +165,7 @@
// @ts-ignore
const update = existingChange.updates?.find(u => u.key === row.key);
if (update) {
return { ...row, value: update.value };
return { ...row, value: update.value, TTL: update.ttl !== undefined ? update.ttl : row.TTL };
}
} else if (keyInfo.type === 'list') {
// @ts-ignore
@@ -189,7 +189,7 @@
c => c.key === keyInfo.key && c.type === keyInfo.type
);
if (existingChange && (keyInfo.type === 'string' || keyInfo.type === 'json')) {
if (existingChange && (keyInfo.type === 'string' || keyInfo.type === 'JSON')) {
// @ts-ignore
return existingChange.value || keyInfo.value;
}
@@ -316,10 +316,10 @@
const updateIndex = hashChange.updates?.findIndex(u => u.key === item.key) ?? -1;
if (updateIndex >= 0) {
// @ts-ignore
hashChange.updates[updateIndex] = { key: item.key, value: item.value, ttl: keyInfo.ttl };
hashChange.updates[updateIndex] = { key: item.key, value: item.value, ttl: item.TTL };
} else {
// @ts-ignore
hashChange.updates = [...(hashChange.updates || []), { key: item.key, value: item.value, ttl: keyInfo.ttl }];
hashChange.updates = [...(hashChange.updates || []), { key: item.key, value: item.value, ttl: item.TTL }];
}
addOrUpdateChange(hashChange);
} else if (keyInfo.type === 'list') {
@@ -367,7 +367,7 @@
type: 'string',
value: value,
});
} else if (keyInfo.type === 'json') {
} else if (keyInfo.type === 'JSON') {
addOrUpdateChange({
key: key,
type: 'json',
@@ -388,7 +388,7 @@
disabled={!hasChanges}
>{_t('common.save', { defaultMessage: 'Save' })}</ToolStripButton>
{#if keyInfo.keyType?.addMethod && keyInfo.keyType?.showItemList}
<ToolStripButton icon="icon add" on:click={() => addItem(keyInfo)}>Add field</ToolStripButton>
<ToolStripButton icon="icon add" on:click={() => { showAddForm = true; }}>Add field</ToolStripButton>
{/if}
<ToolStripButton icon="icon refresh" on:click={refresh}>{_t('common.refresh', { defaultMessage: 'Refresh' })}</ToolStripButton>
</svelte:fragment>