Skip to content

Commit 7d12592

Browse files
committed
Fix column sorting in SearchUI
1 parent 7a4a51e commit 7d12592

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ For more complicated components like `MaterialsInput` and `SearchUI`, some of th
7676

7777
Other utils that are used across multiple components can be found in the higher-level `src/utils` directory. For example, the functions for initializing table columns can be found in `src/utils/table.tsx`.
7878

79+
### Component Types
80+
7981
### Exporting Components
8082

8183
Any component that you want to be usable when this library is imported as a third-party node module must be added to the exports list in `src/index.ts`.
@@ -139,3 +141,5 @@ Stories are defined in `./src/stories`
139141
```
140142
npm deploy-storybook
141143
```
144+
145+
### Build Tools

src/components/data-display/SearchUI/SearchUIContextProvider/SearchUIContextProvider.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,24 @@ export const SearchUIContextProvider: React.FC<SearchState> = ({
120120
});
121121
}
122122
},
123+
/**
124+
* Set the primary sort field and sort direction
125+
*/
123126
setSort: (sortField: string, sortAscending: boolean) => {
124-
const sortFields = [...query[props.sortKey]];
127+
let sortFields: string[] | undefined = [];
128+
if (query[props.sortKey]) {
129+
sortFields = [...query[props.sortKey]];
130+
}
125131
const directionPrefix = sortAscending ? '' : '-';
126132
sortFields[0] = directionPrefix + sortField;
127133
setQuery({
128134
[props.sortKey]: sortFields,
129135
[props.skipKey]: undefined
130136
});
131137
},
138+
/**
139+
* Set the primary sort column without changing sort direction
140+
*/
132141
setSortField: (sortField: string) => {
133142
const sortFields = [...query[props.sortKey]];
134143
sortFields[0] = sortField;
@@ -237,7 +246,8 @@ export const SearchUIContextProvider: React.FC<SearchState> = ({
237246
const params = preprocessQueryParams(
238247
{ ...query, ...props.apiEndpointParams },
239248
state.filterGroups,
240-
defaultQuery
249+
defaultQuery,
250+
state.sortKey
241251
);
242252
params[props.fieldsKey] = fields;
243253

src/components/data-display/SearchUI/types.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,12 @@ export interface SearchUIContainerProps {
310310
* Optionally include up to 2 fields to sort by on initial load.
311311
* To sort in descending order, prefix the field name with "-".
312312
* The first sort field can be modified within the UI. The second will be the default secondary sort field.
313-
* e.g. ["-energy_above_hull", "formula_pretty"]
313+
* e.g. `["-energy_above_hull", "formula_pretty"]`
314+
* If you want to include a default secondary sort field but no default primary sort,
315+
* then the first item in the array should be null or undefined.
316+
* e.g. `[null, "formula_pretty"]`
314317
*/
315-
sortFields?: string[];
318+
sortFields?: (string | undefined | null)[];
316319
/**
317320
* Name of the sort parameter in the linked API.
318321
* @default 'sort_fields'

src/components/data-display/SearchUI/utils.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ export const initQueryParams = (
227227
export const preprocessQueryParams = (
228228
query: DecodedValueMap<QueryParamConfigMap>,
229229
filterGroups: FilterGroup[],
230-
defaultQuery: any
230+
defaultQuery: any,
231+
sortParamKey: string
231232
) => {
232233
const processedQuery = {};
233234
for (const paramName in query) {
@@ -266,13 +267,39 @@ export const preprocessQueryParams = (
266267
}
267268
processedQuery[paramName] = paramValue;
268269
}
270+
} else if (paramName === sortParamKey && query[sortParamKey]) {
271+
/**
272+
* Add the secondary sort field to the sort query if one exists.
273+
* (Secondary sort is controlled by the sortFields prop, not from the UI)
274+
*/
275+
const processedSortFields = [...query[sortParamKey]];
276+
if (defaultQuery[sortParamKey] && defaultQuery[sortParamKey].length === 2) {
277+
processedSortFields.push(defaultQuery[sortParamKey][1]);
278+
}
279+
processedQuery[sortParamKey] = processedSortFields;
269280
} else {
270281
processedQuery[paramName] = query[paramName];
271282
}
272283
}
284+
/**
285+
* Add default query params for params that require a value
286+
* but haven't been explicitly set (e.g. skip or limit).
287+
*/
273288
for (const defaultParam in defaultQuery) {
274289
if (query[defaultParam] === undefined) {
275-
processedQuery[defaultParam] = defaultQuery[defaultParam];
290+
/**
291+
* If there is a default secondary sort field, but no default primary sort field
292+
* then only include the secondary sort field in the API query.
293+
*/
294+
if (
295+
defaultParam === sortParamKey &&
296+
defaultQuery[sortParamKey][1] &&
297+
(defaultQuery[sortParamKey][0] === null || defaultQuery[sortParamKey][0] === undefined)
298+
) {
299+
processedQuery[defaultParam] = [defaultQuery[defaultParam][1]];
300+
} else {
301+
processedQuery[defaultParam] = defaultQuery[defaultParam];
302+
}
276303
}
277304
}
278305
return processedQuery;

src/pages/MaterialsExplorer/MaterialsExplorer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const MaterialsExplorer: React.FC = () => {
5353
}
5454
apiKey={process.env.REACT_APP_API_KEY ? process.env.REACT_APP_API_KEY : undefined}
5555
hasSortMenu={true}
56-
sortFields={['energy_above_hull', 'formula_pretty']}
56+
sortFields={['-energy_above_hull', 'formula_pretty']}
5757
>
5858
<SearchUISearchBar
5959
periodicTableMode={PeriodicTableMode.TOGGLE}

0 commit comments

Comments
 (0)