The locals.user.groups.some(...WRITE_ALL) derivation was copy-pasted across the persons directory, persons review and the two document loaders touched by this PR. Extract a single tested hasWriteAll(locals) helper in $lib/shared/server and reuse it, removing the ad-hoc casts. Refs #667 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import { error } from '@sveltejs/kit';
|
|
import { createApiClient } from '$lib/shared/api.server';
|
|
import { getErrorMessage } from '$lib/shared/errors';
|
|
import { hasWriteAll } from '$lib/shared/server/permissions';
|
|
|
|
const PAGE_SIZE = 50;
|
|
|
|
type PersonType = 'PERSON' | 'INSTITUTION' | 'GROUP';
|
|
|
|
function parseType(raw: string | null): PersonType | undefined {
|
|
return raw === 'PERSON' || raw === 'INSTITUTION' || raw === 'GROUP' ? raw : undefined;
|
|
}
|
|
|
|
export async function load({ url, fetch, locals }) {
|
|
const q = url.searchParams.get('q') || '';
|
|
const page = Math.max(0, Number.parseInt(url.searchParams.get('page') ?? '0', 10) || 0);
|
|
const review =
|
|
url.searchParams.get('review') === '1' || url.searchParams.get('review') === 'true';
|
|
const type = parseType(url.searchParams.get('type'));
|
|
const familyOnly = url.searchParams.get('familyOnly') === 'true';
|
|
const hasDocuments = url.searchParams.get('hasDocuments') === 'true';
|
|
|
|
const api = createApiClient(fetch);
|
|
|
|
const canWrite = hasWriteAll(locals);
|
|
|
|
const filters = {
|
|
q: q || undefined,
|
|
type,
|
|
familyOnly: familyOnly || undefined,
|
|
hasDocuments: hasDocuments || undefined,
|
|
review: review || undefined,
|
|
page,
|
|
size: PAGE_SIZE
|
|
};
|
|
|
|
// The "Zu prüfen (N)" link count is the totalElements of a provisional-only query. A size=1
|
|
// page keeps the extra request cheap — we only need the count, not the rows.
|
|
const [personsResult, statsResult, reviewCountResult] = await Promise.all([
|
|
api.GET('/api/persons', { params: { query: filters } }),
|
|
api.GET('/api/stats', {}),
|
|
canWrite
|
|
? api.GET('/api/persons', { params: { query: { provisional: true, review: true, size: 1 } } })
|
|
: Promise.resolve(null)
|
|
]);
|
|
|
|
if (!personsResult.response.ok) {
|
|
throw error(personsResult.response.status, getErrorMessage(undefined));
|
|
}
|
|
|
|
const result = personsResult.data!;
|
|
|
|
const stats = statsResult.response.ok
|
|
? {
|
|
totalPersons: statsResult.data!.totalPersons ?? 0,
|
|
totalDocuments: statsResult.data!.totalDocuments ?? 0
|
|
}
|
|
: { totalPersons: 0, totalDocuments: 0 };
|
|
|
|
const needsReviewCount =
|
|
reviewCountResult && reviewCountResult.response.ok
|
|
? (reviewCountResult.data!.totalElements ?? 0)
|
|
: 0;
|
|
|
|
return {
|
|
persons: result.items,
|
|
totalElements: result.totalElements,
|
|
totalPages: result.totalPages,
|
|
pageNumber: result.pageNumber,
|
|
pageSize: result.pageSize,
|
|
filters: { type, familyOnly, hasDocuments, review },
|
|
needsReviewCount,
|
|
stats,
|
|
q,
|
|
canWrite
|
|
};
|
|
}
|