Skip to content

Payment: Attendance Approval Flow #2097

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

Open
wants to merge 135 commits into
base: console
Choose a base branch
from

Conversation

rachana-egov
Copy link
Contributor

@rachana-egov rachana-egov commented Jan 3, 2025

Choose the appropriate template for your PR:

Feature PR

Feature Request

JIRA ID

Module

Description

Related Issues


Bugfix PR

Bugfix Request

JIRA ID

Module

Description

Root Cause

Related Issues


Release PR

Summary by CodeRabbit

Based on the comprehensive summary of changes, here are the release notes:

  • New Features

    • Added new components for attendance and bill management
    • Introduced advanced search and filtering capabilities
    • Enhanced project and boundary selection interfaces
    • Implemented custom breadcrumb navigation
  • Improvements

    • Updated routing for employee payment workflows
    • Added internationalization support
    • Improved data fetching and state management
    • Enhanced user interaction with toast notifications
  • Performance

    • Optimized data loading with custom hooks
    • Implemented efficient pagination and filtering mechanisms
  • UI/UX

    • Refined styling for inbox and table components
    • Added responsive design elements
    • Improved error handling and user feedback

rachana-egov and others added 30 commits December 19, 2024 09:50
#2065)

HCMPRE-1717:: Load and store project details on Payments module initialization
attendance inbox in  progress
* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component
* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component

* boundary service API integration implemented for inbox screen

* Update filter_section.js

---------

Co-authored-by: rachana-egov <[email protected]>
* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component

* boundary service API integration implemented for inbox screen

* check box and register search API integration in progress
* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component

* boundary service API integration implemented for inbox screen

* check box and register search API integration in progress

* table data enriched
* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component

* boundary service API integration implemented for inbox screen

* check box and register search API integration in progress

* table data enriched

* removed debugger

* variable name changed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 19

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a584bf3 and b72304c.

📒 Files selected for processing (11)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/PaymentsCard.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1 hunks)
👮 Files not reviewed due to content moderation or server errors (2)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js
🧰 Additional context used
📓 Path-based instructions (11)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/PaymentsCard.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/PaymentsCard.js

[error] 30-30: Avoid unnecessary callback in flatMap call.

You can just use flat to flatten the array.
Safe fix: Replace unnecessary flatMap call to flat instead.

(lint/correctness/noFlatMapIdentity)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 220-224: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 235-244: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


[error] 112-125: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js

[error] 43-43: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js

[error] 124-132: 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)


[error] 133-155: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js

[error] 116-116: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

[error] 44-44: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 99-99: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 276-276: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 301-303: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 466-476: 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)


[error] 478-490: 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)


[error] 492-521: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 51-51: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 54-54: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 71-71: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 244-251: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 289-298: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 321-335: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js

[error] 34-34: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

🔇 Additional comments (42)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/PaymentsCard.js (4)

22-25: Use window.contextPath instead of hardcoded /payments-ui prefix

The hardcoded path should be changed to use the dynamic context path.

Apply this diff:

- link: `/payments-ui/employee/payments/${pathSuffix}`,
+ link: `/${window?.contextPath}/employee/payments/${pathSuffix}`,

35-37: LGTM! Links are well-structured.

The links array is properly configured with appropriate role assignments for each route.


40-42: LGTM! Role checking logic is correct.

The implementation properly validates user roles against required roles.


50-50: 🧹 Nitpick (assertive)

Update className to match module context.

The class name microplan-employee-module-card uses an incorrect prefix. Since this is a health payments module, consider using a more appropriate prefix.

Apply this diff:

- className: "microplan-employee-module-card",
+ className: "health-payments-employee-module-card",

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (2)

111-126: 🧹 Nitpick (assertive)

Use self-closing tag for BoundaryComponent.

For consistency and cleaner code, use self-closing tags for components without children.

- <BoundaryComponent
+ <BoundaryComponent
    reset={reset}
    makeReset={() => {
      setReset(false);
    }}
    isRequired={isRequired}
    initialValue={Digit.SessionStorage.get("selectedValues")}
    updateSeeeionStorage={(newSelectedValues) => {
      Digit.SessionStorage.set("selectedValues", JSON.stringify(newSelectedValues));
    }}
    onChange={onChangeId}
    selectedProject={projectSelected}
    lowestLevel={Digit.SessionStorage.get("paymentConfig")?.lowestLevelBoundary || lowerBoundaryDefaultSet}
-  ></BoundaryComponent>
+  />

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 112-125: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


119-120: 🧹 Nitpick (assertive)

Extract session storage key to a constant.

The session storage key "selectedValues" should be extracted to a constant for better maintainability.

+ const SELECTED_VALUES_KEY = "selectedValues";

- initialValue={Digit.SessionStorage.get("selectedValues")}
+ initialValue={Digit.SessionStorage.get(SELECTED_VALUES_KEY)}

- Digit.SessionStorage.set("selectedValues", JSON.stringify(newSelectedValues));
+ Digit.SessionStorage.set(SELECTED_VALUES_KEY, JSON.stringify(newSelectedValues));

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (4)

34-36: ⚠️ Potential issue

Remove debug console.log statement.

Debug statements should not be present in production code.

 selector: (row) => {
-    console.log(row);
     return (

Likely invalid or redundant comment.


168-174: 🧹 Nitpick (assertive)

Use optional chaining for prop function calls.

Make the event handlers more defensive using optional chaining on the function calls rather than the props object.

 const handlePageChange = (page, totalRows) => {
-    props?.handlePageChange(page, totalRows);
+    props.handlePageChange?.(page, totalRows);
 };

 const handlePerRowsChange = async (currentRowsPerPage, currentPage) => {
-    props?.handlePerRowsChange(currentRowsPerPage, currentPage);
+    props.handlePerRowsChange?.(currentRowsPerPage, currentPage);
 };

Likely invalid or redundant comment.


116-116: 🧹 Nitpick (assertive)

Simplify boolean expression.

The ternary expression can be simplified using the logical NOT operator.

-showBottom={isLastRow ? false : true}
+showBottom={!isLastRow}

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 116-116: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


8-11: 🧹 Nitpick (assertive)

Destructure specific props instead of using spread operator.

Explicitly listing the required props improves code maintainability and makes the component's dependencies clear.

-const MyBillsTable = ({ ...props }) => {
+const MyBillsTable = ({
+    data,
+    totalCount,
+    currentPage,
+    rowsPerPage,
+    handlePageChange,
+    handlePerRowsChange
+}) => {

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (10)

1-1: Remove unused and invalid imports

The imports useReducer, useMemo, and use are not used in this file. Additionally, use is not a valid React hook and may have been included by mistake. Please remove these to clean up the code.


5-5: Define 'location' or use 'useLocation' hook

The variable location is used but not defined in this scope. If you intend to access the browser's location or the route's state, consider importing useLocation from react-router-dom and using it to retrieve the location object.


51-51: Simplify the boolean expression

The ternary operator is unnecessary here. You can directly assign the boolean result of the condition.

🧰 Tools
🪛 Biome (1.9.4)

[error] 51-51: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


54-54: Simplify the boolean expression

Similarly, the ternary operator here is unnecessary. You can assign the boolean expression directly.

🧰 Tools
🪛 Biome (1.9.4)

[error] 54-54: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


215-223: Use a self-closing tag for <CustomInboxSearchLinks>

JSX elements without child content should be self-closing.

🧰 Tools
🪛 Biome (1.9.4)

[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


244-251: Use a self-closing tag for <BillBoundaryFilter>

JSX elements without child content should be self-closing.

🧰 Tools
🪛 Biome (1.9.4)

[error] 244-251: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


289-298: Use a self-closing tag for <BillInboxTable>

JSX elements without child content should be self-closing.

🧰 Tools
🪛 Biome (1.9.4)

[error] 289-298: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


321-335: Add a key prop to the Button component in the actionFields array

When rendering elements in an array, React recommends providing a unique key prop to each element to help identify which items have changed, are added, or are removed.

🧰 Tools
🪛 Biome (1.9.4)

[error] 321-335: 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)


198-200: Handle errors in the catch block

The catch block is empty, which may make debugging difficult if an error occurs. Consider adding error handling or logging inside the catch block.


165-165: Correct the offset calculation in handlePerRowsChange

The offset should be calculated using the updated currentRowsPerPage to ensure correct pagination.

Apply this diff:

- setLimitAndOffset({ limit: currentRowsPerPage, offset: (currentPage - 1) * rowsPerPage });
+ setLimitAndOffset({ limit: currentRowsPerPage, offset: (currentPage - 1) * currentRowsPerPage });
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (13)

44-44: Simplify boolean expression

The use of a ternary operator returning boolean literals is unnecessary. You can simplify the expression for better readability:

- enabled: registerNumber ? true : false,
+ enabled: !!registerNumber,
🧰 Tools
🪛 Biome (1.9.4)

[error] 44-44: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


99-99: Simplify boolean expression

The conditional check can be simplified by removing the unnecessary ternary operator:

- enabled: (AttendanceData ? true : false),
+ enabled: !!AttendanceData,
🧰 Tools
🪛 Biome (1.9.4)

[error] 99-99: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


276-276: Simplify boolean expression

Simplify the boolean condition by removing the ternary operator:

- enabled: individualIds.length > 0 ? true : false,
+ enabled: individualIds.length > 0,
🧰 Tools
🪛 Biome (1.9.4)

[error] 276-276: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


301-303: Simplify boolean expression

Remove the unnecessary ternary operator to streamline the condition:

- enabled: AttendanceData?.attendanceRegister[0]?.staff?.find(
-   (staff) => staff?.staffType?.includes("OWNER")
- )?.userId ? true : false,
+ enabled: !!AttendanceData?.attendanceRegister[0]?.staff?.find(
+   (staff) => staff?.staffType?.includes("OWNER")
+ )?.userId,
🧰 Tools
🪛 Biome (1.9.4)

[error] 301-303: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


466-476: Add unique key prop for each child in actionFields

When rendering elements in an array, each element should have a unique key prop to help React identify which items have changed or moved.

              disabledAction ? (
+               <Button
+                 key="goBackButton"
                  label={t(`HCM_AM_GO_BACK`)}
                  title={t(`HCM_AM_GO_BACK`)}
                  onClick={() => {
                    fromCampaignSupervisor
                      ? history.push(`/${window.contextPath}/employee/payments/generate-bill`, { fromViewScreen: true })
                      : history.push(`/${window.contextPath}/employee/payments/registers-inbox`);
                  }}
                  type="button"
                  style={{ minWidth: "14rem" }}
                  variation="primary"
                />
🧰 Tools
🪛 Biome (1.9.4)

[error] 466-476: 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)


478-490: Add unique key prop for each child in actionFields

Ensure that each element in the array has a unique key prop:

              ) : editAttendance ? (
+               <Button
+                 key="submitButton"
                  icon="CheckCircle"
                  label={t(`HCM_AM_SUBMIT_LABEL`)}
                  title={t(`HCM_AM_SUBMIT_LABEL`)}
                  onClick={() => {
                    setUpdateDisabled(true);
                    triggerMusterRollUpdate();
                  }}
                  style={{ minWidth: "14rem" }}
                  type="button"
                  variation="primary"
                  isDisabled={updateMutation.isLoading || updateDisabled || !isSubmitEnabled}
                />
🧰 Tools
🪛 Biome (1.9.4)

[error] 478-490: 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)


492-521: Add unique key prop for each child in actionFields

Add a unique key prop to the elements to prevent React warnings:

              ) : (
+               <Button
+                 key="actionsButton"
                  className="custom-class"
                  iconFill=""
                  label={t(`HCM_AM_ACTIONS`)}
                  menuStyles={{
                    bottom: "40px",
                  }}
                  onOptionSelect={(value) => {
                    if (value.code === "EDIT_ATTENDANCE") {
                      setOpenEditAlertPopUp(true);
                    } else if (value.code === "APPROVE") {
                      setOpenApproveCommentPopUp(true);
                    }
                  }}
                  options={[
                    {
                      code: "EDIT_ATTENDANCE",
                      name: t(`HCM_AM_ACTIONS_EDIT_ATTENDANCE`),
                    },
                    {
                      code: "APPROVE",
                      name: t(`HCM_AM_ACTIONS_APPROVE`),
                    },
                  ]}
                  optionsKey="name"
                  size=""
                  style={{ minWidth: "14rem" }}
                  title=""
                  type="actionButton"
                />
🧰 Tools
🪛 Biome (1.9.4)

[error] 492-521: 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)


183-185: Handle errors appropriately in the catch block

Empty catch blocks can obscure errors and make debugging difficult. Consider adding error handling or logging within the catch block to ensure any issues are surfaced during execution.

        } catch (error) {
-         /// will show estimate data only
+         console.error('Error approving muster roll:', error);
          /// will show estimate data only
        }

226-228: Handle errors appropriately in the catch block

Add error handling or logging to the catch block to capture potential errors:

        } catch (error) {
-         /// will show estimate data only
+         console.error('Error updating muster roll:', error);
          /// will show estimate data only
        }

210-218: Avoid using setTimeout for navigation after showing a toast

Using setTimeout to delay navigation can lead to unpredictable behavior. Instead, use a callback or the onClose prop of the Toast component to navigate after the toast is dismissed.

              onSuccess: (data) => {
                setShowToast({
                  key: "success",
                  label: t("HCM_AM_ATTENDANCE_UPDATED_SUCCESSFULLY"),
                  transitionTime: 3000,
+                 onClose: () => {
+                   setUpdateDisabled(false);
+                   history.push(
+                     `/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`
+                   );
+                 },
                });
-               // Delay the navigation for 3 seconds
-               setTimeout(() => {
-                 setUpdateDisabled(false);
-                 history.push(
-                   `/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`
-                 );
-               }, 3000);
              },

212-222: Handle possible undefined error messages

When handling errors, ensure that you have a default message to prevent displaying undefined to the user.

              onError: (error) => {
                setUpdateDisabled(false);
-               setShowToast({ key: "error", label: t(error?.response?.data?.Errors?.[0]?.message), transitionTime: 3000 });
+               const errorMessage = error?.response?.data?.Errors?.[0]?.message || t("COMMON_ERROR_MESSAGE");
+               setShowToast({ key: "error", label: errorMessage, transitionTime: 3000 });
              },

342-342: Update the dependencies array in useEffect hook

The comment /// need to update dependency suggests that the dependencies array might be incomplete. Ensure all external variables used inside the useEffect are included in the dependencies array to prevent potential issues.

      }, [AllIndividualsData, data]); /// need to update dependency

21-21: 🧹 Nitpick (assertive)

Remove debugging console.log statement

There is a console.log statement used for debugging purposes. It's good practice to remove such statements from production code to keep the console output clean.

-   console.log(Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()), 'vvvvv');

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (3)

19-19: Ensure safe access to location.state

Destructuring fromCampaignSupervisor from local?.state || false can cause issues if local.state is null or not an object. Consider providing a default object to prevent errors.

-   const { fromCampaignSupervisor } = local?.state || false;
+   const { fromCampaignSupervisor } = local?.state || {};

62-62: Use optional chaining with window.contextPath

Accessing window.contextPath directly without checking if it exists can lead to runtime errors if window.contextPath is undefined. Use optional chaining to prevent potential issues.

-     if (window.location.pathname !== `/${window.contextPath}/employee/`) {
+     if (window.location.pathname !== `/${window?.contextPath}/employee/`) {

77-85: Avoid inline function components in routes

Using inline arrow functions in the component prop of PrivateRoute can lead to unnecessary re-renders. Consider passing the component reference directly for better performance.

-            <PrivateRoute path={`${path}/view-attendance`} component={() => <ViewAttendance />} />
-            <PrivateRoute path={`${path}/edit-attendance`} component={() => <ViewAttendance editAttendance={true} />} />
-            <PrivateRoute path={`${path}/attendance-approve-success`} component={() => <Response />} />
-            <PrivateRoute path={`${path}/attendance-approve-failed`} component={() => <Response />} />
-            <PrivateRoute path={`${path}/registers-inbox`} component={() => <AttendanceInbox />} />
-            <PrivateRoute path={`${path}/generate-bill`} component={() => <BillInbox />} />
-            <PrivateRoute path={`${path}/my-bills`} component={() => <MyBills />} />
+            <PrivateRoute path={`${path}/view-attendance`} component={ViewAttendance} />
+            <PrivateRoute path={`${path}/edit-attendance`}>
+              <ViewAttendance editAttendance={true} />
+            </PrivateRoute>
+            <PrivateRoute path={`${path}/attendance-approve-success`} component={Response} />
+            <PrivateRoute path={`${path}/attendance-approve-failed`} component={Response} />
+            <PrivateRoute path={`${path}/registers-inbox`} component={AttendanceInbox} />
+            <PrivateRoute path={`${path}/generate-bill`} component={BillInbox} />
+            <PrivateRoute path={`${path}/my-bills`} component={MyBills} />
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (6)

26-31: Remove commented-out code

The commented-out code is unnecessary and can be removed to improve code readability.

      // const [tableDatak, setTableDatak] = useState([]);

      // useEffect(() => {
      //   setTableDatak(tableData)

      // }, [tableData]);

53-62: Remove commented-out column definitions

The commented-out column definition can be removed to clean up the code.

        // {
        //   name: t("HCM_AM_ATTENDANCE_NAME"),
        //   selector: (row) => {
        //     return (
        //       <div style={{ fontSize: "14px" }} className="ellipsis-cell" title={row?.name || t("NA")}>
        //         {row?.name || t("NA")}
        //       </div>
        //     );
        //   },
        // },

104-107: Consolidate NoResultsFound checks

Instead of checking !tableData, consider consolidating the condition to improve clarity:

          {
-           !tableData ? (
+           (!tableData || tableData.length === 0) ? (
              <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />
            ) : (

135-137: Consolidate NoResultsFound checks

You can simplify the condition to check for empty data:

-           {tableData && tableData.length === 0 ? (
+           {(!tableData || tableData.length === 0) ? (
              <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />
            ) : (

40-99: Refactor column definitions to reduce code duplication

Several columns have similar structures. Consider creating a helper function to generate the column definitions to improve maintainability.


114-124: Extract tab configurations into constants

To enhance readability and ease future changes, consider moving the tab configuration into a constant.

Comment on lines +11 to +17
Digit.SessionStorage.set("AttendandeData");
Digit.SessionStorage.del("paymentInbox");
Digit.SessionStorage.del("selectedValues");
window.Digit.SessionStorage.del("selectedLevel");
window.Digit.SessionStorage.del("selectedProject");
window.Digit.SessionStorage.del("selectedBoundaryCode");
window.Digit.SessionStorage.del("boundary");
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

Fix session storage operations and maintain consistency.

Several issues found in session storage operations:

  1. AttendandeData is being set without a value
  2. There's a typo in "AttendandeData" (should be "AttendanceData")
  3. Inconsistent usage of Digit vs window.Digit

Apply this diff to fix the issues:

- Digit.SessionStorage.set("AttendandeData");
+ Digit.SessionStorage.set("AttendanceData", null);
  Digit.SessionStorage.del("paymentInbox");
  Digit.SessionStorage.del("selectedValues");
- window.Digit.SessionStorage.del("selectedLevel");
- window.Digit.SessionStorage.del("selectedProject");
- window.Digit.SessionStorage.del("selectedBoundaryCode");
- window.Digit.SessionStorage.del("boundary");
+ Digit.SessionStorage.del("selectedLevel");
+ Digit.SessionStorage.del("selectedProject");
+ Digit.SessionStorage.del("selectedBoundaryCode");
+ Digit.SessionStorage.del("boundary");
📝 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
Digit.SessionStorage.set("AttendandeData");
Digit.SessionStorage.del("paymentInbox");
Digit.SessionStorage.del("selectedValues");
window.Digit.SessionStorage.del("selectedLevel");
window.Digit.SessionStorage.del("selectedProject");
window.Digit.SessionStorage.del("selectedBoundaryCode");
window.Digit.SessionStorage.del("boundary");
Digit.SessionStorage.set("AttendanceData", null);
Digit.SessionStorage.del("paymentInbox");
Digit.SessionStorage.del("selectedValues");
Digit.SessionStorage.del("selectedLevel");
Digit.SessionStorage.del("selectedProject");
Digit.SessionStorage.del("selectedBoundaryCode");
Digit.SessionStorage.del("boundary");

Comment on lines +98 to +113
return (
<React.Fragment>
<Header styles={{ fontSize: "32px" }}>
{t("HCM_AM_MY_BILLS")}
</Header>


<MyBillsSearch onSubmit={onSubmit} onClear={onClear} />

<Card>
{isFetching ? <Loader /> : tableData.length === 0 ? <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND_FOR_BILLS`)} /> : <MyBillsTable data={tableData} totalCount={totalCount} rowsPerPage={rowsPerPage} currentPage={currentPage} handlePageChange={handlePageChange}
handlePerRowsChange={handlePerRowsChange} />}
</Card>

</React.Fragment>
);
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

Add error boundary for better error handling.

The component lacks an error boundary to gracefully handle runtime errors. Consider wrapping the component with an error boundary to prevent the entire app from crashing.

Create an error boundary component:

class BillsErrorBoundary extends React.Component {
  state = { hasError: false };
  
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  
  render() {
    if (this.state.hasError) {
      return <Card>
        <div>{t("HCM_AM_ERROR_LOADING_BILLS")}</div>
      </Card>;
    }
    return this.props.children;
  }
}

Wrap the component with the error boundary:

 return (
+    <BillsErrorBoundary>
         <React.Fragment>
             {/* existing code */}
         </React.Fragment>
+    </BillsErrorBoundary>
 );

body: {
billCriteria: {
tenantId: tenantId,
referenceIds: ["1dd5cd57-61d5-4c41-9861-769bb8735617"],
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

Remove hardcoded referenceId.

The API request contains a hardcoded referenceId. This should be derived from the project or configuration.

-                referenceIds: ["1dd5cd57-61d5-4c41-9861-769bb8735617"],
+                referenceIds: project?.[0]?.id ? [project[0].id] : [],
📝 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
referenceIds: ["1dd5cd57-61d5-4c41-9861-769bb8735617"],
referenceIds: project?.[0]?.id ? [project[0].id] : [],

title: '',
});
const [currentPage, setCurrentPage] = useState(1);
const [rowsPerPage, setRowsPerPage] = useState(5);
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)

Consider making the rows per page configurable.

The initial value for rowsPerPage is hardcoded to 5. Consider making this configurable through constants or environment variables for better maintainability and flexibility.

-    const [rowsPerPage, setRowsPerPage] = useState(5);
+    const [rowsPerPage, setRowsPerPage] = useState(Digit.Config.ROWS_PER_PAGE || 5);

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +72 to +77
useEffect(() => {
if (BillData) {
setTableData(BillData.bills);
setTotalCount(BillData?.pagination?.totalCount);
}
}, [BillData])
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

Prevent potential memory leak in useEffect.

The effect that updates table data doesn't handle component unmount scenarios, which could lead to memory leaks if the component unmounts while the data is being processed.

 useEffect(() => {
+    let isSubscribed = true;
     if (BillData) {
+        if (isSubscribed) {
             setTableData(BillData.bills);
             setTotalCount(BillData?.pagination?.totalCount);
+        }
     }
+    return () => {
+        isSubscribed = false;
+    };
 }, [BillData])
📝 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
useEffect(() => {
if (BillData) {
setTableData(BillData.bills);
setTotalCount(BillData?.pagination?.totalCount);
}
}, [BillData])
useEffect(() => {
let isSubscribed = true;
if (BillData) {
if (isSubscribed) {
setTableData(BillData.bills);
setTotalCount(BillData?.pagination?.totalCount);
}
}
return () => {
isSubscribed = false;
};
}, [BillData])

const local = useLocation();
const { fromCampaignSupervisor } = local?.state || false;

console.log(Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()), 'vvvvv');
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 debugging console.log statement

There is a console.log statement present which seems to be for debugging purposes. It's recommended to remove such statements from production code.

-     console.log(Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()), 'vvvvv');

Comment on lines +8 to +9
const iconHeight = props?.height || 262;
const iconWidth = props?.width || 336;
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)

Make props access consistent.

The optional chaining operator (?.) is used inconsistently. Since default props are defined, you can safely access props directly.

-    const iconHeight = props?.height || 262;
-    const iconWidth = props?.width || 336;
+    const iconHeight = props.height;
+    const iconWidth = props.width;
     return (
-        <div className={`digit-no-data-found ${props?.className ? props?.className : ""}`} style={props?.style}>
+        <div className={`digit-no-data-found ${props.className || ''}`} style={props.style}>
             <SearchCustomSVG height={iconHeight} width={iconWidth} />
-            <span className="digit-error-msg">{t(props?.placeholderText) || t("COMMON_NO_RESULTS_FOUND")}</span>
+            <span className="digit-error-msg">{t(props.placeholderText || "COMMON_NO_RESULTS_FOUND")}</span>

Also applies to: 11-13

import React from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
// import {SearchCustomSVG} from ./SearchCustomSVG
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 or fix the commented import statement.

The commented import statement appears to be incomplete and has incorrect syntax. Either remove it if it's no longer needed or uncomment and fix it to properly import the SVG component.

-// import {SearchCustomSVG} from ./SearchCustomSVG

const iconHeight = props?.height || 262;
const iconWidth = props?.width || 336;
return (
<div className={`digit-no-data-found ${props?.className ? props?.className : ""}`} style={props?.style}>
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)

Simplify className concatenation using template literals.

The className concatenation can be simplified using template literals for better readability.

-<div className={`digit-no-data-found ${props?.className ? props?.className : ""}`} style={props?.style}>
+<div className={`digit-no-data-found ${props.className || ''}`} style={props.style}>
📝 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
<div className={`digit-no-data-found ${props?.className ? props?.className : ""}`} style={props?.style}>
<div className={`digit-no-data-found ${props.className || ''}`} style={props.style}>

Comment on lines +33 to +79
const SearchCustomSVG = ({ style = {}, width = "15", height = "15", fill = "#C84C0E" }) => (
<svg width="438" height="339" viewBox="0 0 438 339" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_69315_98758)">
<path d="M282.846 148.82C292.701 148.82 300.691 140.857 300.691 131.035C300.691 121.213 292.701 113.25 282.846 113.25C272.99 113.25 265 121.213 265 131.035C265 140.857 272.99 148.82 282.846 148.82Z" fill="#E6E6E6" />
<path d="M326.578 153.894L307.929 135.308C309.358 133.092 310.327 130.613 310.778 128.017C311.228 125.422 311.151 122.762 310.551 120.196C309.952 117.631 308.841 115.211 307.286 113.081C305.731 110.951 303.762 109.153 301.498 107.795C297.233 105.256 292.166 104.406 287.302 105.413C282.438 106.42 278.131 109.211 275.233 113.232C272.567 116.958 271.287 121.493 271.612 126.057C271.937 130.621 273.848 134.93 277.016 138.243C280.183 141.555 284.41 143.665 288.969 144.208C293.528 144.752 298.134 143.695 301.997 141.221L320.646 159.806C321.432 160.589 322.499 161.029 323.611 161.029C324.723 161.029 325.79 160.588 326.576 159.804C327.363 159.021 327.805 157.958 327.805 156.849C327.805 155.741 327.364 154.678 326.578 153.894ZM301.3 134.615C298.99 136.918 295.949 138.351 292.697 138.67C289.445 138.989 286.182 138.175 283.465 136.365C280.748 134.556 278.744 131.864 277.795 128.747C276.847 125.631 277.012 122.283 278.262 119.274C279.513 116.265 281.772 113.781 284.654 112.246C287.536 110.711 290.863 110.219 294.068 110.854C297.273 111.49 300.158 113.213 302.231 115.73C304.304 118.248 305.437 121.404 305.437 124.661C305.44 126.51 305.075 128.341 304.365 130.049C303.655 131.757 302.614 133.309 301.3 134.615Z" fill="#3F3D56" />
<path d="M428.319 198.245C476.012 250.808 337.759 326.56 226.048 326.56C114.336 326.56 37.0494 267.866 23.7762 198.245C-8.40666 29.4382 297.982 -77.8546 226.048 69.9303C121.195 285.344 390.76 156.85 428.319 198.245Z" fill="#E6E6E6" />
<path d="M406.921 210.683C454.613 263.246 316.361 338.997 204.649 338.997C92.9378 338.997 15.651 280.303 2.37779 210.683C-29.8051 41.8757 276.584 -65.4171 204.649 82.3678C99.7964 297.781 369.362 169.288 406.921 210.683Z" fill="#0B4B66" fill-opacity="0.31" />
<path d="M75.2701 58.9113C77.486 58.9113 79.2823 57.1211 79.2823 54.9127C79.2823 52.7043 77.486 50.9141 75.2701 50.9141C73.0542 50.9141 71.2578 52.7043 71.2578 54.9127C71.2578 57.1211 73.0542 58.9113 75.2701 58.9113Z" fill="white" />
<path d="M54.6168 74.4615C58.31 74.4615 61.3039 71.4778 61.3039 67.7972C61.3039 64.1165 58.31 61.1328 54.6168 61.1328C50.9236 61.1328 47.9297 64.1165 47.9297 67.7972C47.9297 71.4778 50.9236 74.4615 54.6168 74.4615Z" fill="white" />
<path d="M155.544 67.9325C158.006 67.9325 160.002 65.9434 160.002 63.4897C160.002 61.036 158.006 59.0469 155.544 59.0469C153.082 59.0469 151.086 61.036 151.086 63.4897C151.086 65.9434 153.082 67.9325 155.544 67.9325Z" fill="white" />
<path d="M54.7921 203.886C56.2694 203.886 57.4669 202.693 57.4669 201.22C57.4669 199.748 56.2694 198.555 54.7921 198.555C53.3148 198.555 52.1172 199.748 52.1172 201.22C52.1172 202.693 53.3148 203.886 54.7921 203.886Z" fill="#E6E6E6" />
<path d="M242.034 295.41C243.512 295.41 244.709 294.216 244.709 292.744C244.709 291.272 243.512 290.078 242.034 290.078C240.557 290.078 239.359 291.272 239.359 292.744C239.359 294.216 240.557 295.41 242.034 295.41Z" fill="#E6E6E6" />
<path d="M67.7203 152.345C68.4589 152.345 69.0577 151.749 69.0577 151.013C69.0577 150.276 68.4589 149.68 67.7203 149.68C66.9816 149.68 66.3828 150.276 66.3828 151.013C66.3828 151.749 66.9816 152.345 67.7203 152.345Z" fill="#E6E6E6" />
<path d="M178.283 251.869C179.021 251.869 179.62 251.272 179.62 250.536C179.62 249.8 179.021 249.203 178.283 249.203C177.544 249.203 176.945 249.8 176.945 250.536C176.945 251.272 177.544 251.869 178.283 251.869Z" fill="#E6E6E6" />
<path d="M379.337 238.986C380.076 238.986 380.675 238.389 380.675 237.653C380.675 236.917 380.076 236.32 379.337 236.32C378.599 236.32 378 236.917 378 237.653C378 238.389 378.599 238.986 379.337 238.986Z" fill="#E6E6E6" />
<path d="M316.478 278.525C317.217 278.525 317.816 277.928 317.816 277.192C317.816 276.456 317.217 275.859 316.478 275.859C315.739 275.859 315.141 276.456 315.141 277.192C315.141 277.928 315.739 278.525 316.478 278.525Z" fill="#E6E6E6" />
<path d="M250.947 230.541C251.685 230.541 252.284 229.944 252.284 229.208C252.284 228.472 251.685 227.875 250.947 227.875C250.208 227.875 249.609 228.472 249.609 229.208C249.609 229.944 250.208 230.541 250.947 230.541Z" fill="#E6E6E6" />
<path d="M166.244 99.033C166.982 99.033 167.581 98.4362 167.581 97.7001C167.581 96.964 166.982 96.3672 166.244 96.3672C165.505 96.3672 164.906 96.964 164.906 97.7001C164.906 98.4362 165.505 99.033 166.244 99.033Z" fill="#E6E6E6" />
<path d="M176.947 33.2752C177.685 33.2752 178.284 32.6784 178.284 31.9423C178.284 31.2061 177.685 30.6094 176.947 30.6094C176.208 30.6094 175.609 31.2061 175.609 31.9423C175.609 32.6784 176.208 33.2752 176.947 33.2752Z" fill="#E6E6E6" />
<path d="M170.705 310.072C171.443 310.072 172.042 309.475 172.042 308.739C172.042 308.003 171.443 307.406 170.705 307.406C169.966 307.406 169.367 308.003 169.367 308.739C169.367 309.475 169.966 310.072 170.705 310.072Z" fill="#E6E6E6" />
<path d="M104.72 282.08C105.459 282.08 106.058 281.483 106.058 280.747C106.058 280.011 105.459 279.414 104.72 279.414C103.982 279.414 103.383 280.011 103.383 280.747C103.383 281.483 103.982 282.08 104.72 282.08Z" fill="#E6E6E6" />
<path d="M313.806 234.095C314.545 234.095 315.144 233.499 315.144 232.763C315.144 232.026 314.545 231.43 313.806 231.43C313.068 231.43 312.469 232.026 312.469 232.763C312.469 233.499 313.068 234.095 313.806 234.095Z" fill="#E6E6E6" />
<path d="M66.1451 103.872C68.361 103.872 70.1573 102.082 70.1573 99.8736C70.1573 97.6652 68.361 95.875 66.1451 95.875C63.9292 95.875 62.1328 97.6652 62.1328 99.8736C62.1328 102.082 63.9292 103.872 66.1451 103.872Z" fill="white" />
<path d="M131.822 161.231C131.822 173.174 113.295 201.002 107.88 208.88C107.717 209.118 107.498 209.312 107.242 209.447C106.986 209.582 106.7 209.652 106.411 209.652C106.122 209.652 105.836 209.582 105.58 209.447C105.324 209.312 105.105 209.118 104.942 208.88C99.5275 201.002 81 173.174 81 161.231C81 157.905 81.6573 154.612 82.9343 151.54C84.2113 148.467 86.0831 145.675 88.4427 143.324C90.8023 140.972 93.6036 139.107 96.6866 137.834C99.7696 136.561 103.074 135.906 106.411 135.906C109.748 135.906 113.052 136.561 116.135 137.834C119.218 139.107 122.02 140.972 124.379 143.324C126.739 145.675 128.611 148.467 129.888 151.54C131.165 154.612 131.822 157.905 131.822 161.231Z" fill="white" />
<path d="M106.405 172.339C113.545 172.339 119.333 166.571 119.333 159.455C119.333 152.339 113.545 146.57 106.405 146.57C99.2648 146.57 93.4766 152.339 93.4766 159.455C93.4766 166.571 99.2648 172.339 106.405 172.339Z" fill="#C84C0E" />
<path d="M106.185 223.432C114.433 223.432 121.119 222.139 121.119 220.544C121.119 218.949 114.433 217.656 106.185 217.656C97.9364 217.656 91.25 218.949 91.25 220.544C91.25 222.139 97.9364 223.432 106.185 223.432Z" fill="white" />
<path d="M322.762 141.51C322.888 141.729 322.993 141.957 323.079 142.192L346.644 148.115L350.891 144.356L358 149.412L351.197 156.728C350.648 157.319 349.901 157.733 349.069 157.908C348.237 158.082 347.366 158.008 346.585 157.696L321.129 147.531C320.265 148.073 319.24 148.364 318.188 148.367C317.137 148.369 316.11 148.081 315.244 147.542C314.377 147.003 313.713 146.239 313.339 145.35C312.965 144.461 312.899 143.49 313.149 142.567C313.4 141.643 313.955 140.811 314.742 140.179C315.528 139.548 316.509 139.149 317.552 139.034C318.596 138.919 319.653 139.095 320.584 139.537C321.515 139.979 322.275 140.667 322.762 141.51Z" fill="#FFB8B8" />
<path d="M343.999 240L337.901 240L335 219L344 219L343.999 240Z" fill="#FFB8B8" />
<path d="M345 238L333.396 238C332.425 238 331.462 238.175 330.565 238.516C329.668 238.857 328.853 239.356 328.166 239.985C327.479 240.615 326.935 241.362 326.563 242.185C326.191 243.007 326 243.889 326 244.779V244.999L345 245L345 238Z" fill="#2F2E41" />
<path d="M327.999 239L321.901 239L319 218L328 218L327.999 239Z" fill="#FFB8B8" />
<path d="M330 237L317.785 237C316.763 237 315.75 237.175 314.805 237.516C313.861 237.857 313.003 238.356 312.28 238.985C311.557 239.615 310.984 240.362 310.593 241.185C310.201 242.007 310 242.889 310 243.779V243.999L330 244L330 237Z" fill="#2F2E41" />
<path d="M370.818 190.399C369.539 193.847 367.113 196.849 363.875 198.987C360.638 201.126 356.75 202.297 352.748 202.338L352.445 202.343C349.345 202.423 345.707 201.514 342.137 200.21C335.086 197.631 328.313 193.503 326.516 192.368L329.562 218.993L330.796 229.787C330.827 230.066 330.794 230.348 330.698 230.615C330.602 230.882 330.445 231.127 330.239 231.336C330.032 231.544 329.779 231.711 329.498 231.825C329.216 231.94 328.911 231.999 328.602 232H320.997C320.51 232 320.036 231.854 319.649 231.583C319.263 231.312 318.986 230.933 318.862 230.504L306.307 187.02C305.93 185.718 305.9 184.354 306.218 183.039C306.537 181.725 307.195 180.499 308.138 179.462C309.081 178.424 310.283 177.607 311.643 177.076C313.003 176.545 314.482 176.316 315.958 176.408L342.039 178.033L340.217 171.407L363.497 170L363.566 170.045C364.124 170.414 364.667 170.802 365.186 171.207C366.484 172.205 367.635 173.351 368.609 174.618C370.353 176.89 371.465 179.513 371.849 182.261C372.234 185.01 371.88 187.803 370.818 190.399Z" fill="#2F2E41" />
<path d="M370.814 190.681C369.53 194.107 367.095 197.089 363.847 199.215C360.598 201.34 356.696 202.504 352.68 202.544C348.84 200.794 345.135 198.815 341.589 196.619L342.031 200.429L345.884 233.801C345.915 234.078 345.881 234.359 345.785 234.624C345.689 234.889 345.532 235.133 345.324 235.34C345.117 235.547 344.864 235.713 344.581 235.827C344.298 235.94 343.992 235.999 343.682 236H336.051C335.561 236 335.085 235.854 334.698 235.585C334.31 235.316 334.032 234.939 333.908 234.513L329.411 219.093L321.308 191.305C320.93 190.012 320.899 188.656 321.219 187.35C321.539 186.044 322.199 184.826 323.146 183.795C324.092 182.765 325.298 181.952 326.663 181.424C328.027 180.897 329.512 180.669 330.994 180.761L357.167 182.376L355.339 175.792L368.597 175C370.347 177.258 371.463 179.864 371.849 182.595C372.235 185.326 371.88 188.101 370.814 190.681Z" fill="#2F2E41" />
<path d="M365.195 173.262L365.371 173.242L369.453 154.989C369.488 154.83 372.824 139.085 362.595 130.854L362.417 129.727C362.372 129.439 362.258 129.163 362.084 128.919C361.91 128.674 361.679 128.467 361.409 128.312C361.138 128.156 360.833 128.056 360.516 128.017C360.199 127.979 359.876 128.004 359.57 128.09L349.934 130.809C349.388 130.962 348.929 131.301 348.652 131.755C348.375 132.209 348.302 132.743 348.448 133.245L349.385 136.486C348.086 137.873 332.796 154.618 338.122 167.518L340.507 176L365.195 173.262Z" fill="#C84C0E" />
<path d="M325.777 159.404C326.004 159.534 326.22 159.681 326.422 159.842L349.662 154.15L351.181 149L360 150.076L358.281 159.432C358.143 160.188 357.739 160.882 357.131 161.411C356.522 161.939 355.743 162.273 354.909 162.363L327.721 165.293C327.289 166.151 326.582 166.868 325.692 167.35C324.803 167.831 323.774 168.054 322.742 167.989C321.71 167.924 320.724 167.574 319.916 166.985C319.108 166.396 318.515 165.597 318.216 164.693C317.918 163.79 317.928 162.825 318.246 161.927C318.563 161.029 319.173 160.24 319.994 159.666C320.814 159.092 321.807 158.759 322.84 158.712C323.873 158.665 324.898 158.906 325.777 159.404Z" fill="#FFB8B8" />
<path d="M349.991 153.717L361.426 154.984C361.751 155.02 362.082 154.995 362.395 154.912C362.708 154.828 362.997 154.687 363.241 154.499C363.485 154.31 363.679 154.079 363.81 153.82C363.941 153.562 364.006 153.282 364 153L363.782 143.118C363.987 141.685 363.523 140.241 362.492 139.102C361.46 137.964 359.946 137.223 358.281 137.043C356.616 136.862 354.935 137.258 353.608 138.141C352.281 139.025 351.416 140.325 351.202 141.756L348.086 151.237C347.997 151.509 347.977 151.793 348.027 152.072C348.078 152.351 348.197 152.617 348.378 152.852C348.559 153.088 348.797 153.287 349.075 153.436C349.353 153.585 349.666 153.681 349.991 153.717Z" fill="#C84C0E" />
<path d="M353.5 126C346.596 126 341 121.075 341 115C341 108.925 346.596 104 353.5 104C360.404 104 366 108.925 366 115C366 121.075 360.404 126 353.5 126Z" fill="#FFB8B8" />
<path d="M354.181 116.174L355.684 113.68C358.531 124.251 353.503 133 353.503 133L373.019 124.714L372.833 121.775L374.764 123.772L377.539 122.378L377.906 120.472L380 120.944L372.355 108.3C364.934 96.2673 354.147 100.861 354.147 100.861C336.985 100.118 339.081 115.55 339.081 115.55L354.181 116.174Z" fill="#2F2E41" />
<path d="M210.881 197.214C213.405 195.601 210.335 186.34 204.024 176.527C197.712 166.715 190.549 160.068 188.024 161.681C185.5 163.294 188.57 172.556 194.881 182.368C201.193 192.18 208.356 198.827 210.881 197.214Z" fill="#3F3D56" />
</g>
<defs>
<clipPath id="clip0_69315_98758">
<rect width="438" height="339" fill="white" />
</clipPath>
</defs>
</svg>
);
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

Add accessibility attributes to the SVG.

The SVG lacks accessibility attributes, which are essential for screen readers. Also, consider memoizing the component for performance optimization.

-const SearchCustomSVG = ({ style = {}, width = "15", height = "15", fill = "#C84C0E" }) => (
+const SearchCustomSVG = React.memo(({ style = {}, width = "15", height = "15", fill = "#C84C0E" }) => (
-    <svg width="438" height="339" viewBox="0 0 438 339" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <svg
+        width={width}
+        height={height}
+        viewBox="0 0 438 339"
+        fill="none"
+        xmlns="http://www.w3.org/2000/svg"
+        role="img"
+        aria-label="No search results found"
+    >
+        <title>No search results found</title>
         {/* SVG content */}
     </svg>
-);
+));
+
+SearchCustomSVG.displayName = 'SearchCustomSVG';
📝 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
const SearchCustomSVG = ({ style = {}, width = "15", height = "15", fill = "#C84C0E" }) => (
<svg width="438" height="339" viewBox="0 0 438 339" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_69315_98758)">
<path d="M282.846 148.82C292.701 148.82 300.691 140.857 300.691 131.035C300.691 121.213 292.701 113.25 282.846 113.25C272.99 113.25 265 121.213 265 131.035C265 140.857 272.99 148.82 282.846 148.82Z" fill="#E6E6E6" />
<path d="M326.578 153.894L307.929 135.308C309.358 133.092 310.327 130.613 310.778 128.017C311.228 125.422 311.151 122.762 310.551 120.196C309.952 117.631 308.841 115.211 307.286 113.081C305.731 110.951 303.762 109.153 301.498 107.795C297.233 105.256 292.166 104.406 287.302 105.413C282.438 106.42 278.131 109.211 275.233 113.232C272.567 116.958 271.287 121.493 271.612 126.057C271.937 130.621 273.848 134.93 277.016 138.243C280.183 141.555 284.41 143.665 288.969 144.208C293.528 144.752 298.134 143.695 301.997 141.221L320.646 159.806C321.432 160.589 322.499 161.029 323.611 161.029C324.723 161.029 325.79 160.588 326.576 159.804C327.363 159.021 327.805 157.958 327.805 156.849C327.805 155.741 327.364 154.678 326.578 153.894ZM301.3 134.615C298.99 136.918 295.949 138.351 292.697 138.67C289.445 138.989 286.182 138.175 283.465 136.365C280.748 134.556 278.744 131.864 277.795 128.747C276.847 125.631 277.012 122.283 278.262 119.274C279.513 116.265 281.772 113.781 284.654 112.246C287.536 110.711 290.863 110.219 294.068 110.854C297.273 111.49 300.158 113.213 302.231 115.73C304.304 118.248 305.437 121.404 305.437 124.661C305.44 126.51 305.075 128.341 304.365 130.049C303.655 131.757 302.614 133.309 301.3 134.615Z" fill="#3F3D56" />
<path d="M428.319 198.245C476.012 250.808 337.759 326.56 226.048 326.56C114.336 326.56 37.0494 267.866 23.7762 198.245C-8.40666 29.4382 297.982 -77.8546 226.048 69.9303C121.195 285.344 390.76 156.85 428.319 198.245Z" fill="#E6E6E6" />
<path d="M406.921 210.683C454.613 263.246 316.361 338.997 204.649 338.997C92.9378 338.997 15.651 280.303 2.37779 210.683C-29.8051 41.8757 276.584 -65.4171 204.649 82.3678C99.7964 297.781 369.362 169.288 406.921 210.683Z" fill="#0B4B66" fill-opacity="0.31" />
<path d="M75.2701 58.9113C77.486 58.9113 79.2823 57.1211 79.2823 54.9127C79.2823 52.7043 77.486 50.9141 75.2701 50.9141C73.0542 50.9141 71.2578 52.7043 71.2578 54.9127C71.2578 57.1211 73.0542 58.9113 75.2701 58.9113Z" fill="white" />
<path d="M54.6168 74.4615C58.31 74.4615 61.3039 71.4778 61.3039 67.7972C61.3039 64.1165 58.31 61.1328 54.6168 61.1328C50.9236 61.1328 47.9297 64.1165 47.9297 67.7972C47.9297 71.4778 50.9236 74.4615 54.6168 74.4615Z" fill="white" />
<path d="M155.544 67.9325C158.006 67.9325 160.002 65.9434 160.002 63.4897C160.002 61.036 158.006 59.0469 155.544 59.0469C153.082 59.0469 151.086 61.036 151.086 63.4897C151.086 65.9434 153.082 67.9325 155.544 67.9325Z" fill="white" />
<path d="M54.7921 203.886C56.2694 203.886 57.4669 202.693 57.4669 201.22C57.4669 199.748 56.2694 198.555 54.7921 198.555C53.3148 198.555 52.1172 199.748 52.1172 201.22C52.1172 202.693 53.3148 203.886 54.7921 203.886Z" fill="#E6E6E6" />
<path d="M242.034 295.41C243.512 295.41 244.709 294.216 244.709 292.744C244.709 291.272 243.512 290.078 242.034 290.078C240.557 290.078 239.359 291.272 239.359 292.744C239.359 294.216 240.557 295.41 242.034 295.41Z" fill="#E6E6E6" />
<path d="M67.7203 152.345C68.4589 152.345 69.0577 151.749 69.0577 151.013C69.0577 150.276 68.4589 149.68 67.7203 149.68C66.9816 149.68 66.3828 150.276 66.3828 151.013C66.3828 151.749 66.9816 152.345 67.7203 152.345Z" fill="#E6E6E6" />
<path d="M178.283 251.869C179.021 251.869 179.62 251.272 179.62 250.536C179.62 249.8 179.021 249.203 178.283 249.203C177.544 249.203 176.945 249.8 176.945 250.536C176.945 251.272 177.544 251.869 178.283 251.869Z" fill="#E6E6E6" />
<path d="M379.337 238.986C380.076 238.986 380.675 238.389 380.675 237.653C380.675 236.917 380.076 236.32 379.337 236.32C378.599 236.32 378 236.917 378 237.653C378 238.389 378.599 238.986 379.337 238.986Z" fill="#E6E6E6" />
<path d="M316.478 278.525C317.217 278.525 317.816 277.928 317.816 277.192C317.816 276.456 317.217 275.859 316.478 275.859C315.739 275.859 315.141 276.456 315.141 277.192C315.141 277.928 315.739 278.525 316.478 278.525Z" fill="#E6E6E6" />
<path d="M250.947 230.541C251.685 230.541 252.284 229.944 252.284 229.208C252.284 228.472 251.685 227.875 250.947 227.875C250.208 227.875 249.609 228.472 249.609 229.208C249.609 229.944 250.208 230.541 250.947 230.541Z" fill="#E6E6E6" />
<path d="M166.244 99.033C166.982 99.033 167.581 98.4362 167.581 97.7001C167.581 96.964 166.982 96.3672 166.244 96.3672C165.505 96.3672 164.906 96.964 164.906 97.7001C164.906 98.4362 165.505 99.033 166.244 99.033Z" fill="#E6E6E6" />
<path d="M176.947 33.2752C177.685 33.2752 178.284 32.6784 178.284 31.9423C178.284 31.2061 177.685 30.6094 176.947 30.6094C176.208 30.6094 175.609 31.2061 175.609 31.9423C175.609 32.6784 176.208 33.2752 176.947 33.2752Z" fill="#E6E6E6" />
<path d="M170.705 310.072C171.443 310.072 172.042 309.475 172.042 308.739C172.042 308.003 171.443 307.406 170.705 307.406C169.966 307.406 169.367 308.003 169.367 308.739C169.367 309.475 169.966 310.072 170.705 310.072Z" fill="#E6E6E6" />
<path d="M104.72 282.08C105.459 282.08 106.058 281.483 106.058 280.747C106.058 280.011 105.459 279.414 104.72 279.414C103.982 279.414 103.383 280.011 103.383 280.747C103.383 281.483 103.982 282.08 104.72 282.08Z" fill="#E6E6E6" />
<path d="M313.806 234.095C314.545 234.095 315.144 233.499 315.144 232.763C315.144 232.026 314.545 231.43 313.806 231.43C313.068 231.43 312.469 232.026 312.469 232.763C312.469 233.499 313.068 234.095 313.806 234.095Z" fill="#E6E6E6" />
<path d="M66.1451 103.872C68.361 103.872 70.1573 102.082 70.1573 99.8736C70.1573 97.6652 68.361 95.875 66.1451 95.875C63.9292 95.875 62.1328 97.6652 62.1328 99.8736C62.1328 102.082 63.9292 103.872 66.1451 103.872Z" fill="white" />
<path d="M131.822 161.231C131.822 173.174 113.295 201.002 107.88 208.88C107.717 209.118 107.498 209.312 107.242 209.447C106.986 209.582 106.7 209.652 106.411 209.652C106.122 209.652 105.836 209.582 105.58 209.447C105.324 209.312 105.105 209.118 104.942 208.88C99.5275 201.002 81 173.174 81 161.231C81 157.905 81.6573 154.612 82.9343 151.54C84.2113 148.467 86.0831 145.675 88.4427 143.324C90.8023 140.972 93.6036 139.107 96.6866 137.834C99.7696 136.561 103.074 135.906 106.411 135.906C109.748 135.906 113.052 136.561 116.135 137.834C119.218 139.107 122.02 140.972 124.379 143.324C126.739 145.675 128.611 148.467 129.888 151.54C131.165 154.612 131.822 157.905 131.822 161.231Z" fill="white" />
<path d="M106.405 172.339C113.545 172.339 119.333 166.571 119.333 159.455C119.333 152.339 113.545 146.57 106.405 146.57C99.2648 146.57 93.4766 152.339 93.4766 159.455C93.4766 166.571 99.2648 172.339 106.405 172.339Z" fill="#C84C0E" />
<path d="M106.185 223.432C114.433 223.432 121.119 222.139 121.119 220.544C121.119 218.949 114.433 217.656 106.185 217.656C97.9364 217.656 91.25 218.949 91.25 220.544C91.25 222.139 97.9364 223.432 106.185 223.432Z" fill="white" />
<path d="M322.762 141.51C322.888 141.729 322.993 141.957 323.079 142.192L346.644 148.115L350.891 144.356L358 149.412L351.197 156.728C350.648 157.319 349.901 157.733 349.069 157.908C348.237 158.082 347.366 158.008 346.585 157.696L321.129 147.531C320.265 148.073 319.24 148.364 318.188 148.367C317.137 148.369 316.11 148.081 315.244 147.542C314.377 147.003 313.713 146.239 313.339 145.35C312.965 144.461 312.899 143.49 313.149 142.567C313.4 141.643 313.955 140.811 314.742 140.179C315.528 139.548 316.509 139.149 317.552 139.034C318.596 138.919 319.653 139.095 320.584 139.537C321.515 139.979 322.275 140.667 322.762 141.51Z" fill="#FFB8B8" />
<path d="M343.999 240L337.901 240L335 219L344 219L343.999 240Z" fill="#FFB8B8" />
<path d="M345 238L333.396 238C332.425 238 331.462 238.175 330.565 238.516C329.668 238.857 328.853 239.356 328.166 239.985C327.479 240.615 326.935 241.362 326.563 242.185C326.191 243.007 326 243.889 326 244.779V244.999L345 245L345 238Z" fill="#2F2E41" />
<path d="M327.999 239L321.901 239L319 218L328 218L327.999 239Z" fill="#FFB8B8" />
<path d="M330 237L317.785 237C316.763 237 315.75 237.175 314.805 237.516C313.861 237.857 313.003 238.356 312.28 238.985C311.557 239.615 310.984 240.362 310.593 241.185C310.201 242.007 310 242.889 310 243.779V243.999L330 244L330 237Z" fill="#2F2E41" />
<path d="M370.818 190.399C369.539 193.847 367.113 196.849 363.875 198.987C360.638 201.126 356.75 202.297 352.748 202.338L352.445 202.343C349.345 202.423 345.707 201.514 342.137 200.21C335.086 197.631 328.313 193.503 326.516 192.368L329.562 218.993L330.796 229.787C330.827 230.066 330.794 230.348 330.698 230.615C330.602 230.882 330.445 231.127 330.239 231.336C330.032 231.544 329.779 231.711 329.498 231.825C329.216 231.94 328.911 231.999 328.602 232H320.997C320.51 232 320.036 231.854 319.649 231.583C319.263 231.312 318.986 230.933 318.862 230.504L306.307 187.02C305.93 185.718 305.9 184.354 306.218 183.039C306.537 181.725 307.195 180.499 308.138 179.462C309.081 178.424 310.283 177.607 311.643 177.076C313.003 176.545 314.482 176.316 315.958 176.408L342.039 178.033L340.217 171.407L363.497 170L363.566 170.045C364.124 170.414 364.667 170.802 365.186 171.207C366.484 172.205 367.635 173.351 368.609 174.618C370.353 176.89 371.465 179.513 371.849 182.261C372.234 185.01 371.88 187.803 370.818 190.399Z" fill="#2F2E41" />
<path d="M370.814 190.681C369.53 194.107 367.095 197.089 363.847 199.215C360.598 201.34 356.696 202.504 352.68 202.544C348.84 200.794 345.135 198.815 341.589 196.619L342.031 200.429L345.884 233.801C345.915 234.078 345.881 234.359 345.785 234.624C345.689 234.889 345.532 235.133 345.324 235.34C345.117 235.547 344.864 235.713 344.581 235.827C344.298 235.94 343.992 235.999 343.682 236H336.051C335.561 236 335.085 235.854 334.698 235.585C334.31 235.316 334.032 234.939 333.908 234.513L329.411 219.093L321.308 191.305C320.93 190.012 320.899 188.656 321.219 187.35C321.539 186.044 322.199 184.826 323.146 183.795C324.092 182.765 325.298 181.952 326.663 181.424C328.027 180.897 329.512 180.669 330.994 180.761L357.167 182.376L355.339 175.792L368.597 175C370.347 177.258 371.463 179.864 371.849 182.595C372.235 185.326 371.88 188.101 370.814 190.681Z" fill="#2F2E41" />
<path d="M365.195 173.262L365.371 173.242L369.453 154.989C369.488 154.83 372.824 139.085 362.595 130.854L362.417 129.727C362.372 129.439 362.258 129.163 362.084 128.919C361.91 128.674 361.679 128.467 361.409 128.312C361.138 128.156 360.833 128.056 360.516 128.017C360.199 127.979 359.876 128.004 359.57 128.09L349.934 130.809C349.388 130.962 348.929 131.301 348.652 131.755C348.375 132.209 348.302 132.743 348.448 133.245L349.385 136.486C348.086 137.873 332.796 154.618 338.122 167.518L340.507 176L365.195 173.262Z" fill="#C84C0E" />
<path d="M325.777 159.404C326.004 159.534 326.22 159.681 326.422 159.842L349.662 154.15L351.181 149L360 150.076L358.281 159.432C358.143 160.188 357.739 160.882 357.131 161.411C356.522 161.939 355.743 162.273 354.909 162.363L327.721 165.293C327.289 166.151 326.582 166.868 325.692 167.35C324.803 167.831 323.774 168.054 322.742 167.989C321.71 167.924 320.724 167.574 319.916 166.985C319.108 166.396 318.515 165.597 318.216 164.693C317.918 163.79 317.928 162.825 318.246 161.927C318.563 161.029 319.173 160.24 319.994 159.666C320.814 159.092 321.807 158.759 322.84 158.712C323.873 158.665 324.898 158.906 325.777 159.404Z" fill="#FFB8B8" />
<path d="M349.991 153.717L361.426 154.984C361.751 155.02 362.082 154.995 362.395 154.912C362.708 154.828 362.997 154.687 363.241 154.499C363.485 154.31 363.679 154.079 363.81 153.82C363.941 153.562 364.006 153.282 364 153L363.782 143.118C363.987 141.685 363.523 140.241 362.492 139.102C361.46 137.964 359.946 137.223 358.281 137.043C356.616 136.862 354.935 137.258 353.608 138.141C352.281 139.025 351.416 140.325 351.202 141.756L348.086 151.237C347.997 151.509 347.977 151.793 348.027 152.072C348.078 152.351 348.197 152.617 348.378 152.852C348.559 153.088 348.797 153.287 349.075 153.436C349.353 153.585 349.666 153.681 349.991 153.717Z" fill="#C84C0E" />
<path d="M353.5 126C346.596 126 341 121.075 341 115C341 108.925 346.596 104 353.5 104C360.404 104 366 108.925 366 115C366 121.075 360.404 126 353.5 126Z" fill="#FFB8B8" />
<path d="M354.181 116.174L355.684 113.68C358.531 124.251 353.503 133 353.503 133L373.019 124.714L372.833 121.775L374.764 123.772L377.539 122.378L377.906 120.472L380 120.944L372.355 108.3C364.934 96.2673 354.147 100.861 354.147 100.861C336.985 100.118 339.081 115.55 339.081 115.55L354.181 116.174Z" fill="#2F2E41" />
<path d="M210.881 197.214C213.405 195.601 210.335 186.34 204.024 176.527C197.712 166.715 190.549 160.068 188.024 161.681C185.5 163.294 188.57 172.556 194.881 182.368C201.193 192.18 208.356 198.827 210.881 197.214Z" fill="#3F3D56" />
</g>
<defs>
<clipPath id="clip0_69315_98758">
<rect width="438" height="339" fill="white" />
</clipPath>
</defs>
</svg>
);
const SearchCustomSVG = React.memo(({ style = {}, width = "15", height = "15", fill = "#C84C0E" }) => (
<svg
width={width}
height={height}
viewBox="0 0 438 339"
fill="none"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label="No search results found"
>
<title>No search results found</title>
<g clip-path="url(#clip0_69315_98758)">
<path d="M282.846 148.82C292.701 148.82 300.691 140.857 300.691 131.035C300.691 121.213 292.701 113.25 282.846 113.25C272.99 113.25 265 121.213 265 131.035C265 140.857 272.99 148.82 282.846 148.82Z" fill="#E6E6E6" />
<path d="M326.578 153.894L307.929 135.308C309.358 133.092 310.327 130.613 310.778 128.017C311.228 125.422 311.151 122.762 310.551 120.196C309.952 117.631 308.841 115.211 307.286 113.081C305.731 110.951 303.762 109.153 301.498 107.795C297.233 105.256 292.166 104.406 287.302 105.413C282.438 106.42 278.131 109.211 275.233 113.232C272.567 116.958 271.287 121.493 271.612 126.057C271.937 130.621 273.848 134.93 277.016 138.243C280.183 141.555 284.41 143.665 288.969 144.208C293.528 144.752 298.134 143.695 301.997 141.221L320.646 159.806C321.432 160.589 322.499 161.029 323.611 161.029C324.723 161.029 325.79 160.588 326.576 159.804C327.363 159.021 327.805 157.958 327.805 156.849C327.805 155.741 327.364 154.678 326.578 153.894ZM301.3 134.615C298.99 136.918 295.949 138.351 292.697 138.67C289.445 138.989 286.182 138.175 283.465 136.365C280.748 134.556 278.744 131.864 277.795 128.747C276.847 125.631 277.012 122.283 278.262 119.274C279.513 116.265 281.772 113.781 284.654 112.246C287.536 110.711 290.863 110.219 294.068 110.854C297.273 111.49 300.158 113.213 302.231 115.73C304.304 118.248 305.437 121.404 305.437 124.661C305.44 126.51 305.075 128.341 304.365 130.049C303.655 131.757 302.614 133.309 301.3 134.615Z" fill="#3F3D56" />
<path d="M428.319 198.245C476.012 250.808 337.759 326.56 226.048 326.56C114.336 326.56 37.0494 267.866 23.7762 198.245C-8.40666 29.4382 297.982 -77.8546 226.048 69.9303C121.195 285.344 390.76 156.85 428.319 198.245Z" fill="#E6E6E6" />
<path d="M406.921 210.683C454.613 263.246 316.361 338.997 204.649 338.997C92.9378 338.997 15.651 280.303 2.37779 210.683C-29.8051 41.8757 276.584 -65.4171 204.649 82.3678C99.7964 297.781 369.362 169.288 406.921 210.683Z" fill="#0B4B66" fill-opacity="0.31" />
<path d="M75.2701 58.9113C77.486 58.9113 79.2823 57.1211 79.2823 54.9127C79.2823 52.7043 77.486 50.9141 75.2701 50.9141C73.0542 50.9141 71.2578 52.7043 71.2578 54.9127C71.2578 57.1211 73.0542 58.9113 75.2701 58.9113Z" fill="white" />
<path d="M54.6168 74.4615C58.31 74.4615 61.3039 71.4778 61.3039 67.7972C61.3039 64.1165 58.31 61.1328 54.6168 61.1328C50.9236 61.1328 47.9297 64.1165 47.9297 67.7972C47.9297 71.4778 50.9236 74.4615 54.6168 74.4615Z" fill="white" />
<path d="M155.544 67.9325C158.006 67.9325 160.002 65.9434 160.002 63.4897C160.002 61.036 158.006 59.0469 155.544 59.0469C153.082 59.0469 151.086 61.036 151.086 63.4897C151.086 65.9434 153.082 67.9325 155.544 67.9325Z" fill="white" />
<path d="M54.7921 203.886C56.2694 203.886 57.4669 202.693 57.4669 201.22C57.4669 199.748 56.2694 198.555 54.7921 198.555C53.3148 198.555 52.1172 199.748 52.1172 201.22C52.1172 202.693 53.3148 203.886 54.7921 203.886Z" fill="#E6E6E6" />
<path d="M242.034 295.41C243.512 295.41 244.709 294.216 244.709 292.744C244.709 291.272 243.512 290.078 242.034 290.078C240.557 290.078 239.359 291.272 239.359 292.744C239.359 294.216 240.557 295.41 242.034 295.41Z" fill="#E6E6E6" />
<path d="M67.7203 152.345C68.4589 152.345 69.0577 151.749 69.0577 151.013C69.0577 150.276 68.4589 149.68 67.7203 149.68C66.9816 149.68 66.3828 150.276 66.3828 151.013C66.3828 151.749 66.9816 152.345 67.7203 152.345Z" fill="#E6E6E6" />
<path d="M178.283 251.869C179.021 251.869 179.62 251.272 179.62 250.536C179.62 249.8 179.021 249.203 178.283 249.203C177.544 249.203 176.945 249.8 176.945 250.536C176.945 251.272 177.544 251.869 178.283 251.869Z" fill="#E6E6E6" />
<path d="M379.337 238.986C380.076 238.986 380.675 238.389 380.675 237.653C380.675 236.917 380.076 236.32 379.337 236.32C378.599 236.32 378 236.917 378 237.653C378 238.389 378.599 238.986 379.337 238.986Z" fill="#E6E6E6" />
<path d="M316.478 278.525C317.217 278.525 317.816 277.928 317.816 277.192C317.816 276.456 317.217 275.859 316.478 275.859C315.739 275.859 315.141 276.456 315.141 277.192C315.141 277.928 315.739 278.525 316.478 278.525Z" fill="#E6E6E6" />
<path d="M250.947 230.541C251.685 230.541 252.284 229.944 252.284 229.208C252.284 228.472 251.685 227.875 250.947 227.875C250.208 227.875 249.609 228.472 249.609 229.208C249.609 229.944 250.208 230.541 250.947 230.541Z" fill="#E6E6E6" />
<path d="M166.244 99.033C166.982 99.033 167.581 98.4362 167.581 97.7001C167.581 96.964 166.982 96.3672 166.244 96.3672C165.505 96.3672 164.906 96.964 164.906 97.7001C164.906 98.4362 165.505 99.033 166.244 99.033Z" fill="#E6E6E6" />
<path d="M176.947 33.2752C177.685 33.2752 178.284 32.6784 178.284 31.9423C178.284 31.2061 177.685 30.6094 176.947 30.6094C176.208 30.6094 175.609 31.2061 175.609 31.9423C175.609 32.6784 176.208 33.2752 176.947 33.2752Z" fill="#E6E6E6" />
<path d="M170.705 310.072C171.443 310.072 172.042 309.475 172.042 308.739C172.042 308.003 171.443 307.406 170.705 307.406C169.966 307.406 169.367 308.003 169.367 308.739C169.367 309.475 169.966 310.072 170.705 310.072Z" fill="#E6E6E6" />
<path d="M104.72 282.08C105.459 282.08 106.058 281.483 106.058 280.747C106.058 280.011 105.459 279.414 104.72 279.414C103.982 279.414 103.383 280.011 103.383 280.747C103.383 281.483 103.982 282.08 104.72 282.08Z" fill="#E6E6E6" />
<path d="M313.806 234.095C314.545 234.095 315.144 233.499 315.144 232.763C315.144 232.026 314.545 231.43 313.806 231.43C313.068 231.43 312.469 232.026 312.469 232.763C312.469 233.499 313.068 234.095 313.806 234.095Z" fill="#E6E6E6" />
<path d="M66.1451 103.872C68.361 103.872 70.1573 102.082 70.1573 99.8736C70.1573 97.6652 68.361 95.875 66.1451 95.875C63.9292 95.875 62.1328 97.6652 62.1328 99.8736C62.1328 102.082 63.9292 103.872 66.1451 103.872Z" fill="white" />
<path d="M131.822 161.231C131.822 173.174 113.295 201.002 107.88 208.88C107.717 209.118 107.498 209.312 107.242 209.447C106.986 209.582 106.7 209.652 106.411 209.652C106.122 209.652 105.836 209.582 105.58 209.447C105.324 209.312 105.105 209.118 104.942 208.88C99.5275 201.002 81 173.174 81 161.231C81 157.905 81.6573 154.612 82.9343 151.54C84.2113 148.467 86.0831 145.675 88.4427 143.324C90.8023 140.972 93.6036 139.107 96.6866 137.834C99.7696 136.561 103.074 135.906 106.411 135.906C109.748 135.906 113.052 136.561 116.135 137.834C119.218 139.107 122.02 140.972 124.379 143.324C126.739 145.675 128.611 148.467 129.888 151.54C131.165 154.612 131.822 157.905 131.822 161.231Z" fill="white" />
<path d="M106.405 172.339C113.545 172.339 119.333 166.571 119.333 159.455C119.333 152.339 113.545 146.57 106.405 146.57C99.2648 146.57 93.4766 152.339 93.4766 159.455C93.4766 166.571 99.2648 172.339 106.405 172.339Z" fill="#C84C0E" />
<path d="M106.185 223.432C114.433 223.432 121.119 222.139 121.119 220.544C121.119 218.949 114.433 217.656 106.185 217.656C97.9364 217.656 91.25 218.949 91.25 220.544C91.25 222.139 97.9364 223.432 106.185 223.432Z" fill="white" />
<path d="M365.195 173.262L365.371 173.242L369.453 154.989C369.488 154.83 372.824 139.085 362.595 130.854L362.417 129.727C362.372 129.439 362.258 129.163 362.084 128.919C361.91 128.674 361.679 128.467 361.409 128.312C361.138 128.156 360.833 128.056 360.516 128.017C360.199 127.979 359.876 128.004 359.57 128.09L349.934 130.809C349.388 130.962 348.929 131.301 348.652 131.755C348.375 132.209 348.302 132.743 348.448 133.245L349.385 136.486C348.086 137.873 332.796 154.618 338.122 167.518L340.507 176L365.195 173.262Z" fill="#C84C0E" />
<path d="M343.999 240L337.901 240L335 219L344 219L343.999 240Z" fill="#FFB8B8" />
<path d="M345 238L333.396 238C332.425 238 331.462 238.175 330.565 238.516C329.668 238.857 328.853 239.356 328.166 239.985C327.479 240.615 326.935 241.362 326.563 242.185C326.191 243.007 326 243.889 326 244.779V244.999L345 245L345 238Z" fill="#2F2E41" />
<path d="M327.999 239L321.901 239L319 218L328 218L327.999 239Z" fill="#FFB8B8" />
<path d="M330 237L317.785 237C316.763 237 315.75 237.175 314.805 237.516C313.861 237.857 313.003 238.356 312.28 238.985C311.557 239.615 310.984 240.362 310.593 241.185C310.201 242.007 310 242.889 310 243.779V243.999L330 244L330 237Z" fill="#2F2E41" />
<path d="M370.818 190.399C369.539 193.847 367.113 196.849 363.875 198.987C360.638 201.126 356.75 202.297 352.748 202.338L352.445 202.343C349.345 202.423 345.707 201.514 342.137 200.21C335.086 197.631 328.313 193.503 326.516 192.368L329.562 218.993L330.796 229.787C330.827 230.066 330.794 230.348 330.698 230.615C330.602 230.882 330.445 231.127 330.239 231.336C330.032 231.544 329.779 231.711 329.498 231.825C329.216 231.94 328.911 231.999 328.602 232H320.997C320.51 232 320.036 231.854 319.649 231.583C319.263 231.312 318.986 230.933 318.862 230.504L306.307 187.02C305.93 185.718 305.9 184.354 306.218 183.039C306.537 181.725 307.195 180.499 308.138 179.462C309.081 178.424 310.283 177.607 311.643 177.076C313.003 176.545 314.482 176.316 315.958 176.408L342.039 178.033L340.217 171.407L363.497 170L363.566 170.045C364.124 170.414 364.667 170.802 365.186 171.207C366.484 172.205 367.635 173.351 368.609 174.618C370.353 176.89 371.465 179.513 371.849 182.261C372.234 185.01 371.88 187.803 370.818 190.399Z" fill="#2F2E41" />
<path d="M370.814 190.681C369.53 194.107 367.095 197.089 363.847 199.215C360.598 201.34 356.696 202.504 352.68 202.544C348.84 200.794 345.135 198.815 341.589 196.619L342.031 200.429L345.884 233.801C345.915 234.078 345.881 234.359 345.785 234.624C345.689 234.889 345.532 235.133 345.324 235.34C345.117 235.547 344.864 235.713 344.581 235.827C344.298 235.94 343.992 235.999 343.682 236H336.051C335.561 236 335.085 235.854 334.698 235.585C334.31 235.316 334.032 234.939 333.908 234.513L329.411 219.093L321.308 191.305C320.93 190.012 320.899 188.656 321.219 187.35C321.539 186.044 322.199 184.826 323.146 183.795C324.092 182.765 325.298 181.952 326.663 181.424C328.027 180.897 329.512 180.669 330.994 180.761L357.167 182.376L355.339 175.792L368.597 175C370.347 177.258 371.463 179.864 371.849 182.595C372.235 185.326 371.88 188.101 370.814 190.681Z" fill="#2F2E41" />
<path d="M365.195 173.262L365.371 173.242L369.453 154.989C369.488 154.83 372.824 139.085 362.595 130.854L362.417 129.727C362.372 129.439 362.258 129.163 362.084 128.919C361.91 128.674 361.679 128.467 361.409 128.312C361.138 128.156 360.833 128.056 360.516 128.017C360.199 127.979 359.876 128.004 359.57 128.09L349.934 130.809C349.388 130.962 348.929 131.301 348.652 131.755C348.375 132.209 348.302 132.743 348.448 133.245L349.385 136.486C348.086 137.873 332.796 154.618 338.122 167.518L340.507 176L365.195 173.262Z" fill="#C84C0E" />
<path d="M325.777 159.404C326.004 159.534 326.22 159.681 326.422 159.842L349.662 154.15L351.181 149L360 150.076L358.281 159.432C358.143 160.188 357.739 160.882 357.131 161.411C356.522 161.939 355.743 162.273 354.909 162.363L327.721 165.293C327.289 166.151 326.582 166.868 325.692 167.35C324.803 167.831 323.774 168.054 322.742 167.989C321.71 167.924 320.724 167.574 319.916 166.985C319.108 166.396 318.515 165.597 318.216 164.693C317.918 163.79 317.928 162.825 318.246 161.927C318.563 161.029 319.173 160.24 319.994 159.666C320.814 159.092 321.807 158.759 322.84 158.712C323.873 158.665 324.898 158.906 325.777 159.404Z" fill="#FFB8B8" />
<path d="M349.991 153.717L361.426 154.984C361.751 155.02 362.082 154.995 362.395 154.912C362.708 154.828 362.997 154.687 363.241 154.499C363.485 154.31 363.679 154.079 363.81 153.82C363.941 153.562 364.006 153.282 364 153L363.782 143.118C363.987 141.685 363.523 140.241 362.492 139.102C361.46 137.964 359.946 137.223 358.281 137.043C356.616 136.862 354.935 137.258 353.608 138.141C352.281 139.025 351.416 140.325 351.202 141.756L348.086 151.237C347.997 151.509 347.977 151.793 348.027 152.072C348.078 152.351 348.197 152.617 348.378 152.852C348.559 153.088 348.797 153.287 349.075 153.436C349.353 153.585 349.666 153.681 349.991 153.717Z" fill="#C84C0E" />
<path d="M353.5 126C346.596 126 341 121.075 341 115C341 108.925 346.596 104 353.5 104C360.404 104 366 108.925 366 115C366 121.075 360.404 126 353.5 126Z" fill="#FFB8B8" />
<path d="M354.181 116.174L355.684 113.68C358.531 124.251 353.503 133 353.503 133L373.019 124.714L372.833 121.775L374.764 123.772L377.539 122.378L377.906 120.472L380 120.944L372.355 108.3C364.934 96.2673 354.147 100.861 354.147 100.861C336.985 100.118 339.081 115.55 339.081 115.55L354.181 116.174Z" fill="#2F2E41" />
<path d="M210.881 197.214C213.405 195.601 210.335 186.34 204.024 176.527C197.712 166.715 190.549 160.068 188.024 161.681C185.5 163.294 188.57 172.556 194.881 182.368C201.193 192.18 208.356 198.827 210.881 197.214Z" fill="#3F3D56" />
</g>
<defs>
<clipPath id="clip0_69315_98758">
<rect width="438" height="339" fill="white" />
</clipPath>
</defs>
</svg>
));
SearchCustomSVG.displayName = 'SearchCustomSVG';
🧰 Tools
🪛 Biome (1.9.4)

[error] 34-34: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

♻️ Duplicate comments (7)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (2)

1-1: ⚠️ Potential issue

Remove the invalid import of 'use' from 'react'

The 'use' named export does not exist in 'react', and attempting to import it will cause an error. Remove 'use' from the import statement.

Apply this diff to fix the import:

-import React, { useEffect, useReducer, useState, useMemo, use } from "react";
+import React, { useEffect, useReducer, useState, useMemo } from "react";

75-79: 🧹 Nitpick (assertive)

Simplify nested ternary operators for readability

The nested ternary operator in setting localityCode is hard to read and may lead to errors. Consider refactoring it to improve clarity.

You can refactor the code as follows:

- localityCode:
-   filterData?.code == undefined || filterData?.code == null
-     ? filterCriteria?.code == undefined || filterCriteria?.code == null
-       ? Digit.SessionStorage.get("paymentInbox").code
-       : filterCriteria?.code
-     : filterData?.code,
+ const localityCode =
+   filterData?.code ??
+   filterCriteria?.code ??
+   Digit.SessionStorage.get("paymentInbox").code;
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

1-1: 🧹 Nitpick (assertive)

Remove unused imports

The following imports from @egovernments/digit-ui-components are not used in this file: Button, Chip, Header, PopUp, Toast, CardText. Consider removing them to clean up the code.

Apply this diff to remove the unused imports:

-import { Button, Card, Chip, Header, Loader, PopUp, Toast, CardText, NoResultsFound, Tab } from "@egovernments/digit-ui-components";
+import { Card, Loader, NoResultsFound, Tab } from "@egovernments/digit-ui-components";
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js (4)

5-5: 🧹 Nitpick (assertive)

Remove or fix the commented import statement

The commented import statement appears to be incomplete and has incorrect syntax. Either remove it if it's no longer needed or uncomment and fix it to properly import the SearchCustomSVG component.

Apply this diff:

-// import {SearchCustomSVG} from ./SearchCustomSVG

9-10: 🧹 Nitpick (assertive)

Access props directly without optional chaining

Since default props are defined for height and width, and props is always defined, you can access props.height and props.width directly without optional chaining.

Apply this diff to simplify the code:

-    const iconHeight = props?.height || 262;
-    const iconWidth = props?.width || 336;
+    const iconHeight = props.height;
+    const iconWidth = props.width;

12-12: 🧹 Nitpick (assertive)

Simplify className concatenation

You can simplify the className concatenation using template literals and default to an empty string if props.className is undefined.

Apply this diff:

-            <div className={`digit-no-data-found ${props?.className ? props?.className : ""}`} style={props?.style}>
+            <div className={`digit-no-data-found ${props.className || ""}`} style={props.style}>

38-38: 🧹 Nitpick (assertive)

Add accessibility attributes to the SVG

The SVG lacks accessibility attributes, which are essential for screen readers. Consider adding a <title> element and necessary aria attributes.

Apply this diff to improve accessibility:

-        <svg width="438" height="339" viewBox="0 0 438 339" fill="none" xmlns="http://www.w3.org/2000/svg">
+        <svg
+            width={width}
+            height={height}
+            viewBox="0 0 438 339"
+            fill="none"
+            xmlns="http://www.w3.org/2000/svg"
+            role="img"
+            aria-label="No search results found"
+        >
+            <title>No search results found</title>
🧰 Tools
🪛 Biome (1.9.4)

[error] 38-38: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b72304c and 029bdb1.

📒 Files selected for processing (6)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js

[error] 91-96: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 97-97: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


[error] 111-124: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js

[error] 131-139: 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)


[error] 140-161: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 219-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 235-245: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

[error] 46-46: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 101-101: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 293-293: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 318-320: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 483-493: 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)


[error] 495-507: 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)


[error] 509-538: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/SearchResultsPlaceholder.js

[error] 38-38: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

🔇 Additional comments (8)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (3)

110-125: 🧹 Nitpick (assertive)

Use self-closing tag for BoundaryComponent.

For consistency and cleaner code, use self-closing tags for components without children.

 {projectSelected?.address?.boundary && (
   <BoundaryComponent
     reset={reset}
     makeReset={() => {
       setReset(false);
     }}
     isRequired={isRequired}
     initialValue={Digit.SessionStorage.get("selectedValues")}
     updateSeeeionStorage={(newSelectedValues) => {
       Digit.SessionStorage.set("selectedValues", JSON.stringify(newSelectedValues));
     }}
     onChange={onChangeId}
     selectedProject={projectSelected}
     lowestLevel={Digit.SessionStorage.get("paymentConfig")?.lowestLevelBoundary || lowerBoundaryDefaultSet}
-  ></BoundaryComponent>
+  />
 )}

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 111-124: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


39-53: 🛠️ Refactor suggestion

Simplify project initialization logic.

The current implementation has unnecessary complexity:

  1. Empty array mapping is redundant as it will never be used
  2. Variable declaration uses let when it should be const
 useEffect(() => {
   if (project.length == 0) {
-    let datak =
-      Digit?.SessionStorage.get("staffProjects") ||
-      [].map((target) => ({
-        code: target.id,
-        projectType: target.projectType,
-        name: target.name,
-        boundary: target?.address?.boundary,
-        boundaryType: target?.address?.boundaryType,
-        projectHierarchy: target.projectHierarchy,
-      }));
-    setProject(datak);
+    const staffProjects = Digit?.SessionStorage.get("staffProjects") || [];
+    setProject(staffProjects);
   }
 }, []);

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


91-103: 🛠️ Refactor suggestion

Improve reset button accessibility.

The reset button needs keyboard accessibility and proper ARIA attributes.

 <span
   onClick={() => {
     setReset(true);
   }}
+  onKeyPress={(e) => {
+    if (e.key === "Enter") {
+      setReset(true);
+    }
+  }}
+  role="button"
+  tabIndex={0}
   style={{ border: "1px solid #e0e0e0", padding: "6px", marginBottom: "10px", cursor: "pointer" }}
 >
-  <svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <svg 
+    width="17" 
+    height="17" 
+    viewBox="0 0 16 22" 
+    fill="none" 
+    xmlns="http://www.w3.org/2000/svg"
+    aria-label="Reset filters"
+  >

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 91-96: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 97-97: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (2)

1-7: LGTM! Well-organized imports.

The imports are properly structured and include all necessary dependencies for the component's functionality.


76-85: LGTM! Well-implemented event handlers.

The event handlers are concise, follow React best practices, and properly manage both state and session storage.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

230-233: 🧹 Nitpick (assertive)

Align setTimeout duration with the comment

The comment mentions delaying navigation for 3 seconds, but the setTimeout is set to 2000 milliseconds (2 seconds). Please update the duration to match the intended delay or adjust the comment accordingly.

Apply this diff to correct the duration:

  // Delay the navigation for 3 seconds
  setTimeout(() => {
    setUpdateDisabled(false);
    history.push(`/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`);
- }, 2000);
+ }, 3000);

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (2)

235-245: 🧹 Nitpick (assertive)

Use self-closing tags for components without children

The CustomInboxTable component has no children and can be self-closed for cleaner code.

Apply this diff to simplify the component syntax:

-<CustomInboxTable
-  statusCount={childrenData?.statusCount}
-  handleTabChange={callServiceOnTap}
-  rowsPerPage={rowsPerPage}
-  customHandleRowsPerPageChange={handleRowsPerPageChange}
-  customHandlePaginationChange={handlePaginationChange}
-  isLoading={childrenDataLoading}
-  tableData={childrenData?.data}
-  totalCount={childrenData?.totalCount}
-  selectedProject={selectedProject}
-></CustomInboxTable>
+<CustomInboxTable
+  statusCount={childrenData?.statusCount}
+  handleTabChange={callServiceOnTap}
+  rowsPerPage={rowsPerPage}
+  customHandleRowsPerPageChange={handleRowsPerPageChange}
+  customHandlePaginationChange={handlePaginationChange}
+  isLoading={childrenDataLoading}
+  tableData={childrenData?.data}
+  totalCount={childrenData?.totalCount}
+  selectedProject={selectedProject}
/>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 235-245: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


219-223: 🧹 Nitpick (assertive)

Use self-closing tags for components without children

The CustomFilter component has no children and can be self-closed for cleaner code.

Apply this diff to simplify the component syntax:

-<CustomFilter
-  resetTable={resetTable}
-  isRequired={ScreenTypeEnum.REGISTER}
-  onFilterChange={handleFilterUpdate}
-></CustomFilter>
+<CustomFilter
+  resetTable={resetTable}
+  isRequired={ScreenTypeEnum.REGISTER}
+  onFilterChange={handleFilterUpdate}
/>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 219-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

Comment on lines +21 to +26
const onChangeId = (value) => {
setBoundary(value);
if (value?.boundaryType === "DISTRICT") {
setIsDistrictSelected(true); // Set flag if district is selected
}
};
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

Reset district flag for non-district boundaries.

The isDistrictSelected flag is set when a district is selected but never reset when other boundary types are selected.

 const onChangeId = (value) => {
   setBoundary(value);
-  if (value?.boundaryType === "DISTRICT") {
-    setIsDistrictSelected(true); // Set flag if district is selected
-  }
+  setIsDistrictSelected(value?.boundaryType === "DISTRICT");
 };
📝 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
const onChangeId = (value) => {
setBoundary(value);
if (value?.boundaryType === "DISTRICT") {
setIsDistrictSelected(true); // Set flag if district is selected
}
};
const onChangeId = (value) => {
setBoundary(value);
setIsDistrictSelected(value?.boundaryType === "DISTRICT");
};

Comment on lines +169 to +177
<Toast
style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
// error={showToast.key === "error"}
transitionTime={showToast.transitionTime}
onClose={() => setShowToast(null)}
/>
)}
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)

Consider moving Toast component to a shared context.

The Toast component could be moved to a shared context or custom hook to make it reusable across the application.

Would you like me to provide an example implementation of a shared Toast context?

Comment on lines 52 to 63
const datak =
Digit?.SessionStorage.get("staffProjects") ||
[].map((target) => ({
code: target.id,
projectType: target.projectType,
name: target.name,
boundary: target?.address?.boundary,
boundaryType: target?.address?.boundaryType,
projectHierarchy: target.projectHierarchy,
}));
setProject(datak);
}
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

Fix potential issue with empty array mapping.

The fallback for project data could result in mapping an empty array. Consider providing a more appropriate fallback value.

-            const datak =
-                Digit?.SessionStorage.get("staffProjects") ||
-                [].map((target) => ({
-                    code: target.id,
-                    projectType: target.projectType,
-                    name: target.name,
-                    boundary: target?.address?.boundary,
-                    boundaryType: target?.address?.boundaryType,
-                    projectHierarchy: target.projectHierarchy,
-                }));
+            const datak = Digit?.SessionStorage.get("staffProjects") || [];
📝 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
const datak =
Digit?.SessionStorage.get("staffProjects") ||
[].map((target) => ({
code: target.id,
projectType: target.projectType,
name: target.name,
boundary: target?.address?.boundary,
boundaryType: target?.address?.boundaryType,
projectHierarchy: target.projectHierarchy,
}));
setProject(datak);
}
const datak = Digit?.SessionStorage.get("staffProjects") || [];
setProject(datak);
}

const location = useLocation();
const { t } = useTranslation();
const history = useHistory();
const billScreen = location.pathname.includes("project-and-aggregation-selection");
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)

Consider using a more descriptive variable name.

The variable billScreen could be renamed to better reflect its purpose, such as isBillAggregationScreen or isBillSelectionFlow.

-    const billScreen = location.pathname.includes("project-and-aggregation-selection");
+    const isBillAggregationScreen = location.pathname.includes("project-and-aggregation-selection");
📝 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
const billScreen = location.pathname.includes("project-and-aggregation-selection");
const isBillAggregationScreen = location.pathname.includes("project-and-aggregation-selection");

Comment on lines 67 to 73
useEffect(() => {
window.Digit.SessionStorage.del("selectedLevel");
window.Digit.SessionStorage.del("selectedBoundaryCode");
window.Digit.SessionStorage.del("boundary");
window.Digit.SessionStorage.del("selectedValues");
window.Digit.SessionStorage.del("paymentInbox");
}, []);
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)

Consider extracting session storage clearing logic.

The session storage clearing logic could be moved to a utility function for better maintainability and reusability.

+const clearProjectSelectionStorage = () => {
+    const keysToDelete = [
+        "selectedLevel",
+        "selectedBoundaryCode",
+        "boundary",
+        "selectedValues",
+        "paymentInbox"
+    ];
+    keysToDelete.forEach(key => window.Digit.SessionStorage.del(key));
+};
+
 useEffect(() => {
-    window.Digit.SessionStorage.del("selectedLevel");
-    window.Digit.SessionStorage.del("selectedBoundaryCode");
-    window.Digit.SessionStorage.del("boundary");
-    window.Digit.SessionStorage.del("selectedValues");
-    window.Digit.SessionStorage.del("paymentInbox");
+    clearProjectSelectionStorage();
 }, []);
📝 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
useEffect(() => {
window.Digit.SessionStorage.del("selectedLevel");
window.Digit.SessionStorage.del("selectedBoundaryCode");
window.Digit.SessionStorage.del("boundary");
window.Digit.SessionStorage.del("selectedValues");
window.Digit.SessionStorage.del("paymentInbox");
}, []);
const clearProjectSelectionStorage = () => {
const keysToDelete = [
"selectedLevel",
"selectedBoundaryCode",
"boundary",
"selectedValues",
"paymentInbox"
];
keysToDelete.forEach(key => window.Digit.SessionStorage.del(key));
};
useEffect(() => {
clearProjectSelectionStorage();
}, []);

import { useTranslation } from "react-i18next";
import CustomFilter from "./custom_comp/filter_section";
import CustomInboxTable from "./custom_comp/table_inbox";
import { FilterCard, Toast, Card } from "@egovernments/digit-ui-components";
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 unused import 'FilterCard'

The FilterCard component is imported but not used in this file. Consider removing it.

Apply this diff to remove the unused import:

-import { FilterCard, Toast, Card } from "@egovernments/digit-ui-components";
+import { Toast, Card } from "@egovernments/digit-ui-components";
📝 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
import { FilterCard, Toast, Card } from "@egovernments/digit-ui-components";
import { Toast, Card } from "@egovernments/digit-ui-components";

@@ -0,0 +1,265 @@
import React, { useEffect, useReducer, useState, useMemo, use } from "react";

import _ from "lodash";
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 unused import of 'lodash'

The '_' import from 'lodash' is not used in this file. Consider removing it to clean up the code.

Apply this diff to remove the unused import:

-import _ from "lodash";

Comment on lines +63 to +66
const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
try {
setChildrenDataLoading(true);
fetchRegisters.mutateAsync(
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

Ensure proper error handling with async functions

In triggerMusterRollApprove, the fetchRegisters.mutateAsync call is an asynchronous operation, but you are not awaiting it. As a result, the try-catch block will not catch any errors thrown by fetchRegisters.mutateAsync. Consider making triggerMusterRollApprove an async function and awaiting fetchRegisters.mutateAsync to ensure errors are properly caught.

Apply this diff to fix the error handling:

-const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
+const triggerMusterRollApprove = async (filterData, status, totalRows, totalNext, selectedProject) => {
    try {
-     fetchRegisters.mutateAsync(
+     await fetchRegisters.mutateAsync(
📝 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
const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
try {
setChildrenDataLoading(true);
fetchRegisters.mutateAsync(
const triggerMusterRollApprove = async (filterData, status, totalRows, totalNext, selectedProject) => {
try {
setChildrenDataLoading(true);
await fetchRegisters.mutateAsync(

Comment on lines +4 to +5
import CustomInboxSearchLinks from "./custom_comp/link_section";
import CustomSearchComponent from "./custom_comp/search_section";
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 unused imports

The imports CustomInboxSearchLinks and CustomSearchComponent are not used in this file. Consider removing them to clean up the code.

Apply this diff to remove the unused imports:

-import CustomInboxSearchLinks from "./custom_comp/link_section";
-import CustomSearchComponent from "./custom_comp/search_section";

Committable suggestion skipped: line range outside the PR's diff.

// },

{
name: activeLink?.code == "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY"),
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)

Use strict equality operator for comparisons

To avoid potential type coercion issues, use === instead of == when comparing values.

Apply this diff:

-  name: activeLink?.code == "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY"),
+  name: activeLink?.code === "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY"),
📝 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
name: activeLink?.code == "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY"),
name: activeLink?.code === "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY"),

rachana-egov and others added 3 commits January 10, 2025 17:19
* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component

* boundary service API integration implemented for inbox screen

* check box and register search API integration in progress

* table data enriched

* removed debugger

* variable name changed

* tab section functionlity added

* attendance register param changed

* localization code and table value changed

* inbox pagination and status register count fixed

* table component css style changed

* padding removed from table style

* console removed

* HCMPRE-1774: point-1 project drop down is put in the filter section and search section is not required as per last demo

* fliter boundary dropdown in progress

* staffName key changed for attendance mark by

* bug fixes

* code comment added why not used inboxsearch composer

* boundary service made dynamic

* boundary component made dynamic

* boundary component issue fixed for mandatory filed and drop down reset

* commented code removed

* bug fixes done

* ticket: HCMPRE-1822, boundary option reloaded and error scenation handled for project selection and boundary selection in attendance register inbox

* HCMPRE-1822::table rows per page issue fixed, and digit.session storage implemented

* reworking on the tavle component in view attendance screen

* HCMPRE-1884, worked on preselected boundary

* HCMPRE-1884:: project is also bydefault selected

---------

Co-authored-by: rachana-egov <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (22)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

233-236: 🛠️ Refactor suggestion

Avoid using setTimeout for navigation after showing toast

Using setTimeout to delay navigation can lead to unpredictable behavior if the UI experiences lag. Consider using the onClose callback of the Toast component to ensure navigation occurs after the toast is dismissed.

Apply this diff to improve the navigation logic:

  setShowToast({ 
    key: "success", 
    label: t("HCM_AM_ATTENDANCE_UPDATED_SUCCESSFULLY"), 
    transitionTime: 3000,
+   onClose: () => {
+     setUpdateDisabled(false);
+     history.push(`/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`);
+   },
  });
- // Delay the navigation for 3 seconds
- setTimeout(() => {
-   setUpdateDisabled(false);
-   history.push(`/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`);
- }, 3000);
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (7)

3-3: 🧹 Nitpick (assertive)

Remove unused import CheckBox

The CheckBox component imported from @egovernments/digit-ui-components is not used in this file. Removing it will clean up the code.


54-54: 🧹 Nitpick (assertive)

Ensure consistent reset of boundary state

In handleClearFilter, the boundary state is reset using setBoundary(""), whereas in other parts of the code setBoundary(null) is used (e.g., lines 31 and 40). This inconsistency might lead to unexpected behavior. Consider using null consistently to represent an unset boundary.

Apply this diff to standardize the reset value:

-        setBoundary(""); // Clear the boundary value
+        setBoundary(null); // Clear the boundary value

75-85: 🧹 Nitpick (assertive)

Add keyboard event handlers for accessibility

The <div> element with an onClick handler should support keyboard interactions for accessibility. Add onKeyPress and tabIndex={0} to enable keyboard navigation.

Apply this diff:

<div onClick={handleClearFilter}
+     onKeyPress={(e) => { if (e.key === 'Enter') handleClearFilter(); }}
+     tabIndex={0}
     style={{
         cursor: "pointer",
         alignItems: "center",
         gap: ".75rem",
         marginBottom: "24px",
         display: "flex",
         flexDirection: "row",
         justifyContent: "space-between",
     }}
>
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-85: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


90-90: 🧹 Nitpick (assertive)

Improve accessibility by adding keyboard event handlers

The <span> element with an onClick handler should support keyboard interactions for accessibility. Add tabIndex={0} and onKeyPress to enhance accessibility for keyboard users.

Apply this diff:

<span onClick={() => { }}
+     onKeyPress={(e) => { if (e.key === 'Enter') {/* handle action */} }}
+     tabIndex={0}
     style={{ border: "1px solid #E0E0E0", padding: "6px", marginBottom: "10px" }}>
🧰 Tools
🪛 Biome (1.9.4)

[error] 90-90: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


91-91: 🧹 Nitpick (assertive)

Provide SVG accessibility attributes

For accessibility purposes, the <svg> element should include role="img" and either aria-label or a <title> element to provide alternative text for screen readers.

Apply this diff:

<svg width="17" height="17" viewBox="0 0 16 22" fill="none"
+     role="img" aria-label={t("Refresh")}
     xmlns="http://www.w3.org/2000/svg">
+    <title>{t("Refresh")}</title>
🧰 Tools
🪛 Biome (1.9.4)

[error] 91-91: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


99-110: 🧹 Nitpick (assertive)

Remove commented-out code block

The commented-out code block can be removed to keep the code clean. If this code might be needed later, consider tracking it in version control or adding a TODO comment.


120-120: ⚠️ Potential issue

Fix the spelling of updateSeeeionStorage

The prop updateSeeeionStorage appears to be misspelled. Correcting it to updateSessionStorage will improve code readability and avoid confusion.

Apply this diff to fix the spelling:

-    updateSeeeionStorage={(newSelectedValues) => {
+    updateSessionStorage={(newSelectedValues) => {
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (10)

1-1: 🛠️ Refactor suggestion

Remove unused and invalid imports

The imports useReducer, useMemo, and use are not used in this file. Additionally, use is not a valid React hook and may have been included by mistake. Please remove these to clean up the code.

Apply this diff:

- import React, { useEffect, useReducer, useState, useMemo, use } from "react";
+ import React, { useEffect, useState } from "react";

5-5: ⚠️ Potential issue

Define 'location' or use 'useLocation' hook

The variable location is used but not defined in this scope. If you intend to access the route's state, consider importing useLocation from react-router-dom and using it to retrieve the location object.

Apply this diff to import useLocation and update the code:

+ import { useLocation } from "react-router-dom";

...

- const { fromViewScreen } = location.state || false;
+ const location = useLocation();
+ const { fromViewScreen } = location.state || {};

47-47: 🧹 Nitpick (assertive)

Use strict equality and optional chaining

Using strict equality operator (===) avoids unintended type coercion. Also, consider using optional chaining on Digit.SessionStorage.get("paymentInbox") to prevent potential runtime errors if the session storage item is missing.

Apply this diff:

-     referenceId: selectedProject == undefined ? Digit.SessionStorage.get("paymentInbox").selectedProject?.id : selectedProject?.id,
+     referenceId: selectedProject === undefined ? Digit.SessionStorage.get("paymentInbox")?.selectedProject?.id : selectedProject?.id,

51-51: 🧹 Nitpick (assertive)

Simplify the boolean expression

The ternary operator is unnecessary here. You can directly assign the result of the logical expression.

Apply this diff:

-     isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
+     isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType,
🧰 Tools
🪛 Biome (1.9.4)

[error] 51-51: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


54-54: 🧹 Nitpick (assertive)

Simplify the boolean expression

The ternary operator is unnecessary here. You can directly assign the result of the logical expression.

Apply this diff:

-     enabled: selectedBoundaryCode && selectedProject ? true : false,
+     enabled: !!(selectedBoundaryCode && selectedProject),
🧰 Tools
🪛 Biome (1.9.4)

[error] 54-54: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


71-71: 🧹 Nitpick (assertive)

Simplify the boolean expression

The ternary operator is unnecessary here. You can directly assign the result of the logical expression.

Apply this diff:

-     enabled: selectedBoundaryCode ? true : false,
+     enabled: !!selectedBoundaryCode,
🧰 Tools
🪛 Biome (1.9.4)

[error] 71-71: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


98-101: 🧹 Nitpick (assertive)

Simplify conditional state update

Instead of using an if-else block to update showGenerateBillAction, you can directly assign the boolean result of the condition.

Apply this diff:

-    if (AttendanceData?.statusCount.PENDINGFORAPPROVAL === 0 && AttendanceData?.statusCount.APPROVED > 0) {
-        setShowGenerateBillAction(true);
-    } else {
-        setShowGenerateBillAction(false);
-    }
+    setShowGenerateBillAction(AttendanceData?.statusCount.PENDINGFORAPPROVAL === 0 && AttendanceData?.statusCount.APPROVED > 0);

198-200: 🧹 Nitpick (assertive)

Handle errors in the catch block

The catch block is empty, which may make debugging difficult if an error occurs. Consider adding error handling or logging inside the catch block.

Apply this diff:

} catch (error) {
-    /// will show estimate data only
+    console.error('Error generating bill:', error);
+    setShowToast({ key: "error", label: t("HCM_AM_BILL_GENERATION_FAILED"), transitionTime: 3000 });
}

302-311: 🧹 Nitpick (assertive)

Use self-closing tags for JSX elements without children

JSX elements without children should be self-closing for cleaner code and better readability.

Apply this diff:

<BillInboxTable
    isFetching={isFetching}
    tableData={tableData}
    currentPage={currentPage}
    rowsPerPage={rowsPerPage}
    handlePageChange={handlePageChange}
    handlePerRowsChange={handlePerRowsChange}
    totalCount={totalCount}
    status={activeLink.code}
- ></BillInboxTable>
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 302-311: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


334-348: 🧹 Nitpick (assertive)

Add a key prop to the Button component in the actionFields array

When rendering elements in an array, React recommends providing a unique key prop to each element to help identify which items have changed, are added, or are removed.

Apply this diff:

actionFields={[
-     <Button
+     <Button
+         key="generate-bill-btn"
          icon="CheckCircle"
          label={t(`HCM_AM_GENERATE_BILL_LABEL`)}
          onClick={() => {
              setOpenAlertPopUp(true);
          }}
          style={{
              minWidth: "14rem",
              opacity: billGenerationStatus != null ? 0.5 : 1,
          }}
          type="button"
          variation="primary"
          isDisabled={generateBillMutation.isLoading}
      />,
]}
🧰 Tools
🪛 Biome (1.9.4)

[error] 334-348: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (4)

17-23: 🧹 Nitpick (assertive)

Simplify event handlers by passing prop functions directly

The current handlers simply call the corresponding prop functions without adding any additional logic. You can simplify the code by passing the prop functions directly to the DataTable component.

Apply this diff:

- const handlePageChange = (page, totalRows) => {
-     props?.handlePageChange(page, totalRows);
- };

- const handlePerRowsChange = async (currentRowsPerPage, currentPage) => {
-     props?.handlePerRowsChange(currentRowsPerPage, currentPage);
- };
...
<DataTable
-     onChangePage={handlePageChange}
-     onChangeRowsPerPage={handlePerRowsChange}
+     onChangePage={props.handlePageChange}
+     onChangeRowsPerPage={props.handlePerRowsChange}
     ...
/>

59-60: ⚠️ Potential issue

Ensure consistency in property names between tooltip and displayed text

In the "Approved By"/"Marked By" column, the tooltip uses row?.markby, whereas the displayed text uses row?.approvedBy or row?.markedBy. Verify if this mismatch was intentional or correct the property name to ensure consistency.

Apply this diff:

-         <div className="ellipsis-cell" title={row?.markby || t("NA")}>
+         <div className="ellipsis-cell" title={row?.markedBy || t("NA")}>

69-70: ⚠️ Potential issue

Ensure tooltip content matches displayed data

In the "Attendees" column, the tooltip uses row?.status, while the displayed text uses row?.noOfAttendees. To provide consistent information, the tooltip should reference row?.noOfAttendees.

Apply this diff:

-         <div className="ellipsis-cell" title={t(row?.status || "0")}>
+         <div className="ellipsis-cell" title={t(row?.noOfAttendees || "0")}>

103-103: 🧹 Nitpick (assertive)

Add PropTypes for the component

Defining propTypes for the BillInboxTable component will help catch potential issues early and improve code maintainability.

Example:

import PropTypes from 'prop-types';

BillInboxTable.propTypes = {
  tableData: PropTypes.array.isRequired,
  currentPage: PropTypes.number.isRequired,
  totalCount: PropTypes.number.isRequired,
  rowsPerPage: PropTypes.number.isRequired,
  handlePageChange: PropTypes.func.isRequired,
  handlePerRowsChange: PropTypes.func.isRequired,
  isFetching: PropTypes.bool,
  status: PropTypes.string,
};

BillInboxTable.defaultProps = {
  isFetching: false,
  status: "",
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 029bdb1 and d17cac4.

📒 Files selected for processing (8)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

[error] 47-47: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 102-102: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 298-298: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 323-325: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 488-498: 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)


[error] 500-512: 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)


[error] 514-543: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js

[error] 75-85: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 90-90: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 91-91: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 51-51: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 54-54: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 71-71: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 244-251: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 302-311: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 334-348: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js

[error] 218-218: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 220-224: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 236-246: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


[error] 112-125: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js

[error] 133-141: 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)


[error] 142-165: 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)

🔇 Additional comments (32)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (9)

6-6: Correct the spelling of 'updateSeeeionStorage'

The prop updateSeeeionStorage appears to be misspelled. It should be updateSessionStorage to reflect the intended functionality.


7-7: Add null check before accessing 'boundaryHierarchyOrder'

Ensure that Digit.SessionStorage.get("boundaryHierarchyOrder") is not null or undefined before calling .map to prevent runtime errors.


35-48: Remove commented-out code to maintain code cleanliness

Large blocks of commented-out code can clutter the codebase and reduce maintainability. If this code is no longer needed, please consider removing it.


89-105: Clean up commented-out code

There is a block of commented-out code that may no longer be necessary. Removing unused code enhances readability and maintainability.


110-116: Ensure safe access to nested properties

When accessing deeply nested properties like childrenData[0]?.boundary[0].boundaryType, add null checks to prevent potential runtime errors if any of the intermediate properties are undefined.


137-140: Consider merging 'handleButtonClick' and 'handleDropdownOptions'

Since handleButtonClick immediately calls handleDropdownOptions, you might consolidate these functions or rename them for clarity.


166-174: Optimize the boundary item check

Use includes instead of find for better performance and readability when checking if an item exists in an array.


218-218: Simplify the boolean expression for 'isRequired'

Avoid using redundant ternary operators with boolean literals. Simplify the expression for clarity:

- isRequired={isRequired == ScreenTypeEnum.BILL ? true : key == lowestLevelBoundaryType ? true : false}
+ isRequired={isRequired === ScreenTypeEnum.BILL || key === lowestLevelBoundaryType}
🧰 Tools
🪛 Biome (1.9.4)

[error] 218-218: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


248-250: Move inline styles to CSS classes

Inline styles can make the code harder to maintain. Consider moving styles into a CSS class for better readability and reusability.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (7)

56-56: Use strict equality for comparison

Replace the loose equality == with strict equality === for better type safety.

- if (reset == true) {
+ if (reset === true) {

112-125: Use self-closing tags for components without children

Components that do not have children can be self-closed for brevity and cleanliness.

Apply this diff:

{projectSelected?.address?.boundary && (
  <BoundaryComponent
    reset={reset}
    makeReset={() => {
      setReset(false);
    }}
    isRequired={isRequired}
    initialValue={Digit.SessionStorage.get("selectedValues")}
    updateSeeeionStorage={(newSelectedValues) => {
      Digit.SessionStorage.set("selectedValues", newSelectedValues);
    }}
    onChange={onChangeId}
    selectedProject={projectSelected}
    lowestLevel={Digit.SessionStorage.get("paymentConfig")?.lowestLevelBoundary || lowerBoundaryDefaultSet}
- ></BoundaryComponent>
+ />
)}
🧰 Tools
🪛 Biome (1.9.4)

[error] 112-125: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


41-41: Use 'const' instead of 'let' for variables that are not reassigned

The variable datak is never reassigned. Using const is more appropriate here.

Apply this diff:

- let datak =
+ const datak =
  Digit?.SessionStorage.get("staffProjects") || ...
🧰 Tools
🪛 Biome (1.9.4)

[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


11-19: State management is properly initialized

The use of useState hooks to manage component state is appropriate, and the initial values are correctly set.


57-57: 🧹 Nitpick (assertive)

Remove commented-out code

The commented line //setProjectSelected(null); may no longer be needed. Removing it helps keep the code clean.

Apply this diff:

- //setProjectSelected(null);

Likely invalid or redundant comment.


92-97: 🧹 Nitpick (assertive)

Add keyboard accessibility to clickable elements

To improve accessibility, add keyboard event handling and appropriate ARIA attributes to elements with onClick handlers.

Apply this diff:

<span
  onClick={() => {
    setReset(true);
  }}
+ onKeyPress={(e) => {
+   if (e.key === "Enter") {
+     setReset(true);
+   }
+ }}
+ role="button"
+ tabIndex="0"
  style={{ border: "1px solid #e0e0e0", padding: "6px", marginBottom: "10px", cursor: "pointer" }}
>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


98-104: 🧹 Nitpick (assertive)

Provide alternative text for SVG icon

For accessibility, include an aria-label or <title> in the SVG to describe its purpose.

Apply this diff:

<svg
  width="17"
  height="17"
  viewBox="0 0 16 22"
  fill="none"
+ aria-label="Reset icon"
  xmlns="http://www.w3.org/2000/svg"
>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (4)

214-222: Handle potential undefined values in attendance data

When mapping over data[0].individualEntries, ensure that attendanceSummary and entry.individualId are defined to prevent potential runtime errors.

Please verify that attendanceSummary and entry.individualId are always defined. If there's a possibility of them being undefined, add appropriate checks to handle such cases.


61-61: Verify correct calculation of attendance duration

The calculation for attendanceDuration may not account for time zone differences or daylight saving changes. Ensure that the duration calculation correctly reflects the number of days between startDate and endDate.

Consider using a date library like moment.js or date-fns for accurate duration calculations if necessary.


397-398: ⚠️ Potential issue

Ensure the component returns a valid React element

When the update mutation is loading, the LoaderComponent should be returned as a valid React element. Make sure to wrap it in parentheses if necessary.

Apply this diff:

  if (updateMutation.isLoading) {
-   return <LoaderComponent variant={"OverlayLoader"} />
+   return (<LoaderComponent variant={"OverlayLoader"} />);
  }

Likely invalid or redundant comment.


233-236: ⚠️ Potential issue

Ensure consistency in timeout duration

The comment mentions delaying navigation for 3 seconds, but the setTimeout delay is set to 2000 milliseconds (2 seconds). Please adjust the setTimeout duration to match the intended 3-second delay.

Apply this diff to fix the inconsistency:

  // Delay the navigation for 3 seconds
  setTimeout(() => {
    setUpdateDisabled(false);
    history.push(`/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`);
- }, 2000);
+ }, 3000);

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (5)

12-12: Consider renaming billScreen for clarity.

The variable billScreen could be renamed to better reflect its purpose. A more descriptive name like isBillAggregationScreen or isBillSelectionFlow would improve code readability.


20-28: Extract complex mapping logic into a utility function.

The mapping logic for AGGREGATION_LEVEL_OPTIONS is complex and could be abstracted into a utility function. This would enhance readability and maintainability.


53-63: Fix potential issue with empty array mapping.

Mapping over an empty array returns an empty array, which might not be the intended fallback value. Consider providing a more appropriate default value.


70-75: Consider extracting session storage clearing logic.

The repeated session storage clearing could be moved into a utility function for better reusability and cleaner code.


133-141: Add missing key props to elements in iterables.

When rendering lists of elements, each child in an array or iterator should have a unique key prop. This helps React identify which items have changed.

Apply this diff to add the missing key props:

 <ActionBar
     actionFields={[
         <Button
+            key="back"
             label={t(`HCM_AM_BACK_LABEL`)}
             onClick={() => {
                 history.push(`/${window.contextPath}/employee`);
             }}
             style={{ marginLeft: "2.5rem", minWidth: "14rem" }}
             type="button"
             variation="secondary"
         />,
         <Button
+            key="next"
             label={t(`HCM_AM_NEXT_LABEL`)}
             title={t(`HCM_AM_NEXT_LABEL`)}
             onClick={() => {
                 // Existing onClick logic
             }}
             style={{ minWidth: "14rem" }}
             type="button"
             variation="primary"
         />,
     ]}
     className=""
     maxActionFieldsAllowed={5}
     sortActionFields
     style={{}}
 />

Also applies to: 142-165

🧰 Tools
🪛 Biome (1.9.4)

[error] 133-141: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (7)

1-1: Remove the unused use import from React.

There is no use named export from react, and importing it will cause an error. Please remove it.

-import React, { useEffect, useReducer, useState, useMemo, use } from "react";
+import React, { useEffect, useReducer, useState, useMemo } from "react";

4-5: Remove unused imports.

The imports CustomInboxSearchLinks and CustomSearchComponent are not used in this file. Removing unused imports improves code clarity.

-import CustomInboxSearchLinks from "./custom_comp/link_section";
-import CustomSearchComponent from "./custom_comp/search_section";

116-116: Clarify or remove the vague comment in error handling.

The comment /// will show estimate data only is unclear. If it serves no purpose, consider removing it. If it's meant to document a fallback behavior, please provide a more detailed explanation.


220-224: Use self-closing tags for components without children.

JSX elements without children should be self-closing for cleaner syntax.

Apply this diff to use self-closing tags:

-<CustomFilter
+<CustomFilter
     resetTable={resetTable}
     isRequired={ScreenTypeEnum.REGISTER}
     onFilterChange={handleFilterUpdate}
-/></CustomFilter>
+/>

...

-<CustomInboxTable
+<CustomInboxTable
     statusCount={childrenData?.statusCount}
     handleTabChange={callServiceOnTap}
     rowsPerPage={rowsPerPage}
     customHandleRowsPerPageChange={handleRowsPerPageChange}
     customHandlePaginationChange={handlePaginationChange}
     isLoading={childrenDataLoading}
     tableData={childrenData?.data}
     totalCount={childrenData?.totalCount}
     selectedProject={selectedProject}
-/></CustomInboxTable>
+/>

Also applies to: 236-246

🧰 Tools
🪛 Biome (1.9.4)

[error] 220-224: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


63-66: Ensure proper error handling with async functions.

Since fetchRegisters.mutateAsync is asynchronous, the try...catch block won't catch errors unless you await the promise. Consider making triggerMusterRollApprove an async function and await the mutation call to properly handle errors.

Apply this diff to fix the error handling:

-const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
+const triggerMusterRollApprove = async (filterData, status, totalRows, totalNext, selectedProject) => {
     try {
-      fetchRegisters.mutateAsync(
+      await fetchRegisters.mutateAsync(
         {
           // existing code
         },
         {
           onSuccess: (data) => {
             // success logic
           },
           onError: (error) => {
             // error handling
           },
         }
       );
     } catch (error) {
       // handle errors from mutateAsync
       console.error(error);
       setChildrenDataLoading(false);
       setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"), transitionTime: 3000 });
     }
};

176-179: 🧹 Nitpick (assertive)

Remove commented-out code blocks.

Removing unused or commented-out code helps maintain code readability and reduces confusion.

- // refetchPlanEmployee();
- // handleCreateRateAnalysis();

Likely invalid or redundant comment.


3-3: Remove unused import of lodash.

The _ import from lodash is not used in this file. Consider removing it to clean up the code.

-import _ from "lodash";

Please confirm if lodash is required. If it's used elsewhere in the code not shown here, you can disregard this comment.

✅ Verification successful

The lodash import is indeed unused and can be safely removed

The file doesn't contain any usage of lodash methods or utilities, making this import redundant. The suggested removal is correct.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# First, let's see the content of the file
cat "health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js"

# Then, let's search for any usage of lodash methods via the '_' variable
ast-grep --pattern '$_._($$$)' "health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js"
ast-grep --pattern '_($$$)' "health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js"

Length of output: 11235

const [triggerEstimate, setTriggerEstimate] = useState(false);
const [comment, setComment] = useState(null);
const [showToast, setShowToast] = useState(null);
const [loding, setLoding] = useState(false);
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

Correct the typo in state variable name

The state variable loding appears to be a typo. It should be loading for clarity and consistency.

Apply this diff to fix the typo:

- const [loding, setLoding] = useState(false);
+ const [loading, setLoading] = useState(false);

Also, update all occurrences of loding and setLoding in the file:

- setLoding(true);
+ setLoading(true);

- setLoding(false);
+ setLoading(false);
📝 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
const [loding, setLoding] = useState(false);
const [loading, setLoading] = useState(false);

import { Link, useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import DataTable from "react-data-table-component";
import { useQueryClient } from "react-query";
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 unused import useQueryClient

The useQueryClient function imported from react-query is not used in this file. Removing it will clean up the code.

Apply this diff:

- import { useQueryClient } from "react-query";

style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
// error={showToast.key === "error"}
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 commented-out code.

There's a commented-out line that can be removed to clean up the code.

- // error={showToast.key === "error"}

Comment on lines 195 to 200
const resetTable = () => {
setchildrenData([]);
setFilterCriteria(null);
// setSelectedProject({});
setCard(false);
};
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 commented-out code.

There are several blocks of commented-out code that can be removed to clean up the file.

- //-------//

...

- // setSelectedProject({});

...

{/*<div style={{ width: "80%", display: "flex", flexDirection: "row" }}>
    <CustomSearchComponent onProjectSelect={handleProjectChange}></CustomSearchComponent>
</div>*/}

...

- // error={showToast.key === "error"}

Also applies to: 206-209

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b17c451 and 8658973.

📒 Files selected for processing (9)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox_custom_style.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1 hunks)
👮 Files not reviewed due to content moderation or server errors (3)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox_custom_style.js
🧰 Additional context used
📓 Path-based instructions (9)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox_custom_style.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js

[error] 105-105: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 109-109: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js

[error] 43-43: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js

[error] 135-143: 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)


[error] 144-167: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js

[error] 139-139: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 52-52: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 55-55: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 72-72: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 244-251: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 296-305: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 330-344: 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)

🔇 Additional comments (35)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (8)

1-8: Optimize imports for better maintainability.

  1. Remove unused imports: useMemo, InboxSearchComposer
  2. Consolidate component imports from @egovernments/digit-ui-react-components and @egovernments/digit-ui-components

16-20: Use consistent date state initialization.

Initialize date values with null instead of empty strings for better type consistency.


28-48: Improve API configuration robustness.

  1. The enabled flag can be simplified
  2. The select function should validate the response
  3. Error handling is missing
config: {
-   enabled: project ? true : false,
+   enabled: Boolean(project),
    select: (data) => {
+       if (!data?.bills) {
+           throw new Error('Invalid response format');
+       }
        return data;
    },
+   onError: (error) => {
+       console.error('Bill search failed:', error);
+       // Handle error appropriately
+   }
},
🧰 Tools
🪛 Biome (1.9.4)

[error] 43-43: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


50-56: Add cleanup dependencies and consolidate storage cleanup.

The effect is missing dependencies and the storage cleanup can be consolidated.


66-70: Fix pagination offset calculation.

The offset calculation in handlePerRowsChange should use 0 since we're resetting to the first page.


72-77: Prevent potential memory leak in useEffect.

Add cleanup to prevent state updates after component unmount.


88-91: Use consistent state reset values.

Reset billID to null instead of an empty string to match the initial state.


98-113: Improve component error handling and accessibility.

  1. Add an error boundary for better error handling
  2. Add proper ARIA attributes for accessibility
  3. Simplify conditional rendering
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js (2)

105-109: Avoid reassigning function parameters for better code clarity

Reassigning the function parameter value within handleDaysWorkedChange can lead to confusion and potential bugs. It's recommended to assign the processed value to a new variable instead.

🧰 Tools
🪛 Biome (1.9.4)

[error] 105-105: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 109-109: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


143-161: Add keyField prop to DataTable for unique row identification

To ensure each row is uniquely identified and to avoid potential rendering issues, specify the keyField prop in the DataTable component. Set it to the unique identifier in your data, such as workerId.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (5)

19-19: Handle potential undefined state in useLocation

Destructuring from local?.state || false may cause an error because destructuring properties from false is invalid if local.state is undefined. Consider defaulting to an empty object {} to ensure safe destructuring.

Apply this diff to fix the issue:

-  const { fromCampaignSupervisor } = local?.state || false;
+  const { fromCampaignSupervisor } = local?.state || {};

31-33: Refactor repeated transformation logic for clarity

The expression Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()) is called multiple times. Extracting it into a variable reduces duplication and enhances readability.

Consider applying this refactor:

+  const transformedPageName = Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop());

   const crumbs = [
     {
-      show:
-        Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()) === "REGISTERS_INBOX" ||
-        ((Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()) === "VIEW_ATTENDANCE" ||
-          Digit.Utils.locale.getTransformedLocale(location.pathname.split("/").pop()) === "EDIT_ATTENDANCE") &&
-          !fromCampaignSupervisor),
+      show:
+        transformedPageName === "REGISTERS_INBOX" ||
+        ((transformedPageName === "VIEW_ATTENDANCE" || transformedPageName === "EDIT_ATTENDANCE") && !fromCampaignSupervisor),
     },

54-54: Optional: Additional styling or positioning

The BreadCrumbs component is rendered without additional styling. If needed, consider adding styling or spacing props to align with your design system.


61-61: Use optional chaining to prevent potential runtime errors

Accessing window.contextPath without optional chaining could cause a runtime error if window.contextPath is undefined. Use optional chaining to ensure safety.

Apply this diff to fix the issue:

-    if (window.location.pathname !== `/${window.contextPath}/employee/`) {
+    if (window.location.pathname !== `/${window?.contextPath}/employee/`) {

76-84: Avoid inline function components in routes for performance

Using inline functions like component={() => <Component />} in PrivateRoute can lead to unnecessary re-renders. Pass the component directly to improve performance.

Apply this diff:

-        <PrivateRoute path={`${path}/view-attendance`} component={() => <ViewAttendance />} />
-        <PrivateRoute path={`${path}/edit-attendance`} component={() => <ViewAttendance editAttendance={true} />} />
+        <PrivateRoute path={`${path}/view-attendance`} component={ViewAttendance} />
+        <PrivateRoute path={`${path}/edit-attendance`}>
+            <ViewAttendance editAttendance={true} />
+        </PrivateRoute>
-        <PrivateRoute path={`${path}/attendance-approve-success`} component={() => <Response />} />
-        <PrivateRoute path={`${path}/attendance-approve-failed`} component={() => <Response />} />
+        <PrivateRoute path={`${path}/attendance-approve-success`} component={Response} />
+        <PrivateRoute path={`${path}/attendance-approve-failed`} component={Response} />
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (4)

12-12: Use a more descriptive variable name

The variable billScreen could be renamed to better reflect its purpose, improving code readability. Consider using isBillAggregationScreen or isBillSelectionFlow.

Apply this diff:

-    const billScreen = location.pathname.includes("project-and-aggregation-selection");
+    const isBillAggregationScreen = location.pathname.includes("project-and-aggregation-selection");

135-143: Add missing key props to ActionBar buttons

Each element in the actionFields array should have a unique key prop to prevent potential issues during rendering.

Apply this diff:

 actionFields={[
     <Button
+        key="backButton"
         label={t(`HCM_AM_BACK_LABEL`)}
         onClick={() => {
             history.push(`/${window.contextPath}/employee`);
         }}
         style={{ marginLeft: "2.5rem", minWidth: "14rem" }}
         type="button"
         variation="secondary"
     />,
     <Button
+        key="nextButton"
         label={t(`HCM_AM_NEXT_LABEL`)}
         title={t(`HCM_AM_NEXT_LABEL`)}
         onClick={() => {
             // ...
         }}
         style={{ minWidth: "14rem" }}
         type="button"
         variation="primary"
     />,
 ]}

Also applies to: 145-167

🧰 Tools
🪛 Biome (1.9.4)

[error] 135-143: 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)


53-66: Fix potential issue with empty array mapping

Mapping over an empty array as a fallback results in no data. Simplify the fallback to an empty array to prevent unnecessary operations.

Apply this diff:

             const datak =
                 Digit?.SessionStorage.get("staffProjects") ||
-                [].map((target) => ({
-                    code: target.id,
-                    projectType: target.projectType,
-                    name: target.name,
-                    boundary: target?.address?.boundary,
-                    boundaryType: target?.address?.boundaryType,
-                    projectHierarchy: target.projectHierarchy,
-                }));
+                [];

179-179: Remove commented-out code

There is a commented-out line that can be removed to clean up the codebase.

Apply this diff:

-                        // error={showToast.key === "error"}
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (12)

1-1: Remove unused and invalid imports

The imports useReducer, useMemo, and use are not used in this file. Additionally, use is not a valid React hook and may have been included by mistake. Please remove these to clean up the code.


5-5: Define 'location' or use 'useLocation' hook

The variable location is used but not defined in this scope. If you intend to access the route's state, consider importing useLocation from react-router-dom and using it to retrieve the location object.


48-48: Use strict equality and optional chaining

Consider using triple equals (===) for strict comparison to avoid type coercion pitfalls. Also, use optional chaining on Digit.SessionStorage.get("paymentInbox") to handle cases where the session storage may not have the paymentInbox object.

Apply this diff to improve the code:

- referenceId: selectedProject == undefined ? Digit.SessionStorage.get("paymentInbox").selectedProject?.id : selectedProject?.id,
+ referenceId: selectedProject === undefined ? Digit.SessionStorage.get("paymentInbox")?.selectedProject?.id : selectedProject?.id,

52-52: Simplify the boolean expression

The ternary operator is unnecessary here. You can assign the condition directly to isChildrenRequired.

Apply this diff to simplify:

- isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
+ isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType,
🧰 Tools
🪛 Biome (1.9.4)

[error] 52-52: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


55-55: Simplify the boolean expression

Instead of using a ternary operator returning true or false, you can assign the condition directly to enabled.

Apply this diff to simplify:

- enabled: selectedBoundaryCode && selectedProject ? true : false,
+ enabled: !!(selectedBoundaryCode && selectedProject),
🧰 Tools
🪛 Biome (1.9.4)

[error] 55-55: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


72-72: Simplify the boolean expression

Assign the condition directly to enabled without using a ternary operator.

Apply this diff to simplify:

- enabled: selectedBoundaryCode ? true : false,
+ enabled: !!selectedBoundaryCode,
🧰 Tools
🪛 Biome (1.9.4)

[error] 72-72: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


215-223: Use a self-closing tag for <CustomInboxSearchLinks>

JSX elements without children should be self-closing.

Apply this diff to fix:

- <CustomInboxSearchLinks
-     headerText={"HCM_AM_BILL_INBOX"}
-     links={[
-         {
-             url: "/employee/payments/my-bills",
-             text: "HCM_AM_MY_BILLS",
-         },
-     ]}
- ></CustomInboxSearchLinks>
+ <CustomInboxSearchLinks
+     headerText={"HCM_AM_BILL_INBOX"}
+     links={[
+         {
+             url: "/employee/payments/my-bills",
+             text: "HCM_AM_MY_BILLS",
+         },
+     ]}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


244-251: Use a self-closing tag for <BillBoundaryFilter>

JSX elements without children should be self-closing.

Apply this diff to fix:

- <BillBoundaryFilter
-     isRequired={ScreenTypeEnum.BILL}
-     selectedProject={selectedProject}
-     selectedLevel={selectedLevel}
-     onFilterChange={handleFilterUpdate}
-     updateBoundaryFilters={updateFilters}
-     resetBoundaryFilter={resetBoundaryFilter}
- ></BillBoundaryFilter>
+ <BillBoundaryFilter
+     isRequired={ScreenTypeEnum.BILL}
+     selectedProject={selectedProject}
+     selectedLevel={selectedLevel}
+     onFilterChange={handleFilterUpdate}
+     updateBoundaryFilters={updateFilters}
+     resetBoundaryFilter={resetBoundaryFilter}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 244-251: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


296-305: Use a self-closing tag for <BillInboxTable>

JSX elements without children should be self-closing.

Apply this diff to fix:

- <BillInboxTable
-     isFetching={isFetching}
-     tableData={tableData}
-     currentPage={currentPage}
-     rowsPerPage={rowsPerPage}
-     handlePageChange={handlePageChange}
-     handlePerRowsChange={handlePerRowsChange}
-     totalCount={totalCount}
-     status={activeLink.code}
- ></BillInboxTable>
+ <BillInboxTable
+     isFetching={isFetching}
+     tableData={tableData}
+     currentPage={currentPage}
+     rowsPerPage={rowsPerPage}
+     handlePageChange={handlePageChange}
+     handlePerRowsChange={handlePerRowsChange}
+     totalCount={totalCount}
+     status={activeLink.code}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 296-305: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


330-344: Add a key prop to the Button component in the actionFields array

When rendering elements in an array, each element should have a unique key prop to help React identify which items have changed.

Apply this diff to fix:

{
  actionFields: [
-     <Button
+     <Button
+         key="generate-bill-btn"
          icon="CheckCircle"
          label={t(`HCM_AM_GENERATE_BILL_LABEL`)}
          onClick={() => {
              setOpenAlertPopUp(true);
          }}
          style={{
              minWidth: "14rem",
              opacity: billGenerationStatus != null ? 0.5 : 1,
          }}
          type="button"
          variation="primary"
          isDisabled={generateBillMutation.isLoading}
      />,
  ]
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 330-344: 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)


199-200: Handle errors in the catch block

The catch block is empty, which may make debugging difficult if an error occurs. Consider adding error handling or logging inside the catch block.

Apply this diff to improve error handling:

} catch (error) {
-     /// will show estimate data only
+     console.error('Error generating bill:', error);
+     setShowToast({ key: "error", label: t("HCM_AM_BILL_GENERATION_FAILED"), transitionTime: 3000 });
}

21-21: Remove unused state variable filterCriteria

The state variable filterCriteria is defined but not used in the component. Consider removing it to clean up the code.

Apply this diff to remove it:

- const [filterCriteria, setFilterCriteria] = useState(null);
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (4)

6-6: Remove unused import useQueryClient

The useQueryClient function imported from react-query is not used in this file. Removing it will clean up the code.

Apply this diff to remove the unused import:

- import { useQueryClient } from "react-query";

17-23: Simplify event handlers by passing prop functions directly

The handlers handlePageChange and handlePerRowsChange simply invoke the functions passed via props without adding any additional logic. You can simplify the code by passing the prop functions directly to the DataTable component.

Apply this diff to simplify:

- const handlePageChange = (page, totalRows) => {
-     props?.handlePageChange(page, totalRows);
- };
 
- const handlePerRowsChange = async (currentRowsPerPage, currentPage) => {
-     props?.handlePerRowsChange(currentRowsPerPage, currentPage);
- };

Then, in the DataTable component:

<DataTable
  columns={columns}
  data={props.tableData}
  pagination
  paginationServer
  customStyles={tableCustomStyle}
  paginationDefaultPage={props?.currentPage}
- onChangePage={handlePageChange}
- onChangeRowsPerPage={handlePerRowsChange}
+ onChangePage={props.handlePageChange}
+ onChangeRowsPerPage={props.handlePerRowsChange}
  paginationTotalRows={props?.totalCount}
  paginationPerPage={props?.rowsPerPage}
  sortIcon={<CustomSVG.SortUp width={"16px"} height={"16px"} fill={"#0b4b66"} />}
  paginationRowsPerPageOptions={[5, 10, 15, 20]}
  fixedHeader={true}
  fixedHeaderScrollHeight={"32vh"}
/>

70-72: ⚠️ Potential issue

Ensure consistency between tooltip and displayed text

In the table cell, the title attribute uses row?.markby, whereas the displayed text uses row?.approvedBy or row?.markedBy. This inconsistency can lead to confusion. Please ensure that both the tooltip and the displayed text refer to the same property.

Apply this diff to fix the issue:

- <div className="ellipsis-cell" title={row?.markby || t("NA")}>
+ <div className="ellipsis-cell" title={props.status === "APPROVED" ? row?.approvedBy : row?.markedBy || t("NA")}>

Likely invalid or redundant comment.


81-83: ⚠️ Potential issue

Ensure tooltip matches displayed data

The title attribute uses row?.status, while the displayed text uses row?.noOfAttendees. To avoid confusion, both should reference the same property.

Apply this diff to fix the issue:

- <div className="ellipsis-cell" title={t(row?.status || "0")}>
+ <div className="ellipsis-cell" title={t(row?.noOfAttendees || "0")}>

Likely invalid or redundant comment.

Comment on lines +79 to +81
useEffect(() => {
refetchBill();
}, [billID, dateRange, limitAndOffset])
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)

Consider debouncing the refetch calls.

The effect depends on multiple state variables that could trigger rapid refetches. Consider debouncing the refetch calls for better performance.

+const debouncedRefetch = useMemo(
+  () => Digit.Utils.debounce(() => refetchBill(), 300),
+  [refetchBill]
+);

 useEffect(() => {
-    refetchBill();
+    debouncedRefetch();
 }, [billID, dateRange, limitAndOffset])

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 109 to 125
value = String(value).replace(/^0+/, "");

const selectProps = {
hideLabel: true,
isIntermediate: isIntermediate,
mainClassName: "data-table-select-checkbox",
};
// Find the worker whose attendance is being updated
const worker = props.data.find((worker) => worker[2] === workerId);

if (!worker) return; // If worker is not found, exit early

const previousValue = worker[4]; // Previous value for daysWorked

// Check if both current value and previous value are 0
if (value === 0 && previousValue === 0) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_CAN_NOT_BE_LESS_THAN_ZERO"), transitionTime: 3000 });
return;
}

if (value > props.duration) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_CAN_NOT_EXCEED_EVENT_DURATION_ERROR"), transitionTime: 3000 });
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

Convert value to a number before comparison to ensure correct logic

After removing leading zeros, value remains a string. When comparing value with numbers in subsequent conditions (lines 119 and 124), this may lead to incorrect behavior. Convert value to a number before performing numeric comparisons.

Apply this diff to fix the issue:

   // Remove leading zeros from the value
   value = String(value).replace(/^0+/, "");

+  // Convert value to a number
+  value = Number(value);

   // Find the worker whose attendance is being updated
📝 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
value = String(value).replace(/^0+/, "");
const selectProps = {
hideLabel: true,
isIntermediate: isIntermediate,
mainClassName: "data-table-select-checkbox",
};
// Find the worker whose attendance is being updated
const worker = props.data.find((worker) => worker[2] === workerId);
if (!worker) return; // If worker is not found, exit early
const previousValue = worker[4]; // Previous value for daysWorked
// Check if both current value and previous value are 0
if (value === 0 && previousValue === 0) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_CAN_NOT_BE_LESS_THAN_ZERO"), transitionTime: 3000 });
return;
}
if (value > props.duration) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_CAN_NOT_EXCEED_EVENT_DURATION_ERROR"), transitionTime: 3000 });
value = String(value).replace(/^0+/, "");
// Convert value to a number
value = Number(value);
// Find the worker whose attendance is being updated
const worker = props.data.find((worker) => worker[2] === workerId);
if (!worker) return; // If worker is not found, exit early
const previousValue = worker[4]; // Previous value for daysWorked
// Check if both current value and previous value are 0
if (value === 0 && previousValue === 0) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_CAN_NOT_BE_LESS_THAN_ZERO"), transitionTime: 3000 });
return;
}
if (value > props.duration) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_CAN_NOT_EXCEED_EVENT_DURATION_ERROR"), transitionTime: 3000 });
🧰 Tools
🪛 Biome (1.9.4)

[error] 109-109: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

* attendance inbox in  progress

* composer in progress

* inboxserach composer replaced with custom inbox component

* boundary service API integration implemented for inbox screen

* check box and register search API integration in progress

* table data enriched

* removed debugger

* variable name changed

* tab section functionlity added

* attendance register param changed

* localization code and table value changed

* inbox pagination and status register count fixed

* table component css style changed

* padding removed from table style

* console removed

* HCMPRE-1774: point-1 project drop down is put in the filter section and search section is not required as per last demo

* fliter boundary dropdown in progress

* staffName key changed for attendance mark by

* bug fixes

* code comment added why not used inboxsearch composer

* boundary service made dynamic

* boundary component made dynamic

* boundary component issue fixed for mandatory filed and drop down reset

* commented code removed

* bug fixes done

* ticket: HCMPRE-1822, boundary option reloaded and error scenation handled for project selection and boundary selection in attendance register inbox

* HCMPRE-1822::table rows per page issue fixed, and digit.session storage implemented

* reworking on the tavle component in view attendance screen

* HCMPRE-1884, worked on preselected boundary

* HCMPRE-1884:: project is also bydefault selected

* inline css code removed from custom div

* css
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 15

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8658973 and 0707199.

📒 Files selected for processing (7)
  • health/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/payment.scss (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1 hunks)
👮 Files not reviewed due to content moderation or server errors (3)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js
🧰 Additional context used
📓 Path-based instructions (6)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js

[error] 135-143: 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)


[error] 144-167: 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)


[error] 189-197: 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)


[error] 198-221: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js

[error] 202-202: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 208-208: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 220-230: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


[error] 110-123: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 48-48: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

🔇 Additional comments (21)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (6)

6-6: Remove unused import.

The useQueryClient import is not used in this component.

- import { useQueryClient } from "react-query";

10-12: Destructure props for better maintainability.

Instead of using spread operator, explicitly destructure the required props.

- const BillInboxTable = ({
-     ...props
- }) => {
+ const BillInboxTable = ({
+     tableData,
+     currentPage,
+     totalCount,
+     rowsPerPage,
+     handlePageChange,
+     handlePerRowsChange,
+     isFetching,
+     status
+ }) => {

17-23: Simplify event handlers.

The handlers are just wrapping the prop functions without adding any logic. Pass them directly to the DataTable component.


80-84: Fix inconsistent tooltip in attendees column.

The tooltip uses row?.status while displaying row?.noOfAttendees.

- title={t(row?.status || "0")}
+ title={t(row?.noOfAttendees || "0")}

70-72: Fix inconsistent property usage in approved/marked by column.

The tooltip uses row?.markby while the displayed text uses row?.markedBy.

- title={row?.markby || t("NA")}
+ title={row?.markedBy || t("NA")}

95-95: Move inline styles to CSS.

Inline styles make maintenance difficult. Move them to a CSS class.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (5)

140-142: ⚠️ Potential issue

Update Prop Name to updateSessionStorage

Following the correction of the prop name, ensure all references within the component are updated accordingly.

Apply this diff:

          if (updateSeeeionStorage) {
-           updateSeeeionStorage(newSelectedValues);
+           updateSessionStorage(newSelectedValues);
          }

Likely invalid or redundant comment.


6-6: ⚠️ Potential issue

Fix the Prop Name: updateSeeeionStorage

The prop updateSeeeionStorage appears to have a misspelling. It should likely be updateSessionStorage.

Apply this diff to correct the prop name:

- const BoundaryComponent = ({ reset, makeReset, initialValue, updateSeeeionStorage, selectedProject, onChange, lowestLevel, isRequired }) => {
+ const BoundaryComponent = ({ reset, makeReset, initialValue, updateSessionStorage, selectedProject, onChange, lowestLevel, isRequired }) => {

Also, update all references to updateSeeeionStorage within the component.

Likely invalid or redundant comment.


8-8: ⚠️ Potential issue

Add Null Check for boundaryHierarchyOrder

Accessing boundaryHierarchyOrder without checking if it exists can lead to runtime errors if the session storage item is not set.

Apply this diff to add a null check:

- const kk = Digit.SessionStorage.get("boundaryHierarchyOrder").map((item) => item.code);
+ const boundaryHierarchyOrder = Digit.SessionStorage.get("boundaryHierarchyOrder") || [];
+ const kk = boundaryHierarchyOrder.map((item) => item.code);

Likely invalid or redundant comment.


117-120: 🧹 Nitpick (assertive)

Consolidate Functions handleButtonClick and handleDropdownOptions

The function handleButtonClick immediately calls handleDropdownOptions after invoking onChange. Consider merging these functions for clarity and simplicity.

Apply this refactor:

- const handleButtonClick = (value) => {
-   onChange(value); // Call the callback with the selected value
-   handleDropdownOptions(value); // Update dropdown options
- };
+ const handleSelectionChange = (value) => {
+   onChange(value);
+   if (value?.children && value.children.length > 0) {
+     // Update dropdown options logic here
+     // (Merge the contents of handleDropdownOptions)
+   }
+ };

Update all references to handleButtonClick to use handleSelectionChange.

Likely invalid or redundant comment.


87-91: ⚠️ Potential issue

Add Null Checks for Boundary Data Access

When accessing childrenData[0]?.boundary[0], there's a possibility that boundary or its elements may be undefined. Add null checks to prevent runtime errors.

Apply this diff:

          if (childrenData && childrenData[0]?.boundary && childrenData[0].boundary[0]) {
            setValue((prevState) => ({
              ...prevState,
-             [childrenData[0]?.boundary[0].boundaryType]: [childrenData[0]?.boundary[0]],
+             [childrenData[0].boundary[0].boundaryType]: [childrenData[0].boundary[0]],
            }));

            const formattedData = createFormattedData(childrenData[0].boundary[0].boundaryType);
            setBoundaryData(formattedData);
            handleSelectionChange(childrenData[0].boundary[0]);
          }

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (10)

64-64: 🧹 Nitpick (assertive)

Use Strict Equality Operator

Use === instead of == for strict type comparison.

Apply this diff:

- if (reset == true) {
+ if (reset === true) {

Likely invalid or redundant comment.


25-30: ⚠️ Potential issue

Reset isDistrictSelected When Boundary Changes

isDistrictSelected is set when the boundary type is "DISTRICT" but not reset when it changes. Ensure it reflects the current selection.

Apply this diff:

const onChangeId = (value) => {
  setBoundary(value);
- if (value?.boundaryType === "DISTRICT") {
-   setIsDistrictSelected(true); // Set flag if district is selected
- }
+ setIsDistrictSelected(value?.boundaryType === "DISTRICT");
};

Likely invalid or redundant comment.


48-48: 🧹 Nitpick (assertive)

Use const Instead of let

The variable datak is not reassigned after initialization. Use const instead of let for better code practices.

Apply this diff:

- let datak =
+ const datak =

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


92-97: ⚠️ Potential issue

Improve Accessibility for Clickable Span

The <span> element with an onClick handler should be accessible via keyboard navigation.

Apply this diff:

< span
  onClick={() => {
    setReset(true);
  }}
+ onKeyPress={(e) => {
+   if (e.key === 'Enter') {
+     setReset(true);
+   }
+ }}
+ role="button"
+ tabIndex="0"
  className="on-icon-reset-proximity"
>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


46-60: 🧹 Nitpick (assertive)

Simplify Project Initialization Logic

The current logic can be streamlined for better readability and efficiency.

Apply this diff:

useEffect(() => {
  if (project.length === 0) {
-   let datak =
+   const datak =
      Digit?.SessionStorage.get("staffProjects") || [];
-     [].map((target) => ({
-       code: target.id,
-       projectType: target.projectType,
-       name: target.name,
-       boundary: target?.address?.boundary,
-       boundaryType: target?.address?.boundaryType,
-       projectHierarchy: target.projectHierarchy,
-     }));
    setProject(datak);
  }
- }, []);
+ }, [project.length, setProject]);

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


4-4: ⚠️ Potential issue

Update Import Path for BoundaryComponent

The import statement for BoundaryComponent uses a non-descriptive path "../sample". Update the import to reflect the actual file name for better clarity.

Apply this diff:

- import BoundaryComponent from "../sample";
+ import BoundaryComponent from "../components/BoundaryComponent";

Ensure the file is named appropriately and the path is correct.

Likely invalid or redundant comment.


110-123: 🧹 Nitpick (assertive)

Self-Closing JSX Elements

The BoundaryComponent is a JSX element without children. It should be self-closing for cleaner syntax.

Apply this diff:

- ></BoundaryComponent>
+ />

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 110-123: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


98-104: ⚠️ Potential issue

Add Accessible Title to SVG

The SVG lacks a title or aria-label, which is important for accessibility.

Apply this diff:

< svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg"
+ aria-label={t('CS_COMMON_RESET')}
>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


38-43: Add Missing Dependencies to useEffect Hook

The useEffect hook depends on setProjectSelected. Include it in the dependency array to prevent potential issues.

Apply this diff:

- }, []);
+ }, [setProjectSelected]);

55-60: Add Missing Dependencies to Second useEffect Hook

Similarly, include project.length and setProject in the dependency array.

Apply this diff:

- }, []);
+ }, [project.length, setProject]);

sortIcon={<CustomSVG.SortUp width={"16px"} height={"16px"} fill={"#0b4b66"} />}
paginationRowsPerPageOptions={[5, 10, 15, 20]}
fixedHeader={true}
fixedHeaderScrollHeight={"32vh"}
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)

Review fixed header scroll height.

The current scroll height of "32vh" might be too restrictive for tables with more data. Consider increasing it or making it configurable via props.

- fixedHeaderScrollHeight={"32vh"}
+ fixedHeaderScrollHeight={"45vh"}
📝 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
fixedHeaderScrollHeight={"32vh"}
fixedHeaderScrollHeight={"45vh"}

Comment on lines 113 to 131
display: flex;
flex-direction: column;
gap: 24px;
margin-bottom: 2.5rem;


}











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 excessive empty lines

The file contains unnecessary empty lines at the end. Consider maintaining a single empty line at the end of the file as per common coding standards.

Comment on lines 94 to 99
max-width: 100%;
overflow: auto;
margin: 0px;
height: 75vh;
}
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)

Fix typo in class name

The class name contains a spelling error.

-.custom-inbox-outer-table-section .card-overide {
+.custom-inbox-outer-table-section .card-override {
    max-width: 100%; 
    overflow: auto;
    margin: 0px;
    height: 75vh;
}
📝 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
.custom-inbox-outer-table-section .card-overide{
max-width: 100%;
overflow: auto;
margin: 0px;
height: 75vh;
}
.custom-inbox-outer-table-section .card-override{
max-width: 100%;
overflow: auto;
margin: 0px;
height: 75vh;
}

Comment on lines 105 to 107
border: 1px solid #e0e0e0; padding: 6px; margin-bottom: 10px; cursor: pointer;
}
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)

Improve code formatting and use theme variables

The styles are written in a single line and use hardcoded colors. Consider improving readability and maintaining design system consistency.

.on-icon-reset-proximity {
-    border: 1px solid #e0e0e0; padding: 6px; margin-bottom: 10px; cursor: pointer;
+    border: 1px solid theme(digitv2.lightTheme.border);
+    padding: 6px;
+    margin-bottom: 10px;
+    cursor: pointer;
}

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +32 to +36
border-right: 2px solid #787878;
width: 100%;
text-align: start;
}
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)

Use theme variables for colors instead of hardcoded hex values

Replace the hardcoded border color with a theme variable to maintain consistency with the design system.

.custom-inbox-table-row {
-    border-right: 2px solid #787878;
+    border-right: 2px solid theme(digitv2.lightTheme.border);
    width: 100%;
    text-align: start;
}

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +149 to +155
const handleInsertion = (boundaryType, newValue) => {
setValue((prevState) => {
const newState = { ...prevState };
const currentBoundary = newState[boundaryType] || [];
if (!currentBoundary.find((item) => item === newValue)) {
newState[boundaryType] = [...currentBoundary, newValue];
}
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)

Optimize Array Search

In handleInsertion, replacing find with some can improve performance as it stops searching after finding a match.

Apply this diff:

- if (!currentBoundary.find((item) => item === newValue)) {
+ if (!currentBoundary.some((item) => item === newValue)) {
📝 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
const handleInsertion = (boundaryType, newValue) => {
setValue((prevState) => {
const newState = { ...prevState };
const currentBoundary = newState[boundaryType] || [];
if (!currentBoundary.find((item) => item === newValue)) {
newState[boundaryType] = [...currentBoundary, newValue];
}
const handleInsertion = (boundaryType, newValue) => {
setValue((prevState) => {
const newState = { ...prevState };
const currentBoundary = newState[boundaryType] || [];
if (!currentBoundary.some((item) => item === newValue)) {
newState[boundaryType] = [...currentBoundary, newValue];
}

Comment on lines 229 to 251
// Reusable dropdown component
const BoundaryDropdown = ({ label, data, onChange, selected, setSelected, isRequired }) => {
const { t } = useTranslation();

return (
<div style={{ width: "100%", marginTop: "14px" }}>
<div className="comment-label">
{t(label)}
{isRequired && <span className="required"> *</span>}
</div>
<Dropdown
selected={selected}
t={t}
option={data}
optionKey={"code"}
select={(value) => {
setSelected(value);
onChange(value);
}}
/>
</div>
);
};
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)

Consider Using React.memo for BoundaryDropdown

If the BoundaryDropdown component receives the same props frequently, wrapping it with React.memo can prevent unnecessary re-renders.

- const BoundaryDropdown = ({ label, data, onChange, selected, setSelected, isRequired }) => {
+ const BoundaryDropdown = React.memo(({ label, data, onChange, selected, setSelected, isRequired }) => {
    // component code
- };
+ });
📝 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
// Reusable dropdown component
const BoundaryDropdown = ({ label, data, onChange, selected, setSelected, isRequired }) => {
const { t } = useTranslation();
return (
<div style={{ width: "100%", marginTop: "14px" }}>
<div className="comment-label">
{t(label)}
{isRequired && <span className="required"> *</span>}
</div>
<Dropdown
selected={selected}
t={t}
option={data}
optionKey={"code"}
select={(value) => {
setSelected(value);
onChange(value);
}}
/>
</div>
);
};
// Reusable dropdown component
const BoundaryDropdown = React.memo(({ label, data, onChange, selected, setSelected, isRequired }) => {
const { t } = useTranslation();
return (
<div style={{ width: "100%", marginTop: "14px" }}>
<div className="comment-label">
{t(label)}
{isRequired && <span className="required"> *</span>}
</div>
<Dropdown
selected={selected}
t={t}
option={data}
optionKey={"code"}
select={(value) => {
setSelected(value);
onChange(value);
}}
/>
</div>
);
});

if (boundaryData[key] && isBoundaryAllowed(key)) {
return (
<BoundaryDropdown
isRequired={isRequired == ScreenTypeEnum.BILL ? true : key == lowestLevelBoundaryType ? true : false}
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)

Simplify Boolean Expression

The expression in the isRequired prop uses unnecessary ternary operators. Simplify it for better readability.

Apply this diff:

- isRequired={isRequired == ScreenTypeEnum.BILL ? true : key == lowestLevelBoundaryType ? true : false}
+ isRequired={isRequired === ScreenTypeEnum.BILL || key === lowestLevelBoundaryType}
📝 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
isRequired={isRequired == ScreenTypeEnum.BILL ? true : key == lowestLevelBoundaryType ? true : false}
isRequired={isRequired === ScreenTypeEnum.BILL || key === lowestLevelBoundaryType}
🧰 Tools
🪛 Biome (1.9.4)

[error] 202-202: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

Comment on lines 85 to 93
setValue((prevState) => ({
...prevState,
[childrenData[0]?.boundary[0].boundaryType]: [childrenData[0]?.boundary[0]],
}));

const formattedData = createFormattedData(childrenData[0]?.boundary[0].boundaryType);
setBoundaryData(formattedData);
handleButtonClick(childrenData[0]?.boundary[0]);
}
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)

Consolidate State Updates

When setting multiple state values based on childrenData, consider consolidating the updates to improve performance.

if (childrenData && childrenData.length > 0) {
  const boundaryItem = childrenData[0]?.boundary[0];
  if (boundaryItem) {
    setValue((prevState) => ({
      ...prevState,
      [boundaryItem.boundaryType]: [boundaryItem],
    }));

    const formattedData = createFormattedData(boundaryItem.boundaryType);
    setBoundaryData(formattedData);
    handleSelectionChange(boundaryItem);
  }
}
📝 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
setValue((prevState) => ({
...prevState,
[childrenData[0]?.boundary[0].boundaryType]: [childrenData[0]?.boundary[0]],
}));
const formattedData = createFormattedData(childrenData[0]?.boundary[0].boundaryType);
setBoundaryData(formattedData);
handleButtonClick(childrenData[0]?.boundary[0]);
}
if (childrenData && childrenData.length > 0) {
const boundaryItem = childrenData[0]?.boundary[0];
if (boundaryItem) {
setValue((prevState) => ({
...prevState,
[boundaryItem.boundaryType]: [boundaryItem],
}));
const formattedData = createFormattedData(boundaryItem.boundaryType);
setBoundaryData(formattedData);
handleSelectionChange(boundaryItem);
}
}

Comment on lines +130 to +135
marginTop: "auto", // Pushes this section to the bottom
paddingTop: "16px", // Adds spacing above the button
}}
>
<SubmitBar onSubmit={handleApplyFilter} className="w-fullwidth" label={t("HCM_AM_COMMON_APPLY")} />
</div>
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)

Avoid Inline Styles

Move inline styles to a CSS class for better maintainability.

Apply this diff:

- style={{
-   justifyContent: "center",
-   marginTop: "auto",
-   paddingTop: "16px",
- }}
+ className="filter-section-footer"

Then define the CSS class:

.filter-section-footer {
  justify-content: center;
  margin-top: auto;
  padding-top: 16px;
}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0707199 and 0fdc821.

📒 Files selected for processing (4)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js

[error] 135-144: 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)


[error] 145-169: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 52-52: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 55-55: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 72-72: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 233-240: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 296-306: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 331-345: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

[error] 47-47: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 102-102: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 298-298: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 323-325: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 488-498: 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)


[error] 500-511: 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)


[error] 513-542: 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)

🔇 Additional comments (33)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/project_selection.js (5)

12-12: Consider using a more descriptive variable name.

The variable billScreen could be renamed to better reflect its purpose, such as isBillAggregationScreen.


20-28: Consider extracting complex mapping logic into a utility function.

The aggregation level options mapping logic could be moved to a separate utility function for better maintainability.


53-65: Fix potential issue with empty array mapping.

The fallback for project data could result in mapping an empty array.


68-72: Remove commented-out code.

There's commented-out code that should be removed to maintain code cleanliness.


134-170: ⚠️ Potential issue

Add missing key props to ActionBar buttons.

React requires key props for elements in iterables to help with rendering optimization.

Apply this diff:

 actionFields={[
     <Button
+        key="back"
         icon="ArrowBack"
         label={t(`HCM_AM_BACK_LABEL`)}
         onClick={() => {
             history.push(`/${window.contextPath}/employee`);
         }}
         style={{ marginLeft: "2.5rem", minWidth: "14rem" }}
         type="button"
         variation="secondary"
     />,
     <Button
+        key="next"
         icon="ArrowForward"
         isSuffix={true}
         label={t(`HCM_AM_NEXT_LABEL`)}

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 135-144: 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)


[error] 145-169: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (13)

16-16: Ensure safe access to location.state

Destructuring fromCampaignSupervisor from location.state || false can cause issues if location.state is null or not an object. Consider providing a default object to prevent errors.


35-35: Correct the typo in state variable name

The state variable loding appears to be a typo. It should be loading for clarity and consistency.

Apply this diff to fix the typo:

- const [loding, setLoding] = useState(false);
+ const [loading, setLoading] = useState(false);

47-47: Simplify boolean expression

Simplify the condition by removing the unnecessary ternary operator.

Apply this diff:

- enabled: registerNumber ? true : false,
+ enabled: !!registerNumber,
🧰 Tools
🪛 Biome (1.9.4)

[error] 47-47: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


102-102: Simplify boolean expression

Simplify the condition by removing the unnecessary ternary operator.

Apply this diff:

- enabled: (AttendanceData ? true : false),
+ enabled: !!AttendanceData,
🧰 Tools
🪛 Biome (1.9.4)

[error] 102-102: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


298-298: Simplify boolean expression

Simplify the condition by removing the unnecessary ternary operator.

Apply this diff:

- enabled: individualIds.length > 0 ? true : false,
+ enabled: individualIds.length > 0,
🧰 Tools
🪛 Biome (1.9.4)

[error] 298-298: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


323-325: Simplify boolean expression

Simplify the condition by removing the unnecessary ternary operator.

Apply this diff:

- enabled: AttendanceData?.attendanceRegister[0]?.staff?.find(
-   (staff) => staff?.staffType?.includes("OWNER")
- )?.userId ? true : false,
+ enabled: !!AttendanceData?.attendanceRegister[0]?.staff?.find(
+   (staff) => staff?.staffType?.includes("OWNER")
+ )?.userId,
🧰 Tools
🪛 Biome (1.9.4)

[error] 323-325: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


364-364: Address the pending dependency update

The comment /// need to update dependency indicates that there might be a missing dependency in the useEffect hook. Ensure all necessary dependencies are included to prevent potential bugs.


397-398: Return the loader component to display it

The <LoaderComponent /> inside the if block is not returned or rendered, so it won't display as intended. Ensure you return the component.

Apply this diff:

- if (updateMutation.isLoading) {
-   <LoaderComponent variant={"OverlayLoader"} />
- }
+ if (updateMutation.isLoading) {
+   return <LoaderComponent variant={"OverlayLoader"} />;
+ }

203-205: Handle errors appropriately in catch block

Empty catch blocks can hide errors and make debugging difficult. Add error handling or logging within the catch block to surface any issues during execution.

Apply this diff:

} catch (error) {
- /// will show estimate data only
+ console.error('Error approving muster roll:', error);
}

245-247: Handle errors appropriately in catch block

Empty catch blocks can hide errors and make debugging difficult. Add error handling or logging within the catch block to surface any issues during execution.

Apply this diff:

} catch (error) {
- /// will show estimate data only
+ console.error('Error updating muster roll:', error);
}

488-498: Add a unique key prop to elements in actionFields

When rendering elements conditionally within an array, each element should have a unique key prop to help React identify which elements have changed.

Apply this diff:

            actionFields={[
-              disabledAction ? (
+              disabledAction ? (
+                <Button
+                  key="goBackButton"
                   label={t(`HCM_AM_GO_BACK`)}
                   title={t(`HCM_AM_GO_BACK`)}
                   onClick={() => {
                     fromCampaignSupervisor ? history.push(`/${window.contextPath}/employee/payments/generate-bill`, { fromViewScreen: true }) :
                       history.push(`/${window.contextPath}/employee/payments/registers-inbox`);
                   }}
                   type="button"
                   style={{ minWidth: "14rem" }}
                   variation="primary"
                 />
               ) : editAttendance ? (
🧰 Tools
🪛 Biome (1.9.4)

[error] 488-498: 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)


500-511: Add a unique key prop to elements in actionFields

Each element in the array should have a unique key prop.

Apply this diff:

              ) : editAttendance ? (
                <Button
+                 key="submitButton"
                  label={t(`HCM_AM_SUBMIT_LABEL`)}
                  title={t(`HCM_AM_SUBMIT_LABEL`)}
                  onClick={() => {
                    setUpdateDisabled(true);
                    triggerMusterRollUpdate();
                  }}
                  style={{ minWidth: "14rem" }}
                  type="button"
                  variation="primary"
                  isDisabled={updateMutation.isLoading || updateDisabled || !isSubmitEnabled}
                />
🧰 Tools
🪛 Biome (1.9.4)

[error] 500-511: 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)


513-542: Add a unique key prop to elements in actionFields

Ensure each child element has a unique key prop.

Apply this diff:

              ) : (
                <Button
+                 key="actionsButton"
                  className="custom-class"
                  iconFill=""
                  label={t(`HCM_AM_ACTIONS`)}
                  menuStyles={{
                    bottom: "40px",
                  }}
                  onOptionSelect={(value) => {
                    if (value.code === "EDIT_ATTENDANCE") {
                      setOpenEditAlertPopUp(true);
                    } else if (value.code === "APPROVE") {
                      setOpenApproveCommentPopUp(true);
                    }
                  }}
                  options={[
                    {
                      code: "EDIT_ATTENDANCE",
                      name: t(`HCM_AM_ACTIONS_EDIT_ATTENDANCE`),
                    },
                    {
                      code: "APPROVE",
                      name: t(`HCM_AM_ACTIONS_APPROVE`),
                    },
                  ]}
                  optionsKey="name"
                  size=""
                  style={{ minWidth: "14rem" }}
                  title=""
                  type="actionButton"
                />
              ),
🧰 Tools
🪛 Biome (1.9.4)

[error] 513-542: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (10)

1-1: Remove unused and invalid imports

The imports useReducer, useMemo, and use are not used in this file. Additionally, use is not a valid React hook and may have been included by mistake. Please remove these to clean up the code.

Apply this diff:

- import React, { useEffect, useReducer, useState, useMemo, use } from "react";
+ import React, { useEffect, useState } from "react";

5-5: Define 'location' or use 'useLocation' hook

The variable location is used but not defined in this scope. If you intend to access the browser's location or the route's state, consider importing useLocation from react-router-dom and using it to retrieve the location object.

Apply this diff to import useLocation and update the code:

+ import { useLocation } from "react-router-dom";
...
- const { fromViewScreen } = location.state || false;
+ const location = useLocation();
+ const { fromViewScreen } = location.state || {};

52-52: Simplify the boolean expression

The ternary operator can be simplified by directly assigning the boolean result of the condition to isChildrenRequired.

Apply this diff to simplify:

- isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
+ isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType,
🧰 Tools
🪛 Biome (1.9.4)

[error] 52-52: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


55-55: Simplify the boolean expression

The ternary operator is unnecessary here. You can directly assign the result of the logical expression to enabled.

Apply this diff to simplify:

- enabled: selectedBoundaryCode && selectedProject ? true : false,
+ enabled: !!(selectedBoundaryCode && selectedProject),
🧰 Tools
🪛 Biome (1.9.4)

[error] 55-55: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


72-72: Simplify the boolean expression

The ternary operator can be simplified by directly assigning the truthiness of selectedBoundaryCode to enabled.

Apply this diff to simplify:

- enabled: selectedBoundaryCode ? true : false,
+ enabled: !!selectedBoundaryCode,
🧰 Tools
🪛 Biome (1.9.4)

[error] 72-72: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


215-223: Use a self-closing tag for <CustomInboxSearchLinks>

JSX elements without child content should be self-closing.

Apply this diff:

- <CustomInboxSearchLinks
-   headerText={"HCM_AM_BILL_INBOX"}
-   links={[
-     {
-       url: "/employee/payments/my-bills",
-       text: "HCM_AM_MY_BILLS",
-     },
-   ]}
- ></CustomInboxSearchLinks>
+ <CustomInboxSearchLinks
+   headerText={"HCM_AM_BILL_INBOX"}
+   links={[
+     {
+       url: "/employee/payments/my-bills",
+       text: "HCM_AM_MY_BILLS",
+     },
+   ]}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


233-240: Use a self-closing tag for <BillBoundaryFilter>

JSX elements without child content should be self-closing.

Apply this diff:

- <BillBoundaryFilter
-   isRequired={ScreenTypeEnum.BILL}
-   selectedProject={selectedProject}
-   selectedLevel={selectedLevel}
-   onFilterChange={handleFilterUpdate}
-   updateBoundaryFilters={updateFilters}
-   resetBoundaryFilter={resetBoundaryFilter}
- ></BillBoundaryFilter>
+ <BillBoundaryFilter
+   isRequired={ScreenTypeEnum.BILL}
+   selectedProject={selectedProject}
+   selectedLevel={selectedLevel}
+   onFilterChange={handleFilterUpdate}
+   updateBoundaryFilters={updateFilters}
+   resetBoundaryFilter={resetBoundaryFilter}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 233-240: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


296-306: Use a self-closing tag for <BillInboxTable>

JSX elements without child content should be self-closing.

Apply this diff:

- <BillInboxTable
-   isFetching={isFetching}
-   tableData={tableData}
-   currentPage={currentPage}
-   rowsPerPage={rowsPerPage}
-   handlePageChange={handlePageChange}
-   handlePerRowsChange={handlePerRowsChange}
-   totalCount={totalCount}
-   status={activeLink.code}
-   infoDescription={infoDescription}
- ></BillInboxTable>
+ <BillInboxTable
+   isFetching={isFetching}
+   tableData={tableData}
+   currentPage={currentPage}
+   rowsPerPage={rowsPerPage}
+   handlePageChange={handlePageChange}
+   handlePerRowsChange={handlePerRowsChange}
+   totalCount={totalCount}
+   status={activeLink.code}
+   infoDescription={infoDescription}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 296-306: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


331-345: Add a key prop to the Button in actionFields

When rendering elements in an array, React recommends providing a unique key prop to each element to help identify which items have changed, are added, or are removed.

Apply this diff:

actionFields={[
-   <Button
+   <Button
+     key="generate-bill-btn"
      icon="CheckCircle"
      label={t(`HCM_AM_GENERATE_BILL_LABEL`)}
      onClick={() => {
        setOpenAlertPopUp(true);
        // triggerGenerateBill();
      }}
      style={{
        minWidth: "14rem",
        opacity: billGenerationStatus != null ? 0.5 : 1,
      }}
      type="button"
      variation="primary"
      isDisabled={generateBillMutation.isLoading}
    />,
]}
🧰 Tools
🪛 Biome (1.9.4)

[error] 331-345: 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)


198-200: 🛠️ Refactor suggestion

Handle errors in the catch block

The catch block is empty, which may make debugging difficult if an error occurs. Consider adding error handling or logging inside the catch block.

Apply this diff to add error handling:

} catch (error) {
-     /// will show estimate data only
+     console.error('Error generating bill:', error);
+     setShowToast({ key: "error", label: t("HCM_AM_BILL_GENERATION_FAILED"), transitionTime: 3000 });
}

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (5)

6-6: Remove unused import useQueryClient

The useQueryClient function imported from react-query is not used in this file. Removing it will clean up the code.

Apply this diff:

- import { useQueryClient } from "react-query";

17-23: Simplify event handlers by passing prop functions directly

The current handlers are just wrapping the prop functions without adding any logic. They can be simplified by passing the prop functions directly to the DataTable component.

Apply this diff:

- const handlePageChange = (page, totalRows) => {
-     props?.handlePageChange(page, totalRows);
- };
-
- const handlePerRowsChange = async (currentRowsPerPage, currentPage) => {
-     props?.handlePerRowsChange(currentRowsPerPage, currentPage);
- };

Then, in the DataTable component, pass the props directly:

<DataTable
  ...
- onChangePage={handlePageChange}
- onChangeRowsPerPage={handlePerRowsChange}
+ onChangePage={props.handlePageChange}
+ onChangeRowsPerPage={props.handlePerRowsChange}
  ...
/>

10-12: Add propTypes and defaultProps for the component

To enhance maintainability and catch potential issues early, consider defining propTypes and defaultProps for the BillInboxTable component.

Example:

+ import PropTypes from "prop-types";
...
- const BillInboxTable = ({
-     ...props
- }) => {
+ const BillInboxTable = ({
+     tableData,
+     currentPage,
+     totalCount,
+     rowsPerPage,
+     handlePageChange,
+     handlePerRowsChange,
+     isFetching,
+     status,
+     infoDescription,
+ }) => {
    // Component code
};
+ 
+ BillInboxTable.propTypes = {
+     tableData: PropTypes.array.isRequired,
+     currentPage: PropTypes.number.isRequired,
+     totalCount: PropTypes.number.isRequired,
+     rowsPerPage: PropTypes.number.isRequired,
+     handlePageChange: PropTypes.func.isRequired,
+     handlePerRowsChange: PropTypes.func.isRequired,
+     isFetching: PropTypes.bool,
+     status: PropTypes.string,
+     infoDescription: PropTypes.string,
+ };
+ 
+ BillInboxTable.defaultProps = {
+     isFetching: false,
+     status: "",
+     infoDescription: "",
+ };

70-73: Mismatched property in tooltip and displayed text

The title attribute uses row?.markby, whereas the displayed text uses row?.approvedBy or row?.markedBy. Ensure consistency between the tooltip and the displayed text.

Apply this diff:

- <div className="ellipsis-cell" title={row?.markby || t("NA")}>
+ <div className="ellipsis-cell" title={props.status === "APPROVED" ? row?.approvedBy || t("NA") : row?.markedBy || t("NA")}>

Also, verify that row?.approvedBy and row?.markedBy contain the correct data.


81-84: Table cell shows attendee count but tooltip references status

The tooltip uses t(row?.status || "0"), while the displayed text is derived from t(row?.noOfAttendees || "0"). Adjust to ensure consistency.

Apply this diff:

- <div className="ellipsis-cell" title={t(row?.status || "0")}>
+ <div className="ellipsis-cell" title={t(row?.noOfAttendees || "0")}>

history.push(`/${window.contextPath}/employee/payments/registers-inbox`);
}
} else {
if (selectedProject === null || selectedLevel == null) {
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 strict equality comparison.

Replace loose equality (==) with strict equality (===) for more predictable behavior.

Apply this diff:

-                if (selectedProject === null || selectedLevel == null) {
+                if (selectedProject === null || selectedLevel === null) {
📝 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 (selectedProject === null || selectedLevel == null) {
if (selectedProject === null || selectedLevel === null) {

const [showToast, setShowToast] = useState(null);
const [selectedLevel, setSelectedLevel] = useState(() => Digit.SessionStorage.get("selectedLevel") || null);
const boundaryHierarchyOrder = Digit.SessionStorage.get("boundaryHierarchyOrder");
const lowestLevelBoundaryType = Digit.SessionStorage.get("paymentConfig")?.lowestLevelBoundary || "DISTRICT";
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)

Consider making the default boundary type configurable.

Hardcoding "DISTRICT" as the default lowestLevelBoundaryType might not be flexible enough for different hierarchical structures.

Consider moving this to a configuration object:

-    const lowestLevelBoundaryType = Digit.SessionStorage.get("paymentConfig")?.lowestLevelBoundary || "DISTRICT";
+    const lowestLevelBoundaryType = Digit.SessionStorage.get("paymentConfig")?.lowestLevelBoundary || Digit.Configs.PaymentModule.DEFAULT_BOUNDARY_TYPE;

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +81 to +89
const handleAggregationLevelChange = (value) => {
if (value !== window.Digit.SessionStorage.get("selectedLevel")) {
window.Digit.SessionStorage.del("selectedBoundaryCode");
window.Digit.SessionStorage.del("boundary");
window.Digit.SessionStorage.del("selectedValues");
}
setSelectedLevel(value);
Digit.SessionStorage.set("selectedLevel", value);
};
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)

Add error handling for session storage operations.

Multiple session storage operations are performed without try-catch blocks, which could fail silently.

Consider wrapping the operations in a try-catch block:

 const handleAggregationLevelChange = (value) => {
+    try {
         if (value !== window.Digit.SessionStorage.get("selectedLevel")) {
             window.Digit.SessionStorage.del("selectedBoundaryCode");
             window.Digit.SessionStorage.del("boundary");
             window.Digit.SessionStorage.del("selectedValues");
         }
         setSelectedLevel(value);
         Digit.SessionStorage.set("selectedLevel", value);
+    } catch (error) {
+        console.error("Failed to update session storage:", error);
+        setShowToast({ key: "error", label: t("HCM_ERROR_UPDATING_SETTINGS"), transitionTime: 3000 });
+    }
 };

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (19)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (12)

36-36: ⚠️ Potential issue

Correct the typo in state variable name

There's a typo in the state variable name loding. It should be loading for clarity and consistency.

Apply this diff to fix the typo throughout the code:

- const [loding, setLoding] = useState(false);
+ const [loading, setLoading] = useState(false);

- setLoding(true);
+ setLoading(true);

- setLoding(false);
+ setLoading(false);

48-48: 🧹 Nitpick (assertive)

Simplify boolean expression

The ternary operator registerNumber ? true : false is unnecessary. You can directly use the truthiness of registerNumber.

Apply this diff:

- enabled: registerNumber ? true : false,
+ enabled: !!registerNumber,
🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


103-103: 🧹 Nitpick (assertive)

Simplify boolean expression

The ternary operator (AttendanceData ? true : false) can be simplified by directly using !!AttendanceData.

Apply this diff:

- enabled: (AttendanceData ? true : false),
+ enabled: !!AttendanceData,
🧰 Tools
🪛 Biome (1.9.4)

[error] 103-103: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


299-299: 🧹 Nitpick (assertive)

Simplify boolean expression

The condition individualIds.length > 0 ? true : false can be simplified by using !!individualIds.length.

Apply this diff:

- enabled: individualIds.length > 0 ? true : false,
+ enabled: !!individualIds.length,
🧰 Tools
🪛 Biome (1.9.4)

[error] 299-299: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


324-326: 🧹 Nitpick (assertive)

Simplify boolean expression

The ternary operator in the enabled property is unnecessary. Use direct truthiness evaluation.

Apply this diff:

- enabled: AttendanceData?.attendanceRegister[0]?.staff?.find(
-   (staff) => staff?.staffType?.includes("OWNER")
- )?.userId ? true : false,
+ enabled: !!AttendanceData?.attendanceRegister[0]?.staff?.find(
+   (staff) => staff?.staffType?.includes("OWNER")
+ )?.userId,
🧰 Tools
🪛 Biome (1.9.4)

[error] 324-326: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


497-507: ⚠️ Potential issue

Add unique key prop to elements in iterables

When rendering elements within an iterable, each element should have a unique key prop to help React identify which items have changed.

Apply this diff:

actionFields={[
+  disabledAction ? (
+    <Button
+      key="goBackButton"
       label={t(`HCM_AM_GO_BACK`)}
       title={t(`HCM_AM_GO_BACK`)}
       onClick={() => { /* ... */ }}
       type="button"
       style={{ minWidth: "14rem" }}
       variation="primary"
     />
   ) : editAttendance ? (
+    <Button
+      key="submitButton"
       label={t(`HCM_AM_SUBMIT_LABEL`)}
       title={t(`HCM_AM_SUBMIT_LABEL`)}
       onClick={() => { /* ... */ }}
       style={{ minWidth: "14rem" }}
       type="button"
       variation="primary"
       isDisabled={updateMutation.isLoading || updateDisabled || !isSubmitEnabled}
     />
   ) : (
+    <Button
+      key="actionsButton"
       className="custom-class"
       iconFill=""
       label={t(`HCM_AM_ACTIONS`)}
       menuStyles={{ bottom: "40px" }}
       onOptionSelect={(value) => { /* ... */ }}
       options={[ /* ... */ ]}
       optionsKey="name"
       size=""
       style={{ minWidth: "14rem" }}
       title=""
       type="actionButton"
     />
   ),
]}
🧰 Tools
🪛 Biome (1.9.4)

[error] 497-507: 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)


233-238: 🧹 Nitpick (assertive)

Avoid using setTimeout for navigation after showing toast

Using setTimeout for delayed navigation can lead to unpredictable behavior. It's better to use the onClose callback of the toast to ensure reliable navigation after the toast is dismissed.

Apply this diff:

onSuccess: (data) => {
- setShowToast({ key: "success", label: t("HCM_AM_ATTENDANCE_UPDATED_SUCCESSFULLY"), transitionTime: 3000 });
- // Delay the navigation for 2 seconds
- setTimeout(() => {
-   setUpdateDisabled(false);
-   history.push(`/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`);
- }, 2000);
+ setShowToast({
+   key: "success",
+   label: t("HCM_AM_ATTENDANCE_UPDATED_SUCCESSFULLY"),
+   transitionTime: 3000,
+   onClose: () => {
+     setUpdateDisabled(false);
+     history.push(`/${window.contextPath}/employee/payments/view-attendance?registerNumber=${registerNumber}&boundaryCode=${boundaryCode}`);
+   },
+ });
},

203-205: ⚠️ Potential issue

Handle errors appropriately in catch block

Empty catch blocks can hide errors and make debugging difficult. Please add error handling or logging within the catch block to ensure any issues are surfaced during execution.

Apply this diff:

} catch (error) {
- /// will show estimate data only
+ console.error('Error approving muster roll:', error);
  /// will show estimate data only
}

245-247: ⚠️ Potential issue

Handle errors appropriately in catch block

Adding error handling in the catch block helps in debugging and ensures that errors are not silently ignored.

Apply this diff:

} catch (error) {
- /// will show estimate data only
+ console.error('Error updating muster roll:', error);
  /// will show estimate data only
}

17-17: ⚠️ Potential issue

Ensure safe access to location.state

Destructuring fromCampaignSupervisor from location.state || false may lead to errors if location.state is not an object. Provide a default empty object to prevent potential runtime errors.

Apply this diff:

- const { fromCampaignSupervisor } = location.state || false;
+ const { fromCampaignSupervisor } = location.state || {};

Alternatively, use optional chaining:

const fromCampaignSupervisor = location.state?.fromCampaignSupervisor || false;

335-356: ⚠️ Potential issue

Handle cases where matchingIndividual is undefined

In the getUserAttendanceSummary function, ensure that when matchingIndividual is undefined, the individualId is correctly assigned to avoid potential issues.

Apply this diff:

- return ["N/A", "Unknown", "N/A", "Unassigned", individualEntry?.modifiedTotalAttendance || individualEntry.actualTotalAttendance || 0];
+ const id = individualEntry.individualId || "N/A";
+ return [id, "Unknown", "N/A", "Unassigned", individualEntry?.modifiedTotalAttendance || individualEntry.actualTotalAttendance || 0];

362-363: ⚠️ Potential issue

Update dependencies in the useEffect hook

The comment /// need to update dependency suggests missing dependencies in the useEffect hook. Ensure all variables used inside the hook are included in the dependency array to prevent stale closures.

Apply this diff:

- }, [AllIndividualsData, data]); /// need to update dependency
+ }, [AllIndividualsData, data, t]);
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (6)

3-3: 🧹 Nitpick (assertive)

Remove unused import CheckBox

The CheckBox component imported from @egovernments/digit-ui-components is not used in this file. Removing it will clean up the code.

Apply this diff to remove the unused import:

- import { CheckBox, SubmitBar } from "@egovernments/digit-ui-components";
+ import { SubmitBar } from "@egovernments/digit-ui-components";

75-85: 🧹 Nitpick (assertive)

Enhance accessibility by adding keyboard event handlers

The <div> element with an onClick handler should support keyboard interactions for accessibility. Add onKeyPress and tabIndex={0} to enable keyboard navigation.

Apply this diff:

  <div
    onClick={handleClearFilter}
+   onKeyPress={(e) => { if (e.key === 'Enter') handleClearFilter(); }}
+   tabIndex={0}
    style={{
      cursor: "pointer",
      alignItems: "center",
      gap: ".75rem",
      marginBottom: "24px",
      display: "flex",
      flexDirection: "row",
      justifyContent: "space-between",
    }}
  >

Alternatively, consider using a <button> element for better semantic meaning.

🧰 Tools
🪛 Biome (1.9.4)

[error] 75-85: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


90-98: 🧹 Nitpick (assertive)

Improve accessibility of the clickable <span> element

The <span> element with an onClick handler should support keyboard interactions and have appropriate accessibility attributes. Consider changing it to a <button> or adding tabIndex and onKeyPress.

For example, change it to a <button>:

- <span onClick={() => { }} style={{ border: "1px solid #E0E0E0", padding: "6px", marginBottom: "10px" }}>
+ <button
+   onClick={() => { }}
+   style={{ border: "1px solid #E0E0E0", padding: "6px", marginBottom: "10px" }}
+   aria-label={t("Refresh")}
+ >

Or, if keeping as a <span>, add accessibility attributes:

  <span
+   tabIndex="0"
    onClick={() => { }}
+   onKeyPress={(e) => { if (e.key === 'Enter') /* handle action */ }}
    style={{ border: "1px solid #E0E0E0", padding: "6px", marginBottom: "10px" }}
  >
🧰 Tools
🪛 Biome (1.9.4)

[error] 90-90: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 91-91: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


54-54: 🧹 Nitpick (assertive)

Ensure consistent reset of boundary state

In handleClearFilter, setBoundary("") is used to reset the boundary state, while elsewhere setBoundary(null) is used. For consistency and to avoid potential issues, consider using null throughout.

Apply this diff to standardize the reset value:

    const handleClearFilter = () => {
        setResetFilters(true);
-       setBoundary(""); // Clear the boundary value
+       setBoundary(null); // Clear the boundary value
        setBoundaryKey((prevKey) => prevKey + 1); // Increment the key to re-render BoundaryComponent
        Digit.SessionStorage.set("boundary", null);
        Digit.SessionStorage.set("selectedBoundaryCode", null);
        resetBoundaryFilter();
    };

36-45: ⚠️ Potential issue

Add updateBoundaryFilters to the dependency array in useEffect

The useEffect uses updateBoundaryFilters but does not include it in the dependency array. This could lead to missed updates when updateBoundaryFilters changes. Include it to ensure the effect runs as expected.

Apply this diff:

  useEffect(() => {
    if (updateBoundaryFilters) {
      setResetFilters(true);
      setBoundary(null);
      Digit.SessionStorage.set("boundary", null);
      Digit.SessionStorage.set("selectedBoundaryCode", null);
    }
- }, [levelSelected]);
+ }, [levelSelected, updateBoundaryFilters]);

108-108: ⚠️ Potential issue

Fix the spelling of updateSeeeionStorage

The prop updateSeeeionStorage appears to be misspelled. Correcting it to updateSessionStorage will improve code readability and prevent potential bugs.

Apply this diff to fix the spelling:

  <BoundaryComponent
      key={boundaryKey}
      isRequired={isRequired}
      reset={resetFilters}
      makeReset={() => {
          setResetFilters(false);
      }}
      initialValue={Digit.SessionStorage.get("selectedValues")}
-     updateSeeeionStorage={(newSelectedValues) => {
+     updateSessionStorage={(newSelectedValues) => {
          Digit.SessionStorage.set("selectedValues", newSelectedValues);
      }}
      onChange={onBoundaryChange}
      selectedProject={selectedProject}
      lowestLevel={selectedLevel.code}
  >
health/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/payment.scss (1)

32-36: 🧹 Nitpick (assertive)

Use theme variables for colors instead of hardcoded hex values

The hardcoded border color #787878 can be replaced with a theme variable to maintain consistency with the design system.

Apply this diff:

.custom-inbox-table-row {
-   border-right: 2px solid #787878;
+   border-right: 2px solid theme(digitv2.lightTheme.border);
    width: 100%;
    text-align: start;
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0fdc821 and ed8615f.

📒 Files selected for processing (5)
  • health/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/payment.scss (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/index.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/index.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js

[error] 122-122: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 103-103: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 299-299: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 324-326: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 497-507: 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)


[error] 509-520: 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)


[error] 522-551: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js

[error] 75-85: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 90-90: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 91-91: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

🔇 Additional comments (10)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (3)

137-137: 🧹 Nitpick (assertive)

Add PropTypes for component props

Defining prop types enhances code maintainability and helps catch potential type-related issues early. Consider adding PropTypes definitions for BillBoundaryFilter.

Example:

+ import PropTypes from "prop-types";

  const BillBoundaryFilter = ({ isRequired, selectedProject, selectedLevel, onFilterChange, updateBoundaryFilters, resetBoundaryFilter }) => {
    // component code
  };

+ BillBoundaryFilter.propTypes = {
+   isRequired: PropTypes.bool,
+   selectedProject: PropTypes.object,
+   selectedLevel: PropTypes.object,
+   onFilterChange: PropTypes.func.isRequired,
+   updateBoundaryFilters: PropTypes.bool,
+   resetBoundaryFilter: PropTypes.func.isRequired,
+ };

Likely invalid or redundant comment.


10-10: ⚠️ Potential issue

Set boundaryType in onBoundaryChange

The boundaryType state is initialized but never updated. In handleApplyFilter, boundaryType is compared but may not have the correct value. Update boundaryType in onBoundaryChange when boundary changes.

Apply this diff to set boundaryType:

  const onBoundaryChange = (boundary) => {
      if (boundary) {
          setBoundary(boundary);
+         setBoundaryType(boundary.boundaryType);
          Digit.SessionStorage.set("boundary", boundary);
      } else {
          setBoundary(null);
+         setBoundaryType("");
          Digit.SessionStorage.set("boundary", null);
      }
  };

Likely invalid or redundant comment.


91-96: 🧹 Nitpick (assertive)

Add accessibility attributes to SVG

For accessibility purposes, SVG elements should have an alternative text via a <title> element or aria-label attribute. Include role="img" and provide descriptive text.

Apply this diff to add a <title> and role="img":

  <span onClick={() => { }} style={{ border: "1px solid #E0E0E0", padding: "6px", marginBottom: "10px" }}>
-   <svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+   <svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="refreshIconTitle">
+     <title id="refreshIconTitle">{t("Refresh Icon")}</title>
      <path
        d="M8 5V8L12 4L8 0V3C3.58 3 0 6.58 0 11C0 12.57 0.46 14.03 1.24 15.26L2.7 13.8C2.25 12.97 2 12.01 2 11C2 7.69 4.69 5 8 5ZM14.76 6.74L13.3 8.2C13.74 9.04 14 9.99 14 11C14 14.31 11.31 17 8 17V14L4 18L8 22V19C12.42 19 16 15.42 16 11C16 9.43 15.54 7.97 14.76 6.74Z"
        fill="#505A5F"
      />
    </svg>
  </span>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 91-91: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/css/src/pages/employee/payment.scss (3)

61-71: 🧹 Nitpick (assertive)

Consider responsive height values for better adaptability

Using fixed viewport heights like 80vh and 75vh may cause layout issues on different screen sizes. Consider using min-height, max-height, or percentage-based heights for responsiveness.

Example adjustment:

.custom-register-inbox-screen .custom-inbox-filter-section {
    width: 30%;
    display: flex;
    flex-direction: column; 
    gap: 24px;
-   height: 80vh;
+   min-height: 60vh;
+   max-height: 80vh;
}

.custom-register-inbox-screen .custom-inbox-inner-filter-section {
    width: 100%;
    display: flex;
    flex-direction: row;
-   height: 75vh;
+   min-height: 60vh;
+   max-height: 75vh;
    overflow-y: auto;
}

Likely invalid or redundant comment.


95-95: 🧹 Nitpick (assertive)

Fix typo in class name .card-overide

The class name .card-overide contains a spelling error. Correcting it to .card-override improves code clarity and maintainability.

Apply this diff:

.custom-inbox-outer-table-section .card-overide {
+ /* Corrected class name */
+ .card-override {
    max-width: 100%; 
    overflow: auto;
    margin: 0px;
    height: 75vh;
}

Likely invalid or redundant comment.


105-110: 🧹 Nitpick (assertive)

Improve code formatting and use theme variables

The styles are on a single line and use a hardcoded color. For better readability and consistency, expand the styles and use theme variables.

Apply this diff:

.on-icon-reset-proximity {
-   border: 1px solid #e0e0e0; padding: 6px; margin-bottom: 10px; cursor: pointer;
+   border: 1px solid theme(digitv2.lightTheme.border);
+   padding: 6px;
+   margin-bottom: 10px;
+   cursor: pointer;
}

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (2)

174-180: 🧹 Nitpick (assertive)

Use optional chaining for prop function calls.

Make the event handlers more defensive using optional chaining.

Apply these changes:

 const handlePageChange = (page, totalRows) => {
-    props?.handlePageChange(page, totalRows);
+    props.handlePageChange?.(page, totalRows);
 };

 const handlePerRowsChange = async (currentRowsPerPage, currentPage) => {
-    props?.handlePerRowsChange(currentRowsPerPage, currentPage);
+    props.handlePerRowsChange?.(currentRowsPerPage, currentPage);
 };

Likely invalid or redundant comment.


1-10: 🧹 Nitpick (assertive)

Improve props handling and remove unused state.

  1. Consider destructuring specific props instead of using the spread operator for better code clarity.
  2. The showToast state is declared but never used.

Apply these changes:

-const MyBillsTable = ({ ...props }) => {
+const MyBillsTable = ({ 
+    data,
+    handlePageChange,
+    handlePerRowsChange,
+    totalCount,
+    currentPage,
+    rowsPerPage 
+}) => {
     const { t } = useTranslation();
-    const [showToast, setShowToast] = useState(null);
     const project = Digit?.SessionStorage.get("staffProjects");

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/index.js (2)

48-94: 🛠️ Refactor suggestion

Add error handling and improve file download implementation.

The file download implementation needs several improvements:

  1. Add error handling
  2. Use a more descriptive default filename
  3. Add loading state management
  4. Add validation for fileStoreId

Apply these changes:

-export const downloadFileWithName = ({ fileStoreId = null, customName = null, type = "excel" }) => {
+export const downloadFileWithName = ({ fileStoreId = null, customName = null, type = "excel", onLoadingChange = null }) => {
+  if (!fileStoreId) {
+    console.error('FileStoreId is required');
+    return;
+  }
+  if (onLoadingChange) onLoadingChange(true);

   // ... existing code ...

   axios
     .then((res) => {
       downloadFile(
         new Blob([res.data], { type: mimeType }),
-        customName || "download",
+        customName || `${type}_export_${new Date().toISOString().split('T')[0]}`,
         extension
       );
+      if (onLoadingChange) onLoadingChange(false);
     })
+    .catch((error) => {
+      console.error('Error downloading file:', error);
+      Digit.Utils.notificationHandler(
+        { message: "ERROR_DOWNLOADING_FILE" },
+        "error"
+      );
+      if (onLoadingChange) onLoadingChange(false);
+    });

Likely invalid or redundant comment.


8-45: 🧹 Nitpick (assertive)

Improve code quality and remove commented code.

  1. Use .forEach() instead of .map() for side effects.
  2. Remove commented code if not needed.

Apply these changes:

-Object.keys(CustomisedHooks).map((ele) => {
+Object.keys(CustomisedHooks).forEach((ele) => {
   if (ele === "Hooks") {
-    Object.keys(CustomisedHooks[ele]).map((hook) => {
+    Object.keys(CustomisedHooks[ele]).forEach((hook) => {
-      Object.keys(CustomisedHooks[ele][hook]).map((method) => {
+      Object.keys(CustomisedHooks[ele][hook]).forEach((method) => {
         setupHooks(hook, method, CustomisedHooks[ele][hook][method]);
       });
     });
   } else if (ele === "Utils") {
-    Object.keys(CustomisedHooks[ele]).map((hook) => {
+    Object.keys(CustomisedHooks[ele]).forEach((hook) => {
-      Object.keys(CustomisedHooks[ele][hook]).map((method) => {
+      Object.keys(CustomisedHooks[ele][hook]).forEach((method) => {
         setupHooks(hook, method, CustomisedHooks[ele][hook][method], false);
       });
     });
   } else {
-    Object.keys(CustomisedHooks[ele]).map((method) => {
+    Object.keys(CustomisedHooks[ele]).forEach((method) => {
       setupLibraries(ele, method, CustomisedHooks[ele][method]);
     });
   }
 });

-// setupLibraries("Utils", "parsingUtils", { ...window?.Digit?.Utils?.parsingUtils, ...parsingUtils });

Likely invalid or redundant comment.

.bill-container-margin-bottom {
margin-bottom: 2.5rem;
}

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 excessive empty lines at the end of the file

The file ends with multiple empty lines. Maintaining a single empty line at the end of the file conforms to standard coding practices.

Comment on lines +13 to +172
},
style: {
justifyContent: "flex-end",
},
},
{
name: (
<div style={{ borderRight: "2px solid #787878", width: "100%", textAlign: "start" }}>
{t("HCM_AM_BOUNDARY_NAME")}
</div>
),
selector: (row) => {
return (
<div className="ellipsis-cell" >
{t(row.localityCode) || t("NA")}
</div>
);
},
},

{
name: (
<div style={{ borderRight: "2px solid #787878", width: "100%", textAlign: "start" }}>
{t("HCM_AM_PROJECT_NAME")}
</div>
),
selector: (row) => {
return (
<div className="ellipsis-cell" title={t(project?.[0]?.name || "0")}>
{t(project?.[0]?.name || `NA`)}
</div>
);
},
},
{
name: t("HCM_AM_BILL_ACTIONS"),
selector: (row, index) => {
const reportDetails = row?.additionalDetails?.reportDetails;
const billId = row?.billNumber;
const isLastRow = index === props.totalCount - 1;

return (
reportDetails?.status === "COMPLETED" ? <Button
className="custom-class"
iconFill=""
icon="FileDownload"
isSuffix
label={t(`HCM_AM_DOWNLOAD_BILLS`)}
title={t(`HCM_AM_DOWNLOAD_BILLS`)}
showBottom={isLastRow ? false : true}
onOptionSelect={(value) => {
if (value.code === "HCM_AM_PDF") {
if (reportDetails?.pdfReportId) {
downloadFileWithName({ fileStoreId: reportDetails?.pdfReportId, customName: `${billId}`, type: "pdf" })
} else {
setShowToast({ key: "error", label: t(`HCM_AM_PDF_GENERATION_FAILED`), transitionTime: 3000 });
}
} else if (value.code === "HCM_AM_EXCEL") {
if (reportDetails?.excelReportId) {
downloadFileWithName({ fileStoreId: reportDetails?.excelReportId, customName: `${billId}`, type: "excel" });
} else {
setShowToast({ key: "error", label: t(`HCM_AM_EXCEL_GENERATION_FAILED`), transitionTime: 3000 });
}

}
}}
options={[
{
code: "HCM_AM_EXCEL",
name: t(`HCM_AM_EXCEL`),
},
{
code: "HCM_AM_PDF",
name: t(`HCM_AM_PDF`),
},
]}
optionsKey="name"
size=""
style={{ minWidth: "14rem" }}
type="actionButton"
variation="secondary"
/> :
<div>
<Tag
{...(reportDetails?.status !== "FAILED" && { icon: "Info" })}
label={reportDetails?.status === "FAILED" ? t("HCM_AM_FAILED_REPORT_GENERATION") : t("HCM_AM_PROGRESS_REPORT_GENERATION")}
labelStyle={{}}
showIcon={true}
style={{}}
{...(reportDetails?.status === "FAILED" && { type: "error" })}
/>
</div>
);
},
width: "300px",
},
];

return baseColumns;
}, [props.data, t]);
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)

Move inline styles to CSS classes and fix useMemo dependencies.

  1. Inline styles make the code harder to maintain. Consider moving them to CSS classes.
  2. The project variable is used in the columns but missing from the useMemo dependencies array.

Apply these changes:

  1. Move styles to CSS:
-<div style={{ borderRight: "2px solid #787878", width: "100%", textAlign: "start" }}>
+<div className="column-header">

Add to your CSS:

.column-header {
  border-right: 2px solid #787878;
  width: 100%;
  text-align: start;
}
  1. Fix useMemo dependencies:
-}, [props.data, t]);
+}, [props.data, t, project]);
🧰 Tools
🪛 Biome (1.9.4)

[error] 122-122: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

Comment on lines +201 to +208
<Toast
style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
// error={showToast.key === "error"}
transitionTime={showToast.transitionTime}
onClose={() => setShowToast(null)}
/>
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)

Clean up Toast component implementation.

  1. Move inline style to CSS.
  2. Remove commented code.

Apply these changes:

 <Toast
-    style={{ zIndex: 10001 }}
+    className="toast-overlay"
     label={showToast.label}
     type={showToast.key}
-    // error={showToast.key === "error"}
     transitionTime={showToast.transitionTime}
     onClose={() => setShowToast(null)}
 />

Add to your CSS:

.toast-overlay {
  z-index: 10001;
}

Comment on lines +115 to +154
reportDetails?.status === "COMPLETED" ? <Button
className="custom-class"
iconFill=""
icon="FileDownload"
isSuffix
label={t(`HCM_AM_DOWNLOAD_BILLS`)}
title={t(`HCM_AM_DOWNLOAD_BILLS`)}
showBottom={isLastRow ? false : true}
onOptionSelect={(value) => {
if (value.code === "HCM_AM_PDF") {
if (reportDetails?.pdfReportId) {
downloadFileWithName({ fileStoreId: reportDetails?.pdfReportId, customName: `${billId}`, type: "pdf" })
} else {
setShowToast({ key: "error", label: t(`HCM_AM_PDF_GENERATION_FAILED`), transitionTime: 3000 });
}
} else if (value.code === "HCM_AM_EXCEL") {
if (reportDetails?.excelReportId) {
downloadFileWithName({ fileStoreId: reportDetails?.excelReportId, customName: `${billId}`, type: "excel" });
} else {
setShowToast({ key: "error", label: t(`HCM_AM_EXCEL_GENERATION_FAILED`), transitionTime: 3000 });
}

}
}}
options={[
{
code: "HCM_AM_EXCEL",
name: t(`HCM_AM_EXCEL`),
},
{
code: "HCM_AM_PDF",
name: t(`HCM_AM_PDF`),
},
]}
optionsKey="name"
size=""
style={{ minWidth: "14rem" }}
type="actionButton"
variation="secondary"
/> :
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)

Simplify boolean expression and improve download action handling.

  1. The ternary expression for showBottom can be simplified.
  2. The download action handler should be extracted into a separate function for better maintainability.

Apply these changes:

  1. Simplify boolean expression:
-showBottom={isLastRow ? false : true}
+showBottom={!isLastRow}
  1. Extract download handler:
+const handleDownload = (value, reportDetails, billId) => {
+    const downloadTypes = {
+        'HCM_AM_PDF': {
+            reportId: reportDetails?.pdfReportId,
+            errorKey: 'HCM_AM_PDF_GENERATION_FAILED'
+        },
+        'HCM_AM_EXCEL': {
+            reportId: reportDetails?.excelReportId,
+            errorKey: 'HCM_AM_EXCEL_GENERATION_FAILED'
+        }
+    };
+
+    const downloadType = downloadTypes[value.code];
+    if (!downloadType) return;
+
+    if (downloadType.reportId) {
+        downloadFileWithName({ 
+            fileStoreId: downloadType.reportId, 
+            customName: billId,
+            type: value.code === 'HCM_AM_PDF' ? 'pdf' : 'excel'
+        });
+    } else {
+        setShowToast({ 
+            key: "error", 
+            label: t(downloadType.errorKey), 
+            transitionTime: 3000 
+        });
+    }
+};

-onOptionSelect={(value) => {
-    if (value.code === "HCM_AM_PDF") {
-        if (reportDetails?.pdfReportId) {
-            downloadFileWithName({ fileStoreId: reportDetails?.pdfReportId, customName: `${billId}`, type: "pdf" })
-        } else {
-            setShowToast({ key: "error", label: t(`HCM_AM_PDF_GENERATION_FAILED`), transitionTime: 3000 });
-        }
-    } else if (value.code === "HCM_AM_EXCEL") {
-        if (reportDetails?.excelReportId) {
-            downloadFileWithName({ fileStoreId: reportDetails?.excelReportId, customName: `${billId}`, type: "excel" });
-        } else {
-            setShowToast({ key: "error", label: t(`HCM_AM_EXCEL_GENERATION_FAILED`), transitionTime: 3000 });
-        }
-    }
-}}
+onOptionSelect={(value) => handleDownload(value, reportDetails, billId)}
📝 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
reportDetails?.status === "COMPLETED" ? <Button
className="custom-class"
iconFill=""
icon="FileDownload"
isSuffix
label={t(`HCM_AM_DOWNLOAD_BILLS`)}
title={t(`HCM_AM_DOWNLOAD_BILLS`)}
showBottom={isLastRow ? false : true}
onOptionSelect={(value) => {
if (value.code === "HCM_AM_PDF") {
if (reportDetails?.pdfReportId) {
downloadFileWithName({ fileStoreId: reportDetails?.pdfReportId, customName: `${billId}`, type: "pdf" })
} else {
setShowToast({ key: "error", label: t(`HCM_AM_PDF_GENERATION_FAILED`), transitionTime: 3000 });
}
} else if (value.code === "HCM_AM_EXCEL") {
if (reportDetails?.excelReportId) {
downloadFileWithName({ fileStoreId: reportDetails?.excelReportId, customName: `${billId}`, type: "excel" });
} else {
setShowToast({ key: "error", label: t(`HCM_AM_EXCEL_GENERATION_FAILED`), transitionTime: 3000 });
}
}
}}
options={[
{
code: "HCM_AM_EXCEL",
name: t(`HCM_AM_EXCEL`),
},
{
code: "HCM_AM_PDF",
name: t(`HCM_AM_PDF`),
},
]}
optionsKey="name"
size=""
style={{ minWidth: "14rem" }}
type="actionButton"
variation="secondary"
/> :
reportDetails?.status === "COMPLETED" ? <Button
className="custom-class"
iconFill=""
icon="FileDownload"
isSuffix
label={t(`HCM_AM_DOWNLOAD_BILLS`)}
title={t(`HCM_AM_DOWNLOAD_BILLS`)}
showBottom={!isLastRow}
onOptionSelect={(value) => handleDownload(value, reportDetails, billId)}
options={[
{
code: "HCM_AM_EXCEL",
name: t(`HCM_AM_EXCEL`),
},
{
code: "HCM_AM_PDF",
name: t(`HCM_AM_PDF`),
},
]}
optionsKey="name"
size=""
style={{ minWidth: "14rem" }}
type="actionButton"
variation="secondary"
/> :
🧰 Tools
🪛 Biome (1.9.4)

[error] 122-122: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

Comment on lines +97 to +117
export function formatTimestampToDate(timestamp) {
// Check if the timestamp is valid
if (!timestamp || typeof timestamp !== "number") {
return "Invalid timestamp";
}

// Convert timestamp to a JavaScript Date object
const date = new Date(timestamp);

// Define an array of month abbreviations
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

// Extract day, month, and year from the date
const day = date.getDate().toString().padStart(2, "0");
const month = monthNames[date.getMonth()]; // getMonth() returns 0-11
const year = date.getFullYear();

// Return the formatted date string
return `${day} ${month} ${year}`;
}
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)

Use Intl.DateTimeFormat for better locale support.

The current date formatting implementation could be improved using the native Intl.DateTimeFormat API for better internationalization support.

Apply these changes:

 export function formatTimestampToDate(timestamp) {
   if (!timestamp || typeof timestamp !== "number") {
     return "Invalid timestamp";
   }
-  const date = new Date(timestamp);
-  const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
-    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
-  const day = date.getDate().toString().padStart(2, "0");
-  const month = monthNames[date.getMonth()];
-  const year = date.getFullYear();
-  return `${day} ${month} ${year}`;
+  return new Intl.DateTimeFormat('en-IN', {
+    day: '2-digit',
+    month: 'short',
+    year: 'numeric'
+  }).format(new Date(timestamp));
 }
📝 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
export function formatTimestampToDate(timestamp) {
// Check if the timestamp is valid
if (!timestamp || typeof timestamp !== "number") {
return "Invalid timestamp";
}
// Convert timestamp to a JavaScript Date object
const date = new Date(timestamp);
// Define an array of month abbreviations
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
// Extract day, month, and year from the date
const day = date.getDate().toString().padStart(2, "0");
const month = monthNames[date.getMonth()]; // getMonth() returns 0-11
const year = date.getFullYear();
// Return the formatted date string
return `${day} ${month} ${year}`;
}
export function formatTimestampToDate(timestamp) {
// Check if the timestamp is valid
if (!timestamp || typeof timestamp !== "number") {
return "Invalid timestamp";
}
return new Intl.DateTimeFormat('en-IN', {
day: '2-digit',
month: 'short',
year: 'numeric'
}).format(new Date(timestamp));
}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

♻️ Duplicate comments (1)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/constants.js (1)

1-4: 🧹 Nitpick (assertive)

Use consistent naming for status enum values.

The key name and the string value differ in naming style.

Apply this diff for consistency:

 export const StatusEnum = Object.freeze({
-    PENDING_FOR_APPROVAL: "PENDINGFORAPPROVAL",
+    PENDING_FOR_APPROVAL: "PENDING_FOR_APPROVAL",
     APPROVED: "APPROVED",
-    });
+});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed8615f and 488aff3.

📒 Files selected for processing (9)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/constants.js (1 hunks)
👮 Files not reviewed due to content moderation or server errors (2)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js
🧰 Additional context used
📓 Path-based instructions (9)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/constants.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js

[error] 44-44: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js

[error] 106-106: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 113-113: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 103-103: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 299-299: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 324-326: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 505-515: 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)


[error] 517-528: 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)


[error] 530-559: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 208-208: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 220-230: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 52-52: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 55-55: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 72-72: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 233-240: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 296-306: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 331-345: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/MyBillsTable.js

[error] 123-123: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

🔇 Additional comments (33)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/utils/constants.js (2)

21-21: 🧹 Nitpick (assertive)

Fix indentation and approve values.

The constant definition has incorrect indentation, but the values are well-chosen and consistent with defaultRowsPerPage.

Apply this diff to fix the indentation:

-    export const defaultPaginationValues = [10, 20, 30, 40, 50];
+export const defaultPaginationValues = [10, 20, 30, 40, 50];

Likely invalid or redundant comment.


14-14: 🧹 Nitpick (assertive)

Fix formatting issues.

The constant definition has incorrect indentation and inconsistent spacing around the assignment operator.

Apply this diff to fix the formatting:

-    export const lowerBoundaryDefaultSet= "DISTRICT";
+export const lowerBoundaryDefaultSet = "DISTRICT";

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/attendanceManagementTable.js (5)

14-14: Initialize showToast with an Empty Object

Initializing showToast as null may lead to conditional checks failing. Consider initializing it with an empty object {} for consistency.

Apply this diff:

- const [showToast, setShowToast] = useState(null);
+ const [showToast, setShowToast] = useState({});

130-132: Ensure Valid Number Comparison in Attendance Validation

Before comparing updatedValue with props.duration, verify that both are valid numbers to avoid unintended results, especially if updatedValue is NaN.


80-95: ⚠️ Potential issue

Add Unique key Props to Elements in Iterables

When rendering elements inside a list or array, such as within the DataTable, each element should have a unique key prop to help React identify which items have changed.

Apply this diff:

return props.editAttendance ? (
-  <div>
+  <div key={`edit-${row?.[2]}`}>
    <TextInput
+     key={`textinput-${row?.[2]}`}
      type="numeric"
      value={row?.[4]}
      onChange={(e) => {
        handleDaysWorkedChange(row?.[2], e);
      }}
      populators={{ disableTextField: false }}
      style={{ width: "100%" }}
    />
  </div>
) : (

Likely invalid or redundant comment.


105-107: ⚠️ Potential issue

Convert updatedValue to Number Before Validation

Ensure that updatedValue is converted to a number before performing numeric comparisons to prevent logical errors.

Apply this diff:

if (updatedValue?.target) {
  updatedValue = updatedValue.target.value;
}
+ updatedValue = Number(updatedValue);

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 106-106: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


103-145: 🧹 Nitpick (assertive)

Avoid Reassigning Function Parameters

Reassigning parameters within a function can cause confusion and unexpected behavior. In handleDaysWorkedChange, create a new variable instead of reassigning value.

Apply this diff:

const handleDaysWorkedChange = (workerId, value) => {
+ let updatedValue = value;
  if (updatedValue?.target) {
-   value = value?.target?.value;
+   updatedValue = updatedValue.target.value;
  }
  // Remove leading zeros from the value
- value = value === 0 ? value : String(value).replace(/^0+/, "");
+ updatedValue = updatedValue === 0 ? updatedValue : String(updatedValue).replace(/^0+/, "");
  // Continue using 'updatedValue' in place of 'value' in the rest of the function

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 106-106: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 113-113: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js (9)

36-36: Fix Typo in State Variable loding

The state variable loding appears to be a typo. It should be loading to reflect its purpose clearly.

Apply this diff:

- const [loding, setLoding] = useState(false);
+ const [loading, setLoading] = useState(false);

Also, update all occurrences of loding and setLoding throughout the file.


48-48: Simplify Boolean Expression in enabled Property

You can simplify the enabled property by directly using the truthiness of registerNumber.

Apply this diff:

- enabled: registerNumber ? true : false,
+ enabled: !!registerNumber,
🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


299-299: Simplify Length Check for individualIds

You can directly use the result of the length check without the ternary operator.

Apply this diff:

- enabled: individualIds.length > 0 ? true : false,
+ enabled: individualIds.length > 0,
🧰 Tools
🪛 Biome (1.9.4)

[error] 299-299: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


324-326: Simplify Boolean Expression in enabled Configuration

Simplify the condition by directly evaluating the truthiness.

Apply this diff:

enabled: AttendanceData?.attendanceRegister[0]?.staff?.find(
  (staff) => staff?.staffType?.includes("OWNER")
)?.userId ? true : false,

Simplifies to:

enabled: !!AttendanceData?.attendanceRegister[0]?.staff?.find(
  (staff) => staff?.staffType?.includes("OWNER")
)?.userId,
🧰 Tools
🪛 Biome (1.9.4)

[error] 324-326: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


505-560: Add Unique key Props to Elements Within Arrays

When rendering elements conditionally inside an array (e.g., within actionFields), each top-level element should have a unique key prop.

Apply this diff:

<ActionBar
  actionFields={[
-   disabledAction ? (
+   disabledAction ? (
+     <Button
+       key="goBackButton"
        label={t(`HCM_AM_GO_BACK`)}
        ...
      />
    ) : editAttendance ? (
+     <Button
+       key="submitButton"
        label={t(`HCM_AM_SUBMIT_LABEL`)}
        ...
      />
    ) : (
+     <Button
+       key="actionsButton"
        label={t(`HCM_AM_ACTIONS`)}
        ...
      />
    ),
  ]}
  ...
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 505-515: 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)


[error] 517-528: 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)


[error] 530-559: 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)


203-205: Add Error Handling in Empty catch Block

An empty catch block can suppress errors and hinder debugging. Add error handling or logging to ensure issues are surfaced.

Apply this diff:

} catch (error) {
- /// will show estimate data only
+ console.error('Error approving muster roll:', error);
  /// will show estimate data only
}

245-247: Add Error Handling in Empty catch Block

Similarly, in the triggerMusterRollUpdate function, ensure errors are not silently ignored.

Apply this diff:

} catch (error) {
- /// will show estimate data only
+ console.error('Error updating muster roll:', error);
  /// will show estimate data only
}

103-103: 🧹 Nitpick (assertive)

Simplify Boolean Check for AttendanceData

Similarly, simplify the enabled property by using the truthiness of AttendanceData.

Apply this diff:

- enabled: (AttendanceData ? true : false),
+ enabled: !!AttendanceData,

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 103-103: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


370-371: Address the Pending Dependency Update in useEffect

The comment indicates a need to update dependencies in the useEffect hook. Ensure all variables used within the hook are included to prevent stale closures.

Review the dependencies and include any missing ones. For instance, if t is used inside the hook, it should be included:

}, [AllIndividualsData, data, t]); // Updated dependency array
✅ Verification successful

Dependency Update Required: Review Comment is Accurate

The review comment is correct. The useEffect hook uses the t function within getUserAttendanceSummary, but it's missing from the dependency array. The suggested fix to include t in the dependencies is the right approach.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find the useEffect implementation
ast-grep --pattern 'useEffect(() => {
  $$$
}, [$$$]);'  health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

# Get more context around the component
rg "setAttendanceSummary|getUserAttendanceSummary" -A 5 -B 5 health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/ViewAttendance.js

Length of output: 13059

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (3)

29-37: 🧹 Nitpick (assertive)

Simplify handler functions.

The handler functions are simple pass-through functions that can be removed by directly using the props.

Apply this diff to simplify the code:

-  const handlePaginationChange = (page) => {
-    customHandlePaginationChange(page);
-  };
-  const handleRowsPerPageChange = (newPerPage, page) => {
-    customHandleRowsPerPageChange(newPerPage, page);
-  };

Then update the DataTable component:

   <DataTable
     ...
-    onChangePage={handlePaginationChange}
-    onChangeRowsPerPage={handleRowsPerPageChange}
+    onChangePage={customHandlePaginationChange}
+    onChangeRowsPerPage={customHandleRowsPerPageChange}
     ...
   />

Likely invalid or redundant comment.


111-121: 🧹 Nitpick (assertive)

Extract tab configuration to constants.

The tab configuration contains hardcoded values that should be extracted to constants.

Apply this diff to improve maintainability:

+const TAB_CONFIG = {
+  PENDING: {
+    code: "PENDINGFORAPPROVAL",
+    translationKey: "HCM_AM_PENDING_FOR_APPROVAL"
+  },
+  APPROVED: {
+    code: "APPROVED",
+    translationKey: "HCM_AM_APPROVED"
+  }
+};

+const getTabItems = (statusCount) => [
+  {
+    code: TAB_CONFIG.PENDING.code,
+    name: `${t(TAB_CONFIG.PENDING.translationKey)} (${statusCount?.PENDINGFORAPPROVAL})`,
+  },
+  {
+    code: TAB_CONFIG.APPROVED.code,
+    name: `${t(TAB_CONFIG.APPROVED.translationKey)} (${statusCount?.APPROVED})`,
+  },
+];

 <Tab
   ...
-  configNavItems={[
-    {
-      code: "PENDINGFORAPPROVAL",
-      name: `${t("HCM_AM_PENDING_FOR_APPROVAL")} (${statusCount?.PENDINGFORAPPROVAL})`,
-    },
-    {
-      code: "APPROVED",
-      name: `${t("HCM_AM_APPROVED")} (${statusCount?.APPROVED})`,
-    },
-  ]}
+  configNavItems={getTabItems(statusCount)}
   ...
 />

Likely invalid or redundant comment.


40-95: 🛠️ Refactor suggestion

Refactor column definitions and use strict equality.

The column definitions contain repeated patterns and use loose equality operators.

Apply this diff to improve the code:

+const createCell = (content, title) => (
+  <div style={{ fontSize: "14px" }} className="ellipsis-cell" title={title}>
+    {content}
+  </div>
+);

 const columns = [
   {
     name: <div className="custom-inbox-table-row">{t("HCM_AM_ATTENDANCE_ID")}</div>,
     selector: (row) => (
       <span className="link" style={{ fontSize: "14px" }}>
         <Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${row?.id}&boundaryCode=${row?.boundary}`}>
           {String(row?.id ? row?.id : t("ES_COMMON_NA"))}
         </Link>
       </span>
     ),
   },
   {
     name: (
       <div className="custom-inbox-table-row">
-        {activeLink?.code == "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY")}
+        {activeLink?.code === "PENDINGFORAPPROVAL" ? t("HCM_AM_ATTENDANCE_MARKED_BY") : t("HCM_AM_ATTENDANCE_APPROVED_BY")}
       </div>
     ),
     selector: (row) => {
-      return (
-        <div
-          style={{ fontSize: "14px" }}
-          className="ellipsis-cell"
-          title={activeLink?.code == "PENDINGFORAPPROVAL" ? row?.markby : row?.approvedBy || t("NA")}
-        >
-          {activeLink?.code == "PENDINGFORAPPROVAL" ? row?.markby : row?.approvedBy || t("NA")}
-        </div>
-      );
+      const content = activeLink?.code === "PENDINGFORAPPROVAL" ? row?.markby : row?.approvedBy || t("NA");
+      return createCell(content, content);
     },
   },
   // ... similar refactoring for other columns
 ];

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (10)

1-1: Remove unused and invalid imports

The imports useReducer, useMemo, and use are not used in this file. Additionally, use is not a valid React hook and may have been included by mistake. Please remove these to clean up the code.


5-5: Define 'location' or use 'useLocation' hook

The variable location is used but not defined in this scope. If you intend to access the browser's location or the route's state, consider importing useLocation from react-router-dom and using it to retrieve the location object.


55-55: Simplify the boolean expression

The ternary operator is unnecessary here. You can directly assign the boolean result of the condition.

🧰 Tools
🪛 Biome (1.9.4)

[error] 55-55: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


72-72: Simplify the boolean expression

You can simplify the code by directly assigning the boolean expression without using a ternary operator.

🧰 Tools
🪛 Biome (1.9.4)

[error] 72-72: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


215-223: Use a self-closing tag for <CustomInboxSearchLinks>

JSX elements without child content should be self-closing.

Apply this diff:

- <CustomInboxSearchLinks
-     headerText={"HCM_AM_BILL_INBOX"}
-     links={[
-         {
-             url: "/employee/payments/my-bills",
-             text: "HCM_AM_MY_BILLS",
-         },
-     ]}
- ></CustomInboxSearchLinks>
+ <CustomInboxSearchLinks
+     headerText={"HCM_AM_BILL_INBOX"}
+     links={[
+         {
+             url: "/employee/payments/my-bills",
+             text: "HCM_AM_MY_BILLS",
+         },
+     ]}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 215-223: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


233-240: Use a self-closing tag for <BillBoundaryFilter>

JSX elements without child content should be self-closing.

Apply this diff:

- <BillBoundaryFilter
-     isRequired={ScreenTypeEnum.BILL}
-     selectedProject={selectedProject}
-     selectedLevel={selectedLevel}
-     onFilterChange={handleFilterUpdate}
-     updateBoundaryFilters={updateFilters}
-     resetBoundaryFilter={resetBoundaryFilter}
- ></BillBoundaryFilter>
+ <BillBoundaryFilter
+     isRequired={ScreenTypeEnum.BILL}
+     selectedProject={selectedProject}
+     selectedLevel={selectedLevel}
+     onFilterChange={handleFilterUpdate}
+     updateBoundaryFilters={updateFilters}
+     resetBoundaryFilter={resetBoundaryFilter}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 233-240: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


296-306: Use a self-closing tag for <BillInboxTable>

JSX elements without child content should be self-closing.

Apply this diff:

- <BillInboxTable
-     isFetching={isFetching}
-     tableData={tableData}
-     currentPage={currentPage}
-     rowsPerPage={rowsPerPage}
-     handlePageChange={handlePageChange}
-     handlePerRowsChange={handlePerRowsChange}
-     totalCount={totalCount}
-     status={activeLink.code}
-     infoDescription={infoDescription}
- ></BillInboxTable>
+ <BillInboxTable
+     isFetching={isFetching}
+     tableData={tableData}
+     currentPage={currentPage}
+     rowsPerPage={rowsPerPage}
+     handlePageChange={handlePageChange}
+     handlePerRowsChange={handlePerRowsChange}
+     totalCount={totalCount}
+     status={activeLink.code}
+     infoDescription={infoDescription}
+ />
🧰 Tools
🪛 Biome (1.9.4)

[error] 296-306: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


331-345: Add a key prop to the Button component in the actionFields array

When rendering elements in an array, React recommends providing a unique key prop to each element to help identify which items have changed, are added, or are removed.

Apply this diff:

 actionFields={[
-    <Button
+    <Button
+        key="generate-bill-btn"
         icon="CheckCircle"
         label={t(`HCM_AM_GENERATE_BILL_LABEL`)}
         onClick={() => {
             setOpenAlertPopUp(true);
             // triggerGenerateBill();
         }}
         style={{
             minWidth: "14rem",
             opacity: billGenerationStatus != null ? 0.5 : 1,
         }}
         type="button"
         variation="primary"
         isDisabled={generateBillMutation.isLoading}
     />,
 ]}
🧰 Tools
🪛 Biome (1.9.4)

[error] 331-345: 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)


52-52: 🧹 Nitpick (assertive)

Simplify the boolean expression

You can simplify the code by directly assigning the result without using a ternary operator.

Apply this diff to simplify:

- isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
+ isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType,

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 52-52: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


165-165: ⚠️ Potential issue

Correct the offset calculation in handlePerRowsChange

The offset should be calculated using the updated currentRowsPerPage to ensure correct pagination.

Apply this diff to fix the calculation:

 setLimitAndOffset({ limit: currentRowsPerPage, offset: (currentPage - 1) * rowsPerPage });
+ setLimitAndOffset({ limit: currentRowsPerPage, offset: (currentPage - 1) * currentRowsPerPage });

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (4)

6-6: Remove unused import useQueryClient

The useQueryClient function imported from react-query is not used in this file. Removing it will clean up the code.


18-24: Simplify event handlers by passing prop functions directly

The handlers are just wrapping the prop functions without adding any logic. They can be simplified by passing the prop functions directly to the DataTable component.

Apply this diff:

- const handlePageChange = (page, totalRows) => {
-     props?.handlePageChange(page, totalRows);
- };
- 
- const handlePerRowsChange = async (currentRowsPerPage, currentPage) => {
-     props?.handlePerRowsChange(currentRowsPerPage, currentPage);
- };

And update the DataTable component:

  <DataTable
-     onChangePage={handlePageChange}
-     onChangeRowsPerPage={handlePerRowsChange}
+     onChangePage={props.handlePageChange}
+     onChangeRowsPerPage={props.handlePerRowsChange}
  />

70-75: ⚠️ Potential issue

Correct mismatched properties in tooltips

The title attribute uses row?.markby, whereas the displayed text uses row?.markedBy. Ensure consistency by using the same property.

Apply this diff:

 return (
     <div className="ellipsis-cell" title={row?.markby || t("NA")}>
-        {props.status === "APPROVED" ? row?.approvedBy : row?.markedBy || t("NA")}
+        {props.status === "APPROVED" ? row?.approvedBy : row?.markedBy || t("NA")}
     </div>
 );

Likely invalid or redundant comment.


82-85: ⚠️ Potential issue

Ensure tooltips reflect the displayed data

The tooltip uses t(row?.status || "0") while the text displays t(row?.noOfAttendees || "0"). Adjust to ensure the tooltip accurately represents the data shown.

Apply this diff:

 return (
     <div className="ellipsis-cell" title={t(row?.status || "0")}>
-        {t(row?.noOfAttendees || "0")}
+        {t(row?.status || "0")}
     </div>
 );

Likely invalid or redundant comment.




export const defaultRowsPerPage= 10;
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)

Fix formatting issues.

The constant definition has incorrect indentation and inconsistent spacing around the assignment operator.

Apply this diff to fix the formatting:

-    export const defaultRowsPerPage= 10;
+export const defaultRowsPerPage = 10;
📝 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
export const defaultRowsPerPage= 10;
export const defaultRowsPerPage = 10;

Comment on lines +8 to +11
export const ScreenTypeEnum = Object.freeze({
BILL: "BILL",
REGISTER: "REGISTER",
});
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)

Fix indentation for consistent formatting.

The entire enum definition is over-indented.

Apply this diff to fix the indentation:

-    export const ScreenTypeEnum = Object.freeze({
-        BILL: "BILL",
-        REGISTER: "REGISTER",
-        });
+export const ScreenTypeEnum = Object.freeze({
+    BILL: "BILL",
+    REGISTER: "REGISTER",
+});
📝 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
export const ScreenTypeEnum = Object.freeze({
BILL: "BILL",
REGISTER: "REGISTER",
});
export const ScreenTypeEnum = Object.freeze({
BILL: "BILL",
REGISTER: "REGISTER",
});

Comment on lines +1 to +6
import React, { Fragment, useState, } from "react";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Button, Loader } from "@egovernments/digit-ui-components";
import { Loader, TextInput, Toast } from "@egovernments/digit-ui-components";
import { CustomSVG } from "@egovernments/digit-ui-components";
import { CheckBox } from "@egovernments/digit-ui-components";



import DataTable from "react-data-table-component";
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)

Consolidate Import Statements for Clarity

You have multiple import statements from the same module @egovernments/digit-ui-components. Consolidating them into a single statement improves readability.

Apply this diff:

-import { Loader, TextInput, Toast } from "@egovernments/digit-ui-components";
-import { CustomSVG } from "@egovernments/digit-ui-components";
+import { Loader, TextInput, Toast, CustomSVG } from "@egovernments/digit-ui-components";
📝 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
import React, { Fragment, useState, } from "react";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Button, Loader } from "@egovernments/digit-ui-components";
import { Loader, TextInput, Toast } from "@egovernments/digit-ui-components";
import { CustomSVG } from "@egovernments/digit-ui-components";
import { CheckBox } from "@egovernments/digit-ui-components";
import DataTable from "react-data-table-component";
import React, { Fragment, useState, } from "react";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Loader, TextInput, Toast, CustomSVG } from "@egovernments/digit-ui-components";
import DataTable from "react-data-table-component";

Comment on lines 1 to 21
import { Button, Card, Chip, Header, Loader, PopUp, Toast, CardText, NoResultsFound, Tab } from "@egovernments/digit-ui-components";
import React, { useEffect, useState } from "react";
import { Link, useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import DataTable from "react-data-table-component";
import { useQueryClient } from "react-query";
import { CustomSVG } from "@egovernments/digit-ui-components";
import { tableCustomStyle } from "./table_inbox_custom_style";
import { defaultPaginationValues } from "../../utils/constants";

const CustomInboxTable = ({
handleTabChange,
rowsPerPage,
isLoading,
tableData,
customHandleRowsPerPageChange,
customHandlePaginationChange,
totalCount,
statusCount,
selectedProject,
}) => {
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 unused imports and add prop types documentation.

Several imports are not used in the component. Additionally, the component's props should be documented for better maintainability.

Apply this diff to clean up imports:

-import { Button, Card, Chip, Header, Loader, PopUp, Toast, CardText, NoResultsFound, Tab } from "@egovernments/digit-ui-components";
+import { Card, Loader, NoResultsFound, Tab } from "@egovernments/digit-ui-components";

Consider adding PropTypes or TypeScript types for the component props:

CustomInboxTable.propTypes = {
  handleTabChange: PropTypes.func.isRequired,
  rowsPerPage: PropTypes.number.isRequired,
  isLoading: PropTypes.bool.isRequired,
  tableData: PropTypes.array,
  customHandleRowsPerPageChange: PropTypes.func.isRequired,
  customHandlePaginationChange: PropTypes.func.isRequired,
  totalCount: PropTypes.number,
  statusCount: PropTypes.object,
  selectedProject: PropTypes.object
};

Comment on lines +101 to +104
/*(!planEmployee?.data || planEmployee?.data?.length === 0) */
!tableData ? (
<NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />
) : (
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

Consolidate NoResultsFound checks.

The component has duplicate checks for displaying the NoResultsFound component.

Apply this diff to simplify the logic:

-  !tableData ? (
-    <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />
-  ) : (
-    <div>
-      {tableData && tableData.length === 0 ? (
-        <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />
-      ) : (
+  (!tableData || tableData.length === 0) ? (
+    <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />
+  ) : (

Also applies to: 132-133

Comment on lines 1 to 40
import React, { useEffect, useState } from "react";

import _ from "lodash";

import { useTranslation } from "react-i18next";
import CustomFilter from "./custom_comp/filter_section";
import CustomInboxTable from "./custom_comp/table_inbox";
import { Toast, Card } from "@egovernments/digit-ui-components";
import { defaultRowsPerPage, ScreenTypeEnum, StatusEnum } from "../utils/constants";
import SearchResultsPlaceholder from "./SearchResultsPlaceholder";

/**
* Business Flow Description:
* 1. In the search section, a project select dropdown is provided.
* - When a project is selected from the dropdown, the Boundary Search Service is invoked to fetch the boundary hierarchy.
* 2. On successful fetching of the boundary hierarchy from the service:
* - A dynamic list of boundary selection dropdowns is rendered in the filter section.
* 3. When filters are applied:
* - The Attendance Register Search API is called with the applied filter criteria.
* - On receiving a successful response, the table data is rendered accordingly.
* 4. Tab Functionality:
* - Tabs are implemented in the UI for additional functionality.
* - Based on the tab selection, the Attendance Register Search API is triggered with a custom payload specific to the selected tab.

*/

/**
* Reason for not using React Component - InboxComposer:
* 1. Restrictions in InboxComposer:
* - The component requires showing "No Results" initially, which does not align with our requirement.
* - Search should only be triggered after filters are applied.
* 2. Dynamic Boundary Filters:
* - The boundary filter options need to be dynamically determined based on the selected project.
* 3. Tab-Specific API Calls:
* - On tab selection, the same Attendance Register Search API must be called with different status filters,
* which is not inherently supported by the InboxComposer component.


*/

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 unused import and enhance JSDoc documentation.

The lodash import is not used in the component. Additionally, the JSDoc documentation could be enhanced with parameter types.

Apply this diff to clean up imports:

-import _ from "lodash";

Consider enhancing the JSDoc documentation:

/**
 * CustomInboxSearchComposer component for managing attendance approval workflow.
 * @component
 * @returns {JSX.Element} The rendered component
 *
 * Business Flow Description:
 * ...existing documentation...
 */

Comment on lines +126 to +163
const handleFilterUpdate = (newFilter, isSelectedData) => {
setFilterCriteria(newFilter);
setSelectedStatus(StatusEnum.PENDING_FOR_APPROVAL);

const existingPaymentInbox = Digit.SessionStorage.get("paymentInbox");

const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;

// Validation 1: Check if both `selectedProject` and `existingPaymentInbox.selectedProject` are empty
if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_PROJECT_SELECT"), transitionTime: 3000 });
return;
}

// Validation 2: Check if `newFilter` is null or undefined

if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_BOUNDARY_SELECT"), transitionTime: 3000 });
return;
}

// Proceed with updating session storage if validations pass
const existingData = existingPaymentInbox || {};

// Ensure `selectedProject` is stored if missing
if (!existingData.selectedProject) {
existingData.selectedProject = selectedProject;
}

// Always update the object with `newFilter` data
Object.assign(existingData, newFilter);

// Save the updated object back to SessionStorage
Digit.SessionStorage.set("paymentInbox", existingData);

// Trigger the approval action
triggerMusterRollApprove(newFilter, StatusEnum.PENDING_FOR_APPROVAL);
};
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)

Simplify validation logic in handleFilterUpdate.

The validation logic is well-structured but can be simplified.

Apply this diff to improve the code:

+const validateFilter = (newFilter, selectedProject, existingPaymentInbox) => {
+  const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
+
+  if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
+    return { isValid: false, error: "HCM_AM_ATTENDANCE_PROJECT_SELECT" };
+  }
+
+  if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
+    return { isValid: false, error: "HCM_AM_ATTENDANCE_BOUNDARY_SELECT" };
+  }
+
+  return { isValid: true };
+};

 const handleFilterUpdate = (newFilter, isSelectedData) => {
   setFilterCriteria(newFilter);
   setSelectedStatus(StatusEnum.PENDING_FOR_APPROVAL);

   const existingPaymentInbox = Digit.SessionStorage.get("paymentInbox");
-  const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
-
-  if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
-    setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_PROJECT_SELECT"), transitionTime: 3000 });
-    return;
-  }
-
-  if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
-    setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_BOUNDARY_SELECT"), transitionTime: 3000 });
-    return;
+  const validation = validateFilter(newFilter, selectedProject, existingPaymentInbox);
+  if (!validation.isValid) {
+    setShowToast({ key: "error", label: t(validation.error), transitionTime: 3000 });
+    return;
   }
📝 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
const handleFilterUpdate = (newFilter, isSelectedData) => {
setFilterCriteria(newFilter);
setSelectedStatus(StatusEnum.PENDING_FOR_APPROVAL);
const existingPaymentInbox = Digit.SessionStorage.get("paymentInbox");
const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
// Validation 1: Check if both `selectedProject` and `existingPaymentInbox.selectedProject` are empty
if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_PROJECT_SELECT"), transitionTime: 3000 });
return;
}
// Validation 2: Check if `newFilter` is null or undefined
if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_BOUNDARY_SELECT"), transitionTime: 3000 });
return;
}
// Proceed with updating session storage if validations pass
const existingData = existingPaymentInbox || {};
// Ensure `selectedProject` is stored if missing
if (!existingData.selectedProject) {
existingData.selectedProject = selectedProject;
}
// Always update the object with `newFilter` data
Object.assign(existingData, newFilter);
// Save the updated object back to SessionStorage
Digit.SessionStorage.set("paymentInbox", existingData);
// Trigger the approval action
triggerMusterRollApprove(newFilter, StatusEnum.PENDING_FOR_APPROVAL);
};
const validateFilter = (newFilter, selectedProject, existingPaymentInbox) => {
const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
return { isValid: false, error: "HCM_AM_ATTENDANCE_PROJECT_SELECT" };
}
if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
return { isValid: false, error: "HCM_AM_ATTENDANCE_BOUNDARY_SELECT" };
}
return { isValid: true };
};
const handleFilterUpdate = (newFilter, isSelectedData) => {
setFilterCriteria(newFilter);
setSelectedStatus(StatusEnum.PENDING_FOR_APPROVAL);
const existingPaymentInbox = Digit.SessionStorage.get("paymentInbox");
const validation = validateFilter(newFilter, selectedProject, existingPaymentInbox);
if (!validation.isValid) {
setShowToast({ key: "error", label: t(validation.error), transitionTime: 3000 });
return;
}
// Proceed with updating session storage if validations pass
const existingData = existingPaymentInbox || {};
// Ensure `selectedProject` is stored if missing
if (!existingData.selectedProject) {
existingData.selectedProject = selectedProject;
}
// Always update the object with `newFilter` data
Object.assign(existingData, newFilter);
// Save the updated object back to SessionStorage
Digit.SessionStorage.set("paymentInbox", existingData);
// Trigger the approval action
triggerMusterRollApprove(newFilter, StatusEnum.PENDING_FOR_APPROVAL);
};

Comment on lines 198 to 247
return (
<React.Fragment>
<div className="custom-register-inbox-screen">
<div className="inner-div-row-section">
<div className="custom-inbox-filter-section">
{/*<div style={{ width: "80%", display: "flex", flexDirection: "row" }}>
<CustomSearchComponent onProjectSelect={handleProjectChange}></CustomSearchComponent>
</div>*/}

<div className="custom-inbox-inner-filter-section">
<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate}></CustomFilter>
</div>
</div>

<div className="custom-inbox-outer-table-section">
<div className="inner-table-section">
{card == false ? (
<Card className="card-overide">
<div className="summary-sub-heading">{t(selectedProject?.name)}</div>
<SearchResultsPlaceholder placeholderText={"HCM_AM_FILTER_AND_CHOOSE_BOUNDARY_PLACEHOLDER_TEXT"} />
</Card>
) : (
<CustomInboxTable
statusCount={childrenData?.statusCount}
handleTabChange={callServiceOnTap}
rowsPerPage={rowsPerPage}
customHandleRowsPerPageChange={handleRowsPerPageChange}
customHandlePaginationChange={handlePaginationChange}
isLoading={childrenDataLoading}
tableData={childrenData?.data}
totalCount={childrenData?.totalCount}
selectedProject={selectedProject}
></CustomInboxTable>
)}
</div>
</div>
</div>
</div>
{showToast && (
<Toast
style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
// error={showToast.key === "error"}
transitionTime={showToast.transitionTime}
onClose={() => setShowToast(null)}
/>
)}
</React.Fragment>
);
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)

Clean up JSX rendering code.

The JSX code has style issues and contains commented-out code.

Apply these improvements:

  1. Use self-closing tags:
-<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate}></CustomFilter>
+<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate} />

-<CustomInboxTable {...props}></CustomInboxTable>
+<CustomInboxTable {...props} />
  1. Remove commented-out code:
-{/*<div style={{ width: "80%", display: "flex", flexDirection: "row" }}>
-  <CustomSearchComponent onProjectSelect={handleProjectChange}></CustomSearchComponent>
-</div>*/}

-// error={showToast.key === "error"}
📝 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 (
<React.Fragment>
<div className="custom-register-inbox-screen">
<div className="inner-div-row-section">
<div className="custom-inbox-filter-section">
{/*<div style={{ width: "80%", display: "flex", flexDirection: "row" }}>
<CustomSearchComponent onProjectSelect={handleProjectChange}></CustomSearchComponent>
</div>*/}
<div className="custom-inbox-inner-filter-section">
<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate}></CustomFilter>
</div>
</div>
<div className="custom-inbox-outer-table-section">
<div className="inner-table-section">
{card == false ? (
<Card className="card-overide">
<div className="summary-sub-heading">{t(selectedProject?.name)}</div>
<SearchResultsPlaceholder placeholderText={"HCM_AM_FILTER_AND_CHOOSE_BOUNDARY_PLACEHOLDER_TEXT"} />
</Card>
) : (
<CustomInboxTable
statusCount={childrenData?.statusCount}
handleTabChange={callServiceOnTap}
rowsPerPage={rowsPerPage}
customHandleRowsPerPageChange={handleRowsPerPageChange}
customHandlePaginationChange={handlePaginationChange}
isLoading={childrenDataLoading}
tableData={childrenData?.data}
totalCount={childrenData?.totalCount}
selectedProject={selectedProject}
></CustomInboxTable>
)}
</div>
</div>
</div>
</div>
{showToast && (
<Toast
style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
// error={showToast.key === "error"}
transitionTime={showToast.transitionTime}
onClose={() => setShowToast(null)}
/>
)}
</React.Fragment>
);
return (
<React.Fragment>
<div className="custom-register-inbox-screen">
<div className="inner-div-row-section">
<div className="custom-inbox-filter-section">
<div className="custom-inbox-inner-filter-section">
<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate} />
</div>
</div>
<div className="custom-inbox-outer-table-section">
<div className="inner-table-section">
{card == false ? (
<Card className="card-overide">
<div className="summary-sub-heading">{t(selectedProject?.name)}</div>
<SearchResultsPlaceholder placeholderText={"HCM_AM_FILTER_AND_CHOOSE_BOUNDARY_PLACEHOLDER_TEXT"} />
</Card>
) : (
<CustomInboxTable
statusCount={childrenData?.statusCount}
handleTabChange={callServiceOnTap}
rowsPerPage={rowsPerPage}
customHandleRowsPerPageChange={handleRowsPerPageChange}
customHandlePaginationChange={handlePaginationChange}
isLoading={childrenDataLoading}
tableData={childrenData?.data}
totalCount={childrenData?.totalCount}
selectedProject={selectedProject}
/>
)}
</div>
</div>
</div>
</div>
{showToast && (
<Toast
style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
transitionTime={showToast.transitionTime}
onClose={() => setShowToast(null)}
/>
)}
</React.Fragment>
);
🧰 Tools
🪛 Biome (1.9.4)

[error] 208-208: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 220-230: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

Comment on lines 61 to 116
const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
try {
setChildrenDataLoading(true);
fetchRegisters.mutateAsync(
{
params: {
tenantId: Digit.ULBService.getStateId(),
limit: totalRows || rowsPerPage,
offset: totalNext == undefined ? (currentPage - 1) * rowsPerPage : (totalNext - 1) * totalRows,
referenceId: selectedProject?.id == undefined ? Digit.SessionStorage.get("paymentInbox").selectedProject?.id : selectedProject?.id,
staffId: Digit.SessionStorage.get("UserIndividual")?.[0]?.id,
localityCode:
filterData?.code == undefined || filterData?.code == null
? filterCriteria?.code == undefined || filterCriteria?.code == null
? Digit.SessionStorage.get("paymentInbox").code
: filterCriteria?.code
: filterData?.code,
reviewStatus: status == undefined ? selectedStatus : status,
isChildrenRequired: true,
},
},
{
onSuccess: (data) => {
const rowData =
data?.attendanceRegister.length > 0
? data?.attendanceRegister?.map((item, index) => {
return {
id: item?.registerNumber,
//name: item?.name,
name: selectedProject?.name,
boundary: item?.localityCode,
status: item?.attendees == null ? 0 : item?.attendees.length || 0,
markby: item?.staff?.[0].additionalDetails?.ownerName || "NA",
approvedBy: item?.staff?.[0].additionalDetails?.staffName || "NA",
};
})
: [];
setChildrenDataLoading(false);
setCard(true);
setchildrenData({
data: rowData,
totalCount: data?.totalCount,
statusCount: data?.statusCount,
});
},
onError: (error) => {
setCard(true);
setChildrenDataLoading(false);
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"), transitionTime: 3000 });
},
}
);
} catch (error) {
/// will show estimate data only
}
};
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

Improve error handling and simplify complex conditions.

The function has complex nested ternaries and minimal error handling.

  1. Simplify the localityCode parameter:
-localityCode:
-  filterData?.code == undefined || filterData?.code == null
-    ? filterCriteria?.code == undefined || filterCriteria?.code == null
-      ? Digit.SessionStorage.get("paymentInbox").code
-      : filterCriteria?.code
-    : filterData?.code,
+localityCode: filterData?.code ?? filterCriteria?.code ?? Digit.SessionStorage.get("paymentInbox").code,
  1. Improve error handling:
 } catch (error) {
-  /// will show estimate data only
+  console.error('Failed to fetch attendance data:', error);
+  setChildrenDataLoading(false);
+  setShowToast({
+    key: "error",
+    label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"),
+    transitionTime: 3000
+  });
 }
📝 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
const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
try {
setChildrenDataLoading(true);
fetchRegisters.mutateAsync(
{
params: {
tenantId: Digit.ULBService.getStateId(),
limit: totalRows || rowsPerPage,
offset: totalNext == undefined ? (currentPage - 1) * rowsPerPage : (totalNext - 1) * totalRows,
referenceId: selectedProject?.id == undefined ? Digit.SessionStorage.get("paymentInbox").selectedProject?.id : selectedProject?.id,
staffId: Digit.SessionStorage.get("UserIndividual")?.[0]?.id,
localityCode:
filterData?.code == undefined || filterData?.code == null
? filterCriteria?.code == undefined || filterCriteria?.code == null
? Digit.SessionStorage.get("paymentInbox").code
: filterCriteria?.code
: filterData?.code,
reviewStatus: status == undefined ? selectedStatus : status,
isChildrenRequired: true,
},
},
{
onSuccess: (data) => {
const rowData =
data?.attendanceRegister.length > 0
? data?.attendanceRegister?.map((item, index) => {
return {
id: item?.registerNumber,
//name: item?.name,
name: selectedProject?.name,
boundary: item?.localityCode,
status: item?.attendees == null ? 0 : item?.attendees.length || 0,
markby: item?.staff?.[0].additionalDetails?.ownerName || "NA",
approvedBy: item?.staff?.[0].additionalDetails?.staffName || "NA",
};
})
: [];
setChildrenDataLoading(false);
setCard(true);
setchildrenData({
data: rowData,
totalCount: data?.totalCount,
statusCount: data?.statusCount,
});
},
onError: (error) => {
setCard(true);
setChildrenDataLoading(false);
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"), transitionTime: 3000 });
},
}
);
} catch (error) {
/// will show estimate data only
}
};
const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => {
try {
setChildrenDataLoading(true);
fetchRegisters.mutateAsync(
{
params: {
tenantId: Digit.ULBService.getStateId(),
limit: totalRows || rowsPerPage,
offset: totalNext == undefined ? (currentPage - 1) * rowsPerPage : (totalNext - 1) * totalRows,
referenceId: selectedProject?.id == undefined ? Digit.SessionStorage.get("paymentInbox").selectedProject?.id : selectedProject?.id,
staffId: Digit.SessionStorage.get("UserIndividual")?.[0]?.id,
localityCode: filterData?.code ?? filterCriteria?.code ?? Digit.SessionStorage.get("paymentInbox").code,
reviewStatus: status == undefined ? selectedStatus : status,
isChildrenRequired: true,
},
},
{
onSuccess: (data) => {
const rowData =
data?.attendanceRegister.length > 0
? data?.attendanceRegister?.map((item, index) => {
return {
id: item?.registerNumber,
//name: item?.name,
name: selectedProject?.name,
boundary: item?.localityCode,
status: item?.attendees == null ? 0 : item?.attendees.length || 0,
markby: item?.staff?.[0].additionalDetails?.ownerName || "NA",
approvedBy: item?.staff?.[0].additionalDetails?.staffName || "NA",
};
})
: [];
setChildrenDataLoading(false);
setCard(true);
setchildrenData({
data: rowData,
totalCount: data?.totalCount,
statusCount: data?.statusCount,
});
},
onError: (error) => {
setCard(true);
setChildrenDataLoading(false);
setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"), transitionTime: 3000 });
},
}
);
} catch (error) {
console.error('Failed to fetch attendance data:', error);
setChildrenDataLoading(false);
setShowToast({
key: "error",
label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"),
transitionTime: 3000
});
}
};

Comment on lines +11 to +13
const BillInboxTable = ({
...props
}) => {
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)

Add propTypes and defaultProps for the component

Defining propTypes and defaultProps will enhance maintainability and catch potential issues early.

Here's an example of how to implement it:

import PropTypes from "prop-types";

const BillInboxTable = ({
    tableData,
    currentPage,
    totalCount,
    rowsPerPage,
    handlePageChange,
    handlePerRowsChange,
    isFetching,
    status,
    infoDescription,
}) => {
    // Component code
};

BillInboxTable.propTypes = {
    tableData: PropTypes.array.isRequired,
    currentPage: PropTypes.number.isRequired,
    totalCount: PropTypes.number.isRequired,
    rowsPerPage: PropTypes.number.isRequired,
    handlePageChange: PropTypes.func.isRequired,
    handlePerRowsChange: PropTypes.func.isRequired,
    isFetching: PropTypes.bool,
    status: PropTypes.string,
    infoDescription: PropTypes.string,
};

BillInboxTable.defaultProps = {
    isFetching: false,
    status: "",
    infoDescription: "",
};

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 488aff3 and 4b06e06.

📒 Files selected for processing (1)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 208-208: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 220-230: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

🔇 Additional comments (4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (4)

43-56: 🧹 Nitpick (assertive)

Consider consolidating related state variables.

Multiple state variables managing related data could be combined into a single state object for better maintainability:

-const [filterCriteria, setFilterCriteria] = useState(null);
-const [selectedProject, setSelectedProject] = useState(() => Digit.SessionStorage.get("selectedProject") || {});
-const [currentPage, setCurrentPage] = useState(1);
-const [rowsPerPage, setRowsPerPage] = useState(defaultRowsPerPage);
-const [selectedStatus, setSelectedStatus] = useState(StatusEnum.PENDING_FOR_APPROVAL);
+const [tableState, setTableState] = useState({
+  filterCriteria: null,
+  selectedProject: Digit.SessionStorage.get("selectedProject") || {},
+  currentPage: 1,
+  rowsPerPage: defaultRowsPerPage,
+  selectedStatus: StatusEnum.PENDING_FOR_APPROVAL
+});

Likely invalid or redundant comment.


126-163: 🧹 Nitpick (assertive)

Extract and simplify validation logic in handleFilterUpdate.

The validation logic can be extracted into a separate function for better maintainability:

+const validateFilter = (newFilter, selectedProject, existingPaymentInbox) => {
+  const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
+
+  if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
+    return { isValid: false, error: "HCM_AM_ATTENDANCE_PROJECT_SELECT" };
+  }
+
+  if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
+    return { isValid: false, error: "HCM_AM_ATTENDANCE_BOUNDARY_SELECT" };
+  }
+
+  return { isValid: true };
+};

 const handleFilterUpdate = (newFilter, isSelectedData) => {
   const validation = validateFilter(newFilter, selectedProject, existingPaymentInbox);
   if (!validation.isValid) {
     setShowToast({ key: "error", label: t(validation.error), transitionTime: 3000 });
     return;
   }
   // ... rest of the code

Likely invalid or redundant comment.


198-247: 🧹 Nitpick (assertive)

Clean up JSX rendering code.

  1. Use self-closing tags for components without children
  2. Remove commented-out code
-<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate}></CustomFilter>
+<CustomFilter resetTable={resetTable} isRequired={ScreenTypeEnum.REGISTER} onFilterChange={handleFilterUpdate} />

-<CustomInboxTable {...props}></CustomInboxTable>
+<CustomInboxTable {...props} />

-{/*<div style={{ width: "80%", display: "flex", flexDirection: "row" }}>
-  <CustomSearchComponent onProjectSelect={handleProjectChange}></CustomSearchComponent>
-</div>*/}

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 208-208: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 220-230: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


61-116: 🛠️ Refactor suggestion

Improve error handling and simplify complex conditions.

  1. The nested ternary operator for localityCode is hard to read
  2. The catch block lacks proper error handling
-localityCode:
-  filterData?.code == undefined || filterData?.code == null
-    ? filterCriteria?.code == undefined || filterCriteria?.code == null
-      ? Digit.SessionStorage.get("paymentInbox").code
-      : filterCriteria?.code
-    : filterData?.code,
+localityCode: filterData?.code ?? filterCriteria?.code ?? Digit.SessionStorage.get("paymentInbox").code,

 } catch (error) {
-  /// will show estimate data only
+  console.error('Failed to fetch attendance data:', error);
+  setChildrenDataLoading(false);
+  setShowToast({
+    key: "error",
+    label: t("HCM_AM_ATTENDANCE_REGISTER_FETCH_FAILED"),
+    transitionTime: 3000
+  });
 }

Likely invalid or redundant comment.

Comment on lines +12 to +39
/**
* Business Flow Description:
* 1. In the search section, a project select dropdown is provided.
* - When a project is selected from the dropdown, the Boundary Search Service is invoked to fetch the boundary hierarchy.
* 2. On successful fetching of the boundary hierarchy from the service:
* - A dynamic list of boundary selection dropdowns is rendered in the filter section.
* 3. When filters are applied:
* - The Attendance Register Search API is called with the applied filter criteria.
* - On receiving a successful response, the table data is rendered accordingly.
* 4. Tab Functionality:
* - Tabs are implemented in the UI for additional functionality.
* - Based on the tab selection, the Attendance Register Search API is triggered with a custom payload specific to the selected tab.

*/

/**
* Reason for not using React Component - InboxComposer:
* 1. Restrictions in InboxComposer:
* - The component requires showing "No Results" initially, which does not align with our requirement.
* - Search should only be triggered after filters are applied.
* 2. Dynamic Boundary Filters:
* - The boundary filter options need to be dynamically determined based on the selected project.
* 3. Tab-Specific API Calls:
* - On tab selection, the same Attendance Register Search API must be called with different status filters,
* which is not inherently supported by the InboxComposer component.


*/
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)

Enhance JSDoc documentation with parameter and return type information.

While the business flow documentation is comprehensive, consider adding TypeScript-style documentation:

/**
 * CustomInboxSearchComposer component for managing attendance approval workflow.
 * @component
 * @returns {JSX.Element} The rendered component
 *
 * Business Flow Description:
 * ...existing documentation...
 */

Comment on lines 1 to 3
import React, { useEffect, useState } from "react";

import _ from "lodash";
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 unused lodash import.

The lodash library is imported but not used in this component.

-import _ from "lodash";
📝 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
import React, { useEffect, useState } from "react";
import _ from "lodash";
import React, { useEffect, useState } from "react";

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (16)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (8)

5-5: ⚠️ Potential issue

Define 'location' or use 'useLocation' hook

The variable location is used but not defined in this scope. If you intend to access the route's state, consider importing useLocation from react-router-dom and using it to retrieve the location object.

Apply this diff to fix the issue:

+import { useLocation } from "react-router-dom";

...

-const { fromViewScreen } = location.state || false;
+const location = useLocation();
+const { fromViewScreen } = location.state || {};

48-48: 🧹 Nitpick (assertive)

Simplify boolean expressions in 'isChildrenRequired' and 'enabled' properties

The ternary operators returning true or false are unnecessary. You can simplify the expressions by assigning the boolean result directly.

Apply these diffs to simplify the expressions:

For line 48:

-isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
+isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType,

For line 51:

-enabled: selectedBoundaryCode && selectedProject ? true : false,
+enabled: !!(selectedBoundaryCode && selectedProject),

For line 68:

-enabled: selectedBoundaryCode ? true : false,
+enabled: !!selectedBoundaryCode,

Also applies to: 51-51, 68-68

🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


201-209: 🧹 Nitpick (assertive)

Use self-closing tag for <CustomInboxSearchLinks>

JSX elements without children should be self-closing to improve code readability.

Apply this diff:

-<CustomInboxSearchLinks
-    headerText={"HCM_AM_BILL_INBOX"}
-    links={[
-        {
-            url: "/employee/payments/my-bills",
-            text: "HCM_AM_MY_BILLS",
-        },
-    ]}
-></CustomInboxSearchLinks>
+<CustomInboxSearchLinks
+    headerText={"HCM_AM_BILL_INBOX"}
+    links={[
+        {
+            url: "/employee/payments/my-bills",
+            text: "HCM_AM_MY_BILLS",
+        },
+    ]}
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 201-209: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


219-226: 🧹 Nitpick (assertive)

Use self-closing tag for <BillBoundaryFilter>

JSX elements without children should be self-closing to enhance code cleanliness.

Apply this diff:

-<BillBoundaryFilter
-    isRequired={ScreenTypeEnum.BILL}
-    selectedProject={selectedProject}
-    selectedLevel={selectedLevel}
-    onFilterChange={handleFilterUpdate}
-    updateBoundaryFilters={updateFilters}
-    resetBoundaryFilter={resetBoundaryFilter}
-></BillBoundaryFilter>
+<BillBoundaryFilter
+    isRequired={ScreenTypeEnum.BILL}
+    selectedProject={selectedProject}
+    selectedLevel={selectedLevel}
+    onFilterChange={handleFilterUpdate}
+    updateBoundaryFilters={updateFilters}
+    resetBoundaryFilter={resetBoundaryFilter}
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 219-226: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


282-292: 🧹 Nitpick (assertive)

Use self-closing tag for <BillInboxTable>

Since <BillInboxTable> has no child content, it should be self-closing.

Apply this diff:

-<BillInboxTable
-    isFetching={isFetching}
-    tableData={tableData}
-    currentPage={currentPage}
-    rowsPerPage={rowsPerPage}
-    handlePageChange={handlePageChange}
-    handlePerRowsChange={handlePerRowsChange}
-    totalCount={totalCount}
-    status={activeLink.code}
-    infoDescription={infoDescription}
-></BillInboxTable>
+<BillInboxTable
+    isFetching={isFetching}
+    tableData={tableData}
+    currentPage={currentPage}
+    rowsPerPage={rowsPerPage}
+    handlePageChange={handlePageChange}
+    handlePerRowsChange={handlePerRowsChange}
+    totalCount={totalCount}
+    status={activeLink.code}
+    infoDescription={infoDescription}
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 282-292: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


317-331: 🛠️ Refactor suggestion

Add a key prop to the <Button> component in actionFields

When rendering elements inside an array, each element should have a unique key prop to help React identify which items have changed.

Apply this diff:

 actionFields={[
-    <Button
+    <Button
+        key="generate-bill-btn"
         icon="CheckCircle"
         label={t(`HCM_AM_GENERATE_BILL_LABEL`)}
         onClick={() => {
             setOpenAlertPopUp(true);
         }}
         style={{
             minWidth: "14rem",
             opacity: billGenerationStatus != null ? 0.5 : 1,
         }}
         type="button"
         variation="primary"
         isDisabled={generateBillMutation.isLoading}
     />,
 ]}
🧰 Tools
🪛 Biome (1.9.4)

[error] 317-331: 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)


184-186: 🛠️ Refactor suggestion

Handle errors properly in the catch block

The catch block is empty, which may make debugging difficult if an error occurs. Consider adding error handling or logging inside the catch block.

Apply this diff:

} catch (error) {
-    /// will show estimate data only
+    console.error('Error generating bill:', error);
+    setShowToast({ key: "error", label: t("HCM_AM_BILL_GENERATION_FAILED"), transitionTime: 3000 });
}

189-191: ⚠️ Potential issue

Fix the conditional rendering of <LoaderWithGap />

The <LoaderWithGap /> component is not being rendered because it's not returned or used in the JSX output. To render the loader, include it in the return statement.

Apply this diff:

if (generateBillMutation.isLoading) {
-    return <LoaderWithGap />
+    return <LoaderWithGap />;
}
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (8)

3-3: 🧹 Nitpick (assertive)

Remove unused import CheckBox

The CheckBox component imported from @egovernments/digit-ui-components is not used in this file. Removing it will clean up the code.

Apply this diff:

-import { CheckBox, SubmitBar } from "@egovernments/digit-ui-components";
+import { SubmitBar } from "@egovernments/digit-ui-components";

10-10: ⚠️ Potential issue

Initialize boundaryType correctly

The state variable boundaryType is initialized but never updated. Ensure that boundaryType is set appropriately when the boundary changes to prevent potential undefined comparisons.

Update the onBoundaryChange method to set boundaryType:

const onBoundaryChange = (boundary) => {
    if (boundary) {
        setBoundary(boundary);
+       setBoundaryType(boundary.boundaryType);
        Digit.SessionStorage.set("boundary", boundary);
    } else {
        setBoundary(null);
+       setBoundaryType("");
        Digit.SessionStorage.set("boundary", null);
    }
};

17-19: ⚠️ Potential issue

Add null checks before comparing 'boundaryType' and 'selectedLevel.code'

To prevent potential runtime errors, ensure that boundaryType and selectedLevel.code are defined before comparing them.

Modify the condition in handleApplyFilter:

if (!boundaryType || !selectedLevel?.code || boundaryType !== selectedLevel.code) {
    setShowToast({ key: "error", label: t("HCM_AM_SELECT_BOUNDARY_TILL_LAST_LEVEL"), transitionTime: 3000 });
    return;
}

76-86: 🛠️ Refactor suggestion

Enhance accessibility by adding keyboard event handlers

The <div> element with an onClick handler should support keyboard interactions for better accessibility. Add onKeyPress and tabIndex={0} to enable keyboard navigation.

Apply this diff:

<div
    onClick={handleClearFilter}
+   onKeyPress={(e) => { if (e.key === 'Enter') handleClearFilter(); }}
+   tabIndex={0}
    style={{
        cursor: "pointer",
        alignItems: "center",
        gap: ".75rem",
        marginBottom: "24px",
        display: "flex",
        flexDirection: "row",
        justifyContent: "space-between",
    }}
>

Alternatively, consider using a <button> element for better semantic meaning.

🧰 Tools
🪛 Biome (1.9.4)

[error] 76-86: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


91-91: 🛠️ Refactor suggestion

Add keyboard event for accessibility on clickable <span>

The <span> with an onClick handler should support keyboard interactions. Add onKeyPress and tabIndex={0} to improve accessibility.

Apply this diff:

<span
    onClick={() => { }}
+   onKeyPress={(e) => { if (e.key === 'Enter') { /* handle action */ } }}
+   tabIndex={0}
    style={{ border: "1px solid #E0E0E0", padding: "6px", marginBottom: "10px" }}
>
🧰 Tools
🪛 Biome (1.9.4)

[error] 91-91: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


92-99: 🧹 Nitpick (assertive)

Provide accessibility attributes for SVG

Include a <title> element or aria-label inside the SVG to provide alternative text for screen readers.

Apply this diff:

<svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label={t("HCM_AM_REFRESH_ICON_DESCRIPTION")}>
+   <title>{t("HCM_AM_REFRESH_ICON_DESCRIPTION")}</title>
    <path
        d="M8 5V8L12 4L8 0V3C3.58 3 0 6.58 0 11C0 12.57 0.46 14.03 1.24 15.26L2.7 13.8C2.25 12.97 2 12.01 2 11C2 7.69 4.69 5 8 5ZM14.76 6.74L13.3 8.2C13.74 9.04 14 9.99 14 11C14 14.31 11.31 17 8 17V14L4 18L8 22V19C12.42 19 16 15.42 16 11C16 9.43 15.54 7.97 14.76 6.74Z"
        fill="#505A5F"
    />
</svg>
🧰 Tools
🪛 Biome (1.9.4)

[error] 92-92: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


54-54: 🧹 Nitpick (assertive)

Ensure consistent reset of boundary state

In handleClearFilter, the boundary state is reset using an empty string, whereas elsewhere null is used. Consider using null consistently.

Apply this diff:

-    setBoundary(""); // Clear the boundary value
+    setBoundary(null); // Clear the boundary value

115-115: ⚠️ Potential issue

Fix typo in prop name updateSeeeionStorage

The prop updateSeeeionStorage appears to be misspelled. Correct it to updateSessionStorage for clarity.

Apply this diff:

-    updateSeeeionStorage={(newSelectedValues) => {
+    updateSessionStorage={(newSelectedValues) => {

Also, ensure that the prop is correctly referenced in the BoundaryComponent.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b06e06 and 6fae825.

📒 Files selected for processing (2)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js

[error] 76-86: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 91-91: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 92-92: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 51-51: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 68-68: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 201-209: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 219-226: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 282-292: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 317-331: 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)

🔇 Additional comments (4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (4)

241-244: ⚠️ Potential issue

Ensure the placeholder text is correctly translated

The placeholderText prop in <SearchResultsPlaceholder> should correctly reference the translation function.

Apply this diff:

<SearchResultsPlaceholder placeholderText={t("HCM_AM_BILL_INBOX_PLACEHOLDER_IMAGE_TEXT")} />

This ensures that the placeholder text is properly localized.

Likely invalid or redundant comment.


76-99: 🧹 Nitpick (assertive)

Simplify state update logic in useEffect

You can simplify the logic that determines whether to show the generate bill action by directly assigning the boolean result.

Apply this diff:

 if (AttendanceData?.statusCount.PENDINGFORAPPROVAL === 0 && AttendanceData?.statusCount.APPROVED > 0) {
-    setShowGenerateBillAction(true);
-} else {
-    setInfoDescription("HCM_AM_PENDING_REGISTER_AND_APPROVAL_REGISTER_VALIDATION_FAILED_INFO_MESSAGE")
-    setShowGenerateBillAction(false);
-}
+    setShowGenerateBillAction(true);
+} else {
+    setInfoDescription("HCM_AM_PENDING_REGISTER_AND_APPROVAL_REGISTER_VALIDATION_FAILED_INFO_MESSAGE");
+    setShowGenerateBillAction(false);
+}

Alternatively, you can assign the result directly:

setShowGenerateBillAction(AttendanceData?.statusCount.PENDINGFORAPPROVAL === 0 && AttendanceData?.statusCount.APPROVED > 0);
if (!(AttendanceData?.statusCount.PENDINGFORAPPROVAL === 0 && AttendanceData?.statusCount.APPROVED > 0)) {
    setInfoDescription("HCM_AM_PENDING_REGISTER_AND_APPROVAL_REGISTER_VALIDATION_FAILED_INFO_MESSAGE");
}

Likely invalid or redundant comment.


154-183: Verify the correctness of the API endpoint and parameters

Ensure that the API endpoint /health-expense-calculator/v1/_calculate and the parameters passed are correct and conform to the backend expectations.

Please run the following script to confirm the availability and correctness of the API endpoint:

Replace <tenantId>, <selectedBoundaryCode>, and <selectedProject.id> with appropriate values.

✅ Verification successful

API endpoint and parameters are correctly implemented

The API endpoint /health-expense-calculator/v1/_calculate is properly configured in the development setup and the request parameters match the expected structure. The implementation includes comprehensive error handling and appropriate user feedback for different response scenarios.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the API endpoint and method

# Expected: The endpoint should accept POST requests and respond with appropriate status codes.
curl -X POST -H "Content-Type: application/json" -d '{
    "criteria": {
        "tenantId": "<tenantId>",
        "localityCode": "<selectedBoundaryCode>",
        "referenceId": "<selectedProject.id>"
    }
}' "https://example.com/health-expense-calculator/v1/_calculate" -I

Length of output: 400


Script:

#!/bin/bash
# Search for the API endpoint usage and configuration
echo "=== Searching for API endpoint usage ==="
rg -l "/health-expense-calculator/v1/_calculate"

echo -e "\n=== Searching for response handling patterns ==="
ast-grep --pattern 'statusCode === "SUCCESSFUL"'

echo -e "\n=== Looking for API configurations ==="
fd -e yaml -e json -e js | xargs rg "health-expense-calculator"

Length of output: 917


125-129: ⚠️ Potential issue

Check for potential issues with bill data handling

Verify that the logic correctly handles the case when BillData?.bills is undefined or null to prevent runtime errors.

Consider adding a null check:

if (BillData && BillData?.bills && BillData?.bills.length > 0) {
    setInfoDescription(`HCM_AM_BILL_IS_ALREADY_GENERATED_INFO_MESSAGE`);
}

Comment on lines +341 to +349
<Toast
style={{ zIndex: 10001 }}
label={showToast.label}
type={showToast.key}
// error={showToast.key === "error"}
transitionTime={showToast.transitionTime}
onClose={() => setShowToast(null)}
/>
)}
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)

Adjust z-index for the <Toast> component if overlapping occurs

Ensure that the zIndex value does not cause the toast to overlay important interface elements unintentionally.

Verify whether style={{ zIndex: 10001 }} is necessary, or if a lower value would suffice.

If not required, consider removing or adjusting it.

const [infoDescription, setInfoDescription] = useState(null);
const [pendingApprovalCount, setPendingApprovalCount] = useState(null);
const [limitAndOffset, setLimitAndOffset] = useState({ limit: rowsPerPage, offset: (currentPage - 1) * rowsPerPage });
const project = Digit?.SessionStorage.get("staffProjects");
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 unused state variable project

The state variable project is defined but not used in the component. Consider removing it to clean up the code.

Apply this diff:

-const project = Digit?.SessionStorage.get("staffProjects");

Comment on lines +136 to +137
);
};
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)

Add PropTypes definitions for BillBoundaryFilter

To improve code maintainability and catch potential type-related issues, add prop type definitions.

Example with PropTypes:

import PropTypes from 'prop-types';

BillBoundaryFilter.propTypes = {
  isRequired: PropTypes.bool,
  selectedProject: PropTypes.object,
  selectedLevel: PropTypes.object,
  onFilterChange: PropTypes.func.isRequired,
  updateBoundaryFilters: PropTypes.bool,
  resetBoundaryFilter: PropTypes.func,
};

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fae825 and 65129c5.

⛔ Files ignored due to path filters (1)
  • health/micro-ui/web/micro-ui-internals/packages/css/package.json is excluded by !**/*.json
📒 Files selected for processing (2)
  • health/micro-ui/web/micro-ui-internals/example/public/index.html (1 hunks)
  • health/micro-ui/web/public/index.html (1 hunks)

@@ -10,7 +10,7 @@
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />
<!-- added below css for hcm-workbench module inclusion-->
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected].33/dist/index.css" />
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected].38/dist/index.css" />
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)

Consider adding Subresource Integrity (SRI) hash.

Loading CSS from a CDN without integrity checks poses a security risk. Consider adding an integrity hash to ensure the resource hasn't been tampered with.

Example format:

-  <link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />
+  <link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" 
+        integrity="sha384-[BASE64_HASH]"
+        crossorigin="anonymous" />

Committable suggestion skipped: line range outside the PR's diff.


💡 Codebase verification

❌ Critical: Referenced CSS package version 0.2.38 does not exist

The specified version @egovernments/[email protected] is not available. The latest published version is 0.2.1. This will cause UI styling failures as the CSS file cannot be loaded.

🔗 Analysis chain

Verify the health CSS package version.

Please ensure that version 0.2.38 of @egovernments/digit-ui-health-css exists and is stable.

Run this script to verify the package version:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if the specified version exists and check for any breaking changes

# Check if the version exists on unpkg
curl -s -o /dev/null -w "%{http_code}" https://unpkg.com/@egovernments/[email protected]/dist/index.css

# Get the latest version and compare
curl -s https://registry.npmjs.org/@egovernments/digit-ui-health-css/latest | jq -r '.version'

Length of output: 218

@@ -12,7 +12,7 @@
<title>DIGIT</title>
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected].33/dist/index.css" />
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected].38/dist/index.css" />
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)

Document the reason for version update.

Consider adding a comment in the HTML file or updating the PR description to document the specific improvements or fixes introduced in this version update of the health CSS package.

+  <!-- Updated to 0.2.38 for health payments UI enhancements -->
   <link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />
📝 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
<link rel="stylesheet" href="https://unpkg.com/@egovernments/digit-ui-health-css@0.2.38/dist/index.css" />
<!-- Updated to 0.2.38 for health payments UI enhancements -->
<link rel="stylesheet" href="https://unpkg.com/@egovernments/[email protected]/dist/index.css" />

💡 Codebase verification

Package version 0.2.38 does not exist in the npm registry

The CSS package @egovernments/[email protected] is not available in the npm registry. This will cause the application to fail as unpkg.com serves files directly from npm.

  • Either use an existing version of the package
  • Or ensure version 0.2.38 is published to npm before merging this PR
🔗 Analysis chain

Verify the updated package version.

The health CSS package version has been updated from 0.2.33 to 0.2.38. Let's verify the version's existence and check for any security concerns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the package version and check for security advisories

# Check if the version exists on npm
curl -s https://registry.npmjs.org/@egovernments/digit-ui-health-css | jq '.versions | has("0.2.38")'

# Check for any security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@egovernments/digit-ui-health-css") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 476

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 13

♻️ Duplicate comments (20)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (7)

1-8: 🧹 Nitpick (assertive)

Optimize imports for better maintainability.

  1. The InboxSearchComposer component is imported but never used
  2. Components are imported from two similar packages which could be consolidated
-import { Header, InboxSearchComposer, Loader } from "@egovernments/digit-ui-react-components";
+import { Header, Loader } from "@egovernments/digit-ui-react-components";

17-21: 🧹 Nitpick (assertive)

Use consistent types for date state.

Using empty strings for date values could lead to type inconsistencies.

const [dateRange, setDateRange] = useState({
-   startDate: '',
-   endDate: '',
+   startDate: null,
+   endDate: null,
    title: '',
});

27-27: 🛠️ Refactor suggestion

Add null check for SessionStorage access.

The project retrieval doesn't handle potential undefined values.

-const project = Digit?.SessionStorage.get("staffProjects");
+const project = Digit?.SessionStorage?.get("staffProjects") ?? null;

29-49: 🛠️ Refactor suggestion

Improve API configuration robustness.

  1. The boolean expression can be simplified
  2. The API configuration lacks error handling
const BillSearchCri = {
    config: {
-       enabled: project ? true : false,
+       enabled: Boolean(project),
        select: (data) => {
+           if (!data?.bills) {
+               throw new Error('Invalid response format');
+           }
            return data;
        },
+       onError: (error) => {
+           console.error('Bill search failed:', error);
+           // Consider showing a user-friendly error message
+       }
    },
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 44-44: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


64-69: 🛠️ Refactor suggestion

Prevent potential memory leak in useEffect.

Add cleanup to handle component unmount scenarios.

useEffect(() => {
+   let isSubscribed = true;
    if (BillData) {
+       if (isSubscribed) {
            setTableData(BillData.bills);
            setTotalCount(BillData?.pagination?.totalCount);
+       }
    }
+   return () => {
+       isSubscribed = false;
+   };
}, [BillData])

58-62: ⚠️ Potential issue

Fix pagination calculation in handlePerRowsChange.

The offset calculation should use 0 since we're resetting to the first page.

const handlePerRowsChange = (currentRowsPerPage, currentPage) => {
    setRowsPerPage(currentRowsPerPage);
    setCurrentPage(1);
-   setLimitAndOffset({ limit: currentRowsPerPage, offset: (currentPage - 1) * rowsPerPage });
+   setLimitAndOffset({ limit: currentRowsPerPage, offset: 0 });
}

100-101: 🧹 Nitpick (assertive)

Simplify conditional rendering.

The nested ternary operators make the code harder to read.

-{isFetching ? <Loader /> : tableData.length === 0 ? <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND_FOR_BILLS`)} /> : <MyBillsTable data={tableData} totalCount={totalCount} rowsPerPage={rowsPerPage} currentPage={currentPage} handlePageChange={handlePageChange}
-    handlePerRowsChange={handlePerRowsChange} />}
+{isFetching && <Loader />}
+{!isFetching && tableData.length === 0 && <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND_FOR_BILLS`)} />}
+{!isFetching && tableData.length > 0 && (
+    <MyBillsTable
+        data={tableData}
+        totalCount={totalCount}
+        rowsPerPage={rowsPerPage}
+        currentPage={currentPage}
+        handlePageChange={handlePageChange}
+        handlePerRowsChange={handlePerRowsChange}
+    />
+)}
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (5)

6-6: 🧹 Nitpick (assertive)

Fix the spelling of “updateSeeeionStorage” prop.

Please rename it consistently to avoid confusion.

-const BoundaryComponent = ({ reset, makeReset, initialValue, updateSeeeionStorage, selectedProject, onChange, lowestLevel, isRequired }) => {
+const BoundaryComponent = ({ reset, makeReset, initialValue, updateSessionStorage, selectedProject, onChange, lowestLevel, isRequired }) => {

35-48: 🧹 Nitpick (assertive)

Remove or clarify the commented-out code.

Large blocks of commented code can clutter the file. If it’s no longer needed, please remove or move it to documentation.


119-120: 🧹 Nitpick (assertive)

Use strict equality to avoid type coercion.

Replace == with === for correctness and consistency.

-    if (reset == true) {
+    if (reset === true) {

218-218: 🧹 Nitpick (assertive)

Simplify the boolean expression for isRequired.

Use a logical expression instead of nested ternaries.

-                isRequired={isRequired == ScreenTypeEnum.BILL ? true : key == lowestLevelBoundaryType ? true : false}
+                isRequired={isRequired === ScreenTypeEnum.BILL || key === lowestLevelBoundaryType}
🧰 Tools
🪛 Biome (1.9.4)

[error] 218-218: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


249-249: 🧹 Nitpick (assertive)

Avoid using inline styles.

Inline styles hamper maintainability. Prefer using a dedicated CSS class instead.

-    <div style={{ width: "100%", marginTop: "14px" }}>
+    <div className="boundary-dropdown-container">
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (4)

39-41: 🧹 Nitpick (assertive)

Replace “let” with “const” since it is never reassigned.

Improves readability and reduces the risk of accidental reassignments.

-    let datak =
+    const datak =
🧰 Tools
🪛 Biome (1.9.4)

[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


56-56: 🧹 Nitpick (assertive)

Use strict equality for clarity.

Avoid type coercion by replacing == with ===.

-    if (reset == true) {
+    if (reset === true) {

112-125: 🧹 Nitpick (assertive)

Mark empty JSX elements as self-closing.

When there aren’t any children, use a self-closing tag for a cleaner structure.

-          ></BoundaryComponent>
+          />
🧰 Tools
🪛 Biome (1.9.4)

[error] 112-125: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


64-69: 🧹 Nitpick (assertive)

Extract inline styles into CSS classes.

Multiple inline styles hamper maintainability. Move them to a separate stylesheet or a styled component.

-<div
-  style={{
-    display: "flex",
-    flexDirection: "column",
-    height: "100%",
-  }}
->
+<div className="custom-filter-layout">

...

-<div
-  style={{
-    justifyContent: "center",
-    marginTop: "auto",
-    paddingTop: "16px",
-  }}
->
+<div className="custom-filter-footer">

Also applies to: 130-134

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1)

101-117: 🧹 Nitpick (assertive)

Mark BoundaryComponent as self-closing if it has no children.

Since the component has no children (only props), you can simplify the JSX for better readability.

<BoundaryComponent
  ...
>
</BoundaryComponent>

can be written as:

<BoundaryComponent
  ...
/>
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (3)

213-220: 🧹 Nitpick (assertive)

Use a self-closing tag for <CustomInboxSearchLinks>.

This component does not have children, so it can be self-closing for improved readability.

<CustomInboxSearchLinks
  headerText={"HCM_AM_BILL_INBOX"}
  links={[{ url: "/employee/payments/my-bills", text: "HCM_AM_MY_BILLS" }]}
>
</CustomInboxSearchLinks>

=>

<CustomInboxSearchLinks
  headerText={"HCM_AM_BILL_INBOX"}
  links={[{ url: "/employee/payments/my-bills", text: "HCM_AM_MY_BILLS" }]}
  />
🧰 Tools
🪛 Biome (1.9.4)

[error] 212-220: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


230-237: 🧹 Nitpick (assertive)

Use a self-closing tag for <BillBoundaryFilter>.

This component also does not contain child elements, so a self-closing tag is preferable.

<BillBoundaryFilter
  isRequired={ScreenTypeEnum.BILL}
  ...
>
</BillBoundaryFilter>

=>

<BillBoundaryFilter
  isRequired={ScreenTypeEnum.BILL}
  ...
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 230-237: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


293-303: 🧹 Nitpick (assertive)

Use a self-closing tag for <BillInboxTable>.

Like above, if there are no child elements, prefer a self-closing tag.

<BillInboxTable
  isFetching={isFetching}
  ...
>
</BillInboxTable>

=>

<BillInboxTable
  isFetching={isFetching}
  ...
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 293-303: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65129c5 and 4c4e516.

📒 Files selected for processing (8)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (1)

Pattern **/*.js: check

🪛 Biome (1.9.4)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/my_bills.js

[error] 44-44: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js

[error] 220-224: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 236-246: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js

[error] 77-87: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 92-92: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 93-93: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js

[error] 218-218: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)


[error] 112-125: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 41-41: This let declares a variable that is only assigned once.

'datak' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 51-51: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 77-77: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 212-220: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 230-237: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 293-303: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 328-342: 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)

🔇 Additional comments (19)
health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/table_inbox.js (2)

146-147: 🧹 Nitpick (assertive)

Add debouncing to loading state.

Direct binding of isLoading to progressPending could cause UI flickering during rapid updates. Consider debouncing the loading state.

+  const [debouncedLoading, setDebouncedLoading] = useState(isLoading);
+
+  useEffect(() => {
+    const timer = setTimeout(() => setDebouncedLoading(isLoading), 150);
+    return () => clearTimeout(timer);
+  }, [isLoading]);

   <DataTable
     ...
-    progressPending={isLoading}
+    progressPending={debouncedLoading}
     progressComponent={<Loader />}
     ...
   />

Likely invalid or redundant comment.


23-26: 🧹 Nitpick (assertive)

Extract status codes to constants.

The status codes are hardcoded in multiple places. Extract them to named constants for better maintainability.

+const ATTENDANCE_STATUS = {
+  PENDING: {
+    code: "PENDINGFORAPPROVAL",
+    name: "HCM_AM_PENDING_FOR_APPROVAL"
+  },
+  APPROVED: {
+    code: "APPROVED",
+    name: "HCM_AM_APPROVED"
+  }
+};

-  const [activeLink, setActiveLink] = useState({
-    code: "PENDINGFORAPPROVAL",
-    name: "HCM_AM_PENDING_FOR_APPROVAL",
-  });
+  const [activeLink, setActiveLink] = useState(ATTENDANCE_STATUS.PENDING);

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_inbox_composer.js (2)

220-225: Use self-closing tags for components without children.

-<CustomFilter
-  resetTable={resetTable}
-  isRequired={ScreenTypeEnum.REGISTER}
-  onFilterChange={handleFilterUpdate}
-></CustomFilter>
+<CustomFilter
+  resetTable={resetTable}
+  isRequired={ScreenTypeEnum.REGISTER}
+  onFilterChange={handleFilterUpdate}
+/>

-<CustomInboxTable
-  statusCount={childrenData?.statusCount}
-  handleTabChange={callServiceOnTap}
-  rowsPerPage={rowsPerPage}
-  customHandleRowsPerPageChange={handleRowsPerPageChange}
-  customHandlePaginationChange={handlePaginationChange}
-  isLoading={childrenDataLoading}
-  tableData={childrenData?.data}
-  totalCount={childrenData?.totalCount}
-  selectedProject={selectedProject}
-></CustomInboxTable>
+<CustomInboxTable
+  statusCount={childrenData?.statusCount}
+  handleTabChange={callServiceOnTap}
+  rowsPerPage={rowsPerPage}
+  customHandleRowsPerPageChange={handleRowsPerPageChange}
+  customHandlePaginationChange={handlePaginationChange}
+  isLoading={childrenDataLoading}
+  tableData={childrenData?.data}
+  totalCount={childrenData?.totalCount}
+  selectedProject={selectedProject}
+/>

Also applies to: 236-247

🧰 Tools
🪛 Biome (1.9.4)

[error] 220-224: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


130-167: 🧹 Nitpick (assertive)

Simplify validation logic in handleFilterUpdate.

Extract validation logic into a separate function for better maintainability and reusability.

+const validateFilter = (newFilter, selectedProject, existingPaymentInbox) => {
+  const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
+
+  if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
+    return { isValid: false, error: "HCM_AM_ATTENDANCE_PROJECT_SELECT" };
+  }
+
+  if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
+    return { isValid: false, error: "HCM_AM_ATTENDANCE_BOUNDARY_SELECT" };
+  }
+
+  return { isValid: true };
+};

 const handleFilterUpdate = (newFilter, isSelectedData) => {
   setFilterCriteria(newFilter);
   setSelectedStatus(StatusEnum.PENDING_FOR_APPROVAL);

   const existingPaymentInbox = Digit.SessionStorage.get("paymentInbox");
-  const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
-
-  if (isEmptyObject(selectedProject) && isEmptyObject(existingPaymentInbox?.selectedProject)) {
-    setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_PROJECT_SELECT"), transitionTime: 3000 });
-    return;
-  }
-
-  if ((!newFilter || isEmptyObject(newFilter)) && !existingPaymentInbox?.boundaryType) {
-    setShowToast({ key: "error", label: t("HCM_AM_ATTENDANCE_BOUNDARY_SELECT"), transitionTime: 3000 });
-    return;
+  const validation = validateFilter(newFilter, selectedProject, existingPaymentInbox);
+  if (!validation.isValid) {
+    setShowToast({ key: "error", label: t(validation.error), transitionTime: 3000 });
+    return;
   }

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js (4)

33-33: 🧹 Nitpick (assertive)

Remove unused state.

[lowest, setLowest] is never used. Consider removing it for cleaner code.

-  const [lowest, setLowest] = useState(lowestLevel);

Likely invalid or redundant comment.


137-140: 🧹 Nitpick (assertive)

Consider merging handleButtonClick and handleDropdownOptions.

They closely tie together, and combining them, or clearly naming them, might reduce complexity.

-const handleButtonClick = (value) => {
-  onChange(value);
-  handleDropdownOptions(value);
-};
+const handleBoundaryChange = (value) => {
+  onChange(value);
+  if (value?.children?.length) {
+    // existing handleDropdownOptions logic
+  }
+};

Likely invalid or redundant comment.


7-7: ⚠️ Potential issue

Add a null check to avoid runtime errors.

Digit.SessionStorage.get("boundaryHierarchyOrder") might return null or undefined, causing .map(...) to fail.

-  const kk = Digit.SessionStorage.get("boundaryHierarchyOrder").map((item) => item.code);
+  const boundaryOrder = Digit.SessionStorage.get("boundaryHierarchyOrder") || [];
+  const kk = boundaryOrder.map((item) => item.code);

Likely invalid or redundant comment.


106-110: Add a defensive check for nested boundary objects.

Accessing childrenData[0]?.boundary[0] can lead to undefined errors if the array is empty.

   if (childrenData && childrenData.length > 0 && childrenData[0]?.boundary?.length > 0) {
     setValue((prevState) => ({
       ...prevState,
-      [childrenData[0]?.boundary[0].boundaryType]: [childrenData[0]?.boundary[0]],
+      [childrenData[0].boundary[0].boundaryType]: [childrenData[0].boundary[0]],
     }));
     ...
   }
✅ Verification successful

The suggested defensive check for boundary array is necessary

The review is correct as the data comes from an API call through useAttendanceBoundarySearch, making it crucial to validate the boundary array's existence and length before access. The suggested fix properly guards against potential undefined errors while maintaining consistent error handling patterns seen elsewhere in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Search for childrenData usage and boundary patterns in the file
echo "=== Searching for childrenData in the file ==="
rg "childrenData" health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/sample.js -B 2 -A 2

echo -e "\n=== Searching for boundary-related patterns across the codebase ==="
rg "boundary\[0\]" health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/ -B 2 -A 2

echo -e "\n=== Looking for type definitions or interfaces ==="
fd "types?.ts" health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/

Length of output: 2665


Script:

#!/bin/bash
# Search for similar boundary access patterns and error handling in other components
echo "=== Searching for similar boundary patterns across components ==="
rg "\.boundary\." health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/ -B 2 -A 2

echo -e "\n=== Looking for error handling patterns ==="
rg "useAttendanceBoundarySearch" health/micro-ui/web/micro-ui-internals/packages/modules/ -B 2 -A 2

Length of output: 5065

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/custom_comp/filter_section.js (2)

92-97: 🛠️ Refactor suggestion

Improve accessibility by handling keyboard events.

Elements with onClick should also handle keyboard events for users relying on keyboard navigation.

 <span
   onClick={() => {
     setReset(true);
   }}
+  onKeyPress={(e) => {
+    if (e.key === "Enter") {
+      setReset(true);
+    }
+  }}
   role="button"
   tabIndex="0"
   style={{ border: "1px solid #e0e0e0", padding: "6px", marginBottom: "10px", cursor: "pointer" }}
>

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 92-97: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.

Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.

(lint/a11y/useKeyWithClickEvents)


98-98: 🛠️ Refactor suggestion

Add descriptive text or aria-label to the SVG.

For screen readers, a title or aria-label is required to describe the icon’s purpose.

 <svg
   width="17"
   height="17"
   viewBox="0 0 16 22"
   fill="none"
   xmlns="http://www.w3.org/2000/svg"
+  aria-label="Reset icon"
 >

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 98-98: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/bill_boundary_filter.js (4)

10-10: Verify necessity of boundaryType state.

The boundaryType state is set but never updated or referenced elsewhere. If it's not needed, removing it can reduce clutter.


3-3: 🧹 Nitpick (assertive)

Remove unused import CheckBox.

This import is declared but not used in the component. Removing it will help keep the codebase clean and maintainable.

-import { CheckBox, SubmitBar } from "@egovernments/digit-ui-components";
+import { SubmitBar } from "@egovernments/digit-ui-components";

Likely invalid or redundant comment.


110-110: ⚠️ Potential issue

Correct the prop name from updateSeeeionStorage to updateSessionStorage.

This minor spelling error could lead to confusion for other developers.

- updateSeeeionStorage={(newSelectedValues) => {
+ updateSessionStorage={(newSelectedValues) => {

Likely invalid or redundant comment.


53-61: 🛠️ Refactor suggestion

Use a consistent reset value for boundary.

Currently, handleClearFilter sets boundary to an empty string, whereas elsewhere it's set to null. This may cause inconsistent state checks downstream. Prefer a single convention for unsetting the boundary to avoid edge cases.

- setBoundary(""); // Clear the boundary value
+ setBoundary(null); // Clear the boundary value

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/BillInbox.js (2)

328-342: ⚠️ Potential issue

Add a key prop to the array element.

When rendering items in an array, React requires a unique key to ensure stable identity across re-renders.

actionFields={[
-  <Button
+  <Button key="generate-bill-btn"
    icon="CheckCircle"
    label={t(`HCM_AM_GENERATE_BILL_LABEL`)}
    onClick={() => {
      ...

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 328-342: 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)


5-5: ⚠️ Potential issue

Define or remove the location reference.

Using location.state without importing useLocation or otherwise defining location can cause a runtime error. If you intend to access route state, import and use useLocation; otherwise, remove this line.

- const { fromViewScreen } = location.state || false;
+ // Either remove this or define location properly via useLocation or other means

Likely invalid or redundant comment.

health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js (3)

6-6: 🧹 Nitpick (assertive)

Remove unused import useQueryClient.

This import is never referenced, so removing it helps keep the file tidy.

- import { useQueryClient } from "react-query";

Likely invalid or redundant comment.


70-73: ⚠️ Potential issue

Ensure consistent naming of marker or approver.

The title attribute references row?.markby, while the displayed text references row?.approvedBy or row?.markedBy. This discrepancy may confuse downstream readers. Align the naming for both title and displayed value.

      <div className="ellipsis-cell" title={row?.markby || t("NA")}>
-         {props.status === "APPROVED" ? row?.approvedBy : row?.markedBy || t("NA")}
+         {props.status === "APPROVED" ? row?.approvedBy : row?.markedBy || t("NA")}
+         /* Also make sure 'markby' is the correct property if needed:
+            title={row?.markedBy || t("NA")} */

Likely invalid or redundant comment.


11-13: 🧹 Nitpick (assertive)

Add PropTypes to BillInboxTable.

Defining prop types ensures future developers can clearly understand and validate the expected shape of props.

+ import PropTypes from "prop-types";

const BillInboxTable = ({
    tableData,
    currentPage,
    totalCount,
    rowsPerPage,
    handlePageChange,
    handlePerRowsChange,
    isFetching,
    status,
    infoDescription,
}) => { ... };

+ BillInboxTable.propTypes = {
+   tableData: PropTypes.array.isRequired,
+   currentPage: PropTypes.number.isRequired,
+   totalCount: PropTypes.number.isRequired,
+   rowsPerPage: PropTypes.number.isRequired,
+   handlePageChange: PropTypes.func.isRequired,
+   handlePerRowsChange: PropTypes.func.isRequired,
+   isFetching: PropTypes.bool,
+   status: PropTypes.string,
+   infoDescription: PropTypes.string,
+ };

+ BillInboxTable.defaultProps = {
+   isFetching: false,
+   status: "",
+   infoDescription: "",
+ };

Likely invalid or redundant comment.

Comment on lines +11 to +21
const CustomInboxTable = ({
handleTabChange,
rowsPerPage,
isLoading,
tableData,
customHandleRowsPerPageChange,
customHandlePaginationChange,
totalCount,
statusCount,
selectedProject
}) => {
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)

Add runtime prop validation for required props.

While PropTypes documentation was suggested in a past review, also consider adding runtime validation to fail fast during development.

const validateProps = ({ handleTabChange, rowsPerPage, tableData, customHandleRowsPerPageChange, customHandlePaginationChange }) => {
  if (!handleTabChange || typeof handleTabChange !== 'function') throw new Error('handleTabChange must be a function');
  if (!rowsPerPage || typeof rowsPerPage !== 'number') throw new Error('rowsPerPage must be a number');
  if (!customHandleRowsPerPageChange || typeof customHandleRowsPerPageChange !== 'function') throw new Error('customHandleRowsPerPageChange must be a function');
  if (!customHandlePaginationChange || typeof customHandlePaginationChange !== 'function') throw new Error('customHandlePaginationChange must be a function');
  if (tableData && !Array.isArray(tableData)) throw new Error('tableData must be an array');
};

🛠️ Refactor suggestion

Add error boundary for production safety.

The component lacks error boundaries which could expose sensitive information in stack traces. Consider wrapping the component with an error boundary.

class TableErrorBoundary extends React.Component {
  state = { hasError: false };
  
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  
  render() {
    if (this.state.hasError) {
      return <Card><NoResultsFound text="Something went wrong. Please try again." /></Card>;
    }
    return this.props.children;
  }
}

// Usage:
export default function CustomInboxTableWithErrorBoundary(props) {
  return (
    <TableErrorBoundary>
      <CustomInboxTable {...props} />
    </TableErrorBoundary>
  );
}

Also applies to: 104-166

Comment on lines +52 to +53
<Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${row?.id}&boundaryCode=${row?.boundary}`}>
{String(row?.id ? row?.id : t("ES_COMMON_NA"))}
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

Sanitize URL parameters for security.

The URL parameters are directly interpolated from row data, which could be vulnerable to XSS attacks. Consider encoding the parameters.

-            <Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${row?.id}&boundaryCode=${row?.boundary}`}>
+            <Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${encodeURIComponent(row?.id)}&boundaryCode=${encodeURIComponent(row?.boundary)}`}>
📝 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
<Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${row?.id}&boundaryCode=${row?.boundary}`}>
{String(row?.id ? row?.id : t("ES_COMMON_NA"))}
<Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${encodeURIComponent(row?.id)}&boundaryCode=${encodeURIComponent(row?.boundary)}`}>
{String(row?.id ? row?.id : t("ES_COMMON_NA"))}

@@ -0,0 +1,266 @@
import React, { useEffect, useReducer, useState, useMemo, use } from "react";
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

Clean up unused and invalid imports.

  1. Remove the invalid use import from React
  2. Remove unused imports:
    • lodash
    • CustomInboxSearchLinks
    • CustomSearchComponent
    • FilterCard
-import React, { useEffect, useReducer, useState, useMemo, use } from "react";
+import React, { useEffect, useReducer, useState, useMemo } from "react";

-import _ from "lodash";
-import CustomInboxSearchLinks from "./custom_comp/link_section";
-import CustomSearchComponent from "./custom_comp/search_section";

import { useTranslation } from "react-i18next";
import CustomFilter from "./custom_comp/filter_section";
import CustomInboxTable from "./custom_comp/table_inbox";
-import { FilterCard, Toast, Card } from "@egovernments/digit-ui-components";
+import { Toast, Card } from "@egovernments/digit-ui-components";

Also applies to: 3-5, 10-10

Comment on lines +204 to +251
<div style={{ width: "100%", display: "flex", flexDirection: "column", gap: "24px" }}>
<div style={{ width: "100%", display: "flex", flexDirection: "row", gap: "24px" }}>
<div style={{ width: "30%", display: "flex", flexDirection: "column", gap: "24px", height: "80vh" }}>
{/*<div style={{ width: "80%", display: "flex", flexDirection: "row" }}>
<CustomSearchComponent onProjectSelect={handleProjectChange}></CustomSearchComponent>
</div>*/}

<div
style={{
width: "100%",
display: "flex",
flexDirection: "row",
height: "75vh",
overflowY: "auto",
}}
>
<CustomFilter
resetTable={resetTable}
isRequired={ScreenTypeEnum.REGISTER}
onFilterChange={handleFilterUpdate}
></CustomFilter>
</div>
</div>

<div style={{ width: "100%", display: "flex", flexDirection: "row", gap: "24px" }}>
<div style={{ width: "100%", display: "flex", flexDirection: "column", height: "75vh", minHeight: "75vh" }}>
{card == false ? (
<Card style={{ maxWidth: "100%", overflow: "auto", margin: "0px", height: "75vh" }}>
<div className="summary-sub-heading">{t(selectedProject?.name)}</div>
<SearchResultsPlaceholder placeholderText={"HCM_AM_FILTER_AND_CHOOSE_BOUNDARY_PLACEHOLDER_TEXT"} />
</Card>
) : (
<CustomInboxTable
statusCount={childrenData?.statusCount}
handleTabChange={callServiceOnTap}
rowsPerPage={rowsPerPage}
customHandleRowsPerPageChange={handleRowsPerPageChange}
customHandlePaginationChange={handlePaginationChange}
isLoading={childrenDataLoading}
tableData={childrenData?.data}
totalCount={childrenData?.totalCount}
selectedProject={selectedProject}
></CustomInboxTable>
)}
</div>
</div>
</div>
</div>
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)

Move inline styles to CSS for better maintainability.

Consider extracting the inline styles to a separate CSS file using CSS modules or styled-components.

Example using CSS modules:

/* styles.module.css */
.container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.filterSection {
  width: 30%;
  display: flex;
  flex-direction: column;
  gap: 24px;
  height: 80vh;
}

.tableSection {
  width: 100%;
  display: flex;
  flex-direction: column;
  height: 75vh;
  min-height: 75vh;
}

Then import and use these styles in your component:

+import styles from './styles.module.css';

-<div style={{ width: "100%", display: "flex", flexDirection: "column", gap: "24px" }}>
+<div className={styles.container}>
🧰 Tools
🪛 Biome (1.9.4)

[error] 220-224: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)


[error] 236-246: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.

Unsafe fix: Use a SelfClosingElement instead

(lint/style/useSelfClosingElements)

Comment on lines +45 to +58
const [showToast, setShowToast] = useState(null);
const [filterCriteria, setFilterCriteria] = useState(null);
const [selectedProject, setSelectedProject] = useState(() => Digit.SessionStorage.get("selectedProject") || {});
//-------//

const [currentPage, setCurrentPage] = useState(1);
const [rowsPerPage, setRowsPerPage] = useState(defaultRowsPerPage);
const [selectedStatus, setSelectedStatus] = useState(StatusEnum.PENDING_FOR_APPROVAL);

const [card, setCard] = useState(false);

const [childrenDataLoading, setChildrenDataLoading] = useState(false);
const [childrenData, setchildrenData] = useState([]);

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)

Optimize state management by consolidating related states.

Consider grouping related state variables into a single state object for better maintainability:

-const [showToast, setShowToast] = useState(null);
-const [filterCriteria, setFilterCriteria] = useState(null);
-const [selectedProject, setSelectedProject] = useState(() => Digit.SessionStorage.get("selectedProject") || {});
-const [currentPage, setCurrentPage] = useState(1);
-const [rowsPerPage, setRowsPerPage] = useState(defaultRowsPerPage);
-const [selectedStatus, setSelectedStatus] = useState(StatusEnum.PENDING_FOR_APPROVAL);
-const [card, setCard] = useState(false);
-const [childrenDataLoading, setChildrenDataLoading] = useState(false);
-const [childrenData, setchildrenData] = useState([]);

+const [state, setState] = useState({
+  toast: null,
+  filterCriteria: null,
+  selectedProject: Digit.SessionStorage.get("selectedProject") || {},
+  pagination: {
+    currentPage: 1,
+    rowsPerPage: defaultRowsPerPage
+  },
+  selectedStatus: StatusEnum.PENDING_FOR_APPROVAL,
+  card: false,
+  children: {
+    loading: false,
+    data: []
+  }
+});

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +93 to +100
<svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M8 5V8L12 4L8 0V3C3.58 3 0 6.58 0 11C0 12.57 0.46 14.03 1.24 15.26L2.7 13.8C2.25 12.97 2 12.01 2 11C2 7.69 4.69 5 8 5ZM14.76 6.74L13.3 8.2C13.74 9.04 14 9.99 14 11C14 14.31 11.31 17 8 17V14L4 18L8 22V19C12.42 19 16 15.42 16 11C16 9.43 15.54 7.97 14.76 6.74Z"
fill="#505A5F"
/>
</svg>
</span>
</div>
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)

Provide alt text or a title for the inline SVG.

The <svg> element lacks a title or aria-label for assistive technologies, which can degrade accessibility for visually impaired users.

<svg
+  role="img"
+  aria-label={t("HCM_AM_REFRESH_ICON")}
   width="17"
   height="17"
   ...
>
  <title>{t("HCM_AM_REFRESH_ICON")}</title>
  <path ...
📝 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
<svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M8 5V8L12 4L8 0V3C3.58 3 0 6.58 0 11C0 12.57 0.46 14.03 1.24 15.26L2.7 13.8C2.25 12.97 2 12.01 2 11C2 7.69 4.69 5 8 5ZM14.76 6.74L13.3 8.2C13.74 9.04 14 9.99 14 11C14 14.31 11.31 17 8 17V14L4 18L8 22V19C12.42 19 16 15.42 16 11C16 9.43 15.54 7.97 14.76 6.74Z"
fill="#505A5F"
/>
</svg>
</span>
</div>
<svg width="17" height="17" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label={t("HCM_AM_REFRESH_ICON")}>
<title>{t("HCM_AM_REFRESH_ICON")}</title>
<path
d="M8 5V8L12 4L8 0V3C3.58 3 0 6.58 0 11C0 12.57 0.46 14.03 1.24 15.26L2.7 13.8C2.25 12.97 2 12.01 2 11C2 7.69 4.69 5 8 5ZM14.76 6.74L13.3 8.2C13.74 9.04 14 9.99 14 11C14 14.31 11.31 17 8 17V14L4 18L8 22V19C12.42 19 16 15.42 16 11C16 9.43 15.54 7.97 14.76 6.74Z"
fill="#505A5F"
/>
</svg>
</span>
</div>
🧰 Tools
🪛 Biome (1.9.4)

[error] 93-93: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

// staffId: Digit.SessionStorage.get("UserIndividual")?.[0]?.id,
localityCode: selectedBoundaryCode,
reviewStatus: activeLink.code,
isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
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)

Simplify boolean expressions.

On lines 48, 51, and 77, ternary operators are used to return true or false from an expression, which can be replaced with the expression’s truthiness. This improves clarity:

// Line 48:
- isChildrenRequired: selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType ? true : false,
+ isChildrenRequired: !!(selectedLevel != null && selectedLevel?.code === lowestLevelBoundaryType),

// Line 51:
- enabled: selectedBoundaryCode && selectedProject ? true : false,
+ enabled: !!(selectedBoundaryCode && selectedProject),

// Line 77:
- enabled: selectedBoundaryCode ? true : false,
+ enabled: !!selectedBoundaryCode,

Also applies to: 51-51, 77-77

🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

return (
<React.Fragment>
{
props.isFetching || props.tableData.length === 0 ? <div style={{ height: props.infoDescription ? "38vh" : "52vh" }}> {props.isFetching ? <Loader /> : <NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} />} </div> : <DataTable
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)

Extract inline styles into CSS.

Inline styles can hinder maintainability in large codebases. Consider using a CSS class or a styled component for the height property.

sortIcon={<CustomSVG.SortUp width={"16px"} height={"16px"} fill={"#0b4b66"} />}
paginationRowsPerPageOptions={defaultPaginationValues}
fixedHeader={true}
fixedHeaderScrollHeight={props.infoDescription ? "32vh" : "47vh"}
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)

Consider making fixedHeaderScrollHeight configurable.

Currently, it's hardcoded to "32vh" or "47vh". Exposing this as a prop or retrieving it from a theme/config can improve reusability.

Comment on lines +82 to +83
<div className="ellipsis-cell" title={t(row?.status || "0")}>
{t(row?.noOfAttendees || "0")}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Tooltip shows incorrect field for attendees count

The tooltip should show the number of attendees (using row?.noOfAttendees) instead of the status, as this column specifically displays the attendee count. This mismatch creates confusing UX where hovering shows different information than what's displayed.

🔗 Analysis chain

Match the tooltip with the displayed text.

The tooltip uses row?.status, but the displayed text derives from row?.noOfAttendees. If the goal is to show the same info, align these references.

title={t(row?.status || "0")}
=>
title={t(row?.noOfAttendees || "0")}
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Get the complete file content to understand the context
cat health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/components/bill_inbox/billInboxTable.js

# Search for similar table implementations
rg -l "className=\"ellipsis-cell\"" --type js

# Look for row type definition or usage
rg "row\?" --type js health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/

Length of output: 10849

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants