Project: workspace-doctolib · Branch: HEAD · Mode: ` · **Model:**claude-haiku-4-5-20251001`
Stats: 1 user messages, 30 tool calls, tools used: Glob, Bash, Read.
Conversation
Turn 1 — User
Explore the following files and directories thoroughly and return their full content with line numbers. I need to understand the current pagination implementation across two projects.
Project 1: treatment-plan at /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src
Find and read:
1. NhrDocumentListTable.tsx (contains client-side pagination logic)
2. NhrEntryPoint.tsx (passes searchDocuments callback)
3. Any related types/interfaces files (especially those related to NhrDocument, pagination, searchDocuments)
4. Any test files for NhrDocumentListTable or NhrEntryPoint
5. The package's index.ts or main exports
Also explore /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src and find:
1. Any searchDocuments-related files or types
2. Any API client files
Project 2: monolith at /Users/USER/workspace/doctolib/doctolib
Find and read:
1. packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
2. packages/@doctolib/national-health-records/src/ directory listing
3. packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx (around line 117)
4. Any hook useNhrDocumentListVariant - search for it across the monolith
5. Any existing pagination types in the national-health-records package
Return the FULL content of each file found. This is a research task only - do not modify any files.
Turn 1 — Assistant
I'll help you explore these files to understand the pagination implementation across both projects. Let me start by searching and reading the relevant files.
Tools used:
Glob:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/**/*.tsx
Tool results:
→ result (ok): treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrEntryPointButton/NhrEntryPointButton.stories.tsx treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrEntryPointButton/NhrEntryPointButton.tsx treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListTable/NhrDocumentListTableHead/NhrDocumentListTableHead.test.tsx treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/Nh …(truncated, 11049 more chars)
Tools used:
Glob:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/**/*.ts
Tool results:
→ result (ok): treatment-plan/packages/tpf-national-health-records-ui/src/tests/index.test.ts treatment-plan/packages/tpf-national-health-records-ui/src/i18n.ts treatment-plan/packages/tpf-national-health-records-ui/src/entry.ts treatment-plan/packages/tpf-national-health-records-ui/src/test-helpers/fixtures/createFixtureBuilder.ts treatment-plan/packages/tpf-national-health-records-ui/src/test-helpers/fixtures/index.ts treatment-plan/packages/tpf-national-health-records-ui/src/test-helpers/fixtures/nhrDoc …(truncated, 2770 more chars)
Tools used:
Glob:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/**/*.ts
Tool results:
→ result (ok): treatment-plan/packages/tpf-national-health-records/src/business/nhr-service-factory.ts treatment-plan/packages/tpf-national-health-records/src/business/systems/dmp/types/index.ts treatment-plan/packages/tpf-national-health-records/src/business/systems/dmp/types/types.ts treatment-plan/packages/tpf-national-health-records/src/business/types/index.ts treatment-plan/packages/tpf-national-health-records/src/business/types/participant.ts treatment-plan/packages/tpf-national-health-records/src/busine …(truncated, 272 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src -type f \( -name "*.ts" -o -name "*.tsx" \) | head -30
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/generateNhrDocuments.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/nhrMockedColumns.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/nhrMockedDocuments.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/generateNhrDocuments.test.ts /Users/USER/workspace/doctolib/do …(truncated, 2679 more chars)
Now let me read the key files from the treatment-plan project:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListTable/NhrDocumentListTable.tsx
Tool results:
→ result (ok): 1 import { PAGE_SIZE } from '#utils/nhrPaginationHelpers'
2 import { Pagination } from '@doctolib/design-system/Pagination'
3 import { Table } from '@doctolib/design-system/Table'
4 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
5
6 import type { ActionConfig, ColumnConfig } from '../../../types'
7 import { NhrDocumentListTableBody } from './NhrDocumentListTableBody/NhrDocumentListTableBody'
8 import { NhrDocumentListTableHead } from './NhrDocumentListTableHead/NhrDocu
…(truncated, 856 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrEntryPoint/NhrEntryPoint.tsx
Tool results:
→ result (ok): 1 import { useState } from 'react'
2
3 import type { ActionConfig, ColumnConfig, FilterConfig, NhrPatientInfo, SearchDocumentsFn } from '../../types'
4 import { NhrDocumentListModal } from '../NhrDocumentListModal/NhrDocumentListModal'
5 import { NhrEntryPointButton } from '../NhrEntryPointButton/NhrEntryPointButton'
6
7 export type NhrEntryPointProps = {
8 patient: {
9 show_ins_features?: boolean
10 }
11 patientInfo: NhrPatientInfo
12 title: string
13 columns: ColumnConfig[]
14
…(truncated, 1162 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/types.ts
Tool results:
→ result (ok): 1 import type { DesignSystemIconComponent } from '@doctolib/design-system-icons'
2 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
3 import type { ReactNode } from 'react'
4
5 export type NhrPatientInfo = {
6 fullName: string
7 gender: 'male' | 'female' | 'other'
8 birthDate: string
9 age: number
10 }
11
12 export type ColumnConfig = {
13 key: string
14 header: string
15 sortable: boolean
16 /** Only required when sortable: true. Returns a string for lo
…(truncated, 2157 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts
Tool results:
→ result (ok): 1 export { NhrDocumentList } from './components/NhrDocumentList/NhrDocumentList' 2 export { NhrDocumentListFilterPanel } from './components/NhrDocumentListFilterPanel/NhrDocumentListFilterPanel' 3 export type { 4 ActionConfig, 5 ActionsFactory, 6 ColumnConfig, 7 FilterConfig, 8 FilterRenderContext, 9 NhrPatientInfo, 10 NhrVisibilityEntry, 11 StatusOption, 12 NhrDocumentStatusFilterProps, 13 VisibilityOption, 14 SearchDocumentsFn, 15 } from './types' 16 export { NhrEntryPoin …(truncated, 2130 more chars)
Let me continue reading the pagination helpers and other key files:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/utils/nhrPaginationHelpers.ts
Tool results:
→ result (ok): 1 export const PAGE_SIZE = 20
2
3 export const getPagedData = <T>(data: T[] | undefined, currentPage: number): T[] | undefined =>
4 data?.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE)
5
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx
Tool results:
→ result (ok): 1 import { Modal } from '@doctolib/design-system/Modal'
2 import { ModalBody } from '@doctolib/design-system/ModalBody'
3 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
4 import { useEffect, useMemo, useState } from 'react'
5
6 import type { ActionConfig, ColumnConfig, FilterConfig, NhrPatientInfo, SearchDocumentsFn } from '../../types'
7 import { NhrDocumentList } from '../NhrDocumentList/NhrDocumentList'
8
9 export type NhrDocumentListModalProps = {
10 isOpen: boo
…(truncated, 2194 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/document.ts
Tool results:
→ result (ok): 1 import type { NhrDocumentAuthor, NhrPatientInformation } from '#business/types/participant'
2
3 // General types ---
4 /* The services/procedures this document is associated with /
5 export type NhrServiceInformation = {
6 startDate?: string
7 endDate?: string
8 }
9
10 export type NhrDocumentClassification = {
11 codes: Code[]
12 }
13
14 export type Code = {
15 system: string
16 code: string
17 }
18
19 export type DateRange = {
20 upperLimit?: string
21 lowerLimit?: string
…(truncated, 1348 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/index.ts
Tool results:
→ result (ok): 1 // bump 2 export { createNhrService } from '#business/nhr-service-factory' 3 export type { NhrAdapter, NhrService, CountryCode } from '#business/types/service' 4 export type { 5 NhrDocumentSearchProps, 6 NhrDocumentSearchResult, 7 NhrDocument, 8 NhrServiceInformation, 9 NhrDocumentSearchParams, 10 NhrDocumentClassification, 11 DateRange, 12 Code, 13 NhrDocumentFile, 14 NhrGetDocumentsContentProps, 15 NhrDocumentContentResult, 16 } from '#business/types/document' 17 export …(truncated, 359 more chars)
Now let me read the monolith files:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
Tool results:
→ result (ok): 1 import { useQueryClient } from '@tanstack/react-query-v5' 2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 3 import { isFeatureEnabled } from '@doctolib/variation_management' 4 import type { NhrDocumentListVariant, MapFiltersToSearchDocumentsParams, ServerFilters } from '../variants/types' 5 import { useNationalHealthRecords } from './useNationalHealthRecords' 6 import { generateNhrDocuments } from '../mocks/generateNhrDocuments' 7 import { toNhrPatientInformation …(truncated, 2248 more chars)
Tools used:
Bash:ls -la /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/
Tool results:
→ result (ok): drwxr-xr-x clertonra staff 256 B Wed Apr 8 16:08:29 2026 . drwxr-xr-x clertonra staff 352 B Mon Apr 13 15:34:16 2026 .. drwxr-xr-x clertonra staff 160 B Wed Apr 8 16:08:29 2026 business drwxr-xr-x clertonra staff 256 B Tue Apr 14 08:54:10 2026 hooks .rw-r--r-- clertonra staff 404 B Wed Apr 8 16:08:29 2026 index.ts drwxr-xr-x clertonra staff 128 B Thu Feb 26 14:08:52 2026 locales drwxr-xr-x clertonra staff 192 B Tue Apr 14 08:54:10 2026 mocks drwxr-xr-x clertonra staff 160 B Tue Apr 14 08:54:1 …(truncated, 15 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src -name "*Pagination*" -o -name "*pagination*"
Tool results:
→ result (ok): (Bash completed with no output)
Let me search for the hook and other relevant files in the monolith:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts
Tool results:
→ result (ok): 1 import { useProductLineVariation, ProductLineKey } from '@doctolib/variation_management'
2 import type { DocumentSearchOptions, NhrDocumentListVariant } from './types'
3 import { useDmpDocumentListVariant } from './dmp'
4
5 export const useNhrDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant | null => {
6 const dmpVariant = useDmpDocumentListVariant(patient)
7
8 return useProductLineVariation<NhrDocumentListVariant>({
9 variants: {
10 [Pr
…(truncated, 389 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
Tool results:
→ result (ok): 1 import type { ColumnConfig, FilterConfig } from '@doctolib/tpf-national-health-records-ui'
2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient'
3 import type { NhrDocument, NhrDocumentSearchParams } from '@doctolib/tpf-national-health-records'
4
5 interface SearchDocumentsResult {
6 data: NhrDocument[]
7 total: number
8 }
9
10 export type NhrDocumentListVariant = {
11 columns: ColumnConfig[]
12 filters: FilterConfig[]
13 searchDocuments: (appliedFilters?: R
…(truncated, 791 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src -name "PatientCard*" | head -5
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.test.tsx /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCardIcons /Users/USER/workspace/doctolib/doctolib/packages/@doctoli …(truncated, 272 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx
Tool results:
→ result (ok): 1 import PatientFileIcon from 'images/icons/patient-file-icon.svg?as-react-component' 2 import PatientAppointmentIcon from 'images/icons/patient-appointment-icon.svg?as-react-component' 3 import { type ComponentType, lazy, useContext, useMemo, Suspense } from 'react' 4 import classNames from 'classnames' 5 import AccountContext from 'monolith_DEPRECATED/contexts/doctor/AccountContext' 6 import INSiAutomaticCallContext from '@doctolib/financial_os_api/public/contexts/INSiAutomaticCallContext' 7 i …(truncated, 7405 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/index.ts
Tool results:
→ result (ok): 1 export { useNationalHealthRecords, type UseNhrOperations } from './hooks/useNationalHealthRecords' 2 export { useDmpNhr } from './hooks/useDmpNhr' 3 export { useNhrDocumentListVariant } from './variants/useNhrDocumentListVariant' 4 export type { DocumentSearchOptions, NhrDocumentListVariant } from './variants/types' 5 export { actionsBuilder, type NhrActionsBuilder } from './business/builders/actionsBuilder' 6
Tools used:
Bash:grep -r "useNhrDocumentListVariant" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/.claude/worktrees/fhir-2144_nhr-document-list-add-action-config-column/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts:export const useNhrDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant | null => { /Users/USER/workspace/doctolib/doctolib/.claude/worktrees/fhir-2144_nhr-document-list-add-action-config-column/packages/@doctolib/national-health-records/src/index.ts:export { useNhrD …(truncated, 3551 more chars)
Let me read the NhrDocumentList component and get test files:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentList.tsx
Tool results:
→ result (ok): 1 import { getPagedData } from '#utils/nhrPaginationHelpers'
2 import { SpinnerLoader } from '@doctolib/design-system/SpinnerLoader'
3 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
4 import { useMemo, useState } from 'react'
5
6 import type { ActionConfig, ColumnConfig, FilterConfig, NhrPatientInfo } from '../../types'
7 import { NhrDocumentListFilterPanel } from '../NhrDocumentListFilterPanel/NhrDocumentListFilterPanel'
8 import { NhrDocumentListHeader } from '../Nhr
…(truncated, 3084 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListTable/NhrDocumentListTable.test.tsx
Tool results:
→ result (ok): 1 import { setup } from '@doctolib/test-helpers'
2 import { screen } from '@testing-library/react'
3 import { describe, expect, it } from 'vitest'
4
5 import { mockColumns, mockRows } from '../../../test-helpers'
6 import { NhrDocumentListTable } from './NhrDocumentListTable'
7
8 const defaultPaginationProps = {
9 currentPage: 1,
10 total: 0,
11 onPageChange: () => {},
12 }
13
14 describe('NhrDocumentListTable', () => {
15 it('should render a table', () => {
16 setup(<NhrDocumentL
…(truncated, 1991 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrEntryPoint/NhrEntryPoint.test.tsx
Tool results:
→ result (ok): 1 import { t } from '#i18n'
2 import { setup } from '@doctolib/test-helpers'
3 import { screen } from '@testing-library/react'
4 import { describe, expect, it, vi } from 'vitest'
5
6 import { mockColumns, mockPatientInfo } from '../../test-helpers'
7 import { NhrEntryPoint } from './NhrEntryPoint'
8
9 describe('NhrEntryPoint', () => {
10 it('should render the button if show_ins_features flag in patient is true and status is enabled', () => {
11 setup(
12 <NhrEntryPoint
13 p
…(truncated, 2240 more chars)
Let me get the DMP variant implementation and mapper:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/useDmpDocumentListVariant.ts
Tool results:
→ result (ok): 1 import { columnsFactory } from './factories/columnsFactory'
2 import { filtersFactory } from './factories/filtersFactory'
3 import type { NhrDocumentListVariant, DocumentSearchOptions } from '../types'
4 import useDmpSearchDocuments from '../../hooks/useSearchDocuments'
5 import { mapFiltersToSearchDocumentsParams } from './mappers/mapFiltersToSearchDocumentsParams'
6
7 export const useDmpDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant => {
8 const
…(truncated, 207 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/mappers/mapFiltersToSearchDocumentsParams.ts
Tool results:
→ result (ok): 1 import type { NhrDocumentSearchParams } from '@doctolib/tpf-national-health-records'
2 import { DOCUMENT_STATUS, DOCUMENT_VISIBILITY } from '@doctolib/dmp'
3 import type { ServerFilters } from '../../types'
4 import { toNhrPatientInformation } from '../../../business/mappers/toNhrPatientInformation'
5
6 // Maps UI-level ServerFilters to the NhrDocumentSearchParams format expected by the NHR API.
7 // Each ServerFilters field needs an explicit mapping — field names do not match NhrDocumentSear
…(truncated, 2415 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src -name "*test*" -type f | head -10
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/generateNhrDocuments.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/factories/columnsFactory.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/factories/filtersFactory.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/mappers/mapF …(truncated, 521 more chars)
Let me read some key test files to understand how pagination is tested:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.test.ts
Tool results:
→ result (ok): 1 import React from 'react' 2 import { renderHook } from '@testing-library/react' 3 import { QueryClient, QueryClientProvider } from '@tanstack/react-query-v5' 4 import * as variationManagement from '@doctolib/variation_management' 5 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 6 import type { NhrDocument, NhrDocumentSearchParams } from '@doctolib/tpf-national-health-records' 7 import { useNationalHealthRecords } from './useNationalHealthRecords' 8 import { generat …(truncated, 12586 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/utils/nhrPaginationHelpers.test.ts
Tool results:
→ result (ok): 1 import { describe, expect, it } from 'vitest'
2
3 import { PAGE_SIZE, getPagedData } from './nhrPaginationHelpers'
4
5 describe('PAGE_SIZE', () => {
6 it('should be 20', () => {
7 expect(PAGE_SIZE).toBe(20)
8 })
9 })
10
11 describe('getPagedData', () => {
12 it('should return undefined when data is undefined', () => {
13 expect(getPagedData(undefined, 1)).toBeUndefined()
14 })
15
16 it('should return empty array when data is empty', () => {
17 expect(getPagedData([],
…(truncated, 1741 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentList.test.tsx
Tool results:
→ result (ok): 1 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
2 import { render, screen } from '@testing-library/react'
3 // eslint-disable-next-line import/no-extraneous-dependencies, @doctolib-tpf/no-undeclared-dependencies
4 import { userEvent } from '@testing-library/user-event'
5 import { describe, expect, it, vi } from 'vitest'
6
7 import type { ColumnConfig, FilterConfig, NhrPatientInfo } from '../../types'
8 import { NhrDocumentList } from './NhrDocumentList'
9
10 // Mock
…(truncated, 10820 more chars)
Perfect! Now I have a comprehensive view of the pagination implementation. Let me create a summary document with all the findings.
Pagination Implementation Analysis
I have thoroughly explored both projects and identified their pagination implementations. Here's the complete breakdown:
PROJECT 1: TREATMENT-PLAN
/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src
1. Pagination Helpers
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/utils/nhrPaginationHelpers.ts
- PAGE_SIZE constant: 20 documents per page
- getPagedData function: Generic client-side pagination using array slicing
- Takes data array and currentPage number
- Returns slice of data for that page
- Returns undefined if data is undefined
2. Main Entry Point
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrEntryPoint/NhrEntryPoint.tsx (53 lines)
- Props: searchDocuments callback function
- Type: SearchDocumentsFn = (appliedFilters?: Record<string, unknown>) => Promise<{ data: NhrDocument[]; total?: number }>
- Returns: Renders NhrEntryPointButton + NhrDocumentListModal
- Condition: Only renders if patient.show_ins_features is true AND status === 'enabled'
- Integration: Passes searchDocuments callback down to modal
3. Document List Table (with Pagination)
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListTable/NhrDocumentListTable.tsx (39 lines)
export type NhrDocumentListTableProps = {
columns: ColumnConfig[]
isLoading?: boolean
rows?: NhrDocument[]
actions?: ActionConfig[]
currentPage: number // Pagination state
onPageChange: (page: number) => void // Page change handler
total: number // Total results count
}
- Rendering: Uses Design System's
<Pagination>component - Props: Passes
currentPage,total,nbRowsPerPage={PAGE_SIZE},onPageChange - Data: Shows only
rows(already paginated data from parent)
4. Document List Container (Pagination Logic)
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentList.tsx (93 lines)
export type NhrDocumentListProps = {
data?: NhrDocument[]
resultCount?: number // Server-side total
appliedFilters?: Record<string, unknown>
onApplyFilters?: (filters: Record<string, unknown>) => void
// ... other props
}
- State:
currentPage(useState, local client-side) - Pagination Logic:
1. Stores
currentPagein local state 2. When filters applied → resets to page 1:setCurrentPage(1)3. UsesgetPagedData(data, currentPage)to slice data for current page 4. PassescurrentPage,total,onPageChangeto NhrDocumentListTable 5. Total calculation: UsesresultCountProp ?? data?.length ?? 0
5. Modal (Fetches All Data)
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx (89 lines)
export type NhrDocumentListModalProps = {
searchDocuments: SearchDocumentsFn
}
- State:
rows: Array of documentstotal: Total count from serverisLoading: Loading stateappliedFilters: Current filter state- Fetch Logic (useEffect):
- Triggers on
searchDocumentsorappliedFilterschanges - Calls
searchDocuments(appliedFilters) - Expects response:
{ data, total } - Stores full data set + total count
- Pattern: Server returns ALL matching results; client handles pagination
6. Type Definitions
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/types.ts
export type SearchDocumentsFn = (
appliedFilters?: Record<string, unknown>
) => Promise<{ data: NhrDocument[]; total?: number }>
7. Package Exports
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts
- Exports: NhrEntryPoint, SearchDocumentsFn, column/filter factories, actions builders
8. Tests
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/utils/nhrPaginationHelpers.test.ts
- Tests PAGE_SIZE === 20
- Tests getPagedData slicing for all page scenarios (pages 1, 2, 3, partial pages, beyond range)
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListTable/NhrDocumentListTable.test.tsx
- Tests pagination rendering and display
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentList.test.tsx
- Tests: first page display (docs 1-20), page 2 navigation (docs 21-25), filter → reset to page 1
- Tests: resultCount prop override and fallback to data.length
- Tests controlled mode (appliedFilters + onApplyFilters props)
PROJECT 2: MONOLITH
/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src
1. Search Documents Hook (Integration with React Query)
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts (61 lines)
interface UseSearchDocumentsProps {
patient: Patient
mapFiltersToSearchDocumentsParams: MapFiltersToSearchDocumentsParams
}
const useSearchDocuments = ({
patient,
mapFiltersToSearchDocumentsParams,
}: UseSearchDocumentsProps): NhrDocumentListVariant['searchDocuments']
- Returns:
async (appliedFilters?: Record<string, unknown>) => Promise<{ data, total }> - Caching Strategy:
- Uses
queryClient.fetchQuery()with React Query - Query key:
['dmp-documents', ins, appliedFilters] - Stale time: 5 minutes (close + reopen within 5 min → cache hit)
- Retry Logic:
- Max retries: 3 (for network errors)
- Skip retries for
DMPAccessDeniedByExcededThresholderror (EX_3.1-2035) - Mock Support:
- Feature flag:
nhr_document_list_search_mocked - When enabled: returns generated mock documents
- Edge Cases:
- No INS → returns
{ data: [], total: 0 } - Returns
total: documents.length(all results count)
2. Variant Types
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
interface SearchDocumentsResult {
data: NhrDocument[]
total: number
}
export type NhrDocumentListVariant = {
columns: ColumnConfig[]
filters: FilterConfig[]
searchDocuments: (appliedFilters?: Record<string, unknown>) => Promise<SearchDocumentsResult>
}
export type ServerFilters = BaseServerFilters & DmpServerFilters
export type BaseServerFilters = {
typeCodes?: string[]
dateType?: 'shareDate' | 'procedureDate'
submissionDateFrom?: string
submissionDateTo?: string
}
export type DmpServerFilters = {
includeArchived?: boolean
includeObsolete?: boolean
includeMaskedToProfessionals?: boolean
includeInvisibleToPatient?: boolean
includeInvisibleToLegalReps?: boolean
}
3. Variant Selector Hook
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts (20 lines)
export const useNhrDocumentListVariant = (
patient: DocumentSearchOptions['patient']
): NhrDocumentListVariant | null => {
const dmpVariant = useDmpDocumentListVariant(patient)
return useProductLineVariation<NhrDocumentListVariant>({
variants: {
[ProductLineKey.EhrFranceDefault]: dmpVariant,
[ProductLineKey.EhrFrancePhysiotherapists]: null,
[ProductLineKey.EhrFranceN
…(truncated, 5143 more chars)