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

hierarchy #1647

Merged
merged 3 commits into from
Oct 23, 2024
Merged

hierarchy #1647

merged 3 commits into from
Oct 23, 2024

Conversation

suryansh-egov
Copy link
Collaborator

@suryansh-egov suryansh-egov commented Oct 23, 2024

Choose the appropriate template for your PR:

Summary by CodeRabbit

  • New Features

    • Users can now download an Excel template with a delay after file generation, enhancing the user experience during file operations.
    • Improved state management and authorization checks in the Boundary component, providing better feedback through notifications for unauthorized access.
    • Enhanced error handling and status polling for data creation processes in the ViewHierarchy component.
  • Bug Fixes

    • Adjustments made to ensure proper error feedback and loading states during operations.
  • Documentation

    • Updates to the overall structure of the components for clarity and functionality.

@suryansh-egov suryansh-egov requested a review from a team as a code owner October 23, 2024 11:08
Copy link
Contributor

coderabbitai bot commented Oct 23, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces several enhancements across multiple components within the campaign manager module. Key changes include the addition of a delay function in UICustomizations.js to pause execution during file downloads, improvements to state management and authorization checks in Boundary.js, and modifications to error handling and API calls in ViewHierarchy.js. These updates collectively enhance the user experience and functionality of the application, ensuring smoother operations and better feedback mechanisms.

Changes

File Change Summary
.../campaign-manager/src/configs/UICustomizations.js Added delay function for execution pause; updated downloadExcelTemplate to include file generation and download logic; enhanced additionalCustomizations.
.../campaign-manager/src/pages/employee/Boundary.js Transitioned to dynamic state variables for hierarchy types; enhanced user authorization checks; added Toast notifications for unauthorized access.
.../campaign-manager/src/pages/employee/ViewHierarchy.js Commented out generateFile() call in downloadExcelTemplate; added pollForStatusCompletion for enhanced error handling; refined user feedback mechanisms.

Possibly related PRs

Suggested reviewers

  • nipunarora-eGov

🐰 In the meadow, changes bloom,
With custom templates, we make room.
Delays and checks, all in a line,
A hop, a skip, our code will shine!
With boundaries set and data in tow,
Let's celebrate the progress we sow! 🌼


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: 10

🧹 Outside diff range comments (2)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js (1)

Line range hint 232-238: Improve the file download implementation.

The current implementation has potential reliability issues:

  1. The hardcoded 2-second delay might not be sufficient for all file sizes
  2. No loading state management for user feedback

Consider implementing a polling mechanism instead of a fixed delay:

 const downloadExcelTemplate = async () => {
+  try {
     const res = await generateFile();
-    await delay(2000);
+    let attempts = 0;
+    const maxAttempts = 10;
+    while (attempts < maxAttempts) {
+      const resFile = await generateTemplate();
+      if (resFile?.GeneratedResource?.[0]?.fileStoreid) {
+        const fileNameWithoutExtension = row?.hierarchyType;
+        Digit.Utils.campaign.downloadExcelWithCustomName({ 
+          fileStoreId: resFile.GeneratedResource[0].fileStoreid, 
+          customName: fileNameWithoutExtension 
+        });
+        return;
+      }
+      attempts++;
+      await delay(1000);
+    }
+    throw new Error('File generation timed out');
+  } catch (error) {
+    console.error('Error downloading template:', error);
+    // Add error notification here
+  }
-    const resFile = await generateTemplate();
-    if (resFile && resFile?.GeneratedResource?.[0]?.fileStoreid) {
-      const fileNameWithoutExtension = row?.hierarchyType;
-      Digit.Utils.campaign.downloadExcelWithCustomName({ fileStoreId: resFile?.GeneratedResource?.[0]?.fileStoreid, customName: fileNameWithoutExtension });
-    }
 }
🧰 Tools
🪛 Biome

[error] 234-234: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

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

Line range hint 108-112: Ensure consistent casing for 'fileStoreId'

In the downloadExcelTemplate function, you're accessing resFile?.GeneratedResource?.[0]?.fileStoreid with a lowercase 'i' in 'fileStoreid'. However, elsewhere in the code and typically in JavaScript conventions, it's used as fileStoreId with an uppercase 'I'. This inconsistency might lead to undefined values and potential errors if the API actually returns fileStoreId.

Apply this diff to correct the property name:

- if (resFile && resFile?.GeneratedResource?.[0]?.fileStoreid) {
+ if (resFile && resFile?.GeneratedResource?.[0]?.fileStoreId) {
🧰 Tools
🪛 Biome

[error] 110-110: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 8e0e650 and 870cad5.

📒 Files selected for processing (3)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js (2 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/Boundary.js (5 hunks)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/ViewHierarchy.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js (1)

Pattern **/*.js: check

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

Pattern **/*.js: check

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

Pattern **/*.js: check

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

[error] 215-215: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

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

[error] 204-204: 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/campaign-manager/src/pages/employee/ViewHierarchy.js

[error] 196-196: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 198-198: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

🔇 Additional comments (2)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/Boundary.js (1)

201-201: 🧹 Nitpick (assertive)

Modify Toast component to be self-closing

JSX elements without children should be self-closing to adhere to style guidelines.

Apply this diff:

-{toast &&
-  <Toast label={t("USER_NOT_AUTHORISED")} type={"error"} onClose={() => setToast(false)} ></Toast>}
+{toast &&
+  <Toast label={t("USER_NOT_AUTHORISED")} type={"error"} onClose={() => setToast(false)} />}

Likely invalid or redundant comment.

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

154-191: Verify API response handling in 'callCreateDataApi'

After calling the _create API, you extract id and typeOfData from createResponse?.ResourceDetails. Ensure that createResponse?.ResourceDetails exists and contains these properties to prevent potential undefined access.

Please verify that createResponse?.ResourceDetails always contains id and type when the API call is successful.

@@ -212,6 +212,7 @@ export const UICustomizations = {
});
return res;
}
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
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 enhancing the delay utility function.

The delay function could be improved for better maintainability and reusability.

-const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
+/**
+ * Creates a Promise that resolves after the specified delay
+ * @param {number} ms - The delay duration in milliseconds
+ * @returns {Promise<void>}
+ */
+const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

Consider moving this utility function to a shared utilities file for reuse across the application.

📝 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 delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
/**
* Creates a Promise that resolves after the specified delay
* @param {number} ms - The delay duration in milliseconds
* @returns {Promise<void>}
*/
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
🧰 Tools
🪛 Biome

[error] 215-215: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


⚠️ Potential issue

Fix switch case declaration scope.

The delay function is declared within a switch case, which could lead to scoping issues.

Move the declaration outside the switch statement:

+const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
+
 switch (key) {
   case "ACTION":
     const tenantId = Digit.ULBService.getCurrentTenantId();
     const generateFile = async () => {
       // ...
     }
-    const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
     const generateTemplate = async () => {
       // ...
     }
     // ...
 }

Committable suggestion was skipped due to low confidence.

🧰 Tools
🪛 Biome

[error] 215-215: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

Comment on lines +12 to +13
// const [config, setConfig] = useState({defaultHierarchyType: "DEFAULTBOUNDARY",
// hierarchyType: "DEMOONCONSOLE"});
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Remove commented-out code to improve code cleanliness

The commented-out code appears to be unnecessary. Removing it can help keep the codebase clean and maintainable.

Comment on lines +232 to +243
isDisabled={!directView && !authorized}
variation={"secondary"}
label={t("EDIT_BOUNDARY_DATA")}
onClick={() => {
// setShowPopUp(false);
callDirectView();
if(authorized)
{
callDirectView();
}
else{
setToast(true);
}
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

Align isDisabled property with authorized state for the "Edit Boundary Data" button

For consistency, adjust the isDisabled property and simplify the onClick handler by relying on the button's disabled state.

Apply this diff:

-isDisabled={!directView && !authorized}
+isDisabled={!authorized}

...

onClick={() => {
-  if(authorized)
-  {
     callDirectView();
-  }
-  else{
-    setToast(true);
-  }
}}
📝 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
isDisabled={!directView && !authorized}
variation={"secondary"}
label={t("EDIT_BOUNDARY_DATA")}
onClick={() => {
// setShowPopUp(false);
callDirectView();
if(authorized)
{
callDirectView();
}
else{
setToast(true);
}
isDisabled={!authorized}
variation={"secondary"}
label={t("EDIT_BOUNDARY_DATA")}
onClick={() => {
// setShowPopUp(false);
callDirectView();

Comment on lines +19 to +20
const [defaultHierarchyType, setDefaultHierarchyType] = useState(config?.defaultHierarchyType || searchParams.get("defaultHierarchyType"));
const [hierarchyType, setHierarchyType] = useState(config?.hierarchyType || searchParams.get("hierarchyType"));
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Simplify optional chaining for the config object

Since config is always defined in this scope, you can remove the optional chaining config?. to simplify the code.

Apply this diff:

-const [defaultHierarchyType, setDefaultHierarchyType] = useState(config?.defaultHierarchyType || searchParams.get("defaultHierarchyType"));
+const [defaultHierarchyType, setDefaultHierarchyType] = useState(config.defaultHierarchyType || searchParams.get("defaultHierarchyType"));

-const [hierarchyType, setHierarchyType] = useState(config?.hierarchyType || searchParams.get("hierarchyType"));
+const [hierarchyType, setHierarchyType] = useState(config.hierarchyType || searchParams.get("hierarchyType"));
📝 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 [defaultHierarchyType, setDefaultHierarchyType] = useState(config?.defaultHierarchyType || searchParams.get("defaultHierarchyType"));
const [hierarchyType, setHierarchyType] = useState(config?.hierarchyType || searchParams.get("hierarchyType"));
const [defaultHierarchyType, setDefaultHierarchyType] = useState(config.defaultHierarchyType || searchParams.get("defaultHierarchyType"));
const [hierarchyType, setHierarchyType] = useState(config.hierarchyType || searchParams.get("hierarchyType"));

Comment on lines +104 to +105
if (JSON.stringify(hierarchyType) !== JSON.stringify(newHierarchyTypes)) {
setHierarchyType(newHierarchyTypes);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use direct comparison for hierarchy types instead of JSON.stringify

When comparing hierarchyType and newHierarchyTypes, using JSON.stringify may be unnecessary if they are strings or simple types. Consider using direct comparison for better performance.

Apply this diff:

-if (JSON.stringify(hierarchyType) !== JSON.stringify(newHierarchyTypes)) {
+if (hierarchyType !== newHierarchyTypes) {

Similarly, for defaultHierarchyType:

-if (JSON.stringify(defaultHierarchyType) !== JSON.stringify(newDefHierarchyTypes)) {
+if (defaultHierarchyType !== newDefHierarchyTypes) {

Committable suggestion was skipped due to low confidence.

Comment on lines +209 to +224
// isDisabled={!authorized}
variation={"secondary"}
label={t("CREATE_NEW_BOUNDARY_DATA")}
onClick={() => {
if (direct && geoPodeData) {
if(authorized)
{
if (direct) {
callDirectView();
} else {
setShowPopUp(true);
}
}
else{
setToast(true);

}
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

Ensure consistent handling of authorized checks and isDisabled properties

To improve user experience and code consistency, consider re-enabling the isDisabled={!authorized} property for the "Create New Boundary Data" button and removing the authorized check from the onClick handler. This prevents unauthorized users from interacting with the button.

Apply this diff:

-// isDisabled={!authorized}
+isDisabled={!authorized}

...

onClick={() => {
-  if(authorized)
-  {
     if (direct) {
       callDirectView();
     } else {
       setShowPopUp(true);
     }
-  }
-  else{
-    setToast(true);
-  }
}}
📝 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
// isDisabled={!authorized}
variation={"secondary"}
label={t("CREATE_NEW_BOUNDARY_DATA")}
onClick={() => {
if (direct && geoPodeData) {
if(authorized)
{
if (direct) {
callDirectView();
} else {
setShowPopUp(true);
}
}
else{
setToast(true);
}
isDisabled={!authorized}
variation={"secondary"}
label={t("CREATE_NEW_BOUNDARY_DATA")}
onClick={() => {
if (direct) {
callDirectView();
} else {
setShowPopUp(true);
}
}}

Comment on lines 235 to 236
setDataCreationGoing(false);
return true; // Stop polling once status is "completed"
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)

Double-check success toast message placement

In the polling function, upon successful completion (status === "completed"), you're setting a success toast message inside pollForStatusCompletion. Verify if displaying the toast here aligns with the user experience, or if it should be managed after polling completes in callCreateDataApi.

Comment on lines 193 to 200
let label = `${t("WBH_BOUNDARY_CREATION_FAIL")}: `;
resp?.response?.data?.Errors?.map((err, idx) => {
if (idx === resp?.response?.data?.Errors?.length - 1) {
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ".";
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ".";
} else {
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ", ";
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ", ";
}
});
setShowToast({ label, isError: "error" });
setDataCreationGoing(false);
return {};
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use template literals instead of string concatenation

The static analysis tool has flagged the use of string concatenation in building the label string. Using template literals improves readability and consistency.

Apply this diff to refactor the code:

let label = `${t("WBH_BOUNDARY_CREATION_FAIL")}: `;
resp?.response?.data?.Errors?.map((err, idx) => {
  if (idx === resp?.response?.data?.Errors?.length - 1) {
-   label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ".";
+   label = `${label}${t(Digit.Utils.locale.getTransformedLocale(err?.code))}.`;
  } else {
-   label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ", ";
+   label = `${label}${t(Digit.Utils.locale.getTransformedLocale(err?.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
let label = `${t("WBH_BOUNDARY_CREATION_FAIL")}: `;
resp?.response?.data?.Errors?.map((err, idx) => {
if (idx === resp?.response?.data?.Errors?.length - 1) {
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ".";
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ".";
} else {
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ", ";
label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ", ";
}
});
setShowToast({ label, isError: "error" });
setDataCreationGoing(false);
return {};
});
let label = `${t("WBH_BOUNDARY_CREATION_FAIL")}: `;
resp?.response?.data?.Errors?.map((err, idx) => {
if (idx === resp?.response?.data?.Errors?.length - 1) {
label = `${label}${t(Digit.Utils.locale.getTransformedLocale(err?.code))}.`;
} else {
label = `${label}${t(Digit.Utils.locale.getTransformedLocale(err?.code))}, `;
}
});
🧰 Tools
🪛 Biome

[error] 196-196: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 198-198: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Comment on lines 208 to 244
const pollForStatusCompletion = async (id, typeOfData) => {
const pollInterval = 1000; // Poll every 1 seconds
const maxRetries = 10; // Limit the number of retries to avoid infinite loop
let retries = 0;

const poll = async () => {
if (retries >= maxRetries) {
throw new Error("Max retries reached");
}

const searchResponse = await Digit.CustomService.getResponse({
url: "/project-factory/v1/data/_search",
params: {},
body: {
SearchCriteria:{
id: [id],
tenantId: tenantId,
type: typeOfData
}

},
});

const status = searchResponse?.ResourceDetails?.status;

if (status === "completed") {
setShowToast({ label: `${t("WBH_HIERARCHY_STATUS_COMPLETED")}`, isError: "success" });
setDataCreationGoing(false);
return true; // Stop polling once status is "completed"
} else {
retries++;
setTimeout(poll, pollInterval); // Retry after the interval
}
};

await poll();
};
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 'maxRetries' scenario in polling mechanism

In the pollForStatusCompletion function, if the maxRetries limit is reached without the status being "completed", the function throws an error but does not reset the dataCreationGoing state. This could leave the UI in a loading state indefinitely.

Apply this diff to ensure the state is properly reset:

if (retries >= maxRetries) {
+ setDataCreationGoing(false);
  throw new Error("Max retries reached");
}
📝 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 pollForStatusCompletion = async (id, typeOfData) => {
const pollInterval = 1000; // Poll every 1 seconds
const maxRetries = 10; // Limit the number of retries to avoid infinite loop
let retries = 0;
const poll = async () => {
if (retries >= maxRetries) {
throw new Error("Max retries reached");
}
const searchResponse = await Digit.CustomService.getResponse({
url: "/project-factory/v1/data/_search",
params: {},
body: {
SearchCriteria:{
id: [id],
tenantId: tenantId,
type: typeOfData
}
},
});
const status = searchResponse?.ResourceDetails?.status;
if (status === "completed") {
setShowToast({ label: `${t("WBH_HIERARCHY_STATUS_COMPLETED")}`, isError: "success" });
setDataCreationGoing(false);
return true; // Stop polling once status is "completed"
} else {
retries++;
setTimeout(poll, pollInterval); // Retry after the interval
}
};
await poll();
};
const pollForStatusCompletion = async (id, typeOfData) => {
const pollInterval = 1000; // Poll every 1 seconds
const maxRetries = 10; // Limit the number of retries to avoid infinite loop
let retries = 0;
const poll = async () => {
if (retries >= maxRetries) {
setDataCreationGoing(false);
throw new Error("Max retries reached");
}
const searchResponse = await Digit.CustomService.getResponse({
url: "/project-factory/v1/data/_search",
params: {},
body: {
SearchCriteria:{
id: [id],
tenantId: tenantId,
type: typeOfData
}
},
});
const status = searchResponse?.ResourceDetails?.status;
if (status === "completed") {
setShowToast({ label: `${t("WBH_HIERARCHY_STATUS_COMPLETED")}`, isError: "success" });
setDataCreationGoing(false);
return true; // Stop polling once status is "completed"
} else {
retries++;
setTimeout(poll, pollInterval); // Retry after the interval
}
};
await poll();
};


if (status === "completed") {
setShowToast({ label: `${t("WBH_HIERARCHY_STATUS_COMPLETED")}`, isError: "success" });
setDataCreationGoing(false);
Copy link
Collaborator

Choose a reason for hiding this comment

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

if dataCreationGoing show a loader linke in upload screen

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 870cad5 and 1f04d4b.

📒 Files selected for processing (1)
  • health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/ViewHierarchy.js (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/ViewHierarchy.js (1)

Pattern **/*.js: check

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

[error] 278-278: The catch clause that only rethrows the original error is useless.

An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.

(lint/complexity/noUselessCatch)


[error] 293-293: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 295-295: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

🔇 Additional comments (1)
health/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/ViewHierarchy.js (1)

293-295: Use template literals instead of string concatenation

This issue has already been noted in previous reviews.

🧰 Tools
🪛 Biome

[error] 293-293: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 295-295: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

@@ -105,7 +104,7 @@ const ViewHierarchy = () => {

}
const downloadExcelTemplate = async() => {
const res = await generateFile()
// const res = await generateFile()
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider removing commented-out code

The line // const res = await generateFile() is commented out. If this code is no longer needed, consider removing it to keep the codebase clean.

Comment on lines 153 to 244
// const callCreateDataApi = async () => {
// setDisable(true);
// setDataCreationGoing(true);
// try {
// setDataCreateToast(true);

// // Call the create API
// const createResponse = await Digit.CustomService.getResponse({
// url: "/project-factory/v1/data/_create",
// params: {},
// body: {
// ResourceDetails: {
// tenantId: tenantId,
// type: "boundaryManagement",
// fileStoreId: fileStoreId,
// action: "create",
// hierarchyType: hierarchyType,
// additionalDetails: {
// source: "boundary",
// },
// campaignId: "default"
// },
// },
// });

// // Extract the id from the response
// const id = createResponse?.ResourceDetails?.id;
// const typeOfData = createResponse?.ResourceDetails?.type;

// if (id) {
// // Start polling the search API
// await pollForStatusCompletion(id, typeOfData);
// }

// setDataCreateToast(false);
// setShowToast({ label: `${t("WBH_HIERARCHY_CREATED")}`, isError: "success" });
// return createResponse;
// } catch (resp) {
// setDisable(false);
// let label = `${t("WBH_BOUNDARY_CREATION_FAIL")}: `;
// resp?.response?.data?.Errors?.map((err, idx) => {
// if (idx === resp?.response?.data?.Errors?.length - 1) {
// label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ".";
// } else {
// label = label + t(Digit.Utils.locale.getTransformedLocale(err?.code)) + ", ";
// }
// });
// setShowToast({ label, isError: "error" });
// setDataCreationGoing(false);
// return {};
// }
// };

// // Function to poll the search API until status is "completed"
// const pollForStatusCompletion = async (id, typeOfData) => {
// const pollInterval = 1000; // Poll every 1 seconds
// const maxRetries = 10; // Limit the number of retries to avoid infinite loop
// let retries = 0;

// const poll = async () => {
// if (retries >= maxRetries) {
// throw new Error("Max retries reached");
// }

// const searchResponse = await Digit.CustomService.getResponse({
// url: "/project-factory/v1/data/_search",
// params: {},
// body: {
// SearchCriteria:{
// id: [id],
// tenantId: tenantId,
// type: typeOfData
// }

// },
// });

// const status = searchResponse?.ResourceDetails?.status;

// if (status === "completed") {
// setShowToast({ label: `${t("WBH_HIERARCHY_STATUS_COMPLETED")}`, isError: "success" });
// setDataCreationGoing(false);
// return true; // Stop polling once status is "completed"
// } else {
// retries++;
// setTimeout(poll, pollInterval); // Retry after the interval
// }
// };

// await poll();
// };

Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Remove unnecessary commented-out code

The block of code from lines 153 to 244 is commented out. If this code is obsolete or no longer needed, consider removing it to improve code readability and maintainability.

{previewPage && (
<Card type={"primary"} variant={"viewcard"} className={"example-view-card"}>
<div style={{fontSize:"2.5rem", fontWeight:700}}>{t("CONFIRM_BOUNDARY_DATA")}</div>
<div style={{height:"1.5rem"}}></div>
<XlsPreviewNew file={fileData} onDownload={() => {}} onBack={() => {setShowPreview(false); setUploadPage(true)}} />
{!dataCreationGoing && <XlsPreviewNew file={fileData} onDownload={() => {}} onBack={() => {setShowPreview(false); setUploadPage(true)}} />}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix undefined state variables in onBack handler

In the onBack handler of XlsPreviewNew, you're calling setShowPreview and setUploadPage, but these state setters are not defined in the component. It seems you intended to use setPreviewPage and setFirstPage, which are the defined state variables.

Apply this diff to fix the state setters:

    {!dataCreationGoing && (
      <XlsPreviewNew
        file={fileData}
        onDownload={() => {}}
        onBack={() => {
-         setShowPreview(false);
-         setUploadPage(true);
+         setPreviewPage(false);
+         setFirstPage(true);
        }}
      />
    )}
📝 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
{!dataCreationGoing && <XlsPreviewNew file={fileData} onDownload={() => {}} onBack={() => {setShowPreview(false); setUploadPage(true)}} />}
{!dataCreationGoing && (
<XlsPreviewNew
file={fileData}
onDownload={() => {}}
onBack={() => {
setPreviewPage(false);
setFirstPage(true);
}}
/>
)}

Comment on lines +278 to +280
throw pollError; // Propagate polling errors to the outer catch block
}
}
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 catch clause that rethrows the error

The catch block catches pollError only to rethrow it without any additional handling. This is redundant and can be removed to simplify the code.

Apply this diff to remove the unnecessary try-catch block:

              if (id) {
-                try {
                    await pollForStatusCompletion(id, typeOfData);
                    setDataCreateToast(false);
                    setShowToast({ label: `${t("WBH_HIERARCHY_CREATED")}`, isError: "success" });
-                } catch (pollError) {
-                  throw pollError; // Propagate polling errors to the outer catch block
-                }
              }
📝 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
throw pollError; // Propagate polling errors to the outer catch block
}
}
if (id) {
await pollForStatusCompletion(id, typeOfData);
setDataCreateToast(false);
setShowToast({ label: `${t("WBH_HIERARCHY_CREATED")}`, isError: "success" });
}
🧰 Tools
🪛 Biome

[error] 278-278: The catch clause that only rethrows the original error is useless.

An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.

(lint/complexity/noUselessCatch)

@jagankumar-egov jagankumar-egov merged commit 979f68d into console Oct 23, 2024
3 checks passed
@jagankumar-egov jagankumar-egov deleted the feature/final-hier branch October 23, 2024 11:56
@coderabbitai coderabbitai bot mentioned this pull request Oct 25, 2024
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