diff --git a/src/components/KTableData/KTableData.cy.ts b/src/components/KTableData/KTableData.cy.ts index af9b52b8f4..e005ef7828 100644 --- a/src/components/KTableData/KTableData.cy.ts +++ b/src/components/KTableData/KTableData.cy.ts @@ -507,6 +507,33 @@ describe('KTableData', () => { cy.wrap($el).should('not.have.class', 'sortable') }) }) + + it('should support client-side sorting', () => { + const fns = { + fetcher: () => { + return { data: options.data } + }, + } + cy.spy(fns, 'fetcher').as('fetcher') + + cy.mount(KTableData, { + props: { + headers: options.headers, + clientSort: true, + fetcher: fns.fetcher, + }, + }) + + cy.get('@fetcher') + .should('have.callCount', 1) + + cy.get('th').eq(0).click() + cy.get('td').eq(0).should('contain.text', 'Android App') + + cy.get('@fetcher') + .should('have.callCount', 1) // ensure fetcher is NOT called again on client-side sort + + }) }) describe('pagination', () => { diff --git a/src/components/KTableData/KTableData.vue b/src/components/KTableData/KTableData.vue index 9f71367c15..315f3cc15d 100644 --- a/src/components/KTableData/KTableData.vue +++ b/src/components/KTableData/KTableData.vue @@ -307,13 +307,26 @@ const getCellSlots = computed((): string[] => { return Object.keys(slots).filter((slot) => tableHeaders.value.some((header) => header.key === slot)) }) -const fetcherParams = computed(() => ({ +const sortParams = computed(() => ({ + sortColumnKey: sortColumnKey.value, + sortColumnOrder: sortColumnOrder.value, +})) + +// Params that are used in the cache key for the fetcher. +// For client-side sorting, we don't need to include the sort params in the cache key otherwise the cache key will change on every sort, +// which will cause the table to re-fetch data on every sort even though we don't need to fetch new data. +const cacheKeyParams = computed(() => ({ pageSize: pageSize.value, page: page.value, query: filterQuery.value, - sortColumnKey: sortColumnKey.value, - sortColumnOrder: sortColumnOrder.value, offset: offset.value, + ...props.clientSort ? {} : sortParams.value, +})) + +// We still need all params for the fetcher +const fetcherParams = computed(() => ({ + ...cacheKeyParams.value, + ...sortParams.value, })) const isInitialFetch = ref(true) @@ -369,7 +382,7 @@ const tableFetcherCacheKey = computed((): string => { identifierKey = props.cacheIdentifier } - identifierKey += `-${JSON.stringify(fetcherParams.value)}` + identifierKey += `-${JSON.stringify(cacheKeyParams.value)}` if (props.fetcherCacheKey) { identifierKey += `-${props.fetcherCacheKey}` @@ -378,8 +391,6 @@ const tableFetcherCacheKey = computed((): string => { return `k-table_${identifierKey}` }) -watch(tableFetcherCacheKey, (key: string) => console.log(key)) - const { debouncedFn: debouncedSearch, generateDebouncedFn: generateDebouncedSearch } = useDebounce((q: string) => { filterQuery.value = q }, 350)