[FA-misc] Various UI updates
This commit is contained in:
@@ -1,20 +1,37 @@
|
||||
import type { NovelDtoFilterInput, NovelStatus } from '$lib/graphql/__generated__/graphql';
|
||||
import type { NovelDtoFilterInput, NovelDtoSortInput, NovelStatus, SortEnumType } from '$lib/graphql/__generated__/graphql';
|
||||
|
||||
export type SortField = 'lastUpdatedTime' | 'createdTime' | 'name';
|
||||
export type SortDirection = SortEnumType;
|
||||
|
||||
export interface NovelSort {
|
||||
field: SortField;
|
||||
direction: SortDirection;
|
||||
}
|
||||
|
||||
export interface NovelFilters {
|
||||
search: string;
|
||||
statuses: NovelStatus[];
|
||||
tags: string[];
|
||||
authorName: string;
|
||||
sort: NovelSort;
|
||||
}
|
||||
|
||||
export const DEFAULT_SORT: NovelSort = {
|
||||
field: 'lastUpdatedTime',
|
||||
direction: 'DESC'
|
||||
};
|
||||
|
||||
export const EMPTY_FILTERS: NovelFilters = {
|
||||
search: '',
|
||||
statuses: [],
|
||||
tags: [],
|
||||
authorName: ''
|
||||
authorName: '',
|
||||
sort: DEFAULT_SORT
|
||||
};
|
||||
|
||||
const VALID_STATUSES: NovelStatus[] = ['ABANDONED', 'COMPLETED', 'HIATUS', 'IN_PROGRESS', 'UNKNOWN'];
|
||||
const VALID_SORT_FIELDS: SortField[] = ['lastUpdatedTime', 'createdTime', 'name'];
|
||||
const VALID_SORT_DIRECTIONS: SortDirection[] = ['ASC', 'DESC'];
|
||||
|
||||
/**
|
||||
* Parse filter state from URL search parameters
|
||||
@@ -34,7 +51,15 @@ export function parseFiltersFromURL(searchParams?: URLSearchParams): NovelFilter
|
||||
|
||||
const authorName = params.get('author') ?? '';
|
||||
|
||||
return { search, statuses, tags, authorName };
|
||||
// Parse sort parameters
|
||||
const sortField = params.get('sortBy') as SortField | null;
|
||||
const sortDir = params.get('sortDir') as SortDirection | null;
|
||||
const sort: NovelSort = {
|
||||
field: sortField && VALID_SORT_FIELDS.includes(sortField) ? sortField : DEFAULT_SORT.field,
|
||||
direction: sortDir && VALID_SORT_DIRECTIONS.includes(sortDir) ? sortDir : DEFAULT_SORT.direction
|
||||
};
|
||||
|
||||
return { search, statuses, tags, authorName, sort };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +84,12 @@ export function filtersToURLParams(filters: NovelFilters): string {
|
||||
params.set('author', filters.authorName.trim());
|
||||
}
|
||||
|
||||
// Only include sort params if different from default
|
||||
if (filters.sort.field !== DEFAULT_SORT.field || filters.sort.direction !== DEFAULT_SORT.direction) {
|
||||
params.set('sortBy', filters.sort.field);
|
||||
params.set('sortDir', filters.sort.direction);
|
||||
}
|
||||
|
||||
return params.toString();
|
||||
}
|
||||
|
||||
@@ -135,3 +166,10 @@ export function hasActiveFilters(filters: NovelFilters): boolean {
|
||||
filters.authorName.trim().length > 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert sort state to GraphQL order input
|
||||
*/
|
||||
export function sortToGraphQLOrder(sort: NovelSort): NovelDtoSortInput[] {
|
||||
return [{ [sort.field]: sort.direction }];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user