From bc4cd89739bac152b94ea643e08179f366ae70d2 Mon Sep 17 00:00:00 2001 From: Swathi-eGov Date: Mon, 13 Oct 2025 14:16:30 +0530 Subject: [PATCH] Referring mobile number validations from global configs or from mdms --- .../micro-ui-internals/example/package.json | 2 +- .../packages/modules/pgr/src/hooks/index.js | 2 + .../pgr/src/hooks/pgr/useMobileValidation.js | 128 ++++++++++++++++++ .../src/pages/citizen/Create/CitizenCreate.js | 44 +++++- .../pages/employee/CreateComplaint/index.js | 45 +++++- .../pgr/src/pages/employee/PGRInbox.js | 43 +++++- frontend/micro-ui/web/package.json | 2 +- 7 files changed, 259 insertions(+), 7 deletions(-) create mode 100644 frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/pgr/useMobileValidation.js diff --git a/frontend/micro-ui/web/micro-ui-internals/example/package.json b/frontend/micro-ui/web/micro-ui-internals/example/package.json index fa0e665a..d86c8b3a 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/package.json +++ b/frontend/micro-ui/web/micro-ui-internals/example/package.json @@ -11,7 +11,7 @@ "devDependencies": { "@egovernments/digit-ui-libraries": "1.8.15", "@egovernments/digit-ui-components": "0.2.0-beta.45", - "@egovernments/digit-ui-module-core": "1.8.44", + "@egovernments/digit-ui-module-core": "1.8.55", "@egovernments/digit-ui-module-utilities": "1.0.12", "@egovernments/digit-ui-react-components": "1.8.21", "@egovernments/digit-ui-module-health-pgr": "0.0.1", diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/index.js index 860b5fb7..d4d09fbc 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/index.js @@ -6,6 +6,7 @@ import useCreateComplaint from "./pgr/useCreateComplaint"; import usePGRSearch from "./pgr/usePGRSearch"; import usePGRUpdate from "./pgr/usePGRUpdate"; import useServiceDefs from "./pgr/useServiceDefs"; +import useMobileValidation from "./pgr/useMobileValidation"; const pgr = { useProjectSearch, @@ -15,6 +16,7 @@ const pgr = { usePGRSearch, usePGRUpdate, useServiceDefs, + useMobileValidation, }; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/pgr/useMobileValidation.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/pgr/useMobileValidation.js new file mode 100644 index 00000000..31fbdfde --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/hooks/pgr/useMobileValidation.js @@ -0,0 +1,128 @@ +import { useQuery } from "react-query"; + +/** + * Custom hook to fetch mobile number validation configuration from MDMS + * Priority: + * 1. Global configs (window.globalConfigs?.getConfig("CORE_MOBILE_CONFIGS")) + * 2. MDMS configs (ValidationConfigs.mobileNumberValidation) + * 3. Default fallback validation + * @param {string} tenantId - The tenant ID + * @param {string} validationName - The validation name (default: "defaultMobileValidation") + * @returns {object} - Returns validation rules and loading state + */ +const useMobileValidation = (tenantId, validationName = "defaultMobileValidation") => { + const reqCriteria = { + url: `/mdms-v2/v1/_search`, + params: { + tenantId: tenantId, + }, + body: { + MdmsCriteria: { + tenantId: tenantId, + "moduleDetails": [ + { + "moduleName": "ValidationConfigs", + "masterDetails": [ + { + "name": "mobileNumberValidation" + } + ] + } + ] + }, + }, + config: { + enabled: !!tenantId, + select: (data) => { + return data.MdmsRes; + }, + }, + }; + // Fetch project staff details using custom API hook + const { isLoading, data, error } = Digit.Hooks.useCustomAPIHook(reqCriteria); + + /** ---------- Priority 1: Global Config ---------- */ + const globalConfig = window?.globalConfigs?.getConfig?.("CORE_MOBILE_CONFIGS") || {}; + + + // Extract validation rules + const mdmsConfig = data?.ValidationConfigs?.mobileNumberValidation?.find( + (config) => config.validationName === validationName + ); + + // Default fallback validation if MDMS fails + const defaultValidation = { + validationName: "defaultMobileValidation", + rules: { + allowedStartingDigits: ["6", "7", "8", "9"], + prefix: "+91", + pattern: "^[6-9][0-9]{9}$", + minLength: 10, + maxLength: 10, + errorMessage: "Please enter a valid 10-digit mobile number starting with 6-9", + isActive: true, + }, + }; + + /** ---------- Combine configs with priority ---------- */ + const validationRules = { + allowedStartingDigits: + globalConfig?.mobileNumberAllowedStartingDigits || mdmsConfig?.rules?.allowedStartingDigits || defaultValidation?.rules?.allowedStartingDigits, + + prefix: + globalConfig?.mobilePrefix || + mdmsConfig?.rules?.prefix || + defaultValidation?.rules?.prefix, + + pattern: + globalConfig?.mobileNumberPattern || + mdmsConfig?.rules?.pattern || + defaultValidation?.rules?.pattern, + + minLength: + globalConfig?.mobileNumberLength || + mdmsConfig?.rules?.minLength || + defaultValidation?.rules?.minLength, + + maxLength: + globalConfig?.mobileNumberLength || + mdmsConfig?.rules?.maxLength || + defaultValidation?.rules?.maxLength, + + errorMessage: + globalConfig?.mobileNumberErrorMessage || mdmsConfig?.rules?.errorMessage || defaultValidation?.rules?.errorMessage, + + isActive: (mdmsConfig && mdmsConfig.rules && mdmsConfig.rules.isActive !== undefined) + ? mdmsConfig.rules.isActive + : (defaultValidation && defaultValidation.rules && defaultValidation.rules.isActive !== undefined) + ? defaultValidation.rules.isActive + : true + + }; + + + // Helper function to get min/max values for number validation + const getMinMaxValues = () => { + const { allowedStartingDigits, minLength } = validationRules; + if (!allowedStartingDigits || allowedStartingDigits.length === 0) { + return { min: 0, max: 9999999999 }; + } + + const minDigit = Math.min(...allowedStartingDigits.map(Number)); + const maxDigit = Math.max(...allowedStartingDigits.map(Number)); + + const min = minDigit * Math.pow(10, minLength - 1); + const max = (maxDigit + 1) * Math.pow(10, minLength - 1) - 1; + + return { min, max }; + }; + + return { + validationRules, + isLoading, + error, + getMinMaxValues, + }; +}; + +export default useMobileValidation; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Create/CitizenCreate.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Create/CitizenCreate.js index 4e755cae..7d4bc848 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Create/CitizenCreate.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Create/CitizenCreate.js @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next"; import { Redirect, Route, Switch, useHistory, useRouteMatch, useLocation } from "react-router-dom"; import { FormComposerCitizen} from "@egovernments/digit-ui-components"; import { newConfig as baseConfig } from "./CreateCommonConfig"; +import { Loader } from "@egovernments/digit-ui-components"; // import { newConfig } from "../../configs/IndividualCreateConfig"; // import { transformIndividualCreateData } from "../../utils/createUtils"; @@ -11,6 +12,10 @@ const IndividualCreateCitizen = () => { const tenantId = Digit.ULBService.getCurrentTenantId(); const { t } = useTranslation(); + + // Fetch mobile validation config from MDMS + const { validationRules, isLoading: isValidationLoading, getMinMaxValues } = Digit.Hooks.pgr.useMobileValidation(tenantId); + const reqCreate = { url: `/individual/v1/_create`, params: {}, @@ -22,6 +27,40 @@ const IndividualCreateCitizen = () => { const mutation = Digit.Hooks.useCustomAPIMutationHook(reqCreate); + // Inject mobile validation rules from MDMS into the config + const config = useMemo(() => { + if (!validationRules) return baseConfig; + + const { min, max } = getMinMaxValues(); + + return baseConfig.map((section) => { + if (section.head === "Create Individual") { + return { + ...section, + body: section.body.map((field) => { + if (field.key === "phno" && field.type === "number") { + return { + ...field, + populators: { + ...field.populators, + validation: { + min: min, + max: max, + minlength: validationRules.minLength, + maxlength: validationRules.maxLength, + pattern: validationRules.pattern, + }, + error: validationRules.errorMessage || field.populators.error, + }, + }; + } + return field; + }), + }; + } + return section; + }); + }, [validationRules]); const onFormSubmit = async (data) => { @@ -36,10 +75,13 @@ const IndividualCreateCitizen = () => { }); }; + if (isValidationLoading) { + return ; + } return (
- { console.log(formData, "formData"); }} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/CreateComplaint/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/CreateComplaint/index.js index b888ecab..34747eb4 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/CreateComplaint/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/CreateComplaint/index.js @@ -29,6 +29,9 @@ const CreateComplaint = () => { const CreateComplaintSession = Digit.Hooks.useSessionStorage("COMPLAINT_CREATE", {}); const [sessionFormData, setSessionFormData, clearSessionFormData] = CreateComplaintSession; + // Fetch mobile validation config from MDMS + const { validationRules, isLoading: isValidationLoading, getMinMaxValues } = Digit.Hooks.pgr.useMobileValidation(tenantId); + // Fetch MDMS config for Create Complaint screen (RAINMAKER-PGR.CreateComplaintConfig) const { data: mdmsData, isLoading } = Digit.Hooks.useCommonMDMS( Digit.ULBService.getStateId(), @@ -45,15 +48,53 @@ const CreateComplaint = () => { // const serviceDefs = Digit.Hooks.pgr.useServiceDefs(tenantId, "PGR"); // Use MDMS config if available, otherwise fallback to local static config - const configs = mdmsData || CreateComplaintConfig?.CreateComplaintConfig?.[0]; + let configs = mdmsData || CreateComplaintConfig?.CreateComplaintConfig?.[0]; /** * Preprocess config using translation and inject complaint types into the serviceCode dropdown + * and inject mobile validation from MDMS */ + // Inject mobile validation rules from MDMS into the config + if (configs && validationRules) { + const { min, max } = getMinMaxValues(); + configs = { + ...configs, + form: configs.form.map((section) => { + if (section.head === "ES_CREATECOMPLAINT_PROVIDE_COMPLAINANT_DETAILS") { + return { + ...section, + body: section.body.map((field) => { + if (field.label === "COMPLAINTS_COMPLAINANT_CONTACT_NUMBER") { + return { + ...field, + populators: { + ...field.populators, + componentInFront: validationRules.prefix, + validation: { + required: true, + minlength: validationRules.minLength, + maxlength: validationRules.maxLength, + min: min, + max: max, + pattern: validationRules.pattern, + }, + error: validationRules.errorMessage || "CORE_COMMON_MOBILE_ERROR", + }, + }; + } + return field; + }), + }; + } + return section; + }), + }; + } + // Show loader while fetching MDMS config - if (isLoading || !configs) { + if (isLoading || isValidationLoading || !configs) { return ; } diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/PGRInbox.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/PGRInbox.js index e672cce2..690a948e 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/PGRInbox.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/PGRInbox.js @@ -41,6 +41,9 @@ const PGRSearchInbox = () => { // Used to detect route/location changes to trigger config reset const location = useLocation(); + // Fetch mobile validation config from MDMS + const { validationRules, isLoading: isValidationLoading } = Digit.Hooks.pgr.useMobileValidation(tenantId); + // Fetch MDMS config for inbox screen (RAINMAKER-PGR.SearchInboxConfig) const { data: mdmsData, isLoading } = Digit.Hooks.useCommonMDMS( Digit.ULBService.getStateId(), @@ -56,7 +59,43 @@ const PGRSearchInbox = () => { ); // Fallback to static config if MDMS is not available - const configs = mdmsData || PGRSearchInboxConfig(); + let configs = mdmsData || PGRSearchInboxConfig(); + + // Inject mobile validation rules from MDMS into the search config + if (configs && validationRules && configs.sections?.search?.uiConfig?.fields) { + const { min, max } = getMinMaxValues(); + configs = { + ...configs, + sections: { + ...configs.sections, + search: { + ...configs.sections.search, + uiConfig: { + ...configs.sections.search.uiConfig, + fields: configs.sections.search.uiConfig.fields.map((field) => { + if (field.label === "CS_COMMON_MOBILE_NO" && field.populators?.name === "mobileNumber") { + return { + ...field, + populators: { + ...field.populators, + validation: { + minlength: validationRules.minLength, + maxlength: validationRules.maxLength, + min: min, + max: max, + pattern: validationRules.pattern, + }, + error: validationRules.errorMessage || field.populators.error, + }, + }; + } + return field; + }), + }, + }, + }, + }; + } // Fetch the list of service definitions (e.g., complaint types) for current tenant const serviceDefs = Digit.Hooks.pgr.useServiceDefs(tenantId, "PGR"); @@ -92,7 +131,7 @@ const PGRSearchInbox = () => { /** * Show loader until necessary data is available */ - if (isLoading || !pageConfig || serviceDefs?.length === 0) { + if (isLoading || isValidationLoading || !pageConfig || serviceDefs?.length === 0) { return ; } diff --git a/frontend/micro-ui/web/package.json b/frontend/micro-ui/web/package.json index 5e9ed005..7fe3e1aa 100644 --- a/frontend/micro-ui/web/package.json +++ b/frontend/micro-ui/web/package.json @@ -15,7 +15,7 @@ "homepage": "/digit-ui", "dependencies": { "@egovernments/digit-ui-libraries": "1.8.14", - "@egovernments/digit-ui-module-core": "1.8.44", + "@egovernments/digit-ui-module-core": "1.8.55", "@egovernments/digit-ui-module-utilities": "1.0.12", "@egovernments/digit-ui-react-components": "1.8.21", "@egovernments/digit-ui-svg-components": "1.0.21",