fix: completely remove node tree info when close connection
perf: add back to button to server status page
This commit is contained in:
parent
0bc8335eef
commit
d7e6485806
|
@ -87,7 +87,6 @@ const theme = computed(() => {
|
||||||
<n-message-provider>
|
<n-message-provider>
|
||||||
<n-dialog-provider>
|
<n-dialog-provider>
|
||||||
<n-spin v-show="initializing" :theme-overrides="{ opacitySpinning: 0 }">
|
<n-spin v-show="initializing" :theme-overrides="{ opacitySpinning: 0 }">
|
||||||
<template #description>{{ $t('launching') }}</template>
|
|
||||||
<div id="launch-container" />
|
<div id="launch-container" />
|
||||||
</n-spin>
|
</n-spin>
|
||||||
<app-content v-if="!initializing" />
|
<app-content v-if="!initializing" />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onActivated, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
import { types } from '../../consts/support_redis_type.js'
|
import { types } from '../../consts/support_redis_type.js'
|
||||||
import ContentValueHash from '../content_value/ContentValueHash.vue'
|
import ContentValueHash from '../content_value/ContentValueHash.vue'
|
||||||
import ContentValueList from '../content_value/ContentValueList.vue'
|
import ContentValueList from '../content_value/ContentValueList.vue'
|
||||||
|
@ -60,6 +60,15 @@ const tab = computed(() =>
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => tabStore.nav,
|
||||||
|
(nav) => {
|
||||||
|
if (nav === 'structure') {
|
||||||
|
refreshInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const tabContent = computed(() => {
|
const tabContent = computed(() => {
|
||||||
const tab = tabStore.currentTab
|
const tab = tabStore.currentTab
|
||||||
if (tab == null) {
|
if (tab == null) {
|
||||||
|
@ -113,7 +122,7 @@ const onCloseTab = (tabIndex) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-container flex-box-v">
|
<div class="content-container flex-box-v">
|
||||||
<!-- <content-tab :model-value="tab"></content-tab>-->
|
<!-- <content-tab :model-value="tab"></content-tab>-->
|
||||||
<n-tabs
|
<n-tabs
|
||||||
v-model:value="tabStore.activatedIndex"
|
v-model:value="tabStore.activatedIndex"
|
||||||
:closable="true"
|
:closable="true"
|
||||||
|
@ -130,7 +139,12 @@ const onCloseTab = (tabIndex) => {
|
||||||
|
|
||||||
<div v-if="showServerStatus" class="content-container flex-item-expand flex-box-v">
|
<div v-if="showServerStatus" class="content-container flex-item-expand flex-box-v">
|
||||||
<!-- select nothing or select server node, display server status -->
|
<!-- select nothing or select server node, display server status -->
|
||||||
<content-server-status v-model:auto-refresh="autoRefresh" :server="serverName" :info="serverInfo" />
|
<content-server-status
|
||||||
|
v-model:auto-refresh="autoRefresh"
|
||||||
|
:server="serverName"
|
||||||
|
:info="serverInfo"
|
||||||
|
@refresh="refreshInfo"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="showNonexists" class="content-container flex-item-expand flex-box-v">
|
<div v-else-if="showNonexists" class="content-container flex-item-expand flex-box-v">
|
||||||
<n-empty :description="$t('nonexist_tab_content')" class="empty-content">
|
<n-empty :description="$t('nonexist_tab_content')" class="empty-content">
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import AddLink from '../icons/AddLink.vue'
|
import AddLink from '../icons/AddLink.vue'
|
||||||
import { useDialog } from 'naive-ui'
|
import useDialogStore from '../../stores/dialog.js'
|
||||||
|
|
||||||
const dialogStore = useDialog()
|
const dialogStore = useDialogStore()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import Help from '../icons/Help.vue'
|
||||||
import IconButton from '../common/IconButton.vue'
|
import IconButton from '../common/IconButton.vue'
|
||||||
import Filter from '../icons/Filter.vue'
|
import Filter from '../icons/Filter.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import Refresh from '../icons/Refresh.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
server: String,
|
server: String,
|
||||||
|
@ -12,8 +13,9 @@ const props = defineProps({
|
||||||
autoRefresh: false,
|
autoRefresh: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:autoRefresh'])
|
const emit = defineEmits(['update:autoRefresh', 'refresh'])
|
||||||
|
|
||||||
|
const scrollRef = ref(null)
|
||||||
const redisVersion = computed(() => {
|
const redisVersion = computed(() => {
|
||||||
return get(props.info, 'redis_version', '')
|
return get(props.info, 'redis_version', '')
|
||||||
})
|
})
|
||||||
|
@ -67,7 +69,6 @@ const totalKeys = computed(() => {
|
||||||
})
|
})
|
||||||
return sum(toArray(nums))
|
return sum(toArray(nums))
|
||||||
})
|
})
|
||||||
|
|
||||||
const infoList = computed(() => map(props.info, (value, key) => ({ value, key })))
|
const infoList = computed(() => map(props.info, (value, key) => ({ value, key })))
|
||||||
|
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
|
@ -92,9 +93,10 @@ const onFilterInfo = (val) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-scrollbar>
|
<n-scrollbar ref="scrollRef">
|
||||||
|
<n-back-top :listen-to="scrollRef" />
|
||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
<n-card :theme-override1s="{ paddingMedium: '10px 20px 10px' }">
|
<n-card>
|
||||||
<template #header>
|
<template #header>
|
||||||
{{ props.server }}
|
{{ props.server }}
|
||||||
<n-space inline size="small">
|
<n-space inline size="small">
|
||||||
|
@ -104,9 +106,19 @@ const onFilterInfo = (val) => {
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-space inline size="small">
|
<n-space inline align="center">
|
||||||
{{ $t('auto_refresh') }}
|
{{ $t('auto_refresh') }}
|
||||||
<n-switch :value="props.autoRefresh" @update:value="(v) => emit('update:autoRefresh', v)" />
|
<n-switch :value="props.autoRefresh" @update:value="(v) => emit('update:autoRefresh', v)" />
|
||||||
|
<n-tooltip>
|
||||||
|
{{ $t('refresh') }}
|
||||||
|
<template #trigger>
|
||||||
|
<n-button tertiary circle size="small" @click="emit('refresh')">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon :component="Refresh" />
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
</n-tooltip>
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
<n-grid x-gap="5" style="min-width: 500px">
|
<n-grid x-gap="5" style="min-width: 500px">
|
||||||
|
@ -138,7 +150,7 @@ const onFilterInfo = (val) => {
|
||||||
</n-card>
|
</n-card>
|
||||||
<n-card :title="$t('all_info')">
|
<n-card :title="$t('all_info')">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-input v-model:value="infoFilter" @update:value="onFilterInfo" placeholder="">
|
<n-input v-model:value="infoFilter" @update:value="onFilterInfo" placeholder="" clearable>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<icon-button :icon="Filter" size="18" />
|
<icon-button :icon="Filter" size="18" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
"lang_name": "English",
|
"lang_name": "English",
|
||||||
"launching": "Launching...",
|
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"success": "Success",
|
"success": "Success",
|
||||||
|
@ -134,6 +133,7 @@
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
"check_update": "Check for Updates...",
|
"check_update": "Check for Updates...",
|
||||||
"auto_refresh": "Auto Refresh",
|
"auto_refresh": "Auto Refresh",
|
||||||
|
"refresh": "Refresh",
|
||||||
"uptime": "Uptime",
|
"uptime": "Uptime",
|
||||||
"connected_clients": "Clients",
|
"connected_clients": "Clients",
|
||||||
"total_keys": "Keys",
|
"total_keys": "Keys",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
"lang_name": "简体中文",
|
"lang_name": "简体中文",
|
||||||
"launching": "启动中...",
|
|
||||||
"confirm": "确认",
|
"confirm": "确认",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"success": "成功",
|
"success": "成功",
|
||||||
|
@ -137,6 +136,7 @@
|
||||||
"help": "帮助",
|
"help": "帮助",
|
||||||
"check_update": "检查更新...",
|
"check_update": "检查更新...",
|
||||||
"auto_refresh": "自动刷新",
|
"auto_refresh": "自动刷新",
|
||||||
|
"refresh": "立即刷新",
|
||||||
"uptime": "运行时间",
|
"uptime": "运行时间",
|
||||||
"connected_clients": "已连客户端",
|
"connected_clients": "已连客户端",
|
||||||
"total_keys": "键总数",
|
"total_keys": "键总数",
|
||||||
|
|
|
@ -299,6 +299,10 @@ const useConnectionStore = defineStore('connections', {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dbs = this.databases[name]
|
||||||
|
for (const db of dbs) {
|
||||||
|
this.nodeMap[`${db.name}#${db.db}`]?.clear()
|
||||||
|
}
|
||||||
delete this.databases[name]
|
delete this.databases[name]
|
||||||
delete this.serverStats[name]
|
delete this.serverStats[name]
|
||||||
|
|
||||||
|
@ -317,6 +321,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.databases = {}
|
this.databases = {}
|
||||||
|
this.serverStats = {}
|
||||||
const tabStore = useTabStore()
|
const tabStore = useTabStore()
|
||||||
tabStore.removeAllTab()
|
tabStore.removeAllTab()
|
||||||
},
|
},
|
||||||
|
@ -419,7 +424,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
dbs[db].children = undefined
|
dbs[db].children = undefined
|
||||||
dbs[db].isLeaf = false
|
dbs[db].isLeaf = false
|
||||||
|
|
||||||
delete this.nodeMap[`${connName}#${db}`]
|
this.nodeMap[`${connName}#${db}`]?.clear()
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -564,10 +569,9 @@ const useConnectionStore = defineStore('connections', {
|
||||||
if (this.nodeMap[`${connName}#${db}`] == null) {
|
if (this.nodeMap[`${connName}#${db}`] == null) {
|
||||||
this.nodeMap[`${connName}#${db}`] = new Map()
|
this.nodeMap[`${connName}#${db}`] = new Map()
|
||||||
}
|
}
|
||||||
// construct tree node list, the format of item key likes 'server/db#type/key'
|
// construct a tree node list, the format of item key likes 'server/db#type/key'
|
||||||
const nodeMap = this.nodeMap[`${connName}#${db}`]
|
const nodeMap = this.nodeMap[`${connName}#${db}`]
|
||||||
const rootChildren = dbs[db].children
|
const rootChildren = dbs[db].children
|
||||||
let count = 0
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
const keyPart = split(key, separator)
|
const keyPart = split(key, separator)
|
||||||
// const prefixLen = size(keyPart) - 1
|
// const prefixLen = size(keyPart) - 1
|
||||||
|
|
Loading…
Reference in New Issue