Open Contracts Annotator Components¶
Key Questions¶
- How is the PDF loaded?
- The PDF is loaded in the
Annotator.tsx
component. - Inside the
useEffect
hook that runs when theopenedDocument
prop changes, the PDF loading process is initiated. - The
pdfjsLib.getDocument
function from thepdfjs-dist
library is used to load the PDF file specified byopenedDocument.pdfFile
. - The loading progress is tracked using the
loadingTask.onProgress
callback, which updates theprogress
state. - Once the PDF is loaded, the
loadingTask.promise
is resolved, and thePDFDocumentProxy
object is obtained. -
The
PDFPageInfo
objects are created for each page of the PDF usingdoc.getPage(i)
and stored in thepages
state. -
Where and how are annotations loaded?
- Annotations are loaded using the
REQUEST_ANNOTATOR_DATA_FOR_DOCUMENT
GraphQL query in theAnnotator.tsx
component. - The
useQuery
hook from Apollo Client is used to fetch the annotator data based on the providedinitial_query_vars
. - The
annotator_data
received from the query contains information about existing text annotations, document label annotations, and relationships. -
The annotations are transformed into
ServerAnnotation
,DocTypeAnnotation
, andRelationGroup
objects and stored in thepdfAnnotations
state usingsetPdfAnnotations
. -
Where is the PAWLs layer loaded?
- The PAWLs layer is loaded in the
Annotator.tsx
component. - Inside the
useEffect
hook that runs when theopenedDocument
prop changes, the PAWLs layer is loaded using thegetPawlsLayer
function fromapi/rest.ts
. - The
getPawlsLayer
function makes an HTTP GET request to fetch the PAWLs data file specified byopenedDocument.pawlsParseFile
. - The PAWLs data is expected to be an array of
PageTokens
objects, which contain token information for each page of the PDF. - The loaded PAWLs data is then used to create
PDFPageInfo
objects for each page, which include the page tokens.
High-level Components Overview¶
- The
Annotator
component is the top-level component that manages the state and data loading for the annotator. - It renders the
PDFView
component, which is responsible for displaying the PDF and annotations. - The
PDFView
component renders various sub-components, such asLabelSelector
,DocTypeLabelDisplay
,AnnotatorSidebar
,AnnotatorTopbar
, andPDF
. - The
PDF
component renders individualPage
components for each page of the PDF. - Each
Page
component rendersSelection
andSearchResult
components for annotations and search results, respectively. - The
AnnotatorSidebar
component displays the list of annotations, relations, and a search widget. - The
PDFStore
andAnnotationStore
are context providers that hold the PDF and annotation data, respectively.
Specific Component Deep Dives¶
PDFView.tsx¶
The PDFView
component is a top-level component that renders the PDF document with annotations, relations, and text search capabilities. It manages the state and functionality related to annotations, relations, and user interactions. Here's a detailed explanation of how the component works:
-
The
PDFView
component receives several props, including permissions, callbacks for CRUD operations on annotations and relations, refs for container and selection elements, and various configuration options. -
It initializes several state variables using the
useState
hook, including: selectionElementRefs
andsearchResultElementRefs
: Refs for annotation selections and search results.pageElementRefs
: Refs for individual PDF pages.scrollContainerRef
: Ref for the scroll container.textSearchMatches
andsearchText
: State for text search matches and search text.selectedAnnotations
andselectedRelations
: State for currently selected annotations and relations.pageSelection
andpageSelectionQueue
: State for current page selection and queued selections.pdfPageInfoObjs
: State for PDF page information objects.-
Various other state variables for active labels, relation modal visibility, and annotation options.
-
The component defines several functions for updating state and handling user interactions, such as:
insertSelectionElementRef
,insertSearchResultElementRefs
, andinsertPageRef
: Functions to add refs for selections, search results, and pages.onError
: Error handling callback.advanceTextSearchMatch
andreverseTextSearchMatch
: Functions to navigate through text search matches.onRelationModalOk
andonRelationModalCancel
: Callbacks for relation modal actions.-
createMultiPageAnnotation
: Function to create a multi-page annotation from queued selections. -
The component uses the
useEffect
hook to handle side effects, such as: - Setting the scroll container ref on load.
- Listening for changes in the shift key and triggering annotation creation.
-
Updating text search matches when the search text changes.
-
The component renders the PDF document and its related components using the
PDFStore
andAnnotationStore
contexts: - The
PDFStore
context provides the PDF document, pages, and error handling. -
The
AnnotationStore
context provides annotation-related state and functions. -
The component renders the following main sections:
LabelSelector
: Allows the user to select the active label for annotations.DocTypeLabelDisplay
: Displays the document type labels.AnnotatorSidebar
: Sidebar component for managing annotations and relations.AnnotatorTopbar
: Top bar component for additional controls and options.-
PDF
: The actual PDF component that renders the PDF pages and annotations. -
The
PDF
component, defined inPDF.tsx
, is responsible for rendering the PDF pages and annotations. It receives props from thePDFView
component, such as permissions, configuration options, and callbacks. -
The
PDF
component maps over each page of the PDF document and renders aPage
component for each page, passing the necessary props. -
The
Page
component, also defined inPDF.tsx
, is responsible for rendering a single page of the PDF document along with its annotations and search results. It handles mouse events for creating and modifying annotations. -
The
PDFView
component also renders theRelationModal
component when the active relation label is set and the user has the necessary permissions. The modal allows the user to create or modify relations between annotations.
PDF.tsx¶
PDF
renders the actual PDF document with annotations and text search capabilities. PDFView (see above) is what actually interacts with the backend / API.
- The
PDF
component receives several props: shiftDown
: Indicates whether the Shift key is pressed (optional).doc_permissions
andcorpus_permissions
: Specify the permissions for the document and corpus, respectively.read_only
: Determines if the component is in read-only mode.show_selected_annotation_only
: Specifies whether to show only the selected annotation.show_annotation_bounding_boxes
: Specifies whether to show annotation bounding boxes.show_annotation_labels
: Specifies the behavior for displaying annotation labels.setJumpedToAnnotationOnLoad
: A callback function to set the jumped-to annotation on load.- The
PDF
component retrieves the PDF document and pages from thePDFStore
context. - It maps over each page of the PDF document and renders a
Page
component for each page, passing the necessary props. - The
Page
component is responsible for rendering a single page of the PDF document along with its annotations and search results. - Inside the
Page
component: - It creates a canvas element using the
useRef
hook to render the PDF page. - It retrieves the annotations for the current page from the
AnnotationStore
context. - It defines a
ConvertBoundsToSelections
function that converts the selected bounds to annotations and tokens. - It uses the
useEffect
hook to set up the PDF page rendering and event listeners for resizing and scrolling. - It renders the PDF page canvas, annotations, search results, and queued selections.
- The
Page
component renders the following sub-components: PageAnnotationsContainer
: A styled container for the page annotations.PageCanvas
: A styled canvas element for rendering the PDF page.Selection
: Represents a single annotation selection on the page.SearchResult
: Represents a search result on the page.- The
Page
component handles mouse events for creating and modifying annotations: - On
mouseDown
, it initializes the selection if the necessary permissions are granted and the component is not in read-only mode. - On
mouseMove
, it updates the selection bounds if a selection is active. - On
mouseUp
, it adds the completed selection to thepageSelectionQueue
and triggers the creation of a multi-page annotation if the Shift key is not pressed. - The
Page
component also handles fetching more annotations for previous and next pages using theFetchMoreOnVisible
component. - The
SelectionBoundary
andSelectionTokens
components are used to render the annotation boundaries and tokens, respectively. - The
PDFPageRenderer
class is responsible for rendering a single PDF page on the canvas. It manages the rendering tasks and provides methods for canceling and rescaling the rendering. - The
getPageBoundsFromCanvas
function calculates the bounding box of the page based on the canvas dimensions and its parent container.