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

Revamp Asset Create/Update Workflow using ShadCN, React-Hook-Form, and TanStack Query #9192

Closed

Conversation

rajku-dev
Copy link
Contributor

@rajku-dev rajku-dev commented Nov 24, 2024

Proposed Changes

issue_9198_fix.mp4
  • Fixes Unnecessary API Calls in Assets Update Page #9189
    -Initialized form state using 'fetchedValues' to pre-fill the form with asset data.
    -Introduced a mechanism to compare current form values with initial values and enable/disable the submit button based on changes made by the user in form.
    -Used a useRef (isInitialLoad.current) to skip comparisons during the initial load and avoid unnecessary state updates.
    -Once the initial values are set, this flag is updated to ensure further state checks and updates are triggered properly to enable or disable the 'Update' button accordingly.

@ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate bug / test a new feature.
  • Update product documentation.
  • Ensure that UI text is kept in I18n files.
  • Prep screenshot or demo video for changelog entry, and attach it to issue.
  • Request for Peer Reviews
  • Completion of QA

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced asset creation form with improved validation and form management.
    • Added new UI components for calendar, select, switch, textarea, and phone input.
    • Integrated advanced form handling with react-hook-form.
  • Dependencies

    • Added new libraries for form management, UI components, and utilities.
    • Updated Zod validation library.
  • Improvements

    • Streamlined form submission and error handling.
    • Improved user interface with more robust and flexible components.
    • Enhanced form validation with detailed schema checks.

@rajku-dev rajku-dev requested a review from a team as a code owner November 24, 2024 06:03
Copy link
Contributor

coderabbitai bot commented Nov 24, 2024

Walkthrough

This pull request introduces a comprehensive refactoring of the asset creation workflow, focusing on enhancing form management and validation. Key changes include the integration of react-hook-form and Zod for robust form handling, the addition of new UI components such as Calendar, Select, and Phone Input, and significant improvements to the structure and usability of the AssetCreate component.

Changes

File Change Summary
src/components/Facility/AssetCreate.tsx Refactored form management using react-hook-form, integrated Zod validation, streamlined submission logic, and added QR code scanning functionality.
src/components/Facility/AssetFormSchema.tsx Created new Zod schema for asset form with comprehensive validation rules.
package.json Added new dependencies for form management, UI components, and validation; updated zod version.
src/components/ui/ Added new UI components: calendar.tsx, form.tsx, select.tsx, switch.tsx, textarea.tsx, phone-input.tsx.

Assessment against linked issues

Objective Addressed Explanation
Prevent unnecessary API calls when no data changes [#9189] The changes do not explicitly implement logic to disable the update button when there are no changes in the data.

Possibly related PRs

Suggested Labels

tested, reviewed

Suggested Reviewers

  • rithviknishad
  • Jacobjeevan

Poem

🐰 In the realm of forms so neat,
Zod and hooks make validation sweet.
Components dance with grace and might,
Transforming assets, shining bright!
A rabbit's code, precise and clean 🚀


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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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

netlify bot commented Nov 24, 2024

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit 760b363
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/6772af4930435300082edbac
😎 Deploy Preview https://deploy-preview-9192--care-ohc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

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

🧹 Outside diff range and nitpick comments (3)
src/components/Facility/AssetCreate.tsx (3)

113-147: Consider using a more maintainable type definition.

The type definition could be extracted and reused to improve maintainability and reduce duplication.

+type AssetFormValues = {
+  name: string;
+  description: string;
+  location: string;
+  asset_class: AssetClass | undefined;
+  is_working: string | undefined;
+  not_working_reason: string;
+  serial_number: string;
+  vendor_name: string;
+  support_name: string;
+  support_email: string;
+  support_phone: string;
+  qr_code_id: string;
+  manufacturer: string;
+  warranty_amc_end_of_validity: any;
+  last_serviced_on: any;
+  notes: string;
+};

-const [initialValues, setInitialValues] = useState<{...}>({
+const [initialValues, setInitialValues] = useState<AssetFormValues>({

267-313: Optimize form value comparison logic.

The current implementation recreates the currentValues object on every render. Consider memoizing it with useMemo to prevent unnecessary object creation.

+const currentValues = useMemo(() => ({
+  name,
+  description,
+  location,
+  asset_class,
+  is_working,
+  not_working_reason,
+  serial_number,
+  vendor_name,
+  support_name,
+  support_email,
+  support_phone,
+  qr_code_id: qrCodeId,
+  manufacturer,
+  warranty_amc_end_of_validity,
+  last_serviced_on,
+  notes,
+}), [
+  name,
+  description,
+  location,
+  asset_class,
+  is_working,
+  not_working_reason,
+  serial_number,
+  vendor_name,
+  support_name,
+  support_email,
+  support_phone,
+  qrCodeId,
+  manufacturer,
+  warranty_amc_end_of_validity,
+  last_serviced_on,
+  notes,
+]);
-const currentValues = {
-  name,
-  description,
-  // ... other fields
-};

288-288: Remove debug console.log statement.

Debug logging should be removed before merging to production.

-    console.log("Initial Values " + currentValues);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2fdffa2 and 3b41347.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (4 hunks)
🔇 Additional comments (1)
src/components/Facility/AssetCreate.tsx (1)

1005-1005: LGTM! Good implementation of form submission optimization.

The disabled state on submit buttons effectively prevents unnecessary API calls when no changes are made to the form, which directly addresses the PR objectives.

Also applies to: 1012-1012

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

🧹 Outside diff range and nitpick comments (4)
src/components/Facility/AssetCreate.tsx (4)

64-88: Consider improving the AssetT interface.

The interface has some potential improvements:

  1. The notes field is marked as required (no ?), but it's optional in the form.
  2. The last_service type is set to any, which should be avoided for type safety.
interface AssetT {
-  last_service?: any;
+  last_service?: {
+    serviced_on?: string;
+    note?: string;
+  };
-  notes: string;
+  notes?: string;
}

225-263: Enhance form validation for better user experience.

The validation logic has some areas for improvement:

  1. Phone number validation is complex and could be extracted into a separate function
  2. Email validation could be moved closer to the email field validation
const AssetFormValidator = (form: AssetT): FormErrors<AssetT> => {
  const errors: Partial<Record<keyof AssetT, FieldError>> = {};

+  const validateSupportPhone = (phone?: string): string | undefined => {
+    if (!phone) return t("field_required");
+    const checkTollFree = phone.startsWith("1800");
+    const supportPhoneSimple = phone.replace(/[^0-9]/g, "").slice(2);
+    if (supportPhoneSimple.length !== 10 && !checkTollFree) {
+      return "Please enter valid phone number";
+    }
+    if ((phone.length < 10 || phone.length > 11) && checkTollFree) {
+      return "Please enter valid phone number";
+    }
+    return undefined;
+  };

  errors.name = RequiredFieldValidator()(form.name);
  errors.is_working = form.is_working === undefined ? t("field_required") : undefined;
  errors.location = !form.location || form.location === "0" || form.location === "" 
    ? "Select a location" 
    : undefined;
-  if (!form.support_phone) {
-    errors.support_phone = t("field_required");
-  } else {
-    const checkTollFree = form.support_phone.startsWith("1800");
-    // ... rest of phone validation
-  }
+  errors.support_phone = validateSupportPhone(form.support_phone);
  errors.support_email = form.support_email && !validateEmailAddress(form.support_email)
    ? "Please enter valid email id"
    : undefined;
  errors.serviced_on = form.notes && !form.serviced_on
    ? "Last serviced on date is required with notes"
    : undefined;

  return errors;
};

710-734: Improve date validation logic.

The warranty expiry date validation could be improved:

  1. The date comparison logic could be simplified using dayjs
  2. The validation message could be more user-friendly
<TextFormField
  {...field("warranty_amc_end_of_validity")}
  label={t("warranty_amc_expiry")}
  onChange={(event) => {
    const { value } = event;
    const selectedDate = dayjs(value);
-   const formattedDate = selectedDate.format("YYYY-MM-DD");
-   const today = dayjs().format("YYYY-MM-DD");

-   if (selectedDate.isBefore(today)) {
+   if (selectedDate.isBefore(dayjs().startOf('day'))) {
      Notification.Error({
-       msg: "Warranty / AMC Expiry date can't be in the past",
+       msg: "Please select a future date for warranty/AMC expiry",
      });
    } else {
      field("warranty_amc_end_of_validity").onChange({
        name: "warranty_amc_end_of_validity",
-       value: formattedDate,
+       value: selectedDate.format("YYYY-MM-DD"),
      });
    }
  }}
  type="date"
-  min={dayjs().format("YYYY-MM-DD")}
+  min={dayjs().startOf('day').format("YYYY-MM-DD")}
/>

813-847: Simplify last serviced date validation.

Similar to the warranty date validation, the last serviced date validation could be simplified:

  1. Use dayjs consistently for date comparisons
  2. Improve error message clarity
<DateFormField
  {...field("serviced_on")}
  label={t("last_serviced_on")}
  className="mt-2"
  disableFuture
  value={field("serviced_on").value ? new Date(field("serviced_on").value) : undefined}
  onChange={(date) => {
-   const selectedDate = dayjs(date.value).format("YYYY-MM-DD");
-   const today = new Date().toLocaleDateString("en-ca");
+   const selectedDate = dayjs(date.value);
+   const today = dayjs();

-   if (selectedDate > today) {
+   if (selectedDate.isAfter(today)) {
      Notification.Error({
-       msg: "Last Serviced date can't be in the future",
+       msg: "Service date cannot be in the future",
      });
    } else {
      field("serviced_on").onChange({
        name: "serviced_on",
-       value: selectedDate,
+       value: selectedDate.format("YYYY-MM-DD"),
      });
    }
  }}
/>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3b41347 and ea14bd0.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (9 hunks)
🔇 Additional comments (1)
src/components/Facility/AssetCreate.tsx (1)

139-141: Form state initialization aligns with PR objectives.

The implementation correctly addresses the PR objective by initializing the form state with fetched values, which will help prevent unnecessary API calls when no changes are made.

Also applies to: 197-221

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
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: 1

🧹 Outside diff range and nitpick comments (3)
src/components/Facility/AssetCreate.tsx (3)

225-263: Simplify phone number validation and ensure consistent translations

The phone number validation logic could be simplified, and error messages should consistently use translations.

Consider this refactor:

 if (!form.support_phone) {
   errors.support_phone = t("field_required");
 } else {
-  const checkTollFree = form.support_phone.startsWith("1800");
-  const supportPhoneSimple = form.support_phone
-    .replace(/[^0-9]/g, "")
-    .slice(2);
-  if (supportPhoneSimple.length !== 10 && !checkTollFree) {
-    errors.support_phone = "Please enter valid phone number";
-  } else if (
-    (form.support_phone.length < 10 || form.support_phone.length > 11) &&
-    checkTollFree
-  ) {
-    errors.support_phone = "Please enter valid phone number";
+  const isTollFree = form.support_phone.startsWith("1800");
+  const phoneLength = form.support_phone.replace(/[^0-9]/g, "").length;
+  const isValidLength = isTollFree ? phoneLength >= 10 && phoneLength <= 11 : phoneLength === 10;
+  if (!isValidLength) {
+    errors.support_phone = t("please_enter_valid_phone_number");
   }
 }

 if (form.support_email && !validateEmailAddress(form.support_email)) {
-  errors.support_email = "Please enter valid email id";
+  errors.support_email = t("please_enter_valid_email");
 }

Line range hint 294-356: Improve error handling specificity

The error handling in the submission function could be more specific and informative.

Consider this improvement:

-    } catch (error) {
-      // Handle error (optional)
-      Notification.Error({
-        msg: "An error occurred while processing the asset",
-      });
+    } catch (error: unknown) {
+      const operation = form.id ? "updating" : "creating";
+      console.error(`Error ${operation} asset:`, error);
+      Notification.Error({
+        msg: t("error_processing_asset", { operation }),
+      });

748-769: Consolidate date validation logic

The date validation logic is duplicated between warranty and service date handling. Consider extracting this into a reusable function.

Consider creating a utility function:

const validateDate = (date: string, options: { 
  disableFuture?: boolean, 
  disablePast?: boolean,
  errorMessage: string 
}) => {
  const selectedDate = dayjs(date).format("YYYY-MM-DD");
  const today = dayjs().format("YYYY-MM-DD");
  
  if (options.disableFuture && selectedDate > today) {
    Notification.Error({ msg: options.errorMessage });
    return false;
  }
  if (options.disablePast && selectedDate < today) {
    Notification.Error({ msg: options.errorMessage });
    return false;
  }
  return true;
};

Then use it in both places:

 onChange={(event) => {
   const { value } = event;
-  const selectedDate = dayjs(value);
-  const formattedDate = selectedDate.format("YYYY-MM-DD");
-  const today = dayjs().format("YYYY-MM-DD");
-
-  if (selectedDate.isBefore(today)) {
-    Notification.Error({
-      msg: "Warranty / AMC Expiry date can't be in the past",
-    });
-  } else {
+  if (validateDate(value, {
+    disablePast: true,
+    errorMessage: t("warranty_date_past_error")
+  })) {
     field("warranty_amc_end_of_validity").onChange({
       name: "warranty_amc_end_of_validity",
-      value: formattedDate,
+      value: dayjs(value).format("YYYY-MM-DD"),
     });
   }
 }}

Also applies to: 858-876

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ea14bd0 and 3c1a2ac.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (10 hunks)
🔇 Additional comments (1)
src/components/Facility/AssetCreate.tsx (1)

64-88: LGTM! Well-structured data management

The consolidated state management using the AssetData interface and proper initialization of form state aligns well with the PR objective of preventing unnecessary API calls.

Also applies to: 113-137, 139-140

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
@github-actions github-actions bot added the Deploy-Failed Deplyment is not showing preview label Nov 26, 2024
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: 1

🧹 Outside diff range and nitpick comments (3)
src/components/Facility/AssetCreate.tsx (3)

225-263: Refactor validation logic for better maintainability

Consider these improvements to the validation logic:

  1. Move phone validation to a separate validator function
  2. Use the existing RequiredFieldValidator for support phone
  3. Reuse validateEmailAddress as a validator function
 const AssetFormValidator = (form: AssetData): FormErrors<AssetData> => {
   const errors: Partial<Record<keyof AssetData, FieldError>> = {};
   
   errors.name = RequiredFieldValidator()(form.name);
   
   if (form.is_working === undefined) {
     errors.is_working = t("field_required");
   }
   
   if (!form.location || form.location === "0" || form.location === "") {
     errors.location = t("select_local_body");
   }
   
-  if (!form.support_phone) {
-    errors.support_phone = t("field_required");
-  } else {
-    const checkTollFree = form.support_phone.startsWith("1800");
-    const supportPhoneSimple = form.support_phone
-      .replace(/[^0-9]/g, "")
-      .slice(2);
-    if (supportPhoneSimple.length !== 10 && !checkTollFree) {
-      errors.support_phone = "Please enter valid phone number";
-    } else if (
-      (form.support_phone.length < 10 || form.support_phone.length > 11) &&
-      checkTollFree
-    ) {
-      errors.support_phone = "Please enter valid phone number";
-    }
-  }
+  errors.support_phone = RequiredFieldValidator()(form.support_phone);
+  if (form.support_phone && !validatePhoneNumber(form.support_phone)) {
+    errors.support_phone = t("invalid_phone_number");
+  }
   
-  if (form.support_email && !validateEmailAddress(form.support_email)) {
-    errors.support_email = "Please enter valid email id";
+  if (form.support_email) {
+    errors.support_email = validateEmailAddress(form.support_email) 
+      ? undefined 
+      : t("invalid_email");
   }
   
   if (form.notes && !form.serviced_on) {
     errors.serviced_on = "Last serviced on date is required with notes";
   }
   
   return errors;
 };

Line range hint 294-354: Improve error handling in form submission

The error handling in the submission function could be more specific:

  1. The catch block should type the error properly
  2. The error message could be more descriptive based on the operation (create/update)
 } catch (error) {
-  // Handle error (optional)
+  const operation = form.id ? "updating" : "creating";
+  console.error(`Error ${operation} asset:`, error);
   Notification.Error({
-    msg: "An error occurred while processing the asset",
+    msg: `An error occurred while ${operation} the asset. Please try again.`,
   });
 }

745-769: Refactor warranty date validation for consistency

The warranty date validation could be improved:

  1. Move validation logic to a common function
  2. Use consistent date formatting
+const validateFutureDate = (date: string, fieldName: string) => {
+  const selectedDate = dayjs(date).format("YYYY-MM-DD");
+  const today = dayjs().format("YYYY-MM-DD");
+  
+  if (dayjs(selectedDate).isBefore(today)) {
+    Notification.Error({
+      msg: `${fieldName} date can't be in the past`,
+    });
+    return false;
+  }
+  return true;
+};

 <TextFormField
   {...field("warranty_amc_end_of_validity")}
   label={t("warranty_amc_expiry")}
   onChange={(event) => {
     const { value } = event;
-    const selectedDate = dayjs(value);
-    const formattedDate = selectedDate.format("YYYY-MM-DD");
-    const today = dayjs().format("YYYY-MM-DD");
-
-    if (selectedDate.isBefore(today)) {
-      Notification.Error({
-        msg: "Warranty / AMC Expiry date can't be in the past",
-      });
-    } else {
+    if (validateFutureDate(value, "Warranty / AMC Expiry")) {
       field("warranty_amc_end_of_validity").onChange({
         name: "warranty_amc_end_of_validity",
-        value: formattedDate,
+        value: dayjs(value).format("YYYY-MM-DD"),
       });
     }
   }}
   type="date"
   min={dayjs().format("YYYY-MM-DD")}
 />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3c1a2ac and 29aa629.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (10 hunks)
🔇 Additional comments (1)
src/components/Facility/AssetCreate.tsx (1)

113-137: LGTM! Form initialization implements the PR objectives

The implementation correctly initializes form state and updates it with fetched values, which enables comparison with current values to prevent unnecessary API calls.

Also applies to: 197-221

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
@Jacobjeevan
Copy link
Contributor

Depends on #8956. Merge only after that PR is merged.

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

🧹 Outside diff range and nitpick comments (1)
src/components/Facility/AssetCreate.tsx (1)

350-354: Improve error handling specificity

The error handling could be more specific to help users understand what went wrong.

-    } catch (error) {
-      // Handle error (optional)
-      Notification.Error({
-        msg: "An error occurred while processing the asset",
-      });
+    } catch (error) {
+      const operation = form.id ? "updating" : "creating";
+      console.error(`Error ${operation} asset:`, error);
+      Notification.Error({
+        msg: `An error occurred while ${operation} the asset. Please try again.`,
+      });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 29aa629 and c5312fb.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (9 hunks)
🔇 Additional comments (2)
src/components/Facility/AssetCreate.tsx (2)

518-539: LGTM! Form implementation meets requirements

The Form component implementation successfully addresses the PR objectives:

  1. Initializes form state with fetched values
  2. Properly handles the "Create & Add More" functionality
  3. Implements validation and error display

64-88: ⚠️ Potential issue

Fix incorrect type definition for notes field

The notes field in the AssetData interface is marked as required but it's actually optional in the implementation. This is evident from:

  1. The validation logic only requiring notes when serviced_on is present
  2. The form treating it as an optional field

Apply this fix:

-  notes: string;
+  notes?: string;

Likely invalid or redundant comment.

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
@rajku-dev
Copy link
Contributor Author

Depends on #8956. Merge only after that PR is merged.

@Jacobjeevan sir, can you please review the final changes?

@github-actions github-actions bot added needs-triage question Further information is requested labels Nov 29, 2024
@Jacobjeevan
Copy link
Contributor

Depends on #8956. Merge only after that PR is merged.

@Jacobjeevan sir, can you please review the final changes?

Nothing else apart from translations for now 👍

Also, don't need to refer to anyone here as sir/madam. Just refer to us by our names.

Copy link
Member

@rithviknishad rithviknishad left a comment

Choose a reason for hiding this comment

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

Optional but recommended: Since this is doing quite a lot of refactor on pretty much the entire asset form, I'd recommend switching to using shadcn's form components along with other shadcn's input components too.

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
@rithviknishad rithviknishad added needs review and removed question Further information is requested blocked Deploy-Failed Deplyment is not showing preview needs-triage labels Dec 25, 2024
@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Dec 25, 2024
Copy link

👋 Hi, @rajku-dev,
Conflicts have been detected against the base branch. Please rebase your branch against the base branch.


This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there.

Copy link
Contributor

@Jacobjeevan Jacobjeevan left a comment

Choose a reason for hiding this comment

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

Overall, good job nonetheless, esp on sticking with the issue despite all the changes 👍

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
@@ -180,210 +242,41 @@ const AssetCreate = (props: AssetProps) => {
);

const assetQuery = useTanStackQueryInstead(routes.getAsset, {
Copy link
Contributor

Choose a reason for hiding this comment

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

useQuery here.

Copy link
Contributor Author

@rajku-dev rajku-dev Dec 29, 2024

Choose a reason for hiding this comment

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

useTanStackQueryInstead is also a wrapper around useQuery hook right?
I've replaced those with useQuery for GET and useMutation for POST/UPDATE requests.

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
className="w-auto p-0"
align="start"
>
<Calendar
Copy link
Contributor

Choose a reason for hiding this comment

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

There's issues with both rendering and behavior for the calendar. If you aren't able to solve it, stick with existing DateFormField for now; we will need to migrate or create a similar component with Shadcn's styles eventually.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will be working on it..

Copy link
Contributor Author

@rajku-dev rajku-dev Dec 30, 2024

Choose a reason for hiding this comment

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

There's issues with both rendering and behavior for the calendar. If you aren't able to solve it, stick with existing DateFormField for now; we will need to migrate or create a similar component with Shadcn's styles eventually.

@Jacobjeevan tried to align it properly, but i think its a problem in the template itself, hope they fix it soon🤞
I've switched to good old DateFormField for Expiry and Last Service Date fields wrapped in ShadCN FormControl, please review the changes.
Thank You

@rajku-dev
Copy link
Contributor Author

rajku-dev commented Dec 29, 2024

Overall, good job nonetheless, esp on sticking with the issue despite all the changes 👍

Thanks🙌
I hope the original issue will be reopened and re-assigned to me.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/components/Facility/AssetCreate.tsx (3)

86-152: Improve form submission error handling and state management.

  1. The error handling in the submit function could be more robust
  2. The addMore state management could be simplified
 const onSubmit = async (values: FormData) => {
   if (Object.keys(errors).length > 0) {
     const firstErrorField = Object.keys(errors)[0] as keyof FormData;
     form.setFocus(firstErrorField, { shouldSelect: true });
     const firstErrorElement = document.querySelector(
       `[name=${firstErrorField}]`,
     );
     if (firstErrorElement) {
       firstErrorElement.scrollIntoView({
         behavior: "smooth",
         block: "center",
       });
     }
+    return;
   }
   setLoading(true);
+  try {
     const data: any = {
       // ... data preparation
     };

     if (!assetId) {
       const res = await createAsset(data);
-      if (res) {
-        Notification.Success({ msg: "Asset created successfully" });
-        if (addMore) {
-          form.reset();
-          const pageContainer = window.document.getElementById("pages");
-          pageContainer?.scroll(0, 0);
-          setAddMore(false);
-        } else {
-          goBack();
-        }
-      }
+      Notification.Success({ msg: t("asset_created_successfully") });
+      if (addMore) {
+        form.reset();
+        window.document.getElementById("pages")?.scroll(0, 0);
+      } else {
+        goBack();
+      }
     } else {
       const res = await updateAsset(data);
-      if (res) {
-        Notification.Success({ msg: "Asset updated successfully" });
-        goBack();
-      }
+      Notification.Success({ msg: t("asset_updated_successfully") });
+      goBack();
     }
+  } catch (error) {
+    // Error handling is now moved to mutation callbacks
+  } finally {
     setLoading(false);
   }
 };

153-169: Improve QR code parsing error handling.

The error handling in parseAssetId could be more specific and user-friendly.

 const parseAssetId = (assetUrl: string) => {
   try {
     const params = parseQueryParams(assetUrl);
     const assetId = params.asset || params.assetQR;
     if (assetId) {
       form.setValue("qr_code_id", assetId);
       form.clearErrors("qr_code_id");
       setIsScannerActive(false);
       return;
     }
+    throw new Error(t("invalid_qr_code"));
   } catch (err) {
-    Notification.Error({ msg: err });
+    Notification.Error({
+      msg: err instanceof Error ? err.message : t("qr_code_parsing_error"),
+    });
   }
-  Notification.Error({ msg: "Invalid Asset Id" });
   setIsScannerActive(false);
 };

Line range hint 68-977: Overall component structure looks good with some areas for improvement.

The component has been well-refactored to use modern form handling with react-hook-form and Zod. Consider these improvements:

  1. Add missing translations for form labels
  2. Enhance error handling in mutations and QR code scanning
  3. Review Calendar component implementation
  4. Consider using TypeScript's strict mode to avoid any type in form data

The component structure and organization are clean and maintainable.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4f24c9b and 06b1f88.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (4 hunks)
🔇 Additional comments (2)
src/components/Facility/AssetCreate.tsx (2)

1-57: LGTM! Well-organized imports using absolute paths.

The imports are properly organized and use absolute paths as requested in previous reviews.


901-909: Review Calendar component implementation.

As mentioned in previous reviews, there are issues with the Calendar component's rendering and behavior. Consider using the existing DateFormField component until the Calendar component is properly implemented.

src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/AssetCreate.tsx Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the merge conflict pull requests with merge conflict label Dec 29, 2024
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: 1

♻️ Duplicate comments (2)
src/components/Facility/AssetCreate.tsx (2)

132-145: 🛠️ Refactor suggestion

Add error handling to mutations.

The mutations should handle errors explicitly to provide better user feedback.

 const { mutateAsync: createAsset } = useMutation({
   mutationFn: mutate(routes.createAsset),
+  onError: (error) => {
+    Notification.Error({
+      msg: t("failed_to_create_asset"),
+    });
+  },
 });

 const { mutateAsync: updateAsset } = useMutation({
   mutationFn: mutate(routes.updateAsset, {
     pathParams: { external_id: String(assetId) },
   }),
+  onError: (error) => {
+    Notification.Error({
+      msg: t("failed_to_update_asset"),
+    });
+  },
   onSuccess: () => {
     queryClient.invalidateQueries({
       queryKey: [assetQueryKey],
     });
   },
 });

455-455: 🛠️ Refactor suggestion

Add translations for form labels.

Several form labels are missing translations. Add translation keys for these labels in the en.json file:

  • Asset Name
  • Asset Class
  • Manufacturer
  • Customer Support Name
  • Customer Support Email
  • Vendor Name
  • Serial Number
  • Last Serviced On
  • Notes

Also applies to: 513-515, 690-692, 772-774, 819-821, 841-843, 863-865, 887-889, 943-943

🧹 Nitpick comments (1)
src/components/Facility/AssetCreate.tsx (1)

213-229: Improve error handling in asset ID parsing.

The error handling in parseAssetId could be more specific:

  1. Type the error properly
  2. Use translations for error messages
 try {
   const params = parseQueryParams(assetUrl);
   const assetId = params.asset || params.assetQR;
   if (assetId) {
     form.setValue("qr_code_id", assetId);
     form.clearErrors("qr_code_id");
     setIsScannerActive(false);
     return;
   }
- } catch (err) {
+ } catch (error) {
-  Notification.Error({ msg: err });
+  console.error("Error parsing asset ID:", error);
+  Notification.Error({ msg: t("error_parsing_asset_id") });
 }
- Notification.Error({ msg: "Invalid Asset Id" });
+ Notification.Error({ msg: t("invalid_asset_id") });
 setIsScannerActive(false);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between aaee965 and 2b09246.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (4 hunks)
🔇 Additional comments (2)
src/components/Facility/AssetCreate.tsx (2)

1-56: Switch to absolute imports consistently.

As mentioned in the past review comments, let's maintain consistency by using absolute imports throughout the file.

For example:

-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/utils";
-import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon";
+import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon";

231-253: Well-structured form setup with proper typing and validation!

The form setup follows best practices:

  • Uses Zod for type-safe schema validation
  • Properly infers types from the schema
  • Sets appropriate default values

Comment on lines 147 to 212
const onSubmit = async (values: FormData) => {
if (Object.keys(errors).length > 0) {
const firstErrorField = Object.keys(errors)[0] as keyof FormData;
form.setFocus(firstErrorField, { shouldSelect: true });
const firstErrorElement = document.querySelector(
`[name=${firstErrorField}]`,
);
if (firstErrorElement) {
firstErrorElement.scrollIntoView({
behavior: "smooth",
block: "center",
});
}
}
setLoading(true);

const data: any = {
name: values.name,
asset_type: AssetType.INTERNAL,
asset_class: values.asset_class || "",
description: values.description,
is_working: values.is_working,
not_working_reason: values.is_working ? "" : values.not_working_reason,
serial_number: values.serial_number,
location: values.location,
vendor_name: values.vendor_name,
support_name: values.support_name,
support_email: values.support_email,
support_phone: values.support_phone?.startsWith("1800")
? values.support_phone
: parsePhoneNumber(String(values.support_phone)),
qr_code_id: values.qr_code_id !== "" ? values.qr_code_id : null,
manufacturer: values.manufacturer,
warranty_amc_end_of_validity: values.warranty_amc_end_of_validity
? dateQueryString(values.warranty_amc_end_of_validity)
: null,
};

if (values.serviced_on) {
data["last_serviced_on"] = dateQueryString(values.serviced_on);
data["note"] = values.note ?? "";
}

if (!assetId) {
const res = await createAsset(data);
if (res) {
Notification.Success({ msg: "Asset created successfully" });
if (addMore) {
form.reset();
const pageContainer = window.document.getElementById("pages");
pageContainer?.scroll(0, 0);
setAddMore(false);
} else {
goBack();
}
}
setLoading(false);
} else {
const res = await updateAsset(data);
if (res) {
Notification.Success({ msg: "Asset updated successfully" });
goBack();
}
setLoading(false);
}
};
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 form submission handling.

A few suggestions for improvement:

  1. Use translations for success messages
  2. Add error handling for the else case in update flow
  3. Consider using a phone number validator utility
 if (!assetId) {
   const res = await createAsset(data);
   if (res) {
-    Notification.Success({ msg: "Asset created successfully" });
+    Notification.Success({ msg: t("asset_created_successfully") });
     if (addMore) {
       form.reset();
       const pageContainer = window.document.getElementById("pages");
       pageContainer?.scroll(0, 0);
       setAddMore(false);
     } else {
       goBack();
     }
+  } else {
+    Notification.Error({ msg: t("failed_to_create_asset") });
   }
   setLoading(false);
 } else {
   const res = await updateAsset(data);
   if (res) {
-    Notification.Success({ msg: "Asset updated successfully" });
+    Notification.Success({ msg: t("asset_updated_successfully") });
     goBack();
+  } else {
+    Notification.Error({ msg: t("failed_to_update_asset") });
   }
   setLoading(false);
 }
📝 Committable suggestion

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

Suggested change
const onSubmit = async (values: FormData) => {
if (Object.keys(errors).length > 0) {
const firstErrorField = Object.keys(errors)[0] as keyof FormData;
form.setFocus(firstErrorField, { shouldSelect: true });
const firstErrorElement = document.querySelector(
`[name=${firstErrorField}]`,
);
if (firstErrorElement) {
firstErrorElement.scrollIntoView({
behavior: "smooth",
block: "center",
});
}
}
setLoading(true);
const data: any = {
name: values.name,
asset_type: AssetType.INTERNAL,
asset_class: values.asset_class || "",
description: values.description,
is_working: values.is_working,
not_working_reason: values.is_working ? "" : values.not_working_reason,
serial_number: values.serial_number,
location: values.location,
vendor_name: values.vendor_name,
support_name: values.support_name,
support_email: values.support_email,
support_phone: values.support_phone?.startsWith("1800")
? values.support_phone
: parsePhoneNumber(String(values.support_phone)),
qr_code_id: values.qr_code_id !== "" ? values.qr_code_id : null,
manufacturer: values.manufacturer,
warranty_amc_end_of_validity: values.warranty_amc_end_of_validity
? dateQueryString(values.warranty_amc_end_of_validity)
: null,
};
if (values.serviced_on) {
data["last_serviced_on"] = dateQueryString(values.serviced_on);
data["note"] = values.note ?? "";
}
if (!assetId) {
const res = await createAsset(data);
if (res) {
Notification.Success({ msg: "Asset created successfully" });
if (addMore) {
form.reset();
const pageContainer = window.document.getElementById("pages");
pageContainer?.scroll(0, 0);
setAddMore(false);
} else {
goBack();
}
}
setLoading(false);
} else {
const res = await updateAsset(data);
if (res) {
Notification.Success({ msg: "Asset updated successfully" });
goBack();
}
setLoading(false);
}
};
const onSubmit = async (values: FormData) => {
if (Object.keys(errors).length > 0) {
const firstErrorField = Object.keys(errors)[0] as keyof FormData;
form.setFocus(firstErrorField, { shouldSelect: true });
const firstErrorElement = document.querySelector(
`[name=${firstErrorField}]`,
);
if (firstErrorElement) {
firstErrorElement.scrollIntoView({
behavior: "smooth",
block: "center",
});
}
}
setLoading(true);
const data: any = {
name: values.name,
asset_type: AssetType.INTERNAL,
asset_class: values.asset_class || "",
description: values.description,
is_working: values.is_working,
not_working_reason: values.is_working ? "" : values.not_working_reason,
serial_number: values.serial_number,
location: values.location,
vendor_name: values.vendor_name,
support_name: values.support_name,
support_email: values.support_email,
support_phone: values.support_phone?.startsWith("1800")
? values.support_phone
: parsePhoneNumber(String(values.support_phone)),
qr_code_id: values.qr_code_id !== "" ? values.qr_code_id : null,
manufacturer: values.manufacturer,
warranty_amc_end_of_validity: values.warranty_amc_end_of_validity
? dateQueryString(values.warranty_amc_end_of_validity)
: null,
};
if (values.serviced_on) {
data["last_serviced_on"] = dateQueryString(values.serviced_on);
data["note"] = values.note ?? "";
}
if (!assetId) {
const res = await createAsset(data);
if (res) {
Notification.Success({ msg: t("asset_created_successfully") });
if (addMore) {
form.reset();
const pageContainer = window.document.getElementById("pages");
pageContainer?.scroll(0, 0);
setAddMore(false);
} else {
goBack();
}
} else {
Notification.Error({ msg: t("failed_to_create_asset") });
}
setLoading(false);
} else {
const res = await updateAsset(data);
if (res) {
Notification.Success({ msg: t("asset_updated_successfully") });
goBack();
} else {
Notification.Error({ msg: t("failed_to_update_asset") });
}
setLoading(false);
}
};

@rajku-dev rajku-dev changed the title 💊Fix unnecessary API Calls on updating an existing asset (#9189) Revamp Asset Create/Update Workflow using ShadCN, React-Hook-Form, and TanStack Query Dec 29, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 70d52bb and 760b363.

📒 Files selected for processing (1)
  • src/components/Facility/AssetCreate.tsx (4 hunks)
🔇 Additional comments (3)
src/components/Facility/AssetCreate.tsx (3)

1-48: LGTM! Well-organized imports and type definitions.

The code follows best practices with:

  • Consistent use of absolute imports
  • Clear organization of imports by category
  • Proper type definitions for props and form data

124-137: 🛠️ Refactor suggestion

Add error handling to mutations.

The mutations should handle errors explicitly to provide better user feedback.

 const { mutateAsync: createAsset } = useMutation({
   mutationFn: mutate(routes.createAsset),
+  onError: (error) => {
+    Notification.Error({
+      msg: t("failed_to_create_asset"),
+    });
+  },
 });

 const { mutateAsync: updateAsset } = useMutation({
   mutationFn: mutate(routes.updateAsset, {
     pathParams: { external_id: String(assetId) },
   }),
+  onError: (error) => {
+    Notification.Error({
+      msg: t("failed_to_update_asset"),
+    });
+  },
   onSuccess: () => {
     queryClient.invalidateQueries({
       queryKey: [assetQueryKey],
     });
   },
 });

Likely invalid or redundant comment.


97-122: ⚠️ Potential issue

Add null check for location_object access.

The code directly accesses asset.location_object.id without checking if location_object exists.

 useEffect(() => {
   if (assetId && assetQuery.data && assetQuery.data.data) {
     const asset = assetQuery.data.data;
     form.reset({
       name: asset.name,
-      location: asset.location_object.id,
+      location: asset.location_object?.id || "",
       asset_class: asset.asset_class,
       // ... rest of the fields
     });
   }
 }, [assetQuery.data]);

Likely invalid or redundant comment.

Comment on lines +449 to +450
Asset Name{" "}
<span className="text-red-500">*</span>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add translations for form labels.

Several form labels are hardcoded in English. Add translation keys for consistency.

Examples of labels needing translation:

  • "Asset Name"
  • "Location"
  • "Asset Class"
  • "Description"
  • "Why the asset is not working?"
  • "QR Code ID"
  • "Manufacturer"
  • "Warranty / AMC Expiry"
  • "Customer Support Name"
  • "Customer Support Phone"
  • "Customer Support Email"
  • "Vendor Name"
  • "Serial Number"
  • "Last Serviced On Date"
  • "Notes"

Add corresponding keys to the translation files and use them with the t() function.

Also applies to: 476-477, 515-516, 559-560, 625-626, 664-665, 700-701, 726-727, 755-756, 781-782, 808-809, 834-835, 860-861, 888-889, 917-917

Comment on lines +183 to +204
if (!assetId) {
const res = await createAsset(data);
if (res) {
Notification.Success({ msg: "Asset created successfully" });
if (addMore) {
form.reset();
const pageContainer = window.document.getElementById("pages");
pageContainer?.scroll(0, 0);
setAddMore(false);
} else {
goBack();
}
}
setLoading(false);
} else {
const res = await updateAsset(data);
if (res) {
Notification.Success({ msg: "Asset updated successfully" });
goBack();
}
setLoading(false);
}
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 translations for success messages.

Success notifications should use translated messages for consistency.

 if (!assetId) {
   const res = await createAsset(data);
   if (res) {
-    Notification.Success({ msg: "Asset created successfully" });
+    Notification.Success({ msg: t("asset_created_successfully") });
     if (addMore) {
       // ... rest of the code
     }
   }
 } else {
   const res = await updateAsset(data);
   if (res) {
-    Notification.Success({ msg: "Asset updated successfully" });
+    Notification.Success({ msg: t("asset_updated_successfully") });
     goBack();
   }
 }
📝 Committable suggestion

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

Suggested change
if (!assetId) {
const res = await createAsset(data);
if (res) {
Notification.Success({ msg: "Asset created successfully" });
if (addMore) {
form.reset();
const pageContainer = window.document.getElementById("pages");
pageContainer?.scroll(0, 0);
setAddMore(false);
} else {
goBack();
}
}
setLoading(false);
} else {
const res = await updateAsset(data);
if (res) {
Notification.Success({ msg: "Asset updated successfully" });
goBack();
}
setLoading(false);
}
if (!assetId) {
const res = await createAsset(data);
if (res) {
Notification.Success({ msg: t("asset_created_successfully") });
if (addMore) {
form.reset();
const pageContainer = window.document.getElementById("pages");
pageContainer?.scroll(0, 0);
setAddMore(false);
} else {
goBack();
}
}
setLoading(false);
} else {
const res = await updateAsset(data);
if (res) {
Notification.Success({ msg: t("asset_updated_successfully") });
goBack();
}
setLoading(false);
}

@rajku-dev
Copy link
Contributor Author

All fields look pretty similar to the original one now

image

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Dec 31, 2024
Copy link

👋 Hi, @rajku-dev,
Conflicts have been detected against the base branch. Please rebase your branch against the base branch.


This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there.

@rithviknishad
Copy link
Member

rithviknishad commented Dec 31, 2024

"assets" is no longer present in new architecture as of now. we can rethink once it's brought back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge conflict pull requests with merge conflict needs review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unnecessary API Calls in Assets Update Page
4 participants