feat(transcription): add block-level comment threads with quote support
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 1m33s
CI / Backend Unit Tests (pull_request) Failing after 2m47s
CI / E2E Tests (pull_request) Failing after 19m44s

TranscriptionBlock.svelte:
- "Kommentieren" button opens expandable comment thread per block
- Text selection in textarea captured as quoted text (> "...") prefix
- Quote hint "Text markieren für Zitat" shown when block is active/focused
- Comment thread uses existing CommentThread with blockId prop

CommentThread.svelte:
- Add blockId prop for block-level comments URL routing
- Add quotedText prop — pre-fills comment input with markdown blockquote
- commentsBase now supports 3 URL patterns: document, annotation, block

TranscriptionEditView.svelte:
- Pass canComment + currentUserId through to block components

3 new frontend tests:
- Kommentieren button present
- Quote hint shown when active
- Quote hint hidden when inactive

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-05 21:05:39 +02:00
parent da43cadb0a
commit 8c26876345
5 changed files with 126 additions and 6 deletions

View File

@@ -9,24 +9,28 @@ import type { MentionDTO } from '$lib/types';
type Props = {
documentId: string;
annotationId?: string | null;
blockId?: string | null;
initialComments?: Comment[];
loadOnMount?: boolean;
canComment: boolean;
currentUserId: string | null;
canAdmin: boolean;
targetCommentId?: string | null;
quotedText?: string | null;
onCountChange?: (count: number) => void;
};
let {
documentId,
annotationId = null,
blockId = null,
initialComments = [],
loadOnMount = false,
canComment,
currentUserId,
canAdmin,
targetCommentId = null,
quotedText = null,
onCountChange
}: Props = $props();
@@ -43,11 +47,20 @@ let replyMentionCandidates: MentionDTO[] = $state([]);
let editMentionCandidates: MentionDTO[] = $state([]);
const commentsBase = $derived(
annotationId
? `/api/documents/${documentId}/annotations/${annotationId}/comments`
: `/api/documents/${documentId}/comments`
blockId
? `/api/documents/${documentId}/transcription-blocks/${blockId}/comments`
: annotationId
? `/api/documents/${documentId}/annotations/${annotationId}/comments`
: `/api/documents/${documentId}/comments`
);
// Pre-fill comment box with quoted text when selection changes
$effect(() => {
if (quotedText && quotedText.trim()) {
newText = `> "${quotedText}"\n\n`;
}
});
function timeAgo(iso: string): string {
const diff = Date.now() - new Date(iso).getTime();
const minutes = Math.floor(diff / 60000);