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

chore: decouple widget-config.json from main chunk #36924

Merged
merged 7 commits into from
Oct 17, 2024
Merged

chore: decouple widget-config.json from main chunk #36924

merged 7 commits into from
Oct 17, 2024

Conversation

vsvamsi1
Copy link
Contributor

@vsvamsi1 vsvamsi1 commented Oct 17, 2024

Description

We decoupled the widget-config.json file (177KB when zipped) from the main bundle and implemented lazy loading during DSL migrations. This optimisation reduces the size of the main chunk by 10%, which should lead to better performance, specifically improving FCP and LCP, as the main chunk's fetch and evaluation times are reduced

Fixes #Issue Number
or
Fixes Issue URL

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/11384816747
Commit: ae14b3f
Cypress dashboard.
Tags: @tag.All
Spec:


Thu, 17 Oct 2024 15:04:34 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Enhanced migration logic for DSL widgets with asynchronous operations.
    • Improved performance with lazy loading of widget configurations.
    • Added optional properties to page response data structures.
  • Bug Fixes

    • Resolved issues with dynamic binding path migrations.
  • Tests

    • Updated test cases to handle asynchronous operations for better reliability and accuracy.
  • Chores

    • Improved type safety and error handling in widget factory utilities and mock functions.

@vsvamsi1 vsvamsi1 added the ok-to-test Required label for CI label Oct 17, 2024
@vsvamsi1 vsvamsi1 self-assigned this Oct 17, 2024
@vsvamsi1 vsvamsi1 requested a review from a team as a code owner October 17, 2024 05:41
@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Oct 17, 2024
@vsvamsi1
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11379443183.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36924.
recreate: .

Comment on lines +50 to +51
isDefault?: boolean;
isHidden?: boolean;
Copy link
Contributor Author

@vsvamsi1 vsvamsi1 Oct 17, 2024

Choose a reason for hiding this comment

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

@jsartisan I had to support these two types because the test case was asking mock response.

Copy link

Deploy-Preview-URL: https://ce-36924.dp.appsmith.com

Copy link
Contributor

@jsartisan jsartisan left a comment

Choose a reason for hiding this comment

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

Left some tiny comments. Otherwise looks ok to me.

@@ -47,6 +47,8 @@ export interface PageLayoutsRequest {
}

export interface FetchPageResponseData {
isDefault?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add comments about what these two new properties used for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was actually used in the mock of the test case. I assumed there were missing properties in the interface hence added them.

@vsvamsi1
Copy link
Contributor Author

@jsartisan can you review the dom test cases, i had to add wait for the canvas dom element to load since we are lazily loading the config json script.

@jsartisan
Copy link
Contributor

It looks weird from the look of it, but if it works then fine.

Copy link
Contributor

coderabbitai bot commented Oct 17, 2024

Walkthrough

The pull request introduces significant enhancements to the migration logic for DSL widgets by implementing asynchronous operations across multiple functions. Key functions such as migrateVersionedDSL, migrateDSL, and various widget property configuration functions have been updated to support async handling. Additionally, several test cases have been restructured to accommodate these changes, ensuring proper handling of asynchronous behavior. The modifications extend to various components, services, and tests, enhancing the overall robustness of the DSL migration process.

Changes

File Path Change Summary
app/client/packages/dsl/src/migrate/index.ts Updated migrateVersionedDSL and migrateDSL functions to async, changed return type to Promise.
app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts Added loadWidgetConfig function, updated multiple functions to async for dynamic binding paths.
app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts Restructured tests to use test function from Jest, ensured async operations are awaited.
app/client/packages/dsl/src/migrate/tests/DSLMigrationsUtils.test.ts Updated tests to handle async, added alignment property in expected output for RadioGroupWidget.
app/client/packages/rts/src/controllers/Dsl/DslController.ts Modified migrateDSL method to async for handling migration.
app/client/packages/rts/src/routes/dsl_routes.ts Updated /migrate route to wrap dslController.migrateDSL in async function.
app/client/packages/rts/src/services/DslService.ts Changed migrateDSLToLatest function to async, returning a promise.
app/client/src/api/PageApi.tsx Added optional properties isDefault and isHidden to response data interfaces.
app/client/src/components/designSystems/blueprintjs/icon/Icon.tsx Enhanced SVG caching mechanism, added IconSize enum and async function for SVG imports.
app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.test.tsx Updated tests for async behavior.
app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx Updated tests to handle async rendering.
app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.test.tsx Enhanced async handling in test cases.
app/client/src/pages/Editor/IDE/AppsmithIDE.test.tsx Updated drag-and-drop tests to handle async operations.
app/client/src/pages/Editor/IDE/EditorPane/UI/UIRender.test.tsx Enhanced structure and reliability of tests.
app/client/src/utils/WidgetPropsUtils.tsx Updated extractCurrentDSL to return a Promise.
app/client/src/widgets/ContainerWidget/widget/index.test.tsx Enhanced async behavior handling in tests.
app/client/src/widgets/TabsWidget/widget/index.test.tsx Updated test cases for async handling.
app/client/test/factories/WidgetFactoryUtils.ts Improved type assertions and error handling.
app/client/test/testCommon.ts Enhanced type safety and control rendering based on loading status.
app/client/test/testMockedWidgets.tsx Modified conditional rendering based on loading status.

Possibly related PRs

Suggested labels

Enhancement, Task, Tech Debt, Integrations Product, Integrations Pod General

Suggested reviewers

  • ApekshaBhosale
  • jsartisan
  • sagar-qa007
  • rishabhrathod01

🌟 In the realm of code, where logic does flow,
Asynchronous magic begins to bestow.
With functions now waiting, the future looks bright,
Migration's a journey, a wondrous delight!
Through tests that are structured, and widgets that gleam,
We dance with the code, living out our dream! 🌟


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.

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

🧹 Outside diff range and nitpick comments (19)
app/client/packages/rts/src/routes/dsl_routes.ts (1)

16-21: Excellent work on embracing asynchronous programming, students!

Your modification to wrap the route handler in an async function is a step in the right direction. It's like learning to ride a bicycle - once you master it, you'll wonder how you ever managed without it!

However, let's not forget about error handling. Remember, in the real world, things don't always go as planned. Let's add a try-catch block to make our code more robust.

Here's a little homework assignment for you:

 router.post(
   "/migrate",
   validator.validateRequest,
-  async (req: Request, res: Response) =>
-    await dslController.migrateDSL(req, res),
+  async (req: Request, res: Response) => {
+    try {
+      await dslController.migrateDSL(req, res);
+    } catch (error) {
+      console.error('Error during DSL migration:', error);
+      res.status(500).json({ error: 'An error occurred during migration' });
+    }
+  },
 );

This way, we're prepared for any unexpected hiccups in our migration process. Always remember, class: "Prepare for the worst, hope for the best!"

app/client/test/testMockedWidgets.tsx (2)

16-19: Good job on improving type safety and handling loading state!

Class, let's review the changes made to the UpdateAppViewer function:

  1. The type annotation for the dsl parameter has been updated from any to unknown. This is a step in the right direction for type safety. Well done!

  2. The hasLoaded variable is introduced to track the loading state of the mock DSL. This is a good practice for handling asynchronous operations.

  3. The conditional rendering ensures that the AppViewerPageContainer is only rendered when the DSL has finished loading. This prevents potential errors from rendering with incomplete data.

These changes align well with our lesson on decoupling and asynchronous loading. However, to make it even better, consider adding a loading indicator for a smoother user experience:

return hasLoaded ? <AppViewerPageContainer /> : <LoadingIndicator />;

21-24: Excellent work on maintaining consistency across functions!

Class, let's examine the changes made to the UpdatedEditor function:

  1. Just like in UpdateAppViewer, the type annotation for the dsl parameter has been updated from any to unknown. This consistency in improving type safety across functions is commendable. Keep up the good work!

  2. The hasLoaded variable is used here as well to track the loading state of the mock DSL. This parallel structure between functions is a great example of maintaining code consistency.

  3. The conditional rendering ensures that the IDE component is only rendered when the DSL has finished loading. This prevents potential errors from rendering with incomplete data.

These changes demonstrate a good understanding of our lessons on type safety and asynchronous operations. To further improve this function and maintain consistency with UpdateAppViewer, consider adding a loading indicator here as well:

return hasLoaded ? <IDE /> : <LoadingIndicator />;

Remember, consistency in your code is key to maintaining readability and reducing confusion for other developers who might work on this code in the future.

app/client/packages/rts/src/controllers/Dsl/DslController.ts (1)

Line range hint 24-35: Consider future-proofing getLatestDSLVersion

Class, let's turn our attention to the getLatestDSLVersion method. While it hasn't been changed in this update, it's a good opportunity to think about future-proofing our code.

Currently, this method is synchronous, which is fine if latestDSLVersion is a simple constant or synchronous function. However, in the spirit of preparing for future changes, we might want to consider making this method asynchronous as well.

Here's a little homework for you to ponder:

  1. Could retrieving the latest DSL version ever involve asynchronous operations in the future?
  2. Would making this method async now make it easier to implement such changes later?
  3. Is there a benefit to keeping the interface of both methods (migrateDSL and getLatestDSLVersion) consistent?

Remember, good software design often involves thinking ahead! What do you think about making this change?

If you decide to make this change, here's how you could modify the method:

- getLatestDSLVersion(req: Request, res: Response) {
+ async getLatestDSLVersion(req: Request, res: Response) {
    try {
-     super.sendResponse(res, { version: latestDSLVersion });
+     const version = await latestDSLVersion;
+     super.sendResponse(res, { version });
    } catch (err) {
      return super.sendError(
        res,
        this.serverErrorMessage,
        [err.message],
        StatusCodes.INTERNAL_SERVER_ERROR,
      );
    }
  }
app/client/test/factories/WidgetFactoryUtils.ts (1)

28-28: Good job on adding error logging!

I'm pleased to see you've added error logging to help diagnose issues with child widget data. This will be very helpful during development and debugging. However, let's make it even better! Instead of a generic message, consider including the actual error in the log. Here's a suggestion:

console.error("Error processing child widget data:", error);

This way, we'll have more specific information about what went wrong. Remember, clear error messages are like detailed notes in your homework - they help us understand and solve problems faster!

app/client/src/widgets/TabsWidget/widget/index.test.tsx (1)

Line range hint 52-80: Well done, class! Let's review these changes.

Now, pay attention to how we've improved our test. We've made it asynchronous and added a waiting period for the canvas to load. This is excellent practice!

Remember, in the real world of web development, things don't always happen instantly. By waiting for the canvas to load, we're ensuring our test mimics real-world scenarios more accurately. It's like waiting for all students to arrive before starting the lesson - it's only fair!

As a small suggestion, consider adding a comment explaining why we're waiting for the canvas to load. It's always good to leave notes for future developers (or yourself) to understand the reasoning behind such changes.

 // wait for the dom to settle down by waitng for the canvas to be loaded
+// This ensures all components are fully rendered before we start our assertions
 await component.findByTestId("t--canvas-artboard");

Any questions about these changes?

app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx (4)

Line range hint 118-139: Excellent progress on asynchronous testing!

Students, let's examine this test case. The use of await component.findByText is like giving our test a magnifying glass to find the widget it needs to interact with. This is a significant improvement over the previous method.

However, I have a small suggestion to make our code even clearer:

Consider extracting the timeout value into a constant at the top of the file. For example:

const ELEMENT_WAIT_TIMEOUT = 3000; // milliseconds

Then use it like this:

const tabsWidget: Element = await component.findByText(
  children[0].widgetName,
  undefined,
  { timeout: ELEMENT_WAIT_TIMEOUT },
);

This way, if we need to adjust the timeout in the future, we only need to change it in one place. It's like having a single clock that all our tests can refer to!


Line range hint 154-180: Good progress, but let's ensure consistency!

Class, I'm pleased to see the continued improvement in our test cases. The use of await component.findByText for the checkbox widget is commendable. It's like giving our test a pair of binoculars to spot the widget from afar!

However, I've noticed something that needs our attention:

The switchWidget is still being queried using component.queryByText. For consistency and to prevent potential timing issues, we should update this as well. Here's how it should look:

const switchWidget: Element = await component.findByText(
  children[1].widgetName,
  undefined,
  { timeout: 3000 },
);

Remember, consistency in our code is like having a well-organized classroom. It makes everything easier to understand and maintain. Let's make sure all our widget queries are using the same method.


Line range hint 211-239: Good progress, but let's complete the transformation!

Students, I'm glad to see we're continuing to improve our test cases. The use of await component.findByText for the checkbox widget is like giving our test a stopwatch to wait for the right moment. Well done!

However, we have a small oversight that needs our attention:

The buttonWidget is still being queried using component.queryByText. To maintain consistency and prevent potential timing issues, we should update this as well. Here's the correction we need to make:

const buttonWidget: Element = await component.findByText(
  children[2].widgetName,
  undefined,
  { timeout: 3000 },
);

Remember, in programming, as in the classroom, consistency is key. It helps us avoid confusion and makes our code more reliable. Let's make sure all our widget queries are using the same asynchronous method.


Line range hint 271-330: Good start, but let's finish strong!

Class, I'm pleased to see the progress in updating our test cases. The use of await component.findByText for the container widget is a step in the right direction. It's like giving our test a patient teacher who waits for the student to arrive before starting the lesson.

However, we have a few more improvements to make:

The buttonWidget, checkBoxWidget, and chartWidget are still being queried using component.queryByText. To ensure consistency and reliability across our tests, we should update these as well. Here's what we need to do:

  1. Update buttonWidget:
const buttonWidget: Element = await component.findByText(
  children[2].widgetName,
  undefined,
  { timeout: 3000 },
);
  1. Update checkBoxWidget:
const checkBoxWidget: Element = await component.findByText(
  children[0].widgetName,
  undefined,
  { timeout: 3000 },
);
  1. Update chartWidget:
const chartWidget: Element = await component.findByText(
  containerChildren[1].widgetName,
  undefined,
  { timeout: 3000 },
);

Remember, consistency in our tests is like having a well-tuned orchestra. When all instruments play in harmony, we create beautiful music - or in our case, reliable and robust tests. Let's make sure all our widget queries are using the same asynchronous method.

app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.test.tsx (3)

Line range hint 127-175: Excellent consistency in applying async patterns, students!

I'm impressed to see you've applied the same improvements to this test case as well. Using await component.findByTestId with a timeout is indeed the correct approach here. It's like waiting for all students to arrive before starting the lesson - very considerate!

However, I have a small suggestion that could make your code even better. Can anyone tell me what we could do with the number 3000 that appears in both test cases? That's right! We could extract it into a constant. Something like:

const ELEMENT_WAIT_TIMEOUT = 3000;

This way, if we ever need to adjust the timeout, we only need to change it in one place. Remember, good code is not just about making it work, but also about making it easy to maintain!

Keep up the fantastic work, class!


Line range hint 229-366: Bravo on your error handling skills, young coders!

I'm thrilled to see you've not only applied our async improvements consistently but also introduced some excellent error handling in your new test case. It's like you're not just answering the questions I've asked, but anticipating the next lesson too!

Your use of a try-catch block to handle the case where the canvas component isn't found is commendable. It's always important to expect the unexpected in our tests.

However, I have a small suggestion that could make your code even more robust. Instead of setting selectionCanvas to null in the catch block, why not check if the error is specifically about the element not being found? Something like this:

} catch (e) {
  if (e.name === 'TestingLibraryElementError') {
    selectionCanvas = null;
  } else {
    throw e;  // Re-throw unexpected errors
  }
}

This way, we're only catching the specific error we're expecting, and any other unexpected errors will still be thrown and caught by our test runner. It's like distinguishing between a student who's absent and one who's causing trouble!

Keep up this excellent attention to detail, class!


Line range hint 371-452: Consistency is key, and you're nailing it, class!

I'm delighted to see you've applied the same async improvements to this test case as well. Your dedication to maintaining a consistent coding style across all tests is commendable. It's like everyone in the class is wearing the same uniform - it looks neat and professional!

However, I notice that we're still seeing that magic number 3000 pop up again. Remember our earlier discussion about extracting this value into a constant? This would be another perfect place to use it.

Let's have a quick pop quiz: What are the benefits of using a constant instead of repeating the number 3000?

  1. It makes the code more maintainable
  2. It reduces the chance of errors if we need to change the value
  3. It gives the value a meaningful name, improving readability

The answer? All of the above!

Keep up the great work, and don't forget to apply this improvement across all your tests!

app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts (1)

958-969: A suggestion for improvement, students!

In the mock implementation, you're using the delete operator to remove the children property. While this works, it's not the most efficient approach. Let's consider a more performance-friendly alternative:

- dsl && delete dsl.children;
+ if (dsl) dsl.children = undefined;

This change will achieve the same result but without the potential performance impact of the delete operator. Remember, in JavaScript, setting a property to undefined is generally faster than deleting it!

🧰 Tools
🪛 Biome

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

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

app/client/src/pages/Editor/IDE/AppsmithIDE.test.tsx (3)

Line range hint 279-393: Excellent work on making this test asynchronous!

Class, let's give a round of applause for this improvement. By making the test asynchronous and using await, we're ensuring that our widgets are fully present before we start moving them around. It's like making sure all the desks are in place before rearranging the classroom!

However, I have a small suggestion to make this even better. Can anyone spot the variable that could use a more descriptive name?

Consider renaming the tab variable to something more specific, like tabsWidgetElement. This will make it clearer what the variable represents. Remember, clear variable names are like name tags in a classroom – they help everyone understand what's what!

-const tab: any = component.container.querySelector(".t--widget-tabswidget");
+const tabsWidgetElement: any = component.container.querySelector(".t--widget-tabswidget");

Line range hint 503-642: Good job on updating this test to be asynchronous!

Class, let's take a moment to appreciate the consistency in making our tests asynchronous. It's like everyone remembering to raise their hand before speaking – it keeps everything orderly!

Now, I have a little homework assignment for you. Can you spot the repeated code in this test? That's right, the mouse event simulation is repeated several times. Let's clean this up a bit, shall we?

I suggest we create a helper function to simulate mouse events. This will make our test easier to read and maintain. Here's an example of how we could do this:

function simulateMouseEvent(canvas: HTMLElement, eventType: string, offsetX: number, offsetY: number) {
  fireEvent(
    canvas,
    syntheticTestMouseEvent(
      new MouseEvent(eventType, {
        bubbles: true,
        cancelable: true,
      }),
      {
        offsetX,
        offsetY,
      },
    ),
  );
}

// Usage in the test:
act(() => {
  simulateMouseEvent(mainCanvas, "mousemove", 0, 0);
  simulateMouseEvent(mainCanvas, "mousemove", 0, 300);
  simulateMouseEvent(mainCanvas, "mouseup", 0, 300);
});

Remember, clean code is like a tidy classroom – it makes everything easier for everyone!


Line range hint 643-736: Great job on making this test asynchronous!

Class, let's give a round of applause for consistently updating our tests to be asynchronous. It's like everyone remembering to bring their homework – it makes everything run smoothly!

Now, I have a little challenge for you. Can anyone think of what might happen if the "Container" button doesn't appear? That's right, our test might hang indefinitely! Let's add a safety net, shall we?

I suggest we add a timeout to our findAllByText call. This way, if the button doesn't appear, our test will fail gracefully instead of hanging. Here's how we can do it:

const containerButton: any = await component.findAllByText("Container", { timeout: 5000 });

By adding a timeout, we're saying "If the button doesn't appear within 5 seconds, something's wrong." It's like setting a time limit for a pop quiz – it keeps things moving along!

Remember, good tests not only check for correct behavior but also fail informatively when something goes wrong. Keep up the excellent work!

app/client/packages/dsl/src/migrate/tests/DSLMigrationsUtils.test.ts (1)

Line range hint 3099-3224: A valiant effort on this complex test case, but there's room for improvement!

Your thoroughness in checking multiple validation properties is commendable. However, let's work on making this test more readable and robust:

  1. Consider breaking down the complex DSL structure into smaller, more manageable pieces. This will make it easier for your classmates to understand and maintain.

  2. Instead of using indexOf to check for string presence, try using more precise methods like includes() or regular expressions. This will make your tests more reliable.

  3. Add some comments explaining the purpose of each validation check. Remember, clear communication is key in coding!

Keep up the good work, and don't be afraid to ask for help in simplifying complex structures!

app/client/test/testCommon.ts (1)

Line range hint 265-271: Update deprecated 'initKeyboardEvent' to 'KeyboardEvent' constructor

The initKeyboardEvent() method is deprecated and may not be supported in all browsers. It's better to use the KeyboardEvent constructor for creating keyboard events.

Apply this diff to modernize the event creation:

 export function dispatchTestKeyboardEventWithCode(
   target: EventTarget,
   eventType: string,
   key: string,
   keyCode: number,
   shift = false,
   meta = false,
 ) {
-  const event = document.createEvent("KeyboardEvent");
-  event.initKeyboardEvent(
-    eventType,
-    true,
-    true,
-    window,
-    key,
-    0,
-    meta,
-    false,
-    shift,
-  );
+  const event = new KeyboardEvent(eventType, {
+    bubbles: true,
+    cancelable: true,
+    key,
+    code: key,
+    keyCode,
+    shiftKey: shift,
+    metaKey: meta,
+  });
   Object.defineProperty(event, "key", { get: () => key });
   Object.defineProperty(event, "which", { get: () => keyCode });

   target.dispatchEvent(event);
 }

This change enhances compatibility and adheres to modern web standards.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 81b2146 and 32806b9.

📒 Files selected for processing (21)
  • app/client/packages/dsl/src/migrate/index.ts (3 hunks)
  • app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (6 hunks)
  • app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts (1 hunks)
  • app/client/packages/dsl/src/migrate/tests/DSLMigrationsUtils.test.ts (5 hunks)
  • app/client/packages/rts/src/controllers/Dsl/DslController.ts (1 hunks)
  • app/client/packages/rts/src/routes/dsl_routes.ts (2 hunks)
  • app/client/packages/rts/src/services/DslService.ts (1 hunks)
  • app/client/src/api/PageApi.tsx (1 hunks)
  • app/client/src/ce/sagas/PageSagas.tsx (7 hunks)
  • app/client/src/components/designSystems/blueprintjs/icon/Icon.tsx (1 hunks)
  • app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.test.tsx (11 hunks)
  • app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx (11 hunks)
  • app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.test.tsx (10 hunks)
  • app/client/src/pages/Editor/IDE/AppsmithIDE.test.tsx (15 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/UI/UIRender.test.tsx (2 hunks)
  • app/client/src/utils/WidgetPropsUtils.tsx (2 hunks)
  • app/client/src/widgets/ContainerWidget/widget/index.test.tsx (2 hunks)
  • app/client/src/widgets/TabsWidget/widget/index.test.tsx (2 hunks)
  • app/client/test/factories/WidgetFactoryUtils.ts (2 hunks)
  • app/client/test/testCommon.ts (7 hunks)
  • app/client/test/testMockedWidgets.tsx (1 hunks)
🧰 Additional context used
🪛 Biome
app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts

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

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

🔇 Additional comments (38)
app/client/packages/rts/src/services/DslService.ts (1)

3-6: Class, pay attention to this excellent asynchronous transformation!

Well done on updating the migrateDSLToLatest function to be asynchronous. This change aligns perfectly with the asynchronous nature of the migrateDSL function it's calling. It's like upgrading from a chalkboard to a smart board - much more efficient!

However, let's make sure we've updated all our "lesson plans" to accommodate this change. We need to verify that all callers of this function are now using await or handling the returned promise correctly.

Let's run a quick pop quiz to check for any stragglers:

Make sure to review the results and update any calls that aren't using await or properly handling the promise. Remember, asynchronous programming is like a group project - everyone needs to be on the same page!

✅ Verification successful

Oops! It looks like our first attempt to locate migrateDSLToLatest ran into a hiccup with the file types. No worries—we'll get things back on track! Let’s adjust our search to target TypeScript files more precisely and uncover those elusive calls and imports. Here’s the updated plan:

Let's give this script another go to ensure all instances are properly identified. Once we have the results, we'll be able to confirm that the asynchronous changes are seamlessly integrated throughout our codebase. Keep up the great work!


Excellent work on ensuring all calls to migrateDSLToLatest are properly handled!

After reviewing the results, it's clear that the migrateDSLToLatest function is consistently awaited wherever it's called. This means our asynchronous transformation is well-integrated and functions as intended across the codebase. Keep up the great attention to detail!

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all occurrences of migrateDSLToLatest that might need updating

echo "Searching for calls to migrateDSLToLatest:"
rg --type typescript "migrateDSLToLatest\(" -C 2

echo "\nSearching for imports of migrateDSLToLatest:"
rg --type typescript "import.*migrateDSLToLatest" -C 2

Length of output: 375


Script:

#!/bin/bash
# Description: Find all occurrences of migrateDSLToLatest that might need updating in .ts and .tsx files.

echo "Searching for calls to migrateDSLToLatest in TypeScript files:"
rg "migrateDSLToLatest\(" -g "*.ts" -g "*.tsx" -C 2

echo "\nSearching for imports of migrateDSLToLatest in TypeScript files:"
rg "import.*migrateDSLToLatest" -g "*.ts" -g "*.tsx" -C 2

Length of output: 1826

app/client/packages/rts/src/routes/dsl_routes.ts (1)

4-4: Well done, class! A gold star for improving type safety!

The addition of these type imports is a commendable step towards enhancing the overall type safety of our code. Remember, children, in the world of TypeScript, explicit types are our friends!

app/client/packages/rts/src/controllers/Dsl/DslController.ts (1)

11-13: Well done on implementing asynchronous handling!

Class, let's take a moment to appreciate the importance of this change. By making migrateDSL an async method and using await with migrateDSLToLatest, we're ensuring that our code properly handles asynchronous operations. This is crucial for maintaining the correct flow of execution and preventing potential race conditions.

Remember, when dealing with asynchronous operations, it's always important to:

  1. Use the async keyword for functions that contain await.
  2. Use await when calling functions that return promises.
  3. Properly handle errors that may occur during asynchronous operations.

You've done an excellent job implementing these principles here. Keep up the good work!

app/client/test/factories/WidgetFactoryUtils.ts (1)

7-7: Well done on improving type safety!

Class, let's take a moment to appreciate this excellent use of TypeScript's type assertion. By first casting to 'unknown' and then to 'DSLWidget', we're following best practices and making our code more robust. This two-step approach helps prevent accidental misuse of the 'any' type, which can lead to type-related bugs. Keep up the good work!

app/client/src/components/designSystems/blueprintjs/icon/Icon.tsx (1)

Line range hint 32-45: Excellent work on implementing caching for SVG imports!

Class, let's take a moment to appreciate the thoughtful optimization implemented here. The introduction of cachedSvgImportsMap and the loadSvgImportsMapOnce function demonstrates a keen understanding of performance considerations.

This caching mechanism serves as a valuable lesson in efficient resource management. By lazily loading the SVG imports and storing them in a cache, we're ensuring that subsequent renders won't unnecessarily reload these assets. This is particularly beneficial when dealing with a large number of icons, as it can significantly reduce load times and improve overall application performance.

Remember, students, in the world of web development, every millisecond counts!

app/client/src/pages/Editor/IDE/EditorPane/UI/UIRender.test.tsx (3)

Line range hint 98-105: Well done, class! Let's discuss this change.

Children, notice how we've renamed our variable from getByTestId to component. This is a splendid improvement! It's like giving our test a better name tag. Now, we can easily use all the wonderful methods our rendered component provides, not just getByTestId. Remember, clear naming is the key to understanding our code better!


109-111: Excellent addition to our test, students!

Now, pay attention to this new line. We're asking our test to wait patiently for the canvas to load before moving on. It's like waiting for everyone to sit down before starting the lesson. This ensures our test doesn't get ahead of itself and try to check things before they're ready. Remember, in the world of asynchronous operations, patience is a virtue!


113-113: Wonderful consistency, class!

Here, we see how our earlier change bears fruit. We're now using component.getByTestId instead of just getByTestId. This is like using our full name instead of just our first name - it's more precise and leaves no room for confusion. It shows great attention to detail and ensures our test remains consistent throughout. Well done!

app/client/src/widgets/ContainerWidget/widget/index.test.tsx (3)

16-16: Good job updating the import statement, class!

I see you've added waitFor to the import statement. This is a crucial step in preparing for asynchronous testing. Remember, in the world of web development, patience is a virtue, and waitFor is our way of teaching our tests to be patient!


113-115: Excellent use of waitFor, students!

You've demonstrated a good understanding of asynchronous testing principles here. By wrapping our expectation in waitFor, we're giving our test the patience it needs to wait for the spyUseCanvasDragging to be called.

Remember, class, in the asynchronous world of React, things don't always happen immediately. It's like waiting for a chemical reaction in our science experiments - sometimes we need to give it a moment!

This change will make our tests more reliable and less prone to false negatives. Keep up the good work!


Line range hint 1-115: Class, let's recap our lesson on asynchronous testing!

Today, we've learned an important lesson about patience in testing. By introducing waitFor, we've made our ContainerWidget test more robust and reliable.

Remember these key points:

  1. Always import the tools you need - just like we added waitFor to our import statement.
  2. Use waitFor when dealing with asynchronous operations - it's like giving your test a little extra time to complete its homework!

Overall, these changes show excellent progress in your understanding of advanced testing techniques. Keep up the great work, and don't forget to apply these principles in your future tests!

app/client/src/api/PageApi.tsx (2)

50-51: ⚠️ Potential issue

Let's review this change in our page list interface, class.

We've made an important adjustment to our FetchPageListResponseData interface. It's like changing the rules for our class attendance sheet:

  1. isDefault: boolean; - This property is now required, not optional. It's like making it mandatory to mark if a student is the class representative.
  2. isHidden?: boolean; - This property remains optional, like noting if a student is participating in a secret surprise party planning.

This change has some important implications:

  • By making isDefault required, we ensure every page in the list has a clear default status. It's like ensuring every student has a defined role in the class.
  • However, this could potentially cause issues with existing code that doesn't provide this property. It's similar to suddenly requiring all students to wear a badge indicating their role - those without badges would be in trouble!

To address this, I suggest the following:

  1. Review all places where FetchPageListResponseData is used and ensure isDefault is always provided.
  2. Update the API to always return isDefault for each page.
  3. Consider adding a migration step or a default value to handle cases where isDefault might not be set.

Class, remember: changing requirements can have ripple effects! Let's make sure we've done our homework on this one.

Let's run a quick test to see where we might need to update our code:

✅ Verification successful

Alright class, let's fix our shell script to properly check for potential issues with the isDefault property.


Verification Successful: isDefault Property Usage Confirmed

Great job! I've reviewed the usage of the isDefault property in the FetchPageListResponseData interface, and no instances were found where isDefault is not provided. This means the change from optional to required is safe and should not break existing code.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential issues with the isDefault property

# Test: Look for usages of FetchPageListResponseData that might not provide isDefault
echo "Checking for potential issues with isDefault in FetchPageListResponseData"
rg --type typescript 'FetchPageListResponseData' -C 5

Length of output: 339


Script:

#!/bin/bash
# Description: Check for potential issues with the isDefault property

# Test: Look for usages of FetchPageListResponseData that might not provide isDefault
echo "Checking for potential issues with isDefault in FetchPageListResponseData"
rg --glob '*.ts' --glob '*.tsx' 'FetchPageListResponseData' -C 5

Length of output: 1462


50-51: Class, let's examine these new properties carefully.

I see we've added two new optional properties to our FetchPageResponseData interface. This is like adding new fields to our report card template. Let's break it down:

  1. isDefault?: boolean; - This tells us if a page is the default one, like the first page in your notebook.
  2. isHidden?: boolean; - This indicates if a page is hidden, similar to a secret page in your diary.

These additions are good for flexibility, but remember:

  • We need to make sure our API documentation reflects these changes. It's like updating the school handbook when we change the rules.
  • Any code using this interface might need to be reviewed. It's similar to informing all teachers when we change the grading system.

Class, can anyone tell me why these properties are optional? That's right, it allows for backwards compatibility!

Let's do a quick pop quiz to check if we've used these new properties correctly:

✅ Verification successful

Great effort on initiating the verification! Let's refine our approach to ensure we accurately detect the usage of the new properties:


Excellent perseverance! Let's fine-tune our search to accurately locate the usage of isDefault and isHidden:


Let's adjust our strategy to effectively locate where isDefault and isHidden are used:


Fantastic work! The isDefault and isHidden properties are consistently utilized across the codebase.

The recent verification shows that these properties are integrated seamlessly in various components and utilities, ensuring both backward compatibility and enhanced flexibility. No issues were found regarding their implementation or usage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the new properties are used consistently

# Test 1: Check for usage of isDefault
echo "Test 1: Checking for usage of isDefault"
rg --type typescript 'isDefault'

# Test 2: Check for usage of isHidden
echo "Test 2: Checking for usage of isHidden"
rg --type typescript 'isHidden'

Length of output: 339


Script:

#!/bin/bash
# Description: Check if the new properties are used consistently

# Test 1: Check for usage of isDefault
echo "Test 1: Checking for usage of isDefault"
rg 'isDefault' --type ts --type tsx

# Test 2: Check for usage of isHidden
echo "Test 2: Checking for usage of isHidden"
rg 'isHidden' --type ts --type tsx

Length of output: 302


Script:

#!/bin/bash
# Description: Check if the new properties are used consistently

# Test 1: Check for usage of isDefault
echo "Test 1: Checking for usage of isDefault"
rg 'isDefault' --type typescript

# Test 2: Check for usage of isHidden
echo "Test 2: Checking for usage of isHidden"
rg 'isHidden' --type typescript

Length of output: 310


Script:

#!/bin/bash
# Description: Check if the new properties are used consistently

# Test 1: Check for usage of isDefault
echo "Test 1: Checking for usage of isDefault"
rg 'isDefault' --glob '*.ts' --glob '*.tsx'

# Test 2: Check for usage of isHidden
echo "Test 2: Checking for usage of isHidden"
rg 'isHidden' --glob '*.ts' --glob '*.tsx'

Length of output: 58392

app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx (1)

Line range hint 75-97: Good job on implementing asynchronous testing!

Class, let's take a moment to appreciate the improvements made to this test case. By using await component.findByText instead of component.queryByText, we're ensuring that our test patiently waits for the "Widgets" element to appear in the DOM. This is like giving our test a pair of glasses to see better!

The addition of a 3000 millisecond timeout is also a smart move. It's like setting a timer for our test to wait, but not wait forever. This helps prevent our tests from becoming "flaky" or unreliable.

Keep up the good work! These changes will make our tests more robust and less likely to fail due to timing issues.

app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.test.tsx (7)

58-60: Well done on improving the UpdatedEditor component!

Class, let's take a moment to appreciate the improvements made to the UpdatedEditor component. The use of the hasLoaded variable to conditionally render the IDE component is a smart move. It's like waiting for all the students to arrive before starting the lesson. This change ensures that we don't try to render our application before all the necessary data is ready. Keep up the good work!


143-143: Excellent use of asynchronous testing methods!

Class, pay attention to this improvement in our test case. By using await with findAllByTestId, we're showing patience in our testing, just like a good teacher waits for all students to understand before moving on. This change ensures that our test waits for all widgets to be rendered before proceeding, making our tests more reliable and less prone to timing-related failures. Remember, in testing as in teaching, timing is everything!


294-294: Good job on improving test reliability!

Class, let's appreciate this small but significant change. By using await with findByTestId for the artboard element, we're ensuring that our test waits for the canvas to be fully loaded before interacting with it. This is like making sure all students have their materials ready before starting an exercise. It's a great way to prevent flaky tests and make our test suite more robust. Keep up this attention to detail!


392-392: Excellent consistency in test improvements!

Class, I'm pleased to see that you've applied the same improvement to this test case as well. Just like we use consistent teaching methods across different lessons, you've used await with findByTestId for the artboard element here too. This consistency in your approach to asynchronous testing is commendable. It shows that you understand the importance of waiting for elements to be rendered before interacting with them. Well done on maintaining this good practice throughout your test suite!


Line range hint 437-470: Excellent improvements in asynchronous testing!

Class, let's take a moment to appreciate the thoughtful changes made to this test case. Just as we ensure all students are ready before starting a new topic, this test now waits for the canvas to be loaded before proceeding. The use of await with findByTestId shows patience in waiting for elements to render.

Furthermore, the addition of waitFor for our assertions is like giving students a moment to think before answering a question. It allows for any asynchronous state updates to complete, making our test more robust and reliable.

These changes demonstrate a deep understanding of asynchronous JavaScript and testing best practices. Keep up this excellent work!


Line range hint 472-489: Consistent application of asynchronous testing techniques!

Class, I'm delighted to see that you've applied the same principles of asynchronous testing to this test case as well. Just as we review previous lessons before moving on to new material, you've consistently used await with findByTestId to ensure the canvas is loaded before proceeding with the test.

This consistency in your approach shows that you've truly grasped the importance of waiting for elements to be rendered before interacting with them. It's like making sure all students have turned to the correct page before starting a new exercise. Well done on maintaining this good practice throughout your test suite!


Line range hint 506-523: Bravo on maintaining consistency across all test cases!

Class, I'm thoroughly impressed with the consistency you've shown in improving these test cases. Just as we apply the same principles across different subjects, you've consistently used await with findByTestId to ensure the canvas is loaded before proceeding with each test.

This uniformity in your approach to asynchronous testing is exemplary. It's like having a well-organized lesson plan that follows the same structure for each topic. Your tests now patiently wait for elements to render before interacting with them, just as a good teacher ensures all students are ready before moving forward.

This consistent improvement across all test cases demonstrates a deep understanding of the principles we've been learning. Keep up this excellent work!

app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.test.tsx (2)

Line range hint 56-103: Well done on improving the test reliability, class!

I'm pleased to see you've made this test asynchronous. By using await component.findByTestId instead of component.queryByTestId, you're ensuring that the test waits for the element to be available before proceeding. This is much better than the previous approach!

The addition of a 3000ms timeout is also a smart move. It gives the element enough time to appear without letting the test hang indefinitely if something goes wrong. Remember, in testing, patience is a virtue, but we don't want to wait forever!

Keep up the good work, and don't forget to apply these improvements to other similar tests in your homework!


Line range hint 504-554: A round of applause for your consistent improvements, class!

I'm thoroughly impressed with how you've systematically applied the async improvements to all your test cases, including this one for drawing selection from outside the canvas. Your code is like a well-rehearsed orchestra, with every part playing in perfect harmony!

Let's recap the excellent changes you've made throughout this file:

  1. You've made all test cases asynchronous, allowing for better handling of component rendering times.
  2. You've replaced queryByTestId with await findByTestId, ensuring that your tests wait for elements to be available.
  3. You've added timeouts to prevent tests from hanging indefinitely.
  4. You've introduced error handling for cases where components might not be found.

These changes will significantly improve the reliability and robustness of your tests. It's like you've upgraded from a pencil to a pen - your tests are now much more dependable!

For your homework, I'd like you to:

  1. Extract the timeout value (3000) into a constant.
  2. Apply these improvements to any other test files in your project.
  3. Consider adding comments explaining the rationale behind the async changes for future students (I mean, developers) who might work on this code.

Great job, class! You should all be very proud of your work today.

app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts (2)

941-942: Excellent restructuring of the test cases, class!

I'm pleased to see you've improved the test structure by using individual test cases instead of a loop. This change enhances readability and allows for more precise identification of failing migrations. Keep up the good work!


994-1015: Well done on enhancing our test coverage, class!

I'm impressed with the new assertions you've added. Let's review what they accomplish:

  1. We're now verifying that each migration function is called with the correct DSL version. This ensures our migrations are executed in the proper order and context.
  2. The additional check comparing the migration count to LATEST_DSL_VERSION is a clever way to ensure our test cases stay in sync with the actual implementation.

These improvements significantly boost the reliability of our migration process. Keep up this attention to detail in your future work!

Also applies to: 1017-1019

app/client/src/pages/Editor/IDE/AppsmithIDE.test.tsx (2)

Line range hint 157-278: Well done on updating the test case to be asynchronous!

Class, let's take a moment to appreciate the improvements made to this test case. By making it asynchronous and using await when finding elements, we've ensured that our test will patiently wait for the widgets to appear before interacting with them. This is like waiting for all students to arrive before starting the lesson – it's just good manners!

Remember, in the world of testing, patience is a virtue. These changes will make our tests more reliable and less prone to false failures. Keep up the good work!


Line range hint 737-1169: Excellent work on consistently updating the test suite!

Class, let's take a moment to appreciate the big picture here. All of our test cases have been updated to be asynchronous, and they're consistently using await when finding elements. This is like everyone in the class adopting the same note-taking system – it makes everything more organized and easier to follow!

These changes will make our test suite more reliable by ensuring that elements are properly loaded before we interact with them. This reduces the chance of flaky tests, which are like those students who sometimes show up late to class – unpredictable and disruptive!

Remember, consistency in our code is key. It makes our tests easier to read, understand, and maintain. Great job on improving the quality of our test suite!

app/client/packages/dsl/src/migrate/tests/DSLMigrationsUtils.test.ts (2)

1232-1235: Well done on structuring this test case, class!

I'm pleased to see you've used async/await syntax correctly here. It's important to handle asynchronous operations properly in our tests. Your approach of defining both the input and expected output is exemplary. Keep up the good work!


Line range hint 1237-2455: Excellent work on maintaining consistency in your test structure!

I'm impressed by your attention to detail in this test case. The use of currentVersion and nextVersion variables is a smart move - it makes the purpose of the test crystal clear. Remember, class, clear and consistent test structures make our code more maintainable!

app/client/test/testCommon.ts (2)

20-20: Excellent use of the 'unknown' type for 'dsl' parameter

You've appropriately updated the type of dsl from any to unknown. This change enhances type safety by ensuring that the variable is type-checked before use, preventing unintended errors. Great job embracing TypeScript best practices!


111-122: Great implementation of conditional rendering with 'hasLoaded'

Introducing the hasLoaded state and using it to conditionally render children enhances the reliability of your component. This ensures that the child components are rendered only after the necessary data is loaded, preventing potential runtime errors. Well done on this thoughtful addition!

app/client/src/utils/WidgetPropsUtils.tsx (2)

65-68: Excellent use of await with migrateDSL

Students, it's great to see that you've correctly used await with the migrateDSL function. This ensures that the DSL migration process completes before proceeding, which is essential for data integrity and application stability. Keep up the good work in applying asynchronous programming principles!


47-53: Ensure all callers handle the asynchronous extractCurrentDSL

Class, now that extractCurrentDSL has been converted to an asynchronous function returning a Promise, it's important to verify that all parts of your application that call this function are updated accordingly. Ensure that you're using await when calling this function or properly handling the returned Promise. Neglecting this might lead to unhandled Promise rejections or unexpected behavior.

To assist you, please run the following script to find all usages of extractCurrentDSL:

✅ Verification successful

All callers of extractCurrentDSL properly handle the asynchronous function

  • Verified that all instances in app/client/src/ce/sagas/PageSagas.tsx and app/client/test/testCommon.ts use await or yield when calling extractCurrentDSL, ensuring correct Promise handling.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all calls to `extractCurrentDSL` to ensure they handle the Promise correctly.

# Search for calls to extractCurrentDSL
rg --type typescript 'extractCurrentDSL\(' -A 2

Length of output: 84


Script:

#!/bin/bash
# Description: Find all calls to `extractCurrentDSL` to ensure they handle the Promise correctly.

# Search for calls to extractCurrentDSL in TypeScript files
rg --type ts 'extractCurrentDSL\(' -A 2
rg --type tsx 'extractCurrentDSL\(' -A 2

Length of output: 1348


Script:

#!/bin/bash
# Description: Find all calls to `extractCurrentDSL` to ensure they handle the Promise correctly.

# Search for calls to extractCurrentDSL in TypeScript (.ts) files
rg --type ts 'extractCurrentDSL\(' -A 2

# Search for calls to extractCurrentDSL in TSX (.tsx) files using glob
rg 'extractCurrentDSL\(' -A 2 --glob '*.tsx'

Length of output: 2378

app/client/packages/dsl/src/migrate/index.ts (1)

629-631: Good use of 'await' with 'migrateVersionedDSL'

You've correctly updated the return statements to await the asynchronous migrateVersionedDSL function. This ensures that the migration process completes before returning the result, which is essential for maintaining application consistency.

app/client/src/ce/sagas/PageSagas.tsx (4)

196-204: Excellent work on updating getCanvasWidgetsPayload to async

You have correctly converted getCanvasWidgetsPayload into an asynchronous function using the async keyword. The use of await with extractCurrentDSL ensures that the Promise is resolved before proceeding, which is essential for maintaining the proper execution flow.


254-255: Proper handling of asynchronous calls with yield

In your generator functions, you've appropriately used yield when calling the now asynchronous getCanvasWidgetsPayload. This ensures that the asynchronous operation is completed before the execution continues, preserving the saga's flow.

Also applies to: 332-333


692-693: Consistent use of yield with extractCurrentDSL

By using yield with extractCurrentDSL, you've correctly handled its asynchronous nature within the sagas. This consistency is crucial for preventing unexpected behavior due to unresolved Promises.

Also applies to: 760-765, 1178-1181


888-889: Verify the omission of dslTransformer in extractCurrentDSL

In this instance, extractCurrentDSL is called without the dslTransformer parameter:

const { dsl, layoutId } = yield extractCurrentDSL({
  response,
});

Please ensure that this omission is intentional. If dslTransformer is required for transforming the DSL according to the layout system, you should include it to maintain consistency across the application.

Comment on lines +34 to +36
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const children: any = buildChildren(childData);

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Let's improve our type safety, shall we?

I see you've used the 'any' type here, which is like using a wildcard in a game - it might seem convenient, but it can lead to unexpected results! Instead, let's try to be more specific. The buildChildren function should return an array of WidgetProps, so we can type our children variable accordingly:

const children: WidgetProps[] = buildChildren(childData) || [];

This way, we maintain type safety and avoid the need for the eslint-disable comment. Remember, in TypeScript, being specific with our types is like showing your work in math class - it helps prevent errors and makes our code easier to understand!

Comment on lines +184 to +189
export function MockApplication({ children }: { children: JSX.Element }) {
editorInitializer();
const dispatch = useDispatch();

dispatch(initEditorAction({ basePageId: pageId, mode: APP_MODE.EDIT }));
const mockResp: any = {

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

Move dispatch calls into useEffect to prevent multiple executions

Dispatching actions directly within the component body executes them on every render, which can lead to performance issues and unintended side effects. It's advisable to wrap these dispatch calls inside a useEffect hook so they run only once upon component mount.

Apply this diff to refactor the dispatch calls:

 export function MockApplication({ children }: { children: JSX.Element }) {
   editorInitializer();
   const dispatch = useDispatch();

+  useEffect(() => {
     dispatch(initEditorAction({ basePageId: pageId, mode: APP_MODE.EDIT }));

     const mockResp = {
       workspaceId: "workspace_id",
       pages: [
         // ...rest of the code
       ],
     };

     urlBuilder.updateURLParams(
       // ...parameters
     );
     dispatch({
       type: ReduxActionTypes.FETCH_APPLICATION_SUCCESS,
       payload: mockResp,
     });
     dispatch({
       type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS,
       payload: {
         pages: mockResp.pages,
       },
     });
     dispatch({
       type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID,
       payload: {
         id: pageId,
         slug: "page-1",
         permissions: [
           "read:pages",
           "manage:pages",
           "create:pageActions",
           "delete:pages",
         ],
       },
     });
+  }, [dispatch]);
 
   return children;
 }

By doing this, you ensure these actions are dispatched only once, improving performance and preventing unintended side effects.

📝 Committable suggestion

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

Suggested change
export function MockApplication({ children }: { children: JSX.Element }) {
editorInitializer();
const dispatch = useDispatch();
dispatch(initEditorAction({ basePageId: pageId, mode: APP_MODE.EDIT }));
const mockResp: any = {
export function MockApplication({ children }: { children: JSX.Element }) {
editorInitializer();
const dispatch = useDispatch();
useEffect(() => {
dispatch(initEditorAction({ basePageId: pageId, mode: APP_MODE.EDIT }));
const mockResp = {
workspaceId: "workspace_id",
pages: [
// ...rest of the code
],
};
urlBuilder.updateURLParams(
// ...parameters
);
dispatch({
type: ReduxActionTypes.FETCH_APPLICATION_SUCCESS,
payload: mockResp,
});
dispatch({
type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS,
payload: {
pages: mockResp.pages,
},
});
dispatch({
type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID,
payload: {
id: pageId,
slug: "page-1",
permissions: [
"read:pages",
"manage:pages",
"create:pageActions",
"delete:pages",
],
},
});
}, [dispatch]);
return children;
}

Comment on lines +50 to +106
useEffect(function loadScripts() {
const loadMigrationScripts = async () => {
const canvasWidgetsPayloadD = await getCanvasWidgetsPayload(mockResp);
const currentDSL = await extractCurrentDSL({
response: mockResp,
});

const currentDsl = currentDSL.dsl;
const canvasWidgetsPayload = canvasWidgetsPayloadD.widgets;

dispatch(setAppMode(mode || APP_MODE.EDIT));

dispatch({
type: ReduxActionTypes.FETCH_PAGE_DSLS_SUCCESS,
payload: [
{
pageId: mockResp.data.id,
dsl: currentDsl,
},
],
});
const pages = [
{
pageName: mockResp.data.name,
pageId: mockResp.data.id,
basePageId: mockResp.data.id,
isDefault: mockResp.data.isDefault,
isHidden: !!mockResp.data.isHidden,
slug: mockResp.data.slug,
userPermissions: [
"read:pages",
"manage:pages",
"create:pageActions",
"delete:pages",
],
},
] as unknown as Page[];

dispatch({
type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS,
payload: {
pages,
applicationId: mockResp.data.applicationId,
},
});
dispatch({
type: "UPDATE_LAYOUT",
payload: { widgets: canvasWidgetsPayload },
});

dispatch(updateCurrentPage(mockResp.data.id));
setHasLoaded(true);
};

loadMigrationScripts();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
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

Include dependencies in useEffect to ensure consistent behavior

It's important to specify all dependencies in your useEffect hook to prevent unexpected behavior. Disabling the ESLint rule react-hooks/exhaustive-deps might lead to maintenance challenges down the line.

Consider updating the dependency array to include all relevant variables:

Apply this diff to include dependencies:

-      // eslint-disable-next-line react-hooks/exhaustive-deps
       }, []);
+      }, [dispatch, mode, mockResp]);

By listing dispatch, mode, and mockResp as dependencies, you ensure that the effect runs consistently whenever these values change.

📝 Committable suggestion

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

Suggested change
useEffect(function loadScripts() {
const loadMigrationScripts = async () => {
const canvasWidgetsPayloadD = await getCanvasWidgetsPayload(mockResp);
const currentDSL = await extractCurrentDSL({
response: mockResp,
});
const currentDsl = currentDSL.dsl;
const canvasWidgetsPayload = canvasWidgetsPayloadD.widgets;
dispatch(setAppMode(mode || APP_MODE.EDIT));
dispatch({
type: ReduxActionTypes.FETCH_PAGE_DSLS_SUCCESS,
payload: [
{
pageId: mockResp.data.id,
dsl: currentDsl,
},
],
});
const pages = [
{
pageName: mockResp.data.name,
pageId: mockResp.data.id,
basePageId: mockResp.data.id,
isDefault: mockResp.data.isDefault,
isHidden: !!mockResp.data.isHidden,
slug: mockResp.data.slug,
userPermissions: [
"read:pages",
"manage:pages",
"create:pageActions",
"delete:pages",
],
},
] as unknown as Page[];
dispatch({
type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS,
payload: {
pages,
applicationId: mockResp.data.applicationId,
},
});
dispatch({
type: "UPDATE_LAYOUT",
payload: { widgets: canvasWidgetsPayload },
});
dispatch(updateCurrentPage(mockResp.data.id));
setHasLoaded(true);
};
loadMigrationScripts();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(function loadScripts() {
const loadMigrationScripts = async () => {
const canvasWidgetsPayloadD = await getCanvasWidgetsPayload(mockResp);
const currentDSL = await extractCurrentDSL({
response: mockResp,
});
const currentDsl = currentDSL.dsl;
const canvasWidgetsPayload = canvasWidgetsPayloadD.widgets;
dispatch(setAppMode(mode || APP_MODE.EDIT));
dispatch({
type: ReduxActionTypes.FETCH_PAGE_DSLS_SUCCESS,
payload: [
{
pageId: mockResp.data.id,
dsl: currentDsl,
},
],
});
const pages = [
{
pageName: mockResp.data.name,
pageId: mockResp.data.id,
basePageId: mockResp.data.id,
isDefault: mockResp.data.isDefault,
isHidden: !!mockResp.data.isHidden,
slug: mockResp.data.slug,
userPermissions: [
"read:pages",
"manage:pages",
"create:pageActions",
"delete:pages",
],
},
] as unknown as Page[];
dispatch({
type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS,
payload: {
pages,
applicationId: mockResp.data.applicationId,
},
});
dispatch({
type: "UPDATE_LAYOUT",
payload: { widgets: canvasWidgetsPayload },
});
dispatch(updateCurrentPage(mockResp.data.id));
setHasLoaded(true);
};
loadMigrationScripts();
}, [dispatch, mode, mockResp]);

@@ -146,7 +146,7 @@ const migrateUnversionedDSL = (currentDSL: DSLWidget) => {
// A rudimentary transform function which updates the DSL based on its version.
// A more modular approach needs to be designed.
// This needs the widget config to be already built to migrate correctly
const migrateVersionedDSL = (currentDSL: DSLWidget, newPage = false) => {
const migrateVersionedDSL = async (currentDSL: DSLWidget, newPage = false) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure proper error handling in 'migrateVersionedDSL'

When converting migrateVersionedDSL into an asynchronous function, it's important to handle any potential errors that may occur during asynchronous operations. Remember, unhandled promise rejections can lead to unexpected behaviors in your application. Consider adding error handling, such as try/catch blocks, to make the function more robust.

@@ -205,7 +205,7 @@
}

if (currentDSL.version === 12) {
currentDSL = migrateIncorrectDynamicBindingPathLists(currentDSL);
currentDSL = await migrateIncorrectDynamicBindingPathLists(currentDSL);
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

Properly handle errors when awaiting 'migrateIncorrectDynamicBindingPathLists'

Awaiting the asynchronous function migrateIncorrectDynamicBindingPathLists means that any errors it may throw will propagate up the call stack. To ensure reliability, please implement appropriate error handling within migrateVersionedDSL, potentially using a try/catch block around this await call.

Comment on lines +622 to +625
export const migrateDSL = async (
currentDSL: DSLWidget,
newPage = false,
): DSLWidget => {
): Promise<DSLWidget> => {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure error handling in the asynchronous function 'migrateDSL'

Now that migrateDSL is an asynchronous function, it's crucial to handle any errors that might occur during its execution. Incorporating error-handling mechanisms will enhance the robustness of your migration process.

Comment on lines +516 to +519
/*
Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading
this large file it can be reduce the main chunk only be loaded for certain limited conditions.
*/
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

Improve the clarity of the comment block

The multi-line comment contains grammatical errors that could affect comprehension. Let's revise it for better readability:

/*
- Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading 
- this large file it can be reduce the main chunk only be loaded for certain limited conditions.
+ Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading 
+ this large file, we can reduce the main chunk size, ensuring it is only loaded under certain limited conditions.
*/
📝 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
/*
Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading
this large file it can be reduce the main chunk only be loaded for certain limited conditions.
*/
/*
Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading
this large file, we can reduce the main chunk size, ensuring it is only loaded under certain limited conditions.
*/

migrateIncorrectDynamicBindingPathLists,
migratedDsl.children = await Promise.all(
currentDSL.children.map(
async (value) => await migrateIncorrectDynamicBindingPathLists(value),
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

Simplify the async function inside map

In the Promise.all statement, using await inside the async function is unnecessary. Remember, an async function automatically returns a Promise. Let's make the code more concise:

-            async (value) => await migrateIncorrectDynamicBindingPathLists(value),
+            async (value) => migrateIncorrectDynamicBindingPathLists(value),

This change simplifies the code without altering its functionality.

📝 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
async (value) => await migrateIncorrectDynamicBindingPathLists(value),
async (value) => migrateIncorrectDynamicBindingPathLists(value),

@vsvamsi1 vsvamsi1 added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Oct 17, 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: 4

🧹 Outside diff range and nitpick comments (1)
app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (1)

Line range hint 539-543: Add null check for widgetConfigs to prevent runtime errors

Remember, it's important to handle cases where a promise might resolve to null or undefined. If widgetConfigs is null, accessing its properties will cause a runtime error. Let's add a null check to ensure our code is robust.

Here's how you might modify the code:

const widgetConfigs = await loadWidgetConfig();

+ if (!widgetConfigs) {
+   throw new Error("Failed to load widget configurations");
+ }

const propertyPaneContentConfig = (widgetConfigs as any)[type]
  .propertyPaneContentConfig;
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 32806b9 and 7307a7d.

📒 Files selected for processing (2)
  • app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (6 hunks)
  • app/client/src/components/designSystems/blueprintjs/icon/Icon.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/components/designSystems/blueprintjs/icon/Icon.tsx
🧰 Additional context used
🔇 Additional comments (1)
app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (1)

516-519: Improve the clarity and grammar of the comment block

As we've discussed, clear comments are vital for code maintainability. The comment contains grammatical errors that could hinder understanding. Revising it will enhance readability.

Comment on lines +570 to 574
const widgetConfigs = await loadWidgetConfig();

const propertyPaneStyleConfig = (widgetConfigs as any)[type]
.propertyPaneStyleConfig;

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

Add null check for widgetConfigs in getWidgetPropertyPaneStyleConfig

Just as before, we should verify that widgetConfigs is not null to prevent potential runtime errors. Consistent error handling improves code reliability.

Consider adding a null check:

const widgetConfigs = await loadWidgetConfig();

+ if (!widgetConfigs) {
+   throw new Error("Failed to load widget configurations");
+ }

const propertyPaneStyleConfig = (widgetConfigs as any)[type]
  .propertyPaneStyleConfig;
📝 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 widgetConfigs = await loadWidgetConfig();
const propertyPaneStyleConfig = (widgetConfigs as any)[type]
.propertyPaneStyleConfig;
const widgetConfigs = await loadWidgetConfig();
if (!widgetConfigs) {
throw new Error("Failed to load widget configurations");
}
const propertyPaneStyleConfig = (widgetConfigs as any)[type]
.propertyPaneStyleConfig;

Comment on lines +1022 to +1023
currentDSL.children.map(async (value) =>
migrateIncorrectDynamicBindingPathLists(value),
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

Simplify the map function inside Promise.all

Recall that if an arrow function doesn't use await, we don't need the async keyword. Removing it simplifies the code without changing its functionality.

Here's the simplified code:

-      currentDSL.children.map(async (value) =>
+      currentDSL.children.map((value) =>
        migrateIncorrectDynamicBindingPathLists(value),
📝 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
currentDSL.children.map(async (value) =>
migrateIncorrectDynamicBindingPathLists(value),
currentDSL.children.map((value) =>
migrateIncorrectDynamicBindingPathLists(value),

Comment on lines +610 to 614
const widgetConfigs = await loadWidgetConfig();

const propertyPaneConfig = (widgetConfigs as any)[type].propertyPaneConfig;

const features = (widgetConfigs as any)[type].features;
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

Add null check for widgetConfigs in getWidgetPropertyPaneConfig

Again, let's ensure that widgetConfigs is not null before accessing its properties. This practice helps prevent unexpected crashes.

Here's the suggested modification:

const widgetConfigs = await loadWidgetConfig();

+ if (!widgetConfigs) {
+   throw new Error("Failed to load widget configurations");
+ }

const propertyPaneConfig = (widgetConfigs as any)[type].propertyPaneConfig;

Committable suggestion was skipped due to low confidence.

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 (4)
app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (4)

516-519: Now, pay attention to this comment block, students.

While the comment explains the purpose of lazy loading, there's a small grammatical error that we should address. Remember, clear communication is key in coding!

Let's correct the comment to improve its clarity:

/*
- Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading 
- this large file it can be reduce the main chunk only be loaded for certain limited conditions.
+ Lazily load this file since it is very large and used in migrations for certain DSL versions. By lazily loading 
+ this large file, we can reduce the main chunk size, ensuring it is only loaded under certain limited conditions.
*/

520-534: Let's examine this new function, class.

The loadWidgetConfig function is a well-implemented lazy loading mechanism. It checks the cache before loading, which is efficient. However, we should consider adding a more specific error message.

Consider updating the error message to be more specific:

-      log.error("Error loading WidgetConfig", e);
+      log.error("Error loading widget-configs.json", e);

Line range hint 607-635: Now, class, pay close attention to this function.

The getWidgetPropertyPaneConfig function has been updated to be async and use the lazy loading mechanism. However, there's a potential issue here. We should add a null check for widgetConfigs to prevent potential runtime errors.

Consider adding a null check:

const widgetConfigs = await loadWidgetConfig();

+ if (!widgetConfigs) {
+   throw new Error("Failed to load widget configurations");
+ }

const propertyPaneConfig = (widgetConfigs as any)[type].propertyPaneConfig;

994-996: Finally, let's look at how we've updated our migration function.

The migrateIncorrectDynamicBindingPathLists function has been converted to async and now uses the async getWidgetPropertyPaneConfig. The Promise.all usage for handling children is correct, but we can simplify the arrow function inside map.

Let's simplify the map function:

-      currentDSL.children.map(async (value) =>
-        migrateIncorrectDynamicBindingPathLists(value),
+      currentDSL.children.map((value) =>
+        migrateIncorrectDynamicBindingPathLists(value),

Remember, if an arrow function doesn't use await, we don't need the async keyword.

Also applies to: 1001-1024

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7307a7d and ae14b3f.

📒 Files selected for processing (1)
  • app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (6 hunks)
🧰 Additional context used
🔇 Additional comments (4)
app/client/packages/dsl/src/migrate/migrations/012-migrate-incorrect-dynamic-binding-path-lists.ts (4)

513-514: Class, let's examine this new addition to our code.

The introduction of a cache for lazy-loaded widget configurations is a smart move. It's like having a well-organized desk where you can quickly find what you need without searching through all your drawers every time.


Line range hint 536-566: Now, let's look at how we've updated this function.

The getWidgetPropertyPaneContentConfig function has been nicely converted to an async function. It now uses the lazy loading mechanism we just examined. Good job on maintaining the existing flow of enhancements!


Line range hint 567-597: Here's another function that's been updated, class.

The getWidgetPropertyPaneStyleConfig function has also been converted to async and now uses our lazy loading mechanism. The implementation is consistent with the previous function, which is excellent for maintaining code readability.


598-605: Let's examine this small but important change.

The getWidgetPropertyPaneCombinedConfig function has been updated to handle the new async nature of its dependencies. This is a good example of how changes in one part of the code can ripple through to other functions.

@vsvamsi1 vsvamsi1 merged commit b122c81 into release Oct 17, 2024
86 checks passed
@vsvamsi1 vsvamsi1 deleted the release6 branch October 17, 2024 15:18
@coderabbitai coderabbitai bot mentioned this pull request Oct 30, 2024
2 tasks
github-actions bot pushed a commit to Zeral-Zhang/appsmith that referenced this pull request Nov 20, 2024
## Description
We decoupled the widget-config.json file (177KB when zipped) from the
main bundle and implemented lazy loading during DSL migrations. This
optimisation reduces the size of the main chunk by 10%, which should
lead to better performance, specifically improving FCP and LCP, as the
main chunk's fetch and evaluation times are reduced

Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/11384816747>
> Commit: ae14b3f
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11384816747&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Thu, 17 Oct 2024 15:04:34 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Enhanced migration logic for DSL widgets with asynchronous operations.
	- Improved performance with lazy loading of widget configurations.
	- Added optional properties to page response data structures.

- **Bug Fixes**
	- Resolved issues with dynamic binding path migrations.

- **Tests**
- Updated test cases to handle asynchronous operations for better
reliability and accuracy.

- **Chores**
- Improved type safety and error handling in widget factory utilities
and mock functions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@coderabbitai coderabbitai bot mentioned this pull request Jan 6, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants