refactor: move checked keys mark from tree view to tab store

fix: deleting message may not disappear #102

fix: some error in check mode
This commit is contained in:
Lykin 2023-12-13 11:48:27 +08:00
parent f7f394972d
commit 08c42ca85c
4 changed files with 98 additions and 44 deletions

View File

@ -4,7 +4,7 @@ import BrowserTree from './BrowserTree.vue'
import IconButton from '@/components/common/IconButton.vue' import IconButton from '@/components/common/IconButton.vue'
import useTabStore from 'stores/tab.js' import useTabStore from 'stores/tab.js'
import { computed, nextTick, onMounted, reactive, ref, unref } from 'vue' import { computed, nextTick, onMounted, reactive, ref, unref } from 'vue'
import { find, map } from 'lodash' import { find, map, size } from 'lodash'
import Refresh from '@/components/icons/Refresh.vue' import Refresh from '@/components/icons/Refresh.vue'
import useDialogStore from 'stores/dialog.js' import useDialogStore from 'stores/dialog.js'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@ -43,7 +43,6 @@ const browserTreeRef = ref(null)
const loading = ref(false) const loading = ref(false)
const fullyLoaded = ref(false) const fullyLoaded = ref(false)
const inCheckState = ref(false) const inCheckState = ref(false)
const checkedCount = ref(0)
const dbSelectOptions = computed(() => { const dbSelectOptions = computed(() => {
const dblist = browserStore.getDBList(props.server) const dblist = browserStore.getDBList(props.server)
@ -80,10 +79,14 @@ const loadProgress = computed(() => {
return (db.keys * 100) / Math.max(db.keys, db.maxKeys) return (db.keys * 100) / Math.max(db.keys, db.maxKeys)
}) })
const checkedCount = computed(() => {
return size(tabStore.getCheckedKeys(props.server))
})
const checkedTip = computed(() => { const checkedTip = computed(() => {
const dblist = browserStore.getDBList(props.server) const dblist = browserStore.getDBList(props.server)
const db = find(dblist, { db: props.db }) const db = find(dblist, { db: props.db })
return `${checkedCount.value} / ${db.maxKeys}` return `${checkedCount.value} / ${Math.max(db.maxKeys, checkedCount.value)}`
}) })
const onReload = async () => { const onReload = async () => {
@ -267,7 +270,6 @@ onMounted(() => onReload())
<!-- tree view --> <!-- tree view -->
<browser-tree <browser-tree
ref="browserTreeRef" ref="browserTreeRef"
v-model:checked-count="checkedCount"
:check-mode="inCheckState" :check-mode="inCheckState"
:db="props.db" :db="props.db"
:full-loaded="fullyLoaded" :full-loaded="fullyLoaded"

View File

@ -35,19 +35,12 @@ const props = defineProps({
pattern: String, pattern: String,
fullLoaded: Boolean, fullLoaded: Boolean,
checkMode: Boolean, checkMode: Boolean,
checkedCount: Number,
}) })
const emit = defineEmits(['update:checked-count'])
const themeVars = useThemeVars() const themeVars = useThemeVars()
const render = useRender() const render = useRender()
const i18n = useI18n() const i18n = useI18n()
const expandedKeys = ref([]) const expandedKeys = ref([])
const checkedKeys = reactive({
keys: [],
redisKeys: [],
})
const connectionStore = useConnectionStore() const connectionStore = useConnectionStore()
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const prefStore = usePreferencesStore() const prefStore = usePreferencesStore()
@ -57,9 +50,8 @@ const dialogStore = useDialogStore()
watchEffect( watchEffect(
() => { () => {
if (!props.checkMode) { if (!props.checkMode) {
resetCheckedKey() tabStore.setCheckedKeys(props.server)
} }
emit('update:checked-count', size(checkedKeys.keys))
}, },
{ flush: 'post' }, { flush: 'post' },
) )
@ -76,6 +68,19 @@ const selectedKeys = computed(() => {
return [] return []
}) })
/**
*
* @type {ComputedRef<string[]>}
*/
const checkedKeys = computed(() => {
const tab = find(tabStore.tabList, { name: props.server })
if (tab != null) {
const checkedKeys = get(tab, 'checkedKeys', [])
return map(checkedKeys, 'key')
}
return []
})
const data = computed(() => { const data = computed(() => {
// const dbs = get(browserStore.databases, props.server, []) // const dbs = get(browserStore.databases, props.server, [])
// return dbs // return dbs
@ -193,11 +198,6 @@ const resetExpandKey = (server, db, includeDB) => {
}) })
} }
const resetCheckedKey = () => {
checkedKeys.keys = []
checkedKeys.redisKeys = []
}
const handleSelectContextMenu = (key) => { const handleSelectContextMenu = (key) => {
contextMenuParam.show = false contextMenuParam.show = false
const selectedKey = get(selectedKeys.value, 0) const selectedKey = get(selectedKeys.value, 0)
@ -333,11 +333,11 @@ const onUpdateExpanded = (value, option, meta) => {
* @param {TreeOption[]} options * @param {TreeOption[]} options
*/ */
const onUpdateCheckedKeys = (keys, options) => { const onUpdateCheckedKeys = (keys, options) => {
checkedKeys.keys = keys const checkedKeys = map(
checkedKeys.redisKeys = map(
filter(options, (o) => o.type === ConnectionType.RedisValue), filter(options, (o) => o.type === ConnectionType.RedisValue),
(o) => o.redisKeyCode || o.redisKey, (o) => ({ key: o.key, redisKey: o.redisKeyCode || o.redisKey }),
) )
tabStore.setCheckedKeys(props.server, checkedKeys)
} }
const renderPrefix = ({ option }) => { const renderPrefix = ({ option }) => {
@ -510,7 +510,10 @@ const calcValueMenu = () => {
// render menu function icon // render menu function icon
const renderSuffix = ({ option }) => { const renderSuffix = ({ option }) => {
if ((option.type === ConnectionType.RedisDB && option.opened) || includes(selectedKeys.value, option.key)) { if (
(option.type === ConnectionType.RedisDB && option.opened) ||
(includes(selectedKeys.value, option.key) && !props.checkMode)
) {
switch (option.type) { switch (option.type) {
case ConnectionType.RedisDB: case ConnectionType.RedisDB:
return renderIconMenu(calcDBMenu(option.opened, option.loading, option.fullLoaded)) return renderIconMenu(calcDBMenu(option.opened, option.loading, option.fullLoaded))
@ -568,11 +571,13 @@ defineExpose({
refreshTree: () => { refreshTree: () => {
treeKey.value = Date.now() treeKey.value = Date.now()
expandedKeys.value = [] expandedKeys.value = []
resetCheckedKey() tabStore.setCheckedKeys(props.server)
}, },
deleteCheckedItems: () => { deleteCheckedItems: () => {
if (!isEmpty(checkedKeys.redisKeys)) { const checkedKeys = tabStore.currentCheckedKeys
dialogStore.openDeleteKeyDialog(props.server, props.db, checkedKeys.redisKeys) const redisKeys = map(checkedKeys, 'redisKey')
if (!isEmpty(redisKeys)) {
dialogStore.openDeleteKeyDialog(props.server, props.db, redisKeys)
} }
}, },
}) })
@ -591,7 +596,7 @@ defineExpose({
:cancelable="false" :cancelable="false"
:cascade="true" :cascade="true"
:checkable="props.checkMode" :checkable="props.checkMode"
:checked-keys="checkedKeys.keys" :checked-keys="checkedKeys"
:data="data" :data="data"
:expand-on-click="false" :expand-on-click="false"
:expanded-keys="expandedKeys" :expanded-keys="expandedKeys"

View File

@ -1875,11 +1875,12 @@ const useBrowserStore = defineStore('browser', {
* @return {Promise<void>} * @return {Promise<void>}
*/ */
async deleteKeys(server, db, keys) { async deleteKeys(server, db, keys) {
const delMsgRef = $message.loading('', { duration: 0 }) const delMsgRef = $message.loading('', { duration: 0, closable: true })
let progress = 0 let progress = 0
let count = size(keys) let count = size(keys)
let deletedCount = 0, let deletedCount = 0
failCount = 0 let failCount = 0
try {
for (const key of keys) { for (const key of keys) {
delMsgRef.content = i18nGlobal.t('dialogue.deleting_key', { delMsgRef.content = i18nGlobal.t('dialogue.deleting_key', {
key: decodeRedisKey(key), key: decodeRedisKey(key),
@ -1894,7 +1895,12 @@ const useBrowserStore = defineStore('browser', {
failCount += 1 failCount += 1
} }
} }
} finally {
delMsgRef.destroy() delMsgRef.destroy()
// clear checked keys
const tab = useTabStore()
tab.setCheckedKeys(server)
}
// refresh model data // refresh model data
this._tidyNode(server, db, '', true) this._tidyNode(server, db, '', true)
this._updateDBMaxKeys(server, db, -deletedCount) this._updateDBMaxKeys(server, db, -deletedCount)

View File

@ -10,7 +10,7 @@ const useTabStore = defineStore('tab', {
* @property {string} [title] tab title * @property {string} [title] tab title
* @property {string} [icon] tab icon * @property {string} [icon] tab icon
* @property {string[]} selectedKeys * @property {string[]} selectedKeys
* @property {string[]} checkdeKeys * @property {CheckedKey[]} checkedKeys
* @property {string} [type] key type * @property {string} [type] key type
* @property {*} [value] key value * @property {*} [value] key value
* @property {string} [server] server name * @property {string} [server] server name
@ -27,6 +27,12 @@ const useTabStore = defineStore('tab', {
* @param {boolean} [loading] * @param {boolean} [loading]
*/ */
/**
* @typedef {Object} CheckedKey
* @property {string[]} key
* @property {string[]} redisKey
*/
/** /**
* @typedef {Object} ListEntryItem * @typedef {Object} ListEntryItem
* @property {string|number[]} v value * @property {string|number[]} v value
@ -124,9 +130,14 @@ const useTabStore = defineStore('tab', {
}, },
currentSelectedKeys() { currentSelectedKeys() {
const tab = this.currentTab() const tab = this.currentTab
return get(tab, 'selectedKeys', []) return get(tab, 'selectedKeys', [])
}, },
currentCheckedKeys() {
const tab = this.currentTab
return get(tab, 'checkedKeys', [])
},
}, },
actions: { actions: {
/** /**
@ -660,6 +671,36 @@ const useTabStore = defineStore('tab', {
} }
} }
}, },
/**
* get checked keys
* @param server
* @returns {CheckedKey[]}
*/
getCheckedKeys(server) {
let tab = find(this.tabList, { name: server })
if (tab != null) {
return tab.checkedKeys || []
}
return []
},
/**
* set checked keys in current display browser tree
* @param {string} server
* @param {CheckedKey[]} [keys]
*/
setCheckedKeys(server, keys) {
let tab = find(this.tabList, { name: server })
if (tab != null) {
if (isEmpty(keys)) {
// select nothing
tab.checkedKeys = []
} else {
tab.checkedKeys = keys
}
}
},
}, },
}) })