diff --git a/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStep.tsx b/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStep.tsx index d5387012c..2169ad51f 100644 --- a/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStep.tsx +++ b/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStep.tsx @@ -6,8 +6,8 @@ import { AnnotationLLMJobResult } from "../../../../api/openapi/models/Annotatio import { useAppDispatch, useAppSelector } from "../../../../plugins/ReduxHooks.ts"; import { CRUDDialogActions } from "../../../dialogSlice.ts"; import SdocRenderer from "../../../SourceDocument/SdocRenderer.tsx"; -import SpanAnnotationRenderer from "../../../SpanAnnotation/SpanAnnotationRenderer.tsx"; import LLMUtterance from "../LLMUtterance.tsx"; +import AnnotationResultStepDocument from "./AnnotationResultStepDocument.tsx"; function AnnotationResultStep() { // get the job @@ -64,9 +64,7 @@ function AnnotationResultStep() { {(llmJob.data.result.specific_llm_job_result as AnnotationLLMJobResult).results.map((annotationResult) => ( - {annotationResult.suggested_annotations.map((annotation, idx) => ( - - ))} + ))} diff --git a/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStepDocument.tsx b/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStepDocument.tsx new file mode 100644 index 000000000..745f3ff5b --- /dev/null +++ b/frontend/src/components/LLMDialog/steps/AnnotationResultStep/AnnotationResultStepDocument.tsx @@ -0,0 +1,14 @@ +import { AnnotationResult } from "../../../../api/openapi/models/AnnotationResult.ts"; +import SdocHooks from "../../../../api/SdocHooks.ts"; +import TextAnnotatorValidator from "../../../../views/annotation/TextAnnotatorValidator/TextAnnotatorValidator.tsx"; + +function AnnotationResultStepDocument({ annotationResult }: { annotationResult: AnnotationResult }) { + const sdoc = SdocHooks.useGetDocument(annotationResult.sdoc_id); + + if (sdoc.isSuccess) { + return ; + } + return null; +} + +export default AnnotationResultStepDocument; diff --git a/frontend/src/components/dialogSlice.ts b/frontend/src/components/dialogSlice.ts index c11ab5abc..4b0bfe1f8 100644 --- a/frontend/src/components/dialogSlice.ts +++ b/frontend/src/components/dialogSlice.ts @@ -44,6 +44,7 @@ interface DialogState { llmStep: number; llmTags: DocumentTagRead[]; llmMetadata: ProjectMetadataRead[]; + llmCodes: CodeRead[]; llmPrompts: LLMPromptTemplates[]; llmJobId?: string; llmJobResult: LLMJobResult | null | undefined; @@ -86,6 +87,7 @@ const initialState: DialogState = { llmStep: 0, llmTags: [], llmMetadata: [], + llmCodes: [], llmPrompts: [], llmJobId: undefined, llmJobResult: undefined, @@ -211,12 +213,14 @@ export const dialogSlice = createSlice({ prompts: LLMPromptTemplates[]; tags: DocumentTagRead[]; metadata: ProjectMetadataRead[]; + codes: CodeRead[]; }>, ) => { state.llmStep = 2; state.llmPrompts = action.payload.prompts; state.llmTags = action.payload.tags; state.llmMetadata = action.payload.metadata; + state.llmCodes = action.payload.codes; }, updateLLMPrompts: ( state, diff --git a/frontend/src/views/annotation/DocumentRenderer/useComputeTokenDataWithAnnotations.ts b/frontend/src/views/annotation/DocumentRenderer/useComputeTokenDataWithAnnotations.ts new file mode 100644 index 000000000..a55e97c1d --- /dev/null +++ b/frontend/src/views/annotation/DocumentRenderer/useComputeTokenDataWithAnnotations.ts @@ -0,0 +1,53 @@ +import { useMemo } from "react"; +import { SourceDocumentWithDataRead } from "../../../api/openapi/models/SourceDocumentWithDataRead.ts"; +import { SpanAnnotationReadResolved } from "../../../api/openapi/models/SpanAnnotationReadResolved.ts"; +import { IToken } from "./IToken.ts"; + +function useComputeTokenDataWithAnnotations({ + sdoc, + annotations, +}: { + sdoc: SourceDocumentWithDataRead; + annotations: SpanAnnotationReadResolved[]; +}) { + // computed + // todo: maybe implement with selector? + const tokenData: IToken[] | undefined = useMemo(() => { + const offsets = sdoc.token_character_offsets; + const texts = sdoc.tokens; + const result = texts.map((text, index) => ({ + beginChar: offsets[index][0], + endChar: offsets[index][1], + index, + text, + whitespace: offsets.length > index + 1 && offsets[index + 1][0] - offsets[index][1] > 0, + newLine: text.split("\n").length - 1, + })); + return result; + }, [sdoc]); + + // todo: maybe implement with selector? + // this map stores annotationId -> SpanAnnotationReadResolved + const annotationMap = useMemo(() => { + const result = new Map(); + annotations.forEach((a) => result.set(a.id, a)); + return result; + }, [annotations]); + + // this map stores tokenId -> spanAnnotationId[] + const annotationsPerToken = useMemo(() => { + const result = new Map(); + annotations.forEach((annotation) => { + for (let i = annotation.begin_token; i <= annotation.end_token - 1; i++) { + const tokenAnnotations = result.get(i) || []; + tokenAnnotations.push(annotation.id); + result.set(i, tokenAnnotations); + } + }); + return result; + }, [annotations]); + + return { tokenData, annotationsPerToken, annotationMap }; +} + +export default useComputeTokenDataWithAnnotations; diff --git a/frontend/src/views/annotation/TextAnnotatorValidator/TextAnnotatorValidator.tsx b/frontend/src/views/annotation/TextAnnotatorValidator/TextAnnotatorValidator.tsx new file mode 100644 index 000000000..bf2158a80 --- /dev/null +++ b/frontend/src/views/annotation/TextAnnotatorValidator/TextAnnotatorValidator.tsx @@ -0,0 +1,35 @@ +import { SourceDocumentWithDataRead } from "../../../api/openapi/models/SourceDocumentWithDataRead.ts"; +import { SpanAnnotationReadResolved } from "../../../api/openapi/models/SpanAnnotationReadResolved.ts"; +import DocumentRenderer from "../DocumentRenderer/DocumentRenderer.tsx"; +import useComputeTokenDataWithAnnotations from "../DocumentRenderer/useComputeTokenDataWithAnnotations.ts"; + +interface TextAnnotatorValidatorProps { + sdoc: SourceDocumentWithDataRead; + annotations: SpanAnnotationReadResolved[]; +} + +function TextAnnotatorValidator({ sdoc, annotations }: TextAnnotatorValidatorProps) { + // computed / custom hooks + const { tokenData, annotationsPerToken, annotationMap } = useComputeTokenDataWithAnnotations({ + sdoc: sdoc, + annotations: annotations, + }); + + return ( + <> + console.log("HI")} + html={sdoc.html} + tokenData={tokenData} + annotationsPerToken={annotationsPerToken} + annotationMap={annotationMap} + isViewer={false} + projectId={sdoc.project_id} + style={{ zIndex: 1, overflowY: "auto" }} + /> + + ); +} + +export default TextAnnotatorValidator;