feat: complete function in toolbar of browser

refactor: use uniform confirm dialog for delete key
This commit is contained in:
tiny-craft 2023-07-04 00:42:17 +08:00
parent 2c7021af31
commit e906a91964
9 changed files with 110 additions and 66 deletions

View File

@ -25,7 +25,7 @@ const emit = defineEmits(['edit', 'delete', 'save', 'cancel'])
<template #trigger> <template #trigger>
<icon-button :icon="Delete" /> <icon-button :icon="Delete" />
</template> </template>
{{ $t('delete_key_tip', { key: props.bindKey }) }} {{ $t('remove_tip', { name: props.bindKey }) }}
</n-popconfirm> </n-popconfirm>
</div> </div>
</template> </template>

View File

@ -10,6 +10,7 @@ import { useI18n } from 'vue-i18n'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import IconButton from '../common/IconButton.vue' import IconButton from '../common/IconButton.vue'
import useConnectionStore from '../../stores/connections.js' import useConnectionStore from '../../stores/connections.js'
import { useConfirmDialog } from '../../utils/confirm_dialog.js'
const props = defineProps({ const props = defineProps({
server: String, server: String,
@ -37,11 +38,15 @@ const onReloadKey = () => {
connectionStore.loadKeyValue(props.server, props.db, props.keyPath) connectionStore.loadKeyValue(props.server, props.db, props.keyPath)
} }
const onConfirmDelete = async () => { const confirmDialog = useConfirmDialog()
const success = await connectionStore.removeKey(props.server, props.db, props.keyPath) const onDeleteKey = () => {
if (success) { confirmDialog.warning(i18n.t('remove_tip', { name: props.keyPath }), () => {
message.success(i18n.t('delete_key_succ', { key: props.keyPath })) connectionStore.removeKey(props.server, props.db, props.keyPath).then((success) => {
} if (success) {
message.success(i18n.t('delete_key_succ', { key: props.keyPath }))
}
})
})
} }
</script> </script>
@ -86,20 +91,11 @@ const onConfirmDelete = async () => {
</n-button-group> </n-button-group>
<n-tooltip> <n-tooltip>
<template #trigger> <template #trigger>
<n-popconfirm <n-button>
:negative-text="$t('cancel')" <template #icon>
:positive-text="$t('confirm')" <n-icon :component="Delete" size="18" @click="onDeleteKey" />
@positive-click="onConfirmDelete"
>
<template #trigger>
<n-button>
<template #icon>
<n-icon :component="Delete" size="18" />
</template>
</n-button>
</template> </template>
{{ $t('delete_key_tip', { key: props.keyPath }) }} </n-button>
</n-popconfirm>
</template> </template>
{{ $t('delete_key') }} {{ $t('delete_key') }}
</n-tooltip> </n-tooltip>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { NIcon } from 'naive-ui' import { NIcon, useMessage } from 'naive-ui'
import AddLink from '../icons/AddLink.vue' import AddLink from '../icons/AddLink.vue'
import BrowserTree from './BrowserTree.vue' import BrowserTree from './BrowserTree.vue'
import IconButton from '../common/IconButton.vue' import IconButton from '../common/IconButton.vue'
@ -10,10 +10,47 @@ import { get } from 'lodash'
import Delete from '../icons/Delete.vue' import Delete from '../icons/Delete.vue'
import Refresh from '../icons/Refresh.vue' import Refresh from '../icons/Refresh.vue'
import useDialogStore from '../../stores/dialog.js' import useDialogStore from '../../stores/dialog.js'
import { useConfirmDialog } from '../../utils/confirm_dialog.js'
import { useI18n } from 'vue-i18n'
import useConnectionStore from '../../stores/connections.js'
const dialogStore = useDialogStore() const dialogStore = useDialogStore()
const tabStore = useTabStore() const tabStore = useTabStore()
const currentName = computed(() => get(tabStore.currentTab, 'name', '')) const currentName = computed(() => get(tabStore.currentTab, 'name', ''))
/**
*
* @type {ComputedRef<{server: string, db: number, key: string}>}
*/
const currentSelect = computed(() => {
const { server, db, key } = tabStore.currentTab || {}
return { server, db, key }
})
const onNewKey = () => {
const { server, db, key } = currentSelect.value
dialogStore.openNewKeyDialog(key, server, db)
}
const i18n = useI18n()
const connectionStore = useConnectionStore()
const confirmDialog = useConfirmDialog()
const message = useMessage()
const onDeleteKey = () => {
const { server, db, key } = currentSelect.value
confirmDialog.warning(i18n.t('remove_tip', { name: key }), () => {
connectionStore.removeKey(server, db, key).then((success) => {
if (success) {
message.success(i18n.t('delete_key_succ', { key }))
}
})
})
}
const onRefresh = () => {
connectionStore.openConnection(currentSelect.value.server, true).then(() => {
message.success(i18n.t('reload_succ'))
})
}
</script> </script>
<template> <template>
@ -22,27 +59,39 @@ const currentName = computed(() => get(tabStore.currentTab, 'name', ''))
<!-- bottom function bar --> <!-- bottom function bar -->
<div class="nav-pane-bottom flex-box-h"> <div class="nav-pane-bottom flex-box-h">
<icon-button :icon="AddLink" color="#555" size="20" stroke-width="4" t-tooltip="new_key" /> <icon-button
<icon-button :icon="Delete" color="#555" size="20" stroke-width="4" t-tooltip="remove_key" /> :icon="AddLink"
<icon-button :icon="Refresh" color="#555" size="20" stroke-width="4" t-tooltip="reload" /> color="#555"
<n-input placeholder=""> size="20"
<template #prefix> stroke-width="4"
<n-icon :component="Filter" color="#aaa" size="20" /> t-tooltip="new_key"
</template> @click="onNewKey"
</n-input> />
<icon-button
:icon="Refresh"
color="#555"
size="20"
stroke-width="4"
t-tooltip="reload"
@click="onRefresh"
/>
<div class="flex-item-expand"></div>
<icon-button
:disabled="currentSelect.key == null"
:icon="Delete"
color="#555"
size="20"
stroke-width="4"
t-tooltip="remove_key"
@click="onDeleteKey"
/>
<!-- <n-input placeholder="">-->
<!-- <template #prefix>-->
<!-- <n-icon :component="Filter" color="#aaa" size="20" />-->
<!-- </template>-->
<!-- </n-input>-->
</div> </div>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped></style>
.nav-pane-container {
overflow: hidden;
background-color: var(--bg-color);
.nav-pane-bottom {
align-items: center;
gap: 5px;
padding: 3px 3px 5px 5px;
}
}
</style>

View File

@ -162,15 +162,6 @@ const onUpdateSelectedKeys = (keys, option) => {
selectedKeys.value = keys selectedKeys.value = keys
} }
watch(
() => selectedKeys,
(keys) => {
if (size(keys) > 0) {
console.log('selected')
}
}
)
const renderPrefix = ({ option }) => { const renderPrefix = ({ option }) => {
switch (option.type) { switch (option.type) {
case ConnectionType.RedisDB: case ConnectionType.RedisDB:
@ -290,7 +281,7 @@ const handleSelectContextMenu = (key) => {
break break
case 'key_remove': case 'key_remove':
case 'value_remove': case 'value_remove':
confirmDialog.warning(i18n.t('delete_key_tip', { key: redisKey }), () => { confirmDialog.warning(i18n.t('remove_tip', { name: redisKey }), () => {
connectionStore.removeKey(name, db, redisKey).then((success) => { connectionStore.removeKey(name, db, redisKey).then((success) => {
if (success) { if (success) {
message.success(i18n.t('delete_key_succ', { key: redisKey })) message.success(i18n.t('delete_key_succ', { key: redisKey }))

View File

@ -59,15 +59,4 @@ const onDisconnectAll = () => {
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped></style>
.nav-pane-container {
overflow: hidden;
background-color: var(--bg-color);
.nav-pane-bottom {
align-items: center;
gap: 5px;
padding: 3px 3px 5px 5px;
}
}
</style>

View File

@ -19,7 +19,6 @@
"forever": "Forever", "forever": "Forever",
"rename_key": "Rename Key", "rename_key": "Rename Key",
"delete_key": "Delete Key", "delete_key": "Delete Key",
"delete_key_tip": "\"{key}\" will be deleted",
"delete_key_succ": "\"{key}\" has been deleted", "delete_key_succ": "\"{key}\" has been deleted",
"copy_value": "Copy Value", "copy_value": "Copy Value",
"edit_value": "Edit Value", "edit_value": "Edit Value",
@ -110,6 +109,7 @@
"copy_value_succ": "Value Copied !", "copy_value_succ": "Value Copied !",
"save_value_succ": "Value Saved !", "save_value_succ": "Value Saved !",
"handle_succ": "Handle Success !", "handle_succ": "Handle Success !",
"reload_succ": "Reload Success !",
"field_required": "This item should not be blank", "field_required": "This item should not be blank",
"spec_field_required": "\"{key}\" should not be blank", "spec_field_required": "\"{key}\" should not be blank",
"no_connections": "No Connection", "no_connections": "No Connection",

View File

@ -19,7 +19,6 @@
"forever": "永久", "forever": "永久",
"rename_key": "重命名键", "rename_key": "重命名键",
"delete_key": "删除键", "delete_key": "删除键",
"delete_key_tip": "{key} 将会被删除",
"delete_key_succ": "{key} 已被删除", "delete_key_succ": "{key} 已被删除",
"copy_value": "复制值", "copy_value": "复制值",
"edit_value": "修改值", "edit_value": "修改值",
@ -113,6 +112,7 @@
"copy_succ": "已复制到剪切板", "copy_succ": "已复制到剪切板",
"save_value_succ": "已保存值", "save_value_succ": "已保存值",
"handle_succ": "操作成功", "handle_succ": "操作成功",
"reload_succ": "已重新载入",
"field_required": "此项不能为空", "field_required": "此项不能为空",
"spec_field_required": "{key} 不能为空", "spec_field_required": "{key} 不能为空",
"no_connections": "空空如也", "no_connections": "空空如也",

View File

@ -233,11 +233,17 @@ const useConnectionStore = defineStore('connections', {
/** /**
* open connection * open connection
* @param {string} name * @param {string} name
* @param {boolean} [reload]
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async openConnection(name) { async openConnection(name, reload) {
if (this.isConnected(name)) { if (this.isConnected(name)) {
return if (reload !== true) {
return
} else {
// reload mode, try close connection first
await CloseConnection(name)
}
} }
const { data, success, msg } = await OpenConnection(name) const { data, success, msg } = await OpenConnection(name)

View File

@ -111,3 +111,16 @@ body {
min-width: 100px; min-width: 100px;
padding-right: 10px; padding-right: 10px;
} }
.nav-pane-container {
overflow: hidden;
background-color: var(--bg-color);
.nav-pane-bottom {
align-items: center;
gap: 8px;
padding: 3px 5px 5px 5px;
min-height: 35px;
border-top: var(--border-color) 1px solid;
}
}