Files
threshold-ui/addons/api/addon/utils/sort-results.js
T

84 lines
2.7 KiB
JavaScript
Raw Normal View History

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
// created_time is not an attribute defined on all models, but is present in all the resources
// coming from API
const SORT_DEFAULT_ATTRIBUTE = 'created_time';
const SORT_DIRECTION_ASCENDING = 'asc';
const SORT_DIRECTION_DESCENDING = 'desc';
const sortFunctions = {
string: (a, b) => String(a).localeCompare(String(b)),
date: (a, b) => new Date(a).getTime() - new Date(b).getTime(),
number: (a, b) => Number(a) - Number(b),
boolean: (a, b) => Number(a) - Number(b),
};
function getSortableValue(schema, record, attribute) {
if (attribute === 'id') {
return record.id;
}
// all models have a created_time attribute but not all models have it defined
if (attribute === 'created_time') {
return record.attributes.created_time;
}
if (schema.attributes.has(attribute)) {
return record.attributes[attribute];
}
const attributes = Array.from(schema.attributes.keys());
throw new Error(
`The attribute "${attribute}" does not map to the model definition of type "${record.type}". Supported sortable attributes are 'id', 'created_time', or ${attributes.map((attr) => `'${attr}'`).join(', ')}`,
);
}
export const sortResults = (results, { querySort, schema }) => {
querySort = querySort ?? {};
const sortAttribute = querySort.attribute || SORT_DEFAULT_ATTRIBUTE;
// Default sort direction is ascending unless we are sorting by `created_time` (default sort attribute)
const defaultSortDirection =
2025-06-05 11:00:25 -07:00
sortAttribute === SORT_DEFAULT_ATTRIBUTE && !querySort.sortFunction
? SORT_DIRECTION_DESCENDING
: SORT_DIRECTION_ASCENDING;
const sortDirection = querySort.direction || defaultSortDirection;
if (
![SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING].includes(
sortDirection,
)
) {
throw new Error('Invalid sort direction');
}
2025-06-05 11:00:25 -07:00
// Execute custom sort function if one is provided.
if (querySort.sortFunction) {
return results.toSorted((a, b) => {
const sortResult = querySort.sortFunction(a, b);
return sortDirection === SORT_DIRECTION_ASCENDING
? sortResult
: -1 * sortResult;
});
}
const sortAttributeDataType = schema.attributes.get(sortAttribute)?.type;
const sortFunction =
sortFunctions[sortAttributeDataType] ?? sortFunctions.string;
return results.toSorted((a, b) => {
// Extract the values to sort and sort them.
const sortValueA = getSortableValue(schema, a, sortAttribute);
const sortValueB = getSortableValue(schema, b, sortAttribute);
const sortResult = sortFunction(sortValueA, sortValueB);
return sortDirection === SORT_DIRECTION_ASCENDING
? sortResult
: -1 * sortResult;
});
};