diff --git a/SharePointFramework/PortfolioWebParts/src/components/PortfolioAggregation/reducer/createPortfolioAggregationReducer.ts b/SharePointFramework/PortfolioWebParts/src/components/PortfolioAggregation/reducer/createPortfolioAggregationReducer.ts index 0d6a7b5e9..87296450b 100644 --- a/SharePointFramework/PortfolioWebParts/src/components/PortfolioAggregation/reducer/createPortfolioAggregationReducer.ts +++ b/SharePointFramework/PortfolioWebParts/src/components/PortfolioAggregation/reducer/createPortfolioAggregationReducer.ts @@ -6,7 +6,7 @@ import sortArray from 'array-sort' import _ from 'lodash' import { IFilterItemProps } from 'pp365-shared-library/lib/components/FilterPanel' import { DataSource } from 'pp365-shared-library/lib/models/DataSource' -import { parseUrlHash, setUrlHash } from 'pp365-shared-library/lib/util' +import { parseUrlHash, setUrlHash, sortAlphabetically, sortNumerically } from 'pp365-shared-library/lib/util' import { getObjectValue as get } from 'pp365-shared-library/lib/util/getObjectValue' import { IPortfolioAggregationHashState, @@ -223,18 +223,17 @@ export const createPortfolioAggregationReducer = ( state.groups = null } if (payload.column.dataType === 'currency') { - state.items = state.items.sort((a, b) => { - const aValue = parseFloat(a[payload.column.fieldName]?.replace(/[^0-9.-]+/g, '')) || null - const bValue = parseFloat(b[payload.column.fieldName]?.replace(/[^0-9.-]+/g, '')) || null - if (aValue === bValue) return 0 - if (aValue === null) return isSortedDescending ? 1 : -1 - if (bValue === null) return isSortedDescending ? -1 : 1 - return isSortedDescending ? aValue - bValue : aValue - bValue - }) + state.items = state.items.sort((a, b) => + sortNumerically(a, b, isSortedDescending, payload.column.fieldName, 'kr ') + ) + } else if (payload.column.dataType === 'number') { + state.items = state.items.sort((a, b) => + sortNumerically(a, b, isSortedDescending, payload.column.fieldName) + ) } else { - state.items = sortArray([...state.items], [payload.column.fieldName], { - reverse: !isSortedDescending - }) + state.items.sort((a, b) => + sortAlphabetically(a, b, isSortedDescending, payload.column.fieldName) + ) } state.columns = [...state.columns].map((col) => { col.isSorted = col.key === payload.column.key diff --git a/SharePointFramework/PortfolioWebParts/src/components/PortfolioOverview/reducer/index.ts b/SharePointFramework/PortfolioWebParts/src/components/PortfolioOverview/reducer/index.ts index fc2debd8f..043b31349 100644 --- a/SharePointFramework/PortfolioWebParts/src/components/PortfolioOverview/reducer/index.ts +++ b/SharePointFramework/PortfolioWebParts/src/components/PortfolioOverview/reducer/index.ts @@ -1,8 +1,7 @@ import { format, MessageBarType } from '@fluentui/react' import { createReducer } from '@reduxjs/toolkit' -import sortArray from 'array-sort' import strings from 'PortfolioWebPartsStrings' -import { ProjectColumn, setUrlHash } from 'pp365-shared-library' +import { ProjectColumn, setUrlHash, sortAlphabetically, sortNumerically } from 'pp365-shared-library' import _ from 'underscore' import { IPortfolioOverviewHashState, IPortfolioOverviewState } from '../types' import { @@ -146,20 +145,17 @@ const $createReducer = (params: IPortfolioOverviewReducerParams) => }) } else { if (payload.column.dataType === 'currency') { - state.items = state.items.sort((a, b) => { - const aValue = - parseFloat(a[payload.column.fieldName]?.replace(/[^0-9.-]+/g, '')) || null - const bValue = - parseFloat(b[payload.column.fieldName]?.replace(/[^0-9.-]+/g, '')) || null - if (aValue === bValue) return 0 - if (aValue === null) return isSortedDescending ? 1 : -1 - if (bValue === null) return isSortedDescending ? -1 : 1 - return isSortedDescending ? aValue - bValue : aValue - bValue - }) + state.items = state.items.sort((a, b) => + sortNumerically(a, b, isSortedDescending, payload.column.fieldName, 'kr ') + ) + } else if (payload.column.dataType === 'number') { + state.items = state.items.sort((a, b) => + sortNumerically(a, b, isSortedDescending, payload.column.fieldName) + ) } else { - state.items = sortArray(state.items, [payload.column.fieldName], { - reverse: !isSortedDescending - }) + state.items.sort((a, b) => + sortAlphabetically(a, b, isSortedDescending, payload.column.fieldName) + ) } } state.sortBy = _.pick(payload, ['column', 'customSort']) diff --git a/SharePointFramework/shared-library/src/util/index.ts b/SharePointFramework/shared-library/src/util/index.ts index c08a6af6f..75042e493 100644 --- a/SharePointFramework/shared-library/src/util/index.ts +++ b/SharePointFramework/shared-library/src/util/index.ts @@ -12,6 +12,7 @@ export * from './createFieldValueMap' export * from './t9r' export * from './arrayMove' export * from './sortAlphabetically' +export * from './sortNumerically' export * from './formatDate' export * from './getBreakpoint' export * from './getDateValue' diff --git a/SharePointFramework/shared-library/src/util/sortAlphabetically.ts b/SharePointFramework/shared-library/src/util/sortAlphabetically.ts index 7ffbdb1fa..b91352b0f 100644 --- a/SharePointFramework/shared-library/src/util/sortAlphabetically.ts +++ b/SharePointFramework/shared-library/src/util/sortAlphabetically.ts @@ -1,3 +1,4 @@ +import { stringIsNullOrEmpty } from '@pnp/core' import { getObjectValue } from './' /** @@ -9,12 +10,22 @@ import { getObjectValue } from './' * @param property Property */ export function sortAlphabetically(a: T, b: T, ascending?: boolean, property?: string): number { - const aValue = getObjectValue(a, property, '') || a - const bValue = getObjectValue(b, property, '') || b - if (aValue < bValue) { + const aValue = getObjectValue(a, property, '*') || a + const bValue = getObjectValue(b, property, '*') || b + const lowerAValue = typeof aValue === 'string' ? aValue.toLowerCase() : aValue + const lowerBValue = typeof bValue === 'string' ? bValue.toLowerCase() : bValue + + if (typeof aValue === 'string' && stringIsNullOrEmpty(lowerAValue as string)) { + return 1 + } + if (typeof bValue === 'string' && stringIsNullOrEmpty(lowerBValue as string)) { + return -1 + } + + if (lowerAValue < lowerBValue) { return ascending ? -1 : 1 } - if (aValue > bValue) { + if (lowerAValue > lowerBValue) { return ascending ? 1 : -1 } return 0 diff --git a/SharePointFramework/shared-library/src/util/sortNumerically.ts b/SharePointFramework/shared-library/src/util/sortNumerically.ts new file mode 100644 index 000000000..d1bc55251 --- /dev/null +++ b/SharePointFramework/shared-library/src/util/sortNumerically.ts @@ -0,0 +1,50 @@ +import { getObjectValue } from '.' + +/** + * Sort numerically + * + * @param a Object a + * @param b Object b + * @param ascending Sort ascending + * @param property Property + * @param currency Currency + */ +export function sortNumerically( + a: T, + b: T, + ascending?: boolean, + property?: string, + currency?: string +): number { + const aValue = getObjectValue(a, property, '-') || a + const bValue = getObjectValue(b, property, '-') || b + + if (typeof aValue === 'number' && isNaN(aValue)) { + return 1 + } + if (typeof bValue === 'number' && isNaN(bValue)) { + return -1 + } + + if (currency && typeof aValue === 'string' && typeof bValue === 'string') { + const aCurrencyValue = parseFloat(aValue.replace(currency, '')) + const bCurrencyValue = parseFloat(bValue.replace(currency, '')) + + if (!isNaN(aCurrencyValue) && !isNaN(bCurrencyValue)) { + if (aCurrencyValue < bCurrencyValue) { + return ascending ? -1 : 1 + } + if (aCurrencyValue > bCurrencyValue) { + return ascending ? 1 : -1 + } + } + } + + if (aValue < bValue) { + return ascending ? -1 : 1 + } + if (aValue > bValue) { + return ascending ? 1 : -1 + } + return 0 +} diff --git a/SharePointFramework/shared-library/tsconfig.json b/SharePointFramework/shared-library/tsconfig.json index ab3720085..7d52bd4d8 100644 --- a/SharePointFramework/shared-library/tsconfig.json +++ b/SharePointFramework/shared-library/tsconfig.json @@ -35,4 +35,4 @@ "src/**/*.ts", "src/**/*.tsx" ] -} \ No newline at end of file +}