diff --git a/frontend/src/lib/components/AnnotateHintStrip.svelte b/frontend/src/lib/components/AnnotateHintStrip.svelte deleted file mode 100644 index e3ea7ab6..00000000 --- a/frontend/src/lib/components/AnnotateHintStrip.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - -{#if annotateMode} - -{/if} diff --git a/frontend/src/lib/components/AnnotateHintStrip.svelte.spec.ts b/frontend/src/lib/components/AnnotateHintStrip.svelte.spec.ts deleted file mode 100644 index 80f72c13..00000000 --- a/frontend/src/lib/components/AnnotateHintStrip.svelte.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { describe, it, expect, afterEach } from 'vitest'; -import { cleanup, render } from 'vitest-browser-svelte'; -import { page } from 'vitest/browser'; -import AnnotateHintStrip from './AnnotateHintStrip.svelte'; - -afterEach(cleanup); - -describe('AnnotateHintStrip', () => { - it('is absent from the DOM when annotateMode is false', async () => { - render(AnnotateHintStrip, { annotateMode: false }); - const strip = page.getByTestId('annotate-hint-strip'); - await expect.element(strip).not.toBeInTheDocument(); - }); - - it('is present in the DOM when annotateMode is true', async () => { - render(AnnotateHintStrip, { annotateMode: true }); - const strip = page.getByTestId('annotate-hint-strip'); - await expect.element(strip).toBeInTheDocument(); - }); - - it('has hidden md:flex class to hide below 768px', async () => { - render(AnnotateHintStrip, { annotateMode: true }); - const strip = page.getByTestId('annotate-hint-strip'); - await expect.element(strip).toHaveClass('hidden'); - await expect.element(strip).toHaveClass('md:flex'); - }); -}); diff --git a/frontend/src/lib/components/AnnotationCommentPanel.svelte b/frontend/src/lib/components/AnnotationCommentPanel.svelte deleted file mode 100644 index d863e4a1..00000000 --- a/frontend/src/lib/components/AnnotationCommentPanel.svelte +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - -
- - - - -
-
-

- {m.comment_panel_title()} -

- -
-
- -
-
-
diff --git a/frontend/src/lib/components/AnnotationSidePanel.svelte b/frontend/src/lib/components/AnnotationSidePanel.svelte deleted file mode 100644 index 28d292e4..00000000 --- a/frontend/src/lib/components/AnnotationSidePanel.svelte +++ /dev/null @@ -1,68 +0,0 @@ - - -
- -
- - {m.doc_panel_discussion_annotation_tab({ page: String(activeAnnotationPage ?? '?') })} - - -
- - -
- {#if activeAnnotationId} - {#key activeAnnotationId} - - {/key} - {/if} -
-
diff --git a/frontend/src/lib/components/AnnotationSidePanel.svelte.spec.ts b/frontend/src/lib/components/AnnotationSidePanel.svelte.spec.ts deleted file mode 100644 index 84745470..00000000 --- a/frontend/src/lib/components/AnnotationSidePanel.svelte.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { describe, it, expect, vi, afterEach } from 'vitest'; -import { cleanup, render } from 'vitest-browser-svelte'; -import { page } from 'vitest/browser'; -import AnnotationSidePanel from './AnnotationSidePanel.svelte'; - -afterEach(() => { - cleanup(); - vi.restoreAllMocks(); -}); - -vi.stubGlobal( - 'fetch', - vi.fn().mockResolvedValue({ - ok: true, - json: async () => [] - }) -); - -const baseProps = { - documentId: 'doc-1', - activeAnnotationPage: 1, - canComment: true, - currentUserId: 'user-1', - canAdmin: false, - onClose: vi.fn() -}; - -describe('AnnotationSidePanel – visibility', () => { - it('is hidden (translated off-screen) when activeAnnotationId is null', async () => { - render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: null }); - const panel = document.querySelector('[data-testid="annotation-side-panel"]'); - expect(panel?.classList.contains('translate-x-full')).toBe(true); - expect(panel?.classList.contains('translate-x-0')).toBe(false); - }); - - it('is visible when activeAnnotationId is set', async () => { - render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: 'ann-1' }); - const panel = document.querySelector('[data-testid="annotation-side-panel"]'); - expect(panel?.classList.contains('translate-x-0')).toBe(true); - expect(panel?.classList.contains('translate-x-full')).toBe(false); - }); -}); - -describe('AnnotationSidePanel – close button', () => { - it('calls onClose when the close button is clicked', async () => { - const onClose = vi.fn(); - render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: 'ann-1', onClose }); - await page.getByRole('button', { name: /schließen/i }).click(); - expect(onClose).toHaveBeenCalledOnce(); - }); -}); - -describe('AnnotationSidePanel – targetCommentId forwarding', () => { - it('renders CommentThread when annotation is active', async () => { - render(AnnotationSidePanel, { - ...baseProps, - activeAnnotationId: 'ann-1', - targetCommentId: 'comment-42' - }); - // CommentThread renders inside the panel when activeAnnotationId is set - const panel = document.querySelector('[data-testid="annotation-side-panel"]'); - expect(panel).not.toBeNull(); - expect(panel?.classList.contains('translate-x-0')).toBe(true); - }); - - it('does not render CommentThread when annotation is null', async () => { - render(AnnotationSidePanel, { - ...baseProps, - activeAnnotationId: null, - targetCommentId: 'comment-42' - }); - // Panel is hidden and no fetch should have been triggered for comments - const panel = document.querySelector('[data-testid="annotation-side-panel"]'); - expect(panel?.classList.contains('translate-x-full')).toBe(true); - }); -}); diff --git a/frontend/src/lib/components/CommentThread.svelte b/frontend/src/lib/components/CommentThread.svelte index 4a1a4b13..f8e5495d 100644 --- a/frontend/src/lib/components/CommentThread.svelte +++ b/frontend/src/lib/components/CommentThread.svelte @@ -1,7 +1,7 @@ - -{#snippet commentEntry(comment: Comment | CommentReply, threadId: string, showReplyButton: boolean)} - {#if editingId === comment.id} -
- saveEdit(comment.id)} - /> -
- - -
-
- {:else} -
-
-
- {comment.authorName} - {#if wasEdited(comment)} - {timeAgo(comment.updatedAt)} {m.comment_edited_label()} - {:else} - {timeAgo(comment.createdAt)} - {/if} -
-

- - {@html renderBody(comment.content, comment.mentionDTOs ?? [])} -

-
- {#if canModify(comment)} -
- - -
- {/if} -
- {#if showReplyButton && canComment} -
- -
- {/if} - {/if} -{/snippet} - -
- {#each comments as thread, ti (thread.id)} -
0 ? 'border-t border-line pt-4' : ''}> - -
0} +
+
+ - {@render commentEntry(thread, thread.id, thread.replies.length === 0)} -
+ + + {flatMessages.length} + {flatMessages.length === 1 ? 'Kommentar' : 'Kommentare'} +
- - {#each thread.replies as reply, ri (reply.id)} -
- {@render commentEntry(reply, thread.id, ri === thread.replies.length - 1)} -
- {/each} - - - {#if replyingTo === thread.id} -
- postReply(thread.id)} - /> -
- - +
+ {#each flatMessages as msg (msg.id)} + {@const parsed = extractQuote(msg.content)} +
+
+ {getInitials(msg.authorName)} +
+
+
+ {msg.authorName} + {#if wasEdited(msg)} + {timeAgo(msg.updatedAt)} {m.comment_edited_label()} + {:else} + {timeAgo(msg.createdAt)} + {/if} +
+ {#if parsed.quote} +
+ “{parsed.quote}” +
+ {/if} +

+ + {@html renderBody(parsed.body, msg.mentionDTOs ?? [])} +

- {/if} + {/each}
- {/each} +
+{/if} - - {#if canComment && showCompose} -
0 ? 'border-t border-line pt-4' : ''}> -
- -
- -
-
+{#if canComment && showCompose} +
+
+
- {/if} -
+ +
+{/if} diff --git a/frontend/src/lib/components/PanelDiscussion.svelte b/frontend/src/lib/components/PanelDiscussion.svelte deleted file mode 100644 index 40d9af39..00000000 --- a/frontend/src/lib/components/PanelDiscussion.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - -
- -
diff --git a/frontend/src/lib/components/PanelHistory.svelte b/frontend/src/lib/components/PanelHistory.svelte deleted file mode 100644 index 2be6f7aa..00000000 --- a/frontend/src/lib/components/PanelHistory.svelte +++ /dev/null @@ -1,519 +0,0 @@ - - -
- {#if historyLoading} -

{m.history_loading()}

- {:else if !historyLoaded} - - {:else if versions.length === 0} -

{m.history_empty()}

- {:else} - -
- -
- - {#if compareMode} -
-
- - -
-
- - -
- -
- - - {#if diffLoading} -

{m.history_loading()}

- {:else if noDiff} -
- {m.history_diff_no_changes()} -
- {:else if diffEntries.length > 0} -
- {#each diffEntries as entry (entry.field)} -
- {entry.label} - {#if entry.kind === 'text'} -

- {#each entry.parts as part, partIdx (partIdx)} - {#if part.added} - {part.value} - {:else if part.removed} - {part.value} - {:else} - {part.value} - {/if} - {/each} -

- {:else if entry.kind === 'scalar'} -
- {entry.oldVal || '—'} - - {entry.newVal || '—'} -
- {:else if entry.kind === 'relation'} -
- {#each entry.removed as item (item)} - {item} - {/each} - {#each entry.added as item (item)} - {item} - {/each} -
- {/if} -
- {/each} -
- {/if} - {:else} - -
    - {#each versions as v, i (v.id)} -
  • - - - - {#if selectedVersionId === v.id} - {#if diffLoading} -

    {m.history_loading()}

    - {:else if noDiff} -
    - {m.history_diff_no_changes()} -
    - {:else if diffEntries.length > 0} -
    - {#each diffEntries as entry (entry.field)} -
    - {entry.label} - {#if entry.kind === 'text'} -

    - {#each entry.parts as part, partIdx (partIdx)} - {#if part.added} - {part.value} - {:else if part.removed} - {part.value} - {:else} - {part.value} - {/if} - {/each} -

    - {:else if entry.kind === 'scalar'} -
    - {entry.oldVal || '—'} - - {entry.newVal || '—'} -
    - {:else if entry.kind === 'relation'} -
    - {#each entry.removed as item (item)} - {item} - {/each} - {#each entry.added as item (item)} - {item} - {/each} -
    - {/if} -
    - {/each} -
    - {/if} - {/if} -
  • - {/each} -
- {/if} - {/if} -
diff --git a/frontend/src/lib/components/PanelMetadata.svelte b/frontend/src/lib/components/PanelMetadata.svelte deleted file mode 100644 index f8c2719c..00000000 --- a/frontend/src/lib/components/PanelMetadata.svelte +++ /dev/null @@ -1,198 +0,0 @@ - - -
- -
-

- {m.doc_section_details()} -

-
- -
- - - -
- - {doc.documentDate ? formatDate(doc.documentDate) : '—'} - - {m.doc_label_document_date()} -
-
- - -
- - - -
- - {doc.location ? doc.location : '—'} - - {m.doc_label_creation_location()} -
-
- - - {#if doc.documentLocation} -
- - - -
- - {doc.documentLocation} - - {m.doc_label_archive_location_original()} -
-
- {/if} - - - {#if doc.tags && doc.tags.length > 0} -
- - - -
-
- {#each doc.tags as tag (tag.id)} - - {tag.name} - - {/each} -
- {m.form_label_tags()} -
-
- {/if} -
-
- - -
-

- {m.doc_section_persons()} -

- - - -
- {m.form_label_receivers()} - {#if doc.receivers && doc.receivers.length > 0} -
- {#each doc.receivers as receiver (receiver.id)} - - {/each} -
- {:else} - {m.doc_no_receivers()} - {/if} -
-
-
diff --git a/frontend/src/lib/components/PanelTranscription.svelte b/frontend/src/lib/components/PanelTranscription.svelte deleted file mode 100644 index d8bc79a8..00000000 --- a/frontend/src/lib/components/PanelTranscription.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - -
-
- {#if !doc.summary && !doc.transcription} -

- {/if} - - {#if doc.summary} -
- - {m.doc_label_summary()} - -

{doc.summary}

-
- {/if} - - {#if doc.transcription} -
- - {m.form_label_transcription()} - -

- {doc.transcription} -

-
- {/if} -
-
diff --git a/frontend/src/lib/components/TranscriptionBlock.svelte b/frontend/src/lib/components/TranscriptionBlock.svelte index dd7caf05..371401b4 100644 --- a/frontend/src/lib/components/TranscriptionBlock.svelte +++ b/frontend/src/lib/components/TranscriptionBlock.svelte @@ -13,7 +13,6 @@ type Props = { active: boolean; saveState: SaveState; canComment: boolean; - currentUserId: string | null; onTextChange: (text: string) => void; onFocus: () => void; onDeleteClick: () => void; @@ -29,7 +28,6 @@ let { active, saveState, canComment, - currentUserId, onTextChange, onFocus, onDeleteClick, @@ -204,8 +202,6 @@ function captureSelectionAndOpenComments() { blockId={blockId} loadOnMount={true} canComment={canComment} - currentUserId={currentUserId} - canAdmin={false} quotedText={selectedQuote} showCompose={commentOpen} /> diff --git a/frontend/src/lib/components/TranscriptionBlock.svelte.spec.ts b/frontend/src/lib/components/TranscriptionBlock.svelte.spec.ts index 7489ed52..6a166861 100644 --- a/frontend/src/lib/components/TranscriptionBlock.svelte.spec.ts +++ b/frontend/src/lib/components/TranscriptionBlock.svelte.spec.ts @@ -15,7 +15,6 @@ function renderBlock(overrides: Record = {}) { active: false, saveState: 'idle' as const, canComment: true, - currentUserId: 'user-1', onTextChange: vi.fn(), onFocus: vi.fn(), onDeleteClick: vi.fn(), diff --git a/frontend/src/lib/components/TranscriptionEditView.svelte b/frontend/src/lib/components/TranscriptionEditView.svelte index 4bb02688..cdcc4b67 100644 --- a/frontend/src/lib/components/TranscriptionEditView.svelte +++ b/frontend/src/lib/components/TranscriptionEditView.svelte @@ -10,21 +10,12 @@ type Props = { documentId: string; blocks: TranscriptionBlockData[]; canComment: boolean; - currentUserId: string | null; onBlockFocus: (blockId: string) => void; onSaveBlock: (blockId: string, text: string) => Promise; onDeleteBlock: (blockId: string) => Promise; }; -let { - documentId, - blocks, - canComment, - currentUserId, - onBlockFocus, - onSaveBlock, - onDeleteBlock -}: Props = $props(); +let { documentId, blocks, canComment, onBlockFocus, onSaveBlock, onDeleteBlock }: Props = $props(); let activeBlockId: string | null = $state(null); let saveStates = new SvelteMap(); @@ -165,7 +156,6 @@ $effect(() => { active={activeBlockId === block.id} saveState={getSaveState(block.id)} canComment={canComment} - currentUserId={currentUserId} onTextChange={(text) => handleTextChange(block.id, text)} onFocus={() => handleFocus(block.id)} onDeleteClick={() => handleDelete(block.id)} diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index 7864ce00..27dd403c 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -9,7 +9,6 @@ let { data } = $props(); const doc = $derived(data.document); const canWrite = $derived(data.canWrite ?? false); -const currentUserId = $derived((data.user?.id as string | undefined) ?? null); // ── File loading ────────────────────────────────────────────────────────────── @@ -218,7 +217,6 @@ onMount(() => { documentId={doc.id} blocks={transcriptionBlocks} canComment={canWrite} - currentUserId={currentUserId} onBlockFocus={handleBlockFocus} onSaveBlock={saveBlock} onDeleteBlock={deleteBlock}