Files
oranguru/src/Griddy/adapters/mapOptions.ts
Hein 7244bd33fc refactor(advancedSearch): reorder exports and improve type definitions
refactor(types): reorganize SearchCondition and AdvancedSearchState interfaces
refactor(filterPresets): streamline useFilterPresets hook and localStorage handling
refactor(filtering): clean up ColumnFilterButton and ColumnFilterPopover components
refactor(loading): separate GriddyLoadingOverlay from GriddyLoadingSkeleton
refactor(searchHistory): enhance useSearchHistory hook with persistence
refactor(index): update exports for adapters and core components
refactor(rendering): improve EditableCell and TableCell components for clarity
refactor(rendering): enhance TableHeader and VirtualBody components for better readability
2026-02-15 19:54:33 +02:00

127 lines
3.2 KiB
TypeScript

import type { ColumnFiltersState, PaginationState, SortingState } from '@tanstack/react-table';
import type { FilterOption, Options, SortOption } from '@warkypublic/resolvespec-js';
const OPERATOR_MAP: Record<string, string> = {
between: 'between',
contains: 'ilike',
endsWith: 'endswith',
equals: 'eq',
excludes: 'in',
greaterThan: 'gt',
greaterThanOrEqual: 'gte',
includes: 'in',
is: 'eq',
isAfter: 'gt',
isBefore: 'lt',
isBetween: 'between_inclusive',
isEmpty: 'is_null',
isFalse: 'eq',
isNotEmpty: 'is_not_null',
isTrue: 'eq',
lessThan: 'lt',
lessThanOrEqual: 'lte',
notContains: 'ilike',
notEquals: 'neq',
startsWith: 'startswith',
};
export function applyCursor(opts: Options, cursor: null | string, limit: number): Options {
const result = { ...opts, limit };
if (cursor) {
result.cursor_forward = cursor;
}
return result;
}
export function buildOptions(
sorting: SortingState,
filters: ColumnFiltersState,
pagination: PaginationState | undefined,
columnMap?: Record<string, string>,
defaultOptions?: Partial<Options>
): Options {
const opts: Options = { ...defaultOptions };
if (sorting.length > 0) {
opts.sort = mapSorting(sorting, columnMap);
}
if (filters.length > 0) {
opts.filters = mapFilters(filters, columnMap);
}
if (pagination) {
const { limit, offset } = mapPagination(pagination);
opts.limit = limit;
opts.offset = offset;
}
return opts;
}
export function mapFilters(
filters: ColumnFiltersState,
columnMap?: Record<string, string>
): FilterOption[] {
return filters.flatMap((filter) => {
const filterValue = filter.value as any;
// Enum filter with values array
if (filterValue?.values && Array.isArray(filterValue.values)) {
return [
{
column: resolveColumn(filter.id, columnMap),
operator: 'in',
value: filterValue.values,
},
];
}
const operator = filterValue?.operator ?? 'eq';
const value = filterValue?.value ?? filterValue;
return [
{
column: resolveColumn(filter.id, columnMap),
operator: resolveOperator(operator),
value: resolveFilterValue(operator, value),
},
];
});
}
export function mapPagination(pagination: PaginationState): { limit: number; offset: number } {
return {
limit: pagination.pageSize,
offset: pagination.pageIndex * pagination.pageSize,
};
}
export function mapSorting(
sorting: SortingState,
columnMap?: Record<string, string>
): SortOption[] {
return sorting.map(({ desc, id }) => ({
column: resolveColumn(id, columnMap),
direction: desc ? ('desc' as const) : ('asc' as const),
}));
}
function resolveColumn(id: string, columnMap?: Record<string, string>): string {
return columnMap?.[id] ?? id;
}
function resolveFilterValue(operator: string, value: any): any {
if (operator === 'isTrue') return true;
if (operator === 'isFalse') return false;
if (operator === 'contains') return `%${value}%`;
if (operator === 'startsWith') return `${value}%`;
if (operator === 'endsWith') return `%${value}`;
if (operator === 'notContains') return `%${value}%`;
return value;
}
function resolveOperator(op: string): string {
return OPERATOR_MAP[op] ?? op;
}