perf: support reload option after import data

This commit is contained in:
Lykin 2024-01-03 18:44:51 +08:00
parent 1340f911c8
commit a71f5e0070
7 changed files with 53 additions and 16 deletions

View File

@ -219,7 +219,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 label=" " path="key" required> <n-form-item :show-label="false" 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

@ -10,6 +10,7 @@ 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,
@ -25,6 +26,7 @@ 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
@ -33,7 +35,7 @@ watchEffect(() => {
}) })
const i18n = useI18n() const i18n = useI18n()
const conflictOption = [ const conflictOption = computed(() => [
{ {
value: 0, value: 0,
label: i18n.t('dialogue.import.conflict_overwrite'), label: i18n.t('dialogue.import.conflict_overwrite'),
@ -42,7 +44,7 @@ const conflictOption = [
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)
@ -51,8 +53,8 @@ const importEnable = computed(() => {
const onConfirmImport = async () => { const onConfirmImport = async () => {
try { try {
importing.value = true importing.value = true
const { server, db, file, conflict, expire } = importKeyForm const { server, db, file, conflict, expire, reload } = importKeyForm
browserStore.importKeysFromCSVFile(server, db, file, conflict, expire).catch((e) => {}) browserStore.importKeysFromCSVFile(server, db, file, conflict, expire, reload).catch((e) => {})
} catch (e) { } catch (e) {
$message.error(e.message) $message.error(e.message)
return return
@ -93,11 +95,6 @@ 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
@ -107,6 +104,16 @@ 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

@ -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 } from 'vue' import { computed, nextTick, onMounted, reactive, ref, unref, watch } 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,6 +238,11 @@ 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) => {
@ -284,6 +289,7 @@ onMounted(() => onReload())
: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

@ -277,6 +277,8 @@
}, },
"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",
@ -285,12 +287,13 @@
}, },
"import": { "import": {
"name": "Import Data", "name": "Import Data",
"export_expire_title": "Expiration", "import_expire_title": "Expiration",
"export_expire": "Export Expiration Time", "import_expire": "Import 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": "Handle Key Conflict", "conflict_handle": "Key Conflict Resolution",
"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}",

View File

@ -289,6 +289,7 @@
"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": "选择需要导入的文件",

View File

@ -19,6 +19,7 @@ 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
@ -40,6 +41,7 @@ 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

View File

@ -166,6 +166,20 @@ 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
@ -1660,9 +1674,10 @@ 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) { async importKeysFromCSVFile(server, db, path, conflict, expire, reload) {
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
@ -1695,8 +1710,11 @@ const useBrowserStore = defineStore('browser', {
if (canceled) { if (canceled) {
$message.info(i18nGlobal.t('dialogue.handle_cancel')) $message.info(i18nGlobal.t('dialogue.handle_cancel'))
} else { } else {
// no fail // finish
$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)
}
} }
}, },