diff --git a/micro-ui/web/micro-ui-internals/example/package.json b/micro-ui/web/micro-ui-internals/example/package.json index 4e8870cf596..9002783c5b1 100644 --- a/micro-ui/web/micro-ui-internals/example/package.json +++ b/micro-ui/web/micro-ui-internals/example/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@egovernments/digit-ui-libraries": "1.8.1-beta.1", - "@egovernments/digit-ui-module-core": "1.8.1-beta.17", + "@egovernments/digit-ui-module-core": "1.8.1-beta.23", "@egovernments/digit-ui-module-utilities": "1.0.1-beta.1", "@egovernments/digit-ui-react-components": "1.8.1-beta.20", "@egovernments/digit-ui-module-hcmmicroplanning":"0.0.1", diff --git a/micro-ui/web/micro-ui-internals/example/src/UICustomizations.js b/micro-ui/web/micro-ui-internals/example/src/UICustomizations.js index 72ca593db95..829186ba46e 100644 --- a/micro-ui/web/micro-ui-internals/example/src/UICustomizations.js +++ b/micro-ui/web/micro-ui-internals/example/src/UICustomizations.js @@ -234,6 +234,7 @@ export const UICustomizations = { data.body.CampaignDetails.pagination = data?.state?.tableForm data.body.CampaignDetails.tenantId = Digit.ULBService.getCurrentTenantId(); // data.body.CampaignDetails.boundaryCode = boundaryCode; + data.body.CampaignDetails.createdBy = Digit.UserService.getUser().info.uuid; data.body.CampaignDetails.campaignName = campaignName; data.body.CampaignDetails.status = ["drafted"] if (startDate) { 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 c514d68148e..07c202a5d9a 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.0.32-microplan", + "version": "1.0.33-microplan", "license": "MIT", "main": "dist/index.css", "author": "Jagankumar ", diff --git a/micro-ui/web/micro-ui-internals/packages/css/src/components/microplanning.scss b/micro-ui/web/micro-ui-internals/packages/css/src/components/microplanning.scss index 61369ef35e3..67208de114f 100644 --- a/micro-ui/web/micro-ui-internals/packages/css/src/components/microplanning.scss +++ b/micro-ui/web/micro-ui-internals/packages/css/src/components/microplanning.scss @@ -579,13 +579,15 @@ $border-color: rgba(214, 213, 212, 1); display: block; overflow: auto; padding-bottom: 0; + position: relative; @include select-dropdown; table { - background-color: rgb(0, 0, 0, 0); + background-color: rgb(0, 0, 0, 0) !important; width: 100%; - + border-collapse: collapse; + .select-dropdown { background-color: rgb(0, 0, 0, 0); font-family: Roboto; @@ -594,22 +596,32 @@ $border-color: rgba(214, 213, 212, 1); text-align: left; } - th { + thead { + position: sticky !important; + z-index: 100; + top:0; + background-color: rgba(250, 250, 250); + padding: 0; + } + + th{ width: 50%; font-weight: 700; font-size: 1rem; padding: 1.5rem; margin: 0; text-align: left; + border-bottom: 0.063rem solid rgba(214, 213, 212, 1) ; } - + td { width: 50%; font-weight: 400; font-size: 1rem; padding: 1.5rem; margin: 0; - + border-top: 0 !important; + border-bottom: 0.063rem solid rgba(214, 213, 212, 1) ; p { max-width: 20.594rem; font-weight: 700; @@ -2124,7 +2136,7 @@ $border-color: rgba(214, 213, 212, 1); height: 100%; background-color: rgb(244, 119, 56, 0.12) !important; } - + th, td { min-width: 7.578rem; @@ -2136,6 +2148,20 @@ $border-color: rgba(214, 213, 212, 1); font-family: Arial, sans-serif; font-size: 0.875rem; cursor: pointer; + position: relative; + + .edited-row-marker{ + width: 0.313rem; + position: absolute; + top: 0; + left: -0.313rem; + padding: 0; + margin: 0; + height: 100%; + border-top-left-radius: 0.125rem; + border-bottom-left-radius: 0.125rem ; + background-color: $primary-theme-color; + } } th { diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Hypothesis.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Hypothesis.js index f9cd5ab678e..4c696facfc2 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Hypothesis.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Hypothesis.js @@ -107,7 +107,7 @@ const Hypothesis = ({ campaignType = "SMC", microplanData, setMicroplanData, che if (check) { setMicroplanData((previous) => ({ ...previous, hypothesis: assumptions })); let checkValid = validateAssumptions(assumptions); - checkValid = checkValid && assumptions.length !== 0; + checkValid = checkValid && assumptions.filter((subItem) => subItem?.active).length !== 0; if (checkValid) setCheckDataCompletion("valid"); else setCheckDataCompletion("invalid"); } else { @@ -121,7 +121,7 @@ const Hypothesis = ({ campaignType = "SMC", microplanData, setMicroplanData, che ); const validateAssumptions = useCallback((assumptions) => { - return assumptions.every((item) => Object.values(item).filter(subItem => subItem.active).every((data) => data !== "")) && assumptions.length !== 0; + return assumptions.filter((item) => item?.active).every((item) => Object.values(item).every((data) => data !== "")) && assumptions.length !== 0; }, []); const cancelUpdateData = useCallback(() => { @@ -143,6 +143,7 @@ const Hypothesis = ({ campaignType = "SMC", microplanData, setMicroplanData, che return ( <>
+
{/* NonInterractable Section */} {/* Interractable Section that includes the example as well as the assumptions */} @@ -432,7 +433,7 @@ const Example = ({ exampleOption, t }) => { const deleteAssumptionHandler = (item, setItemForDeletion, setAssumptions, setHypothesisAssumptionsList, setToast, t) => { let add = true; setAssumptions((previous) => { - if (!previous.length) return []; + if (!previous.length) return []; if (previous?.length <= 1) { setToast({ state: "error", message: t("ERROR_CANNOT_DELETE_LAST_HYPOTHESIS") }); add = false; @@ -440,7 +441,7 @@ const deleteAssumptionHandler = (item, setItemForDeletion, setAssumptions, setHy } // const filteredData = previous.filter((data) => data.id !== item.id); const deletionElementIndex = previous.findIndex((data) => data.id === item.id); - const filteredData = previous.map((data, index) => index === deletionElementIndex ? { ...data, active: false } : data); + const filteredData = previous.map((data, index) => (index === deletionElementIndex ? { ...data, active: false } : data)); return filteredData || []; }); if (add && item && item.key) @@ -486,7 +487,7 @@ const Select = React.memo(({ item, assumptions, setAssumptions, disabled = false }); setOptions((previous) => { - let newOptions = previous.filter((item) => item !== e?.code); + let newOptions = previous.filter((item) => item?.active && item !== e?.code); if (selected && !newOptions.includes(selected)) newOptions.unshift(selected); return newOptions; }); @@ -495,18 +496,20 @@ const Select = React.memo(({ item, assumptions, setAssumptions, disabled = false ); return ( - ({ code: item }))} - selected={selected} - optionKey="code" - select={selectChangeHandler} - // style={{ width: "100%", backgroundColor: "rgb(0,0,0,0)", position:"sticky" }} - optionCardStyles={{ position: "absolute" }} - placeholder={t("SELECT_OPTION")} - /> +
+ ({ code: item }))} + selected={selected} + optionKey="code" + select={selectChangeHandler} + // style={{ width: "100%", backgroundColor: "rgb(0,0,0,0)", position:"sticky" }} + optionCardStyles={{ position: "absolute" }} + placeholder={t("SELECT_OPTION")} + /> +
); }); @@ -519,7 +522,7 @@ const Input = React.memo(({ item, setAssumptions, t, disabled = false }) => { const inputChangeHandler = useCallback( (e) => { - if( e.target.value.includes("+") || e.target.value.includes("e") ) return + if (e.target.value.includes("+") || e.target.value.includes("e")) return; if ((e.target.value <= 0 || e.target.value > 10000000000) && e.target.value !== "") return; let value; const decimalIndex = e.target.value.indexOf("."); diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanPreview.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanPreview.js index 5719e81c33a..780e13df4ca 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanPreview.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanPreview.js @@ -148,8 +148,8 @@ const MicroplanPreview = ({ ...previous, microplanPreview: { previewData: dataToShow, - userEditedResources - } + userEditedResources, + }, })); setCheckDataCompletion("perform-action"); }, [dataToShow, setMicroplanData, userEditedResources, setCheckDataCompletion]); @@ -481,6 +481,9 @@ const DataPreview = memo( if (!previewData) return; const [tempResourceChanges, setTempResourceChanges] = useState(userEditedResources); const [selectedRow, setSelectedRow] = useState(); + const conmmonColumnIndex = useMemo(() => { + return previewData?.[0]?.indexOf(commonColumn); + }, [previewData]); if (isCampaignLoading || ishierarchyLoading) { return (
@@ -520,12 +523,20 @@ const DataPreview = memo( {previewData.slice(1).map((rowData, rowIndex) => { - const rowDataList = Object.values(previewData[0]).map((_, cellIndex) => ( + const rowDataList = Object.values(previewData[0]).map((header, cellIndex) => ( + {cellIndex==0 && userEditedResources?.[rowData?.[conmmonColumnIndex]] && Object.keys(userEditedResources?.[rowData?.[conmmonColumnIndex]]).length !==0 &&
} + {rowData[cellIndex] || rowData[cellIndex] === 0 ? rowData[cellIndex] : t("NO_DATA")} )); @@ -535,6 +546,9 @@ const DataPreview = memo( onDoubleClick={() => { rowClick(rowIndex + 1); }} + // style={{...(userEditedResources?.[rowData?.[conmmonColumnIndex]] && Object.keys(userEditedResources?.[rowData?.[conmmonColumnIndex]]).length !==0 + // ? { borderL: "1px solid rgba(244, 119, 56, 0.12)" } + // : {}),}} > {rowDataList} @@ -550,7 +564,6 @@ const DataPreview = memo( display: "flex", flex: 1, justifyContent: "flex-end", - padding: 0, width: "100%", padding: "1rem", }} @@ -560,6 +573,7 @@ const DataPreview = memo( marginTop: "0.5rem", marginBottom: "0.5rem", marginRight: "1.4rem", + height: "2.5rem", width: "12.5rem", }} headerBarMainStyle={{ padding: "0 0 0 0.5rem" }} @@ -1007,8 +1021,9 @@ const EditResourceData = ({ previewData, selectedRow, resources, tempResourceCha const valueChangeHandler = (item, value) => { if (!conmmonColumnData) return; + if (isNaN(value) || (!isFinite(value) && value !== "")) return; let changedDataAgainstBoundaryCode = tempResourceChanges?.[conmmonColumnData] || {}; - changedDataAgainstBoundaryCode[item] = value; + changedDataAgainstBoundaryCode[item] = value == "" ? undefined : parseFloat(value); setTempResourceChanges((previous) => ({ ...previous, [conmmonColumnData]: changedDataAgainstBoundaryCode })); }; @@ -1051,6 +1066,7 @@ const EditResourceData = ({ previewData, selectedRow, resources, tempResourceCha let index = previewData?.[0]?.indexOf(item); if (index === -1) return; const currentData = previewData?.[selectedRow]?.[index]; + return ( @@ -1062,9 +1078,13 @@ const EditResourceData = ({ previewData, selectedRow, resources, tempResourceCha valueChangeHandler(item, value.target.value)} /> diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanningHeader.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanningHeader.js index c3e39302304..a220c1c4db8 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanningHeader.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/MicroplanningHeader.js @@ -18,7 +18,7 @@ const MicroplanningHeader = () => { return ( <> - +
diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/RuleEngine.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/RuleEngine.js index 363270ed8fe..fdb97136528 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/RuleEngine.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/RuleEngine.js @@ -86,12 +86,8 @@ const RuleEngine = ({ campaignType = "SMC", microplanData, setMicroplanData, che if (!rules || !setMicroplanData) return; if (check) { setMicroplanData((previous) => ({ ...previous, ruleEngine: rules })); - let isValid = rules.every((item) => - Object.values(item) - .filter((item) => item.active) - .every((data) => data !== "") - ); - isValid = isValid && rules.length !== 0; + const activeRules = rules.filter((item) => item.active); + const isValid = activeRules.every((item) => Object.values(item).every((data) => data !== "")) && activeRules.length !== 0; if (isValid) setCheckDataCompletion("valid"); else setCheckDataCompletion("invalid"); } else { @@ -158,7 +154,7 @@ const RuleEngine = ({ campaignType = "SMC", microplanData, setMicroplanData, che } } if (!AutoFilledRuleConfigurationsList || !outputs || !hypothesisAssumptions || !schemas) return; - + filteredRules = setAutoFillRules( AutoFilledRuleConfigurationsList, filteredRules, @@ -606,6 +602,12 @@ const deleteAssumptionHandler = (item, setItemForDeletion, setRules, setOutputs, setRules((previous) => { if (!previous.length) return []; // const filteredData = previous.filter((data) => data.id !== item.id); + previous = previous.map((e) => { + if (e.input === item.output) { + return { ...e, input: "" }; + } + return e; + }); const deletionElementIndex = previous.findIndex((data) => data.id === item.id); const filteredData = previous.map((data, index) => (index === deletionElementIndex ? { ...data, active: false } : data)); return filteredData || []; @@ -628,7 +630,7 @@ const Select = React.memo(({ item, rules, setRules, disabled = false, options, s useEffect(() => { if (item) { if (outputs && outputs.some((e) => e === item?.input)) { - if (rules.some((e) => e?.output === item?.input)) setSelected({ code: item[toChange] }); + if (rules.filter(item => item.active).some((e) => e?.output === item?.input)) setSelected({ code: item?.[toChange] }); } else setSelected({ code: item[toChange] }); } }, [item]); @@ -650,8 +652,11 @@ const Select = React.memo(({ item, rules, setRules, disabled = false, options, s const selectChangeHandler = useCallback( (e) => { if (e.code === "SELECT_OPTION") return; - const existingEntry = rules.find((item) => item[toChange] === e.code); - if (existingEntry && unique) return; + const existingEntry = rules.find((item) => item.active && item[toChange] === e.code); + if (existingEntry && unique) { + console.error("Attempted to add a duplicate entry where uniqueness is required."); + return; + } const newDataSegment = { ...item }; newDataSegment[toChange] = e.code; setRules((previous) => { @@ -682,16 +687,7 @@ const Select = React.memo(({ item, rules, setRules, disabled = false, options, s ); return ( - // +
+
); }); @@ -710,7 +707,7 @@ const getRuleConfigInputsFromSchema = (campaignType, microplanData, schemas) => if (!schemas || !microplanData || !microplanData?.upload || !campaignType) return []; let sortData = []; if (!schemas) return; - for (const value of microplanData?.upload?.filter((value) => value?.error === null) || []) { + for (const value of microplanData?.upload?.filter((value) => value?.active && value?.error === null) || []) { sortData.push({ section: value?.section, fileType: value?.fileType }); } const filteredSchemas = @@ -738,19 +735,23 @@ const getRuleConfigInputsFromSchema = (campaignType, microplanData, schemas) => const setAutoFillRules = (autofillData, rules, hypothesisAssumptionsList, outputs, operators, inputs, setInputs, setOutputs) => { if (rules && rules.filter((item) => item.active).length !== 0) return rules; let newRules = []; - const ruleOuputList = rules ? rules.map((item) => item?.output) : []; + const ruleOuputList = rules ? rules.filter((item) => item.active).map((item) => item?.output) : []; let rulePlusInputs; if (ruleOuputList) rulePlusInputs = [...inputs, ...ruleOuputList]; else rulePlusInputs = inputs; - autofillData.forEach((item) => { + for (const item of autofillData) { if ( ruleOuputList?.includes(item?.output) || - !outputs?.includes(item?.output) || - !rulePlusInputs.includes(item?.input) || - !operators?.includes(item?.operator) || - !hypothesisAssumptionsList?.includes(item?.assumptionValue) + (outputs && !outputs.includes(item?.output)) || + (rulePlusInputs && !rulePlusInputs.includes(item?.input)) || + (operators && !operators.includes(item?.operator)) || + (hypothesisAssumptionsList && !hypothesisAssumptionsList.includes(item?.assumptionValue)) || + !outputs || + !rulePlusInputs || + !operators || + !hypothesisAssumptionsList ) - return; + continue; if (!item["id"]) { let uuid = uuidv4(); item["id"] = uuid; @@ -759,7 +760,7 @@ const setAutoFillRules = (autofillData, rules, hypothesisAssumptionsList, output newRules.push(item); rulePlusInputs?.push(item?.output); ruleOuputList?.push(item?.output); - }); + } if (newRules.length !== 0) { let newOutputs = []; outputs.forEach((e) => { @@ -770,16 +771,18 @@ const setAutoFillRules = (autofillData, rules, hypothesisAssumptionsList, output setOutputs(newOutputs); setInputs(rulePlusInputs); // setRules((previous) => [...previous, ...newRules]); - return [...rules,...newRules]; + return [...(rules ? rules : []), ...newRules]; } }; const setRuleEngineDataFromSsn = (rules, hypothesisAssumptions) => { - if (rules && rules.length === 0) return; + if (rules && rules.length === 0) return []; let newRules = []; let outputs = []; rules.forEach((item, index) => { - if (!hypothesisAssumptions?.includes(item?.assumptionValue)) return; + if (item.active && !hypothesisAssumptions?.includes(item?.assumptionValue)) { + item.active = false; + } if (!item["id"]) { let uuid = uuidv4(); item["id"] = uuid; @@ -793,6 +796,6 @@ const setRuleEngineDataFromSsn = (rules, hypothesisAssumptions) => { // item["id"] = newRules.length; // filteredRules.push(item); // }); - return newRules; + return newRules || []; }; export default RuleEngine; diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Upload.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Upload.js index b1110dbc98d..8969c53416c 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Upload.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/Upload.js @@ -265,6 +265,7 @@ const Upload = ({ hierarchyType: campaignData?.hierarchyType, Schemas: validationSchemas, HierarchyConfigurations: state?.HierarchyConfigurations, + setLoaderActivation, t, }; downloadTemplate(downloadParams); @@ -555,20 +556,26 @@ const Upload = ({ // Function for creating blob out of data const dataToBlob = () => { - let blob; - switch (fileData.fileType) { - case EXCEL: - blob = fileData.file; - break; - case SHAPEFILE: - case GEOJSON: - if (fileData && fileData.data) { - const result = Digit.Utils.microplan.convertGeojsonToExcelSingleSheet(fileData?.data?.features, fileData?.fileName); - blob = convertJsonToXlsx(result, { skipHeader: true }); - } - break; + try { + let blob; + switch (fileData.fileType) { + case EXCEL: + if (fileData?.errorLocationObject?.length !== 0) blob = prepareExcelFileBlobWithErrors(fileData.data, fileData.errorLocationObject, t); + else blob = fileData.file; + break; + case SHAPEFILE: + case GEOJSON: + if (fileData && fileData.data) { + const result = Digit.Utils.microplan.convertGeojsonToExcelSingleSheet(fileData?.data?.features, fileData?.fileName); + if (fileData?.errorLocationObject?.length !== 0) blob = prepareExcelFileBlobWithErrors(result, fileData.errorLocationObject, t); + } + break; + } + return blob; + } catch (error) { + console.error("Error generating blob:", error); + return; } - return blob; }; // Download the selected file @@ -1430,8 +1437,20 @@ const checkProjection = async (zip) => { }; // Function to handle the template download -const downloadTemplate = async ({ campaignType, type, section, setToast, campaignData, hierarchyType, Schemas, HierarchyConfigurations, t }) => { +const downloadTemplate = async ({ + campaignType, + type, + section, + setToast, + campaignData, + hierarchyType, + Schemas, + HierarchyConfigurations, + setLoaderActivation, + t, +}) => { try { + setLoaderActivation(true); // Find the template based on the provided parameters const schema = getSchema(campaignType, type, section, Schemas); const hierarchyLevelName = HierarchyConfigurations?.find((item) => item.name === "devideBoundaryDataBy")?.value; @@ -1450,9 +1469,9 @@ const downloadTemplate = async ({ campaignType, type, section, setToast, campaig translatedTemplate.forEach(({ sheetName, data }) => { const worksheet = XLSX.utils.json_to_sheet(data, { skipHeader: true }); - let columnCount = data?.[0]?.length || 0 - const wscols = Array(columnCount).fill({ width: 30 }); - worksheet['!cols'] = wscols; + const columnCount = data?.[0]?.length || 0; + const wscols = Array(columnCount).fill({ width: 30 }); + worksheet["!cols"] = wscols; XLSX.utils.book_append_sheet(workbook, worksheet, sheetName); }); @@ -1463,8 +1482,10 @@ const downloadTemplate = async ({ campaignType, type, section, setToast, campaig link.href = url; link.download = t(section) + ".xlsx"; link.click(); + setLoaderActivation(false); URL.revokeObjectURL(url); } catch (error) { + setLoaderActivation(false); setToast({ state: "error", message: t("ERROR_DOWNLOADING_TEMPLATE") }); } }; @@ -1480,7 +1501,7 @@ const translateTemplate = (template, t) => { // Find the index of the boundaryCode column in the header row const boundaryCodeIndex = sheetData[0].indexOf(commonColumn); - const sheetName = t(sheet.sheetName) + const sheetName = t(sheet.sheetName); const transformedSheet = { sheetName: sheetName.length > 31 ? sheetName.slice(0, 31) : sheetName, data: [], @@ -1610,4 +1631,42 @@ const resourceMappingAndDataFilteringForExcelFiles = (schemaData, hierarchy, sel return { tempResourceMappingData: resourceMappingData, tempFileDataToStore: newFileData }; }; +const prepareExcelFileBlobWithErrors = (data, errors, t) => { + let tempData = {...data}; + // Process each dataset within the data object + const processedData = {}; + for (const key in tempData) { + if (tempData.hasOwnProperty(key)) { + const dataset = [...tempData[key]]; + + // Add the 'error' column to the header + dataset[0] = dataset[0].map((item) => t(item)); + // Process each data row + if (errors) { + dataset[0].push(t("error")); + for (let i = 1; i < dataset.length; i++) { + const row = dataset[i]; + + // Check if there are errors for the given commonColumnData + const errorInfo = errors?.[key]?.[i - 1]; + if (errorInfo) { + let rowDataAddOn = Object.entries(errorInfo) + .map(([key, value]) => { + return t(key) + ": " + value.map((item) => t(item)).join(", "); + }) + .join("; "); + row.push({ v: rowDataAddOn }); + } else { + row.push(""); + } + } + } + processedData[key] = dataset; + } + } + + let xlsxBlob = convertJsonToXlsx(processedData, { skipHeader: true }); + return xlsxBlob; +}; + export default Upload; diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/resourceMapping.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/resourceMapping.js index fd407fa043b..034b5089535 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/resourceMapping.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/components/resourceMapping.js @@ -40,7 +40,7 @@ export const SpatialDataPropertyMapping = ({ uploadedData, resourceMapping, setR // Scroll the container to the target position scrollContainer.scrollTo({ - top: scrollContainer.scrollTop + offset - 10, + top: scrollContainer.scrollTop + offset + 10, behavior: "smooth", }); } diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/UICustomizations.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/UICustomizations.js index d9b2e576b0d..7976f1751f7 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/UICustomizations.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/UICustomizations.js @@ -234,6 +234,7 @@ export const UICustomizations = { data.body.CampaignDetails.pagination = data?.state?.tableForm data.body.CampaignDetails.tenantId = Digit.ULBService.getCurrentTenantId(); // data.body.CampaignDetails.boundaryCode = boundaryCode; + data.body.CampaignDetails.createdBy = Digit.UserService.getUser().info.uuid; data.body.CampaignDetails.campaignName = campaignName; data.body.CampaignDetails.status = ["drafted"] if (startDate) { diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/tourSteps.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/tourSteps.js index d59dd4725c7..081b47951fa 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/tourSteps.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/configs/tourSteps.js @@ -44,9 +44,9 @@ export const tourSteps = (t) => { steps: [ { content: t("HELP_HYPOTHESIS_INTERACTABLE_SECTION"), - target: ".hypothesis-section", + target: ".hypothesis-help", disableBeacon: true, - placement: "top-start", + placement: "right-start", title: "", disableScrolling: true, }, diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/CreateMicroplan.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/CreateMicroplan.js index d3bd00ef79a..2cc9b58123f 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/CreateMicroplan.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/CreateMicroplan.js @@ -151,7 +151,7 @@ const CreateMicroplan = () => { // return; // } setCheckDataCompletion("false"); - let body = Digit.Utils.microplan.mapDataForApi(microplanData, operatorsObject, microplanData?.microplanDetails?.name, campaignId, "DRAFT"); + let body = Digit.Utils.microplan.mapDataForApi(microplanData, operatorsObject, microplanData?.microplanDetails?.name, campaignId, "DRAFT",microplanData?.planConfigurationId?"update":"create"); if(!Digit.Utils.microplan.planConfigRequestBodyValidator(body, state, campaignType)){ setCheckDataCompletion("perform-action"); return @@ -201,7 +201,7 @@ const CreateMicroplan = () => { setTimeout(() => { setLoaderActivation(false); // setToastCreateMicroplan(undefined); - setCheckDataCompletion("perform-action"); + setCheckDataCompletion("false"); }, 2000); }, }); @@ -239,7 +239,7 @@ const CreateMicroplan = () => { setTimeout(() => { // setToastCreateMicroplan(undefined); setLoaderActivation(false); - setCheckDataCompletion("perform-action"); + setCheckDataCompletion("false"); }, 2000); }, }); diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/SelectCampaign.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/SelectCampaign.js index 4df5e8d0b81..62dcdad91c6 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/SelectCampaign.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/pages/employee/SelectCampaign.js @@ -10,7 +10,7 @@ const configs = { serviceName: "/project-factory/v1/project-type/search", requestParam: {}, requestBody: {}, - minParametersForSearchForm: 1, + minParametersForSearchForm: 0, masterName: "commonUiConfig", moduleName: "SearchCampaign", tableFormJsonPath: "requestBody.CampaignDetails.pagination", @@ -200,7 +200,8 @@ const SelectCampaign = () => { const history = useHistory(); const onClickRow = (row) => { - history.push(`/${window.contextPath}/employee/microplanning/help-guidelines?id=${row?.original?.id}`); + // history.push(`/${window.contextPath}/employee/microplanning/help-guidelines?id=${row?.original?.id}`); + history.push(`/${window.contextPath}/employee/microplanning/create-microplan?id=${row?.original?.id}`); }; const SelectCampaignSession = Digit.Hooks.useSessionStorage("SELECT_CAMPAIGN_SESSION", {}); diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/createTemplate.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/createTemplate.js index d85767d4d31..aad826c2705 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/createTemplate.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/createTemplate.js @@ -128,13 +128,14 @@ const addBoundaryData = (xlsxData, boundaryData) => { return newXlsxData; }; - -const fillDataWithBlanks = (data,tillRow)=>{ - // Ensure all rows are of the same length by filling them with empty strings - data = data.concat(new Array(tillRow - data.length).fill([])); +const fillDataWithBlanks = (data, tillRow) => { + while (data.length < tillRow) { + data.push([]); + } + const maxLength = Math.max(...data.map(row => row.length)); return data.map(row => [...row, ...new Array(maxLength - row.length).fill('')]); -} +}; /** diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelValidations.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelValidations.js index 2d00f502658..23055671367 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelValidations.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelValidations.js @@ -48,7 +48,7 @@ export const excelValidations = (data, schemaData, t) => { let errors = {}; let hasDataErrors = "false"; // true, false, missing_properties, unknown let missingColumnsList = new Set(); - let errorMessages = []; + let errorMessages = {}; for (let i = 0; i < validateExcel.errors.length; i++) { let tempErrorStore = ""; @@ -60,11 +60,11 @@ export const excelValidations = (data, schemaData, t) => { break; case "type": { - const instancePathType = validateExcel.errors[i].instancePath.split("/"); - tempErrorStore = locationDataColumns.includes(instancePathType[instancePathType.length - 1]) - ? "ERROR_INCORRECT_LOCATION_COORDINATES" - : "ERROR_DATA_TYPE"; - hasDataErrors = "true"; + const instancePathType = validateExcel.errors[i].instancePath.split("/"); + tempErrorStore = locationDataColumns.includes(instancePathType[instancePathType.length - 1]) + ? "ERROR_INCORRECT_LOCATION_COORDINATES" + : "ERROR_DATA_TYPE"; + hasDataErrors = "true"; } break; case "required": @@ -82,7 +82,7 @@ export const excelValidations = (data, schemaData, t) => { hasDataErrors = "true"; break; case "pattern": - tempErrorStore = "ERROR_VALUE_NOT_ALLOWED" + tempErrorStore = "ERROR_VALUE_NOT_ALLOWED"; hasDataErrors = "true"; break; default: @@ -106,20 +106,27 @@ export const excelValidations = (data, schemaData, t) => { switch (hasDataErrors) { case "true": - errorMessages = [...new Set([...errorMessages,(t("ERROR_REFER_UPLOAD_PREVIEW_TO_SEE_THE_ERRORS"))])]; + errorMessages = { dataError: t("ERROR_REFER_UPLOAD_PREVIEW_TO_SEE_THE_ERRORS") }; break; case "unknown": - errorMessages= [...new Set([...errorMessages,(t("ERROR_UNKNOWN"))])]; + errorMessages = { unkown: t("ERROR_UNKNOWN") }; break; case "missing_properties": - errorMessages= [...new Set([...errorMessages,(t("ERROR_MISSING_PROPERTY",{properties: [...missingColumnsList].map(item=>t(item)).join(", ")}))])]; + errorMessages = { missingProperty: t("ERROR_MISSING_PROPERTY", { properties: [...missingColumnsList].map((item) => t(item)).join(", ") }) }; break; case "false": break; } } - return { valid: !hasDataErrors, message: errorMessages, errors, validationError: validateExcel.errors }; + ajv.removeSchema(); + + return { + valid: !hasDataErrors, + message: errorMessages ? [...new Set(Object.values(errorMessages))] : [], + errors, + validationError: validateExcel.errors, + }; } ajv.removeSchema(); return { valid }; diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/geojsonValidations.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/geojsonValidations.js index ac9a0e50947..d39296390f3 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/geojsonValidations.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/geojsonValidations.js @@ -160,28 +160,27 @@ export const geojsonPropetiesValidation = (data, schemaData, name, t) => { ], }, }; - } - switch (hasDataErrors) { - case "true": - errorMessages = [...new Set([...errorMessages,(t("ERROR_REFER_UPLOAD_PREVIEW_TO_SEE_THE_ERRORS"))])]; - break; - case "unknown": - errorMessages= [...new Set([...errorMessages,(t("ERROR_UNKNOWN"))])]; - break; - case "missing_properties": - errorMessages= [...new Set([...errorMessages,t("ERROR_MISSING_PROPERTY", {properties:[...missingColumnsList].map(item=>t(item)).join(", ")})])]; - break; - case "false": - break; + switch (hasDataErrors) { + case "true": + errorMessages = { ...errorMessages, dataError: t("ERROR_REFER_UPLOAD_PREVIEW_TO_SEE_THE_ERRORS") }; + break; + case "unknown": + errorMessages = { ...errorMessages, unkown: t("ERROR_UNKNOWN") }; + break; + case "missing_properties": + errorMessages = {...errorMessages, missingProperty: t("ERROR_MISSING_PROPERTY", { properties: [...missingColumnsList].map((item) => t(item)).join(", ") }) }; + break; + case "false": + break; + } } ajv.removeSchema(); - return { valid: !hasDataErrors, + message: errorMessages ? [...new Set(Object.values(errorMessages))] : [], errors, - message: errorMessages, validationError: validateGeojson.errors, }; } diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/index.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/index.js index 2c953b64ec3..42e6135da92 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/index.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/index.js @@ -156,12 +156,13 @@ const inputScrollPrevention = (e) => { }; // Construct api request body -const mapDataForApi = (data, Operators, microplanName, campaignId, status) => { +const mapDataForApi = (data, Operators, microplanName, campaignId, status, reqType="update") => { let files = [], resourceMapping = []; if (data && data.upload) { Object.values(data?.upload).forEach((item) => { if (!item || item.error || !item.filestoreId) return; + if (reqType==="create" && !item?.active) return; const data = { active: item?.active, filestoreId: item?.filestoreId, @@ -196,13 +197,15 @@ const mapDataForApi = (data, Operators, microplanName, campaignId, status) => { executionPlanId: campaignId, files, assumptions: data?.hypothesis?.reduce((acc, item) => { - if (item.key && item.value) { + if (reqType==="create" && !item?.active) return acc; + if (item.key && item.value) { acc.push(JSON.parse(JSON.stringify(item))); } return acc; }, []), operations: data?.ruleEngine?.reduce((acc, item) => { - if (item.operator && item.output && item.input && item.assumptionValue) { + if (reqType==="create" && !item?.active) return acc; + if (item.operator && item.output && item.input && item.assumptionValue) { const data = JSON.parse(JSON.stringify(item)); const operator = Operators.find((e) => e.name === data.operator); if (operator && operator.code) data.operator = operator?.code; @@ -353,14 +356,14 @@ const addResourcesToFilteredDataToShow = (previewData, resources, hypothesisAssu }; const calculateResource = (resourceName, rowData, formulaConfiguration, headers, hypothesisAssumptionsList, t) => { - let formula = formulaConfiguration?.find((item) => item?.output === resourceName); + let formula = formulaConfiguration?.find((item) =>item?.active && item?.output === resourceName); if (!formula) return null; // Finding Input // check for Uploaded Data let inputValue = findInputValue(formula, rowData, formulaConfiguration, headers, hypothesisAssumptionsList, t); if (inputValue == undefined || inputValue === null) return null; - let assumptionValue = hypothesisAssumptionsList?.find((item) => item?.key === formula?.assumptionValue)?.value; + let assumptionValue = hypothesisAssumptionsList?.find((item) => item?.active && item?.key === formula?.assumptionValue)?.value; if (assumptionValue == undefined) return null; return findResult(inputValue, assumptionValue, formula?.operator); @@ -427,7 +430,7 @@ const ruleOutputCheck = (rules, ruleOuputList) => { }; const ruleHypothesisCheck = (rules, ruleHypothesis) => { if (rules && Array.isArray(rules) && rules.length !== 0 && ruleHypothesis && Array.isArray(ruleHypothesis) && ruleHypothesis.length !== 0) { - return rules.every((item) => ruleHypothesis.includes(item.assumptionValue)); + return rules.filter(item=>item.active).every((item) => ruleHypothesis.includes(item.assumptionValue)); } return false; }; diff --git a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/jsonToExcelBlob.js b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/jsonToExcelBlob.js index 930708738bd..95c77a852f4 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/jsonToExcelBlob.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/jsonToExcelBlob.js @@ -3,10 +3,13 @@ import XLSX from 'xlsx'; export const convertJsonToXlsx = (jsonData,options) => { const workbook = XLSX.utils.book_new(); - Object.keys(jsonData).forEach(sheetName => { - const worksheet = XLSX.utils.json_to_sheet(jsonData[sheetName], options); + for (const [sheetName, data] of Object.entries(jsonData)) { + const worksheet = XLSX.utils.json_to_sheet(data, { skipHeader: true }); + const columnCount = data?.[0]?.length || 0; + const wscols = Array(columnCount).fill({ width: 30 }); + worksheet["!cols"] = wscols; XLSX.utils.book_append_sheet(workbook, worksheet, sheetName); - }); + }; const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array', compression: true }); const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); diff --git a/micro-ui/web/microplan/package.json b/micro-ui/web/microplan/package.json index e54abcabb37..5d5e9d243a1 100644 --- a/micro-ui/web/microplan/package.json +++ b/micro-ui/web/microplan/package.json @@ -13,7 +13,7 @@ "homepage": "/microplan-ui", "dependencies": { "@egovernments/digit-ui-libraries": "1.8.1-beta.1", - "@egovernments/digit-ui-module-core": "1.8.1-beta.17", + "@egovernments/digit-ui-module-core": "1.8.1-beta.23", "@egovernments/digit-ui-module-utilities": "1.0.1-beta.1", "@egovernments/digit-ui-react-components": "1.8.1-beta.20", "@egovernments/digit-ui-module-hcmmicroplanning":"0.0.1", diff --git a/micro-ui/web/public/index.html b/micro-ui/web/public/index.html index b17e7c65178..0222c0b79db 100644 --- a/micro-ui/web/public/index.html +++ b/micro-ui/web/public/index.html @@ -15,7 +15,7 @@