Compare commits

...

4 Commits

Author SHA1 Message Date
Lykin a682aabb0b fix: can not refresh value display after edit 2024-04-19 17:21:20 +08:00
Lykin 971c89a5cf perf: add shortcut for key operations 2024-04-19 16:43:42 +08:00
Lykin b72855b707 perf: add shortcut `esc` for close modal dialog (#235) 2024-04-19 15:13:06 +08:00
Lykin 974477cb49 fix: maximum call stack size exceeded (#234) 2024-04-19 11:54:05 +08:00
20 changed files with 92 additions and 28 deletions

View File

@ -23,6 +23,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
resetKey: {
type: String,
default: '',
},
offsetKey: { offsetKey: {
type: String, type: String,
default: '', default: '',
@ -144,6 +148,17 @@ watch(
}, },
) )
watch(
() => props.resetKey,
async () => {
if (editorNode != null) {
editorNode.setValue(props.content)
await nextTick(() => emit('reset', props.content))
updateScroll()
}
},
)
watch( watch(
() => props.offsetKey, () => props.offsetKey,
() => { () => {

View File

@ -178,8 +178,8 @@ const onListLimitChanged = (limit) => {
<n-form-item :label="$t('slog.limit')"> <n-form-item :label="$t('slog.limit')">
<n-input-number <n-input-number
v-model:value="data.listLimit" v-model:value="data.listLimit"
:min="1"
:max="9999" :max="9999"
:min="1"
style="width: 120px" style="width: 120px"
@update:value="onListLimitChanged" /> @update:value="onListLimitChanged" />
</n-form-item> </n-form-item>

View File

@ -71,6 +71,7 @@ const viewAs = reactive({
}) })
const editingContent = ref('') const editingContent = ref('')
const resetKey = ref('')
const enableSave = computed(() => { const enableSave = computed(() => {
return editingContent.value !== viewAs.value && !props.loading return editingContent.value !== viewAs.value && !props.loading
@ -110,6 +111,7 @@ const onFormatChanged = async (decode = '', format = '') => {
viewAs.decode = decode || retDecode viewAs.decode = decode || retDecode
viewAs.format = format || retFormat viewAs.format = format || retFormat
browserStore.setSelectedFormat(props.name, props.keyPath, props.db, viewAs.format, viewAs.decode) browserStore.setSelectedFormat(props.name, props.keyPath, props.db, viewAs.format, viewAs.decode)
resetKey.value = Date.now().toString()
} finally { } finally {
converting.value = false converting.value = false
} }
@ -207,6 +209,7 @@ defineExpose({
:language="viewLanguage" :language="viewLanguage"
:loading="props.loading" :loading="props.loading"
:offset-key="props.keyPath" :offset-key="props.keyPath"
:reset-key="resetKey"
class="flex-item-expand" class="flex-item-expand"
keep-offset keep-offset
style="height: 100%" style="height: 100%"

View File

@ -14,6 +14,7 @@ import useDialogStore from 'stores/dialog.js'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentToolbar from '@/components/content_value/ContentToolbar.vue' import ContentToolbar from '@/components/content_value/ContentToolbar.vue'
import ContentValueJson from '@/components/content_value/ContentValueJson.vue' import ContentValueJson from '@/components/content_value/ContentValueJson.vue'
import { isMacOS } from '@/utils/platform.js'
const themeVars = useThemeVars() const themeVars = useThemeVars()
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
@ -126,6 +127,35 @@ const onReload = async (selDecode, selFormat) => {
} }
} }
const onKeyShortcut = (e) => {
// console.log(e)
switch (e.key) {
case 'Delete':
onDelete()
return
case 'd':
if (e.metaKey) {
onDelete()
}
return
case 'F5':
onReload()
return
case 'r':
if (e.metaKey && isMacOS()) {
onReload()
}
return
case 'F2':
onRename()
return
}
}
const onRename = () => { const onRename = () => {
const { name, db, keyPath } = data.value const { name, db, keyPath } = data.value
if (binaryKey.value) { if (binaryKey.value) {
@ -189,6 +219,8 @@ watch(() => data.value?.keyPath, initContent)
<!-- FIXME: keep alive may cause virtual list null value error. --> <!-- FIXME: keep alive may cause virtual list null value error. -->
<!-- <keep-alive v-else> --> <!-- <keep-alive v-else> -->
<component <component
tabindex="0"
@keydown="onKeyShortcut"
:is="valueComponents[data.type]" :is="valueComponents[data.type]"
v-else v-else
ref="contentRef" ref="contentRef"

View File

@ -197,7 +197,6 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.addFieldsDialogVisible" v-model:show="dialogStore.addFieldsDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ size: 'medium' }" :negative-button-props="{ size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
@ -205,9 +204,11 @@ const onClose = () => {
:positive-text="$t('common.confirm')" :positive-text="$t('common.confirm')"
:show-icon="false" :show-icon="false"
:title="title ? $t(title) : ''" :title="title ? $t(title) : ''"
close-on-esc
preset="dialog" preset="dialog"
style="width: 600px" style="width: 600px"
transform-origin="center" transform-origin="center"
@esc="onClose"
@positive-click="onAdd" @positive-click="onAdd"
@negative-click="onClose"> @negative-click="onClose">
<n-scrollbar style="max-height: 500px"> <n-scrollbar style="max-height: 500px">

View File

@ -329,14 +329,15 @@ const pasteFromClipboard = async () => {
<n-modal <n-modal
v-model:show="dialogStore.connDialogVisible" v-model:show="dialogStore.connDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:on-after-leave="resetForm" :on-after-leave="resetForm"
:show-icon="false" :show-icon="false"
:title="isEditMode ? $t('dialogue.connection.edit_title') : $t('dialogue.connection.new_title')" :title="isEditMode ? $t('dialogue.connection.edit_title') : $t('dialogue.connection.new_title')"
close-on-esc
preset="dialog" preset="dialog"
style="width: 600px" style="width: 600px"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<n-spin :show="closingConnection"> <n-spin :show="closingConnection">
<n-tabs <n-tabs
v-model:value="tab" v-model:value="tab"

View File

@ -75,7 +75,6 @@ const onClose = () => {}
<n-modal <n-modal
v-model:show="dialogStore.decodeDialogVisible" v-model:show="dialogStore.decodeDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ focusable: false, size: 'medium' }" :negative-button-props="{ focusable: false, size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
@ -83,8 +82,10 @@ const onClose = () => {}
:positive-text="$t('common.confirm')" :positive-text="$t('common.confirm')"
:show-icon="false" :show-icon="false"
:title="editName ? $t('dialogue.decoder.edit_name') : $t('dialogue.decoder.name')" :title="editName ? $t('dialogue.decoder.edit_name') : $t('dialogue.decoder.name')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center" transform-origin="center"
@esc="onClose"
@positive-click="onAddOrUpdate" @positive-click="onAddOrUpdate"
@negative-click="onClose"> @negative-click="onClose">
<n-form :model="decoderForm" :show-require-mark="false" label-align="left" label-placement="top"> <n-form :model="decoderForm" :show-require-mark="false" label-align="left" label-placement="top">

View File

@ -93,12 +93,13 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.deleteKeyDialogVisible" v-model:show="dialogStore.deleteKeyDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:show-icon="false" :show-icon="false"
:title="$t('interface.batch_delete_key')" :title="$t('interface.batch_delete_key')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<n-spin :show="loading"> <n-spin :show="loading">
<n-form :model="deleteForm" :show-require-mark="false" label-placement="top"> <n-form :model="deleteForm" :show-require-mark="false" label-placement="top">
<n-grid :x-gap="10"> <n-grid :x-gap="10">

View File

@ -64,12 +64,13 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.exportKeyDialogVisible" v-model:show="dialogStore.exportKeyDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:show-icon="false" :show-icon="false"
:title="$t('dialogue.export.name')" :title="$t('dialogue.export.name')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<n-spin :show="loading"> <n-spin :show="loading">
<n-form :model="exportKeyForm" :show-require-mark="false" label-placement="top"> <n-form :model="exportKeyForm" :show-require-mark="false" label-placement="top">
<n-grid :x-gap="10"> <n-grid :x-gap="10">

View File

@ -54,12 +54,13 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.flushDBDialogVisible" v-model:show="dialogStore.flushDBDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:show-icon="false" :show-icon="false"
:title="$t('interface.flush_db')" :title="$t('interface.flush_db')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<n-spin :show="loading"> <n-spin :show="loading">
<n-form :model="flushForm" :show-require-mark="false" label-placement="top"> <n-form :model="flushForm" :show-require-mark="false" label-placement="top">
<n-form-item :label="$t('dialogue.key.server')"> <n-form-item :label="$t('dialogue.key.server')">

View File

@ -89,7 +89,6 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.groupDialogVisible" v-model:show="dialogStore.groupDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ size: 'medium' }" :negative-button-props="{ size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
@ -97,8 +96,10 @@ const onClose = () => {
:positive-text="$t('common.confirm')" :positive-text="$t('common.confirm')"
:show-icon="false" :show-icon="false"
:title="isRenameMode ? $t('dialogue.group.rename') : $t('dialogue.group.new')" :title="isRenameMode ? $t('dialogue.group.rename') : $t('dialogue.group.new')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center" transform-origin="center"
@esc="onClose"
@positive-click="onConfirm" @positive-click="onConfirm"
@negative-click="onClose"> @negative-click="onClose">
<n-form <n-form

View File

@ -103,12 +103,13 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.importKeyDialogVisible" v-model:show="dialogStore.importKeyDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:show-icon="false" :show-icon="false"
:title="$t('dialogue.import.name')" :title="$t('dialogue.import.name')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<n-spin :show="loading"> <n-spin :show="loading">
<n-form :model="importKeyForm" :show-require-mark="false" label-placement="top"> <n-form :model="importKeyForm" :show-require-mark="false" label-placement="top">
<n-grid :x-gap="10"> <n-grid :x-gap="10">

View File

@ -47,7 +47,6 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.keyFilterDialogVisible" v-model:show="dialogStore.keyFilterDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ size: 'medium' }" :negative-button-props="{ size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
@ -55,9 +54,11 @@ const onClose = () => {
:positive-text="$t('common.confirm')" :positive-text="$t('common.confirm')"
:show-icon="false" :show-icon="false"
:title="$t('dialogue.filter.set_key_filter')" :title="$t('dialogue.filter.set_key_filter')"
close-on-esc
preset="dialog" preset="dialog"
style="width: 450px" style="width: 450px"
transform-origin="center" transform-origin="center"
@esc="onClose"
@positive-click="onConfirm" @positive-click="onConfirm"
@negative-click="onClose"> @negative-click="onClose">
<n-form <n-form

View File

@ -191,13 +191,14 @@ const onImport = () => {
<n-modal <n-modal
v-model:show="dialogStore.newKeyDialogVisible" v-model:show="dialogStore.newKeyDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:show-icon="false" :show-icon="false"
:title="$t('dialogue.key.new')" :title="$t('dialogue.key.new')"
close-on-esc
preset="dialog" preset="dialog"
style="width: 600px" style="width: 600px"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<n-scrollbar ref="scrollRef" style="max-height: 500px"> <n-scrollbar ref="scrollRef" style="max-height: 500px">
<n-form <n-form
ref="newFormRef" ref="newFormRef"

View File

@ -192,13 +192,14 @@ const onClose = () => {
v-model:show="dialogStore.preferencesDialogVisible" v-model:show="dialogStore.preferencesDialogVisible"
:auto-focus="false" :auto-focus="false"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:show-icon="false" :show-icon="false"
:title="$t('preferences.name')" :title="$t('preferences.name')"
close-on-esc
preset="dialog" preset="dialog"
style="width: 640px" style="width: 640px"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<!-- FIXME: set loading will slow down appear animation of dialog in linux --> <!-- FIXME: set loading will slow down appear animation of dialog in linux -->
<!-- <n-spin :show="loading"> --> <!-- <n-spin :show="loading"> -->
<n-tabs <n-tabs

View File

@ -53,7 +53,6 @@ const onClose = () => {
<n-modal <n-modal
v-model:show="dialogStore.renameDialogVisible" v-model:show="dialogStore.renameDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ focusable: false, size: 'medium' }" :negative-button-props="{ focusable: false, size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
@ -61,8 +60,10 @@ const onClose = () => {
: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')"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center" transform-origin="center"
@esc="onClose"
@positive-click="onRename" @positive-click="onRename"
@negative-click="onClose"> @negative-click="onClose">
<n-form <n-form

View File

@ -93,7 +93,6 @@ const onConfirm = async () => {
<n-modal <n-modal
v-model:show="dialogStore.ttlDialogVisible" v-model:show="dialogStore.ttlDialogVisible"
:closable="false" :closable="false"
:close-on-esc="false"
:mask-closable="false" :mask-closable="false"
:negative-button-props="{ focusable: false, size: 'medium' }" :negative-button-props="{ focusable: false, size: 'medium' }"
:negative-text="$t('common.cancel')" :negative-text="$t('common.cancel')"
@ -103,8 +102,10 @@ const onConfirm = async () => {
:positive-text="$t('common.save')" :positive-text="$t('common.save')"
:show-icon="false" :show-icon="false"
:title="title" :title="title"
close-on-esc
preset="dialog" preset="dialog"
transform-origin="center"> transform-origin="center"
@esc="onClose">
<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 v-if="!isBatchAction" :label="$t('common.key')"> <n-form-item v-if="!isBatchAction" :label="$t('common.key')">
<n-input :value="ttlForm.key" readonly /> <n-input :value="ttlForm.key" readonly />

View File

@ -598,6 +598,7 @@ defineExpose({
check-strategy="child" check-strategy="child"
class="fill-height" class="fill-height"
virtual-scroll virtual-scroll
@keydown.delete="handleSelectContextMenu('value_remove')"
@update:selected-keys="onUpdateSelectedKeys" @update:selected-keys="onUpdateSelectedKeys"
@update:expanded-keys="onUpdateExpanded" @update:expanded-keys="onUpdateExpanded"
@update:checked-keys="onUpdateCheckedKeys" /> @update:checked-keys="onUpdateCheckedKeys" />

View File

@ -204,11 +204,7 @@ const exThemeVars = computed(() => {
</div> </div>
<!-- wechat official modal --> <!-- wechat official modal -->
<n-modal <n-modal v-model:show="showWechat" close-on-esc mask-closable transform-origin="center">
:show="showWechat"
transform-origin="center"
@close="showWechat = false"
@mask-click="showWechat = false">
<n-image :src="wechatUrl" :width="400" preview-disabled /> <n-image :src="wechatUrl" :width="400" preview-disabled />
</n-modal> </n-modal>
</div> </div>

View File

@ -244,7 +244,11 @@ const useTabStore = defineStore('tab', {
if (!!!reset && typeof value === 'object') { if (!!!reset && typeof value === 'object') {
if (value instanceof Array) { if (value instanceof Array) {
tabData.value = tabData.value || [] tabData.value = tabData.value || []
tabData.value.push(...value) // direct deconstruction leads to 'Maximum call stack size exceeded'
// tabData.value.push(...value)
for (let i = 0; i < value.length; i++) {
tabData.value.push(value[i])
}
} else { } else {
tabData.value = assign(value, tabData.value || {}) tabData.value = assign(value, tabData.value || {})
} }