refactor(types): extract shared types to \$lib/types.ts
Some checks failed
CI / Unit & Component Tests (pull_request) Successful in 2m22s
CI / Backend Unit Tests (pull_request) Successful in 2m16s
CI / E2E Tests (pull_request) Failing after 31m23s
CI / Unit & Component Tests (push) Successful in 2m24s
CI / Backend Unit Tests (push) Successful in 2m6s
CI / E2E Tests (push) Failing after 30m19s

Eliminates type duplication across 6 files by introducing a single
shared types module:

- Comment + CommentReply: were identically defined in CommentThread,
  PanelDiscussion, and DocumentBottomPanel
- DocumentPanelTab: was identically defined in DocumentBottomPanel
  and documents/[id]/+page.svelte
- Annotation: was defined in both AnnotationLayer and PdfViewer
  (PdfViewer's variant with fileHash? is now the canonical definition)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #76.
This commit is contained in:
Marcel
2026-03-26 12:47:08 +01:00
parent 40f01a7712
commit 2bfbf45eba
7 changed files with 44 additions and 90 deletions

View File

@@ -1,15 +1,5 @@
<script lang="ts">
type Annotation = {
id: string;
documentId: string;
pageNumber: number;
x: number;
y: number;
width: number;
height: number;
color: string;
createdAt: string;
};
import type { Annotation } from '$lib/types';
type DrawRect = {
x: number;

View File

@@ -1,25 +1,7 @@
<script lang="ts">
import { onMount, untrack } from 'svelte';
import { m } from '$lib/paraglide/messages.js';
type CommentReply = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
};
type Comment = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
replies: CommentReply[];
};
import type { Comment, CommentReply } from '$lib/types';
type Props = {
documentId: string;

View File

@@ -4,27 +4,7 @@ import PanelMetadata from './PanelMetadata.svelte';
import PanelTranscription from './PanelTranscription.svelte';
import PanelDiscussion from './PanelDiscussion.svelte';
import PanelHistory from './PanelHistory.svelte';
type Tab = 'metadata' | 'transcription' | 'discussion' | 'history';
type CommentReply = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
};
type Comment = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
replies: CommentReply[];
};
import type { Comment, DocumentPanelTab } from '$lib/types';
type Doc = {
id: string;
@@ -47,7 +27,7 @@ type Props = {
canAdmin: boolean;
open: boolean;
height: number;
activeTab: Tab;
activeTab: DocumentPanelTab;
};
let {
@@ -72,7 +52,7 @@ function fullHeight() {
return window.innerHeight - (topbar?.getBoundingClientRect().bottom ?? 0);
}
function openTab(tab: Tab) {
function openTab(tab: DocumentPanelTab) {
activeTab = tab;
if (!open) {
open = true;
@@ -110,7 +90,7 @@ function onDragEnd() {
isDragging = false;
}
const tabs: { id: Tab; label: () => string }[] = [
const tabs: { id: DocumentPanelTab; label: () => string }[] = [
{ id: 'metadata', label: m.doc_panel_tab_metadata },
{ id: 'transcription', label: m.doc_panel_tab_transcription },
{ id: 'discussion', label: m.doc_panel_tab_discussion },

View File

@@ -1,24 +1,6 @@
<script lang="ts">
import CommentThread from './CommentThread.svelte';
type CommentReply = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
};
type Comment = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
replies: CommentReply[];
};
import type { Comment } from '$lib/types';
type Props = {
documentId: string;

View File

@@ -3,6 +3,7 @@ import { onMount } from 'svelte';
import { SvelteMap } from 'svelte/reactivity';
import type { PDFDocumentProxy, PDFPageProxy, RenderTask } from 'pdfjs-dist';
import AnnotationLayer from './AnnotationLayer.svelte';
import type { Annotation } from '$lib/types';
import { m } from '$lib/paraglide/messages.js';
let {
@@ -43,19 +44,6 @@ let textLayerInstance: { cancel: () => void } | null = null;
let pdfjsLib: typeof import('pdfjs-dist') | null = null;
let pdfjsReady = $state(false);
type Annotation = {
id: string;
documentId: string;
pageNumber: number;
x: number;
y: number;
width: number;
height: number;
color: string;
createdAt: string;
fileHash?: string | null;
};
let annotations = $state<Annotation[]>([]);
let annotateColor = $state('#ffff00');
let commentCounts = new SvelteMap<string, number>();

33
frontend/src/lib/types.ts Normal file
View File

@@ -0,0 +1,33 @@
export type CommentReply = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
};
export type Comment = {
id: string;
authorId: string | null;
authorName: string;
content: string;
createdAt: string;
updatedAt: string;
replies: CommentReply[];
};
export type DocumentPanelTab = 'metadata' | 'transcription' | 'discussion' | 'history';
export type Annotation = {
id: string;
documentId: string;
pageNumber: number;
x: number;
y: number;
width: number;
height: number;
color: string;
createdAt: string;
fileHash?: string | null;
};

View File

@@ -4,8 +4,7 @@ import DocumentTopBar from '$lib/components/DocumentTopBar.svelte';
import DocumentViewer from '$lib/components/DocumentViewer.svelte';
import DocumentBottomPanel from '$lib/components/DocumentBottomPanel.svelte';
import AnnotationSidePanel from '$lib/components/AnnotationSidePanel.svelte';
type Tab = 'metadata' | 'transcription' | 'discussion' | 'history';
import type { DocumentPanelTab } from '$lib/types';
let { data } = $props();
@@ -72,7 +71,7 @@ const LS_KEY_TAB = 'doc-panel-tab';
let panelOpen = $state(false);
let panelHeight = $state(0); // set to full height on mount
let navHeight = $state(0);
let activeTab = $state<Tab>('metadata');
let activeTab = $state<DocumentPanelTab>('metadata');
let localStorageRestored = $state(false);
onMount(() => {
@@ -82,7 +81,7 @@ onMount(() => {
const savedTab = localStorage.getItem(LS_KEY_TAB);
if (savedTab && ['metadata', 'transcription', 'discussion', 'history'].includes(savedTab)) {
activeTab = savedTab as Tab;
activeTab = savedTab as DocumentPanelTab;
}
const topbar = document.querySelector('[data-topbar]');
panelHeight = window.innerHeight - navHeight - (topbar?.getBoundingClientRect().height ?? 0);