Compare commits

..

No commits in common. "c5abaa65730c165ee4267ebadd660ba75a917443" and "c7a365e8e900909b3f32737e71342f062a12f2c3" have entirely different histories.

38 changed files with 226 additions and 322 deletions

View File

@ -562,59 +562,47 @@ func (b *browserService) GetKeySummary(param types.KeySummaryParam) (resp types.
client, ctx := item.client, item.ctx client, ctx := item.client, item.ctx
key := strutil.DecodeRedisKey(param.Key) key := strutil.DecodeRedisKey(param.Key)
var keyType string
pipe := client.Pipeline() var dur time.Duration
typeVal := pipe.Type(ctx, key) keyType, err = client.Type(ctx, key).Result()
ttlVal := pipe.TTL(ctx, key)
sizeVal := pipe.MemoryUsage(ctx, key, 0)
_, err = pipe.Exec(ctx)
if err != nil { if err != nil {
resp.Msg = err.Error() resp.Msg = err.Error()
return return
} }
if typeVal.Err() != nil { if keyType == "none" {
resp.Msg = typeVal.Err().Error()
return
}
data := types.KeySummary{
Type: strings.ToLower(typeVal.Val()),
Size: sizeVal.Val(),
}
if data.Type == "none" {
resp.Msg = "key not exists" resp.Msg = "key not exists"
return return
} }
if ttlVal.Err() != nil { var data types.KeySummary
data.Type = strings.ToLower(keyType)
if dur, err = client.TTL(ctx, key).Result(); err != nil {
data.TTL = -1 data.TTL = -1
} else { } else {
if ttlVal.Val() < 0 { if dur < 0 {
data.TTL = -1 data.TTL = -1
} else { } else {
data.TTL = int64(ttlVal.Val().Seconds()) data.TTL = int64(dur.Seconds())
} }
} }
data.Size, _ = client.MemoryUsage(ctx, key, 0).Result()
switch data.Type { switch data.Type {
case "string": case "string":
data.Length, err = client.StrLen(ctx, key).Result() data.Length, _ = client.StrLen(ctx, key).Result()
case "list": case "list":
data.Length, err = client.LLen(ctx, key).Result() data.Length, _ = client.LLen(ctx, key).Result()
case "hash": case "hash":
data.Length, err = client.HLen(ctx, key).Result() data.Length, _ = client.HLen(ctx, key).Result()
case "set": case "set":
data.Length, err = client.SCard(ctx, key).Result() data.Length, _ = client.SCard(ctx, key).Result()
case "zset": case "zset":
data.Length, err = client.ZCard(ctx, key).Result() data.Length, _ = client.ZCard(ctx, key).Result()
case "stream": case "stream":
data.Length, err = client.XLen(ctx, key).Result() data.Length, _ = client.XLen(ctx, key).Result()
default: default:
err = errors.New("unknown key type") resp.Msg = "unknown key type"
}
if err != nil {
resp.Msg = err.Error()
return return
} }

View File

@ -63,7 +63,7 @@ func (s *systemService) SelectFile(title string) (resp types.JSResp) {
func (s *systemService) loopWindowEvent() { func (s *systemService) loopWindowEvent() {
var fullscreen, maximised, minimised, normal bool var fullscreen, maximised, minimised, normal bool
var width, height int var width, height, posx, posy int
var dirty bool var dirty bool
for { for {
time.Sleep(300 * time.Millisecond) time.Sleep(300 * time.Millisecond)
@ -84,6 +84,12 @@ func (s *systemService) loopWindowEvent() {
dirty = true dirty = true
} }
if x, y := runtime.WindowGetPosition(s.ctx); x != posx || y != posy {
// window position changed
posx, posy = x, y
dirty = true
}
if m := runtime.WindowIsMaximised(s.ctx); m != maximised { if m := runtime.WindowIsMaximised(s.ctx); m != maximised {
maximised = m maximised = m
dirty = true dirty = true
@ -112,6 +118,7 @@ func (s *systemService) loopWindowEvent() {
if !fullscreen && !minimised { if !fullscreen && !minimised {
// save window size and position // save window size and position
Preferences().SaveWindowSize(width, height, maximised) Preferences().SaveWindowSize(width, height, maximised)
Preferences().SaveWindowPosition(posx, posy)
} }
} }
} }

View File

@ -132,11 +132,10 @@ func autoDecode(str string) (value, resultDecode string) {
return return
} }
// FIXME: skip decompress with brotli due to incorrect format checking if value, ok = decodeBrotli(str); ok {
//if value, ok = decodeBrotli(str); ok { resultDecode = types.DECODE_BROTLI
// resultDecode = types.DECODE_BROTLI return
// return }
//}
} }
} }

View File

@ -6,7 +6,7 @@
<title>Tiny RDM</title> <title>Tiny RDM</title>
<!-- <link href="./src/styles/style.scss" rel="stylesheet">--> <!-- <link href="./src/styles/style.scss" rel="stylesheet">-->
</head> </head>
<body spellcheck="false"> <body>
<div id='app'></div> <div id='app'></div>
<script src='./src/main.js' type='module'></script> <script src='./src/main.js' type='module'></script>
</body> </body>

View File

@ -17,7 +17,7 @@ const handleUpdateValue = (val) => {
<template> <template>
<div style="min-height: 22px"> <div style="min-height: 22px">
<template v-if="props.isEdit"> <template v-if="props.isEdit">
<n-input :value="props.value" @update:value="handleUpdateValue" /> <n-input :input-props="{ spellcheck: 'false' }" :value="props.value" @update:value="handleUpdateValue" />
</template> </template>
<template v-else> <template v-else>
{{ props.value }} {{ props.value }}

View File

@ -23,7 +23,12 @@ const handleSelectFile = async () => {
<template> <template>
<n-input-group> <n-input-group>
<n-input v-model:value="props.value" :disabled="props.disabled" :placeholder="placeholder" clearable /> <n-input
v-model:value="props.value"
:disabled="props.disabled"
:input-props="{ spellcheck: 'false' }"
:placeholder="placeholder"
clearable />
<n-button :disabled="props.disabled" :focusable="false" @click="handleSelectFile">...</n-button> <n-button :disabled="props.disabled" :focusable="false" @click="handleSelectFile">...</n-button>
</n-input-group> </n-input-group>
</template> </template>

View File

@ -76,10 +76,10 @@ const columns = computed(() => [
return h( return h(
'div', 'div',
null, null,
map(cmdList, (c) => h('div', { class: 'cmd-line' }, c)), map(cmdList, (c) => h('div', null, c)),
) )
} }
return h('div', { class: 'cmd-line' }, cmd) return cmd
}, },
}, },
{ {
@ -148,7 +148,7 @@ defineExpose({
style="min-width: 100px" /> style="min-width: 100px" />
</n-form-item> </n-form-item>
<n-form-item :label="$t('log.filter_keyword')"> <n-form-item :label="$t('log.filter_keyword')">
<n-input v-model:value="data.keyword" clearable placeholder="" /> <n-input v-model:value="data.keyword" :input-props="{ spellcheck: 'false' }" clearable placeholder="" />
</n-form-item> </n-form-item>
<n-form-item label="&nbsp;"> <n-form-item label="&nbsp;">
<icon-button :icon="Refresh" border t-tooltip="log.refresh" @click="loadHistory" /> <icon-button :icon="Refresh" border t-tooltip="log.refresh" @click="loadHistory" />

View File

@ -164,6 +164,7 @@ const onSave = () => {
<div class="editor-content-item-label">{{ props.fieldLabel }}</div> <div class="editor-content-item-label">{{ props.fieldLabel }}</div>
<n-input <n-input
v-model:value="viewAs.field" v-model:value="viewAs.field"
:input-props="{ spellcheck: 'false' }"
:placeholder="props.field + ''" :placeholder="props.field + ''"
:readonly="props.fieldReadonly" :readonly="props.fieldReadonly"
class="editor-content-item-input" class="editor-content-item-input"

View File

@ -88,6 +88,7 @@ defineExpose({
<slot name="prepend" /> <slot name="prepend" />
<n-input <n-input
v-model:value="inputData.filter" v-model:value="inputData.filter"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('interface.filter')" :placeholder="$t('interface.filter')"
:size="props.small ? 'small' : ''" :size="props.small ? 'small' : ''"
clearable clearable

View File

@ -186,7 +186,7 @@ const infoFilter = ref('')
</n-card> </n-card>
<n-card :title="$t('status.all_info')" embedded> <n-card :title="$t('status.all_info')" embedded>
<template #header-extra> <template #header-extra>
<n-input v-model:value="infoFilter" clearable placeholder=""> <n-input v-model:value="infoFilter" :input-props="{ spellcheck: 'false' }" clearable placeholder="">
<template #prefix> <template #prefix>
<icon-button :icon="Filter" size="18" /> <icon-button :icon="Filter" size="18" />
</template> </template>

View File

@ -89,10 +89,10 @@ const columns = computed(() => [
return h( return h(
'div', 'div',
null, null,
map(cmdList, (c) => h('div', { class: 'cmd-line' }, c)), map(cmdList, (c) => h('div', null, c)),
) )
} }
return h('div', { class: 'cmd-line' }, cmd) return cmd
}, },
}, },
{ {
@ -176,7 +176,7 @@ const onListLimitChanged = (limit) => {
</n-tooltip> </n-tooltip>
</n-form-item> </n-form-item>
<n-form-item :label="$t('slog.filter')"> <n-form-item :label="$t('slog.filter')">
<n-input v-model:value="data.keyword" clearable placeholder="" /> <n-input v-model:value="data.keyword" :input-props="{ spellcheck: 'false' }" clearable placeholder="" />
</n-form-item> </n-form-item>
</n-form> </n-form>
<div class="content-value fill-height flex-box-h"> <div class="content-value fill-height flex-box-h">

View File

@ -78,7 +78,7 @@ const onCopyKey = () => {
<div class="content-toolbar flex-box-h"> <div class="content-toolbar flex-box-h">
<n-input-group> <n-input-group>
<redis-type-tag :binary-key="binaryKey" :type="props.keyType" size="large" /> <redis-type-tag :binary-key="binaryKey" :type="props.keyType" size="large" />
<n-input v-model:value="props.keyPath" :title="props.keyPath" readonly> <n-input v-model:value="props.keyPath" :input-props="{ spellcheck: 'false' }" readonly>
<template #suffix> <template #suffix>
<icon-button <icon-button
:icon="Refresh" :icon="Refresh"

View File

@ -205,13 +205,12 @@ const actionColumn = {
onEdit: () => startEdit(index + 1, row.k, row.v), onEdit: () => startEdit(index + 1, row.k, row.v),
onDelete: async () => { onDelete: async () => {
try { try {
const { removed, success, msg } = await browserStore.removeHashField({ const { removed, success, msg } = await browserStore.removeHashField(
server: props.name, props.name,
db: props.db, props.db,
key: keyName.value, keyName.value,
field: row.k, row.k,
reload: false, )
})
if (success) { if (success) {
props.value.splice(index, 1) props.value.splice(index, 1)
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.k })) $message.success(i18n.t('dialogue.delete_key_succ', { key: row.k }))

View File

@ -183,13 +183,14 @@ const actionColumn = {
}, },
onDelete: async () => { onDelete: async () => {
try { try {
const { success, msg } = await browserStore.removeListItem({ const { success, msg } = await browserStore.removeListItem(
server: props.name, props.name,
db: props.db, props.db,
key: keyName.value, keyName.value,
index, index,
}) )
if (success) { if (success) {
props.value.splice(index, 1)
$message.success(i18n.t('dialogue.delete_key_succ', { key: `#${index + 1}` })) $message.success(i18n.t('dialogue.delete_key_succ', { key: `#${index + 1}` }))
} else { } else {
$message.error(msg) $message.error(msg)

View File

@ -180,13 +180,14 @@ const actionColumn = {
}, },
onDelete: async () => { onDelete: async () => {
try { try {
const { success, msg } = await browserStore.removeSetItem({ const { success, msg } = await browserStore.removeSetItem(
server: props.name, props.name,
db: props.db, props.db,
key: keyName.value, keyName.value,
value: row.v, row.v,
}) )
if (success) { if (success) {
// props.value.splice(index, 1)
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.v })) $message.success(i18n.t('dialogue.delete_key_succ', { key: row.v }))
} else { } else {
$message.error(msg) $message.error(msg)

View File

@ -120,12 +120,12 @@ const actionColumn = {
}, },
onDelete: async () => { onDelete: async () => {
try { try {
const { success, msg } = await browserStore.removeStreamValues({ const { success, msg } = await browserStore.removeStreamValues(
server: props.name, props.name,
db: props.db, props.db,
key: keyName.value, keyName.value,
ids: row.id, row.id,
}) )
if (success) { if (success) {
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.id })) $message.success(i18n.t('dialogue.delete_key_succ', { key: row.id }))
} else { } else {

View File

@ -145,6 +145,7 @@ const onSave = async () => {
decode: viewAs.decode, decode: viewAs.decode,
}) })
if (success) { if (success) {
// await browserStore.loadKeyDetail({ server: props.name, db: props.db, key: keyName.value })
$message.success(i18n.t('interface.save_value_succ')) $message.success(i18n.t('interface.save_value_succ'))
} else { } else {
$message.error(msg) $message.error(msg)

View File

@ -227,13 +227,14 @@ const actionColumn = {
onEdit: () => startEdit(index + 1, row.s, row.v), onEdit: () => startEdit(index + 1, row.s, row.v),
onDelete: async () => { onDelete: async () => {
try { try {
const { success, msg } = await browserStore.removeZSetItem({ const { success, msg } = await browserStore.removeZSetItem(
server: props.name, props.name,
db: props.db, props.db,
key: keyName.value, keyName.value,
value: row.v, row.v,
}) )
if (success) { if (success) {
// props.value.splice(index, 1)
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.v })) $message.success(i18n.t('dialogue.delete_key_succ', { key: row.v }))
} else { } else {
$message.error(msg) $message.error(msg)

View File

@ -9,7 +9,7 @@ import AddListValue from '@/components/new_value/AddListValue.vue'
import AddHashValue from '@/components/new_value/AddHashValue.vue' import AddHashValue from '@/components/new_value/AddHashValue.vue'
import AddZSetValue from '@/components/new_value/AddZSetValue.vue' import AddZSetValue from '@/components/new_value/AddZSetValue.vue'
import NewStreamValue from '@/components/new_value/NewStreamValue.vue' import NewStreamValue from '@/components/new_value/NewStreamValue.vue'
import { get, isEmpty, size, slice } from 'lodash' import { isEmpty, size, slice } from 'lodash'
import useBrowserStore from 'stores/browser.js' import useBrowserStore from 'stores/browser.js'
import useTabStore from 'stores/tab.js' import useTabStore from 'stores/tab.js'
@ -22,7 +22,7 @@ const newForm = reactive({
type: '', type: '',
opType: 0, opType: 0,
value: null, value: null,
reload: false, reload: true,
}) })
const addValueComponent = { const addValueComponent = {
@ -89,102 +89,88 @@ const onAdd = async () => {
value = defaultValue[type] value = defaultValue[type]
} }
const keyName = isEmpty(keyCode) ? key : keyCode const keyName = isEmpty(keyCode) ? key : keyCode
let success = false let updated = false
let msg = ''
switch (type) { switch (type) {
case types.LIST: case types.LIST:
{ {
let data let data
if (newForm.opType === 1) { if (newForm.opType === 1) {
data = await browserStore.prependListItem({ data = await browserStore.prependListItem({ server, db, key: keyName, values: value })
server,
db,
key: keyName,
values: value,
reload: newForm.reload,
})
} else { } else {
data = await browserStore.appendListItem({ data = await browserStore.appendListItem({ server, db, key: keyName, values: value })
server, }
db, const { success, msg } = data
key: keyName, if (success) {
values: value, updated = true
reload: newForm.reload, $message.success(i18n.t('dialogue.handle_succ'))
}) } else {
$message.error(msg)
} }
success = get(data, 'success')
msg = get(data, 'msg')
} }
break break
case types.HASH: case types.HASH:
{ {
const data = await browserStore.addHashField({ const { success, msg } = await browserStore.addHashField(server, db, keyName, newForm.opType, value)
server, if (success) {
db, updated = true
key: keyName, $message.success(i18n.t('dialogue.handle_succ'))
action: newForm.opType, } else {
fieldItems: value, $message.error(msg)
reload: newForm.reload, }
})
success = get(data, 'success')
msg = get(data, 'msg')
} }
break break
case types.SET: case types.SET:
{ {
const data = await browserStore.addSetItem({ const { success, msg } = await browserStore.addSetItem(server, db, keyName, value)
server, if (success) {
db, updated = true
key: keyName, $message.success(i18n.t('dialogue.handle_succ'))
value, } else {
reload: newForm.reload, $message.error(msg)
}) }
success = get(data, 'success')
msg = get(data, 'msg')
} }
break break
case types.ZSET: case types.ZSET:
{ {
const data = await browserStore.addZSetItem({ const { success, msg } = await browserStore.addZSetItem(server, db, keyName, newForm.opType, value)
server, if (success) {
db, updated = true
key: keyName, $message.success(i18n.t('dialogue.handle_succ'))
action: newForm.opType, } else {
vs: value, $message.error(msg)
reload: newForm.reload, }
})
success = get(data, 'success')
msg = get(data, 'msg')
} }
break break
case types.STREAM: case types.STREAM:
{ {
if (size(value) > 2) { if (size(value) > 2) {
const data = await browserStore.addStreamValue({ const { success, msg } = await browserStore.addStreamValue(
server, server,
db, db,
key: keyName, keyName,
id: value[0], value[0],
values: slice(value, 1), slice(value, 1),
reload: newForm.reload, )
}) if (success) {
success = get(data, 'success') updated = true
msg = get(data, 'msg') $message.success(i18n.t('dialogue.handle_succ'))
} else {
$message.error(msg)
}
} }
} }
break break
} }
if (success) { if (updated) {
$message.success(i18n.t('dialogue.handle_succ')) if (newForm.reload) {
} else if (!isEmpty(msg)) { browserStore.reloadKey({ server, db, key: keyName })
$message.error(msg) }
} }
dialogStore.closeAddFieldsDialog() dialogStore.closeAddFieldsDialog()
} catch (e) { } catch (e) {
$message.error(e.message) $message.error(e.message)
@ -216,7 +202,11 @@ const onClose = () => {
<n-scrollbar style="max-height: 500px"> <n-scrollbar style="max-height: 500px">
<n-form :model="newForm" :show-require-mark="false" label-placement="top" style="padding-right: 15px"> <n-form :model="newForm" :show-require-mark="false" label-placement="top" style="padding-right: 15px">
<n-form-item :label="$t('common.key')" path="key" required> <n-form-item :label="$t('common.key')" path="key" required>
<n-input v-model:value="newForm.key" placeholder="" readonly /> <n-input
v-model:value="newForm.key"
:input-props="{ spellcheck: 'false' }"
placeholder=""
readonly />
</n-form-item> </n-form-item>
<component <component
:is="addValueComponent[newForm.type]" :is="addValueComponent[newForm.type]"

View File

@ -271,6 +271,7 @@ const onClose = () => {
required> required>
<n-input <n-input
v-model:value="generalForm.name" v-model:value="generalForm.name"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.name_tip')" /> :placeholder="$t('dialogue.connection.name_tip')" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi <n-form-item-gi
@ -283,6 +284,7 @@ const onClose = () => {
<n-form-item-gi :label="$t('dialogue.connection.addr')" :span="24" path="addr" required> <n-form-item-gi :label="$t('dialogue.connection.addr')" :span="24" path="addr" required>
<n-input <n-input
v-model:value="generalForm.addr" v-model:value="generalForm.addr"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.addr_tip')" /> :placeholder="$t('dialogue.connection.addr_tip')" />
<n-text style="width: 40px; text-align: center">:</n-text> <n-text style="width: 40px; text-align: center">:</n-text>
<n-input-number <n-input-number
@ -294,6 +296,7 @@ const onClose = () => {
<n-form-item-gi :label="$t('dialogue.connection.pwd')" :span="12" path="password"> <n-form-item-gi :label="$t('dialogue.connection.pwd')" :span="12" path="password">
<n-input <n-input
v-model:value="generalForm.password" v-model:value="generalForm.password"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.pwd_tip')" :placeholder="$t('dialogue.connection.pwd_tip')"
show-password-on="click" show-password-on="click"
type="password" /> type="password" />
@ -301,6 +304,7 @@ const onClose = () => {
<n-form-item-gi :label="$t('dialogue.connection.usr')" :span="12" path="username"> <n-form-item-gi :label="$t('dialogue.connection.usr')" :span="12" path="username">
<n-input <n-input
v-model:value="generalForm.username" v-model:value="generalForm.username"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.usr_tip')" /> :placeholder="$t('dialogue.connection.usr_tip')" />
</n-form-item-gi> </n-form-item-gi>
</n-grid> </n-grid>
@ -322,6 +326,7 @@ const onClose = () => {
path="defaultFilter"> path="defaultFilter">
<n-input <n-input
v-model:value="generalForm.defaultFilter" v-model:value="generalForm.defaultFilter"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.advn.filter_tip')" /> :placeholder="$t('dialogue.connection.advn.filter_tip')" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi <n-form-item-gi
@ -330,6 +335,7 @@ const onClose = () => {
path="keySeparator"> path="keySeparator">
<n-input <n-input
v-model:value="generalForm.keySeparator" v-model:value="generalForm.keySeparator"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.advn.separator_tip')" /> :placeholder="$t('dialogue.connection.advn.separator_tip')" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi <n-form-item-gi
@ -386,6 +392,7 @@ const onClose = () => {
v-model:value="dbFilterList" v-model:value="dbFilterList"
:clearable="true" :clearable="true"
:disabled="generalForm.dbFilterType === 'none'" :disabled="generalForm.dbFilterType === 'none'"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.advn.dbfilter_input_tip')" :placeholder="$t('dialogue.connection.advn.dbfilter_input_tip')"
:show="false" :show="false"
:show-arrow="false" :show-arrow="false"
@ -464,6 +471,7 @@ const onClose = () => {
<n-form-item :label="$t('dialogue.connection.addr')" required> <n-form-item :label="$t('dialogue.connection.addr')" required>
<n-input <n-input
v-model:value="generalForm.ssh.addr" v-model:value="generalForm.ssh.addr"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.ssh.addr_tip')" /> :placeholder="$t('dialogue.connection.ssh.addr_tip')" />
<n-text style="width: 40px; text-align: center">:</n-text> <n-text style="width: 40px; text-align: center">:</n-text>
<n-input-number <n-input-number
@ -483,11 +491,13 @@ const onClose = () => {
:label="$t('dialogue.connection.usr')"> :label="$t('dialogue.connection.usr')">
<n-input <n-input
v-model:value="generalForm.ssh.username" v-model:value="generalForm.ssh.username"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.ssh.usr_tip')" /> :placeholder="$t('dialogue.connection.ssh.usr_tip')" />
</n-form-item> </n-form-item>
<n-form-item v-if="sshLoginType === 'pwd'" :label="$t('dialogue.connection.pwd')"> <n-form-item v-if="sshLoginType === 'pwd'" :label="$t('dialogue.connection.pwd')">
<n-input <n-input
v-model:value="generalForm.ssh.password" v-model:value="generalForm.ssh.password"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.ssh.pwd_tip')" :placeholder="$t('dialogue.connection.ssh.pwd_tip')"
show-password-on="click" show-password-on="click"
type="password" /> type="password" />
@ -501,6 +511,7 @@ const onClose = () => {
<n-form-item v-if="sshLoginType === 'pkfile'" :label="$t('dialogue.connection.ssh.passphrase')"> <n-form-item v-if="sshLoginType === 'pkfile'" :label="$t('dialogue.connection.ssh.passphrase')">
<n-input <n-input
v-model:value="generalForm.ssh.passphrase" v-model:value="generalForm.ssh.passphrase"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.ssh.passphrase_tip')" :placeholder="$t('dialogue.connection.ssh.passphrase_tip')"
show-password-on="click" show-password-on="click"
type="password" /> type="password" />
@ -524,6 +535,7 @@ const onClose = () => {
<n-input-group> <n-input-group>
<n-select <n-select
v-model:value="generalForm.sentinel.master" v-model:value="generalForm.sentinel.master"
:input-props="{ spellcheck: 'false' }"
:options="masterNameOptions" :options="masterNameOptions"
filterable filterable
tag /> tag />
@ -535,6 +547,7 @@ const onClose = () => {
<n-form-item :label="$t('dialogue.connection.sentinel.password')"> <n-form-item :label="$t('dialogue.connection.sentinel.password')">
<n-input <n-input
v-model:value="generalForm.sentinel.password" v-model:value="generalForm.sentinel.password"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.sentinel.pwd_tip')" :placeholder="$t('dialogue.connection.sentinel.pwd_tip')"
show-password-on="click" show-password-on="click"
type="password" /> type="password" />
@ -542,6 +555,7 @@ const onClose = () => {
<n-form-item :label="$t('dialogue.connection.sentinel.username')"> <n-form-item :label="$t('dialogue.connection.sentinel.username')">
<n-input <n-input
v-model:value="generalForm.sentinel.username" v-model:value="generalForm.sentinel.username"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.connection.sentinel.usr_tip')" /> :placeholder="$t('dialogue.connection.sentinel.usr_tip')" />
</n-form-item> </n-form-item>
</n-form> </n-form>

View File

@ -109,7 +109,11 @@ const onClose = () => {
v-if="!(deleteForm.key instanceof Array)" v-if="!(deleteForm.key instanceof Array)"
:label="$t('dialogue.key.key_expression')" :label="$t('dialogue.key.key_expression')"
required> required>
<n-input v-model:value="deleteForm.key" placeholder="" @input="resetAffected" /> <n-input
v-model:value="deleteForm.key"
:input-props="{ spellcheck: 'false' }"
placeholder=""
@input="resetAffected" />
</n-form-item> </n-form-item>
<!-- <n-form-item :label="$t('dialogue.key.async_delete')" required>--> <!-- <n-form-item :label="$t('dialogue.key.async_delete')" required>-->
<!-- <n-checkbox v-model:checked="deleteForm.async">--> <!-- <n-checkbox v-model:checked="deleteForm.async">-->

View File

@ -112,7 +112,7 @@ const onClose = () => {
:show-require-mark="false" :show-require-mark="false"
label-placement="top"> label-placement="top">
<n-form-item :label="$t('dialogue.group.name')" path="name" required> <n-form-item :label="$t('dialogue.group.name')" path="name" required>
<n-input v-model:value="groupForm.name" placeholder="" /> <n-input v-model:value="groupForm.name" :input-props="{ spellcheck: 'false' }" placeholder="" />
</n-form-item> </n-form-item>
</n-form> </n-form>
</n-modal> </n-modal>

View File

@ -85,6 +85,7 @@ const onClose = () => {
<template #trigger> <template #trigger>
<n-input <n-input
v-model:value="filterForm.pattern" v-model:value="filterForm.pattern"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.filter.filter_pattern')" :placeholder="$t('dialogue.filter.filter_pattern')"
clearable /> clearable />
</template> </template>

View File

@ -2,7 +2,7 @@
import { computed, h, reactive, ref, watch } from 'vue' import { computed, h, reactive, ref, watch } from 'vue'
import { types, typesColor } from '@/consts/support_redis_type.js' import { types, typesColor } from '@/consts/support_redis_type.js'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import { get, isEmpty, keys, map, trim } from 'lodash' import { get, isEmpty, keys, map } from 'lodash'
import NewStringValue from '@/components/new_value/NewStringValue.vue' import NewStringValue from '@/components/new_value/NewStringValue.vue'
import NewHashValue from '@/components/new_value/NewHashValue.vue' import NewHashValue from '@/components/new_value/NewHashValue.vue'
import NewListValue from '@/components/new_value/NewListValue.vue' import NewListValue from '@/components/new_value/NewListValue.vue'
@ -46,7 +46,7 @@ const options = computed(() => {
label: t, label: t,
})) }))
}) })
const newValueComponent = { const addValueComponent = {
[types.STRING]: NewStringValue, [types.STRING]: NewStringValue,
[types.HASH]: NewHashValue, [types.HASH]: NewHashValue,
[types.LIST]: NewListValue, [types.LIST]: NewListValue,
@ -100,10 +100,6 @@ const renderTypeLabel = (option) => {
) )
} }
const onChangeType = () => {
newForm.value = null
}
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const tabStore = useTabStore() const tabStore = useTabStore()
const onAdd = async () => { const onAdd = async () => {
@ -132,7 +128,7 @@ const onAdd = async () => {
const { success, msg, nodeKey } = await browserStore.setKey({ const { success, msg, nodeKey } = await browserStore.setKey({
server, server,
db, db,
key: trim(key), key,
keyType: type, keyType: type,
value, value,
ttl, ttl,
@ -140,7 +136,7 @@ const onAdd = async () => {
if (success) { if (success) {
// select current key // select current key
tabStore.setSelectedKeys(server, nodeKey) tabStore.setSelectedKeys(server, nodeKey)
browserStore.loadKeySummary({ server, db, key, clearValue: true }) browserStore.loadKeySummary({ server, db, key })
} else if (!isEmpty(msg)) { } else if (!isEmpty(msg)) {
$message.error(msg) $message.error(msg)
} }
@ -182,17 +178,17 @@ const onClose = () => {
label-placement="top" label-placement="top"
style="padding-right: 15px"> style="padding-right: 15px">
<n-form-item :label="$t('common.key')" path="key" required> <n-form-item :label="$t('common.key')" path="key" required>
<n-input v-model:value="newForm.key" placeholder="" /> <n-input v-model:value="newForm.key" :input-props="{ spellcheck: 'false' }" placeholder="" />
</n-form-item> </n-form-item>
<n-form-item :label="$t('dialogue.key.db_index')" path="db" required> <n-form-item :label="$t('dialogue.key.db_index')" path="db" required>
<n-select v-model:value="newForm.db" :options="dbOptions" filterable /> <n-select
v-model:value="newForm.db"
:input-props="{ spellcheck: 'false' }"
:options="dbOptions"
filterable />
</n-form-item> </n-form-item>
<n-form-item :label="$t('interface.type')" path="type" required> <n-form-item :label="$t('interface.type')" path="type" required>
<n-select <n-select v-model:value="newForm.type" :options="options" :render-label="renderTypeLabel" />
v-model:value="newForm.type"
:options="options"
:render-label="renderTypeLabel"
@update:value="onChangeType" />
</n-form-item> </n-form-item>
<n-form-item :label="$t('interface.ttl')" required> <n-form-item :label="$t('interface.ttl')" required>
<n-input-group> <n-input-group>
@ -210,7 +206,7 @@ const onClose = () => {
</n-button> </n-button>
</n-input-group> </n-input-group>
</n-form-item> </n-form-item>
<component :is="newValueComponent[newForm.type]" ref="subFormRef" v-model:value="newForm.value" /> <component :is="addValueComponent[newForm.type]" ref="subFormRef" v-model:value="newForm.value" />
<!-- TODO: Add import from txt file option --> <!-- TODO: Add import from txt file option -->
</n-form> </n-form>
</n-scrollbar> </n-scrollbar>

View File

@ -88,12 +88,14 @@ const onClose = () => {
<n-form-item-gi :label="$t('preferences.general.language')" :span="24" required> <n-form-item-gi :label="$t('preferences.general.language')" :span="24" required>
<n-select <n-select
v-model:value="prefStore.general.language" v-model:value="prefStore.general.language"
:input-props="{ spellcheck: 'false' }"
:options="prefStore.langOption" :options="prefStore.langOption"
filterable /> filterable />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('preferences.general.font')" :span="12" required> <n-form-item-gi :label="$t('preferences.general.font')" :span="12" required>
<n-select <n-select
v-model:value="prefStore.general.font" v-model:value="prefStore.general.font"
:input-props="{ spellcheck: 'false' }"
:options="prefStore.fontOption" :options="prefStore.fontOption"
filterable /> filterable />
</n-form-item-gi> </n-form-item-gi>
@ -104,7 +106,10 @@ const onClose = () => {
<n-input-number v-model:value="prefStore.general.scanSize" :min="1" /> <n-input-number v-model:value="prefStore.general.scanSize" :min="1" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('preferences.general.key_icon_style')" :span="12"> <n-form-item-gi :label="$t('preferences.general.key_icon_style')" :span="12">
<n-select v-model:value="prefStore.general.keyIconStyle" :options="keyOptions" /> <n-select
v-model:value="prefStore.general.keyIconStyle"
:input-props="{ spellcheck: 'false' }"
:options="keyOptions" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('preferences.general.proxy')" :span="24"> <n-form-item-gi :label="$t('preferences.general.proxy')" :span="24">
<n-space> <n-space>
@ -131,6 +136,7 @@ const onClose = () => {
<n-form-item-gi :label="$t('preferences.general.font')" :span="24" required> <n-form-item-gi :label="$t('preferences.general.font')" :span="24" required>
<n-select <n-select
v-model:value="prefStore.editor.font" v-model:value="prefStore.editor.font"
:input-props="{ spellcheck: 'false' }"
:options="prefStore.fontOption" :options="prefStore.fontOption"
filterable /> filterable />
</n-form-item-gi> </n-form-item-gi>

View File

@ -74,7 +74,7 @@ const onClose = () => {
label-align="left" label-align="left"
label-placement="top"> label-placement="top">
<n-form-item :label="$t('dialogue.key.new_name')" required> <n-form-item :label="$t('dialogue.key.new_name')" required>
<n-input v-model:value="renameForm.newKey" /> <n-input v-model:value="renameForm.newKey" :input-props="{ spellcheck: 'false' }" />
</n-form-item> </n-form-item>
</n-form> </n-form>
</n-modal> </n-modal>

View File

@ -80,7 +80,7 @@ const onConfirm = async () => {
transform-origin="center"> transform-origin="center">
<n-form :model="ttlForm" :show-require-mark="false" label-placement="top"> <n-form :model="ttlForm" :show-require-mark="false" label-placement="top">
<n-form-item :label="$t('common.key')"> <n-form-item :label="$t('common.key')">
<n-input :value="ttlForm.key" readonly> <n-input :input-props="{ spellcheck: 'false' }" :value="ttlForm.key" readonly>
<template #prefix> <template #prefix>
<n-icon v-if="!!ttlForm.keyCode" :component="Binary" size="20" /> <n-icon v-if="!!ttlForm.keyCode" :component="Binary" size="20" />
</template> </template>

View File

@ -65,6 +65,7 @@ const onUpdate = () => {
<template #default="{ value }"> <template #default="{ value }">
<n-input <n-input
v-model:value="value.value" v-model:value="value.value"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.field.enter_value')" :placeholder="$t('dialogue.field.enter_value')"
type="text" type="text"
@update:value="onUpdate" /> @update:value="onUpdate" />

View File

@ -41,7 +41,7 @@ defineExpose({
<template> <template>
<n-form-item label="ID"> <n-form-item label="ID">
<n-input v-model:value="id" /> <n-input v-model:value="id" :input-props="{ spellcheck: 'false' }" />
</n-form-item> </n-form-item>
<n-form-item :label="$t('common.field') + ':' + $t('common.value')" required> <n-form-item :label="$t('common.field') + ':' + $t('common.value')" required>
<n-dynamic-input <n-dynamic-input

View File

@ -9,6 +9,7 @@ const emit = defineEmits(['update:value'])
<template> <template>
<n-form-item :label="$t('common.value')"> <n-form-item :label="$t('common.value')">
<n-input <n-input
:input-props="{ spellcheck: 'false' }"
:rows="6" :rows="6"
:value="props.value" :value="props.value"
placeholder="" placeholder=""

View File

@ -46,6 +46,7 @@ defineExpose({
<template #default="{ value }"> <template #default="{ value }">
<n-input <n-input
v-model:value="value.value" v-model:value="value.value"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('dialogue.field.enter_member')" :placeholder="$t('dialogue.field.enter_member')"
type="text" type="text"
@update:value="onUpdate" /> @update:value="onUpdate" />

View File

@ -166,7 +166,7 @@ const handleSelectDB = async (db) => {
await browserStore.openDatabase(props.server, db) await browserStore.openDatabase(props.server, db)
await nextTick() await nextTick()
await connectionStore.saveLastDB(props.server, db) await connectionStore.saveLastDB(props.server, db)
tabStore.upsertTab({ server: props.server, db, clearValue: true }) tabStore.upsertTab({ server: props.server, db })
// browserTreeRef.value?.resetExpandKey(props.server, db) // browserTreeRef.value?.resetExpandKey(props.server, db)
fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db) fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db)
browserTreeRef.value?.refreshTree() browserTreeRef.value?.refreshTree()
@ -290,6 +290,7 @@ onMounted(() => onReload())
<n-select <n-select
:consistent-menu-width="false" :consistent-menu-width="false"
:filter="(pattern, option) => option.value.toString() === pattern" :filter="(pattern, option) => option.value.toString() === pattern"
:input-props="{ spellcheck: 'false' }"
:options="dbSelectOptions" :options="dbSelectOptions"
:value="props.db" :value="props.db"
filterable filterable

View File

@ -288,7 +288,6 @@ const onUpdateSelectedKeys = (keys, options) => {
server: props.server, server: props.server,
db, db,
key: redisKey, key: redisKey,
clearValue: true,
}) })
} }
return return

View File

@ -33,7 +33,11 @@ const filterPattern = ref('')
stroke-width="4" stroke-width="4"
t-tooltip="interface.new_group" t-tooltip="interface.new_group"
@click="dialogStore.openNewGroupDialog()" /> @click="dialogStore.openNewGroupDialog()" />
<n-input v-model:value="filterPattern" :placeholder="$t('interface.filter')" clearable> <n-input
v-model:value="filterPattern"
:input-props="{ spellcheck: 'false' }"
:placeholder="$t('interface.filter')"
clearable>
<template #prefix> <template #prefix>
<n-icon :component="Filter" size="20" /> <n-icon :component="Filter" size="20" />
</template> </template>

View File

@ -413,10 +413,9 @@ const useBrowserStore = defineStore('browser', {
* @param {string} server * @param {string} server
* @param {number} db * @param {number} db
* @param {string|number[]} [key] null or blank indicate that update tab to display normal content (blank content or server status) * @param {string|number[]} [key] null or blank indicate that update tab to display normal content (blank content or server status)
* @param {boolean} [clearValue]
* @return {Promise<void>} * @return {Promise<void>}
*/ */
async loadKeySummary({ server, db, key, clearValue }) { async loadKeySummary({ server, db, key }) {
try { try {
const tab = useTabStore() const tab = useTabStore()
if (!isEmpty(key)) { if (!isEmpty(key)) {
@ -439,7 +438,6 @@ const useBrowserStore = defineStore('browser', {
key: k, key: k,
size, size,
length, length,
clearValue,
}) })
return return
} else { } else {
@ -460,9 +458,9 @@ const useBrowserStore = defineStore('browser', {
ttl: -1, ttl: -1,
key: null, key: null,
keyCode: null, keyCode: null,
value: null,
size: 0, size: 0,
length: 0, length: 0,
clearValue,
}) })
} catch (e) { } catch (e) {
$message.error('') $message.error('')
@ -513,7 +511,7 @@ const useBrowserStore = defineStore('browser', {
const tab = useTabStore() const tab = useTabStore()
try { try {
tab.updateLoading({ server, db, loading: true }) tab.updateLoading({ server, db, loading: true })
await this.loadKeySummary({ server, db, key, clearValue: true }) await this.loadKeySummary({ server, db, key })
await this.loadKeyDetail({ server, db, key, decode, format, matchPattern, reset: true }) await this.loadKeyDetail({ server, db, key, decode, format, matchPattern, reset: true })
} finally { } finally {
tab.updateLoading({ server, db, loading: false }) tab.updateLoading({ server, db, loading: false })
@ -1067,8 +1065,6 @@ const useBrowserStore = defineStore('browser', {
} }
const tab = useTabStore() const tab = useTabStore()
tab.updateValue({ server, db, key, value }) tab.updateValue({ server, db, key, value })
this.loadKeySummary({ server, db, key })
return { return {
success, success,
nodeKey: `${server}/db${db}#${ConnectionType.RedisValue}/${key}`, nodeKey: `${server}/db${db}#${ConnectionType.RedisValue}/${key}`,
@ -1100,7 +1096,6 @@ const useBrowserStore = defineStore('browser', {
* @param {formatTypes} [retFormat] * @param {formatTypes} [retFormat]
* @param {boolean} [refresh] * @param {boolean} [refresh]
* @param {number} [index] index for retrieve affect entries quickly * @param {number} [index] index for retrieve affect entries quickly
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>} * @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
*/ */
async setHash({ async setHash({
@ -1115,7 +1110,6 @@ const useBrowserStore = defineStore('browser', {
retDecode, retDecode,
retFormat, retFormat,
index, index,
reload,
}) { }) {
try { try {
const { data, success, msg } = await SetHashValue({ const { data, success, msg } = await SetHashValue({
@ -1156,12 +1150,6 @@ const useBrowserStore = defineStore('browser', {
index: [index], index: [index],
}) })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success, updated } return { success, updated }
} else { } else {
return { success, msg } return { success, msg }
@ -1178,10 +1166,9 @@ const useBrowserStore = defineStore('browser', {
* @param {string|number[]} key * @param {string|number[]} key
* @param {number }action 0:ignore duplicated fields 1:overwrite duplicated fields * @param {number }action 0:ignore duplicated fields 1:overwrite duplicated fields
* @param {string[]} fieldItems field1, value1, filed2, value2... * @param {string[]} fieldItems field1, value1, filed2, value2...
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean, [updated]: [], [added]: []}>} * @returns {Promise<{[msg]: string, success: boolean, [updated]: [], [added]: []}>}
*/ */
async addHashField({ server, db, key, action, fieldItems, reload }) { async addHashField(server, db, key, action, fieldItems) {
try { try {
const { data, success, msg } = await AddHashField(server, db, key, action, fieldItems) const { data, success, msg } = await AddHashField(server, db, key, action, fieldItems)
if (success) { if (success) {
@ -1193,12 +1180,6 @@ const useBrowserStore = defineStore('browser', {
if (!isEmpty(added)) { if (!isEmpty(added)) {
tab.insertValueEntries({ server, db, key, type: 'hash', entries: added }) tab.insertValueEntries({ server, db, key, type: 'hash', entries: added })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success, updated, added } return { success, updated, added }
} else { } else {
return { success: false, msg } return { success: false, msg }
@ -1214,10 +1195,9 @@ const useBrowserStore = defineStore('browser', {
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {string} field * @param {string} field
* @param {boolean} reload
* @returns {Promise<{[msg]: {}, success: boolean, [removed]: string[]}>} * @returns {Promise<{[msg]: {}, success: boolean, [removed]: string[]}>}
*/ */
async removeHashField({ server, db, key, field, reload }) { async removeHashField(server, db, key, field) {
try { try {
const { data, success, msg } = await SetHashValue({ server, db, key, field, newField: '' }) const { data, success, msg } = await SetHashValue({ server, db, key, field, newField: '' })
if (success) { if (success) {
@ -1226,12 +1206,6 @@ const useBrowserStore = defineStore('browser', {
// const tab = useTabStore() // const tab = useTabStore()
// tab.removeValueEntries({ server, db, key, type: 'hash', entries: removed }) // tab.removeValueEntries({ server, db, key, type: 'hash', entries: removed })
// } // }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success, removed } return { success, removed }
} else { } else {
return { success, msg } return { success, msg }
@ -1241,16 +1215,32 @@ const useBrowserStore = defineStore('browser', {
} }
}, },
/**
* insert list item
* @param {string} connName
* @param {number} db
* @param {string|number[]} key
* @param {int} action 0: push to head, 1: push to tail
* @param {string[]}values
* @returns {Promise<*|{msg, success: boolean}>}
*/
async addListItem(connName, db, key, action, values) {
try {
return AddListItem(connName, db, key, action, values)
} catch (e) {
return { success: false, msg: e.message }
}
},
/** /**
* prepend item to head of list * prepend item to head of list
* @param {string} server * @param {string} server
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {string[]} values * @param {string[]} values
* @param {boolean} reload
* @returns {Promise<{[msg]: string, success: boolean, [item]: []}>} * @returns {Promise<{[msg]: string, success: boolean, [item]: []}>}
*/ */
async prependListItem({ server, db, key, values, reload }) { async prependListItem({ server, db, key, values }) {
try { try {
const { data, success, msg } = await AddListItem(server, db, key, 0, values) const { data, success, msg } = await AddListItem(server, db, key, 0, values)
if (success) { if (success) {
@ -1265,12 +1255,6 @@ const useBrowserStore = defineStore('browser', {
entries: left, entries: left,
prepend: true, prepend: true,
}) })
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
} }
return { success, item: left } return { success, item: left }
} else { } else {
@ -1287,10 +1271,9 @@ const useBrowserStore = defineStore('browser', {
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {string[]} values * @param {string[]} values
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean, [item]: any[]}>} * @returns {Promise<{[msg]: string, success: boolean, [item]: any[]}>}
*/ */
async appendListItem({ server, db, key, values, reload }) { async appendListItem({ server, db, key, values }) {
try { try {
const { data, success, msg } = await AddListItem(server, db, key, 1, values) const { data, success, msg } = await AddListItem(server, db, key, 1, values)
if (success) { if (success) {
@ -1306,12 +1289,6 @@ const useBrowserStore = defineStore('browser', {
entries: right, entries: right,
prepend: false, prepend: false,
}) })
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
} }
return { success, item: right } return { success, item: right }
} else { } else {
@ -1333,7 +1310,6 @@ const useBrowserStore = defineStore('browser', {
* @param {formatTypes} format * @param {formatTypes} format
* @param {decodeTypes} [retDecode] * @param {decodeTypes} [retDecode]
* @param {formatTypes} [retFormat] * @param {formatTypes} [retFormat]
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async updateListItem({ async updateListItem({
@ -1346,7 +1322,6 @@ const useBrowserStore = defineStore('browser', {
format = formatTypes.RAW, format = formatTypes.RAW,
retDecode, retDecode,
retFormat, retFormat,
reload,
}) { }) {
try { try {
const { data, success, msg } = await SetListItem({ const { data, success, msg } = await SetListItem({
@ -1383,12 +1358,6 @@ const useBrowserStore = defineStore('browser', {
entries: removedIndex, entries: removedIndex,
}) })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success } return { success }
} else { } else {
return { success, msg } return { success, msg }
@ -1404,10 +1373,9 @@ const useBrowserStore = defineStore('browser', {
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {number} index * @param {number} index
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean, [removed]: string[]}>} * @returns {Promise<{[msg]: string, success: boolean, [removed]: string[]}>}
*/ */
async removeListItem({ server, db, key, index, reload }) { async removeListItem(server, db, key, index) {
try { try {
const { data, success, msg } = await SetListItem({ server, db, key, index }) const { data, success, msg } = await SetListItem({ server, db, key, index })
if (success) { if (success) {
@ -1422,12 +1390,6 @@ const useBrowserStore = defineStore('browser', {
type: 'list', type: 'list',
entries: removedIndexes, entries: removedIndexes,
}) })
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
} }
return { success, removed } return { success, removed }
} else { } else {
@ -1444,10 +1406,9 @@ const useBrowserStore = defineStore('browser', {
* @param {number} db * @param {number} db
* @param {string|number} key * @param {string|number} key
* @param {string|string[]} value * @param {string|string[]} value
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async addSetItem({ server, db, key, value, reload }) { async addSetItem(server, db, key, value) {
try { try {
if ((!value) instanceof Array) { if ((!value) instanceof Array) {
value = [value] value = [value]
@ -1459,12 +1420,6 @@ const useBrowserStore = defineStore('browser', {
const tab = useTabStore() const tab = useTabStore()
tab.insertValueEntries({ server, db, key, type: 'set', entries: added }) tab.insertValueEntries({ server, db, key, type: 'set', entries: added })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success } return { success }
} else { } else {
return { success, msg } return { success, msg }
@ -1485,7 +1440,6 @@ const useBrowserStore = defineStore('browser', {
* @param {formatTypes} [format] * @param {formatTypes} [format]
* @param {decodeTypes} [retDecode] * @param {decodeTypes} [retDecode]
* @param {formatTypes} [retFormat] * @param {formatTypes} [retFormat]
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async updateSetItem({ async updateSetItem({
@ -1498,7 +1452,6 @@ const useBrowserStore = defineStore('browser', {
format = formatTypes.RAW, format = formatTypes.RAW,
retDecode, retDecode,
retFormat, retFormat,
reload,
}) { }) {
try { try {
const { data, success, msg } = await UpdateSetItem({ const { data, success, msg } = await UpdateSetItem({
@ -1522,12 +1475,6 @@ const useBrowserStore = defineStore('browser', {
if (!isEmpty(added)) { if (!isEmpty(added)) {
tab.insertValueEntries({ server, db, key, type: 'set', entries: added }) tab.insertValueEntries({ server, db, key, type: 'set', entries: added })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success } return { success }
} else { } else {
return { success: false, msg } return { success: false, msg }
@ -1543,10 +1490,9 @@ const useBrowserStore = defineStore('browser', {
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {string} value * @param {string} value
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async removeSetItem({ server, db, key, value, reload }) { async removeSetItem(server, db, key, value) {
try { try {
const { data, success, msg } = await SetSetItem(server, db, key, true, [value]) const { data, success, msg } = await SetSetItem(server, db, key, true, [value])
if (success) { if (success) {
@ -1556,12 +1502,6 @@ const useBrowserStore = defineStore('browser', {
const removedValues = map(removed, 'v') const removedValues = map(removed, 'v')
tab.removeValueEntries({ server, db, key, type: 'set', entries: removedValues }) tab.removeValueEntries({ server, db, key, type: 'set', entries: removedValues })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success } return { success }
} else { } else {
return { success, msg } return { success, msg }
@ -1578,10 +1518,9 @@ const useBrowserStore = defineStore('browser', {
* @param {string|number[]} key * @param {string|number[]} key
* @param {number} action * @param {number} action
* @param {Object.<string, number>} vs value: score * @param {Object.<string, number>} vs value: score
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async addZSetItem({ server, db, key, action, vs, reload }) { async addZSetItem(server, db, key, action, vs) {
try { try {
const { data, success, msg } = await AddZSetValue(server, db, key, action, vs) const { data, success, msg } = await AddZSetValue(server, db, key, action, vs)
if (success) { if (success) {
@ -1593,12 +1532,6 @@ const useBrowserStore = defineStore('browser', {
if (!isEmpty(updated)) { if (!isEmpty(updated)) {
tab.updateValueEntries({ server, db, key, type: 'zset', entries: updated }) tab.updateValueEntries({ server, db, key, type: 'zset', entries: updated })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success } return { success }
} else { } else {
return { success, msg } return { success, msg }
@ -1621,7 +1554,6 @@ const useBrowserStore = defineStore('browser', {
* @param {decodeTypes} [retDecode] * @param {decodeTypes} [retDecode]
* @param {formatTypes} [retFormat] * @param {formatTypes} [retFormat]
* @param {number} [index] index for retrieve affect entries quickly * @param {number} [index] index for retrieve affect entries quickly
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async updateZSetItem({ async updateZSetItem({
@ -1636,7 +1568,6 @@ const useBrowserStore = defineStore('browser', {
retDecode, retDecode,
retFormat, retFormat,
index, index,
reload,
}) { }) {
try { try {
const { data, success, msg } = await UpdateZSetValue({ const { data, success, msg } = await UpdateZSetValue({
@ -1667,12 +1598,6 @@ const useBrowserStore = defineStore('browser', {
if (!isEmpty(replaced)) { if (!isEmpty(replaced)) {
tab.replaceValueEntries({ server, db, key, type: 'zset', entries: replaced, index: [index] }) tab.replaceValueEntries({ server, db, key, type: 'zset', entries: replaced, index: [index] })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success, updated, removed } return { success, updated, removed }
} else { } else {
return { success, msg } return { success, msg }
@ -1688,10 +1613,9 @@ const useBrowserStore = defineStore('browser', {
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {string} value * @param {string} value
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean, [removed]: []}>} * @returns {Promise<{[msg]: string, success: boolean, [removed]: []}>}
*/ */
async removeZSetItem({ server, db, key, value, reload }) { async removeZSetItem(server, db, key, value) {
try { try {
const { data, success, msg } = await UpdateZSetValue({ server, db, key, value, newValue: '', score: 0 }) const { data, success, msg } = await UpdateZSetValue({ server, db, key, value, newValue: '', score: 0 })
if (success) { if (success) {
@ -1701,12 +1625,6 @@ const useBrowserStore = defineStore('browser', {
const removeValues = map(removed, 'v') const removeValues = map(removed, 'v')
tab.removeValueEntries({ server, db, key, type: 'zset', entries: removeValues }) tab.removeValueEntries({ server, db, key, type: 'zset', entries: removeValues })
} }
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success, removed } return { success, removed }
} else { } else {
return { success, msg } return { success, msg }
@ -1723,10 +1641,9 @@ const useBrowserStore = defineStore('browser', {
* @param {string|number[]} key * @param {string|number[]} key
* @param {string} id * @param {string} id
* @param {string[]} values field1, value1, filed2, value2... * @param {string[]} values field1, value1, filed2, value2...
* @param {boolean} [reload]
* @returns {Promise<{[msg]: string, success: boolean}>} * @returns {Promise<{[msg]: string, success: boolean}>}
*/ */
async addStreamValue({ server, db, key, id, values, reload }) { async addStreamValue(server, db, key, id, values) {
try { try {
const { data = {}, success, msg } = await AddStreamValue(server, db, key, id, values) const { data = {}, success, msg } = await AddStreamValue(server, db, key, id, values)
if (success) { if (success) {
@ -1740,12 +1657,6 @@ const useBrowserStore = defineStore('browser', {
type: 'stream', type: 'stream',
entries: added, entries: added,
}) })
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
} }
return { success } return { success }
} else { } else {
@ -1758,28 +1669,21 @@ const useBrowserStore = defineStore('browser', {
/** /**
* remove stream field * remove stream field
* @param {string} server * @param {string} connName
* @param {number} db * @param {number} db
* @param {string|number[]} key * @param {string|number[]} key
* @param {string[]|string} ids * @param {string[]|string} ids
* @param {boolean} [reload]
* @returns {Promise<{[msg]: {}, success: boolean}>} * @returns {Promise<{[msg]: {}, success: boolean}>}
*/ */
async removeStreamValues({ server, db, key, ids, reload }) { async removeStreamValues(connName, db, key, ids) {
if (typeof ids === 'string') { if (typeof ids === 'string') {
ids = [ids] ids = [ids]
} }
try { try {
const { data = {}, success, msg } = await RemoveStreamValues(server, db, key, ids) const { data = {}, success, msg } = await RemoveStreamValues(connName, db, key, ids)
if (success) { if (success) {
const tab = useTabStore() const tab = useTabStore()
tab.removeValueEntries({ server, db, key, type: 'stream', entries: ids }) tab.removeValueEntries({ server: connName, db, key, type: 'stream', entries: ids })
if (reload === true) {
this.reloadKey({ server, db, key })
} else {
// reload summary only
this.loadKeySummary({ server, db, key })
}
return { success } return { success }
} else { } else {
return { success, msg } return { success, msg }

View File

@ -162,7 +162,7 @@ const useTabStore = defineStore('tab', {
}, },
openBlank(server) { openBlank(server) {
this.upsertTab({ server, clearValue: true }) this.upsertTab({ server })
}, },
/** /**
@ -177,10 +177,9 @@ const useTabStore = defineStore('tab', {
* @param {number} [size] * @param {number} [size]
* @param {number} [length] * @param {number} [length]
* @param {string} [matchPattern] * @param {string} [matchPattern]
* @param {boolean} [clearValue]
* @param {*} [value] * @param {*} [value]
*/ */
upsertTab({ subTab, server, db, type, ttl, key, keyCode, size, length, matchPattern = '', clearValue }) { upsertTab({ subTab, server, db, type, ttl, key, keyCode, size, length, matchPattern = '' }) {
let tabIndex = findIndex(this.tabList, { name: server }) let tabIndex = findIndex(this.tabList, { name: server })
if (tabIndex === -1) { if (tabIndex === -1) {
this.tabList.push({ this.tabList.push({
@ -214,9 +213,7 @@ const useTabStore = defineStore('tab', {
tab.size = size tab.size = size
tab.length = length tab.length = length
tab.matchPattern = matchPattern tab.matchPattern = matchPattern
if (clearValue === true) { tab.value = undefined
tab.value = undefined
}
} }
this._setActivatedIndex(tabIndex, true, subTab) this._setActivatedIndex(tabIndex, true, subTab)
// this.activatedTab = tab.name // this.activatedTab = tab.name
@ -227,16 +224,14 @@ const useTabStore = defineStore('tab', {
* @param {string} server * @param {string} server
* @param {number} db * @param {number} db
* @param {string} key * @param {string} key
* @param {*} [value] * @param {*} value
* @param {string} [format] * @param {string} [format]
* @param {string] [decode] * @param {string] [decode]
* @param {string} [matchPattern] * @param {string} [matchPattern]
* @param {boolean} [reset] * @param {boolean} [reset]
* @param {boolean} [end] keep end status if not set * @param {boolean} [end] keep end status if not set
* @param {number} [size]
* @param {number} [length]
*/ */
updateValue({ server, db, key, value, format, decode, matchPattern, reset, end, size = -1, length = -1 }) { updateValue({ server, db, key, value, format, decode, matchPattern, reset, end }) {
const tabData = find(this.tabList, { name: server, db, key }) const tabData = find(this.tabList, { name: server, db, key })
if (tabData == null) { if (tabData == null) {
return return
@ -245,12 +240,6 @@ const useTabStore = defineStore('tab', {
tabData.format = format || tabData.format tabData.format = format || tabData.format
tabData.decode = decode || tabData.decode tabData.decode = decode || tabData.decode
tabData.matchPattern = matchPattern || '' tabData.matchPattern = matchPattern || ''
if (size >= 0) {
tabData.size = size
}
if (length >= 0) {
tabData.length = length
}
if (typeof end === 'boolean') { if (typeof end === 'boolean') {
tabData.end = end tabData.end = end
} }

View File

@ -15,9 +15,3 @@
.tab-content { .tab-content {
} }
:deep(.cmd-line) {
word-wrap: break-word;
white-space: pre-wrap;
word-break: break-all;
}

View File

@ -73,14 +73,9 @@ func main() {
services.GA().Startup(version) services.GA().Startup(version)
}, },
OnDomReady: func(ctx context.Context) { OnDomReady: func(ctx context.Context) {
runtime2.WindowShow(ctx)
x, y := prefSvc.GetWindowPosition(ctx) x, y := prefSvc.GetWindowPosition(ctx)
runtime2.WindowSetPosition(ctx, x, y) runtime2.WindowSetPosition(ctx, x, y)
runtime2.WindowShow(ctx)
},
OnBeforeClose: func(ctx context.Context) (prevent bool) {
x, y := runtime2.WindowGetPosition(ctx)
prefSvc.SaveWindowPosition(x, y)
return false
}, },
OnShutdown: func(ctx context.Context) { OnShutdown: func(ctx context.Context) {
browserSvc.Stop() browserSvc.Stop()