Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TNO-2534 sort by string #1755

Merged
merged 10 commits into from
May 2, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
WorkOrderStatusName,
} from 'tno-core';

import { naturalSortValue } from '../utils/naturalSort';

export interface IColumnProps {
fetch: (
filter: IContentListFilter & Partial<IContentListAdvancedFilter>,
Expand Down Expand Up @@ -67,11 +69,7 @@ export const useColumns = ({ fetch }: IColumnProps): ITableHookColumn<IContentSe
},
{
accessor: 'section',
sort: (row) => {
return `${row.original.page ? row.original.page : ''}:${
row.original.section ? row.original.section : ''
}`;
},
sort: (row) => naturalSortValue(row.original),
label: (
<Row nowrap>
Page:Section
Expand Down
23 changes: 23 additions & 0 deletions app/editor/src/features/content/list-view/utils/naturalSort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { IContentSearchResult } from 'store/slices';

function getPageSectionValue(row: IContentSearchResult) {
// gnerate page:section string, keep it in the lowercase
const value = `${row.original.page ? row.original.page : ''}:${
row.original.section ? row.original.section : ''
}`.toLowerCase();
return value;
}

export function naturalSortValue(row: IContentSearchResult) {
const pageSectionValue = getPageSectionValue(row);
// Replace each segment of digits and non-digits with formatted strings
// Digits are padded with zeros to the left to ensure correct natural sorting
// Non-digits are left as is
// eq. 'A2:sport' -> 'A0000000002:sport'
// eq. 'A02:sport' -> 'A0000000002:sport'
const formattedPageSectionValue = pageSectionValue.replace(/(\d+)|(\D+)/g, (_, $1, $2) =>
$1 ? Number($1).toString().padStart(10, '0') : $2,
);
// we do consider source as the primary key for sorting
return formattedPageSectionValue;
}
7 changes: 2 additions & 5 deletions app/editor/src/features/content/papers/hooks/useColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Status } from 'components/status';
import { TabControl } from 'components/tab-control';
import { AdvancedSearchKeys } from 'features/content/constants';
import { IContentListAdvancedFilter, IContentListFilter } from 'features/content/interfaces';
import { naturalSortValue } from 'features/content/list-view/utils/naturalSort';
import { useContent } from 'store/hooks';
import { IContentSearchResult } from 'store/slices';
import { CellEllipsis, Checkbox, ITableHookColumn, LogicalOperator, Page, Row } from 'tno-core';
Expand Down Expand Up @@ -45,11 +46,7 @@ export const useColumns = ({
},
{
accessor: 'section',
sort: (row) => {
return `${row.original.page ? row.original.page : ''}:${
row.original.section ? row.original.section : ''
}`;
},
sort: (row) => naturalSortValue(row.original),
label: (
<Row nowrap>
Page:Section
Expand Down
7 changes: 2 additions & 5 deletions libs/npm/core/src/components/table/FlexboxTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Container } from '../container';
import { Text } from '../form';
import { getSortId, ITableProps, SortFlag, TablePager, useTable } from '.';
import * as styled from './styled';

import { determineSortValue } from './utils/determineSort';
export const FlexboxTable = <T extends object>({
rowId,
columns,
Expand Down Expand Up @@ -109,10 +109,7 @@ export const FlexboxTable = <T extends object>({
{
id: getSortId(col, index),
index: index,
sort:
col.sort ?? typeof col.accessor === 'function'
? undefined
: col.accessor,
sort: determineSortValue(col),
isSorted: !col.isSorted ? true : col.isSortedDesc ? false : true,
isSortedDesc: col.isSorted ? !col.isSortedDesc : col.isSortedDesc,
},
Expand Down
16 changes: 16 additions & 0 deletions libs/npm/core/src/components/table/utils/determineSort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ITableInternalHeaderColumn } from '../interfaces/ITableInternalHeaderColumn';

export const determineSortValue = <T extends object>(col: ITableInternalHeaderColumn<T>) => {
// If 'col.sort' is defined and not null, use it directly for sorting
if (col.sort !== undefined && col.sort !== null) {
return col.sort;
}
// If 'col.sort' is undefined or null and 'accessor' is a function,
// it indicates that 'accessor' cannot be used for sorting directly (e.g., dynamic values)
if (typeof col.accessor === 'function') {
return undefined;
}
// If 'col.sort' is undefined or null, and 'accessor' is not a function,
// use 'accessor' as the field name for sorting
return col.accessor;
};
Loading