diff --git a/frontend/micro-ui/web/docker/Dockerfile b/frontend/micro-ui/web/docker/Dockerfile index e4f8af1c9..c52aeb9cf 100644 --- a/frontend/micro-ui/web/docker/Dockerfile +++ b/frontend/micro-ui/web/docker/Dockerfile @@ -1,5 +1,4 @@ -# FROM egovio/alpine-node-builder-14:yarn AS build -FROM ghcr.io/egovernments/alpine-node-builder-14:yarn AS build +FROM egovio/alpine-node-builder-14:yarn AS build RUN apk update && apk upgrade RUN apk add --no-cache git>2.30.0 ARG WORK_DIR @@ -13,7 +12,7 @@ RUN ls -lah RUN cd web/ \ && ./install-deps.sh \ && yarn install \ - && yarn build + && yarn build:webpack FROM nginx:mainline-alpine #FROM ghcr.io/egovernments/nginx:mainline-alpine diff --git a/frontend/micro-ui/web/micro-ui-internals/example/devpackage.json b/frontend/micro-ui/web/micro-ui-internals/example/devpackage.json index 92ee3ae02..625090509 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/devpackage.json +++ b/frontend/micro-ui/web/micro-ui-internals/example/devpackage.json @@ -4,12 +4,12 @@ "main": "index.js", "license": "MIT", "private": true, - "homepage": "digit-ui/", + "homepage": "mgramseva-web/", "scripts": { "start": "react-scripts start" }, "devDependencies": { - "@egovernments/digit-ui-libraries":"^1.5.7", + "@egovernments/digit-ui-libraries":"^1.4.0", "@egovernments/digit-ui-module-common":"^1.4.0", "@egovernments/digit-ui-module-engagement":"^1.4.0", "@egovernments/digit-ui-module-fsm":"^1.4.0", diff --git a/frontend/micro-ui/web/micro-ui-internals/example/maspackage.json b/frontend/micro-ui/web/micro-ui-internals/example/maspackage.json index 1f5432856..9294a8f51 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/maspackage.json +++ b/frontend/micro-ui/web/micro-ui-internals/example/maspackage.json @@ -4,7 +4,7 @@ "main": "index.js", "license": "MIT", "private": true, - "homepage": "digit-ui/", + "homepage": "mgramseva-web/", "scripts": { "start": "react-scripts start" }, 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 1214078d6..ea63ba6af 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/package.json +++ b/frontend/micro-ui/web/micro-ui-internals/example/package.json @@ -4,23 +4,18 @@ "main": "index.js", "license": "MIT", "private": true, - "homepage": "digit-ui", + "homepage": "mgramseva-web", "scripts": { "start": "react-scripts start" }, "devDependencies": { - "@egovernments/digit-ui-module-dss": "1.5.37", - "@egovernments/digit-ui-module-core": "1.5.42", - "@egovernments/digit-ui-module-common": "1.5.30", - "@egovernments/digit-ui-module-hrms": "1.5.25", - "@egovernments/digit-ui-module-utilities": "0.0.8", + "@egovernments/digit-ui-libraries": "1.5.7", + "@egovernments/digit-ui-module-dss": "1.5.34", + "@egovernments/digit-ui-module-core": "1.5.46", + "@egovernments/digit-ui-module-hrms": "1.5.27", + "@egovernments/digit-ui-module-pgr": "1.7.0", "@egovernments/digit-ui-module-engagement": "1.5.20", - "@egovernments/digit-ui-react-components": "1.5.28", - "@egovernments/digit-ui-svg-components": "0.0.1", - "@egovernments/digit-ui-libraries": "1.5.7", - "@egovernments/digit-ui-module-sample": "0.0.1", - "@egovernments/digit-ui-module-workbench":"0.0.3", - "@egovernments/digit-ui-customisation-mukta": "0.0.1", + "@egovernments/digit-ui-react-components": "1.5.26", "http-proxy-middleware": "^1.0.5", "react": "17.0.2", "react-dom": "17.0.2", @@ -40,4 +35,4 @@ "last 1 safari version" ] } -} +} \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/example/public/index.html b/frontend/micro-ui/web/micro-ui-internals/example/public/index.html index 4b1dd8760..609ecaa54 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/public/index.html +++ b/frontend/micro-ui/web/micro-ui-internals/example/public/index.html @@ -9,19 +9,26 @@ rel='stylesheet' type='text/css'> - mSeva - - - - - - - + mGramSeva + - + @@ -29,4 +36,4 @@
- \ No newline at end of file + diff --git a/frontend/micro-ui/web/micro-ui-internals/example/src/index.js b/frontend/micro-ui/web/micro-ui-internals/example/src/index.js index b885c8d42..0a103644a 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/src/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/example/src/index.js @@ -2,18 +2,12 @@ import React from "react"; import ReactDOM from "react-dom"; import { initLibraries } from "@egovernments/digit-ui-libraries"; -import { paymentConfigs, PaymentLinks, PaymentModule } from "@egovernments/digit-ui-module-common"; import { DigitUI } from "@egovernments/digit-ui-module-core"; import { initDSSComponents } from "@egovernments/digit-ui-module-dss"; import { initEngagementComponents } from "@egovernments/digit-ui-module-engagement"; import { initHRMSComponents } from "@egovernments/digit-ui-module-hrms"; -import { initUtilitiesComponents } from "@egovernments/digit-ui-module-utilities"; -import { initSampleComponents } from "@egovernments/digit-ui-module-sample"; -import {initWorkbenchComponents} from "@egovernments/digit-ui-module-workbench"; - -import { initMuktaCustomisations } from "@egovernments/digit-ui-customisation-mukta"; - -import "@egovernments/digit-ui-custom-css/example/index.css"; +import { initPGRComponents, PGRReducers } from "@egovernments/digit-ui-module-pgr"; +import "@egovernments/digit-ui-css/example/index.css"; import { pgrCustomizations } from "./pgr"; import { UICustomizations } from "./UICustomizations"; @@ -21,15 +15,13 @@ import { UICustomizations } from "./UICustomizations"; var Digit = window.Digit || {}; const enabledModules = [ + "DSS", "HRMS", + "PGR", // "Engagement", "NDSS","QuickPayLinks", "Payment", - "Utilities", + // "Utilities", //added to check fsm // "FSM" - "Mukta", - "Sample", - // "Workbench" - ]; const initTokens = (stateCode) => { @@ -59,35 +51,32 @@ const initTokens = (stateCode) => { }; const initDigitUI = () => { - window.contextPath = window?.globalConfigs?.getConfig("CONTEXT_PATH") || "digit-ui"; + window.contextPath = window?.globalConfigs?.getConfig("CONTEXT_PATH") || "mgramseva-web"; - window?.Digit.ComponentRegistryService.setupRegistry({ - PaymentModule, - ...paymentConfigs, - PaymentLinks, - }); + // window?.Digit.ComponentRegistryService.setupRegistry({ + // PaymentModule, + // ...paymentConfigs, + // PaymentLinks, + // }); initDSSComponents(); initHRMSComponents(); initEngagementComponents(); - initUtilitiesComponents(); - initSampleComponents(); - initWorkbenchComponents(); + initPGRComponents(); - const moduleReducers = (initData) => initData; + const moduleReducers = (initData) => ({ + pgr: PGRReducers(initData), + }); window.Digit.Customizations = { PGR: pgrCustomizations, commonUiConfig: UICustomizations, }; - const stateCode = window?.globalConfigs?.getConfig("STATE_LEVEL_TENANT_ID") || "pg"; + const stateCode = window?.globalConfigs?.getConfig("STATE_LEVEL_TENANT_ID") || "pb"; initTokens(stateCode); - initMuktaCustomisations(); - ReactDOM.render( - , - document.getElementById("root") - ); + + ReactDOM.render(, document.getElementById("root")); }; initLibraries().then(() => { diff --git a/frontend/micro-ui/web/micro-ui-internals/example/src/setupProxy.js b/frontend/micro-ui/web/micro-ui-internals/example/src/setupProxy.js index 17fffdd8f..b05780473 100644 --- a/frontend/micro-ui/web/micro-ui-internals/example/src/setupProxy.js +++ b/frontend/micro-ui/web/micro-ui-internals/example/src/setupProxy.js @@ -5,21 +5,16 @@ const createProxy = createProxyMiddleware({ // target: process.env.REACT_APP_PROXY_API || "https://qa.digit.org", target: process.env.REACT_APP_PROXY_API || "https://works-dev.digit.org", changeOrigin: true, - secure:false + secure: true, }); const assetsProxy = createProxyMiddleware({ target: process.env.REACT_APP_PROXY_ASSETS || "https://works-dev.digit.org", changeOrigin: true, - secure:false -}); -const mdmsProxy = createProxyMiddleware({ - target: process.env.REACT_APP_PROXY_ASSETS || "http://localhost:8080", - changeOrigin: true, - secure:false + secure: true, }); module.exports = function (app) { - ["/mdms-v2/v2/_create"].forEach((location) => app.use(location, mdmsProxy)); - [ "/access/v1/actions/mdms", + [ + "/access/v1/actions/mdms", "/egov-mdms-service", "/egov-location", "/localization", @@ -76,7 +71,7 @@ module.exports = function (app) { "/egov-pdf/download/WORKSESTIMATE/estimatepdf", "/muster-roll", "/individual", - "/mdms-v2" + "/mdms-v2", ].forEach((location) => app.use(location, createProxy)); ["/pb-egov-assets"].forEach((location) => app.use(location, assetsProxy)); }; diff --git a/frontend/micro-ui/web/micro-ui-internals/package.json b/frontend/micro-ui/web/micro-ui-internals/package.json index 533a4988d..dfbfd4ff1 100644 --- a/frontend/micro-ui/web/micro-ui-internals/package.json +++ b/frontend/micro-ui/web/micro-ui-internals/package.json @@ -5,10 +5,9 @@ "workspaces": [ "packages/libraries", "example", - "packages/custom-css", + "packages/css", "packages/react-components", - "packages/modules/*", - "packages/Mukta" + "packages/modules/*" ], "author": "JaganKumar ", "license": "MIT", @@ -21,24 +20,29 @@ "sprint": "SKIP_PREFLIGHT_CHECK=true run-s start:script", "start:dev": "run-p dev:**", "start:script": "./scripts/create.sh", - "dev:css": "cd packages/custom-css && yarn start", - "publish:css": "cd packages/custom-css && yarn publish --access public", + "dev:css": "cd packages/css && yarn start", + "publish:css": "cd packages/css && yarn publish --access public", "dev:libraries": "cd packages/libraries && yarn start", "dev:components": "cd packages/react-components && yarn start", + "dev:pgr": "cd packages/modules/pgr && yarn start", + "dev:hrms": "cd packages/modules/hrms && yarn start", + "dev:core": "cd packages/modules/core && yarn start", "dev:example": "cd example && yarn start", - "dev:sample": "cd packages/modules/sample && yarn start", - "dev:mukta": "cd packages/Mukta && yarn start", "build": "run-p build:**", + "build:css": "cd packages/css && yarn build:prod", "build:libraries": "cd packages/libraries && yarn build", "build:components": "cd packages/react-components && yarn build", - "build:mukta": "cd packages/Mukta && yarn build", + "build:pgr": "cd packages/modules/pgr && yarn build", + "build:hrms": "cd packages/modules/hrms && yarn build", + "build:core": "cd packages/modules/core && yarn build", "build:sample": "cd packages/modules/sample && yarn build", "deploy:jenkins": "./scripts/jenkins.sh", "clean": "rm -rf node_modules" }, "resolutions": { "**/@babel/runtime": "7.20.1", - "**/babel-preset-react-app": "10.0.0" + "**/babel-preset-react-app": "10.0.0", + "**/polished": "4.2.2" }, "devDependencies": { "husky": "7.0.4", diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/package.json deleted file mode 100644 index 2302f62dc..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@egovernments/digit-ui-customisation-mukta", - "version": "0.0.1", - "description": "MUKTA Customisation of Works UI", - "main": "dist/index.js", - "module": "dist/index.modern.js", - "source": "src/Module.js", - "files": [ - "dist" - ], - "scripts": { - "start": "microbundle-crl watch --no-compress --format modern,cjs", - "build": "microbundle-crl --compress --no-sourcemap --format cjs", - "prepublish": "yarn build" - }, - "peerDependencies": { - "react": "17.0.2", - "react-router-dom": "5.3.0" - }, - "dependencies": { - "@egovernments/digit-ui-react-components": "^1.5.0", - "react": "17.0.2", - "react-date-range": "^1.4.0", - "react-dom": "17.0.2", - "react-hook-form": "6.15.8", - "react-i18next": "11.16.2", - "react-query": "3.6.1", - "react-router-dom": "5.3.0" - }, - "author": "JaganKumar ", - "license": "MIT" - } \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/Module.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/Module.js deleted file mode 100644 index 59482bf27..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/Module.js +++ /dev/null @@ -1,81 +0,0 @@ -import { Loader } from "@egovernments/digit-ui-react-components"; -import React from "react"; -import { useRouteMatch } from "react-router-dom"; -import EmployeeApp from "./pages/employee"; -import { CustomisedHooks } from "./hooks"; -import { UICustomizations } from "./configs/UICustomizations"; -import HRMSCard from "./components/HRMSCard"; -import MuktaCard from "./components/MuktaCard"; -import SampleComponent from "./components/SampleComponent"; - - -const MuktaModule = ({ stateCode, userType, tenants }) => { - stateCode=Digit.ULBService.getStateId(); - const moduleCode = ["Mukta"]; - const { path, url } = useRouteMatch(); - const language = Digit.StoreData.getCurrentLanguage(); - const { isLoading, data: store } = Digit.Services.useStore({ - stateCode, - moduleCode, - language, - }); - - if (isLoading) { - return ; - } - - return ; -}; - -const componentsToRegister = { - MuktaModule, - MuktaCard, - DSSCard:null, // TO HIDE THE DSS CARD IN HOME SCREEN as per MUKTA - AttendenceMgmtCard:null , // TO HIDE THE Attendance Mgmt CARD IN HOME SCREEN as per MUKTA - HRMSCard ,// Overridden the HRMS card as per MUKTA - - SampleComponent -}; - -const overrideHooks = () => { - Object.keys(CustomisedHooks).map((ele) => { - if (ele === "Hooks") { - Object.keys(CustomisedHooks[ele]).map((hook) => { - Object.keys(CustomisedHooks[ele][hook]).map((method) => { - setupHooks(hook, method, CustomisedHooks[ele][hook][method]); - }); - }); - } else { - Object.keys(CustomisedHooks[ele]).map((method) => { - setupLibraries(ele, method, CustomisedHooks[ele][method]); - }); - } - }); -}; - -/* To Overide any existing hook we need to use similar method */ -const setupHooks = (HookName, HookFunction, method) => { - window.Digit = window.Digit || {}; - window.Digit["Hooks"] = window.Digit["Hooks"] || {}; - window.Digit["Hooks"][HookName] = window.Digit["Hooks"][HookName] || {}; - window.Digit["Hooks"][HookName][HookFunction] = method; -}; -/* To Overide any existing libraries we need to use similar method */ -const setupLibraries = (Library, service, method) => { - window.Digit = window.Digit || {}; - window.Digit[Library] = window.Digit[Library] || {}; - window.Digit[Library][service] = method; -}; - -/* To Overide any existing config/middlewares we need to use similar method */ -const updateCustomConfigs = () => { - setupLibraries("Customizations", "commonUiConfig", { ...window?.Digit?.Customizations?.commonUiConfig, ...UICustomizations }); -}; - -export const initMuktaCustomisations = () => { - overrideHooks(); - updateCustomConfigs(); - Object.entries(componentsToRegister).forEach(([key, value]) => { - Digit.ComponentRegistryService.setComponent(key, value); - }); -}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/HRMSCard.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/HRMSCard.js deleted file mode 100644 index 9e4124b65..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/HRMSCard.js +++ /dev/null @@ -1,44 +0,0 @@ -import { HRIcon, EmployeeModuleCard } from "@egovernments/digit-ui-react-components"; -import React from "react"; -import { useTranslation } from "react-i18next"; - -const HRMSCard = () => { - const ADMIN = Digit.Utils.hrmsAccess(); - if (!ADMIN) { - return null; - } - const { t } = useTranslation(); - // const tenantId = Digit.ULBService.getCurrentTenantId(); - // const { isLoading, isError, error, data, ...rest } = Digit.Hooks.hrms.useHRMSCount(tenantId); - - const propsForModuleCard = { - Icon: , - moduleName: t("ACTION_TEST_9HRMS"), - kpis: [ - // { - // count: isLoading ? "-" : data?.EmployeCount?.totalEmployee, - // label: t("TOTAL_EMPLOYEES"), - // link: `/${window?.contextPath}/employee/hrms/inbox` - // }, - // { - // count: isLoading ? "-" : data?.EmployeCount?.activeEmployee, - // label: t("ACTIVE_EMPLOYEES"), - // link: `/${window?.contextPath}/employee/hrms/inbox` - // } - ], - links: [ - { - label: t("HR_HOME_SEARCH_RESULTS_HEADING"), - link: `/${window?.contextPath}/employee/hrms/inbox`, - }, - { - label: t("HR_COMMON_CREATE_EMPLOYEE_HEADER"), - link: `/${window?.contextPath}/employee/hrms/create`, - }, - ], - }; - - return ; -}; - -export default HRMSCard; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/MuktaCard.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/MuktaCard.js deleted file mode 100644 index 6c3c6a46d..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/MuktaCard.js +++ /dev/null @@ -1,26 +0,0 @@ -import { HRIcon, EmployeeModuleCard, AttendanceIcon, } from "@egovernments/digit-ui-react-components"; -import React from "react"; -import { useTranslation } from "react-i18next"; - -const MuktaCard = () => { - - const { t } = useTranslation(); - - const propsForModuleCard = { - Icon: , - moduleName: t("Mukta Customisation Module"), - kpis: [ - - ], - links: [ - { - label: t("Sample"), - link: `/${window?.contextPath}/employee/Mukta/pageone`, - } - ], - }; - - return ; -}; - -export default MuktaCard; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/SampleComponent.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/SampleComponent.js deleted file mode 100644 index 08bd5fa24..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/components/SampleComponent.js +++ /dev/null @@ -1,28 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; - -const SampleComponent = (props) => { - const [data, updateData] = useState({}); - const { t } = useTranslation(); - useEffect(() => { - updateData(props?.formData || {}); - }, [props, props?.formData]); - return ( -
-

View Entered Data(SampleComponent)

-
- {Object.keys(data).map((key) => { - return ( - data?.[key] && ( -
- {key} : {JSON.stringify(data?.[key])} -
- ) - ); - })} -
-
- ); -}; - -export default SampleComponent; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/configs/UICustomizations.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/configs/UICustomizations.js deleted file mode 100644 index e7d116933..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/configs/UICustomizations.js +++ /dev/null @@ -1,265 +0,0 @@ -import { Link } from "react-router-dom"; -import _ from "lodash"; -import React from "react"; -import { LinkLabel } from "@egovernments/digit-ui-react-components"; - -//create functions here based on module name set in mdms(eg->SearchProjectConfig) -//how to call these -> Digit?.Customizations?.[masterName]?.[moduleName] -// these functions will act as middlewares -var Digit = window.Digit || {}; - - - -export const UICustomizations = { - - AttendanceInboxConfig: { - preProcess: (data) => { - - //set tenantId - data.body.inbox.tenantId = Digit.ULBService.getCurrentTenantId(); - data.body.inbox.processSearchCriteria.tenantId = Digit.ULBService.getCurrentTenantId(); - - const musterRollNumber = data?.body?.inbox?.moduleSearchCriteria?.musterRollNumber?.trim(); - if(musterRollNumber) data.body.inbox.moduleSearchCriteria.musterRollNumber = musterRollNumber - - const attendanceRegisterName = data?.body?.inbox?.moduleSearchCriteria?.attendanceRegisterName?.trim(); - if(attendanceRegisterName) data.body.inbox.moduleSearchCriteria.attendanceRegisterName = attendanceRegisterName - - // deleting them for now(assignee-> need clarity from pintu,ward-> static for now,not implemented BE side) - const assignee = _.clone(data.body.inbox.moduleSearchCriteria.assignee); - delete data.body.inbox.moduleSearchCriteria.assignee; - if (assignee?.code === "ASSIGNED_TO_ME") { - data.body.inbox.moduleSearchCriteria.assignee = Digit.UserService.getUser().info.uuid; - } - - //cloning locality and workflow states to format them - // let locality = _.clone(data.body.inbox.moduleSearchCriteria.locality ? data.body.inbox.moduleSearchCriteria.locality : []); - - let selectedOrg = _.clone(data.body.inbox.moduleSearchCriteria.orgId ? data.body.inbox.moduleSearchCriteria.orgId : null); - delete data.body.inbox.moduleSearchCriteria.orgId; - if(selectedOrg) { - data.body.inbox.moduleSearchCriteria.orgId = selectedOrg?.[0]?.applicationNumber; - } - - // let selectedWard = _.clone(data.body.inbox.moduleSearchCriteria.ward ? data.body.inbox.moduleSearchCriteria.ward : null); - // delete data.body.inbox.moduleSearchCriteria.ward; - // if(selectedWard) { - // data.body.inbox.moduleSearchCriteria.ward = selectedWard?.[0]?.code; - // } - - let states = _.clone(data.body.inbox.moduleSearchCriteria.state ? data.body.inbox.moduleSearchCriteria.state : []); - let ward = _.clone(data.body.inbox.moduleSearchCriteria.ward ? data.body.inbox.moduleSearchCriteria.ward : []); - // delete data.body.inbox.moduleSearchCriteria.locality; - delete data.body.inbox.moduleSearchCriteria.state; - delete data.body.inbox.moduleSearchCriteria.ward; - - // locality = locality?.map((row) => row?.code); - states = Object.keys(states)?.filter((key) => states[key]); - ward = ward?.map((row) => row?.code); - - - // //adding formatted data to these keys - // if (locality.length > 0) data.body.inbox.moduleSearchCriteria.locality = locality; - if (states.length > 0) data.body.inbox.moduleSearchCriteria.status = states; - if (ward.length > 0) data.body.inbox.moduleSearchCriteria.ward = ward; - const projectType = _.clone(data.body.inbox.moduleSearchCriteria.projectType ? data.body.inbox.moduleSearchCriteria.projectType : {}); - if (projectType?.code) data.body.inbox.moduleSearchCriteria.projectType = projectType.code; - - //adding tenantId to moduleSearchCriteria - data.body.inbox.moduleSearchCriteria.tenantId = Digit.ULBService.getCurrentTenantId(); - - //setting limit and offset becoz somehow they are not getting set in muster inbox - data.body.inbox .limit = data.state.tableForm.limit - data.body.inbox.offset = data.state.tableForm.offset - delete data.state - return data; - }, - postProcess: (responseArray, uiConfig) => { - const statusOptions = responseArray?.statusMap - ?.filter((item) => item.applicationstatus) - ?.map((item) => ({ code: item.applicationstatus, i18nKey: `COMMON_MASTERS_${item.applicationstatus}` })); - if (uiConfig?.type === "filter") { - let fieldConfig = uiConfig?.fields?.filter((item) => item.type === "dropdown" && item.populators.name === "musterRollStatus"); - if (fieldConfig.length) { - fieldConfig[0].populators.options = statusOptions; - } - } - }, - additionalCustomizations: (row, key, column, value, t, searchResult) => { - if (key === "ATM_MUSTER_ROLL_ID") { - return ( - - - {String(value ? (column.translate ? t(column.prefix ? `${column.prefix}${value}` : value) : value) : t("ES_COMMON_NA"))} - - - ); - } - if (key === "ATM_ATTENDANCE_WEEK") { - const week = `${Digit.DateUtils.ConvertTimestampToDate(value?.startDate, "dd/MM/yyyy")}-${Digit.DateUtils.ConvertTimestampToDate( - value?.endDate, - "dd/MM/yyyy" - )}`; - return
{week}
; - } - if (key === "ATM_NO_OF_INDIVIDUALS") { - return
{value?.length}
; - } - - if(key === "ATM_AMOUNT_IN_RS"){ - return {value ? Digit.Utils.dss.formatterWithoutRound(value, "number") : t("ES_COMMON_NA")}; - } - if (key === "ATM_SLA") { - return parseInt(value) > 0 ? ( - {t(value) || ""} - ) : ( - {t(value) || ""} - ); - } - if (key === "COMMON_WORKFLOW_STATES") { - return {t(`WF_MUSTOR_${value}`)} - } - - //added this in case we change the key and not updated here , it'll throw that nothing was returned from cell error if that case is not handled here. To prevent that error putting this default - return {t(`CASE_NOT_HANDLED`)} - }, - MobileDetailsOnClick: (row, tenantId) => { - let link; - Object.keys(row).map((key) => { - if (key === "ATM_MUSTER_ROLL_ID") - link = `/${window.contextPath}/employee/attendencemgmt/view-attendance?tenantId=${tenantId}&musterRollNumber=${row[key]}`; - }); - return link; - }, - populateReqCriteria: () => { - - const tenantId = Digit.ULBService.getCurrentTenantId(); - - return { - url: "/org-services/organisation/v1/_search", - params: { limit: 50, offset: 0 }, - body: { - SearchCriteria: { - tenantId: tenantId, - functions : { - type : "CBO" - } - }, - }, - config: { - enabled: true, - select: (data) => { - return data?.organisations; - }, - }, - }; - }, - }, - - - SearchWageSeekerConfig: { - customValidationCheck: (data) => { - //checking both to and from date are present - const { createdFrom, createdTo } = data; - if ((createdFrom === "" && createdTo !== "") || (createdFrom !== "" && createdTo === "")) - return { warning: true, label: "ES_COMMON_ENTER_DATE_RANGE" }; - - return false; - }, - preProcess: (data) => { - data.params = { ...data.params, tenantId: Digit.ULBService.getCurrentTenantId() }; - - let requestBody = { ...data.body.Individual }; - const pathConfig = { - name: "name.givenName", - }; - const dateConfig = { - createdFrom: "daystart", - createdTo: "dayend", - }; - const selectConfig = { - wardCode: "wardCode[0].code", - socialCategory: "socialCategory.code", - }; - const textConfig = ["name", "individualId"] - let Individual = Object.keys(requestBody) - .map((key) => { - if (selectConfig[key]) { - requestBody[key] = _.get(requestBody, selectConfig[key], null); - } else if (typeof requestBody[key] == "object") { - requestBody[key] = requestBody[key]?.code; - } else if (textConfig?.includes(key)) { - requestBody[key] = requestBody[key]?.trim() - } - return key; - }) - .filter((key) => requestBody[key]) - .reduce((acc, curr) => { - if (pathConfig[curr]) { - _.set(acc, pathConfig[curr], requestBody[curr]); - } else if (dateConfig[curr] && dateConfig[curr]?.includes("day")) { - _.set(acc, curr, Digit.Utils.date.convertDateToEpoch(requestBody[curr], dateConfig[curr])); - } else { - _.set(acc, curr, requestBody[curr]); - } - return acc; - }, {}); - - data.body.Individual = { ...Individual }; - return data; - }, - additionalCustomizations: (row, key, column, value, t, searchResult) => { - //here we can add multiple conditions - //like if a cell is link then we return link - //first we can identify which column it belongs to then we can return relevant result - switch (key) { - case "MASTERS_WAGESEEKER_ID": - return ( - - - {String(value ? (column.translate ? t(column.prefix ? `${column.prefix}${value}` : value) : value) : t("ES_COMMON_NA"))} - - - ); - - case "MASTERS_SOCIAL_CATEGORY": - return value ? {String(t(`MASTERS_${value}`))} : t("ES_COMMON_NA"); - - case "CORE_COMMON_PROFILE_CITY": - return value ? {String(t(Digit.Utils.locale.getCityLocale(value)))} : t("ES_COMMON_NA"); - - case "MASTERS_WARD": - return value ? ( - {String(t(Digit.Utils.locale.getMohallaLocale(value, row?.tenantId)))} - ) : ( - t("ES_COMMON_NA") - ); - - case "MASTERS_LOCALITY": - return value ? ( - {String(t(Digit.Utils.locale.getMohallaLocale(value, row?.tenantId)))} - ) : ( - t("ES_COMMON_NA") - ); - default: - return t("ES_COMMON_NA"); - } - }, - MobileDetailsOnClick: (row, tenantId) => { - let link; - Object.keys(row).map((key) => { - if (key === "MASTERS_WAGESEEKER_ID") - link = `/${window.contextPath}/employee/masters/view-wageseeker?tenantId=${tenantId}&wageseekerId=${row[key]}`; - }); - return link; - }, - additionalValidations: (type, data, keys) => { - if (type === "date") { - return data[keys.start] && data[keys.end] ? () => new Date(data[keys.start]).getTime() <= new Date(data[keys.end]).getTime() : true; - } - } - }, - -}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/index.js deleted file mode 100644 index dedad1697..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import {logoutV1} from "./logout"; -import useEventDetails from "./useEventDetails"; - -const UserService={ - logoutV1, -} - -const works = { - -} - -const contracts = { - -} -const events={ - useEventDetails -} - -const Hooks ={ - attendance:{ - update:()=>{} - }, - works, - contracts, - events -} - - -export const CustomisedHooks ={ - Hooks, - UserService -} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/logout.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/logout.js deleted file mode 100644 index cfceb8c69..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/logout.js +++ /dev/null @@ -1,58 +0,0 @@ -var Digit = window.Digit || {}; - - - -/* Recreated a new hook in same name*/ -export const logoutV1 = async () => { - let user = Digit.UserService.getUser(); - if (!user || !user.info || !user.access_token) return false; - const { type } = user.info; - const access_token = user?.access_token; - const tenantId = - type === "CITIZEN" - ? Digit.ULBService.getStateId() - : Digit.ULBService.getCurrentTenantId(); - const myHeaders = new Headers(); - myHeaders.append("accept", "application/json, text/plain, */*"); - myHeaders.append("content-type", "application/json;charset=UTF-8"); - const raw = { - RequestInfo: { - apiId: "Rainmaker", - ver: ".01", - ts: "", - action: "_logout", - did: "1", - key: "", - msgId: "20170310130900|en_IN", - authToken: access_token, - }, - access_token: access_token, - }; - - var requestOptions = { - method: "POST", - headers: myHeaders, - body: JSON.stringify(raw), - redirect: "follow", - }; - const userType = Digit.UserService.getType(); - try { - await fetch( - `${window.location.origin}/user/v1/_logout?tenantId=${tenantId}`, - requestOptions - ) - .then((response) => response.json()) - .catch((error) => console.log("error", error)); - } catch (e) { - } finally { - window.localStorage.clear(); - window.sessionStorage.clear(); - if (userType === "citizen") { - window.location.replace("/digit-ui/citizen"); - } else { - window.location.replace("/digit-ui/employee/user/language-selection"); - } - } -}; - - diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/useEventDetails.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/useEventDetails.js deleted file mode 100644 index fa2cd35ab..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/hooks/useEventDetails.js +++ /dev/null @@ -1,44 +0,0 @@ -import { useQuery } from 'react-query'; -import { format } from "date-fns"; - -const useEventDetails = (tenantId, filters, config = {}) => { - return useQuery( - ['EVENT_DETAILS', tenantId, filters], - () => Digit.EventsServices.EventDetails(tenantId, filters), - { - select: (data) => { - const details = [{ - title:" ", - asSectionHeader: true, - values: [ - { title: "JAGAN", value: data?.tenantId },// added a different view screen - { title: "EVENTS_NAME_LABEL", value: data?.name }, - { title: "EVENTS_CATEGORY_LABEL", value: data?.eventCategory }, - { title: "EVENTS_DESCRIPTION_LABEL", value: data?.description }, - { title: "EVENTS_FROM_DATE_LABEL", value: format(new Date(data?.eventDetails?.fromDate), 'dd/MM/yyyy') }, - { title: "EVENTS_TO_DATE_LABEL", value: format(new Date(data?.eventDetails?.toDate), 'dd/MM/yyyy') }, - { title: "EVENTS_FROM_TIME_LABEL", value: format(new Date(data?.eventDetails?.fromDate), 'hh:mm'), skip: true }, - { title: "EVENTS_TO_TIME_LABEL", value: format(new Date(data?.eventDetails?.toDate), 'hh:mm'), skip: true }, - { title: "EVENTS_ADDRESS_LABEL", value: data?.eventDetails?.address }, - { title: "EVENTS_MAP_LABEL", - map: true, - value: data?.eventDetails?.latitude && data?.eventDetails?.longitude ? - Digit.Utils.getStaticMapUrl(data?.eventDetails?.latitude, data?.eventDetails?.longitude) : - 'N/A' - }, - { title: "EVENTS_ORGANIZER_NAME_LABEL", value: data?.eventDetails?.organizer }, - { title: "EVENTS_ENTRY_FEE_INR_LABEL", value: data?.eventDetails?.fees }, - ] - }] - return { - applicationData: data, - applicationDetails: details, - tenantId: tenantId - } - }, - ...config - } - ) -} - -export default useEventDetails; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/pages/employee/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/pages/employee/index.js deleted file mode 100644 index ef8a4a3f0..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/pages/employee/index.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from "react"; -import { PrivateRoute, BreadCrumb, Card } from "@egovernments/digit-ui-react-components"; -import { Switch } from "react-router-dom"; -import { useTranslation } from "react-i18next"; - -import { Redirect } from "react-router-dom"; - -const CustomBredcrumb = ({ t }) => ( - -); - -const App = ({ path }) => { - const { t } = useTranslation(); - return ( - - -
- -
Sample screen created in Mukta Customisation folder
} /> - - {/* - - */} -
-
-
- ); -}; - -export default App; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/services/Search.js b/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/services/Search.js deleted file mode 100644 index 865eceb2a..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/Mukta/src/services/Search.js +++ /dev/null @@ -1,145 +0,0 @@ -import _ from "lodash"; - -const createProjectsArray = (t, project, searchParams, headerLocale) => { - let totalProjects = { - searchedProject : {}, - subProjects : [] - }; - let basicDetails = {}; - let totalProjectsLength = project.length; - // for(let projectIndex = 0; projectIndex < totalProjectsLength; projectIndex++) { - let currentProject = project[0]; - const headerDetails = { - title: " ", - asSectionHeader: true, - values: [ - { title: "WORKS_PROJECT_ID", value: currentProject?.projectNumber || "NA"}, - { title: "ES_COMMON_PROPOSAL_DATE", value: Digit.Utils.pt.convertEpochToDate(currentProject?.additionalDetails?.dateOfProposal) || "NA"}, - { title: "WORKS_PROJECT_NAME", value: currentProject?.name || "NA"}, - { title: "PROJECT_PROJECT_DESC", value: currentProject?.description || "NA"} - ] - }; - - const projectDetails = { - title: "WORKS_PROJECT_DETAILS", - asSectionHeader: true, - values: [ - { title: "PROJECT_LOR", value: currentProject?.referenceID || "NA" }, - { title: "WORKS_PROJECT_TYPE", value: currentProject?.projectType ? t(`COMMON_MASTERS_${Digit.Utils.locale.getTransformedLocale(currentProject?.projectType)}`) : "NA" }, - { title: "PROJECT_TARGET_DEMOGRAPHY", value: currentProject?.additionalDetails?.targetDemography ? t(`COMMON_MASTERS_${currentProject?.additionalDetails?.targetDemography }`) : "NA" }, - { title: "PROJECT_ESTIMATED_COST", value: currentProject?.additionalDetails?.estimatedCostInRs ? `₹ ${Digit.Utils.dss.formatterWithoutRound(currentProject?.additionalDetails?.estimatedCostInRs, 'number')}` : "NA" }, - ] - }; - - const locationDetails = { - title: "WORKS_LOCATION_DETAILS", - asSectionHeader: true, - values: [ - { title: "WORKS_GEO_LOCATION",value: (currentProject?.address?.latitude || currentProject?.address?.longitude ) ? `${currentProject?.address?.latitude}, ${currentProject?.address?.longitude}` : "NA" }, - { title: "WORKS_CITY",value: currentProject?.address?.city ? t(`TENANT_TENANTS_${Digit.Utils.locale.getTransformedLocale(currentProject?.address?.city)}`) : "NA" }, //will check with Backend - { title: "WORKS_WARD", value: currentProject?.address?.boundary ? t(`${headerLocale}_ADMIN_${currentProject?.address?.boundary}`) : "NA" }, ///backend to update this - { title: "WORKS_LOCALITY",value: currentProject?.additionalDetails?.locality ? t(`${headerLocale}_ADMIN_${currentProject?.additionalDetails?.locality}`) : "NA" }, - ] - }; - - // const financialDetails = { - // title: "WORKS_FINANCIAL_DETAILS", - // asSectionHeader: false, - // values: [ - // { title: "WORKS_HEAD_OF_ACCOUNTS", value: currentProject?.additionalDetails?.fund ? t(`COMMON_MASTERS_FUND_${currentProject?.additionalDetails?.fund}`) : "NA" }, - // ], - // }; - - - let documentDetails = { - title: "", - asSectionHeader: true, - additionalDetails: { - documents: [{ - title: "WORKS_RELEVANT_DOCUMENTS", - BS : 'Works', - values: currentProject?.documents?.map((document) => { - if(document?.status !== "INACTIVE") { - return { - title: document?.documentType === "OTHERS" ? document?.additionalDetails?.otherCategoryName : t(`PROJECT_${document?.documentType}`), - documentType: document?.documentType, - documentUid: document?.fileStore, - fileStoreId: document?.fileStore, - }; - } - return {}; - }), - }, - ] - } - } - - //filter any empty object - documentDetails.additionalDetails.documents[0].values =documentDetails?.additionalDetails?.documents?.[0]?.values?.filter(value=>{ - if(value?.title){ - return value; - } - }); - - // if(currentProject?.projectNumber === searchParams?.Projects?.[0]?.projectNumber) { - basicDetails = { - projectID : currentProject?.projectNumber, - projectProposalDate : Digit.Utils.pt.convertEpochToDate(currentProject?.additionalDetails?.dateOfProposal) || "NA", - projectName : currentProject?.name || "NA", - projectDesc : currentProject?.description || "NA", - projectHasSubProject : (totalProjectsLength > 1 ? "COMMON_YES" : "COMMON_NO"), - projectParentProjectID : currentProject?.ancestors?.[0]?.projectNumber || "NA", - uuid:currentProject?.id, - address:currentProject?.address, - ward: currentProject?.address?.boundary, - locality:currentProject?.additionalDetails?.locality - } - totalProjects.searchedProject = { - basicDetails, - headerDetails, - projectDetails, - locationDetails, - documentDetails - } - // } - // } - return totalProjects; -} - -export const Search = { - viewProjectDetailsScreen: async(t,tenantId, searchParams, filters = {limit : 10, offset : 0, includeAncestors : true, includeDescendants : true}, headerLocale)=> { - const response = await Digit.WorksService?.searchProject(tenantId, searchParams, filters); - - let projectDetails = { - searchedProject : { - basicDetails : {}, - details : { - projectDetails : [], - } - }, - } - - if(response?.Project) { - let projects = createProjectsArray(t, response?.Project, searchParams, headerLocale); - - //searched Project details - projectDetails.searchedProject['basicDetails'] = projects?.searchedProject?.basicDetails; - projectDetails.searchedProject['details']['projectDetails'] = {applicationDetails : [projects?.searchedProject?.headerDetails, projects?.searchedProject?.projectDetails, projects?.searchedProject?.locationDetails, projects?.searchedProject?.documentDetails]}; //rest categories will come here - - } - - return { - projectDetails : response?.Project ? projectDetails : [], - response : response?.Project, - processInstancesDetails: [], - applicationData: {}, - workflowDetails: [], - applicationData:{}, - isNoDataFound : response?.Project?.length === 0 - } - }, - searchEstimate : async(tenantId, filters) => { - const response = await Digit.WorksService?.estimateSearch({tenantId, filters}); - return response?.estimates; - } -} \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/README.md b/frontend/micro-ui/web/micro-ui-internals/packages/css/README.md index 2d494b4c6..600bb6a68 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/README.md +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/README.md @@ -42,6 +42,12 @@ frontend/micro-ui/web/public/index.html # Changelog ```bash +1.5.31 Corrected the CSS for inbox composers and default core ui +1.5.30 Updated the css for dynamic drodown filter dss +1.5.29 layout issues fixed +1.5.28 Horizontal Bar chart alignment fixes +1.5.27 DSS UI alignment fixes for Horizontal Metric and bar chart +1.5.26 added new css class for dss enhancements 1.5.25 added the css of inbox search composers 1.5.24 added the readme file 1.5.23 base version diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/css/package.json index 56b75fdc8..fa4b0ee9e 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/package.json +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/package.json @@ -1,6 +1,6 @@ { "name": "@egovernments/digit-ui-css", - "version": "1.5.25", + "version": "1.5.50", "license": "MIT", "main": "dist/index.css", "author": "Jagankumar ", @@ -21,12 +21,12 @@ "last 2 versions" ], "style": "./dist/index.css", - "dependencies": { - "node-sass": "^4.14.1", - "normalize.css": "^8.0.1", - "postcss-scss": "^3.0.1", - "tailwindcss": "^1.8.10" - }, + "dependencies": { + "node-sass": "^4.14.1", + "normalize.css": "^8.0.1", + "postcss-scss": "^3.0.1", + "tailwindcss": "^1.8.10" + }, "devDependencies": { "autoprefixer": "^10.0.0", "cssnano": "^4.1.10", @@ -35,7 +35,7 @@ "gulp-clean": "^0.4.0", "gulp-clean-css": "^4.3.0", "gulp-livereload": "^4.0.2", - "gulp-postcss": "^9.0.0", + "gulp-postcss": "9.0.1", "gulp-rename": "^2.0.0", "gulp-sass": "^4.1.0", "postcss": "^8.0.9", diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/body.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/body.scss index c7401c9f1..e9df5ebdc 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/body.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/body.scss @@ -50,6 +50,14 @@ body { color: theme(colors.text.secondary); display: flex; margin-bottom: 10px; + padding: initial; + list-style: none; + .bread-crumb--item { + a { + text-decoration: inherit; + color: inherit; + } + } } .bread-crumb--item { margin-left: 5px; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/card.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/card.scss index 8f9077f6f..a6f52f961 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/card.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/card.scss @@ -62,7 +62,7 @@ } .employeeCard { - @apply bg-white shadow-card p-md mb-xl; + @apply bg-white shadow-card mb-xl; border-radius: 4px; .card-header { diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/datatable.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/datatable.scss index dd931c255..b2756a61e 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/datatable.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/datatable.scss @@ -49,6 +49,8 @@ .value { width: 50%; @apply text-heading-s; + white-space: break-spaces !important; + word-break: break-all; } .caption { @@ -64,9 +66,69 @@ } } +.employee-data-table { + .row { + @apply flex pb-sm mb-sm; + + span { + width: 70%; + display: contents; + } + + h2 { + width: 30%; + @apply font-medium text-heading-s; + } + + .value { + white-space: break-spaces !important; + word-break: break-all; + width: 60%; + @apply text-heading-s; + &.status-row-radio { + div { + margin-right: 1rem; + width: 50%; + } + .mg-sm { + width: 30%; + } + } + } + + .caption { + width: 70%; + @apply text-heading-s text-text-secondary; + } + } + + .last { + border: none; + padding: 0; + margin: 0; + } + &.status-radio-table { + margin-top: 1rem; + .row { + span { + width: 24px; + display: block; + float: left; + border-radius: 50%; + } + } + } + + &.view-header { + .row { + display: grid; + grid-template-columns: 1fr 68%; + } + } +} .pt-citizen {.data-table {.row { justify-content: space-between; -}}} \ No newline at end of file +}}} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxLinks.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/InboxLinks.scss similarity index 100% rename from frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxLinks.scss rename to frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/InboxLinks.scss diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/horizontalNav.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/horizontalNav.scss similarity index 66% rename from frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/horizontalNav.scss rename to frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/horizontalNav.scss index b2b2a6276..b97b7c827 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/horizontalNav.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/horizontalNav.scss @@ -114,6 +114,73 @@ } } } + .sidebar-list-search-form { + padding-right: 30px; + padding-left: 30px; + + &.active { + font-weight: 600; + border-bottom: 3px solid theme(colors.primary.main); + + background-color: #FFFFFF; + + .menu-label { + color: theme(colors.primary.main); + } + + .icon { + fill: theme(colors.primary.main); + } + } + + .submenu-container { + cursor: pointer; + display: flex; + flex-direction: column; + + .sidebar-link { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15px!important; + padding-top: 20px!important; + svg { + width: 24px !important; + height: 24px !important; + color: rgb(117, 117, 117); + fill: rgb(117, 117, 117); + } + + .actions { + .tooltip { + margin-left: 16px; + } + } + } + + .actions { + display: flex; + align-items: center; + overflow: hidden !important; + + span { + margin-left: 13px; + line-height: 48px; + white-space: nowrap; + color: #5f5c62; + overflow: hidden; + text-overflow: ellipsis; + } + } + } + .submenu-container:first-child { + margin-top:5px; + .employee-search-input{ + margin-left:16px !important; + } + } + } + .dropdown-link { .actions { @@ -134,6 +201,9 @@ } } } + + + .sidebar-link { display: flex; justify-content: space-between; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxSearch.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/inboxSearch.scss similarity index 100% rename from frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxSearch.scss rename to frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/inboxSearch.scss diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxSearchComposer.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/inboxSearchComposer.scss similarity index 100% rename from frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxSearchComposer.scss rename to frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/inboxSearchComposer.scss diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/index.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/index.scss new file mode 100644 index 000000000..bad206269 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/index.scss @@ -0,0 +1,5 @@ +@import "./horizontalNav.scss"; +@import "./InboxLinks.scss"; +@import "./inboxSearch.scss"; +@import "./searchComponentTable.scss"; +@import "./inboxSearchComposer.scss"; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/searchComponentTable.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/searchComponentTable.scss new file mode 100644 index 000000000..a542d721f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/components/inboxv2/searchComponentTable.scss @@ -0,0 +1,44 @@ +.search-component-table { + width: 100%; + display: block; + overflow-x: auto; + overflow-y:hidden; + table { + th { + .tooltip { + min-width: 80px; + } + } + tr { + td { + span { + white-space: pre; + min-width: 80px; + .tooltip { + position: relative; + min-width: 80px; + display: inline-block; + margin-left: 16px; + .tooltiptext { + visibility: hidden; + background-color: #555; + color: #fff; + text-align: left; + border-radius: 6px; + padding: 5px; + position: absolute; + z-index: 1; + bottom: 125%; + left: 50%; + margin-left: -60px; + opacity: 0; + transition: opacity 0.3s; + width: 30rem; + } + } + + } + } + } + } +} \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/index.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/index.scss index 812553373..2e19e082d 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/index.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/index.scss @@ -81,10 +81,6 @@ @import "./components/staticDynamicMessages.scss"; @import "./components/toggleSwitch.scss"; @import "./components/plusMinus.scss"; -@import "./components/horizontalNav.scss"; -@import "./components/inboxLinks.scss"; -@import "./components/inboxSearch.scss"; -@import "./components/inboxSearchComposer.scss"; @import "./pages/employee/index.scss"; @import "./pages/employee/cardfix.scss"; @@ -110,6 +106,7 @@ @import "./pages/citizen/updatePropertyNumber.scss"; @import "./pages/citizen/citizenDocument.scss"; @import "./pages/employee/surveys.scss"; +@import "./components/inboxv2/index.scss"; .display-none { display: none; @@ -558,6 +555,11 @@ input[type="number"] { .full-employee-card-link { width: 100% !important; margin: 7px 0px; + a{ + color: inherit; + text-decoration: inherit + } + } .full-employee-card-height { height: unset !important; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/dss.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/dss.scss index a030de136..f211b0416 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/dss.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/dss.scss @@ -247,3 +247,20 @@ border-color: rgba(244, 119, 56, var(--border-opacity)); width:100%; } } + +.dss-metric-horizontal{ + width: 48%; + max-width: 48%; +} +.dss-primary{ + display: inline; + margin-right: 10px; + path{ + fill:theme(colors.primary.main); + } +} + +.dss-horizontal-v2{ + width: 22.7%; + max-width: 22.7%; +} \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/inbox.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/inbox.scss index 122ecab44..b19e0b2d1 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/inbox.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/inbox.scss @@ -28,6 +28,10 @@ .link { @apply p-sm text-primary-main items-center; display: flex !important; + a{ + color: inherit; + text-decoration: inherit + } } .inbox-total { @@ -446,6 +450,7 @@ .employeeTotalLink { color: theme(colors.text.secondary); font-size: 16px; + text-decoration: none; } @screen dt { diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/index.scss b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/index.scss index d3759a59c..5aad56dd9 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/index.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/index.scss @@ -374,7 +374,7 @@ @media (min-width: 640px) { .employee { .ground-container { - @apply block ml-md; + @apply block; } .breadcrumb { @apply mb-lg; @@ -395,7 +395,6 @@ display: flex; flex-direction: column; padding-top: 80px; - margin-left: 72px; width: calc(100%-83px); } .citizen-home-container { @@ -496,3 +495,29 @@ margin-right: 16px; } } + +.link { + a{ + color: inherit; + text-decoration: inherit + } +} + +.breadcrumb { + a{ + color: inherit; + text-decoration: inherit + } +} + +.sidebar-link.active{ +.custom-link{ + text-decoration: none; + div{ + span{ + color: #f47738; + text-decoration: none; + } + } +} +} \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/example/index.css b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/example/index.css index 45de94778..b3e1be6e0 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/example/index.css +++ b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/example/index.css @@ -1032,8 +1032,8 @@ img, video { position: relative; } .radio-wrap .radio-btn-wrap:hover .radio-btn-checkmark { --border-opacity:1; - border-color: #ae1e28; - border-color: rgba(174, 30, 40, var(--border-opacity)); } + border-color: #f47738; + border-color: rgba(244, 119, 56, var(--border-opacity)); } .radio-wrap .radio-btn { opacity: 0; position: absolute; @@ -1051,8 +1051,8 @@ img, video { display: block; } .radio-wrap label { --text-opacity:1; - color: #ae1e28; - color: rgba(174, 30, 40, var(--text-opacity)); + color: #0b0c0c; + color: rgba(11, 12, 12, var(--text-opacity)); font-size: 16px; line-height: 20px; margin-left: 16px; } @@ -1061,13 +1061,13 @@ img, video { .radio-wrap .radio-btn-wrap input:checked ~ .radio-btn-checkmark { border-width: 1px; --border-opacity:1; - border-color: #ae1e28; - border-color: rgba(174, 30, 40, var(--border-opacity)); } + border-color: #f47738; + border-color: rgba(244, 119, 56, var(--border-opacity)); } .radio-wrap .radio-btn-wrap input:checked ~ .radio-btn-checkmark:after { display: block; --bg-opacity:1; - background-color: #ae1e28; - background-color: rgba(174, 30, 40, var(--bg-opacity)); + background-color: #f47738; + background-color: rgba(244, 119, 56, var(--bg-opacity)); height: .75rem; width: .75rem; border-radius: 9999px; @@ -1104,8 +1104,8 @@ img, video { .data-table { --text-opacity:1; - color: #ae1e28; - color: rgba(174, 30, 40, var(--text-opacity)); } + color: #0b0c0c; + color: rgba(11, 12, 12, var(--text-opacity)); } .data-table .row { display: -webkit-box; display: -ms-flexbox; @@ -1497,8 +1497,8 @@ img, video { border-color: #464646; border-color: rgba(70, 70, 70, var(--border-opacity)); } .filters-wrapper .switch-wrapper label:hover { - border: 1px solid #ae1e28; - border-color: rgba(174, 30, 40, var(--border-opacity)); } + border: 1px solid #f47738; + border-color: rgba(244, 119, 56, var(--border-opacity)); } .pickerShadow { -webkit-box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); @@ -1843,8 +1843,8 @@ img, video { .link { --text-opacity:1; - color: #ae1e28; - color: rgba(174, 30, 40, var(--text-opacity)); + color: #f47738; + color: rgba(244, 119, 56, var(--text-opacity)); cursor: pointer; } .link :hover { --text-opacity:1; @@ -2189,8 +2189,8 @@ img, video { .dark { --text-opacity:1; - color: #ae1e28; - color: rgba(174, 30, 40, var(--text-opacity)); } + color: #0b0c0c; + color: rgba(11, 12, 12, var(--text-opacity)); } .mrlg { margin-right: 24px; } @@ -2261,13 +2261,29 @@ img, video { flex: 1 1 0%; } .primary-label-btn { - color: #f47738; } + display: -webkit-box; + display: -ms-flexbox; + display: flex; + grid-gap: 10px; + gap: 10px; + color: #f47738; + cursor: pointer; + font-weight: 500; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; } .primary-label-btn svg { fill: #f47738; } .primaryColor { color: #0b0c0c !important; } +@media (hover: hover) { + .primary-label-btn:hover { + color: #000; } + .primary-label-btn:hover svg { + fill: #000; } } + .disabled { --border-opacity:1!important; border-color: #9e9e9e !important; @@ -2473,8 +2489,8 @@ input[type=number] { width: 100%; } .text-input input:hover { --border-opacity:1; - border: 1px solid #ae1e28; - border-color: rgba(174, 30, 40, var(--border-opacity)); } + border: 1px solid #f47738; + border-color: rgba(244, 119, 56, var(--border-opacity)); } .text-input-width { max-width: 540px; } @@ -2917,81 +2933,3 @@ input[type=number] { .employee .user-profile { width: auto; } - -.sample-component-style { - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - min-height: 300px; - overflow-y: scroll; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - border: 1px solid grey; } - -.primary-label-btn, .sample-component-style { - display: -webkit-box; - display: -ms-flexbox; - display: flex; } - -.primary-label-btn { - grid-gap: 10px; - gap: 10px; - color: #ae1e28; - cursor: pointer; - font-weight: 500; - width: -webkit-fit-content; - width: -moz-fit-content; - width: fit-content; } - .primary-label-btn svg { - fill: #ae1e28; } - -.primaryColor { - color: #ae1e28 !important; } - -@media (hover: hover) { - .primary-label-btn:hover { - color: #000; } - .primary-label-btn:hover svg { - fill: #000; } } - -.submit-bar { - --bg-opacity:1; - background-color: #ae1e28; - background-color: rgba(174, 30, 40, var(--bg-opacity)); } - -.complaint-links-container .header .logo { - --bg-opacity:1!important; - background-color: #ae1e28 !important; - background-color: rgba(174, 30, 40, var(--bg-opacity)) !important; } - -.complaint-links-container .links-wrapper .link .inbox-total { - --bg-opacity:1; - background-color: #ae1e28; - background-color: rgba(174, 30, 40, var(--bg-opacity)); } - -.complaint-links-container .links-wrapper .link a { - color: #ae1e28 !important; } - -.citizen .sidebar, .employee .sidebar { - background-image: url(https://in-egov-assets.s3.ap-south-1.amazonaws.com/images/top-green-card.png), url(https://in-egov-assets.s3.ap-south-1.amazonaws.com/images/top-red-card.png); - background-blend-mode: lighten; - background-size: cover; } - .citizen .sidebar .sidebar-link.active, .employee .sidebar .sidebar-link.active { - color: #ae1e28 !important; } - .citizen .sidebar .sidebar-link.active svg, .employee .sidebar .sidebar-link.active svg { - fill: #ae1e28; } - -.user-img-txt { - --bg-opacity:1!important; - background-color: #ae1e28 !important; - background-color: rgba(174, 30, 40, var(--bg-opacity)) !important; } - -.selector-button-primary { - height: 2rem; } - -.customBtn-selected, .selector-button-primary { - --bg-opacity:1; - background-color: #ae1e28; - background-color: rgba(174, 30, 40, var(--bg-opacity)); } diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/package.json index 95a4d54a0..ca755ead5 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/package.json +++ b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/package.json @@ -1,9 +1,9 @@ { - "name": "@egovernments/digit-ui-custom-css", - "version": "0.0.2", + "name": "@egovernments/digit-ui-ifix-css", + "version": "0.0.1", "license": "MIT", - "main": "dist/index.css", "author": "Jagankumar ", + "main": "dist/index.css", "engines": { "node": ">=14" }, @@ -21,31 +21,31 @@ "last 2 versions" ], "style": "./dist/index.css", - "dependencies": { - "node-sass": "^4.14.1", - "normalize.css": "^8.0.1", - "postcss-scss": "^3.0.1", - "tailwindcss": "^1.8.10" - }, - "devDependencies": { - "autoprefixer": "^10.0.0", - "cssnano": "^4.1.10", - "gh-pages": "^3.1.0", - "gulp": "^4.0.2", - "gulp-clean": "^0.4.0", - "gulp-clean-css": "^4.3.0", - "gulp-livereload": "^4.0.2", - "gulp-postcss": "^9.0.0", - "gulp-rename": "^2.0.0", - "gulp-sass": "^4.1.0", - "postcss": "^8.0.9", - "postcss-cli": "^8.0.0", - "postcss-header": "^2.0.0", - "postcss-import": "^12.0.1", - "postcss-prefixer": "^2.1.2", - "postcss-preset-env": "^6.7.0", - "postcss-scss": "^3.0.1", - "sass": "^1.26.11" + "dependencies": { + "node-sass": "4.14.1", + "normalize.css": "8.0.1", + "postcss-scss": "3.0.5", + "tailwindcss": "2.2.19" + }, + "devDependencies": { + "autoprefixer": "10.4.4", + "cssnano": "4.1.11", + "gh-pages": "3.2.3", + "gulp": "4.0.2", + "gulp-clean": "0.4.0", + "gulp-clean-css": "4.3.0", + "gulp-livereload": "4.0.2", + "gulp-postcss": "9.0.1", + "gulp-rename": "2.0.0", + "gulp-sass": "4.1.1", + "postcss": "8.4.12", + "postcss-cli": "8.3.1", + "postcss-header": "2.0.0", + "postcss-import": "12.0.1", + "postcss-prefixer": "2.1.3", + "postcss-preset-env": "6.7.1", + "postcss-scss": "3.0.5", + "sass": "1.49.11" }, "files": [ "dist/index.min.css", @@ -55,4 +55,4 @@ "src/**/*.scss", "src/**/*.css" ] -} \ No newline at end of file +} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/src/index.scss b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/src/index.scss index cae5a79b3..66308e873 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/src/index.scss +++ b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/src/index.scss @@ -836,93 +836,4 @@ input[type="number"] { .user-profile{ width: auto; } -} - - -.sample-component-style{ - display: flex; - align-items: center; - min-height: 300px; - overflow-y: scroll; - flex-direction: column; - border: 1px solid gray; -} - - -.primary-label-btn { - @apply flex; - gap: 10px; - - svg { - fill: theme(colors.primary.main); - } - - color: theme(colors.primary.main); - - cursor: pointer; - font-weight: 500; - width: fit-content; -} - -.primaryColor { - color: theme(colors.text.primary) !important; -} - -@media (hover: hover) { - .primary-label-btn { - &:hover { - color: #000; - - svg { - fill: #000; - } - } - } -} - -.submit-bar { - @apply bg-primary-main -} - -.complaint-links-container { - .header {.logo{ - @apply bg-primary-main !important; - } -} - -.links-wrapper{ - .link{ - .inbox-total{ - @apply bg-primary-main ; - } - a{ - color: theme(colors.text.primary) !important; - - } - } -} -} -.citizen, .employee{ - .sidebar{ - background-image: url(https://in-egov-assets.s3.ap-south-1.amazonaws.com/images/top-green-card.png), url(https://in-egov-assets.s3.ap-south-1.amazonaws.com/images/top-red-card.png); - background-blend-mode: lighten; - background-size: cover; - - .sidebar-link.active{ - color: theme(colors.text.primary) !important; - svg{ - fill:theme(colors.text.primary) ; - } - - } - } -} -.user-img-txt{ - @apply bg-primary-main !important; -} -.selector-button-primary { - @apply h-8 bg-primary-main; -} -.customBtn-selected { - @apply bg-primary-main; } \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/tailwind.config.js b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/tailwind.config.js index 80e3f03f2..1fc8ea183 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/tailwind.config.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/custom-css/tailwind.config.js @@ -11,13 +11,13 @@ module.exports = { }, colors: { primary: { - light: "rgb(174, 30, 40)", - main: "rgb(174, 30, 40)", + light: "#F18F5E", + main: "#F47738", dark: "#C8602B", }, secondary: "#22394D", text: { - primary: "rgb(174, 30, 40)", + primary: "#0B0C0C", secondary: "#505A5F", }, link: { diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/package.json index e84819bba..17f81e9c8 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/package.json +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/package.json @@ -32,12 +32,12 @@ "i18next-react-postprocessor": "3.0.7", "pdfmake": "0.1.72", "react": "17.0.2", - "jsonpath": "^1.1.1", "react-i18next": "11.16.2", "react-query": "3.6.1", "react-redux": "7.2.8", "react-router-dom": "5.3.0", "redux": "4.1.2", - "xlsx": "0.17.5" + "xlsx": "0.17.5", + "jsonpath": "^1.1.1" } } diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSCount.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSCount.js index 50b63dadb..2ff2ea8e5 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSCount.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSCount.js @@ -1,8 +1,8 @@ import { useQuery, useQueryClient } from "react-query"; import HrmsService from "../../services/elements/HRMS"; -export const useHRMSCount = (tenantId, config = {}) => { - return useQuery(["HRMS_COUNT", tenantId], () => HrmsService.count(tenantId), config); +export const useHRMSCount = (tenantId, roles, config = {}) => { + return useQuery(["HRMS_COUNT", tenantId], () => HrmsService.count(tenantId, roles), config); }; -export default useHRMSCount; +export default useHRMSCount; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSMDMS.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSMDMS.js index 6616cbe08..3cf3fbabe 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSMDMS.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSMDMS.js @@ -13,6 +13,10 @@ const useHrmsMDMS = (tenantId, moduleCode, type, config = {}) => { return useQuery(["HRMS_EMP_REASON", tenantId], () => MdmsService.getHrmsEmployeeReason(tenantId, moduleCode, type), config); }; + const useHrmsData = () => { + return useQuery(["HRMS_EMP_REASON", tenantId], () => MdmsService.getHrmsEmployeeData(tenantId, moduleCode, type), config); + }; + switch (type) { case "HRMSRolesandDesignation": return useHrmsRolesandDesignations(); @@ -20,6 +24,8 @@ const useHrmsMDMS = (tenantId, moduleCode, type, config = {}) => { return useHrmsEmployeeTypes(); case "DeactivationReason": return useHrmsEmployeeReasons(); + case "HRMSConfig": + return useHrmsData(); } }; export default useHrmsMDMS; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSsearch.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSsearch.js index 77822d3a7..19c9515bf 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSsearch.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/hrms/useHRMSsearch.js @@ -1,8 +1,16 @@ import { useQuery, useQueryClient } from "react-query"; import HrmsService from "../../services/elements/HRMS"; -export const useHRMSSearch = (searchparams, tenantId, filters, isupdated, config = {}) => { - return useQuery(["HRMS_SEARCH", searchparams, tenantId, filters, isupdated], () => HrmsService.search(tenantId, filters, searchparams), config); +export const useHRMSSearch = (searchparams, tenantId, filters, isupdated, roles, config = {}) => { + return useQuery( + ["HRMS_SEARCH", searchparams, tenantId, filters, isupdated], + () => HrmsService.search(tenantId, filters, searchparams, roles), + config + ); }; export default useHRMSSearch; + +export const useHRMSEmployeeSearch = (criteria, isupdated, config = {}) => { + return useQuery(["HRMS_SEARCH", criteria, isupdated], () => HrmsService.searchEmployee(criteria), config); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/index.js index e1839c46f..65a42b4af 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/index.js @@ -2,7 +2,15 @@ import { useClearNotifications, useEvents, useNotificationCount } from "./events import useCreateEvent from "./events/useCreateEvent"; import useUpdateEvent from "./events/useUpdateEvent"; import { - useBulkPdfDetails, useDemandSearch, useFetchBillsForBuissnessService, useFetchCitizenBillsForBuissnessService, useFetchPayment, useGetPaymentRulesForBusinessServices, usePaymentSearch, usePaymentUpdate, useRecieptSearch + useBulkPdfDetails, + useDemandSearch, + useFetchBillsForBuissnessService, + useFetchCitizenBillsForBuissnessService, + useFetchPayment, + useGetPaymentRulesForBusinessServices, + usePaymentSearch, + usePaymentUpdate, + useRecieptSearch, } from "./payment"; import { useInitStore } from "./store"; import useAccessControl from "./useAccessControl"; @@ -12,7 +20,6 @@ import useCustomMDMS from "./useCustomMDMS"; import useDocumentSearch from "./useDocumentSearch"; import useDynamicData from "./useDynamicData"; import useLocation from "./useLocation"; -import useCustomAPIMutationHook from "./useCustomAPIMutationHook"; import useInboxGeneral from "./useInboxGeneral/useInboxGeneral"; import useNewInboxGeneral from "./useInboxGeneral/useNewInbox"; @@ -52,18 +59,15 @@ import useDSSDashboard from "./dss/useDSSDashboard"; import useGetChart from "./dss/useGetChart"; import useDssMdms from "./dss/useMDMS"; import useGetCustomFilterValues from "./dss/useGetCustomFilterValues"; -import useGetCustomFilterRequestValues from './dss/useGetCustomFilterRequestValues'; - +import useGetCustomFilterRequestValues from "./dss/useGetCustomFilterRequestValues"; import useHRMSCount from "./hrms/useHRMSCount"; import useHRMSCreate from "./hrms/useHRMScreate"; import useHRMSGenderMDMS from "./hrms/useHRMSGender"; import useHrmsMDMS from "./hrms/useHRMSMDMS"; -import useHRMSSearch from "./hrms/useHRMSsearch"; +import useHRMSSearch, { useHRMSEmployeeSearch } from "./hrms/useHRMSsearch"; import useHRMSUpdate from "./hrms/useHRMSUpdate"; - - import useDocCreate from "./engagement/useCreate"; import useDocDelete from "./engagement/useDelete"; import { useEngagementMDMS } from "./engagement/useMdms"; @@ -80,8 +84,6 @@ import useSurveySubmitResponse from "./surveys/useSubmitResponse"; import useSurveyInbox from "./surveys/useSurveyInbox"; import useSurveyUpdate from "./surveys/useUpdate"; - - import useGetDSSAboutJSON from "./useGetDSSAboutJSON"; import useGetDSSFAQsJSON from "./useGetDSSFAQsJSON"; import useGetFAQsJSON from "./useGetFAQsJSON"; @@ -89,8 +91,6 @@ import useGetHowItWorksJSON from "./useHowItWorksJSON"; import { usePrivacyContext } from "./usePrivacyContext"; import useStaticData from "./useStaticData"; - - const pgr = { useComplaintDetails, useComplaintsList, @@ -107,17 +107,15 @@ const pgr = { useComplaintStatusCount, }; - const dss = { useMDMS: useDssMdms, useDashboardConfig, useDSSDashboard, useGetChart, useGetCustomFilterValues, - useGetCustomFilterRequestValues + useGetCustomFilterRequestValues, }; - const hrms = { useHRMSSearch, useHrmsMDMS, @@ -125,11 +123,9 @@ const hrms = { useHRMSUpdate, useHRMSCount, useHRMSGenderMDMS, + useHRMSEmployeeSearch, }; - - - const events = { useInbox: useEventInbox, useCreateEvent, @@ -187,18 +183,17 @@ const Hooks = { useAccessControl, usePrivacyContext, pgr, - + dss, - + hrms, - + events, engagement, survey, useGenderMDMS, useRouteSubscription, useCustomAPIHook, - useCustomAPIMutationHook, useWorkflowDetailsV2, useUpdateCustom, useCustomMDMS, @@ -209,7 +204,7 @@ const Hooks = { useStaticData, useDynamicData, useBulkPdfDetails, - useLocation + useLocation, }; -export default Hooks; +export default Hooks; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintDetails.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintDetails.js index ee40baaf4..d20e4cd0a 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintDetails.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintDetails.js @@ -18,9 +18,9 @@ const getDetailsRow = ({ id, service, complaintType }) => ({ CS_COMPLAINT_ADDTIONAL_DETAILS: service.description, CS_COMPLAINT_FILED_DATE: Digit.DateUtils.ConvertTimestampToDate(service.auditDetails.createdTime), ES_CREATECOMPLAINT_ADDRESS: [ - service.address.landmark, - Digit.Utils.locale.getLocalityCode(service.address.locality, service.tenantId), service.address.city, + Digit.Utils.locale.getLocalityCode(service.address.locality, service.tenantId), + service.address.landmark, service.address.pincode, ], }); diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintTypes.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintTypes.js index 6110a9549..78303b5de 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintTypes.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/pgr/useComplaintTypes.js @@ -9,7 +9,6 @@ const useComplaintTypes = ({ stateCode }) => { (async () => { const res = await Digit.GetServiceDefinitions.getMenu(stateCode, t); let menu = res.filter((o) => o.key !== ""); - menu.push({ key: "Others", name: t("SERVICEDEFS.OTHERS") }); setComplaintTypes(menu); })(); }, [t, stateCode]); diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useCustomAPIMutationHook.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useCustomAPIMutationHook.js deleted file mode 100644 index 6afcfe74d..000000000 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useCustomAPIMutationHook.js +++ /dev/null @@ -1,68 +0,0 @@ -import { useQueryClient, useMutation } from "react-query"; -import { CustomService } from "../services/elements/CustomService"; - -/** - * Custom hook which can make api call and format response - * - * @author jagankumar-egov - * - * - * @example - * - const requestCriteria = [ - "/user/_search", // API details - {}, //requestParam - {data : {uuid:[Useruuid]}}, // requestBody - {} , // privacy value - { // other configs - enabled: privacyState, - cacheTime: 100, - select: (data) => { - // format data - return _.get(data, loadData?.jsonPath, value); - }, - }, - ]; - const mutation = Digit.Hooks.useCustomAPIMutationHook(...requestCriteria); - - -while mutating use the following format - -mutation.mutate({ - params: {}, - body: { "payload": { - // custom data - } - }}, - { - onError : ()=> { // custom logic}, - onSuccess : ()=> { // custom logic} - } - ); - - * - * @returns {Object} Returns the object which contains data and isLoading flag - */ - -const useCustomAPIMutationHook = ({ url, params, body, config = {}, plainAccessRequest, changeQueryName = "Random" }) => { - const client = useQueryClient(); - - const { isLoading, data, isFetching, ...rest } = useMutation( - (data) => CustomService.getResponse({ url, params: { ...params, ...data?.params }, body: { ...body, ...data?.body }, plainAccessRequest }), - { - cacheTime: 0, - ...config, - } - ); - return { - ...rest, - isLoading, - isFetching, - data, - revalidate: () => { - data && client.invalidateQueries({ queryKey: [url].filter((e) => e) }); - }, - }; -}; - -export default useCustomAPIMutationHook; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useMDMS.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useMDMS.js index ec3579d93..3b3b410dc 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useMDMS.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useMDMS.js @@ -1,5 +1,7 @@ import { MdmsService } from "../services/elements/MDMS"; + import { useQuery } from "react-query"; +import { MdmsServiceV1 } from "../services/elements/MDMSV1"; const useMDMS = (tenantId, moduleCode, type, config = {}, payload = []) => { const usePaymentGateway = () => { @@ -24,6 +26,10 @@ const useMDMS = (tenantId, moduleCode, type, config = {}, payload = []) => { }; const _default = () => { + if (moduleCode === "commonUiConfig") { + return useQuery([tenantId, moduleCode, type], () => MdmsServiceV1.getMultipleTypes(tenantId, moduleCode, type), config); + } + return useQuery([tenantId, moduleCode, type], () => MdmsService.getMultipleTypes(tenantId, moduleCode, type), config); }; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useModuleTenants.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useModuleTenants.js index 25e51a94e..39c7cff14 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useModuleTenants.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/hooks/useModuleTenants.js @@ -13,10 +13,7 @@ const useModuleTenants = (module, config = {}) => { ...tenant, ulbKey: t(`TENANT_TENANTS_${tenant?.code?.toUpperCase?.()?.replace(".", "_")}`), ddrKey: t( - `DDR_${data.tenants - .filter((t) => t.code === tenant.code)?.[0] - .city?.districtTenantCode?.toUpperCase?.() - .replace(".", "_")}` + `DDR_${data.tenants?.filter((t) => t.code === tenant?.code)?.[0]?.city?.districtTenantCode?.toUpperCase?.().replace(".", "_")}` ), })) .filter((item, i, arr) => i === arr.findIndex((t) => t.ddrKey === item.ddrKey)), @@ -26,10 +23,7 @@ const useModuleTenants = (module, config = {}) => { ...tenant, ulbKey: t(`TENANT_TENANTS_${tenant?.code?.toUpperCase?.()?.replace(".", "_")}`), ddrKey: t( - `DDR_${data.tenants - .filter((t) => t.code === tenant.code)?.[0] - .city?.districtTenantCode?.toUpperCase?.() - .replace(".", "_")}` + `DDR_${data?.tenants?.filter((t) => t.code === tenant?.code)?.[0]?.city?.districtTenantCode?.toUpperCase?.().replace(".", "_")}` ), })), }), diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/index.js index 12002ed8b..6eced226f 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/index.js @@ -18,13 +18,14 @@ import * as dateUtils from "./services/atoms/Utils/Date"; import Download from "./services/atoms/Download"; import { WorkflowService } from "./services/elements/WorkFlow"; import { MdmsService } from "./services/elements/MDMS"; +import { MdmsServiceV1 } from "./services/elements/MDMSV1"; + import { Complaint } from "./services/elements/Complaint"; import { UserService } from "./services/elements/User"; import HrmsService from "./services/elements/HRMS"; import { InboxGeneral } from "./services/elements/InboxService"; import EventsServices from "./services/elements/Events"; - import ShareFiles from "./services/molecules/ShareFiles"; import { GetServiceDefinitions } from "./services/molecules/ServiceDefinitions"; import { ULBService } from "./services/molecules/Ulb"; @@ -79,6 +80,7 @@ const initLibraries = () => { setupLibraries("Download", Download); setupLibraries("AccessControlService", AccessControlService); + setupLibraries("MdmsServiceV1", MdmsServiceV1); return new Promise((resolve) => { initI18n(resolve); diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/ApiCacheService.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/ApiCacheService.js index 31bbe25c6..d98bf5398 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/ApiCacheService.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/ApiCacheService.js @@ -24,6 +24,17 @@ const defaultApiCachingSettings = [ }, ], }, + { + serviceName: "mdms-v2", + cacheTimeInSecs: 3600, + debounceTimeInMS: 100, + moduleSettings: [ + { + moduleName: "FSM", + cacheTimeInSecs: 7200, + }, + ], + }, ]; const storageKey = "cachingService"; @@ -39,8 +50,8 @@ const getSetting = (serviceName, moduleName) => { const setting = getCachedSetting(); const serviceSetting = setting.find((item) => item.serviceName === serviceName); const responseSetting = { - cacheTimeInSecs: serviceSetting.cacheTimeInSecs, - debounceTimeInMS: serviceSetting.debounceTimeInMS || 100, + cacheTimeInSecs: serviceSetting?.cacheTimeInSecs, + debounceTimeInMS: serviceSetting?.debounceTimeInMS || 100, }; if (!moduleName) { return responseSetting; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/urls.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/urls.js index 8f48cc54f..3d237f7b6 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/urls.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/atoms/urls.js @@ -1,5 +1,8 @@ const Urls = { - MDMS: `/egov-mdms-service/v1/_search`, + MDMSV1: "/egov-mdms-service/v1/_search", + // MDMS: "/egov-mdms-service/v1/_search", + + MDMS: "/mdms-v2/v1/_search", WorkFlow: `/egov-workflow-v2/egov-wf/businessservice/_search`, WorkFlowProcessSearch: `/egov-workflow-v2/egov-wf/process/_search`, localization: `/localization/messages/v1/_search`, @@ -34,15 +37,15 @@ const Urls = { Shortener: "/egov-url-shortening/shortener", works: { - create:"/loi-service/v1/_create", - estimateSearch:"/estimate-service/estimate/v1/_search", - loiSearch:"/loi-service/v1/_search", - createEstimate:"/estimate-service/estimate/v1/_create", - approvedEstimateSearch:"/estimate-service/estimate/v1/_search", - searchEstimate:"/estimate-service/estimate/v1/_search", - updateLOI:"/loi-service/v1/_update", - updateEstimate:"/estimate-service/estimate/v1/_update", - download_pdf:"/egov-pdf/download/WORKSESTIMATE/estimatepdf" + create: "/loi-service/v1/_create", + estimateSearch: "/estimate-service/estimate/v1/_search", + loiSearch: "/loi-service/v1/_search", + createEstimate: "/estimate-service/estimate/v1/_create", + approvedEstimateSearch: "/estimate-service/estimate/v1/_search", + searchEstimate: "/estimate-service/estimate/v1/_search", + updateLOI: "/loi-service/v1/_update", + updateEstimate: "/estimate-service/estimate/v1/_update", + download_pdf: "/egov-pdf/download/WORKSESTIMATE/estimatepdf", }, fsm: { @@ -112,7 +115,8 @@ const Urls = { }, hrms: { search: "/egov-hrms/employees/_search", - count: "/egov-hrms/employees/_count", + searchListOfEmployee: "/egov-hrms/employees/_searchListOfEmployee", + count: "/egov-hrms/employees/v1/_count", create: "/egov-hrms/employees/_create", update: "/egov-hrms/employees/_update", }, @@ -143,7 +147,7 @@ const Urls = { bpaRegUpdate: "/tl-services/v1/BPAREG/_update", receipt_download: "/egov-pdf/download/PAYMENT/consolidatedreceipt", edcrreportdownload: "/bpa-services/v1/bpa/_permitorderedcr", - getSearchDetails: "/inbox/v1/dss/_search" + getSearchDetails: "/inbox/v1/dss/_search", }, edcr: { @@ -178,7 +182,7 @@ const Urls = { wns_group_bill: "/egov-pdf/download/WNS/wnsgroupbill", cancel_group_bill: "/pdf-service/v1/_cancelProcess", wns_generate_pdf: "/egov-pdf/download/WNS/wnsbill", - water_applyAdhocTax : "/ws-calculator/waterCalculator/_applyAdhocTax", + water_applyAdhocTax: "/ws-calculator/waterCalculator/_applyAdhocTax", sewerage_applyAdhocTax: "/sw-calculator/sewerageCalculator/_applyAdhocTax", getSearchDetails: "/inbox/v1/dss/_search", }, @@ -205,8 +209,8 @@ const Urls = { estimate: "/muster-roll/v1/_estimate", create: "/muster-roll/v1/_create", update: "/muster-roll/v1/_update", - search: "/muster-roll/v1/_search" - } + search: "/muster-roll/v1/_search", + }, }, noc: { @@ -215,8 +219,8 @@ const Urls = { reports: { reportSearch: "/report/", }, - bills:{ - cancelBill:"/billing-service/bill/v2/_cancelbill" + bills: { + cancelBill: "/billing-service/bill/v2/_cancelbill", }, access_control: "/access/v1/actions/mdms/_get", billgenie: "/egov-searcher", diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/HRMS.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/HRMS.js index 1fe9a3f42..8d5725430 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/HRMS.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/HRMS.js @@ -3,14 +3,23 @@ import Urls from "../atoms/urls"; import { Request } from "../atoms/Utils/Request"; const HrmsService = { - search: (tenantId, filters, searchParams) => + search: (tenantId, filters, searchParams, roles) => Request({ url: Urls.hrms.search, useCache: false, method: "POST", auth: true, userService: true, - params: { tenantId, ...filters, ...searchParams }, + params: { tenantId, ...filters, ...searchParams, ...roles }, + }), + searchEmployee: (data) => + Request({ + url: Urls.hrms.searchListOfEmployee, + useCache: false, + method: "POST", + auth: true, + userService: true, + data: data, }), create: (data, tenantId) => Request({ @@ -32,15 +41,15 @@ const HrmsService = { userService: true, params: { tenantId }, }), - count: (tenantId) => + count: (tenantId, roles) => Request({ url: Urls.hrms.count, useCache: false, method: "POST", auth: true, userService: true, - params: { tenantId }, + params: { tenantId, ...roles }, }), }; -export default HrmsService; +export default HrmsService; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/Localization/service.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/Localization/service.js index 38ae77822..6d2e8605a 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/Localization/service.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/Localization/service.js @@ -27,9 +27,9 @@ const LocalizationStore = { const cacheSetting = ApiCacheService.getSettingByServiceUrl(Urls.localization); PersistantStorage.set(key, value, cacheSetting.cacheTimeInSecs); }, - getList: (locale) => LocalizationStore.getCaheData(LOCALE_LIST(locale)) || [], + getList: (locale) => LocalizationStore?.getCaheData(LOCALE_LIST(locale)) || [], setList: (locale, namespaces) => LocalizationStore.setCacheData(LOCALE_LIST(locale), namespaces), - getAllList: () => LocalizationStore.getCaheData(LOCALE_ALL_LIST()) || [], + getAllList: () => LocalizationStore?.getCaheData(LOCALE_ALL_LIST()) || [], setAllList: (namespaces) => LocalizationStore.setCacheData(LOCALE_ALL_LIST(), namespaces), store: (locale, modules, messages) => { const AllNamespaces = LocalizationStore.getAllList(); @@ -48,8 +48,8 @@ const LocalizationStore = { const storedModules = LocalizationStore.getList(locale); const newModules = modules.filter((module) => !storedModules.includes(module)); const messages = []; - storedModules.forEach((module) => { - messages.push(...LocalizationStore.getCaheData(LOCALE_MODULE(locale, module))); + storedModules?.forEach((module) => { + messages.push(...LocalizationStore?.getCaheData(LOCALE_MODULE(locale, module))); }); return [newModules, messages]; }, diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMS.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMS.js index d7f226208..c7d1037a8 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMS.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMS.js @@ -142,9 +142,9 @@ const getBillsGenieKey = (tenantId, moduleCode) => ({ masterDetails: [{ name: "tenants" }, { name: "citymodule" }], }, { - moduleName: "common-masters", - masterDetails: [{name: "uiCommonPay"}] - } + moduleName: "common-masters", + masterDetails: [{ name: "uiCommonPay" }], + }, ], }, }); @@ -638,32 +638,31 @@ const getGenderTypeList = (tenantId, moduleCode, type) => ({ }); const getMeterStatusTypeList = (tenantId) => ({ - moduleDetails: [ - { - moduleName: "ws-services-calculation", - masterDetails: [ - { - name: "MeterStatus", - filter: `$.*.name` - }, - ], - }, - ], - + moduleDetails: [ + { + moduleName: "ws-services-calculation", + masterDetails: [ + { + name: "MeterStatus", + filter: `$.*.name`, + }, + ], + }, + ], }); const getBillingPeriodValidation = (tenantId) => ({ - moduleDetails: [ - { - moduleName: "ws-services-masters", - masterDetails: [ - { - name: "billingPeriod", - filter: "*" - }, - ], - }, - ], + moduleDetails: [ + { + moduleName: "ws-services-masters", + masterDetails: [ + { + name: "billingPeriod", + filter: "*", + }, + ], + }, + ], }); const getDssDashboardCriteria = (tenantId, moduleCode) => ({ @@ -735,10 +734,11 @@ const getHrmsEmployeeRolesandDesignations = () => ({ masterDetails: [{ name: "tenants" }], }, { - moduleName: "ACCESSCONTROL-ROLES", - masterDetails: [{ name: "roles", filter: "$.[?(@.code!='CITIZEN')]" }], + moduleName: "ws-services-masters", + masterDetails: [{ name: "WSServiceRoles" }], }, { moduleName: "egov-location", masterDetails: [{ name: "TenantBoundary" }] }, + { moduleName: "egov-hrms", masterDetails: [{ name: "EmployeeType" }] }, ], }); const getFSTPPlantCriteria = (tenantId, moduleCode, type) => ({ @@ -915,53 +915,53 @@ const getWSTaxHeadMasterCritera = (tenantId, moduleCode, type) => ({ }); const getHowItWorksJSON = (tenantId) => ({ - moduleDetails: [ - { - moduleName: "common-masters", - masterDetails: [ - { - name: "howItWorks", - }, - ], - }, - ], + moduleDetails: [ + { + moduleName: "common-masters", + masterDetails: [ + { + name: "howItWorks", + }, + ], + }, + ], }); const getFAQsJSON = (tenantId) => ({ moduleDetails: [ - { - moduleName: "common-masters", - masterDetails: [ - { - name: "faqs", - }, - ], - }, -], + { + moduleName: "common-masters", + masterDetails: [ + { + name: "faqs", + }, + ], + }, + ], }); const getDSSFAQsJSON = (tenantId) => ({ moduleDetails: [ - { - moduleName: "dss-dashboard", - masterDetails: [ - { - name: "FAQs", - }, - ], - }, -], + { + moduleName: "dss-dashboard", + masterDetails: [ + { + name: "FAQs", + }, + ], + }, + ], }); const getDSSAboutJSON = (tenantId) => ({ moduleDetails: [ - { - moduleName: "dss-dashboard", - masterDetails: [ - { - name: "About", - }, - ], - }, -], + { + moduleName: "dss-dashboard", + masterDetails: [ + { + name: "About", + }, + ], + }, + ], }); const getStaticData = () => ({ @@ -1022,12 +1022,11 @@ const GetVehicleType = (MdmsRes) => }); const GetVehicleMakeModel = (MdmsRes) => - MdmsRes["Vehicle"].VehicleMakeModel.filter((vehicle) => vehicle.active) - .map((vehicleDetails) => { - return { - ...vehicleDetails, - i18nKey: `COMMON_MASTER_VEHICLE_${vehicleDetails.code}`, - }; + MdmsRes["Vehicle"].VehicleMakeModel.filter((vehicle) => vehicle.active).map((vehicleDetails) => { + return { + ...vehicleDetails, + i18nKey: `COMMON_MASTER_VEHICLE_${vehicleDetails.code}`, + }; }); const GetSlumLocalityMapping = (MdmsRes, tenantId) => @@ -1300,7 +1299,7 @@ const GetPreFields = (MdmsRes) => MdmsRes["FSM"].PreFieldsConfig; const GetPostFields = (MdmsRes) => MdmsRes["FSM"].PostFieldsConfig; -const GetFSTPPlantInfo = (MdmsRes) => MdmsRes["FSM"].FSTPPlantInfo; +const GetFSTPPlantInfo = (MdmsRes) => MdmsRes["FSM"]?.FSTPPlantInfo; const GetDocumentsTypes = (MdmsRes) => MdmsRes["BPA"].DocTypeMapping; @@ -1635,6 +1634,9 @@ export const MdmsService = { getHrmsEmployeeReason: (tenantId, moduleCode, type) => { return MdmsService.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); }, + getHrmsEmployeeData: (tenantId, moduleCode, type) => { + return MdmsService.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); + }, getMultipleTypes: (tenantId, moduleCode, types) => { return MdmsService.getDataByCriteria(tenantId, getMultipleTypes(tenantId, moduleCode, types), moduleCode); }, @@ -1720,11 +1722,11 @@ export const MdmsService = { getDSSFAQsJSONData: (tenantId) => { return MdmsService.call(tenantId, getDSSFAQsJSON(tenantId)); }, - + getDSSAboutJSONData: (tenantId) => { return MdmsService.call(tenantId, getDSSAboutJSON(tenantId)); }, getStaticDataJSON: (tenantId) => { return MdmsService.call(tenantId, getStaticData()); - } + }, }; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMSV1.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMSV1.js new file mode 100644 index 000000000..cbb6c421b --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/elements/MDMSV1.js @@ -0,0 +1,1732 @@ +//HAVE TO CHANGE THI +import { ApiCacheService } from "../atoms/ApiCacheService"; +import Urls from "../atoms/urls"; +import { Request, ServiceRequest } from "../atoms/Utils/Request"; +import { PersistantStorage } from "../atoms/Utils/Storage"; + +// export const stringReplaceAll = (str = "", searcher = "", replaceWith = "") => { +// if (searcher == "") return str; +// while (str.includes(searcher)) { +// str = str.replace(searcher, replaceWith); +// } +// return str; +// }; + +const SortByName = (na, nb) => { + if (na < nb) { + return -1; + } + if (na > nb) { + return 1; + } + return 0; +}; + +const GetCitiesWithi18nKeys = (MdmsRes, moduleCode) => { + const cityList = (MdmsRes.tenant.citymodule && MdmsRes.tenant.citymodule.find((module) => module.code === moduleCode).tenants) || []; + const citiesMap = cityList.map((city) => city.code); + const cities = MdmsRes.tenant.tenants + .filter((city) => citiesMap.includes(city.code)) + .map(({ code, name, logoId, emailId, address, contactNumber }) => ({ + code, + name, + logoId, + emailId, + address, + contactNumber, + i18nKey: "TENANT_TENANTS_" + code.replace(".", "_").toUpperCase(), + })) + .sort((cityA, cityB) => { + const na = cityA.name.toLowerCase(), + nb = cityB.name.toLowerCase(); + return SortByName(na, nb); + }); + return cities; +}; + +const initRequestBody = (tenantId) => ({ + MdmsCriteria: { + tenantId, + moduleDetails: [ + { + moduleName: "common-masters", + masterDetails: [{ name: "Department" }, { name: "Designation" }, { name: "StateInfo" }, { name: "wfSlaConfig" }, { name: "uiHomePage" }], + }, + { + moduleName: "tenant", + masterDetails: [{ name: "tenants" }, { name: "citymodule" }], + }, + { + moduleName: "DIGIT-UI", + masterDetails: [{ name: "ApiCachingSettings" }], + }, + ], + }, +}); + +const getCriteria = (tenantId, moduleDetails) => { + return { + MdmsCriteria: { + tenantId, + ...moduleDetails, + }, + }; +}; + +export const getGeneralCriteria = (tenantId, moduleCode, type) => ({ + details: { + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: type, + }, + ], + }, + ], + }, +}); + +export const getMultipleTypes = (tenantId, moduleCode, types) => ({ + details: { + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: types.map((type) => ({ name: type })), + }, + ], + }, +}); +export const getMultipleTypesWithFilter = (moduleCode, masterDetails) => ({ + details: { + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: masterDetails, + }, + ], + }, +}); + +const getReceiptKey = (tenantId, moduleCode) => ({ + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "uiCommonPay", + }, + ], + }, + ], + }, +}); + +const getBillsGenieKey = (tenantId, moduleCode) => ({ + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "BusinessService", + }, + ], + }, + { + moduleName: "tenant", + masterDetails: [{ name: "tenants" }, { name: "citymodule" }], + }, + { + moduleName: "common-masters", + masterDetails: [{ name: "uiCommonPay" }], + }, + ], + }, +}); + +const getModuleServiceDefsCriteria = (tenantId, moduleCode) => ({ + type: "serviceDefs", + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: `RAINMAKER-${moduleCode}`, + masterDetails: [ + { + name: "ServiceDefs", + }, + ], + }, + ], + }, +}); + +const getSanitationTypeCriteria = (tenantId, moduleCode) => ({ + type: "SanitationType", + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "SanitationType", + filter: null, + }, + ], + }, + ], + }, +}); + +const getPitTypeCriteria = (tenantId, moduleCode) => ({ + type: "PitType", + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "PitType", + filter: null, + }, + ], + }, + ], + }, +}); + +const getApplicationChannelCriteria = (tenantId, moduleCode) => ({ + type: "ApplicationChannel", + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "ApplicationChannel", + filter: null, + }, + ], + }, + ], + }, +}); + +const getPropertyTypeCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "PropertyType", + filter: null, + }, + ], + }, + ], + }, +}); + +const getPropertyUsageCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "PropertyType", + filter: null, + }, + ], + }, + ], + }, +}); + +const getCommonFieldsCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "CommonFieldsConfig", + filter: null, + }, + ], + }, + ], + }, +}); + +const getPreFieldsCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "PreFieldsConfig", + filter: null, + }, + ], + }, + ], + }, +}); + +const getPostFieldsCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "PostFieldsConfig", + filter: null, + }, + ], + }, + ], + }, +}); + +const getConfig = (tenantId, moduleCode) => ({ + type: "Config", + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "Config", + }, + ], + }, + ], + }, +}); + +const getVehicleTypeCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "VehicleMakeModel", + filter: null, + }, + ], + }, + ], + }, +}); + +const getChecklistCriteria = (tenantId, moduleCode) => ({ + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "CheckList", + filter: null, + }, + ], + }, + ], + }, +}); + +const getSlumLocalityCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "Slum", + }, + ], + }, + ], + }, +}); +const getPropertyOwnerTypeCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "OwnerType" }], + }, + ], + }, +}); + +const getSubPropertyOwnerShipCategoryCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "SubOwnerShipCategory" }], + }, + ], + }, +}); +const getPropertyOwnerShipCategoryCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "OwnerShipCategory" }], + }, + ], + }, +}); + +const getTradeOwnerShipCategoryCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "OwnerShipCategory" }], + }, + ], + }, +}); + +const getDocumentRequiredScreenCategory = (tenantId, moduleCode) => ({ + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "Documents", + }, + ], + }, + ], + }, +}); + +const getDefaultMapConfig = (tenantId, moduleCode) => ({ + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "MapConfig", + }, + ], + }, + ], + }, +}); + +const getUsageCategoryList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "UsageCategory" }], + }, + ], + }, +}); + +const getPTPropertyTypeList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "PropertyType" }], + }, + ], + }, +}); + +const getTLStructureTypeList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "StructureType" }], + }, + ], + }, +}); + +const getTLAccessoriesTypeList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "AccessoriesCategory" }], + }, + ], + }, +}); + +const getTLFinancialYearList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "FinancialYear", filter: `[?(@.module == "TL")]` }], + }, + ], + }, +}); + +const getPTFloorList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "Floor" }], + }, + ], + }, +}); + +const getReasonCriteria = (tenantId, moduleCode, type, payload) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: payload.map((mdmsLoad) => ({ + name: mdmsLoad, + })), + }, + ], + }, +}); + +const getBillingServiceForBusinessServiceCriteria = (filter) => ({ + moduleDetails: [ + { + moduleName: "BillingService", + masterDetails: [ + { name: "BusinessService", filter }, + { + name: "TaxHeadMaster", + }, + { + name: "TaxPeriod", + }, + ], + }, + ], +}); + +const getRoleStatusCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "RoleStatusMapping", + filter: null, + }, + ], + }, + ], + }, +}); +const getRentalDetailsCategoryCriteria = (tenantId, moduleCode) => ({ + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "RentalDetails", + }, + ], + }, + ], + }, +}); + +const getChargeSlabsCategoryCriteria = (tenantId, moduleCode) => ({ + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "ChargeSlabs", + }, + ], + }, + ], + }, +}); + +const getGenderTypeList = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "GenderType", + }, + ], + }, + ], + }, +}); + +const getMeterStatusTypeList = (tenantId) => ({ + moduleDetails: [ + { + moduleName: "ws-services-calculation", + masterDetails: [ + { + name: "MeterStatus", + filter: `$.*.name`, + }, + ], + }, + ], +}); + +const getBillingPeriodValidation = (tenantId) => ({ + moduleDetails: [ + { + moduleName: "ws-services-masters", + masterDetails: [ + { + name: "billingPeriod", + filter: "*", + }, + ], + }, + ], +}); + +const getDssDashboardCriteria = (tenantId, moduleCode) => ({ + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "dashboard-config", + }, + ], + }, + ], + }, +}); + +const getMCollectBillingServiceCriteria = (tenantId, moduleCode, type, filter) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "BusinessService", filter: filter }], + }, + ], + }, +}); + +const getTradeUnitsDataList = (tenantId, moduleCode, type, filter) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "TradeType", filter: filter }], + }, + ], + }, +}); + +const getMCollectApplicationStatusCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "applicationStatus" }], + }, + ], + }, +}); + +const getHrmsEmployeeRolesandDesignations = () => ({ + moduleDetails: [ + { + moduleName: "common-masters", + masterDetails: [ + { name: "Department", filter: "[?(@.active == true)]" }, + { name: "Designation", filter: "[?(@.active == true)]" }, + ], + }, + { + moduleName: "tenant", + masterDetails: [{ name: "tenants" }], + }, + { + moduleName: "ws-services-masters", + masterDetails: [{ name: "WSServiceRoles" }], + }, + { moduleName: "egov-location", masterDetails: [{ name: "TenantBoundary" }] }, + { moduleName: "egov-hrms", masterDetails: [{ name: "EmployeeType" }] }, + ], +}); +const getFSTPPlantCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "FSTPPlantInfo" }], + }, + ], + }, +}); +const getCancelReceiptReason = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "CancelReceiptReason" }], + }, + ], + }, +}); +const getReceiptStatus = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "ReceiptStatus" }], + }, + ], + }, +}); +const getCancelReceiptReasonAndStatus = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [{ name: "ReceiptStatus" }, { name: "uiCommonPay" }], + }, + ], + }, +}); + +const getDocumentTypesCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "DocTypeMapping", + }, + ], + }, + ], + }, +}); + +const getTradeTypeRoleCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "TradeTypetoRoleMapping", + }, + ], + }, + ], + }, +}); + +const getFSTPORejectionReasonCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "FSTPORejectionReason", + filter: null, + }, + ], + }, + ], + }, +}); + +const getFSMPaymentTypeCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "PaymentType", + filter: null, + }, + ], + }, + ], + }, +}); + +const getFSMTripNumberCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "TripNumber", + filter: null, + }, + ], + }, + ], + }, +}); + +const getFSMReceivedPaymentTypeCriteria = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: moduleCode, + masterDetails: [ + { + name: "ReceivedPaymentType", + filter: null, + }, + ], + }, + ], + }, +}); + +const getWSTaxHeadMasterCritera = (tenantId, moduleCode, type) => ({ + type, + details: { + tenantId: tenantId, + moduleDetails: [ + { + moduleName: "BillingService", + masterDetails: [ + { + name: "TaxHeadMaster", + filter: null, + }, + ], + }, + ], + }, +}); + +const getHowItWorksJSON = (tenantId) => ({ + moduleDetails: [ + { + moduleName: "common-masters", + masterDetails: [ + { + name: "howItWorks", + }, + ], + }, + ], +}); + +const getFAQsJSON = (tenantId) => ({ + moduleDetails: [ + { + moduleName: "common-masters", + masterDetails: [ + { + name: "faqs", + }, + ], + }, + ], +}); +const getDSSFAQsJSON = (tenantId) => ({ + moduleDetails: [ + { + moduleName: "dss-dashboard", + masterDetails: [ + { + name: "FAQs", + }, + ], + }, + ], +}); +const getDSSAboutJSON = (tenantId) => ({ + moduleDetails: [ + { + moduleName: "dss-dashboard", + masterDetails: [ + { + name: "About", + }, + ], + }, + ], +}); + +const getStaticData = () => ({ + moduleDetails: [ + { + moduleName: "common-masters", + masterDetails: [ + { + name: "StaticData", + }, + ], + }, + ], +}); + +const GetEgovLocations = (MdmsRes) => { + return MdmsRes["egov-location"].TenantBoundary[0].boundary.children.map((obj) => ({ + name: obj.localname, + i18nKey: obj.localname, + })); +}; + +const GetServiceDefs = (MdmsRes, moduleCode) => MdmsRes[`RAINMAKER-${moduleCode}`].ServiceDefs.filter((def) => def.active); + +const GetSanitationType = (MdmsRes) => MdmsRes["FSM"].SanitationType.filter((type) => type.active); + +const GetPitType = (MdmsRes) => + MdmsRes["FSM"].PitType.filter((item) => item.active).map((type) => ({ ...type, i18nKey: `PITTYPE_MASTERS_${type.code}` })); + +const GetApplicationChannel = (MdmsRes) => + MdmsRes["FSM"].ApplicationChannel.filter((type) => type.active).map((channel) => ({ + ...channel, + i18nKey: `ES_APPLICATION_DETAILS_APPLICATION_CHANNEL_${channel.code}`, + })); + +const GetPropertyType = (MdmsRes) => + MdmsRes["FSM"].PropertyType.filter((property) => property.active && !property.propertyType).map((item) => ({ + ...item, + i18nKey: `PROPERTYTYPE_MASTERS_${item.code}`, + code: item.code, + })); + +const GetPropertySubtype = (MdmsRes) => + MdmsRes["FSM"].PropertyType.filter((property) => property.active && property.propertyType).map((item) => ({ + ...item, + i18nKey: `PROPERTYTYPE_MASTERS_${item.code}`, + code: item.code, + })); + +const GetVehicleType = (MdmsRes) => + MdmsRes["Vehicle"].VehicleMakeModel.filter((vehicle) => vehicle.active) + .filter((vehicle) => vehicle.make) + .map((vehicleDetails) => { + return { + ...vehicleDetails, + i18nKey: `COMMON_MASTER_VEHICLE_${vehicleDetails.code}`, + }; + }); + +const GetVehicleMakeModel = (MdmsRes) => + MdmsRes["Vehicle"].VehicleMakeModel.filter((vehicle) => vehicle.active).map((vehicleDetails) => { + return { + ...vehicleDetails, + i18nKey: `COMMON_MASTER_VEHICLE_${vehicleDetails.code}`, + }; + }); + +const GetSlumLocalityMapping = (MdmsRes, tenantId) => + MdmsRes["FSM"].Slum.filter((type) => type.active).reduce((prev, curr) => { + return prev[curr.locality] + ? { + ...prev, + [curr.locality]: [ + ...prev[curr.locality], + { + ...curr, + i18nKey: `${tenantId.toUpperCase().replace(".", "_")}_${curr.locality}_${curr.code}`, + }, + ], + } + : { + ...prev, + [curr.locality]: [ + { + ...curr, + i18nKey: `${tenantId.toUpperCase().replace(".", "_")}_${curr.locality}_${curr.code}`, + }, + ], + }; + }, {}); + +const GetPropertyOwnerShipCategory = (MdmsRes) => + MdmsRes["PropertyTax"].OwnerShipCategory.filter((ownerShip) => ownerShip.active).map((ownerShipDetails) => { + return { + ...ownerShipDetails, + i18nKey: `COMMON_MASTER_OWNER_TYPE_${ownerShipDetails.code}`, + }; + }); + +const GetTradeOwnerShipCategory = (MdmsRes) => + MdmsRes["common-masters"].OwnerShipCategory.filter((ownerShip) => ownerShip.active).map((ownerShipDetails) => { + return { + ...ownerShipDetails, + i18nKey: `COMMON_MASTER_OWNER_TYPE_${ownerShipDetails.code}`, + }; + }); + +const GetPropertyOwnerType = (MdmsRes) => + MdmsRes["PropertyTax"].OwnerType.filter((owner) => owner.active).map((ownerDetails) => { + return { + ...ownerDetails, + i18nKey: `PROPERTYTAX_OWNERTYPE_${ownerDetails.code}`, + }; + }); + +const getSubPropertyOwnerShipCategory = (MdmsRes) => { + MdmsRes["PropertyTax"].SubOwnerShipCategory.filter((category) => category.active).map((subOwnerShipDetails) => { + return { + ...subOwnerShipDetails, + i18nKey: `PROPERTYTAX_BILLING_SLAB_${subOwnerShipDetails.code}`, + }; + }); + sessionStorage.setItem("getSubPropertyOwnerShipCategory", JSON.stringify(MdmsRes)); +}; + +const getDocumentRequiredScreen = (MdmsRes) => { + MdmsRes["PropertyTax"].Documents.filter((Documents) => Documents.active).map((dropdownData) => { + return { + ...Documents, + i18nKey: `${dropdownData.code}`, + }; + }); +}; + +const getTLDocumentRequiredScreen = (MdmsRes) => { + MdmsRes["TradeLicense"].Documents.filter((Documents) => Documents.active).map((dropdownData) => { + return { + ...Documents, + i18nKey: `${dropdownData.code}`, + }; + }); +}; + +const getMapConfig = (MdmsRes) => { + MdmsRes["PropertyTax"].MapConfig.filter((MapConfig) => MapConfig).map((MapData) => { + return { + ...MapConfig, + defaultconfig: MapData.defaultConfig, + }; + }); +}; + +const getUsageCategory = (MdmsRes) => + MdmsRes["PropertyTax"].UsageCategory.filter((UsageCategory) => UsageCategory.active).map((UsageCategorylist) => { + return { + ...UsageCategorylist, + i18nKey: `PROPERTYTAX_BILLING_SLAB_${UsageCategorylist.code}`, + }; + }); + +const getPTPropertyType = (MdmsRes) => + MdmsRes["PropertyTax"].UsageCategory.filter((PropertyType) => PropertyType.active).map((PTPropertyTypelist) => { + return { + ...UsageCategorylist, + i18nKey: `COMMON_PROPTYPE_${Digit.Utils.locale.stringReplaceAll(PTPropertyTypelist.code, ".", "_")}`, + }; + }); + +const getTLStructureType = (MdmsRes) => + MdmsRes["common-masters"].StructureType.filter((StructureType) => StructureType.active).map((TLStructureTypeList) => { + return { + ...TLStructureTypeList, + i18nKey: `COMMON_MASTERS_STRUCTURETYPE_${Digit.Utils.locale.stringReplaceAll(TLStructureTypeList.code, ".", "_")}`, + }; + }); + +const getTLAccessoriesType = (MdmsRes) => + MdmsRes["TradeLicense"].AccessoriesCategory.filter((AccessoriesCategory) => AccessoriesCategory.active).map((TLAccessoryTypeList) => { + return { + ...TLAccessoryTypeList, + i18nKey: `TRADELICENSE_ACCESSORIESCATEGORY_${Digit.Utils.locale.stringReplaceAll(TLAccessoryTypeList.code, ".", "_")}`, + }; + }); + +const getTLFinancialYear = (MdmsRes) => + MdmsRes["egf-master"].FinancialYear.filter((FinancialYear) => FinancialYear.active && FinancialYear.module === "TL").map((FinancialYearList) => { + return { + ...FinancialYearList, + //i18nKey: `TRADELICENSE_ACCESSORIESCATEGORY_${stringReplaceAll(TLAccessoryTypeList.code, ".", "_")}`, + }; + }); +const getFloorList = (MdmsRes) => + MdmsRes["PropertyTax"].Floor.filter((PTFloor) => PTFloor.active).map((PTFloorlist) => { + return { + ...PTFloorlist, + i18nKey: `PROPERTYTAX_FLOOR_${PTFloorlist.code}`, + }; + }); + +const GetReasonType = (MdmsRes, type, moduleCode) => + Object.assign( + {}, + ...Object.keys(MdmsRes[moduleCode]).map((collection) => ({ + [collection]: MdmsRes[moduleCode][collection] + .filter((reason) => reason.active) + .map((reason) => ({ + ...reason, + i18nKey: `ES_ACTION_REASON_${reason.code}`, + })), + })) + ); + +const getRentalDetailsCategory = (MdmsRes) => { + MdmsRes["PropertyTax"].RentalDetails.filter((category) => category.active).map((RentalDetailsInfo) => { + return { + ...RentalDetailsInfo, + i18nKey: `PROPERTYTAX_BILLING_SLAB_${RentalDetailsInfo.code}`, + }; + }); +}; + +const getChargeSlabsCategory = (MdmsRes) => { + MdmsRes["PropertyTax"].ChargeSlabs.filter((category) => category.active).map((ChargeSlabsInfo) => { + return { + ...ChargeSlabsInfo, + }; + }); +}; + +const getGenderType = (MdmsRes) => { + return MdmsRes["common-masters"].GenderType.filter((GenderType) => GenderType.active).map((genderDetails) => { + return { + ...genderDetails, + i18nKey: `PT_COMMON_GENDER_${genderDetails.code}`, + }; + }); + //return MdmsRes; +}; + +const TLGenderType = (MdmsRes) => { + MdmsRes["common-masters"].GenderType.filter((GenderType) => GenderType.active).map((genders) => { + return { + ...genders, + i18nKey: `TL_GENDER_${genders.code}`, + }; + }); +}; + +const PTGenderType = (MdmsRes) => { + MdmsRes["common-masters"].GenderType.filter((GenderType) => GenderType.active).map((formGender) => { + return { + ...formGender, + i18nKey: `PT_FORM3_${formGender.code}`, + }; + }); +}; + +const HRGenderType = (MdmsRes) => { + MdmsRes["common-masters"].GenderType.filter((GenderType) => GenderType.active).map((comGender) => { + return { + ...comGender, + i18nKey: `COMMON_GENDER_${comGender.code}`, + }; + }); +}; + +const GetMCollectBusinessService = (MdmsRes) => + MdmsRes["BillingService"].BusinessService.map((businesServiceDetails) => { + return { + ...businesServiceDetails, + i18nKey: `BILLINGSERVICE_BUSINESSSERVICE_${businesServiceDetails.code}`, + }; + }); + +const GetMCollectApplicationStatus = (MdmsRes) => + MdmsRes["mCollect"].applcationStatus.map((appStatusDetails) => { + return { + ...appStatusDetails, + i18nKey: `BILLINGSERVICE_BUSINESSSERVICE_${appStatusDetails.code}`, + }; + }); + +const getFSMGenderType = (MdmsRes) => { + return MdmsRes["common-masters"].GenderType.map((genderDetails) => { + return { + ...genderDetails, + i18nKey: `COMMON_GENDER_${genderDetails.code}`, + }; + }); +}; + +const GetFSTPORejectionReason = (MdmsRes) => { + return MdmsRes["Vehicle"].FSTPORejectionReason.filter((reason) => reason.active).map((reasonDetails) => { + return { + ...reasonDetails, + i18nKey: `ES_ACTION_REASON_${reasonDetails.code}`, + }; + }); +}; + +const GetPaymentType = (MdmsRes) => { + return MdmsRes["FSM"].PaymentType.filter((option) => option.active).map((reasonDetails) => { + return { + ...reasonDetails, + i18nKey: `ES_ACTION_${reasonDetails.code}`, + }; + }); +}; + +const GetTripNumber = (MdmsRes) => { + return MdmsRes["FSM"].TripNumber.filter((option) => option.active).map((reasonDetails) => { + return { + ...reasonDetails, + i18nKey: `ES_ACTION_TRIP_${reasonDetails.code}`, + }; + }); +}; + +const GetReceivedPaymentType = (MdmsRes) => { + return MdmsRes["FSM"].ReceivedPaymentType.filter((option) => option.active).map((reasonDetails) => { + return { + ...reasonDetails, + i18nKey: `ES_ACTION_${reasonDetails.code}`, + }; + }); +}; + +const getDssDashboard = (MdmsRes) => MdmsRes["dss-dashboard"]["dashboard-config"]; + +const GetRoleStatusMapping = (MdmsRes) => MdmsRes["DIGIT-UI"].RoleStatusMapping; +const GetCommonFields = (MdmsRes, moduleCode) => + moduleCode.toUpperCase() === "PROPERTYTAX" ? MdmsRes["PropertyTax"].CommonFieldsConfig : MdmsRes["FSM"].CommonFieldsConfig; + +const GetPreFields = (MdmsRes) => MdmsRes["FSM"].PreFieldsConfig; + +const GetPostFields = (MdmsRes) => MdmsRes["FSM"].PostFieldsConfig; + +const GetFSTPPlantInfo = (MdmsRes) => MdmsRes["FSM"]?.FSTPPlantInfo; + +const GetDocumentsTypes = (MdmsRes) => MdmsRes["BPA"].DocTypeMapping; + +const GetChecklist = (MdmsRes) => MdmsRes["BPA"].CheckList; + +const transformResponse = (type, MdmsRes, moduleCode, tenantId) => { + switch (type) { + case "citymodule": + return GetCitiesWithi18nKeys(MdmsRes, moduleCode); + case "egovLocation": + return GetEgovLocations(MdmsRes); + case "serviceDefs": + return GetServiceDefs(MdmsRes, moduleCode); + case "ApplicationChannel": + return GetApplicationChannel(MdmsRes); + case "SanitationType": + return GetSanitationType(MdmsRes); + case "PropertyType": + return GetPropertyType(MdmsRes); + case "PropertySubtype": + return GetPropertySubtype(MdmsRes); + case "PitType": + return GetPitType(MdmsRes); + case "VehicleType": + return GetVehicleType(MdmsRes); + case "VehicleMakeModel": + return GetVehicleMakeModel(MdmsRes); + case "Slum": + return GetSlumLocalityMapping(MdmsRes, tenantId); + case "OwnerShipCategory": + return GetPropertyOwnerShipCategory(MdmsRes); + case "TLOwnerShipCategory": + return GetTradeOwnerShipCategory(MdmsRes); + case "OwnerType": + return GetPropertyOwnerType(MdmsRes); + case "SubOwnerShipCategory": + return getSubPropertyOwnerShipCategory(MdmsRes); + case "Documents": + return getDocumentRequiredScreen(MdmsRes); + case "TLDocuments": + return getTLDocumentRequiredScreen(MdmsRes); + case "MapConfig": + return getMapConfig(MdmsRes); + case "UsageCategory": + return getUsageCategory(MdmsRes); + case "PTPropertyType": + return getPTPropertyType(MdmsRes); + case "StructureType": + return getTLStructureType(MdmsRes); + case "AccessoryCategory": + return getTLAccessoriesType(MdmsRes); + case "FinancialYear": + return getTLFinancialYear(MdmsRes); + case "Floor": + return getFloorList(MdmsRes); + case "Reason": + return GetReasonType(MdmsRes, type, moduleCode); + case "RoleStatusMapping": + return GetRoleStatusMapping(MdmsRes); + case "CommonFieldsConfig": + return GetCommonFields(MdmsRes, moduleCode); + case "PreFieldsConfig": + return GetPreFields(MdmsRes); + case "PostFieldsConfig": + return GetPostFields(MdmsRes); + case "RentalDeatils": + return getRentalDetailsCategory(MdmsRes); + case "ChargeSlabs": + return getChargeSlabsCategory(MdmsRes); + case "DssDashboard": + return getDssDashboard(MdmsRes); + case "BusinessService": + return GetMCollectBusinessService(MdmsRes); + case "applcatonStatus": + return GetMCollectApplicationStatus(MdmsRes); + case "FSTPPlantInfo": + return GetFSTPPlantInfo(MdmsRes); + case "GenderType": + return getGenderType(MdmsRes); + case "TLGendertype": + return TLGenderType(MdmsRes); + case "PTGenderType": + return PTGenderType(MdmsRes); + case "HRGenderType": + return HRGenderType(MdmsRes); + case "DocumentTypes": + return GetDocumentsTypes(MdmsRes); + case "CheckList": + return GetChecklist(MdmsRes); + case "FSMGenderType": + return getFSMGenderType(MdmsRes); + case "FSTPORejectionReason": + return GetFSTPORejectionReason(MdmsRes); + case "PaymentType": + return GetPaymentType(MdmsRes); + case "TripNumber": + return GetTripNumber(MdmsRes); + case "ReceivedPaymentType": + return GetReceivedPaymentType(MdmsRes); + default: + return MdmsRes; + } +}; + +const getCacheSetting = (moduleName) => { + return ApiCacheService.getSettingByServiceUrl(Urls.MDMSV1, moduleName); +}; + +const mergedData = {}; +const mergedPromises = {}; +const callAllPromises = (success, promises = [], resData) => { + promises.forEach((promise) => { + if (success) { + promise.resolve(resData); + } else { + promise.reject(resData); + } + }); +}; +const mergeMDMSData = (data, tenantId) => { + if (!mergedData[tenantId] || Object.keys(mergedData[tenantId]).length === 0) { + mergedData[tenantId] = data; + } else { + data.MdmsCriteria.moduleDetails.forEach((dataModuleDetails) => { + const moduleName = dataModuleDetails.moduleName; + const masterDetails = dataModuleDetails.masterDetails; + let found = false; + mergedData[tenantId].MdmsCriteria.moduleDetails.forEach((moduleDetail) => { + if (moduleDetail.moduleName === moduleName) { + found = true; + moduleDetail.masterDetails = [...moduleDetail.masterDetails, ...masterDetails]; + } + }); + if (!found) { + mergedData[tenantId].MdmsCriteria.moduleDetails.push(dataModuleDetails); + } + }); + } +}; +const debouncedCall = ({ serviceName, url, data, useCache, params }, resolve, reject) => { + if (!mergedPromises[params.tenantId] || mergedPromises[params.tenantId].length === 0) { + const cacheSetting = getCacheSetting(); + setTimeout(() => { + let callData = JSON.parse(JSON.stringify(mergedData[params.tenantId])); + mergedData[params.tenantId] = {}; + let callPromises = [...mergedPromises[params.tenantId]]; + mergedPromises[params.tenantId] = []; + ServiceRequest({ + serviceName, + url, + data: callData, + useCache, + params, + }) + .then((data) => { + callAllPromises(true, callPromises, data); + }) + .catch((err) => { + callAllPromises(false, callPromises, err); + }); + }, cacheSetting.debounceTimeInMS || 500); + } + mergeMDMSData(data, params.tenantId); + if (!mergedPromises[params.tenantId]) { + mergedPromises[params.tenantId] = []; + } + mergedPromises[params.tenantId].push({ resolve, reject }); +}; + +export const MdmsServiceV1 = { + init: (stateCode) => + ServiceRequest({ + serviceName: "mdmsInit", + url: Urls.MDMSV1, + data: initRequestBody(stateCode), + useCache: true, + params: { tenantId: stateCode }, + }), + call: (tenantId, details) => { + return new Promise((resolve, reject) => + debouncedCall( + { + serviceName: "mdmsCall", + url: Urls.MDMSV1, + data: getCriteria(tenantId, details), + useCache: true, + params: { tenantId }, + }, + resolve, + reject + ) + ); + }, + getDataByCriteria: async (tenantId, mdmsDetails, moduleCode) => { + const key = `MDMS.${tenantId}.${moduleCode}.${mdmsDetails.type}.${JSON.stringify(mdmsDetails.details)}`; + const inStoreValue = PersistantStorage.get(key); + if (inStoreValue) { + return inStoreValue; + } + const { MdmsRes } = await MdmsServiceV1.call(tenantId, mdmsDetails.details); + const responseValue = transformResponse(mdmsDetails.type, MdmsRes, moduleCode.toUpperCase(), tenantId); + const cacheSetting = getCacheSetting(mdmsDetails.details.moduleDetails[0].moduleName); + PersistantStorage.set(key, responseValue, cacheSetting.cacheTimeInSecs); + return responseValue; + }, + getServiceDefs: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getModuleServiceDefsCriteria(tenantId, moduleCode), moduleCode); + }, + getSanitationType: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getSanitationTypeCriteria(tenantId, moduleCode), moduleCode); + }, + getApplicationChannel: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getApplicationChannelCriteria(tenantId, moduleCode), moduleCode); + }, + getPropertyType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPropertyTypeCriteria(tenantId, moduleCode, type), moduleCode); + }, + getPropertyUsage: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPropertyUsageCriteria(tenantId, moduleCode, type), moduleCode); + }, + getPropertySubtype: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPropertyTypeCriteria(tenantId, moduleCode, type), moduleCode); + }, + getPitType: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPitTypeCriteria(tenantId, moduleCode), moduleCode); + }, + getVehicleType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getVehicleTypeCriteria(tenantId, moduleCode, type), moduleCode); + }, + getChecklist: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getChecklistCriteria(tenantId, moduleCode), moduleCode); + }, + getPaymentRules: (tenantId, filter) => { + return MdmsServiceV1.call(tenantId, getBillingServiceForBusinessServiceCriteria(filter)); + }, + + getCustomizationConfig: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getConfig(tenantId, moduleCode), moduleCode); + }, + getSlumLocalityMapping: (tenantId, moduleCode, type) => + MdmsServiceV1.getDataByCriteria(tenantId, getSlumLocalityCriteria(tenantId, moduleCode, type), moduleCode), + + getReason: (tenantId, moduleCode, type, payload) => + MdmsServiceV1.getDataByCriteria(tenantId, getReasonCriteria(tenantId, moduleCode, type, payload), moduleCode), + + getRoleStatus: (tenantId, moduleCode, type) => + MdmsServiceV1.getDataByCriteria(tenantId, getRoleStatusCriteria(tenantId, moduleCode, type), moduleCode), + + getCommonFieldsConfig: (tenantId, moduleCode, type, payload) => + MdmsServiceV1.getDataByCriteria(tenantId, getCommonFieldsCriteria(tenantId, moduleCode, type, payload), moduleCode), + + getPreFieldsConfig: (tenantId, moduleCode, type, payload) => + MdmsServiceV1.getDataByCriteria(tenantId, getPreFieldsCriteria(tenantId, moduleCode, type, payload), moduleCode), + + getPostFieldsConfig: (tenantId, moduleCode, type, payload) => + MdmsServiceV1.getDataByCriteria(tenantId, getPostFieldsCriteria(tenantId, moduleCode, type, payload), moduleCode), + + getPropertyOwnerShipCategory: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPropertyOwnerShipCategoryCriteria(tenantId, moduleCode, type), moduleCode); + }, + + GetTradeOwnerShipCategory: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getTradeOwnerShipCategoryCriteria(tenantId, moduleCode, type), moduleCode); + }, + + getPropertyOwnerType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPropertyOwnerTypeCriteria(tenantId, moduleCode, type), moduleCode); + }, + getPropertySubOwnerShipCategory: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getSubPropertyOwnerShipCategoryCriteria(tenantId, moduleCode, type), moduleCode); + }, + getDocumentRequiredScreen: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getDocumentRequiredScreenCategory(tenantId, moduleCode), moduleCode); + }, + getTLDocumentRequiredScreen: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getDocumentRequiredScreenCategory(tenantId, moduleCode), moduleCode); + }, + getTradeUnitsData: (tenantId, moduleCode, type, filter) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getTradeUnitsDataList(tenantId, moduleCode, type, filter), moduleCode); + }, + getMapConfig: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getDefaultMapConfig(tenantId, moduleCode), moduleCode); + }, + getUsageCategory: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getUsageCategoryList(tenantId, moduleCode), moduleCode); + }, + getPTPropertyType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPTPropertyTypeList(tenantId, moduleCode), moduleCode); + }, + getTLStructureType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getTLStructureTypeList(tenantId, moduleCode), moduleCode); + }, + getTLAccessoriesType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getTLAccessoriesTypeList(tenantId, moduleCode), moduleCode); + }, + getTLFinancialYear: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getTLFinancialYearList(tenantId, moduleCode), moduleCode); + }, + getFloorList: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getPTFloorList(tenantId, moduleCode, type), moduleCode); + }, + getRentalDetails: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getRentalDetailsCategoryCriteria(tenantId, moduleCode), moduleCode); + }, + getChargeSlabs: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getChargeSlabsCategoryCriteria(tenantId, moduleCode), moduleCode); + }, + getDssDashboard: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getDssDashboardCriteria(tenantId, moduleCode), moduleCode); + }, + getPaymentGateway: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); + }, + getReceiptKey: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getReceiptKey(tenantId, moduleCode), moduleCode); + }, + getHelpText: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); + }, + getMCollectBillingService: (tenantId, moduleCode, type, filter) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getMCollectBillingServiceCriteria(tenantId, moduleCode, type, filter), moduleCode); + }, + getMCollectApplcationStatus: (tenantId, moduleCode, type, filter) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getMCollectApplicationStatusCriteria(tenantId, moduleCode, type, filter), moduleCode); + }, + getHrmsEmployeeRolesandDesignation: (tenantId) => { + return MdmsServiceV1.call(tenantId, getHrmsEmployeeRolesandDesignations()); + }, + getHrmsEmployeeTypes: (tenantId, moduleCode, type, filter) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); + }, + getHrmsEmployeeReason: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); + }, + getHrmsEmployeeData: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGeneralCriteria(tenantId, moduleCode, type), moduleCode); + }, + getMultipleTypes: (tenantId, moduleCode, types) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getMultipleTypes(tenantId, moduleCode, types), moduleCode); + }, + getMultipleTypesWithFilter: (tenantId, moduleCode, types) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getMultipleTypesWithFilter(moduleCode, types), moduleCode); + }, + getFSTPPlantInfo: (tenantId, moduleCode, types) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getFSTPPlantCriteria(tenantId, moduleCode, types), moduleCode); + }, + getCancelReceiptReason: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getCancelReceiptReason(tenantId, moduleCode), moduleCode); + }, + getReceiptStatus: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getReceiptStatus(tenantId, moduleCode), moduleCode); + }, + getCancelReceiptReasonAndStatus: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getCancelReceiptReasonAndStatus(tenantId, moduleCode), moduleCode); + }, + + getGenderType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGenderTypeList(tenantId, moduleCode, type), moduleCode); + }, + + TLGenderType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGenderTypeList(tenantId, moduleCode, type), moduleCode); + }, + + PTGenderType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGenderTypeList(tenantId, moduleCode, type), moduleCode); + }, + + HRGenderType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGenderTypeList(tenantId, moduleCode, type), moduleCode); + }, + + getDocumentTypes: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getDocumentTypesCriteria(tenantId, moduleCode, type), moduleCode); + }, + + getTradeTypeRoleTypes: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getTradeTypeRoleCriteria(tenantId, moduleCode, type), moduleCode); + }, + + getFSMGenderType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getGenderTypeList(tenantId, moduleCode, type), moduleCode); + }, + + getFSTPORejectionReason: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getFSTPORejectionReasonCriteria(tenantId, moduleCode, type), moduleCode); + }, + + getFSMPaymentType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getFSMPaymentTypeCriteria(tenantId, moduleCode, type), moduleCode); + }, + getBillsGenieKey: (tenantId, moduleCode) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getBillsGenieKey(tenantId, moduleCode), moduleCode); + }, + + getFSMTripNumber: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getFSMTripNumberCriteria(tenantId, moduleCode, type), moduleCode); + }, + + getFSMReceivedPaymentType: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getFSMReceivedPaymentTypeCriteria(tenantId, moduleCode, type), moduleCode); + }, + getWSTaxHeadMaster: (tenantId, moduleCode, type) => { + return MdmsServiceV1.getDataByCriteria(tenantId, getWSTaxHeadMasterCritera(tenantId, moduleCode, type), moduleCode); + }, + + getMeterStatusType: (tenantId) => { + return MdmsServiceV1.call(tenantId, getMeterStatusTypeList(tenantId)); + }, + + getBillingPeriod: (tenantId) => { + return MdmsServiceV1.call(tenantId, getBillingPeriodValidation(tenantId)); + }, + getHowItWorksJSONData: (tenantId) => { + return MdmsServiceV1.call(tenantId, getHowItWorksJSON(tenantId)); + }, + getFAQsJSONData: (tenantId) => { + return MdmsServiceV1.call(tenantId, getFAQsJSON(tenantId)); + }, + getDSSFAQsJSONData: (tenantId) => { + return MdmsServiceV1.call(tenantId, getDSSFAQsJSON(tenantId)); + }, + + getDSSAboutJSONData: (tenantId) => { + return MdmsServiceV1.call(tenantId, getDSSAboutJSON(tenantId)); + }, + getStaticDataJSON: (tenantId) => { + return MdmsServiceV1.call(tenantId, getStaticData()); + }, +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/molecules/Store/service.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/molecules/Store/service.js index fd5682358..13174979b 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/molecules/Store/service.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/services/molecules/Store/service.js @@ -56,8 +56,8 @@ export const StoreService = { }, digitInitData: async (stateCode, enabledModules) => { const { MdmsRes } = await MdmsService.init(stateCode); - const stateInfo = MdmsRes["common-masters"]?.StateInfo?.[0]||{}; - const uiHomePage = MdmsRes["common-masters"]?.uiHomePage?.[0]||{}; + const stateInfo = MdmsRes["common-masters"]?.StateInfo?.[0] || {}; + const uiHomePage = MdmsRes["common-masters"]?.uiHomePage?.[0] || {}; const localities = {}; const revenue_localities = {}; const initData = { @@ -70,31 +70,34 @@ export const StoreService = { logoUrlWhite: stateInfo.logoUrlWhite, bannerUrl: stateInfo.bannerUrl, }, - localizationModules: stateInfo.localizationModules, - modules: MdmsRes?.tenant?.citymodule.filter((module) => module?.active).filter((module) => enabledModules?.includes(module?.code))?.sort((x,y)=>x?.order-y?.order), - uiHomePage: uiHomePage + localizationModules: stateInfo?.localizationModules, + modules: MdmsRes?.tenant?.citymodule + .filter((module) => module?.active) + .filter((module) => enabledModules?.includes(module?.code)) + ?.sort((x, y) => x?.order - y?.order), + uiHomePage: uiHomePage, }; - - initData.selectedLanguage = Digit.SessionStorage.get("locale") || initData.languages[0].value; + initData.selectedLanguage = + Digit.SessionStorage.get("locale") || initData?.languages[2] ? initData?.languages[2]?.value : initData?.languages[1]?.value; ApiCacheService.saveSetting(MdmsRes["DIGIT-UI"]?.ApiCachingSettings); - const moduleTenants = initData.modules + const moduleTenants = initData?.modules .map((module) => module.tenants) .flat() .reduce((unique, ele) => (unique.find((item) => item.code === ele.code) ? unique : [...unique, ele]), []); initData.tenants = MdmsRes?.tenant?.tenants - .map((tenant) => ({ i18nKey: `TENANT_TENANTS_${tenant.code.replace(".", "_").toUpperCase()}`, ...tenant })); - // .filter((item) => !!moduleTenants.find((mt) => mt.code === item.code)) - // .map((tenant) => ({ i18nKey: `TENANT_TENANTS_${tenant.code.replace(".", "_").toUpperCase()}`, ...tenant })); + ?.filter((x) => x.pgrEnabled) + .map((tenant) => ({ + i18nKey: `TENANT_TENANTS_${tenant.code.replace(".", "_").toUpperCase()}`, + ...tenant, + })); + // .filter((item) => !!moduleTenants.find((mt) => mt.code === item.code)) + // .map((tenant) => ({ i18nKey: `TENANT_TENANTS_${tenant.code.replace(".", "_").toUpperCase()}`, ...tenant })); await LocalizationService.getLocale({ - modules: [ - `rainmaker-common`, - `rainmaker-${stateCode.toLowerCase()}`, - `rainmaker-works` - ], + modules: [`rainmaker-common`], locale: initData.selectedLanguage, tenantId: stateCode, }); @@ -108,7 +111,10 @@ export const StoreService = { }, defaultData: async (stateCode, moduleCode, language) => { let moduleCodes = []; - if(typeof moduleCode !== "string") moduleCode.forEach(code => { moduleCodes.push(`rainmaker-${code.toLowerCase()}`) }); + if (typeof moduleCode !== "string") + moduleCode.forEach((code) => { + moduleCodes.push(`rainmaker-${code.toLowerCase()}`); + }); const LocalePromise = LocalizationService.getLocale({ modules: typeof moduleCode == "string" ? [`rainmaker-${moduleCode.toLowerCase()}`] : moduleCodes, locale: language, diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/dss/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/dss/index.js index 803da0240..f3f1b91ba 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/dss/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/dss/index.js @@ -29,7 +29,7 @@ export const formatter = (value, symbol, unit, commaSeparated = true, t) => { return parseInt(value); } const Nformatter = new Intl.NumberFormat("en-IN"); - return Nformatter.format(Math.round(value)); + return Nformatter.format(value); case "percentage": const Pformatter = new Intl.NumberFormat("en-IN", { maximumSignificantDigits: 3 }); return `${Pformatter.format(value.toFixed(2))} %`; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/index.js index e58155596..8921129f6 100644 --- a/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/index.js +++ b/frontend/micro-ui/web/micro-ui-internals/packages/libraries/src/utils/index.js @@ -91,11 +91,20 @@ const getPattern = (type) => { return /^[a-zA-z0-9\s\\/\-]$/i; } }; - +/* +Digit.Utils.getUnique() +get unique elements from an array */ const getUnique = (arr) => { return arr.filter((value, index, self) => self.indexOf(value) === index); }; +/* +Digit.Utils.createFunction() +get function from a string */ +const createFunction = (functionAsString) => { + return Function("return " + functionAsString)(); +}; + const getStaticMapUrl = (latitude, longitude) => { const key = globalConfigs?.getConfig("GMAPS_API_KEY"); return `https://maps.googleapis.com/maps/api/staticmap?markers=${latitude},${longitude}&zoom=15&size=400x400&key=${key}&style=element:geometry%7Ccolor:0xf5f5f5&style=element:labels.icon%7Cvisibility:off&style=element:labels.text.fill%7Ccolor:0x616161&style=element:labels.text.stroke%7Ccolor:0xf5f5f5&style=feature:administrative.land_parcel%7Celement:labels.text.fill%7Ccolor:0xbdbdbd&style=feature:poi%7Celement:geometry%7Ccolor:0xeeeeee&style=feature:poi%7Celement:labels.text.fill%7Ccolor:0x757575&style=feature:poi.park%7Celement:geometry%7Ccolor:0xe5e5e5&style=feature:poi.park%7Celement:labels.text.fill%7Ccolor:0x9e9e9e&style=feature:road%7Celement:geometry%7Ccolor:0xffffff&style=feature:road.arterial%7Celement:labels.text.fill%7Ccolor:0x757575&style=feature:road.highway%7Celement:geometry%7Ccolor:0xdadada&style=feature:road.highway%7Celement:labels.text.fill%7Ccolor:0x616161&style=feature:road.local%7Celement:labels.text.fill%7Ccolor:0x9e9e9e&style=feature:transit.line%7Celement:geometry%7Ccolor:0xe5e5e5&style=feature:transit.station%7Celement:geometry%7Ccolor:0xeeeeee&style=feature:water%7Celement:geometry%7Ccolor:0xc9c9c9&style=feature:water%7Celement:labels.text.fill%7Ccolor:0x9e9e9e`; @@ -107,23 +116,6 @@ const detectDsoRoute = (pathname) => { return employeePages.some((url) => pathname.split("/").includes(url)); }; - -/* to check the employee (loggedin user ) has given role */ -const didEmployeeHasRole = (role = "") => { - const tenantId = Digit.ULBService.getCurrentTenantId(); - const userInfo = Digit.UserService.getUser(); - const rolearray = userInfo?.info?.roles.filter((item) => { - if (item.code === role && item.tenantId === tenantId) return true; - }); - return rolearray?.length > 0; -}; - - -/* to check the employee (loggedin user ) has given roles */ -const didEmployeeHasAtleastOneRole = (roles = []) => { - return roles.some((role) => didEmployeeHasRole(role)); -}; - const routeSubscription = (pathname) => { let classname = "citizen"; const isEmployeeUrl = detectDsoRoute(pathname); @@ -134,6 +126,14 @@ const routeSubscription = (pathname) => { } }; +const didEmployeeHasRole = (role) => { + const tenantId = Digit.ULBService.getCurrentTenantId(); + const userInfo = Digit.UserService.getUser(); + const rolearray = userInfo?.info?.roles.filter((item) => { + if (item.code == role && item.tenantId === tenantId) return true; + }); + return rolearray?.length; +}; const pgrAccess = () => { const userInfo = Digit.UserService.getUser(); @@ -287,20 +287,9 @@ const swAccess = () => { const getConfigModuleName = () => { return window?.globalConfigs?.getConfig("UICONFIG_MODULENAME") || "commonUiConfig"; }; - - -/* -Digit.Utils.createFunction() -get function from a string */ -const createFunction = (functionAsString) => { - return Function("return " + functionAsString)(); -}; - - - export default { - createFunction, pdf: PDFUtil, + createFunction, downloadReceipt, downloadBill, downloadPDFFromLink, @@ -326,7 +315,6 @@ export default { mCollectAccess, receiptsAccess, didEmployeeHasRole, - didEmployeeHasAtleastOneRole, hrmsAccess, getPattern, hrmsRoles, diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/README.md b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/README.md new file mode 100644 index 000000000..85c382a05 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/README.md @@ -0,0 +1,98 @@ + + +# digit-ui-module-core + +## Install + +```bash +npm install --save @egovernments/digit-ui-module-core +``` + +## Limitation + +```bash +This Package is more specific to DIGIT-UI's can be used across mission's +``` + +## Usage + +After adding the dependency make sure you have this dependency in + +```bash +frontend/micro-ui/web/package.json +``` + +```json +"@egovernments/digit-ui-module-core":"^1.5.0", +``` + +then navigate to App.js + +```bash + frontend/micro-ui/web/src/App.js +``` + +```jsx +/** add this import **/ + +import { DigitUI } from "@egovernments/digit-ui-module-core"; + + +/** inside render Function add the import for the component **/ + + ReactDOM.render(, document.getElementById("root")); + +``` + +# Mandatory changes to use following version + +``` +from 1.5.38 add the following utility method in micro-ui-internals/packages/libraries/src/utils/index.js + +const createFunction = (functionAsString) => { + return Function("return " + functionAsString)(); +}; + +export as createFunction; + +similarly update line 76 of react-components/src/molecules/CustomDropdown.js + +with + .filter((opt) => (opt?.hasOwnProperty("active") ? opt.active : true)) + +``` + +# Changelog + +```bash +1.5.46 added classname for topbar options dropdown. +1.5.45 aligment issue in edit and logout +1.5.44 updated login scss and alignment issues +1.5.42 fixed the mdms call in login component for dynamic updating +1.5.41 updated the readme content +1.5.40 Updated the login componenet to handle mdms config, which can be accessed from master - commonUiConfig and module - LoginConfig +1.5.39 Show the Toast when password changed and need to logout from profile page +1.5.38 enabled the admin mode for employee login which can be accessed through route employee/user/login?mode=admin and updated to use formcomposerv2 +1.5.37 fixed hiding upload drawer icons. +1.5.36 fixed after clicking on change password and then try to save profile without changing password showing error. +1.5.35 fixed user profile email was prefilled when clicking on change password +1.5.34 fixed module not found redirection issue +1.5.33 fixed payment not throwing error page for sanitation +1.5.32 fixed the localisation issue by adding translation to the keys and fixed payment response issue for sanitation UI +1.5.31 fixed the allservices screen back button for sanitation UI +1.5.30 fixed the home routing issue in error screen +1.5.29 added the readme file +1.5.28 fixed the route issue for profile screen +``` + +# Contributors + +[jagankumar-egov] [nipunarora-eGov] [Tulika-eGov] [Ramkrishna-egov] [nabeelmd-eGov] [anil-egov] [vamshikrishnakole-wtt-egov] + +## Published from DIGIT Core + +Digit Dev Repo () + +## License + +MIT © [jagankumar-egov](https://github.com/jagankumar-egov) diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/package.json new file mode 100644 index 000000000..7182d7e8d --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/package.json @@ -0,0 +1,29 @@ +{ + "name": "@egovernments/digit-ui-module-core", + "version": "1.5.46", + "license": "MIT", + "main": "dist/index.js", + "module": "dist/index.modern.js", + "source": "src/Module.js", + "files": [ + "dist" + ], + "scripts": { + "start": "microbundle-crl watch --no-compress --format modern,cjs", + "build": "microbundle-crl --compress --no-sourcemap --format cjs", + "prepublish": "yarn build" + }, + "dependencies": { + "@egovernments/digit-ui-react-components": "^1.5.5", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-i18next": "11.16.2", + "react-query": "3.6.1", + "react-redux": "7.2.8", + "react-router-dom": "5.3.0", + "react-tooltip": "4.1.2", + "redux": "4.1.2", + "redux-thunk": "2.4.1" + }, + "keywords": ["digit","egov","dpg","digit-ui","core"] +} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/App.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/App.js new file mode 100644 index 000000000..ab2535630 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/App.js @@ -0,0 +1,80 @@ +import React, { useEffect } from "react"; +import { Redirect, Route, Switch, useHistory, useLocation } from "react-router-dom"; +import CitizenApp from "./pages/citizen"; +import EmployeeApp from "./pages/employee"; + +export const DigitApp = ({ stateCode, modules, appTenants, logoUrl, initData ,defaultLanding="citizen"}) => { + const history = useHistory(); + const { pathname } = useLocation(); + const innerWidth = window.innerWidth; + const cityDetails = Digit.ULBService.getCurrentUlb(); + const userDetails = Digit.UserService.getUser(); + const { data: storeData } = Digit.Hooks.useStore.getInitData(); + const { stateInfo } = storeData || {}; + + const DSO = Digit.UserService.hasAccess(["FSM_DSO"]); + let CITIZEN = userDetails?.info?.type === "CITIZEN" || !window.location.pathname.split("/").includes("employee") ? true : false; + + if (window.location.pathname.split("/").includes("employee")) CITIZEN = false; + + useEffect(() => { + if (!pathname?.includes("application-details")) { + if (!pathname?.includes("inbox")) { + Digit.SessionStorage.del("fsm/inbox/searchParams"); + } + if (pathname?.includes("search")) { + Digit.SessionStorage.del("fsm/search/searchParams"); + } + } + if (!pathname?.includes("dss")) { + Digit.SessionStorage.del("DSS_FILTERS"); + } + if (pathname?.toString() === `/${window?.contextPath}/employee`) { + Digit.SessionStorage.del("SEARCH_APPLICATION_DETAIL"); + Digit.SessionStorage.del("WS_EDIT_APPLICATION_DETAILS"); + } + if (pathname?.toString() === `/${window?.contextPath}/citizen` || pathname?.toString() === `/${window?.contextPath}/employee`) { + Digit.SessionStorage.del("WS_DISCONNECTION"); + } + }, [pathname]); + + history.listen(() => { + window?.scrollTo({ top: 0, left: 0, behavior: "smooth" }); + }); + + const handleUserDropdownSelection = (option) => { + option.func(); + }; + + const mobileView = innerWidth <= 640; + let sourceUrl = `${window.location.origin}/citizen`; + const commonProps = { + stateInfo, + userDetails, + CITIZEN, + cityDetails, + mobileView, + handleUserDropdownSelection, + logoUrl, + DSO, + stateCode, + modules, + appTenants, + sourceUrl, + pathname, + initData, + }; + return ( + + + + + + + + + + + + ); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/Module.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/Module.js new file mode 100644 index 000000000..95a29d987 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/Module.js @@ -0,0 +1,118 @@ +import { Body, Loader } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { getI18n } from "react-i18next"; +import { QueryClient, QueryClientProvider } from "react-query"; +import { Provider } from "react-redux"; +import { BrowserRouter as Router } from "react-router-dom"; +import { DigitApp } from "./App"; +import SelectOtp from "./pages/citizen/Login/SelectOtp"; + +import { useState } from "react"; +import ErrorBoundary from "./components/ErrorBoundaries"; +import getStore from "./redux/store"; + +const DigitUIWrapper = ({ stateCode, enabledModules, moduleReducers,defaultLanding }) => { + const { isLoading, data: initData } = Digit.Hooks.useInitStore(stateCode, enabledModules); + if (isLoading) { + return ; + } + + const i18n = getI18n(); + return ( + + + + + + + + ); +}; + +export const DigitUI = ({ stateCode, registry, enabledModules, moduleReducers ,defaultLanding}) => { + const [privacy, setPrivacy] = useState(Digit.Utils.getPrivacyObject() || {}); + const userType = Digit.UserService.getType(); + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 15 * 60 * 1000, + cacheTime: 50 * 60 * 1000, + retry: false, + retryDelay: (attemptIndex) => Infinity, + /* + enable this to have auto retry incase of failure + retryDelay: attemptIndex => Math.min(1000 * 3 ** attemptIndex, 60000) + */ + }, + }, + }); + + const ComponentProvider = Digit.Contexts.ComponentProvider; + const PrivacyProvider = Digit.Contexts.PrivacyProvider; + + const DSO = Digit.UserService.hasAccess(["FSM_DSO"]); + + return ( +
+ + + + { + Digit.Utils.setPrivacyObject({}); + setPrivacy({}); + }, + getPrivacy: () => { + const privacyObj = Digit.Utils.getPrivacyObject(); + setPrivacy(privacyObj); + return privacyObj; + }, + /* Descoped method to update privacy object */ + updatePrivacyDescoped: (_data) => { + const privacyObj = Digit.Utils.getAllPrivacyObject(); + const newObj = { ...privacyObj, [window.location.pathname]: _data }; + Digit.Utils.setPrivacyObject({ ...newObj }); + setPrivacy(privacyObj?.[window.location.pathname] || {}); + }, + /** + * Main Method to update the privacy object anywhere in the application + * + * @author jagankumar-egov + * + * Feature :: Privacy + * + * @example + * const { privacy , updatePrivacy } = Digit.Hooks.usePrivacyContext(); + */ + updatePrivacy: (uuid, fieldName) => { + setPrivacy(Digit.Utils.updatePrivacy(uuid, fieldName) || {}); + }, + }} + > + + + + + +
+ ); +}; + +const componentsToRegister = { + SelectOtp, +}; + +export const initCoreComponents = () => { + Object.entries(componentsToRegister).forEach(([key, value]) => { + Digit.ComponentRegistryService.setComponent(key, value); + }); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/AppModules.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/AppModules.js new file mode 100644 index 000000000..26177b600 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/AppModules.js @@ -0,0 +1,59 @@ +import React from "react"; +import { Redirect, Route, Switch, useLocation, useRouteMatch } from "react-router-dom"; + +import ChangePassword from "../pages/employee/ChangePassword/index"; +import ForgotPassword from "../pages/employee/ForgotPassword/index"; +import { AppHome } from "./Home"; +// import UserProfile from "./userProfile"; + +const getTenants = (codes, tenants) => { + return tenants.filter((tenant) => codes?.map?.((item) => item.code).includes(tenant.code)); +}; + +export const AppModules = ({ stateCode, userType, modules, appTenants }) => { + const ComponentProvider = Digit.Contexts.ComponentProvider; + const { path } = useRouteMatch(); + const location = useLocation(); + + const user = Digit.UserService.getUser(); + + if (!user || !user?.access_token || !user?.info) { + return ; + } + + const appRoutes = modules.map(({ code, tenants }, index) => { + const Module = Digit.ComponentRegistryService.getComponent(`${code}Module`); + return Module ? ( + + + + ) : ( + + + + ); + }); + + return ( +
+ + {appRoutes} + + + + + + + + + + + + + {/* */} + +
+ ); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Background.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Background.js new file mode 100644 index 000000000..f2b4c0c0d --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Background.js @@ -0,0 +1,7 @@ +import React from "react"; + +const Background = ({ children }) => { + return
{children}
; +}; + +export default Background; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ChangeCity.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ChangeCity.js new file mode 100644 index 000000000..122f6e506 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ChangeCity.js @@ -0,0 +1,113 @@ +import { Dropdown } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; + +const stringReplaceAll = (str = "", searcher = "", replaceWith = "") => { + if (searcher == "") return str; + while (str?.includes(searcher)) { + str = str?.replace(searcher, replaceWith); + } + return str; +}; + +const ChangeCity = (prop) => { + const [dropDownData, setDropDownData] = useState({ + label: `TENANT_TENANTS_${stringReplaceAll(Digit.SessionStorage.get("Employee.tenantId"), ".", "_")?.toUpperCase()}`, + value: Digit.SessionStorage.get("Employee.tenantId"), + }); + const [selectCityData, setSelectCityData] = useState([]); + const [selectedCity, setSelectedCity] = useState([]); //selectedCities?.[0]?.value + const history = useHistory(); + const isDropdown = prop.dropdown || false; + let selectedCities = []; + + const { data: data = {}, isLoading } = + Digit.Hooks.hrms.useHrmsMDMS(Digit.ULBService.getCurrentTenantId(), "egov-hrms", "HRMSRolesandDesignation") || {}; + + const handleChangeCity = (city) => { + const loggedInData = Digit.SessionStorage.get("citizen.userRequestObject"); + const filteredRoles = Digit.SessionStorage.get("citizen.userRequestObject")?.info?.roles?.filter((role) => role.tenantId === city.value); + if (filteredRoles?.length > 0) { + loggedInData.info.roles = filteredRoles; + loggedInData.info.tenantId = city?.value; + } + Digit.SessionStorage.set("Employee.tenantId", city?.value); + Digit.UserService.setUser(loggedInData); + setDropDownData(city); + if (window.location.href.includes(`/${window?.contextPath}/employee/`)) { + const redirectPath = location.state?.from || `/${window?.contextPath}/employee`; + history.replace(redirectPath); + } + window.location.reload(); + }; + + useEffect(() => { + const userloggedValues = Digit.SessionStorage.get("citizen.userRequestObject"); + let teantsArray = [], + filteredArray = []; + userloggedValues?.info?.roles?.forEach((role) => teantsArray.push(role.tenantId)); + let unique = teantsArray.filter((item, i, ar) => ar.indexOf(item) === i); + + unique?.forEach((uniCode) => { + data?.MdmsRes?.["tenant"]["tenants"]?.map((items) => { + if (items?.code !== "pb" && items?.code === uniCode) { + filteredArray.push({ + label: `${prop?.t(Digit.Utils.locale.convertToLocale(items?.divisionCode, "EGOV_LOCATION_DIVISION"))} - ${prop?.t( + `TENANT_TENANTS_${stringReplaceAll(uniCode, ".", "_")?.toUpperCase()}` + )}`, + value: uniCode, + }); + } else if (items?.code === "pb" && items?.code === uniCode) { + filteredArray.push({ + label: `TENANT_TENANTS_${stringReplaceAll(uniCode, ".", "_")?.toUpperCase()}`, + value: uniCode, + }); + } + }); + }); + selectedCities = filteredArray?.filter((select) => select.value == Digit.SessionStorage.get("Employee.tenantId")); + setSelectCityData(filteredArray); + }, [dropDownData, data?.MdmsRes]); + + // if (isDropdown) { + return ( +
+ + // {prop?.t(`TENANT_TENANTS_${stringReplaceAll(Digit.SessionStorage.get("Employee.tenantId"), ".", "_")?.toUpperCase()}`)} + // + // } + /> +
+ ); + // } else { + // return ( + // + //
City
+ //
+ // {selectCityData?.map((city, index) => ( + //
+ // handleChangeCity(city)} + // > + //
+ // ))} + //
+ //
+ // ); + // } +}; + +export default ChangeCity; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ChangeLanguage.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ChangeLanguage.js new file mode 100644 index 000000000..a5eba9163 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ChangeLanguage.js @@ -0,0 +1,50 @@ +import { CustomButton, Dropdown } from "@egovernments/digit-ui-react-components"; +import React, { useState } from "react"; + +const ChangeLanguage = (prop) => { + const isDropdown = prop.dropdown || false; + const { data: storeData, isLoading } = Digit.Hooks.useStore.getInitData(); + const { languages, stateInfo } = storeData || {}; + const selectedLanguage = Digit.StoreData.getCurrentLanguage(); + const [selected, setselected] = useState(selectedLanguage); + const handleChangeLanguage = (language) => { + setselected(language.value); + Digit.LocalizationService.changeLanguage(language.value, stateInfo.code); + }; + + if (isLoading) return null; + + if (isDropdown) { + return ( +
+ language.value === selectedLanguage)} + optionKey={"label"} + select={handleChangeLanguage} + freeze={true} + customSelector={} + /> +
+ ); + } else { + return ( + +
Language
+
+ {languages.map((language, index) => ( +
+ handleChangeLanguage(language)} + > +
+ ))} +
+
+ ); + } +}; + +export default ChangeLanguage; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Dialog/LogoutDialog.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Dialog/LogoutDialog.js new file mode 100644 index 000000000..0b28ea1a7 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Dialog/LogoutDialog.js @@ -0,0 +1,114 @@ +import { CardText, CloseSvg, Modal } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useTranslation } from "react-i18next"; + +const Heading = (props) => { + return

{props.label}

; +}; +const Close = () => ( + + + + +); +const CloseBtn = (props) => { + return ( +
+ {props?.isMobileView ? ( + + ) : ( +
+ {" "} + {" "} +
+ )} +
+ ); +}; +const LogoutDialog = ({ onSelect, onCancel, onDismiss }) => { + const { t } = useTranslation(); + const mobileDeviceWidth = 780; + const [isMobileView, setIsMobileView] = React.useState(window.innerWidth <= mobileDeviceWidth); + const onResize = () => { + if (window.innerWidth <= mobileDeviceWidth) { + if (!isMobileView) { + setIsMobileView(true); + } + } else { + if (isMobileView) { + setIsMobileView(false); + } + } + }; + React.useEffect(() => { + window.addEventListener("resize", () => { + onResize(); + }); + return () => { + window.addEventListener("resize", () => { + onResize(); + }); + }; + }); + return isMobileView ? ( + } + headerBarEnd={} + actionCancelLabel={t("CORE_LOGOUT_CANCEL")} + actionCancelOnSubmit={onCancel} + actionSaveLabel={t("CORE_LOGOUT_WEB_YES")} + actionSaveOnSubmit={onSelect} + formId="modal-action" + > +
+ {t("CORE_LOGOUT_WEB_CONFIRMATION_MESSAGE") + " "} +
+
+ ) : ( + } + headerBarEnd={} + actionCancelLabel={t("CORE_LOGOUT_CANCEL")} + actionCancelOnSubmit={onCancel} + actionSaveLabel={t("CORE_LOGOUT_WEB_YES")} + actionSaveOnSubmit={onSelect} + formId="modal-action" + > +
+ + {t("CORE_LOGOUT_WEB_CONFIRMATION_MESSAGE") + " "} + {t("CORE_LOGOUT_MESSAGE")}? + +
+
+ ); +}; +export default LogoutDialog; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ErrorBoundaries.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ErrorBoundaries.js new file mode 100644 index 000000000..42b619b3c --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ErrorBoundaries.js @@ -0,0 +1,57 @@ +import React from "react"; +import ErrorComponent from "./ErrorComponent"; + +const Redircter = () => { + const path = Digit.UserService.getType() === "employee" ? `/${window?.contextPath}/employee/user/error` : `/${window?.contextPath}/citizen/error`; + if ( + window.location.href.includes("employee/user/error") || + window.location.href.includes("citizen/error") || + process.env.NODE_ENV === "development" + ) { + //do nothing + }else{ + window.location.href = path; + } + return ; +}; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { error: null, errorStack: null, hasError: false }; + } + + static getDerivedStateFromError(error) { + // Update state so the next render will show the fallback UI. + return { error: error?.message, hasError: true, errorStack: error?.stack }; + } + + componentDidCatch(error, errorInfo) { + // Catch errors in any components below and re-render with error message + this.setState({ error: error?.message, hasError: true, errorStack: error?.stack }); + // You can also log error messages to an error reporting service here + } + + render() { + if (this.state.hasError) { + // ("UI-errorInfo", this.state?.errorStack); + // ("UI-component-details", this.props); + // You can render any custom fallback UI + return ( +
+ + + + {/* Something went wrong +
+ {this.state?.errorStack && this.state.errorStack.toString().substring(0, 600)} + {this.state?.error} +
*/} +
+ ); + } + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ErrorComponent.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ErrorComponent.js new file mode 100644 index 000000000..de347f17e --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/ErrorComponent.js @@ -0,0 +1,46 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; + +const ErrorConfig = { + error: { + imgUrl: `https://s3.ap-south-1.amazonaws.com/egov-qa-assets/error-image.png`, + infoMessage: "CORE_SOMETHING_WENT_WRONG", + buttonInfo: "ACTION_TEST_HOME", + }, + maintenance: { + imgUrl: `https://s3.ap-south-1.amazonaws.com/egov-qa-assets/maintainence-image.png`, + infoMessage: "CORE_UNDER_MAINTENANCE", + buttonInfo: "ACTION_TEST_HOME", + }, + notfound: { + imgUrl: `https://s3.ap-south-1.amazonaws.com/egov-qa-assets/PageNotFound.png`, + infoMessage: "MODULE_NOT_FOUND", + buttonInfo: "ACTION_TEST_HOME", + }, +}; + +const ErrorComponent = (props) => { + const { type = "error" } = Digit.Hooks.useQueryParams(); + const config = ErrorConfig[type]; + const { t } = useTranslation(); + + const stateInfo = props.stateInfo; + + return ( +
+
+ error +

{t(config.infoMessage)}

+ +
+
+ ); +}; + +export default ErrorComponent; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Header.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Header.js new file mode 100644 index 000000000..e3ba91196 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Header.js @@ -0,0 +1,22 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { Loader, BackButton } from "@egovernments/digit-ui-react-components" + +const Header = () => { + const { data: storeData, isLoading } = Digit.Hooks.useStore.getInitData(); + const { stateInfo } = storeData || {}; + const { t } = useTranslation() + + if (isLoading) return ; + + return ( +
+ {window.location.href.includes("employee/user/forgot-password")?:""} + + +

{t(`TENANT_TENANTS_${stateInfo?.code.toUpperCase()}`)}

+
+ ); +} + +export default Header; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Home.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Home.js new file mode 100644 index 000000000..71b7fde48 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Home.js @@ -0,0 +1,147 @@ +import { + BackButton, + BillsIcon, + CitizenHomeCard, + CitizenInfoLabel, + FSMIcon, + Loader, + MCollectIcon, + OBPSIcon, + PGRIcon, + PTIcon, + TLIcon, + WSICon, +} from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useTranslation } from "react-i18next"; + +/* +Feature :: Citizen All service screen cards +*/ +export const processLinkData = (newData, code, t) => { + const obj = newData?.[`${code}`]; + if (obj) { + obj.map((link) => { + (link.link = link["navigationURL"]), (link.i18nKey = t(link["name"])); + }); + } + const newObj = { + links: obj?.reverse(), + header: Digit.Utils.locale.getTransformedLocale(`ACTION_TEST_${code}`), + iconName: `CITIZEN_${code}_ICON`, + }; + if (code === "FSM") { + const roleBasedLoginRoutes = [ + { + role: "FSM_DSO", + from: `/${window?.contextPath}/citizen/fsm/dso-dashboard`, + dashoardLink: "CS_LINK_DSO_DASHBOARD", + loginLink: "CS_LINK_LOGIN_DSO", + }, + ]; + //RAIN-7297 + roleBasedLoginRoutes.map(({ role, from, loginLink, dashoardLink }) => { + if (Digit.UserService.hasAccess(role)) + newObj?.links?.push({ + link: from, + i18nKey: t(dashoardLink), + }); + else + newObj?.links?.push({ + link: `/${window?.contextPath}/citizen/login`, + state: { role: "FSM_DSO", from }, + i18nKey: t(loginLink), + }); + }); + } + + return newObj; +}; +const iconSelector = (code) => { + switch (code) { + case "PT": + return ; + case "WS": + return ; + case "FSM": + return ; + case "MCollect": + return ; + case "PGR": + return ; + case "TL": + return ; + case "OBPS": + return ; + case "Bills": + return ; + default: + return ; + } +}; +const CitizenHome = ({ modules, getCitizenMenu, fetchedCitizen, isLoading }) => { + const paymentModule = modules.filter(({ code }) => code === "Payment")[0]; + const moduleArr = modules.filter(({ code }) => code !== "Payment"); + const moduleArray = [paymentModule, ...moduleArr]; + const { t } = useTranslation(); + if (isLoading) { + return ; + } + + return ( + +
+ {location.pathname.includes("sanitation-ui/citizen/all-services") ? null : } +
+ {moduleArray + .filter((mod) => mod) + .map(({ code }, index) => { + let mdmsDataObj; + if (fetchedCitizen) mdmsDataObj = fetchedCitizen ? processLinkData(getCitizenMenu, code, t) : undefined; + if (mdmsDataObj?.links?.length > 0) { + return ( + ele?.link)?.sort((x, y) => x?.orderNumber - y?.orderNumber)} + Icon={() => iconSelector(code)} + Info={ + code === "OBPS" + ? () => ( + + ) + : null + } + isInfo={code === "OBPS" ? true : false} + /> + ); + } else return ; + })} +
+
+
+ ); +}; + +const EmployeeHome = ({ modules }) => { + return ( +
+
+ {modules.map(({ code }, index) => { + const Card = Digit.ComponentRegistryService.getComponent(`${code}Card`) || (() => ); + return ; + })} +
+
+ ); +}; + +export const AppHome = ({ userType, modules, getCitizenMenu, fetchedCitizen, isLoading }) => { + if (userType === "citizen") { + return ; + } + return ; +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/MobileSearchApplication.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/MobileSearchApplication.js new file mode 100644 index 000000000..0e85156f5 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/MobileSearchApplication.js @@ -0,0 +1,174 @@ +import { + BackButton, CloseSvg, DetailsCard, DownloadBtnCommon, Header, Loader, PopUp, SearchAction, SearchForm +} from "@egovernments/digit-ui-react-components"; +import React, { useCallback, useEffect, useMemo, useReducer, useState } from "react"; +import SearchFormFields from "./SearchFields"; +// import { convertEpochToDateDMY } from "../../utils"; + +const MobileSearchApplication = ({ Controller, register, control, t, reset, previousPage, handleSubmit, tenantId, data, onSubmit, isLoading }) => { + function activateModal(state, action) { + switch (action.type) { + case "set": + return action.payload; + case "remove": + return false; + default: + break; + } + } + const [tabledata, settabledata] = useState([]); + const DownloadBtn = (props) => { + return ( +
+ +
+ ); + }; + const handleExcelDownload = (tabData) => { + if (tabData?.[0] !== undefined) { + return Digit.Download.Excel(tabData?.[0], "AuditReport"); + } + }; + useEffect(() => { + if (data?.length > 0) { + settabledata([ + data?.map((obj) => { + let returnObject = {}; + returnObject[t("AUDIT_DATE_LABEL")] = convertEpochToDate(obj?.timestamp); + returnObject[t("AUDIT_TIME_LABEL")] = convertEpochToTimeInHours(obj?.timestamp); + returnObject[t("AUDIT_DATAVIEWED_LABEL")] = obj?.dataView[0] + "," + obj?.dataView[1]; + returnObject[t("AUDIT_DATAVIEWED_BY_LABEL")] = obj?.dataViewedBy; + returnObject[t("AUDIT_ROLE_LABEL")] = obj?.roles.map((obj) => obj.name).join(","); + return { + ...returnObject, + }; + }), + ]); + } + }, [data]); + const convertEpochToDate = (dateEpoch) => { + if (dateEpoch == null || dateEpoch == undefined || dateEpoch == "") { + return "NA"; + } + const dateFromApi = new Date(dateEpoch); + let month = dateFromApi.getMonth() + 1; + let day = dateFromApi.getDate(); + let year = dateFromApi.getFullYear(); + month = (month > 9 ? "" : "0") + month; + day = (day > 9 ? "" : "0") + day; + return `${day}/${month}/${year}`; + }; + const convertEpochToTimeInHours = (dateEpoch) => { + if (dateEpoch == null || dateEpoch == undefined || dateEpoch == "") { + return "NA"; + } + const dateFromApi = new Date(dateEpoch); + let hour = dateFromApi.getHours(); + let min = dateFromApi.getMinutes(); + let period = hour > 12 ? "PM" : "AM"; + hour = hour > 12 ? hour - 12 : hour; + hour = (hour > 9 ? "" : "0") + hour; + min = (min > 9 ? "" : "0") + min; + return `${hour}:${min} ${period}`; + }; + const [currentlyActiveMobileModal, setActiveMobileModal] = useReducer(activateModal, false); + + const closeMobilePopupModal = () => { + setActiveMobileModal({ type: "remove" }); + }; + + const MobilePopUpCloseButton = () => ( +
+ +
+ ); + const searchFormFieldsComponentProps = { Controller, register, control, t, reset, previousPage }; + + const MobileComponentDirectory = ({ currentlyActiveMobileModal, searchFormFieldsComponentProps, tenantId, ...props }) => { + const { closeMobilePopupModal } = props; + switch (currentlyActiveMobileModal) { + case "SearchFormComponent": + return ( + + +
+

{t("PRIVACY_AUDIT_REPORT")}:

+
+ + {/* + +

{t(`ES_COMMON_CLEAR_ALL`)}

+
*/} +
+ ); + default: + return ; + } + }; + const CurrentMobileModalComponent = useCallback( + ({ currentlyActiveMobileModal, searchFormFieldsComponentProps, tenantId, ...props }) => + MobileComponentDirectory({ currentlyActiveMobileModal, searchFormFieldsComponentProps, tenantId, ...props }), + [currentlyActiveMobileModal] + ); + let roles = []; + data?.roles?.forEach((item) => { + roles.push(item?.name); + }); + const propsMobileInboxCards = useMemo(() => { + if (data?.display) { + return []; + } + if (data === "") { + return []; + } + return data?.map((data) => ({ + [t("AUDIT_DATE_LABEL")]: convertEpochToDate(data.timestamp), + [t("AUDIT_TIME_LABEL")]: convertEpochToTimeInHours(data.timestamp), + [t("AUDIT_DATAVIEWED_LABEL")]: data.dataView[0] + "," + data.dataView[1], + [t("AUDIT_DATAVIEWED_BY_LABEL")]: data.dataViewedBy, + [t("AUDIT_ROLE_LABEL")]: data.roles + .slice(0, 3) + ?.map((e) => e.name) + .join(","), + })); + }, [data]); + + return ( + + +
+ handleExcelDownload(tabledata)} /> +
+
{t("PRIVACY_AUDIT_REPORT")}:
+
+ setActiveMobileModal({ type: "set", payload: "SearchFormComponent" })} + {...{ tenantId, t }} + /> +
+ {currentlyActiveMobileModal ? ( + + { + setActiveMobileModal({ type: "remove" }); + onSubmit(data); + }} + handleSubmit={handleSubmit} + id="search-form" + className="rm-mb form-field-flex-one inboxPopupMobileWrapper" + {...{ searchFormFieldsComponentProps, currentlyActiveMobileModal, closeMobilePopupModal, tenantId }} + /> + + ) : null} + {isLoading && } + +
+ ); +}; + +export default MobileSearchApplication; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/SearchFields.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/SearchFields.js new file mode 100644 index 000000000..c3a37bd29 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/SearchFields.js @@ -0,0 +1,29 @@ +import { + DatePicker, SearchField, SubmitBar +} from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { Controller } from "react-hook-form"; +const SearchFields = ({ register, control, reset, tenantId, t, previousPage, formState, isLoading }) => { + const isMobile = window.Digit.Utils.browser.isMobile(); + + return ( + <> + + + } name="fromDate" control={control} /> + + + + } name="toDate" control={control} /> + + + + + + ); +}; +export default SearchFields; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/index.js new file mode 100644 index 000000000..2882a3aaf --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/Search/index.js @@ -0,0 +1,208 @@ +import { BackButton, DownloadBtnCommon, Header, Loader, SearchForm, Table } from "@egovernments/digit-ui-react-components"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { Controller, useForm } from "react-hook-form"; +import MobileSearchApplication from "./MobileSearchApplication"; +import SearchFields from "./SearchFields"; + +const SearchApplication = ({ tenantId, t, onSubmit, data, count }) => { + const initialValues = Digit.SessionStorage.get("AUDIT_APPLICATION_DETAIL") || { + offset: 0, + limit: 5, + sortOrder: "DESC", + }; + const { register, control, handleSubmit, setValue, getValues, reset } = useForm({ + defaultValues: initialValues, + }); + const convertEpochToDate = (dateEpoch) => { + if (dateEpoch == null || dateEpoch == undefined || dateEpoch == "") { + return "NA"; + } + const dateFromApi = new Date(dateEpoch); + let month = dateFromApi.getMonth() + 1; + let day = dateFromApi.getDate(); + let year = dateFromApi.getFullYear(); + month = (month > 9 ? "" : "0") + month; + day = (day > 9 ? "" : "0") + day; + return `${day}/${month}/${year}`; + }; + const convertEpochToTimeInHours = (dateEpoch) => { + if (dateEpoch == null || dateEpoch == undefined || dateEpoch == "") { + return "NA"; + } + const dateFromApi = new Date(dateEpoch); + let hour = dateFromApi.getHours(); + let min = dateFromApi.getMinutes(); + let period = hour > 12 ? "PM" : "AM"; + hour = hour > 12 ? hour - 12 : hour; + hour = (hour > 9 ? "" : "0") + hour; + min = (min > 9 ? "" : "0") + min; + return `${hour}:${min} ${period}`; + }; + const [tabledata, settabledata] = useState([]); + const DownloadBtn = (props) => { + return ( +
+ +
+ ); + }; + const handleExcelDownload = (tabData) => { + if (tabData?.[0] !== undefined) { + return Digit.Download.Excel(tabData?.[0], "AuditReport"); + } + }; + useEffect(() => { + register("offset", 0); + register("limit", 5); + register("sortOrder", "DESC"); + }, [register]); + useEffect(() => { + if (data?.length > 0) { + settabledata([ + data?.map((obj) => { + let returnObject = {}; + returnObject[t("AUDIT_DATE_LABEL")] = convertEpochToDate(obj?.timestamp); + returnObject[t("AUDIT_TIME_LABEL")] = convertEpochToTimeInHours(obj?.timestamp); + returnObject[t("AUDIT_DATAVIEWED_LABEL")] = obj?.dataView[0] + "," + obj?.dataView[1]; + returnObject[t("AUDIT_DATAVIEWED_BY_LABEL")] = obj?.dataViewedBy; + returnObject[t("AUDIT_ROLE_LABEL")] = obj?.roles.map((obj) => obj.name).join(","); + return { + ...returnObject, + }; + }), + ]); + } + }, [data]); + const onSort = useCallback((args) => { + if (args.length === 0) return; + setValue("sortBy", args.id); + setValue("sortOrder", args.desc ? "DESC" : "ASC"); + }, []); + + function onPageSizeChange(e) { + setValue("limit", Number(e.target.value)); + handleSubmit(onSubmit)(); + } + + function nextPage() { + setValue("offset", getValues("offset") + getValues("limit")); + handleSubmit(onSubmit)(); + } + function previousPage() { + setValue("offset", getValues("offset") - getValues("limit")); + handleSubmit(onSubmit)(); + } + const isMobile = window.Digit.Utils.browser.isMobile(); + + if (isMobile) { + return ; + } + + //need to get from workflow + const GetCell = (value) => {value}; + const columns = useMemo( + () => [ + { + Header: t("AUDIT_DATE_LABEL"), + disableSortBy: true, + accessor: (row) => { + const timestamp = row.timestamp === "NA" ? t("WS_NA") : convertEpochToDate(row.timestamp); + return GetCell(`${timestamp}`); + }, + }, + { + Header: t("AUDIT_TIME_LABEL"), + disableSortBy: true, + accessor: (row) => { + const timestamp = row.timestamp === "NA" ? t("WS_NA") : convertEpochToTimeInHours(row.timestamp); + return GetCell(`${timestamp}`); + }, + }, + { + Header: isMobile ? t("AUDIT_DATAVIEWED_LABEL") : t("AUDIT_DATAVIEWED_PRIVACY"), + disableSortBy: true, + accessor: (row) => { + return GetCell(`${row?.dataView}`); + }, + }, + { + Header: isMobile ? t("AUDIT_DATAVIEWED_BY_LABEL") : t("AUDIT_DATAVIEWED_BY_PRIVACY"), + disableSortBy: true, + accessor: (row) => { + return GetCell(`${row?.dataViewedBy}`); + }, + }, + { + Header: t("AUDIT_ROLE_LABEL"), + disableSortBy: true, + accessor: (row) => { + return GetCell(`${row?.roles.slice(0, 3)?.map((e) => e.name)}`); + }, + }, + ], + [] + ); + + return ( + +
+ {" "} + {" "} +
+
+ {" "} +
{t("PRIVACY_AUDIT_REPORT")}
{" "} +
+ + + +
+ {data?.display ? ( +
+ {t(data.display) + .split("\\n") + .map((text, index) => ( +

+ {text} +

+ ))} +
+ ) : data !== "" ? ( +
+
+ handleExcelDownload(tabledata)} /> +
+ { + return { + style: { + minWidth: cellInfo.column.Header === t("ES_INBOX_APPLICATION_NO") ? "240px" : "", + padding: "20px 18px", + fontSize: "16px", + }, + }; + }} + onPageSizeChange={onPageSizeChange} + currentPage={getValues("offset") / getValues("limit")} + onNextPage={nextPage} + onPrevPage={previousPage} + manualPagination={false} + pageSizeLimit={getValues("limit")} + onSort={onSort} + disableSort={false} + sortParams={[{ id: getValues("sortBy"), desc: getValues("sortOrder") === "DESC" ? true : false }]} + /> + + ) : ( + + )} + + + ); +}; + +export default SearchApplication; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/CitizenSideBar.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/CitizenSideBar.js new file mode 100644 index 000000000..b82356e05 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/CitizenSideBar.js @@ -0,0 +1,249 @@ +import { + Loader, NavBar +} from "@egovernments/digit-ui-react-components"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import SideBarMenu from "../../../config/sidebar-menu"; +import ChangeCity from "../../ChangeCity"; +import { defaultImage } from "../../utils"; +import StaticCitizenSideBar from "./StaticCitizenSideBar"; + + +const Profile = ({ info, stateName, t }) => { + const [profilePic, setProfilePic] = React.useState(null); + React.useEffect(async () => { + const tenant = Digit.ULBService.getCurrentTenantId(); + const uuid = info?.uuid; + if (uuid) { + const usersResponse = await Digit.UserService.userSearch(tenant, { uuid: [uuid] }, {}); + + if (usersResponse && usersResponse.user && usersResponse.user.length) { + const userDetails = usersResponse.user[0]; + const thumbs = userDetails?.photo?.split(","); + setProfilePic(thumbs?.at(0)); + } + } + }, [profilePic !== null]); + return ( +
+
+ +
+
+
{info?.name}
+
+
+
{info?.mobileNumber}
+
+ {info?.emailId && ( +
+
{info.emailId}
+
+ )} +
+ {window.location.href.includes("/employee") && + !window.location.href.includes("/employee/user/login") && + !window.location.href.includes("employee/user/language-selection") && } +
+ ); +}; +const PoweredBy = () => ( +
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + />{" "} +
+); + +/* +Feature :: Citizen Webview sidebar +*/ +export const CitizenSideBar = ({ isOpen, isMobile = false, toggleSidebar, onLogout, isEmployee = false, linkData, islinkDataLoading }) => { + const { data: storeData, isFetched } = Digit.Hooks.useStore.getInitData(); + const { stateInfo } = storeData || {}; + const user = Digit.UserService.getUser(); + const [search, setSearch] = useState(""); + + const { t } = useTranslation(); + const history = useHistory(); + const closeSidebar = () => { + Digit.clikOusideFired = true; + toggleSidebar(false); + }; + + const { isLoading, data } = Digit.Hooks.useAccessControl(); + const tenantId = Digit.ULBService.getCurrentTenantId(); + const showProfilePage = () => { + const redirectUrl = isEmployee ? `/${window?.contextPath}/employee/user/profile` : `/${window?.contextPath}/citizen/user/profile`; + history.push(redirectUrl); + closeSidebar(); + }; + const redirectToLoginPage = () => { + // localStorage.clear(); + // sessionStorage.clear(); + history.push(`/${window?.contextPath}/citizen/login`); + closeSidebar(); + }; + if (islinkDataLoading || isLoading) { + return ; + } + + let menuItems = [...SideBarMenu(t, closeSidebar, redirectToLoginPage, isEmployee)]; + let profileItem; + if (isFetched && user && user.access_token) { + profileItem = ; + menuItems = menuItems.filter((item) => item?.id !== "login-btn"); + menuItems = [ + ...menuItems, + { + text: t("EDIT_PROFILE"), + element: "PROFILE", + icon: "EditPencilIcon", + populators: { + onClick: showProfilePage, + }, + }, + { + text: t("CORE_COMMON_LOGOUT"), + element: "LOGOUT", + icon: "LogoutIcon", + populators: { + onClick: onLogout, + }, + }, + { + text: ( + + {t("CS_COMMON_HELPLINE")} +
+ {storeData?.tenants.map((i) => { + i.code === tenantId ? ( + + ) : ( + + ); + })} + +
+
+ ), + element: "Helpline", + icon: "Phone", + }, + ]; + } + + let configEmployeeSideBar = {}; + + if (!isEmployee) { + Object.keys(linkData) + ?.sort((x, y) => y.localeCompare(x)) + ?.map((key) => { + if (linkData[key][0]?.sidebar === "digit-ui-links") + menuItems.splice(1, 0, { + type: linkData[key][0]?.sidebarURL?.includes(window?.contextPath) ? "link" : "external-link", + text: t(`ACTION_TEST_${Digit.Utils.locale.getTransformedLocale(key)}`), + links: linkData[key], + icon: linkData[key][0]?.leftIcon, + link: linkData[key][0]?.sidebarURL, + }); + }); + } else { + data?.actions + .filter((e) => e.url === "url" && e.displayName !== "Home") + .forEach((item) => { + if (search == "" && item.path !== "") { + let index = item.path.split(".")[0]; + if (index === "TradeLicense") index = "Trade License"; + if (!configEmployeeSideBar[index]) { + configEmployeeSideBar[index] = [item]; + } else { + configEmployeeSideBar[index].push(item); + } + } else if (item.path !== "" && item?.displayName?.toLowerCase().includes(search.toLowerCase())) { + let index = item.path.split(".")[0]; + if (index === "TradeLicense") index = "Trade License"; + if (!configEmployeeSideBar[index]) { + configEmployeeSideBar[index] = [item]; + } else { + configEmployeeSideBar[index].push(item); + } + } + }); + const keys = Object.keys(configEmployeeSideBar); + for (let i = 0; i < keys.length; i++) { + const getSingleDisplayName = configEmployeeSideBar[keys[i]][0]?.displayName?.toUpperCase()?.replace(/[ -]/g, "_"); + const getParentDisplayName = keys[i]?.toUpperCase()?.replace(/[ -]/g, "_"); + + if (configEmployeeSideBar[keys[i]][0].path.indexOf(".") === -1) { + menuItems.splice(1, 0, { + type: "link", + text: t(`ACTION_TEST_${getSingleDisplayName}`), + link: configEmployeeSideBar[keys[i]][0]?.navigationURL, + icon: configEmployeeSideBar[keys[i]][0]?.leftIcon?.split?.(":")[1], + populators: { + onClick: () => { + history.push(configEmployeeSideBar[keys[i]][0]?.navigationURL); + closeSidebar(); + }, + }, + }); + } else { + menuItems.splice(1, 0, { + type: "dynamic", + moduleName: t(`ACTION_TEST_${getParentDisplayName}`), + links: configEmployeeSideBar[keys[i]]?.map((ob) => {return {...ob, displayName: t(`ACTION_TEST_${ob?.displayName?.toUpperCase()?.replace(/[ -]/g, "_")}`)}}), + icon: configEmployeeSideBar[keys[i]][1]?.leftIcon, + }); + } + } + const indx = menuItems.findIndex(a => a.element === "HOME"); + const home = menuItems.splice(indx,1); + const comp = menuItems.findIndex(a => a.element === "LANGUAGE"); + const part = menuItems.splice(comp,menuItems?.length-comp); + menuItems.sort((a,b) => { + let c1 = a?.type === "dynamic" ? a?.moduleName : a?.text; + let c2 = b?.type === "dynamic" ? b?.moduleName : b?.text; + return c1.localeCompare(c2) + } ); + home?.[0] && menuItems.splice(0,0,home[0]); + menuItems = part?.length > 0 ? menuItems.concat(part) : menuItems; + } + + /* URL with openlink wont have sidebar and actions */ + if (history.location.pathname.includes("/openlink")) { + profileItem = ; + menuItems = menuItems.filter((ele) => ele.element === "LANGUAGE"); + } + return isMobile ? ( + } + isEmployee={isEmployee} + search={search} + setSearch={setSearch} + /> + ) : ( + + ); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/EmployeeSideBar.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/EmployeeSideBar.js new file mode 100644 index 000000000..619832fa4 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/EmployeeSideBar.js @@ -0,0 +1,144 @@ +import React, { useRef, useEffect, useState } from "react"; +import SubMenu from "./SubMenu"; +import { Loader, SearchIcon } from "@egovernments/digit-ui-react-components"; +import { useTranslation } from "react-i18next"; + +const checkMatch=(path="",searchCriteria="")=>(path.toLowerCase().includes(searchCriteria.toLowerCase())) + + + +const EmployeeSideBar = () => { + const sidebarRef = useRef(null); + const { isLoading, data } = Digit.Hooks.useAccessControl(); + const [search, setSearch] = useState(""); + const { t } = useTranslation(); + useEffect(() => { + if (isLoading) { + return ; + } + sidebarRef.current.style.cursor = "pointer"; + collapseNav(); + }, [isLoading]); + + const expandNav = () => { + sidebarRef.current.style.width = "260px"; + sidebarRef.current.style.overflow = "auto"; + + sidebarRef.current.querySelectorAll(".dropdown-link").forEach((element) => { + element.style.display = "flex"; + }); + }; + const collapseNav = () => { + sidebarRef.current.style.width = "55px"; + sidebarRef.current.style.overflow = "hidden"; + + sidebarRef.current.querySelectorAll(".dropdown-link").forEach((element) => { + element.style.display = "none"; + }); + sidebarRef.current.querySelectorAll(".actions").forEach((element) => { + element.style.padding = "0"; + }); + }; + const configEmployeeSideBar = {}; + data?.actions + .filter((e) => e.url === "url") + .forEach((item) => { + let index = item?.path?.split(".")?.[0] || ""; + if (search == "" && item.path !== "") { + index = item.path.split(".")[0]; + if (!configEmployeeSideBar[index]) { + configEmployeeSideBar[index] = [item]; + } else { + configEmployeeSideBar[index].push(item); + } + } else if ( + checkMatch(t(`ACTION_TEST_${index?.toUpperCase()?.replace(/[ -]/g, "_")}`),search) || checkMatch(t(Digit.Utils.locale.getTransformedLocale(`ACTION_TEST_${item?.displayName}`)),search) + ) { + index = item.path.split(".")[0]; + if (!configEmployeeSideBar[index]) { + configEmployeeSideBar[index] = [item]; + } else { + configEmployeeSideBar[index].push(item); + } + } + }); + let res = []; + const splitKeyValue = () => { + const keys = Object.keys(configEmployeeSideBar); + keys.sort((a, b) => a.orderNumber - b.orderNumber); + for (let i = 0; i < keys.length; i++) { + if (configEmployeeSideBar[keys[i]][0].path.indexOf(".") === -1) { + if (configEmployeeSideBar[keys[i]][0].displayName === "Home") { + const homeURL = `/${window?.contextPath}/employee`; + res.unshift({ + moduleName: keys[i].toUpperCase(), + icon: configEmployeeSideBar[keys[i]][0], + navigationURL: homeURL, + type: "single", + }); + } else { + res.push({ + moduleName: configEmployeeSideBar[keys[i]][0]?.displayName.toUpperCase(), + type: "single", + icon: configEmployeeSideBar[keys[i]][0], + navigationURL: configEmployeeSideBar[keys[i]][0].navigationURL, + }); + } + } else { + res.push({ + moduleName: keys[i].toUpperCase(), + links: configEmployeeSideBar[keys[i]], + icon: configEmployeeSideBar[keys[i]][0], + orderNumber: configEmployeeSideBar[keys[i]][0].orderNumber, + }); + } + } + if (res.find((a) => a.moduleName === "HOME")) { + const home = res?.filter((ob) => ob?.moduleName === "HOME"); + let res1 = res?.filter((ob) => ob?.moduleName !== "HOME"); + res = res1.sort((a, b) => a.moduleName.localeCompare(b.moduleName)); + home?.[0] && res.unshift(home[0]); + } else { + res.sort((a, b) => a.moduleName.localeCompare(b.moduleName)); + } + return res?.map((item, index) => { + return ; + }); + }; + + if (isLoading) { + return ; + } + if (!res) { + return ""; + } + + const renderSearch = () => { + return ( +
+
+
+ + setSearch(e.target.value)} + /> +
+
+
+ ); + }; + + return ( +
+ {renderSearch()} + {splitKeyValue()} +
+ ); +}; + +export default EmployeeSideBar; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/StaticCitizenSideBar.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/StaticCitizenSideBar.js new file mode 100644 index 000000000..3fcbfc232 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/StaticCitizenSideBar.js @@ -0,0 +1,247 @@ +import React, { useEffect, useState } from "react"; +import { + HomeIcon, + EditPencilIcon, + LogoutIcon, + Loader, + AddressBookIcon, + PropertyHouse, + CaseIcon, + CollectionIcon, + PTIcon, + OBPSIcon, + PGRIcon, + FSMIcon, + WSICon, + MCollectIcon, + Phone, + BirthIcon, + DeathIcon, + FirenocIcon, +} from "@egovernments/digit-ui-react-components"; +import { Link, useLocation } from "react-router-dom"; +import SideBarMenu from "../../../config/sidebar-menu"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import LogoutDialog from "../../Dialog/LogoutDialog"; +import ChangeCity from "../../ChangeCity"; +import { defaultImage } from "../../utils"; + + +/* +Feature :: Citizen Webview sidebar +*/ +const Profile = ({ info, stateName, t }) => ( +
+
+ +
+
+
{info?.name}
+
+
+
{info?.mobileNumber}
+
+ {info?.emailId && ( +
+
{info.emailId}
+
+ )} +
+ {window.location.href.includes("/employee") && + !window.location.href.includes("/employee/user/login") && + !window.location.href.includes("employee/user/language-selection") && } +
+); +const IconsObject = { + CommonPTIcon: , + OBPSIcon: , + propertyIcon: , + TLIcon: , + PGRIcon: , + FSMIcon: , + WSIcon: , + MCollectIcon: , + BillsIcon: , + BirthIcon: , + DeathIcon: , + FirenocIcon: , + HomeIcon: , + EditPencilIcon: , + LogoutIcon: , + Phone: , +}; +const StaticCitizenSideBar = ({ linkData, islinkDataLoading }) => { + const { t } = useTranslation(); + const history = useHistory(); + const location = useLocation(); + const { pathname } = location; + const { data: storeData, isFetched } = Digit.Hooks.useStore.getInitData(); + const { stateInfo } = storeData || {}; + const user = Digit.UserService.getUser(); + let isMobile = window.Digit.Utils.browser.isMobile(); + + const [isEmployee, setisEmployee] = useState(false); + const [isSidebarOpen, toggleSidebar] = useState(false); + const [showDialog, setShowDialog] = useState(false); + + const handleLogout = () => { + toggleSidebar(false); + setShowDialog(true); + }; + const handleOnSubmit = () => { + Digit.UserService.logout(); + setShowDialog(false); + }; + const handleOnCancel = () => { + setShowDialog(false); + }; + + if (islinkDataLoading) { + return ; + } + + const redirectToLoginPage = () => { + // localStorage.clear(); + // sessionStorage.clear(); + history.push(`/${window?.contextPath}/citizen/login`); + }; + const showProfilePage = () => { + history.push(`/${window?.contextPath}/citizen/user/profile`); + }; + + let menuItems = [...SideBarMenu(t, showProfilePage, redirectToLoginPage, isEmployee)]; + + menuItems = menuItems.filter((item) => item.element !== "LANGUAGE"); + + const tenantId = Digit.ULBService.getCurrentTenantId(); + const MenuItem = ({ item }) => { + const leftIconArray = item?.icon || item.icon?.type?.name; + const leftIcon = leftIconArray ? IconsObject[leftIconArray] : IconsObject.BillsIcon; + let itemComponent; + if (item.type === "component") { + itemComponent = item.action; + } else { + itemComponent = item.text; + } + const Item = () => ( + + {leftIcon} +
{itemComponent}
+
+ ); + if (item.type === "external-link") { + return ( + + + + ); + } + if (item.type === "link") { + return ( + + + + ); + } + + return ; + }; + let profileItem; + + if (isFetched && user && user.access_token) { + profileItem = ; + menuItems = menuItems.filter((item) => item?.id !== "login-btn"); + menuItems = [ + ...menuItems, + { + text: t("EDIT_PROFILE"), + element: "PROFILE", + icon: "EditPencilIcon", + populators: { + onClick: showProfilePage, + }, + }, + { + text: t("CORE_COMMON_LOGOUT"), + element: "LOGOUT", + icon: "LogoutIcon", + populators: { onClick: handleLogout }, + }, + { + text: ( + + {t("CS_COMMON_HELPLINE")} +
+ {storeData?.tenants.map((i) => { + i.code === tenantId ? ( + + ) : ( + + ); + })} + +
+
+ ), + element: "Helpline", + icon: "Phone", + }, + ]; + } + Object.keys(linkData) + ?.sort((x, y) => y.localeCompare(x)) + ?.map((key) => { + if (linkData[key][0]?.sidebar === `${window.contextPath}-links`) { + menuItems.splice(1, 0, { + type: linkData[key][0]?.sidebarURL?.includes(window?.contextPath) ? "link" : "external-link", + text: t(`ACTION_TEST_${Digit.Utils.locale.getTransformedLocale(key)}`), + links: linkData[key], + icon: linkData[key][0]?.leftIcon, + link: linkData[key][0]?.sidebarURL, + }); + } + }); + + return ( + +
+
+
+ {profileItem} +
+ {menuItems?.map((item, index) => ( +
+ +
+ ))} +
+
+
{showDialog && }
+
+
+ ); +}; + +export default StaticCitizenSideBar; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/SubMenu.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/SubMenu.js new file mode 100644 index 000000000..6ab5cb7e6 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/SubMenu.js @@ -0,0 +1,193 @@ +import React, { useState, useContext } from "react"; +import { useHistory, useLocation, Link } from "react-router-dom"; +import { + ArrowForward, + ArrowVectorDown, + ArrowDirection, + HomeIcon, + ComplaintIcon, + BPAHomeIcon, + PropertyHouse, + CaseIcon, + ReceiptIcon, + PersonIcon, + DocumentIconSolid, + DropIcon, + CollectionsBookmarIcons, + FinanceChartIcon, + CollectionIcon, +} from "@egovernments/digit-ui-react-components"; +import { useTranslation } from "react-i18next"; +import ReactTooltip from "react-tooltip"; + +const SubMenu = ({ item }) => { + const [subnav, setSubnav] = useState(false); + const location = useLocation(); + const { pathname } = location; + const { t } = useTranslation(); + const history = useHistory(); + + const showSubnav = () => setSubnav(!subnav); + const IconsObject = { + home: , + announcement: , + business: , + store: , + assignment: , + receipt: , + "business-center": , + description: , + "water-tap": , + "collections-bookmark": , + "insert-chart": , + edcr: , + collections: , + }; + const leftIconArray = item?.icon?.leftIcon?.split?.(":")?.[1] || item?.leftIcon?.split?.(":")[1]; + let leftIcon = IconsObject[leftIconArray] || IconsObject.collections; + const iconArr = item?.icon?.leftIcon?.split?.(":") || item?.leftIcon?.split?.(":"); + if (iconArr?.[0] == "dynamic") { + var IconComp = require("@egovernments/digit-ui-react-components")?.[iconArr?.[1]]; + leftIcon = IconComp ? : leftIcon; + } + const getModuleName = item?.moduleName?.replace(/[ -]/g, "_"); + const appendTranslate = t(`ACTION_TEST_${getModuleName}`); + const trimModuleName = t(appendTranslate?.length > 20 ? appendTranslate.substring(0, 20) + "..." : appendTranslate); + + if (item.type === "single") { + const getOrigin = window.location.origin; + return ( +
+
+
+ history.push(`${ item.navigationURL}`)}>{leftIcon} + {item.navigationURL?.indexOf(`/${window?.contextPath}`) === -1 ? ( + + {trimModuleName} + + {trimModuleName?.includes("...") && ( + + {t(`ACTION_TEST_${getModuleName}`)} + + )} + + ) : ( + // + //
+ //

{trimModuleName}

+ // {t(`ACTION_TEST_${getModuleName}`)} + //
+ //
+ +
+ {trimModuleName} + + {trimModuleName?.includes("...") && ( + + {t(`ACTION_TEST_${getModuleName}`)} + + )} +
+ {/*
+

{trimModuleName}

+ {t(`ACTION_TEST_${getModuleName}`)} +
{" "} */} + + )} +
+
+
+ ); + } else { + return ( + +
+
ele?.url === "url" && pathname?.includes(ele?.navigationURL)) ? "active" : ""}`} + > +
+ {leftIcon} +
+ {trimModuleName} + {trimModuleName?.includes("...") && ( + + {t(`ACTION_TEST_${getModuleName}`)} + + )} +
+ {/*
+

{trimModuleName}

+ {t(`ACTION_TEST_${getModuleName}`)} +
{" "} */} +
+
{item.links && subnav ? : item.links ? : null}
+
+
+ + {subnav && + item.links + .sort((a, b) => a.orderNumber - b.orderNumber) + .filter((item) => item.url === "url" || item.url !== "") + .map((item, index) => { + const getChildName = item?.displayName?.toUpperCase()?.replace(/[ -]/g, "_"); + const appendTranslate = t(`ACTION_TEST_${getChildName}`); + const trimModuleName = t(appendTranslate?.length > 20 ? appendTranslate.substring(0, 20) + "..." : appendTranslate); + + if (item.navigationURL.indexOf(`/${window?.contextPath}`) === -1) { + const getOrigin = window.location.origin; + return ( + +
+ {trimModuleName} + {trimModuleName?.includes("...") && ( + + {t(`ACTION_TEST_${getChildName}`)} + + )} +
+ {/*
+
+

{trimModuleName}

+ {t(`ACTION_TEST_${getChildName}`)} +
{" "} +
*/} +
+ ); + } + return ( + +
+ {trimModuleName} + {trimModuleName?.includes("...") && ( + + {t(`ACTION_TEST_${getChildName}`)} + + )} + {/*
+

{trimModuleName}

+ {t(`ACTION_TEST_${getChildName}`)} +
{" "} */} +
+ + ); + })} +
+ ); + } +}; + +export default SubMenu; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/index.js new file mode 100644 index 000000000..c47afa498 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/SideBar/index.js @@ -0,0 +1,23 @@ +import React from "react"; +import { CitizenSideBar } from "./CitizenSideBar"; +import EmployeeSideBar from "./EmployeeSideBar"; + +const SideBar = ({ t, CITIZEN, isSidebarOpen, toggleSidebar, handleLogout, mobileView, userDetails, modules, linkData, islinkDataLoading }) => { + if (CITIZEN) + return ( + + ); + else { + if (!mobileView && userDetails?.access_token) return ; + else return ; + } +}; + +export default SideBar; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/TopBar.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/TopBar.js new file mode 100644 index 000000000..43adc8100 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/TopBar.js @@ -0,0 +1,156 @@ +import { Dropdown, Hamburger, TopBar as TopBarComponent } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useHistory, useLocation } from "react-router-dom"; +import ChangeCity from "../ChangeCity"; +import ChangeLanguage from "../ChangeLanguage"; + +const TextToImg = (props) => ( + + {props?.name?.[0]?.toUpperCase()} + +); +const TopBar = ({ + t, + stateInfo, + toggleSidebar, + isSidebarOpen, + handleLogout, + userDetails, + CITIZEN, + cityDetails, + mobileView, + userOptions, + handleUserDropdownSelection, + logoUrl, + showLanguageChange = true, +}) => { + const [profilePic, setProfilePic] = React.useState(null); + React.useEffect(async () => { + const tenant = Digit.ULBService.getCurrentTenantId(); + const uuid = userDetails?.info?.uuid; + if (uuid) { + const usersResponse = await Digit.UserService.userSearch(tenant, { uuid: [uuid] }, {}); + if (usersResponse && usersResponse.user && usersResponse.user.length) { + const userDetails = usersResponse.user[0]; + const thumbs = userDetails?.photo?.split(","); + setProfilePic(thumbs?.at(0)); + } + } + }, [profilePic !== null, userDetails?.info?.uuid]); + + const CitizenHomePageTenantId = Digit.ULBService.getCitizenCurrentTenant(true); + + let history = useHistory(); + const { pathname } = useLocation(); + + const conditionsToDisableNotificationCountTrigger = () => { + if (Digit.UserService?.getUser()?.info?.type === "EMPLOYEE") return false; + if (Digit.UserService?.getUser()?.info?.type === "CITIZEN") { + if (!CitizenHomePageTenantId) return false; + else return true; + } + return false; + }; + + const { data: { unreadCount: unreadNotificationCount } = {}, isSuccess: notificationCountLoaded } = Digit.Hooks.useNotificationCount({ + tenantId: CitizenHomePageTenantId, + config: { + enabled: conditionsToDisableNotificationCountTrigger(), + }, + }); + + const updateSidebar = () => { + if (!Digit.clikOusideFired) { + toggleSidebar(true); + } else { + Digit.clikOusideFired = false; + } + }; + + function onNotificationIconClick() { + history.push(`/${window?.contextPath}/citizen/engagement/notifications`); + } + + const urlsToDisableNotificationIcon = (pathname) => + !!Digit.UserService?.getUser()?.access_token + ? false + : [`/${window?.contextPath}/citizen/select-language`, `/${window?.contextPath}/citizen/select-location`].includes(pathname); + + if (CITIZEN) { + return ( +
+ : null} + /> +
+ ); + } + const loggedin = userDetails?.access_token ? true : false; + return ( +
+ {mobileView ? : null} + + + {loggedin && + (cityDetails?.city?.ulbGrade ? ( +

+ {t(cityDetails?.i18nKey).toUpperCase()}{" "} + {t(`ULBGRADE_${cityDetails?.city?.ulbGrade.toUpperCase().replace(" ", "_").replace(".", "_")}`).toUpperCase()} +

+ ) : ( + + ))} + {!loggedin && ( +

+ {t(`MYCITY_${stateInfo?.code?.toUpperCase()}_LABEL`)} {t(`MYCITY_STATECODE_LABEL`)} +

+ )} + {!mobileView && ( +
+
+ {!window.location.href.includes("employee/user/login") && !window.location.href.includes("employee/user/language-selection") && ( + + )} +
+
{showLanguageChange && }
+ {userDetails?.access_token && ( +
+ + ) : ( + + ) + } + /> +
+ )} + +
+ )} +
+
+ ); +}; + +export default TopBar; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/index.js new file mode 100644 index 000000000..dec6eb104 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/TopBarSideBar/index.js @@ -0,0 +1,76 @@ +import React, { useState } from "react"; +import { EditPencilIcon, LogoutIcon } from "@egovernments/digit-ui-react-components"; +import TopBar from "./TopBar"; +import { useHistory } from "react-router-dom"; +import SideBar from "./SideBar"; +import LogoutDialog from "../Dialog/LogoutDialog"; +const TopBarSideBar = ({ + t, + stateInfo, + userDetails, + CITIZEN, + cityDetails, + mobileView, + handleUserDropdownSelection, + logoUrl, + showSidebar = true, + showLanguageChange, + linkData, + islinkDataLoading, +}) => { + const [isSidebarOpen, toggleSidebar] = useState(false); + const history = useHistory(); + const [showDialog, setShowDialog] = useState(false); + const handleLogout = () => { + toggleSidebar(false); + setShowDialog(true); + }; + const handleOnSubmit = () => { + Digit.UserService.logout(); + setShowDialog(false); + }; + const handleOnCancel = () => { + setShowDialog(false); + }; + const userProfile = () => { + history.push(`/${window?.contextPath}/employee/user/profile`); + }; + const userOptions = [ + { name: t("EDIT_PROFILE"), icon: , func: userProfile }, + { name: t("CORE_COMMON_LOGOUT"), icon: , func: handleLogout }, + ]; + return ( + + + {showDialog && } + {/* {showSidebar && ( + + )} */} + + ); +}; +export default TopBarSideBar; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/utils.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/utils.js new file mode 100644 index 000000000..44dfca5e7 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/components/utils.js @@ -0,0 +1,22 @@ +export const defaultImage = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAO4AAADUCAMAAACs0e/bAAAAM1BMVEXK0eL" + + "/" + + "/" + + "/" + + "/Dy97GzuD4+fvL0uPg5O7T2efb4OvR1+Xr7vTk5/Df4+37/P3v8fbO1eTt8PUsnq5FAAAGqElEQVR4nO2d25ajIBBFCajgvf/" + + "/a0eMyZgEjcI5xgt7Hmatme507UaxuJXidiDqjmSgeVIMlB1ZR1WZAf2gbdu0QwixSYzjOJPmHurfEGEfY9XzjNGG9whQCeVAuv5xQEySLtR9hPuIcwj0EeroN5m3D1IbsbgHK0esiQ9MKs" + + "qXVr8Hm/a/Pulk6wihpCIXBw3dh7bTvRBt9+dC5NfS1VH3xETdM3MxXRN1T0zUPTNR98xcS1dlV9NNfx3DhkTdM6PKqHteVBF1z0vU5f0sKdpc2zWLKutXrjJjdLvpesRmukqYonauPhXpds" + + "Lb6CppmpnltsYIuY2yavi6Mi2/rzAWm1zUfF0limVLqkZyA+mDYevKBS37aGC+L1lX5e7uyU1Cv565uiua9k5LFqbqqrnu2I3m+jJ11ZoLeRtfmdB0Uw/ZDsP0VTxdn7a1VERfmq7Xl" + + "Xyn5D2QWLoq8bZlPoBJumphJjVBw/Ll6CoTZGsTDs4NrGqKbqBth8ZHJUi6cn168QmleSm6GmB7Kxm+6obXlf7PoDHosCwM3QpiS2legi6ocSl3L0G3BdneDDgwQdENfeY+SfDJBkF37Z" + + "B+GvwzA6/rMaafAn8143VhPZWdjMWG1oHXhdnemgPoAvLlB/iZyRTfVeF06wPoQhJmlm4bdcOAZRlRN5gcPc5SoPEQR1fDdbOo6wn+uYvXxY0QCLom6gYROKH+Aj5nvphuFXWDiLpRdxl" + + "/19LFT95k6CHCrnW7pCDqBn1i1PUFvii2c11oZOJ6usWeH0RRNzC4Zs+6FTi2nevCVwCjbugnXklX5fkfTldL8PEilUB1kfNyN1u9MME2sATr4lbuB7AjfLAuvsRm1A0g6gYRdcPAjvBlje" + + "2Z8brI8OC68AcRdlCkwLohx2mcZMjw9q+LzarQurjtnwPYAydX08WecECO/u6Ad0GBdYG7jO5gB4Ap+PwKcA9ZT43dn4/W9TyiPAn4OAJaF7h3uwe8StSCddFdM3jqFa2LvnnB5zzhuuBBAj" + + "Y4gi50cg694gnXhTYvfMdrjtcFZhrwE9r41gUem8IXWMC3LrBzxh+a0gRd1N1LOK7M0IUUGuggvEmHoStA2/MJh7MpupiDU4TzjhxdzLAoO4ouZvqVURbFMHQlZD6SUeWHoguZsSLUGegreh" + + "A+FZFowPdUWTi6iMoZlIpGGUUXkDbjj/9ZOLqAQS/+GIKl5BQOCn/ycqpzkXSDm5dU7ZWkG7wUyGlcmm7g5Ux56AqirgoaJ7BeokPTDbp9CbVunjFxPrl7+HqnkrSq1Da7JX20f3dV8yJi6v" + + "oO81mX8vV0mx3qUsZCPRfTlVRdz2EvdufYGDvNQvvwqHtmXd+a1ITinwNcXc+lT6JuzdT1XDyBn/x7wtX1HCQQdW9MXc8xArGrirowfLeUEbMqqq6f7TF1lfRdOuGNiGi6SpT+WxY06xUfNN" + + "2wBfyE9I4tlm7w5hvOPDNJN3yNiLMipji6gE3chKhouoCtN5x3QlF0EZt8OW/8ougitqJQlk1aii7iFC9l0MvRReyao7xNjKML2Z/PuHlzhi5mFxljiZeiC9rPTEisNEMX9KYAwo5Xhi7qaA" + + "3hamboYm7dG+NVrXhdaYDv5zFaQZsYrCtbbAGnjkQDX2+J1FXCwOsqWOpKoIQNTFdqYBWydxqNqUoG0pVpCS+H8kaJaGKErlIaXj7CRRE+gRWuKwW9YZ80oVOUgbpdT0zpnSZJTIiwCtJVelv" + + "Xntr4P5j6BWfPb5Wcx84C4cq3hb11lco2u2Mdwp6XdJ/Ne3wb8DWdfiRenZaXrhLwOj4e+GQeHroy3YOspS7TlU28Wle2m2QUS0mqdcbrdNW+ZHsSsyK7tBfm0q/dWcv+Z3mytVx3t7KWulq" + + "Ue6ilunu8jF8pFwgv1FXp3mUt35OtRbr7eM4u4Gs6vUBXgeuHc5kfE/cbvWZtkROLm1DMtLCy80tzsu2PRj0hTI8fvrQuvsjlJkyutszq+m423wHaLTyniy/XuiGZ84LuT+m5ZfNfRxyGs7L" + + "XZOvia7VujatUwVTrIt+Q/Csc7Tuhe+BOakT10b4TuoiiJjvgU9emTO42PwEfBa+cuodKkuf42DXr1D3JpXz73Hnn0j10evHKe+nufgfUm+7B84sX9FfdEzXux2DBpWuKokkCqN/5pa/8pmvn" + + "L+RGKCddCGmatiPyPB/+ekO/M/q/7uvbt22kTt3zEnXPzCV13T3Gel4/6NduDu66xRvlPNkM1RjjxUdv+4WhGx6TftD19Q/dfzpwcHO+rE3fAAAAAElFTkSuQmCC"; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/config/sidebar-menu.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/config/sidebar-menu.js new file mode 100644 index 000000000..01d786ad7 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/config/sidebar-menu.js @@ -0,0 +1,33 @@ +import React from "react"; +import { HomeIcon, LanguageIcon, LogoutIcon, AddressBookIcon, LocationIcon } from "@egovernments/digit-ui-react-components"; +import ChangeLanguage from "../components/ChangeLanguage"; + +const SideBarMenu = (t, closeSidebar, redirectToLoginPage, isEmployee) => [ + { + type: "link", + element: "HOME", + text: t("COMMON_BOTTOM_NAVIGATION_HOME"), + link: isEmployee ? `/${window?.contextPath}/employee` : `/${window?.contextPath}/citizen`, + icon: "HomeIcon", + populators: { + onClick: closeSidebar, + }, + }, + { + type: "component", + element: "LANGUAGE", + action: , + icon: "LanguageIcon", + }, + { + id: "login-btn", + element: "LOGIN", + text: t("CORE_COMMON_LOGIN"), + icon: , + populators: { + onClick: redirectToLoginPage, + }, + }, +]; + +export default SideBarMenu; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/context/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/context/index.js new file mode 100644 index 000000000..71c86df0f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/context/index.js @@ -0,0 +1,3 @@ +import React from "react"; + +export const ComponentProvider = React.createContext(); diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/hooks/useInterval.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/hooks/useInterval.js new file mode 100644 index 000000000..7161e6d42 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/hooks/useInterval.js @@ -0,0 +1,20 @@ +import React, { useEffect, useRef } from "react"; + +function useInterval(callback, delay) { + const savedCallback = useRef(); + useEffect(() => { + savedCallback.current = callback; + }, [callback]); + + useEffect(() => { + function tick() { + savedCallback.current(); + } + if (delay !== null) { + const timer = setInterval(tick, delay); + return () => clearInterval(timer); + } + }, [delay]); +} + +export default useInterval; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Allservices/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Allservices/index.js new file mode 100644 index 000000000..02c4dec13 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Allservices/index.js @@ -0,0 +1,25 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { AppModules } from "../../../components/AppModules"; + +const CitizenApp = ({ + stateInfo, + userDetails, + CITIZEN, + cityDetails, + mobileView, + handleUserDropdownSelection, + logoUrl, + DSO, + stateCode, + modules, + appTenants, + sourceUrl, + pathname, +}) => { + const { t } = useTranslation(); + + return ; +}; + +export default CitizenApp; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/FAQs/FAQs.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/FAQs/FAQs.js new file mode 100644 index 000000000..199cd50ca --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/FAQs/FAQs.js @@ -0,0 +1,39 @@ +import { BackButton, Header, Loader, SearchIconSvg } from "@egovernments/digit-ui-react-components"; +import React, { Fragment } from "react"; +import { useTranslation } from "react-i18next"; +import FaqComponent from "./FaqComponent"; + +const FAQsSection = ({ module }) => { + const user = Digit.UserService.getUser(); + const tenantId = user?.info?.tenantId || Digit.ULBService.getCurrentTenantId(); + const { t } = useTranslation(); + + const SearchImg = () => { + return ; + }; + + const { isLoading, data } = Digit.Hooks.useGetFAQsJSON(Digit.ULBService.getStateId()); + + const moduleFaqs = data?.MdmsRes["common-masters"]?.faqs[0]?.[`${module}`].faqs; + + if (isLoading) { + return ; + } + return ( + +
+ +
+
{t("FAQ_S")}
+
+
+ {moduleFaqs.map((faq, i) => ( + + ))} +
+
+
+ ); +}; + +export default FAQsSection; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/FAQs/FaqComponent.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/FAQs/FaqComponent.js new file mode 100644 index 000000000..0bfe07829 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/FAQs/FaqComponent.js @@ -0,0 +1,27 @@ +import { ArrowForward } from "@egovernments/digit-ui-react-components"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; + +const FaqComponent = (props) => { + const { question, answer, lastIndex } = props; + const [isOpen, toggleOpen] = useState(false); + const { t } = useTranslation(); + + return ( +
toggleOpen(!isOpen)}> +
+ {t(question)} + + {isOpen ? : } + +
+ +
+ {t(answer)} +
+ {!lastIndex ?
: null} +
+ ); +}; + +export default FaqComponent; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/ImageUpload/UploadDrawer.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/ImageUpload/UploadDrawer.js new file mode 100644 index 000000000..3da67339c --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/ImageUpload/UploadDrawer.js @@ -0,0 +1,97 @@ +import React, { useState, useEffect } from "react"; +import { GalleryIcon, RemoveIcon, UploadFile } from "@egovernments/digit-ui-react-components"; +import { useTranslation } from "react-i18next"; + +function UploadDrawer({ setProfilePic, closeDrawer, userType, removeProfilePic ,showToast, closeFileUploadDrawer}) { + const [uploadedFile, setUploadedFile] = useState(null); + const [file, setFile] = useState(""); + const [error, setError] = useState(null); + const { t } = useTranslation(); + const selectfile = (e) => setFile(e.target.files[0]); + const removeimg = () => {removeProfilePic(); closeDrawer()}; + const onOverlayBodyClick = () => closeDrawer(); + + useEffect(() => { + (async () => { + setError(null); + if (file) { + if (file.size >= 1000000) { + showToast("error", t("CORE_COMMON_PROFILE_MAXIMUM_UPLOAD_SIZE_EXCEEDED")) + setError(t("CORE_COMMON_PROFILE_MAXIMUM_UPLOAD_SIZE_EXCEEDED")); + closeFileUploadDrawer(); + } else { + try { + const response = await Digit.UploadServices.Filestorage(`${userType}-profile`, file, Digit.ULBService.getStateId()); + if (response?.data?.files?.length > 0) { + const fileStoreId = response?.data?.files[0]?.fileStoreId; + setUploadedFile(fileStoreId); + setProfilePic(fileStoreId); + } else { + showToast("error", t("CORE_COMMON_PROFILE_FILE_UPLOAD_ERROR")) + setError(t("CORE_COMMON_PROFILE_FILE_UPLOAD_ERROR")); + } + } catch (err) { + showToast("error",t("CORE_COMMON_PROFILE_INVALID_FILE_INPUT")) + // setError(t("PT_FILE_UPLOAD_ERROR")); + } + } + } + })(); + }, [file]); + + return ( + +
+
+
+ + + +
+ +
+ + +
+
+
+ ); +} + +export default UploadDrawer; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/LanguageSelection.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/LanguageSelection.js new file mode 100644 index 000000000..1e840a4ca --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/LanguageSelection.js @@ -0,0 +1,48 @@ +import React, { useMemo } from "react"; +import { PageBasedInput, Loader, RadioButtons, CardHeader } from "@egovernments/digit-ui-react-components"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; + +const LanguageSelection = () => { + const { t } = useTranslation(); + const history = useHistory(); + + const { data: { languages, stateInfo } = {}, isLoading } = Digit.Hooks.useStore.getInitData(); + const selectedLanguage = Digit.StoreData.getCurrentLanguage(); + + const texts = useMemo( + () => ({ + header: t("CS_COMMON_CHOOSE_LANGUAGE"), + submitBarLabel: t("CORE_COMMON_CONTINUE"), + }), + [t] + ); + + const RadioButtonProps = useMemo( + () => ({ + options: languages, + optionsKey: "label", + additionalWrapperClass: "reverse-radio-selection-wrapper", + onSelect: (language) => Digit.LocalizationService.changeLanguage(language.value, stateInfo.code), + selectedOption: languages?.filter((i) => i.value === selectedLanguage)[0], + }), + [selectedLanguage, languages] + ); + + function onSubmit() { + history.push(`/${window?.contextPath}/citizen/select-location`); + } + + return isLoading ? ( + + ) : ( +
+ + {t("CS_COMMON_CHOOSE_LANGUAGE")} + + +
+ ); +}; + +export default LanguageSelection; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/LocationSelection.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/LocationSelection.js new file mode 100644 index 000000000..97b1764e7 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/LocationSelection.js @@ -0,0 +1,64 @@ +import { BackButton, CardHeader, CardLabelError, PageBasedInput, SearchOnRadioButtons } from "@egovernments/digit-ui-react-components"; +import React, { useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory, useLocation } from "react-router-dom"; + +const LocationSelection = () => { + const { t } = useTranslation(); + const history = useHistory(); + const location = useLocation(); + const { data: cities, isLoading } = Digit.Hooks.useTenants(); + + const [selectedCity, setSelectedCity] = useState(() => ({ code: Digit.ULBService.getCitizenCurrentTenant(true) })); + const [showError, setShowError] = useState(false); + + const texts = useMemo( + () => ({ + header: t("CS_COMMON_CHOOSE_LOCATION"), + submitBarLabel: t("CORE_COMMON_CONTINUE"), + }), + [t] + ); + + function selectCity(city) { + setSelectedCity(city); + setShowError(false); + } + + const RadioButtonProps = useMemo(() => { + return { + options: cities, + optionsKey: "i18nKey", + additionalWrapperClass: "reverse-radio-selection-wrapper", + onSelect: selectCity, + selectedOption: selectedCity, + }; + }, [cities, t, selectedCity]); + + function onSubmit() { + if (selectedCity) { + Digit.SessionStorage.set("CITIZEN.COMMON.HOME.CITY", selectedCity); + const redirectBackTo = location.state?.redirectBackTo; + if (redirectBackTo) { + history.replace(redirectBackTo); + } else history.push(`/${window?.contextPath}/citizen`); + } else { + setShowError(true); + } + } + + return isLoading ? ( + + ) : ( +
+ + + {t("CS_COMMON_CHOOSE_LOCATION")} + + {showError ? {t("CS_COMMON_LOCATION_SELECTION_ERROR")} : null} + +
+ ); +}; + +export default LocationSelection; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/UserProfile.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/UserProfile.js new file mode 100644 index 000000000..6203cabdc --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/UserProfile.js @@ -0,0 +1,710 @@ +import { + CameraIcon, + CardLabel, + Dropdown, + LabelFieldPair, + MobileNumber, + TextInput, + Toast, + CardLabelError, + BreadCrumb, + BackButton, + Loader, + SubmitBar, +} from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import UploadDrawer from "./ImageUpload/UploadDrawer"; + +const defaultImage = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAO4AAADUCAMAAACs0e/bAAAAM1BMVEXK0eL" + + "/" + + "/" + + "/" + + "/Dy97GzuD4+fvL0uPg5O7T2efb4OvR1+Xr7vTk5/Df4+37/P3v8fbO1eTt8PUsnq5FAAAGqElEQVR4nO2d25ajIBBFCajgvf/" + + "/a0eMyZgEjcI5xgt7Hmatme507UaxuJXidiDqjmSgeVIMlB1ZR1WZAf2gbdu0QwixSYzjOJPmHurfEGEfY9XzjNGG9whQCeVAuv5xQEySLtR9hPuIcwj0EeroN5m3D1IbsbgHK0esiQ9MKs" + + "qXVr8Hm/a/Pulk6wihpCIXBw3dh7bTvRBt9+dC5NfS1VH3xETdM3MxXRN1T0zUPTNR98xcS1dlV9NNfx3DhkTdM6PKqHteVBF1z0vU5f0sKdpc2zWLKutXrjJjdLvpesRmukqYonauPhXpds" + + "Lb6CppmpnltsYIuY2yavi6Mi2/rzAWm1zUfF0limVLqkZyA+mDYevKBS37aGC+L1lX5e7uyU1Cv565uiua9k5LFqbqqrnu2I3m+jJ11ZoLeRtfmdB0Uw/ZDsP0VTxdn7a1VERfmq7Xl" + + "Xyn5D2QWLoq8bZlPoBJumphJjVBw/Ll6CoTZGsTDs4NrGqKbqBth8ZHJUi6cn168QmleSm6GmB7Kxm+6obXlf7PoDHosCwM3QpiS2legi6ocSl3L0G3BdneDDgwQdENfeY+SfDJBkF37Z" + + "B+GvwzA6/rMaafAn8143VhPZWdjMWG1oHXhdnemgPoAvLlB/iZyRTfVeF06wPoQhJmlm4bdcOAZRlRN5gcPc5SoPEQR1fDdbOo6wn+uYvXxY0QCLom6gYROKH+Aj5nvphuFXWDiLpRdxl" + + "/19LFT95k6CHCrnW7pCDqBn1i1PUFvii2c11oZOJ6usWeH0RRNzC4Zs+6FTi2nevCVwCjbugnXklX5fkfTldL8PEilUB1kfNyN1u9MME2sATr4lbuB7AjfLAuvsRm1A0g6gYRdcPAjvBlje" + + "2Z8brI8OC68AcRdlCkwLohx2mcZMjw9q+LzarQurjtnwPYAydX08WecECO/u6Ad0GBdYG7jO5gB4Ap+PwKcA9ZT43dn4/W9TyiPAn4OAJaF7h3uwe8StSCddFdM3jqFa2LvnnB5zzhuuBBAj" + + "Y4gi50cg694gnXhTYvfMdrjtcFZhrwE9r41gUem8IXWMC3LrBzxh+a0gRd1N1LOK7M0IUUGuggvEmHoStA2/MJh7MpupiDU4TzjhxdzLAoO4ouZvqVURbFMHQlZD6SUeWHoguZsSLUGegreh" + + "A+FZFowPdUWTi6iMoZlIpGGUUXkDbjj/9ZOLqAQS/+GIKl5BQOCn/ycqpzkXSDm5dU7ZWkG7wUyGlcmm7g5Ux56AqirgoaJ7BeokPTDbp9CbVunjFxPrl7+HqnkrSq1Da7JX20f3dV8yJi6v" + + "oO81mX8vV0mx3qUsZCPRfTlVRdz2EvdufYGDvNQvvwqHtmXd+a1ITinwNcXc+lT6JuzdT1XDyBn/x7wtX1HCQQdW9MXc8xArGrirowfLeUEbMqqq6f7TF1lfRdOuGNiGi6SpT+WxY06xUfNN" + + "2wBfyE9I4tlm7w5hvOPDNJN3yNiLMipji6gE3chKhouoCtN5x3QlF0EZt8OW/8ougitqJQlk1aii7iFC9l0MvRReyao7xNjKML2Z/PuHlzhi5mFxljiZeiC9rPTEisNEMX9KYAwo5Xhi7qaA" + + "3hamboYm7dG+NVrXhdaYDv5zFaQZsYrCtbbAGnjkQDX2+J1FXCwOsqWOpKoIQNTFdqYBWydxqNqUoG0pVpCS+H8kaJaGKErlIaXj7CRRE+gRWuKwW9YZ80oVOUgbpdT0zpnSZJTIiwCtJVelv" + + "Xntr4P5j6BWfPb5Wcx84C4cq3hb11lco2u2Mdwp6XdJ/Ne3wb8DWdfiRenZaXrhLwOj4e+GQeHroy3YOspS7TlU28Wle2m2QUS0mqdcbrdNW+ZHsSsyK7tBfm0q/dWcv+Z3mytVx3t7KWulq" + + "Ue6ilunu8jF8pFwgv1FXp3mUt35OtRbr7eM4u4Gs6vUBXgeuHc5kfE/cbvWZtkROLm1DMtLCy80tzsu2PRj0hTI8fvrQuvsjlJkyutszq+m423wHaLTyniy/XuiGZ84LuT+m5ZfNfRxyGs7L" + + "XZOvia7VujatUwVTrIt+Q/Csc7Tuhe+BOakT10b4TuoiiJjvgU9emTO42PwEfBa+cuodKkuf42DXr1D3JpXz73Hnn0j10evHKe+nufgfUm+7B84sX9FfdEzXux2DBpWuKokkCqN/5pa/8pmvn" + + "L+RGKCddCGmatiPyPB/+ekO/M/q/7uvbt22kTt3zEnXPzCV13T3Gel4/6NduDu66xRvlPNkM1RjjxUdv+4WhGx6TftD19Q/dfzpwcHO+rE3fAAAAAElFTkSuQmCC"; + +const UserProfile = ({ stateCode, userType, cityDetails }) => { + const history = useHistory(); + const { t } = useTranslation(); + const url = window.location.href; + const stateId = Digit.ULBService.getStateId(); + const tenant = Digit.ULBService.getCurrentTenantId(); + const userInfo = Digit.UserService.getUser()?.info || {}; + const [userDetails, setUserDetails] = useState(null); + const [name, setName] = useState(userInfo?.name ? userInfo.name : ""); + const [email, setEmail] = useState(userInfo?.emailId ? userInfo.emailId : ""); + const [gender, setGender] = useState(userDetails?.gender); + const [city, setCity] = useState(userInfo?.permanentCity ? userInfo.permanentCity : cityDetails?.name); + const [mobileNumber, setMobileNo] = useState(userInfo?.mobileNumber ? userInfo.mobileNumber : ""); + const [profilePic, setProfilePic] = useState(null); + const [profileImg, setProfileImg] = useState(""); + const [openUploadSlide, setOpenUploadSide] = useState(false); + const [changepassword, setChangepassword] = useState(false); + const [currentPassword, setCurrentPassword] = useState(""); + const [newPassword, setNewPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [toast, setToast] = useState(null); + const [loading, setLoading] = useState(false); + const [windowWidth, setWindowWidth] = React.useState(window.innerWidth); + const [errors, setErrors] = React.useState({}); + const isMobile = window.Digit.Utils.browser.isMobile(); + + const getUserInfo = async () => { + const uuid = userInfo?.uuid; + if (uuid) { + const usersResponse = await Digit.UserService.userSearch(window.localStorage.getItem("tenant-id"), { uuid: [uuid] }, {}); + usersResponse && usersResponse.user && usersResponse.user.length && setUserDetails(usersResponse.user[0]); + } + }; + + React.useEffect(() => { + window.addEventListener("resize", () => setWindowWidth(window.innerWidth)); + return () => { + window.removeEventListener("resize", () => setWindowWidth(window.innerWidth)); + }; + }); + + useEffect(() => { + setLoading(true); + + getUserInfo(); + + setGender({ + i18nKey: undefined, + code: userDetails?.gender, + value: userDetails?.gender, + }); + + const thumbs = userDetails?.photo?.split(","); + setProfileImg(thumbs?.at(0)); + + setLoading(false); + }, [userDetails !== null]); + + let validation = {}; + const editScreen = false; // To-do: Deubug and make me dynamic or remove if not needed + const onClickAddPic = () => setOpenUploadSide(!openUploadSlide); + const TogleforPassword = () => setChangepassword(!changepassword); + const setGenderName = (value) => setGender(value); + const closeFileUploadDrawer = () => setOpenUploadSide(false); + + const setUserName = (value) => { + setName(value); + + if (!new RegExp(/^[a-zA-Z ]+$/i).test(value) || value.length === 0 || value.length > 50) { + setErrors({ ...errors, userName: { type: "pattern", message: "CORE_COMMON_PROFILE_NAME_INVALID" } }); + } else { + setErrors({ ...errors, userName: null }); + } + }; + + const setUserEmailAddress = (value) => { + if (userInfo?.userName !== value) { + setEmail(value); + + if (value.length && !(value.includes("@") && value.includes("."))) { + setErrors({ + ...errors, + emailAddress: { type: "pattern", message: "CORE_COMMON_PROFILE_EMAIL_INVALID" }, + }); + } else { + setErrors({ ...errors, emailAddress: null }); + } + } else { + setErrors({ ...errors, emailAddress: null }); + } + }; + + const setUserMobileNumber = (value) => { + setMobileNo(value); + + if (userType === "employee" && !new RegExp(/^[6-9]{1}[0-9]{9}$/).test(value)) { + setErrors({ ...errors, mobileNumber: { type: "pattern", message: "CORE_COMMON_PROFILE_MOBILE_NUMBER_INVALID" } }); + } else { + setErrors({ ...errors, mobileNumber: null }); + } + }; + + const setUserCurrentPassword = (value) => { + setCurrentPassword(value); + + if (!new RegExp(/^([a-zA-Z0-9@#$%]{8,15})$/i).test(value)) { + setErrors({ ...errors, currentPassword: { type: "pattern", message: "CORE_COMMON_PROFILE_PASSWORD_INVALID" } }); + } else { + setErrors({ ...errors, currentPassword: null }); + } + }; + + const setUserNewPassword = (value) => { + setNewPassword(value); + + if (!new RegExp(/^([a-zA-Z0-9@#$%]{8,15})$/i).test(value)) { + setErrors({ ...errors, newPassword: { type: "pattern", message: "CORE_COMMON_PROFILE_PASSWORD_INVALID" } }); + } else { + setErrors({ ...errors, newPassword: null }); + } + }; + + const setUserConfirmPassword = (value) => { + setConfirmPassword(value); + + if (!new RegExp(/^([a-zA-Z0-9@#$%]{8,15})$/i).test(value)) { + setErrors({ ...errors, confirmPassword: { type: "pattern", message: "CORE_COMMON_PROFILE_PASSWORD_INVALID" } }); + } else { + setErrors({ ...errors, confirmPassword: null }); + } + }; + + const removeProfilePic = () => { + setProfilePic(null); + setProfileImg(null); + }; + + const showToast = (type, message, duration = 5000) => { + setToast({ key: type, action: message }); + setTimeout(() => { + setToast(null); + }, duration); + }; + + const updateProfile = async () => { + setLoading(true); + try { + const requestData = { + ...userInfo, + name, + gender: gender?.value, + emailId: email, + photo: profilePic, + }; + + if (!new RegExp(/^([a-zA-Z ])*$/).test(name) || name === "" || name.length > 50 || name.length < 1) { + throw JSON.stringify({ type: "error", message: t("CORE_COMMON_PROFILE_NAME_INVALID") }); + } + + if (userType === "employee" && !new RegExp(/^[6-9]{1}[0-9]{9}$/).test(mobileNumber)) { + throw JSON.stringify({ type: "error", message: t("CORE_COMMON_PROFILE_MOBILE_NUMBER_INVALID") }); + } + + if (email.length && !(email.includes("@") && email.includes("."))) { + throw JSON.stringify({ type: "error", message: t("CORE_COMMON_PROFILE_EMAIL_INVALID") }); + } + + if (changepassword && (currentPassword.length || newPassword.length || confirmPassword.length)) { + if (newPassword !== confirmPassword) { + throw JSON.stringify({ type: "error", message: t("CORE_COMMON_PROFILE_PASSWORD_MISMATCH") }); + } + + if (!(currentPassword.length && newPassword.length && confirmPassword.length)) { + throw JSON.stringify({ type: "error", message: t("CORE_COMMON_PROFILE_PASSWORD_INVALID") }); + } + + if (!new RegExp(/^([a-zA-Z0-9@#$%]{8,15})$/i).test(newPassword) && !new RegExp(/^([a-zA-Z0-9@#$%]{8,15})$/i).test(confirmPassword)) { + throw JSON.stringify({ type: "error", message: t("CORE_COMMON_PROFILE_PASSWORD_INVALID") }); + } + } + + const { responseInfo, user } = await Digit.UserService.updateUser(requestData, stateCode); + + if (responseInfo && responseInfo.status === "200") { + const user = Digit.UserService.getUser(); + + if (user) { + Digit.UserService.setUser({ + ...user, + info: { + ...user.info, + name, + mobileNumber, + emailId: email, + permanentCity: city, + }, + }); + } + } + + if (currentPassword.length && newPassword.length && confirmPassword.length) { + const requestData = { + existingPassword: currentPassword, + newPassword: newPassword, + tenantId: tenant, + type: "EMPLOYEE", + username: userInfo?.userName, + confirmPassword: confirmPassword, + }; + + if (newPassword === confirmPassword) { + try { + const res = await Digit.UserService.changePassword(requestData, tenant); + + const { responseInfo: changePasswordResponseInfo } = res; + if (changePasswordResponseInfo?.status && changePasswordResponseInfo.status === "200") { + showToast("success", t("CORE_COMMON_PROFILE_UPDATE_SUCCESS_WITH_PASSWORD"), 5000); + setTimeout(() => Digit.UserService.logout(), 2000); + } else { + throw ""; + } + } catch (error) { + throw JSON.stringify({ + type: "error", + message: error.Errors?.at(0)?.description ? error.Errors.at(0).description : "CORE_COMMON_PROFILE_UPDATE_ERROR_WITH_PASSWORD", + }); + } + } else { + throw JSON.stringify({ type: "error", message: "CORE_COMMON_PROFILE_ERROR_PASSWORD_NOT_MATCH" }); + } + } else if (responseInfo?.status && responseInfo.status === "200") { + showToast("success", t("CORE_COMMON_PROFILE_UPDATE_SUCCESS"), 5000); + } + } catch (error) { + if(error?.response?.data?.Errors[0].message){ + showToast("error", error?.response?.data?.Errors[0].message); + + }else{ + const errorObj = JSON.parse(error); + showToast(errorObj.type, t(errorObj.message), 5000); + } + } + + setLoading(false); + }; + + let menu = []; + const { data: Menu } = Digit.Hooks.useGenderMDMS(stateId, "common-masters", "GenderType"); + Menu && + Menu.map((genderDetails) => { + menu.push({ i18nKey: `PT_COMMON_GENDER_${genderDetails.code}`, code: `${genderDetails.code}`, value: `${genderDetails.code}` }); + }); + + const setFileStoreId = async (fileStoreId) => { + setProfilePic(fileStoreId); + + const thumbnails = fileStoreId ? await getThumbnails([fileStoreId], stateId) : null; + + setProfileImg(thumbnails?.thumbs[0]); + + closeFileUploadDrawer(); + }; + + const getThumbnails = async (ids, tenantId) => { + const res = await Digit.UploadServices.Filefetch(ids, tenantId); + if (res.data.fileStoreIds && res.data.fileStoreIds.length !== 0) { + return { + thumbs: res.data.fileStoreIds.map((o) => o.url.split(",")[3]), + images: res.data.fileStoreIds.map((o) => Digit.Utils.getFileUrl(o.url)), + }; + } else { + return null; + } + }; + + if (loading) return ; + + return ( +
+
+ {userType === "citizen" ? ( + + ) : ( + + )} +
+
+
+
+ + +
+
+
+ {userType === "citizen" ? ( + + + {`${t("CORE_COMMON_PROFILE_NAME")}`}* +
+ setUserName(e.target.value)} + {...(validation = { + isRequired: true, + pattern: "^[a-zA-Z-.`' ]*$", + type: "tel", + title: t("CORE_COMMON_PROFILE_NAME_ERROR_MESSAGE"), + })} + disable={editScreen} + /> + {errors?.userName && {t(errors?.userName?.message)} } +
+
+ + + {`${t("CORE_COMMON_PROFILE_GENDER")}`} + + + + + {`${t("CORE_COMMON_PROFILE_EMAIL")}`} +
+ setUserEmailAddress(e.target.value)} + disable={editScreen} + /> + {errors?.emailAddress && {t(errors?.emailAddress?.message)} } +
+
+ + +
+ ) : ( + + + + {`${t("CORE_COMMON_PROFILE_NAME")}`}* + +
+ setUserName(e.target.value)} + placeholder="Enter Your Name" + {...(validation = { + isRequired: true, + pattern: "^[a-zA-Z-.`' ]*$", + type: "text", + title: t("CORE_COMMON_PROFILE_NAME_ERROR_MESSAGE"), + })} + disable={editScreen} + /> + {errors?.userName && {t(errors?.userName?.message)} } +
+
+ + + {`${t( + "CORE_COMMON_PROFILE_GENDER" + )}`} + + + + + {`${t( + "CORE_COMMON_PROFILE_CITY" + )}`} +
+ setCity(e.target.value)} + placeholder="Enter Your City Name" + {...(validation = { + isRequired: true, + // pattern: "^[a-zA-Z-.`' ]*$", + type: "text", + title: t("CORE_COMMON_PROFILE_CITY_ERROR_MESSAGE"), + })} + disable={true} + /> + +
+
+ + + {`${t("CORE_COMMON_PROFILE_MOBILE_NUMBER")}*`} +
+ setUserMobileNumber(value)} + disable={true} + {...{ required: true, pattern: "[6-9]{1}[0-9]{9}", type: "tel", title: t("CORE_COMMON_PROFILE_MOBILE_NUMBER_INVALID") }} + /> + {errors?.mobileNumber && {t(errors?.mobileNumber?.message)} } +
+
+ + + {`${t( + "CORE_COMMON_PROFILE_EMAIL" + )}`} +
+ setUserEmailAddress(e.target.value)} + disable={editScreen} + /> + {errors?.emailAddress && {t(errors?.emailAddress?.message)} } +
+
+ + +
+ + {t("CORE_COMMON_CHANGE_PASSWORD")} + + {changepassword ? ( +
+ + {`${t("CORE_COMMON_PROFILE_CURRENT_PASSWORD")}`} +
+ setUserCurrentPassword(e.target.value)} + disable={editScreen} + /> + {errors?.currentPassword && {t(errors?.currentPassword?.message)}} +
+
+ + + {`${t("CORE_COMMON_PROFILE_NEW_PASSWORD")}`} +
+ setUserNewPassword(e.target.value)} + disable={editScreen} + /> + {errors?.newPassword && {t(errors?.newPassword?.message)}} +
+
+ + + {`${t("CORE_COMMON_PROFILE_CONFIRM_PASSWORD")}`} +
+ setUserConfirmPassword(e.target.value)} + disable={editScreen} + /> + {errors?.confirmPassword && {t(errors?.confirmPassword?.message)}} +
+
+
+ ) : ( + "" + )} +
+
+
+ )} +
+
+ + {userType === "employee" ? ( +
+ + {/* */} +
+ ) : ( + "" + )} + {toast && ( + setToast(null)} + style={{ maxWidth: "670px" }} + /> + )} + + {openUploadSlide == true ? ( + + ) : ( + "" + )} +
+ ); +}; + +export default UserProfile; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/index.js new file mode 100644 index 000000000..84e33e7ad --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Home/index.js @@ -0,0 +1,173 @@ +import { + Calender, CardBasedOptions, CaseIcon, ComplaintIcon, DocumentIcon, HomeIcon, Loader, OBPSIcon, PTIcon, WhatsNewCard +} from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; + +const Home = () => { + const { t } = useTranslation(); + const history = useHistory(); + const tenantId = Digit.ULBService.getCitizenCurrentTenant(true); + const { data: { stateInfo, uiHomePage } = {}, isLoading } = Digit.Hooks.useStore.getInitData(); + let isMobile = window.Digit.Utils.browser.isMobile(); + + const conditionsToDisableNotificationCountTrigger = () => { + if (Digit.UserService?.getUser()?.info?.type === "EMPLOYEE") return false; + if (!Digit.UserService?.getUser()?.access_token) return false; + return true; + }; + + const { data: EventsData, isLoading: EventsDataLoading } = Digit.Hooks.useEvents({ + tenantId, + variant: "whats-new", + config: { + enabled: conditionsToDisableNotificationCountTrigger(), + }, + }); + + if (!tenantId) { + history.push(`/${window?.contextPath}/citizen/select-language`); + } + + const appBannerWebObj = uiHomePage?.appBannerDesktop; + const appBannerMobObj = uiHomePage?.appBannerMobile; + const citizenServicesObj = uiHomePage?.citizenServicesCard; + const infoAndUpdatesObj = uiHomePage?.informationAndUpdatesCard; + const whatsAppBannerWebObj = uiHomePage?.whatsAppBannerDesktop; + const whatsAppBannerMobObj = uiHomePage?.whatsAppBannerMobile; + const whatsNewSectionObj = uiHomePage?.whatsNewSection; + const redirectURL = uiHomePage?.redirectURL; + /* configure redirect URL only if it is required to overide the default citizen home screen */ + if (redirectURL) { + history.push(`/${window?.contextPath}/citizen/${redirectURL}`); + } + /* fix for sanitation ui */ + if (window?.location?.href?.includes?.("sanitation-ui")) { + history.push(`/${window?.contextPath}/citizen/all-services`); + } + + const handleClickOnWhatsAppBanner = (obj) => { + window.open(obj?.navigationUrl); + }; + + const allCitizenServicesProps = { + header: t(citizenServicesObj?.headerLabel), + sideOption: { + name: t(citizenServicesObj?.sideOption?.name), + onClick: () => history.push(citizenServicesObj?.sideOption?.navigationUrl), + }, + options: [ + { + name: t(citizenServicesObj?.props?.[0]?.label), + Icon: , + onClick: () => history.push(citizenServicesObj?.props?.[0]?.navigationUrl), + }, + { + name: t(citizenServicesObj?.props?.[1]?.label), + Icon: , + onClick: () => history.push(citizenServicesObj?.props?.[1]?.navigationUrl), + }, + { + name: t(citizenServicesObj?.props?.[2]?.label), + Icon: , + onClick: () => history.push(citizenServicesObj?.props?.[2]?.navigationUrl), + }, + // { + // name: t("ACTION_TEST_WATER_AND_SEWERAGE"), + // Icon: , + // onClick: () => history.push(`/${window?.contextPath}/citizen`) + // }, + { + name: t(citizenServicesObj?.props?.[3]?.label), + Icon: , + onClick: () => history.push(citizenServicesObj?.props?.[3]?.navigationUrl), + }, + ], + styles: { display: "flex", flexWrap: "wrap", justifyContent: "flex-start", width: "100%" }, + }; + const allInfoAndUpdatesProps = { + header: t(infoAndUpdatesObj?.headerLabel), + sideOption: { + name: t(infoAndUpdatesObj?.sideOption?.name), + onClick: () => history.push(infoAndUpdatesObj?.sideOption?.navigationUrl), + }, + options: [ + { + name: t(infoAndUpdatesObj?.props?.[0]?.label), + Icon: , + onClick: () => history.push(infoAndUpdatesObj?.props?.[0]?.navigationUrl), + }, + { + name: t(infoAndUpdatesObj?.props?.[1]?.label), + Icon: , + onClick: () => history.push(infoAndUpdatesObj?.props?.[1]?.navigationUrl), + }, + { + name: t(infoAndUpdatesObj?.props?.[2]?.label), + Icon: , + onClick: () => history.push(infoAndUpdatesObj?.props?.[2]?.navigationUrl), + }, + { + name: t(infoAndUpdatesObj?.props?.[3]?.label), + Icon: , + onClick: () => history.push(infoAndUpdatesObj?.props?.[3]?.navigationUrl), + }, + // { + // name: t("CS_COMMON_HELP"), + // Icon: + // } + ], + styles: { display: "flex", flexWrap: "wrap", justifyContent: "flex-start", width: "100%" }, + }; + + return isLoading ? ( + + ) : ( +
+ {/*
+ +
*/} +
+ { +
+ {isMobile ? : } + {/*
+ +
*/} +
+ + +
+
+ } + + {(whatsAppBannerMobObj || whatsAppBannerWebObj) && ( +
+ {isMobile ? ( + handleClickOnWhatsAppBanner(whatsAppBannerMobObj)} /> + ) : ( + handleClickOnWhatsAppBanner(whatsAppBannerWebObj)} /> + )} +
+ )} + + {conditionsToDisableNotificationCountTrigger() ? ( + EventsDataLoading ? ( + + ) : ( +
+
+

{t(whatsNewSectionObj?.headerLabel)}

+

history.push(whatsNewSectionObj?.sideOption?.navigationUrl)}>{t(whatsNewSectionObj?.sideOption?.name)}

+
+ +
+ ) + ) : null} +
+
+ ); +}; + +export default Home; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/HowItWorks/howItWorks.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/HowItWorks/howItWorks.js new file mode 100644 index 000000000..ba60ddd40 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/HowItWorks/howItWorks.js @@ -0,0 +1,121 @@ +import { BackButton, CloseSvg, CustomButton, DownloadImgIcon, Header, Loader, PDFSvg } from "@egovernments/digit-ui-react-components"; +import React, { Fragment, useState } from "react"; +import { useTranslation } from "react-i18next"; + +const HowItWorks = ({ module }) => { + const user = Digit.UserService.getUser(); + const tenantId = user?.info?.tenantId || Digit.ULBService.getCurrentTenantId(); + const { t } = useTranslation(); + const storeData = Digit.SessionStorage.get("initData"); + const stateInfo = storeData.stateInfo; + const selectedLanguage = Digit.StoreData.getCurrentLanguage(); + const [selected, setselected] = useState(selectedLanguage); + const handleChangeLanguage = (language) => { + setselected(language?.value); + Digit.LocalizationService.changeLanguage(language?.value, stateInfo.code); + }; + const [videoPlay, setVideoPlay] = useState(false); + const [vidSrc, setVidSrc] = useState(""); + + const ViDSvg = () => ( + + + + ); + const onClickVideo = (vidObj) => { + if (selected === "hi_IN") { + setVidSrc(vidObj["hi_IN"]); + } else { + setVidSrc(vidObj["en_IN"]); + } + setVideoPlay(true); + }; + const onClose = () => { + setVideoPlay(false); + }; + + const { isLoading, data } = Digit.Hooks.useGetHowItWorksJSON(Digit.ULBService.getStateId()); + + const mdmsConfigResult = data?.MdmsRes["common-masters"]?.howItWorks[0]?.[`${module}`]; + const languages = [ + { + label: "ENGLISH", + value: "en_IN", + }, + { + label: "हिंदी", + value: "hi_IN", + }, + ]; + + if (isLoading) { + return ; + } + return ( + +
+ +
+
{t("HOW_IT_WORKS")}
+
+
+ {languages.map((language, index) => ( +
+ handleChangeLanguage(language)} + > +
+ ))} +
+ {mdmsConfigResult?.videosJson.map((videos, index) => ( +
+
+
onClickVideo(videos)}> +
+ +
+
+
+

{t(videos.headerLabel)}

+

{t(videos.description)}

+
+
+
+ ))} +
+
+
+
+ +
+
+

{t(mdmsConfigResult.pdfHeader)}

+

{t(mdmsConfigResult.pdfDesc)}

+
+
+
+ +
+
+
+ {videoPlay && ( +
+
+ +
+ +
+ )} +
+
+ ); +}; + +export default HowItWorks; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectMobileNumber.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectMobileNumber.js new file mode 100644 index 000000000..353f8336e --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectMobileNumber.js @@ -0,0 +1,18 @@ +import { FormStep } from "@egovernments/digit-ui-react-components"; +import React from "react"; + +const SelectMobileNumber = ({ t, onSelect, showRegisterLink, mobileNumber, onMobileChange, config, canSubmit }) => { + return ( + + ); +}; + +export default SelectMobileNumber; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectName.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectName.js new file mode 100644 index 000000000..489998a48 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectName.js @@ -0,0 +1,8 @@ +import { FormStep } from "@egovernments/digit-ui-react-components"; +import React from "react"; + +const SelectName = ({ config, onSelect, t, isDisabled }) => { + return ; +}; + +export default SelectName; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectOtp.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectOtp.js new file mode 100644 index 000000000..0162167a0 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/SelectOtp.js @@ -0,0 +1,51 @@ +import { CardLabelError, CardText, FormStep, OTPInput } from "@egovernments/digit-ui-react-components"; +import React, { Fragment, useState } from "react"; +import useInterval from "../../../hooks/useInterval"; + +const SelectOtp = ({ config, otp, onOtpChange, onResend, onSelect, t, error, userType = "citizen", canSubmit }) => { + const [timeLeft, setTimeLeft] = useState(30); + + useInterval( + () => { + setTimeLeft(timeLeft - 1); + }, + timeLeft > 0 ? 1000 : null + ); + + const handleResendOtp = () => { + onResend(); + setTimeLeft(2); + }; + + if (userType === "employee") { + return ( + + + {timeLeft > 0 ? ( + {`${t("CS_RESEND_ANOTHER_OTP")} ${timeLeft} ${t("CS_RESEND_SECONDS")}`} + ) : ( +

+ {t("CS_RESEND_OTP")} +

+ )} + {!error && {t("CS_INVALID_OTP")}} +
+ ); + } + + return ( + + + {timeLeft > 0 ? ( + {`${t("CS_RESEND_ANOTHER_OTP")} ${timeLeft} ${t("CS_RESEND_SECONDS")}`} + ) : ( +

+ {t("CS_RESEND_OTP")} +

+ )} + {!error && {t("CS_INVALID_OTP")}} +
+ ); +}; + +export default SelectOtp; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/config.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/config.js new file mode 100644 index 000000000..f43118eff --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/config.js @@ -0,0 +1,52 @@ +export const loginSteps = [ + { + texts: { + header: "CS_LOGIN_PROVIDE_MOBILE_NUMBER", + cardText: "CS_LOGIN_TEXT", + nextText: "CS_COMMONS_NEXT", + submitBarLabel: "CS_COMMONS_NEXT", + }, + inputs: [ + { + label: "CORE_COMMON_MOBILE_NUMBER", + type: "text", + name: "mobileNumber", + error: "ERR_HRMS_INVALID_MOB_NO", + validation: { + required: true, + minLength: 10, + maxLength: 10, + }, + }, + ], + }, + { + texts: { + header: "CS_LOGIN_OTP", + cardText: "CS_LOGIN_OTP_TEXT", + nextText: "CS_COMMONS_NEXT", + submitBarLabel: "CS_COMMONS_NEXT", + }, + }, + { + texts: { + header: "CS_LOGIN_PROVIDE_NAME", + cardText: "CS_LOGIN_NAME_TEXT", + nextText: "CS_COMMONS_NEXT", + submitBarLabel: "CS_COMMONS_NEXT", + }, + inputs: [ + { + label: "CORE_COMMON_NAME", + type: "text", + name: "name", + error: "CORE_COMMON_NAME_VALIDMSG", + validation: { + required: true, + minLength: 1, + pattern: /^[^{0-9}^\$\"<>?\\\\~!@#$%^()+={}\[\]*,/_:;“”‘’]{1,50}$/i, + }, + }, + ], + }, +]; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/index.js new file mode 100644 index 000000000..fc41c87b2 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/Login/index.js @@ -0,0 +1,270 @@ +import { AppContainer, BackButton, Toast } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Route, Switch, useHistory, useLocation, useRouteMatch } from "react-router-dom"; +import { loginSteps } from "./config"; +import SelectMobileNumber from "./SelectMobileNumber"; +import SelectName from "./SelectName"; +import SelectOtp from "./SelectOtp"; + +const TYPE_REGISTER = { type: "register" }; +const TYPE_LOGIN = { type: "login" }; +const DEFAULT_USER = "digit-user"; +const DEFAULT_REDIRECT_URL = `/${window?.contextPath}/citizen`; + +/* set citizen details to enable backward compatiable */ +const setCitizenDetail = (userObject, token, tenantId) => { + let locale = JSON.parse(sessionStorage.getItem("Digit.initData"))?.value?.selectedLanguage; + localStorage.setItem("Citizen.tenant-id", tenantId); + localStorage.setItem("tenant-id", tenantId); + localStorage.setItem("citizen.userRequestObject", JSON.stringify(userObject)); + localStorage.setItem("locale", locale); + localStorage.setItem("Citizen.locale", locale); + localStorage.setItem("token", token); + localStorage.setItem("Citizen.token", token); + localStorage.setItem("user-info", JSON.stringify(userObject)); + localStorage.setItem("Citizen.user-info", JSON.stringify(userObject)); +}; + +const getFromLocation = (state, searchParams) => { + return state?.from || searchParams?.from || DEFAULT_REDIRECT_URL; +}; + +const Login = ({ stateCode, isUserRegistered = true }) => { + const { t } = useTranslation(); + const location = useLocation(); + const { path, url } = useRouteMatch(); + const history = useHistory(); + const [user, setUser] = useState(null); + const [error, setError] = useState(null); + const [isOtpValid, setIsOtpValid] = useState(true); + const [tokens, setTokens] = useState(null); + const [params, setParmas] = useState(isUserRegistered ? {} : location?.state?.data); + const [errorTO, setErrorTO] = useState(null); + const searchParams = Digit.Hooks.useQueryParams(); + const [canSubmitName, setCanSubmitName] = useState(false); + const [canSubmitOtp, setCanSubmitOtp] = useState(true); + const [canSubmitNo, setCanSubmitNo] = useState(true); + + useEffect(() => { + let errorTimeout; + if (error) { + if (errorTO) { + clearTimeout(errorTO); + setErrorTO(null); + } + errorTimeout = setTimeout(() => { + setError(""); + }, 5000); + setErrorTO(errorTimeout); + } + return () => { + errorTimeout && clearTimeout(errorTimeout); + }; + }, [error]); + + useEffect(() => { + if (!user) { + return; + } + Digit.SessionStorage.set("citizen.userRequestObject", user); + Digit.UserService.setUser(user); + setCitizenDetail(user?.info, user?.access_token, stateCode); + const redirectPath = location.state?.from || DEFAULT_REDIRECT_URL; + if (!Digit.ULBService.getCitizenCurrentTenant(true)) { + history.replace(`/${window?.contextPath}/citizen/select-location`, { + redirectBackTo: redirectPath, + }); + } else { + history.replace(redirectPath); + } + }, [user]); + + const stepItems = useMemo(() => + loginSteps.map( + (step) => { + const texts = {}; + for (const key in step.texts) { + texts[key] = t(step.texts[key]); + } + return { ...step, texts }; + }, + [loginSteps] + ) + ); + + const getUserType = () => Digit.UserService.getType(); + + const handleOtpChange = (otp) => { + setParmas({ ...params, otp }); + }; + + const handleMobileChange = (event) => { + const { value } = event.target; + setParmas({ ...params, mobileNumber: value }); + }; + + const selectMobileNumber = async (mobileNumber) => { + setCanSubmitNo(false); + setParmas({ ...params, ...mobileNumber }); + const data = { + ...mobileNumber, + tenantId: stateCode, + userType: getUserType(), + }; + if (isUserRegistered) { + const [res, err] = await sendOtp({ otp: { ...data, ...TYPE_LOGIN } }); + if (!err) { + setCanSubmitNo(true); + history.replace(`${path}/otp`, { from: getFromLocation(location.state, searchParams), role: location.state?.role }); + return; + } else { + setCanSubmitNo(true); + if (!(location.state && location.state.role === "FSM_DSO")) { + history.push(`/${window?.contextPath}/citizen/register/name`, { from: getFromLocation(location.state, searchParams), data: data }); + } + } + if (location.state?.role) { + setCanSubmitNo(true); + setError(location.state?.role === "FSM_DSO" ? t("ES_ERROR_DSO_LOGIN") : "User not registered."); + } + } else { + const [res, err] = await sendOtp({ otp: { ...data, ...TYPE_REGISTER } }); + if (!err) { + setCanSubmitNo(true); + history.replace(`${path}/otp`, { from: getFromLocation(location.state, searchParams) }); + return; + } + setCanSubmitNo(true); + } + }; + + const selectName = async (name) => { + const data = { + ...params, + tenantId: stateCode, + userType: getUserType(), + ...name, + }; + setParmas({ ...params, ...name }); + setCanSubmitName(true); + const [res, err] = await sendOtp({ otp: { ...data, ...TYPE_REGISTER } }); + if (res) { + setCanSubmitName(false); + history.replace(`${path}/otp`, { from: getFromLocation(location.state, searchParams) }); + } else { + setCanSubmitName(false); + } + }; + + const selectOtp = async () => { + try { + setIsOtpValid(true); + setCanSubmitOtp(false); + const { mobileNumber, otp, name } = params; + if (isUserRegistered) { + const requestData = { + username: mobileNumber, + password: otp, + tenantId: stateCode, + userType: getUserType(), + }; + const { ResponseInfo, UserRequest: info, ...tokens } = await Digit.UserService.authenticate(requestData); + + if (location.state?.role) { + const roleInfo = info.roles.find((userRole) => userRole.code === location.state.role); + if (!roleInfo || !roleInfo.code) { + setError(t("ES_ERROR_USER_NOT_PERMITTED")); + setTimeout(() => history.replace(DEFAULT_REDIRECT_URL), 5000); + return; + } + } + if (window?.globalConfigs?.getConfig("ENABLE_SINGLEINSTANCE")) { + info.tenantId = Digit.ULBService.getStateId(); + } + + setUser({ info, ...tokens }); + } else if (!isUserRegistered) { + const requestData = { + name, + username: mobileNumber, + otpReference: otp, + tenantId: stateCode, + }; + + const { ResponseInfo, UserRequest: info, ...tokens } = await Digit.UserService.registerUser(requestData, stateCode); + + if (window?.globalConfigs?.getConfig("ENABLE_SINGLEINSTANCE")) { + info.tenantId = Digit.ULBService.getStateId(); + } + + setUser({ info, ...tokens }); + } + } catch (err) { + setCanSubmitOtp(true); + setIsOtpValid(false); + } + }; + + const resendOtp = async () => { + const { mobileNumber } = params; + const data = { + mobileNumber, + tenantId: stateCode, + userType: getUserType(), + }; + if (!isUserRegistered) { + const [res, err] = await sendOtp({ otp: { ...data, ...TYPE_REGISTER } }); + } else if (isUserRegistered) { + const [res, err] = await sendOtp({ otp: { ...data, ...TYPE_LOGIN } }); + } + }; + + const sendOtp = async (data) => { + try { + const res = await Digit.UserService.sendOtp(data, stateCode); + return [res, null]; + } catch (err) { + return [null, err]; + } + }; + + return ( +
+ + + + + + + + + + + + + {error && setError(null)} />} + + +
+ ); +}; + +export default Login; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/SearchApp.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/SearchApp.js new file mode 100644 index 000000000..40d6f6d0d --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/SearchApp.js @@ -0,0 +1,88 @@ +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import AuditSearchApplication from "../../components/Search"; +const Search = ({ path }) => { + const { t } = useTranslation(); + const tenantId = Digit.ULBService.getCitizenCurrentTenant() + const [payload, setPayload] = useState({}); + const convertDateToEpoch = (dateString, dayStartOrEnd = "dayend") => { + //example input format : "2018-10-02" + try { + const parts = dateString.match(/(\d{4})-(\d{1,2})-(\d{1,2})/); + const DateObj = new Date(Date.UTC(parts[1], parts[2] - 1, parts[3])); + DateObj.setMinutes(DateObj.getMinutes() + DateObj.getTimezoneOffset()); + if (dayStartOrEnd === "dayend") { + DateObj.setHours(DateObj.getHours() + 24); + DateObj.setSeconds(DateObj.getSeconds() - 1); + } + return DateObj.getTime(); + } catch (e) { + return dateString; + } + }; + function onSubmit(_data) { + Digit.SessionStorage.set("AUDIT_APPLICATION_DETAIL", { + offset: 0, + limit: 5, + sortBy: "commencementDate", + sortOrder: "DESC", + }); + const data = { + ..._data, + fromDate: convertDateToEpoch(_data?.fromDate), + toDate: convertDateToEpoch(_data?.toDate), + }; + + setPayload( + Object.keys(data) + .filter((k) => data[k]) + .reduce((acc, key) => ({ ...acc, [key]: typeof data[key] === "object" ? data[key] : data[key] }), {}) + ); + } + useEffect(() => { + const storedPayload = Digit.SessionStorage.get("AUDIT_APPLICATION_DETAIL") || {}; + if (storedPayload) { + const data = { + ...storedPayload, + }; + + setPayload( + Object.keys(data) + .filter((k) => data[k]) + .reduce((acc, key) => ({ ...acc, [key]: typeof data[key] === "object" ? data[key].code : data[key] }), {}) + ); + } + }, []); + const config = { + enabled: !!(payload && Object.keys(payload).length > 0), + }; + const newObj = { ...payload }; + + const { + isLoading, + data, +} = Digit.Hooks.useAudit({ + tenantId, + filters: { + ...newObj, + }, + config, + }); + + return ( + 0 + ? data?.ElasticSearchData + : { display: "ES_COMMON_NO_DATA" } + : "" + } + count={data?.ElasticSearchData?.length} + /> + ); + }; + export default Search; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/StaticDynamicComponent/StaticDynamicCard.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/StaticDynamicComponent/StaticDynamicCard.js new file mode 100644 index 000000000..143a62d71 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/StaticDynamicComponent/StaticDynamicCard.js @@ -0,0 +1,269 @@ +import { + Card, + CaseIcon, ComplaintIcon, HelpLineIcon, Loader, MCollectIcon, PTIcon, RupeeSymbol, ServiceCenterIcon, TimerIcon, ValidityTimeIcon, + WhatsappIconGreen +} from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useTranslation } from "react-i18next"; + +const StaticDynamicCard = ({ moduleCode }) => { + const { t } = useTranslation(); + const tenantId = Digit.ULBService.getCitizenCurrentTenant(); + const { isLoading: isMdmsLoading, data: mdmsData } = Digit.Hooks.useStaticData(Digit.ULBService.getStateId()); + const { isLoading: isSearchLoading, error, data: dynamicData, isSuccess } = Digit.Hooks.useDynamicData({ + moduleCode, + tenantId: tenantId, + filters: {}, + t, + }); + const handleClickOnWhatsApp = (obj) => { + window.open(obj); + }; + + const IconComponent = ({ module, styles }) => { + switch (module) { + case "TL": + return ; + case "PT": + return ; + case "MCOLLECT": + return ; + case "PGR": + return ; + default: + return ; + } + }; + const mdmsConfigResult = mdmsData?.MdmsRes["common-masters"]?.StaticData[0]?.[`${moduleCode}`]; + + const StaticDataIconComponentOne = ({ module }) => { + switch (module) { + case "PT": + case "WS": + return ( + + + + ); + default: + return null; + } + }; + const StaticDataIconComponentTwo = ({ module }) => { + switch (module) { + case "PT": + return ( + + + + ); + case "WS": + return ( + + + + ); + default: + return null; + } + }; + const staticContent = (module) => { + switch (module) { + case "TL": + case "PT": + case "MCOLLECT": + return { + staticCommonContent: t("COMMON_VALIDITY"), + validity: mdmsConfigResult?.validity + (mdmsConfigResult?.validity === "1" ? t("COMMON_DAY") : t("COMMON_DAYS")), + }; + case "PGR": + return { + staticCommonContent: t("ACTION_TEST_COMPLAINT_TYPES"), + }; + case "OBPS": + return { + staticCommonContent: t("BUILDING_PLAN_PERMIT_VALIDITY"), + validity: mdmsConfigResult?.validity + " " + (mdmsConfigResult?.validity === "1" ? t("COMMON_DAY") : t("COMMON_DAYS")), + }; + default: + return { + staticCommonContent: "", + }; + } + }; + + const staticData = (module) => { + switch (module) { + case "PT": + return { + staticDataOne: mdmsConfigResult?.staticDataOne + " " + t("COMMON_DAYS"), + staticDataOneHeader: t("APPLICATION_PROCESSING_TIME"), + staticDataTwo: mdmsConfigResult?.staticDataTwo, + staticDataTwoHeader: t("APPLICATION_PROCESSING_FEE"), + }; + case "WS": + return { + staticDataOne: "", + staticDataOneHeader: + t("PAY_WATER_CHARGES_BY") + " " + mdmsConfigResult?.staticDataOne + " " + t("COMMON_DAYS") + " " + t("OF_BILL_GEN_TO_AVOID_LATE_FEE"), + staticDataTwo: mdmsConfigResult?.staticDataTwo + " " + t("COMMON_DAYS"), + staticDataTwoHeader: t("APPLICATION_PROCESSING_TIME"), + }; + default: + return {}; + } + }; + + if (isMdmsLoading || isSearchLoading) { + return ; + } + return mdmsConfigResult ? ( + + {mdmsConfigResult && mdmsConfigResult?.payViaWhatsApp ? ( + +
handleClickOnWhatsApp(mdmsConfigResult?.payViaWhatsApp)}> +
{t("PAY_VIA_WHATSAPP")}
+
+ +
+
+
+ ) : null} + {mdmsConfigResult && mdmsConfigResult?.helpline ? ( + +
+
{t("CALL_CENTER_HELPLINE")}
+
+ +
+
+
+ {mdmsConfigResult?.helpline?.contactOne ? ( + + ) : null} + {mdmsConfigResult?.helpline?.contactTwo ? ( + + ) : null} +
+
+ ) : null} + {mdmsConfigResult && mdmsConfigResult?.serviceCenter ? ( + +
+
{t("CITIZEN_SERVICE_CENTER")}
+
+ +
+
+
+
{mdmsConfigResult?.serviceCenter}
+
+ {mdmsConfigResult?.viewMapLocation ? ( + + ) : null} +
+ ) : ( +
+ )} + + {error || dynamicData == null || dynamicData?.dynamicDataOne === null ? ( +
+ ) : ( +
+
+ + {dynamicData?.dynamicDataOne} +
+
+ )} + {error || dynamicData == null || dynamicData?.dynamicDataTwo === null ? ( +
+ ) : ( +
+
+ + {dynamicData?.dynamicDataTwo} +
+
+ )} + {mdmsConfigResult && mdmsConfigResult?.staticDataOne ? ( +
+
+ + + + {staticData(moduleCode)?.staticDataOneHeader} + + {`${staticData(moduleCode)?.staticDataOne}`} + +
+
+ ) : ( +
+ )} + {mdmsConfigResult && mdmsConfigResult?.staticDataTwo ? ( +
+
+ + + {staticData(moduleCode)?.staticDataTwoHeader} + {staticData(moduleCode)?.staticDataTwo} + +
+
+ ) : ( +
+ )} + {mdmsConfigResult && mdmsConfigResult?.validity ? ( +
+
+ + + + + {staticContent(moduleCode)?.staticCommonContent} + {staticContent(moduleCode)?.validity} + +
+
+ ) : ( +
+ )} + {error || dynamicData == null || !dynamicData?.staticData || dynamicData?.staticData === null ? ( +
+ ) : ( +
+
+ {moduleCode === "PGR" ? ( + + ) : ( + + + + )} + + {staticContent(moduleCode)?.staticCommonContent} + {dynamicData?.staticData} + +
+
+ )} + + + ) : ( + + ); +}; + +export default StaticDynamicCard; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/index.js new file mode 100644 index 000000000..ac66a2ceb --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/citizen/index.js @@ -0,0 +1,227 @@ +import { BackButton, CitizenHomeCard, CitizenInfoLabel } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useTranslation } from "react-i18next"; +import { Route, Switch, useHistory, useRouteMatch } from "react-router-dom"; +import ErrorBoundary from "../../components/ErrorBoundaries"; +import ErrorComponent from "../../components/ErrorComponent"; +import { AppHome, processLinkData } from "../../components/Home"; +import TopBarSideBar from "../../components/TopBarSideBar"; +import StaticCitizenSideBar from "../../components/TopBarSideBar/SideBar/StaticCitizenSideBar"; +import FAQsSection from "./FAQs/FAQs"; +import CitizenHome from "./Home"; +import LanguageSelection from "./Home/LanguageSelection"; +import LocationSelection from "./Home/LocationSelection"; +import UserProfile from "./Home/UserProfile"; +import HowItWorks from "./HowItWorks/howItWorks"; +import Login from "./Login"; +import Search from "./SearchApp"; +import StaticDynamicCard from "./StaticDynamicComponent/StaticDynamicCard"; + +const sidebarHiddenFor = [ + `${window?.contextPath}/citizen/register/name`, + `/${window?.contextPath}/citizen/select-language`, + `/${window?.contextPath}/citizen/select-location`, + `/${window?.contextPath}/citizen/login`, + `/${window?.contextPath}/citizen/register/otp`, +]; + +const getTenants = (codes, tenants) => { + return tenants.filter((tenant) => codes.map((item) => item.code).includes(tenant.code)); +}; + +const Home = ({ + stateInfo, + userDetails, + CITIZEN, + cityDetails, + mobileView, + handleUserDropdownSelection, + logoUrl, + DSO, + stateCode, + modules, + appTenants, + sourceUrl, + pathname, + initData, +}) => { + const { isLoading: islinkDataLoading, data: linkData, isFetched: isLinkDataFetched } = Digit.Hooks.useCustomMDMS( + Digit.ULBService.getStateId(), + "ACCESSCONTROL-ACTIONS-TEST", + [ + { + name: "actions-test", + filter: `[?(@.url == '${window.contextPath}-card')]`, + }, + ], + { + select: (data) => { + const formattedData = data?.["ACCESSCONTROL-ACTIONS-TEST"]?.["actions-test"] + ?.filter((el) => el.enabled === true) + .reduce((a, b) => { + a[b.parentModule] = a[b.parentModule]?.length > 0 ? [b, ...a[b.parentModule]] : [b]; + return a; + }, {}); + return formattedData; + }, + } + ); + + const classname = Digit.Hooks.useRouteSubscription(pathname); + const { t } = useTranslation(); + const { path } = useRouteMatch(); + const history = useHistory(); + const handleClickOnWhatsApp = (obj) => { + window.open(obj); + }; + + const hideSidebar = sidebarHiddenFor.some((e) => window.location.href.includes(e)); + const appRoutes = modules.map(({ code, tenants }, index) => { + const Module = Digit.ComponentRegistryService.getComponent(`${code}Module`); + return Module ? ( + + + + ) : null; + }); + + const ModuleLevelLinkHomePages = modules.map(({ code, bannerImage }, index) => { + let Links = Digit.ComponentRegistryService.getComponent(`${code}Links`) || (() => ); + let mdmsDataObj = isLinkDataFetched ? processLinkData(linkData, code, t) : undefined; + + if (mdmsDataObj?.header === "ACTION_TEST_WS") { + mdmsDataObj?.links.sort((a, b) => { + return b.orderNumber - a.orderNumber; + }); + } + return ( + + +
+ noimagefound + +

{t("MODULE_" + code.toUpperCase())}

+
+ {mdmsDataObj && ( + } + Info={ + code === "OBPS" + ? () => ( + + ) + : null + } + isInfo={code === "OBPS" ? true : false} + /> + )} + {/* */} +
+ +
+
+ + + + + + +
+ ); + }); + + return ( +
+ + +
+ {hideSidebar ? null : ( +
+ +
+ )} + + + + + + + + + + + + + + + { + history.push(`/${window?.contextPath}/${Digit?.UserService?.getType?.()}`); + }} + /> + + + + + + + + + + + + + + + + + + + + + + {appRoutes} + {ModuleLevelLinkHomePages} + + +
+
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + /> +
+
+ ); +}; + +export default Home; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/changePassword.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/changePassword.js new file mode 100644 index 000000000..c67853708 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/changePassword.js @@ -0,0 +1,168 @@ +import { BackButton, CardSubHeader, CardText, FormComposer, Toast } from "@egovernments/digit-ui-react-components"; +import PropTypes from "prop-types"; +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; +import Background from "../../../components/Background"; +import Header from "../../../components/Header"; +import SelectOtp from "../../citizen/Login/SelectOtp"; + + +const ChangePasswordComponent = ({ config: propsConfig, t }) => { + const [user, setUser] = useState(null); + const { mobile_number: mobileNumber, tenantId } = Digit.Hooks.useQueryParams(); + const history = useHistory(); + const [otp, setOtp] = useState(""); + const [isOtpValid, setIsOtpValid] = useState(true); + const [showToast, setShowToast] = useState(null); + const getUserType = () => Digit.UserService.getType(); + useEffect(() => { + if (!user) { + Digit.UserService.setType("employee"); + return; + } + Digit.UserService.setUser(user); + const redirectPath = location.state?.from || `/${window?.contextPath}/employee`; + history.replace(redirectPath); + }, [user]); + + const closeToast = () => { + setShowToast(null); + }; + + const onResendOTP = async () => { + const requestData = { + otp: { + mobileNumber, + userType: getUserType().toUpperCase(), + type: "passwordreset", + tenantId, + }, + }; + + try { + await Digit.UserService.sendOtp(requestData, tenantId); + setShowToast(t("ES_OTP_RESEND")); + } catch (err) { + setShowToast(err?.response?.data?.error_description || t("ES_INVALID_LOGIN_CREDENTIALS")); + } + setTimeout(closeToast, 5000); + }; + + const onChangePassword = async (data) => { + try { + if (data.newPassword !== data.confirmPassword) { + return setShowToast(t("ERR_PASSWORD_DO_NOT_MATCH")); + } + const requestData = { + ...data, + otpReference: otp, + tenantId, + type: getUserType().toUpperCase(), + }; + + const response = await Digit.UserService.changePassword(requestData, tenantId); + navigateToLogin(); + } catch (err) { + setShowToast(err?.response?.data?.error?.fields?.[0]?.message || t("ES_SOMETHING_WRONG")); + setTimeout(closeToast, 5000); + } + }; + + const navigateToLogin = () => { + history.replace(`/${window?.contextPath}/employee/user/login`); + }; + + const [username, password, confirmPassword] = propsConfig.inputs; + const config = [ + { + body: [ + { + label: t(username.label), + type: username.type, + populators: { + name: username.name, + }, + isMandatory: true, + }, + { + label: t(password.label), + type: password.type, + populators: { + name: password.name, + }, + isMandatory: true, + }, + { + label: t(confirmPassword.label), + type: confirmPassword.type, + populators: { + name: confirmPassword.name, + }, + isMandatory: true, + }, + ], + }, + ]; + + return ( + +
+ +
+ +
+ {propsConfig.texts.header} + + {`${t(`CS_LOGIN_OTP_TEXT`)} `} + + {" "} + {`${t(`+ 91 - `)}`} {mobileNumber} + + + + {/*
+ {t("CORE_OTP_SENT_MESSAGE")} + {mobileNumber} + {t("CORE_EMPLOYEE_OTP_CHECK_MESSAGE")} +
+ {t("CORE_OTP_OTP")} * + +
+
+ {t("CORE_OTP_RESEND")} +
+
*/} + + {showToast && } +
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + />{" "} +
+ + ); +}; + +ChangePasswordComponent.propTypes = { + loginParams: PropTypes.any, +}; + +ChangePasswordComponent.defaultProps = { + loginParams: null, +}; + +export default ChangePasswordComponent; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/config.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/config.js new file mode 100644 index 000000000..487112dfd --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/config.js @@ -0,0 +1,28 @@ +export const config = [ + { + texts: { + header: "CORE_COMMON_RESET_PASSWORD_LABEL", + submitButtonLabel: "CORE_COMMON_CHANGE_PASSWORD", + }, + inputs: [ + { + label: "CORE_LOGIN_USERNAME", + type: "text", + name: "userName", + error: "ERR_HRMS_INVALID_USERNAME", + }, + { + label: "CORE_LOGIN_NEW_PASSWORD", + type: "password", + name: "newPassword", + error: "CORE_COMMON_REQUIRED_ERRMSG", + }, + { + label: "CORE_LOGIN_CONFIRM_NEW_PASSWORD", + type: "password", + name: "confirmPassword", + error: "CORE_COMMON_REQUIRED_ERRMSG", + }, + ], + }, +]; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/index.js new file mode 100644 index 000000000..58231ea6d --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ChangePassword/index.js @@ -0,0 +1,33 @@ +import React, { useMemo } from "react"; +import { useTranslation } from "react-i18next"; +import { Route, Switch, useRouteMatch } from "react-router-dom"; +import ChangePasswordComponent from "./changePassword"; +import { config } from "./config"; + +const EmployeeChangePassword = () => { + const { t } = useTranslation(); + const { path } = useRouteMatch(); + + const params = useMemo(() => + config.map( + (step) => { + const texts = {}; + for (const key in step.texts) { + texts[key] = t(step.texts[key]); + } + return { ...step, texts }; + }, + [config] + ) + ); + + return ( + + + + + + ); +}; + +export default EmployeeChangePassword; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/config.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/config.js new file mode 100644 index 000000000..237f5c8e5 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/config.js @@ -0,0 +1,23 @@ +export const loginConfig = [ + { + texts: { + header: "CORE_COMMON_FORGOT_PASSWORD_LABEL", + description: "ES_FORGOT_PASSWORD_DESC", + submitButtonLabel: "CORE_COMMON_CONTINUE", + }, + inputs: [ + { + label: "CORE_COMMON_MOBILE_NUMBER", + type: "text", + name: "mobileNumber", + error: "ERR_HRMS_INVALID_MOBILE_NUMBER", + }, + { + label: "CORE_COMMON_CITY", + type: "custom", + name: "city", + error: "ERR_HRMS_INVALID_CITY", + }, + ], + }, +]; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/forgotPassword.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/forgotPassword.js new file mode 100644 index 000000000..2d7e32865 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/forgotPassword.js @@ -0,0 +1,120 @@ +import { BackButton, Dropdown, FormComposer, Loader, Toast } from "@egovernments/digit-ui-react-components"; +import PropTypes from "prop-types"; +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; +import Background from "../../../components/Background"; +import Header from "../../../components/Header"; + +const ForgotPassword = ({ config: propsConfig, t }) => { + const { data: cities, isLoading } = Digit.Hooks.useTenants(); + const [user, setUser] = useState(null); + const history = useHistory(); + const [showToast, setShowToast] = useState(null); + const getUserType = () => Digit.UserService.getType(); + + useEffect(() => { + if (!user) { + Digit.UserService.setType("employee"); + return; + } + Digit.UserService.setUser(user); + const redirectPath = location.state?.from || `/${window?.contextPath}/employee`; + history.replace(redirectPath); + }, [user]); + + const closeToast = () => { + setShowToast(null); + }; + + const onForgotPassword = async (data) => { + if (!data.city) { + alert("Please Select City!"); + return; + } + const requestData = { + otp: { + mobileNumber: data.mobileNumber, + userType: getUserType().toUpperCase(), + type: "passwordreset", + tenantId: data.city.code, + }, + }; + try { + await Digit.UserService.sendOtp(requestData, data.city.code); + history.push(`/${window?.contextPath}/employee/user/change-password?mobile_number=${data.mobileNumber}&tenantId=${data.city.code}`); + } catch (err) { + setShowToast(err?.response?.data?.error?.fields?.[0]?.message || "Invalid login credentials!"); + setTimeout(closeToast, 5000); + } + }; + + const navigateToLogin = () => { + history.replace(`/${window?.contextPath}/employee/login`); + }; + + const [userId, city] = propsConfig.inputs; + const config = [ + { + body: [ + { + label: t(userId.label), + type: userId.type, + populators: { + name: userId.name, + componentInFront: "+91", + }, + isMandatory: true, + } + ], + }, + ]; + + if (isLoading) { + return ; + } + return ( + +
+ +
+ +
+ + {showToast && } +
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + />{" "} +
+ + ); +}; + +ForgotPassword.propTypes = { + loginParams: PropTypes.any, +}; + +ForgotPassword.defaultProps = { + loginParams: null, +}; + +export default ForgotPassword; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/index.js new file mode 100644 index 000000000..9fbb7ba02 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/ForgotPassword/index.js @@ -0,0 +1,33 @@ +import React, { useMemo } from "react"; +import { useTranslation } from "react-i18next"; +import { Route, Switch, useRouteMatch } from "react-router-dom"; +import { loginConfig } from "./config"; +import ForgotPasswordComponent from "./forgotPassword"; + +const EmployeeForgotPassword = () => { + const { t } = useTranslation(); + const { path } = useRouteMatch(); + + const params = useMemo(() => + loginConfig.map( + (step) => { + const texts = {}; + for (const key in step.texts) { + texts[key] = t(step.texts[key]); + } + return { ...step, texts }; + }, + [loginConfig] + ) + ); + + return ( + + + + + + ); +}; + +export default EmployeeForgotPassword; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/LanguageSelection/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/LanguageSelection/index.js new file mode 100644 index 000000000..eca20e76f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/LanguageSelection/index.js @@ -0,0 +1,60 @@ +import { Card, CustomButton, SubmitBar } from "@egovernments/digit-ui-react-components"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import Background from "../../../components/Background"; + +const LanguageSelection = () => { + const { data: storeData, isLoading } = Digit.Hooks.useStore.getInitData(); + const { t } = useTranslation(); + const history = useHistory(); + const { languages, stateInfo } = storeData || {}; + const selectedLanguage = Digit.StoreData.getCurrentLanguage(); + const [selected, setselected] = useState(selectedLanguage); + const handleChangeLanguage = (language) => { + setselected(language.value); + Digit.LocalizationService.changeLanguage(language.value, stateInfo.code); + }; + + const handleSubmit = (event) => { + history.push(`/${window?.contextPath}/employee/user/login`); + }; + + if (isLoading) return null; + + return ( + + +
+ Digit + +

{t(`TENANT_TENANTS_${stateInfo?.code.toUpperCase()}`)}

+
+
+ {languages.map((language, index) => ( +
+ handleChangeLanguage(language)} + > +
+ ))} +
+ +
+
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + />{" "} +
+
+ ); +}; + +export default LanguageSelection; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/config.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/config.js new file mode 100644 index 000000000..34215c98b --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/config.js @@ -0,0 +1,46 @@ +export const loginConfig = [ + { + texts: { + header: "CORE_COMMON_LOGIN", + submitButtonLabel: "CORE_COMMON_CONTINUE", + secondaryButtonLabel: "CORE_COMMON_FORGOT_PASSWORD", + }, + inputs: [ + { + label: "CORE_LOGIN_USERNAME", + type: "text", + populators: { + name: "username", + }, + isMandatory: true, + }, + { + label: "CORE_LOGIN_PASSWORD", + type: "password", + populators: { + name: "password", + }, + isMandatory: true, + }, + { + isMandatory: true, + type: "dropdown", + key: "city", + label: "CORE_COMMON_CITY", + disable: false, + populators: { + name: "city", + optionsKey: "name", + error: "ERR_HRMS_INVALID_CITY", + mdmsConfig: { + masterName: "tenants", + moduleName: "tenant", + localePrefix: "TENANT_TENANTS", + select: + "(data)=>{ return Array.isArray(data['tenant'].tenants) && Digit.Utils.getUnique(data['tenant'].tenants).map(ele=>({code:ele.code,name:Digit.Utils.locale.getTransformedLocale('TENANT_TENANTS_'+ele.code)}))}", + }, + }, + }, + ], + }, +]; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/index.js new file mode 100644 index 000000000..7d0456e9c --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/index.js @@ -0,0 +1,50 @@ +import React, { useEffect, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Route, Switch, useRouteMatch } from "react-router-dom"; +import { loginConfig as defaultLoginConfig } from "./config"; +import LoginComponent from "./login"; + +const EmployeeLogin = () => { + const { t } = useTranslation(); + const { path } = useRouteMatch(); + const [loginConfig, setloginConfig] = useState(defaultLoginConfig); + + const { data: mdmsData, isLoading } = Digit.Hooks.useCommonMDMS(Digit.ULBService.getStateId(), "commonUiConfig", ["LoginConfig"], { + select: (data) => { + return { + config: data?.commonUiConfig?.LoginConfig, + }; + }, + retry: false, + }); + + //let loginConfig = mdmsData?.config ? mdmsData?.config : defaultLoginConfig; + useEffect(() => { + if (isLoading == false && mdmsData?.config) { + setloginConfig(mdmsData?.config); + } + }, [mdmsData, isLoading]); + + const loginParams = useMemo(() => + loginConfig.map( + (step) => { + const texts = {}; + for (const key in step.texts) { + texts[key] = t(step.texts[key]); + } + return { ...step, texts }; + }, + [loginConfig] + ) + ); + + return ( + + + + + + ); +}; + +export default EmployeeLogin; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/login.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/login.js new file mode 100644 index 000000000..733971c1f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/Login/login.js @@ -0,0 +1,162 @@ +import { BackButton, Dropdown, FormComposer, FormComposerV2, Loader, Toast } from "@egovernments/digit-ui-react-components"; +import PropTypes from "prop-types"; +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; +import Background from "../../../components/Background"; +import Header from "../../../components/Header"; + +/* set employee details to enable backward compatiable */ +const setEmployeeDetail = (userObject, token) => { + let locale = JSON.parse(sessionStorage.getItem("Digit.locale"))?.value || "en_IN"; + localStorage.setItem("Employee.tenant-id", userObject?.tenantId); + localStorage.setItem("tenant-id", userObject?.tenantId); + localStorage.setItem("citizen.userRequestObject", JSON.stringify(userObject)); + localStorage.setItem("locale", locale); + localStorage.setItem("Employee.locale", locale); + localStorage.setItem("token", token); + localStorage.setItem("Employee.token", token); + localStorage.setItem("user-info", JSON.stringify(userObject)); + localStorage.setItem("Employee.user-info", JSON.stringify(userObject)); +}; + +const Login = ({ config: propsConfig, t, isDisabled }) => { + const { data: cities, isLoading } = Digit.Hooks.useTenants(); + const { data: storeData, isLoading: isStoreLoading } = Digit.Hooks.useStore.getInitData(); + const { stateInfo } = storeData || {}; + const [user, setUser] = useState(null); + const [showToast, setShowToast] = useState(null); + const [disable, setDisable] = useState(false); + + const history = useHistory(); + // const getUserType = () => "EMPLOYEE" || Digit.UserService.getType(); + + useEffect(() => { + if (!user) { + return; + } + Digit.SessionStorage.set("citizen.userRequestObject", user); + const filteredRoles = user?.info?.roles?.filter((role) => role.tenantId === Digit.SessionStorage.get("Employee.tenantId")); + if (user?.info?.roles?.length > 0) user.info.roles = filteredRoles; + Digit.UserService.setUser(user); + setEmployeeDetail(user?.info, user?.access_token); + let redirectPath = `/${window?.contextPath}/employee`; + + /* logic to redirect back to same screen where we left off */ + if (window?.location?.href?.includes("from=")) { + redirectPath = decodeURIComponent(window?.location?.href?.split("from=")?.[1]) || `/${window?.contextPath}/employee`; + } + + /* RAIN-6489 Logic to navigate to National DSS home incase user has only one role [NATADMIN]*/ + // if (user?.info?.roles && user?.info?.roles?.every((e) => e.code === "NATADMIN")) { + // redirectPath = `/${window?.contextPath}/employee/dss/landing/NURT_DASHBOARD`; + // } + /* RAIN-6489 Logic to navigate to National DSS home incase user has only one role [NATADMIN]*/ + // if (user?.info?.roles && user?.info?.roles?.every((e) => e.code === "STADMIN")) { + // redirectPath = `/${window?.contextPath}/employee/dss/landing/home`; + // } + history.replace(redirectPath); + }, [user]); + + const onLogin = async (data) => { + // if (!data.city) { + // alert("Please Select City!"); + // return; + // } + setDisable(true); + + const requestData = { + ...data, + userType: "EMPLOYEE", + }; + requestData.tenantId = data?.city?.code || Digit.ULBService.getStateId(); + delete requestData.city; + try { + const { UserRequest: info, ...tokens } = await Digit.UserService.authenticate(requestData); + Digit.SessionStorage.set("Employee.tenantId", info?.tenantId); + setUser({ info, ...tokens }); + } catch (err) { + setShowToast( + err?.response?.data?.error_description || + (err?.message == "ES_ERROR_USER_NOT_PERMITTED" && t("ES_ERROR_USER_NOT_PERMITTED")) || + t("INVALID_LOGIN_CREDENTIALS") + ); + setTimeout(closeToast, 5000); + } + setDisable(false); + }; + + const closeToast = () => { + setShowToast(null); + }; + + const onForgotPassword = () => { + history.push(`/${window?.contextPath}/employee/user/forgot-password`); + }; + const defaultValue = { + code: Digit.ULBService.getStateId(), + name: Digit.Utils.locale.getTransformedLocale(`TENANT_TENANTS_${Digit.ULBService.getStateId()}`), + }; + + let config = [{ body: propsConfig?.inputs }]; + + const { mode } = Digit.Hooks.useQueryParams(); + if (mode === "admin" && config?.[0]?.body?.[2]?.disable == false && config?.[0]?.body?.[2]?.populators?.defaultValue == undefined) { + config[0].body[2].disable = true; + config[0].body[2].isMandatory = false; + config[0].body[2].populators.defaultValue = defaultValue; + } + if(config && config[0].body && config[0].body[1].label === 'CORE_LOGIN_PASSWORD'){ + config[0].body[1].populators.validation = { + maxlength: 30 + }; + } + return isLoading || isStoreLoading ? ( + + ) : ( + +
+ +
+ + +
+ + {showToast && } +
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + />{" "} +
+ + ); +}; + +Login.propTypes = { + loginParams: PropTypes.any, +}; + +Login.defaultProps = { + loginParams: null, +}; + +export default Login; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/index.js new file mode 100644 index 000000000..edd21baf6 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/pages/employee/index.js @@ -0,0 +1,137 @@ +import React, { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { Redirect, Route, Switch, useLocation, useRouteMatch, useHistory } from "react-router-dom"; +import { AppModules } from "../../components/AppModules"; +import ErrorBoundary from "../../components/ErrorBoundaries"; +import TopBarSideBar from "../../components/TopBarSideBar"; +import ChangePassword from "./ChangePassword"; +import ForgotPassword from "./ForgotPassword"; +import LanguageSelection from "./LanguageSelection"; +import EmployeeLogin from "./Login"; +import UserProfile from "../citizen/Home/UserProfile"; +import ErrorComponent from "../../components/ErrorComponent"; +import { PrivateRoute } from "@egovernments/digit-ui-react-components"; + +const userScreensExempted = ["user/profile", "user/error"]; + +const EmployeeApp = ({ + stateInfo, + userDetails, + CITIZEN, + cityDetails, + mobileView, + handleUserDropdownSelection, + logoUrl, + DSO, + stateCode, + modules, + appTenants, + sourceUrl, + pathname, + initData, +}) => { + const history = useHistory(); + const { t } = useTranslation(); + const { path } = useRouteMatch(); + const location = useLocation(); + const showLanguageChange = location?.pathname?.includes("language-selection"); + const isUserProfile = userScreensExempted.some((url) => location?.pathname?.includes(url)); + useEffect(() => { + Digit.UserService.setType("employee"); + }, []); + + return ( +
+ + + {isUserProfile && ( + + )} +
+ + + + + + + + + + + + + + + { + history.push(`/${window?.contextPath}/${Digit?.UserService?.getType?.()}`); + }} + /> + + + + + + + + +
+
+ + +
+
+ + + +
+
+ Powered by DIGIT { + window.open(window?.globalConfigs?.getConfig?.("DIGIT_HOME_URL"), "_blank").focus(); + }} + /> +
+
+
+ + + +
+
+ ); +}; + +export default EmployeeApp; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/redux/reducers/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/redux/reducers/index.js new file mode 100644 index 000000000..11591c2b2 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/redux/reducers/index.js @@ -0,0 +1,8 @@ +export const commonReducer = (defaultData) => (state = defaultData, action) => { + switch (action.type) { + case "LANGUAGE_SELECT": + return { ...state, selectedLanguage: action.payload }; + default: + return state; + } +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/redux/store.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/redux/store.js new file mode 100644 index 000000000..1ce1faa45 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/core/src/redux/store.js @@ -0,0 +1,24 @@ +import { applyMiddleware, combineReducers, compose, createStore } from "redux"; +import thunk from "redux-thunk"; +import { commonReducer } from "./reducers"; + +const getRootReducer = (defaultStore, moduleReducers) => + combineReducers({ + common: commonReducer(defaultStore), + ...moduleReducers, + }); + +const middleware = [thunk]; + +const composeEnhancers = + typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose; + +const enhancer = composeEnhancers( + applyMiddleware(...middleware) + // other store enhancers if any +); + +const getStore = (defaultStore, moduleReducers = {}) => { + return createStore(getRootReducer(defaultStore, moduleReducers), enhancer); +}; +export default getStore; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/README.md b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/README.md new file mode 100644 index 000000000..71752708d --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/README.md @@ -0,0 +1,71 @@ + + +# digit-ui-module-hrms + +## Install + +```bash +npm install --save @egovernments/digit-ui-module-hrms +``` + +## Limitation + +```bash +This Package is more specific to DIGIT-UI's can be used across mission's +``` + +## Usage + +After adding the dependency make sure you have this dependency in + +```bash +frontend/micro-ui/web/package.json +``` + +```json +"@egovernments/digit-ui-module-hrms":"^1.5.0", +``` + +then navigate to App.js + +```bash + frontend/micro-ui/web/src/App.js +``` + + +```jsx +/** add this import **/ + +import { initHRMSComponents } from "@egovernments/digit-ui-module-hrms"; + +/** inside enabledModules add this new module key **/ + +const enabledModules = ["HRMS"]; + +/** inside init Function call this function **/ + +const initDigitUI = () => { + initHRMSComponents(); +}; +``` + +# Changelog + +```bash +1.5.27 updated the readme content +1.5.26 some issue +1.5.25 corrected the bredcrumb issue +1.5.24 added the readme file +1.5.23 base version +``` + +# Contributors + +[jagankumar-egov] [naveen-egov] [nipunarora-eGov] [Tulika-eGov] [Ramkrishna-egov] [vamshikrishnakole-wtt-egov] + +## Published from DIGIT Core +Digit Dev Repo (https://github.com/egovernments/DIGIT-Dev/tree/digit-ui-core) + +## License + +MIT © [jagankumar-egov](https://github.com/jagankumar-egov) \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/package.json new file mode 100644 index 000000000..b7fb1d599 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/package.json @@ -0,0 +1,28 @@ +{ + "name": "@egovernments/digit-ui-module-hrms", + "version": "1.5.27", + "description": "HRMS", + "license": "MIT", + "main": "dist/index.js", + "module": "dist/index.modern.js", + "source": "src/Module.js", + "files": [ + "dist" + ], + "scripts": { + "start": "microbundle-crl watch --no-compress --format modern,cjs", + "build": "microbundle-crl --compress --no-sourcemap --format cjs", + "prepublish": "yarn build" + }, + "dependencies": { + "@egovernments/digit-ui-react-components": "1.5.27", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-hook-form": "6.15.8", + "react-i18next": "11.16.2", + "react-query": "3.6.1", + "react-router-dom": "5.3.0", + "rooks": "^4.4.0" + }, + "keywords": ["digit","egov","dpg","digit-ui","hrms","employee","management"] +} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/Module.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/Module.js new file mode 100644 index 000000000..614e1ec81 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/Module.js @@ -0,0 +1,68 @@ +import React from "react"; +import { useRouteMatch } from "react-router-dom"; +import HRMSCard from "./components/hrmscard"; +import InboxFilter from "./components/InboxFilter"; +import ActionModal from "./components/Modal"; +import Assignments from "./components/pageComponents/assignment"; +import HRBanner from "./components/pageComponents/Banner"; +import SelectDateofBirthEmployment from "./components/pageComponents/EmployeeDOB"; +import SelectEmployeePhoneNumber from "./components/pageComponents/EmployeePhoneNumber"; +import Jurisdictions from "./components/pageComponents/jurisdiction"; +import SelectDateofEmployment from "./components/pageComponents/SelectDateofEmployment"; +import SelectEmployeeEmailId from "./components/pageComponents/SelectEmailId"; +import SelectEmployeeCorrespondenceAddress from "./components/pageComponents/SelectEmployeeCorrespondenceAddress"; +import SelectEmployeeGender from "./components/pageComponents/SelectEmployeeGender"; +import SelectEmployeeId from "./components/pageComponents/SelectEmployeeId"; +import SelectEmployeeName from "./components/pageComponents/SelectEmployeeName"; +import SelectEmployeeType from "./components/pageComponents/SelectEmployeeType"; +import EmployeeApp from "./pages"; +import CreateEmployee from "./pages/createEmployee"; +import EditEmployee from "./pages/EditEmployee/index"; +import Details from "./pages/EmployeeDetails"; +import Inbox from "./pages/Inbox"; +import Response from "./pages/Response"; + +export const HRMSModule = ({ stateCode, userType, tenants }) => { + const moduleCode = "HR"; + const language = Digit.StoreData.getCurrentLanguage(); + const { isLoading, data: store } = Digit.Services.useStore({ stateCode, moduleCode, language }); + + Digit.SessionStorage.set("HRMS_TENANTS", tenants); + const { path, url } = useRouteMatch(); + if (!Digit.Utils.hrmsAccess()) { + return null; + } + if (userType === "employee") { + return ; + } else return null; +}; + +const componentsToRegister = { + HRMSCard, + HRMSDetails: Details, + SelectEmployeeEmailId, + SelectEmployeeName, + SelectEmployeeId, + Jurisdictions, + Assignments, + ActionModal, + HRBanner, + SelectEmployeePhoneNumber, + SelectDateofEmployment, + SelectEmployeeType, + SelectEmployeeCorrespondenceAddress, + SelectEmployeeGender, + SelectDateofBirthEmployment, + HRMSModule, + HRMSResponse: Response, + HREditEmpolyee: EditEmployee, + HRCreateEmployee: CreateEmployee, + HRInbox: Inbox, + HRMS_INBOX_FILTER: (props) => , +}; + +export const initHRMSComponents = () => { + Object.entries(componentsToRegister).forEach(([key, value]) => { + Digit.ComponentRegistryService.setComponent(key, value); + }); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/EmployeeAction.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/EmployeeAction.js new file mode 100644 index 000000000..aea9d4d6d --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/EmployeeAction.js @@ -0,0 +1,169 @@ +import { FormComposer, Loader, Modal } from "@egovernments/digit-ui-react-components"; +import set from "lodash/set"; +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; +import { configEmployeeActiveApplication } from "./Modal/EmployeeActivation"; +import { configEmployeeApplication } from "./Modal/EmployeeAppliaction"; + +const EmployeeAction = ({ t, action, tenantId, closeModal, submitAction, applicationData, billData }) => { + const history = useHistory(); + const [config, setConfig] = useState({}); + const [file, setFile] = useState(null); + const [uploadedFile, setUploadedFile] = useState(null); + const [error, setError] = useState(null); + const [Reasons, setReasons] = useState([]); + const [selectedReason, selecteReason] = useState(""); + const tenant = Digit.ULBService.getStateId() || tenantId?.split(".")?.[0]; + const { isLoading, isError, errors, data, ...rest } = Digit.Hooks.hrms.useHrmsMDMS(tenant, "egov-hrms", "DeactivationReason"); + + useEffect(() => { + if(Reasons?.length > 0) + switch (action) { + case "DEACTIVATE_EMPLOYEE_HEAD": + return setConfig( + configEmployeeApplication({ + t, + action, + selectFile, + uploadedFile, + setUploadedFile, + selectedReason, + Reasons, + selectReason, + }) + ); + case "ACTIVATE_EMPLOYEE_HEAD": + return setConfig( + configEmployeeActiveApplication({ + t, + action, + selectFile, + uploadedFile, + setUploadedFile, + selectedReason, + Reasons, + selectReason, + employees: applicationData?.Employees[0] || {} + }) + ); + default: + break; + } + }, [action, uploadedFile, Reasons]); + + const Heading = (props) => { + return

{props.label}

; + }; + + function selectReason(e) { + selecteReason(e); + } + const Close = () => ( + + + + + ); + + const CloseBtn = (props) => { + return ( +
+ +
+ ); + }; + + function selectFile(e) { + setFile(e.target.files[0]); + } + useEffect(() => { + setReasons( + data?.["egov-hrms"]?.DeactivationReason?.map((ele) => { + ele["i18key"] = "EGOV_HRMS_DEACTIVATIONREASON_" + ele.code; + return ele; + }) + ); + }, [data, isLoading]); + + useEffect(() => { + (async () => { + setError(null); + if (file) { + if (file.size >= 5242880) { + setError(t("CS_MAXIMUM_UPLOAD_SIZE_EXCEEDED")); + } else { + try { + setUploadedFile(null); + const response = await Digit.UploadServices.Filestorage("HRMS", file, Digit.ULBService.getStateId()); + if (response?.data?.files?.length > 0) { + setUploadedFile(response?.data?.files[0]?.fileStoreId); + } else { + setError(t("CS_FILE_UPLOAD_ERROR")); + } + } catch (err) { + setError(t("CS_FILE_UPLOAD_ERROR")); + } + } + } + })(); + }, [file]); + + function submit(data) { + // useHRMSUpdate + data.effectiveFrom = new Date(data.effectiveFrom).getTime(); + data.reasonForDeactivation = selectedReason.code; + let Employees = [...applicationData.Employees]; + if (action !== "ACTIVATE_EMPLOYEE_HEAD") { + if (file) { + let documents = { + referenceType: "DEACTIVATION", + documentId: uploadedFile, + documentName: file.name, + }; + applicationData.Employees[0]["documents"].push(documents); + } + + set(Employees[0], 'deactivationDetails[0].effectiveFrom', data?.effectiveFrom); + set(Employees[0], 'deactivationDetails[0].orderNo', data?.orderNo); + set(Employees[0], 'deactivationDetails[0].reasonForDeactivation', data?.reasonForDeactivation); + set(Employees[0], 'deactivationDetails[0].remarks', data?.remarks); + + Employees[0].isActive = false; + history.replace( `/${window?.contextPath}/employee/hrms/response`, { Employees, key: "UPDATE", action: "DEACTIVATION" }); + } else { + if (file) { + let documents = { + referenceType: "ACTIVATION", + documentId: uploadedFile, + documentName: file.name, + }; + applicationData.Employees[0]["documents"].push(documents); + } + + set(Employees[0], 'reactivationDetails[0].effectiveFrom', data?.effectiveFrom); + set(Employees[0], 'reactivationDetails[0].orderNo', data?.orderNo); + set(Employees[0], 'reactivationDetails[0].reasonForDeactivation', data?.reasonForDeactivation); + set(Employees[0], 'reactivationDetails[0].remarks', data?.remarks); + Employees[0].isActive = true; + + history.replace( `/${window?.contextPath}/employee/hrms/response`, { Employees, key: "UPDATE", action: "ACTIVATION" }); + } + } + + return action && config?.form ? ( + } + headerBarEnd={} + actionCancelOnSubmit={closeModal} + actionSaveLabel={t(config?.label?.submit)} + actionSaveOnSubmit={() => { }} + formId="modal-action" + isDisabled={!selectedReason} + > + + + ) : ( + + ); +}; +export default EmployeeAction; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/EmployeeModuleCard.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/EmployeeModuleCard.js new file mode 100644 index 000000000..4e02d0591 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/EmployeeModuleCard.js @@ -0,0 +1,74 @@ +import React, { Fragment } from "react"; +import { Link } from "react-router-dom"; + +const EmployeeModuleCard = ({ + Icon, + moduleName, + kpis = [], + links = [], + isCitizen = false, + className, + styles, + longModuleName = false, + FsmHideCount, +}) => { + const ArrowRightInbox = ({ style }) => ( + + + + ); + + return ( +
+
+
+ {moduleName} + {Icon} +
+
+ {kpis.length !== 0 && ( +
+ {kpis.map(({ count, label, link }, index) => ( +
+
+ {count ? count : count == 0 ? 0 : "-"} +
+
+ {link ? ( + + {label} + + ) : null} +
+
+ ))} +
+ )} +
+ {links.map(({ count, label, link }, index) => ( + + {link && link?.includes("https") ? ( + + {label} + + ) : ( + {label} + )} + {count ? ( + <> + {FsmHideCount ? null : {count || "-"}} + + + + + ) : null} + + ))} +
+
+
+
+ ); +}; + +export default EmployeeModuleCard; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/InboxFilter.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/InboxFilter.js new file mode 100644 index 000000000..00b059fd8 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/InboxFilter.js @@ -0,0 +1,276 @@ +import { ActionBar, ApplyFilterBar, CloseSvg, Dropdown, RadioButtons, RemoveableTag, SubmitBar } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { getCityThatUserhasAccess } from "./Utils"; + +const Filter = ({ searchParams, onFilterChange, onSearch, removeParam, ...props }) => { + const [filters, onSelectFilterRoles] = useState(searchParams?.filters?.role || { role: [] }); + const [_searchParams, setSearchParams] = useState(() => searchParams); + const [selectedRoles, onSelectFilterRolessetSelectedRole] = useState(null); + const [divisionTenants, setDivisionTenants] = useState([]); + const [selectedDivision, setSelectedDivision] = useState(); + const [Divisions, setDivisions] = useState([]); + const [rolesData, setRolesData] = useState([]); + const [isRefreshed, setIsRefreshed] = useState(false); + const { t } = useTranslation(); + const tenantIds = Digit.SessionStorage.get("HRMS_TENANTS"); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + + function onSelectRoles(value, type) { + if (!ifExists(filters.role, value)) { + onSelectFilterRoles({ ...filters, role: [...filters.role, value] }); + } + } + const onRemove = (index, key) => { + let afterRemove = filters[key].filter((value, i) => { + return i !== index; + }); + onSelectFilterRoles({ ...filters, [key]: afterRemove }); + }; + + useEffect(() => { + if (filters.role.length > 1) { + onSelectFilterRolessetSelectedRole({ name: `${filters.role.length} selected` }); + } else { + onSelectFilterRolessetSelectedRole(filters.role[0]); + } + }, [filters.role]); + const [tenantId, settenantId] = useState(() => { + return tenantIds.filter( + (ele) => + ele.code == (searchParams?.tenantId != undefined ? { code: searchParams?.tenantId } : { code: Digit.ULBService.getCurrentTenantId() })?.code + )[0]; + }); + const { isLoading, isError, errors, data: data, ...rest } = Digit.Hooks.hrms.useHrmsMDMS( + tenantId ? tenantId.code : searchParams?.tenantId, + "egov-hrms", + "HRMSRolesandDesignation" + ); + const [departments, setDepartments] = useState(() => { + return { departments: null }; + }); + + const [roles, setRoles] = useState(() => { + return { roles: null }; + }); + const [isActive, setIsactive] = useState(() => { + return { isActive: true }; + }); + + useEffect(() => { + if (tenantId?.code) { + setSearchParams({ ..._searchParams, tenantId: tenantId.code }); + } + }, [tenantId]); + + useEffect(() => { + if (filters.role && filters.role.length > 0) { + let res = []; + filters.role.forEach((ele) => { + res.push(ele.code); + }); + + setSearchParams({ ..._searchParams, roles: [...res].join(",") }); + if (filters?.role && filters?.role?.length > 1) { + let res = []; + filters.role.forEach((ele) => { + res.push(ele.code); + }); + setSearchParams({ ..._searchParams, roles: [...res].join(",") }); + } + } else if (filters?.role && filters?.role?.length === 0) { + setSearchParams({ ..._searchParams, roles: undefined }); + } + }, [filters.role]); + + useEffect(() => { + if (departments) { + setSearchParams({ ..._searchParams, departments: departments.code }); + } + }, [departments]); + + useEffect(() => { + if (roles) { + setSearchParams({ ..._searchParams, roles: roles.code }); + } + }, [roles]); + + const ifExists = (list, key) => { + return list?.filter((object) => object.code === key.code).length; + }; + + useEffect(() => { + if (isActive) { + setSearchParams({ ..._searchParams, isActive: isActive.code }); + } + }, [isActive]); + + useEffect(() => { + if (divisionTenants) { + setSearchParams({ ..._searchParams, tenantIds: divisionTenants }); + } + }, [divisionTenants]); + + useEffect(() => { + let divisions = []; + divisions = data?.MdmsRes?.["tenant"]["tenants"] + ?.filter((items) => items?.divisionCode) + ?.map((item) => { + return { + code: item.divisionCode, + name: item.divisionName, + i18text: Digit.Utils.locale.convertToLocale(item?.divisionCode, "EGOV_LOCATION_DIVISION"), + }; + }); + const uniqueDivisions = divisions?.reduce((unique, obj) => { + const isDuplicate = unique.some((item) => item.id === obj.id && item.name === obj.name); + if (!isDuplicate) { + unique.push(obj); + } + return unique; + }, []); + + setDivisions(uniqueDivisions); + + // Specify the role codes you want to filter + const roleCodesToFilter = ["HRMS_ADMIN", "DIV_ADMIN", "MDMS_ADMIN", "LOC_ADMIN", "SYSTEM"]; + // Use the filter method to extract roles with the specified codes + const roles = data?.MdmsRes?.["ws-services-masters"]?.WSServiceRoles?.filter((role) => { + return !roleCodesToFilter.includes(role.code); + })?.map((role) => { + return { code: role.code, name: role?.name ? role?.name : " ", i18text: "ACCESSCONTROL_ROLES_ROLES_" + role.code }; + }); + setRolesData(roles); + }, [data?.MdmsRes, isRefreshed, divisionTenants, selectedDivision]); + + const clearAll = () => { + onFilterChange({ delete: Object.keys(searchParams) }); + settenantId(tenantIds.filter((ele) => ele.code == Digit.ULBService.getCurrentTenantId())[0]); + setDepartments(null); + setRoles(null); + setIsactive(null); + props?.onClose?.(); + onSelectFilterRoles({ role: [] }); + setDivisionTenants(null); + setSelectedDivision(null); + setIsRefreshed(!isRefreshed); + }; + + const GetSelectOptions = (lable, options, selected, select, optionKey, onRemove, key) => { + selected = selected || { [optionKey]: " ", code: "" }; + return ( +
+
{lable}
+ { select(value, key)} optionKey={optionKey} />} +
+ {filters?.role?.length > 0 && + filters?.role?.map((value, index) => { + return onRemove(index, key)} />; + })} +
+
+ ); + }; + + const selectDivision = (value) => { + // Extract projects using array methods + const project = data?.MdmsRes?.["tenant"]["tenants"].filter((obj) => obj.divisionCode === value.code); + const finalProjects = project?.map((project) => project?.code); + setDivisionTenants(finalProjects); + setSelectedDivision(value); + }; + + return ( + +
+
+
+
+ + + + + + {t("HR_COMMON_FILTER")}:{" "} +
+
+ {t("HR_COMMON_CLEAR_ALL")} +
+ {props.type === "desktop" && ( + + + + + + )} + {props.type === "mobile" && ( + + + + )} +
+
+ {STATE_ADMIN ? ( +
+
{t("HR_DIVISIONS_LABEL")}
+ +
+ ) : ( +
+
{t("HR_COMMON_TABLE_COL_ROLE")}
+ +
+ {filters?.role?.length > 0 && + filters?.role?.map((value, index) => { + return onRemove(index, "role")} />; + })} +
+
+ )} +
+
{t("HR_EMP_STATUS_LABEL")}
+ + {props.type !== "mobile" && ( +
+ onFilterChange(_searchParams)} label={t("HR_COMMON_APPLY")} /> +
+ )} +
+
+
+
+ {props.type === "mobile" && ( + + { + onFilterChange(_searchParams); + props?.onClose?.(); + }} + style={{ flex: 1 }} + /> + + )} +
+ ); +}; + +export default Filter; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/EmployeeActivation.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/EmployeeActivation.js new file mode 100644 index 000000000..9a90aaccd --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/EmployeeActivation.js @@ -0,0 +1,84 @@ +import { Dropdown, UploadFile } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { convertEpochToDate } from "../Utils/index"; + +export const configEmployeeActiveApplication = ({ + t, + action, + selectFile, + uploadedFile, + setUploadedFile, + selectedReason, + Reasons, + selectReason, + employees = {}, +}) => { + employees.deactivationDetails = employees?.deactivationDetails?.sort((y, x) => x?.auditDetails?.createdDate - y?.auditDetails?.createdDate); + return { + label: { + heading: `HR_ACTIVATE_EMPLOYEE_HEAD`, + submit: `HR_ACTIVATE_EMPLOYEE_HEAD`, + }, + form: [ + { + body: [ + { + label: t("HR_ACTIVATION_REASON"), + //type: "dropdown", + isMandatory: true, + name: "reasonForDeactivation", + populators: , + }, + { + label: t("HR_ORDER_NO"), + type: "text", + populators: { + name: "orderNo", + }, + }, + + { + label: t("HR_EFFECTIVE_DATE"), + type: "date", + isMandatory: true, + disable: true /* Disabled date and set defaultvalue */, + populators: { + error: t("HR_EFFECTIVE_DATE_INVALID"), + name: "effectiveFrom", + min: convertEpochToDate(employees?.deactivationDetails?.[0].effectiveFrom), + max: convertEpochToDate(new Date().toJSON().slice(0, 10).replace(/-/g, "/")), + defaultValue: convertEpochToDate(new Date().toJSON().slice(0, 10).replace(/-/g, "/")), + }, + }, + { + label: t("HR_APPROVAL_UPLOAD_HEAD"), + populators: ( +
+ {t("TL_APPROVAL_UPLOAD_SUBHEAD")} + { + setUploadedFile(null); + }} + enableButton={true} + uploadedFiles={[]} + message={uploadedFile ? `1 ${t(`HR_ACTION_FILEUPLOADED`)}` : t(`HR_ACTION_NO_FILEUPLOADED`)} + /> +
+ ), + }, + + { + label: t("HR_REMARKS"), + type: "text", + populators: { + name: "remarks", + }, + }, + ], + }, + ], + }; +}; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/EmployeeAppliaction.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/EmployeeAppliaction.js new file mode 100644 index 000000000..c49e4de32 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/EmployeeAppliaction.js @@ -0,0 +1,73 @@ +import React from "react"; +import { UploadFile, Dropdown } from "@egovernments/digit-ui-react-components"; +import { convertEpochToDate } from "../Utils/index"; + +export const configEmployeeApplication = ({ t, action, selectFile, uploadedFile, setUploadedFile, selectedReason, Reasons, selectReason }) => { + return { + label: { + heading: `HR_DEACTIVATE_EMPLOYEE_HEAD`, + submit: `HR_DEACTIVATE_EMPLOYEE_HEAD`, + }, + form: [ + { + body: [ + { + label: t("HR_DEACTIVATION_REASON"), + //type: "dropdown", + isMandatory: true, + name: "reasonForDeactivation", + populators: , + }, + { + label: t("HR_ORDER_NO"), + type: "text", + populators: { + name: "orderNo", + }, + }, + + { + label: t("HR_EFFECTIVE_DATE"), + type: "date", + isMandatory: true, + disable: true /* Disabled date and set defaultvalue */, + populators: { + error: t("HR_EFFECTIVE_DATE_INVALID"), + name: "effectiveFrom", + min: convertEpochToDate(new Date().toJSON().slice(0, 10).replace(/-/g, "/")), + max: convertEpochToDate(new Date().toJSON().slice(0, 10).replace(/-/g, "/")), + defaultValue: convertEpochToDate(new Date().toJSON().slice(0, 10).replace(/-/g, "/")), + }, + }, + { + label: t("HR_APPROVAL_UPLOAD_HEAD"), + populators: ( +
+ {t("TL_APPROVAL_UPLOAD_SUBHEAD")} + { + setUploadedFile(null); + }} + enableButton={true} + uploadedFiles={[]} + message={uploadedFile ? `1 ${t(`HR_ACTION_FILEUPLOADED`)}` : t(`HR_ACTION_NO_FILEUPLOADED`)} + /> +
+ ), + }, + + { + label: t("HR_REMARKS"), + type: "text", + populators: { + name: "remarks", + }, + }, + ], + }, + ], + }; +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/index.js new file mode 100644 index 000000000..624837a76 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Modal/index.js @@ -0,0 +1,8 @@ +import React, { useState, useEffect } from "react"; +import EmployeeAction from "../EmployeeAction"; + +const ActionModal = (props) => { + return ; +}; + +export default ActionModal; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Utils/cleanup.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Utils/cleanup.js new file mode 100644 index 000000000..3191c92e9 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Utils/cleanup.js @@ -0,0 +1,14 @@ +const cleanup = (payload) => { + if (payload) { + return Object.keys(payload).reduce((acc, key) => { + if (payload[key] === undefined) { + return acc; + } + + // todo: find a better way to check object + acc[key] = typeof payload[key] === "object" ? cleanup(payload[key]) : payload[key]; + return acc; + }, {}); + } +}; +export default cleanup; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Utils/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Utils/index.js new file mode 100644 index 000000000..7f0149bf7 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/Utils/index.js @@ -0,0 +1,70 @@ + +export const pdfDownloadLink = (documents = {}, fileStoreId = "", format = "") => { + /* Need to enhance this util to return required format*/ + + let downloadLink = documents[fileStoreId] || ""; + let differentFormats = downloadLink?.split(",") || []; + let fileURL = ""; + differentFormats.length > 0 && + differentFormats.map((link) => { + if (!link.includes("large") && !link.includes("medium") && !link.includes("small")) { + fileURL = link; + } + }); + return fileURL; +}; + +/* method to get filename from fielstore url*/ +export const pdfDocumentName = (documentLink = "", index = 0) => { + let documentName = decodeURIComponent(documentLink.split("?")[0].split("/").pop().slice(13)) || `Document - ${index + 1}`; + return documentName; +}; + +/* methid to get date from epoch */ +export const convertEpochToDate = (dateEpoch) => { + // Returning null in else case because new Date(null) returns initial date from calender + if (dateEpoch) { + const dateFromApi = new Date(dateEpoch); + let month = dateFromApi.getMonth() + 1; + let day = dateFromApi.getDate(); + let year = dateFromApi.getFullYear(); + month = (month > 9 ? "" : "0") + month; + day = (day > 9 ? "" : "0") + day; + return `${year}-${month}-${day}`; + } else { + return null; + } +}; + +export const convertEpochFormateToDate = (dateEpoch) => { + // Returning null in else case because new Date(null) returns initial date from calender + if (dateEpoch) { + const dateFromApi = new Date(dateEpoch); + let month = dateFromApi.getMonth() + 1; + let day = dateFromApi.getDate(); + let year = dateFromApi.getFullYear(); + month = (month > 9 ? "" : "0") + month; + day = (day > 9 ? "" : "0") + day; + return `${day}/${month}/${year}`; + } else { + return null; + } +}; + +const objectsEqual = (o1, o2) => Object.keys(o1).length === Object.keys(o2).length && Object.keys(o1).every((p) => o1[p] === o2[p]); + +export const arraysEqual = (a1, a2) => a1.length === a2.length && a1.every((o, idx) => objectsEqual(o, a2[idx])); + + +/* function returns only the city which user has access to */ +/* exceptional incase of state level user , where return all cities*/ +export const getCityThatUserhasAccess = (cities = []) => { + const userInfo = Digit.UserService.getUser(); + let roleObject = {}; + userInfo?.info?.roles.map((roleData) => { roleObject[roleData?.code] = roleObject[roleData?.code] ? [...roleObject[roleData?.code], roleData?.tenantId] : [roleData?.tenantId] }); + const tenant = Digit.ULBService.getCurrentTenantId(); + if (roleObject[Digit.Utils?.hrmsRoles?.[0]].includes(Digit.ULBService.getStateId())) { + return cities; + } + return cities.filter(city => roleObject[Digit.Utils?.hrmsRoles?.[0]]?.includes(city?.code)); +} \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/config/config.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/config/config.js new file mode 100644 index 000000000..527cfae45 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/config/config.js @@ -0,0 +1,43 @@ +export const newConfig = [ + { + head: "Personal Details", + body: [ + { + type: "component", + component: "SelectEmployeeName", + key: "SelectEmployeeName", + withoutLabel: true, + }, + { + type: "component", + component: "SelectEmployeePhoneNumber", + key: "SelectEmployeePhoneNumber", + withoutLabel: true, + }, + { + type: "component", + component: "SelectEmployeeGender", + key: "SelectEmployeeGender", + withoutLabel: true, + }, + { + type: "component", + component: "SelectEmployeeEmailId", + key: "SelectEmployeeEmailId", + withoutLabel: true, + }, + ], + }, + { + head: "HR_JURISDICTION_DETAILS_HEADER", + body: [ + { + type: "component", + isMandatory: true, + component: "Jurisdictions", + key: "Jurisdictions", + withoutLabel: true, + }, + ], + }, +]; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/hrmscard.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/hrmscard.js new file mode 100644 index 000000000..02736b550 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/hrmscard.js @@ -0,0 +1,83 @@ +import { PersonIcon } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { useTranslation } from "react-i18next"; +import EmployeeModuleCard from "./EmployeeModuleCard"; + +const HRMSCard = () => { + const ADMIN = Digit.Utils.hrmsAccess(); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + const DIV_ADMIN = Digit.UserService.hasAccess(["DIV_ADMIN"]); + const MDMS_ADMIN = Digit.UserService.hasAccess(["MDMS_ADMIN"]); + if (!ADMIN) { + return null; + } + const { t } = useTranslation(); + const tenantId = Digit.ULBService.getCurrentTenantId(); + let roles = STATE_ADMIN + ? { roles: "DIV_ADMIN, HRMS_ADMIN", isStateLevelSearch: true } + : { roles: "SYSTEM, GP_ADMIN, COLLECTION_OPERATOR, PROFILE_UPDATE, DASHBOAD_VIEWER", isStateLevelSearch: false }; + const { isLoading, isError, error, data, ...rest } = Digit.Hooks.hrms.useHRMSCount(tenantId, roles); + + const moduleForSomeDIVAdmin = + DIV_ADMIN && MDMS_ADMIN + ? [ + { + label: t("WORK_BENCH_URL_MASTER_DATA"), + link: `${window?.location?.origin}/workbench-ui/employee/workbench/mdms-search-v2?moduleName=ws-services-calculation&masterName=WCBillingSlab`, + }, + // { + // label: t("WORK_BENCH_URL_LOCALIZATION"), + // link: `${window?.location?.origin}/workbench-ui/employee/workbench/localisation-search`, + // }, + ] + : []; + + const moduleForSomeSTATEUser = + STATE_ADMIN && MDMS_ADMIN + ? [ + { + label: t("WORK_BENCH_URL_MASTER_DATA"), + link: `${window?.location?.origin}/workbench-ui/employee/workbench/mdms-search-v2?moduleName=tenant&masterName=tenants`, + }, + ] + : []; + + + const propsForModuleCard = { + Icon: , + moduleName: t("ACTION_TEST_HRMS"), + kpis: [ + { + count: isLoading ? "-" : data?.EmployeCount?.totalEmployee, + label: t("TOTAL_EMPLOYEES"), + link: `/${window?.contextPath}/employee/hrms/inbox`, + }, + { + count: isLoading ? "-" : data?.EmployeCount?.activeEmployee, + label: t("ACTIVE_EMPLOYEES"), + link: `/${window?.contextPath}/employee/hrms/inbox`, + }, + ], + links: [ + { + label: t("HR_HOME_SEARCH_RESULTS_HEADING"), + link: `/${window?.contextPath}/employee/hrms/inbox`, + }, + { + label: STATE_ADMIN ? t("HR_COMMON_CREATE_DIVISION_EMPLOYEE_HEADER") : t("HR_COMMON_CREATE_EMPLOYEE_HEADER"), + link: `/${window?.contextPath}/employee/hrms/create`, + }, + { + label: t("HR_STATE_ REPORTS"), + link: "https://ifix-dwss.psegs.in/digit-ui/employee/dss/dashboard/ifix", + }, + ...moduleForSomeDIVAdmin, + ...moduleForSomeSTATEUser, + + ], + }; + + return ; +}; + +export default HRMSCard; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationCard.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationCard.js new file mode 100644 index 000000000..41f5f1ad3 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationCard.js @@ -0,0 +1,153 @@ +import React, { useCallback, useEffect, useState } from "react"; + +import { Card, DetailsCard, Loader, PopUp, SearchAction } from "@egovernments/digit-ui-react-components"; +import { FilterAction } from "@egovernments/digit-ui-react-components"; +import Filter from "../InboxFilter"; +import SearchApplication from "./search"; + +export const ApplicationCard = ({ + t, + data, + onFilterChange, + onSearch, + onSort, + serviceRequestIdKey, + isFstpOperator, + isLoading, + isSearch, + searchParams, + searchFields, + sortParams, + linkPrefix, + removeParam, +}) => { + const [type, setType] = useState(isSearch ? "SEARCH" : ""); + const [popup, setPopup] = useState(isSearch ? true : false); + const [params, setParams] = useState(searchParams); + const [_sortparams, setSortParams] = useState(sortParams); + + const selectParams = (param) => { + setParams((o) => ({ ...o, ...param })); + }; + + const clearParam = () => { + setParams({}); + }; + + const onSearchPara = (param) => { + onFilterChange({ ...params, ...param }); + setType(""); + setPopup(false); + onSearch() + }; + + useEffect(() => { + if (type) setPopup(true); + }, [type]); + + const DSO = Digit.UserService.hasAccess(["FSM_DSO"]) || false; + + const handlePopupClose = () => { + setPopup(false); + setType(""); + setParams(searchParams); + setSortParams(sortParams); + }; + + const onSearchSortParams = (d) => { + setSortParams(d); + setPopup(false); + setType(""); + onSort(d); + }; + + if (isLoading) { + return ; + } + + let result; + if (!data || data?.length === 0) { + result = ( + + {t("CS_MYAPPLICATIONS_NO_APPLICATION") + .split("\\n") + .map((text, index) => ( +

+ {text} +

+ ))} +
+ ); + } else if (data && data?.length > 0) { + result = ( + + ); + } + + return ( + +
+ {onSearch && ( + { + setType("SEARCH"); + setPopup(true); + }} + /> + )} + {!isSearch && onFilterChange && ( + { + setType("FILTER"); + setPopup(true); + }} + /> + )} + {/* { + setType("SORT"); + setPopup(true); + }} + /> */} +
+ {result} + {popup && ( + + {type === "FILTER" && ( +
+ { + + } +
+ )} + {type === "SEARCH" && ( +
+ +
+ )} +
+ )} +
+ ); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationLinks.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationLinks.js new file mode 100644 index 000000000..efd5a1a26 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationLinks.js @@ -0,0 +1,43 @@ +import { Card, PersonIcon } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; + +const InboxLinks = ({ parentRoute, businessService, allLinks, headerText }) => { + const { t } = useTranslation(); + const [links, setLinks] = useState([]); + const { roles: userRoles } = Digit.UserService.getUser().info; + useEffect(() => { + let linksToShow = allLinks + .filter((e) => e.businessService === businessService) + .filter(({ roles }) => roles.some((e) => userRoles.map(({ code }) => code).includes(e)) || !roles.length); + setLinks(linksToShow); + }, []); + + const GetLogo = () => ( +
+ + + {" "} + {t(headerText)} +
+ ); + return ( + +
+ {GetLogo()} +
+ {links.map(({ link, text, hyperlink = false, accessTo = [] }, index) => { + return ( + + {hyperlink ? {t(text)} : {t(text)}} + + ); + })} +
+
+
+ ); +}; + +export default InboxLinks; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationTable.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationTable.js new file mode 100644 index 000000000..eb184ed22 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/ApplicationTable.js @@ -0,0 +1,37 @@ +import React from "react"; +import { Table } from "@egovernments/digit-ui-react-components"; + +const ApplicationTable = ({ + t, + columns, + data, + getCellProps, + onNextPage, + onPrevPage, + currentPage, + totalRecords, + pageSizeLimit, + onPageSizeChange, + // onSort, + sortParams, + disableSort, +}) => ( +
+); + +export default ApplicationTable; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/DesktopInbox.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/DesktopInbox.js new file mode 100644 index 000000000..5e432b1d2 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/DesktopInbox.js @@ -0,0 +1,198 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import ApplicationTable from "../inbox/ApplicationTable"; +import { Card, Loader } from "@egovernments/digit-ui-react-components"; +import InboxLinks from "../inbox/ApplicationLinks"; +import SearchApplication from "./search"; +import { Link } from "react-router-dom"; + +const DesktopInbox = ({ tableConfig, filterComponent, ...props }) => { + const { t } = useTranslation(); + const tenantIds = Digit.SessionStorage.get("HRMS_TENANTS"); + const GetCell = (value) => {t(value)}; + const GetSlaCell = (value) => { + return value == "INACTIVE" ? ( + {t(value) || ""} + ) : ( + {t(value) || ""} + ); + }; + const data = props?.data?.Employees; + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + + const [FilterComponent, setComp] = useState(() => Digit.ComponentRegistryService?.getComponent(filterComponent)); + + const columns = React.useMemo(() => { + return [ + { + Header: t("HR_EMP_ID_LABEL"), + disableSortBy: false, + accessor: "code", + Cell: ({ row }) => { + return ( + + {row.original.code} + + ); + }, + }, + { + Header: t("HR_EMP_NAME_LABEL"), + disableSortBy: false, + accessor: "name", + Cell: ({ row }) => { + return GetCell(`${row.original?.user?.name}`); + }, + }, + // { + // Header: t("HR_ROLE_NO_LABEL"), + // Cell: ({ row }) => { + // return ( + //
+ // {" "} + // {GetCell(`${row.original?.user?.roles.length}`)} + // + // {row.original?.user?.roles.map((ele, index) => ( + // + // {`${index + 1}. ` + t(`ACCESSCONTROL_ROLES_ROLES_${ele.code}`)}
{" "} + //
+ // ))} + //
+ //
+ // ); + // }, + // disableSortBy: true, + // }, + // { + // Header: t("HR_DESG_LABEL"), + // disableSortBy: true, + // Cell: ({ row }) => { + // return GetCell( + // `${ + // t( + // "COMMON_MASTERS_DESIGNATION_" + row.original?.assignments?.sort((a, b) => new Date(a.fromDate) - new Date(b.fromDate))[0]?.designation + // ) || "" + // }` + // ); + // }, + // }, + { + Header: t("HR_USER_ID_LABEL"), + disableSortBy: false, + accessor: "mobileNumber", + Cell: ({ row }) => { + return GetCell(`${row.original?.user?.mobileNumber}`); + // return GetCell( + // `${ + // t( + // "COMMON_MASTERS_DEPARTMENT_" + row.original?.assignments?.sort((a, b) => new Date(a.fromDate) - new Date(b.fromDate))[0]?.department + // ) || "" + // }` + // ); + }, + }, + { + Header: t("HR_STATUS_LABEL"), + disableSortBy: false, + accessor: "isActive", + Cell: ({ row }) => { + return GetSlaCell(`${row.original?.isActive ? "ACTIVE" : "INACTIVE"}`); + }, + }, + ]; + }, []); + + let result; + if (props.isLoading) { + result = ; + } else if (data?.length === 0) { + result = ( + + {/* TODO Change localization key */} + {t("COMMON_TABLE_NO_RECORD_FOUND") + .split("\\n") + .map((text, index) => ( +

+ {text} +

+ ))} +
+ ); + } else if (data?.length > 0) { + result = ( + { + return { + style: { + maxWidth: cellInfo.column.Header == t("HR_EMP_ID_LABEL") ? "150px" : "", + padding: "20px 18px", + fontSize: "16px", + minWidth: "150px", + }, + }; + }} + onPageSizeChange={props.onPageSizeChange} + currentPage={props.currentPage} + onNextPage={props.onNextPage} + onPrevPage={props.onPrevPage} + pageSizeLimit={props.pageSizeLimit} + // onSort={props.onSort} + disableSort={props.disableSort} + sortParams={props.sortParams} + totalRecords={props.totalRecords} + /> + ); + } + + return ( +
+ {!props.isSearch && ( +
+ +
+ { + + } +
+
+ )} +
+ +
+ {result} +
+
+
+ ); +}; + +export default DesktopInbox; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/MobileInbox.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/MobileInbox.js new file mode 100644 index 000000000..5261cb531 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/MobileInbox.js @@ -0,0 +1,76 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { ApplicationCard } from "./ApplicationCard"; +// import { ApplicationLinks } from "@egovernments/digit-ui-react-components"; + +const MobileInbox = ({ + data, + isLoading, + isSearch, + searchFields, + onFilterChange, + onSearch, + onSort, + parentRoute, + searchParams, + sortParams, + linkPrefix, + tableConfig, + filterComponent, + allLinks, +}) => { + const { t } = useTranslation(); + // const getData = () => { + // return data?.Employees?.map((dataObj) => { + // const obj = {}; + // const columns = isSearch ? tableConfig.searchColumns() : tableConfig.inboxColumns(); + // columns.forEach((el) => { + // if (el.mobileCell) obj[el.Header] = el.mobileCell(dataObj); + // }); + // return obj; + // }); + // }; + + const GetCell = (value) => {t(value)}; +const GetSlaCell = (value) => { + return value == "INACTIVE" ? { t(value )|| ""} : { t(value) || ""}; +}; + const getData = () => { + return data?.Employees?.map((original) => ({ + [t("HR_EMP_ID_LABEL")]: original?.code, + [t("HR_EMP_NAME_LABEL")]: GetCell(original?.user?.name || ""), + [t("HR_ROLE_NO_LABEL")]: GetCell(original?.user?.roles.length || ""), + [t("HR_DESG_LABEL")]: GetCell(t("COMMON_MASTERS_DESIGNATION_" +original?.assignments?.sort((a, b) => new Date(a.fromDate) - new Date(b.fromDate))[0]?.designation)), + [t("HR_DEPT_LABEL")]: GetCell(t(`COMMON_MASTERS_DEPARTMENT_${original?.assignments?.sort((a, b) => new Date(a.fromDate) - new Date(b.fromDate))[0]?.department}`)), + [t("HR_STATUS_LABEL")]: GetSlaCell(original?.isActive ? "ACTIVE" : "INACTIVE"), + })); + }; + const serviceRequestIdKey = (original) => {return `${searchParams?.tenantId}/${original?.[t("HR_EMP_ID_LABEL")]}`}; + + return ( +
+
+
+ {/* {!isSearch && } */} + +
+
+
+ ); +}; + +export default MobileInbox; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/search.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/search.js new file mode 100644 index 000000000..33e6be599 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/inbox/search.js @@ -0,0 +1,117 @@ +import { ActionBar, CloseSvg, DatePicker, Label, LinkLabel, SubmitBar, TextInput } from "@egovernments/digit-ui-react-components"; +import React from "react"; +import { Controller, useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; + +const SearchApplication = ({ onSearch, type, onClose, searchFields, searchParams, isInboxPage, defaultSearchParams }) => { + const { t } = useTranslation(); + const { register, handleSubmit, reset, watch, control } = useForm({ + defaultValues: searchParams, + }); + const mobileView = innerWidth <= 640; + const onSubmitInput = (data) => { + if (!data.mobileNumber) { + delete data.mobileNumber; + } + data.delete = []; + searchFields.forEach((field) => { + if (!data[field.name]) data.delete.push(field.name); + }); + onSearch(data); + if (type === "mobile") { + onClose(); + } + }; + + function clearSearch() { + const resetValues = searchFields.reduce((acc, field) => ({ ...acc, [field?.name]: "" }), {}); + reset(resetValues); + const _newParams = { ...searchParams }; + _newParams.delete = []; + searchFields.forEach((e) => { + _newParams.delete.push(e?.name); + }); + onSearch({ ..._newParams }); + } + + const clearAll = (mobileView) => { + const mobileViewStyles = mobileView ? { margin: 0 } : {}; + return ( + + {t("HR_COMMON_CLEAR_SEARCH")} + + ); + }; + + return ( +
+ +
+
+ {(type === "mobile" || mobileView) && ( +
+

{t("ES_COMMON_SEARCH_BY")}

+ + + +
+ )} +
+ {searchFields + ?.filter((e) => true) + ?.map((input, index) => ( +
+ + + {input.type !== "date" ? ( +
+ {input?.componentInFront ? ( + + {input?.componentInFront} + + ) : null} + +
+ ) : ( + } + name={input.name} + control={control} + defaultValue={null} + /> + )}{" "} +
+
+ ))} +
+
+ {type === "desktop" && !mobileView && ( + + {clearAll()} + + )} + {type === "desktop" && !mobileView && ( + + )} +
+
+
+ {(type === "mobile" || mobileView) && ( + + + + + )} +
+ + ); +}; + +export default SearchApplication; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/Banner.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/Banner.js new file mode 100644 index 000000000..61307199b --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/Banner.js @@ -0,0 +1,15 @@ +import React, { useEffect, useState } from "react"; +import { CardLabel, LabelFieldPair } from "@egovernments/digit-ui-react-components"; +const HRBanner = ({ t, config }) => { + return ( + + {config?.texts?.nosideText!==true && + . + } + + {t(config?.texts?.header)} + + + ); +}; +export default HRBanner; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/EmployeeDOB.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/EmployeeDOB.js new file mode 100644 index 000000000..6b3eb1960 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/EmployeeDOB.js @@ -0,0 +1,52 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError, DatePicker } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; +import { convertEpochToDate } from "../Utils/index"; + +const SelectDateofBirthEmployment = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + const inputs = [ + { + label: "HR_BIRTH_DATE_LABEL", + type: "date", + name: "dob", + validation: { + isRequired: true, + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + isMandatory: true, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + return ( +
+ {inputs?.map((input, index) => ( + + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e, input.name)} + disable={false} + max={convertEpochToDate(new Date().setFullYear(new Date().getFullYear() - 18))} + defaultValue={undefined} + {...input.validation} + /> +
+
+
+ ))} +
+ ); +}; + +export default SelectDateofBirthEmployment; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/EmployeePhoneNumber.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/EmployeePhoneNumber.js new file mode 100644 index 000000000..3d36d026f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/EmployeePhoneNumber.js @@ -0,0 +1,90 @@ +import React, { useState } from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeePhoneNumber = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + const [iserror, setError] = useState(false); + let isMobile = window.Digit.Utils.browser.isMobile(); + const isEdit = window.location.href?.includes("hrms/edit"); + + const inputs = [ + { + label: t("HR_MOB_NO_LABEL"), + isMandatory: true, + type: "mobileNumber", + name: "mobileNumber", + populators: { + validation: { + maxLength: 10, + required: true, + // pattern: /^[6-9]\d{9}$/, + }, + // componentInFront:
+91
, + // error: t("CORE_COMMON_MOBILE_ERROR"), + }, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + function validate(value, input) { + setError(!input?.populators?.validation?.pattern?.test(value)); + } + + return ( +
+ {inputs?.map((input, index) => ( + + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+
+
+
+91
+ { + const value = e.target.value.replace(/\D/, ""); // Remove non-numeric characters + setValue(value, input.name, validate(value, input)); + }} + disable={isEdit ? true : false} + defaultValue={undefined} + maxlength={input.populators.validation.maxLength} + onBlur={(e) => validate(e.target.value, input)} + {...input.populators.validation} + /> +
+
+ {iserror ? ( + {t(input.populators.error)} + ) : ( + + {t("HR_MOBILE_NO_CHECK")} + + )} +
+
+
+
+
+ ))} +
+ ); +}; + +export default SelectEmployeePhoneNumber; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/Multiselect.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/Multiselect.js new file mode 100644 index 000000000..0b92d0c5a --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/Multiselect.js @@ -0,0 +1,276 @@ +import React, { useEffect, useReducer, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; + +const MultiSelectDropdown = ({ + options, + optionsKey, + selected = [], + onSelect, + defaultLabel = "", + defaultUnit = "", + BlockNumber = 1, + isOBPSMultiple = false, + props = {}, + isPropsNeeded = false, + ServerStyle = {}, + config, + showSelectAll = false, +}) => { + const [active, setActive] = useState(false); + const [searchQuery, setSearchQuery] = useState(); + const [optionIndex, setOptionIndex] = useState(-1); + const [isSelected, setIsSelected] = useState(false); + const dropdownRef = useRef(); + const { t } = useTranslation(); + + const CheckSvg = ({ className, style = {} }) => ( + + + + + ); + + const ArrowDown = ({ className, onClick, styles, disable }) => ( + + + + + ); + + const RemoveableTag = ({ text, onClick, extraStyles, disabled = false }) => ( +
+ + {text} + + + + +
+ ); + function reducer(state, action) { + switch (action.type) { + case "ADD_TO_SELECTED_EVENT_QUEUE": + const newStateData = Array.isArray(action?.payload?.[1]) + ? action?.payload?.[1]?.map((items, index) => { + let obj = { + i18text: items?.i18text, + propsData: [action.payload?.[0], action.payload?.[1]?.[index]], + }; + return obj; + }) + : [...state, { [optionsKey]: action.payload?.[1]?.[optionsKey], propsData: action.payload }]; + return newStateData; + case "REMOVE_FROM_SELECTED_EVENT_QUEUE": + const newState = Array.isArray(action?.payload?.[1]) ? [] : state.filter((e) => e?.[optionsKey] !== action.payload?.[1]?.[optionsKey]); + onSelect( + newState?.map((e) => e?.propsData), + props + ); // Update the form state here + return newState; + case "REPLACE_COMPLETE_STATE": + return action.payload; + default: + return state; + } + } + + useEffect(() => { + dispatch({ type: "REPLACE_COMPLETE_STATE", payload: fnToSelectOptionThroughProvidedSelection(selected) }); + }, [selected?.length]); + + function fnToSelectOptionThroughProvidedSelection(selected) { + + return selected?.map((e) => ( + { + [optionsKey]: `ACCESSCONTROL_ROLES_ROLES_${e.code}`, + propsData: [null, e] + } + )); + } + + const [alreadyQueuedSelectedState, dispatch] = useReducer(reducer, selected, fnToSelectOptionThroughProvidedSelection); + + useEffect(() => { + if (!active) { + onSelect( + alreadyQueuedSelectedState?.map((e) => e.propsData), + props + ); + } + }, [active]); + + function handleOutsideClickAndSubmitSimultaneously() { + setActive(false); + } + + Digit.Hooks.useClickOutside(dropdownRef, handleOutsideClickAndSubmitSimultaneously, active, { capture: true }); + const filtOptns = + searchQuery?.length > 0 + ? options.filter( + (option) => + t(option[optionsKey] && typeof option[optionsKey] == "string" && option[optionsKey].toUpperCase()) + .toLowerCase() + .indexOf(searchQuery.toLowerCase()) >= 0 + ) + : options; + + function onSearch(e) { + setSearchQuery(e.target.value); + } + + function onSelectToAddToQueue(...props) { + const isChecked = arguments[0].target.checked; + isChecked + ? dispatch({ type: "ADD_TO_SELECTED_EVENT_QUEUE", payload: arguments }) + : dispatch({ type: "REMOVE_FROM_SELECTED_EVENT_QUEUE", payload: arguments }); + } + + /* Custom function to scroll and select in the dropdowns while using key up and down */ + const keyChange = (e) => { + if (e.key == "ArrowDown") { + setOptionIndex((state) => (state + 1 == filtOptns.length ? 0 : state + 1)); + if (optionIndex + 1 == filtOptns.length) { + e?.target?.parentElement?.parentElement?.children?.namedItem("jk-dropdown-unique")?.scrollTo?.(0, 0); + } else { + optionIndex > 2 && e?.target?.parentElement?.parentElement?.children?.namedItem("jk-dropdown-unique")?.scrollBy?.(0, 45); + } + e.preventDefault(); + } else if (e.key == "ArrowUp") { + setOptionIndex((state) => (state !== 0 ? state - 1 : filtOptns.length - 1)); + if (optionIndex === 0) { + e?.target?.parentElement?.parentElement?.children?.namedItem("jk-dropdown-unique")?.scrollTo?.(100000, 100000); + } else { + optionIndex > 2 && e?.target?.parentElement?.parentElement?.children?.namedItem("jk-dropdown-unique")?.scrollBy?.(0, -45); + } + e.preventDefault(); + } else if (e.key == "Enter") { + onSelectToAddToQueue(e, filtOptns[optionIndex]); + } + }; + + const filteredOptions = + searchQuery?.length > 0 + ? options.filter( + (option) => + t(option[optionsKey] && typeof option[optionsKey] == "string" && option[optionsKey].toUpperCase()) + .toLowerCase() + .indexOf(searchQuery.toLowerCase()) >= 0 + ) + : options; + + const handleSelectAll = (...data) => { + const isChecked = data[0].target.checked; + setIsSelected(isChecked); + isChecked + ? dispatch({ type: "ADD_TO_SELECTED_EVENT_QUEUE", payload: data }) + : dispatch({ type: "REMOVE_FROM_SELECTED_EVENT_QUEUE", payload: data }); + }; + const MenuItem = ({ option, index }) => ( +
+ selectedOption[optionsKey] === option[optionsKey]) ? true : false} + onChange={(e) => + isPropsNeeded + ? onSelectToAddToQueue(e, option, props) + : isOBPSMultiple + ? onSelectToAddToQueue(e, option, BlockNumber) + : onSelectToAddToQueue(e, option) + } + style={{ minWidth: "24px", width: "100%" }} + /> +
+ +
+

+ {t(option[optionsKey] && typeof option[optionsKey] == "string" && option[optionsKey])} +

+
+ ); + const Menu = () => { + return ( +
+ {showSelectAll && ( +
+ handleSelectAll(e, filteredOptions)} // Create this function + style={{ minWidth: "24px", width: "100%" }} + /> +
+ +
+

{t("SELECT_ALL")}

+
+ )} + {filteredOptions.map((option, index) => ( + + ))} +
+ ); + // return filteredOptions?.map((option, index) => ); + }; + return ( +
+
+
+ setActive(true)} + value={searchQuery} + onChange={onSearch} + /> +
+

{alreadyQueuedSelectedState.length > 0 ? `${alreadyQueuedSelectedState.length} ${defaultUnit}` : defaultLabel}

+ +
+
+ {active ? ( +
+ +
+ ) : null} +
+ {config?.isDropdownWithChip ? ( +
+ {alreadyQueuedSelectedState.length > 0 && + alreadyQueuedSelectedState.map((value, index) => { + return ( + onSelectToAddToQueue(e, value, props) : (e) => onSelectToAddToQueue(e, value)} + /> + ); + })} +
+ ) : null} +
+ ); +}; + +export default MultiSelectDropdown; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectDateofEmployment.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectDateofEmployment.js new file mode 100644 index 000000000..1168e2855 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectDateofEmployment.js @@ -0,0 +1,54 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError, DatePicker } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; +import { convertEpochToDate } from "../Utils/index"; + +const SelectDateofEmployment = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + const inputs = [ + { + label: "HR_APPOINTMENT_DATE_LABEL", + type: "date", + name: "dateOfAppointment", + validation: { + isRequired: true, + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + isMandatory: true, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + + return ( +
+ {inputs?.map((input, index) => ( + + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e, input.name)} + disable={false} + {...input.validation} + defaultValue={undefined} + /> +
+
+
+ ))} +
+ ); +}; + +export default SelectDateofEmployment; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmailId.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmailId.js new file mode 100644 index 000000000..98cef560f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmailId.js @@ -0,0 +1,53 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeeEmailId = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + + const inputs = [ + { + label: "HR_EMAIL_LABEL", + type: "email", + name: "emailId", + validation: { + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + + return ( +
+ {inputs?.map((input, index) => { + let currentValue=formData && formData[config.key] && formData[config.key][input.name]||''; + return( + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e.target.value, input.name)} + disable={false} + defaultValue={undefined} + {...input.validation} + /> + {currentValue&¤tValue.length>0&&!currentValue.match(Digit.Utils.getPattern('Email'))&&{t("CS_PROFILE_EMAIL_ERRORMSG")}} +
+
+
+ )})} +
+ ); +}; + +export default SelectEmployeeEmailId; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeCorrespondenceAddress.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeCorrespondenceAddress.js new file mode 100644 index 000000000..e16a078d3 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeCorrespondenceAddress.js @@ -0,0 +1,54 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeeCorrespondenceAddress = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + const inputs = [ + { + label: "HR_CORRESPONDENCE_ADDRESS_LABEL", + type: "text", + name: "correspondenceAddress", + validation: { + pattern: Digit.Utils.getPattern('Address'), + isRequired: true, + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + isMandatory: true, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + + return ( +
+ {inputs?.map((input, index) => { + let currentValue=formData && formData[config.key] && formData[config.key][input.name]||''; + return( + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e.target.value, input.name)} + disable={false} + defaultValue={undefined} + {...input.validation} + /> + {currentValue&¤tValue.length>0&&!currentValue.match(Digit.Utils.getPattern('Address'))&&{t("CORE_COMMON_APPLICANT_ADDRESS_INVALID")}} +
+
+
+ )})} +
+ ); +}; + +export default SelectEmployeeCorrespondenceAddress; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeGender.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeGender.js new file mode 100644 index 000000000..9bbc15997 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeGender.js @@ -0,0 +1,82 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError, RadioButtons } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeeGender = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + + const inputs = [ + { + label: "HR_GENDER_LABEL", + type: "text", + name: "gender", + validation: { + isRequired: true, + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + isMandatory: true, + }, + ]; + + const tenantId = Digit.ULBService.getCurrentTenantId(); + const stateId = Digit.ULBService.getStateId(); + + const { data: Menu} = Digit.Hooks.hrms.useHRMSGenderMDMS(stateId, "common-masters", "GenderType"); + + let HRMenu = []; + + Menu && + Menu.map((comGender) => { + HRMenu.push({name: `COMMON_GENDER_${comGender.code}`, code: `${comGender.code}`}) + }); + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + + return ( +
+ {inputs?.map((input, index) => ( + + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e, input.name)} + disable={false} + defaultValue={undefined} + t={t} + {...input.validation} + /> +
+
+
+ ))} +
+ ); +}; + +export default SelectEmployeeGender; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeId.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeId.js new file mode 100644 index 000000000..bfd97abfb --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeId.js @@ -0,0 +1,50 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeeId = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + const isEdit = window.location.pathname.includes("/edit/"); + const inputs = [ + { + label: "HR_EMP_ID_LABEL", + type: "text", + name: "code", + validation: { + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + + return ( +
+ {inputs?.map((input, index) => ( + + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e.target.value, input.name)} + disable={isEdit} + defaultValue={undefined} + {...input.validation} + /> +
+
+
+ ))} +
+ ); +}; + +export default SelectEmployeeId; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeName.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeName.js new file mode 100644 index 000000000..3cc384f37 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeName.js @@ -0,0 +1,54 @@ +import React from "react"; +import { LabelFieldPair, CardLabel, TextInput, CardLabelError } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeeName = ({ t, config, onSelect, formData = {}, userType, register, errors }) => { + const { pathname: url } = useLocation(); + const inputs = [ + { + label: "HR_EMP_NAME_LABEL", + type: "text", + name: "employeeName", + validation: { + isRequired: true, + pattern: Digit.Utils.getPattern('Name'), + title: t("CORE_COMMON_APPLICANT_NAME_INVALID"), + }, + isMandatory: true, + }, + ]; + + function setValue(value, input) { + onSelect(config.key, { ...formData[config.key], [input]: value }); + } + + return ( +
+ {inputs?.map((input, index) => { + let currentValue=formData && formData[config.key] && formData[config.key][input.name]||''; + return( + {errors[input.name] && {t(input.error)}} + + + {t(input.label)} + {input.isMandatory ? " * " : null} + +
+ setValue(e.target.value, input.name)} + disable={false} + defaultValue={undefined} + {...input.validation} + /> + {currentValue&¤tValue.length>0&&!currentValue.match(Digit.Utils.getPattern('Name'))&&{t("CORE_COMMON_APPLICANT_NAME_INVALID")}} +
+
+
+ )})} +
+ ); +}; + +export default SelectEmployeeName; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeType.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeType.js new file mode 100644 index 000000000..9f7cde494 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/SelectEmployeeType.js @@ -0,0 +1,63 @@ +import React, { useState, useEffect } from "react"; +import { Loader } from "@egovernments/digit-ui-react-components"; +import { Dropdown, LabelFieldPair, CardLabel } from "@egovernments/digit-ui-react-components"; +import { useLocation } from "react-router-dom"; + +const SelectEmployeeType = ({ t, config, onSelect, formData = {}, userType }) => { + const tenantId = Digit.ULBService.getCurrentTenantId(); + + const { pathname: url } = useLocation(); + const editScreen = url.includes("/modify-application/"); + const { data: data = {}, isLoading } = Digit.Hooks.hrms.useHrmsMDMS(tenantId, "egov-hrms", "HRMSRolesandDesignation") || {}; + const [employeeType, setemployeeType] = useState(formData?.SelectEmployeeType); + const [employeeTypeData, setEmployeeTypeData] = useState([]); + + function SelectEmployeeType(value) { + setemployeeType(value); + } + useEffect(() => { + setEmployeeTypeData(data?.MdmsRes?.["egov-hrms"]?.EmployeeType?.filter((x) => x?.code === "PERMANENT")); + }, [data, data?.MdmsRes]); + + useEffect(() => { + onSelect(config.key, employeeTypeData?.length == 1 ? employeeTypeData[0] : employeeType); + }, [employeeTypeData]); + const inputs = [ + { + label: "HR_EMPLOYMENT_TYPE_LABEL", + type: "text", + name: "EmployeeType", + validation: { + isRequired: true, + }, + isMandatory: true, + }, + ]; + + if (isLoading) { + return ; + } + + return inputs?.map((input, index) => { + return ( + + + {t(input.label)} + {input.isMandatory ? " * " : null} + + 0 ? employeeTypeData[0] : employeeType} + option={employeeTypeData} + select={SelectEmployeeType} + disable={true} + optionKey="code" + defaultValue={undefined} + t={t} + /> + + ); + }); +}; + +export default SelectEmployeeType; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/assignment.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/assignment.js new file mode 100644 index 000000000..92abd194a --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/assignment.js @@ -0,0 +1,319 @@ +import { CardLabel, CheckBox, DatePicker, Dropdown, LabelFieldPair, Loader } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import cleanup from "../Utils/cleanup"; +import { convertEpochToDate } from "../Utils/index"; + +const makeDefaultValues = (sessionFormData) => { + return sessionFormData?.Assignments?.map((ele, index) => { + return { + key: index, + fromDate: ele.fromDate ? convertEpochToDate(ele.fromDate) : null, + toDate: ele.toDate ? convertEpochToDate(ele.toDate) : null, + isCurrentAssignment: ele?.isCurrentAssignment, + designation: { + code: ele?.designation, + i18key: ele.designation ? "COMMON_MASTERS_DESIGNATION_" + ele.designation : null, + }, + department: { + code: ele?.department, + i18key: ele.department ? "COMMON_MASTERS_DEPARTMENT_" + ele.department : null, + }, + }; + }); +}; + +const Assignments = ({ t, config, onSelect, userType, formData }) => { + const tenantId = Digit.ULBService.getCurrentTenantId(); + const { data: data = {}, isLoading } = Digit.Hooks.hrms.useHrmsMDMS(tenantId, "egov-hrms", "HRMSRolesandDesignation") || {}; + const [currentassignemtDate, setCurrentAssiginmentDate] = useState(null); + + const employeeCreateSession = Digit.Hooks.useSessionStorage("NEW_EMPLOYEE_CREATE", {}); + const [sessionFormData, setSessionFormData, clearSessionFormData] = employeeCreateSession; + const isEdit = window.location.href.includes("hrms/edit"); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + const [assignments, setassignments] = useState( + !isEdit && sessionFormData?.Assignments + ? makeDefaultValues(sessionFormData) + : formData?.Assignments || [ + { + key: 1, + fromDate: undefined, + toDate: undefined, + isCurrentAssignment: true, + department: "DWSS", + designation: null, + }, + ] + ); + const reviseIndexKeys = () => { + setassignments((prev) => prev.map((unit, index) => ({ ...unit, key: index }))); + }; + + function getdesignationdata() { + if (STATE_ADMIN) { + return data?.MdmsRes?.["common-masters"]?.Designation?.filter((obj) => obj.name === "Division Admin")?.map((ele) => { + ele["i18key"] = t("COMMON_MASTERS_DESIGNATION_" + ele.code); + return ele; + }); + } else { + return data?.MdmsRes?.["common-masters"]?.Designation?.map((ele) => { + ele["i18key"] = t("COMMON_MASTERS_DESIGNATION_" + ele.code); + return ele; + }); + } + } + + function getdepartmentdata() { + return data?.MdmsRes?.["common-masters"]?.Department?.map((ele) => { + ele["i18key"] = t("COMMON_MASTERS_DEPARTMENT_" + ele.code); + return ele; + }); + } + + const handleAddUnit = () => { + setassignments((prev) => [ + ...prev, + { + key: prev.length + 1, + fromDate: undefined, + toDate: undefined, + isCurrentAssignment: false, + department: null, + designation: null, + }, + ]); + }; + + const handleRemoveUnit = (unit) => { + setassignments((prev) => prev.filter((el) => el.key !== unit.key)); + if (FormData.errors?.Assignments?.type == unit.key) { + clearErrors("Jurisdictions"); + } + reviseIndexKeys(); + }; + + useEffect(() => { + var promises = assignments?.map((assignment) => { + return assignment + ? cleanup({ + id: assignment?.id, + position: assignment?.position, + govtOrderNumber: assignment?.govtOrderNumber, + tenantid: assignment?.tenantid, + auditDetails: assignment?.auditDetails, + fromDate: assignment?.fromDate ? new Date(assignment?.fromDate).getTime() : undefined, + toDate: assignment?.toDate ? new Date(assignment?.toDate).getTime() : undefined, + isCurrentAssignment: assignment?.isCurrentAssignment, + department: assignment?.department?.code || "DWSS", + designation: STATE_ADMIN + ? getdesignationdata()?.length > 0 && (getdesignationdata()[0]?.code || "DIV_ADMIN") + : assignment?.designation?.code, + }) + : []; + }); + Promise.all(promises).then(function (results) { + onSelect( + config.key, + results.filter((value) => Object.keys(value).length !== 0) + ); + }); + + assignments.map((ele) => { + if (ele.isCurrentAssignment) { + setCurrentAssiginmentDate(ele.fromDate); + } + }); + }, [assignments]); + + let department = []; + let designation = []; + const [focusIndex, setFocusIndex] = useState(-1); + if (isLoading) { + return ; + } + return ( +
+ {assignments?.map((assignment, index) => ( + + ))} + {/* */} +
+ ); +}; +function Assignment({ + t, + assignment, + assignments, + setassignments, + index, + focusIndex, + setFocusIndex, + getdepartmentdata, + department, + formData, + handleRemoveUnit, + designation, + getdesignationdata, + setCurrentAssiginmentDate, + currentassignemtDate, +}) { + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + const selectDepartment = (value) => { + setassignments((pre) => pre.map((item) => (item.key === assignment.key ? { ...item, department: getdepartmentdata(department)[0] } : item))); + }; + const selectDesignation = (value) => { + setassignments((pre) => pre.map((item) => (item.key === assignment.key ? { ...item, designation: value } : item))); + }; + + const onAssignmentChange = (value) => { + setassignments((pre) => + pre.map((item) => (item.key === assignment.key ? { ...item, isCurrentAssignment: value } : { ...item, isCurrentAssignment: false })) + ); + if (value) { + setassignments((pre) => + pre.map((item) => + item.key === assignment.key + ? { + ...item, + toDate: null, + } + : item + ) + ); + assignments.map((ele) => { + if (ele.key == assignment.key) { + setCurrentAssiginmentDate(ele.fromDate); + } + }); + } else { + setCurrentAssiginmentDate(null); + } + }; + const onIsHODchange = (value) => { + setassignments((pre) => pre.map((item) => (item.key === assignment.key ? { ...item, isHOD: value } : item))); + }; + + const ValidateDatePickers = (value) => { + assignments; + }; + return ( +
+
+ +
+

+ {t("HR_ASSIGNMENT")} {index + 1} +

+
+ {assignments.length > 1 && !assignment?.id && !assignment?.isCurrentAssignment ? ( +
handleRemoveUnit(assignment)} style={{ marginBottom: "16px", padding: "5px", cursor: "pointer", textAlign: "right" }}> + X +
+ ) : null} +
+ + + {`${t("HR_ASMT_FROM_DATE_LABEL")} * `} +
+ { + setassignments((pre) => pre.map((item) => (item.key === assignment.key ? { ...item, fromDate: e } : item))); + setFocusIndex(index); + }} + date={assignment?.fromDate} + autoFocus={focusIndex === index} + /> +
+
+ + + {t("HR_ASMT_TO_DATE_LABEL")} + {assignment?.isCurrentAssignment ? "" : " * "}{" "} + +
+ { + setassignments((pre) => pre.map((item) => (item.key === assignment.key ? { ...item, toDate: e } : item))); + setFocusIndex(index); + }} + date={assignment?.toDate} + autoFocus={focusIndex === index} + /> +
+
+ + + + . + +
+ onAssignmentChange(e.target.checked)} + checked={assignment?.isCurrentAssignment} + label={t("HR_CURRENTLY_ASSIGNED_HERE_SWITCH_LABEL")} + /> +
+
+ + {`${t("HR_DEPT_LABEL")} * `} + + + + + {`${t("HR_DESG_LABEL")} * `} + + +
+
+ ); +} + +export default Assignments; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/jurisdiction.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/jurisdiction.js new file mode 100644 index 000000000..5a406bce8 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/components/pageComponents/jurisdiction.js @@ -0,0 +1,633 @@ +import { CardLabel, Dropdown, LabelFieldPair, Loader, RemoveableTag } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import cleanup from "../Utils/cleanup"; +import MultiSelectDropdown from "./Multiselect"; + +const makeDefaultValues = (sessionFormData) => { + return sessionFormData?.Jurisdictions?.map((ele, index) => { + return { + key: index, + hierarchy: { + code: ele?.hierarchy, + name: ele?.hierarchy, + }, + boundaryType: { label: ele?.boundaryType, i18text: ele.boundaryType ? `EGOV_LOCATION_BOUNDARYTYPE_${ele.boundaryType?.toUpperCase()}` : null }, + boundary: { code: ele?.boundary }, + divisionBoundary: ele?.divisionBoundary, + division: ele?.division, + roles: ele?.roles, + }; + }); +}; + +const Jurisdictions = ({ t, config, onSelect, userType, formData }) => { + const tenantId = Digit.ULBService.getCurrentTenantId(); + const [inactiveJurisdictions, setInactiveJurisdictions] = useState([]); + const { data: data = {}, isLoading } = Digit.Hooks.hrms.useHrmsMDMS(tenantId, "egov-hrms", "HRMSRolesandDesignation") || {}; + const userDetails = Digit.UserService.getUser(); + const uuids = [userDetails?.info?.uuid]; + const { data: userData, isUserDataLoading } = Digit.Hooks.useUserSearch(Digit.ULBService.getStateId(), { uuid: uuids }, {}); + + const employeeCreateSession = Digit.Hooks.useSessionStorage("NEW_EMPLOYEE_CREATE", {}); + const [sessionFormData, setSessionFormData, clearSessionFormData] = employeeCreateSession; + const isEdit = window.location.href?.includes("hrms/edit"); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + const [Boundary, selectboundary] = useState([]); + const [jurisdictions, setjurisdictions] = useState( + !isEdit && sessionFormData?.Jurisdictions?.length > 0 + ? makeDefaultValues(sessionFormData) + : formData?.Jurisdictions || [ + { + id: undefined, + key: 1, + hierarchy: null, + boundaryType: null, + boundary: null, + division: {}, + divisionBoundary: [], + roles: [], + }, + ] + ); + const [jurisdictionsData, setJuristictionsData] = useState([]); + let hierarchylist = []; + // const hierarchyData = data?.MdmsRes?.["egov-location"]["TenantBoundary"].filter((ele) => ele?.hierarchyType?.code == "REVENUE")[0]?.hierarchyType; + // hierarchylist.push(hierarchyData); + + let divisions = []; + divisions = data?.MdmsRes?.["tenant"]["tenants"] + ?.filter((items) => items?.divisionCode) + ?.map((item) => { + return { + code: item.divisionCode, + name: item.divisionName, + i18text: Digit.Utils.locale.getCityLocale(item.divisionCode), + }; + }); + const uniqueDivisions = divisions?.reduce((unique, obj) => { + const isDuplicate = unique.some((item) => item.id === obj.id && item.name === obj.name); + if (!isDuplicate) { + unique.push(obj); + } + return unique; + }, []); + + useEffect(() => { + let cities = userData?.user[0]?.roles?.map((role) => role.tenantId)?.filter((value, index, array) => array.indexOf(value) === index); + + selectboundary( + data?.MdmsRes?.tenant?.tenants + ?.filter((city) => city.code != Digit.ULBService.getStateId() && cities?.includes(city.code)) + ?.map((city) => { + return { ...city, i18text: Digit.Utils.locale.getCityLocale(city.code) }; + }) + ); + }, [data, userData]); + + useEffect(() => { + let jurisdictionData = jurisdictions?.map((jurisdiction) => { + let res = { + id: jurisdiction?.id, + hierarchy: jurisdiction?.boundary?.code, + boundaryType: "City", + boundary: jurisdiction?.boundary?.code, + tenantId: STATE_ADMIN ? jurisdiction?.divisionBoundary && jurisdiction?.divisionBoundary[0]?.code : jurisdiction?.boundary?.code, + auditDetails: jurisdiction?.auditDetails, + division: jurisdiction?.division, + }; + res = cleanup(res); + if (jurisdiction?.roles) { + res["roles"] = jurisdiction?.roles.map((ele) => { + delete ele.description; + return ele; + }); + } + if (jurisdiction?.divisionBoundary) { + res["divisionBoundary"] = jurisdiction?.divisionBoundary; + } + if (isEdit && STATE_ADMIN) { + data?.MdmsRes?.["tenant"]["tenants"]?.map((items) => { + if (items?.code === jurisdiction?.boundary?.code) { + res["division"] = { + code: items?.divisionCode, + i18text: Digit.Utils.locale.convertToLocale(items?.divisionCode, "EGOV_LOCATION_DIVISION"), + }; + res["divisionBoundary"] = [ + { + name: items.name, + code: items.code, + i18text: Digit.Utils.locale.getCityLocale(items.code), + }, + ]; + } + }); + } + return res; + }); + if (isEdit && STATE_ADMIN) { + let divisionData = []; + if (isEdit && jurisdictionData.length > 0) { + jurisdictionData?.map((jurisdiction) => { + if (jurisdiction?.divisionBoundary && jurisdiction?.divisionBoundary?.length > 0 && divisionData.length === 0) { + divisionData.push(jurisdiction); + } else if (divisionData.length > 0) { + if (divisionData[divisionData.length - 1]?.division?.code !== jurisdiction?.division?.code) { + divisionData.push(jurisdiction); + } + } + }); + } + + let finalData = []; + divisionData && + divisionData?.length > 0 && + divisionData?.map((data, index) => { + let divisionBoundarydata = []; + jurisdictionData?.map((jurisdiction) => { + if (data?.division?.code === jurisdiction?.division?.code) { + if (divisionBoundarydata?.length === 0) { + jurisdiction?.divisionBoundary[0] !== undefined && divisionBoundarydata.push(jurisdiction?.divisionBoundary[0]); + } else if (divisionBoundarydata?.length > 0) { + if (divisionBoundarydata[divisionBoundarydata?.length - 1]?.code !== jurisdiction?.divisionBoundary[0]) { + jurisdiction?.divisionBoundary[0] !== undefined && divisionBoundarydata.push(jurisdiction?.divisionBoundary[0]); + } + } + } + }); + let obj = { + ...data, + key: index, + divisionBoundary: divisionBoundarydata, + }; + finalData.push(obj); + }); + + jurisdictionData = finalData; + } + setJuristictionsData(jurisdictionData); + onSelect( + config.key, + [...jurisdictionData, ...inactiveJurisdictions].filter((value) => Object.keys(value).length !== 0) + ); + }, [jurisdictions, data?.MdmsRes]); + // useEffect(() => { + // setJuristictionsData(formData?.Jurisdictions); + // }, [formData?.Jurisdictions, jurisdictions]); + + const reviseIndexKeys = () => { + setjurisdictions((prev) => prev.map((unit, index) => ({ ...unit, key: index }))); + }; + + const handleAddUnit = () => { + setjurisdictions((prev) => [ + ...prev, + { + key: prev.length + 1, + hierarchy: null, + boundaryType: null, + boundary: null, + division: null, + divisionBoundary: [], + roles: [], + }, + ]); + }; + const handleRemoveUnit = (unit) => { + if (unit.id) { + let res = { + id: unit?.id, + hierarchy: unit?.hierarchy?.code, + boundaryType: unit?.boundaryType?.label, + boundary: unit?.boundary?.code, + division: unit?.division?.code, + tenantId: unit?.boundary?.code, + auditDetails: unit?.auditDetails, + isdeleted: true, + isActive: false, + }; + res = cleanup(res); + if (unit?.roles) { + res["roles"] = unit?.roles.map((ele) => { + delete ele.description; + return ele; + }); + } + setInactiveJurisdictions([...inactiveJurisdictions, res]); + } + setJuristictionsData((pre) => pre.filter((el) => el.key !== unit.key)); + setjurisdictions((prev) => prev.filter((el) => el.key !== unit.key)); + if (FormData.errors?.Jurisdictions?.type == unit.key) { + clearErrors("Jurisdictions"); + } + reviseIndexKeys(); + }; + let boundaryTypeoption = []; + const [focusIndex, setFocusIndex] = useState(-1); + + function getroledata() { + if (STATE_ADMIN) { + // Specify the role codes you want to filter + const roleCodesToFilter = ["HRMS_ADMIN", "EMPLOYEE", "DIV_ADMIN"]; + // Use the filter method to extract roles with the specified codes + return data?.MdmsRes?.["ws-services-masters"]["WSServiceRoles"] + .filter((role) => { + return roleCodesToFilter.includes(role.code); + }) + .map((role) => { + return { code: role.code, name: role?.name ? role?.name : " ", labelKey: "ACCESSCONTROL_ROLES_ROLES_" + role.code }; + }); + } else { + // Specify the role codes you want to filter + const roleCodesToFilter = ["HRMS_ADMIN", "DIV_ADMIN", "MDMS_ADMIN", "LOC_ADMIN", "SYSTEM"]; + // Use the filter method to extract roles with the specified codes + return data?.MdmsRes?.["ws-services-masters"].WSServiceRoles?.filter((role) => { + return !roleCodesToFilter.includes(role.code); + })?.map((role) => { + return { code: role.code, name: role?.name ? role?.name : " ", labelKey: "ACCESSCONTROL_ROLES_ROLES_" + role.code }; + }); + } + } + if (isLoading && isUserDataLoading) { + return ; + } + return ( +
+ {isEdit && STATE_ADMIN ? ( + + {jurisdictionsData?.map((jurisdiction, index) => ( + + ))} + + ) : ( + jurisdictions?.map((jurisdiction, index) => ( + + )) + )} + +
+ ); +}; +// ------------------------------------------------------------------------------------- +function Jurisdiction({ + t, + formData, + data, + userDetails, + jurisdiction, + jurisdictions, + setjurisdictions, + setJuristictionsData, + jurisdictionsData, + onSelect, + config, + handleRemoveUnit, + hierarchylist, + divisions, + getroledata, + roleoption, + index, + Boundary, +}) { + const [BoundaryType, selectBoundaryType] = useState([]); + // const [Boundary, selectboundary] = useState([]); + const [divisionBoundary, setDivisionBoundary] = useState([]); + const [Division, setDivision] = useState([]); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + let isMobile = window.Digit.Utils.browser.isMobile(); + const isEdit = window.location.href?.includes("hrms/edit"); + + // useEffect(() => { + // selectBoundaryType( + // data?.MdmsRes?.["egov-location"]["TenantBoundary"] + // .filter((ele) => { + // return ele?.hierarchyType?.code == hierarchylist[0]?.code; + // }) + // .map((item) => { + // return { ...item.boundary, i18text: Digit.Utils.locale.convertToLocale(item.boundary.label, "EGOV_LOCATION_BOUNDARYTYPE") }; + // }) + // ); + // }, [jurisdiction?.hierarchy, data?.MdmsRes]); + + useEffect(() => { + setDivision( + divisions?.map((item) => { + return { ...item, i18text: Digit.Utils.locale.convertToLocale(item.code, "EGOV_LOCATION_DIVISION") }; + }) + ); + }, [divisions]); + + const tenant = Digit.ULBService.getCurrentTenantId(); + // useEffect(() => { + // console.log("ssss") + // let cities = userDetails?.roles.map((role) => role.tenantId)?.filter((value, index, array) => array.indexOf(value) === index); + // selectboundary( + // data?.MdmsRes?.tenant?.tenants + // ?.filter((city) => city.code != Digit.ULBService.getStateId() && cities?.includes(city.code)) + // ?.map((city) => { + // return { ...city, i18text: Digit.Utils.locale.getCityLocale(city.code) }; + // }) + // ); + // }, [data]); + + useEffect(() => { + if (Boundary?.length > 0) { + selectedboundary(Boundary?.filter((ele) => ele.code == jurisdiction?.boundary?.code)[0]); + } + }, [Boundary]); + const selectHierarchy = (value) => { + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, hierarchy: value } : item))); + }; + + const selectboundaryType = (value) => { + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, boundaryType: value } : item))); + }; + + const selectedboundary = (value) => { + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, boundary: value } : item))); + }; + + const selectDivision = (value) => { + // Extract projects using array methods + const project = data?.MdmsRes?.["tenant"]["tenants"].filter((obj) => obj.divisionCode === value.code); + const finalProjects = project?.map((project) => ({ + name: project.name, + code: project.code, + i18text: Digit.Utils.locale.getCityLocale(project.code), + })); + setDivisionBoundary(finalProjects); + if (isEdit && STATE_ADMIN) { + setJuristictionsData((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, division: value, divisionBoundary: [] } : item))); + let data = jurisdictionsData?.map((items, index) => { + let obj = {}; + if (index === jurisdiction?.key) { + obj = { + ...items, + division: value, + divisionBoundary: [], + }; + } else { + obj = { ...items }; + } + return obj; + }); + onSelect( + config.key, + [...data].filter((value) => Object.keys(value).length !== 0) + ); + } else { + setjurisdictions((pre) => pre.map((item) => (item.key == jurisdiction.key ? { ...item, division: value, divisionBoundary: [] } : item))); + } + }; + + const getboundarydata = (value) => { + // Extract projects using array methods + const project = data?.MdmsRes?.["tenant"]["tenants"].filter((obj) => obj.divisionCode === value?.code); + const finalProjects = project?.map((project) => ({ + name: project.name, + code: project.code, + i18text: Digit.Utils.locale.getCityLocale(project.code), + })); + return finalProjects; + }; + const selectrole = (e) => { + let res = []; + e && + e?.map((ob) => { + res.push(ob?.[1]); + }); + + res?.forEach((resData) => { + resData.labelKey = "ACCESSCONTROL_ROLES_ROLES_" + resData.code; + }); + + if (isEdit && STATE_ADMIN) setJuristictionsData((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, roles: res } : item))); + let data = jurisdictionsData?.map((items, index) => { + let obj = {}; + if (index === jurisdiction?.key) { + obj = { + ...items, + roles: res, + }; + } else { + obj = { ...items }; + } + return obj; + }); + if (isEdit && STATE_ADMIN) + onSelect( + config?.key, + [...data].filter((value) => Object.keys(value).length !== 0) + ); + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, roles: res } : item))); + }; + + const selectDivisionBoundary = (e) => { + let res = []; + e && + e?.map((ob) => { + res.push(ob?.[1]); + }); + if (isEdit && STATE_ADMIN) { + setJuristictionsData((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, divisionBoundary: res } : item))); + let data = jurisdictionsData?.map((items, index) => { + let obj = {}; + if (index === jurisdiction?.key) { + obj = { + ...items, + divisionBoundary: res, + }; + } else { + obj = { ...items }; + } + return obj; + }); + onSelect( + config.key, + [...data].filter((value) => Object.keys(value).length !== 0) + ); + } else { + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, divisionBoundary: res } : item))); + } + }; + + const onRemove = (index, key) => { + let afterRemove = jurisdiction?.roles.filter((value, i) => { + return i !== index; + }); + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, roles: afterRemove } : item))); + }; + + const onRemoveBoundary = (index) => { + let afterRemove = jurisdiction?.divisionBoundary.filter((value, i) => { + return i !== index; + }); + if (isEdit && STATE_ADMIN) { + setJuristictionsData((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, divisionBoundary: afterRemove } : item))); + let data = jurisdictionsData?.map((items, index) => { + let obj = {}; + if (index === jurisdiction?.key) { + obj = { + ...items, + divisionBoundary: afterRemove, + }; + } else { + obj = { ...items }; + } + return obj; + }); + onSelect( + config.key, + [...data].filter((value) => Object.keys(value).length !== 0) + ); + } else { + setjurisdictions((pre) => pre.map((item) => (item.key === jurisdiction.key ? { ...item, divisionBoundary: afterRemove } : item))); + } + }; + return ( +
+
+ +
+

+ {t("HR_JURISDICTION")} {index + 1} +

+
+ {jurisdictions.length > 1 ? ( +
handleRemoveUnit(jurisdiction)} + style={{ marginBottom: "16px", padding: "5px", cursor: "pointer", textAlign: "right" }} + > + X +
+ ) : null} +
+ {STATE_ADMIN ? ( + + + {`${t("HR_DIVISIONS_LABEL")} * `} + + +
+ {`${t("HR_BOUNDARY_LABEL")} * `} +
+ +
0 && "50px", overflowY: "scroll" }}> + {jurisdiction?.divisionBoundary?.length > 0 && + jurisdiction?.divisionBoundary[0] !== undefined && + jurisdiction?.divisionBoundary?.map((value, index) => { + return ( + onRemoveBoundary(index, value)} /> + ); + })} +
+
+
+
+ ) : ( + + + {`${t("HR_BOUNDARY_LABEL")} * `} + + +
+ {t("HR_COMMON_TABLE_COL_ROLE")} * +
+ +
+ {jurisdiction?.roles.length > 0 && + jurisdiction?.roles.map((value, index) => { + return onRemove(index, value)} />; + })} +
+
+
+
+ )} +
+
+ ); +} + +export default Jurisdictions; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EditEmployee/EditForm.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EditEmployee/EditForm.js new file mode 100644 index 000000000..68a576d10 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EditEmployee/EditForm.js @@ -0,0 +1,318 @@ +import { FormComposer, Toast, Loader } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import { newConfig } from "../../components/config/config"; +import { convertEpochToDate } from "../../components/Utils"; + +const EditForm = ({ tenantId, data }) => { + const { t } = useTranslation(); + const history = useHistory(); + const [canSubmit, setSubmitValve] = useState(false); + const [showToast, setShowToast] = useState(null); + const [mobileNumber, setMobileNumber] = useState(null); + const [phonecheck, setPhonecheck] = useState(false); + const [checkfield, setcheck] = useState(false); + const { data: mdmsData, isLoading } = Digit.Hooks.useCommonMDMS(Digit.ULBService.getStateId(), "egov-hrms", ["CommonFieldsConfig"], { + select: (data) => { + return { + config: data?.MdmsRes?.["egov-hrms"]?.CommonFieldsConfig, + }; + }, + retry: false, + enable: false, + }); + const [errorInfo, setErrorInfo, clearError] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_ERROR_DATA", false); + const [mutationHappened, setMutationHappened, clear] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_HAPPENED", false); + const [successData, setsuccessData, clearSuccessData] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_SUCCESS_DATA", false); + + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + useEffect(() => { + setMutationHappened(false); + clearSuccessData(); + clearError(); + }, []); + + useEffect(() => { + if (mobileNumber && mobileNumber.length == 10 && mobileNumber?.match(Digit.Utils.getPattern("MobileNo"))) { + setShowToast(null); + if (data.user.mobileNumber == mobileNumber) { + setPhonecheck(true); + } else { + Digit.HRMSService?.search(tenantId, null, { phone: mobileNumber })?.then((result, err) => { + if (result.Employees.length > 0) { + setShowToast({ key: true, label: "ERR_HRMS_USER_EXIST_MOB" }); + setPhonecheck(false); + } else { + setPhonecheck(true); + } + }); + } + } else { + setPhonecheck(false); + } + }, [mobileNumber]); + + let defaultValues = { + tenantId: tenantId, + employeeStatus: "EMPLOYED", + employeeType: data?.code, + SelectEmployeePhoneNumber: { mobileNumber: data?.user?.mobileNumber }, + SelectEmployeeId: { code: data?.code }, + SelectEmployeeName: { employeeName: data?.user?.name }, + SelectEmployeeEmailId: { emailId: data?.user?.emailId }, + SelectEmployeeCorrespondenceAddress: { correspondenceAddress: data?.user?.correspondenceAddress }, + SelectDateofEmployment: { dateOfAppointment: convertEpochToDate(data?.dateOfAppointment) }, + SelectEmployeeType: { code: data?.employeeType, active: true }, + SelectEmployeeGender: { + gender: { + code: data?.user?.gender, + name: `COMMON_GENDER_${data?.user?.gender}`, + }, + }, + + SelectDateofBirthEmployment: { dob: convertEpochToDate(data?.user?.dob) }, + Jurisdictions: data?.jurisdictions?.map((ele, index) => { + let obj = { + key: index, + hierarchy: { + code: ele.hierarchy, + name: ele.hierarchy, + }, + boundaryType: { label: ele.boundaryType, i18text: `EGOV_LOCATION_BOUNDARYTYPE_${ele.boundaryType.toUpperCase()}` }, + boundary: { code: ele.boundary }, + roles: data?.user?.roles?.filter((item) => item.tenantId == ele.boundary), + division: {}, + divisionBoundary: [], + }; + + return obj; + }), + Assignments: data?.assignments?.map((ele, index) => { + return Object.assign({}, ele, { + key: index, + fromDate: convertEpochToDate(ele.fromDate), + toDate: convertEpochToDate(ele.toDate), + isCurrentAssignment: ele.isCurrentAssignment, + designation: { + code: ele.designation, + i18key: "COMMON_MASTERS_DESIGNATION_" + ele.designation, + }, + department: { + code: ele.department, + i18key: "COMMON_MASTERS_DEPARTMENT_" + ele.department, + }, + }); + }), + }; + const checkMailNameNum = (formData) => { + const email = formData?.SelectEmployeeEmailId?.emailId || ""; + const name = formData?.SelectEmployeeName?.employeeName || ""; + const validEmail = email.length == 0 ? true : email.match(Digit.Utils.getPattern("Email")); + return validEmail && name.match(Digit.Utils.getPattern("Name")); + }; + + const onFormValueChange = (setValue = true, formData) => { + if (formData?.SelectEmployeePhoneNumber?.mobileNumber) { + setMobileNumber(formData?.SelectEmployeePhoneNumber?.mobileNumber); + } else { + setMobileNumber(formData?.SelectEmployeePhoneNumber?.mobileNumber); + } + + for (let i = 0; i < formData?.Jurisdictions?.length; i++) { + let key = formData?.Jurisdictions[i]; + if (!((key?.boundary || key?.divisionBoundary) && (key?.boundaryType || key?.division))) { + setcheck(false); + break; + } else { + if (!STATE_ADMIN) { + key?.roles?.length > 0 && setcheck(true); + } else if (STATE_ADMIN) { + setcheck(true); + } + } + } + + if ( + formData?.SelectEmployeeGender?.gender.code && + formData?.SelectEmployeeName?.employeeName && + formData?.SelectEmployeePhoneNumber?.mobileNumber && + checkfield && + // setassigncheck && + phonecheck && + checkMailNameNum(formData) + ) { + setSubmitValve(true); + } else { + setSubmitValve(false); + } + }; + + const onSubmit = (input) => { + if (!STATE_ADMIN && input.Jurisdictions.filter((juris) => juris.tenantId == tenantId && juris.isActive !== false).length == 0) { + setShowToast({ key: true, label: "ERR_BASE_TENANT_MANDATORY" }); + return; + } else if (!STATE_ADMIN && input.Jurisdictions.filter((juris) => !juris?.roles?.length).length > 0) { + setShowToast({ key: true, label: "Atleast one Role should be selected per Jurisdiction" }); + return; + } + if ( + !Object.values( + input.Jurisdictions.reduce((acc, sum) => { + if (sum && sum?.tenantId) { + acc[sum.tenantId] = acc[sum.tenantId] ? acc[sum.tenantId] + 1 : 1; + } + return acc; + }, {}) + ).every((s) => s == 1) + ) { + setShowToast({ key: true, label: "ERR_INVALID_JURISDICTION" }); + return; + } + let roles = []; + let jurisdictions = []; + if (STATE_ADMIN) { + const divisionBoundaryCodes = input?.Jurisdictions.flatMap((j) => j.divisionBoundary.map((item) => item.code)); + let stateRoles = [ + { + code: "EMPLOYEE", + name: "EMPLOYEE", + labelKey: "ACCESSCONTROL_ROLES_ROLES_EMPLOYEE", + }, + { + code: "DIV_ADMIN", + name: "DIVISION ADMIN", + labelKey: "ACCESSCONTROL_ROLES_ROLES_DIV_ADMIN", + }, + { + code: "HRMS_ADMIN", + name: "HRMS_ADMIN", + labelKey: "ACCESSCONTROL_ROLES_ROLES_HRMS_ADMIN", + }, + { + code: "MDMS_ADMIN", + name: "MDMS Admin", + description: "Mdms admin", + }, + ]; + divisionBoundaryCodes && + divisionBoundaryCodes.length > 0 && + divisionBoundaryCodes.map((item) => { + stateRoles?.map((role) => { + roles.push({ + code: role.code, + name: role.name, + labelKey: role.labelKey, + tenantId: item, + }); + }); + }); + input?.Jurisdictions?.map((items) => { + items?.divisionBoundary.map((item) => { + let obj = { + hierarchy: "REVENUE", + boundaryType: "City", + boundary: item?.code, + tenantId: item?.code, + roles: items.roles, + }; + data?.jurisdictions?.map((jurisdition) => { + if (jurisdition?.boundary === item?.code) { + obj["id"] = jurisdition.id; + obj["auditDetails"] = jurisdition.auditDetails; + } + }); + jurisdictions.push(obj); + }); + }); + // Map the data and add tenantId to roles array + const mappedData = jurisdictions.map((jurisdiction, index) => { + return { + ...jurisdiction, + roles: stateRoles.map((role) => ({ + ...role, + tenantId: jurisdiction.tenantId, + })), + }; + }); + + jurisdictions = mappedData; + } else { + input.Jurisdictions.map((items) => { + let obj = { + hierarchy: items?.hierarchy, + boundaryType: items?.boundaryType, + boundary: items?.boundary, + tenantId: items?.tenantId, + roles: items?.roles, + }; + data?.jurisdictions?.map((jurisdition) => { + if (jurisdition?.boundary === items?.boundary) { + obj["id"] = jurisdition.id; + obj["auditDetails"] = jurisdition.auditDetails; + } + }); + jurisdictions.push(obj); + }); + roles = input?.Jurisdictions?.map((ele) => { + return ele.roles?.map((item) => { + item["tenantId"] = ele.boundary; + return item; + }); + }); + } + let requestdata = Object.assign({}, data); + roles = [].concat.apply([], roles); + requestdata.assignments = input?.Assignments ? input?.Assignments : data?.assignments; + requestdata.dateOfAppointment = Date.parse(input?.SelectDateofEmployment?.dateOfAppointment); + requestdata.code = input?.SelectEmployeeId?.code ? input?.SelectEmployeeId?.code : data?.code; + requestdata.jurisdictions = jurisdictions; + requestdata.user.emailId = input?.SelectEmployeeEmailId?.emailId ? input?.SelectEmployeeEmailId?.emailId : undefined; + requestdata.user.gender = input?.SelectEmployeeGender?.gender.code; + requestdata.user.dob = Date.parse(input?.SelectDateofBirthEmployment?.dob) || data?.user?.dob; + requestdata.user.mobileNumber = input?.SelectEmployeePhoneNumber?.mobileNumber; + requestdata["user"]["name"] = input?.SelectEmployeeName?.employeeName; + requestdata.user.correspondenceAddress = input?.SelectEmployeeCorrespondenceAddress?.correspondenceAddress; + requestdata.user.roles = roles.filter((role) => role && role.name); + let Employees = [requestdata]; + + /* use customiseUpdateFormData hook to make some chnages to the Employee object */ + Employees = Digit?.Customizations?.HRMS?.customiseUpdateFormData ? Digit.Customizations.HRMS.customiseUpdateFormData(data, Employees) : Employees; + history.replace(`/${window?.contextPath}/employee/hrms/response`, { Employees, key: "UPDATE", action: "UPDATE" }); + }; + if (isLoading) { + return ; + } + + const config = mdmsData?.config ? mdmsData.config : newConfig; + + return ( +
+ { + return { + ...config, + body: config.body.filter((a) => !a.hideInEmployee), + }; + })} + fieldStyle={{ marginRight: 0 }} + onSubmit={onSubmit} + defaultValues={defaultValues} + onFormValueChange={onFormValueChange} + />{" "} + {showToast && ( + { + setShowToast(null); + }} + /> + )} +
+ ); +}; +export default EditForm; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EditEmployee/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EditEmployee/index.js new file mode 100644 index 000000000..2cfa645c1 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EditEmployee/index.js @@ -0,0 +1,16 @@ +import React, { useState } from "react"; +import { useParams } from "react-router-dom"; +import EditForm from "./EditForm"; +import { Loader } from "@egovernments/digit-ui-react-components"; +const EditEmpolyee = ({ parentUrl, heading }) => { + const isupdate = Digit.SessionStorage.get("isupdate"); + const { id: employeeId } = useParams(); + const { tenantId: tenantId } = useParams(); + const { isLoading, isError, error, data, ...rest } = Digit.Hooks.hrms.useHRMSSearch({ codes: employeeId }, tenantId, isupdate); + if (isLoading) { + return ; + } + return ; +}; + +export default EditEmpolyee; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EmployeeDetails.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EmployeeDetails.js new file mode 100644 index 000000000..44d54f83a --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/EmployeeDetails.js @@ -0,0 +1,233 @@ +import { + ActionBar, + Card, + CardSubHeader, + DocumentSVG, + Header, + Loader, + Menu, + Row, + StatusTable, + SubmitBar, +} from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory, useParams } from "react-router-dom"; +import ActionModal from "../components/Modal"; +import { convertEpochFormateToDate, pdfDownloadLink } from "../components/Utils"; + +const Details = () => { + const activeworkflowActions = ["DEACTIVATE_EMPLOYEE_HEAD", "COMMON_EDIT_EMPLOYEE_HEADER"]; + const deactiveworkflowActions = ["ACTIVATE_EMPLOYEE_HEAD"]; + const [selectedAction, setSelectedAction] = useState(null); + const [showModal, setShowModal] = useState(false); + const { t } = useTranslation(); + const { id: employeeId } = useParams(); + const { tenantId: tenantId } = useParams(); + const history = useHistory(); + const [displayMenu, setDisplayMenu] = useState(false); + const isupdate = Digit.SessionStorage.get("isupdate"); + const { isLoading, isError, error, data, ...rest } = Digit.Hooks.hrms.useHRMSSearch({ codes: employeeId }, tenantId, null, isupdate); + const [errorInfo, setErrorInfo, clearError] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_ERROR_DATA", false); + const [mutationHappened, setMutationHappened, clear] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_HAPPENED", false); + const [successData, setsuccessData, clearSuccessData] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_SUCCESS_DATA", false); + const isMobile = window.Digit.Utils.browser.isMobile(); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + const { data: mdmsData = {} } = Digit.Hooks.hrms.useHrmsMDMS(tenantId, "egov-hrms", "HRMSRolesandDesignation") || {}; + + mdmsData?.MdmsRes?.["tenant"]["tenants"]?.map((items) => { + data?.Employees[0]?.jurisdictions?.map((jurisdiction) => { + if (items?.code === jurisdiction?.boundary) { + jurisdiction["division"] = items?.divisionCode; + } + }); + }); + useEffect(() => { + setMutationHappened(false); + clearSuccessData(); + clearError(); + }, []); + + function onActionSelect(action) { + setSelectedAction(action); + setDisplayMenu(false); + } + + const closeModal = () => { + setSelectedAction(null); + setShowModal(false); + }; + const handleDownload = async (document) => { + const res = await Digit.UploadServices.Filefetch([document?.documentId], Digit.ULBService.getStateId()); + let documentLink = pdfDownloadLink(res.data, document?.documentId); + window.open(documentLink, "_blank"); + }; + + const submitAction = (data) => {}; + + useEffect(() => { + switch (selectedAction) { + case "DEACTIVATE_EMPLOYEE_HEAD": + return setShowModal(true); + case "ACTIVATE_EMPLOYEE_HEAD": + return setShowModal(true); + case "COMMON_EDIT_EMPLOYEE_HEADER": + return history.push(`/${window?.contextPath}/employee/hrms/edit/${tenantId}/${employeeId}`); + default: + break; + } + }, [selectedAction]); + + if (isLoading) { + return ; + } + + return ( + +
+
{t("HR_NEW_EMPLOYEE_FORM_HEADER")}
+
+ {!isLoading && data?.Employees.length > 0 ? ( +
+ + + {t("HR_EMP_STATUS_LABEL")} } + text={ + data?.Employees?.[0]?.isActive ? ( +
{t("ACTIVE")}
+ ) : ( +
{t("INACTIVE")}
+ ) + } + textStyle={{ fontWeight: "bold", maxWidth: "7rem" }} + /> +
+ {t("HR_PERSONAL_DETAILS_FORM_HEADER")} + + + + + + + {data?.Employees?.[0]?.isActive == false ? ( + + new Date(a.effectiveFrom) - new Date(b.effectiveFrom))[0]?.effectiveFrom + )} + /> + new Date(a.effectiveFrom) - new Date(b.effectiveFrom))[0] + .reasonForDeactivation + ) || "NA" + } + /> + new Date(a.effectiveFrom) - new Date(b.effectiveFrom))[0].remarks || + "NA" + } + /> + + new Date(a.effectiveFrom) - new Date(b.effectiveFrom))[0]?.orderNo || + "NA" + } + /> + + ) : null} + + {data?.Employees?.[0]?.documents ? ( + + +
+ {data?.Employees?.[0]?.documents?.map((document, index) => { + return ( + handleDownload(document)} style={{ minWidth: "160px", marginRight: "20px" }} key={index}> + +

{document.documentName}

+
+ ); + })} +
+
+ ) : null} + {data?.Employees?.[0]?.jurisdictions.length > 0 ? ( + {t("HR_JURIS_DET_HEADER")} + ) : null} + + {data?.Employees?.[0]?.jurisdictions?.length > 0 + ? data?.Employees?.[0]?.jurisdictions?.map((element, index) => { + return ( + +
+ {" "} + {t("HR_JURISDICTION")} {index + 1} +
+ {STATE_ADMIN ? ( + + ) : null} + + {!STATE_ADMIN ? ( + ele.tenantId == element?.boundary) + ?.map((ele) => t(`ACCESSCONTROL_ROLES_ROLES_` + ele?.code))} + /> + ) : null} +
+ ); + }) + : null} +
+
+ ) : null} + {showModal ? ( + + ) : null} + + {displayMenu && data ? ( + + ) : null} + setDisplayMenu(!displayMenu)} /> + + + ); +}; + +export default Details; \ No newline at end of file diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/Inbox.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/Inbox.js new file mode 100644 index 000000000..61aeef862 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/Inbox.js @@ -0,0 +1,214 @@ +import { Header, Loader, Toast } from "@egovernments/digit-ui-react-components"; +import React, { useCallback, useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import DesktopInbox from "../components/inbox/DesktopInbox"; +import MobileInbox from "../components/inbox/MobileInbox"; + +const Inbox = ({ parentRoute, businessService = "HRMS", initialStates = {}, filterComponent, isInbox }) => { + const tenantId = Digit.ULBService.getCurrentTenantId(); + const { isLoading: isLoading, Errors, data: res } = Digit.Hooks.hrms.useHRMSCount(tenantId); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + const DIVISION_ADMIN = Digit.UserService.hasAccess(["DIV_ADMIN"]); + + const { t } = useTranslation(); + const [pageOffset, setPageOffset] = useState(initialStates.pageOffset || 0); + const [pageSize, setPageSize] = useState(initialStates.pageSize || 10); + const [sortParams, setSortParams] = useState([{ id: "code", desc: false }]); + const [totalRecords, setTotalReacords] = useState(undefined); + const [searchParams, setSearchParams] = useState(() => { + return initialStates.searchParams || {}; + }); + const [toast, setToast] = useState(null); + + let isMobile = window.Digit.Utils.browser.isMobile(); + let paginationParams = isMobile + ? { limit: 100, offset: pageOffset, sortBy: sortParams?.[0]?.id, sortOrder: sortParams?.[0]?.desc ? "DESC" : "ASC" } + : { limit: pageSize, offset: pageOffset, sortBy: sortParams?.[0]?.id, sortOrder: sortParams?.[0]?.desc ? "DESC" : "ASC" }; + const isupdate = Digit.SessionStorage.get("isupdate"); + + let roles = STATE_ADMIN + ? { roles: "DIV_ADMIN, HRMS_ADMIN", isStateLevelSearch: true } + : { roles: "SYSTEM, GP_ADMIN, COLLECTION_OPERATOR, PROFILE_UPDATE, DASHBOAD_VIEWER", isStateLevelSearch: false }; + + let requestBody = { + criteria: { + tenantIds: searchParams?.tenantIds, + isActive: searchParams?.isActive, + roles: ["DIV_ADMIN", "HRMS_ADMIN"], + type: "EMPLOYEE", + }, + }; + if (searchParams?.hasOwnProperty("isActive")) { + requestBody.criteria = { + ...requestBody.criteria, + isActive: searchParams?.isActive, + }; + } + + const checkRoles = requestBody.criteria.roles[0] !== "DIV_ADMIN"; + + const { data: divisionData, ...rests } = Digit.Hooks.hrms.useHRMSEmployeeSearch(requestBody, isupdate, { + enabled: (STATE_ADMIN && searchParams?.hasOwnProperty("isActive")) || searchParams?.hasOwnProperty("tenantIds") ? true : false, + }); + + if (searchParams?.hasOwnProperty("roles")) { + roles.roles = searchParams?.roles; + } + + const { isLoading: hookLoading, isError, error, data, ...rest } = Digit.Hooks.hrms.useHRMSSearch( + searchParams, + tenantId, + paginationParams, + isupdate, + roles, + { + enabled: (!searchParams?.hasOwnProperty("isActive") && !searchParams?.hasOwnProperty("tenantIds")) || DIVISION_ADMIN ? true : false, + } + ); + + useEffect(() => { + // setTotalReacords(res?.EmployeCount?.totalEmployee); + }, [res]); + + useEffect(() => {}, [hookLoading, rest]); + + useEffect(() => { + setPageOffset(0); + }, [searchParams]); + + const fetchNextPage = () => { + setPageOffset((prevState) => prevState + pageSize); + }; + + const fetchPrevPage = () => { + setPageOffset((prevState) => prevState - pageSize); + }; + + const closeToast = () => { + setTimeout(() => { + setToast(null); + }, 5000); + }; + const handleFilterChange = (filterParam) => { + // if (!searchParams.names || !searchParams.phone || !searchParams.codes || !filterParam.tenantIds || !filterParam.isActive) { + // // Show toast message + // setToast({ key: true, label: "Please enter a minimum one value to search" }); + // closeToast(); + // return; // Don't proceed with the search + // } + + let keys_to_delete = filterParam.delete; + let _new = { ...searchParams, ...filterParam }; + if (keys_to_delete) keys_to_delete.forEach((key) => delete _new[key]); + filterParam.delete; + delete _new.delete; + if (!_new.tenantId){ + _new = {tenantId: tenantId} + } + setSearchParams({ ..._new }); + }; + + const handleSort = useCallback((args) => { + if (args.length === 0) return; + setSortParams(args); + }, []); + + const handlePageSizeChange = (e) => { + setPageSize(Number(e.target.value)); + }; + + const getSearchFields = () => { + return [ + { + label: t("HR_NAME_LABEL"), + name: "names", + }, + { + label: t("HR_MOB_NO_LABEL"), + name: "phone", + maxlength: 10, + pattern: "[6-9][0-9]{9}", + title: t("ES_SEARCH_APPLICATION_MOBILE_INVALID"), + componentInFront: "+91", + }, + { + label: t("HR_EMPLOYEE_ID_LABEL"), + name: "codes", + }, + ]; + }; + if (isLoading) { + return ; + } + + if (data?.length !== null) { + if (isMobile) { + return ( + + //
+ ); + } else { + return ( +
+ {isInbox &&
{t("HR_HOME_SEARCH_RESULTS_HEADING")}
} + + {toast && ( + { + setToast(null); + }} + /> + )} +
+ ); + } + } +}; + +export default Inbox; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/Response.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/Response.js new file mode 100644 index 000000000..7b55756e9 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/Response.js @@ -0,0 +1,116 @@ +import React, { useEffect } from "react"; +import { Card, Banner, CardText, SubmitBar, Loader, LinkButton, ActionBar } from "@egovernments/digit-ui-react-components"; +import { Link } from "react-router-dom"; +import { useTranslation } from "react-i18next"; + +const GetMessage = (type, action, isSuccess, isEmployee, t) => { + return t(`EMPLOYEE_RESPONSE_${action ? action : "CREATE"}_${type}${isSuccess ? "" : "_ERROR"}`); +}; + +const GetActionMessage = (action, isSuccess, isEmployee, t) => { + return GetMessage("ACTION", action, isSuccess, isEmployee, t); +}; + +const GetLabel = (action, isSuccess, isEmployee, t) => { + if (isSuccess) { + return t("HR_EMPLOYEE_ID_LABEL"); + } + // return GetMessage("LABEL", action, isSuccess, isEmployee, t); +}; + +const BannerPicker = (props) => { + return ( + + ); +}; + +const Response = (props) => { + const { t } = useTranslation(); + const tenantId = Digit.ULBService.getCurrentTenantId(); + const stateId = Digit.ULBService.getStateId(); + const { state } = props.location; + const [mutationHappened, setMutationHappened, clear] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_HAPPENED", false); + const [successData, setsuccessData, clearSuccessData] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_SUCCESS_DATA", false); + const [errorInfo, setErrorInfo, clearError] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_ERROR_DATA", false); + const mutation = state.key === "UPDATE" ? Digit.Hooks.hrms.useHRMSUpdate(tenantId) : Digit.Hooks.hrms.useHRMSCreate(tenantId); + + const employeeCreateSession = Digit.Hooks.useSessionStorage("NEW_EMPLOYEE_CREATE", {}); + const [sessionFormData,setSessionFormData, clearSessionFormData] = employeeCreateSession; + + // remove session form data if user navigates away from the estimate create screen + useEffect(()=>{ + if (!window.location.href.includes("/hrms/create") && sessionFormData && Object.keys(sessionFormData) != 0) { + clearSessionFormData(); + } +},[location]); + + const onError = (error, variables) => { + setErrorInfo(error?.response?.data?.Errors[0]?.code || 'ERROR'); + setMutationHappened(true); + }; + + useEffect(() => { + if (mutation.data) setsuccessData(mutation.data); + }, [mutation.data]); + + useEffect(() => { + const onSuccess = () => { + setMutationHappened(true); + }; + if (!mutationHappened ) { + if (state.key === "UPDATE") { + mutation.mutate( + { + Employees: state.Employees, + }, + { + onError, + onSuccess, + } + ); + } else { + mutation.mutate(state, { + onSuccess, + }); + } + } + }, []); + + const DisplayText = (action, isSuccess, isEmployee, t) => { + if (!isSuccess) { + return mutation?.error?.response?.data?.Errors[0].code||errorInfo; + } else { + Digit.SessionStorage.set("isupdate", Math.floor(100000 + Math.random() * 900000)); + return state.key === "CREATE"?"HRMS_CREATE_EMPLOYEE_INFO" :""; + } + }; + if (mutation.isLoading || (mutation.isIdle && !mutationHappened)) { + return ; + } + return ( + + + {t(DisplayText(state.action, mutation.isSuccess || !!successData, props.parentRoute.includes("employee"), t), t)} + + + + + + + + ); +}; + +export default Response; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/createEmployee.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/createEmployee.js new file mode 100644 index 000000000..c259087ef --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/createEmployee.js @@ -0,0 +1,329 @@ +import { FormComposer, Toast, Loader, Header } from "@egovernments/digit-ui-react-components"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import { newConfig } from "../components/config/config"; +import _ from "lodash"; + +const CreateEmployee = () => { + const tenantId = Digit.ULBService.getCurrentTenantId(); + const [canSubmit, setSubmitValve] = useState(false); + const [mobileNumber, setMobileNumber] = useState(null); + const [showToast, setShowToast] = useState(null); + const [phonecheck, setPhonecheck] = useState(false); + const [checkfield, setcheck] = useState(false); + const { t } = useTranslation(); + const history = useHistory(); + const isMobile = window.Digit.Utils.browser.isMobile(); + const STATE_ADMIN = Digit.UserService.hasAccess(["STATE_ADMIN"]); + + const { data: mdmsData, isLoading } = Digit.Hooks.useCommonMDMS(Digit.ULBService.getStateId(), "egov-hrms", ["CommonFieldsConfig"], { + select: (data) => { + return { + config: data?.MdmsRes?.["egov-hrms"]?.CommonFieldsConfig, + }; + }, + retry: false, + enable: false, + }); + const { data: hrmsData = {} } = Digit.Hooks.hrms.useHrmsMDMS(tenantId, "egov-hrms", "HRMSConfig") || {}; + const [mutationHappened, setMutationHappened, clear] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_HAPPENED", false); + const [errorInfo, setErrorInfo, clearError] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_ERROR_DATA", false); + const [successData, setsuccessData, clearSuccessData] = Digit.Hooks.useSessionStorage("EMPLOYEE_HRMS_MUTATION_SUCCESS_DATA", false); + + useEffect(() => { + setMutationHappened(false); + clearSuccessData(); + clearError(); + }, []); + + const checkMailNameNum = (formData) => { + const email = formData?.SelectEmployeeEmailId?.emailId || ""; + const name = formData?.SelectEmployeeName?.employeeName || ""; + const validEmail = email.length == 0 ? true : email.match(Digit.Utils.getPattern("Email")); + return validEmail && name.match(Digit.Utils.getPattern("Name")); + }; + + const closeToast = () => { + setTimeout(() => { + setShowToast(null); + }, 5000); + }; + useEffect(() => { + if (mobileNumber && mobileNumber.length == 10 && mobileNumber.match(Digit.Utils.getPattern("MobileNo"))) { + setShowToast(null); + Digit.HRMSService.search(tenantId, null, { phone: mobileNumber }).then((result, err) => { + if (result.Employees.length > 0) { + setShowToast({ key: true, label: "ERR_HRMS_USER_EXIST_MOB" }); + closeToast(); + setPhonecheck(false); + } else { + setPhonecheck(true); + } + }); + } else { + setPhonecheck(false); + } + }, [mobileNumber]); + + const defaultValues = { + Jurisdictions: [ + { + id: undefined, + key: 1, + hierarchy: null, + boundaryType: null, + boundary: { + code: tenantId, + }, + division: null, + roles: [], + }, + ], + }; + + const employeeCreateSession = Digit.Hooks.useSessionStorage("NEW_EMPLOYEE_CREATE", {}); + const [sessionFormData, setSessionFormData, clearSessionFormData] = employeeCreateSession; + + const onFormValueChange = (setValue = true, formData) => { + if (!_.isEqual(sessionFormData, formData)) { + setSessionFormData({ ...sessionFormData, ...formData }); + } + if (formData?.SelectEmployeePhoneNumber?.mobileNumber) { + setMobileNumber(formData?.SelectEmployeePhoneNumber?.mobileNumber); + } else { + setMobileNumber(formData?.SelectEmployeePhoneNumber?.mobileNumber); + } + for (let i = 0; i < formData?.Jurisdictions?.length; i++) { + let key = formData?.Jurisdictions[i]; + if (!((key?.boundary || key?.divisionBoundary) && (key?.boundaryType || key?.division) && key?.tenantId)) { + setcheck(false); + break; + } else { + if (!STATE_ADMIN) { + key?.roles?.length > 0 && setcheck(true); + } else if (STATE_ADMIN) { + setcheck(true); + } + } + } + + if ( + formData?.SelectEmployeeGender?.gender.code && + formData?.SelectEmployeeName?.employeeName && + formData?.SelectEmployeePhoneNumber?.mobileNumber && + checkfield && + phonecheck && + checkMailNameNum(formData) + ) { + setSubmitValve(true); + } else { + setSubmitValve(false); + } + }; + + const navigateToAcknowledgement = (Employees) => { + history.replace(`/${window?.contextPath}/employee/hrms/response`, { Employees, key: "CREATE", action: "CREATE" }); + }; + + const onSubmit = (data) => { + if (!STATE_ADMIN && data.Jurisdictions?.filter((juris) => juris.tenantId == tenantId).length == 0) { + setShowToast({ key: true, label: "ERR_BASE_TENANT_MANDATORY" }); + closeToast(); + return; + } + if ( + STATE_ADMIN && + !Object.values( + data.Jurisdictions.reduce((acc, sum) => { + if (sum && sum?.division?.code) { + acc[sum?.division?.code] = acc[sum?.division?.code] ? acc[sum?.division?.code] + 1 : 1; + } + return acc; + }, {}) + ).every((s) => s == 1) + ) { + setShowToast({ key: true, label: "ERR_INVALID_JURISDICTION" }); + closeToast(); + return; + } else if ( + !Object.values( + data.Jurisdictions.reduce((acc, sum) => { + if (sum && sum?.tenantId) { + acc[sum.tenantId] = acc[sum.tenantId] ? acc[sum.tenantId] + 1 : 1; + } + return acc; + }, {}) + ).every((s) => s == 1) + ) { + setShowToast({ key: true, label: "ERR_INVALID_JURISDICTION" }); + closeToast(); + return; + } + let roles = []; + let jurisdictions = []; + if (STATE_ADMIN) { + const divisionBoundaryCodes = data?.Jurisdictions.flatMap((j) => j.divisionBoundary.map((item) => item.code)); + let stateRoles = [ + { + code: "EMPLOYEE", + name: "EMPLOYEE", + labelKey: "ACCESSCONTROL_ROLES_ROLES_EMPLOYEE", + }, + { + code: "DIV_ADMIN", + name: "DIVISION ADMIN", + labelKey: "ACCESSCONTROL_ROLES_ROLES_DIV_ADMIN", + }, + { + code: "HRMS_ADMIN", + name: "HRMS_ADMIN", + labelKey: "ACCESSCONTROL_ROLES_ROLES_HRMS_ADMIN", + }, + { + code: "MDMS_ADMIN", + name: "MDMS Admin", + description: "Mdms admin", + }, + ]; + divisionBoundaryCodes && + divisionBoundaryCodes.length > 0 && + divisionBoundaryCodes.map((item) => { + stateRoles?.map((role) => { + roles.push({ + code: role.code, + name: role.name, + labelKey: role.labelKey, + tenantId: item, + }); + }); + }); + + data?.Jurisdictions?.map((items) => { + items?.divisionBoundary.map((item) => { + jurisdictions.push({ + hierarchy: "REVENUE", + boundaryType: "City", + boundary: item?.code, + tenantId: item?.code, + roles: stateRoles, + }); + }); + }); + + // Map the data and add tenantId to roles array + const mappedData = jurisdictions.map((jurisdiction) => { + return { + ...jurisdiction, + roles: jurisdiction.roles.map((role) => ({ + ...role, + tenantId: jurisdiction.tenantId, + })), + }; + }); + jurisdictions = mappedData; + } else { + roles = data?.Jurisdictions?.map((ele) => { + return ele.roles?.map((item) => { + item["tenantId"] = ele.boundary; + return item; + }); + }); + } + roles.push({ + name: "EMPLOYEE", + code: "EMPLOYEE", + tenantId: "pb", + }); + const mappedroles = [].concat.apply([], roles); + let dateOfAppointment = new Date(); + dateOfAppointment.setDate(dateOfAppointment.getDate() - 1); + let Employees = [ + { + tenantId: tenantId, + employeeStatus: "EMPLOYED", + + code: data?.SelectEmployeeId?.code ? data?.SelectEmployeeId?.code : undefined, + dateOfAppointment: dateOfAppointment.getTime(), + employeeType: hrmsData?.["egov-hrms"]?.HRMSConfig[0]?.employeeType, + jurisdictions: STATE_ADMIN ? jurisdictions : data?.Jurisdictions, + assignments: [ + { + fromDate: new Date().getTime(), + isCurrentAssignment: hrmsData?.["egov-hrms"]?.HRMSConfig[0]?.isCurrentAssignment, + department: hrmsData?.["egov-hrms"]?.HRMSConfig[0]?.department, + designation: STATE_ADMIN + ? hrmsData?.["egov-hrms"]?.HRMSConfig[0]?.designation?.filter((x) => x?.isStateUser)[0]?.code + : hrmsData?.["egov-hrms"]?.HRMSConfig[0]?.designation?.filter((x) => !x?.isStateUser)[0]?.code, + }, + ], + user: { + mobileNumber: data?.SelectEmployeePhoneNumber?.mobileNumber, + name: data?.SelectEmployeeName?.employeeName, + correspondenceAddress: tenantId, + emailId: data?.SelectEmployeeEmailId?.emailId ? data?.SelectEmployeeEmailId?.emailId : undefined, + gender: data?.SelectEmployeeGender?.gender.code, + dob: 805055400000, + roles: mappedroles, + tenantId: tenantId, + }, + serviceHistory: [], + education: [], + tests: [], + }, + ]; + /* use customiseCreateFormData hook to make some chnages to the Employee object */ + Employees = Digit?.Customizations?.HRMS?.customiseCreateFormData ? Digit.Customizations.HRMS.customiseCreateFormData(data, Employees) : Employees; + + if (data?.SelectEmployeeId?.code && data?.SelectEmployeeId?.code?.trim().length > 0) { + Digit.HRMSService.search(tenantId, null, { codes: data?.SelectEmployeeId?.code }).then((result, err) => { + if (result.Employees.length > 0) { + setShowToast({ key: true, label: "ERR_HRMS_USER_EXIST_ID" }); + closeToast(); + return; + } else { + navigateToAcknowledgement(Employees); + } + }); + } else { + navigateToAcknowledgement(Employees); + } + }; + if (isLoading) { + return ; + } + const config = mdmsData?.config ? mdmsData.config : newConfig; + return ( +
+
+
{STATE_ADMIN ? t("HR_COMMON_CREATE_DIVISION_EMPLOYEE_HEADER") : t("HR_COMMON_CREATE_EMPLOYEE_HEADER")}
+
+ + {showToast && ( + { + setShowToast(null); + }} + /> + )} +
+ ); +}; +export default CreateEmployee; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/index.js new file mode 100644 index 000000000..9bf9aeb07 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/hrms/src/pages/index.js @@ -0,0 +1,60 @@ +import { PrivateRoute } from "@egovernments/digit-ui-react-components"; +import React,{ useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { Link, Switch, useLocation } from "react-router-dom"; + +// const {SixFtApart,Rotate360}=SVG; +const EmployeeApp = ({ path, url, userType }) => { + const { t } = useTranslation(); + const location = useLocation(); + const mobileView = innerWidth <= 640; + const tenantId = Digit.ULBService.getCurrentTenantId(); + const inboxInitialState = { + searchParams: { + tenantId: tenantId, + }, + }; + + const HRMSResponse = Digit?.ComponentRegistryService?.getComponent("HRMSResponse"); + const HRMSDetails = Digit?.ComponentRegistryService?.getComponent("HRMSDetails"); + const Inbox = Digit?.ComponentRegistryService?.getComponent("HRInbox"); + const CreateEmployee = Digit?.ComponentRegistryService?.getComponent("HRCreateEmployee"); + const EditEmpolyee = Digit?.ComponentRegistryService?.getComponent("HREditEmpolyee"); + + const employeeCreateSession = Digit.Hooks.useSessionStorage("NEW_EMPLOYEE_CREATE", {}); + const [sessionFormData,setSessionFormData, clearSessionFormData] = employeeCreateSession; + + // remove session form data if user navigates away from the estimate create screen + useEffect(()=>{ + if (!window.location.href.includes("/hrms/create") && sessionFormData && Object.keys(sessionFormData) != 0) { + clearSessionFormData(); + } +},[location]); + + return ( + + +
+

+ + {t("HR_COMMON_BUTTON_HOME")} + {" "} + / {location.pathname === `/${window?.contextPath}/employee/hrms/inbox` ? t("HR_COMMON_HEADER") : t("HR_COMMON_HEADER")} +

+ ( + + )} + /> + } /> + } /> + } /> + } /> +
+
+
+ ); +}; + +export default EmployeeApp; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/README.md b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/package.json b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/package.json new file mode 100644 index 000000000..0b88246fc --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/package.json @@ -0,0 +1,33 @@ +{ + "name": "@egovernments/digit-ui-module-pgr", + "version": "1.7.0", + "license": "MIT", + "main": "dist/index.js", + "module": "dist/index.modern.js", + "source": "src/Module.js", + "files": [ + "dist" + ], + "scripts": { + "start": "microbundle-crl watch --no-compress --format modern,cjs", + "build": "microbundle-crl --compress --no-sourcemap --format cjs", + "prepublish": "yarn build" + }, + "peerDependencies": { + "react": "17.0.2", + "react-router-dom": "5.3.0" + }, + "dependencies": { + "@egovernments/digit-ui-react-components": "1.5.22", + "lodash.merge": "^4.6.2", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-hook-form": "6.15.8", + "react-i18next": "11.16.2", + "react-query": "3.6.1", + "react-redux": "7.2.8", + "react-router-dom": "5.3.0", + "redux": "4.1.2", + "redux-thunk": "2.4.1" + } +} diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/EmployeeApp.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/EmployeeApp.js new file mode 100644 index 000000000..3cbbdc4f5 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/EmployeeApp.js @@ -0,0 +1,13 @@ +import React from "react"; +import { AppContainer, EmployeeAppContainer } from "@egovernments/digit-ui-react-components"; + +import Complaint from "./pages/employee/index"; +const App = () => { + return ( + + + + ); +}; + +export default App; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/Icons.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/Icons.js new file mode 100644 index 000000000..c932e7ad4 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/Icons.js @@ -0,0 +1,8 @@ +import React from "react"; + +export const Close = () => ( + + + + +); diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/Module.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/Module.js new file mode 100644 index 000000000..430b1e75e --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/Module.js @@ -0,0 +1,85 @@ +import React, { useEffect } from "react"; +import PGRCard from "./components/PGRCard"; + +import getRootReducer from "./redux/reducers"; +import CitizenApp from "./pages/citizen"; + +import EmployeeApp from "./EmployeeApp"; +import { ComplaintIcon, CitizenHomeCard, Loader } from "@egovernments/digit-ui-react-components"; +import { PGR_CITIZEN_CREATE_COMPLAINT } from "./constants/Citizen"; +import { useTranslation } from "react-i18next"; +import { LOCALE } from "./constants/Localization"; +import { ComplaintDetails } from "./pages/employee/ComplaintDetails"; +import { CreateComplaint as CreateComplaintEmp } from "./pages/employee/CreateComplaint"; +import Inbox from "./pages/employee/Inbox"; +import ResponseEmp from "./pages/employee/Response"; + +import { CreateComplaint as CreateComplaintCitizen } from "./pages/citizen/Create"; +import { ComplaintsList } from "./pages/citizen/ComplaintsList"; +import ComplaintDetailsPage from "./pages/citizen/ComplaintDetails"; +import SelectRating from "./pages/citizen/Rating/SelectRating"; +import ResponseCitizen from "./pages/citizen/Response"; + + +export const PGRReducers = getRootReducer; + +const PGRModule = ({ stateCode, userType, tenants }) => { + const moduleCode = "PGR"; + const language = Digit.StoreData.getCurrentLanguage(); + const { isLoading, data: store } = Digit.Services.useStore({ stateCode, moduleCode, language }); + + if (isLoading) { + return ; + } + + Digit.SessionStorage.set("PGR_TENANTS", tenants); + + if (userType === "citizen") { + return ; + } else { + return ; + } +}; + +const PGRLinks = ({ matchPath }) => { + const { t } = useTranslation(); + const [params, setParams, clearParams] = Digit.Hooks.useSessionStorage(PGR_CITIZEN_CREATE_COMPLAINT, {}); + + useEffect(() => { + clearParams(); + }, []); + + const links = [ + { + link: `${matchPath}/create-complaint/complaint-type`, + i18nKey: t("CS_COMMON_FILE_A_COMPLAINT"), + }, + { + link: `${matchPath}/complaints`, + i18nKey: t(LOCALE.MY_COMPLAINTS), + }, + ]; + + return ; +}; + +const componentsToRegister = { + PGRModule, + PGRLinks, + PGRCard, + PGRComplaintDetails : ComplaintDetails, + PGRCreateComplaintEmp : CreateComplaintEmp, + PGRInbox : Inbox, + PGRResponseEmp : ResponseEmp, + PGRCreateComplaintCitizen : CreateComplaintCitizen, + PGRComplaintsList : ComplaintsList, + PGRComplaintDetailsPage : ComplaintDetailsPage, + PGRSelectRating : SelectRating, + PGRResponseCitzen : ResponseCitizen +}; + +export const initPGRComponents = () => { + Object.entries(componentsToRegister).forEach(([key, value]) => { + Digit.ComponentRegistryService.setComponent(key, value); + }); +}; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/Complaint.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/Complaint.js new file mode 100644 index 000000000..3583fa17a --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/Complaint.js @@ -0,0 +1,41 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import { Card, DateWrap, KeyNote } from "@egovernments/digit-ui-react-components"; +import { CardSubHeader } from "@egovernments/digit-ui-react-components"; +import { LOCALIZATION_KEY } from "../constants/Localization"; + +// import { ConvertTimestampToDate } from "../@egovernments/digit-utils/services/date"; + +const Complaint = ({ data, path }) => { + let { serviceCode, serviceRequestId, applicationStatus } = data; + + const history = useHistory(); + const { t } = useTranslation(); + + const handleClick = () => { + history.push(`${path}/${serviceRequestId}`); + }; + + const closedStatus = ["RESOLVED", "REJECTED", "CLOSEDAFTERREJECTION", "CLOSEDAFTERRESOLUTION"]; + + return ( + + + {t(`SERVICEDEFS.${serviceCode.toUpperCase()}`)} + + + + + +
+

{(closedStatus.includes(applicationStatus) ? t("CS_COMMON_CLOSED") : t("CS_COMMON_OPEN")).toUpperCase()}

+
+ + {t(`${LOCALIZATION_KEY.CS_COMMON}_${applicationStatus}`)} +
+
+ ); +}; + +export default Complaint; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/DesktopInbox.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/DesktopInbox.js new file mode 100644 index 000000000..62628de1a --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/DesktopInbox.js @@ -0,0 +1,145 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; +import { Card, Loader } from "@egovernments/digit-ui-react-components"; +import ComplaintsLink from "./inbox/ComplaintLinks"; +import ComplaintTable from "./inbox/ComplaintTable"; +import Filter from "./inbox/Filter"; +import SearchComplaint from "./inbox/search"; +import { LOCALE } from "../constants/Localization"; + +const DesktopInbox = ({ + data, + onFilterChange, + onSearch, + isLoading, + searchParams, + onNextPage, + onPrevPage, + currentPage, + pageSizeLimit, + onPageSizeChange, + totalRecords, +}) => { + const { t } = useTranslation(); + const GetCell = (value) => {value}; + const GetSlaCell = (value) => { + return value < 0 ? {value || ""} : {value || ""}; + }; + + const columns = React.useMemo( + () => [ + { + Header: t("CS_COMMON_COMPLAINT_NO"), + Cell: ({ row }) => { + return ( +
+ + + {row.original["serviceRequestId"]} + + + {/* goTo(row.row.original["serviceRequestId"])}>{row.row.original["serviceRequestId"]} */} +
+ {t(`SERVICEDEFS.${row.original["complaintSubType"].toUpperCase()}`)} +
+ ); + }, + }, + { + Header: t("WF_INBOX_HEADER_LOCALITY"), + Cell: ({ row }) => { + return GetCell(t(Digit.Utils.locale.getLocalityCode(row.original["locality"], row.original["tenantId"]))); + }, + }, + { + Header: t("CS_COMPLAINT_DETAILS_CURRENT_STATUS"), + Cell: ({ row }) => { + return GetCell(t(`CS_COMMON_${row.original["status"]}`)); + }, + }, + { + Header: t("WF_INBOX_HEADER_CURRENT_OWNER"), + Cell: ({ row }) => { + return GetCell(row.original["taskOwner"]); + }, + }, + { + Header: t("WF_INBOX_HEADER_SLA_DAYS_REMAINING"), + Cell: ({ row }) => { + return GetSlaCell(row.original["sla"]); + }, + }, + ], + [t] + ); + + let result; + if (isLoading) { + result = ; + } else if (data && data?.length === 0) { + result = ( + + {t(LOCALE.NO_COMPLAINTS_EMPLOYEE) + .split("\\n") + .map((text, index) => ( +

+ {text} +

+ ))} +
+ ); + } else if (data?.length > 0) { + result = ( + { + return { + style: { + minWidth: cellInfo.column.Header === t("CS_COMMON_COMPLAINT_NO") ? "240px" : "", + padding: "20px 18px", + fontSize: "16px", + }, + }; + }} + onNextPage={onNextPage} + onPrevPage={onPrevPage} + totalRecords={totalRecords} + onPageSizeChagne={onPageSizeChange} + currentPage={currentPage} + pageSizeLimit={pageSizeLimit} + /> + ); + } else { + result = ( + + {t(LOCALE.ERROR_LOADING_RESULTS) + .split("\\n") + .map((text, index) => ( +

+ {text} +

+ ))} +
+ ); + } + + return ( +
+
+ +
+ +
+
+
+ +
{result}
+
+
+ ); +}; + +export default DesktopInbox; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/FormComposer.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/FormComposer.js new file mode 100644 index 000000000..785f9cde0 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/components/FormComposer.js @@ -0,0 +1,86 @@ +import React, { useMemo } from "react"; +import { useForm } from "react-hook-form"; +import { + BreakLine, + Card, + CardLabel, + CardLabelError, + CardSubHeader, + CardSectionHeader, + TextArea, + TextInput, + ActionBar, + SubmitBar, + LabelFieldPair, +} from "@egovernments/digit-ui-react-components"; + +import { useTranslation } from "react-i18next"; + +export const FormComposer = (props) => { + const { register, handleSubmit, errors } = useForm(); + const { t } = useTranslation(); + + function onSubmit(data) { + props.onSubmit(data); + } + + const fieldSelector = (type, populators) => { + switch (type) { + case "text": + return ( +
+ {populators.componentInFront ? populators.componentInFront : null} + +
+ ); + case "textarea": + return + + + + + ); +}; + +export default RatingAndFeedBack; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Rating/SelectRating.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Rating/SelectRating.js new file mode 100644 index 000000000..c24bce32f --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Rating/SelectRating.js @@ -0,0 +1,62 @@ +import React, { useCallback, useState } from "react"; +import { useDispatch } from "react-redux"; +import { RatingCard, CardLabelError } from "@egovernments/digit-ui-react-components"; +import { useParams, Redirect, useHistory } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import { updateComplaints } from "../../../redux/actions/index"; + +const SelectRating = ({ parentRoute }) => { + const { t } = useTranslation(); + const { id } = useParams(); + const dispatch = useDispatch(); + const history = useHistory(); + + let tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || Digit.ULBService.getCurrentTenantId(); + const complaintDetails = Digit.Hooks.pgr.useComplaintDetails({ tenantId: tenantId, id: id }).complaintDetails; + const updateComplaint = useCallback((complaintDetails) => dispatch(updateComplaints(complaintDetails)), [dispatch]); + const [submitError, setError] = useState(false) + + function log(data) { + if (complaintDetails && data.rating > 0 ) { + complaintDetails.service.rating = data.rating; + complaintDetails.service.additionalDetail = data.CS_FEEDBACK_WHAT_WAS_GOOD.join(","); + complaintDetails.workflow = { + action: "RATE", + comments: data.comments, + verificationDocuments: [], + }; + updateComplaint({ service: complaintDetails.service, workflow: complaintDetails.workflow }); + history.push(`${parentRoute}/response`); + } + else{ + setError(true) + } + } + + const config = { + texts: { + header: "CS_COMPLAINT_RATE_HELP_TEXT", + submitBarLabel: "CS_COMMONS_NEXT", + }, + inputs: [ + { + type: "rate", + maxRating: 5, + label: t("CS_COMPLAINT_RATE_TEXT"), + error: submitError ? {t("CS_FEEDBACK_ENTER_RATING_ERROR")} : null + }, + { + type: "checkbox", + label: "CS_FEEDBACK_WHAT_WAS_GOOD", + checkLabels: [t("CS_FEEDBACK_SERVICES"), t("CS_FEEDBACK_RESOLUTION_TIME"), t("CS_FEEDBACK_QUALITY_OF_WORK"), t("CS_FEEDBACK_OTHERS")], + }, + { + type: "textarea", + label: t("CS_COMMON_COMMENTS"), + name: "comments", + }, + ], + }; + return ; +}; +export default SelectRating; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/AddtionalDetails.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/AddtionalDetails.js new file mode 100644 index 000000000..7c9ae3f20 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/AddtionalDetails.js @@ -0,0 +1,97 @@ +import React, { useCallback, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams, useHistory, Redirect } from "react-router-dom"; + +import { BackButton, Card, CardHeader, CardText, TextArea, SubmitBar } from "@egovernments/digit-ui-react-components"; + +import { updateComplaints } from "../../../redux/actions/index"; +import { LOCALIZATION_KEY } from "../../../constants/Localization"; + +const AddtionalDetails = (props) => { + // const [details, setDetails] = useState(null); + const history = useHistory(); + let { id } = useParams(); + const dispatch = useDispatch(); + const appState = useSelector((state) => state)["common"]; + let { t } = useTranslation(); + + const {complaintDetails} = props + useEffect(() => { + if (appState.complaints) { + const { response } = appState.complaints; + if (response && response.responseInfo.status === "successful") { + history.push(`${props.match.path}/response/:${id}`); + } + } + }, [appState.complaints, props.history]); + + const updateComplaint = useCallback( + async (complaintDetails) => { + await dispatch(updateComplaints(complaintDetails)); + history.push(`${props.match.path}/response/${id}`); + }, + [dispatch] + ); + + const getUpdatedWorkflow = (reopenDetails, type) => { + switch (type) { + case "REOPEN": + return { + action: "REOPEN", + comments: reopenDetails.addtionalDetail, + assignes: [], + verificationDocuments: reopenDetails.verificationDocuments, + }; + default: + return ""; + } + }; + + function reopenComplaint() { + let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`); + if (complaintDetails) { + complaintDetails.workflow = getUpdatedWorkflow( + reopenDetails, + // complaintDetails, + "REOPEN" + ); + complaintDetails.service.additionalDetail = { + REOPEN_REASON: reopenDetails.reason, + }; + updateComplaint({ service: complaintDetails.service, workflow: complaintDetails.workflow }); + } + return ( + + ); + } + + function textInput(e) { + // setDetails(e.target.value); + let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`); + Digit.SessionStorage.set(`reopen.${id}`, { + ...reopenDetails, + addtionalDetail: e.target.value, + }); + } + + return ( + + + {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_PROVIDE_ADDITIONAL_DETAILS`)} + {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_ADDITIONAL_DETAILS_TEXT`)} + +
+ +
+
+
+ ); +}; + +export default AddtionalDetails; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/Reason.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/Reason.js new file mode 100644 index 000000000..a67b9b52c --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/Reason.js @@ -0,0 +1,57 @@ +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Link, useHistory, useParams } from "react-router-dom"; +import { BackButton, Card, CardHeader, CardLabelError, CardText, RadioButtons, SubmitBar } from "@egovernments/digit-ui-react-components"; + +import { LOCALIZATION_KEY } from "../../../constants/Localization"; +import { getRoute, PgrRoutes, PGR_BASE } from "../../../constants/Routes"; + +const ReasonPage = (props) => { + const history = useHistory(); + const { t } = useTranslation(); + const { id } = useParams(); + const [selected, setSelected] = useState(null); + const [valid, setValid] = useState(true); + + const onRadioChange = (value) => { + let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`); + Digit.SessionStorage.set(`reopen.${id}`, { ...reopenDetails, reason: value }); + setSelected(value); + }; + + function onSave() { + if (selected === null) { + setValid(false); + } else { + history.push(`${props.match.path}/upload-photo/${id}`); + } + } + + return ( + + {t(`${LOCALIZATION_KEY.CS_REOPEN}_COMPLAINT`)} + + {/* Select the option related to your complaint from the list given below. + If the complaint type you are looking for is not listed select others.{" "} */} + {/* {t(`${TRANSLATION_KEY}_OPTION_ONE`)} */} + + {valid ? null : {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_ERROR_REOPEN_REASON`)}} + setSelected(value)} + options={[ + t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_ONE`), + t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_TWO`), + t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_THREE`), + t(`${LOCALIZATION_KEY.CS_REOPEN}_OPTION_FOUR`), + ]} + /> + + + + ); +}; + +export default ReasonPage; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/UploadPhoto.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/UploadPhoto.js new file mode 100644 index 000000000..a50ae8af6 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/UploadPhoto.js @@ -0,0 +1,71 @@ +import React, { useEffect, useState } from "react"; +import { Link, useHistory, useParams } from "react-router-dom"; +import { useTranslation } from "react-i18next"; + +import { Card, SubmitBar, BackButton, ImageUploadHandler, CardLabelError, LinkButton } from "@egovernments/digit-ui-react-components"; + +import { LOCALIZATION_KEY } from "../../../constants/Localization"; + +const UploadPhoto = (props) => { + const { t } = useTranslation(); + const history = useHistory(); + let { id } = useParams(); + const [verificationDocuments, setVerificationDocuments] = useState(null); + const [valid, setValid] = useState(true); + + const handleUpload = (ids) => { + setDocState(ids); + }; + + const setDocState = (ids) => { + if (ids?.length) { + const documents = ids.map((id) => ({ + documentType: "PHOTO", + fileStoreId: id, + documentUid: "", + additionalDetails: {}, + })); + setVerificationDocuments(documents); + } + }; + + function save() { + if (verificationDocuments === null) { + setValid(false); + } else { + history.push(`${props.match.path}/addional-details/${id}`); + } + } + + function skip() { + history.push(`${props.match.path}/addional-details/${id}`); + } + + useEffect(() => { + let reopenDetails = Digit.SessionStorage.get(`reopen.${id}`); + Digit.SessionStorage.set(`reopen.${id}`, { ...reopenDetails, verificationDocuments }); + }, [verificationDocuments, id]); + + return ( + + + + {/* + + */} + + {valid ? null : {t(`${LOCALIZATION_KEY.CS_ADDCOMPLAINT}_UPLOAD_ERROR_MESSAGE`)}} + + {props.skip ? : null} + + + ); +}; + +export default UploadPhoto; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/index.js new file mode 100644 index 000000000..ddd9dab9a --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/ReopenComplaint/index.js @@ -0,0 +1,28 @@ +import React, { useMemo } from "react"; + +import { Route, Switch, useRouteMatch } from "react-router-dom"; +// import UserOnboarding from "../UserOnboarding/index"; +import { PgrRoutes, getRoute } from "../../../constants/Routes"; +import ReasonPage from "./Reason"; +import UploadPhoto from "./UploadPhoto"; +import AddtionalDetails from "./AddtionalDetails"; +import Response from "../Response"; + +const ReopenComplaint = ({ match, history, parentRoute }) => { + + const allParams = window.location.pathname.split("/") + const id = allParams[allParams.length - 1] + const tenantId = Digit.SessionStorage.get("CITIZEN.COMMON.HOME.CITY")?.code || Digit.ULBService.getCurrentTenantId(); + + const complaintDetails = Digit.Hooks.pgr.useComplaintDetails({ tenantId: tenantId, id: id }).complaintDetails; + return ( + + } /> + } /> + } /> + } /> + + ); +}; + +export { ReopenComplaint }; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Response.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Response.js new file mode 100644 index 000000000..28b77b73e --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/Response.js @@ -0,0 +1,59 @@ +import React from "react"; +import { Card, Banner, CardText, SubmitBar } from "@egovernments/digit-ui-react-components"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { PgrRoutes, getRoute } from "../../constants/Routes"; +import { useTranslation } from "react-i18next"; + +const GetActionMessage = ({ action }) => { + const { t } = useTranslation(); + switch (action) { + case "REOPEN": + return t(`CS_COMMON_COMPLAINT_REOPENED`); + case "RATE": + return t("CS_COMMON_THANK_YOU"); + default: + return t(`CS_COMMON_COMPLAINT_SUBMITTED`); + } +}; + +const BannerPicker = ({ response }) => { + const { complaints } = response; + const { t } = useTranslation(); + if (complaints && complaints.response && complaints.response.responseInfo) { + return ( + + ); + } else { + return ; + } +}; + +const TextPicker = ({ response }) => { + const { complaints } = response; + const { t } = useTranslation(); + if (complaints && complaints.response && complaints.response.responseInfo) { + const { action } = complaints.response.ServiceWrappers[0].workflow; + return action === "RATE" ? {t("CS_COMMON_RATING_SUBMIT_TEXT")} : {t("CS_COMMON_TRACK_COMPLAINT_TEXT")}; + } +}; + +const Response = (props) => { + const { t } = useTranslation(); + const appState = useSelector((state) => state)["pgr"]; + return ( + + {appState.complaints.response && } + {appState.complaints.response && } + + + + + ); +}; + +export default Response; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/index.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/index.js new file mode 100644 index 000000000..9319f81be --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/citizen/index.js @@ -0,0 +1,48 @@ +import React from "react"; +import { ReopenComplaint } from "./ReopenComplaint/index"; +import SelectRating from "./Rating/SelectRating"; +import { PgrRoutes, getRoute } from "../../constants/Routes"; +import { useRouteMatch, Switch, useLocation } from "react-router-dom"; +import { AppContainer, BackButton, PrivateRoute } from "@egovernments/digit-ui-react-components"; + +import { CreateComplaint } from "./Create"; +import { ComplaintsList } from "./ComplaintsList"; +import ComplaintDetailsPage from "./ComplaintDetails"; +import Response from "./Response"; +import { useTranslation } from "react-i18next"; + +const App = () => { + const { t } = useTranslation(); + const { path, url, ...match } = useRouteMatch(); + const location = useLocation(); + + const CreateComplaint = Digit?.ComponentRegistryService?.getComponent("PGRCreateComplaintCitizen"); + const ComplaintsList = Digit?.ComponentRegistryService?.getComponent("PGRComplaintsList"); + const ComplaintDetailsPage = Digit?.ComponentRegistryService?.getComponent("PGRComplaintDetailsPage"); + const SelectRating = Digit?.ComponentRegistryService?.getComponent("PGRSelectRating"); + const Response = Digit?.ComponentRegistryService?.getComponent("PGRResponseCitzen"); + + return ( + +
+ {!location.pathname.includes("/response") && {t("CS_COMMON_BACK")}} + + {/* */} + + + + } + /> + } /> + } /> + + {/* */} + +
+
+ ); +}; + +export default App; diff --git a/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/ComplaintDetails.js b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/ComplaintDetails.js new file mode 100644 index 000000000..916413781 --- /dev/null +++ b/frontend/micro-ui/web/micro-ui-internals/packages/modules/pgr/src/pages/employee/ComplaintDetails.js @@ -0,0 +1,504 @@ +import React, { useState, useEffect, Fragment } from "react"; +import { useParams } from "react-router-dom"; +import { + BreakLine, + Card, + CardLabel, + CardLabelDesc, + CardSubHeader, + ConnectingCheckPoints, + CheckPoint, + DisplayPhotos, + MediaRow, + LastRow, + Row, + StatusTable, + PopUp, + HeaderBar, + ImageViewer, + TextInput, + TextArea, + UploadFile, + ButtonSelector, + Toast, + ActionBar, + Menu, + SubmitBar, + Dropdown, + Loader, + Modal, + SectionalDropdown, +} from "@egovernments/digit-ui-react-components"; + +import { Close } from "../../Icons"; +import { useTranslation } from "react-i18next"; +import { isError, useQueryClient } from "react-query"; +import StarRated from "../../components/timelineInstances/StarRated"; + +const MapView = (props) => { + return ( +
+ +
+ ); +}; + +const Heading = (props) => { + return

{props.label}

; +}; + +const CloseBtn = (props) => { + return ( +
+ +
+ ); +}; + +const TLCaption = ({ data, comments }) => { + const { t } = useTranslation() + return ( +
+ {data?.date &&

{data?.date}

} +

{data?.name}

+

{data?.mobileNumber}

+ {data?.source &&

{t("ES_COMMON_FILED_VIA_" + data?.source.toUpperCase())}

} + {comments?.map( e => +
+

{t("WF_COMMON_COMMENTS")}

+

{e}

+
+ )} +
+ ); +}; + +const ComplaintDetailsModal = ({ workflowDetails, complaintDetails, close, popup, selectedAction, onAssign, tenantId, t }) => { + + // RAIN-5692 PGR : GRO is assigning complaint, Selecting employee and assign. Its not getting assigned. + // Fix for next action assignee dropdown issue + const stateArray = workflowDetails?.data?.initialActionState?.nextActions?.filter( ele => ele?.action == selectedAction ); + const useEmployeeData = Digit.Hooks.pgr.useEmployeeFilter( + tenantId, + stateArray?.[0]?.assigneeRoles?.length > 0 ? stateArray?.[0]?.assigneeRoles?.join(",") : "", + complaintDetails + ); + const employeeData = useEmployeeData + ? useEmployeeData.map((departmentData) => { + return { heading: departmentData.department, options: departmentData.employees }; + }) + : null; + + const [selectedEmployee, setSelectedEmployee] = useState(null); + const [comments, setComments] = useState(""); + const [file, setFile] = useState(null); + const [uploadedFile, setUploadedFile] = useState(null); + const [error, setError] = useState(null); + const cityDetails = Digit.ULBService.getCurrentUlb(); + const [selectedReopenReason, setSelectedReopenReason] = useState(null); + + useEffect(() => { + (async () => { + setError(null); + if (file) { + if (file.size >= 5242880) { + setError(t("CS_MAXIMUM_UPLOAD_SIZE_EXCEEDED")); + } else { + try { + // TODO: change module in file storage + const response = await Digit.UploadServices.Filestorage("property-upload", file, cityDetails.code); + if (response?.data?.files?.length > 0) { + setUploadedFile(response?.data?.files[0]?.fileStoreId); + } else { + setError(t("CS_FILE_UPLOAD_ERROR")); + } + } catch (err) { + setError(t("CS_FILE_UPLOAD_ERROR")); + } + } + } + })(); + }, [file]); + + const reopenReasonMenu = [t(`CS_REOPEN_OPTION_ONE`), t(`CS_REOPEN_OPTION_TWO`), t(`CS_REOPEN_OPTION_THREE`), t(`CS_REOPEN_OPTION_FOUR`)]; + // const uploadFile = useCallback( () => { + + // }, [file]); + + function onSelectEmployee(employee) { + setSelectedEmployee(employee); + } + + function addComment(e) { + setError(null); + setComments(e.target.value); + } + + function selectfile(e) { + setFile(e.target.files[0]); + } + + function onSelectReopenReason(reason) { + setSelectedReopenReason(reason); + } + + return ( + + } + headerBarEnd={ close(popup)} />} + actionCancelLabel={t("CS_COMMON_CANCEL")} + actionCancelOnSubmit={() => close(popup)} + actionSaveLabel={ + selectedAction === "ASSIGN" || selectedAction === "REASSIGN" + ? t("CS_COMMON_ASSIGN") + : selectedAction === "REJECT" + ? t("CS_COMMON_REJECT") + : selectedAction === "REOPEN" + ? t("CS_COMMON_REOPEN") + : t("CS_COMMON_RESOLVE") + } + actionSaveOnSubmit={() => { + if(selectedAction === "REJECT" && !comments) + setError(t("CS_MANDATORY_COMMENTS")); + else + onAssign(selectedEmployee, comments, uploadedFile); + }} + error={error} + setError={setError} + > + + {selectedAction === "REJECT" || selectedAction === "RESOLVE" || selectedAction === "REOPEN" ? null : ( + + {t("CS_COMMON_EMPLOYEE_NAME")} + {employeeData && } + + )} + {selectedAction === "REOPEN" ? ( + + {t("CS_REOPEN_COMPLAINT")} + + + ) : null} + {t("CS_COMMON_EMPLOYEE_COMMENTS")} +