Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

project type config simplified #1539

Merged
merged 3 commits into from
Oct 17, 2024
Merged

project type config simplified #1539

merged 3 commits into from
Oct 17, 2024

Conversation

Bhavya-egov
Copy link
Contributor

@Bhavya-egov Bhavya-egov commented Oct 17, 2024

Summary by CodeRabbit

  • New Features
    • Enhanced campaign management with improved handling of delivery rules and attributes.
    • Introduction of new components for managing custom attributes.
  • Bug Fixes
    • Streamlined error handling in campaign updates.
  • Refactor
    • Significant restructuring of data handling and processing logic across multiple components.
    • Improved state management and synchronization with fetched data.
    • Enhanced clarity in data transformations with new operator mappings.
  • Documentation
    • Updated function signatures and component structures for better clarity.

Copy link
Contributor

coderabbitai bot commented Oct 17, 2024

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

The pull request introduces substantial modifications across multiple components related to campaign management. Key changes include the refactoring of the reverseDeliveryRemap function in CampaignSummary.js and DeliveryDetailsSummary.js, improvements to state management in SetupCampaign.js, and the introduction of new components for managing delivery attributes in AddDeliverycontext.js. Additionally, the getDeliveryConfig.js utility function has been rewritten to enhance delivery processing. These updates aim to streamline data handling and improve user interactions within the campaign management interface.

Changes

File Change Summary
.../CampaignSummary.js Refactored reverseDeliveryRemap for improved data mapping; updated state management and toast handling.
.../CampaignUpdateSummary.js Modified handleRedirect for URL parameter changes; commented out summaryErrors processing.
.../DeliveryDetailsSummary.js Enhanced delivery data handling; added getDeliveryConfig utility; restructured reverseDeliveryRemap.
.../SetupCampaign.js Removed several functions for data remapping; added getOperatorSymbol; updated restructureData parameters.
.../AddDeliverycontext.js Introduced AddCustomAttributeField and AddIRSCustomAttributeField; improved attribute handling logic.
.../index.js Enhanced DeliverySetup for better delivery rule management; updated generateTabsData and campaignDataReducer.
.../getDeliveryConfig.js Rewritten generateMRDNConfig; streamlined attributeConfig and productConfig handling.

Possibly related PRs

  • fixed summary and campaign creation #1479: The CampaignSummary.js component has been modified to include significant changes to the reverseDeliveryRemap function, which is also a focus of the main PR, indicating a direct relationship in the handling of delivery data.
  • project type config simplified #1539: This PR also involves modifications to the CampaignSummary.js component, specifically in the reverseDeliveryRemap function and overall data handling logic, aligning closely with the changes made in the main PR.
  • added condition for update #1541: The UpdateBoundary.js component has been updated to enhance validation logic, which may relate to the overall data handling improvements seen in the main PR, particularly in the context of campaign updates and data integrity.

Suggested reviewers

  • nipunarora-eGov

Poem

🐇 In the meadow where data flows,
The rabbits hop where the logic grows.
With each refactor, a clearer path,
Campaigns thrive, and we do the math!
New fields and functions, oh what a sight,
In our burrow, everything feels right! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 21

🧹 Outside diff range comments (12)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignUpdateSummary.js (1)

Potential Missing Error Handling.

The commented-out useEffect hook for processing summaryErrors suggests that error handling logic may no longer be active. Our search did not find any new useEffect hooks or alternative mechanisms handling these errors.

  • File: health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignUpdateSummary.js
    • Commented-out error handling code indicates potential removal without replacement.
🔗 Analysis chain

Line range hint 93-123: Clarify new error handling approach and clean up commented code.

A significant portion of error handling logic in the useEffect hook has been commented out. This suggests a change in how errors are processed and displayed.

Please clarify the new approach for handling and displaying errors, particularly for deliveryErrors, targetErrors, facilityErrors, and userErrors. If this logic has been moved elsewhere or is no longer needed, consider removing the commented code to improve maintainability.

To verify the current error handling mechanism, you can run the following script:

This script will help identify where and how errors are currently being handled in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for new error handling logic in the codebase

# Search for error-related state updates
echo "Searching for error state updates:"
rg -n --type js 'set(Delivery|Target|Facility|User|Summary)Errors'

# Search for error-related useEffect hooks
echo "\nSearching for error-related useEffect hooks:"
rg -n --type js 'useEffect.*Errors'

# Search for error display components
echo "\nSearching for error display components:"
rg -n --type js '(Error|Toast).*component'

Length of output: 29621

🧰 Tools
🪛 Biome

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

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/deliveryRule/AddDeliverycontext.js (11)

Line range hint 58-73: Refactor duplicated selectValue functions to improve maintainability

The selectValue function in both AddAttributeField and AddCustomAttributeField components contains identical logic. Consider extracting this function into a shared utility function or a higher-order component to reduce code duplication and enhance maintainability.

Also applies to: 167-182


Line range hint 100-112: Consolidate duplicated selectOperator functions

The selectOperator function is duplicated in both AddAttributeField and AddCustomAttributeField. Refactoring this into a shared function will reduce redundancy and make future updates easier.

Also applies to: 195-207


Line range hint 138-160: Ensure safe access when updating attributes to prevent potential runtime errors

In the functions selectValue, selectOperator, and selectToFromValue, you access properties on the result of item.attributes.find(...) without checking if the result is defined. If find returns undefined, this will lead to a TypeError. Add a null check to ensure the attribute exists before attempting to set its properties.

Apply this diff to add null checks:

const updatedData = deliveryRules.map((item, index) => {
  if (item.ruleKey === deliveryRuleIndex) {
    const attributeItem = item.attributes.find((i) => i.key === attribute.key);
+   if (attributeItem) {
      attributeItem.value = val;
+   }
  }
  return item;
});

Also applies to: 230-252


Line range hint 475-478: Remove unused reviseIndexKeys function

The reviseIndexKeys function in AddAttributeWrapper is defined but never used. Removing unused code helps keep the codebase clean and improves readability.

Apply this diff to remove the unused function:

-  const reviseIndexKeys = () => {
-    setAttributes((prev) => prev.map((unit, index) => ({ ...unit, key: index + 1 })));
-  };

Line range hint 678-686: Clean up commented-out code for better readability

There is commented-out code in AddDeliveryRuleWrapper which can be removed to reduce clutter and improve code clarity.

Apply this diff to remove the commented code:

-  {/* {filteredDeliveryConfig?.projectType === "IRS-mz"?} */}
-  {/* {((!filteredDeliveryConfig?.deliveryAddDisable && deliveryRules?.length < 5) || isIRSDelivery) && ( */}
-  {/*   <Button */}
-  {/*     variation="secondary" */}
-  {/*     label={t(`CAMPAIGN_ADD_MORE_DELIVERY_BUTTON`)} */}
-  {/*     className={"add-rule-btn hover"} */}
-  {/*     icon={<AddIcon styles={{ height: "1.5rem", width: "1.5rem" }} fill={PRIMARY_COLOR} />} */}
-  {/*     onButtonClick={addMoreDelivery} */}
-  {/*   /> */}
-  {/* )} */}

Line range hint 370-375: Add cleanup function in useEffect to prevent memory leaks

In the useEffect hook within AddDeliveryRule, you set a timeout but do not clear it on component unmounting. This could lead to memory leaks. Include a cleanup function to clear the timeout.

Apply this diff to add the cleanup:

useEffect(() => {
  if (showToast) {
-   setTimeout(closeToast, 5000);
+   const timer = setTimeout(closeToast, 5000);
+   return () => clearTimeout(timer);
  }
}, [showToast]);

Line range hint 265-270: Use stable keys instead of index in list rendering

Using the index as a key in list rendering can lead to issues, especially if the list can change. Consider using a unique identifier like attribute.key for the key prop.

Apply this diff to update the key:

-  key={index}
+  key={item.key}

Line range hint 380-386: Add null check for prodRef.current in confirmResources

In the confirmResources function, you access prodRef.current without checking if it's defined. This could lead to errors if prodRef.current is null or undefined. Add a null check before using it.

Apply this diff to add a null check:

const confirmResources = () => {
+ if (!prodRef.current) {
+   setShowToast({ key: "error", label: "CAMPAIGN_PRODUCT_MISSING_ERROR" });
+   return;
+ }
  const isValid = prodRef.current.every((item) => item?.count !== null && item?.value !== null);
  if (!isValid) {
    setShowToast({ key: "error", label: "CAMPAIGN_PRODUCT_MISSING_ERROR" });
    return;
  }
  // Rest of the code...

Line range hint 578-581: Consider memoizing components to improve performance

Components like AddAttributeWrapper and AddDeliveryRule can benefit from React.memo to prevent unnecessary re-renders when their props have not changed.


Line range hint 58-73: Enhance input validation in selectValue function

The selectValue function's current validation may not handle all edge cases. For instance, entering multiple dots or non-numeric characters in rapid succession could bypass the validation. Consider using more robust validation methods or input masks to ensure only valid numeric input is accepted.

Also applies to: 167-182


Line range hint 138-160: Avoid mutating state directly

In your selectToFromValue and other functions, ensure you are not directly mutating state or its nested objects. Instead, create copies of the objects before making changes to prevent unexpected side effects.

Apply this diff to avoid direct mutation:

const updatedData = deliveryRules.map((item, index) => {
  if (item.ruleKey === deliveryRuleIndex) {
    const attributeItem = item.attributes.find((i) => i.key === attribute.key);
    if (attributeItem) {
+     const updatedAttribute = { ...attributeItem };
      if (range === "to") {
-       attributeItem.toValue = val;
+       updatedAttribute.toValue = val;
      } else {
-       attributeItem.fromValue = val;
+       updatedAttribute.fromValue = val;
      }
+     const updatedAttributes = item.attributes.map(attr => attr.key === attribute.key ? updatedAttribute : attr);
+     return { ...item, attributes: updatedAttributes };
    }
  }
  return item;
});

Also applies to: 230-252

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between f60f691 and 52bd9d6.

📒 Files selected for processing (7)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignSummary.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignUpdateSummary.js (3 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/DeliveryDetailsSummary.js (7 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/SetupCampaign.js (6 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/deliveryRule/AddDeliverycontext.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/deliveryRule/index.js (1 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/utils/getDeliveryConfig.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignSummary.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignUpdateSummary.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/DeliveryDetailsSummary.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/SetupCampaign.js (1)

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/deliveryRule/AddDeliverycontext.js (1)

Pattern **/*.js: check

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

Pattern **/*.js: check

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/utils/getDeliveryConfig.js (1)

Pattern **/*.js: check

🪛 Biome
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignSummary.js

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

'conditionParts' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


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

'rules' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


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

'attributes' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignUpdateSummary.js

[error] 217-217: 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] 237-237: 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] 257-257: 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)

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/DeliveryDetailsSummary.js

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

'conditionParts' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


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

'rules' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


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

'attributes' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/SetupCampaign.js

[error] 90-90: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 91-91: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

🔇 Additional comments (4)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/utils/getDeliveryConfig.js (1)

110-121: Ensure parseCondition handles all possible conditions

The parseCondition function is critical for correctly interpreting condition strings. In the attributeConfig mapping (lines 110-121), ensure that parseCondition robustly handles all expected condition formats to prevent runtime errors or incorrect configurations.

Please verify that parseCondition can handle conditions outside the current regex patterns and gracefully handles unexpected formats.

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/DeliveryDetailsSummary.js (1)

412-414: Verify the logic in onStepClick function

When currentStep equals 1, the function sets key to 8. Please confirm that this mapping is intentional and aligns with the expected navigation flow.

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/CampaignSummary.js (1)

88-97: Operator mapping is well-defined

The operatorMapping object is correctly defined, providing a clear mapping between operator symbols and their corresponding codes.

health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/SetupCampaign.js (1)

73-85: Addition of getOperatorSymbol function enhances code clarity

The getOperatorSymbol function effectively maps operator codes to their corresponding symbols, improving code readability and maintainability.

@@ -214,7 +214,7 @@ const CampaignUpdateSummary = (props) => {
},
cardHeader: { value: t("TARGET_DETAILS"), inlineStyles: { marginTop: 0, fontSize: "1.5rem" } },
cardSecondaryAction: noAction !== "false" && (
<div className="campaign-preview-edit-container" onClick={() => handleRedirect(2)}>
<div className="campaign-preview-edit-container" onClick={() => handleRedirect(4)}>
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Approve changes to handleRedirect function with a minor suggestion.

The updates to the handleRedirect function improve URL parameter handling using URLSearchParams. This approach is more robust and maintainable. However, consider extracting the URL parameter update logic into a separate function for better readability and reusability.

Consider refactoring the URL parameter update logic into a separate function:

const updateUrlParams = (params) => {
  const urlParams = new URLSearchParams(window.location.search);
  Object.entries(params).forEach(([key, value]) => urlParams.set(key, value));
  return `${window.location.pathname}?${urlParams.toString()}`;
};

const handleRedirect = (step, activeCycle) => {
  const params = { key: step, preview: false };
  if (activeCycle) params.activeCycle = activeCycle;
  const newUrl = updateUrlParams(params);
  history.push(newUrl);
};

This refactoring improves code organization and makes it easier to update URL parameters consistently across the component.

Also applies to: 237-237, 257-257

🧰 Tools
🪛 Biome

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


⚠️ Potential issue

Update redirection steps and improve accessibility for secondary actions.

The changes to the redirection steps in the onClick handlers for "target", "facility", and "user" sections appear to be intentional, likely reflecting a reorganization of the campaign setup process. However, there are accessibility concerns that need to be addressed.

To improve accessibility, add keyboard event handlers to these clickable div elements. Here's an example of how to modify the "target" section (apply similar changes to "facility" and "user" sections):

<div 
  className="campaign-preview-edit-container" 
  onClick={() => handleRedirect(4)}
  onKeyDown={(e) => e.key === 'Enter' && handleRedirect(4)}
  tabIndex={0}
  role="button"
  aria-label={t("CAMPAIGN_EDIT_TARGET")}
>
  <span>{t(`CAMPAIGN_EDIT`)}</span>
  <EditIcon />
</div>

These changes ensure that the edit actions are accessible to keyboard users, improving the overall accessibility of the component.

Also applies to: 237-237, 257-257

🧰 Tools
🪛 Biome

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

Comment on lines +105 to +138
conditionConfig: delivery.deliveries.map((deliveryItem, conditionIndex) => {
return {
disableDeliveryType: deliveryItem.deliveryStrategy === "DIRECT",
deliveryType: deliveryItem.deliveryStrategy,
attributeConfig: deliveryItem.doseCriteria.map((criteria, attrIndex) => {
const { operatorValue, value } = parseCondition(criteria.condition);

return {
key: `${conditionIndex + 1}-${attrIndex + 1}`,
label: "Custom",
attrType: criteria.attrType || "dropdown",
attrValue: value.variable,
operatorValue,
fromValue: Number(value.minValue),
toValue: Number(value.maxValue) - 1
};
}),
productConfig: deliveryItem.doseCriteria.flatMap((criteria, prodIndex) => {
return criteria.ProductVariants.map((variant, varIndex) => {
// if(variant?.productVariantId){
// productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });
// }
// const productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });

return {
key: `${conditionIndex + 1}-${varIndex + 1}`,
count: variant.quantity,
value: variant.productVariantId,
name: "Product Name"
};
});
})
};
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve variable naming for clarity

The usage of delivery.deliveries may cause confusion due to repetitive naming. Consider renaming variables to enhance readability. For example, renaming the inner deliveries to deliveryItems or subDeliveries can make the code more understandable.

Apply this suggestion for better code clarity:

-        conditionConfig: delivery.deliveries.map((deliveryItem, conditionIndex) => {
+        conditionConfig: delivery.subDeliveries.map((deliveryItem, conditionIndex) => {

Ensure that all occurrences of delivery.deliveries are updated accordingly.

Committable suggestion was skipped due to low confidence.

const deliveryConfig = ({ data, projectType }) => {
switch (projectType) {
case "MR-DN":
return generateMRDNConfig(data?.cycles?.[0]?.deliveries, projectType);
return generateMRDNConfig(data?.cycles, projectType);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unnecessary parameter projectType

In the deliveryConfig function (line 147), generateMRDNConfig is called with data?.cycles and projectType, but the generateMRDNConfig function definition only accepts a single deliveries parameter. Passing projectType is unnecessary and could lead to confusion.

Apply the following change to remove the extraneous argument:

-      return generateMRDNConfig(data?.cycles, projectType);
+      return generateMRDNConfig(data?.cycles);
📝 Committable suggestion

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

Suggested change
return generateMRDNConfig(data?.cycles, projectType);
return generateMRDNConfig(data?.cycles);

Comment on lines +159 to +168
code: data?.code,
projectType: data?.code,
attrAddDisable: data?.attrAddDisable || false,
deliveryAddDisable: data?.deliveryAddDisable || false,
customAttribute: data?.customAttribute || true,
productCountHide: data?.productCountHide || false,
eligibilityCriteria: data?.eligibilityCriteria,
dashboardUrls: data?.dashboardUrls,
taskProcedure: data?.taskProcedure,
resources: data?.resources,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential undefined properties in convertToConfig

In the convertToConfig function (lines 159-168), several properties are accessed from data, such as beneficiaryType, eligibilityCriteria, dashboardUrls, taskProcedure, and resources. If these properties are undefined, it may lead to unintended behavior.

Consider providing default values to ensure stability:

       return {
         beneficiaryType: data?.beneficiaryType || "", 
         code: data?.code || "",
         projectType: data?.code || "",
         attrAddDisable: data?.attrAddDisable || false,
         deliveryAddDisable: data?.deliveryAddDisable || false,
         customAttribute: data?.customAttribute || true,
         productCountHide: data?.productCountHide || false,
         eligibilityCriteria: data?.eligibilityCriteria || [],
         dashboardUrls: data?.dashboardUrls || [],
         taskProcedure: data?.taskProcedure || {},
         resources: data?.resources || [],
📝 Committable suggestion

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

Suggested change
code: data?.code,
projectType: data?.code,
attrAddDisable: data?.attrAddDisable || false,
deliveryAddDisable: data?.deliveryAddDisable || false,
customAttribute: data?.customAttribute || true,
productCountHide: data?.productCountHide || false,
eligibilityCriteria: data?.eligibilityCriteria,
dashboardUrls: data?.dashboardUrls,
taskProcedure: data?.taskProcedure,
resources: data?.resources,
beneficiaryType: data?.beneficiaryType || "",
code: data?.code || "",
projectType: data?.code || "",
attrAddDisable: data?.attrAddDisable || false,
deliveryAddDisable: data?.deliveryAddDisable || false,
customAttribute: data?.customAttribute || true,
productCountHide: data?.productCountHide || false,
eligibilityCriteria: data?.eligibilityCriteria || [],
dashboardUrls: data?.dashboardUrls || [],
taskProcedure: data?.taskProcedure || {},
resources: data?.resources || [],

Comment on lines +101 to +142
const generateMRDNConfig = (deliveries) => {
const deliveryConfig = deliveries.map((delivery, deliveryIndex) => {
return {
delivery: delivery.id,
conditionConfig: delivery.deliveries.map((deliveryItem, conditionIndex) => {
return {
disableDeliveryType: deliveryItem.deliveryStrategy === "DIRECT",
deliveryType: deliveryItem.deliveryStrategy,
attributeConfig: deliveryItem.doseCriteria.map((criteria, attrIndex) => {
const { operatorValue, value } = parseCondition(criteria.condition);

return {
key: `${conditionIndex + 1}-${attrIndex + 1}`,
label: "Custom",
attrType: criteria.attrType || "dropdown",
attrValue: value.variable,
operatorValue,
fromValue: Number(value.minValue),
toValue: Number(value.maxValue) - 1
};
}),
productConfig: deliveryItem.doseCriteria.flatMap((criteria, prodIndex) => {
return criteria.ProductVariants.map((variant, varIndex) => {
// if(variant?.productVariantId){
// productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });
// }
// const productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });

return {
key: `${conditionIndex + 1}-${varIndex + 1}`,
count: variant.quantity,
value: variant.productVariantId,
name: "Product Name"
};
});
})
};
})
};
});
return deliveryConfig;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid hardcoding product names and remove commented-out code

In the generateMRDNConfig function, within the productConfig construction (lines 123-135), the product name is hardcoded as "Product Name". This may lead to incorrect product display and hinder future scalability. Instead, consider retrieving the product name dynamically from the variant object, assuming it contains a name property.

Additionally, there is commented-out code related to useProductVariantSearch. It's a good practice to remove such code to maintain code cleanliness and readability.

Apply the following changes to address these issues:

-              // if(variant?.productVariantId){
-              //   productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });
-              // }
-              // const productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });

               return {
                 key: `${conditionIndex + 1}-${varIndex + 1}`,
                 count: variant.quantity,
                 value: variant.productVariantId,
-                name: "Product Name"
+                name: variant.name || "Unknown Product"
               };
📝 Committable suggestion

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

Suggested change
const generateMRDNConfig = (deliveries) => {
const deliveryConfig = deliveries.map((delivery, deliveryIndex) => {
return {
delivery: delivery.id,
conditionConfig: delivery.deliveries.map((deliveryItem, conditionIndex) => {
return {
disableDeliveryType: deliveryItem.deliveryStrategy === "DIRECT",
deliveryType: deliveryItem.deliveryStrategy,
attributeConfig: deliveryItem.doseCriteria.map((criteria, attrIndex) => {
const { operatorValue, value } = parseCondition(criteria.condition);
return {
key: `${conditionIndex + 1}-${attrIndex + 1}`,
label: "Custom",
attrType: criteria.attrType || "dropdown",
attrValue: value.variable,
operatorValue,
fromValue: Number(value.minValue),
toValue: Number(value.maxValue) - 1
};
}),
productConfig: deliveryItem.doseCriteria.flatMap((criteria, prodIndex) => {
return criteria.ProductVariants.map((variant, varIndex) => {
// if(variant?.productVariantId){
// productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });
// }
// const productName = useProductVariantSearch({ variantId: variant.productVariantId, tenantId: "mz" });
return {
key: `${conditionIndex + 1}-${varIndex + 1}`,
count: variant.quantity,
value: variant.productVariantId,
name: "Product Name"
};
});
})
};
})
};
});
return deliveryConfig;
};
const generateMRDNConfig = (deliveries) => {
const deliveryConfig = deliveries.map((delivery, deliveryIndex) => {
return {
delivery: delivery.id,
conditionConfig: delivery.deliveries.map((deliveryItem, conditionIndex) => {
return {
disableDeliveryType: deliveryItem.deliveryStrategy === "DIRECT",
deliveryType: deliveryItem.deliveryStrategy,
attributeConfig: deliveryItem.doseCriteria.map((criteria, attrIndex) => {
const { operatorValue, value } = parseCondition(criteria.condition);
return {
key: `${conditionIndex + 1}-${attrIndex + 1}`,
label: "Custom",
attrType: criteria.attrType || "dropdown",
attrValue: value.variable,
operatorValue,
fromValue: Number(value.minValue),
toValue: Number(value.maxValue) - 1
};
}),
productConfig: deliveryItem.doseCriteria.flatMap((criteria, prodIndex) => {
return criteria.ProductVariants.map((variant, varIndex) => {
return {
key: `${conditionIndex + 1}-${varIndex + 1}`,
count: variant.quantity,
value: variant.productVariantId,
name: variant.name || "Unknown Product"
};
});
})
};
})
};
});
return deliveryConfig;
};

Comment on lines 121 to 124
if (attr?.operator?.code === "IN_BETWEEN") {
return `${attr.toValue} <= ${attr.attribute.code} < ${attr.fromValue}`;
} else {
return `${attr?.attribute?.code}${getOperatorSymbol(attr?.operator?.code)}${attr?.value}`;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential logical error in IN_BETWEEN condition

In the IN_BETWEEN operator handling, the fromValue and toValue may be used incorrectly. The current condition is:

return `${attr.toValue} <= ${attr.attribute.code} < ${attr.fromValue}`;

This could lead to incorrect evaluations. Typically, for an "in between" condition, it should be:

return `${attr.fromValue} <= ${attr.attribute.code} <= ${attr.toValue}`;

Apply this diff to correct the condition:

- return `${attr.toValue} <= ${attr.attribute.code} < ${attr.fromValue}`;
+ return `${attr.fromValue} <= ${attr.attribute.code} <= ${attr.toValue}`;

Please verify that fromValue and toValue are correctly assigned.

Comment on lines 86 to 146
function restructureData(data, cycle, DeliveryConfig, projectType) {
const tt = DeliveryConfig?.find((e) => e.code === String(projectType));

if (tt) {
delete tt.cycles; // Remove old cycles
delete tt.resources; // Remove old resources
}

const resourcesMap = new Map();

const cycles = data.map(cycle => ({
mandatoryWaitSinceLastCycleInDays: null,
startDate: Digit.Utils.pt.convertDateToEpoch(cycle?.cycleData?.[0]?.fromDate),
endDate: Digit.Utils.pt.convertDateToEpoch(cycle?.cycleData?.[0]?.toDate),
id: parseInt(cycle.cycleIndex, 10),
deliveries: cycle.deliveries.map(delivery => ({
id: parseInt(delivery.deliveryIndex, 10),
deliveryStrategy: delivery.deliveryStrategy || "DIRECT",
mandatoryWaitSinceLastDeliveryInDays: null,
doseCriteria: delivery.deliveryRules.map(rule => {
// Consolidate product variants for the resources array
rule.products.forEach(product => {
if (resourcesMap.has(product.value)) {
resourcesMap.get(product.value).count += product.count;
} else {
resourcesMap.set(product.value, {
productVariantId: product.value,
isBaseUnitVariant: false,
name: product.name
});
}
});

// Build the condition string, handling IN_BETWEEN separately
const conditions = rule.attributes.map(attr => {
if (attr?.operator?.code === "IN_BETWEEN") {
return `${attr.toValue} <= ${attr.attribute.code} < ${attr.fromValue}`;
} else {
return `${attr?.attribute?.code}${getOperatorSymbol(attr?.operator?.code)}${attr?.value}`;
}
});

return {
condition: conditions.join(" and "),
ProductVariants: rule.products.map(product => ({
productVariantId: product.value,
name: product.name
}))
};
})
}))
}));

const resources = Array.from(resourcesMap.values());

if (tt) {
tt.cycles = cycles;
tt.resources = resources;
}
return [tt];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring restructureData for improved maintainability

The restructureData function is quite lengthy and handles multiple responsibilities, including data transformation, condition building, and resource mapping. Refactoring it into smaller, focused functions can enhance readability and maintainability.

For example, you could extract the condition-building logic into a separate function.

🧰 Tools
🪛 Biome

[error] 90-90: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 91-91: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

Comment on lines 90 to 91
delete tt.cycles; // Remove old cycles
delete tt.resources; // Remove old resources
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid using the delete operator for better performance

Using the delete operator can negatively impact performance. Consider setting the properties to undefined or creating a new object without the unwanted properties.

Apply this diff to set the properties to undefined:

- delete tt.cycles;   // Remove old cycles
- delete tt.resources;  // Remove old resources
+ tt.cycles = undefined;   // Remove old cycles
+ tt.resources = undefined;  // Remove old resources

Alternatively, create a new object excluding the unwanted properties:

- const tt = DeliveryConfig?.find((e) => e.code === String(projectType));
+ const ttOriginal = DeliveryConfig?.find((e) => e.code === String(projectType));
+ const { cycles, resources, ...tt } = ttOriginal || {};
📝 Committable suggestion

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

Suggested change
delete tt.cycles; // Remove old cycles
delete tt.resources; // Remove old resources
tt.cycles = undefined; // Remove old cycles
tt.resources = undefined; // Remove old resources
🧰 Tools
🪛 Biome

[error] 90-90: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 91-91: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

Comment on lines 457 to 458
const temp = restructureData(totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule , totalFormData?.HCM_CAMPAIGN_CYCLE_CONFIGURE?.cycleConfigure , DeliveryConfig);
payloadData.deliveryRules = temp?.[0];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Missing projectType parameter in restructureData function call

The restructureData function now expects four parameters. In this call, the projectType parameter is missing, which may result in errors.

Apply this diff to include the projectType:

- const temp = restructureData(totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule, totalFormData?.HCM_CAMPAIGN_CYCLE_CONFIGURE?.cycleConfigure, DeliveryConfig);
+ const temp = restructureData(
+   totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule,
+   totalFormData?.HCM_CAMPAIGN_CYCLE_CONFIGURE?.cycleConfigure,
+   DeliveryConfig,
+   totalFormData?.HCM_CAMPAIGN_TYPE?.projectType?.code
+ );
📝 Committable suggestion

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

Suggested change
const temp = restructureData(totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule , totalFormData?.HCM_CAMPAIGN_CYCLE_CONFIGURE?.cycleConfigure , DeliveryConfig);
payloadData.deliveryRules = temp?.[0];
const temp = restructureData(
totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule,
totalFormData?.HCM_CAMPAIGN_CYCLE_CONFIGURE?.cycleConfigure,
DeliveryConfig,
totalFormData?.HCM_CAMPAIGN_TYPE?.projectType?.code
);
payloadData.deliveryRules = temp?.[0];

Comment on lines 529 to 531
const temp = restructureData(totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule, totalFormData?.HCM_CAMPAIGN_CYCLE_CONFIGURE?.cycleConfigure , DeliveryConfig , totalFormData?.HCM_CAMPAIGN_TYPE?.projectType?.code);
payloadData.deliveryRules = temp;
// payloadData.deliveryRules = totalFormData?.HCM_CAMPAIGN_DELIVERY_DATA?.deliveryRule;
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Inconsistent Assignments to payloadData.deliveryRules Detected

The verification confirms that payloadData.deliveryRules is assigned inconsistently across the codebase, which may lead to unexpected behavior. Specifically:

  • In SetupCampaign.js:

    • payloadData.deliveryRules = temp;
    • payloadData.deliveryRules = temp?.[0];
    • payloadData.deliveryRules = [temp?.[0]];
  • In UpdateBoundary.js:

    • payloadData.deliveryRules = CampaignData?.CampaignDetails?.[0]?.deliveryRules;

Please standardize the assignment structure of payloadData.deliveryRules to ensure consistent behavior.


🔗 Analysis chain

Inconsistent assignment to payloadData.deliveryRules

There are inconsistencies in how payloadData.deliveryRules is assigned:

  • Line 529: payloadData.deliveryRules = temp;
  • Line 594: payloadData.deliveryRules = temp?.[0];
  • Line 658: payloadData.deliveryRules = [temp?.[0]];

This could lead to unexpected behavior due to differing data structures.

Run the following script to identify all assignments to payloadData.deliveryRules:

Ensure that payloadData.deliveryRules is consistently assigned the correct data structure across the codebase.

Also applies to: 594-596, 658-660

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all assignments to 'payloadData.deliveryRules' to verify consistency.

rg 'payloadData\.deliveryRules\s*=' -A 2

Length of output: 5878

};

const cycles = data?.[0]?.cycles || [];
const transformedCycles = cycles.map((cycle) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

make them into multiple readble functions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants