Skip to content

Commit

Permalink
Extract sort logic to untyped field definition
Browse files Browse the repository at this point in the history
  • Loading branch information
oandregal committed Aug 1, 2024
1 parent b19cf28 commit 2d80886
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 47 deletions.
12 changes: 10 additions & 2 deletions packages/dataviews/src/field-types/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Internal dependencies
*/
import type { FieldType, ValidationContext } from '../types';
import type { FieldType, SortDirection, ValidationContext } from '../types';
import { default as integer } from './integer';
import { default as text } from './text';

Expand All @@ -21,7 +21,15 @@ export default function getFieldTypeDefinition( type?: FieldType ) {
}

return {
sort: () => 0,
sort: ( a: any, b: any, direction: SortDirection ) => {
if ( typeof a === 'number' && typeof b === 'number' ) {
return direction === 'asc' ? a - b : b - a;
}

return direction === 'asc'
? a.localeCompare( b )
: b.localeCompare( a );
},
isValid: ( value: any, context?: ValidationContext ) => {
if ( context?.elements ) {
const validValues = context?.elements?.map( ( f ) => f.value );
Expand Down
26 changes: 1 addition & 25 deletions packages/dataviews/src/filter-and-sort-data-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,31 +140,7 @@ export function filterSortAndPaginate< Item >(
} );
if ( fieldToSort ) {
filteredData.sort( ( a, b ) => {
if (
[ 'integer', 'text' ].includes( fieldToSort.type ?? '' )
) {
return fieldToSort.sort(
a,
b,
view.sort?.direction ?? 'desc'
);
}

// When/if types become required, we can remove the following logic.
const valueA = fieldToSort.getValue( { item: a } ) ?? '';
const valueB = fieldToSort.getValue( { item: b } ) ?? '';
if (
typeof valueA === 'number' &&
typeof valueB === 'number'
) {
return view.sort?.direction === 'asc'
? valueA - valueB
: valueB - valueA;
}

return view.sort?.direction === 'asc'
? valueA.localeCompare( valueB )
: valueB.localeCompare( valueA );
return fieldToSort.sort( a, b, view.sort?.direction ?? 'desc' );
} );
}
}
Expand Down
40 changes: 20 additions & 20 deletions packages/dataviews/src/test/filter-and-sort-data-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,26 +248,6 @@ describe( 'sorting', () => {
expect( result[ 2 ].title ).toBe( 'Uranus' );
} );

it( 'should sort untyped fields if the value is a number', () => {
const { data: result } = filterSortAndPaginate(
data,
{
sort: { field: 'satellites', direction: 'desc' },
},
// Remove type information for satellites field to test sorting untyped fields.
fields.map( ( field ) =>
field.id === 'satellites'
? { ...field, type: undefined }
: field
)
);

expect( result ).toHaveLength( 11 );
expect( result[ 0 ].title ).toBe( 'Saturn' );
expect( result[ 1 ].title ).toBe( 'Jupiter' );
expect( result[ 2 ].title ).toBe( 'Uranus' );
} );

it( 'should sort text field types', () => {
const { data: result } = filterSortAndPaginate(
data,
Expand All @@ -288,6 +268,26 @@ describe( 'sorting', () => {
expect( result[ 1 ].title ).toBe( 'Neptune' );
} );

it( 'should sort untyped fields if the value is a number', () => {
const { data: result } = filterSortAndPaginate(
data,
{
sort: { field: 'satellites', direction: 'desc' },
},
// Remove type information for satellites field to test sorting untyped fields.
fields.map( ( field ) =>
field.id === 'satellites'
? { ...field, type: undefined }
: field
)
);

expect( result ).toHaveLength( 11 );
expect( result[ 0 ].title ).toBe( 'Saturn' );
expect( result[ 1 ].title ).toBe( 'Jupiter' );
expect( result[ 2 ].title ).toBe( 'Uranus' );
} );

it( 'should sort untyped fields if the value is string', () => {
const { data: result } = filterSortAndPaginate(
data,
Expand Down

0 comments on commit 2d80886

Please sign in to comment.