forked from baron/baron-sso
common 정렬 헬퍼 공통화 및 devfront 목록 정렬 추가
This commit is contained in:
@@ -4,3 +4,5 @@ export function mergeClassNames(
|
||||
) {
|
||||
return mergeFn(...classNames);
|
||||
}
|
||||
|
||||
export * from "./sort";
|
||||
|
||||
97
common/core/utils/sort.ts
Normal file
97
common/core/utils/sort.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
export type SortDirection = "asc" | "desc";
|
||||
|
||||
export type SortConfig<Key extends string = string> = {
|
||||
key: Key;
|
||||
direction: SortDirection;
|
||||
};
|
||||
|
||||
export type SortableValue = string | number | boolean | Date | null | undefined;
|
||||
|
||||
export type SortResolver<T> = (item: T) => SortableValue;
|
||||
|
||||
export type SortResolverMap<T, Key extends string = string> = Partial<
|
||||
Record<Key, SortResolver<T>>
|
||||
>;
|
||||
|
||||
function normalizeSortableValue(value: SortableValue) {
|
||||
if (value instanceof Date) {
|
||||
return value.getTime();
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value.toLocaleLowerCase();
|
||||
}
|
||||
if (typeof value === "boolean") {
|
||||
return value ? 1 : 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function compareNullableValues(
|
||||
left: SortableValue,
|
||||
right: SortableValue,
|
||||
direction: SortDirection,
|
||||
) {
|
||||
if (left === right) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left === null || left === undefined) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (right === null || right === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const normalizedLeft = normalizeSortableValue(left);
|
||||
const normalizedRight = normalizeSortableValue(right);
|
||||
|
||||
if (normalizedLeft === normalizedRight) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (normalizedLeft === null || normalizedLeft === undefined) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (normalizedRight === null || normalizedRight === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const comparison = normalizedLeft < normalizedRight ? -1 : 1;
|
||||
return direction === "asc" ? comparison : -comparison;
|
||||
}
|
||||
|
||||
export function toggleSort<Key extends string>(
|
||||
current: SortConfig<Key> | null,
|
||||
key: Key,
|
||||
): SortConfig<Key> {
|
||||
if (current?.key === key && current.direction === "asc") {
|
||||
return { key, direction: "desc" };
|
||||
}
|
||||
|
||||
return { key, direction: "asc" };
|
||||
}
|
||||
|
||||
export function sortItems<T, Key extends string = string>(
|
||||
items: T[],
|
||||
sortConfig: SortConfig<Key> | null,
|
||||
resolverMap: SortResolverMap<T, Key> = {},
|
||||
) {
|
||||
if (!sortConfig) {
|
||||
return [...items];
|
||||
}
|
||||
|
||||
const resolveValue =
|
||||
resolverMap[sortConfig.key] ??
|
||||
((item: T) =>
|
||||
(item as Record<string, SortableValue>)[sortConfig.key] ?? null);
|
||||
|
||||
return [...items].sort((left, right) =>
|
||||
compareNullableValues(
|
||||
resolveValue(left),
|
||||
resolveValue(right),
|
||||
sortConfig.direction,
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user