-
Notifications
You must be signed in to change notification settings - Fork 42
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
base: console
Are you sure you want to change the base?
Conversation
#2065) HCMPRE-1717:: Load and store project details on Payments module initialization
…ents/DIGIT-Frontend into payment_view_attendance
attendance inbox in progress
* attendance inbox in progress * composer in progress * inboxserach composer replaced with custom inbox component
…ents/DIGIT-Frontend into payment_view_attendance
* 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
There was a problem hiding this 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
📒 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
: Usewindow.contextPath
instead of hardcoded/payments-ui
prefixThe 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 issueRemove 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 importsThe imports
useReducer
,useMemo
, anduse
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' hookThe 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 importinguseLocation
fromreact-router-dom
and using it to retrieve the location object.
51-51
: Simplify the boolean expressionThe 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 expressionSimilarly, 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 akey
prop to the Button component in theactionFields
arrayWhen 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 blockThe 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 theoffset
calculation inhandlePerRowsChange
The
offset
should be calculated using the updatedcurrentRowsPerPage
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 expressionThe 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 expressionThe 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 expressionSimplify 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 expressionRemove 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 inactionFields
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 inactionFields
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 inactionFields
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 thecatch
blockEmpty
catch
blocks can obscure errors and make debugging difficult. Consider adding error handling or logging within thecatch
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 thecatch
blockAdd 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 usingsetTimeout
for navigation after showing a toastUsing
setTimeout
to delay navigation can lead to unpredictable behavior. Instead, use a callback or theonClose
prop of theToast
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 messagesWhen 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 inuseEffect
hookThe comment
/// need to update dependency
suggests that the dependencies array might be incomplete. Ensure all external variables used inside theuseEffect
are included in the dependencies array to prevent potential issues.}, [AllIndividualsData, data]); /// need to update dependency
21-21
: 🧹 Nitpick (assertive)Remove debugging
console.log
statementThere 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 tolocation.state
Destructuring
fromCampaignSupervisor
fromlocal?.state || false
can cause issues iflocal.state
isnull
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 withwindow.contextPath
Accessing
window.contextPath
directly without checking if it exists can lead to runtime errors ifwindow.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 routesUsing inline arrow functions in the
component
prop ofPrivateRoute
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 codeThe 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 definitionsThe 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
: ConsolidateNoResultsFound
checksInstead 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
: ConsolidateNoResultsFound
checksYou 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 duplicationSeveral columns have similar structures. Consider creating a helper function to generate the column definitions to improve maintainability.
114-124
: Extract tab configurations into constantsTo enhance readability and ease future changes, consider moving the tab configuration into a constant.
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"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix session storage operations and maintain consistency.
Several issues found in session storage operations:
AttendandeData
is being set without a value- There's a typo in "AttendandeData" (should be "AttendanceData")
- Inconsistent usage of
Digit
vswindow.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.
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"); |
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> | ||
); |
There was a problem hiding this comment.
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"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
referenceIds: ["1dd5cd57-61d5-4c41-9861-769bb8735617"], | |
referenceIds: project?.[0]?.id ? [project[0].id] : [], |
title: '', | ||
}); | ||
const [currentPage, setCurrentPage] = useState(1); | ||
const [rowsPerPage, setRowsPerPage] = useState(5); |
There was a problem hiding this comment.
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.
useEffect(() => { | ||
if (BillData) { | ||
setTableData(BillData.bills); | ||
setTotalCount(BillData?.pagination?.totalCount); | ||
} | ||
}, [BillData]) |
There was a problem hiding this comment.
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.
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'); |
There was a problem hiding this comment.
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');
const iconHeight = props?.height || 262; | ||
const iconWidth = props?.width || 336; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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}> |
There was a problem hiding this comment.
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.
<div className={`digit-no-data-found ${props?.className ? props?.className : ""}`} style={props?.style}> | |
<div className={`digit-no-data-found ${props.className || ''}`} style={props.style}> |
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> | ||
); |
There was a problem hiding this comment.
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.
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)
There was a problem hiding this 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 issueRemove 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
andwidth
, andprops
is always defined, you can accessprops.height
andprops.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 ifprops.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 necessaryaria
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
📒 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 suggestionSimplify project initialization logic.
The current implementation has unnecessary complexity:
- Empty array mapping is redundant as it will never be used
- Variable declaration uses
let
when it should beconst
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 suggestionImprove 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 commentThe 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)
const onChangeId = (value) => { | ||
setBoundary(value); | ||
if (value?.boundaryType === "DISTRICT") { | ||
setIsDistrictSelected(true); // Set flag if district is selected | ||
} | ||
}; |
There was a problem hiding this comment.
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.
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"); | |
}; |
<Toast | ||
style={{ zIndex: 10001 }} | ||
label={showToast.label} | ||
type={showToast.key} | ||
// error={showToast.key === "error"} | ||
transitionTime={showToast.transitionTime} | ||
onClose={() => setShowToast(null)} | ||
/> | ||
)} |
There was a problem hiding this comment.
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?
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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"); |
There was a problem hiding this comment.
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.
const billScreen = location.pathname.includes("project-and-aggregation-selection"); | |
const isBillAggregationScreen = location.pathname.includes("project-and-aggregation-selection"); |
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"); | ||
}, []); |
There was a problem hiding this comment.
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.
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"; |
There was a problem hiding this comment.
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.
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"; |
There was a problem hiding this comment.
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";
const triggerMusterRollApprove = (filterData, status, totalRows, totalNext, selectedProject) => { | ||
try { | ||
setChildrenDataLoading(true); | ||
fetchRegisters.mutateAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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( |
import CustomInboxSearchLinks from "./custom_comp/link_section"; | ||
import CustomSearchComponent from "./custom_comp/search_section"; |
There was a problem hiding this comment.
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"), |
There was a problem hiding this comment.
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.
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"), |
* 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]>
There was a problem hiding this 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 suggestionAvoid using
setTimeout
for navigation after showing toastUsing
setTimeout
to delay navigation can lead to unpredictable behavior if the UI experiences lag. Consider using theonClose
callback of theToast
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
stateIn
handleClearFilter
, theboundary
state is reset usingsetBoundary("")
, whereas in other parts of the codesetBoundary(null)
is used (e.g., lines 31 and 40). This inconsistency might lead to unexpected behavior. Consider usingnull
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 anonClick
handler should support keyboard interactions for accessibility. AddonKeyPress
andtabIndex={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 anonClick
handler should support keyboard interactions for accessibility. AddtabIndex={0}
andonKeyPress
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 includerole="img"
and eitheraria-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 issueFix the spelling of
updateSeeeionStorage
The prop
updateSeeeionStorage
appears to be misspelled. Correcting it toupdateSessionStorage
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 suggestionRemove unused and invalid imports
The imports
useReducer
,useMemo
, anduse
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 issueDefine '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 importinguseLocation
fromreact-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 onDigit.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 updateshowGenerateBillAction
, 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 theButton
component in theactionFields
arrayWhen 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 issueEnsure 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 usesrow?.approvedBy
orrow?.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 issueEnsure tooltip content matches displayed data
In the "Attendees" column, the tooltip uses
row?.status
, while the displayed text usesrow?.noOfAttendees
. To provide consistent information, the tooltip should referencerow?.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 theBillInboxTable
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
📒 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 beupdateSessionStorage
to reflect the intended functionality.
7-7
: Add null check before accessing 'boundaryHierarchyOrder'Ensure that
Digit.SessionStorage.get("boundaryHierarchyOrder")
is notnull
orundefined
before calling.map
to prevent runtime errors.
35-48
: Remove commented-out code to maintain code cleanlinessLarge 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 codeThere 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 propertiesWhen 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 callshandleDropdownOptions
, you might consolidate these functions or rename them for clarity.
166-174
: Optimize the boundary item checkUse
includes
instead offind
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 classesInline 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 comparisonReplace 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 childrenComponents 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 reassignedThe variable
datak
is never reassigned. Usingconst
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 initializedThe 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 dataWhen mapping over
data[0].individualEntries
, ensure thatattendanceSummary
andentry.individualId
are defined to prevent potential runtime errors.Please verify that
attendanceSummary
andentry.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 durationThe 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 betweenstartDate
andendDate
.Consider using a date library like
moment.js
ordate-fns
for accurate duration calculations if necessary.
397-398
:⚠️ Potential issueEnsure 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 issueEnsure 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 thesetTimeout
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 renamingbillScreen
for clarity.The variable
billScreen
could be renamed to better reflect its purpose. A more descriptive name likeisBillAggregationScreen
orisBillSelectionFlow
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 missingkey
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 unuseduse
import from React.There is no
use
named export fromreact
, 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
andCustomSearchComponent
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, thetry...catch
block won't catch errors unless youawait
the promise. Consider makingtriggerMusterRollApprove
an async function andawait
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 oflodash
.The
_
import fromlodash
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 removedThe 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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"; |
There was a problem hiding this comment.
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"} |
There was a problem hiding this comment.
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"}
const resetTable = () => { | ||
setchildrenData([]); | ||
setFilterCriteria(null); | ||
// setSelectedProject({}); | ||
setCard(false); | ||
}; |
There was a problem hiding this comment.
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
There was a problem hiding this 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
📒 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.
- Remove unused imports:
useMemo
,InboxSearchComposer
- 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.
- The
enabled
flag can be simplified- The
select
function should validate the response- 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
tonull
instead of an empty string to match the initial state.
98-113
: Improve component error handling and accessibility.
- Add an error boundary for better error handling
- Add proper ARIA attributes for accessibility
- 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 clarityReassigning the function parameter
value
withinhandleDaysWorkedChange
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
: AddkeyField
prop toDataTable
for unique row identificationTo ensure each row is uniquely identified and to avoid potential rendering issues, specify the
keyField
prop in theDataTable
component. Set it to the unique identifier in your data, such asworkerId
.health/micro-ui/web/micro-ui-internals/packages/modules/health-payments/src/pages/employee/index.js (5)
19-19
: Handle potential undefinedstate
inuseLocation
Destructuring from
local?.state || false
may cause an error because destructuring properties fromfalse
is invalid iflocal.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 clarityThe 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 positioningThe
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 errorsAccessing
window.contextPath
without optional chaining could cause a runtime error ifwindow.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 performanceUsing inline functions like
component={() => <Component />}
inPrivateRoute
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 nameThe variable
billScreen
could be renamed to better reflect its purpose, improving code readability. Consider usingisBillAggregationScreen
orisBillSelectionFlow
.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 buttonsEach element in the
actionFields
array should have a uniquekey
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 mappingMapping 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 codeThere 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 importsThe imports
useReducer
,useMemo
, anduse
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' hookThe variable
location
is used but not defined in this scope. If you intend to access the route's state, consider importinguseLocation
fromreact-router-dom
and using it to retrieve the location object.
48-48
: Use strict equality and optional chainingConsider using triple equals (
===
) for strict comparison to avoid type coercion pitfalls. Also, use optional chaining onDigit.SessionStorage.get("paymentInbox")
to handle cases where the session storage may not have thepaymentInbox
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 expressionThe 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 expressionInstead of using a ternary operator returning
true
orfalse
, you can assign the condition directly toenabled
.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 expressionAssign 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 akey
prop to theButton
component in theactionFields
arrayWhen 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 blockThe 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 variablefilterCriteria
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 importuseQueryClient
The
useQueryClient
function imported fromreact-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 directlyThe handlers
handlePageChange
andhandlePerRowsChange
simply invoke the functions passed via props without adding any additional logic. You can simplify the code by passing the prop functions directly to theDataTable
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 issueEnsure consistency between tooltip and displayed text
In the table cell, the
title
attribute usesrow?.markby
, whereas the displayed text usesrow?.approvedBy
orrow?.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 issueEnsure tooltip matches displayed data
The
title
attribute usesrow?.status
, while the displayed text usesrow?.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.
useEffect(() => { | ||
refetchBill(); | ||
}, [billID, dateRange, limitAndOffset]) |
There was a problem hiding this comment.
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.
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 }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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
There was a problem hiding this 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
📒 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 displayingrow?.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 usesrow?.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 issueUpdate 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 issueFix the Prop Name:
updateSeeeionStorage
The prop
updateSeeeionStorage
appears to have a misspelling. It should likely beupdateSessionStorage
.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 issueAdd 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
andhandleDropdownOptions
The function
handleButtonClick
immediately callshandleDropdownOptions
after invokingonChange
. 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 usehandleSelectionChange
.Likely invalid or redundant comment.
87-91
:⚠️ Potential issueAdd Null Checks for Boundary Data Access
When accessing
childrenData[0]?.boundary[0]
, there's a possibility thatboundary
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 issueReset
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 oflet
The variable
datak
is not reassigned after initialization. Useconst
instead oflet
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 issueImprove Accessibility for Clickable Span
The
<span>
element with anonClick
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 issueUpdate 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 issueAdd 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 touseEffect
HookThe
useEffect
hook depends onsetProjectSelected
. Include it in the dependency array to prevent potential issues.Apply this diff:
- }, []); + }, [setProjectSelected]);
55-60
: Add Missing Dependencies to SeconduseEffect
HookSimilarly, include
project.length
andsetProject
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"} |
There was a problem hiding this comment.
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.
fixedHeaderScrollHeight={"32vh"} | |
fixedHeaderScrollHeight={"45vh"} |
display: flex; | ||
flex-direction: column; | ||
gap: 24px; | ||
margin-bottom: 2.5rem; | ||
|
||
|
||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
There was a problem hiding this comment.
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.
max-width: 100%; | ||
overflow: auto; | ||
margin: 0px; | ||
height: 75vh; | ||
} |
There was a problem hiding this comment.
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.
.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; | |
} |
border: 1px solid #e0e0e0; padding: 6px; margin-bottom: 10px; cursor: pointer; | ||
} |
There was a problem hiding this comment.
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.
border-right: 2px solid #787878; | ||
width: 100%; | ||
text-align: start; | ||
} |
There was a problem hiding this comment.
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.
const handleInsertion = (boundaryType, newValue) => { | ||
setValue((prevState) => { | ||
const newState = { ...prevState }; | ||
const currentBoundary = newState[boundaryType] || []; | ||
if (!currentBoundary.find((item) => item === newValue)) { | ||
newState[boundaryType] = [...currentBoundary, newValue]; | ||
} |
There was a problem hiding this comment.
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.
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]; | |
} |
// 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> | ||
); | ||
}; |
There was a problem hiding this comment.
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.
// 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} |
There was a problem hiding this comment.
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.
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)
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]); | ||
} |
There was a problem hiding this comment.
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.
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); | |
} | |
} |
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> |
There was a problem hiding this comment.
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;
}
There was a problem hiding this 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
📒 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 asisBillAggregationScreen
.
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 issueAdd 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 tolocation.state
Destructuring
fromCampaignSupervisor
fromlocation.state || false
can cause issues iflocation.state
isnull
or not an object. Consider providing a default object to prevent errors.
35-35
: Correct the typo in state variable nameThe state variable
loding
appears to be a typo. It should beloading
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 expressionSimplify 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 expressionSimplify 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 expressionSimplify 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 expressionSimplify 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 updateThe comment
/// need to update dependency
indicates that there might be a missing dependency in theuseEffect
hook. Ensure all necessary dependencies are included to prevent potential bugs.
397-398
: Return the loader component to display itThe
<LoaderComponent />
inside theif
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 incatch
blockEmpty
catch
blocks can hide errors and make debugging difficult. Add error handling or logging within thecatch
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 incatch
blockEmpty
catch
blocks can hide errors and make debugging difficult. Add error handling or logging within thecatch
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 uniquekey
prop to elements inactionFields
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 uniquekey
prop to elements inactionFields
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 uniquekey
prop to elements inactionFields
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 importsThe imports
useReducer
,useMemo
, anduse
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' hookThe 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 importinguseLocation
fromreact-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 expressionThe 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 expressionThe 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 expressionThe ternary operator can be simplified by directly assigning the truthiness of
selectedBoundaryCode
toenabled
.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 akey
prop to theButton
inactionFields
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 suggestionHandle 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 thecatch
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 importuseQueryClient
The
useQueryClient
function imported fromreact-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 directlyThe 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
: AddpropTypes
anddefaultProps
for the componentTo enhance maintainability and catch potential issues early, consider defining
propTypes
anddefaultProps
for theBillInboxTable
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 textThe
title
attribute usesrow?.markby
, whereas the displayed text usesrow?.approvedBy
orrow?.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
androw?.markedBy
contain the correct data.
81-84
: Table cell shows attendee count but tooltip references statusThe tooltip uses
t(row?.status || "0")
, while the displayed text is derived fromt(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) { |
There was a problem hiding this comment.
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.
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"; |
There was a problem hiding this comment.
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.
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); | ||
}; |
There was a problem hiding this comment.
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.
There was a problem hiding this 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 issueCorrect the typo in state variable name
There's a typo in the state variable name
loding
. It should beloading
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 ofregisterNumber
.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 issueAdd 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 toastUsing
setTimeout
for delayed navigation can lead to unpredictable behavior. It's better to use theonClose
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 issueHandle errors appropriately in catch block
Empty
catch
blocks can hide errors and make debugging difficult. Please add error handling or logging within thecatch
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 issueHandle 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 issueEnsure safe access to
location.state
Destructuring
fromCampaignSupervisor
fromlocation.state || false
may lead to errors iflocation.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 issueHandle cases where
matchingIndividual
is undefinedIn the
getUserAttendanceSummary
function, ensure that whenmatchingIndividual
isundefined
, theindividualId
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 issueUpdate dependencies in the
useEffect
hookThe comment
/// need to update dependency
suggests missing dependencies in theuseEffect
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 anonClick
handler should support keyboard interactions for accessibility. AddonKeyPress
andtabIndex={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>
elementThe
<span>
element with anonClick
handler should support keyboard interactions and have appropriate accessibility attributes. Consider changing it to a<button>
or addingtabIndex
andonKeyPress
.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
stateIn
handleClearFilter
,setBoundary("")
is used to reset theboundary
state, while elsewheresetBoundary(null)
is used. For consistency and to avoid potential issues, consider usingnull
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 issueAdd
updateBoundaryFilters
to the dependency array inuseEffect
The
useEffect
usesupdateBoundaryFilters
but does not include it in the dependency array. This could lead to missed updates whenupdateBoundaryFilters
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 issueFix the spelling of
updateSeeeionStorage
The prop
updateSeeeionStorage
appears to be misspelled. Correcting it toupdateSessionStorage
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
📒 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 forBillBoundaryFilter
.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 issueSet
boundaryType
inonBoundaryChange
The
boundaryType
state is initialized but never updated. InhandleApplyFilter
,boundaryType
is compared but may not have the correct value. UpdateboundaryType
inonBoundaryChange
whenboundary
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 oraria-label
attribute. Includerole="img"
and provide descriptive text.Apply this diff to add a
<title>
androle="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
and75vh
may cause layout issues on different screen sizes. Consider usingmin-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.
- Consider destructuring specific props instead of using the spread operator for better code clarity.
- 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 suggestionAdd error handling and improve file download implementation.
The file download implementation needs several improvements:
- Add error handling
- Use a more descriptive default filename
- Add loading state management
- 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.
- Use
.forEach()
instead of.map()
for side effects.- 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; | ||
} | ||
|
There was a problem hiding this comment.
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.
}, | ||
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]); |
There was a problem hiding this comment.
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.
- Inline styles make the code harder to maintain. Consider moving them to CSS classes.
- The
project
variable is used in the columns but missing from theuseMemo
dependencies array.
Apply these changes:
- 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;
}
- 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)
<Toast | ||
style={{ zIndex: 10001 }} | ||
label={showToast.label} | ||
type={showToast.key} | ||
// error={showToast.key === "error"} | ||
transitionTime={showToast.transitionTime} | ||
onClose={() => setShowToast(null)} | ||
/> |
There was a problem hiding this comment.
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.
- Move inline style to CSS.
- 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;
}
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" | ||
/> : |
There was a problem hiding this comment.
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.
- The ternary expression for
showBottom
can be simplified. - The download action handler should be extracted into a separate function for better maintainability.
Apply these changes:
- Simplify boolean expression:
-showBottom={isLastRow ? false : true}
+showBottom={!isLastRow}
- 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.
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)
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}`; | ||
} |
There was a problem hiding this comment.
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.
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)); | |
} |
There was a problem hiding this 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
📒 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
: InitializeshowToast
with an Empty ObjectInitializing
showToast
asnull
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 ValidationBefore comparing
updatedValue
withprops.duration
, verify that both are valid numbers to avoid unintended results, especially ifupdatedValue
isNaN
.
80-95
:⚠️ Potential issueAdd Unique
key
Props to Elements in IterablesWhen rendering elements inside a list or array, such as within the
DataTable
, each element should have a uniquekey
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 issueConvert
updatedValue
to Number Before ValidationEnsure 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 reassigningvalue
.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 functionLikely 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 Variableloding
The state variable
loding
appears to be a typo. It should beloading
to reflect its purpose clearly.Apply this diff:
- const [loding, setLoding] = useState(false); + const [loading, setLoading] = useState(false);Also, update all occurrences of
loding
andsetLoding
throughout the file.
48-48
: Simplify Boolean Expression inenabled
PropertyYou can simplify the
enabled
property by directly using the truthiness ofregisterNumber
.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 forindividualIds
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 inenabled
ConfigurationSimplify 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 Uniquekey
Props to Elements Within ArraysWhen rendering elements conditionally inside an array (e.g., within
actionFields
), each top-level element should have a uniquekey
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 Emptycatch
BlockAn 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 Emptycatch
BlockSimilarly, 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 ofAttendanceData
.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 inuseEffect
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 thet
function withingetUserAttendanceSummary
, but it's missing from the dependency array. The suggested fix to includet
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.jsLength 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 suggestionRefactor 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 importsThe imports
useReducer
,useMemo
, anduse
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' hookThe 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 importinguseLocation
fromreact-router-dom
and using it to retrieve the location object.
55-55
: Simplify the boolean expressionThe 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 expressionYou 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 akey
prop to theButton
component in theactionFields
arrayWhen 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 issueCorrect the
offset
calculation inhandlePerRowsChange
The
offset
should be calculated using the updatedcurrentRowsPerPage
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 importuseQueryClient
The
useQueryClient
function imported fromreact-query
is not used in this file. Removing it will clean up the code.
18-24
: Simplify event handlers by passing prop functions directlyThe 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 issueCorrect mismatched properties in tooltips
The
title
attribute usesrow?.markby
, whereas the displayed text usesrow?.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 issueEnsure tooltips reflect the displayed data
The tooltip uses
t(row?.status || "0")
while the text displayst(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; |
There was a problem hiding this comment.
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.
export const defaultRowsPerPage= 10; | |
export const defaultRowsPerPage = 10; |
export const ScreenTypeEnum = Object.freeze({ | ||
BILL: "BILL", | ||
REGISTER: "REGISTER", | ||
}); |
There was a problem hiding this comment.
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.
export const ScreenTypeEnum = Object.freeze({ | |
BILL: "BILL", | |
REGISTER: "REGISTER", | |
}); | |
export const ScreenTypeEnum = Object.freeze({ | |
BILL: "BILL", | |
REGISTER: "REGISTER", | |
}); |
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"; |
There was a problem hiding this comment.
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.
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"; |
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, | ||
}) => { |
There was a problem hiding this comment.
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
};
/*(!planEmployee?.data || planEmployee?.data?.length === 0) */ | ||
!tableData ? ( | ||
<NoResultsFound text={t(`HCM_AM_NO_DATA_FOUND`)} /> | ||
) : ( |
There was a problem hiding this comment.
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
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. | ||
|
||
|
||
*/ | ||
|
There was a problem hiding this comment.
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...
*/
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); | ||
}; |
There was a problem hiding this comment.
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.
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); | |
}; |
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> | ||
); |
There was a problem hiding this comment.
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:
- 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} />
- 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.
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)
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 | ||
} | ||
}; |
There was a problem hiding this comment.
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.
- 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,
- 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.
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 | |
}); | |
} | |
}; |
const BillInboxTable = ({ | ||
...props | ||
}) => { |
There was a problem hiding this comment.
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: "",
};
There was a problem hiding this 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
📒 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 codeLikely invalid or redundant comment.
198-247
: 🧹 Nitpick (assertive)Clean up JSX rendering code.
- Use self-closing tags for components without children
- 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 suggestionImprove error handling and simplify complex conditions.
- The nested ternary operator for
localityCode
is hard to read- 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.
/** | ||
* 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. | ||
|
||
|
||
*/ |
There was a problem hiding this comment.
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...
*/
import React, { useEffect, useState } from "react"; | ||
|
||
import _ from "lodash"; |
There was a problem hiding this comment.
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.
import React, { useEffect, useState } from "react"; | |
import _ from "lodash"; | |
import React, { useEffect, useState } from "react"; |
There was a problem hiding this 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 issueDefine '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 importinguseLocation
fromreact-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
orfalse
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 suggestionAdd a
key
prop to the<Button>
component inactionFields
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 suggestionHandle 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 issueFix 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 issueInitialize
boundaryType
correctlyThe state variable
boundaryType
is initialized but never updated. Ensure thatboundaryType
is set appropriately when the boundary changes to prevent potential undefined comparisons.Update the
onBoundaryChange
method to setboundaryType
: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 issueAdd null checks before comparing 'boundaryType' and 'selectedLevel.code'
To prevent potential runtime errors, ensure that
boundaryType
andselectedLevel.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 suggestionEnhance accessibility by adding keyboard event handlers
The
<div>
element with anonClick
handler should support keyboard interactions for better accessibility. AddonKeyPress
andtabIndex={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 suggestionAdd keyboard event for accessibility on clickable
<span>
The
<span>
with anonClick
handler should support keyboard interactions. AddonKeyPress
andtabIndex={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 oraria-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
stateIn
handleClearFilter
, theboundary
state is reset using an empty string, whereas elsewherenull
is used. Consider usingnull
consistently.Apply this diff:
- setBoundary(""); // Clear the boundary value + setBoundary(null); // Clear the boundary value
115-115
:⚠️ Potential issueFix typo in prop name
updateSeeeionStorage
The prop
updateSeeeionStorage
appears to be misspelled. Correct it toupdateSessionStorage
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
📒 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 issueEnsure 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 parametersEnsure 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" -ILength 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 issueCheck 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`); }
<Toast | ||
style={{ zIndex: 10001 }} | ||
label={showToast.label} | ||
type={showToast.key} | ||
// error={showToast.key === "error"} | ||
transitionTime={showToast.transitionTime} | ||
onClose={() => setShowToast(null)} | ||
/> | ||
)} |
There was a problem hiding this comment.
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"); |
There was a problem hiding this comment.
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");
); | ||
}; |
There was a problem hiding this comment.
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,
};
There was a problem hiding this 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
⛔ 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" /> |
There was a problem hiding this comment.
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.
- Use the latest stable version:
@egovernments/[email protected]
🔗 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" /> |
There was a problem hiding this comment.
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.
<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
There was a problem hiding this 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.
- The
InboxSearchComposer
component is imported but never used- 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 suggestionAdd 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 suggestionImprove API configuration robustness.
- The boolean expression can be simplified
- 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 suggestionPrevent 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 issueFix 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
📒 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 issueAdd a null check to avoid runtime errors.
Digit.SessionStorage.get("boundaryHierarchyOrder")
might returnnull
orundefined
, 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 2Length 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 suggestionImprove 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 suggestionAdd 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 ofboundaryType
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 issueCorrect the prop name from
updateSeeeionStorage
toupdateSessionStorage
.This minor spelling error could lead to confusion for other developers.
- updateSeeeionStorage={(newSelectedValues) => { + updateSessionStorage={(newSelectedValues) => {Likely invalid or redundant comment.
53-61
: 🛠️ Refactor suggestionUse a consistent reset value for
boundary
.Currently,
handleClearFilter
setsboundary
to an empty string, whereas elsewhere it's set tonull
. 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 valueLikely 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 issueAdd 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 issueDefine or remove the
location
reference.Using
location.state
without importinguseLocation
or otherwise defininglocation
can cause a runtime error. If you intend to access route state, import and useuseLocation
; otherwise, remove this line.- const { fromViewScreen } = location.state || false; + // Either remove this or define location properly via useLocation or other meansLikely 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 issueEnsure consistent naming of marker or approver.
The title attribute references
row?.markby
, while the displayed text referencesrow?.approvedBy
orrow?.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.
const CustomInboxTable = ({ | ||
handleTabChange, | ||
rowsPerPage, | ||
isLoading, | ||
tableData, | ||
customHandleRowsPerPageChange, | ||
customHandlePaginationChange, | ||
totalCount, | ||
statusCount, | ||
selectedProject | ||
}) => { |
There was a problem hiding this comment.
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
<Link to={`/${window?.contextPath}/employee/payments/view-attendance?registerNumber=${row?.id}&boundaryCode=${row?.boundary}`}> | ||
{String(row?.id ? row?.id : t("ES_COMMON_NA"))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
<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"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clean up unused and invalid imports.
- Remove the invalid
use
import from React - 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
<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> |
There was a problem hiding this comment.
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)
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([]); | ||
|
There was a problem hiding this comment.
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.
<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> |
There was a problem hiding this comment.
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.
<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, |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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"} |
There was a problem hiding this comment.
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.
<div className="ellipsis-cell" title={t(row?.status || "0")}> | ||
{t(row?.noOfAttendees || "0")} |
There was a problem hiding this comment.
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
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
Improvements
Performance
UI/UX