refactor(frontend): restructure lib/ from flat-by-type to domain-based (#408) #422

Merged
marcel merged 16 commits from feat/issue-408-frontend-lib-domains into main 2026-05-05 15:32:09 +02:00
389 changed files with 466 additions and 434 deletions

View File

@@ -42,7 +42,7 @@ jobs:
- name: Upload screenshots
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: unit-test-screenshots
path: frontend/test-results/screenshots/

View File

@@ -35,24 +35,40 @@ src/
│ ├── api/ # Internal API proxies (server-side only)
│ ├── login/ logout/ # Auth pages
│ └── ...
├── lib/
│ ├── components/ # Reusable Svelte components
│ │ ├── document/ # Document-specific components
│ │ ├── chronik/ # Activity feed components
│ │ └── user/ # User-related components
├── lib/ # Domain-based package structure (mirrors backend)
│ ├── document/ # Document domain: components, stores, services, utils
│ │ ├── annotation/ # Annotation overlay components
│ │ ├── comment/ # Comment thread components
│ │ └── transcription/ # Transcription editor + block logic
│ ├── person/ # Person domain: chips, typeahead, avatar, format
│ │ ├── relationship/ # Relationship form + chip components
│ │ └── genealogy/ # Stammbaum (family tree) components
│ ├── tag/ # Tag domain: TagInput, TagChipList, TagParentPicker
│ ├── geschichte/ # Geschichte (story) domain: editor + card
│ ├── notification/ # Notification bell + dropdown + store
│ ├── activity/ # Activity feed (Chronik) components
│ ├── conversation/ # Bilateral conversation (Briefwechsel) components
│ ├── ocr/ # OCR progress, training cards, trigger
│ ├── user/ # User profile/password/groups section components
│ ├── shared/ # Cross-domain utilities and primitives
│ │ ├── actions/ # Svelte actions (clickOutside, etc.)
│ │ ├── hooks/ # Reusable Svelte state hooks (useTypeahead, etc.)
│ │ ├── server/ # Server-only utilities (locale, session)
│ │ ├── services/ # Client-side service helpers
│ │ ├── utils/ # Pure utility functions (date, search, etc.)
│ │ ├── primitives/ # Generic UI primitives (BackButton, ProgressRing, etc.)
│ │ ├── dashboard/ # Dashboard stat components
│ │ ├── discussion/ # CommentThread + shared discussion UI
│ │ ├── help/ # Help/FAQ page components
│ │ ├── api.server.ts # Typed API client factory
│ │ ├── errors.ts # Error code mapping (mirrors backend ErrorCode)
│ │ ├── types.ts # Shared TypeScript types
│ │ ├── relativeTime.ts # Relative time formatting
│ │ └── utils.ts # Top-level shared utilities
│ ├── generated/ # Auto-generated API types (openapi-typescript)
│ ├── server/ # Server-only utilities (db, auth helpers)
│ ├── services/ # Client-side service logic
│ ├── stores/ # Svelte stores (global state)
│ ├── types.ts # Shared TypeScript types
│ ├── errors.ts # Error code mapping (mirrors backend ErrorCode)
│ ├── api.server.ts # Typed API client factory
│ ├── utils.ts # Shared utilities
│ ├── relativeTime.ts # Time formatting
│ ├── search.ts # Search utilities
│ └── paraglide/ # Generated i18n code
├── hooks/ # SvelteKit hooks (handle, handleFetch)
└── actions/ # Custom Svelte actions (click outside, etc.)
└── ... # Other SvelteKit config files
```
## API Client Pattern
@@ -130,14 +146,15 @@ Card pattern for content sections:
## Key UI Components
| Component | Props | Description |
| -------------------- | ---------------------------------------------------- | ------------------------------------- |
| `PersonTypeahead` | `name`, `label`, `value`, `initialName`, `on:change` | Single-person selector with typeahead |
| `PersonMultiSelect` | `selectedPersons` (bind) | Chip-based multi-person selector |
| `TagInput` | `tags` (bind), `allowCreation?`, `on:change` | Tag chip input with typeahead |
| `PdfViewer` | `url`, `annotations`, `on:annotation` | PDF rendering with annotation overlay |
| `TranscriptionBlock` | `block`, `mode` | Read/edit transcription block |
| `DocumentTopBar` | `document` | Responsive document metadata header |
| Component | Location | Props | Description |
| -------------------- | ------------------------------ | --------------------------------------- | ------------------------------------------ |
| `PersonTypeahead` | `$lib/person/` | `name`, `label`, `value`, `initialName` | Single-person selector with typeahead |
| `PersonMultiSelect` | `$lib/person/` | `selectedPersons` (bind) | Chip-based multi-person selector |
| `TagInput` | `$lib/tag/` | `tags` (bind), `allowCreation?` | Tag chip input with typeahead |
| `PdfViewer` | `$lib/document/` | `url`, `annotations` | PDF rendering with annotation overlay |
| `TranscriptionBlock` | `$lib/document/transcription/` | `block`, `mode` | Read/edit transcription block |
| `DocumentTopBar` | `$lib/document/` | `document` | Responsive document metadata header |
| `BackButton` | `$lib/shared/primitives/` | — | Calls `history.back()`; 44 px touch target |
## How to Run

View File

@@ -3,7 +3,7 @@ import { paraglideMiddleware } from '$lib/paraglide/server';
import { sequence } from '@sveltejs/kit/hooks';
import { env } from 'process';
import { cookieName, cookieMaxAge } from '$lib/paraglide/runtime';
import { detectLocale } from '$lib/server/locale';
import { detectLocale } from '$lib/shared/server/locale';
const PUBLIC_PATHS = ['/login', '/logout', '/forgot-password', '/reset-password', '/register'];

View File

@@ -1,8 +1,8 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { relativeTime } from '$lib/utils/time';
import type { NotificationItem } from '$lib/stores/notifications.svelte';
import { buildCommentHref } from '$lib/utils/commentDeepLink';
import { relativeTime } from '$lib/shared/utils/time';
import type { NotificationItem } from '$lib/notification/notifications.svelte';
import { buildCommentHref } from '$lib/shared/discussion/commentDeepLink';
interface Props {
unread: NotificationItem[];

View File

@@ -3,7 +3,7 @@ import { cleanup, render } from 'vitest-browser-svelte';
import { page, userEvent } from 'vitest/browser';
import ChronikFuerDichBox from './ChronikFuerDichBox.svelte';
import type { NotificationItem } from '$lib/stores/notifications.svelte';
import type { NotificationItem } from '$lib/notification/notifications.svelte';
afterEach(cleanup);

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { relativeTime } from '$lib/utils/time';
import { buildCommentHref } from '$lib/utils/commentDeepLink';
import { relativeTime } from '$lib/shared/utils/time';
import { buildCommentHref } from '$lib/shared/discussion/commentDeepLink';
import type { components } from '$lib/generated/api';
type ActivityFeedItemDTO = components['schemas']['ActivityFeedItemDTO'];

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { bucketByDay, type DayBucket } from '$lib/utils/date-buckets';
import { bucketByDay, type DayBucket } from '$lib/shared/utils/date-buckets';
import type { components } from '$lib/generated/api';
import ChronikRow from './ChronikRow.svelte';

View File

@@ -3,9 +3,9 @@ import { SvelteMap } from 'svelte/reactivity';
import { goto } from '$app/navigation';
import { onDestroy, onMount, untrack } from 'svelte';
import { m } from '$lib/paraglide/messages.js';
import { getConfirmService } from '$lib/services/confirm.svelte.js';
import type { ConfirmService } from '$lib/services/confirm.svelte.js';
import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
import { getConfirmService } from '$lib/shared/services/confirm.svelte.js';
import type { ConfirmService } from '$lib/shared/services/confirm.svelte.js';
import { bulkSelectionStore } from '$lib/document/bulkSelection.svelte';
import BulkDropZone from './BulkDropZone.svelte';
import FileSwitcherStrip from './FileSwitcherStrip.svelte';
import type { FileEntry } from './FileSwitcherStrip.svelte';
@@ -13,9 +13,9 @@ import ScopeCard from './ScopeCard.svelte';
import UploadSaveBar from './UploadSaveBar.svelte';
import WhoWhenSection from './WhoWhenSection.svelte';
import DescriptionSection from './DescriptionSection.svelte';
import PdfViewer from '$lib/components/PdfViewer.svelte';
import { bulkTitleFromFilename } from '$lib/utils/filename';
import type { Tag } from '$lib/components/TagInput.svelte';
import PdfViewer from '$lib/document/viewer/PdfViewer.svelte';
import { bulkTitleFromFilename } from '$lib/document/filename';
import type { Tag } from '$lib/tag/TagInput.svelte';
import type { components } from '$lib/generated/api';
type Person = components['schemas']['Person'];

View File

@@ -317,7 +317,7 @@ describe('BulkDocumentEditLayout', () => {
describe('BulkDocumentEditLayout — mode="edit" discard', () => {
it('discard in edit mode clears the selection store and navigates back to /documents', async () => {
const { bulkSelectionStore } = await import('$lib/stores/bulkSelection.svelte');
const { bulkSelectionStore } = await import('$lib/document/bulkSelection.svelte');
bulkSelectionStore.setAll(['doc-1']);
const { container } = render(BulkDocumentEditLayout, {

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { m } from '$lib/paraglide/messages.js';
import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
import { bulkSelectionStore } from '$lib/document/bulkSelection.svelte';
let { canWrite }: { canWrite: boolean } = $props();

View File

@@ -3,7 +3,7 @@ import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import { goto } from '$app/navigation';
import BulkSelectionBar from './BulkSelectionBar.svelte';
import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
import { bulkSelectionStore } from '$lib/document/bulkSelection.svelte';
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { relativeTimeDe } from '$lib/relativeTime';
import { relativeTimeDe } from '$lib/shared/relativeTime';
type IncompleteDoc = {
id: string;

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import TagInput, { type Tag } from '$lib/components/TagInput.svelte';
import TagInput, { type Tag } from '$lib/tag/TagInput.svelte';
import FieldLabelBadge from './FieldLabelBadge.svelte';
import { m } from '$lib/paraglide/messages.js';

View File

@@ -3,15 +3,15 @@ import { enhance } from '$app/forms';
import { invalidate } from '$app/navigation';
import { onMount, onDestroy, untrack } from 'svelte';
import type { Snippet } from 'svelte';
import { createFileLoader } from '$lib/hooks/useFileLoader.svelte';
import { createFileLoader } from '$lib/document/viewer/useFileLoader.svelte';
import { m } from '$lib/paraglide/messages.js';
import { countRequiredFilled } from '$lib/utils/requiredFields';
import { validateFile } from '$lib/utils/validateFile';
import DocumentViewer from '$lib/components/DocumentViewer.svelte';
import UploadZone from '$lib/components/document/UploadZone.svelte';
import WhoWhenSection from '$lib/components/document/WhoWhenSection.svelte';
import DescriptionSection from '$lib/components/document/DescriptionSection.svelte';
import type { Tag } from '$lib/components/TagInput.svelte';
import { countRequiredFilled } from '$lib/shared/utils/requiredFields';
import { validateFile } from '$lib/document/validateFile';
import DocumentViewer from '$lib/document/DocumentViewer.svelte';
import UploadZone from '$lib/document/UploadZone.svelte';
import WhoWhenSection from '$lib/document/WhoWhenSection.svelte';
import DescriptionSection from '$lib/document/DescriptionSection.svelte';
import type { Tag } from '$lib/tag/TagInput.svelte';
import type { components } from '$lib/generated/api';
type Person = components['schemas']['Person'];

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import { formatDate } from '$lib/utils/date';
import { formatDocumentStatus } from '$lib/utils/documentStatusLabel';
import { getInitials, personAvatarColor } from '$lib/utils/personFormat';
import RelationshipPill from '$lib/components/RelationshipPill.svelte';
import { formatDate } from '$lib/shared/utils/date';
import { formatDocumentStatus } from '$lib/document/documentStatusLabel';
import { getInitials, personAvatarColor } from '$lib/person/personFormat';
import RelationshipPill from '$lib/person/relationship/RelationshipPill.svelte';
type Person = { id: string; firstName?: string | null; lastName: string; displayName: string };
type Tag = { id: string; name: string };

View File

@@ -1,8 +1,8 @@
<script lang="ts">
import type { components } from '$lib/generated/api';
import { m } from '$lib/paraglide/messages.js';
import { clickOutside } from '$lib/actions/clickOutside';
import { formatDate } from '$lib/utils/date';
import { clickOutside } from '$lib/shared/actions/clickOutside';
import { formatDate } from '$lib/shared/utils/date';
type Document = components['schemas']['Document'];
type DocumentSearchItem = components['schemas']['DocumentSearchItem'];

View File

@@ -1,12 +1,12 @@
<script lang="ts">
import { goto } from '$app/navigation';
import type { components } from '$lib/generated/api';
import { applyOffsets } from '$lib/search';
import { formatDate } from '$lib/utils/date';
import { applyOffsets } from '$lib/document/search';
import { formatDate } from '$lib/shared/utils/date';
import * as m from '$lib/paraglide/messages.js';
import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
import ProgressRing from './ProgressRing.svelte';
import ContributorStack from './ContributorStack.svelte';
import { bulkSelectionStore } from '$lib/document/bulkSelection.svelte';
import ProgressRing from '$lib/shared/primitives/ProgressRing.svelte';
import ContributorStack from '$lib/shared/primitives/ContributorStack.svelte';
import DocumentThumbnail from './DocumentThumbnail.svelte';
type DocumentSearchItem = components['schemas']['DocumentSearchItem'];

View File

@@ -3,7 +3,7 @@ import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import { goto } from '$app/navigation';
import DocumentRow from './DocumentRow.svelte';
import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
import { bulkSelectionStore } from '$lib/document/bulkSelection.svelte';
import type { components } from '$lib/generated/api';
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { statusDotClass, statusLabel } from '$lib/utils/personFormat';
import { statusDotClass, statusLabel } from '$lib/person/personFormat';
type DocumentStatus = 'PLACEHOLDER' | 'UPLOADED' | 'TRANSCRIBED' | 'REVIEWED' | 'ARCHIVED';

View File

@@ -1,12 +1,12 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import { slide } from 'svelte/transition';
import { formatDate } from '$lib/utils/date';
import { clickOutside } from '$lib/actions/clickOutside';
import PersonChipRow from './PersonChipRow.svelte';
import OverflowPillButton from './OverflowPillButton.svelte';
import { formatDate } from '$lib/shared/utils/date';
import { clickOutside } from '$lib/shared/actions/clickOutside';
import PersonChipRow from '$lib/person/PersonChipRow.svelte';
import OverflowPillButton from '$lib/shared/primitives/OverflowPillButton.svelte';
import DocumentMetadataDrawer from './DocumentMetadataDrawer.svelte';
import BackButton from './BackButton.svelte';
import BackButton from '$lib/shared/primitives/BackButton.svelte';
type Person = { id: string; firstName?: string | null; lastName: string; displayName: string };
type Tag = { id: string; name: string };

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import PdfViewer from './PdfViewer.svelte';
import PdfViewer from '$lib/document/viewer/PdfViewer.svelte';
type Doc = {
id: string;

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { getLocale } from '$lib/paraglide/runtime.js';
import { formatMCDate } from '$lib/utils/date.js';
import { formatMCDate } from '$lib/shared/utils/date.js';
import type { components } from '$lib/generated/api';
import ContributorStack from './ContributorStack.svelte';
import ContributorStack from '$lib/shared/primitives/ContributorStack.svelte';
type TranscriptionQueueItemDTO = components['schemas']['TranscriptionQueueItemDTO'];

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { getLocale } from '$lib/paraglide/runtime.js';
import { formatMCDate } from '$lib/utils/date.js';
import { formatMCDate } from '$lib/shared/utils/date.js';
import type { components } from '$lib/generated/api';
import ContributorStack from './ContributorStack.svelte';
import ContributorStack from '$lib/shared/primitives/ContributorStack.svelte';
type TranscriptionQueueItemDTO = components['schemas']['TranscriptionQueueItemDTO'];

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import ConversationThumbnail from '$lib/components/ConversationThumbnail.svelte';
import TagChipList from '$lib/components/TagChipList.svelte';
import { formatDate } from '$lib/utils/date';
import ConversationThumbnail from '$lib/conversation/ConversationThumbnail.svelte';
import TagChipList from '$lib/tag/TagChipList.svelte';
import { formatDate } from '$lib/shared/utils/date';
import * as m from '$lib/paraglide/messages.js';
type Person = { id: string; firstName?: string | null; lastName: string; displayName: string };

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import { onMount, untrack } from 'svelte';
import PersonTypeahead from '$lib/components/PersonTypeahead.svelte';
import PersonMultiSelect from '$lib/components/PersonMultiSelect.svelte';
import PersonTypeahead from '$lib/person/PersonTypeahead.svelte';
import PersonMultiSelect from '$lib/person/PersonMultiSelect.svelte';
import FieldLabelBadge from './FieldLabelBadge.svelte';
import { isoToGerman, handleGermanDateInput } from '$lib/utils/date';
import { isoToGerman, handleGermanDateInput } from '$lib/shared/utils/date';
import { m } from '$lib/paraglide/messages.js';
import type { components } from '$lib/generated/api';

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { getContext } from 'svelte';
import type { Annotation } from '$lib/types';
import type { Annotation } from '$lib/shared/types';
import { m } from '$lib/paraglide/messages.js';
type UpdateAnnotationFn = (

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { render } from 'vitest-browser-svelte';
import AnnotationEditOverlay from './AnnotationEditOverlay.svelte';
import type { Annotation } from '$lib/types';
import type { Annotation } from '$lib/shared/types';
const annotation: Annotation = {
id: 'ann-1',

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import type { Annotation } from '$lib/types';
import type { Annotation } from '$lib/shared/types';
import AnnotationShape from './AnnotationShape.svelte';
type DrawRect = {

View File

@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
import { render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import AnnotationLayer from './AnnotationLayer.svelte';
import type { Annotation } from '$lib/types';
import type { Annotation } from '$lib/shared/types';
const annotation: Annotation = {
id: 'ann-1',

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import type { Annotation } from '$lib/types';
import type { Annotation } from '$lib/shared/types';
import AnnotationEditOverlay from './AnnotationEditOverlay.svelte';
let {

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { render } from 'vitest-browser-svelte';
import AnnotationShape from './AnnotationShape.svelte';
import type { Annotation } from '$lib/types';
import type { Annotation } from '$lib/shared/types';
const annotation: Annotation = {
id: 'ann-1',

View File

@@ -1,4 +1,4 @@
import { isoToGerman } from './date';
import { isoToGerman } from '$lib/shared/utils/date';
export interface FilenameParseResult {
/** ISO format: YYYY-MM-DD */

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import { getConfirmService } from '$lib/services/confirm.svelte.js';
import CommentThread from './CommentThread.svelte';
import PersonMentionEditor from './PersonMentionEditor.svelte';
import type { PersonMention } from '$lib/types';
import { getConfirmService } from '$lib/shared/services/confirm.svelte.js';
import CommentThread from '$lib/shared/discussion/CommentThread.svelte';
import PersonMentionEditor from '$lib/shared/discussion/PersonMentionEditor.svelte';
import type { PersonMention } from '$lib/shared/types';
const { confirm } = getConfirmService();

View File

@@ -2,7 +2,7 @@ import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import TranscriptionBlockHost from './TranscriptionBlock.test-host.svelte';
import type { ConfirmService } from '$lib/services/confirm.svelte.js';
import type { ConfirmService } from '$lib/shared/services/confirm.svelte.js';
afterEach(cleanup);

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { provideConfirmService, type ConfirmService } from '$lib/services/confirm.svelte.js';
import { provideConfirmService, type ConfirmService } from '$lib/shared/services/confirm.svelte.js';
import TranscriptionBlock from './TranscriptionBlock.svelte';
import type { PersonMention } from '$lib/types';
import type { PersonMention } from '$lib/shared/types';
type BlockProps = {
blockId: string;

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { getLocale } from '$lib/paraglide/runtime.js';
import { formatMCDate } from '$lib/utils/date.js';
import { formatMCDate } from '$lib/shared/utils/date.js';
import type { components } from '$lib/generated/api';
import ContributorStack from './ContributorStack.svelte';
import ContributorStack from '$lib/shared/primitives/ContributorStack.svelte';
type TranscriptionQueueItemDTO = components['schemas']['TranscriptionQueueItemDTO'];

View File

@@ -1,11 +1,11 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import TranscriptionBlock from './TranscriptionBlock.svelte';
import OcrTrigger from './OcrTrigger.svelte';
import TranscribeCoachEmptyState from './TranscribeCoachEmptyState.svelte';
import type { PersonMention, TranscriptionBlockData } from '$lib/types';
import { createBlockAutoSave } from '$lib/hooks/useBlockAutoSave.svelte';
import { createBlockDragDrop } from '$lib/hooks/useBlockDragDrop.svelte';
import OcrTrigger from '$lib/ocr/OcrTrigger.svelte';
import TranscribeCoachEmptyState from '$lib/shared/help/TranscribeCoachEmptyState.svelte';
import type { PersonMention, TranscriptionBlockData } from '$lib/shared/types';
import { createBlockAutoSave } from '$lib/document/transcription/useBlockAutoSave.svelte';
import { createBlockDragDrop } from '$lib/document/transcription/useBlockDragDrop.svelte';
type Props = {
documentId: string;

View File

@@ -2,7 +2,7 @@ import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import TranscriptionEditView from './TranscriptionEditView.svelte';
import { createConfirmService, CONFIRM_KEY } from '$lib/services/confirm.svelte.js';
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
afterEach(cleanup);

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import { getLocale } from '$lib/paraglide/runtime.js';
import HelpPopover from './HelpPopover.svelte';
import HelpPopover from '$lib/shared/primitives/HelpPopover.svelte';
type Props = {
mode: 'read' | 'edit';

View File

@@ -1,15 +1,15 @@
<script lang="ts">
import type { TranscriptionBlockData } from '$lib/types';
import type { TranscriptionBlockData } from '$lib/shared/types';
import type { components } from '$lib/generated/api';
import { splitByMarkers } from '$lib/utils/transcriptionMarkers';
import { splitByMarkers } from '$lib/document/transcription/transcriptionMarkers';
import {
renderTranscriptionBody,
type SafeHtml,
PERSON_MENTION_SELECTOR
} from '$lib/utils/mention';
import { computeHoverCardPosition } from '$lib/utils/hoverCardPosition';
import PersonHoverCard from './PersonHoverCard.svelte';
import type { HoverData, LoadState } from '$lib/types/personHoverCard';
} from '$lib/shared/discussion/mention';
import { computeHoverCardPosition } from '$lib/shared/utils/hoverCardPosition';
import PersonHoverCard from '$lib/person/PersonHoverCard.svelte';
import type { HoverData, LoadState } from '$lib/person/personHoverCard';
import { goto } from '$app/navigation';
import { SvelteMap, SvelteSet } from 'svelte/reactivity';

View File

@@ -1,7 +1,7 @@
import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import TranscriptionReadView from './TranscriptionReadView.svelte';
import type { TranscriptionBlockData } from '$lib/types';
import type { TranscriptionBlockData } from '$lib/shared/types';
const PERSON_ID = '11111111-0000-0000-0000-000000000001';

View File

@@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import TranscriptionReadView from './TranscriptionReadView.svelte';
import type { TranscriptionBlockData } from '$lib/types';
import type { TranscriptionBlockData } from '$lib/shared/types';
const blocks: TranscriptionBlockData[] = [
{

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { BlockConflictResolvedError, mergeBlockOnConflict } from './blockConflictMerge';
import type { PersonMention, TranscriptionBlockData } from '$lib/types';
import type { PersonMention, TranscriptionBlockData } from '$lib/shared/types';
const baseBlock: TranscriptionBlockData = {
id: 'b1',

View File

@@ -1,4 +1,4 @@
import type { PersonMention, TranscriptionBlockData } from '$lib/types';
import type { PersonMention, TranscriptionBlockData } from '$lib/shared/types';
/**
* Sentinel thrown by saveBlockWithConflictRetry after a 409 rename-mid-edit

View File

@@ -1,7 +1,7 @@
import { describe, it, expect, vi } from 'vitest';
import { saveBlockWithConflictRetry } from './saveBlockWithConflictRetry';
import { BlockConflictResolvedError } from './blockConflictMerge';
import type { PersonMention } from '$lib/types';
import type { PersonMention } from '$lib/shared/types';
const DOC = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa';
const BLK = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb';

View File

@@ -1,5 +1,8 @@
import type { PersonMention, TranscriptionBlockData } from '$lib/types';
import { BlockConflictResolvedError, mergeBlockOnConflict } from '$lib/utils/blockConflictMerge';
import type { PersonMention, TranscriptionBlockData } from '$lib/shared/types';
import {
BlockConflictResolvedError,
mergeBlockOnConflict
} from '$lib/document/transcription/blockConflictMerge';
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

Some files were not shown because too many files have changed in this diff Show More