feat: add key filter for database scan
This commit is contained in:
parent
ea2c24a5f9
commit
41e5ecfad2
|
@ -179,7 +179,7 @@ func (c *connectionService) OpenConnection(name string) (resp types.JSResp) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get total database
|
// get total databases
|
||||||
config, err := rdb.ConfigGet(ctx, "databases").Result()
|
config, err := rdb.ConfigGet(ctx, "databases").Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
|
@ -347,12 +347,12 @@ 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) (resp types.JSResp) {
|
func (c *connectionService) OpenDatabase(connName string, db int, match string) (resp types.JSResp) {
|
||||||
return c.ScanKeys(connName, db, "*")
|
return c.ScanKeys(connName, db, match)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScanKeys scan all keys below prefix
|
// ScanKeys scan all keys
|
||||||
func (c *connectionService) ScanKeys(connName string, db int, prefix string) (resp types.JSResp) {
|
func (c *connectionService) ScanKeys(connName string, db int, match 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()
|
||||||
|
@ -364,7 +364,7 @@ func (c *connectionService) ScanKeys(connName string, db int, prefix string) (re
|
||||||
var cursor uint64
|
var cursor uint64
|
||||||
for {
|
for {
|
||||||
var loadedKey []string
|
var loadedKey []string
|
||||||
loadedKey, cursor, err = rdb.Scan(ctx, cursor, prefix, 10000).Result()
|
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
|
||||||
|
|
|
@ -17,6 +17,7 @@ import usePreferencesStore from './stores/preferences.js'
|
||||||
import useConnectionStore from './stores/connections.js'
|
import useConnectionStore from './stores/connections.js'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { darkTheme, lightTheme, useOsTheme } from 'naive-ui'
|
import { darkTheme, lightTheme, useOsTheme } from 'naive-ui'
|
||||||
|
import KeyFilterDialog from './components/dialogs/KeyFilterDialog.vue'
|
||||||
|
|
||||||
hljs.registerLanguage('json', json)
|
hljs.registerLanguage('json', json)
|
||||||
hljs.registerLanguage('plaintext', plaintext)
|
hljs.registerLanguage('plaintext', plaintext)
|
||||||
|
@ -95,6 +96,7 @@ const theme = computed(() => {
|
||||||
<connection-dialog />
|
<connection-dialog />
|
||||||
<group-dialog />
|
<group-dialog />
|
||||||
<new-key-dialog />
|
<new-key-dialog />
|
||||||
|
<key-filter-dialog />
|
||||||
<add-fields-dialog />
|
<add-fields-dialog />
|
||||||
<rename-key-dialog />
|
<rename-key-dialog />
|
||||||
<delete-key-dialog />
|
<delete-key-dialog />
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import useDialog from '../../stores/dialog'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import useConnectionStore from '../../stores/connections.js'
|
||||||
|
|
||||||
|
const i18n = useI18n()
|
||||||
|
const filterForm = reactive({
|
||||||
|
server: '',
|
||||||
|
db: 0,
|
||||||
|
pattern: '',
|
||||||
|
})
|
||||||
|
const filterFormRef = ref(null)
|
||||||
|
|
||||||
|
const formLabelWidth = '100px'
|
||||||
|
const dialogStore = useDialog()
|
||||||
|
watch(
|
||||||
|
() => dialogStore.keyFilterDialogVisible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
const { server, db, pattern } = dialogStore.keyFilterParam
|
||||||
|
filterForm.server = server
|
||||||
|
filterForm.db = db || 0
|
||||||
|
filterForm.pattern = pattern || '*'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const connectionStore = useConnectionStore()
|
||||||
|
const onConfirm = () => {
|
||||||
|
const { server, db, pattern } = filterForm
|
||||||
|
connectionStore.setKeyFilter(server, db, pattern)
|
||||||
|
connectionStore.reopenDatabase(server, db)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
dialogStore.closeKeyFilterDialog()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-modal
|
||||||
|
v-model:show="dialogStore.keyFilterDialogVisible"
|
||||||
|
:closable="false"
|
||||||
|
:close-on-esc="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:negative-button-props="{ size: 'medium' }"
|
||||||
|
:negative-text="$t('cancel')"
|
||||||
|
:positive-button-props="{ size: 'medium' }"
|
||||||
|
:positive-text="$t('confirm')"
|
||||||
|
:show-icon="false"
|
||||||
|
:title="$t('set_key_filter')"
|
||||||
|
preset="dialog"
|
||||||
|
style="width: 450px"
|
||||||
|
transform-origin="center"
|
||||||
|
@positive-click="onConfirm"
|
||||||
|
@negative-click="onClose"
|
||||||
|
>
|
||||||
|
<n-form
|
||||||
|
ref="filterFormRef"
|
||||||
|
:label-width="formLabelWidth"
|
||||||
|
:model="filterForm"
|
||||||
|
:show-require-mark="false"
|
||||||
|
label-align="right"
|
||||||
|
label-placement="left"
|
||||||
|
style="padding-right: 15px"
|
||||||
|
>
|
||||||
|
<n-form-item :label="$t('server')" path="key">
|
||||||
|
<n-text>{{ filterForm.server }}</n-text>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('db_index')" path="db">
|
||||||
|
<n-text>{{ filterForm.db }}</n-text>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('filter_pattern')" required>
|
||||||
|
<n-input-group>
|
||||||
|
<n-tooltip>
|
||||||
|
<template #trigger>
|
||||||
|
<n-input v-model:value="filterForm.pattern" placeholder="Filter Pattern" clearable />
|
||||||
|
</template>
|
||||||
|
<div class="text-block">{{ $t('filter_pattern_tip') }}</div>
|
||||||
|
</n-tooltip>
|
||||||
|
<n-button secondary type="primary" @click="filterForm.pattern = '*'">
|
||||||
|
{{ $t('restore_defaults') }}
|
||||||
|
</n-button>
|
||||||
|
</n-input-group>
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</n-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -1,10 +1,10 @@
|
||||||
<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, useDialog, useMessage } from 'naive-ui'
|
import { NIcon, 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 } from 'lodash'
|
import { get, indexOf, isEmpty, remove } from 'lodash'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import Refresh from '../icons/Refresh.vue'
|
import Refresh from '../icons/Refresh.vue'
|
||||||
import CopyLink from '../icons/CopyLink.vue'
|
import CopyLink from '../icons/CopyLink.vue'
|
||||||
|
@ -18,6 +18,8 @@ import useConnectionStore from '../../stores/connections.js'
|
||||||
import { useConfirmDialog } from '../../utils/confirm_dialog.js'
|
import { useConfirmDialog } from '../../utils/confirm_dialog.js'
|
||||||
import ToggleServer from '../icons/ToggleServer.vue'
|
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 Close from '../icons/Close.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
server: String,
|
server: String,
|
||||||
|
@ -86,6 +88,20 @@ const menuOptions = {
|
||||||
label: i18n.t('new_key'),
|
label: i18n.t('new_key'),
|
||||||
icon: renderIcon(Add),
|
icon: renderIcon(Add),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'db_filter',
|
||||||
|
label: i18n.t('filter_key'),
|
||||||
|
icon: renderIcon(Filter),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'divider',
|
||||||
|
key: 'd1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'db_close',
|
||||||
|
label: i18n.t('close_db'),
|
||||||
|
icon: renderIcon(Close),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
return [
|
return [
|
||||||
|
@ -261,6 +277,26 @@ const renderSuffix = ({ option }) => {
|
||||||
// return h(NButton,
|
// return h(NButton,
|
||||||
// { text: true, type: 'primary' },
|
// { text: true, type: 'primary' },
|
||||||
// { default: () => h(Key) })
|
// { default: () => h(Key) })
|
||||||
|
if (option.type === ConnectionType.RedisDB) {
|
||||||
|
const { name: server, db } = option
|
||||||
|
const filterPattern = connectionStore.getKeyFilter(server, db)
|
||||||
|
if (!isEmpty(filterPattern) && filterPattern !== '*') {
|
||||||
|
return h(
|
||||||
|
NTag,
|
||||||
|
{
|
||||||
|
bordered: false,
|
||||||
|
closable: true,
|
||||||
|
size: 'small',
|
||||||
|
onClose: () => {
|
||||||
|
connectionStore.removeKeyFilter(server, db)
|
||||||
|
connectionStore.reopenDatabase(server, db)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ default: () => filterPattern }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeProps = ({ option }) => {
|
const nodeProps = ({ option }) => {
|
||||||
|
@ -334,10 +370,18 @@ const handleSelectContextMenu = (key) => {
|
||||||
case 'db_reload':
|
case 'db_reload':
|
||||||
connectionStore.reopenDatabase(props.server, db)
|
connectionStore.reopenDatabase(props.server, db)
|
||||||
break
|
break
|
||||||
|
case 'db_close':
|
||||||
|
remove(expandedKeys.value, (k) => k === `${props.server}/db${db}`)
|
||||||
|
connectionStore.closeDatabase(props.server, db)
|
||||||
|
break
|
||||||
case 'db_newkey':
|
case 'db_newkey':
|
||||||
case 'key_newkey':
|
case 'key_newkey':
|
||||||
dialogStore.openNewKeyDialog(redisKey, props.server, db)
|
dialogStore.openNewKeyDialog(redisKey, props.server, db)
|
||||||
break
|
break
|
||||||
|
case 'db_filter':
|
||||||
|
const pattern = connectionStore.getKeyFilter(props.server, db)
|
||||||
|
dialogStore.openKeyFilterDialog(props.server, db, pattern)
|
||||||
|
break
|
||||||
case 'key_reload':
|
case 'key_reload':
|
||||||
connectionStore.loadKeys(props.server, db, redisKey)
|
connectionStore.loadKeys(props.server, db, redisKey)
|
||||||
break
|
break
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
"view_as": "View As",
|
"view_as": "View As",
|
||||||
"reload": "Reload",
|
"reload": "Reload",
|
||||||
"open_connection": "Open Connection",
|
"open_connection": "Open Connection",
|
||||||
"open_db": "Expand Database",
|
"open_db": "Open Database",
|
||||||
|
"close_db": "Close Database",
|
||||||
"filter_key": "Filter Keys",
|
"filter_key": "Filter Keys",
|
||||||
"disconnect": "Disconnect",
|
"disconnect": "Disconnect",
|
||||||
"dup_conn": "Duplicate Connection",
|
"dup_conn": "Duplicate Connection",
|
||||||
|
@ -94,6 +95,10 @@
|
||||||
"enter_elem": "Enter Element",
|
"enter_elem": "Enter Element",
|
||||||
"enter_member": "Enter Member",
|
"enter_member": "Enter Member",
|
||||||
"enter_score": "Enter Score",
|
"enter_score": "Enter Score",
|
||||||
|
"element": "Element",
|
||||||
|
"set_key_filter": "Set Key Filter",
|
||||||
|
"filter_pattern": "Pattern",
|
||||||
|
"filter_pattern_tip": "prefix_*: Matches key names starting with \"prefix_\".\n*_suffix: Matches key names ending with \"_suffix\".\n*pattern*: Matches key names containing \"pattern\".\nprefix_??: Matches key names starting with \"prefix_\" followed by any two characters.\n*abc*: Matches key names containing \"abc\" at any position.",
|
||||||
"key": "Key",
|
"key": "Key",
|
||||||
"value": "Value",
|
"value": "Value",
|
||||||
"field": "Field",
|
"field": "Field",
|
||||||
|
|
|
@ -41,7 +41,8 @@
|
||||||
"view_as": "查看方式",
|
"view_as": "查看方式",
|
||||||
"reload": "重新载入",
|
"reload": "重新载入",
|
||||||
"open_connection": "打开连接",
|
"open_connection": "打开连接",
|
||||||
"open_db": "展开数据库",
|
"open_db": "打开数据库",
|
||||||
|
"close_db": "关闭数据库",
|
||||||
"filter_key": "过滤键",
|
"filter_key": "过滤键",
|
||||||
"disconnect": "断开连接",
|
"disconnect": "断开连接",
|
||||||
"dup_conn": "复制连接",
|
"dup_conn": "复制连接",
|
||||||
|
@ -97,6 +98,9 @@
|
||||||
"enter_member": "输入成员",
|
"enter_member": "输入成员",
|
||||||
"enter_score": "输入分值",
|
"enter_score": "输入分值",
|
||||||
"element": "元素",
|
"element": "元素",
|
||||||
|
"set_key_filter": "设置键过滤器",
|
||||||
|
"filter_pattern": "过滤表达式",
|
||||||
|
"filter_pattern_tip": "prefix_*:匹配以\"prefix_\"开头的键名\n*_suffix:匹配以\"_suffix\"结尾的键名\n*pattern*:匹配包含\"pattern\"的键名\nprefix_??:匹配以\"prefix_\"开头后跟两个任意字符的键名\n*abc*:匹配包含\"abc\"的任意位置的键名",
|
||||||
"key": "键",
|
"key": "键",
|
||||||
"value": "值",
|
"value": "值",
|
||||||
"field": "字段",
|
"field": "字段",
|
||||||
|
|
|
@ -59,7 +59,9 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @typedef {Object} ConnectionState
|
* @typedef {Object} ConnectionState
|
||||||
* @property {string[]} groups
|
* @property {string[]} groups
|
||||||
* @property {ConnectionItem[]} connections
|
* @property {ConnectionItem[]} connections
|
||||||
|
* @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, 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'
|
||||||
*/
|
*/
|
||||||
|
@ -87,8 +89,9 @@ const useConnectionStore = defineStore('connections', {
|
||||||
connections: [], // all connections
|
connections: [], // all 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
|
||||||
databases: {}, // all databases in opened connections group by server name
|
databases: {}, // all databases in opened connections group by server name
|
||||||
nodeMap: {}, // all node in opened connections group by server+db and key+type
|
nodeMap: {}, // all nodes in opened connections group by server#db and type/key
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
anyConnectionOpened() {
|
anyConnectionOpened() {
|
||||||
|
@ -151,6 +154,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
markColor: conn.markColor,
|
markColor: conn.markColor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.setKeyFilter(conn.name, -1, conn.defaultFilter)
|
||||||
}
|
}
|
||||||
this.connections = conns
|
this.connections = conns
|
||||||
this.serverProfile = profiles
|
this.serverProfile = profiles
|
||||||
|
@ -333,8 +337,10 @@ const useConnectionStore = defineStore('connections', {
|
||||||
|
|
||||||
const dbs = this.databases[name]
|
const dbs = this.databases[name]
|
||||||
for (const db of dbs) {
|
for (const db of dbs) {
|
||||||
this.nodeMap[`${db.name}#${db.db}`]?.clear()
|
this.removeKeyFilter(name, db.db)
|
||||||
|
this.nodeMap[`${name}#${db.db}`]?.clear()
|
||||||
}
|
}
|
||||||
|
this.removeKeyFilter(name, -1)
|
||||||
delete this.databases[name]
|
delete this.databases[name]
|
||||||
delete this.serverStats[name]
|
delete this.serverStats[name]
|
||||||
|
|
||||||
|
@ -428,7 +434,8 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async openDatabase(connName, db) {
|
async openDatabase(connName, db) {
|
||||||
const { data, success, msg } = await OpenDatabase(connName, db)
|
const filterPattern = this.getKeyFilter(connName, db)
|
||||||
|
const { data, success, msg } = await OpenDatabase(connName, db, filterPattern)
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new Error(msg)
|
throw new Error(msg)
|
||||||
}
|
}
|
||||||
|
@ -459,6 +466,20 @@ const useConnectionStore = defineStore('connections', {
|
||||||
this.nodeMap[`${connName}#${db}`]?.clear()
|
this.nodeMap[`${connName}#${db}`]?.clear()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close database
|
||||||
|
* @param connName
|
||||||
|
* @param db
|
||||||
|
*/
|
||||||
|
closeDatabase(connName, db) {
|
||||||
|
const dbs = this.databases[connName]
|
||||||
|
delete dbs[db].children
|
||||||
|
dbs[db].isLeaf = false
|
||||||
|
dbs[db].opened = false
|
||||||
|
|
||||||
|
this.nodeMap[`${connName}#${db}`]?.clear()
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param server
|
* @param server
|
||||||
|
@ -1224,6 +1245,34 @@ const useConnectionStore = defineStore('connections', {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get key filter pattern
|
||||||
|
* @param {string} server
|
||||||
|
* @param {number} db
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getKeyFilter(server, db) {
|
||||||
|
const key = `${server}#${db}`
|
||||||
|
if (!this.keyFilter.hasOwnProperty(key)) {
|
||||||
|
return this.keyFilter[`${server}#-1`] || '*'
|
||||||
|
}
|
||||||
|
return this.keyFilter[key] || '*'
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set key filter
|
||||||
|
* @param {string} server
|
||||||
|
* @param {number} db
|
||||||
|
* @param {string} pattern
|
||||||
|
*/
|
||||||
|
setKeyFilter(server, db, pattern) {
|
||||||
|
this.keyFilter[`${server}#${db}`] = pattern || '*'
|
||||||
|
},
|
||||||
|
|
||||||
|
removeKeyFilter(server, db) {
|
||||||
|
this.keyFilter[`${server}#${db}`] = '*'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,13 @@ const useDialogStore = defineStore('dialog', {
|
||||||
},
|
},
|
||||||
newKeyDialogVisible: false,
|
newKeyDialogVisible: false,
|
||||||
|
|
||||||
|
keyFilterParam: {
|
||||||
|
server: '',
|
||||||
|
db: 0,
|
||||||
|
pattern: '*',
|
||||||
|
},
|
||||||
|
keyFilterDialogVisible: false,
|
||||||
|
|
||||||
addFieldParam: {
|
addFieldParam: {
|
||||||
server: '',
|
server: '',
|
||||||
db: 0,
|
db: 0,
|
||||||
|
@ -74,6 +81,26 @@ const useDialogStore = defineStore('dialog', {
|
||||||
this.groupDialogVisible = false
|
this.groupDialogVisible = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} server
|
||||||
|
* @param {number} db
|
||||||
|
* @param {string} pattern
|
||||||
|
*/
|
||||||
|
openKeyFilterDialog(server, db, pattern) {
|
||||||
|
this.keyFilterParam.server = server
|
||||||
|
this.keyFilterParam.db = db
|
||||||
|
this.keyFilterParam.pattern = '*'
|
||||||
|
this.keyFilterDialogVisible = true
|
||||||
|
},
|
||||||
|
closeKeyFilterDialog() {
|
||||||
|
this.keyFilterDialogVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
openRenameGroupDialog(name) {
|
openRenameGroupDialog(name) {
|
||||||
this.editGroup = name
|
this.editGroup = name
|
||||||
this.groupDialogVisible = true
|
this.groupDialogVisible = true
|
||||||
|
|
Loading…
Reference in New Issue