feat(stammbaum): show inferred relationship in the document drawer
- New presentational RelationshipBadge component (labelFromA → arrow → labelFromB) wired into DocumentMetadataDrawer's Personen column, rendered after the receivers block when both endpoints are family members. - DocumentTopBar gains an optional inferredRelationship prop and passes it through. - documents/[id]/+page.server.ts loads the badge: only when sender is a family member, exactly one receiver, and that receiver is also a family member; 404 (no path) → null. - relationshipLabels.ts maps the backend label keys (parent/child/...) to localised strings, so the server load returns badge-ready strings. Refs #358. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { createApiClient } from '$lib/api.server';
|
||||
import { getErrorMessage } from '$lib/errors';
|
||||
import { inferredRelationshipLabel } from '$lib/relationshipLabels';
|
||||
|
||||
export async function load({ params, fetch }) {
|
||||
const { id } = params;
|
||||
@@ -15,5 +16,38 @@ export async function load({ params, fetch }) {
|
||||
throw error(docResult.response.status, getErrorMessage(code));
|
||||
}
|
||||
|
||||
return { document: docResult.data! };
|
||||
const document = docResult.data!;
|
||||
const inferredRelationship = await loadInferredRelationship(api, document);
|
||||
|
||||
return { document, inferredRelationship };
|
||||
}
|
||||
|
||||
async function loadInferredRelationship(
|
||||
api: ReturnType<typeof createApiClient>,
|
||||
document: {
|
||||
sender?: { id: string; familyMember?: boolean } | null;
|
||||
receivers?: { id: string; familyMember?: boolean }[];
|
||||
}
|
||||
): Promise<{ labelFromA: string; labelFromB: string } | null> {
|
||||
const sender = document.sender;
|
||||
const receivers = document.receivers ?? [];
|
||||
|
||||
// The badge is shown only when both endpoints are family members and the
|
||||
// document has exactly one receiver.
|
||||
if (!sender?.familyMember) return null;
|
||||
if (receivers.length !== 1) return null;
|
||||
const receiver = receivers[0];
|
||||
if (!receiver?.familyMember) return null;
|
||||
|
||||
const result = await api.GET('/api/persons/{aId}/relationship-to/{bId}', {
|
||||
params: { path: { aId: sender.id, bId: receiver.id } }
|
||||
});
|
||||
|
||||
if (result.response.status === 404) return null;
|
||||
if (!result.response.ok || !result.data) return null;
|
||||
|
||||
return {
|
||||
labelFromA: inferredRelationshipLabel(result.data.labelFromA),
|
||||
labelFromB: inferredRelationshipLabel(result.data.labelFromB)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -395,6 +395,7 @@ onMount(() => {
|
||||
canWrite={canWrite}
|
||||
fileUrl={fileLoader.fileUrl}
|
||||
bind:transcribeMode={transcribeMode}
|
||||
inferredRelationship={data.inferredRelationship}
|
||||
/>
|
||||
|
||||
<div class="relative flex-1 overflow-hidden {transcribeMode ? 'flex flex-col md:flex-row' : ''}">
|
||||
|
||||
Reference in New Issue
Block a user