import { DocumentViewer } from "@samplehc/ui/components";
import { useTaskState } from "@samplehc/ui/data";

function CitationDocumentViewer({ asyncResultIds }) {
  const [selectedCitations, setSelectedCitations] = useTaskState("citations", []);
  
  return (
    <div className="h-full">
      <DocumentViewer
        asyncResultIds={asyncResultIds}
        selectedCitations={selectedCitations}
      />
    </div>
  );
}

Overview

The DocumentViewer provides a sophisticated interface for viewing multiple document types including PDFs and FHIR resources. It features tabbed navigation, search functionality, citation highlighting, and automatic document processing integration with the SampleHC workflow system.

Basic Usage

import { DocumentViewer } from "@samplehc/ui/components";

function WorkflowDocumentViewer({ asyncResultIds }) {
  return (
    <DocumentViewer
      asyncResultIds={asyncResultIds}
      selectedCitations={[]}
    />
  );
}

API Reference

DocumentViewer (Async Results)

asyncResultIds
string[]
required
Array of async result IDs from document processing workflows. The viewer will automatically extract document IDs from these results.
selectedCitations
Citation[]
Array of citations to highlight across documents. Defaults to empty array.
filterFhirResourceTypes
string[]
Filter FHIR documents to show only specific resource types (e.g., [“Observation”, “DiagnosticReport”]).

DocumentViewerBase (Direct Documents)

documentIds
string[]
required
Array of document IDs to display directly.
selectedCitations
Citation[]
Array of citations to highlight across documents. Defaults to empty array.
refetchDependencies
unknown[]
Dependencies that trigger document refetch when changed. Defaults to empty array.
filterFhirResourceTypes
string[]
Filter FHIR documents to show only specific resource types.

Citation Type

file_metadata_id
string
required
ID of the document containing the citation.
chunk_index
number
required
Index of the chunk within the document.
block_index
number
required
Index of the block within the chunk.

Supported Formats

  • PDF Documents: Interactive PDF viewing with highlights, text selection, and page navigation
  • FHIR JSON: Both single JSON documents and JSONL (line-delimited JSON) formats

Features

Document Management

  • Tabbed Navigation: Switch between multiple documents with file name tabs
  • Document Type Toggle: Switch between PDF and FHIR document sets
  • Auto-loading: Automatic document fetching from async processing results

Search & Navigation

  • Cross-document Search: Search text across all loaded documents
  • Real-time Results: Instant search results with highlighted matches
  • Search Highlighting: Blue highlights for search results with match scores
  • Citation Navigation: Yellow highlights for referenced citations

PDF Features

  • Page-based Viewing: Full PDF viewer with zoom, rotation, and page controls
  • Highlight Overlays: Visual citation and search result highlighting
  • Page Jump: Navigate directly to pages containing highlights

FHIR Features

  • Categorized Display: Organize FHIR resources by type (Notes, Observations, etc.)
  • Timeline View: Chronological organization by months and years
  • Resource Filtering: Filter by specific FHIR resource types
  • Collapsible Sections: Expandable/collapsible chunks with preview
  • Patient Information: Dedicated patient info section

Highlight System

  • Floating Navigation Panel: Navigate between all highlights with keyboard shortcuts
  • Citation Highlighting: Automatic highlighting of referenced text passages
  • Search Highlighting: Visual highlighting of search matches
  • Cross-document Navigation: Jump between highlights across different documents

Keyboard Shortcuts

  • Alt + →: Next highlight
  • Alt + ←: Previous highlight

Advanced Examples

Workflow Integration with Citations

import { DocumentViewer } from "@samplehc/ui/components";
import { useTaskState } from "@samplehc/ui/data";

function CitationDocumentViewer({ asyncResultIds }) {
  const [selectedCitations, setSelectedCitations] = useTaskState("citations", []);
  
  return (
    <div className="h-full">
      <DocumentViewer
        asyncResultIds={asyncResultIds}
        selectedCitations={selectedCitations}
      />
    </div>
  );
}

Filtered FHIR Resource Viewing

import { DocumentViewer } from "@samplehc/ui/components";
import { useState } from "react";
import { Button } from "@/components/ui/button";

function FilteredDocumentViewer({ asyncResultIds }) {
  const [filterTypes, setFilterTypes] = useState<string[]>();
  const [selectedCitations, setSelectedCitations] = useState([]);

  const showOnlyObservations = () => {
    setFilterTypes(["Observation", "DiagnosticReport"]);
  };

  const showAllResources = () => {
    setFilterTypes(undefined);
  };

  return (
    <div className="h-full flex flex-col">
      <div className="p-4 border-b flex gap-2">
        <Button onClick={showOnlyObservations} variant="outline" size="sm">
          Show Labs Only
        </Button>
        <Button onClick={showAllResources} variant="outline" size="sm">
          Show All
        </Button>
      </div>
      <div className="flex-1">
        <DocumentViewer
          asyncResultIds={asyncResultIds}
          selectedCitations={selectedCitations}
          filterFhirResourceTypes={filterTypes}
        />
      </div>
    </div>
  );
}

Direct Document Access

import { DocumentViewerBase } from "@samplehc/ui/components";
import { useDocuments } from "@samplehc/ui/data";
import { useState } from "react";

function DirectDocumentViewer({ documentIds }) {
  const [selectedCitations, setSelectedCitations] = useState([]);
  const { data: documents, isLoading } = useDocuments(documentIds);

  if (isLoading) {
    return <div className="flex h-full items-center justify-center">
      Loading documents...
    </div>;
  }

  return (
    <DocumentViewerBase
      documentIds={documentIds}
      selectedCitations={selectedCitations}
    />
  );
}

Citation Navigation Integration

import { DocumentViewer } from "@samplehc/ui/components";
import { useTaskState } from "@samplehc/ui/data";
import { Button } from "@/components/ui/button";
import { useState } from "react";

function NavigableDocumentViewer({ asyncResultIds }) {
  const [citations] = useTaskState("extractedCitations", []);
  const [currentCitationIndex, setCurrentCitationIndex] = useState(0);

  const navigateToNext = () => {
    if (currentCitationIndex < citations.length - 1) {
      setCurrentCitationIndex(currentCitationIndex + 1);
    }
  };

  const navigateToPrev = () => {
    if (currentCitationIndex > 0) {
      setCurrentCitationIndex(currentCitationIndex - 1);
    }
  };

  const currentCitation = citations[currentCitationIndex];

  return (
    <div className="h-full flex flex-col">
      {citations.length > 0 && (
        <div className="p-4 border-b flex items-center justify-between">
          <span className="text-sm">
            Citation {currentCitationIndex + 1} of {citations.length}
          </span>
          <div className="flex gap-2">
            <Button 
              onClick={navigateToPrev} 
              disabled={currentCitationIndex === 0}
              size="sm"
            >
              Previous
            </Button>
            <Button 
              onClick={navigateToNext} 
              disabled={currentCitationIndex === citations.length - 1}
              size="sm"
            >
              Next
            </Button>
          </div>
        </div>
      )}
      <div className="flex-1">
        <DocumentViewer
          asyncResultIds={asyncResultIds}
          selectedCitations={currentCitation ? [currentCitation] : []}
        />
      </div>
    </div>
  );
}

Integration Notes

Workflow Integration: The DocumentViewer is designed to work with the SampleHC workflow system. Use DocumentViewer for async processing results and DocumentViewerBase for direct document access.
Performance: The component uses virtual scrolling for large documents and lazy loading for better performance. Documents are cached and refetched only when needed.
Document Processing: Ensure documents are fully processed before viewing. The component will show loading states while async results are being processed.

Best Practices

Citation Management

  • Use useTaskState to persist citations across workflow steps
  • Implement citation navigation controls for better user experience
  • Consider debouncing citation updates for performance

Search Integration

  • The search functionality works across all loaded documents
  • Search results are highlighted in blue, citations in yellow
  • Use the floating navigation panel for efficient highlight traversal

FHIR Resource Filtering

  • Filter by resource types to focus on specific medical data
  • Common filters: ["Observation", "DiagnosticReport"] for lab results
  • Use undefined/null to show all resource types

Document Loading

  • Always handle loading states for better UX
  • Consider showing document counts and processing status
  • Implement error boundaries for failed document loads