125 lines
4.4 KiB
JavaScript
125 lines
4.4 KiB
JavaScript
import { useCallback, useEffect, useMemo } from "react";
|
|
import { HasFeatureAccess } from "./../feature-wrapper/feature-wrapper.component";
|
|
|
|
/**
|
|
* Custom hook to preserve form data for conditionally hidden fields based on feature access
|
|
* @param {Object} form - Ant Design form instance
|
|
* @param {Object} bodyshop - Bodyshop data for feature access checks (also contains existing database values)
|
|
* @param {Object} featureConfig - Configuration object defining which features and their associated fields to preserve
|
|
*/
|
|
export const useFormDataPreservation = (form, bodyshop, featureConfig) => {
|
|
// Safe nested getters/setters using path arrays
|
|
const getNestedValue = (obj, path) => path?.reduce((acc, key) => acc?.[key], obj);
|
|
const setNestedValue = (obj, path, value) => {
|
|
const lastKey = path[path.length - 1];
|
|
const parent = path.slice(0, -1).reduce((curr, key) => {
|
|
if (!curr[key] || typeof curr[key] !== "object") curr[key] = {};
|
|
return curr[key];
|
|
}, obj);
|
|
parent[lastKey] = value;
|
|
};
|
|
|
|
// Paths for features that are NOT accessible
|
|
const disabledPaths = useMemo(() => {
|
|
const result = [];
|
|
if (!featureConfig) return result;
|
|
Object.entries(featureConfig).forEach(([featureName, fieldPaths]) => {
|
|
const hasAccess = HasFeatureAccess({ featureName, bodyshop });
|
|
if (hasAccess || !Array.isArray(fieldPaths)) return;
|
|
fieldPaths.forEach((p) => Array.isArray(p) && p.length && result.push(p));
|
|
});
|
|
return result;
|
|
}, [featureConfig, bodyshop]);
|
|
|
|
const preserveHiddenFormData = useCallback(() => {
|
|
const currentValues = form.getFieldsValue();
|
|
const preservationData = {};
|
|
let hasAny = false;
|
|
|
|
disabledPaths.forEach((path) => {
|
|
let value = getNestedValue(currentValues, path);
|
|
if (value == null) value = getNestedValue(bodyshop, path);
|
|
if (value != null) {
|
|
setNestedValue(preservationData, path, value);
|
|
hasAny = true;
|
|
}
|
|
});
|
|
|
|
if (hasAny) form.setFieldsValue(preservationData);
|
|
}, [form, bodyshop, disabledPaths]);
|
|
|
|
const getCompleteFormValues = () => {
|
|
const currentValues = form.getFieldsValue();
|
|
const complete = { ...currentValues };
|
|
|
|
disabledPaths.forEach((path) => {
|
|
let value = getNestedValue(currentValues, path);
|
|
if (value == null) value = getNestedValue(bodyshop, path);
|
|
if (value != null) setNestedValue(complete, path, value);
|
|
});
|
|
|
|
return complete;
|
|
};
|
|
|
|
const createSubmissionHandler = (originalHandler) => {
|
|
return () => {
|
|
const completeValues = getCompleteFormValues();
|
|
|
|
// Call the original handler with complete values including hidden data
|
|
return originalHandler(completeValues);
|
|
};
|
|
};
|
|
|
|
useEffect(() => {
|
|
preserveHiddenFormData();
|
|
}, [bodyshop, preserveHiddenFormData]);
|
|
|
|
return { preserveHiddenFormData, getCompleteFormValues, createSubmissionHandler };
|
|
};
|
|
|
|
/**
|
|
* Predefined feature configurations for common shop-info components
|
|
*/
|
|
export const FEATURE_CONFIGS = {
|
|
responsibilitycenters: {
|
|
export: [
|
|
["md_responsibility_centers", "costs"],
|
|
["md_responsibility_centers", "profits"],
|
|
["md_responsibility_centers", "defaults"],
|
|
["md_responsibility_centers", "dms_defaults"],
|
|
["md_responsibility_centers", "taxes"],
|
|
["md_responsibility_centers", "cieca_pfl"],
|
|
["md_responsibility_centers", "ar"],
|
|
["md_responsibility_centers", "refund"],
|
|
["md_responsibility_centers", "sales_tax_codes"],
|
|
["md_responsibility_centers", "ttl_adjustment"],
|
|
["md_responsibility_centers", "ttl_tax_adjustment"]
|
|
]
|
|
},
|
|
general: {
|
|
export: [
|
|
["accountingconfig", "qbo"],
|
|
["accountingconfig", "qbo_usa"],
|
|
["accountingconfig", "qbo_departmentid"],
|
|
["accountingconfig", "tiers"],
|
|
["accountingconfig", "twotierpref"],
|
|
["accountingconfig", "printlater"],
|
|
["accountingconfig", "emaillater"],
|
|
["accountingconfig", "ReceivableCustomField1"],
|
|
["accountingconfig", "ReceivableCustomField2"],
|
|
["accountingconfig", "ReceivableCustomField3"],
|
|
["md_classes"],
|
|
["enforce_class"],
|
|
["accountingconfig", "ClosingPeriod"],
|
|
["accountingconfig", "companyCode"],
|
|
["accountingconfig", "batchID"]
|
|
],
|
|
bills: [
|
|
["bill_tax_rates", "federal_tax_rate"],
|
|
["bill_tax_rates", "state_tax_rate"],
|
|
["bill_tax_rates", "local_tax_rate"]
|
|
],
|
|
timetickets: [["tt_allow_post_to_invoiced"], ["tt_enforce_hours_for_tech_console"], ["bill_allow_post_to_closed"]]
|
|
}
|
|
};
|