Adding working board

This commit is contained in:
2026-08-17 09:24:53 +02:00
parent 35685f765a
commit 0237da74cf
18 changed files with 1365 additions and 738 deletions
+97 -37
View File
@@ -1,8 +1,24 @@
export type EvidenceType = 'folder' | 'evidence' | 'note' | 'event' | 'party'
export type ExhibitType = 'folder' | 'document' | 'note' | 'event' | 'party'
export type PartyKind = 'person' | 'organization'
export type OrganizationKind = 'business' | 'public_body' | 'association' | 'informal_group' | 'other'
export type SourceFileType = 'image' | 'pdf' | 'web_capture' | 'email' | 'article' | 'filing' | 'price_list' | 'text' | 'file'
export interface CanvasPlacement {
x: number
y: number
width: number
height: number
rotation: number
zIndex: number
hidden: boolean
}
export interface ExhibitBase extends CanvasPlacement {
id: string
type: ExhibitType
title: string
}
export interface DocumentRegion {
id: string
label: string
@@ -10,12 +26,17 @@ export interface DocumentRegion {
date?: string
}
export interface CaseDocument {
id: string
title: string
kind: string
date: string
export interface FolderExhibit extends ExhibitBase {
type: 'folder'
content: string
isOpen: boolean
}
export interface DocumentExhibit extends ExhibitBase {
type: 'document'
publishedAt?: string
capturedAt?: string
sourceUri?: string
body: string[]
regions: DocumentRegion[]
assetId?: string
@@ -26,40 +47,48 @@ export interface CaseDocument {
metadata: Record<string, string>
}
export interface Evidence {
id: string
type: EvidenceType
title: string
export interface NoteExhibit extends ExhibitBase {
type: 'note'
content: string
sourceDocumentId?: string
sourceRegionId?: string
eventDate?: string
supportingEvidenceIds?: string[]
partyKind?: PartyKind
organizationKind?: OrganizationKind
aliases?: string[]
relatedEvidenceIds?: string[]
x: number
y: number
width: number
config?: Record<string, unknown>
/** Compatibility projection for clients predating the generic relation graph. */
containedDocumentIds?: string[]
}
export interface WidgetRelation {
id: string
fromWidgetId: string
toWidgetId: string
type: string
sortOrder?: number
config?: Record<string, unknown>
export interface EventExhibit extends ExhibitBase {
type: 'event'
content: string
eventDate?: string
}
export interface PartyExhibit extends ExhibitBase {
type: 'party'
content: string
partyKind: PartyKind
organizationKind?: OrganizationKind
aliases: string[]
}
export type Exhibit = FolderExhibit | DocumentExhibit | NoteExhibit | EventExhibit | PartyExhibit
export type Evidence = Exclude<Exhibit, DocumentExhibit>
export type CaseDocument = DocumentExhibit
export type EvidenceType = Evidence['type']
interface ExhibitRelationBase {
id: string
fromExhibitId: string
toExhibitId: string
sortOrder: number
note?: string
}
export interface FolderMembership extends ExhibitRelationBase { type: 'contains' }
export interface EventSupportRelation extends ExhibitRelationBase { type: 'supports' }
export interface PartyAssociationRelation extends ExhibitRelationBase { type: 'concerns' }
export interface ProvenanceRelation extends ExhibitRelationBase { type: 'source'; sourceRegionId?: string }
export type ExhibitRelation = FolderMembership | EventSupportRelation | PartyAssociationRelation | ProvenanceRelation
export interface Connection {
id: string
fromEvidenceId: string
toEvidenceId: string
fromExhibitId: string
toExhibitId: string
label?: string
/** Percentage from slack (0) to taut (100). */
tightness?: number
@@ -73,6 +102,31 @@ export interface Connection {
export interface Viewport { x: number; y: number; zoom: number }
export interface TimelineRange { start: string; end: string }
export type BoardViewPlacement =
| { mode: 'docked'; dockEdge: 'top' | 'right' | 'bottom' | 'left'; size: number }
| { mode: 'canvas' | 'window'; x: number; y: number; width: number; height: number }
export interface TimelineView {
id: string
type: 'timeline'
placement: BoardViewPlacement
visible: boolean
zIndex: number
rangeMode: 'auto' | 'fixed'
range?: TimelineRange
}
export type BoardView = TimelineView
export interface TemporalFact {
id: string
exhibitId: string
kind: 'published' | 'captured' | 'occurred' | 'region_date'
start: string
end?: string
label: string
}
export interface BriefConcept {
id: string
label: string
@@ -87,15 +141,21 @@ export interface CaseState {
id: string
title: string
subtitle: string
documents: CaseDocument[]
evidence: Evidence[]
relations: WidgetRelation[]
exhibits: Exhibit[]
relations: ExhibitRelation[]
connections: Connection[]
views: BoardView[]
viewport: Viewport
timelineRange?: TimelineRange | null
brief: LevelBrief
revision: number
updatedAt?: string
levelStatus?: string
sourceTemplateVersionId?: string
editingAllowed?: boolean
}
export function isDocumentExhibit(exhibit: Exhibit): exhibit is DocumentExhibit { return exhibit.type === 'document' }
export function isEvidenceExhibit(exhibit: Exhibit): exhibit is Evidence { return exhibit.type !== 'document' }
export function isFolderExhibit(exhibit: Exhibit): exhibit is FolderExhibit { return exhibit.type === 'folder' }
export function isEventExhibit(exhibit: Exhibit): exhibit is EventExhibit { return exhibit.type === 'event' }
export function isPartyExhibit(exhibit: Exhibit): exhibit is PartyExhibit { return exhibit.type === 'party' }