From 6a54183d91cbfe51a42a6a1192df27708d851838 Mon Sep 17 00:00:00 2001 From: tiny-craft <137850705+tiny-craft@users.noreply.github.com> Date: Mon, 3 Jul 2023 23:30:04 +0800 Subject: [PATCH] feat: support comparison operator to filter ordered set by score --- .../content_value/ContentValueHash.vue | 26 ++--- .../content_value/ContentValueZSet.vue | 102 ++++++++++++++++-- frontend/src/langs/en.json | 1 + frontend/src/langs/zh-cn.json | 1 + frontend/src/style.scss | 4 + 5 files changed, 112 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/content_value/ContentValueHash.vue b/frontend/src/components/content_value/ContentValueHash.vue index 905dfea..bd6ee1a 100644 --- a/frontend/src/components/content_value/ContentValueHash.vue +++ b/frontend/src/components/content_value/ContentValueHash.vue @@ -11,18 +11,6 @@ import useConnectionStore from '../../stores/connections.js' const i18n = useI18n() -const filterOption = [ - { - value: 1, - label: i18n.t('field'), - }, - { - value: 2, - label: i18n.t('value'), - }, -] -const filterType = ref(1) - const props = defineProps({ name: String, db: Number, @@ -34,6 +22,18 @@ const props = defineProps({ value: Object, }) +const filterOption = computed(() => [ + { + value: 1, + label: i18n.t('field'), + }, + { + value: 2, + label: i18n.t('value'), + }, +]) +const filterType = ref(1) + const connectionStore = useConnectionStore() const dialogStore = useDialogStore() const keyType = redisTypes.HASH @@ -206,10 +206,12 @@ const filterValue = ref('') const onFilterInput = (val) => { switch (filterType.value) { case filterOption[0].value: + // filter field valueColumn.filterOptionValue = null fieldColumn.filterOptionValue = val break case filterOption[1].value: + // filter value fieldColumn.filterOptionValue = null valueColumn.filterOptionValue = val break diff --git a/frontend/src/components/content_value/ContentValueZSet.vue b/frontend/src/components/content_value/ContentValueZSet.vue index 2195638..6e7da07 100644 --- a/frontend/src/components/content_value/ContentValueZSet.vue +++ b/frontend/src/components/content_value/ContentValueZSet.vue @@ -6,11 +6,12 @@ import AddLink from '../icons/AddLink.vue' import { NButton, NCode, NIcon, NInput, NInputNumber, useMessage } from 'naive-ui' import { types, types as redisTypes } from '../../consts/support_redis_type.js' import EditableTableColumn from '../common/EditableTableColumn.vue' -import { isEmpty } from 'lodash' +import { isEmpty, replace } from 'lodash' import useDialogStore from '../../stores/dialog.js' import useConnectionStore from '../../stores/connections.js' const i18n = useI18n() + const props = defineProps({ name: String, db: Number, @@ -22,6 +23,18 @@ const props = defineProps({ value: Object, }) +const filterOption = computed(() => [ + { + value: 1, + label: i18n.t('value'), + }, + { + value: 2, + label: i18n.t('score'), + }, +]) +const filterType = ref(1) + const connectionStore = useConnectionStore() const dialogStore = useDialogStore() const keyType = redisTypes.ZSET @@ -36,6 +49,40 @@ const scoreColumn = reactive({ align: 'center', titleAlign: 'center', resizable: true, + filterOptionValue: null, + filter(value, row) { + const score = parseFloat(row.score) + if (isNaN(score)) { + return true + } + + const regex = /^(>=|<=|>|<|=|!=)?(\d+(\.\d*)?)?$/ + const matches = value.match(regex) + if (matches) { + const operator = matches[1] || '' + const filterScore = parseFloat(matches[2] || '') + if (!isNaN(filterScore)) { + switch (operator) { + case '>=': + return score >= filterScore + case '<=': + return score <= filterScore + case '>': + return score > filterScore + case '<': + return score < filterScore + case '=': + return score === filterScore + case '!=': + return score !== filterScore + } + } + } else { + return !!~row.value.indexOf(value.toString()) + } + + return true + }, render: (row) => { const isEdit = currentEditRow.value.no === row.no if (isEdit) { @@ -180,7 +227,18 @@ const onAddRow = () => { const filterValue = ref('') const onFilterInput = (val) => { - valueColumn.filterOptionValue = val + switch (filterType.value) { + case filterOption[0].value: + // filter value + scoreColumn.filterOptionValue = null + valueColumn.filterOptionValue = val + break + case filterOption[1].value: + // filter score + valueColumn.filterOptionValue = null + scoreColumn.filterOptionValue = val + break + } } const onChangeFilterType = (type) => { @@ -189,10 +247,20 @@ const onChangeFilterType = (type) => { const clearFilter = () => { valueColumn.filterOptionValue = null + scoreColumn.filterOptionValue = null } const onUpdateFilter = (filters, sourceColumn) => { - valueColumn.filterOptionValue = filters[sourceColumn.key] + switch (filterType.value) { + case filterOption[0].value: + // filter value + valueColumn.filterOptionValue = filters[sourceColumn.key] + break + case filterOption[1].value: + // filter score + scoreColumn.filterOptionValue = filters[sourceColumn.key] + break + } } @@ -201,13 +269,27 @@ const onUpdateFilter = (filters, sourceColumn) => {
- + + + + +
{{ $t('score_filter_tip') }}
+
+
diff --git a/frontend/src/langs/en.json b/frontend/src/langs/en.json index 4e3fa8b..6ef0b19 100644 --- a/frontend/src/langs/en.json +++ b/frontend/src/langs/en.json @@ -25,6 +25,7 @@ "edit_value": "Edit Value", "save_update": "Save Update", "cancel_update": "Cancel Update", + "score_filter_tip": "Support operator list below:\n= equal\n!= not equal\n> greater than\n>= greater than or equal to\n< less than\n<= less than or equal to\nfor example you want to filter results which greater than 3, input: >3", "add_row": "Add Row", "edit_row": "Edit Row", "delete_row": "Delete Row", diff --git a/frontend/src/langs/zh-cn.json b/frontend/src/langs/zh-cn.json index 5aa0d9c..bd7dda8 100644 --- a/frontend/src/langs/zh-cn.json +++ b/frontend/src/langs/zh-cn.json @@ -25,6 +25,7 @@ "edit_value": "修改值", "save_update": "保存修改", "cancel_update": "取消修改", + "score_filter_tip": "支持如下运算符比较匹配范围\n=:等于\n!=:不等于\n>:大于\n<:小于\n>=:大于等于\n<=:小于等于\n如查询分值大于3的结果,则输入:>3", "add_row": "插入行", "edit_row": "编辑行", "delete_row": "删除行", diff --git a/frontend/src/style.scss b/frontend/src/style.scss index 5d5b12e..bc0f701 100644 --- a/frontend/src/style.scss +++ b/frontend/src/style.scss @@ -77,6 +77,10 @@ body { height: 100%; } +.text-block { + white-space: pre-line; +} + .content-wrapper { background-color: var(--bg-color); height: 100%;