优化
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
import DataTable, { createPaginationItems, normalizePage, normalizePageSizes, type DataTableColumn } from './DataTable.vue'
|
||||
import DataTable, { createPaginationItems, normalizePage, normalizePageSizes, normalizeTotal, type DataTableColumn } from './DataTable.vue'
|
||||
import LayoutPreferenceList from './LayoutPreferenceList.vue'
|
||||
import { UI_PREFERENCE_SCOPE, preferenceStorageKey } from '@/shared/utils/uiLayoutPreference'
|
||||
|
||||
@@ -59,6 +59,27 @@ describe('DataTable pagination helpers', () => {
|
||||
expect(createPaginationItems(1, 0)).toEqual([])
|
||||
})
|
||||
|
||||
it('normalizes totals serialized as JSON strings before calculating pages', () => {
|
||||
expect(normalizeTotal('30')).toBe(30)
|
||||
expect(normalizeTotal(' 30 ')).toBe(30)
|
||||
expect(normalizeTotal(30)).toBe(30)
|
||||
expect(normalizeTotal('')).toBe(0)
|
||||
expect(normalizeTotal('invalid')).toBe(0)
|
||||
})
|
||||
|
||||
it('renders page navigation when the API total is a numeric string', () => {
|
||||
const wrapper = shallowMount(DataTable, {
|
||||
props: { data: [], columns: configurableColumns, total: '30', page: 1, pageSize: 20 },
|
||||
global: {
|
||||
stubs: { ElTable: TableStub, ElTableColumn: ColumnStub, ElButton: ButtonStub, ElPopover: PopoverStub },
|
||||
directives: { loading: {} },
|
||||
},
|
||||
})
|
||||
|
||||
expect(wrapper.get('.data-table__page-buttons').text()).toContain('1')
|
||||
expect(wrapper.get('.data-table__page-buttons').text()).toContain('2')
|
||||
})
|
||||
|
||||
it('shows all pages for a short result set', () => {
|
||||
expect(createPaginationItems(3, 5)).toEqual([1, 2, 3, 4, 5])
|
||||
})
|
||||
|
||||
@@ -30,6 +30,13 @@ export function normalizePage(value: number, pageCount: number) {
|
||||
return Math.min(Math.max(Math.trunc(value), 1), maximum)
|
||||
}
|
||||
|
||||
export function normalizeTotal(value: unknown) {
|
||||
const numericValue = typeof value === 'string' && value.trim() !== '' ? Number(value) : value
|
||||
return typeof numericValue === 'number' && Number.isFinite(numericValue) && numericValue > 0
|
||||
? Math.trunc(numericValue)
|
||||
: 0
|
||||
}
|
||||
|
||||
export function createPaginationItems(page: number, pageCount: number): PaginationItem[] {
|
||||
if (pageCount <= 0) return []
|
||||
if (pageCount <= 7) return Array.from({ length: pageCount }, (_, index) => index + 1)
|
||||
@@ -60,7 +67,7 @@ const props = withDefaults(defineProps<{
|
||||
columns: DataTableColumn[]
|
||||
loading?: boolean
|
||||
emptyText?: string
|
||||
total?: number
|
||||
total?: number | string
|
||||
pageSizes?: number[]
|
||||
preferenceKey?: string
|
||||
columnSettingsMode?: 'auto' | 'show' | 'hide'
|
||||
@@ -208,10 +215,7 @@ function resetPreference() {
|
||||
watch(visibleColumns, () => {
|
||||
void nextTick(() => tableRef.value?.doLayout())
|
||||
})
|
||||
const normalizedTotal = computed(() => {
|
||||
const value = props.total ?? 0
|
||||
return Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0
|
||||
})
|
||||
const normalizedTotal = computed(() => normalizeTotal(props.total))
|
||||
const normalizedPageSizes = computed(() => normalizePageSizes(props.pageSizes))
|
||||
const effectivePageSize = computed(() => (
|
||||
normalizedPageSizes.value.includes(pageSize.value) ? pageSize.value : normalizedPageSizes.value[0]
|
||||
|
||||
Reference in New Issue
Block a user