perf: add non-exists key view
This commit is contained in:
parent
f85b381992
commit
16c096702c
|
@ -363,6 +363,11 @@ func (c *connectionService) GetKeyValue(connName string, db int, key string) (re
|
|||
return
|
||||
}
|
||||
|
||||
if keyType == "none" {
|
||||
resp.Msg = "key not exists"
|
||||
return
|
||||
}
|
||||
|
||||
var ttl int64
|
||||
if dur, err = rdb.TTL(ctx, key).Result(); err != nil {
|
||||
ttl = -1
|
||||
|
|
|
@ -54,6 +54,18 @@ const onUpdateValue = (tabIndex) => {
|
|||
tabStore.switchTab(tabIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* reload current selection key
|
||||
* @returns {Promise<null>}
|
||||
*/
|
||||
const onReloadKey = async () => {
|
||||
const tab = tabStore.currentTab
|
||||
if (tab == null || isEmpty(tab.key)) {
|
||||
return null
|
||||
}
|
||||
await connectionStore.loadKeyValue(tab.name, tab.db, tab.key)
|
||||
}
|
||||
|
||||
const i18n = useI18n()
|
||||
const confirmDialog = useConfirmDialog()
|
||||
const onCloseTab = (tabIndex) => {
|
||||
|
@ -81,21 +93,20 @@ const onCloseTab = (tabIndex) => {
|
|||
<n-ellipsis style="max-width: 150px">{{ t.label }}</n-ellipsis>
|
||||
</n-tab>
|
||||
</n-tabs>
|
||||
<!-- <n-tabs v-model:value="tabStore.activatedIndex" type="line" @update:value="onUpdateValue" :tabs-padding="0">-->
|
||||
<!-- <n-tab v-for="(t, i) in tab" :key="i" :name="i">-->
|
||||
<!-- <div class="tab-item flex-box-h">-->
|
||||
<!-- <div class="tab-item-label ellipsis">-->
|
||||
<!-- {{ t.label }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <n-icon class="tab-item-close" color="gray" size="16" @click.stop="onCloseTab(i)">-->
|
||||
<!-- <Close :round="false" :stroke-width="5" />-->
|
||||
<!-- </n-icon>-->
|
||||
<!-- </div>-->
|
||||
<!-- </n-tab>-->
|
||||
<!-- </n-tabs>-->
|
||||
<!-- TODO: add loading status -->
|
||||
|
||||
<div v-if="tabContent == null || isEmpty(tabContent.keyPath)" class="flex-item-expand flex-box-v">
|
||||
<n-empty :description="$t('empty_tab_content')" class="empty-content" />
|
||||
</div>
|
||||
<div v-else-if="tabContent.value == null" class="flex-item-expand flex-box-v">
|
||||
<n-empty :description="$t('nonexist_tab_content')" class="empty-content">
|
||||
<template #extra>
|
||||
<n-button @click="onReloadKey">{{ $t('reload') }}</n-button>
|
||||
</template>
|
||||
</n-empty>
|
||||
</div>
|
||||
<component
|
||||
v-if="tabContent != null && !isEmpty(tabContent.keyPath)"
|
||||
v-else
|
||||
:is="valueComponents[tabContent.type]"
|
||||
:db="tabContent.db"
|
||||
:key-path="tabContent.keyPath"
|
||||
|
@ -103,9 +114,6 @@ const onCloseTab = (tabIndex) => {
|
|||
:ttl="tabContent.ttl"
|
||||
:value="tabContent.value"
|
||||
/>
|
||||
<div v-else class="flex-item-expand flex-box-v">
|
||||
<n-empty :description="$t('empty_tab_content')" class="empty-content" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
"spec_field_required": "\"{key}\" should not be blank",
|
||||
"no_connections": "No Connection",
|
||||
"empty_tab_content": "Select the key from left list to see detail.",
|
||||
"nonexist_tab_content": "The selected key does not exist. Please retry",
|
||||
"empty_server_content": "Connect server from left list",
|
||||
"reload_when_succ": "Reload immediately after success",
|
||||
"server": "Server",
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
"spec_field_required": "{key} 不能为空",
|
||||
"no_connections": "空空如也",
|
||||
"empty_tab_content": "可以从左边选择键来查看键的详细内容",
|
||||
"nonexist_tab_content": "所选键不存在,请尝试刷新重试",
|
||||
"empty_server_content": "可以从左边选择并打开连接",
|
||||
"reload_when_succ": "操作成功后立即重新加载",
|
||||
"server": "服务器",
|
||||
|
|
|
@ -428,9 +428,9 @@ const useConnectionStore = defineStore('connections', {
|
|||
async loadKeyValue(server, db, key) {
|
||||
try {
|
||||
const { data, success, msg } = await GetKeyValue(server, db, key)
|
||||
const tab = useTabStore()
|
||||
if (success) {
|
||||
const { type, ttl, value } = data
|
||||
const tab = useTabStore()
|
||||
tab.upsertTab({
|
||||
server,
|
||||
db,
|
||||
|
@ -440,7 +440,14 @@ const useConnectionStore = defineStore('connections', {
|
|||
value,
|
||||
})
|
||||
} else {
|
||||
console.warn('TODO: handle get key fail')
|
||||
tab.upsertTab({
|
||||
server,
|
||||
db,
|
||||
type: 'none',
|
||||
ttl: -1,
|
||||
key,
|
||||
value: null,
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
}
|
||||
|
@ -595,6 +602,9 @@ const useConnectionStore = defineStore('connections', {
|
|||
* @private
|
||||
*/
|
||||
_sortNodes(nodeList) {
|
||||
if (nodeList == null) {
|
||||
return
|
||||
}
|
||||
nodeList.sort((a, b) => {
|
||||
return a.key > b.key ? 1 : -1
|
||||
})
|
||||
|
@ -607,8 +617,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
*/
|
||||
_tidyNodeChildren(node) {
|
||||
let count = 0
|
||||
const totalChildren = size(node.children)
|
||||
if (totalChildren > 0) {
|
||||
if (!isEmpty(node.children)) {
|
||||
this._sortNodes(node.children)
|
||||
|
||||
for (const elem of node.children) {
|
||||
|
@ -621,113 +630,6 @@ const useConnectionStore = defineStore('connections', {
|
|||
node.keys = count
|
||||
},
|
||||
|
||||
/**
|
||||
* add key to db
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @private
|
||||
*/
|
||||
_addKey(connName, db, key) {
|
||||
const dbs = this.databases[connName]
|
||||
const dbDetail = get(dbs, db, {})
|
||||
|
||||
if (dbDetail == null) {
|
||||
return
|
||||
}
|
||||
|
||||
const descendantChain = [dbDetail]
|
||||
|
||||
const keyPart = split(key, separator)
|
||||
let redisKey = ''
|
||||
const keyLen = size(keyPart)
|
||||
let added = false
|
||||
for (let i = 0; i < keyLen; i++) {
|
||||
redisKey += keyPart[i]
|
||||
|
||||
const node = last(descendantChain)
|
||||
const nodeList = get(node, 'children', [])
|
||||
const len = size(nodeList)
|
||||
const isLastKeyPart = i === keyLen - 1
|
||||
for (let j = 0; j < len + 1; j++) {
|
||||
const treeKey = get(nodeList[j], 'key')
|
||||
const isLast = j >= len - 1
|
||||
const keyType = isLastKeyPart ? ConnectionType.RedisValue : ConnectionType.RedisKey
|
||||
const curKey = `${connName}/db${db}#${keyType}/${redisKey}`
|
||||
if (treeKey > curKey || isLast) {
|
||||
// out of search range, add new item
|
||||
if (isLastKeyPart) {
|
||||
// key not exists, add new one
|
||||
const item = {
|
||||
key: curKey,
|
||||
label: keyPart[i],
|
||||
name: connName,
|
||||
db,
|
||||
keys: 1,
|
||||
redisKey,
|
||||
type: ConnectionType.RedisValue,
|
||||
}
|
||||
if (isLast) {
|
||||
nodeList.push(item)
|
||||
} else {
|
||||
nodeList.splice(j, 0, item)
|
||||
}
|
||||
added = true
|
||||
} else {
|
||||
// layer not exists, add new one
|
||||
const item = {
|
||||
key: curKey,
|
||||
label: keyPart[i],
|
||||
name: connName,
|
||||
db,
|
||||
keys: 0,
|
||||
redisKey,
|
||||
type: ConnectionType.RedisKey,
|
||||
children: [],
|
||||
}
|
||||
if (isLast) {
|
||||
nodeList.push(item)
|
||||
descendantChain.push(last(nodeList))
|
||||
} else {
|
||||
nodeList.splice(j, 0, item)
|
||||
descendantChain.push(nodeList[j])
|
||||
}
|
||||
redisKey += separator
|
||||
added = true
|
||||
}
|
||||
break
|
||||
} else if (treeKey === curKey) {
|
||||
if (isLastKeyPart) {
|
||||
// same key exists, do nothing
|
||||
console.log('TODO: same key exist, do nothing now, should replace value later')
|
||||
} else {
|
||||
// same group exists, find into it's children
|
||||
descendantChain.push(nodeList[j])
|
||||
redisKey += separator
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update ancestor node's info
|
||||
if (added) {
|
||||
const desLen = size(descendantChain)
|
||||
for (let i = 0; i < desLen; i++) {
|
||||
const children = get(descendantChain[i], 'children', [])
|
||||
let keys = 0
|
||||
for (const child of children) {
|
||||
if (child.type === ConnectionType.RedisKey) {
|
||||
keys += get(child, 'keys', 1)
|
||||
} else if (child.type === ConnectionType.RedisValue) {
|
||||
keys += get(child, 'keys', 0)
|
||||
}
|
||||
}
|
||||
descendantChain[i].keys = keys
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* set redis key
|
||||
* @param {string} connName
|
||||
|
@ -1217,7 +1119,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
if (success) {
|
||||
// delete old key and add new key struct
|
||||
this._deleteKeyNode(connName, db, key)
|
||||
this._addKey(connName, db, newKey)
|
||||
this._addKeyNodes(connName, db, [newKey])
|
||||
return { success: true }
|
||||
} else {
|
||||
return { success: false, msg }
|
||||
|
|
Loading…
Reference in New Issue