From fbc8032d29b513104af110f01e851ebff64f59cb Mon Sep 17 00:00:00 2001 From: tannerlinsley Date: Thu, 18 Jul 2019 12:08:55 -0600 Subject: [PATCH] Fix disableMultiSort, change from sortByFn to sortTypes --- src/hooks/useFilters.js | 12 ++------ src/hooks/useSortBy.js | 61 ++++++++++++++++++++++++++++------------- src/utils.js | 25 ++++------------- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/hooks/useFilters.js b/src/hooks/useFilters.js index 872d8f1..ef4bdc2 100755 --- a/src/hooks/useFilters.js +++ b/src/hooks/useFilters.js @@ -1,7 +1,7 @@ import { useMemo } from 'react' import PropTypes from 'prop-types' -import { getFirstDefined } from '../utils' +import { getFirstDefined, isFunction } from '../utils' import * as filterTypes from '../filterTypes' import { addActions, actions } from '../actions' import { defaultState } from './useTableState' @@ -126,10 +126,10 @@ export const useFilters = props => { // default string lookup on user filters // default string lookup on built-in filters const filterMethod = - getFunctionalFilter(column.filter) || + isFunction(column.filter) || userFilterTypes[column.filter] || filterTypes[column.filter] || - getFunctionalFilter(defaultFilter) || + isFunction(defaultFilter) || userFilterTypes[defaultFilter] || filterTypes[defaultFilter] @@ -189,9 +189,3 @@ export const useFilters = props => { rows: filteredRows, } } - -function getFunctionalFilter(filter) { - if (typeof filter === 'function') { - return filter - } -} diff --git a/src/hooks/useSortBy.js b/src/hooks/useSortBy.js index af3b867..dceeb81 100755 --- a/src/hooks/useSortBy.js +++ b/src/hooks/useSortBy.js @@ -3,12 +3,13 @@ import PropTypes from 'prop-types' import { addActions, actions } from '../actions' import { defaultState } from './useTableState' +import * as sortTypes from '../sortTypes' import { mergeProps, applyPropHooks, getFirstDefined, defaultOrderByFn, - defaultSortByFn, + isFunction, } from '../utils' defaultState.sortBy = [] @@ -21,11 +22,13 @@ const propTypes = { // General columns: PropTypes.arrayOf( PropTypes.shape({ - sortByFn: PropTypes.func, + sortBy: PropTypes.func, defaultSortDesc: PropTypes.bool, }) ), - sortByFn: PropTypes.func, + orderByFn: PropTypes.func, + sortTypes: PropTypes.object, + defaultSortType: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), manualSorting: PropTypes.bool, disableSorting: PropTypes.bool, defaultSortDesc: PropTypes.bool, @@ -41,11 +44,13 @@ export const useSortBy = props => { rows, columns, orderByFn = defaultOrderByFn, - sortByFn = defaultSortByFn, + defaultSort = 'alphanumeric', + sortTypes: userSortTypes = {}, manualSorting, disableSorting, defaultSortDesc, disableSortRemove, + disableMultiSort, hooks, state: [{ sortBy }, setState], } = props @@ -82,7 +87,7 @@ export const useSortBy = props => { // What should we do with this filter? let action - if (!multi) { + if (disableMultiSort || !multi) { if (sortBy.length <= 1 && existingSortBy) { if ( (existingSortBy.desc && !resolvedDefaultSortDesc) || @@ -210,13 +215,11 @@ export const useSortBy = props => { } if (debug) console.info('getSortedRows') - const sortMethodsByColumnID = {} + const sortTypesByColumnID = {} - columns - .filter(col => col.sortMethod) - .forEach(col => { - sortMethodsByColumnID[col.id] = col.sortMethod - }) + columns.forEach(col => { + sortTypesByColumnID[col.id] = col.sortBy + }) const sortData = rows => { // Use the orderByFn to compose multiple sortBy's together. @@ -226,21 +229,32 @@ export const useSortBy = props => { rows, sortBy.map(sort => { // Support custom sorting methods for each column - const columnSortBy = sortMethodsByColumnID[sort.id] + const columnSort = sortTypesByColumnID[sort.id] + + // Look up sortBy functions in this order: + // column function + // column string lookup on user sortType + // column string lookup on built-in sortType + // default function + // default string lookup on user sortType + // default string lookup on built-in sortType + const sortMethod = + isFunction(columnSort) || + userSortTypes[columnSort] || + sortTypes[columnSort] || + isFunction(defaultSort) || + userSortTypes[defaultSort] || + sortTypes[defaultSort] // Return the correct sortFn return (a, b) => - (columnSortBy || sortByFn)( - a.values[sort.id], - b.values[sort.id], - sort.desc - ) + sortMethod(a.values[sort.id], b.values[sort.id], sort.desc) }), // Map the directions sortBy.map(d => !d.desc) ) - // TODO: this should be optimized. Not good to loop again + // If there are sub-rows, sort them sortedData.forEach(row => { if (!row.subRows) { return @@ -252,7 +266,16 @@ export const useSortBy = props => { } return sortData(rows) - }, [manualSorting, sortBy, debug, columns, rows, orderByFn, sortByFn]) + }, [ + manualSorting, + sortBy, + debug, + columns, + rows, + orderByFn, + userSortTypes, + defaultSort, + ]) return { ...props, diff --git a/src/utils.js b/src/utils.js index 32eb13a..daf02df 100755 --- a/src/utils.js +++ b/src/utils.js @@ -28,25 +28,6 @@ export function defaultOrderByFn(arr, funcs, dirs) { }) } -export function defaultSortByFn(a, b, desc) { - // force null and undefined to the bottom - a = a === null || a === undefined ? '' : a - b = b === null || b === undefined ? '' : b - // force any string values to lowercase - a = typeof a === 'string' ? a.toLowerCase() : a - b = typeof b === 'string' ? b.toLowerCase() : b - // Return either 1 or -1 to indicate a sort priority - if (a > b) { - return 1 - } - if (a < b) { - return -1 - } - // returning 0, undefined or any falsey value will defer to the next - // sorting mechanism or eventually the columns index via the orderByFn - return 0 -} - export function getFirstDefined(...args) { for (let i = 0; i < args.length; i += 1) { if (typeof args[i] !== 'undefined') { @@ -154,6 +135,12 @@ export function sum(arr) { return arr.reduce((prev, curr) => prev + curr, 0) } +export function isFunction(a) { + if (typeof a === 'function') { + return a + } +} + function makePathArray(obj) { return flattenDeep(obj) .join('.')