pagamio-frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
104 lines (103 loc) • 5.86 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useForm } from 'react-hook-form';
import { useEffect, useState } from 'react';
import { Button } from '../../components';
import { FieldWrapper } from '../../form-engine';
const DrawerContent = ({ fields, onSubmit, isOpen, initialValues, submitButtonText = 'Submit', cancelButtonText = 'Cancel', handleCloseDrawer, onFieldUpdate, updateFieldOptions, updataFieldLabel, setFieldHidden, addField, updateFieldValidation, }) => {
const { control, handleSubmit, watch, setValue, clearErrors, formState: { errors, isSubmitting }, reset, getValues, } = useForm({ mode: 'onBlur', defaultValues: initialValues });
const [submitError, setSubmitError] = useState(null);
const password = watch('password');
// Watch all form fields for dependency tracking
const allFieldValues = watch();
// Set up field dependencies for watching
useEffect(() => {
if (onFieldUpdate) {
const allDependencies = new Set();
for (const [, updates] of Object.entries(onFieldUpdate)) {
for (const update of updates) {
if (update.dependencies) {
update.dependencies.forEach((dependency) => allDependencies.add(dependency));
}
else {
// For backward compatibility - watch the main field itself
allDependencies.add(update.field);
}
}
}
}
}, [onFieldUpdate]);
useEffect(() => {
if (isOpen && onFieldUpdate) {
const processInitialDependencies = async () => {
for (const [fieldName, updates] of Object.entries(onFieldUpdate)) {
const currentValue = getValues(fieldName);
for (const update of updates) {
try {
const result = await update.action(currentValue);
if (result) {
if (result.hideField !== undefined && setFieldHidden) {
setFieldHidden(result.field, result.hideField);
}
}
}
catch (error) {
console.error(`Error processing initial dependency for ${fieldName}:`, error);
}
}
}
};
processInitialDependencies().then();
}
}, [isOpen, onFieldUpdate]);
const handleFormSubmit = async (data) => {
setSubmitError(null);
try {
const visibleFieldsData = Object.fromEntries(Object.entries(data).filter(([key]) => !fields.find((field) => field.name === key && field.isHidden)));
await onSubmit(visibleFieldsData);
}
catch (error) {
setSubmitError(error instanceof Error ? error.message : 'An error occurred');
}
};
useEffect(() => {
// only reset the form the drawer is closed
if (!isOpen) {
reset();
}
}, [isOpen]);
// Helper function to process dependency validations
const processDependencyValidation = (field) => {
if (!field.validation?.dependency) {
return field.validation;
}
const dependencies = Array.isArray(field.validation.dependency)
? field.validation.dependency
: [field.validation.dependency];
let finalValidation = { ...field.validation };
delete finalValidation.dependency;
// Apply each dependency validation if its condition is met
for (const dep of dependencies) {
const dependencyValue = watch(dep.field);
if (dep.condition(dependencyValue)) {
finalValidation = { ...finalValidation, ...dep.validationToApply };
}
}
return {
...finalValidation,
validate: field.name === 'confirmPassword'
? (value) => value === password || 'Passwords do not match'
: finalValidation.validate,
};
};
return (_jsxs(_Fragment, { children: [_jsxs("form", { className: "grid grid-cols-12 gap-2 align-middle mb-6 border-gray-400 px-6 py-5", onSubmit: handleSubmit(handleFormSubmit), children: [fields?.map((field) => (_jsx(FieldWrapper, { field: {
...field,
validation: processDependencyValidation(field),
}, control: control, errors: errors, layout: "vertical", onFieldUpdate: onFieldUpdate, allFieldValues: allFieldValues, updateFieldOptions: updateFieldOptions, updataFieldLabel: updataFieldLabel, setFieldHidden: setFieldHidden, addField: addField, setValue: setValue, clearErrors: clearErrors, getValues: getValues }, field.name))), isSubmitting && _jsx("span", { children: "Submitting..." }), submitError && _jsx("p", { className: "text-red-500", children: submitError })] }), _jsxs("div", { className: "flex border-t bg-white", style: {
height: '50px',
position: 'fixed',
bottom: 0,
zIndex: 100,
width: '420px',
}, children: [_jsx(Button, { className: "bg-white border-customPurple-5 text-customPurple-15 hover:bg-customPurple-25 hover:text-white w-full flex-1 h-full rounded-none", disabled: isSubmitting, onClick: handleCloseDrawer, children: cancelButtonText }), _jsx(Button, { className: "bg-customPurple-15 text-white hover:bg-customPurple-15 flex-1 h-full rounded-none", disabled: isSubmitting, onClick: handleSubmit(handleFormSubmit), children: submitButtonText })] })] }));
};
export default DrawerContent;