Compare commits
6 Commits
84b73bd5e7
...
23087a5374
Author | SHA1 | Date |
---|---|---|
Lykin | 23087a5374 | |
Lykin | a71f5e0070 | |
Lykin | 1340f911c8 | |
Lykin | 37efe5e72a | |
Lykin | 36a8c38877 | |
Lykin | 18f1b976c6 |
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import ContentPane from './components/content/ContentPane.vue'
|
||||
import BrowserPane from './components/sidebar/BrowserPane.vue'
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { computed, onMounted, reactive, ref, watchEffect } from 'vue'
|
||||
import { debounce } from 'lodash'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
import Ribbon from './components/sidebar/Ribbon.vue'
|
||||
|
@ -43,14 +43,11 @@ const handleResize = () => {
|
|||
saveSidebarWidth()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => tabStore.nav,
|
||||
(nav) => {
|
||||
if (nav === 'log') {
|
||||
logPaneRef.value?.refresh()
|
||||
}
|
||||
},
|
||||
)
|
||||
watchEffect(() => {
|
||||
if (tabStore.nav === 'log') {
|
||||
logPaneRef.value?.refresh()
|
||||
}
|
||||
})
|
||||
|
||||
const logoWrapperWidth = computed(() => {
|
||||
return `${data.navMenuWidth + prefStore.behavior.asideWidth - 4}px`
|
||||
|
|
|
@ -90,6 +90,7 @@ defineExpose({
|
|||
v-model:value="inputData.filter"
|
||||
:placeholder="$t('interface.filter')"
|
||||
:size="props.small ? 'small' : ''"
|
||||
:theme-overrides="{ paddingSmall: '0 3px', paddingMedium: '0 6px' }"
|
||||
clearable
|
||||
@clear="onClearFilter"
|
||||
@input="onInput"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { computed, reactive, watch } from 'vue'
|
||||
import { computed, reactive, watchEffect } from 'vue'
|
||||
import { types } from '@/consts/support_redis_type.js'
|
||||
import useDialog from 'stores/dialog'
|
||||
import NewStringValue from '@/components/new_value/NewStringValue.vue'
|
||||
|
@ -63,21 +63,18 @@ const title = computed(() => {
|
|||
})
|
||||
|
||||
const dialogStore = useDialog()
|
||||
watch(
|
||||
() => dialogStore.addFieldsDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db, key, keyCode, type } = dialogStore.addFieldParam
|
||||
newForm.server = server
|
||||
newForm.db = db
|
||||
newForm.key = key
|
||||
newForm.keyCode = keyCode
|
||||
newForm.type = type
|
||||
newForm.opType = 0
|
||||
newForm.value = null
|
||||
}
|
||||
},
|
||||
)
|
||||
watchEffect(() => {
|
||||
if (dialogStore.addFieldsDialogVisible) {
|
||||
const { server, db, key, keyCode, type } = dialogStore.addFieldParam
|
||||
newForm.server = server
|
||||
newForm.db = db
|
||||
newForm.key = key
|
||||
newForm.keyCode = keyCode
|
||||
newForm.type = type
|
||||
newForm.opType = 0
|
||||
newForm.value = null
|
||||
}
|
||||
})
|
||||
|
||||
const browserStore = useBrowserStore()
|
||||
const tab = useTabStore()
|
||||
|
@ -222,7 +219,7 @@ const onClose = () => {
|
|||
:is="addValueComponent[newForm.type]"
|
||||
v-model:type="newForm.opType"
|
||||
v-model:value="newForm.value" />
|
||||
<n-form-item label=" " path="key" required>
|
||||
<n-form-item :show-label="false" path="key" required>
|
||||
<n-checkbox v-model:checked="newForm.reload">
|
||||
{{ $t('dialogue.field.reload_when_succ') }}
|
||||
</n-checkbox>
|
||||
|
|
|
@ -289,6 +289,7 @@ const onClose = () => {
|
|||
v-model:value="generalForm.port"
|
||||
:max="65535"
|
||||
:min="1"
|
||||
:show-button="false"
|
||||
style="width: 200px" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="$t('dialogue.connection.pwd')" :span="12" path="password">
|
||||
|
@ -336,7 +337,12 @@ const onClose = () => {
|
|||
:label="$t('dialogue.connection.advn.conn_timeout')"
|
||||
:span="12"
|
||||
path="connTimeout">
|
||||
<n-input-number v-model:value="generalForm.connTimeout" :max="999999" :min="1">
|
||||
<n-input-number
|
||||
v-model:value="generalForm.connTimeout"
|
||||
:max="999999"
|
||||
:min="1"
|
||||
:show-button="false"
|
||||
style="width: 100%">
|
||||
<template #suffix>
|
||||
{{ $t('common.second') }}
|
||||
</template>
|
||||
|
@ -346,7 +352,12 @@ const onClose = () => {
|
|||
:label="$t('dialogue.connection.advn.exec_timeout')"
|
||||
:span="12"
|
||||
path="execTimeout">
|
||||
<n-input-number v-model:value="generalForm.execTimeout" :max="999999" :min="1">
|
||||
<n-input-number
|
||||
v-model:value="generalForm.execTimeout"
|
||||
:max="999999"
|
||||
:min="1"
|
||||
:show-button="false"
|
||||
style="width: 100%">
|
||||
<template #suffix>
|
||||
{{ $t('common.second') }}
|
||||
</template>
|
||||
|
@ -363,7 +374,11 @@ const onClose = () => {
|
|||
</n-radio-group>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="$t('dialogue.connection.advn.load_size')" :span="12">
|
||||
<n-input-number v-model:value="generalForm.loadSize" :min="0" />
|
||||
<n-input-number
|
||||
v-model:value="generalForm.loadSize"
|
||||
:min="0"
|
||||
:show-button="false"
|
||||
style="width: 100%" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="$t('dialogue.connection.advn.dbfilter_type')" :span="24">
|
||||
<n-radio-group
|
||||
|
@ -470,6 +485,7 @@ const onClose = () => {
|
|||
v-model:value="generalForm.ssh.port"
|
||||
:max="65535"
|
||||
:min="1"
|
||||
:show-button="false"
|
||||
style="width: 200px" />
|
||||
</n-form-item>
|
||||
<n-form-item :label="$t('dialogue.connection.ssh.login_type')">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { computed, nextTick, reactive, ref, watch } from 'vue'
|
||||
import { computed, nextTick, reactive, ref, watchEffect } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { isEmpty, map, size } from 'lodash'
|
||||
|
@ -18,28 +18,26 @@ const deleteForm = reactive({
|
|||
|
||||
const dialogStore = useDialog()
|
||||
const browserStore = useBrowserStore()
|
||||
watch(
|
||||
() => dialogStore.deleteKeyDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db, key } = dialogStore.deleteKeyParam
|
||||
deleteForm.server = server
|
||||
deleteForm.db = db
|
||||
deleteForm.key = key
|
||||
deleteForm.loadingAffected = false
|
||||
// deleteForm.async = true
|
||||
loading.value = false
|
||||
deleting.value = false
|
||||
if (key instanceof Array) {
|
||||
deleteForm.showAffected = true
|
||||
deleteForm.affectedKeys = key
|
||||
} else {
|
||||
deleteForm.showAffected = false
|
||||
deleteForm.affectedKeys = []
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (dialogStore.deleteKeyDialogVisible) {
|
||||
const { server, db, key } = dialogStore.deleteKeyParam
|
||||
deleteForm.server = server
|
||||
deleteForm.db = db
|
||||
deleteForm.key = key
|
||||
deleteForm.loadingAffected = false
|
||||
// deleteForm.async = true
|
||||
loading.value = false
|
||||
deleting.value = false
|
||||
if (key instanceof Array) {
|
||||
deleteForm.showAffected = true
|
||||
deleteForm.affectedKeys = key
|
||||
} else {
|
||||
deleteForm.showAffected = false
|
||||
deleteForm.affectedKeys = []
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const deleting = ref(false)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { reactive, ref, watchEffect } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import useBrowserStore from 'stores/browser.js'
|
||||
|
@ -14,19 +14,17 @@ const flushForm = reactive({
|
|||
|
||||
const dialogStore = useDialog()
|
||||
const browserStore = useBrowserStore()
|
||||
watch(
|
||||
() => dialogStore.flushDBDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db } = dialogStore.flushDBParam
|
||||
flushForm.server = server
|
||||
flushForm.db = db
|
||||
flushForm.async = true
|
||||
flushForm.confirm = false
|
||||
loading.value = false
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
watchEffect(() => {
|
||||
if (dialogStore.flushDBDialogVisible) {
|
||||
const { server, db } = dialogStore.flushDBParam
|
||||
flushForm.server = server
|
||||
flushForm.db = db
|
||||
flushForm.async = true
|
||||
flushForm.confirm = false
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const i18n = useI18n()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { computed, reactive, ref, watchEffect } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
|
@ -36,14 +36,11 @@ const isRenameMode = computed(() => !isEmpty(editGroup.value))
|
|||
|
||||
const dialogStore = useDialog()
|
||||
const connectionStore = useConnectionStore()
|
||||
watch(
|
||||
() => dialogStore.groupDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
groupForm.name = editGroup.value = dialogStore.editGroup
|
||||
}
|
||||
},
|
||||
)
|
||||
watchEffect(() => {
|
||||
if (dialogStore.groupDialogVisible) {
|
||||
groupForm.name = editGroup.value = dialogStore.editGroup
|
||||
}
|
||||
})
|
||||
|
||||
const i18n = useI18n()
|
||||
const onConfirm = async () => {
|
||||
|
|
|
@ -10,6 +10,7 @@ const importKeyForm = reactive({
|
|||
server: '',
|
||||
db: 0,
|
||||
expire: true,
|
||||
reload: true,
|
||||
file: '',
|
||||
type: 0,
|
||||
conflict: 0,
|
||||
|
@ -25,6 +26,7 @@ watchEffect(() => {
|
|||
importKeyForm.server = server
|
||||
importKeyForm.db = db
|
||||
importKeyForm.expire = true
|
||||
importKeyForm.reload = true
|
||||
importKeyForm.file = ''
|
||||
importKeyForm.type = 0
|
||||
importKeyForm.conflict = 0
|
||||
|
@ -33,7 +35,7 @@ watchEffect(() => {
|
|||
})
|
||||
|
||||
const i18n = useI18n()
|
||||
const conflictOption = [
|
||||
const conflictOption = computed(() => [
|
||||
{
|
||||
value: 0,
|
||||
label: i18n.t('dialogue.import.conflict_overwrite'),
|
||||
|
@ -42,7 +44,7 @@ const conflictOption = [
|
|||
value: 1,
|
||||
label: i18n.t('dialogue.import.conflict_ignore'),
|
||||
},
|
||||
]
|
||||
])
|
||||
|
||||
const importEnable = computed(() => {
|
||||
return !isEmpty(importKeyForm.file)
|
||||
|
@ -51,8 +53,8 @@ const importEnable = computed(() => {
|
|||
const onConfirmImport = async () => {
|
||||
try {
|
||||
importing.value = true
|
||||
const { server, db, file, conflict, expire } = importKeyForm
|
||||
browserStore.importKeysFromCSVFile(server, db, file, conflict, expire).catch((e) => {})
|
||||
const { server, db, file, conflict, expire, reload } = importKeyForm
|
||||
browserStore.importKeysFromCSVFile(server, db, file, conflict, expire, reload).catch((e) => {})
|
||||
} catch (e) {
|
||||
$message.error(e.message)
|
||||
return
|
||||
|
@ -93,11 +95,6 @@ const onClose = () => {
|
|||
:placeholder="$t('dialogue.import.open_csv_file_tip')"
|
||||
ext="csv" />
|
||||
</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-radio-group v-model:value="importKeyForm.conflict">
|
||||
<n-radio-button
|
||||
|
@ -107,6 +104,16 @@ const onClose = () => {
|
|||
:value="op.value" />
|
||||
</n-radio-group>
|
||||
</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-spin>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { computed, reactive, ref, watchEffect } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { types } from '@/consts/support_redis_type.js'
|
||||
|
@ -26,18 +26,16 @@ const typeOptions = computed(() => {
|
|||
})
|
||||
|
||||
const dialogStore = useDialog()
|
||||
watch(
|
||||
() => dialogStore.keyFilterDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db, type, pattern } = dialogStore.keyFilterParam
|
||||
filterForm.server = server
|
||||
filterForm.db = db || 0
|
||||
filterForm.type = type || ''
|
||||
filterForm.pattern = pattern || '*'
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
watchEffect(() => {
|
||||
if (dialogStore.keyFilterDialogVisible) {
|
||||
const { server, db, type, pattern } = dialogStore.keyFilterParam
|
||||
filterForm.server = server
|
||||
filterForm.db = db || 0
|
||||
filterForm.type = type || ''
|
||||
filterForm.pattern = pattern || '*'
|
||||
}
|
||||
})
|
||||
|
||||
const browserStore = useBrowserStore()
|
||||
const onConfirm = () => {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { computed, h, nextTick, reactive, ref, watch } from 'vue'
|
||||
import { computed, h, nextTick, reactive, ref, watchEffect } from 'vue'
|
||||
import { types, typesColor } from '@/consts/support_redis_type.js'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { endsWith, get, isEmpty, keys, map, trim } from 'lodash'
|
||||
|
@ -64,29 +64,26 @@ const defaultValue = {
|
|||
}
|
||||
|
||||
const dialogStore = useDialog()
|
||||
watch(
|
||||
() => dialogStore.newKeyDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { prefix, server, db } = dialogStore.newKeyParam
|
||||
const separator = browserStore.getSeparator(server)
|
||||
newForm.server = server
|
||||
if (isEmpty(prefix)) {
|
||||
newForm.key = ''
|
||||
watchEffect(() => {
|
||||
if (dialogStore.newKeyDialogVisible) {
|
||||
const { prefix, server, db } = dialogStore.newKeyParam
|
||||
const separator = browserStore.getSeparator(server)
|
||||
newForm.server = server
|
||||
if (isEmpty(prefix)) {
|
||||
newForm.key = ''
|
||||
} else {
|
||||
if (!endsWith(prefix, separator)) {
|
||||
newForm.key = prefix + separator
|
||||
} else {
|
||||
if (!endsWith(prefix, separator)) {
|
||||
newForm.key = prefix + separator
|
||||
} else {
|
||||
newForm.key = prefix
|
||||
}
|
||||
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) => {
|
||||
return h(
|
||||
|
@ -210,6 +207,7 @@ const onClose = () => {
|
|||
v-model:value="newForm.ttl"
|
||||
:max="Number.MAX_SAFE_INTEGER"
|
||||
:min="-1"
|
||||
:show-button="false"
|
||||
placeholder="TTL">
|
||||
<template #suffix>
|
||||
{{ $t('common.second') }}
|
||||
|
|
|
@ -101,7 +101,11 @@ const onClose = () => {
|
|||
<n-input-number v-model:value="prefStore.general.fontSize" :max="65535" :min="1" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="$t('preferences.general.scan_size')" :span="12">
|
||||
<n-input-number v-model:value="prefStore.general.scanSize" :min="1" />
|
||||
<n-input-number
|
||||
v-model:value="prefStore.general.scanSize"
|
||||
:min="1"
|
||||
:show-button="false"
|
||||
style="width: 100%" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="$t('preferences.general.key_icon_style')" :span="12">
|
||||
<n-select v-model:value="prefStore.general.keyIconStyle" :options="keyOptions" />
|
||||
|
@ -128,13 +132,13 @@ const onClose = () => {
|
|||
<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-grid :x-gap="10">
|
||||
<n-form-item-gi :label="$t('preferences.general.font')" :span="24" required>
|
||||
<n-form-item-gi :label="$t('preferences.general.font')" :span="12" required>
|
||||
<n-select
|
||||
v-model:value="prefStore.editor.font"
|
||||
:options="prefStore.fontOption"
|
||||
filterable />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="$t('preferences.general.font_size')" :show-feedback="false" :span="24">
|
||||
<n-form-item-gi :label="$t('preferences.general.font_size')" :show-feedback="false" :span="12">
|
||||
<n-input-number v-model:value="prefStore.editor.fontSize" :max="65535" :min="1" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :show-feedback="false" :span="24">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { reactive, watch } from 'vue'
|
||||
import { reactive, watchEffect } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import useBrowserStore from 'stores/browser.js'
|
||||
|
@ -15,18 +15,16 @@ const renameForm = reactive({
|
|||
const dialogStore = useDialog()
|
||||
const browserStore = useBrowserStore()
|
||||
const tab = useTabStore()
|
||||
watch(
|
||||
() => dialogStore.renameDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db, key } = dialogStore.renameKeyParam
|
||||
renameForm.server = server
|
||||
renameForm.db = db
|
||||
renameForm.key = key
|
||||
renameForm.newKey = key
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
watchEffect(() => {
|
||||
if (dialogStore.renameDialogVisible) {
|
||||
const { server, db, key } = dialogStore.renameKeyParam
|
||||
renameForm.server = server
|
||||
renameForm.db = db
|
||||
renameForm.key = key
|
||||
renameForm.newKey = key
|
||||
}
|
||||
})
|
||||
|
||||
const i18n = useI18n()
|
||||
const onRename = async () => {
|
||||
|
@ -57,9 +55,9 @@ const onClose = () => {
|
|||
:closable="false"
|
||||
:close-on-esc="false"
|
||||
:mask-closable="false"
|
||||
:negative-button-props="{ size: 'medium' }"
|
||||
:negative-button-props="{ focusable: false, size: 'medium' }"
|
||||
:negative-text="$t('common.cancel')"
|
||||
:positive-button-props="{ size: 'medium' }"
|
||||
:positive-button-props="{ focusable: false, size: 'medium' }"
|
||||
:positive-text="$t('common.confirm')"
|
||||
:show-icon="false"
|
||||
:title="$t('interface.rename_key')"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<script setup>
|
||||
import { reactive, watch } from 'vue'
|
||||
import { computed, reactive, watchEffect } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import useTabStore from 'stores/tab.js'
|
||||
import Binary from '@/components/icons/Binary.vue'
|
||||
import { isEmpty } from 'lodash'
|
||||
import useBrowserStore from 'stores/browser.js'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const ttlForm = reactive({
|
||||
server: '',
|
||||
|
@ -12,33 +13,62 @@ const ttlForm = reactive({
|
|||
key: '',
|
||||
keyCode: null,
|
||||
ttl: -1,
|
||||
unit: 1,
|
||||
})
|
||||
|
||||
const dialogStore = useDialog()
|
||||
const browserStore = useBrowserStore()
|
||||
const tabStore = useTabStore()
|
||||
|
||||
watch(
|
||||
() => dialogStore.ttlDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
// get ttl from current tab
|
||||
const tab = tabStore.currentTab
|
||||
if (tab != null) {
|
||||
ttlForm.server = tab.name
|
||||
ttlForm.db = tab.db
|
||||
ttlForm.key = tab.key
|
||||
ttlForm.keyCode = tab.keyCode
|
||||
if (tab.ttl < 0) {
|
||||
// forever
|
||||
ttlForm.ttl = -1
|
||||
} else {
|
||||
ttlForm.ttl = tab.ttl
|
||||
}
|
||||
watchEffect(() => {
|
||||
if (dialogStore.ttlDialogVisible) {
|
||||
// get ttl from current tab
|
||||
const tab = tabStore.currentTab
|
||||
if (tab != null) {
|
||||
ttlForm.server = tab.name
|
||||
ttlForm.db = tab.db
|
||||
ttlForm.key = tab.key
|
||||
ttlForm.keyCode = tab.keyCode
|
||||
ttlForm.unit = 1
|
||||
if (tab.ttl < 0) {
|
||||
// forever
|
||||
ttlForm.ttl = -1
|
||||
} 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 = () => {
|
||||
dialogStore.closeTTLDialog()
|
||||
|
@ -51,13 +81,14 @@ const onConfirm = async () => {
|
|||
return
|
||||
}
|
||||
const key = isEmpty(ttlForm.keyCode) ? ttlForm.key : ttlForm.keyCode
|
||||
const success = await browserStore.setTTL(tab.name, tab.db, key, ttlForm.ttl)
|
||||
const ttl = ttlForm.ttl * (ttlForm.unit || 1)
|
||||
const success = await browserStore.setTTL(tab.name, tab.db, key, ttl)
|
||||
if (success) {
|
||||
tabStore.updateTTL({
|
||||
server: ttlForm.server,
|
||||
db: ttlForm.db,
|
||||
key: ttlForm.key,
|
||||
ttl: ttlForm.ttl,
|
||||
ttl: ttl,
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -74,6 +105,12 @@ const onConfirm = async () => {
|
|||
:closable="false"
|
||||
:close-on-esc="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"
|
||||
:title="$t('dialogue.ttl.title')"
|
||||
preset="dialog"
|
||||
|
@ -87,27 +124,30 @@ const onConfirm = async () => {
|
|||
</n-input>
|
||||
</n-form-item>
|
||||
<n-form-item :label="$t('interface.ttl')" required>
|
||||
<n-input-number
|
||||
v-model:value="ttlForm.ttl"
|
||||
:max="Number.MAX_SAFE_INTEGER"
|
||||
:min="-1"
|
||||
style="width: 100%">
|
||||
<template #suffix>
|
||||
{{ $t('common.second') }}
|
||||
</template>
|
||||
</n-input-number>
|
||||
<n-input-group>
|
||||
<n-input-number
|
||||
v-model:value="ttlForm.ttl"
|
||||
:max="Number.MAX_SAFE_INTEGER"
|
||||
:min="-1"
|
||||
:show-button="false"
|
||||
class="flex-item-expand" />
|
||||
<n-select v-model:value="ttlForm.unit" :options="unit" style="max-width: 150px" />
|
||||
</n-input-group>
|
||||
</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>
|
||||
|
||||
<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>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ const onUpdate = () => {
|
|||
<n-input-number
|
||||
v-model:value="value.score"
|
||||
:placeholder="$t('dialogue.field.enter_score')"
|
||||
:show-button="false"
|
||||
@update:value="onUpdate" />
|
||||
</template>
|
||||
<template #action="{ index, create, remove, move }">
|
||||
|
|
|
@ -52,6 +52,7 @@ defineExpose({
|
|||
<n-input-number
|
||||
v-model:value="value.score"
|
||||
:placeholder="$t('dialogue.field.enter_score')"
|
||||
:show-button="false"
|
||||
@update:value="onUpdate" />
|
||||
</template>
|
||||
<template #action="{ index, create, remove, move }">
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useThemeVars } from 'naive-ui'
|
|||
import BrowserTree from './BrowserTree.vue'
|
||||
import IconButton from '@/components/common/IconButton.vue'
|
||||
import useTabStore from 'stores/tab.js'
|
||||
import { computed, nextTick, onMounted, reactive, ref, unref } from 'vue'
|
||||
import { computed, nextTick, onMounted, reactive, ref, unref, watch } from 'vue'
|
||||
import { find, get, map, size } from 'lodash'
|
||||
import Refresh from '@/components/icons/Refresh.vue'
|
||||
import useDialogStore from 'stores/dialog.js'
|
||||
|
@ -238,6 +238,11 @@ const onSelectOptions = (select) => {
|
|||
}
|
||||
|
||||
onMounted(() => onReload())
|
||||
|
||||
watch(
|
||||
() => browserStore.getReloadKey(props.server),
|
||||
(key) => onReload(),
|
||||
)
|
||||
// forbid dynamic switch key view due to performance issues
|
||||
// const viewType = ref(0)
|
||||
// const onSwitchView = (selectView) => {
|
||||
|
@ -284,6 +289,7 @@ onMounted(() => onReload())
|
|||
:options="addOptions"
|
||||
placement="bottom-end"
|
||||
style="min-width: 130px"
|
||||
trigger="click"
|
||||
@select="onSelectOptions">
|
||||
<n-button :focusable="false" size="small" style="padding: 0 3px">
|
||||
<n-icon size="10">
|
||||
|
|
|
@ -367,13 +367,7 @@ const renderPrefix = ({ option }) => {
|
|||
|
||||
case ConnectionType.RedisValue:
|
||||
if (prefStore.keyIconType === typesIconStyle.ICON) {
|
||||
return h(
|
||||
NIcon,
|
||||
{ size: 20 },
|
||||
{
|
||||
default: () => h(!!option.redisKeyCode ? Binary : Key),
|
||||
},
|
||||
)
|
||||
return h(NIcon, { size: 20 }, () => h(Key))
|
||||
}
|
||||
const loading = isEmpty(option.redisType) || option.redisType === 'loading'
|
||||
if (loading) {
|
||||
|
@ -506,10 +500,8 @@ const calcValueMenu = () => {
|
|||
|
||||
// render menu function icon
|
||||
const renderSuffix = ({ option }) => {
|
||||
if (
|
||||
(option.type === ConnectionType.RedisDB && option.opened) ||
|
||||
(includes(selectedKeys.value, option.key) && !props.checkMode)
|
||||
) {
|
||||
const selected = includes(selectedKeys.value, option.key)
|
||||
if (selected && !props.checkMode) {
|
||||
switch (option.type) {
|
||||
case ConnectionType.RedisDB:
|
||||
return renderIconMenu(calcDBMenu(option.opened, option.loading, option.fullLoaded))
|
||||
|
@ -518,6 +510,9 @@ const renderSuffix = ({ option }) => {
|
|||
case ConnectionType.RedisValue:
|
||||
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
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
"update": "Update",
|
||||
"none": "None",
|
||||
"second": "Second(s)",
|
||||
"minute": "Minutes(s)",
|
||||
"hour": "Hour(s)",
|
||||
"day": "Day(s)",
|
||||
"unit_day": "D",
|
||||
"unit_hour": "H",
|
||||
"unit_minute": "M",
|
||||
|
@ -274,6 +277,8 @@
|
|||
},
|
||||
"export": {
|
||||
"name": "Export Data",
|
||||
"export_expire_title": "Expiration",
|
||||
"export_expire": "Include Expiration Time",
|
||||
"export": "Export",
|
||||
"save_file": "Export Path",
|
||||
"save_file_tip": "Select the path to save exported file",
|
||||
|
@ -282,19 +287,21 @@
|
|||
},
|
||||
"import": {
|
||||
"name": "Import Data",
|
||||
"export_expire_title": "Expiration",
|
||||
"export_expire": "Export Expiration Time",
|
||||
"import_expire_title": "Expiration",
|
||||
"import_expire": "Import Expiration Time",
|
||||
"import": "Import",
|
||||
"reload": "Reload Keys After Imported",
|
||||
"open_csv_file": "Import File",
|
||||
"open_csv_file_tip": "Select the file for import",
|
||||
"conflict_handle": "Handle Key Conflict",
|
||||
"conflict_handle": "Key Conflict Resolution",
|
||||
"conflict_overwrite": "Overwrite",
|
||||
"conflict_ignore": "Ignore",
|
||||
"importing": "Importing Keys imported/overwrite:{imported} conflict/fail:{conflict}",
|
||||
"import_completed": "Import completed, {success} successes, {ignored} failed"
|
||||
},
|
||||
"ttl": {
|
||||
"title": "Set Key TTL"
|
||||
"title": "Set Key TTL",
|
||||
"quick_set": "Quick Settings"
|
||||
},
|
||||
"upgrade": {
|
||||
"title": "New Version Available",
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
"update": "更新",
|
||||
"none": "无",
|
||||
"second": "秒",
|
||||
"minute": "分钟",
|
||||
"hour": "小时",
|
||||
"day": "天",
|
||||
"unit_day": "天",
|
||||
"unit_hour": "小时",
|
||||
"unit_minute": "分钟",
|
||||
|
@ -286,6 +289,7 @@
|
|||
"name": "导入数据",
|
||||
"import_expire_title": "过期时间",
|
||||
"import_expire": "包含键过期时间",
|
||||
"reload": "导入完成后重新载入",
|
||||
"import": "确认导入",
|
||||
"open_csv_file": "导入文件路径",
|
||||
"open_csv_file_tip": "选择需要导入的文件",
|
||||
|
@ -296,7 +300,8 @@
|
|||
"import_completed": "已完成导入操作,成功{success}个,忽略{ignored}个"
|
||||
},
|
||||
"ttl": {
|
||||
"title": "设置键存活时间"
|
||||
"title": "设置键存活时间",
|
||||
"quick_set": "快捷设置"
|
||||
},
|
||||
"upgrade": {
|
||||
"title": "有可用新版本",
|
||||
|
|
|
@ -19,6 +19,7 @@ export class RedisServerState {
|
|||
/**
|
||||
* @param {string} name server name
|
||||
* @param {number} db current opened database
|
||||
* @param {number} reloadKey try to reload when changed
|
||||
* @param {{}} stats current server status info
|
||||
* @param {Object.<number, RedisDatabaseItem>} databases database list
|
||||
* @param {string|null} patternFilter pattern filter
|
||||
|
@ -40,6 +41,7 @@ export class RedisServerState {
|
|||
}) {
|
||||
this.name = name
|
||||
this.db = db
|
||||
this.reloadKey = Date.now()
|
||||
this.stats = stats
|
||||
this.databases = databases
|
||||
this.patternFilter = patternFilter
|
||||
|
@ -83,7 +85,7 @@ export class RedisServerState {
|
|||
* @param {number} updateVal
|
||||
*/
|
||||
updateDBKeyCount(db, updateVal) {
|
||||
const dbInst = this.databases[this.db]
|
||||
const dbInst = this.databases[db]
|
||||
if (dbInst != null) {
|
||||
dbInst.maxKeys = Math.max(0, dbInst.maxKeys + updateVal)
|
||||
}
|
||||
|
@ -288,6 +290,11 @@ export class RedisServerState {
|
|||
// clear all key nodes
|
||||
this.nodeMap.clear()
|
||||
this.getRoot()
|
||||
const dbInst = this.databases[this.db]
|
||||
if (dbInst != null) {
|
||||
dbInst.maxKeys = 0
|
||||
dbInst.keyCount = 0
|
||||
}
|
||||
} else {
|
||||
const keyParts = split(key, this.separator)
|
||||
const totalParts = size(keyParts)
|
||||
|
|
|
@ -166,6 +166,20 @@ const useBrowserStore = defineStore('browser', {
|
|||
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
|
||||
* @param {string} connName
|
||||
|
@ -1493,7 +1507,7 @@ const useBrowserStore = defineStore('browser', {
|
|||
*/
|
||||
async deleteKey(server, db, key, soft) {
|
||||
try {
|
||||
let deleteCount = 0
|
||||
let deleteCount = 1
|
||||
if (soft !== true) {
|
||||
const { data } = await DeleteKey(server, db, key)
|
||||
deleteCount = get(data, 'deleteCount', 0)
|
||||
|
@ -1660,9 +1674,10 @@ const useBrowserStore = defineStore('browser', {
|
|||
* @param {string} path
|
||||
* @param {number} conflict
|
||||
* @param {boolean} [expire]
|
||||
* @param {boolean} [reload]
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async importKeysFromCSVFile(server, db, path, conflict, expire) {
|
||||
async importKeysFromCSVFile(server, db, path, conflict, expire, reload) {
|
||||
const msgRef = $message.loading('', { duration: 0, closable: true })
|
||||
let imported = 0
|
||||
let ignored = 0
|
||||
|
@ -1695,8 +1710,11 @@ const useBrowserStore = defineStore('browser', {
|
|||
if (canceled) {
|
||||
$message.info(i18nGlobal.t('dialogue.handle_cancel'))
|
||||
} else {
|
||||
// no fail
|
||||
// finish
|
||||
$message.success(i18nGlobal.t('dialogue.import.import_completed', { success: imported, ignored }))
|
||||
if (reload) {
|
||||
this.reloadServer(server)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1717,7 +1735,6 @@ const useBrowserStore = defineStore('browser', {
|
|||
if (serverInst != null) {
|
||||
// update tree view data
|
||||
serverInst.removeKeyNode()
|
||||
serverInst.setDBKeyCount(db, 0)
|
||||
}
|
||||
// set tab content empty
|
||||
const tab = useTabStore()
|
||||
|
|
|
@ -23,7 +23,7 @@ export const themeOverrides = {
|
|||
paddingMedium: '0 12px',
|
||||
},
|
||||
Tag: {
|
||||
// borderRadius: '3px'
|
||||
borderRadius: '4px',
|
||||
heightLarge: '32px',
|
||||
},
|
||||
Input: {
|
||||
|
|
Loading…
Reference in New Issue