formanitor 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1985 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +247 -4
- package/dist/index.d.ts +247 -4
- package/dist/index.mjs +1983 -128
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
type FieldType = 'text' | 'number' | 'textarea' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | string;
|
|
3
|
+
type FieldType = 'text' | 'number' | 'textarea' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'referral' | 'followup' | string;
|
|
4
4
|
interface ValidationRule {
|
|
5
5
|
min?: number;
|
|
6
6
|
max?: number;
|
|
@@ -42,6 +42,26 @@ interface BaseFieldDef {
|
|
|
42
42
|
disabled?: boolean;
|
|
43
43
|
hidden?: boolean;
|
|
44
44
|
prefill?: FieldPrefill;
|
|
45
|
+
/**
|
|
46
|
+
* High-level column position in SmartForm layout.
|
|
47
|
+
* - "left" and "right" are narrow side columns.
|
|
48
|
+
* - "center" is the main content column and is 2× the width of side columns.
|
|
49
|
+
* Default: "center" when omitted.
|
|
50
|
+
*/
|
|
51
|
+
position?: 'left' | 'center' | 'right';
|
|
52
|
+
/**
|
|
53
|
+
* How many layout columns this field spans horizontally.
|
|
54
|
+
* - 1 = occupies its own column (e.g. just "left", just "center", or just "right")
|
|
55
|
+
* - 2 = spans into an adjacent column (e.g. left+center or center+right)
|
|
56
|
+
* Default: 1.
|
|
57
|
+
*/
|
|
58
|
+
colSpan?: 1 | 2;
|
|
59
|
+
/**
|
|
60
|
+
* Optional theme name for component styling.
|
|
61
|
+
* Renders the field with theme-specific styles (e.g. textarea with "highlight-label"
|
|
62
|
+
* shows the label in a colored block above the input).
|
|
63
|
+
*/
|
|
64
|
+
theme?: string;
|
|
45
65
|
meta?: Record<string, unknown>;
|
|
46
66
|
}
|
|
47
67
|
interface TextFieldDef extends BaseFieldDef {
|
|
@@ -118,7 +138,55 @@ interface StaticTextFieldDef extends BaseFieldDef {
|
|
|
118
138
|
/** Display size. Default: 'regular'. */
|
|
119
139
|
size?: 'regular' | 'large';
|
|
120
140
|
}
|
|
121
|
-
|
|
141
|
+
interface MedicationsFieldDef extends BaseFieldDef {
|
|
142
|
+
type: 'medications';
|
|
143
|
+
}
|
|
144
|
+
interface InvestigationsFieldDef extends BaseFieldDef {
|
|
145
|
+
type: 'investigations';
|
|
146
|
+
}
|
|
147
|
+
interface ProceduresFieldDef extends BaseFieldDef {
|
|
148
|
+
type: 'procedures';
|
|
149
|
+
}
|
|
150
|
+
interface DifferentialDiagnosisFieldDef extends BaseFieldDef {
|
|
151
|
+
type: 'differential_diagnosis';
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* A read-only vitals panel populated by an external API fetch.
|
|
155
|
+
* The consumer provides `onFetch` in `fieldHandlers` for this field ID.
|
|
156
|
+
* The fetched value (raw vitals object) is stored in form state and included in submission.
|
|
157
|
+
*/
|
|
158
|
+
interface VitalsFieldDef extends BaseFieldDef {
|
|
159
|
+
type: 'vitals';
|
|
160
|
+
}
|
|
161
|
+
/** One selected referral. Stored in form state as an array of these. */
|
|
162
|
+
interface ReferralItem {
|
|
163
|
+
specialization: string;
|
|
164
|
+
is_urgent: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Referral field: label "Referral to" with a multiselect dropdown and chips.
|
|
168
|
+
* Value shape: ReferralItem[] e.g. [{ specialization: "Cardiology", is_urgent: false }, ...].
|
|
169
|
+
* Options via fieldHandlers[fieldId].onFetchOptions (e.g. { specializations: string[] }).
|
|
170
|
+
*/
|
|
171
|
+
interface ReferralFieldDef extends BaseFieldDef {
|
|
172
|
+
type: 'referral';
|
|
173
|
+
options?: SelectOption[];
|
|
174
|
+
}
|
|
175
|
+
/** Stored value for followup field: false/null = no followup; object = one-time followup as number of days from current date. */
|
|
176
|
+
interface FollowupValue {
|
|
177
|
+
followupType: 'one time';
|
|
178
|
+
/** Number of days from (current) date when set; always stored as string. */
|
|
179
|
+
value: string;
|
|
180
|
+
unit: 'days';
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Follow-up field: "No Follow-up" | "One Time" with schedule by duration (e.g. 7 days) or by date.
|
|
184
|
+
* Value shape: false | FollowupValue.
|
|
185
|
+
*/
|
|
186
|
+
interface FollowupFieldDef extends BaseFieldDef {
|
|
187
|
+
type: 'followup';
|
|
188
|
+
}
|
|
189
|
+
type FieldDef = TextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | BaseFieldDef;
|
|
122
190
|
interface Condition {
|
|
123
191
|
field?: string;
|
|
124
192
|
op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
|
|
@@ -180,7 +248,25 @@ interface SumComputation {
|
|
|
180
248
|
type: 'sum';
|
|
181
249
|
fields: string[];
|
|
182
250
|
}
|
|
183
|
-
|
|
251
|
+
/** Expression node for formula computation: field ref, number, or binary op. */
|
|
252
|
+
type FormulaExpr = {
|
|
253
|
+
type: 'field';
|
|
254
|
+
field: string;
|
|
255
|
+
} | {
|
|
256
|
+
type: 'number';
|
|
257
|
+
value: number;
|
|
258
|
+
} | {
|
|
259
|
+
type: 'op';
|
|
260
|
+
op: '+' | '-' | '*' | '/' | '**';
|
|
261
|
+
left: FormulaExpr;
|
|
262
|
+
right: FormulaExpr;
|
|
263
|
+
};
|
|
264
|
+
interface FormulaComputation {
|
|
265
|
+
target: string;
|
|
266
|
+
type: 'formula';
|
|
267
|
+
expression: FormulaExpr;
|
|
268
|
+
}
|
|
269
|
+
type Computation = SumComputation | ScoreComputation | FormulaComputation;
|
|
184
270
|
interface FormDef {
|
|
185
271
|
id: string;
|
|
186
272
|
version: number;
|
|
@@ -277,6 +363,15 @@ declare class FormStore {
|
|
|
277
363
|
getFieldDef(fieldId: string): FieldDef | undefined;
|
|
278
364
|
hasPersistence(): boolean;
|
|
279
365
|
setValue(fieldId: string, value: any): void;
|
|
366
|
+
/**
|
|
367
|
+
* Set multiple values at once (e.g. from AI analysis). Only updates keys that
|
|
368
|
+
* exist in the schema. Runs evaluate/notify/save once.
|
|
369
|
+
* @param partial Map of fieldId -> value
|
|
370
|
+
* @param options.touch If false, do not mark fields as touched (e.g. for AI-suggested values)
|
|
371
|
+
*/
|
|
372
|
+
setValues(partial: Record<string, any>, options?: {
|
|
373
|
+
touch?: boolean;
|
|
374
|
+
}): void;
|
|
280
375
|
setTouched(fieldId: string): void;
|
|
281
376
|
setRole(role: string): void;
|
|
282
377
|
load(): Promise<void>;
|
|
@@ -338,9 +433,32 @@ interface RuleResult {
|
|
|
338
433
|
}
|
|
339
434
|
declare function evaluateRules(values: FormValues, rules: Rule[], fields: Record<string, FieldDef>): RuleResult;
|
|
340
435
|
|
|
436
|
+
type FieldHandler = {
|
|
437
|
+
onSearch: (query: string) => Promise<any[]>;
|
|
438
|
+
recentlyUsed?: any[];
|
|
439
|
+
/**
|
|
440
|
+
* Called by widgets that display externally-fetched data (e.g. vitals).
|
|
441
|
+
* Invoked once on mount and again when the user hits the refresh button.
|
|
442
|
+
* The resolved value is written directly into the field's form state.
|
|
443
|
+
*/
|
|
444
|
+
onFetch?: () => Promise<any>;
|
|
445
|
+
/**
|
|
446
|
+
* Called by the referral widget to load dropdown options. May return
|
|
447
|
+
* { specializations: string[] } or { label: string; value: any }[].
|
|
448
|
+
*/
|
|
449
|
+
onFetchOptions?: () => Promise<{
|
|
450
|
+
specializations?: string[];
|
|
451
|
+
} | {
|
|
452
|
+
label: string;
|
|
453
|
+
value: any;
|
|
454
|
+
}[]>;
|
|
455
|
+
};
|
|
456
|
+
type FieldHandlersMap = Record<string, FieldHandler>;
|
|
457
|
+
declare function useFieldHandlers(fieldId: string): FieldHandler;
|
|
341
458
|
interface FormProviderProps {
|
|
342
459
|
schema: FormDef;
|
|
343
460
|
config?: StoreConfig;
|
|
461
|
+
fieldHandlers?: FieldHandlersMap;
|
|
344
462
|
children: React.ReactNode;
|
|
345
463
|
}
|
|
346
464
|
declare const FormProvider: React.FC<FormProviderProps>;
|
|
@@ -376,6 +494,35 @@ declare function useField(fieldId: string): {
|
|
|
376
494
|
|
|
377
495
|
declare const DynamicForm: React.FC;
|
|
378
496
|
|
|
497
|
+
/** Shape of one differential diagnosis item from AI (must match form field value) */
|
|
498
|
+
type AIDifferentialDiagnosisItem = {
|
|
499
|
+
category: string;
|
|
500
|
+
condition: string;
|
|
501
|
+
likelihood: string;
|
|
502
|
+
severity: string;
|
|
503
|
+
treatability: string;
|
|
504
|
+
keyFeatures?: string[];
|
|
505
|
+
nextSteps?: string[];
|
|
506
|
+
};
|
|
507
|
+
interface SmartFormProps {
|
|
508
|
+
/**
|
|
509
|
+
* Structured result from AI analysis (e.g. patient-doctor conversation).
|
|
510
|
+
* When this is set or updated, values are applied to the form by field ID.
|
|
511
|
+
* Only keys that exist in the form schema are applied; unknown keys are ignored.
|
|
512
|
+
* Fields are not marked as "touched" so you can distinguish AI-suggested vs user-edited if needed.
|
|
513
|
+
* Listens to both reference and content changes (e.g. streaming updates to the same object).
|
|
514
|
+
*/
|
|
515
|
+
aiAnalysisResult?: Record<string, any> | null;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Form view that supports applying AI analysis results after load. Use inside
|
|
519
|
+
* FormProvider like DynamicForm. When aiAnalysisResult is provided (e.g. when
|
|
520
|
+
* AI finishes analyzing conversation), its values are applied to the form in
|
|
521
|
+
* one batch without marking fields as touched. Re-applies when the result
|
|
522
|
+
* reference or content changes (e.g. streaming or incremental AI updates).
|
|
523
|
+
*/
|
|
524
|
+
declare const SmartForm: React.FC<SmartFormProps>;
|
|
525
|
+
|
|
379
526
|
interface FieldRendererProps {
|
|
380
527
|
fieldId: string;
|
|
381
528
|
}
|
|
@@ -461,4 +608,100 @@ interface CreateUploadHandlerOptions {
|
|
|
461
608
|
*/
|
|
462
609
|
declare function createUploadHandler(options: CreateUploadHandlerOptions): (file: File | Blob, filename: string) => Promise<string>;
|
|
463
610
|
|
|
464
|
-
|
|
611
|
+
/** Shape of a medication as returned by AI analysis */
|
|
612
|
+
type AIMedication = {
|
|
613
|
+
id: string | number;
|
|
614
|
+
brand_name: string;
|
|
615
|
+
generic_name: string;
|
|
616
|
+
form?: string;
|
|
617
|
+
strength?: string;
|
|
618
|
+
reason?: string;
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
type MedicationSearchResult = {
|
|
622
|
+
id: number;
|
|
623
|
+
name: string;
|
|
624
|
+
generic_name?: string;
|
|
625
|
+
manufacturer?: string;
|
|
626
|
+
score?: number;
|
|
627
|
+
};
|
|
628
|
+
type Medication = {
|
|
629
|
+
id: number;
|
|
630
|
+
brand_name: string;
|
|
631
|
+
generic_name: string;
|
|
632
|
+
frequency: string;
|
|
633
|
+
is_custom: boolean;
|
|
634
|
+
duration_value: string;
|
|
635
|
+
duration_unit: 'days' | 'weeks' | 'months';
|
|
636
|
+
before_after: 'AFTER FOOD' | 'BEFORE FOOD';
|
|
637
|
+
morning: string;
|
|
638
|
+
afternoon: string;
|
|
639
|
+
night: string;
|
|
640
|
+
notes: string;
|
|
641
|
+
};
|
|
642
|
+
type AddMedicationFieldProps = {
|
|
643
|
+
label?: string;
|
|
644
|
+
value: Medication[];
|
|
645
|
+
onChange: (items: Medication[]) => void;
|
|
646
|
+
onSearch: (query: string) => Promise<MedicationSearchResult[]>;
|
|
647
|
+
recentlyUsed?: MedicationSearchResult[];
|
|
648
|
+
/** AI-suggested medications shown as badges; clicking adds to value */
|
|
649
|
+
suggestedMedications?: AIMedication[];
|
|
650
|
+
};
|
|
651
|
+
declare const AddMedicationField: React.FC<AddMedicationFieldProps>;
|
|
652
|
+
|
|
653
|
+
type InvestigationSearchResult = {
|
|
654
|
+
id: string;
|
|
655
|
+
name: string;
|
|
656
|
+
code?: string;
|
|
657
|
+
description?: string;
|
|
658
|
+
categories?: string[];
|
|
659
|
+
synonyms?: string[];
|
|
660
|
+
sample_type?: string;
|
|
661
|
+
method?: string;
|
|
662
|
+
reference_range?: string;
|
|
663
|
+
sample_unit?: string;
|
|
664
|
+
sample_qty?: number;
|
|
665
|
+
turnaround_time?: number;
|
|
666
|
+
preparation?: string;
|
|
667
|
+
service_type?: string;
|
|
668
|
+
department?: string;
|
|
669
|
+
is_vip_enabled?: boolean;
|
|
670
|
+
is_pacs_enabled?: boolean;
|
|
671
|
+
score?: number;
|
|
672
|
+
};
|
|
673
|
+
type Investigation = InvestigationSearchResult & {
|
|
674
|
+
label: string;
|
|
675
|
+
is_custom: boolean;
|
|
676
|
+
fromAI: boolean;
|
|
677
|
+
};
|
|
678
|
+
type AddInvestigationFieldProps = {
|
|
679
|
+
label?: string;
|
|
680
|
+
value: Investigation[];
|
|
681
|
+
onChange: (items: Investigation[]) => void;
|
|
682
|
+
onSearch: (query: string) => Promise<InvestigationSearchResult[]>;
|
|
683
|
+
recentlyUsed?: InvestigationSearchResult[];
|
|
684
|
+
};
|
|
685
|
+
declare const AddInvestigationField: React.FC<AddInvestigationFieldProps>;
|
|
686
|
+
|
|
687
|
+
type DifferentialDiagnosisItem = {
|
|
688
|
+
category: string;
|
|
689
|
+
condition: string;
|
|
690
|
+
likelihood: string;
|
|
691
|
+
severity: string;
|
|
692
|
+
treatability: string;
|
|
693
|
+
keyFeatures?: string[];
|
|
694
|
+
nextSteps?: string[];
|
|
695
|
+
};
|
|
696
|
+
type DifferentialDiagnosisProps = {
|
|
697
|
+
differentialDiagnosis: DifferentialDiagnosisItem[];
|
|
698
|
+
className?: string;
|
|
699
|
+
height?: string;
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* - Outer: rounded border [#D0D0D0], highlight label strip (#FEE8EC)
|
|
703
|
+
* - Body: scrollable list of diagnosis cards with accordion expand/collapse
|
|
704
|
+
*/
|
|
705
|
+
declare const DifferentialDiagnosis: React.FC<DifferentialDiagnosisProps>;
|
|
706
|
+
|
|
707
|
+
export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type FieldDef, type FieldHandler, type FieldHandlersMap, type FieldPrefill, FieldRenderer, type FieldState, type FieldType, type FollowupFieldDef, type FollowupValue, FormControls, type FormControlsProps, type FormDef, type FormErrors, FormProvider, type FormState, FormStore, type FormValues, type FormulaComputation, type FormulaExpr, type ImageUploadFieldDef, ImageUploadWidget, type Investigation, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type Medication, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type Rule, type RuleAction, type RuleResult, type ScoreComputation, type ScoreRange, type Section, type SectionChild, type SelectFieldDef, type SelectOption, type SignatureFieldDef, SignatureUploadWidget, SmartForm, type SmartFormProps, type StaticTextFieldDef, type StoreConfig, type SubmissionData, type SumComputation, type TextFieldDef, type ValidationRule, type VitalsFieldDef, type WebhookDef, type Workflow, type WorkflowTransition, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, validateField, validateForm };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
type FieldType = 'text' | 'number' | 'textarea' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | string;
|
|
3
|
+
type FieldType = 'text' | 'number' | 'textarea' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'referral' | 'followup' | string;
|
|
4
4
|
interface ValidationRule {
|
|
5
5
|
min?: number;
|
|
6
6
|
max?: number;
|
|
@@ -42,6 +42,26 @@ interface BaseFieldDef {
|
|
|
42
42
|
disabled?: boolean;
|
|
43
43
|
hidden?: boolean;
|
|
44
44
|
prefill?: FieldPrefill;
|
|
45
|
+
/**
|
|
46
|
+
* High-level column position in SmartForm layout.
|
|
47
|
+
* - "left" and "right" are narrow side columns.
|
|
48
|
+
* - "center" is the main content column and is 2× the width of side columns.
|
|
49
|
+
* Default: "center" when omitted.
|
|
50
|
+
*/
|
|
51
|
+
position?: 'left' | 'center' | 'right';
|
|
52
|
+
/**
|
|
53
|
+
* How many layout columns this field spans horizontally.
|
|
54
|
+
* - 1 = occupies its own column (e.g. just "left", just "center", or just "right")
|
|
55
|
+
* - 2 = spans into an adjacent column (e.g. left+center or center+right)
|
|
56
|
+
* Default: 1.
|
|
57
|
+
*/
|
|
58
|
+
colSpan?: 1 | 2;
|
|
59
|
+
/**
|
|
60
|
+
* Optional theme name for component styling.
|
|
61
|
+
* Renders the field with theme-specific styles (e.g. textarea with "highlight-label"
|
|
62
|
+
* shows the label in a colored block above the input).
|
|
63
|
+
*/
|
|
64
|
+
theme?: string;
|
|
45
65
|
meta?: Record<string, unknown>;
|
|
46
66
|
}
|
|
47
67
|
interface TextFieldDef extends BaseFieldDef {
|
|
@@ -118,7 +138,55 @@ interface StaticTextFieldDef extends BaseFieldDef {
|
|
|
118
138
|
/** Display size. Default: 'regular'. */
|
|
119
139
|
size?: 'regular' | 'large';
|
|
120
140
|
}
|
|
121
|
-
|
|
141
|
+
interface MedicationsFieldDef extends BaseFieldDef {
|
|
142
|
+
type: 'medications';
|
|
143
|
+
}
|
|
144
|
+
interface InvestigationsFieldDef extends BaseFieldDef {
|
|
145
|
+
type: 'investigations';
|
|
146
|
+
}
|
|
147
|
+
interface ProceduresFieldDef extends BaseFieldDef {
|
|
148
|
+
type: 'procedures';
|
|
149
|
+
}
|
|
150
|
+
interface DifferentialDiagnosisFieldDef extends BaseFieldDef {
|
|
151
|
+
type: 'differential_diagnosis';
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* A read-only vitals panel populated by an external API fetch.
|
|
155
|
+
* The consumer provides `onFetch` in `fieldHandlers` for this field ID.
|
|
156
|
+
* The fetched value (raw vitals object) is stored in form state and included in submission.
|
|
157
|
+
*/
|
|
158
|
+
interface VitalsFieldDef extends BaseFieldDef {
|
|
159
|
+
type: 'vitals';
|
|
160
|
+
}
|
|
161
|
+
/** One selected referral. Stored in form state as an array of these. */
|
|
162
|
+
interface ReferralItem {
|
|
163
|
+
specialization: string;
|
|
164
|
+
is_urgent: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Referral field: label "Referral to" with a multiselect dropdown and chips.
|
|
168
|
+
* Value shape: ReferralItem[] e.g. [{ specialization: "Cardiology", is_urgent: false }, ...].
|
|
169
|
+
* Options via fieldHandlers[fieldId].onFetchOptions (e.g. { specializations: string[] }).
|
|
170
|
+
*/
|
|
171
|
+
interface ReferralFieldDef extends BaseFieldDef {
|
|
172
|
+
type: 'referral';
|
|
173
|
+
options?: SelectOption[];
|
|
174
|
+
}
|
|
175
|
+
/** Stored value for followup field: false/null = no followup; object = one-time followup as number of days from current date. */
|
|
176
|
+
interface FollowupValue {
|
|
177
|
+
followupType: 'one time';
|
|
178
|
+
/** Number of days from (current) date when set; always stored as string. */
|
|
179
|
+
value: string;
|
|
180
|
+
unit: 'days';
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Follow-up field: "No Follow-up" | "One Time" with schedule by duration (e.g. 7 days) or by date.
|
|
184
|
+
* Value shape: false | FollowupValue.
|
|
185
|
+
*/
|
|
186
|
+
interface FollowupFieldDef extends BaseFieldDef {
|
|
187
|
+
type: 'followup';
|
|
188
|
+
}
|
|
189
|
+
type FieldDef = TextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | BaseFieldDef;
|
|
122
190
|
interface Condition {
|
|
123
191
|
field?: string;
|
|
124
192
|
op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
|
|
@@ -180,7 +248,25 @@ interface SumComputation {
|
|
|
180
248
|
type: 'sum';
|
|
181
249
|
fields: string[];
|
|
182
250
|
}
|
|
183
|
-
|
|
251
|
+
/** Expression node for formula computation: field ref, number, or binary op. */
|
|
252
|
+
type FormulaExpr = {
|
|
253
|
+
type: 'field';
|
|
254
|
+
field: string;
|
|
255
|
+
} | {
|
|
256
|
+
type: 'number';
|
|
257
|
+
value: number;
|
|
258
|
+
} | {
|
|
259
|
+
type: 'op';
|
|
260
|
+
op: '+' | '-' | '*' | '/' | '**';
|
|
261
|
+
left: FormulaExpr;
|
|
262
|
+
right: FormulaExpr;
|
|
263
|
+
};
|
|
264
|
+
interface FormulaComputation {
|
|
265
|
+
target: string;
|
|
266
|
+
type: 'formula';
|
|
267
|
+
expression: FormulaExpr;
|
|
268
|
+
}
|
|
269
|
+
type Computation = SumComputation | ScoreComputation | FormulaComputation;
|
|
184
270
|
interface FormDef {
|
|
185
271
|
id: string;
|
|
186
272
|
version: number;
|
|
@@ -277,6 +363,15 @@ declare class FormStore {
|
|
|
277
363
|
getFieldDef(fieldId: string): FieldDef | undefined;
|
|
278
364
|
hasPersistence(): boolean;
|
|
279
365
|
setValue(fieldId: string, value: any): void;
|
|
366
|
+
/**
|
|
367
|
+
* Set multiple values at once (e.g. from AI analysis). Only updates keys that
|
|
368
|
+
* exist in the schema. Runs evaluate/notify/save once.
|
|
369
|
+
* @param partial Map of fieldId -> value
|
|
370
|
+
* @param options.touch If false, do not mark fields as touched (e.g. for AI-suggested values)
|
|
371
|
+
*/
|
|
372
|
+
setValues(partial: Record<string, any>, options?: {
|
|
373
|
+
touch?: boolean;
|
|
374
|
+
}): void;
|
|
280
375
|
setTouched(fieldId: string): void;
|
|
281
376
|
setRole(role: string): void;
|
|
282
377
|
load(): Promise<void>;
|
|
@@ -338,9 +433,32 @@ interface RuleResult {
|
|
|
338
433
|
}
|
|
339
434
|
declare function evaluateRules(values: FormValues, rules: Rule[], fields: Record<string, FieldDef>): RuleResult;
|
|
340
435
|
|
|
436
|
+
type FieldHandler = {
|
|
437
|
+
onSearch: (query: string) => Promise<any[]>;
|
|
438
|
+
recentlyUsed?: any[];
|
|
439
|
+
/**
|
|
440
|
+
* Called by widgets that display externally-fetched data (e.g. vitals).
|
|
441
|
+
* Invoked once on mount and again when the user hits the refresh button.
|
|
442
|
+
* The resolved value is written directly into the field's form state.
|
|
443
|
+
*/
|
|
444
|
+
onFetch?: () => Promise<any>;
|
|
445
|
+
/**
|
|
446
|
+
* Called by the referral widget to load dropdown options. May return
|
|
447
|
+
* { specializations: string[] } or { label: string; value: any }[].
|
|
448
|
+
*/
|
|
449
|
+
onFetchOptions?: () => Promise<{
|
|
450
|
+
specializations?: string[];
|
|
451
|
+
} | {
|
|
452
|
+
label: string;
|
|
453
|
+
value: any;
|
|
454
|
+
}[]>;
|
|
455
|
+
};
|
|
456
|
+
type FieldHandlersMap = Record<string, FieldHandler>;
|
|
457
|
+
declare function useFieldHandlers(fieldId: string): FieldHandler;
|
|
341
458
|
interface FormProviderProps {
|
|
342
459
|
schema: FormDef;
|
|
343
460
|
config?: StoreConfig;
|
|
461
|
+
fieldHandlers?: FieldHandlersMap;
|
|
344
462
|
children: React.ReactNode;
|
|
345
463
|
}
|
|
346
464
|
declare const FormProvider: React.FC<FormProviderProps>;
|
|
@@ -376,6 +494,35 @@ declare function useField(fieldId: string): {
|
|
|
376
494
|
|
|
377
495
|
declare const DynamicForm: React.FC;
|
|
378
496
|
|
|
497
|
+
/** Shape of one differential diagnosis item from AI (must match form field value) */
|
|
498
|
+
type AIDifferentialDiagnosisItem = {
|
|
499
|
+
category: string;
|
|
500
|
+
condition: string;
|
|
501
|
+
likelihood: string;
|
|
502
|
+
severity: string;
|
|
503
|
+
treatability: string;
|
|
504
|
+
keyFeatures?: string[];
|
|
505
|
+
nextSteps?: string[];
|
|
506
|
+
};
|
|
507
|
+
interface SmartFormProps {
|
|
508
|
+
/**
|
|
509
|
+
* Structured result from AI analysis (e.g. patient-doctor conversation).
|
|
510
|
+
* When this is set or updated, values are applied to the form by field ID.
|
|
511
|
+
* Only keys that exist in the form schema are applied; unknown keys are ignored.
|
|
512
|
+
* Fields are not marked as "touched" so you can distinguish AI-suggested vs user-edited if needed.
|
|
513
|
+
* Listens to both reference and content changes (e.g. streaming updates to the same object).
|
|
514
|
+
*/
|
|
515
|
+
aiAnalysisResult?: Record<string, any> | null;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Form view that supports applying AI analysis results after load. Use inside
|
|
519
|
+
* FormProvider like DynamicForm. When aiAnalysisResult is provided (e.g. when
|
|
520
|
+
* AI finishes analyzing conversation), its values are applied to the form in
|
|
521
|
+
* one batch without marking fields as touched. Re-applies when the result
|
|
522
|
+
* reference or content changes (e.g. streaming or incremental AI updates).
|
|
523
|
+
*/
|
|
524
|
+
declare const SmartForm: React.FC<SmartFormProps>;
|
|
525
|
+
|
|
379
526
|
interface FieldRendererProps {
|
|
380
527
|
fieldId: string;
|
|
381
528
|
}
|
|
@@ -461,4 +608,100 @@ interface CreateUploadHandlerOptions {
|
|
|
461
608
|
*/
|
|
462
609
|
declare function createUploadHandler(options: CreateUploadHandlerOptions): (file: File | Blob, filename: string) => Promise<string>;
|
|
463
610
|
|
|
464
|
-
|
|
611
|
+
/** Shape of a medication as returned by AI analysis */
|
|
612
|
+
type AIMedication = {
|
|
613
|
+
id: string | number;
|
|
614
|
+
brand_name: string;
|
|
615
|
+
generic_name: string;
|
|
616
|
+
form?: string;
|
|
617
|
+
strength?: string;
|
|
618
|
+
reason?: string;
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
type MedicationSearchResult = {
|
|
622
|
+
id: number;
|
|
623
|
+
name: string;
|
|
624
|
+
generic_name?: string;
|
|
625
|
+
manufacturer?: string;
|
|
626
|
+
score?: number;
|
|
627
|
+
};
|
|
628
|
+
type Medication = {
|
|
629
|
+
id: number;
|
|
630
|
+
brand_name: string;
|
|
631
|
+
generic_name: string;
|
|
632
|
+
frequency: string;
|
|
633
|
+
is_custom: boolean;
|
|
634
|
+
duration_value: string;
|
|
635
|
+
duration_unit: 'days' | 'weeks' | 'months';
|
|
636
|
+
before_after: 'AFTER FOOD' | 'BEFORE FOOD';
|
|
637
|
+
morning: string;
|
|
638
|
+
afternoon: string;
|
|
639
|
+
night: string;
|
|
640
|
+
notes: string;
|
|
641
|
+
};
|
|
642
|
+
type AddMedicationFieldProps = {
|
|
643
|
+
label?: string;
|
|
644
|
+
value: Medication[];
|
|
645
|
+
onChange: (items: Medication[]) => void;
|
|
646
|
+
onSearch: (query: string) => Promise<MedicationSearchResult[]>;
|
|
647
|
+
recentlyUsed?: MedicationSearchResult[];
|
|
648
|
+
/** AI-suggested medications shown as badges; clicking adds to value */
|
|
649
|
+
suggestedMedications?: AIMedication[];
|
|
650
|
+
};
|
|
651
|
+
declare const AddMedicationField: React.FC<AddMedicationFieldProps>;
|
|
652
|
+
|
|
653
|
+
type InvestigationSearchResult = {
|
|
654
|
+
id: string;
|
|
655
|
+
name: string;
|
|
656
|
+
code?: string;
|
|
657
|
+
description?: string;
|
|
658
|
+
categories?: string[];
|
|
659
|
+
synonyms?: string[];
|
|
660
|
+
sample_type?: string;
|
|
661
|
+
method?: string;
|
|
662
|
+
reference_range?: string;
|
|
663
|
+
sample_unit?: string;
|
|
664
|
+
sample_qty?: number;
|
|
665
|
+
turnaround_time?: number;
|
|
666
|
+
preparation?: string;
|
|
667
|
+
service_type?: string;
|
|
668
|
+
department?: string;
|
|
669
|
+
is_vip_enabled?: boolean;
|
|
670
|
+
is_pacs_enabled?: boolean;
|
|
671
|
+
score?: number;
|
|
672
|
+
};
|
|
673
|
+
type Investigation = InvestigationSearchResult & {
|
|
674
|
+
label: string;
|
|
675
|
+
is_custom: boolean;
|
|
676
|
+
fromAI: boolean;
|
|
677
|
+
};
|
|
678
|
+
type AddInvestigationFieldProps = {
|
|
679
|
+
label?: string;
|
|
680
|
+
value: Investigation[];
|
|
681
|
+
onChange: (items: Investigation[]) => void;
|
|
682
|
+
onSearch: (query: string) => Promise<InvestigationSearchResult[]>;
|
|
683
|
+
recentlyUsed?: InvestigationSearchResult[];
|
|
684
|
+
};
|
|
685
|
+
declare const AddInvestigationField: React.FC<AddInvestigationFieldProps>;
|
|
686
|
+
|
|
687
|
+
type DifferentialDiagnosisItem = {
|
|
688
|
+
category: string;
|
|
689
|
+
condition: string;
|
|
690
|
+
likelihood: string;
|
|
691
|
+
severity: string;
|
|
692
|
+
treatability: string;
|
|
693
|
+
keyFeatures?: string[];
|
|
694
|
+
nextSteps?: string[];
|
|
695
|
+
};
|
|
696
|
+
type DifferentialDiagnosisProps = {
|
|
697
|
+
differentialDiagnosis: DifferentialDiagnosisItem[];
|
|
698
|
+
className?: string;
|
|
699
|
+
height?: string;
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* - Outer: rounded border [#D0D0D0], highlight label strip (#FEE8EC)
|
|
703
|
+
* - Body: scrollable list of diagnosis cards with accordion expand/collapse
|
|
704
|
+
*/
|
|
705
|
+
declare const DifferentialDiagnosis: React.FC<DifferentialDiagnosisProps>;
|
|
706
|
+
|
|
707
|
+
export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type FieldDef, type FieldHandler, type FieldHandlersMap, type FieldPrefill, FieldRenderer, type FieldState, type FieldType, type FollowupFieldDef, type FollowupValue, FormControls, type FormControlsProps, type FormDef, type FormErrors, FormProvider, type FormState, FormStore, type FormValues, type FormulaComputation, type FormulaExpr, type ImageUploadFieldDef, ImageUploadWidget, type Investigation, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type Medication, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type Rule, type RuleAction, type RuleResult, type ScoreComputation, type ScoreRange, type Section, type SectionChild, type SelectFieldDef, type SelectOption, type SignatureFieldDef, SignatureUploadWidget, SmartForm, type SmartFormProps, type StaticTextFieldDef, type StoreConfig, type SubmissionData, type SumComputation, type TextFieldDef, type ValidationRule, type VitalsFieldDef, type WebhookDef, type Workflow, type WorkflowTransition, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, validateField, validateForm };
|