formanitor 0.0.27 → 0.0.28
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 +175 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -3
- package/dist/index.d.ts +35 -3
- package/dist/index.mjs +175 -0
- 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' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
|
|
3
|
+
type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
|
|
4
4
|
interface ValidationRule {
|
|
5
5
|
min?: number;
|
|
6
6
|
max?: number;
|
|
@@ -209,6 +209,20 @@ interface SmartTextareaValue {
|
|
|
209
209
|
text: string;
|
|
210
210
|
extractedKeywords: ExtractedKeywordMatch[];
|
|
211
211
|
}
|
|
212
|
+
/** Selected diagnosis grade chip (single-selection). */
|
|
213
|
+
interface DiagnosisGradeSelection {
|
|
214
|
+
condition: string;
|
|
215
|
+
grade: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Structured value for diagnosis_textarea fields.
|
|
219
|
+
* - `text` is the textarea content (what will be submitted).
|
|
220
|
+
* - `selectedGradesByCondition` stores one selected chip per condition for later metadata/preview use.
|
|
221
|
+
*/
|
|
222
|
+
interface DiagnosisTextareaValue {
|
|
223
|
+
text: string;
|
|
224
|
+
selectedGradesByCondition: Record<string, string>;
|
|
225
|
+
}
|
|
212
226
|
/**
|
|
213
227
|
* Smart textarea that performs client-side NLP keyword extraction and searches
|
|
214
228
|
* matched terms against backend master tables via `fieldHandlers[fieldId].onSearch`.
|
|
@@ -223,6 +237,19 @@ interface SmartTextareaFieldDef extends BaseFieldDef {
|
|
|
223
237
|
/** Debounce delay in ms before NLP + search triggers. Default: 1000. */
|
|
224
238
|
debounceDelay?: number;
|
|
225
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Diagnosis textarea that can display condition-wise grade chips based on
|
|
242
|
+
* asynchronous API response.
|
|
243
|
+
*
|
|
244
|
+
* Value shape in form state can be plain text (legacy) or `DiagnosisTextareaValue`.
|
|
245
|
+
*/
|
|
246
|
+
interface DiagnosisTextareaFieldDef extends BaseFieldDef {
|
|
247
|
+
type: 'diagnosis_textarea';
|
|
248
|
+
/** Height in pixels. If omitted, uses default min height (80px). */
|
|
249
|
+
height?: number;
|
|
250
|
+
/** Debounce delay in ms before API call triggers. Default: 700. */
|
|
251
|
+
debounceDelay?: number;
|
|
252
|
+
}
|
|
226
253
|
interface MedicationFrequentItem {
|
|
227
254
|
id: string;
|
|
228
255
|
name: string;
|
|
@@ -269,7 +296,7 @@ interface DoctorFrequentItems {
|
|
|
269
296
|
investigations?: InvestigationFrequentItem[];
|
|
270
297
|
procedures?: ProcedureFrequentItem[];
|
|
271
298
|
}
|
|
272
|
-
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | BaseFieldDef;
|
|
299
|
+
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
|
|
273
300
|
interface Condition {
|
|
274
301
|
field?: string;
|
|
275
302
|
op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
|
|
@@ -542,6 +569,11 @@ type FieldHandler = {
|
|
|
542
569
|
label: string;
|
|
543
570
|
value: any;
|
|
544
571
|
}[]>;
|
|
572
|
+
/**
|
|
573
|
+
* Called by diagnosis_textarea widgets to fetch condition-wise grades
|
|
574
|
+
* from diagnosis text input.
|
|
575
|
+
*/
|
|
576
|
+
onFetchDiagnosisGrades?: (query: string) => Promise<any>;
|
|
545
577
|
};
|
|
546
578
|
type FieldHandlersMap = Record<string, FieldHandler>;
|
|
547
579
|
declare function useFieldHandlers(fieldId: string): FieldHandler;
|
|
@@ -860,4 +892,4 @@ declare const SmartTextareaWidget: React.FC<{
|
|
|
860
892
|
fieldId: string;
|
|
861
893
|
}>;
|
|
862
894
|
|
|
863
|
-
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, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, 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 InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, 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 SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, 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, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
|
895
|
+
export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, type DiagnosisGradeSelection, type DiagnosisTextareaFieldDef, type DiagnosisTextareaValue, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, 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 InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, 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 SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, 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, useFrequentItems, useSmartKeywords, 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' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
|
|
3
|
+
type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
|
|
4
4
|
interface ValidationRule {
|
|
5
5
|
min?: number;
|
|
6
6
|
max?: number;
|
|
@@ -209,6 +209,20 @@ interface SmartTextareaValue {
|
|
|
209
209
|
text: string;
|
|
210
210
|
extractedKeywords: ExtractedKeywordMatch[];
|
|
211
211
|
}
|
|
212
|
+
/** Selected diagnosis grade chip (single-selection). */
|
|
213
|
+
interface DiagnosisGradeSelection {
|
|
214
|
+
condition: string;
|
|
215
|
+
grade: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Structured value for diagnosis_textarea fields.
|
|
219
|
+
* - `text` is the textarea content (what will be submitted).
|
|
220
|
+
* - `selectedGradesByCondition` stores one selected chip per condition for later metadata/preview use.
|
|
221
|
+
*/
|
|
222
|
+
interface DiagnosisTextareaValue {
|
|
223
|
+
text: string;
|
|
224
|
+
selectedGradesByCondition: Record<string, string>;
|
|
225
|
+
}
|
|
212
226
|
/**
|
|
213
227
|
* Smart textarea that performs client-side NLP keyword extraction and searches
|
|
214
228
|
* matched terms against backend master tables via `fieldHandlers[fieldId].onSearch`.
|
|
@@ -223,6 +237,19 @@ interface SmartTextareaFieldDef extends BaseFieldDef {
|
|
|
223
237
|
/** Debounce delay in ms before NLP + search triggers. Default: 1000. */
|
|
224
238
|
debounceDelay?: number;
|
|
225
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Diagnosis textarea that can display condition-wise grade chips based on
|
|
242
|
+
* asynchronous API response.
|
|
243
|
+
*
|
|
244
|
+
* Value shape in form state can be plain text (legacy) or `DiagnosisTextareaValue`.
|
|
245
|
+
*/
|
|
246
|
+
interface DiagnosisTextareaFieldDef extends BaseFieldDef {
|
|
247
|
+
type: 'diagnosis_textarea';
|
|
248
|
+
/** Height in pixels. If omitted, uses default min height (80px). */
|
|
249
|
+
height?: number;
|
|
250
|
+
/** Debounce delay in ms before API call triggers. Default: 700. */
|
|
251
|
+
debounceDelay?: number;
|
|
252
|
+
}
|
|
226
253
|
interface MedicationFrequentItem {
|
|
227
254
|
id: string;
|
|
228
255
|
name: string;
|
|
@@ -269,7 +296,7 @@ interface DoctorFrequentItems {
|
|
|
269
296
|
investigations?: InvestigationFrequentItem[];
|
|
270
297
|
procedures?: ProcedureFrequentItem[];
|
|
271
298
|
}
|
|
272
|
-
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | BaseFieldDef;
|
|
299
|
+
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
|
|
273
300
|
interface Condition {
|
|
274
301
|
field?: string;
|
|
275
302
|
op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
|
|
@@ -542,6 +569,11 @@ type FieldHandler = {
|
|
|
542
569
|
label: string;
|
|
543
570
|
value: any;
|
|
544
571
|
}[]>;
|
|
572
|
+
/**
|
|
573
|
+
* Called by diagnosis_textarea widgets to fetch condition-wise grades
|
|
574
|
+
* from diagnosis text input.
|
|
575
|
+
*/
|
|
576
|
+
onFetchDiagnosisGrades?: (query: string) => Promise<any>;
|
|
545
577
|
};
|
|
546
578
|
type FieldHandlersMap = Record<string, FieldHandler>;
|
|
547
579
|
declare function useFieldHandlers(fieldId: string): FieldHandler;
|
|
@@ -860,4 +892,4 @@ declare const SmartTextareaWidget: React.FC<{
|
|
|
860
892
|
fieldId: string;
|
|
861
893
|
}>;
|
|
862
894
|
|
|
863
|
-
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, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, 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 InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, 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 SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, 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, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
|
895
|
+
export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, type DiagnosisGradeSelection, type DiagnosisTextareaFieldDef, type DiagnosisTextareaValue, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, 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 InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, 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 SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, 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, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
package/dist/index.mjs
CHANGED
|
@@ -395,6 +395,11 @@ var FormStore = class {
|
|
|
395
395
|
result[field.id] = raw?.text ?? null;
|
|
396
396
|
return;
|
|
397
397
|
}
|
|
398
|
+
if (field.type === "diagnosis_textarea") {
|
|
399
|
+
const raw = values[field.id];
|
|
400
|
+
result[field.id] = typeof raw === "string" ? raw : raw && typeof raw === "object" ? raw.text ?? null : null;
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
398
403
|
if (field.type === "ophthal_diagnosis") {
|
|
399
404
|
const raw = values[field.id];
|
|
400
405
|
const formatEye = (eyeData, eyeLabel) => {
|
|
@@ -4759,6 +4764,174 @@ var SmartTextareaWidget = ({ fieldId }) => {
|
|
|
4759
4764
|
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
4760
4765
|
] });
|
|
4761
4766
|
};
|
|
4767
|
+
function normalizeDiagnosisGrades(payload) {
|
|
4768
|
+
const result = [];
|
|
4769
|
+
const pushGroup = (conditionRaw, gradesRaw) => {
|
|
4770
|
+
const condition = typeof conditionRaw === "string" ? conditionRaw.trim() : "";
|
|
4771
|
+
if (!condition) return;
|
|
4772
|
+
if (!Array.isArray(gradesRaw)) return;
|
|
4773
|
+
const grades = Array.from(
|
|
4774
|
+
new Set(
|
|
4775
|
+
gradesRaw.map((grade) => typeof grade === "string" ? grade.trim() : "").filter(Boolean)
|
|
4776
|
+
)
|
|
4777
|
+
);
|
|
4778
|
+
if (grades.length === 0) return;
|
|
4779
|
+
result.push({ condition, grades });
|
|
4780
|
+
};
|
|
4781
|
+
const asArrayResponse = payload;
|
|
4782
|
+
if (Array.isArray(asArrayResponse?.diagnosisGrades)) {
|
|
4783
|
+
asArrayResponse.diagnosisGrades.forEach((item) => {
|
|
4784
|
+
pushGroup(item?.condition, item?.grades);
|
|
4785
|
+
});
|
|
4786
|
+
return result;
|
|
4787
|
+
}
|
|
4788
|
+
const asMapResponse = payload;
|
|
4789
|
+
const mapLike = asMapResponse?.field === "diagnosisgrade" && asMapResponse?.value && typeof asMapResponse.value === "object" ? asMapResponse.value : null;
|
|
4790
|
+
if (mapLike) {
|
|
4791
|
+
Object.entries(mapLike).forEach(([condition, grades]) => {
|
|
4792
|
+
pushGroup(condition, grades);
|
|
4793
|
+
});
|
|
4794
|
+
}
|
|
4795
|
+
return result;
|
|
4796
|
+
}
|
|
4797
|
+
var DiagnosisTextareaWidget = ({ fieldId }) => {
|
|
4798
|
+
const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
|
|
4799
|
+
const { state } = useForm();
|
|
4800
|
+
const handler = useFieldHandlers(fieldId);
|
|
4801
|
+
const def = fieldDef;
|
|
4802
|
+
const [gradeGroups, setGradeGroups] = React13__default.useState([]);
|
|
4803
|
+
const [isLoadingGrades, setIsLoadingGrades] = React13__default.useState(false);
|
|
4804
|
+
const normalized = React13__default.useMemo(() => {
|
|
4805
|
+
const raw = value;
|
|
4806
|
+
if (typeof raw === "string") {
|
|
4807
|
+
return { text: raw, selectedGradesByCondition: {} };
|
|
4808
|
+
}
|
|
4809
|
+
if (!raw || typeof raw !== "object") {
|
|
4810
|
+
return { text: "", selectedGradesByCondition: {} };
|
|
4811
|
+
}
|
|
4812
|
+
const text = typeof raw.text === "string" ? raw.text : "";
|
|
4813
|
+
const mapRaw = raw.selectedGradesByCondition;
|
|
4814
|
+
let selectedGradesByCondition = {};
|
|
4815
|
+
if (mapRaw && typeof mapRaw === "object" && !Array.isArray(mapRaw)) {
|
|
4816
|
+
const entries = Object.entries(mapRaw);
|
|
4817
|
+
for (const [condition, gradeRaw] of entries) {
|
|
4818
|
+
if (typeof condition !== "string") continue;
|
|
4819
|
+
if (typeof gradeRaw === "string" && gradeRaw.trim()) {
|
|
4820
|
+
selectedGradesByCondition[condition] = gradeRaw;
|
|
4821
|
+
}
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4824
|
+
const sg = raw.selectedGrade;
|
|
4825
|
+
if (sg && typeof sg === "object" && typeof sg.condition === "string" && typeof sg.grade === "string") {
|
|
4826
|
+
const condition = sg.condition.trim();
|
|
4827
|
+
const grade = sg.grade.trim();
|
|
4828
|
+
if (condition && grade && !selectedGradesByCondition[condition]) {
|
|
4829
|
+
selectedGradesByCondition = { ...selectedGradesByCondition, [condition]: grade };
|
|
4830
|
+
}
|
|
4831
|
+
}
|
|
4832
|
+
return { text, selectedGradesByCondition };
|
|
4833
|
+
}, [value]);
|
|
4834
|
+
const textValue = normalized.text;
|
|
4835
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
4836
|
+
React13__default.useEffect(() => {
|
|
4837
|
+
const query = textValue.trim();
|
|
4838
|
+
const fetchGrades = handler.onFetchDiagnosisGrades;
|
|
4839
|
+
const debounceMs = def?.debounceDelay ?? 1e3;
|
|
4840
|
+
if (!query || !fetchGrades) {
|
|
4841
|
+
setGradeGroups([]);
|
|
4842
|
+
setIsLoadingGrades(false);
|
|
4843
|
+
return;
|
|
4844
|
+
}
|
|
4845
|
+
let isActive = true;
|
|
4846
|
+
const timer = window.setTimeout(async () => {
|
|
4847
|
+
setIsLoadingGrades(true);
|
|
4848
|
+
try {
|
|
4849
|
+
const response = await fetchGrades(query);
|
|
4850
|
+
if (!isActive) return;
|
|
4851
|
+
setGradeGroups(normalizeDiagnosisGrades(response));
|
|
4852
|
+
} catch {
|
|
4853
|
+
if (!isActive) return;
|
|
4854
|
+
setGradeGroups([]);
|
|
4855
|
+
} finally {
|
|
4856
|
+
if (isActive) setIsLoadingGrades(false);
|
|
4857
|
+
}
|
|
4858
|
+
}, debounceMs);
|
|
4859
|
+
return () => {
|
|
4860
|
+
isActive = false;
|
|
4861
|
+
window.clearTimeout(timer);
|
|
4862
|
+
};
|
|
4863
|
+
}, [textValue, handler.onFetchDiagnosisGrades, def?.debounceDelay]);
|
|
4864
|
+
if (!def) return null;
|
|
4865
|
+
const theme = getThemeConfig("textarea", def.theme);
|
|
4866
|
+
const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
|
|
4867
|
+
const labelClass = theme?.labelClassName;
|
|
4868
|
+
const inputClass = cn(theme?.inputClassName, showError && "border-red-500");
|
|
4869
|
+
const toggleSelectedGrade = (condition, grade) => {
|
|
4870
|
+
if (disabled) return;
|
|
4871
|
+
const current = normalized.selectedGradesByCondition[condition];
|
|
4872
|
+
const nextForCondition = current === grade ? "" : grade;
|
|
4873
|
+
const nextMap = { ...normalized.selectedGradesByCondition };
|
|
4874
|
+
if (!nextForCondition) {
|
|
4875
|
+
delete nextMap[condition];
|
|
4876
|
+
} else {
|
|
4877
|
+
nextMap[condition] = nextForCondition;
|
|
4878
|
+
}
|
|
4879
|
+
setValue({ text: normalized.text, selectedGradesByCondition: nextMap });
|
|
4880
|
+
setTouched();
|
|
4881
|
+
};
|
|
4882
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4883
|
+
def.label,
|
|
4884
|
+
" ",
|
|
4885
|
+
def.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
4886
|
+
] });
|
|
4887
|
+
return /* @__PURE__ */ jsxs("div", { className: wrapperClass, children: [
|
|
4888
|
+
theme ? /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, children: labelContent }),
|
|
4889
|
+
/* @__PURE__ */ jsx(
|
|
4890
|
+
Textarea,
|
|
4891
|
+
{
|
|
4892
|
+
id: fieldId,
|
|
4893
|
+
value: textValue,
|
|
4894
|
+
onChange: (e) => setValue({ text: e.target.value, selectedGradesByCondition: normalized.selectedGradesByCondition }),
|
|
4895
|
+
onBlur: setTouched,
|
|
4896
|
+
disabled,
|
|
4897
|
+
placeholder: def.placeholder,
|
|
4898
|
+
className: inputClass,
|
|
4899
|
+
...def.height != null ? { height: def.height } : {}
|
|
4900
|
+
}
|
|
4901
|
+
),
|
|
4902
|
+
isLoadingGrades && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: "Checking diagnosis grades..." }),
|
|
4903
|
+
!isLoadingGrades && gradeGroups.length > 0 && /* @__PURE__ */ jsx(
|
|
4904
|
+
"div",
|
|
4905
|
+
{
|
|
4906
|
+
className: "mt-2 space-y-3 rounded-lg border border-border bg-muted/30 p-3",
|
|
4907
|
+
role: "group",
|
|
4908
|
+
"aria-label": "Diagnosis grade options",
|
|
4909
|
+
children: gradeGroups.map((group) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
4910
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium leading-none text-muted-foreground", children: [
|
|
4911
|
+
group.condition,
|
|
4912
|
+
":"
|
|
4913
|
+
] }),
|
|
4914
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: group.grades.map((grade) => /* @__PURE__ */ jsx(
|
|
4915
|
+
"button",
|
|
4916
|
+
{
|
|
4917
|
+
type: "button",
|
|
4918
|
+
onClick: () => toggleSelectedGrade(group.condition, grade),
|
|
4919
|
+
disabled,
|
|
4920
|
+
className: cn(
|
|
4921
|
+
"inline-flex min-h-8 items-center rounded-full border px-3 py-1 text-xs font-medium leading-none transition-colors",
|
|
4922
|
+
normalized.selectedGradesByCondition[group.condition] === grade ? "border-primary bg-primary/15 text-primary shadow-sm" : "border-border/80 bg-background text-foreground hover:bg-muted/80",
|
|
4923
|
+
disabled && "cursor-not-allowed opacity-60"
|
|
4924
|
+
),
|
|
4925
|
+
children: grade
|
|
4926
|
+
},
|
|
4927
|
+
`${group.condition}-${grade}`
|
|
4928
|
+
)) })
|
|
4929
|
+
] }, group.condition))
|
|
4930
|
+
}
|
|
4931
|
+
),
|
|
4932
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
4933
|
+
] });
|
|
4934
|
+
};
|
|
4762
4935
|
var DEFAULT_DRAFT = {
|
|
4763
4936
|
gpal: { G: 0, P: 0, A: 0, L: 0 },
|
|
4764
4937
|
lmp: "",
|
|
@@ -7112,6 +7285,8 @@ var FieldRenderer = ({ fieldId }) => {
|
|
|
7112
7285
|
return /* @__PURE__ */ jsx(FollowupWidget, { fieldId });
|
|
7113
7286
|
case "smart_textarea":
|
|
7114
7287
|
return /* @__PURE__ */ jsx(SmartTextareaWidget, { fieldId });
|
|
7288
|
+
case "diagnosis_textarea":
|
|
7289
|
+
return /* @__PURE__ */ jsx(DiagnosisTextareaWidget, { fieldId });
|
|
7115
7290
|
case "obstetric_history":
|
|
7116
7291
|
return /* @__PURE__ */ jsx(ObstetricHistoryWidget, { fieldId });
|
|
7117
7292
|
case "eye_prescription":
|