diff --git a/frontend/src/components/sidebar/BrowserPane.vue b/frontend/src/components/sidebar/BrowserPane.vue index 80530b2..4e992bb 100644 --- a/frontend/src/components/sidebar/BrowserPane.vue +++ b/frontend/src/components/sidebar/BrowserPane.vue @@ -104,7 +104,6 @@ const onReload = async () => { tabStore.setSelectedKeys(props.server) const db = props.db browserStore.closeDatabase(props.server, db) - // browserTreeRef.value?.resetExpandKey(props.server, db) let matchType = unref(filterForm.type) if (!types.hasOwnProperty(matchType)) { @@ -200,7 +199,6 @@ const handleSelectDB = async (db) => { await nextTick() await connectionStore.saveLastDB(props.server, db) tabStore.upsertTab({ server: props.server, db, clearValue: true }) - // browserTreeRef.value?.resetExpandKey(props.server, db) fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db) browserTreeRef.value?.refreshTree() tabStore.setSelectedKeys(props.server) diff --git a/frontend/src/components/sidebar/BrowserTree.vue b/frontend/src/components/sidebar/BrowserTree.vue index 4c8821a..d07e383 100644 --- a/frontend/src/components/sidebar/BrowserTree.vue +++ b/frontend/src/components/sidebar/BrowserTree.vue @@ -5,7 +5,7 @@ import { NIcon, NSpace, useThemeVars } from 'naive-ui' import Key from '@/components/icons/Key.vue' import Binary from '@/components/icons/Binary.vue' import Database from '@/components/icons/Database.vue' -import { filter, find, get, includes, indexOf, isEmpty, map, remove, size, startsWith, toUpper } from 'lodash' +import { filter, find, get, includes, isEmpty, map, size, toUpper } from 'lodash' import { useI18n } from 'vue-i18n' import Refresh from '@/components/icons/Refresh.vue' import CopyLink from '@/components/icons/CopyLink.vue' @@ -40,14 +40,24 @@ const props = defineProps({ const themeVars = useThemeVars() const render = useRender() const i18n = useI18n() -/** @type {Ref>} */ -const expandedKeys = ref([]) const connectionStore = useConnectionStore() const browserStore = useBrowserStore() const prefStore = usePreferencesStore() const tabStore = useTabStore() const dialogStore = useDialogStore() +/** + * + * @type {ComputedRef} + */ +const expandedKeys = computed(() => { + const tab = find(tabStore.tabList, { name: props.server }) + if (tab != null) { + return get(tab, 'expandedKeys', []) + } + return [] +}) + /** * * @type {ComputedRef} @@ -168,31 +178,6 @@ const renderContextLabel = (option) => { return h('div', { class: 'context-menu-item' }, option.label) } -/** - * - * @param {string} key - * @param {boolean} [toggle] - */ -const expandKey = (key, toggle) => { - const idx = indexOf(expandedKeys.value, key) - if (idx === -1) { - expandedKeys.value.push(key) - } else if (toggle !== false) { - expandedKeys.value.splice(idx, 1) - } -} - -const resetExpandKey = (server, db, includeDB) => { - const prefix = `${server}/db${db}` - remove(expandedKeys.value, (k) => { - if (!!!includeDB) { - return k !== prefix && startsWith(k, prefix) - } else { - return startsWith(k, prefix) - } - }) -} - const handleSelectContextMenu = (key) => { contextMenuParam.show = false const selectedKey = get(selectedKeys.value, 0) @@ -298,7 +283,7 @@ const onUpdateSelectedKeys = (keys, options) => { } const onUpdateExpanded = (value, option, meta) => { - expandedKeys.value = value + tabStore.setExpandedKeys(props.server, value) if (!meta.node) { return } @@ -310,13 +295,13 @@ const onUpdateExpanded = (value, option, meta) => { switch (meta.action) { case 'expand': node.expanded = true - if (!includes(expandedKeys.value, key)) { - expandedKeys.value.push(key) + if (!includes(value, key)) { + tabStore.addExpandedKey(props.server, key) } break case 'collapse': node.expanded = false - remove(expandedKeys.value, (v) => v === key) + tabStore.removeExpandedKey(props.server, key) break } node = node.children[0] @@ -525,8 +510,8 @@ const nodeProps = ({ option }) => { return } if (!props.checkMode) { - // default handle is expand current node - nextTick().then(() => expandKey(option.key)) + // default handle is toggle expand current node + nextTick().then(() => tabStore.toggleExpandKey(props.server, option.key)) } }, onContextmenu(e) { @@ -558,7 +543,7 @@ watchEffect( if (!props.checkMode) { tabStore.setCheckedKeys(props.server) } else { - expandKey(`${ConnectionType.RedisDB}`, false) + tabStore.addExpandedKey(props.server, `${ConnectionType.RedisDB}`) } }, { flush: 'post' }, @@ -569,10 +554,9 @@ watchEffect( const treeKey = ref(0) defineExpose({ handleSelectContextMenu, - resetExpandKey, refreshTree: () => { treeKey.value = Date.now() - expandedKeys.value = [] + tabStore.setExpandedKeys(props.server) tabStore.setCheckedKeys(props.server) }, deleteCheckedItems: () => { diff --git a/frontend/src/objects/tabItem.js b/frontend/src/objects/tabItem.js index 78bbe40..308d2f3 100644 --- a/frontend/src/objects/tabItem.js +++ b/frontend/src/objects/tabItem.js @@ -16,6 +16,7 @@ export class TabItem { * @param {string} subTab secondary tab value * @param {string} [title] tab title * @param {string} [icon] tab icon + * @param {string[]} expandedKeys * @param {string[]} selectedKeys * @param {CheckedKey[]} checkedKeys * @param {string} [type] key type @@ -39,8 +40,9 @@ export class TabItem { blank, subTab, icon, - selectedKeys, - checkedKeys, + expandedKeys = [], + selectedKeys = [], + checkedKeys = [], type, value, server, @@ -61,6 +63,7 @@ export class TabItem { this.blank = blank this.subTab = subTab this.icon = icon + this.expandedKeys = expandedKeys this.selectedKeys = selectedKeys this.checkedKeys = checkedKeys this.type = type diff --git a/frontend/src/stores/browser.js b/frontend/src/stores/browser.js index 631fe01..3b57956 100644 --- a/frontend/src/stores/browser.js +++ b/frontend/src/stores/browser.js @@ -1806,6 +1806,7 @@ const useBrowserStore = defineStore('browser', { tab.emptyTab(server) tab.setSelectedKeys(server) tab.setCheckedKeys(server) + tab.setExpandedKeys(server) return true } } finally { diff --git a/frontend/src/stores/tab.js b/frontend/src/stores/tab.js index 19ad166..6f5b686 100644 --- a/frontend/src/stores/tab.js +++ b/frontend/src/stores/tab.js @@ -1,4 +1,4 @@ -import { assign, find, findIndex, get, isEmpty, pullAt, remove, set, size } from 'lodash' +import { assign, find, findIndex, get, indexOf, isEmpty, pullAt, remove, set, size } from 'lodash' import { defineStore } from 'pinia' import { TabItem } from '@/objects/tabItem.js' import { decodeRedisKey } from '@/utils/key_convert.js' @@ -638,11 +638,73 @@ const useTabStore = defineStore('tab', { }, /** - * set selected keys in current display browser tree + * set expanded keys for server + * @param {string} server + * @param {string[]} keys + */ + setExpandedKeys(server, keys = []) { + /** @type TabItem**/ + let tab = find(this.tabList, { name: server }) + if (tab != null) { + if (isEmpty(keys)) { + tab.expandedKeys = [] + } else { + tab.expandedKeys = keys + } + } + }, + + /** + * + * @param {string} server + * @param {string} key + */ + addExpandedKey(server, key) { + /** @type TabItem**/ + let tab = find(this.tabList, { name: server }) + if (tab != null) { + tab.expandedKeys.push(key) + } + }, + + /** + * + * @param {string} server + * @param {string} key + */ + toggleExpandKey(server, key) { + /** @type TabItem**/ + let tab = find(this.tabList, { name: server }) + if (tab != null) { + const idx = indexOf(tab.expandedKeys, key) + if (idx === -1) { + tab.expandedKeys.push(key) + } else { + tab.expandedKeys.splice(idx, 1) + } + } + }, + + /** + * + * @param {string} server + * @param {string} key + */ + removeExpandedKey(server, key) { + /** @type TabItem**/ + let tab = find(this.tabList, { name: server }) + if (tab != null) { + remove(tab.expandedKeys, (v) => v === key) + } + }, + + /** + * set selected keys for server * @param {string} server * @param {string|string[]} [keys] */ setSelectedKeys(server, keys = null) { + /** @type TabItem**/ let tab = find(this.tabList, { name: server }) if (tab != null) { if (keys == null) { @@ -662,6 +724,7 @@ const useTabStore = defineStore('tab', { * @returns {CheckedKey[]} */ getCheckedKeys(server) { + /** @type TabItem**/ let tab = find(this.tabList, { name: server }) if (tab != null) { return tab.checkedKeys || [] @@ -670,11 +733,12 @@ const useTabStore = defineStore('tab', { }, /** - * set checked keys in current display browser tree + * set checked keys for server * @param {string} server * @param {CheckedKey[]} [keys] */ setCheckedKeys(server, keys = null) { + /** @type TabItem**/ let tab = find(this.tabList, { name: server }) if (tab != null) { if (isEmpty(keys)) {