feat: ReJson/TairJson support
- string.ts: rejsonGet, rejsonSet, rejsonDel using JSON.GET/SET/DEL - IPC + preload for rejsonGet/rejsonSet - New ReJsonEditor.vue: Monaco JSON editor with JSON.GET/SET - KeyDetail: dispatch ReJSON-RL/json/tair-json types to ReJsonEditor
This commit is contained in:
@@ -11,6 +11,7 @@ import ListEditor from './ListEditor.vue'
|
||||
import SetEditor from './SetEditor.vue'
|
||||
import ZsetEditor from './ZsetEditor.vue'
|
||||
import StreamEditor from './StreamEditor.vue'
|
||||
import ReJsonEditor from './ReJsonEditor.vue'
|
||||
|
||||
const keyStore = useKeyStore()
|
||||
const connStore = useConnectionStore()
|
||||
@@ -148,6 +149,7 @@ async function refreshKey() {
|
||||
<SetEditor v-else-if="keyStore.selectedType === 'set'" />
|
||||
<ZsetEditor v-else-if="keyStore.selectedType === 'zset'" />
|
||||
<StreamEditor v-else-if="keyStore.selectedType === 'stream'" />
|
||||
<ReJsonEditor v-else-if="['ReJSON-RL', 'json', 'tair-json'].includes(keyStore.selectedType || '')" />
|
||||
<div v-else class="unsupported">
|
||||
<el-icon><Warning /></el-icon>
|
||||
<p>{{ t('key.unsupported', { type: keyStore.selectedType }) }}</p>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<script setup lang="ts">
|
||||
// src/components/ReJsonEditor.vue
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import { VueMonacoEditor } from '@guolao/vue-monaco-editor'
|
||||
import { useKeyStore } from '@renderer/stores/key'
|
||||
import { useConnectionStore } from '@renderer/stores/connection'
|
||||
import { useAppStore } from '@renderer/stores/app'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const keyStore = useKeyStore()
|
||||
const connStore = useConnectionStore()
|
||||
const appStore = useAppStore()
|
||||
|
||||
const editedValue = ref('')
|
||||
const isEditing = ref(false)
|
||||
|
||||
const monacoTheme = computed(() => appStore.theme === 'light' ? 'vs' : 'vs-dark')
|
||||
|
||||
const editorOptions = computed(() => ({
|
||||
readOnly: !isEditing.value,
|
||||
minimap: { enabled: false },
|
||||
fontSize: appStore.fontSize,
|
||||
wordWrap: 'on' as const,
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
tabSize: 2,
|
||||
}))
|
||||
|
||||
async function loadValue() {
|
||||
if (!connStore.activeId || !keyStore.selectedKey) return
|
||||
try {
|
||||
const raw = await window.electronAPI.redis.rejsonGet(connStore.activeId, keyStore.selectedKey, '.')
|
||||
try {
|
||||
editedValue.value = JSON.stringify(JSON.parse(raw), null, 2)
|
||||
} catch {
|
||||
editedValue.value = raw
|
||||
}
|
||||
} catch (err: any) {
|
||||
editedValue.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => keyStore.selectedKey,
|
||||
() => { if (keyStore.selectedType === 'ReJSON-RL' || keyStore.selectedType === 'json' || keyStore.selectedType === 'tair-json') loadValue() },
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
async function save() {
|
||||
if (!connStore.activeId || !keyStore.selectedKey) return
|
||||
try {
|
||||
await window.electronAPI.redis.rejsonSet(connStore.activeId, keyStore.selectedKey, '.', editedValue.value)
|
||||
isEditing.value = false
|
||||
ElMessage.success('Saved')
|
||||
} catch (err: any) {
|
||||
ElMessage.error(err.message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rejson-editor">
|
||||
<div class="editor-toolbar">
|
||||
<span class="type-badge">ReJSON</span>
|
||||
<span class="spacer" />
|
||||
<el-button v-if="!isEditing" size="small" type="primary" @click="isEditing = true">Edit</el-button>
|
||||
<template v-else>
|
||||
<el-button size="small" type="primary" @click="save">Save</el-button>
|
||||
<el-button size="small" @click="isEditing = false; loadValue()">Cancel</el-button>
|
||||
</template>
|
||||
</div>
|
||||
<div class="editor-content">
|
||||
<vue-monaco-editor
|
||||
v-model:value="editedValue"
|
||||
theme="vs-dark"
|
||||
language="json"
|
||||
:options="editorOptions"
|
||||
height="100%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.rejson-editor { height: 100%; display: flex; flex-direction: column; }
|
||||
.editor-toolbar { padding: 12px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--border-color); flex-shrink: 0; }
|
||||
.type-badge { font-size: 10px; font-weight: 700; color: var(--accent-light); background: var(--accent-bg); padding: 2px 8px; border-radius: 4px; }
|
||||
.spacer { flex: 1; }
|
||||
.editor-content { flex: 1; overflow: hidden; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user