Skip to content

Commit

Permalink
TNO-2534 sort by string (#1755)
Browse files Browse the repository at this point in the history
* Add naturalSort utility function for list view sorting

* added source for sorting as well

* use naturalSort

* Refactor sorting logic in FlexboxTable component

* new sor in paper useColumns.tsx

* not sort by source

* remove unused method
  • Loading branch information
kkwangsir authored May 2, 2024
1 parent 5ca37b7 commit d98ddb6
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 15 deletions.
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;
};

0 comments on commit d98ddb6

Please sign in to comment.