diff --git a/src/renderer/src/components/HashEditor.vue b/src/renderer/src/components/HashEditor.vue
index 0be6584..ded5fcb 100644
--- a/src/renderer/src/components/HashEditor.vue
+++ b/src/renderer/src/components/HashEditor.vue
@@ -78,27 +78,6 @@ async function loadFieldTtls() {
}
}
-async function setFieldTtl(field: HashField) {
- if (!connStore.activeId || !keyStore.selectedKey) return
- try {
- const { value: seconds } = await ElMessageBox.prompt(t('editor.ttlTitle'), t('editor.setFieldTtl'), {
- inputValue: '-1',
- inputPlaceholder: t('key.ttlHint'),
- })
- if (seconds === '-1') {
- // Remove TTL via PERSIST equivalent — HEXPIRE with 0 or use PERSIST on field
- await window.electronAPI.redis.execute(connStore.activeId, 'HEXPIRE', [keyStore.selectedKey, '0', 'FIELDS', '1', field.field])
- field.ttl = -1
- } else {
- await window.electronAPI.redis.execute(connStore.activeId, 'HEXPIRE', [keyStore.selectedKey, seconds, 'FIELDS', '1', field.field])
- field.ttl = Number(seconds)
- }
- ElMessage.success(t('editor.saved'))
- } catch (err: any) {
- if (err !== 'cancel') ElMessage.error(err.message)
- }
-}
-
onMounted(() => {
checkHexpireSupport()
})
@@ -107,7 +86,11 @@ async function saveField(item: HashField) {
if (!connStore.activeId || !keyStore.selectedKey) return
try {
await window.electronAPI.redis.hashSet(connStore.activeId, keyStore.selectedKey, item.field, item.value)
- ElMessage.success('Saved')
+ if (supportsHexpire.value && item.ttl != null) {
+ const seconds = item.ttl < 0 ? '0' : String(item.ttl)
+ await window.electronAPI.redis.execute(connStore.activeId, 'HEXPIRE', [keyStore.selectedKey, seconds, 'FIELDS', '1', item.field])
+ }
+ ElMessage.success(t('editor.saved'))
} catch (err: any) {
ElMessage.error(err.message)
}
@@ -165,16 +148,15 @@ async function addField() {
-
+
- {{ row.ttl != null ? row.ttl : '-' }}
+
-
+
- {{ t('editor.save') }}
- {{ t('editor.setFieldTtl') }}
- {{ t('common.delete') }}
+ {{ t('editor.save') }}
+ {{ t('common.delete') }}
@@ -265,6 +247,33 @@ async function addField() {
color: var(--text-primary);
}
+.hash-ttl-input {
+ width: 90px;
+}
+
+.hash-ttl-input :deep(.el-input__inner) {
+ color: var(--text-primary);
+}
+
+/* Button contrast in both themes */
+.hash-table :deep(.el-button--primary) {
+ --el-button-text-color: var(--accent-light);
+ --el-button-bg-color: transparent;
+ --el-button-border-color: var(--accent);
+ --el-button-hover-text-color: #fff;
+ --el-button-hover-bg-color: var(--accent);
+ --el-button-hover-border-color: var(--accent);
+}
+
+.hash-table :deep(.el-button--danger) {
+ --el-button-text-color: var(--danger);
+ --el-button-bg-color: transparent;
+ --el-button-border-color: var(--danger);
+ --el-button-hover-text-color: #fff;
+ --el-button-hover-bg-color: var(--danger);
+ --el-button-hover-border-color: var(--danger);
+}
+
.item-count {
font-size: 11px;
color: var(--text-muted);
@@ -275,9 +284,4 @@ async function addField() {
color: var(--accent-light);
}
-.field-ttl {
- font-size: 12px;
- font-family: 'Cascadia Code', monospace;
- color: var(--text-muted);
-}