File Map
Source file locations for all Lab Forms components in livehealth-frontend, plus key design decisions.
File Map & Design Decisions
Admin Configuration
Root: src/components/LabAdmin/LabForms/
LabForms/
├── styles.module.scss # Shared styles
├── utils/
│ ├── interface.ts # LabFormConfigList, LabFormSubprocess, LabFormQuestion, LabFormPresetCategory
│ ├── constants.ts # ~30 constants: field type mappers, process type options, date formats, etc.
│ └── helpers.ts # ~25 functions: API calls, navigation, validation, data transform
├── components/
│ ├── index.tsx # LabFormConfiguration — main list page
│ ├── LabFormConfiguration/
│ │ ├── labFormConfigurationList.tsx # AG Grid config list
│ │ ├── emptyLabFormConfiguration.tsx # Empty state with CTAs
│ │ ├── AddConfigViaPresetModal/
│ │ │ ├── index.tsx # Preset picker modal (full screen)
│ │ │ ├── labFormPresetList.tsx # AG Grid preset list
│ │ │ ├── labFormPresetPreview.tsx # Disabled form preview
│ │ │ └── labFormPresetSidebar.tsx # Virtualized category sidebar
│ │ ├── EnableDisableConfigurationModal/
│ │ │ └── index.tsx # Enable/disable confirmation
│ │ └── MapConfigurationsToInstancesModal/
│ │ └── index.tsx # Bulk instance mapping modal
│ └── AddEditConfiguration/
│ ├── index.tsx # AddEditLabFormConfiguration — main add/edit page
│ ├── BasicInformation/
│ │ ├── index.tsx # Form metadata fields
│ │ ├── MappedTests/
│ │ │ ├── mapTests.tsx # Test/profile/promotion selector
│ │ │ ├── mappedTestsList.tsx # AG Grid with mapped items
│ │ │ └── style.css # Grid height overrides
│ │ └── SwitchProcessTypeConfirmationModal/
│ │ └── index.tsx # Process type change warning
│ └── FormComponents/
│ ├── index.tsx # LabFormComponents — drag & drop builder
│ ├── labFormComponentSidebar.tsx # Nested section/question sidebar
│ ├── FormComponentsMenu/
│ │ ├── index.tsx # Multi-level add menu
│ │ ├── MenuActions.ts # handleAddSection, field type definitions
│ │ └── ImportSectionModal/
│ │ └── index.tsx # Import section from other config
│ ├── Section/
│ │ ├── index.tsx # SectionComponent — section editor
│ │ ├── AddCommunicationSectionModal/index.tsx
│ │ ├── DeleteSectionModal/index.tsx
│ │ └── EditExistingSectionModal/index.tsx
│ └── Question/
│ ├── index.tsx # QuestionComponent — question editor
│ ├── AddQuestionModal/index.tsx
│ ├── DeleteQuestionModal/index.tsx
│ ├── EditExistingQuestionModal/index.tsx
│ └── QuestionAttributes/
│ ├── interface.ts
│ ├── commonQuestionAttributes.tsx
│ ├── textQuestionAttributes.tsx
│ ├── numberQuestionAttributes.tsx
│ ├── floatQuestionAttributes.tsx
│ ├── optionsQuestionAttributes.tsx
│ ├── dateQuestionAttributes.tsx
│ └── fileQuestionAttributes.tsxAOE Capturing
Root: src/components/reusable/Billing/components/AOE/
AOE/
├── AOEModal.tsx # Full-screen modal shell
├── AOEForm.tsx # Form renderer (iterates questions)
├── AOEModalFooter.tsx # Navigation + skip logic trigger
├── AOEQuestionValueConfirmationModal.tsx # Confirmation message modal
├── interface.ts # AOEFormProps, SkipFormMapping, QuestionValueKeyMeta
├── utils.ts # 1726 lines: navigation, validation, field props, skip logic, prefilling
└── styles.module.scssRedux Layer
src/redux/
├── types/LabFormTypes.ts # 23 action constants, 20+ interfaces, union type
├── reducers/LabFormReducer.ts # LabFormState, 15 reducer cases
└── actions/LabFormActions.ts # 26 exports: sync actions, thunks, validatorsServices
src/services/LabForms/
├── interface.ts # BillConsentDetails, BillAOEDetails, AOEDetails, UpdateAOESavePayload
└── labForms.ts # getBillConsentDetails, getBillAOEDetails, updateBillAOEValuesHistory / Values Viewing
Root: src/components/Registration/Components/LabFormValues/
LabFormValues/
├── services.ts # fetchLabFormValues()
├── helpers.ts # filterLabFormDataByBranch()
├── constants.ts # formTypeDisplayMapper, TEST_INDEPENDENT_PROCESS_TYPES
├── FormValuesGrid.tsx # AG Grid with 30 columns + Edit AOE button
├── AOEDetailsModal.tsx # View/edit AOE responses modal
├── ValuesExportHeader.tsx # Date picker + export + branch filter
├── styles.module.scss
├── Consent/
│ ├── ConsentHistoryNew.tsx
│ └── ConsentValues.tsx
├── AOE/
│ └── AOEValues.tsx
└── PatientInfo/
└── PatientInfoValues.tsxConsent Management
src/components/reusable/ConsentManagement/
├── helpers.ts # 8 API wrappers: fetch, link, unlink, upload, notify, revoke
└── PatientConsentDetails.tsx # Consent details display componentEdit AOE Responses
src/components/reusable/Modals/BillAOE/EditBillAOEResponses/
└── index.tsx # Edit modal with diff payload + save reasonInput Component Mapper
src/components/reusable/crm/
└── inputMapper.tsx # Maps field_type string → React component (18 mappings)Key Design Decisions
Dual-Track State (labForm + updatedFields)
Enables efficient PATCH-style updates by only sending changed fields to the API. Every action creator maintains both in sync. New entities (sections, questions) are only in labForm; existing modified entities appear in both.
Shared Section Guards
Sections can be reused across multiple configurations. Editing a shared section shows a warning modal listing all affected configs. The user must explicitly opt-in via allowUpdate, allowQuestionAdd, allowQuestionUpdate flags.
UUID-Based New Entities
New sections and questions receive a client-generated UUID instead of a server ID. This allows the UI to track them locally before they are persisted. The id || uuid pattern is used throughout for identity checks.
Resequencing After Delete
When a section or question is removed, all subsequent items have their sequence numbers decremented to maintain contiguous ordering. This ensures the backend receives a clean, gapless sequence on save.
Communication Sections
Consent forms support a special section type (for_communication: true) with pre-configured communication preference questions. These sections cannot be added back once deleted and do not allow adding new questions. They must use reserved question codes (sms_communication, email_communication, etc.).
Skip-To Navigation (Destructive In-Memory)
Skip-to logic physically modifies the aoeForms array at runtime — removing intermediate forms, sections, and questions. This is intentionally destructive on the in-memory state: once a skip is applied, earlier sections are gone from the active session. The persisted configuration is never modified.
Instance Mapping Diffing
The system tracks addedInstanceIds and removedInstanceIds separately against the original config, rather than sending the full list. This allows the backend to efficiently process partial updates without reprocessing unchanged mappings.
AG Grid for All Tables
Configuration lists, mapped tests, form values history, and options editing all use AG Grid for consistent behavior including sorting, filtering, multi-select, Excel export, and controlled row height.