From 13f343977ab90ced82fafdf25af101e146ff189b Mon Sep 17 00:00:00 2001 From: Lykin <137850705+tiny-craft@users.noreply.github.com> Date: Fri, 17 Nov 2023 23:50:10 +0800 Subject: [PATCH] chore: refine ui details --- backend/utils/string/convert.go | 2 +- .../src/components/content/ContentLogPane.vue | 181 +++++++++--------- .../content_value/ContentEntryEditor.vue | 2 + .../components/content_value/ContentSlog.vue | 166 ++++++++-------- .../content_value/ContentValueHash.vue | 4 + .../content_value/ContentValueList.vue | 4 + .../content_value/ContentValueZSet.vue | 10 +- .../src/components/new_value/AddHashValue.vue | 4 +- .../src/components/new_value/AddZSetValue.vue | 7 +- frontend/src/langs/en-us.json | 2 +- frontend/src/langs/pt-br.json | 2 +- frontend/src/langs/zh-cn.json | 2 +- 12 files changed, 204 insertions(+), 182 deletions(-) diff --git a/backend/utils/string/convert.go b/backend/utils/string/convert.go index e8c3e2f..12ebd8c 100644 --- a/backend/utils/string/convert.go +++ b/backend/utils/string/convert.go @@ -109,7 +109,7 @@ func autoDecode(str string) (value, resultDecode string) { // pure digit content may incorrect regard as some encoded type, skip decode if match, _ := regexp.MatchString(`^\d+$`, str); !match { var ok bool - if len(str)%4 == 0 && !isSameChar(str) { + if len(str)%4 == 0 && len(str) >= 12 && !isSameChar(str) { if value, ok = decodeBase64(str); ok { resultDecode = types.DECODE_BASE64 return diff --git a/frontend/src/components/content/ContentLogPane.vue b/frontend/src/components/content/ContentLogPane.vue index fc4c79e..27493d2 100644 --- a/frontend/src/components/content/ContentLogPane.vue +++ b/frontend/src/components/content/ContentLogPane.vue @@ -34,39 +34,101 @@ const filterServerOption = computed(() => { const tableRef = ref(null) -const loadHistory = () => { - data.loading = true - browserStore - .getCmdHistory() - .then((list) => { - data.history = list || [] - }) - .finally(() => { - data.loading = false - tableRef.value?.scrollTo({ top: 999999 }) - }) +const columns = computed(() => [ + { + title: i18n.t('log.exec_time'), + key: 'timestamp', + defaultSortOrder: 'ascend', + sorter: 'default', + width: 180, + align: 'center', + titleAlign: 'center', + render: ({ timestamp }, index) => { + return dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') + }, + }, + { + title: i18n.t('log.server'), + key: 'server', + filterOptionValue: data.server, + filter: (value, row) => { + return value === '' || row.server === value.toString() + }, + width: 150, + align: 'center', + titleAlign: 'center', + ellipsis: { + tooltip: true, + }, + }, + { + title: i18n.t('log.cmd'), + key: 'cmd', + titleAlign: 'center', + filterOptionValue: data.keyword, + resizable: true, + filter: (value, row) => { + return value === '' || !!~row.cmd.indexOf(value.toString()) + }, + render: ({ cmd }, index) => { + const cmdList = split(cmd, '\n') + if (size(cmdList) > 1) { + return h( + 'div', + null, + map(cmdList, (c) => h('div', null, c)), + ) + } + return cmd + }, + }, + { + title: i18n.t('log.cost_time'), + key: 'cost', + width: 100, + align: 'center', + titleAlign: 'center', + render: ({ cost }, index) => { + const ms = dayjs.duration(cost).asMilliseconds() + if (ms < 1000) { + return `${ms} ms` + } else { + return `${Math.floor(ms / 1000)} s` + } + }, + }, +]) + +const loadHistory = async () => { + try { + await nextTick() + data.loading = true + const list = await browserStore.getCmdHistory() + data.history = list || [] + } finally { + data.loading = false + tableRef.value?.scrollTo({ top: 999999 }) + } } const cleanHistory = async () => { - $dialog.warning(i18n.t('log.confirm_clean_log'), () => { - data.loading = true - browserStore - .cleanCmdHistory() - .then((success) => { - if (success) { - data.history = [] - tableRef.value?.scrollTo({ top: 0 }) - $message.success(i18n.t('common.success')) - } - }) - .finally(() => { - data.loading = false - }) + $dialog.warning(i18n.t('log.confirm_clean_log'), async () => { + try { + data.loading = true + const success = await browserStore.cleanCmdHistory() + if (success) { + data.history = [] + tableRef.value?.scrollTo({ top: 0 }) + $message.success(i18n.t('common.success')) + } + } finally { + data.loading = false + } }) } defineExpose({ - refresh: () => nextTick().then(loadHistory), + refresh: loadHistory, }) @@ -98,71 +160,12 @@ defineExpose({
+ flex-height + virtual-scroll />
diff --git a/frontend/src/components/content_value/ContentEntryEditor.vue b/frontend/src/components/content_value/ContentEntryEditor.vue index 789387c..31711a5 100644 --- a/frontend/src/components/content_value/ContentEntryEditor.vue +++ b/frontend/src/components/content_value/ContentEntryEditor.vue @@ -151,6 +151,7 @@ const onSave = () => {
{{ props.fieldLabel }}
@@ -160,6 +161,7 @@ const onSave = () => {
{{ props.valueLabel }}
-import { h, onMounted, onUnmounted, reactive, ref } from 'vue' +import { computed, h, onMounted, onUnmounted, reactive, ref } from 'vue' import Refresh from '@/components/icons/Refresh.vue' import { debounce, isEmpty, map, size, split } from 'lodash' import { useI18n } from 'vue-i18n' @@ -33,6 +33,85 @@ const data = reactive({ const tableRef = ref(null) +const columns = computed(() => [ + { + title: i18n.t('slog.exec_time'), + key: 'timestamp', + sortOrder: data.sortOrder, + sorter: 'default', + width: 180, + align: 'center', + titleAlign: 'center', + render: ({ timestamp }, index) => { + return dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') + }, + }, + { + title: i18n.t('slog.client'), + key: 'client', + filterOptionValue: data.client, + resizable: true, + filter: (value, row) => { + return value === '' || row.client === value.toString() || row.addr === value.toString() + }, + width: 200, + align: 'center', + titleAlign: 'center', + ellipsis: { + tooltip: true, + }, + render: ({ client, addr }, index) => { + let content = '' + if (!isEmpty(client)) { + content += client + } + if (!isEmpty(addr)) { + if (!isEmpty(content)) { + content += ' - ' + } + content += addr + } + return content + }, + }, + { + title: i18n.t('slog.cmd'), + key: 'cmd', + titleAlign: 'center', + filterOptionValue: data.keyword, + resizable: true, + filter: (value, row) => { + return value === '' || !!~row.cmd.indexOf(value.toString()) + }, + render: ({ cmd }, index) => { + const cmdList = split(cmd, '\n') + if (size(cmdList) > 1) { + return h( + 'div', + null, + map(cmdList, (c) => h('div', null, c)), + ) + } + return cmd + }, + }, + { + title: i18n.t('slog.cost_time'), + key: 'cost', + width: 100, + align: 'center', + titleAlign: 'center', + render: ({ cost }, index) => { + const ms = dayjs.duration(cost).asMilliseconds() + if (ms < 1000) { + return `${ms} ms` + } else { + return `${Math.floor(ms / 1000)} s` + } + }, + }, +]) + const _loadSlowLog = () => { data.loading = true browserStore @@ -103,86 +182,12 @@ const onListLimitChanged = (limit) => {
@@ -190,9 +195,4 @@ const onListLimitChanged = (limit) => { diff --git a/frontend/src/components/content_value/ContentValueHash.vue b/frontend/src/components/content_value/ContentValueHash.vue index fd56f00..98be334 100644 --- a/frontend/src/components/content_value/ContentValueHash.vue +++ b/frontend/src/components/content_value/ContentValueHash.vue @@ -158,6 +158,10 @@ const saveEdit = async (field, value, decode, format) => { throw new Error('row not exists') } + if (isEmpty(field)) { + field = currentEditRow.key + } + const { success, msg } = await browserStore.setHash({ server: props.name, db: props.db, diff --git a/frontend/src/components/content_value/ContentValueList.vue b/frontend/src/components/content_value/ContentValueList.vue index fe1717f..1be0501 100644 --- a/frontend/src/components/content_value/ContentValueList.vue +++ b/frontend/src/components/content_value/ContentValueList.vue @@ -130,6 +130,10 @@ const saveEdit = async (pos, value, decode, format) => { throw new Error('row not exists') } + if (isEmpty(value)) { + value = currentEditRow.value + } + const { success, msg } = await browserStore.updateListItem({ server: props.name, db: props.db, diff --git a/frontend/src/components/content_value/ContentValueZSet.vue b/frontend/src/components/content_value/ContentValueZSet.vue index c27f041..838944a 100644 --- a/frontend/src/components/content_value/ContentValueZSet.vue +++ b/frontend/src/components/content_value/ContentValueZSet.vue @@ -68,7 +68,7 @@ const filterOption = [ }, { value: 2, - label: i18n.t('interface.score'), + label: i18n.t('common.score'), }, ] const filterType = ref(1) @@ -95,7 +95,7 @@ const inFullEdit = computed(() => { const scoreFilterOption = ref(null) const scoreColumn = computed(() => ({ key: 'score', - title: i18n.t('interface.score'), + title: i18n.t('common.score'), align: 'center', titleAlign: 'center', resizable: true, @@ -183,6 +183,10 @@ const saveEdit = async (field, value, decode, format) => { throw new Error('row not exists') } + if (isEmpty(value)) { + value = currentEditRow.value + } + const { success, msg } = await browserStore.updateZSetItem({ server: props.name, db: props.db, @@ -429,7 +433,7 @@ defineExpose({ v-model:fullscreen="fullEdit" :decode="currentEditRow.decode" :field="currentEditRow.score" - :field-label="$t('interface.score')" + :field-label="$t('common.score')" :format="currentEditRow.format" :value="currentEditRow.value" :value-label="$t('common.value')" diff --git a/frontend/src/components/new_value/AddHashValue.vue b/frontend/src/components/new_value/AddHashValue.vue index c3e3b97..5803039 100644 --- a/frontend/src/components/new_value/AddHashValue.vue +++ b/frontend/src/components/new_value/AddHashValue.vue @@ -50,7 +50,9 @@ const onUpdate = (val) => { - + { - +