formanitor 0.0.31 → 0.0.32
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 +212 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -3
- package/dist/index.d.ts +19 -3
- package/dist/index.mjs +211 -2
- 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' | '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;
|
|
3
|
+
type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'media_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;
|
|
@@ -112,6 +112,12 @@ interface ImageUploadFieldDef extends BaseFieldDef {
|
|
|
112
112
|
maxSize?: number;
|
|
113
113
|
acceptedTypes?: string[];
|
|
114
114
|
}
|
|
115
|
+
interface MediaUploadFieldDef extends BaseFieldDef {
|
|
116
|
+
type: 'media_upload';
|
|
117
|
+
maxSize?: number;
|
|
118
|
+
/** Default: images (image/*) and application/pdf */
|
|
119
|
+
acceptedTypes?: string[];
|
|
120
|
+
}
|
|
115
121
|
interface SignatureFieldDef extends BaseFieldDef {
|
|
116
122
|
type: 'signature';
|
|
117
123
|
canvasWidth?: number;
|
|
@@ -302,7 +308,7 @@ interface DoctorFrequentItems {
|
|
|
302
308
|
investigations?: InvestigationFrequentItem[];
|
|
303
309
|
procedures?: ProcedureFrequentItem[];
|
|
304
310
|
}
|
|
305
|
-
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
|
|
311
|
+
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | MediaUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
|
|
306
312
|
interface Condition {
|
|
307
313
|
field?: string;
|
|
308
314
|
op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
|
|
@@ -720,6 +726,10 @@ declare const ImageUploadWidget: React.FC<{
|
|
|
720
726
|
fieldId: string;
|
|
721
727
|
}>;
|
|
722
728
|
|
|
729
|
+
declare const MediaUploadWidget: React.FC<{
|
|
730
|
+
fieldId: string;
|
|
731
|
+
}>;
|
|
732
|
+
|
|
723
733
|
declare const SignatureUploadWidget: React.FC<{
|
|
724
734
|
fieldId: string;
|
|
725
735
|
}>;
|
|
@@ -730,6 +740,12 @@ interface ReadOnlyImageUploadProps {
|
|
|
730
740
|
}
|
|
731
741
|
declare const ReadOnlyImageUpload: React.FC<ReadOnlyImageUploadProps>;
|
|
732
742
|
|
|
743
|
+
interface ReadOnlyMediaUploadProps {
|
|
744
|
+
fieldDef: BaseFieldDef;
|
|
745
|
+
value: any;
|
|
746
|
+
}
|
|
747
|
+
declare const ReadOnlyMediaUpload: React.FC<ReadOnlyMediaUploadProps>;
|
|
748
|
+
|
|
733
749
|
interface ReadOnlySignatureProps {
|
|
734
750
|
fieldDef: BaseFieldDef;
|
|
735
751
|
value: any;
|
|
@@ -910,4 +926,4 @@ declare const SmartTextareaWidget: React.FC<{
|
|
|
910
926
|
fieldId: string;
|
|
911
927
|
}>;
|
|
912
928
|
|
|
913
|
-
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 };
|
|
929
|
+
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 MediaUploadFieldDef, MediaUploadWidget, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, 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' | '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;
|
|
3
|
+
type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'media_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;
|
|
@@ -112,6 +112,12 @@ interface ImageUploadFieldDef extends BaseFieldDef {
|
|
|
112
112
|
maxSize?: number;
|
|
113
113
|
acceptedTypes?: string[];
|
|
114
114
|
}
|
|
115
|
+
interface MediaUploadFieldDef extends BaseFieldDef {
|
|
116
|
+
type: 'media_upload';
|
|
117
|
+
maxSize?: number;
|
|
118
|
+
/** Default: images (image/*) and application/pdf */
|
|
119
|
+
acceptedTypes?: string[];
|
|
120
|
+
}
|
|
115
121
|
interface SignatureFieldDef extends BaseFieldDef {
|
|
116
122
|
type: 'signature';
|
|
117
123
|
canvasWidth?: number;
|
|
@@ -302,7 +308,7 @@ interface DoctorFrequentItems {
|
|
|
302
308
|
investigations?: InvestigationFrequentItem[];
|
|
303
309
|
procedures?: ProcedureFrequentItem[];
|
|
304
310
|
}
|
|
305
|
-
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
|
|
311
|
+
type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | MediaUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
|
|
306
312
|
interface Condition {
|
|
307
313
|
field?: string;
|
|
308
314
|
op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
|
|
@@ -720,6 +726,10 @@ declare const ImageUploadWidget: React.FC<{
|
|
|
720
726
|
fieldId: string;
|
|
721
727
|
}>;
|
|
722
728
|
|
|
729
|
+
declare const MediaUploadWidget: React.FC<{
|
|
730
|
+
fieldId: string;
|
|
731
|
+
}>;
|
|
732
|
+
|
|
723
733
|
declare const SignatureUploadWidget: React.FC<{
|
|
724
734
|
fieldId: string;
|
|
725
735
|
}>;
|
|
@@ -730,6 +740,12 @@ interface ReadOnlyImageUploadProps {
|
|
|
730
740
|
}
|
|
731
741
|
declare const ReadOnlyImageUpload: React.FC<ReadOnlyImageUploadProps>;
|
|
732
742
|
|
|
743
|
+
interface ReadOnlyMediaUploadProps {
|
|
744
|
+
fieldDef: BaseFieldDef;
|
|
745
|
+
value: any;
|
|
746
|
+
}
|
|
747
|
+
declare const ReadOnlyMediaUpload: React.FC<ReadOnlyMediaUploadProps>;
|
|
748
|
+
|
|
733
749
|
interface ReadOnlySignatureProps {
|
|
734
750
|
fieldDef: BaseFieldDef;
|
|
735
751
|
value: any;
|
|
@@ -910,4 +926,4 @@ declare const SmartTextareaWidget: React.FC<{
|
|
|
910
926
|
fieldId: string;
|
|
911
927
|
}>;
|
|
912
928
|
|
|
913
|
-
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 };
|
|
929
|
+
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 MediaUploadFieldDef, MediaUploadWidget, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, 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
|
@@ -423,7 +423,7 @@ var FormStore = class {
|
|
|
423
423
|
result[field.id] = parts.length > 0 ? parts.join("\n\n") : null;
|
|
424
424
|
return;
|
|
425
425
|
}
|
|
426
|
-
if (field.type === "image_upload" || field.type === "signature") {
|
|
426
|
+
if (field.type === "image_upload" || field.type === "media_upload" || field.type === "signature") {
|
|
427
427
|
const raw = values[field.id];
|
|
428
428
|
if (raw !== void 0 && raw !== null && raw !== "") {
|
|
429
429
|
const key = typeof raw === "string" ? raw : raw.s3_key || raw.value || null;
|
|
@@ -2151,6 +2151,162 @@ var ImageUploadWidget = ({ fieldId }) => {
|
|
|
2151
2151
|
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
2152
2152
|
] });
|
|
2153
2153
|
};
|
|
2154
|
+
function urlLooksLikePdf(url) {
|
|
2155
|
+
return /\.pdf($|\?)/i.test(url) || url.toLowerCase().includes("application/pdf");
|
|
2156
|
+
}
|
|
2157
|
+
function isAcceptedMediaFile(file) {
|
|
2158
|
+
if (file.type.startsWith("image/")) return true;
|
|
2159
|
+
if (file.type === "application/pdf") return true;
|
|
2160
|
+
if (file.name.toLowerCase().endsWith(".pdf")) return true;
|
|
2161
|
+
return false;
|
|
2162
|
+
}
|
|
2163
|
+
var MediaUploadWidget = ({ fieldId }) => {
|
|
2164
|
+
const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
|
|
2165
|
+
const store = useFormStore();
|
|
2166
|
+
const { state } = useForm();
|
|
2167
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
2168
|
+
const [preview, setPreview] = useState(null);
|
|
2169
|
+
const [previewIsPdf, setPreviewIsPdf] = useState(false);
|
|
2170
|
+
const fileInputRef = useRef(null);
|
|
2171
|
+
const pendingPreviewKindRef = useRef(null);
|
|
2172
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
2173
|
+
if (!fieldDef) return null;
|
|
2174
|
+
const uploadHandler = store.getUploadHandler();
|
|
2175
|
+
if (!uploadHandler) {
|
|
2176
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2177
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
2178
|
+
fieldDef.label,
|
|
2179
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
2180
|
+
] }),
|
|
2181
|
+
/* @__PURE__ */ jsx("div", { className: "border-2 border-red-300 rounded-lg p-4 bg-red-50", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600", children: "Upload handler not configured. Please provide an onUpload function in FormProvider config." }) })
|
|
2182
|
+
] });
|
|
2183
|
+
}
|
|
2184
|
+
React15__default.useEffect(() => {
|
|
2185
|
+
if (value && typeof value === "string") {
|
|
2186
|
+
setPreview(value);
|
|
2187
|
+
if (pendingPreviewKindRef.current) {
|
|
2188
|
+
setPreviewIsPdf(pendingPreviewKindRef.current === "pdf");
|
|
2189
|
+
pendingPreviewKindRef.current = null;
|
|
2190
|
+
} else {
|
|
2191
|
+
setPreviewIsPdf(urlLooksLikePdf(value));
|
|
2192
|
+
}
|
|
2193
|
+
} else {
|
|
2194
|
+
setPreview(null);
|
|
2195
|
+
setPreviewIsPdf(false);
|
|
2196
|
+
}
|
|
2197
|
+
}, [value]);
|
|
2198
|
+
const handleFileSelect = async (event) => {
|
|
2199
|
+
const file = event.target.files?.[0];
|
|
2200
|
+
if (!file) return;
|
|
2201
|
+
if (!isAcceptedMediaFile(file)) {
|
|
2202
|
+
alert("Please select an image or PDF file");
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
const maxSize = 10 * 1024 * 1024;
|
|
2206
|
+
if (file.size > maxSize) {
|
|
2207
|
+
alert("File size must be less than 10MB");
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2210
|
+
const isPdf = file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf");
|
|
2211
|
+
setIsUploading(true);
|
|
2212
|
+
setTouched();
|
|
2213
|
+
store.incrementPendingUploads();
|
|
2214
|
+
try {
|
|
2215
|
+
const previewUrl = URL.createObjectURL(file);
|
|
2216
|
+
setPreview(previewUrl);
|
|
2217
|
+
setPreviewIsPdf(isPdf);
|
|
2218
|
+
const s3Key = await uploadHandler(file, file.name);
|
|
2219
|
+
pendingPreviewKindRef.current = isPdf ? "pdf" : "image";
|
|
2220
|
+
setValue(s3Key);
|
|
2221
|
+
} catch (error2) {
|
|
2222
|
+
console.error("Upload failed:", error2);
|
|
2223
|
+
const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
|
|
2224
|
+
alert(errorMessage);
|
|
2225
|
+
setPreview(null);
|
|
2226
|
+
setPreviewIsPdf(false);
|
|
2227
|
+
} finally {
|
|
2228
|
+
setIsUploading(false);
|
|
2229
|
+
store.decrementPendingUploads();
|
|
2230
|
+
}
|
|
2231
|
+
};
|
|
2232
|
+
const handleRemove = () => {
|
|
2233
|
+
pendingPreviewKindRef.current = null;
|
|
2234
|
+
setValue(null);
|
|
2235
|
+
setPreview(null);
|
|
2236
|
+
setPreviewIsPdf(false);
|
|
2237
|
+
if (fileInputRef.current) {
|
|
2238
|
+
fileInputRef.current.value = "";
|
|
2239
|
+
}
|
|
2240
|
+
setTouched();
|
|
2241
|
+
};
|
|
2242
|
+
const handleUploadClick = () => {
|
|
2243
|
+
fileInputRef.current?.click();
|
|
2244
|
+
};
|
|
2245
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2246
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
2247
|
+
fieldDef.label,
|
|
2248
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
2249
|
+
] }),
|
|
2250
|
+
/* @__PURE__ */ jsx("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-4", children: preview ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2251
|
+
previewIsPdf ? /* @__PURE__ */ jsx(
|
|
2252
|
+
"iframe",
|
|
2253
|
+
{
|
|
2254
|
+
src: preview,
|
|
2255
|
+
title: "Uploaded PDF",
|
|
2256
|
+
className: "w-full max-h-48 min-h-36 rounded-lg border border-gray-200 bg-white"
|
|
2257
|
+
}
|
|
2258
|
+
) : /* @__PURE__ */ jsx(
|
|
2259
|
+
"img",
|
|
2260
|
+
{
|
|
2261
|
+
src: preview,
|
|
2262
|
+
alt: "Uploaded image",
|
|
2263
|
+
className: "max-w-full max-h-48 mx-auto rounded-lg"
|
|
2264
|
+
}
|
|
2265
|
+
),
|
|
2266
|
+
/* @__PURE__ */ jsx(
|
|
2267
|
+
Button,
|
|
2268
|
+
{
|
|
2269
|
+
type: "button",
|
|
2270
|
+
variant: "destructive",
|
|
2271
|
+
size: "sm",
|
|
2272
|
+
className: "absolute top-2 right-2",
|
|
2273
|
+
onClick: handleRemove,
|
|
2274
|
+
disabled: disabled || isUploading,
|
|
2275
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
2276
|
+
}
|
|
2277
|
+
)
|
|
2278
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
2279
|
+
/* @__PURE__ */ jsx(Image, { className: "h-12 w-12 mx-auto text-gray-400 mb-4" }),
|
|
2280
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mb-4", children: "Click to upload an image or PDF, or drag and drop" }),
|
|
2281
|
+
/* @__PURE__ */ jsxs(
|
|
2282
|
+
Button,
|
|
2283
|
+
{
|
|
2284
|
+
type: "button",
|
|
2285
|
+
variant: "outline",
|
|
2286
|
+
onClick: handleUploadClick,
|
|
2287
|
+
disabled: disabled || isUploading,
|
|
2288
|
+
children: [
|
|
2289
|
+
/* @__PURE__ */ jsx(Upload, { className: "h-4 w-4 mr-2" }),
|
|
2290
|
+
isUploading ? "Uploading..." : "Choose Image"
|
|
2291
|
+
]
|
|
2292
|
+
}
|
|
2293
|
+
)
|
|
2294
|
+
] }) }),
|
|
2295
|
+
/* @__PURE__ */ jsx(
|
|
2296
|
+
"input",
|
|
2297
|
+
{
|
|
2298
|
+
ref: fileInputRef,
|
|
2299
|
+
type: "file",
|
|
2300
|
+
accept: "image/*,application/pdf",
|
|
2301
|
+
onChange: handleFileSelect,
|
|
2302
|
+
className: "hidden",
|
|
2303
|
+
disabled: disabled || isUploading
|
|
2304
|
+
}
|
|
2305
|
+
),
|
|
2306
|
+
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description }),
|
|
2307
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
2308
|
+
] });
|
|
2309
|
+
};
|
|
2154
2310
|
var distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
2155
2311
|
var smoothPoint = (prev, curr, smoothing = 0.75) => {
|
|
2156
2312
|
if (!prev) return curr;
|
|
@@ -7415,6 +7571,8 @@ function renderWidget(fieldId, fieldDef) {
|
|
|
7415
7571
|
return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
|
|
7416
7572
|
case "image_upload":
|
|
7417
7573
|
return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
|
|
7574
|
+
case "media_upload":
|
|
7575
|
+
return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
|
|
7418
7576
|
case "signature":
|
|
7419
7577
|
return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
|
|
7420
7578
|
case "editable_table":
|
|
@@ -7822,6 +7980,55 @@ var ReadOnlyImageUpload = ({
|
|
|
7822
7980
|
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description })
|
|
7823
7981
|
] });
|
|
7824
7982
|
};
|
|
7983
|
+
function urlLooksLikePdf2(url) {
|
|
7984
|
+
return /\.pdf($|\?)/i.test(url) || url.toLowerCase().includes("application/pdf");
|
|
7985
|
+
}
|
|
7986
|
+
var ReadOnlyMediaUpload = ({
|
|
7987
|
+
fieldDef,
|
|
7988
|
+
value
|
|
7989
|
+
}) => {
|
|
7990
|
+
const [useIframe, setUseIframe] = useState(false);
|
|
7991
|
+
let url = null;
|
|
7992
|
+
if (typeof value === "string") {
|
|
7993
|
+
url = value;
|
|
7994
|
+
} else if (value && typeof value === "object") {
|
|
7995
|
+
const typed = value;
|
|
7996
|
+
url = typed.presigned_url || typed.value || typed.s3_key || null;
|
|
7997
|
+
}
|
|
7998
|
+
useEffect(() => {
|
|
7999
|
+
setUseIframe(false);
|
|
8000
|
+
}, [url]);
|
|
8001
|
+
const showAsPdf = url && (urlLooksLikePdf2(url) || useIframe);
|
|
8002
|
+
if (!url) {
|
|
8003
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8004
|
+
/* @__PURE__ */ jsx(Label, { children: fieldDef.label }),
|
|
8005
|
+
/* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg p-4 bg-gray-50", children: /* @__PURE__ */ jsxs("div", { className: "text-center py-4", children: [
|
|
8006
|
+
/* @__PURE__ */ jsx(Image, { className: "h-8 w-8 mx-auto text-gray-400 mb-2" }),
|
|
8007
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No file uploaded" })
|
|
8008
|
+
] }) })
|
|
8009
|
+
] });
|
|
8010
|
+
}
|
|
8011
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8012
|
+
/* @__PURE__ */ jsx(Label, { children: fieldDef.label }),
|
|
8013
|
+
/* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg p-4 bg-white", children: showAsPdf ? /* @__PURE__ */ jsx(
|
|
8014
|
+
"iframe",
|
|
8015
|
+
{
|
|
8016
|
+
src: url,
|
|
8017
|
+
title: `${fieldDef.label} PDF`,
|
|
8018
|
+
className: "w-full max-h-48 min-h-36 rounded-lg border border-gray-200 bg-white"
|
|
8019
|
+
}
|
|
8020
|
+
) : /* @__PURE__ */ jsx(
|
|
8021
|
+
"img",
|
|
8022
|
+
{
|
|
8023
|
+
src: url,
|
|
8024
|
+
alt: `${fieldDef.label} upload`,
|
|
8025
|
+
className: "max-w-full max-h-48 mx-auto rounded-lg",
|
|
8026
|
+
onError: () => setUseIframe(true)
|
|
8027
|
+
}
|
|
8028
|
+
) }),
|
|
8029
|
+
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description })
|
|
8030
|
+
] });
|
|
8031
|
+
};
|
|
7825
8032
|
var ReadOnlySignature = ({
|
|
7826
8033
|
fieldDef,
|
|
7827
8034
|
value
|
|
@@ -8023,6 +8230,8 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
|
8023
8230
|
return /* @__PURE__ */ jsx(ReadOnlyRepeatable, { fieldDef, value });
|
|
8024
8231
|
case "image_upload":
|
|
8025
8232
|
return /* @__PURE__ */ jsx(ReadOnlyImageUpload, { fieldDef, value });
|
|
8233
|
+
case "media_upload":
|
|
8234
|
+
return /* @__PURE__ */ jsx(ReadOnlyMediaUpload, { fieldDef, value });
|
|
8026
8235
|
case "signature":
|
|
8027
8236
|
return /* @__PURE__ */ jsx(ReadOnlySignature, { fieldDef, value });
|
|
8028
8237
|
case "editable_table":
|
|
@@ -8230,6 +8439,6 @@ function createUploadHandler(options) {
|
|
|
8230
8439
|
};
|
|
8231
8440
|
}
|
|
8232
8441
|
|
|
8233
|
-
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
|
8442
|
+
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MediaUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
|
8234
8443
|
//# sourceMappingURL=index.mjs.map
|
|
8235
8444
|
//# sourceMappingURL=index.mjs.map
|