feat: add key type filter setting
perf: add closing connection status in edit connection dialog
This commit is contained in:
parent
41e5ecfad2
commit
c4f1a2e178
|
@ -347,24 +347,30 @@ func (c *connectionService) ServerInfo(name string) (resp types.JSResp) {
|
||||||
|
|
||||||
// OpenDatabase open select database, and list all keys
|
// OpenDatabase open select database, and list all keys
|
||||||
// @param path contain connection name and db name
|
// @param path contain connection name and db name
|
||||||
func (c *connectionService) OpenDatabase(connName string, db int, match string) (resp types.JSResp) {
|
func (c *connectionService) OpenDatabase(connName string, db int, match string, keyType string) (resp types.JSResp) {
|
||||||
return c.ScanKeys(connName, db, match)
|
return c.ScanKeys(connName, db, match, keyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScanKeys scan all keys
|
// ScanKeys scan all keys
|
||||||
func (c *connectionService) ScanKeys(connName string, db int, match string) (resp types.JSResp) {
|
func (c *connectionService) ScanKeys(connName string, db int, match, keyType string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filterType := len(keyType) > 0
|
||||||
|
|
||||||
var keys []string
|
var keys []string
|
||||||
//keys := map[string]keyItem{}
|
//keys := map[string]keyItem{}
|
||||||
var cursor uint64
|
var cursor uint64
|
||||||
for {
|
for {
|
||||||
var loadedKey []string
|
var loadedKey []string
|
||||||
loadedKey, cursor, err = rdb.Scan(ctx, cursor, match, 10000).Result()
|
if filterType {
|
||||||
|
loadedKey, cursor, err = rdb.ScanType(ctx, cursor, match, 10000, keyType).Result()
|
||||||
|
} else {
|
||||||
|
loadedKey, cursor, err = rdb.Scan(ctx, cursor, match, 10000).Result()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { types, validType } from '../../consts/support_redis_type.js'
|
import { typesColor, validType } from '../../consts/support_redis_type.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
|
@ -12,30 +12,22 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: 'white',
|
||||||
},
|
},
|
||||||
size: String,
|
size: String,
|
||||||
})
|
})
|
||||||
|
|
||||||
const color = {
|
|
||||||
[types.STRING]: '#626aef',
|
|
||||||
[types.HASH]: '#576bfa',
|
|
||||||
[types.LIST]: '#34b285',
|
|
||||||
[types.SET]: '#bb7d52',
|
|
||||||
[types.ZSET]: '#d053a5',
|
|
||||||
}
|
|
||||||
|
|
||||||
const backgroundColor = computed(() => {
|
const backgroundColor = computed(() => {
|
||||||
return color[props.type]
|
return typesColor[props.type]
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-tag
|
<n-tag
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
:color="{ color: backgroundColor, textColor: 'white' }"
|
:color="{ color: backgroundColor, textColor: props.color }"
|
||||||
:size="props.size"
|
:size="props.size"
|
||||||
class="redis-type-tag"
|
:class="[props.size === 'small' ? 'redis-type-tag-small' : 'redis-type-tag']"
|
||||||
strong
|
strong
|
||||||
>
|
>
|
||||||
{{ props.type }}
|
{{ props.type }}
|
||||||
|
@ -47,4 +39,8 @@ const backgroundColor = computed(() => {
|
||||||
.redis-type-tag {
|
.redis-type-tag {
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.redis-type-tag-small {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -24,7 +24,7 @@ const props = defineProps({
|
||||||
|
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const dialogStore = useDialogStore()
|
const dialogStore = useDialogStore()
|
||||||
const keyType = redisTypes.LIST
|
const keyType = redisTypes.SET
|
||||||
const currentEditRow = ref({
|
const currentEditRow = ref({
|
||||||
no: 0,
|
no: 0,
|
||||||
value: null,
|
value: null,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import Close from '../icons/Close.vue'
|
||||||
import useConnectionStore from '../../stores/connections.js'
|
import useConnectionStore from '../../stores/connections.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for create or edit connection
|
* Dialog for new or edit connection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const dialogStore = useDialog()
|
const dialogStore = useDialog()
|
||||||
|
@ -29,6 +29,12 @@ const generalFormRules = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const isEditMode = computed(() => !isEmpty(editName.value))
|
const isEditMode = computed(() => !isEmpty(editName.value))
|
||||||
|
const closingConnection = computed(() => {
|
||||||
|
if (isEmpty(editName.value)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return connectionStore.isConnected(editName.value)
|
||||||
|
})
|
||||||
|
|
||||||
const groupOptions = computed(() => {
|
const groupOptions = computed(() => {
|
||||||
const options = map(connectionStore.groups, (group) => ({
|
const options = map(connectionStore.groups, (group) => ({
|
||||||
|
@ -152,108 +158,120 @@ const onClose = () => {
|
||||||
preset="dialog"
|
preset="dialog"
|
||||||
transform-origin="center"
|
transform-origin="center"
|
||||||
>
|
>
|
||||||
<n-tabs v-model:value="tab" type="line" animated>
|
<n-spin :show="closingConnection">
|
||||||
<n-tab-pane :tab="$t('general')" display-directive="show" name="general">
|
<n-tabs v-model:value="tab" type="line" animated>
|
||||||
<n-form
|
<n-tab-pane :tab="$t('general')" display-directive="show" name="general">
|
||||||
ref="generalFormRef"
|
<n-form
|
||||||
:label-width="formLabelWidth"
|
ref="generalFormRef"
|
||||||
:model="generalForm"
|
:label-width="formLabelWidth"
|
||||||
:rules="generalFormRules()"
|
:model="generalForm"
|
||||||
:show-require-mark="false"
|
:rules="generalFormRules()"
|
||||||
label-align="right"
|
:show-require-mark="false"
|
||||||
label-placement="left"
|
label-align="right"
|
||||||
>
|
label-placement="left"
|
||||||
<n-form-item :label="$t('conn_name')" path="name" required>
|
>
|
||||||
<n-input v-model:value="generalForm.name" :placeholder="$t('conn_name_tip')" />
|
<n-form-item :label="$t('conn_name')" path="name" required>
|
||||||
</n-form-item>
|
<n-input v-model:value="generalForm.name" :placeholder="$t('conn_name_tip')" />
|
||||||
<n-form-item v-if="!isEditMode" :label="$t('conn_group')" required>
|
</n-form-item>
|
||||||
<n-select v-model:value="generalForm.group" :options="groupOptions" />
|
<n-form-item v-if="!isEditMode" :label="$t('conn_group')" required>
|
||||||
</n-form-item>
|
<n-select v-model:value="generalForm.group" :options="groupOptions" />
|
||||||
<n-form-item :label="$t('conn_addr')" path="addr" required>
|
</n-form-item>
|
||||||
<n-input v-model:value="generalForm.addr" :placeholder="$t('conn_addr_tip')" />
|
<n-form-item :label="$t('conn_addr')" path="addr" required>
|
||||||
<n-text style="width: 40px; text-align: center">:</n-text>
|
<n-input v-model:value="generalForm.addr" :placeholder="$t('conn_addr_tip')" />
|
||||||
<n-input-number v-model:value="generalForm.port" :max="65535" :min="1" style="width: 200px" />
|
<n-text style="width: 40px; text-align: center">:</n-text>
|
||||||
</n-form-item>
|
<n-input-number
|
||||||
<n-form-item :label="$t('conn_pwd')" path="password">
|
v-model:value="generalForm.port"
|
||||||
<n-input
|
:max="65535"
|
||||||
v-model:value="generalForm.password"
|
:min="1"
|
||||||
:placeholder="$t('conn_pwd_tip')"
|
style="width: 200px"
|
||||||
show-password-on="click"
|
/>
|
||||||
type="password"
|
</n-form-item>
|
||||||
/>
|
<n-form-item :label="$t('conn_pwd')" path="password">
|
||||||
</n-form-item>
|
<n-input
|
||||||
<n-form-item :label="$t('conn_usr')" path="username">
|
v-model:value="generalForm.password"
|
||||||
<n-input v-model="generalForm.username" :placeholder="$t('conn_usr_tip')" />
|
:placeholder="$t('conn_pwd_tip')"
|
||||||
</n-form-item>
|
show-password-on="click"
|
||||||
</n-form>
|
type="password"
|
||||||
</n-tab-pane>
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('conn_usr')" path="username">
|
||||||
|
<n-input v-model="generalForm.username" :placeholder="$t('conn_usr_tip')" />
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</n-tab-pane>
|
||||||
|
|
||||||
<n-tab-pane :tab="$t('advanced')" display-directive="show" name="advanced">
|
<n-tab-pane :tab="$t('advanced')" display-directive="show" name="advanced">
|
||||||
<n-form
|
<n-form
|
||||||
ref="advanceFormRef"
|
ref="advanceFormRef"
|
||||||
:label-width="formLabelWidth"
|
:label-width="formLabelWidth"
|
||||||
:model="generalForm"
|
:model="generalForm"
|
||||||
:rules="generalFormRules()"
|
:rules="generalFormRules()"
|
||||||
:show-require-mark="false"
|
:show-require-mark="false"
|
||||||
label-align="right"
|
label-align="right"
|
||||||
label-placement="left"
|
label-placement="left"
|
||||||
>
|
>
|
||||||
<n-form-item :label="$t('conn_advn_filter')" path="defaultFilter">
|
<n-form-item :label="$t('conn_advn_filter')" path="defaultFilter">
|
||||||
<n-input v-model:value="generalForm.defaultFilter" :placeholder="$t('conn_advn_filter_tip')" />
|
<n-input
|
||||||
</n-form-item>
|
v-model:value="generalForm.defaultFilter"
|
||||||
<n-form-item :label="$t('conn_advn_separator')" path="keySeparator">
|
:placeholder="$t('conn_advn_filter_tip')"
|
||||||
<n-input
|
/>
|
||||||
v-model:value="generalForm.keySeparator"
|
</n-form-item>
|
||||||
:placeholder="$t('conn_advn_separator_tip')"
|
<n-form-item :label="$t('conn_advn_separator')" path="keySeparator">
|
||||||
/>
|
<n-input
|
||||||
</n-form-item>
|
v-model:value="generalForm.keySeparator"
|
||||||
<n-form-item :label="$t('conn_advn_conn_timeout')" path="connTimeout">
|
:placeholder="$t('conn_advn_separator_tip')"
|
||||||
<n-input-number v-model:value="generalForm.connTimeout" :max="999999" :min="1">
|
/>
|
||||||
<template #suffix>
|
</n-form-item>
|
||||||
{{ $t('second') }}
|
<n-form-item :label="$t('conn_advn_conn_timeout')" path="connTimeout">
|
||||||
</template>
|
<n-input-number v-model:value="generalForm.connTimeout" :max="999999" :min="1">
|
||||||
</n-input-number>
|
<template #suffix>
|
||||||
</n-form-item>
|
{{ $t('second') }}
|
||||||
<n-form-item :label="$t('conn_advn_exec_timeout')" path="execTimeout">
|
</template>
|
||||||
<n-input-number v-model:value="generalForm.execTimeout" :max="999999" :min="1">
|
</n-input-number>
|
||||||
<template #suffix>
|
</n-form-item>
|
||||||
{{ $t('second') }}
|
<n-form-item :label="$t('conn_advn_exec_timeout')" path="execTimeout">
|
||||||
</template>
|
<n-input-number v-model:value="generalForm.execTimeout" :max="999999" :min="1">
|
||||||
</n-input-number>
|
<template #suffix>
|
||||||
</n-form-item>
|
{{ $t('second') }}
|
||||||
<n-form-item :label="$t('conn_advn_mark_color')" path="markColor">
|
</template>
|
||||||
<div
|
</n-input-number>
|
||||||
v-for="color in predefineColors"
|
</n-form-item>
|
||||||
:key="color"
|
<n-form-item :label="$t('conn_advn_mark_color')" path="markColor">
|
||||||
:class="{
|
<div
|
||||||
'color-preset-item_selected': generalForm.markColor === color,
|
v-for="color in predefineColors"
|
||||||
}"
|
:key="color"
|
||||||
:style="{ backgroundColor: color }"
|
:class="{
|
||||||
class="color-preset-item"
|
'color-preset-item_selected': generalForm.markColor === color,
|
||||||
@click="generalForm.markColor = color"
|
}"
|
||||||
>
|
:style="{ backgroundColor: color }"
|
||||||
<n-icon v-if="color === ''" :component="Close" size="24" />
|
class="color-preset-item"
|
||||||
</div>
|
@click="generalForm.markColor = color"
|
||||||
</n-form-item>
|
>
|
||||||
</n-form>
|
<n-icon v-if="color === ''" :component="Close" size="24" />
|
||||||
</n-tab-pane>
|
</div>
|
||||||
</n-tabs>
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</n-tab-pane>
|
||||||
|
</n-tabs>
|
||||||
|
|
||||||
<!-- test result alert-->
|
<!-- test result alert-->
|
||||||
<n-alert v-if="showTestConnSuccResult" title="" type="success">
|
<n-alert v-if="showTestConnSuccResult" title="" type="success">
|
||||||
{{ $t('conn_test_succ') }}
|
{{ $t('conn_test_succ') }}
|
||||||
</n-alert>
|
</n-alert>
|
||||||
<n-alert v-if="showTestConnFailResult" title="" type="error">
|
<n-alert v-if="showTestConnFailResult" title="" type="error">
|
||||||
{{ $t('conn_test_fail') }}: {{ testResult }}
|
{{ $t('conn_test_fail') }}: {{ testResult }}
|
||||||
</n-alert>
|
</n-alert>
|
||||||
|
</n-spin>
|
||||||
|
|
||||||
<template #action>
|
<template #action>
|
||||||
<div class="flex-item-expand">
|
<div class="flex-item-expand">
|
||||||
<n-button :loading="testing" @click="onTestConnection">{{ $t('conn_test') }}</n-button>
|
<n-button :loading="testing" :disabled="closingConnection" @click="onTestConnection">
|
||||||
|
{{ $t('conn_test') }}
|
||||||
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-item n-dialog__action">
|
<div class="flex-item n-dialog__action">
|
||||||
<n-button @click="onClose">{{ $t('cancel') }}</n-button>
|
<n-button :disabled="closingConnection" @click="onClose">{{ $t('cancel') }}</n-button>
|
||||||
<n-button type="primary" @click="onSaveConnection">
|
<n-button type="primary" :disabled="closingConnection" @click="onSaveConnection">
|
||||||
{{ isEditMode ? $t('update') : $t('confirm') }}
|
{{ isEditMode ? $t('update') : $t('confirm') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,16 +1,29 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref, watch } from 'vue'
|
import { computed, reactive, ref, watch } from 'vue'
|
||||||
import useDialog from '../../stores/dialog'
|
import useDialog from '../../stores/dialog'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import useConnectionStore from '../../stores/connections.js'
|
import useConnectionStore from '../../stores/connections.js'
|
||||||
|
import { types } from '../../consts/support_redis_type.js'
|
||||||
|
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const filterForm = reactive({
|
const filterForm = reactive({
|
||||||
server: '',
|
server: '',
|
||||||
db: 0,
|
db: 0,
|
||||||
|
type: '',
|
||||||
pattern: '',
|
pattern: '',
|
||||||
})
|
})
|
||||||
const filterFormRef = ref(null)
|
const filterFormRef = ref(null)
|
||||||
|
const typeOptions = computed(() => {
|
||||||
|
const options = Object.keys(types).map((t) => ({
|
||||||
|
value: t,
|
||||||
|
label: t,
|
||||||
|
}))
|
||||||
|
options.splice(0, 0, {
|
||||||
|
value: '',
|
||||||
|
label: i18n.t('all'),
|
||||||
|
})
|
||||||
|
return options
|
||||||
|
})
|
||||||
|
|
||||||
const formLabelWidth = '100px'
|
const formLabelWidth = '100px'
|
||||||
const dialogStore = useDialog()
|
const dialogStore = useDialog()
|
||||||
|
@ -18,9 +31,10 @@ watch(
|
||||||
() => dialogStore.keyFilterDialogVisible,
|
() => dialogStore.keyFilterDialogVisible,
|
||||||
(visible) => {
|
(visible) => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
const { server, db, pattern } = dialogStore.keyFilterParam
|
const { server, db, type, pattern } = dialogStore.keyFilterParam
|
||||||
filterForm.server = server
|
filterForm.server = server
|
||||||
filterForm.db = db || 0
|
filterForm.db = db || 0
|
||||||
|
filterForm.type = type || ''
|
||||||
filterForm.pattern = pattern || '*'
|
filterForm.pattern = pattern || '*'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +42,8 @@ watch(
|
||||||
|
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
const { server, db, pattern } = filterForm
|
const { server, db, type, pattern } = filterForm
|
||||||
connectionStore.setKeyFilter(server, db, pattern)
|
connectionStore.setKeyFilter(server, db, pattern, type)
|
||||||
connectionStore.reopenDatabase(server, db)
|
connectionStore.reopenDatabase(server, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +85,9 @@ const onClose = () => {
|
||||||
<n-form-item :label="$t('db_index')" path="db">
|
<n-form-item :label="$t('db_index')" path="db">
|
||||||
<n-text>{{ filterForm.db }}</n-text>
|
<n-text>{{ filterForm.db }}</n-text>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('type')" path="type" required>
|
||||||
|
<n-select v-model:value="filterForm.type" :options="typeOptions" />
|
||||||
|
</n-form-item>
|
||||||
<n-form-item :label="$t('filter_pattern')" required>
|
<n-form-item :label="$t('filter_pattern')" required>
|
||||||
<n-input-group>
|
<n-input-group>
|
||||||
<n-tooltip>
|
<n-tooltip>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, h, nextTick, onMounted, reactive, ref } from 'vue'
|
import { computed, h, nextTick, onMounted, reactive, ref } from 'vue'
|
||||||
import { ConnectionType } from '../../consts/connection_type.js'
|
import { ConnectionType } from '../../consts/connection_type.js'
|
||||||
import { NIcon, NTag, useDialog, useMessage } from 'naive-ui'
|
import { NIcon, NSpace, NTag, useDialog, useMessage } from 'naive-ui'
|
||||||
import Key from '../icons/Key.vue'
|
import Key from '../icons/Key.vue'
|
||||||
import ToggleDb from '../icons/ToggleDb.vue'
|
import ToggleDb from '../icons/ToggleDb.vue'
|
||||||
import { get, indexOf, isEmpty, remove } from 'lodash'
|
import { get, indexOf, isEmpty, remove } from 'lodash'
|
||||||
|
@ -20,6 +20,7 @@ import ToggleServer from '../icons/ToggleServer.vue'
|
||||||
import Unlink from '../icons/Unlink.vue'
|
import Unlink from '../icons/Unlink.vue'
|
||||||
import Filter from '../icons/Filter.vue'
|
import Filter from '../icons/Filter.vue'
|
||||||
import Close from '../icons/Close.vue'
|
import Close from '../icons/Close.vue'
|
||||||
|
import { typesColor } from '../../consts/support_redis_type.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
server: String,
|
server: String,
|
||||||
|
@ -274,27 +275,52 @@ const renderLabel = ({ option }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderSuffix = ({ option }) => {
|
const renderSuffix = ({ option }) => {
|
||||||
// return h(NButton,
|
|
||||||
// { text: true, type: 'primary' },
|
|
||||||
// { default: () => h(Key) })
|
|
||||||
if (option.type === ConnectionType.RedisDB) {
|
if (option.type === ConnectionType.RedisDB) {
|
||||||
const { name: server, db } = option
|
const { name: server, db } = option
|
||||||
const filterPattern = connectionStore.getKeyFilter(server, db)
|
let { match: matchPattern, type: typeFilter } = connectionStore.getKeyFilter(server, db)
|
||||||
if (!isEmpty(filterPattern) && filterPattern !== '*') {
|
const filterNodes = []
|
||||||
return h(
|
// type filter tag
|
||||||
NTag,
|
if (!isEmpty(typeFilter)) {
|
||||||
{
|
filterNodes.push(
|
||||||
bordered: false,
|
h(
|
||||||
closable: true,
|
NTag,
|
||||||
size: 'small',
|
{
|
||||||
onClose: () => {
|
size: 'small',
|
||||||
connectionStore.removeKeyFilter(server, db)
|
closable: true,
|
||||||
connectionStore.reopenDatabase(server, db)
|
bordered: false,
|
||||||
|
color: { color: typesColor[typeFilter], textColor: 'white' },
|
||||||
|
onClose: () => {
|
||||||
|
// remove type filter
|
||||||
|
connectionStore.setKeyFilter(server, db, matchPattern)
|
||||||
|
connectionStore.reopenDatabase(server, db)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{ default: () => typeFilter }
|
||||||
{ default: () => filterPattern }
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
// match pattern tag
|
||||||
|
if (!isEmpty(matchPattern) && matchPattern !== '*') {
|
||||||
|
filterNodes.push(
|
||||||
|
h(
|
||||||
|
NTag,
|
||||||
|
{
|
||||||
|
bordered: false,
|
||||||
|
closable: true,
|
||||||
|
size: 'small',
|
||||||
|
onClose: () => {
|
||||||
|
// remove key match pattern
|
||||||
|
connectionStore.setKeyFilter(server, db, '*', typeFilter)
|
||||||
|
connectionStore.reopenDatabase(server, db)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ default: () => matchPattern }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (filterNodes.length > 0) {
|
||||||
|
return h(NSpace, { align: 'center', inline: true, size: 2 }, () => filterNodes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -379,8 +405,8 @@ const handleSelectContextMenu = (key) => {
|
||||||
dialogStore.openNewKeyDialog(redisKey, props.server, db)
|
dialogStore.openNewKeyDialog(redisKey, props.server, db)
|
||||||
break
|
break
|
||||||
case 'db_filter':
|
case 'db_filter':
|
||||||
const pattern = connectionStore.getKeyFilter(props.server, db)
|
const { match: pattern, type } = connectionStore.getKeyFilter(props.server, db)
|
||||||
dialogStore.openKeyFilterDialog(props.server, db, pattern)
|
dialogStore.openKeyFilterDialog(props.server, db, pattern, type)
|
||||||
break
|
break
|
||||||
case 'key_reload':
|
case 'key_reload':
|
||||||
connectionStore.loadKeys(props.server, db, redisKey)
|
connectionStore.loadKeys(props.server, db, redisKey)
|
||||||
|
|
|
@ -241,11 +241,8 @@ const handleSelectContextMenu = (key) => {
|
||||||
// ask for close relevant connections before edit
|
// ask for close relevant connections before edit
|
||||||
if (connectionStore.isConnected(name)) {
|
if (connectionStore.isConnected(name)) {
|
||||||
confirmDialog.warning(i18n.t('edit_close_confirm'), () => {
|
confirmDialog.warning(i18n.t('edit_close_confirm'), () => {
|
||||||
connectionStore.closeConnection(name).then((success) => {
|
connectionStore.closeConnection(name)
|
||||||
if (success) {
|
dialogStore.openEditDialog(name)
|
||||||
dialogStore.openEditDialog(name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
dialogStore.openEditDialog(name)
|
dialogStore.openEditDialog(name)
|
||||||
|
@ -285,7 +282,7 @@ const findSiblingsAndIndex = (node, nodes) => {
|
||||||
return [null, null]
|
return [null, null]
|
||||||
}
|
}
|
||||||
|
|
||||||
// delay save until stop drop after 2 seconds
|
// delay save until drop stopped after 2 seconds
|
||||||
const saveSort = debounce(connectionStore.saveConnectionSorted, 2000, { trailing: true })
|
const saveSort = debounce(connectionStore.saveConnectionSorted, 2000, { trailing: true })
|
||||||
const handleDrop = ({ node, dragNode, dropPosition }) => {
|
const handleDrop = ({ node, dragNode, dropPosition }) => {
|
||||||
const [dragNodeSiblings, dragNodeIndex] = findSiblingsAndIndex(dragNode, connectionStore.connections)
|
const [dragNodeSiblings, dragNodeIndex] = findSiblingsAndIndex(dragNode, connectionStore.connections)
|
||||||
|
|
|
@ -6,6 +6,14 @@ export const types = {
|
||||||
ZSET: 'ZSET',
|
ZSET: 'ZSET',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const typesColor = {
|
||||||
|
[types.STRING]: '#5A96E3',
|
||||||
|
[types.HASH]: '#9575DE',
|
||||||
|
[types.LIST]: '#7A9D54',
|
||||||
|
[types.SET]: '#F3AA60',
|
||||||
|
[types.ZSET]: '#FF6666',
|
||||||
|
}
|
||||||
|
|
||||||
// export const typesName = Object.fromEntries(Object.entries(types).map(([key, value]) => [key, value.name]))
|
// export const typesName = Object.fromEntries(Object.entries(types).map(([key, value]) => [key, value.name]))
|
||||||
|
|
||||||
export const validType = (t) => {
|
export const validType = (t) => {
|
||||||
|
|
|
@ -149,8 +149,8 @@
|
||||||
"unit_day": "天",
|
"unit_day": "天",
|
||||||
"unit_hour": "小时",
|
"unit_hour": "小时",
|
||||||
"unit_minute": "分钟",
|
"unit_minute": "分钟",
|
||||||
"all_info": "所有信息",
|
"all_info": "全部信息",
|
||||||
"all": "所有",
|
"all": "全部",
|
||||||
"launch_log": "运行日志",
|
"launch_log": "运行日志",
|
||||||
"filter_server": "筛选服务器",
|
"filter_server": "筛选服务器",
|
||||||
"filter_keyword": "筛选关键字",
|
"filter_keyword": "筛选关键字",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { endsWith, findIndex, get, isEmpty, size, split, uniq } from 'lodash'
|
import { endsWith, findIndex, get, isEmpty, size, split, toUpper, uniq } from 'lodash'
|
||||||
import {
|
import {
|
||||||
AddHashField,
|
AddHashField,
|
||||||
AddListItem,
|
AddListItem,
|
||||||
|
@ -31,6 +31,7 @@ import {
|
||||||
} from '../../wailsjs/go/services/connectionService.js'
|
} from '../../wailsjs/go/services/connectionService.js'
|
||||||
import { ConnectionType } from '../consts/connection_type.js'
|
import { ConnectionType } from '../consts/connection_type.js'
|
||||||
import useTabStore from './tab.js'
|
import useTabStore from './tab.js'
|
||||||
|
import { types } from '../consts/support_redis_type.js'
|
||||||
|
|
||||||
const useConnectionStore = defineStore('connections', {
|
const useConnectionStore = defineStore('connections', {
|
||||||
/**
|
/**
|
||||||
|
@ -62,6 +63,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @property {Object} serverStats
|
* @property {Object} serverStats
|
||||||
* @property {Object.<string, ConnectionProfile>} serverProfile
|
* @property {Object.<string, ConnectionProfile>} serverProfile
|
||||||
* @property {Object.<string, string>} keyFilter key is 'server#db', 'server#-1' stores default filter pattern
|
* @property {Object.<string, string>} keyFilter key is 'server#db', 'server#-1' stores default filter pattern
|
||||||
|
* @property {Object.<string, string>} typeFilter key is 'server#db'
|
||||||
* @property {Object.<string, DatabaseItem[]>} databases
|
* @property {Object.<string, DatabaseItem[]>} databases
|
||||||
* @property {Object.<string, Map<string, DatabaseItem>>} nodeMap key format likes 'server#db', children key format likes 'key#type'
|
* @property {Object.<string, Map<string, DatabaseItem>>} nodeMap key format likes 'server#db', children key format likes 'key#type'
|
||||||
*/
|
*/
|
||||||
|
@ -90,6 +92,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
serverStats: {}, // current server status info
|
serverStats: {}, // current server status info
|
||||||
serverProfile: {}, // all server profile
|
serverProfile: {}, // all server profile
|
||||||
keyFilter: {}, // all key filters in opened connections group by server+db
|
keyFilter: {}, // all key filters in opened connections group by server+db
|
||||||
|
typeFilter: {}, // all key type filters in opened connections group by server+db
|
||||||
databases: {}, // all databases in opened connections group by server name
|
databases: {}, // all databases in opened connections group by server name
|
||||||
nodeMap: {}, // all nodes in opened connections group by server#db and type/key
|
nodeMap: {}, // all nodes in opened connections group by server#db and type/key
|
||||||
}),
|
}),
|
||||||
|
@ -434,8 +437,8 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async openDatabase(connName, db) {
|
async openDatabase(connName, db) {
|
||||||
const filterPattern = this.getKeyFilter(connName, db)
|
const { match: filterPattern, type: keyType } = this.getKeyFilter(connName, db)
|
||||||
const { data, success, msg } = await OpenDatabase(connName, db, filterPattern)
|
const { data, success, msg } = await OpenDatabase(connName, db, filterPattern, keyType)
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new Error(msg)
|
throw new Error(msg)
|
||||||
}
|
}
|
||||||
|
@ -1247,17 +1250,24 @@ const useConnectionStore = defineStore('connections', {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get key filter pattern
|
* get key filter pattern and filter type
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @returns {string}
|
* @returns {{match: string, type: string}}
|
||||||
*/
|
*/
|
||||||
getKeyFilter(server, db) {
|
getKeyFilter(server, db) {
|
||||||
|
let match, type
|
||||||
const key = `${server}#${db}`
|
const key = `${server}#${db}`
|
||||||
if (!this.keyFilter.hasOwnProperty(key)) {
|
if (!this.keyFilter.hasOwnProperty(key)) {
|
||||||
return this.keyFilter[`${server}#-1`] || '*'
|
match = this.keyFilter[`${server}#-1`] || '*'
|
||||||
|
} else {
|
||||||
|
match = this.keyFilter[key] || '*'
|
||||||
|
}
|
||||||
|
type = this.typeFilter[`${server}#${db}`] || ''
|
||||||
|
return {
|
||||||
|
match,
|
||||||
|
type: toUpper(type),
|
||||||
}
|
}
|
||||||
return this.keyFilter[key] || '*'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1265,13 +1275,16 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} pattern
|
* @param {string} pattern
|
||||||
|
* @param {string} [type]
|
||||||
*/
|
*/
|
||||||
setKeyFilter(server, db, pattern) {
|
setKeyFilter(server, db, pattern, type) {
|
||||||
this.keyFilter[`${server}#${db}`] = pattern || '*'
|
this.keyFilter[`${server}#${db}`] = pattern || '*'
|
||||||
|
this.typeFilter[`${server}#${db}`] = types[toUpper(type)] || ''
|
||||||
},
|
},
|
||||||
|
|
||||||
removeKeyFilter(server, db) {
|
removeKeyFilter(server, db) {
|
||||||
this.keyFilter[`${server}#${db}`] = '*'
|
this.keyFilter[`${server}#${db}`] = '*'
|
||||||
|
delete this.typeFilter[`${server}#${db}`]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,6 +24,7 @@ const useDialogStore = defineStore('dialog', {
|
||||||
keyFilterParam: {
|
keyFilterParam: {
|
||||||
server: '',
|
server: '',
|
||||||
db: 0,
|
db: 0,
|
||||||
|
type: '',
|
||||||
pattern: '*',
|
pattern: '*',
|
||||||
},
|
},
|
||||||
keyFilterDialogVisible: false,
|
keyFilterDialogVisible: false,
|
||||||
|
@ -85,12 +86,14 @@ const useDialogStore = defineStore('dialog', {
|
||||||
*
|
*
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} pattern
|
* @param {string} [pattern]
|
||||||
|
* @param {string} [type]
|
||||||
*/
|
*/
|
||||||
openKeyFilterDialog(server, db, pattern) {
|
openKeyFilterDialog(server, db, pattern, type) {
|
||||||
this.keyFilterParam.server = server
|
this.keyFilterParam.server = server
|
||||||
this.keyFilterParam.db = db
|
this.keyFilterParam.db = db
|
||||||
this.keyFilterParam.pattern = '*'
|
this.keyFilterParam.type = type || ''
|
||||||
|
this.keyFilterParam.pattern = pattern || '*'
|
||||||
this.keyFilterDialogVisible = true
|
this.keyFilterDialogVisible = true
|
||||||
},
|
},
|
||||||
closeKeyFilterDialog() {
|
closeKeyFilterDialog() {
|
||||||
|
|
Loading…
Reference in New Issue