Compare commits
3 Commits
152fbe962f
...
b4405eb7db
Author | SHA1 | Date |
---|---|---|
Lykin | b4405eb7db | |
Lykin | 04bc103583 | |
Lykin | f17bb744f4 |
|
@ -1331,6 +1331,45 @@ func (b *browserService) SetKeyValue(param types.SetKeyParam) (resp types.JSResp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHashValue get hash field
|
||||||
|
func (b *browserService) GetHashValue(param types.GetHashParam) (resp types.JSResp) {
|
||||||
|
item, err := b.getRedisClient(param.Server, param.DB)
|
||||||
|
if err != nil {
|
||||||
|
resp.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client, ctx := item.client, item.ctx
|
||||||
|
key := strutil.DecodeRedisKey(param.Key)
|
||||||
|
val, err := client.HGet(ctx, key, param.Field).Result()
|
||||||
|
if errors.Is(err, redis.Nil) {
|
||||||
|
resp.Msg = "field in key not found"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
resp.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var displayVal string
|
||||||
|
if (len(param.Decode) > 0 && param.Decode != types.DECODE_NONE) ||
|
||||||
|
(len(param.Format) > 0 && param.Format != types.FORMAT_RAW) {
|
||||||
|
decoder := Preferences().GetDecoder()
|
||||||
|
displayVal, _, _ = convutil.ConvertTo(val, param.Decode, param.Format, decoder)
|
||||||
|
if displayVal == val {
|
||||||
|
displayVal = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Data = types.HashEntryItem{
|
||||||
|
Key: param.Field,
|
||||||
|
Value: val,
|
||||||
|
DisplayValue: displayVal,
|
||||||
|
}
|
||||||
|
resp.Success = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// SetHashValue update hash field
|
// SetHashValue update hash field
|
||||||
func (b *browserService) SetHashValue(param types.SetHashParam) (resp types.JSResp) {
|
func (b *browserService) SetHashValue(param types.SetHashParam) (resp types.JSResp) {
|
||||||
item, err := b.getRedisClient(param.Server, param.DB)
|
item, err := b.getRedisClient(param.Server, param.DB)
|
||||||
|
|
|
@ -101,3 +101,12 @@ type SetZSetParam struct {
|
||||||
RetFormat string `json:"retFormat,omitempty"`
|
RetFormat string `json:"retFormat,omitempty"`
|
||||||
RetDecode string `json:"retDecode,omitempty"`
|
RetDecode string `json:"retDecode,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetHashParam struct {
|
||||||
|
Server string `json:"server"`
|
||||||
|
DB int `json:"db"`
|
||||||
|
Key any `json:"key"`
|
||||||
|
Field string `json:"field,omitempty"`
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
Decode string `json:"decode,omitempty"`
|
||||||
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "^4.4.2",
|
"chart.js": "^4.4.3",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"monaco-editor": "^0.47.0",
|
"monaco-editor": "^0.47.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.77.1",
|
"sass": "^1.77.2",
|
||||||
"vue": "^3.4.27",
|
"vue": "^3.4.27",
|
||||||
"vue-chartjs": "^5.3.1",
|
"vue-chartjs": "^5.3.1",
|
||||||
"vue-i18n": "^9.13.1",
|
"vue-i18n": "^9.13.1",
|
||||||
|
@ -1009,9 +1009,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/chart.js": {
|
"node_modules/chart.js": {
|
||||||
"version": "4.4.2",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz",
|
||||||
"integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
|
"integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kurkle/color": "^0.3.0"
|
"@kurkle/color": "^0.3.0"
|
||||||
},
|
},
|
||||||
|
@ -1891,9 +1891,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.77.1",
|
"version": "1.77.2",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.1.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz",
|
||||||
"integrity": "sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==",
|
"integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
"immutable": "^4.0.0",
|
"immutable": "^4.0.0",
|
||||||
|
@ -2998,9 +2998,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chart.js": {
|
"chart.js": {
|
||||||
"version": "4.4.2",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz",
|
||||||
"integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
|
"integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@kurkle/color": "^0.3.0"
|
"@kurkle/color": "^0.3.0"
|
||||||
}
|
}
|
||||||
|
@ -3625,9 +3625,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sass": {
|
"sass": {
|
||||||
"version": "1.77.1",
|
"version": "1.77.2",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.1.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz",
|
||||||
"integrity": "sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==",
|
"integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
"immutable": "^4.0.0",
|
"immutable": "^4.0.0",
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "^4.4.2",
|
"chart.js": "^4.4.3",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"monaco-editor": "^0.47.0",
|
"monaco-editor": "^0.47.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.77.1",
|
"sass": "^1.77.2",
|
||||||
"vue": "^3.4.27",
|
"vue": "^3.4.27",
|
||||||
"vue-chartjs": "^5.3.1",
|
"vue-chartjs": "^5.3.1",
|
||||||
"vue-i18n": "^9.13.1",
|
"vue-i18n": "^9.13.1",
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
c560453a1ccab2d0c6910daad20e4009
|
76020c81d7419fcb32383b7b397a60c7
|
|
@ -5,14 +5,16 @@ import Edit from '@/components/icons/Edit.vue'
|
||||||
import Close from '@/components/icons/Close.vue'
|
import Close from '@/components/icons/Close.vue'
|
||||||
import Save from '@/components/icons/Save.vue'
|
import Save from '@/components/icons/Save.vue'
|
||||||
import Copy from '@/components/icons/Copy.vue'
|
import Copy from '@/components/icons/Copy.vue'
|
||||||
|
import Refresh from '@/components/icons/Refresh.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
bindKey: String,
|
bindKey: String,
|
||||||
editing: Boolean,
|
editing: Boolean,
|
||||||
readonly: Boolean,
|
readonly: Boolean,
|
||||||
|
canRefresh: Boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['edit', 'delete', 'copy', 'save', 'cancel'])
|
const emit = defineEmits(['edit', 'delete', 'copy', 'refresh', 'save', 'cancel'])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -22,6 +24,7 @@ const emit = defineEmits(['edit', 'delete', 'copy', 'save', 'cancel'])
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex-box-h edit-column-func">
|
<div v-else class="flex-box-h edit-column-func">
|
||||||
<icon-button :icon="Copy" :title="$t('interface.copy_value')" @click="emit('copy')" />
|
<icon-button :icon="Copy" :title="$t('interface.copy_value')" @click="emit('copy')" />
|
||||||
|
<icon-button v-if="props.canRefresh" :icon="Refresh" :title="$t('interface.reload')" @click="emit('refresh')" />
|
||||||
<icon-button v-if="!props.readonly" :icon="Edit" :title="$t('interface.edit_row')" @click="emit('edit')" />
|
<icon-button v-if="!props.readonly" :icon="Edit" :title="$t('interface.edit_row')" @click="emit('edit')" />
|
||||||
<n-popconfirm
|
<n-popconfirm
|
||||||
:negative-text="$t('common.cancel')"
|
:negative-text="$t('common.cancel')"
|
||||||
|
|
|
@ -249,4 +249,8 @@ onUnmounted(() => {
|
||||||
left: 2px;
|
left: 2px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.line-numbers) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -92,11 +92,14 @@ const fieldColumn = computed(() => ({
|
||||||
lineClamp: 1,
|
lineClamp: 1,
|
||||||
},
|
},
|
||||||
filterOptionValue: fieldFilterOption.value,
|
filterOptionValue: fieldFilterOption.value,
|
||||||
className: inEdit.value ? 'clickable' : '',
|
className: inEdit.value ? 'clickable wordline' : 'wordline',
|
||||||
filter: (value, row) => {
|
filter: (value, row) => {
|
||||||
return !!~row.k.indexOf(value.toString())
|
return !!~row.k.indexOf(value.toString())
|
||||||
},
|
},
|
||||||
render: (row) => {
|
render: (row) => {
|
||||||
|
if (row.rm === true) {
|
||||||
|
return h('s', {}, decodeRedisKey(row.k))
|
||||||
|
}
|
||||||
return decodeRedisKey(row.k)
|
return decodeRedisKey(row.k)
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
@ -135,6 +138,9 @@ const valueColumn = computed(() => ({
|
||||||
if (isCode.value) {
|
if (isCode.value) {
|
||||||
return h('pre', {}, row.dv || row.v)
|
return h('pre', {}, row.dv || row.v)
|
||||||
}
|
}
|
||||||
|
if (row.rm === true) {
|
||||||
|
return h('s', {}, row.dv || row.v)
|
||||||
|
}
|
||||||
return row.dv || row.v
|
return row.dv || row.v
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
@ -204,6 +210,25 @@ const actionColumn = {
|
||||||
return h(EditableTableColumn, {
|
return h(EditableTableColumn, {
|
||||||
editing: false,
|
editing: false,
|
||||||
bindKey: row.k,
|
bindKey: row.k,
|
||||||
|
canRefresh: true,
|
||||||
|
onRefresh: async () => {
|
||||||
|
const { updated, success, msg } = await browserStore.getHashField({
|
||||||
|
server: props.name,
|
||||||
|
db: props.db,
|
||||||
|
key: keyName.value,
|
||||||
|
field: row.k,
|
||||||
|
decode: props.decode,
|
||||||
|
format: props.format,
|
||||||
|
})
|
||||||
|
if (success) {
|
||||||
|
delete props.value[index]['rm']
|
||||||
|
$message.success(i18n.t('dialogue.reload_succ'))
|
||||||
|
} else {
|
||||||
|
// update fail, the key may have been deleted
|
||||||
|
$message.error(msg)
|
||||||
|
props.value[index]['rm'] = true
|
||||||
|
}
|
||||||
|
},
|
||||||
onCopy: async () => {
|
onCopy: async () => {
|
||||||
try {
|
try {
|
||||||
const succ = await ClipboardSetText(row.v)
|
const succ = await ClipboardSetText(row.v)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
FlushDB,
|
FlushDB,
|
||||||
GetClientList,
|
GetClientList,
|
||||||
GetCmdHistory,
|
GetCmdHistory,
|
||||||
|
GetHashValue,
|
||||||
GetKeyDetail,
|
GetKeyDetail,
|
||||||
GetKeySummary,
|
GetKeySummary,
|
||||||
GetKeyType,
|
GetKeyType,
|
||||||
|
@ -987,6 +988,31 @@ const useBrowserStore = defineStore('browser', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get hash field
|
||||||
|
* @param {string} server
|
||||||
|
* @param {number} db
|
||||||
|
* @param {string} key
|
||||||
|
* @param {string} field
|
||||||
|
* @param {decodeTypes} [decode]
|
||||||
|
* @param {formatTypes} [format]
|
||||||
|
* @return {Promise<{{msg: string, success: boolean, updated: HashEntryItem[]}>}
|
||||||
|
*/
|
||||||
|
async getHashField({ server, db, key, field, decode = decodeTypes.NONE, format = formatTypes.RAW }) {
|
||||||
|
try {
|
||||||
|
const { data, success, msg } = await GetHashValue({ server, db, key, field, decode, format })
|
||||||
|
if (success && !isEmpty(data)) {
|
||||||
|
const tab = useTabStore()
|
||||||
|
tab.updateValueEntries({ server, db, key, type: 'hash', entries: [data] })
|
||||||
|
return { success, updated: data }
|
||||||
|
} else {
|
||||||
|
return { success: false, msg }
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return { success: false, msg: e.message }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove hash field
|
* remove hash field
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
|
|
|
@ -63,6 +63,10 @@ body {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wordline {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-btn {
|
.icon-btn {
|
||||||
@extend .clickable;
|
@extend .clickable;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
|
|
Loading…
Reference in New Issue