Skip to content

Commit

Permalink
fix(comp:table): sort and filter not work with async columns (#1376)
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm authored Dec 26, 2022
1 parent 17b4d3c commit 9163d69
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 32 deletions.
31 changes: 16 additions & 15 deletions packages/components/table/src/composables/useFilterable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import { type ComputedRef, computed, reactive, watch } from 'vue'
import { type ComputedRef, type Ref, computed, reactive, ref, watch } from 'vue'

import { type VKey, callEmit } from '@idux/cdk/utils'

import { type TableColumnFilterable } from '../types'
import { type TableColumnMerged } from './useColumns'

export interface FilterableContext {
activeFilters: ComputedRef<ActiveFilter[]>
activeFilterByMap: Record<VKey, VKey[]>
activeFilters: Ref<ActiveFilter[]>
activeFilterByMap: Record<VKey, VKey[] | undefined>
handleFilter: (key: VKey, filterable: TableColumnFilterable, filterBy: VKey[]) => void
}

Expand All @@ -27,6 +27,7 @@ export interface ActiveFilter {
export function useFilterable(flattedColumns: ComputedRef<TableColumnMerged[]>): FilterableContext {
const filterableColumns = computed(() => flattedColumns.value.filter(column => column.filterable))
const activeFilterByMap = reactive<Record<VKey, VKey[]>>({})
const activeFilters = ref<ActiveFilter[]>([])

watch(
filterableColumns,
Expand All @@ -46,26 +47,16 @@ export function useFilterable(flattedColumns: ComputedRef<TableColumnMerged[]>):
activeFilterByMap[key] = []
}
})
activeFilters.value = getActiveFilters(currColumns, activeFilterByMap)
},
{ immediate: true },
)

const activeFilters = computed(
() =>
filterableColumns.value
.map(column => {
const { key, filterable } = column
const { filter, filterBy = activeFilterByMap[key] } = filterable!
return { key, filter, filterBy }
})
.filter(item => item.filter && item.filterBy.length > 0) as ActiveFilter[],
)

const handleFilter = (activeKey: VKey, activeFilterable: TableColumnFilterable, filterBy: VKey[]) => {
const { onChange } = activeFilterable

activeFilterByMap[activeKey] = filterBy

activeFilters.value = getActiveFilters(filterableColumns.value, activeFilterByMap)
callEmit(onChange, filterBy, activeFilters.value)
}

Expand All @@ -75,3 +66,13 @@ export function useFilterable(flattedColumns: ComputedRef<TableColumnMerged[]>):
handleFilter,
}
}

function getActiveFilters(filterableColumns: TableColumnMerged[], activeFilterByMap: Record<VKey, VKey[]>) {
return filterableColumns
.map(column => {
const { key, filterable } = column
const { filter, filterBy = activeFilterByMap[key] } = filterable!
return { key, filter, filterBy }
})
.filter(item => item.filter && item.filterBy.length > 0) as ActiveFilter[]
}
35 changes: 20 additions & 15 deletions packages/components/table/src/composables/useSortable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import { type ComputedRef, computed, reactive, watch } from 'vue'
import { type ComputedRef, type Ref, computed, reactive, ref, watch } from 'vue'

import { type VKey, callEmit } from '@idux/cdk/utils'

import { type TableColumnSortOrder, type TableColumnSortable } from '../types'
import { type TableColumnMerged } from './useColumns'

export interface SortableContext {
activeSorters: ComputedRef<ActiveSorter[]>
activeSorters: Ref<ActiveSorter[]>
activeOrderByMap: Record<VKey, TableColumnSortOrder | undefined>
handleSort: (key: VKey, sortable: TableColumnSortable) => void
}
Expand All @@ -27,8 +27,9 @@ export interface ActiveSorter {

export function useSortable(flattedColumns: ComputedRef<TableColumnMerged[]>): SortableContext {
const sortableColumns = computed(() => flattedColumns.value.filter(column => column.sortable))
const activeOrderByMap = reactive<Record<VKey, TableColumnSortOrder | undefined>>({})
const multipleEnabled = computed(() => sortableColumns.value.some(column => column.sortable!.multiple !== undefined))
const activeOrderByMap = reactive<Record<VKey, TableColumnSortOrder | undefined>>({})
const activeSorters = ref<ActiveSorter[]>([])

watch(
sortableColumns,
Expand All @@ -48,21 +49,11 @@ export function useSortable(flattedColumns: ComputedRef<TableColumnMerged[]>): S
activeOrderByMap[key] = undefined
}
})
activeSorters.value = getActiveSorters(currColumns, activeOrderByMap)
},
{ immediate: true },
)

const activeSorters = computed(() =>
sortableColumns.value
.map(column => {
const { key, sortable } = column
const { multiple = 0, orderBy = activeOrderByMap[key], sorter } = sortable!
return { key, multiple, orderBy, sorter } as ActiveSorter
})
.filter(item => item.orderBy)
.sort((c1, c2) => c2.multiple - c1.multiple),
)

const handleSort = (activeKey: VKey, activeSortable: TableColumnSortable) => {
const { orders, onChange } = activeSortable

Expand All @@ -80,7 +71,7 @@ export function useSortable(flattedColumns: ComputedRef<TableColumnMerged[]>): S
}
})
}

activeSorters.value = getActiveSorters(sortableColumns.value, activeOrderByMap)
callEmit(onChange, nextOrderBy, activeSorters.value)
}

Expand All @@ -94,3 +85,17 @@ function getNextOrderBy(orders: TableColumnSortOrder[], currOrderBy?: TableColum

return orders[orders.indexOf(currOrderBy) + 1]
}

function getActiveSorters(
sortableColumns: TableColumnMerged[],
activeOrderByMap: Record<VKey, TableColumnSortOrder | undefined>,
) {
return sortableColumns
.map(column => {
const { key, sortable } = column
const { multiple = 0, orderBy = activeOrderByMap[key], sorter } = sortable!
return { key, multiple, orderBy, sorter } as ActiveSorter
})
.filter(item => item.orderBy)
.sort((c1, c2) => c2.multiple - c1.multiple)
}
4 changes: 2 additions & 2 deletions packages/components/table/src/main/head/HeadCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {

import { isFunction, isObject, isString } from 'lodash-es'

import { type VKey, convertCssPixel } from '@idux/cdk/utils'
import { NoopArray, type VKey, convertCssPixel } from '@idux/cdk/utils'

import { type TableColumnMergedExtra } from '../../composables/useColumns'
import { TABLE_TOKEN } from '../../token'
Expand Down Expand Up @@ -104,7 +104,7 @@ export default defineComponent({
})

const activeSortOrderBy = computed(() => activeOrderByMap[props.column.key])
const activeFilterBy = computed(() => activeFilterByMap[props.column.key])
const activeFilterBy = computed(() => activeFilterByMap[props.column.key] || NoopArray)
const onUpdateFilterBy = (filterBy: VKey[]) => {
const { key, filterable } = props.column
handleFilter(key, filterable!, filterBy)
Expand Down

0 comments on commit 9163d69

Please sign in to comment.