Compare commits

..

No commits in common. "23087a53745ae2b9d54afdc01326b02f3e913f88" and "84b73bd5e7ab1012442dd70ce33a9371abc7cc05" have entirely different histories.

22 changed files with 198 additions and 286 deletions

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import ContentPane from './components/content/ContentPane.vue' import ContentPane from './components/content/ContentPane.vue'
import BrowserPane from './components/sidebar/BrowserPane.vue' import BrowserPane from './components/sidebar/BrowserPane.vue'
import { computed, onMounted, reactive, ref, watchEffect } from 'vue' import { computed, onMounted, reactive, ref, watch } from 'vue'
import { debounce } from 'lodash' import { debounce } from 'lodash'
import { useThemeVars } from 'naive-ui' import { useThemeVars } from 'naive-ui'
import Ribbon from './components/sidebar/Ribbon.vue' import Ribbon from './components/sidebar/Ribbon.vue'
@ -43,11 +43,14 @@ const handleResize = () => {
saveSidebarWidth() saveSidebarWidth()
} }
watchEffect(() => { watch(
if (tabStore.nav === 'log') { () => tabStore.nav,
logPaneRef.value?.refresh() (nav) => {
} if (nav === 'log') {
}) logPaneRef.value?.refresh()
}
},
)
const logoWrapperWidth = computed(() => { const logoWrapperWidth = computed(() => {
return `${data.navMenuWidth + prefStore.behavior.asideWidth - 4}px` return `${data.navMenuWidth + prefStore.behavior.asideWidth - 4}px`

View File

@ -90,7 +90,6 @@ defineExpose({
v-model:value="inputData.filter" v-model:value="inputData.filter"
:placeholder="$t('interface.filter')" :placeholder="$t('interface.filter')"
:size="props.small ? 'small' : ''" :size="props.small ? 'small' : ''"
:theme-overrides="{ paddingSmall: '0 3px', paddingMedium: '0 6px' }"
clearable clearable
@clear="onClearFilter" @clear="onClearFilter"
@input="onInput" @input="onInput"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, reactive, watchEffect } from 'vue' import { computed, reactive, watch } from 'vue'
import { types } from '@/consts/support_redis_type.js' import { types } from '@/consts/support_redis_type.js'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import NewStringValue from '@/components/new_value/NewStringValue.vue' import NewStringValue from '@/components/new_value/NewStringValue.vue'
@ -63,18 +63,21 @@ const title = computed(() => {
}) })
const dialogStore = useDialog() const dialogStore = useDialog()
watchEffect(() => { watch(
if (dialogStore.addFieldsDialogVisible) { () => dialogStore.addFieldsDialogVisible,
const { server, db, key, keyCode, type } = dialogStore.addFieldParam (visible) => {
newForm.server = server if (visible) {
newForm.db = db const { server, db, key, keyCode, type } = dialogStore.addFieldParam
newForm.key = key newForm.server = server
newForm.keyCode = keyCode newForm.db = db
newForm.type = type newForm.key = key
newForm.opType = 0 newForm.keyCode = keyCode
newForm.value = null newForm.type = type
} newForm.opType = 0
}) newForm.value = null
}
},
)
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const tab = useTabStore() const tab = useTabStore()
@ -219,7 +222,7 @@ const onClose = () => {
:is="addValueComponent[newForm.type]" :is="addValueComponent[newForm.type]"
v-model:type="newForm.opType" v-model:type="newForm.opType"
v-model:value="newForm.value" /> v-model:value="newForm.value" />
<n-form-item :show-label="false" path="key" required> <n-form-item label=" " path="key" required>
<n-checkbox v-model:checked="newForm.reload"> <n-checkbox v-model:checked="newForm.reload">
{{ $t('dialogue.field.reload_when_succ') }} {{ $t('dialogue.field.reload_when_succ') }}
</n-checkbox> </n-checkbox>

View File

@ -289,7 +289,6 @@ const onClose = () => {
v-model:value="generalForm.port" v-model:value="generalForm.port"
:max="65535" :max="65535"
:min="1" :min="1"
:show-button="false"
style="width: 200px" /> style="width: 200px" />
</n-form-item-gi> </n-form-item-gi>
<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">
@ -337,12 +336,7 @@ const onClose = () => {
:label="$t('dialogue.connection.advn.conn_timeout')" :label="$t('dialogue.connection.advn.conn_timeout')"
:span="12" :span="12"
path="connTimeout"> path="connTimeout">
<n-input-number <n-input-number v-model:value="generalForm.connTimeout" :max="999999" :min="1">
v-model:value="generalForm.connTimeout"
:max="999999"
:min="1"
:show-button="false"
style="width: 100%">
<template #suffix> <template #suffix>
{{ $t('common.second') }} {{ $t('common.second') }}
</template> </template>
@ -352,12 +346,7 @@ const onClose = () => {
:label="$t('dialogue.connection.advn.exec_timeout')" :label="$t('dialogue.connection.advn.exec_timeout')"
:span="12" :span="12"
path="execTimeout"> path="execTimeout">
<n-input-number <n-input-number v-model:value="generalForm.execTimeout" :max="999999" :min="1">
v-model:value="generalForm.execTimeout"
:max="999999"
:min="1"
:show-button="false"
style="width: 100%">
<template #suffix> <template #suffix>
{{ $t('common.second') }} {{ $t('common.second') }}
</template> </template>
@ -374,11 +363,7 @@ const onClose = () => {
</n-radio-group> </n-radio-group>
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('dialogue.connection.advn.load_size')" :span="12"> <n-form-item-gi :label="$t('dialogue.connection.advn.load_size')" :span="12">
<n-input-number <n-input-number v-model:value="generalForm.loadSize" :min="0" />
v-model:value="generalForm.loadSize"
:min="0"
:show-button="false"
style="width: 100%" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('dialogue.connection.advn.dbfilter_type')" :span="24"> <n-form-item-gi :label="$t('dialogue.connection.advn.dbfilter_type')" :span="24">
<n-radio-group <n-radio-group
@ -485,7 +470,6 @@ const onClose = () => {
v-model:value="generalForm.ssh.port" v-model:value="generalForm.ssh.port"
:max="65535" :max="65535"
:min="1" :min="1"
:show-button="false"
style="width: 200px" /> style="width: 200px" />
</n-form-item> </n-form-item>
<n-form-item :label="$t('dialogue.connection.ssh.login_type')"> <n-form-item :label="$t('dialogue.connection.ssh.login_type')">

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, nextTick, reactive, ref, watchEffect } from 'vue' import { computed, nextTick, reactive, ref, watch } from 'vue'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { isEmpty, map, size } from 'lodash' import { isEmpty, map, size } from 'lodash'
@ -18,26 +18,28 @@ const deleteForm = reactive({
const dialogStore = useDialog() const dialogStore = useDialog()
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
watch(
watchEffect(() => { () => dialogStore.deleteKeyDialogVisible,
if (dialogStore.deleteKeyDialogVisible) { (visible) => {
const { server, db, key } = dialogStore.deleteKeyParam if (visible) {
deleteForm.server = server const { server, db, key } = dialogStore.deleteKeyParam
deleteForm.db = db deleteForm.server = server
deleteForm.key = key deleteForm.db = db
deleteForm.loadingAffected = false deleteForm.key = key
// deleteForm.async = true deleteForm.loadingAffected = false
loading.value = false // deleteForm.async = true
deleting.value = false loading.value = false
if (key instanceof Array) { deleting.value = false
deleteForm.showAffected = true if (key instanceof Array) {
deleteForm.affectedKeys = key deleteForm.showAffected = true
} else { deleteForm.affectedKeys = key
deleteForm.showAffected = false } else {
deleteForm.affectedKeys = [] deleteForm.showAffected = false
deleteForm.affectedKeys = []
}
} }
} },
}) )
const loading = ref(false) const loading = ref(false)
const deleting = ref(false) const deleting = ref(false)

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { reactive, ref, watchEffect } from 'vue' import { reactive, ref, watch } from 'vue'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import useBrowserStore from 'stores/browser.js' import useBrowserStore from 'stores/browser.js'
@ -14,17 +14,19 @@ const flushForm = reactive({
const dialogStore = useDialog() const dialogStore = useDialog()
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
watch(
watchEffect(() => { () => dialogStore.flushDBDialogVisible,
if (dialogStore.flushDBDialogVisible) { (visible) => {
const { server, db } = dialogStore.flushDBParam if (visible) {
flushForm.server = server const { server, db } = dialogStore.flushDBParam
flushForm.db = db flushForm.server = server
flushForm.async = true flushForm.db = db
flushForm.confirm = false flushForm.async = true
loading.value = false flushForm.confirm = false
} loading.value = false
}) }
},
)
const loading = ref(false) const loading = ref(false)
const i18n = useI18n() const i18n = useI18n()

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, reactive, ref, watchEffect } from 'vue' import { computed, reactive, ref, watch } from 'vue'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import useConnectionStore from 'stores/connections.js' import useConnectionStore from 'stores/connections.js'
@ -36,11 +36,14 @@ const isRenameMode = computed(() => !isEmpty(editGroup.value))
const dialogStore = useDialog() const dialogStore = useDialog()
const connectionStore = useConnectionStore() const connectionStore = useConnectionStore()
watchEffect(() => { watch(
if (dialogStore.groupDialogVisible) { () => dialogStore.groupDialogVisible,
groupForm.name = editGroup.value = dialogStore.editGroup (visible) => {
} if (visible) {
}) groupForm.name = editGroup.value = dialogStore.editGroup
}
},
)
const i18n = useI18n() const i18n = useI18n()
const onConfirm = async () => { const onConfirm = async () => {

View File

@ -10,7 +10,6 @@ const importKeyForm = reactive({
server: '', server: '',
db: 0, db: 0,
expire: true, expire: true,
reload: true,
file: '', file: '',
type: 0, type: 0,
conflict: 0, conflict: 0,
@ -26,7 +25,6 @@ watchEffect(() => {
importKeyForm.server = server importKeyForm.server = server
importKeyForm.db = db importKeyForm.db = db
importKeyForm.expire = true importKeyForm.expire = true
importKeyForm.reload = true
importKeyForm.file = '' importKeyForm.file = ''
importKeyForm.type = 0 importKeyForm.type = 0
importKeyForm.conflict = 0 importKeyForm.conflict = 0
@ -35,7 +33,7 @@ watchEffect(() => {
}) })
const i18n = useI18n() const i18n = useI18n()
const conflictOption = computed(() => [ const conflictOption = [
{ {
value: 0, value: 0,
label: i18n.t('dialogue.import.conflict_overwrite'), label: i18n.t('dialogue.import.conflict_overwrite'),
@ -44,7 +42,7 @@ const conflictOption = computed(() => [
value: 1, value: 1,
label: i18n.t('dialogue.import.conflict_ignore'), label: i18n.t('dialogue.import.conflict_ignore'),
}, },
]) ]
const importEnable = computed(() => { const importEnable = computed(() => {
return !isEmpty(importKeyForm.file) return !isEmpty(importKeyForm.file)
@ -53,8 +51,8 @@ const importEnable = computed(() => {
const onConfirmImport = async () => { const onConfirmImport = async () => {
try { try {
importing.value = true importing.value = true
const { server, db, file, conflict, expire, reload } = importKeyForm const { server, db, file, conflict, expire } = importKeyForm
browserStore.importKeysFromCSVFile(server, db, file, conflict, expire, reload).catch((e) => {}) browserStore.importKeysFromCSVFile(server, db, file, conflict, expire).catch((e) => {})
} catch (e) { } catch (e) {
$message.error(e.message) $message.error(e.message)
return return
@ -95,6 +93,11 @@ const onClose = () => {
:placeholder="$t('dialogue.import.open_csv_file_tip')" :placeholder="$t('dialogue.import.open_csv_file_tip')"
ext="csv" /> ext="csv" />
</n-form-item> </n-form-item>
<n-form-item :label="$t('dialogue.import.import_expire_title')">
<n-checkbox v-model:checked="importKeyForm.expire" :autofocus="false">
{{ $t('dialogue.import.import_expire') }}
</n-checkbox>
</n-form-item>
<n-form-item :label="$t('dialogue.import.conflict_handle')"> <n-form-item :label="$t('dialogue.import.conflict_handle')">
<n-radio-group v-model:value="importKeyForm.conflict"> <n-radio-group v-model:value="importKeyForm.conflict">
<n-radio-button <n-radio-button
@ -104,16 +107,6 @@ const onClose = () => {
:value="op.value" /> :value="op.value" />
</n-radio-group> </n-radio-group>
</n-form-item> </n-form-item>
<n-form-item :label="$t('dialogue.import.import_expire_title')" :show-label="false">
<n-space :wrap-item="false">
<n-checkbox v-model:checked="importKeyForm.expire" :autofocus="false">
{{ $t('dialogue.import.import_expire') }}
</n-checkbox>
<n-checkbox v-model:checked="importKeyForm.reload" :autofocus="false">
{{ $t('dialogue.import.reload') }}
</n-checkbox>
</n-space>
</n-form-item>
</n-form> </n-form>
</n-spin> </n-spin>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, reactive, ref, watchEffect } from 'vue' import { computed, reactive, ref, watch } from 'vue'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { types } from '@/consts/support_redis_type.js' import { types } from '@/consts/support_redis_type.js'
@ -26,16 +26,18 @@ const typeOptions = computed(() => {
}) })
const dialogStore = useDialog() const dialogStore = useDialog()
watch(
watchEffect(() => { () => dialogStore.keyFilterDialogVisible,
if (dialogStore.keyFilterDialogVisible) { (visible) => {
const { server, db, type, pattern } = dialogStore.keyFilterParam if (visible) {
filterForm.server = server const { server, db, type, pattern } = dialogStore.keyFilterParam
filterForm.db = db || 0 filterForm.server = server
filterForm.type = type || '' filterForm.db = db || 0
filterForm.pattern = pattern || '*' filterForm.type = type || ''
} filterForm.pattern = pattern || '*'
}) }
},
)
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const onConfirm = () => {} const onConfirm = () => {}

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, h, nextTick, reactive, ref, watchEffect } from 'vue' import { computed, h, nextTick, 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 { endsWith, get, isEmpty, keys, map, trim } from 'lodash' import { endsWith, get, isEmpty, keys, map, trim } from 'lodash'
@ -64,26 +64,29 @@ const defaultValue = {
} }
const dialogStore = useDialog() const dialogStore = useDialog()
watchEffect(() => { watch(
if (dialogStore.newKeyDialogVisible) { () => dialogStore.newKeyDialogVisible,
const { prefix, server, db } = dialogStore.newKeyParam (visible) => {
const separator = browserStore.getSeparator(server) if (visible) {
newForm.server = server const { prefix, server, db } = dialogStore.newKeyParam
if (isEmpty(prefix)) { const separator = browserStore.getSeparator(server)
newForm.key = '' newForm.server = server
} else { if (isEmpty(prefix)) {
if (!endsWith(prefix, separator)) { newForm.key = ''
newForm.key = prefix + separator
} else { } else {
newForm.key = prefix if (!endsWith(prefix, separator)) {
newForm.key = prefix + separator
} else {
newForm.key = prefix
}
} }
newForm.db = db
newForm.type = options.value[0].value
newForm.ttl = -1
newForm.value = null
} }
newForm.db = db },
newForm.type = options.value[0].value )
newForm.ttl = -1
newForm.value = null
}
})
const renderTypeLabel = (option) => { const renderTypeLabel = (option) => {
return h( return h(
@ -207,7 +210,6 @@ const onClose = () => {
v-model:value="newForm.ttl" v-model:value="newForm.ttl"
:max="Number.MAX_SAFE_INTEGER" :max="Number.MAX_SAFE_INTEGER"
:min="-1" :min="-1"
:show-button="false"
placeholder="TTL"> placeholder="TTL">
<template #suffix> <template #suffix>
{{ $t('common.second') }} {{ $t('common.second') }}

View File

@ -101,11 +101,7 @@ const onClose = () => {
<n-input-number v-model:value="prefStore.general.fontSize" :max="65535" :min="1" /> <n-input-number v-model:value="prefStore.general.fontSize" :max="65535" :min="1" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('preferences.general.scan_size')" :span="12"> <n-form-item-gi :label="$t('preferences.general.scan_size')" :span="12">
<n-input-number <n-input-number v-model:value="prefStore.general.scanSize" :min="1" />
v-model:value="prefStore.general.scanSize"
:min="1"
:show-button="false"
style="width: 100%" />
</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" :options="keyOptions" />
@ -132,13 +128,13 @@ const onClose = () => {
<n-tab-pane :tab="$t('preferences.editor.name')" display-directive="show" name="editor"> <n-tab-pane :tab="$t('preferences.editor.name')" display-directive="show" name="editor">
<n-form :disabled="loading" :model="prefStore.editor" :show-require-mark="false" label-placement="top"> <n-form :disabled="loading" :model="prefStore.editor" :show-require-mark="false" label-placement="top">
<n-grid :x-gap="10"> <n-grid :x-gap="10">
<n-form-item-gi :label="$t('preferences.general.font')" :span="12" 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"
:options="prefStore.fontOption" :options="prefStore.fontOption"
filterable /> filterable />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :label="$t('preferences.general.font_size')" :show-feedback="false" :span="12"> <n-form-item-gi :label="$t('preferences.general.font_size')" :show-feedback="false" :span="24">
<n-input-number v-model:value="prefStore.editor.fontSize" :max="65535" :min="1" /> <n-input-number v-model:value="prefStore.editor.fontSize" :max="65535" :min="1" />
</n-form-item-gi> </n-form-item-gi>
<n-form-item-gi :show-feedback="false" :span="24"> <n-form-item-gi :show-feedback="false" :span="24">

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { reactive, watchEffect } from 'vue' import { reactive, watch } from 'vue'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import useBrowserStore from 'stores/browser.js' import useBrowserStore from 'stores/browser.js'
@ -15,16 +15,18 @@ const renameForm = reactive({
const dialogStore = useDialog() const dialogStore = useDialog()
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const tab = useTabStore() const tab = useTabStore()
watch(
watchEffect(() => { () => dialogStore.renameDialogVisible,
if (dialogStore.renameDialogVisible) { (visible) => {
const { server, db, key } = dialogStore.renameKeyParam if (visible) {
renameForm.server = server const { server, db, key } = dialogStore.renameKeyParam
renameForm.db = db renameForm.server = server
renameForm.key = key renameForm.db = db
renameForm.newKey = key renameForm.key = key
} renameForm.newKey = key
}) }
},
)
const i18n = useI18n() const i18n = useI18n()
const onRename = async () => { const onRename = async () => {
@ -55,9 +57,9 @@ const onClose = () => {
:closable="false" :closable="false"
:close-on-esc="false" :close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ focusable: false, size: 'medium' }" :negative-button-props="{ size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
:positive-button-props="{ focusable: false, size: 'medium' }" :positive-button-props="{ size: 'medium' }"
:positive-text="$t('common.confirm')" :positive-text="$t('common.confirm')"
:show-icon="false" :show-icon="false"
:title="$t('interface.rename_key')" :title="$t('interface.rename_key')"

View File

@ -1,11 +1,10 @@
<script setup> <script setup>
import { computed, reactive, watchEffect } from 'vue' import { reactive, watch } from 'vue'
import useDialog from 'stores/dialog' import useDialog from 'stores/dialog'
import useTabStore from 'stores/tab.js' import useTabStore from 'stores/tab.js'
import Binary from '@/components/icons/Binary.vue' import Binary from '@/components/icons/Binary.vue'
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
import useBrowserStore from 'stores/browser.js' import useBrowserStore from 'stores/browser.js'
import { useI18n } from 'vue-i18n'
const ttlForm = reactive({ const ttlForm = reactive({
server: '', server: '',
@ -13,62 +12,33 @@ const ttlForm = reactive({
key: '', key: '',
keyCode: null, keyCode: null,
ttl: -1, ttl: -1,
unit: 1,
}) })
const dialogStore = useDialog() const dialogStore = useDialog()
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const tabStore = useTabStore() const tabStore = useTabStore()
watchEffect(() => { watch(
if (dialogStore.ttlDialogVisible) { () => dialogStore.ttlDialogVisible,
// get ttl from current tab (visible) => {
const tab = tabStore.currentTab if (visible) {
if (tab != null) { // get ttl from current tab
ttlForm.server = tab.name const tab = tabStore.currentTab
ttlForm.db = tab.db if (tab != null) {
ttlForm.key = tab.key ttlForm.server = tab.name
ttlForm.keyCode = tab.keyCode ttlForm.db = tab.db
ttlForm.unit = 1 ttlForm.key = tab.key
if (tab.ttl < 0) { ttlForm.keyCode = tab.keyCode
// forever if (tab.ttl < 0) {
ttlForm.ttl = -1 // forever
} else { ttlForm.ttl = -1
ttlForm.ttl = tab.ttl } else {
ttlForm.ttl = tab.ttl
}
} }
} }
}
})
const i18n = useI18n()
const unit = computed(() => [
{ value: 1, label: i18n.t('common.second') },
{
value: 60,
label: i18n.t('common.minute'),
}, },
{ )
value: 3600,
label: i18n.t('common.hour'),
},
{
value: 86400,
label: i18n.t('common.day'),
},
])
const quickOption = computed(() => [
{ value: -1, unit: 1, label: i18n.t('interface.forever') },
{ value: 10, unit: 1, label: `10 ${i18n.t('common.second')}` },
{ value: 1, unit: 60, label: `1 ${i18n.t('common.minute')}` },
{ value: 1, unit: 3600, label: `1 ${i18n.t('common.hour')}` },
{ value: 1, unit: 86400, label: `1 ${i18n.t('common.day')}` },
])
const onQuickSet = (opt) => {
ttlForm.ttl = opt.value
ttlForm.unit = opt.unit
}
const onClose = () => { const onClose = () => {
dialogStore.closeTTLDialog() dialogStore.closeTTLDialog()
@ -81,14 +51,13 @@ const onConfirm = async () => {
return return
} }
const key = isEmpty(ttlForm.keyCode) ? ttlForm.key : ttlForm.keyCode const key = isEmpty(ttlForm.keyCode) ? ttlForm.key : ttlForm.keyCode
const ttl = ttlForm.ttl * (ttlForm.unit || 1) const success = await browserStore.setTTL(tab.name, tab.db, key, ttlForm.ttl)
const success = await browserStore.setTTL(tab.name, tab.db, key, ttl)
if (success) { if (success) {
tabStore.updateTTL({ tabStore.updateTTL({
server: ttlForm.server, server: ttlForm.server,
db: ttlForm.db, db: ttlForm.db,
key: ttlForm.key, key: ttlForm.key,
ttl: ttl, ttl: ttlForm.ttl,
}) })
} }
} catch (e) { } catch (e) {
@ -105,12 +74,6 @@ const onConfirm = async () => {
:closable="false" :closable="false"
:close-on-esc="false" :close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ focusable: false, size: 'medium' }"
:negative-text="$t('common.cancel')"
:on-negative-click="onClose"
:on-positive-click="onConfirm"
:positive-button-props="{ focusable: false, size: 'medium' }"
:positive-text="$t('common.save')"
:show-icon="false" :show-icon="false"
:title="$t('dialogue.ttl.title')" :title="$t('dialogue.ttl.title')"
preset="dialog" preset="dialog"
@ -124,30 +87,27 @@ const onConfirm = async () => {
</n-input> </n-input>
</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-number
<n-input-number v-model:value="ttlForm.ttl"
v-model:value="ttlForm.ttl" :max="Number.MAX_SAFE_INTEGER"
:max="Number.MAX_SAFE_INTEGER" :min="-1"
:min="-1" style="width: 100%">
:show-button="false" <template #suffix>
class="flex-item-expand" /> {{ $t('common.second') }}
<n-select v-model:value="ttlForm.unit" :options="unit" style="max-width: 150px" /> </template>
</n-input-group> </n-input-number>
</n-form-item>
<n-form-item :label="$t('dialogue.ttl.quick_set')" :show-feedback="false">
<n-space :wrap="true" :wrap-item="false">
<n-button
v-for="(opt, i) in quickOption"
:key="i"
round
secondary
size="small"
@click="onQuickSet(opt)">
{{ opt.label }}
</n-button>
</n-space>
</n-form-item> </n-form-item>
</n-form> </n-form>
<template #action>
<div class="flex-item-expand">
<n-button :focusable="false" @click="ttlForm.ttl = -1">{{ $t('dialogue.key.persist_key') }}</n-button>
</div>
<div class="flex-item n-dialog__action">
<n-button :focusable="false" @click="onClose">{{ $t('common.cancel') }}</n-button>
<n-button :focusable="false" type="primary" @click="onConfirm">{{ $t('common.save') }}</n-button>
</div>
</template>
</n-modal> </n-modal>
</template> </template>

View File

@ -72,7 +72,6 @@ const onUpdate = () => {
<n-input-number <n-input-number
v-model:value="value.score" v-model:value="value.score"
:placeholder="$t('dialogue.field.enter_score')" :placeholder="$t('dialogue.field.enter_score')"
:show-button="false"
@update:value="onUpdate" /> @update:value="onUpdate" />
</template> </template>
<template #action="{ index, create, remove, move }"> <template #action="{ index, create, remove, move }">

View File

@ -52,7 +52,6 @@ defineExpose({
<n-input-number <n-input-number
v-model:value="value.score" v-model:value="value.score"
:placeholder="$t('dialogue.field.enter_score')" :placeholder="$t('dialogue.field.enter_score')"
:show-button="false"
@update:value="onUpdate" /> @update:value="onUpdate" />
</template> </template>
<template #action="{ index, create, remove, move }"> <template #action="{ index, create, remove, move }">

View File

@ -3,7 +3,7 @@ import { useThemeVars } from 'naive-ui'
import BrowserTree from './BrowserTree.vue' import BrowserTree from './BrowserTree.vue'
import IconButton from '@/components/common/IconButton.vue' import IconButton from '@/components/common/IconButton.vue'
import useTabStore from 'stores/tab.js' import useTabStore from 'stores/tab.js'
import { computed, nextTick, onMounted, reactive, ref, unref, watch } from 'vue' import { computed, nextTick, onMounted, reactive, ref, unref } from 'vue'
import { find, get, map, size } from 'lodash' import { find, get, map, size } from 'lodash'
import Refresh from '@/components/icons/Refresh.vue' import Refresh from '@/components/icons/Refresh.vue'
import useDialogStore from 'stores/dialog.js' import useDialogStore from 'stores/dialog.js'
@ -238,11 +238,6 @@ const onSelectOptions = (select) => {
} }
onMounted(() => onReload()) onMounted(() => onReload())
watch(
() => browserStore.getReloadKey(props.server),
(key) => onReload(),
)
// forbid dynamic switch key view due to performance issues // forbid dynamic switch key view due to performance issues
// const viewType = ref(0) // const viewType = ref(0)
// const onSwitchView = (selectView) => { // const onSwitchView = (selectView) => {
@ -289,7 +284,6 @@ watch(
:options="addOptions" :options="addOptions"
placement="bottom-end" placement="bottom-end"
style="min-width: 130px" style="min-width: 130px"
trigger="click"
@select="onSelectOptions"> @select="onSelectOptions">
<n-button :focusable="false" size="small" style="padding: 0 3px"> <n-button :focusable="false" size="small" style="padding: 0 3px">
<n-icon size="10"> <n-icon size="10">

View File

@ -367,7 +367,13 @@ const renderPrefix = ({ option }) => {
case ConnectionType.RedisValue: case ConnectionType.RedisValue:
if (prefStore.keyIconType === typesIconStyle.ICON) { if (prefStore.keyIconType === typesIconStyle.ICON) {
return h(NIcon, { size: 20 }, () => h(Key)) return h(
NIcon,
{ size: 20 },
{
default: () => h(!!option.redisKeyCode ? Binary : Key),
},
)
} }
const loading = isEmpty(option.redisType) || option.redisType === 'loading' const loading = isEmpty(option.redisType) || option.redisType === 'loading'
if (loading) { if (loading) {
@ -500,8 +506,10 @@ const calcValueMenu = () => {
// render menu function icon // render menu function icon
const renderSuffix = ({ option }) => { const renderSuffix = ({ option }) => {
const selected = includes(selectedKeys.value, option.key) if (
if (selected && !props.checkMode) { (option.type === ConnectionType.RedisDB && option.opened) ||
(includes(selectedKeys.value, option.key) && !props.checkMode)
) {
switch (option.type) { switch (option.type) {
case ConnectionType.RedisDB: case ConnectionType.RedisDB:
return renderIconMenu(calcDBMenu(option.opened, option.loading, option.fullLoaded)) return renderIconMenu(calcDBMenu(option.opened, option.loading, option.fullLoaded))
@ -510,9 +518,6 @@ const renderSuffix = ({ option }) => {
case ConnectionType.RedisValue: case ConnectionType.RedisValue:
return renderIconMenu(calcValueMenu()) return renderIconMenu(calcValueMenu())
} }
} else if (!selected && !!option.redisKeyCode && option.type === ConnectionType.RedisValue) {
// render binary icon
return renderIconMenu(h(NIcon, { size: 20 }, () => h(Binary)))
} }
return null return null
} }

View File

@ -10,9 +10,6 @@
"update": "Update", "update": "Update",
"none": "None", "none": "None",
"second": "Second(s)", "second": "Second(s)",
"minute": "Minutes(s)",
"hour": "Hour(s)",
"day": "Day(s)",
"unit_day": "D", "unit_day": "D",
"unit_hour": "H", "unit_hour": "H",
"unit_minute": "M", "unit_minute": "M",
@ -277,8 +274,6 @@
}, },
"export": { "export": {
"name": "Export Data", "name": "Export Data",
"export_expire_title": "Expiration",
"export_expire": "Include Expiration Time",
"export": "Export", "export": "Export",
"save_file": "Export Path", "save_file": "Export Path",
"save_file_tip": "Select the path to save exported file", "save_file_tip": "Select the path to save exported file",
@ -287,21 +282,19 @@
}, },
"import": { "import": {
"name": "Import Data", "name": "Import Data",
"import_expire_title": "Expiration", "export_expire_title": "Expiration",
"import_expire": "Import Expiration Time", "export_expire": "Export Expiration Time",
"import": "Import", "import": "Import",
"reload": "Reload Keys After Imported",
"open_csv_file": "Import File", "open_csv_file": "Import File",
"open_csv_file_tip": "Select the file for import", "open_csv_file_tip": "Select the file for import",
"conflict_handle": "Key Conflict Resolution", "conflict_handle": "Handle Key Conflict",
"conflict_overwrite": "Overwrite", "conflict_overwrite": "Overwrite",
"conflict_ignore": "Ignore", "conflict_ignore": "Ignore",
"importing": "Importing Keys imported/overwrite:{imported} conflict/fail:{conflict}", "importing": "Importing Keys imported/overwrite:{imported} conflict/fail:{conflict}",
"import_completed": "Import completed, {success} successes, {ignored} failed" "import_completed": "Import completed, {success} successes, {ignored} failed"
}, },
"ttl": { "ttl": {
"title": "Set Key TTL", "title": "Set Key TTL"
"quick_set": "Quick Settings"
}, },
"upgrade": { "upgrade": {
"title": "New Version Available", "title": "New Version Available",

View File

@ -10,9 +10,6 @@
"update": "更新", "update": "更新",
"none": "无", "none": "无",
"second": "秒", "second": "秒",
"minute": "分钟",
"hour": "小时",
"day": "天",
"unit_day": "天", "unit_day": "天",
"unit_hour": "小时", "unit_hour": "小时",
"unit_minute": "分钟", "unit_minute": "分钟",
@ -289,7 +286,6 @@
"name": "导入数据", "name": "导入数据",
"import_expire_title": "过期时间", "import_expire_title": "过期时间",
"import_expire": "包含键过期时间", "import_expire": "包含键过期时间",
"reload": "导入完成后重新载入",
"import": "确认导入", "import": "确认导入",
"open_csv_file": "导入文件路径", "open_csv_file": "导入文件路径",
"open_csv_file_tip": "选择需要导入的文件", "open_csv_file_tip": "选择需要导入的文件",
@ -300,8 +296,7 @@
"import_completed": "已完成导入操作,成功{success}个,忽略{ignored}个" "import_completed": "已完成导入操作,成功{success}个,忽略{ignored}个"
}, },
"ttl": { "ttl": {
"title": "设置键存活时间", "title": "设置键存活时间"
"quick_set": "快捷设置"
}, },
"upgrade": { "upgrade": {
"title": "有可用新版本", "title": "有可用新版本",

View File

@ -19,7 +19,6 @@ export class RedisServerState {
/** /**
* @param {string} name server name * @param {string} name server name
* @param {number} db current opened database * @param {number} db current opened database
* @param {number} reloadKey try to reload when changed
* @param {{}} stats current server status info * @param {{}} stats current server status info
* @param {Object.<number, RedisDatabaseItem>} databases database list * @param {Object.<number, RedisDatabaseItem>} databases database list
* @param {string|null} patternFilter pattern filter * @param {string|null} patternFilter pattern filter
@ -41,7 +40,6 @@ export class RedisServerState {
}) { }) {
this.name = name this.name = name
this.db = db this.db = db
this.reloadKey = Date.now()
this.stats = stats this.stats = stats
this.databases = databases this.databases = databases
this.patternFilter = patternFilter this.patternFilter = patternFilter
@ -85,7 +83,7 @@ export class RedisServerState {
* @param {number} updateVal * @param {number} updateVal
*/ */
updateDBKeyCount(db, updateVal) { updateDBKeyCount(db, updateVal) {
const dbInst = this.databases[db] const dbInst = this.databases[this.db]
if (dbInst != null) { if (dbInst != null) {
dbInst.maxKeys = Math.max(0, dbInst.maxKeys + updateVal) dbInst.maxKeys = Math.max(0, dbInst.maxKeys + updateVal)
} }
@ -290,11 +288,6 @@ export class RedisServerState {
// clear all key nodes // clear all key nodes
this.nodeMap.clear() this.nodeMap.clear()
this.getRoot() this.getRoot()
const dbInst = this.databases[this.db]
if (dbInst != null) {
dbInst.maxKeys = 0
dbInst.keyCount = 0
}
} else { } else {
const keyParts = split(key, this.separator) const keyParts = split(key, this.separator)
const totalParts = size(keyParts) const totalParts = size(keyParts)

View File

@ -166,20 +166,6 @@ const useBrowserStore = defineStore('browser', {
return get(rootNode, 'children', []) return get(rootNode, 'children', [])
}, },
getReloadKey(server) {
/** @type {RedisServerState} **/
const serverInst = this.servers[server]
return serverInst != null ? serverInst.reloadKey : 0
},
reloadServer(server) {
/** @type {RedisServerState} **/
const serverInst = this.servers[server]
if (serverInst != null) {
serverInst.reloadKey = Date.now()
}
},
/** /**
* switch key view * switch key view
* @param {string} connName * @param {string} connName
@ -1507,7 +1493,7 @@ const useBrowserStore = defineStore('browser', {
*/ */
async deleteKey(server, db, key, soft) { async deleteKey(server, db, key, soft) {
try { try {
let deleteCount = 1 let deleteCount = 0
if (soft !== true) { if (soft !== true) {
const { data } = await DeleteKey(server, db, key) const { data } = await DeleteKey(server, db, key)
deleteCount = get(data, 'deleteCount', 0) deleteCount = get(data, 'deleteCount', 0)
@ -1674,10 +1660,9 @@ const useBrowserStore = defineStore('browser', {
* @param {string} path * @param {string} path
* @param {number} conflict * @param {number} conflict
* @param {boolean} [expire] * @param {boolean} [expire]
* @param {boolean} [reload]
* @return {Promise<void>} * @return {Promise<void>}
*/ */
async importKeysFromCSVFile(server, db, path, conflict, expire, reload) { async importKeysFromCSVFile(server, db, path, conflict, expire) {
const msgRef = $message.loading('', { duration: 0, closable: true }) const msgRef = $message.loading('', { duration: 0, closable: true })
let imported = 0 let imported = 0
let ignored = 0 let ignored = 0
@ -1710,11 +1695,8 @@ const useBrowserStore = defineStore('browser', {
if (canceled) { if (canceled) {
$message.info(i18nGlobal.t('dialogue.handle_cancel')) $message.info(i18nGlobal.t('dialogue.handle_cancel'))
} else { } else {
// finish // no fail
$message.success(i18nGlobal.t('dialogue.import.import_completed', { success: imported, ignored })) $message.success(i18nGlobal.t('dialogue.import.import_completed', { success: imported, ignored }))
if (reload) {
this.reloadServer(server)
}
} }
}, },
@ -1735,6 +1717,7 @@ const useBrowserStore = defineStore('browser', {
if (serverInst != null) { if (serverInst != null) {
// update tree view data // update tree view data
serverInst.removeKeyNode() serverInst.removeKeyNode()
serverInst.setDBKeyCount(db, 0)
} }
// set tab content empty // set tab content empty
const tab = useTabStore() const tab = useTabStore()

View File

@ -23,7 +23,7 @@ export const themeOverrides = {
paddingMedium: '0 12px', paddingMedium: '0 12px',
}, },
Tag: { Tag: {
borderRadius: '4px', // borderRadius: '3px'
heightLarge: '32px', heightLarge: '32px',
}, },
Input: { Input: {