refactor: migrate all page.server.ts files to typed API client
All server-side fetch calls now go through createApiClient() from $lib/api.server.ts, which wraps openapi-fetch with the generated OpenAPI types. This means backend changes are reflected in the frontend after running npm run generate:api. - Add stub src/lib/generated/api.ts (replaced by generate:api output) - Fix GroupController: missing /api prefix and ResponseStatusException - Root, conversations, persons, documents pages all use typed client - Error handling uses apiError.code directly (no parseBackendError needed) - Edit page load uses typed client; PUT action keeps raw fetch (multipart) - Login keeps raw fetch (explicit Authorization header, not cookie auth) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,72 +1,58 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { createApiClient } from '$lib/api.server';
|
||||
|
||||
export const load: PageServerLoad = async ({ url, fetch }) => {
|
||||
|
||||
|
||||
// 1. Extract params
|
||||
export async function load({ url, fetch }) {
|
||||
const q = url.searchParams.get('q') || '';
|
||||
const from = url.searchParams.get('from') || '';
|
||||
const to = url.searchParams.get('to') || '';
|
||||
const senderId = url.searchParams.get('senderId') || '';
|
||||
const receiverId = url.searchParams.get('receiverId') || '';
|
||||
const tags = url.searchParams.getAll('tag') || '';
|
||||
const tags = url.searchParams.getAll('tag');
|
||||
|
||||
|
||||
|
||||
// 2. Build Search URL
|
||||
const searchUrl = new URL('http://localhost:8080/api/documents/search');
|
||||
if (q) searchUrl.searchParams.set('q', q);
|
||||
if (from) searchUrl.searchParams.set('from', from);
|
||||
if (to) searchUrl.searchParams.set('to', to);
|
||||
if (senderId) searchUrl.searchParams.set('senderId', senderId);
|
||||
if (receiverId) searchUrl.searchParams.set('receiverId', receiverId);
|
||||
if(tags) tags.forEach(tag => searchUrl.searchParams.append('tag', tag));
|
||||
|
||||
|
||||
// 3. Build Persons URL (to resolve names for the typeahead initial value)
|
||||
// Ideally, we would have endpoints like /api/persons/{id}, but for now we load the list or search.
|
||||
// To keep it simple and performant enough for now, we fetch all to find the names.
|
||||
const personsUrl = 'http://localhost:8080/api/persons';
|
||||
const api = createApiClient(fetch);
|
||||
|
||||
try {
|
||||
const [docsRes, personsRes] = await Promise.all([
|
||||
fetch(searchUrl.toString()),
|
||||
fetch(personsUrl)
|
||||
const [docsResult, personsResult] = await Promise.all([
|
||||
api.GET('/api/documents/search', {
|
||||
params: {
|
||||
query: {
|
||||
q: q || undefined,
|
||||
from: from || undefined,
|
||||
to: to || undefined,
|
||||
senderId: senderId || undefined,
|
||||
receiverId: receiverId || undefined,
|
||||
tag: tags.length ? tags : undefined
|
||||
}
|
||||
}
|
||||
}),
|
||||
api.GET('/api/persons')
|
||||
]);
|
||||
|
||||
if (docsRes.status === 401 || personsRes.status === 401) {
|
||||
if (docsResult.response.status === 401 || personsResult.response.status === 401) {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
|
||||
const documents = await docsRes.json();
|
||||
const allPersons = await personsRes.json();
|
||||
const documents = docsResult.data ?? [];
|
||||
const allPersons: { id: string; firstName: string; lastName: string }[] = personsResult.data ?? [];
|
||||
|
||||
// Resolve Names for the Typeahead Inputs
|
||||
const senderObj = allPersons.find((p: any) => p.id === senderId);
|
||||
const receiverObj = allPersons.find((p: any) => p.id === receiverId);
|
||||
|
||||
const senderName = senderObj ? `${senderObj.firstName} ${senderObj.lastName}` : '';
|
||||
const receiverName = receiverObj ? `${receiverObj.firstName} ${receiverObj.lastName}` : '';
|
||||
const senderObj = allPersons.find(p => p.id === senderId);
|
||||
const receiverObj = allPersons.find(p => p.id === receiverId);
|
||||
|
||||
return {
|
||||
documents,
|
||||
// We don't need to pass the full persons list to the frontend anymore,
|
||||
// as the Typeahead fetches it dynamically. We only pass the resolved names.
|
||||
initialValues: {
|
||||
senderName,
|
||||
receiverName
|
||||
senderName: senderObj ? `${senderObj.firstName} ${senderObj.lastName}` : '',
|
||||
receiverName: receiverObj ? `${receiverObj.firstName} ${receiverObj.lastName}` : ''
|
||||
},
|
||||
filters: { q, from, to, senderId, receiverId, tags }
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error loading data:", error);
|
||||
} catch (e) {
|
||||
if ((e as { status?: number }).status) throw e;
|
||||
console.error('Error loading data:', e);
|
||||
return {
|
||||
documents: [],
|
||||
initialValues: { senderName: '', receiverName: '' },
|
||||
filters: { q, from, to, senderId, receiverId },
|
||||
error: "Could not load data."
|
||||
filters: { q, from, to, senderId, receiverId, tags }
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user