Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Role access table #1593

Merged
merged 25 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bda99f1
removed iterator
abishekTa-egov Oct 17, 2024
cb14a31
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 17, 2024
2c7ff86
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 18, 2024
f72669d
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 18, 2024
011e94a
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 18, 2024
2903d4f
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 19, 2024
7a37877
changes
abishekTa-egov Oct 19, 2024
befc447
EOD checkopoint
abishekTa-egov Oct 19, 2024
4c045d7
validation for user role
abishekTa-egov Oct 21, 2024
50b838d
Response and user-employee validation working
abishekTa-egov Oct 21, 2024
72fdb4a
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 21, 2024
cc00681
Pull from console
abishekTa-egov Oct 21, 2024
56713ec
console.log and debuggers removed
abishekTa-egov Oct 21, 2024
0de3e8c
index path for response
abishekTa-egov Oct 21, 2024
df75d96
Making some changes
abishekTa-egov Oct 21, 2024
025d292
console removed
abishekTa-egov Oct 21, 2024
b41490e
random
abishekTa-egov Oct 21, 2024
eb3f03b
user access roles working
abishekTa-egov Oct 21, 2024
93324ea
localizations added
abishekTa-egov Oct 21, 2024
6a85c7d
Removed debuggera dn console
abishekTa-egov Oct 21, 2024
413baf0
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 21, 2024
741342e
Localizations
abishekTa-egov Oct 21, 2024
5a7c851
Changes
abishekTa-egov Oct 21, 2024
5e9eaf5
Merge branch 'console' of https://github.com/egovernments/DIGIT-Front…
abishekTa-egov Oct 21, 2024
02c451d
Delete package-lock.json
nabeelmd-eGov Oct 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,60 +1,55 @@
import React from 'react'
import React from 'react';
import { Card } from '@egovernments/digit-ui-components';
import HeaderComp from './HeaderComp';
import { useTranslation } from 'react-i18next';

const AssumptionsList = ({ customProps }) => {
const {t}=useTranslation();
const assumptionValues= customProps?.sessionData?.HYPOTHESIS.Assumptions?.assumptionValues
const { t } = useTranslation();

// Safely access assumptionValues using optional chaining
const assumptionValues = customProps?.sessionData?.HYPOTHESIS?.Assumptions?.assumptionValues || [];

let dic = {};
abishekTa-egov marked this conversation as resolved.
Show resolved Hide resolved

// Iterate through assumptionValues and build the dictionary
for (const ob of assumptionValues) {
if (!(ob?.category in dic)) {
dic[ob.category] = [{ [ob?.key]: ob.value }]
}else{
dic[ob.category].push({ [ob?.key]: ob.value })
const category = ob?.category || 'NA';
const key = ob?.key || 'NA';
const value = ob?.value || 'NA';

if (!(category in dic)) {
dic[category] = [{ [key]: value }];
} else {
dic[category].push({ [key]: value });
}
}








return (
<div>
{
Object.keys(dic).map((item, ind) => {

return (
< Card key={`card_${ind}`} style={{ padding: '20px', marginBottom: '15px' }}>
<HeaderComp title={String(item)}/>
<div className="as-table-like">
{dic[item].map((item1, index) => {
// Since each item1 is an object with a single key-value pair
const [key, value] = Object.entries(item1)[0]; // Destructure the first and only key-value pair
return (
<div key={`pair_${index}`} className="as-table-row">
<span className="as-table-cell as-key-cell">
<strong>{t(key)}</strong> {/* Display key as label */}
</span>
<span className="as-table-cell as-value-cell">
{t(value)} {/* Display value */}
</span>
</div>
);
})}
</div>
</Card>
);
})
}


</div >
)
}

export default AssumptionsList
{Object.keys(dic).map((item, ind) => (
<Card key={`card_${ind}`} style={{ padding: '20px', marginBottom: '15px' }}>
<HeaderComp title={String(item)} />
<div className="as-table-like">
{dic[item].map((item1, index) => {
// Safely destructure the key-value pair, with fallbacks for missing data
const [key, value] = Object.entries(item1)[0] || ['NA', 'NA'];

return (
<div key={`pair_${index}`} className="as-table-row">
<span className="as-table-cell as-key-cell">
<strong>{t(key)}</strong> {/* Display key as label */}
</span>
<span className="as-table-cell as-value-cell">
{t(value)} {/* Display value */}
</span>
</div>
);
})}
</div>
</Card>
))}
</div>
);
};

export default AssumptionsList;
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import React, { useState, Fragment } from "react";
import { Link, useHistory, useLocation } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { ActionBar, SubmitBar, ArrowLeft, ArrowForward } from "@egovernments/digit-ui-react-components";
import { Button } from "@egovernments/digit-ui-components";
import { PanelCard } from "@egovernments/digit-ui-components";
import { Button } from "@egovernments/digit-ui-react-components";
const Response = () => {

const { t } = useTranslation();
const history = useHistory();
const queryStrings = Digit.Hooks.useQueryParams();
Expand All @@ -14,6 +13,8 @@ const Response = () => {
queryStrings?.isSuccess === "true" ? true : queryStrings?.isSuccess === "false" ? false : true
);
const { state } = useLocation();
const back=(state?.back)?state?.back:"BACK";
const backlink=(state?.backlink)?(state.backlink):"employee";
nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
return (
<>
<PanelCard
Expand All @@ -25,7 +26,7 @@ const Response = () => {
cardStyles={{}}
className=""
customIcon=""
description="The user data uploaded will be available in your microplan user assignment section"
description={state.description}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add t

nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
// footerChildren={[
// <Button label="OK" onClick={function noRefCheck() { }} type="button" />
// ]}
Expand All @@ -44,13 +45,13 @@ const Response = () => {

</PanelCard>
<ActionBar className="mc_back">
<Link to={`/${window.contextPath}/employee/microplan/user-management`}>
<Link to={`/${window.contextPath}${backlink}`}>
<Button
style={{ margin: "0.5rem", minWidth: "12rem", marginLeft: "6rem" }}
style={{ margin: "0.5rem", minWidth: "10rem", marginLeft: "6rem" }}
className="previous-button"
variation="secondary"
label={t("BACK")}
icon="ArrowBack"
label={t(back)}
icon={"ArrowBack"}
nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
/>
</Link>
</ActionBar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useUserAccessContext } from "./UserAccessWrapper";
import { useMyContext } from "../utils/context";
import { useQueryClient } from "react-query";

function RoleTableComposer() {
function RoleTableComposer({nationalRoles}) {
const { t } = useTranslation();
const queryClient = useQueryClient();
const tenantId = Digit.ULBService.getCurrentTenantId();
Expand All @@ -27,6 +27,8 @@ function RoleTableComposer() {
const { mutate: planEmployeeCreate } = Digit.Hooks.microplanv1.usePlanEmployeeCreate();
const { mutate: planEmployeeUpdate } = Digit.Hooks.microplanv1.usePlanEmployeeUpdate();


const topBoundary = state?.boundaryHierarchy.find(boundary => boundary.parentBoundaryType === null);
const { isLoading: isHrmsLoading, data: HrmsData, error: hrmsError, refetch: refetchHrms } = Digit.Hooks.microplanv1.useSearchHRMSEmployee({
tenantId: tenantId,
microplanId: microplanId,
Expand All @@ -39,16 +41,23 @@ function RoleTableComposer() {
enabled: false,
select: (data) => {
const resp = data?.Employees?.map((item, index) => {
let selectedHierarchy = state?.boundaryHierarchy?.find(
nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
(j) => j.boundaryType === data?.planData?.find((i) => i.employeeId === item?.user?.userServiceUuid)?.hierarchyLevel
)
// if(category.startswith("ROOT")){
//
// }
return {
rowIndex: index + 1,
name: item?.user?.name,
email: item?.user?.emailId,
number: item?.user?.mobileNumber,
employeeId: item?.user?.userServiceUuid,
user: item?.user,
selectedHierarchy: state?.boundaryHierarchy?.find(
(j) => j.boundaryType === data?.planData?.find((i) => i.employeeId === item?.user?.userServiceUuid)?.hierarchyLevel
),
selectedHierarchy:
state?.boundaryHierarchy?.find(
(j) => j.boundaryType === data?.planData?.find((i) => i.employeeId === item?.user?.userServiceUuid)?.hierarchyLevel
),
selectedBoundaries: data?.planData?.find((i) => i.employeeId === item?.user?.userServiceUuid)?.jurisdiction,
userServiceUuid: item?.user?.userServiceUuid,
planData: data?.planData?.find((i) => i.employeeId === item?.user?.userServiceUuid),
Expand Down Expand Up @@ -119,11 +128,11 @@ function RoleTableComposer() {
return prev.map((i) =>
i.rowIndex === row.rowIndex
? {
...i,
selectedHierarchy: value,
boundaryOptions,
selectedBoundaries: i.selectedBoundaries || [], // Keep existing selected boundaries
}
...i,
selectedHierarchy: value,
boundaryOptions,
selectedBoundaries: i.selectedBoundaries || [], // Keep existing selected boundaries
}
: i
);
} else {
Expand Down Expand Up @@ -177,9 +186,9 @@ function RoleTableComposer() {
return prev.map((i) =>
i.rowIndex === row.rowIndex
? {
...i,
selectedBoundaries: [], // Clear selected boundaries
}
...i,
selectedBoundaries: [], // Clear selected boundaries
}
: i
);
} else {
Expand Down Expand Up @@ -208,9 +217,9 @@ function RoleTableComposer() {
return prev.map((i) =>
i.rowIndex === row.rowIndex
? {
...i,
selectedBoundaries: boundariesInEvent, // Update boundaries
}
...i,
selectedBoundaries: boundariesInEvent, // Update boundaries
}
: i
);
} else {
Expand Down Expand Up @@ -292,7 +301,18 @@ function RoleTableComposer() {
{
name: "Hierarchy",
cell: (row) => {
return (
return (category in nationalRoles) ? (
<Dropdown
className="form-field"
selected={{ code: topBoundary?.boundaryType }}
disable={true}
isMandatory={true}
option={[{ key: 1, code: topBoundary?.boundaryType }]}
select={{ code:topBoundary?.boundaryType }}
optionKey="code"
t={t}
/>
) : (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect usage of the 'select' prop in 'Dropdown' component

In the Dropdown component within the Hierarchy column, the select prop is expected to be a function that handles selection changes. However, it is currently being assigned an object, which may cause unexpected behavior.

Apply this diff to correct the usage:

<Dropdown
  className="form-field"
  selected={{ code: topBoundary?.boundaryType }}
  disable={true}
  isMandatory={true}
  option={[{ key: 1, code: topBoundary?.boundaryType }]}
-  select={{ code: topBoundary?.boundaryType }}
+  select={() => {}}
  optionKey="code"
  t={t}
/>

Since the dropdown is disabled (disable={true}), the select prop may not be necessary and can be omitted.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (category in nationalRoles) ? (
<Dropdown
className="form-field"
selected={{ code: topBoundary?.boundaryType }}
disable={true}
isMandatory={true}
option={[{ key: 1, code: topBoundary?.boundaryType }]}
select={{ code:topBoundary?.boundaryType }}
optionKey="code"
t={t}
/>
) : (
return (category in nationalRoles) ? (
<Dropdown
className="form-field"
selected={{ code: topBoundary?.boundaryType }}
disable={true}
isMandatory={true}
option={[{ key: 1, code: topBoundary?.boundaryType }]}
select={() => {}}
optionKey="code"
t={t}
/>
) : (

<Dropdown
className="roleTableCell"
selected={rowData?.find((item) => item?.rowIndex === row?.rowIndex)?.selectedHierarchy || null}
Expand All @@ -307,8 +327,9 @@ function RoleTableComposer() {
t={t}
/>
);
},
}
},

{
name: "Selected Boundary",
cell: (row) => (
Expand All @@ -331,7 +352,7 @@ function RoleTableComposer() {
const isUserAlreadyAssigned = HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.length > 0 ? true : false;
nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
const isUserAlreadyAssignedActive =
HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.length > 0 &&
HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.[0]?.active
HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.[0]?.active
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use 'find' instead of 'filter' when checking for a single item

When determining if a user is already assigned, using find is more efficient than filter when you only need to locate a single item.

Apply this diff to optimize the code:

-const isUserAlreadyAssigned = HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.length > 0 ? true : false;
-const isUserAlreadyAssignedActive =
-  HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.length > 0 &&
-    HrmsData?.planSearchData?.filter((i) => i.employeeId === row.employeeId)?.[0]?.active
-    ? true
-    : false;

+const userPlanData = HrmsData?.planSearchData?.find((i) => i.employeeId === row.employeeId);
+const isUserAlreadyAssigned = !!userPlanData;
+const isUserAlreadyAssignedActive = userPlanData?.active === true;

This change simplifies the logic and improves performance by avoiding unnecessary iterations.

Committable suggestion was skipped due to low confidence.

? true
: false;
return (
Expand Down Expand Up @@ -371,7 +392,9 @@ function RoleTableComposer() {
const closeToast = () => {
setShowToast(null);
};
if (isHrmsLoading) return <Loader />;
if (isHrmsLoading) {
return <Loader />
};
Comment on lines +375 to +377
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Remove unnecessary semicolon after 'if' block

There is an unnecessary semicolon after the if block checking isHrmsLoading. This semicolon can be removed to adhere to proper syntax.

Apply this diff to remove the semicolon:

if (isHrmsLoading) {
  return <Loader />
-};
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (isHrmsLoading) {
return <Loader />
};
if (isHrmsLoading) {
return <Loader />
}

return (
<>
<Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next";
import RoleTableComposer from "./RoleTableComposer";
import DataTable from "react-data-table-component";

function UserAccess({ category }) {
function UserAccess({ category,setData,nationalRoles }) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Approve function signature update with documentation suggestion.

The addition of setData and nationalRoles props enhances the component's functionality, aligning with the PR objectives. This change improves data management and potentially supports role-based access control.

Consider adding JSDoc comments to document these new props, their types, and their purpose. For example:

/**
 * @param {Object} props
 * @param {string} props.category - The category of user access
 * @param {Function} props.setData - Function to set data externally
 * @param {Array} props.nationalRoles - Array of national roles
 */
function UserAccess({ category, setData, nationalRoles }) {
  // ...
}

const { t } = useTranslation();
const tenantId = Digit.ULBService.getCurrentTenantId();
const { campaignId, microplanId, key, ...queryParams } = Digit.Hooks.useQueryParams();
Expand Down Expand Up @@ -33,6 +33,7 @@ function UserAccess({ category }) {
config: {
enabled: true,
select: (data) => {
setData(data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Approve data management enhancement with suggestion.

The addition of setData(data); improves data management by allowing external storage of fetched data. This change aligns well with the new setData prop and enhances the component's flexibility.

Consider adding a null check before calling setData to prevent potential errors:

if (setData && typeof setData === 'function') {
  setData(data);
}

This ensures that setData is defined and is a function before calling it, making the code more robust.

const rowData = data?.data?.map((item, index) => {
return {
id: index + 1,
Expand Down Expand Up @@ -84,7 +85,12 @@ function UserAccess({ category }) {
{
name: "Adminitrative Heirarchy",
selector: (row) => {
return row?.hierarchyLevel;
// if (category?.startsWith("ROOT")) {
// return "COUNTRY"; // Set to "Country" if true
// } else {
// return row?.hierarchyLevel; // Otherwise, return the existing hierarchy level
// }
nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
return row?.hierarchyLevel;
},
sortable: true,
},
Expand All @@ -95,6 +101,7 @@ function UserAccess({ category }) {
<>
{row?.jurisdiction?.map((item) => (
<div className="digit-tag-container userAccessCell">

nabeelmd-eGov marked this conversation as resolved.
Show resolved Hide resolved
<Chip
className=""
error=""
Expand Down Expand Up @@ -127,6 +134,7 @@ function UserAccess({ category }) {
<Button variation="secondary" label={t(`ASSIGN`)} icon={"AddIcon"} onClick={() => setShowPopUp(true)} />
</div>
<DataTable
category={category}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Approve addition of category prop with documentation suggestion.

The addition of the category prop to the DataTable component enhances its flexibility and aligns with the role-based functionality improvements.

To improve maintainability, consider adding a comment or updating the component's documentation to explain how the category prop affects the DataTable's behavior or appearance. This will help future developers understand the purpose and impact of this prop.

columns={columns}
data={planEmployee?.data}
pagination
Expand All @@ -149,7 +157,7 @@ function UserAccess({ category }) {
className={"roleComposer"}
type={"default"}
heading={t(`${category}`)}
children={[<RoleTableComposer />]}
children={[<RoleTableComposer category={category} nationalRoles={nationalRoles} />]}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update PopUp children to address React best practices.

The addition of category and nationalRoles props to RoleTableComposer enhances its functionality. However, there are two React-related issues to address:

  1. Use JSX elements instead of passing children as a prop.
  2. Add a key prop to the element in the array.

Please update the PopUp component as follows:

- children={[<RoleTableComposer category={category} nationalRoles={nationalRoles} />]}
+ children={<RoleTableComposer key="roleComposer" category={category} nationalRoles={nationalRoles} />}

This change resolves both the children prop issue and the missing key warning.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
children={[<RoleTableComposer category={category} nationalRoles={nationalRoles} />]}
children={<RoleTableComposer key="roleComposer" category={category} nationalRoles={nationalRoles} />}
🧰 Tools
🪛 Biome

[error] 159-159: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)


[error] 159-159: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

onOverlayClick={() => {}}
footerChildren={[<Button type={"button"} size={"large"} variation={"secondary"} label={t("CLOSE")} onClick={() => setShowPopUp(false)} />]}
sortFooterChildren={true}
Expand All @@ -172,4 +180,4 @@ function UserAccess({ category }) {
);
}

export default UserAccess;
export default UserAccess;
Loading