feat: improve model catalog aggregation
This commit is contained in:
+72
-8
@@ -1,4 +1,4 @@
|
||||
import type { AdminSection, ApiDocSection, PageKey, PlaygroundMode, WorkspaceSection } from './types';
|
||||
import type { AdminSection, ApiDocSection, PageKey, PlaygroundMode, WorkspaceSection, WorkspaceTaskQuery } from './types';
|
||||
|
||||
export interface AppRouteState {
|
||||
activePage: PageKey;
|
||||
@@ -6,6 +6,7 @@ export interface AppRouteState {
|
||||
apiDocSection: ApiDocSection;
|
||||
playgroundMode: PlaygroundMode;
|
||||
workspaceSection: WorkspaceSection;
|
||||
workspaceTaskQuery: WorkspaceTaskQuery;
|
||||
}
|
||||
|
||||
export const defaultRouteState: AppRouteState = {
|
||||
@@ -14,6 +15,7 @@ export const defaultRouteState: AppRouteState = {
|
||||
apiDocSection: 'chat',
|
||||
playgroundMode: 'chat',
|
||||
workspaceSection: 'overview',
|
||||
workspaceTaskQuery: defaultWorkspaceTaskQuery(),
|
||||
};
|
||||
|
||||
const workspacePaths: Record<WorkspaceSection, string> = {
|
||||
@@ -55,21 +57,23 @@ const adminSections = reverseMap(adminPaths);
|
||||
const docsSections = reverseMap(docsPaths);
|
||||
const playgroundSections = reverseMap(playgroundPaths);
|
||||
|
||||
export function parseAppRoute(pathname = window.location.pathname): AppRouteState {
|
||||
const path = normalizePath(pathname);
|
||||
export function parseAppRoute(input = `${window.location.pathname}${window.location.search}`): AppRouteState {
|
||||
const url = new URL(input, window.location.origin);
|
||||
const path = normalizePath(url.pathname);
|
||||
const workspaceTaskQuery = parseWorkspaceTaskQuery(url.searchParams);
|
||||
if (path === '/') return { ...defaultRouteState };
|
||||
if (path.startsWith('/playground')) {
|
||||
return { ...defaultRouteState, activePage: 'playground', playgroundMode: parsePlaygroundMode(path) };
|
||||
return { ...defaultRouteState, activePage: 'playground', playgroundMode: parsePlaygroundMode(path), workspaceTaskQuery };
|
||||
}
|
||||
if (path === '/models') return { ...defaultRouteState, activePage: 'models' };
|
||||
if (path === '/models') return { ...defaultRouteState, activePage: 'models', workspaceTaskQuery };
|
||||
if (path.startsWith('/workspace')) {
|
||||
return { ...defaultRouteState, activePage: 'workspace', workspaceSection: parseWorkspaceSection(path) };
|
||||
return { ...defaultRouteState, activePage: 'workspace', workspaceSection: parseWorkspaceSection(path), workspaceTaskQuery };
|
||||
}
|
||||
if (path.startsWith('/admin')) {
|
||||
return { ...defaultRouteState, activePage: 'admin', adminSection: parseAdminSection(path) };
|
||||
return { ...defaultRouteState, activePage: 'admin', adminSection: parseAdminSection(path), workspaceTaskQuery };
|
||||
}
|
||||
if (path.startsWith('/docs')) {
|
||||
return { ...defaultRouteState, activePage: 'docs', apiDocSection: parseDocSection(path) };
|
||||
return { ...defaultRouteState, activePage: 'docs', apiDocSection: parseDocSection(path), workspaceTaskQuery };
|
||||
}
|
||||
return { ...defaultRouteState };
|
||||
}
|
||||
@@ -87,6 +91,19 @@ export function pathForWorkspaceSection(section: WorkspaceSection) {
|
||||
return workspacePaths[section] ?? workspacePaths.overview;
|
||||
}
|
||||
|
||||
export function pathForWorkspaceTaskQuery(query: WorkspaceTaskQuery) {
|
||||
const normalized = normalizeWorkspaceTaskQuery(query);
|
||||
const search = new URLSearchParams();
|
||||
if (normalized.query) search.set('q', normalized.query);
|
||||
if (normalized.modelType) search.set('type', normalized.modelType);
|
||||
if (normalized.createdFrom) search.set('from', normalized.createdFrom);
|
||||
if (normalized.createdTo) search.set('to', normalized.createdTo);
|
||||
if (normalized.page !== 1) search.set('page', String(normalized.page));
|
||||
if (normalized.pageSize !== 10) search.set('pageSize', String(normalized.pageSize));
|
||||
const suffix = search.toString();
|
||||
return `${workspacePaths.tasks}${suffix ? `?${suffix}` : ''}`;
|
||||
}
|
||||
|
||||
export function pathForAdminSection(section: AdminSection) {
|
||||
return adminPaths[section] ?? adminPaths.overview;
|
||||
}
|
||||
@@ -131,3 +148,50 @@ function normalizePath(pathname: string) {
|
||||
function reverseMap<T extends string>(value: Record<T, string>) {
|
||||
return Object.fromEntries(Object.entries(value).map(([key, path]) => [path, key])) as Record<string, T>;
|
||||
}
|
||||
|
||||
export function defaultWorkspaceTaskQuery(): WorkspaceTaskQuery {
|
||||
return {
|
||||
query: '',
|
||||
modelType: '',
|
||||
createdFrom: '',
|
||||
createdTo: '',
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeWorkspaceTaskQuery(query: WorkspaceTaskQuery): WorkspaceTaskQuery {
|
||||
return {
|
||||
query: query.query.trim(),
|
||||
modelType: query.modelType.trim(),
|
||||
createdFrom: query.createdFrom.trim(),
|
||||
createdTo: query.createdTo.trim(),
|
||||
page: positiveInt(query.page, 1),
|
||||
pageSize: clampPageSize(query.pageSize),
|
||||
};
|
||||
}
|
||||
|
||||
export function workspaceTaskQueryKey(query: WorkspaceTaskQuery) {
|
||||
const normalized = normalizeWorkspaceTaskQuery(query);
|
||||
return JSON.stringify(normalized);
|
||||
}
|
||||
|
||||
function parseWorkspaceTaskQuery(search: URLSearchParams): WorkspaceTaskQuery {
|
||||
return normalizeWorkspaceTaskQuery({
|
||||
query: search.get('q') ?? search.get('query') ?? '',
|
||||
modelType: search.get('type') ?? search.get('modelType') ?? '',
|
||||
createdFrom: search.get('from') ?? search.get('createdFrom') ?? '',
|
||||
createdTo: search.get('to') ?? search.get('createdTo') ?? '',
|
||||
page: Number(search.get('page') ?? 1),
|
||||
pageSize: Number(search.get('pageSize') ?? search.get('limit') ?? 10),
|
||||
});
|
||||
}
|
||||
|
||||
function positiveInt(value: number, fallback: number) {
|
||||
return Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
|
||||
}
|
||||
|
||||
function clampPageSize(value: number) {
|
||||
const normalized = positiveInt(value, 10);
|
||||
return Math.min(100, Math.max(1, normalized));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user