From ae53d00f8810e7878cac20586a100a5e6d783c07 Mon Sep 17 00:00:00 2001 From: ashish-egov <137176738+ashish-egov@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:30:02 +0530 Subject: [PATCH] Facility mapper (#1590) * Facility assgninment initialised * Changes in facility Mapping * Removed logs * Facility Popup changes * Changed facility Popup * Delete health/micro-ui/web/package-lock.json * Delete micro-ui/web/package-lock.json * Css change --- .../example/public/index.html | 2 +- .../packages/css/package.json | 4 +- .../css/src/components/microplan.scss | 6 +- .../microplan/src/components/FacilityPopup.js | 463 +++++++++++++++++- .../src/components/SearchJurisdiction.js | 2 + .../microplan/src/configs/UICustomizations.js | 2 +- .../modules/microplan/src/hooks/index.js | 5 +- .../src/hooks/services/censusSearchConfig.js | 19 + .../microplan/src/hooks/useCensusSearch.js | 7 + health/micro-ui/web/public/index.html | 2 +- micro-ui/web/package.json | 10 +- 11 files changed, 482 insertions(+), 40 deletions(-) create mode 100644 health/micro-ui/web/micro-ui-internals/packages/modules/microplan/src/hooks/services/censusSearchConfig.js create mode 100644 health/micro-ui/web/micro-ui-internals/packages/modules/microplan/src/hooks/useCensusSearch.js diff --git a/health/micro-ui/web/micro-ui-internals/example/public/index.html b/health/micro-ui/web/micro-ui-internals/example/public/index.html index 53afaafba1c..6c6230b91bd 100644 --- a/health/micro-ui/web/micro-ui-internals/example/public/index.html +++ b/health/micro-ui/web/micro-ui-internals/example/public/index.html @@ -16,7 +16,7 @@ /> --> - + diff --git a/health/micro-ui/web/micro-ui-internals/packages/css/package.json b/health/micro-ui/web/micro-ui-internals/packages/css/package.json index da0398fe077..8d6894200ac 100644 --- a/health/micro-ui/web/micro-ui-internals/packages/css/package.json +++ b/health/micro-ui/web/micro-ui-internals/packages/css/package.json @@ -1,6 +1,6 @@ { "name": "@egovernments/digit-ui-health-css", - "version": "0.1.4", + "version": "0.1.5", "license": "MIT", "main": "dist/index.css", "author": "Jagankumar ", @@ -66,4 +66,4 @@ "digit-ui", "css" ] -} \ No newline at end of file +} diff --git a/health/micro-ui/web/micro-ui-internals/packages/css/src/components/microplan.scss b/health/micro-ui/web/micro-ui-internals/packages/css/src/components/microplan.scss index d2162145adb..26bee6993a8 100644 --- a/health/micro-ui/web/micro-ui-internals/packages/css/src/components/microplan.scss +++ b/health/micro-ui/web/micro-ui-internals/packages/css/src/components/microplan.scss @@ -164,6 +164,6 @@ justify-content: right; align-items: center; } - - - \ No newline at end of file +.digit-multiselectdropdown-wrap.nestedmultiselect{ + width: 100%; +} \ No newline at end of file diff --git a/health/micro-ui/web/micro-ui-internals/packages/modules/microplan/src/components/FacilityPopup.js b/health/micro-ui/web/micro-ui-internals/packages/modules/microplan/src/components/FacilityPopup.js index ecda018af1c..f4f484e3913 100644 --- a/health/micro-ui/web/micro-ui-internals/packages/modules/microplan/src/components/FacilityPopup.js +++ b/health/micro-ui/web/micro-ui-internals/packages/modules/microplan/src/components/FacilityPopup.js @@ -1,37 +1,448 @@ -import React, { useState, useMemo, Fragment, useEffect } from "react"; +import React, { useState, Fragment, useEffect } from "react"; import { useTranslation } from "react-i18next"; -import { PopUp, Button, Card } from "@egovernments/digit-ui-components"; -import { InboxSearchComposer } from "@egovernments/digit-ui-react-components"; -import facilityMappingConfig from "../configs/FacilityMappingConfig"; +import { PopUp, Button, Tab, CheckBox, Card, Toast } from "@egovernments/digit-ui-components"; +import SearchJurisdiction from "./SearchJurisdiction"; +import { LoaderWithGap, Loader } from "@egovernments/digit-ui-react-components"; +import DataTable from "react-data-table-component"; +import AccessibilityPopUp from "./accessbilityPopUP"; +import SecurityPopUp from "./securityPopUp"; + + const FacilityPopUp = ({ details, onClose }) => { const { t } = useTranslation(); + const currentUserUuid = Digit.UserService.getUser().info.uuid; + const tenantId = Digit.ULBService.getCurrentTenantId(); + const [facilityAssignedStatus, setFacilityAssignedStatus] = useState(false); + const { microplanId, campaignId } = Digit.Hooks.useQueryParams(); + const [tableLoader, setTableLoader] = useState(false); + const [jurisdiction, setJurisdiction] = useState({}); + const [boundaries, setBoundaries] = useState({}); + const [searchKey, setSearchKey] = useState(0); // Key for forcing re-render of SearchJurisdiction + const [loader, setLoader] = useState(false); + const [selectedRows, setSelectedRows] = useState([]); // State for selected rows + const [isAllSelected, setIsAllSelected] = useState(false); + const [censusData, setCensusData] = useState([]); + const [showToast, setShowToast] = useState(null); + const [accessibilityData, setAccessibilityData] = useState(null); + const [securityData, setSecurityData] = useState(null); + const [viewDetails, setViewDetails] = useState(false) + const [totalCensusCount, setTotalCensusCount] = useState(0); + const [currentPage, setCurrentPage] = useState(1); + const [rowsPerPage, setRowsPerPage] = useState(10); + const configNavItem = [ + { + code: t(`MICROPLAN_UNASSIGNED_FACILITIES`), + name: "Unassigned Facilities", + }, + { + code: t(`MICROPLAN_ASSIGNED_FACILITIES`), + name: "Assigned Facilities", + } + ] + + const firstNavItem = configNavItem[0]; + const [activeLink, setActiveLink] = useState(firstNavItem); + + const handleTabClick = (e) => { + setActiveLink(e); + setSearchKey((prevKey) => prevKey + 1); // Increment key to trigger re-render + + // Update facilityAssignedStatus based on the clicked tab + if (e.code === t(`MICROPLAN_ASSIGNED_FACILITIES`)) { + setFacilityAssignedStatus(true); // Assigned Facilities tab + } else if (e.code === t(`MICROPLAN_UNASSIGNED_FACILITIES`)) { + setFacilityAssignedStatus(false); // Unassigned Facilities tab + } + + // Reset selected rows when changing tabs + setSelectedRows([]); + setIsAllSelected(false); + }; + + + + + const { data: planEmployeeDetailsData, isLoading: isLoadingPlanEmployee } = Digit.Hooks.microplanv1.usePlanSearchEmployee({ + tenantId: tenantId, + body: { + PlanEmployeeAssignmentSearchCriteria: { + tenantId: tenantId, + planConfigurationId: microplanId, + employeeId: [currentUserUuid], + }, + }, + config: { + enabled: true, + select: (data) => { + return data; + }, + }, + }); + + const { data: campaignData, isLoading: isLoadingCampaign } = Digit.Hooks.campaign.useSearchCampaign({ + tenantId: tenantId, + filter: { + ids: [campaignId], + }, + }); + + // Update boundaries when campaign data is available + useEffect(() => { + if (campaignData?.[0]) { + setBoundaries(campaignData?.[0]?.boundaries); + } + }, [campaignData]); + + useEffect(() => { + var jurisdictionArray = []; + const jurisdictionObject = { + boundaryType: planEmployeeDetailsData?.PlanEmployeeAssignment?.[0]?.hierarchyLevel, + boundaryCodes: planEmployeeDetailsData?.PlanEmployeeAssignment?.[0]?.jurisdiction, + }; + setJurisdiction(jurisdictionObject); + jurisdictionArray = planEmployeeDetailsData?.PlanEmployeeAssignment?.[0]?.jurisdiction?.map((item) => { return { code: item } }); + censusSearch(jurisdictionArray); + }, [microplanId, facilityAssignedStatus, details, planEmployeeDetailsData, currentPage, rowsPerPage]); + + useEffect(() => { + if (boundaries || jurisdiction) { + setSearchKey((prevKey) => prevKey + 1); // Increment key to force re-render + } + }, [boundaries, jurisdiction]); + + const censusSearchMutaionConfig = { + url: "/census-service/_search", + body: { + CensusSearchCriteria: { + tenantId: tenantId, + source: microplanId, + facilityAssigned: facilityAssignedStatus, + jurisdiction: null + } + }, + }; + + const mutationForCensusSearch = Digit.Hooks.useCustomAPIMutationHook(censusSearchMutaionConfig); + + + const censusSearch = async (data) => { + setTableLoader(true); + const codeArray = data?.length === 0 + ? planEmployeeDetailsData?.PlanEmployeeAssignment?.[0]?.jurisdiction?.map((item) => item) || [] + : data?.map((item) => item?.code); + await mutationForCensusSearch.mutate( + { + body: { + CensusSearchCriteria: { + tenantId: tenantId, + source: microplanId, + facilityAssigned: facilityAssignedStatus, + jurisdiction: codeArray, + pagination: { + limit: rowsPerPage, + offset: (currentPage - 1) * rowsPerPage, + } + } + }, + }, + { + onSuccess: async (result) => { + if (result?.Census) { + setCensusData(result?.Census); + setTotalCensusCount(result?.TotalCount) + return; + } + else { + setCensusData([]); + setTotalCensusCount(0) + } + }, + onError: (result) => { + // setDownloadError(true); + setShowToast({ key: "error", label: t("ERROR_WHILE_CENSUSSEARCH"), transitionTime: 5000 }); + }, + } + ); + setSelectedRows([]); + setIsAllSelected(false); + await new Promise((resolve) => setTimeout(resolve, 500)); + setTableLoader(false); + } + + useEffect(() => { + if (isLoadingPlanEmployee || isLoadingCampaign) { + setLoader(true); + } else { + setLoader(false); + } + }, [isLoadingPlanEmployee, isLoadingCampaign]); + + const handleRowSelect = (row) => { + const isSelected = selectedRows.includes(row.id); + const newSelectedRows = isSelected + ? selectedRows.filter((id) => id !== row.id) + : [...selectedRows, row.id]; + + setSelectedRows(newSelectedRows); + setIsAllSelected(newSelectedRows.length === censusData.length); + }; + + const handleSelectAll = () => { + if (isAllSelected) { + setSelectedRows([]); + } else { + const allRowIds = censusData.map((row) => row.id); + setSelectedRows(allRowIds); + } + setIsAllSelected(!isAllSelected); + }; + + const handleViewDetailsForAccessibility = (row) => { + setViewDetails(true); + setAccessibilityData(row); + setSecurityData(null); + }; + + const handleViewDetailsForSecurity = (row) => { + setViewDetails(true); + setSecurityData(row); + setAccessibilityData(null); + }; + + const columns = [ + { + name: ( + + ), + cell: (row) => ( + handleRowSelect(row)} + checked={selectedRows.includes(row.id)} + label="" + /> + ), + sortable: false, + allowOverflow: true, + width: "6rem" + }, + { + name: t("MP_FACILITY_VILLAGE"), // Change to your column name + selector: (row) => row.boundaryCode, // Replace with the appropriate field from your data + sortable: false, + }, + { + name: t("MP_VILLAGE_ACCESSIBILITY_LEVEL"), // Change to your column type + cell: (row) => ( + handleViewDetailsForAccessibility(row)} + > + {t("VIEW_DETAILS")} + + ), // Replace with the appropriate field from your data + sortable: false, + }, + { + name: t("MP_VILLAGE_SECURITY_LEVEL"), // Change to your column type + cell: (row) => ( + handleViewDetailsForSecurity(row)} + > + {t("VIEW_DETAILS")} + + ), // Replace with the appropriate field from your data + sortable: false, + }, + { + name: t("MP_FACILITY_TOTALPOPULATION"), // Change to your column type + selector: (row) => row.totalPopulation, // Replace with the appropriate field from your data + sortable: false, + } + // Add more columns as needed + ]; + + const planFacilityUpdateMutaionConfig = { + url: "/plan-service/plan/facility/_update", + body: { + PlanFacility: {} + }, + }; + + const mutationForPlanFacilityUpdate = Digit.Hooks.useCustomAPIMutationHook(planFacilityUpdateMutaionConfig); + + const handleAssignUnassign = async () => { + // Fetching the full data of selected rows + setLoader(true); + const selectedRowData = censusData.filter(row => selectedRows.includes(row.id)); + var newDetails = JSON.parse(JSON.stringify(details)); + if (facilityAssignedStatus) { + const boundarySet = new Set(selectedRowData.map((row) => { + return row.boundaryCode + })) + const filteredBoundaries = newDetails?.serviceBoundaries?.filter((boundary) => { + return !boundarySet.has(boundary) + }) + newDetails.serviceBoundaries = filteredBoundaries + // TODO : remove this logic + // newDetails.serviceBoundaries = Array.from(new Set(newDetails.serviceBoundaries.map(boundary => boundary[0] === " " ? boundary.slice(1) : boundary))); + + + } + else { + const boundarySet = new Set(selectedRowData.map((row) => { + return row.boundaryCode; + })); + const filteredBoundaries = [...boundarySet].filter(boundary => + !newDetails.serviceBoundaries.includes(boundary) + ); + newDetails.serviceBoundaries = newDetails?.serviceBoundaries?.concat(filteredBoundaries); + // TODO : remove this logic + // newDetails.serviceBoundaries = Array.from(new Set(newDetails.serviceBoundaries.map(boundary => boundary[0] === " " ? boundary.slice(1) : boundary))); + + } + await mutationForPlanFacilityUpdate.mutate( + { + body: { + PlanFacility: newDetails + }, + }, + { + onSuccess: async (result) => { + setSelectedRows([]); + setIsAllSelected(false); + }, + onError: (result) => { + // setDownloadError(true); + setShowToast({ key: "error", label: t("ERROR_WHILE_UPDATING_PLANFACILITY"), transitionTime: 5000 }); + }, + } + ); + await new Promise((resolve) => setTimeout(resolve, 500)); + setLoader(false); + }; + + const closeViewDetails = () => { + setAccessibilityData(null); + setSecurityData(null); + setViewDetails(false); + } + + // Handle page change + const handlePageChange = page => { + setCurrentPage(page); + }; - const config = facilityMappingConfig(); + const handleRowsPerPageChange = newPerPage => { + setRowsPerPage(newPerPage); + setCurrentPage(1); // Reset to first page when changing rows per page + }; return ( <> - , - ]} - onOverlayClick={onClose} - footerChildren={[ -