perf: support format viewing for entry value #65

fix: table columns lose reactive
This commit is contained in:
Lykin 2023-11-16 01:06:59 +08:00
parent cc436ad86f
commit 578a8413a1
5 changed files with 147 additions and 95 deletions

View File

@ -3,7 +3,7 @@ import { computed, h, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentToolbar from './ContentToolbar.vue' import ContentToolbar from './ContentToolbar.vue'
import AddLink from '@/components/icons/AddLink.vue' import AddLink from '@/components/icons/AddLink.vue'
import { NButton, NIcon, NInput, useThemeVars } from 'naive-ui' import { NButton, NCode, NIcon, NInput, useThemeVars } from 'naive-ui'
import { types, types as redisTypes } from '@/consts/support_redis_type.js' import { types, types as redisTypes } from '@/consts/support_redis_type.js'
import EditableTableColumn from '@/components/common/EditableTableColumn.vue' import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
import useDialogStore from 'stores/dialog.js' import useDialogStore from 'stores/dialog.js'
@ -94,7 +94,8 @@ const inFullEdit = computed(() => {
}) })
const tableRef = ref(null) const tableRef = ref(null)
const fieldColumn = reactive({ const fieldFilterOption = ref(null)
const fieldColumn = computed(() => ({
key: 'key', key: 'key',
title: i18n.t('common.field'), title: i18n.t('common.field'),
align: 'center', align: 'center',
@ -103,33 +104,46 @@ const fieldColumn = reactive({
ellipsis: { ellipsis: {
tooltip: true, tooltip: true,
}, },
filterOptionValue: null, filterOptionValue: fieldFilterOption.value,
className: inEdit ? 'clickable' : '', className: inEdit.value ? 'clickable' : '',
filter: (value, row) => { filter: (value, row) => {
return !!~row.k.indexOf(value.toString()) return !!~row.k.indexOf(value.toString())
}, },
render: (row) => { render: (row) => {
return decodeRedisKey(row.k) return decodeRedisKey(row.k)
}, },
}))
const displayCode = computed(() => {
return props.format === formatTypes.JSON
}) })
const valueColumn = reactive({ const valueFilterOption = ref(null)
const valueColumn = computed(() => ({
key: 'value', key: 'value',
title: i18n.t('common.value'), title: i18n.t('common.value'),
align: 'center', align: displayCode.value ? 'left' : 'center',
titleAlign: 'center', titleAlign: 'center',
resizable: true, resizable: true,
ellipsis: { ellipsis: displayCode.value
tooltip: true, ? false
}, : {
filterOptionValue: null, tooltip: true,
className: inEdit ? 'clickable' : '', },
filterOptionValue: valueFilterOption.value,
className: inEdit.value ? 'clickable' : '',
filter: (value, row) => { filter: (value, row) => {
if (row.dv) {
return !!~row.dv.indexOf(value.toString())
}
return !!~row.v.indexOf(value.toString()) return !!~row.v.indexOf(value.toString())
}, },
render: (row) => { render: (row) => {
if (displayCode.value) {
return h(NCode, { language: 'json', wordWrap: true, code: row.dv || row.v })
}
return row.dv || row.v return row.dv || row.v
}, },
}) }))
const startEdit = async (no, key, value) => { const startEdit = async (no, key, value) => {
currentEditRow.no = no currentEditRow.no = no
@ -227,8 +241,8 @@ const columns = computed(() => {
return index + 1 return index + 1
}, },
}, },
fieldColumn, fieldColumn.value,
valueColumn, valueColumn.value,
actionColumn, actionColumn,
] ]
} else { } else {
@ -248,7 +262,7 @@ const columns = computed(() => {
} }
}, },
}, },
fieldColumn, fieldColumn.value,
] ]
} }
}) })
@ -278,13 +292,13 @@ const onFilterInput = (val) => {
switch (filterType.value) { switch (filterType.value) {
case filterOption[0].value: case filterOption[0].value:
// filter field // filter field
valueColumn.filterOptionValue = null valueFilterOption.value = null
fieldColumn.filterOptionValue = val fieldFilterOption.value = val
break break
case filterOption[1].value: case filterOption[1].value:
// filter value // filter value
fieldColumn.filterOptionValue = null fieldFilterOption.value = null
valueColumn.filterOptionValue = val valueFilterOption.value = val
break break
} }
} }
@ -294,17 +308,17 @@ const onChangeFilterType = (type) => {
} }
const clearFilter = () => { const clearFilter = () => {
fieldColumn.filterOptionValue = null fieldFilterOption.value = null
valueColumn.filterOptionValue = null valueFilterOption.value = null
} }
const onUpdateFilter = (filters, sourceColumn) => { const onUpdateFilter = (filters, sourceColumn) => {
switch (filterType.value) { switch (filterType.value) {
case filterOption[0].value: case filterOption[0].value:
fieldColumn.filterOptionValue = filters[sourceColumn.key] fieldFilterOption.value = filters[sourceColumn.key]
break break
case filterOption[1].value: case filterOption[1].value:
valueColumn.filterOptionValue = filters[sourceColumn.key] valueFilterOption.value = filters[sourceColumn.key]
break break
} }
} }
@ -370,6 +384,7 @@ defineExpose({
t-tooltip="interface.load_all_entries" t-tooltip="interface.load_all_entries"
@click="emit('loadall')" /> @click="emit('loadall')" />
</n-button-group> </n-button-group>
{{ valueColumn.align }}
<n-button :focusable="false" plain @click="onAddRow"> <n-button :focusable="false" plain @click="onAddRow">
<template #icon> <template #icon>
<n-icon :component="AddLink" size="18" /> <n-icon :component="AddLink" size="18" />
@ -382,6 +397,7 @@ defineExpose({
<n-data-table <n-data-table
ref="tableRef" ref="tableRef"
v-show="!inFullEdit" v-show="!inFullEdit"
:row-key="(row) => row.k"
:bordered="false" :bordered="false"
:bottom-bordered="false" :bottom-bordered="false"
:columns="columns" :columns="columns"

View File

@ -3,7 +3,7 @@ import { computed, h, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentToolbar from './ContentToolbar.vue' import ContentToolbar from './ContentToolbar.vue'
import AddLink from '@/components/icons/AddLink.vue' import AddLink from '@/components/icons/AddLink.vue'
import { NButton, NIcon, NInput, useThemeVars } from 'naive-ui' import { NButton, NCode, NIcon, NInput, useThemeVars } from 'naive-ui'
import { isEmpty, size } from 'lodash' import { isEmpty, size } from 'lodash'
import { types, types as redisTypes } from '@/consts/support_redis_type.js' import { types, types as redisTypes } from '@/consts/support_redis_type.js'
import EditableTableColumn from '@/components/common/EditableTableColumn.vue' import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
@ -79,26 +79,35 @@ const inFullEdit = computed(() => {
return inEdit.value && fullEdit.value return inEdit.value && fullEdit.value
}) })
const valueColumn = reactive({ const displayCode = computed(() => {
return props.format === formatTypes.JSON
})
const valueFilterOption = ref(null)
const valueColumn = computed(() => ({
key: 'value', key: 'value',
title: i18n.t('common.value'), title: i18n.t('common.value'),
align: 'center', align: displayCode.value ? 'left' : 'center',
titleAlign: 'center', titleAlign: 'center',
ellipsis: { ellipsis: displayCode.value
tooltip: true, ? false
}, : {
filterOptionValue: null, tooltip: true,
className: inEdit ? 'clickable' : '', },
filterOptionValue: valueFilterOption.value,
className: inEdit.value ? 'clickable' : '',
filter: (value, row) => { filter: (value, row) => {
if (row.dv) {
return !!~row.dv.indexOf(value.toString())
}
return !!~row.v.indexOf(value.toString()) return !!~row.v.indexOf(value.toString())
}, },
render: (row) => { render: (row) => {
// if (!isEmpty(row.dv)) { if (displayCode.value) {
// return h(NCode, { language: 'json', wordWrap: true, code: row.dv }) return h(NCode, { language: 'json', wordWrap: true, code: row.dv || row.v })
// } }
return row.dv || row.v return row.dv || row.v
}, },
}) }))
const startEdit = async (no, value) => { const startEdit = async (no, value) => {
currentEditRow.no = no currentEditRow.no = no
@ -201,7 +210,7 @@ const columns = computed(() => {
return index + 1 return index + 1
}, },
}, },
valueColumn, valueColumn.value,
actionColumn, actionColumn,
] ]
} else { } else {
@ -221,7 +230,7 @@ const columns = computed(() => {
} }
}, },
}, },
valueColumn, valueColumn.value,
] ]
} }
}) })
@ -248,15 +257,15 @@ const onAddValue = (value) => {
const filterValue = ref('') const filterValue = ref('')
const onFilterInput = (val) => { const onFilterInput = (val) => {
valueColumn.filterOptionValue = val valueFilterOption.value = val
} }
const clearFilter = () => { const clearFilter = () => {
valueColumn.filterOptionValue = null valueFilterOption.value = null
} }
const onUpdateFilter = (filters, sourceColumn) => { const onUpdateFilter = (filters, sourceColumn) => {
valueColumn.filterOptionValue = filters[sourceColumn.key] valueFilterOption.value = filters[sourceColumn.key]
} }
const onFormatChanged = (selDecode, selFormat) => { const onFormatChanged = (selDecode, selFormat) => {
@ -323,6 +332,7 @@ defineExpose({
<!-- table --> <!-- table -->
<n-data-table <n-data-table
v-show="!inFullEdit" v-show="!inFullEdit"
:row-key="(row) => row.no"
:bordered="false" :bordered="false"
:bottom-bordered="false" :bottom-bordered="false"
:columns="columns" :columns="columns"

View File

@ -3,7 +3,7 @@ import { computed, h, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentToolbar from './ContentToolbar.vue' import ContentToolbar from './ContentToolbar.vue'
import AddLink from '@/components/icons/AddLink.vue' import AddLink from '@/components/icons/AddLink.vue'
import { NButton, NIcon, NInput, useThemeVars } from 'naive-ui' import { NButton, NCode, NIcon, NInput, useThemeVars } from 'naive-ui'
import { isEmpty, size } from 'lodash' import { isEmpty, size } from 'lodash'
import useDialogStore from 'stores/dialog.js' import useDialogStore from 'stores/dialog.js'
import { types, types as redisTypes } from '@/consts/support_redis_type.js' import { types, types as redisTypes } from '@/consts/support_redis_type.js'
@ -78,26 +78,35 @@ const inFullEdit = computed(() => {
return inEdit.value && fullEdit.value return inEdit.value && fullEdit.value
}) })
const valueColumn = reactive({ const displayCode = computed(() => {
return props.format === formatTypes.JSON
})
const valueFilterOption = ref(null)
const valueColumn = computed(() => ({
key: 'value', key: 'value',
title: i18n.t('common.value'), title: i18n.t('common.value'),
align: 'center', align: displayCode.value ? 'left' : 'center',
titleAlign: 'center', titleAlign: 'center',
ellipsis: { ellipsis: displayCode.value
tooltip: true, ? false
}, : {
filterOptionValue: null, tooltip: true,
className: inEdit ? 'clickable' : '', },
filterOptionValue: valueFilterOption.value,
className: inEdit.value ? 'clickable' : '',
filter: (value, row) => { filter: (value, row) => {
if (row.dv) {
return !!~row.dv.indexOf(value.toString())
}
return !!~row.v.indexOf(value.toString()) return !!~row.v.indexOf(value.toString())
}, },
render: (row) => { render: (row) => {
// if (!isEmpty(row.dv)) { if (displayCode.value) {
// return h(NCode, { language: 'json', wordWrap: true, code: row.dv }) return h(NCode, { language: 'json', wordWrap: true, code: row.dv || row.v })
// } }
return row.dv || row.v return row.dv || row.v
}, },
}) }))
const startEdit = async (no, value) => { const startEdit = async (no, value) => {
currentEditRow.no = no currentEditRow.no = no
@ -200,7 +209,7 @@ const columns = computed(() => {
return index + 1 return index + 1
}, },
}, },
valueColumn, valueColumn.value,
actionColumn, actionColumn,
] ]
} else { } else {
@ -220,7 +229,7 @@ const columns = computed(() => {
} }
}, },
}, },
valueColumn, valueColumn.value,
] ]
} }
}) })
@ -247,15 +256,15 @@ const onAddValue = (value) => {
const filterValue = ref('') const filterValue = ref('')
const onFilterInput = (val) => { const onFilterInput = (val) => {
valueColumn.filterOptionValue = val valueFilterOption.value = val
} }
const clearFilter = () => { const clearFilter = () => {
valueColumn.filterOptionValue = null valueFilterOption.value = null
} }
const onUpdateFilter = (filters, sourceColumn) => { const onUpdateFilter = (filters, sourceColumn) => {
valueColumn.filterOptionValue = filters[sourceColumn.key] valueFilterOption.value = filters[sourceColumn.key]
} }
const onFormatChanged = (selDecode, selFormat) => { const onFormatChanged = (selDecode, selFormat) => {
@ -322,6 +331,7 @@ defineExpose({
<!-- table --> <!-- table -->
<n-data-table <n-data-table
v-show="!inFullEdit" v-show="!inFullEdit"
:row-key="(row) => row.v"
:bordered="false" :bordered="false"
:bottom-bordered="false" :bottom-bordered="false"
:columns="columns" :columns="columns"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, h, reactive, ref } from 'vue' import { computed, h, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentToolbar from './ContentToolbar.vue' import ContentToolbar from './ContentToolbar.vue'
import AddLink from '@/components/icons/AddLink.vue' import AddLink from '@/components/icons/AddLink.vue'
@ -73,23 +73,24 @@ const filterType = ref(1)
const browserStore = useBrowserStore() const browserStore = useBrowserStore()
const dialogStore = useDialogStore() const dialogStore = useDialogStore()
const keyType = redisTypes.STREAM const keyType = redisTypes.STREAM
const idColumn = reactive({ const idFilterOption = ref(null)
const idColumn = computed(() => ({
key: 'id', key: 'id',
title: 'ID', title: 'ID',
align: 'center', align: 'center',
titleAlign: 'center', titleAlign: 'center',
resizable: true, resizable: true,
}) filterOptionValue: idFilterOption.value,
const valueColumn = reactive({ }))
const valueFilterOption = ref(null)
const valueColumn = computed(() => ({
key: 'value', key: 'value',
title: i18n.t('common.value'), title: i18n.t('common.value'),
align: 'left', align: 'left',
titleAlign: 'center', titleAlign: 'center',
resizable: true, resizable: true,
// ellipsis: { filterOptionValue: valueFilterOption.value,
// tooltip: true,
// },
filterOptionValue: null,
filter: (value, row) => { filter: (value, row) => {
const v = value.toString() const v = value.toString()
if (filterType.value === 1) { if (filterType.value === 1) {
@ -104,7 +105,7 @@ const valueColumn = reactive({
render: (row) => { render: (row) => {
return h(NCode, { language: 'json', wordWrap: true, code: row.dv }) return h(NCode, { language: 'json', wordWrap: true, code: row.dv })
}, },
}) }))
const actionColumn = { const actionColumn = {
key: 'action', key: 'action',
title: i18n.t('interface.action'), title: i18n.t('interface.action'),
@ -136,7 +137,7 @@ const actionColumn = {
}) })
}, },
} }
const columns = computed(() => [idColumn, valueColumn, actionColumn]) const columns = computed(() => [idColumn.value, valueColumn.value, actionColumn])
const entries = computed(() => { const entries = computed(() => {
const len = size(props.value) const len = size(props.value)
@ -149,7 +150,7 @@ const onAddRow = () => {
const filterValue = ref('') const filterValue = ref('')
const onFilterInput = (val) => { const onFilterInput = (val) => {
valueColumn.filterOptionValue = val valueFilterOption.value = val
} }
const onChangeFilterType = (type) => { const onChangeFilterType = (type) => {
@ -157,17 +158,17 @@ const onChangeFilterType = (type) => {
} }
const clearFilter = () => { const clearFilter = () => {
idColumn.filterOptionValue = null idFilterOption.value = null
valueColumn.filterOptionValue = null valueFilterOption.value = null
} }
const onUpdateFilter = (filters, sourceColumn) => { const onUpdateFilter = (filters, sourceColumn) => {
switch (filterType.value) { switch (filterType.value) {
case filterOption[0].value: case filterOption[0].value:
idColumn.filterOptionValue = filters[sourceColumn.key] idFilterOption.value = filters[sourceColumn.key]
break break
case filterOption[1].value: case filterOption[1].value:
valueColumn.filterOptionValue = filters[sourceColumn.key] valueFilterOption.value = filters[sourceColumn.key]
break break
} }
} }
@ -236,7 +237,7 @@ defineExpose({
</div> </div>
<div class="value-wrapper value-item-part flex-box-v flex-item-expand"> <div class="value-wrapper value-item-part flex-box-v flex-item-expand">
<n-data-table <n-data-table
:key="(row) => row.id" :row-key="(row) => row.id"
:bordered="false" :bordered="false"
:bottom-bordered="false" :bottom-bordered="false"
:columns="columns" :columns="columns"

View File

@ -3,7 +3,7 @@ import { computed, h, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentToolbar from './ContentToolbar.vue' import ContentToolbar from './ContentToolbar.vue'
import AddLink from '@/components/icons/AddLink.vue' import AddLink from '@/components/icons/AddLink.vue'
import { NButton, NIcon, NInput, useThemeVars } from 'naive-ui' import { NButton, NCode, NIcon, NInput, useThemeVars } from 'naive-ui'
import { types, types as redisTypes } from '@/consts/support_redis_type.js' import { types, types as redisTypes } from '@/consts/support_redis_type.js'
import EditableTableColumn from '@/components/common/EditableTableColumn.vue' import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
import { head, isEmpty, keys, size } from 'lodash' import { head, isEmpty, keys, size } from 'lodash'
@ -92,13 +92,14 @@ const inFullEdit = computed(() => {
return inEdit.value && fullEdit.value return inEdit.value && fullEdit.value
}) })
const scoreColumn = reactive({ const scoreFilterOption = ref(null)
const scoreColumn = computed(() => ({
key: 'score', key: 'score',
title: i18n.t('interface.score'), title: i18n.t('interface.score'),
align: 'center', align: 'center',
titleAlign: 'center', titleAlign: 'center',
resizable: true, resizable: true,
filterOptionValue: null, filterOptionValue: scoreFilterOption.value,
filter(value, row) { filter(value, row) {
const score = parseFloat(row.s) const score = parseFloat(row.s)
if (isNaN(score)) { if (isNaN(score)) {
@ -134,26 +135,39 @@ const scoreColumn = reactive({
render: (row) => { render: (row) => {
return row.s return row.s
}, },
}))
const displayCode = computed(() => {
return props.format === formatTypes.JSON
}) })
const valueColumn = reactive({ const valueFilterOption = ref(null)
const valueColumn = computed(() => ({
key: 'value', key: 'value',
title: i18n.t('common.value'), title: i18n.t('common.value'),
align: 'center', align: displayCode.value ? 'left' : 'center',
titleAlign: 'center', titleAlign: 'center',
resizable: true, resizable: true,
ellipsis: { ellipsis: displayCode.value
tooltip: true, ? false
}, : {
filterOptionValue: null, tooltip: true,
className: inEdit ? 'clickable' : '', },
filterOptionValue: valueFilterOption.value,
className: inEdit.value ? 'clickable' : '',
filter(value, row) { filter(value, row) {
if (row.dv) {
return !!~row.dv.indexOf(value.toString())
}
return !!~row.v.indexOf(value.toString()) return !!~row.v.indexOf(value.toString())
}, },
// sorter: (row1, row2) => row1.value - row2.value, // sorter: (row1, row2) => row1.value - row2.value,
render: (row) => { render: (row) => {
if (displayCode.value) {
return h(NCode, { language: 'json', wordWrap: true, code: row.dv || row.v })
}
return row.dv || row.v return row.dv || row.v
}, },
}) }))
const startEdit = async (no, score, value) => { const startEdit = async (no, score, value) => {
currentEditRow.no = no currentEditRow.no = no
@ -252,8 +266,8 @@ const columns = computed(() => {
return index + 1 return index + 1
}, },
}, },
valueColumn, valueColumn.value,
scoreColumn, scoreColumn.value,
actionColumn, actionColumn,
] ]
} else { } else {
@ -273,7 +287,7 @@ const columns = computed(() => {
} }
}, },
}, },
valueColumn, valueColumn.value,
] ]
} }
}) })
@ -292,13 +306,13 @@ const onFilterInput = (val) => {
switch (filterType.value) { switch (filterType.value) {
case filterOption[0].value: case filterOption[0].value:
// filter value // filter value
scoreColumn.filterOptionValue = null scoreFilterOption.value = null
valueColumn.filterOptionValue = val valueFilterOption.value = val
break break
case filterOption[1].value: case filterOption[1].value:
// filter score // filter score
valueColumn.filterOptionValue = null valueFilterOption.value = null
scoreColumn.filterOptionValue = val scoreFilterOption.value = val
break break
} }
} }
@ -308,19 +322,19 @@ const onChangeFilterType = (type) => {
} }
const clearFilter = () => { const clearFilter = () => {
valueColumn.filterOptionValue = null valueFilterOption.value = null
scoreColumn.filterOptionValue = null scoreFilterOption.value = null
} }
const onUpdateFilter = (filters, sourceColumn) => { const onUpdateFilter = (filters, sourceColumn) => {
switch (filterType.value) { switch (filterType.value) {
case filterOption[0].value: case filterOption[0].value:
// filter value // filter value
valueColumn.filterOptionValue = filters[sourceColumn.key] valueFilterOption.value = filters[sourceColumn.key]
break break
case filterOption[1].value: case filterOption[1].value:
// filter score // filter score
scoreColumn.filterOptionValue = filters[sourceColumn.key] scoreFilterOption.value = filters[sourceColumn.key]
break break
} }
} }
@ -402,6 +416,7 @@ defineExpose({
<!-- table --> <!-- table -->
<n-data-table <n-data-table
v-show="!inFullEdit" v-show="!inFullEdit"
:row-key="(row) => row.v"
:bordered="false" :bordered="false"
:bottom-bordered="false" :bottom-bordered="false"
:columns="columns" :columns="columns"