From bc4b33188fc1088a276141ddde9f864297dfe14c Mon Sep 17 00:00:00 2001 From: fsimonjetz Date: Tue, 30 Jul 2024 15:42:42 +0000 Subject: [PATCH] add TokenAnnotationTool prototype add isInPopover parameter add AnnotationLineColumns --- .../ui/fragment/CuneiformFragmentEditor.tsx | 20 +++++- .../ui/fragment/TokenAnnotationTool.tsx | 70 +++++++++++++++++++ src/transliteration/domain/columns.ts | 5 +- src/transliteration/ui/LineAccumulator.tsx | 14 ++-- .../ui/TransliterationLines.tsx | 2 +- src/transliteration/ui/line-tokens.tsx | 42 ++++++++++- 6 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 src/fragmentarium/ui/fragment/TokenAnnotationTool.tsx diff --git a/src/fragmentarium/ui/fragment/CuneiformFragmentEditor.tsx b/src/fragmentarium/ui/fragment/CuneiformFragmentEditor.tsx index f16bf2c23..05fc0e8ce 100644 --- a/src/fragmentarium/ui/fragment/CuneiformFragmentEditor.tsx +++ b/src/fragmentarium/ui/fragment/CuneiformFragmentEditor.tsx @@ -20,6 +20,7 @@ import { FindspotService } from 'fragmentarium/application/FindspotService' import { Session } from 'auth/Session' import ColophonEditor from 'fragmentarium/ui/fragment/ColophonEditor' import { Colophon } from 'fragmentarium/domain/Colophon' +import TokenAnnotationTool from './TokenAnnotationTool' const ContentSection: FunctionComponent = ({ children, @@ -47,6 +48,7 @@ type TabName = | 'references' | 'archaeology' | 'colophon' + | 'annotation' const tabNames: TabName[] = [ 'display', @@ -55,6 +57,7 @@ const tabNames: TabName[] = [ 'references', 'archaeology', 'colophon', + 'annotation', ] function EditorTab({ @@ -92,6 +95,7 @@ function TabContentsMatcher({ references: () => ReferencesContents(props), archaeology: () => ArchaeologyContents(props), colophon: () => ColophonContents(props), + annotation: () => AnnotationContents(props), }[name]() } @@ -127,7 +131,9 @@ export const EditorTabs: FunctionComponent = ({ } + +function AnnotationContents(props: TabsProps): JSX.Element { + const updateFragmentAnnotation = async (fragment: Fragment) => { + console.log('Saved fragment!') + } + return ( + + ) +} diff --git a/src/fragmentarium/ui/fragment/TokenAnnotationTool.tsx b/src/fragmentarium/ui/fragment/TokenAnnotationTool.tsx new file mode 100644 index 000000000..5ccacb63d --- /dev/null +++ b/src/fragmentarium/ui/fragment/TokenAnnotationTool.tsx @@ -0,0 +1,70 @@ +import React, { Component } from 'react' +import { Fragment } from 'fragmentarium/domain/fragment' +import { AbstractLine } from 'transliteration/domain/abstract-line' +import { isTextLine } from 'transliteration/domain/type-guards' +import DisplayControlLine from 'transliteration/ui/DisplayControlLine' +import { LineNumber } from 'transliteration/ui/line-number' +import { TextLine } from 'transliteration/domain/text-line' +import { AnnotationLineColumns } from 'transliteration/ui/line-tokens' +import { lineComponents } from 'transliteration/ui/TransliterationLines' + +type Props = { + fragment: Fragment + onSave(fragment: Fragment): void +} + +export default class TokenAnnotationTool extends Component { + readonly fragment: Fragment + constructor(props: Props) { + super(props) + this.fragment = props.fragment + } + + markableLine({ + line, + numberOfColumns, + }: { + line: TextLine + numberOfColumns: number + }): JSX.Element { + return ( + + + + + + + ) + } + + render(): JSX.Element { + const text = this.fragment.text + return ( + + + {text.allLines.map((line: AbstractLine, index) => { + if (isTextLine(line)) { + return ( + + ) + } + const LineComponent = + lineComponents.get(line.type) || DisplayControlLine + return ( + + + + ) + })} + +
+ ) + } +} diff --git a/src/transliteration/domain/columns.ts b/src/transliteration/domain/columns.ts index 263811ddc..57fda840f 100644 --- a/src/transliteration/domain/columns.ts +++ b/src/transliteration/domain/columns.ts @@ -44,6 +44,7 @@ export function lineAccFromColumns({ showIpa = false, phoneticProps, highlightLemmas = [], + isInPopover, }: { columns: readonly TextLineColumn[] isInLineGroup?: boolean @@ -51,6 +52,7 @@ export function lineAccFromColumns({ showIpa?: boolean phoneticProps?: PhoneticProps highlightLemmas: readonly string[] + isInPopover?: boolean }): LineAccumulator { return columns.reduce((acc: LineAccumulator, column) => { acc.addColumn(column.span) @@ -65,7 +67,8 @@ export function lineAccFromColumns({ updatePhoneticPropsContext(column.content, index, phoneticProps), _.isEmpty(_.intersection(token.uniqueLemma, highlightLemmas)) ? [] - : ['highlight'] + : ['highlight'], + isInPopover ) return acc }, diff --git a/src/transliteration/ui/LineAccumulator.tsx b/src/transliteration/ui/LineAccumulator.tsx index 10a16b6ec..45a339deb 100644 --- a/src/transliteration/ui/LineAccumulator.tsx +++ b/src/transliteration/ui/LineAccumulator.tsx @@ -44,13 +44,13 @@ function GlossWrapper({ children }: PropsWithChildren): JSX.Element { ) } -interface ColumnData { +export interface ColumnData { span: number | null content: React.ReactNode[] } export class LineAccumulator { - private columns: ColumnData[] = [] + readonly columns: ColumnData[] = [] private inGloss = false private language = 'AKKADIAN' private enclosureOpened = false @@ -91,7 +91,8 @@ export class LineAccumulator { showMeter = false, showIpa = false, phoneticProps?: PhoneticProps, - bemModifiers: string[] = [] + bemModifiers: string[] = [], + isInPopover?: boolean ): void { if (_.isEmpty(this.columns)) { this.addColumn(1) @@ -113,6 +114,7 @@ export class LineAccumulator { showMeter={showMeter} showIpa={showIpa} phoneticProps={phoneticProps} + isInPopover={isInPopover} /> ) this.enclosureOpened = isOpenEnclosure(token) @@ -143,7 +145,8 @@ export class LineAccumulator { showMeter?: boolean, showIpa?: boolean, phoneticProps?: PhoneticProps, - bemModifiers: string[] = [] + bemModifiers: string[] = [], + isInPopover?: boolean ): void { switch (token.type) { case 'LanguageShift': @@ -165,7 +168,8 @@ export class LineAccumulator { showMeter, showIpa, phoneticProps, - bemModifiers + bemModifiers, + isInPopover ) this.pushLemma(token.uniqueLemma) this.isFirstWord = false diff --git a/src/transliteration/ui/TransliterationLines.tsx b/src/transliteration/ui/TransliterationLines.tsx index 41397cbd4..371b2878c 100644 --- a/src/transliteration/ui/TransliterationLines.tsx +++ b/src/transliteration/ui/TransliterationLines.tsx @@ -17,7 +17,7 @@ import DisplayTranslationLine from './DisplayTranslationLine' import DisplayControlLine from './DisplayControlLine' import { DisplayParallelLine } from './parallel-line' -const lineComponents: ReadonlyMap< +export const lineComponents: ReadonlyMap< string, FunctionComponent > = new Map([ diff --git a/src/transliteration/ui/line-tokens.tsx b/src/transliteration/ui/line-tokens.tsx index 2699c216d..21ef8a7fa 100644 --- a/src/transliteration/ui/line-tokens.tsx +++ b/src/transliteration/ui/line-tokens.tsx @@ -7,7 +7,7 @@ import { LemmaMap, LineLemmasContext, } from './LineLemmasContext' -import { LineAccumulator } from './LineAccumulator' +import { ColumnData, LineAccumulator } from './LineAccumulator' import { lineAccFromColumns, TextLineColumn, @@ -83,6 +83,46 @@ export function LineColumns({ ) } +export function AnnotationLineColumns({ + columns, + maxColumns, +}: { + columns: readonly TextLineColumn[] + maxColumns: number +}): JSX.Element { + const lineAccumulator = lineAccFromColumns({ + columns, + highlightLemmas: [], + isInPopover: true, + }) + + const [lemmaMap, lemmaSetter] = useState( + createLemmaMap(lineAccumulator.lemmas) + ) + + return ( + + {lineAccumulator.columns.map((column: ColumnData, index: number) => ( + + {column.content.map((tokenComponent, index) => ( + console.log(`clicked on token at index=${index}`)} + > + {tokenComponent} + + ))} + + ))} + + ) +} + export class LineToken { token: LemmatizableToken lemma: DictionaryWord[] | null = null