diff --git a/micro-ui/web/core/inter-package.json b/micro-ui/web/core/inter-package.json index af0707eece6..4602f1f42cc 100644 --- a/micro-ui/web/core/inter-package.json +++ b/micro-ui/web/core/inter-package.json @@ -50,6 +50,7 @@ "resolutions": { "**/@babel/runtime": "7.20.1", "**/babel-preset-react-app": "10.0.0", + "**/@babel/traverse":"7.25.9", "**/ajv": "8.11.2", "fast-uri":"2.1.0" }, diff --git a/micro-ui/web/micro-ui-internals/package.json b/micro-ui/web/micro-ui-internals/package.json index f8f56d67ac2..05b2751ef0e 100644 --- a/micro-ui/web/micro-ui-internals/package.json +++ b/micro-ui/web/micro-ui-internals/package.json @@ -57,6 +57,7 @@ "resolutions": { "**/@babel/runtime": "7.20.1", "**/babel-preset-react-app": "10.0.0", + "**/@babel/traverse":"7.25.9", "**/styled-components": "5.0.0", "fast-uri":"2.1.0" }, diff --git a/micro-ui/web/micro-ui-internals/packages/css/package.json b/micro-ui/web/micro-ui-internals/packages/css/package.json index 1dbabf408b3..1ded9719bb9 100644 --- a/micro-ui/web/micro-ui-internals/packages/css/package.json +++ b/micro-ui/web/micro-ui-internals/packages/css/package.json @@ -1,6 +1,6 @@ { "name": "@egovernments/digit-ui-css", - "version": "1.8.10", + "version": "1.8.11", "license": "MIT", "main": "dist/index.css", "author": "Jagankumar ", diff --git a/micro-ui/web/micro-ui-internals/packages/css/src/digitv2/pages/employee/workbench.scss b/micro-ui/web/micro-ui-internals/packages/css/src/digitv2/pages/employee/workbench.scss index 8af10232ef1..226c4653e40 100644 --- a/micro-ui/web/micro-ui-internals/packages/css/src/digitv2/pages/employee/workbench.scss +++ b/micro-ui/web/micro-ui-internals/packages/css/src/digitv2/pages/employee/workbench.scss @@ -1047,4 +1047,58 @@ user-select: none; .diff-code-insert { background-color: #eaffee; } -} \ No newline at end of file + +} + + +.code-details { + padding: 0.5rem 1.5rem; + background-color: #f9f9f9; + border: 0.125rem solid #e0e0e0; + border-radius: 0.25rem; +} + +.code-row { + display: flex; + align-items: flex-start; + margin-bottom: 0.75rem; + + &:last-child { + margin-bottom: 0; + } +} + +.code-key { + flex: 0 0 9rem; + font-size: 0.9rem; + font-weight: bold; + color: #444; + text-align: left; + line-height: 1.2rem; +} + +.code-value-container { + display: flex; + flex-direction: column; + flex: 1; + margin-left: 0.5rem; + align-items: flex-start; +} + +.code-value { + font-size: 0.9rem; + color: #555; + line-height: 1.2rem; +} + + + + + + + + + + + + diff --git a/micro-ui/web/micro-ui-internals/packages/modules/sandbox/src/configs/UICustomizations.js b/micro-ui/web/micro-ui-internals/packages/modules/sandbox/src/configs/UICustomizations.js index 692f65d3d91..26441ac20c2 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/sandbox/src/configs/UICustomizations.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/sandbox/src/configs/UICustomizations.js @@ -269,4 +269,4 @@ export const UICustomizations = { } }, }, -}; +}; \ No newline at end of file diff --git a/micro-ui/web/micro-ui-internals/packages/modules/workbench/src/components/DigitJSONForm.js b/micro-ui/web/micro-ui-internals/packages/modules/workbench/src/components/DigitJSONForm.js index 8f4101875b9..4b991b9251a 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/workbench/src/components/DigitJSONForm.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/workbench/src/components/DigitJSONForm.js @@ -11,7 +11,7 @@ import { Menu, CollapseAndExpandGroups, } from "@egovernments/digit-ui-react-components"; -import React, { useEffect, useMemo, useState } from "react"; +import React, { createContext, useContext, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import _ from "lodash"; import Form from "@rjsf/core"; @@ -20,24 +20,18 @@ import validator from "@rjsf/validator-ajv8"; import { titleId } from "@rjsf/utils"; import CustomDropdown from "./MultiSelect"; import CustomDropdownV2 from "./MultiSelectV2"; - import CustomCheckbox from "./Checbox"; import { BulkModal } from "./BulkModal"; -/* - -created the foem using rjfs json form +import { tranformLocModuleName } from "../pages/employee/localizationUtility"; +/*created the form using rjfs json form https://rjsf-team.github.io/react-jsonschema-form/docs/ - */ -/* -The DigitJSONForm component is a custom form component built using the react-jsonschema-form library. - It takes in a schema, an onSubmit function, an optional uiSchema, - a showToast and showErrorToast as props. - +/* context added for state management in MdmsAddV2*/ +const AdditionalPropertiesContext = createContext(); +export const useAdditionalProperties = () => useContext(AdditionalPropertiesContext); -*/ const uiSchema = { "ui:title": " ", "ui:classNames": "my-class", @@ -56,25 +50,9 @@ const uiSchema = { }, }; -function transformErrors(errors) { - const { t } = this; - console.log(errors, "errors"); - // Custom validation logic for all widgets - // You can modify or add error messages based on your requirements - return errors.map((error) => { - error.message = t(Digit.Utils.workbench.getMDMSLabel(`WBH_ERROR_${error?.name}`)); - if (error?.name === "pattern") { - error.message += ` : ${error?.params?.pattern}`; - } - // if (error.property === '.name' && error.name === 'minLength') { - // error.message = 'Name must be at least 3 characters'; - // } - // if (error.property === '.email' && error.name === 'format') { - // error.message = 'Invalid email format'; - // } - return error; - }); -} +// Removed transformErrors to reduce re-renders +// Removed Digit references from errors to reduce complexity + const getArrayWrapperClassName = (type) => { switch (type) { case "array": @@ -84,7 +62,7 @@ const getArrayWrapperClassName = (type) => { default: return "jk-array-of-non-objects"; } -} +}; function ArrayFieldItemTemplate(props) { const { t } = useTranslation(); @@ -131,6 +109,7 @@ function ArrayFieldItemTemplate(props) { ); } + function TitleFieldTemplate(props) { const { id, required, title } = props; return ( @@ -140,11 +119,13 @@ function TitleFieldTemplate(props) { ); } + function ArrayFieldTitleTemplate(props) { const { title, idSchema } = props; const id = titleId(idSchema); return null; } + function ArrayFieldTemplate(props) { const { t } = useTranslation(); if (props?.required && !props?.schema?.minItems) { @@ -175,14 +156,60 @@ function ArrayFieldTemplate(props) { } function ObjectFieldTemplate(props) { + const { formData, schema, idSchema, formContext } = props; + const { schemaCode, MdmsRes, additionalProperties } = formContext; + const isRoot = idSchema["$id"] === "digit_root"; + const { t } = useTranslation(); + + const localisableFields = MdmsRes?.find((item) => item?.schemaCode === schemaCode)?.localisation?.localisableFields || []; const children = props.properties.map((element) => { + const fieldName = element.name; + const isLocalisable = localisableFields.some((field) => field?.fieldPath === fieldName); + + if (isLocalisable) { + const fieldProps = additionalProperties?.[fieldName]; + const mdmsCode = fieldProps?.mdmsCode; + const localizationCode = fieldProps?.localizationCode; + const transformedLocCode= tranformLocModuleName(localizationCode); + return ( +
+
+ {element.content} +
+ + {/* MDMS and Localization Codes */} +
+
+ +
+ + {mdmsCode || ""} + +
+
+
+ +
+ + {transformedLocCode || ""} + +
+
+
+
+ ); + } + return ( -
+
{element.content}
); }); - const isRoot = props?.["idSchema"]?.["$id"] == "digit_root"; return (
@@ -202,21 +229,25 @@ function CustomFieldTemplate(props) { const { t } = useTranslation(); const { moduleName, masterName } = Digit.Hooks.useQueryParams(); const { id, classNames, style, label, help, required, description, errors, children } = props; + let titleCode = label; let additionalCode = ""; if ( + moduleName && + masterName && + typeof Digit?.Utils?.locale?.getTransformedLocale === "function" && !label?.includes(Digit.Utils.locale.getTransformedLocale(moduleName)) && !label?.includes(Digit.Utils.locale.getTransformedLocale(masterName)) ) { titleCode = Digit.Utils.locale.getTransformedLocale(`${moduleName}.${moduleName}_${label?.slice(0, -2)}`); additionalCode = label?.slice(-2); } + return (
{description} - + {children} {errors} {help} @@ -235,10 +266,8 @@ function CustomFieldTemplate(props) { ); } -const FieldErrorTemplate = (props) => { - const { errors } = props; - return errors && errors.length > 0 && errors?.[0] ? {errors?.[0]} : null; -}; +const FieldErrorTemplate = ({ errors }) => + errors && errors.length > 0 && errors[0] ? {errors[0]} : null; const DigitJSONForm = ({ schema, @@ -255,110 +284,215 @@ const DigitJSONForm = ({ disabled = false, setShowToast, setShowErrorToast, - v2 = true + v2 = true, }) => { const { t } = useTranslation(); - useEffect(() => { - onFormChange({ formData: Digit.Utils.workbench.postProcessData(formData, inputUiSchema) }); - }, []); - const onSubmitV2 = async ({ formData }) => { - const updatedData = await Digit.Utils.workbench.preProcessData(formData, inputUiSchema); - onSubmit(updatedData); - }; - - const customWidgets = { SelectWidget: v2 ? CustomDropdown : CustomDropdownV2, CheckboxWidget: CustomCheckbox }; + const [additionalProperties, setAdditionalProperties] = useState({}); const [displayMenu, setDisplayMenu] = useState(false); - const [liveValidate, setLiveValidate] = useState(false); const [showBulkUploadModal, setShowBulkUploadModal] = useState(false); const { moduleName, masterName } = Digit.Hooks.useQueryParams(); + const tenantId = Digit.ULBService.getCurrentTenantId(); + + const { data: MdmsRes } = Digit.Hooks.useCustomMDMS( + tenantId, + "Workbench", + [{ name: "UISchema" }], + { + select: (data) => data?.["Workbench"]?.["UISchema"], + } + ); + + + useEffect(() => { + if (schema?.code && MdmsRes && formData) { + const localisableFields = MdmsRes?.find((item) => item?.schemaCode === schema?.code)?.localisation?.localisableFields || []; + let newAdditionalProps = {}; + for (const fieldName in formData) { + const inputValue = formData[fieldName]; + const isLocalisable = localisableFields.some((field) => field.fieldPath === fieldName); + if (isLocalisable && inputValue !== undefined) { + const mdmsCode = (inputValue || "").replace(/\s+/g, "").toUpperCase(); + const localizationCode = `${schema.code}_${fieldName}_${mdmsCode}`.toUpperCase(); + newAdditionalProps[fieldName] = { + localizationMessage: inputValue, + mdmsCode, + localizationCode, + }; + } + } + setAdditionalProperties(newAdditionalProps); + } + }, [formData, MdmsRes,schema]); + + const reqCriteriaSecondUpsert = { + url: `/localization/messages/v1/_upsert`, + params: {}, + body: {}, + config: { + enabled: false, + }, + }; + const secondFormatLocalizationMutation = Digit.Hooks.useCustomAPIMutationHook(reqCriteriaSecondUpsert); + +const transformFormDataWithProperties = (formData, additionalProperties) => { + const transformedFormData = { ...formData }; + for (const fieldName in additionalProperties) { + if (Object.hasOwn(additionalProperties, fieldName)) { + const fieldProps = additionalProperties[fieldName]; + if (fieldProps?.localizationCode) { + transformedFormData[fieldName] = fieldProps.mdmsCode; + } + } + } + return transformedFormData; +}; + + +const buildSecondFormatMessages = (additionalProperties, schemaCode, locale) => { + const schemaCodeParts = schemaCode?.split(".") || []; + const firstPart = schemaCodeParts[0]?.toLowerCase() || "default"; + const secondPart = schemaCodeParts[1]?.toUpperCase() || ""; + + const messages = []; + for (const fieldName in additionalProperties) { + if (Object.hasOwn(additionalProperties, fieldName)) { + const fieldProps = additionalProperties[fieldName]; + const { mdmsCode, localizationMessage } = fieldProps; + if (mdmsCode && localizationMessage) { + const code = `${secondPart}.${mdmsCode}`; + messages.push({ + code: code, + message: localizationMessage, + module: firstPart, + locale: locale, + }); + } + } + } + return messages; +}; + +const onSubmitV2 = async ({ formData }, e) => { + const locale = Digit.StoreData.getCurrentLanguage(); + const transformedFormData = transformFormDataWithProperties(formData, additionalProperties); + const secondFormatMessages = buildSecondFormatMessages(additionalProperties, schema?.code, locale); + if (secondFormatMessages.length > 0) { + try { + await secondFormatLocalizationMutation.mutateAsync({ + params: {}, + body: { + tenantId: tenantId, + messages: secondFormatMessages, + }, + }); + } catch (err) { + console.error("Second format localization upsert failed:", err); + } + } + onSubmit && onSubmit(transformedFormData, additionalProperties); +}; + + + const customWidgets = { SelectWidget: v2 ? CustomDropdown : CustomDropdownV2, CheckboxWidget: CustomCheckbox }; const onError = (errors) => { - setLiveValidate(true); - onFormError(errors); + onFormError && onFormError(errors); }; - const person = { t: t }; return ( - -
- {screenType === "add" ? t("WBH_ADD_MDMS") : screenType === "view" ? t("WBH_VIEW_MDMS") : t("WBH_EDIT_MDMS")} -
- - -
{t(Digit.Utils.workbench.getMDMSLabel(`SCHEMA_` + schema?.code))}
-
0} - > - {(screenType === "add" || screenType === "edit") && ( - - {screenType === "add" && !Digit.Utils.getMultiRootTenant() && ( - - {showToast && setShowToast(null)}>} + +