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: Replace entities in entity explorer with new ADS templates #38750

Merged
merged 34 commits into from
Jan 24, 2025

Conversation

ankitakinger
Copy link
Contributor

@ankitakinger ankitakinger commented Jan 17, 2025

Description

Replace entities in entity explorer with new ADS templates

Fixes #38286 #39289

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/12945261277
Commit: bf508e2
Cypress dashboard.
Tags: @tag.All
Spec:


Fri, 24 Jan 2025 08:55:33 UTC

Communication

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

  • Yes
  • No

Summary by CodeRabbit

Summary by CodeRabbit

Release Notes

  • New Features

    • Added new context menu components for JavaScript and Query entities.
    • Introduced enhanced entity item rendering for JavaScript and Query collections.
    • Implemented more granular permission-based context menu actions.
    • Added new components: Rename, Copy, Move, Delete, ShowBindings, Prettify, and EntityContextMenu.
  • Improvements

    • Streamlined context menu functionality across editor interfaces.
    • Enhanced user permissions handling for entity actions.
    • Improved modularity of editor components.
    • Updated rendering logic for JavaScript and Query lists based on feature flags.
  • Bug Fixes

    • Refined component prop management.
    • Updated navigation and analytics event logging for entity interactions.
  • Refactoring

    • Simplified component structures.
    • Removed deprecated prop usage.
    • Consolidated import and export statements.

These changes primarily focus on improving the user experience and developer flexibility within the application's editor interfaces.

Copy link
Contributor

coderabbitai bot commented Jan 17, 2025

Walkthrough

This pull request introduces significant refactoring across multiple components in the Appsmith client application, focusing on enhancing the entity management and context menu functionality. The changes primarily involve removing parentEntityType props, introducing new context menu components, and implementing a more modular approach to rendering entity items and groups.

Changes

File Path Change Summary
app/client/src/pages/Editor/Explorer/Files/index.tsx Removed parentEntityType prop from entity components
app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx Introduced EntityGroupsList and updated rendering logic
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/* Added new context menu components with standardized props
app/client/src/pages/Editor/JSEditor/* Refactored context menu and entity item rendering
app/client/src/ce/pages/Editor/IDE/EditorPane/*/ListItem.tsx Simplified list item components and introduced new rendering strategies

Assessment against linked issues

Objective Addressed Explanation
Replace Group listing with EntityGroupsList
Retain test ids

Possibly related issues

Possibly related PRs

Suggested reviewers

  • hetunandu
  • ApekshaBhosale
  • sagar-qa007

Poem

Code flows like a river's might,
Refactoring brings components light,
Menus dance with newfound grace,
Entities find their perfect space,
In this digital ballet of design! 🌟🚀


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.

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

🧹 Nitpick comments (14)
app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ActionEntity/index.tsx (1)

5-10: LGTM! Consider adding JSDoc documentation.

Clean pass-through component with proper typing. Adding JSDoc would help document the component's purpose and props.

+/**
+ * ActionEntity serves as a wrapper for QueryEntity, providing type-safe prop forwarding
+ * @param props.parentEntityId - ID of the parent entity
+ * @param props.item - Entity item details
+ */
 export const ActionEntity = (props: {
app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx (1)

Line range hint 12-23: Consider making searchKeyword prop configurable.

The searchKeyword prop is hardcoded to an empty string. If search functionality is needed, this should be made configurable through props.

 export interface QueryListItemProps {
   item: EntityItem;
   isActive: boolean;
   parentEntityId: string;
+  searchKeyword?: string;
 }

 export const QueryListItem = (props: QueryListItemProps) => {
-  const { isActive, item, parentEntityId } = props;
+  const { isActive, item, parentEntityId, searchKeyword = "" } = props;
app/client/src/ce/IDE/hooks/useParentEntityInfo.ts (1)

14-19: Consider making parentEntityType dynamic.

The parentEntityType is hardcoded to PAGE. Consider deriving it from ideType parameter for more flexibility.

   return {
     editorId: appId || "",
     parentEntityId: basePageId || "",
-    parentEntityType: ActionParentEntityType.PAGE,
+    parentEntityType: getParentEntityTypeFromIDE(ideType),
   };
app/client/src/ce/entities/IDE/utils.ts (1)

81-88: Simplify redundant switch statement.

The switch statement can be simplified since both cases return the same items.

-export const getMenuItemsForActionEntityByIdeType = (ideType: IDEType) => {
-  switch (ideType) {
-    case IDE_TYPE.App:
-      return defaultActionMenuItems;
-    default:
-      return defaultActionMenuItems;
-  }
-};
+export const getMenuItemsForActionEntityByIdeType = (ideType: IDEType) => {
+  return defaultActionMenuItems;
+};
app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.ts (1)

60-78: Simplify redundant switch statement and consider future extensibility.

The switch statement can be simplified as it returns the same items for all cases. However, if this is a placeholder for future differentiation between parent types, consider adding a TODO comment.

 export const getMenuItemsForActionEntityByParentType = (
   parentEntityType: ActionParentEntityTypeInterface,
 ) => {
   const defaultMenuItems = [
     ActionEntityContextMenuItemsEnum.RENAME,
     ActionEntityContextMenuItemsEnum.DELETE,
     ActionEntityContextMenuItemsEnum.SHOW_BINDING,
     ActionEntityContextMenuItemsEnum.COPY,
     ActionEntityContextMenuItemsEnum.MOVE,
     ActionEntityContextMenuItemsEnum.CONVERT_QUERY_MODULE_INSTANCE,
   ];
-
-  switch (parentEntityType) {
-    case "PAGE":
-      return defaultMenuItems;
-    default:
-      return defaultMenuItems;
-  }
+  // TODO: Add specific menu items for different parent types if needed
+  return defaultMenuItems;
 };
app/client/src/ce/entities/IDE/constants.ts (2)

143-150: LGTM! Consider using const enum for better performance.

The enum values are well-defined and descriptive.

-export enum ActionEntityContextMenuItemsEnum {
+export const enum ActionEntityContextMenuItemsEnum {

152-159: LGTM! Consider adding type annotation for better maintainability.

The array correctly uses all enum values.

-export const defaultActionMenuItems = [
+export const defaultActionMenuItems: ActionEntityContextMenuItemsEnum[] = [
app/client/src/pages/Editor/Explorer/Actions/ActionEntity.tsx (1)

50-50: Consider memoizing ideType to prevent unnecessary recalculations.

The IDE type is derived from the location pathname on every render.

-  const ideType = getIDETypeByUrl(location.pathname);
+  const ideType = useMemo(() => getIDETypeByUrl(location.pathname), [location.pathname]);
app/client/src/ce/hooks/datasourceEditorHooks.tsx (1)

Line range hint 75-134: Consider extracting the nested logic into separate functions.

The useHeaderActions hook contains deeply nested logic that could be simplified for better maintainability.

Consider splitting into:

  • useGeneratePageButton
  • useNewActionButton
  • useHeaderPermissions
app/client/src/pages/Editor/IDE/EditorPane/Query/ActionEntity/QueryEntity.tsx (2)

54-54: Consider memoizing validateName hook dependencies.

The validateName hook is created with empty dependencies on every render.

-  const validateName = useValidateEntityName({});
+  const validateNameOptions = useMemo(() => ({}), []);
+  const validateName = useValidateEntityName(validateNameOptions);

79-94: Consider extracting analytics logic into a custom hook.

The switchToAction callback handles both navigation and analytics tracking. These concerns could be separated for better maintainability.

Consider creating a custom hook like useActionAnalytics to handle all analytics events.

app/client/src/pages/Editor/CustomWidgetBuilder/useCustomBuilder.tsx (1)

Line range hint 166-167: Consider addressing the TODO comment.

The event type could be properly typed instead of using any. This would improve type safety.

-  window.addEventListener("message", (event: any) => {
+  window.addEventListener("message", (event: MessageEvent<{
+    type: string;
+    name?: string;
+    widgetId?: string;
+    srcDoc?: string;
+    uncompiledSrcDoc?: string;
+    model?: unknown;
+    events?: unknown;
+    theme?: unknown;
+  }>) => {
app/client/src/pages/Editor/IDE/EditorPane/Query/ActionEntity/QueryEntityContextMenu.tsx (1)

115-198: Consider extracting menu options configuration.

The optionsTree array is quite large and contains complex logic. Consider extracting it into a separate configuration function for better maintainability.

app/client/src/pages/Editor/IntegrationEditor/APIOrSaasPlugins.tsx (1)

Line range hint 117-125: Consider extracting plugin type determination logic.

The inline ternary for determining plugin type could be extracted into a helper function for better readability.

+ const getPluginType = (source: string) =>
+   source === API_ACTION.CREATE_NEW_GRAPHQL_API
+     ? PluginPackageName.GRAPHQL
+     : PluginPackageName.REST_API;

  props.createNewApiActionBasedOnIdeType(
    ideType,
    editorId,
    parentEntityId || (isOnboardingScreen && pageId) || "",
    parentEntityType,
-   source === API_ACTION.CREATE_NEW_GRAPHQL_API
-     ? PluginPackageName.GRAPHQL
-     : PluginPackageName.REST_API,
+   getPluginType(source),
  );
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19002c3 and 40ba4f9.

📒 Files selected for processing (37)
  • app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceInfo.tsx (2 hunks)
  • app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceTab.tsx (3 hunks)
  • app/client/src/ce/IDE/hooks/useParentEntityInfo.ts (1 hunks)
  • app/client/src/ce/actions/helpers.ts (3 hunks)
  • app/client/src/ce/entities/IDE/constants.ts (1 hunks)
  • app/client/src/ce/entities/IDE/utils.ts (2 hunks)
  • app/client/src/ce/hooks/datasourceEditorHooks.tsx (3 hunks)
  • app/client/src/ce/hooks/hooks.test.ts (0 hunks)
  • app/client/src/ce/hooks/index.ts (0 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ActionEntity/index.tsx (1 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx (1 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.ts (2 hunks)
  • app/client/src/ce/pages/Editor/gitSync/useReconnectModalData.ts (2 hunks)
  • app/client/src/ce/utils/BusinessFeatures/permissionPageHelpers.tsx (2 hunks)
  • app/client/src/ce/utils/lintRulesHelpers.ts (1 hunks)
  • app/client/src/ee/IDE/hooks/useParentEntityInfo.ts (1 hunks)
  • app/client/src/ee/pages/Editor/IDE/EditorPane/Query/ActionEntity/index.tsx (1 hunks)
  • app/client/src/pages/Editor/CustomWidgetBuilder/useCustomBuilder.tsx (2 hunks)
  • app/client/src/pages/Editor/DataSourceEditor/DSFormHeader.tsx (3 hunks)
  • app/client/src/pages/Editor/DataSourceEditor/hooks.ts (3 hunks)
  • app/client/src/pages/Editor/DatasourceInfo/DatasourceStructure.tsx (2 hunks)
  • app/client/src/pages/Editor/DatasourceInfo/DatasourceViewModeSchema.tsx (3 hunks)
  • app/client/src/pages/Editor/DatasourceInfo/GoogleSheetSchema.tsx (3 hunks)
  • app/client/src/pages/Editor/Explorer/Actions/ActionEntity.tsx (3 hunks)
  • app/client/src/pages/Editor/Explorer/Files/index.tsx (0 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ActionEntity/QueryEntity.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ActionEntity/QueryEntityContextMenu.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (4 hunks)
  • app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx (2 hunks)
  • app/client/src/pages/Editor/IDE/hooks.ts (2 hunks)
  • app/client/src/pages/Editor/IntegrationEditor/APIOrSaasPlugins.tsx (6 hunks)
  • app/client/src/pages/Editor/IntegrationEditor/DBOrMostPopularPlugins.tsx (9 hunks)
  • app/client/src/pages/Editor/IntegrationEditor/DatasourceCard.tsx (3 hunks)
  • app/client/src/pages/Editor/gitSync/ReconnectDatasourceModal.tsx (2 hunks)
  • app/client/src/plugins/Linting/constants.ts (3 hunks)
  • app/client/src/plugins/Linting/tests/generateLintingGlobalData.test.ts (0 hunks)
  • app/client/src/plugins/Linting/utils/getLintingErrors.ts (5 hunks)
💤 Files with no reviewable changes (4)
  • app/client/src/ce/hooks/hooks.test.ts
  • app/client/src/pages/Editor/Explorer/Files/index.tsx
  • app/client/src/plugins/Linting/tests/generateLintingGlobalData.test.ts
  • app/client/src/ce/hooks/index.ts
✅ Files skipped from review due to trivial changes (3)
  • app/client/src/ee/pages/Editor/IDE/EditorPane/Query/ActionEntity/index.tsx
  • app/client/src/ee/IDE/hooks/useParentEntityInfo.ts
  • app/client/src/pages/Editor/gitSync/ReconnectDatasourceModal.tsx
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (27)
app/client/src/ce/pages/Editor/gitSync/useReconnectModalData.ts (2)

1-1: LGTM! Clean import of IDE_TYPE constant.

The import from the enterprise edition constants maintains good separation of concerns.


39-39: Verify the IDE_TYPE.App usage across the codebase.

The change from EditorNames to IDE_TYPE is consistent with the PR's objective. Let's verify other usages to ensure consistency.

✅ Verification successful

Migration to IDE_TYPE.App is complete and consistent

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining EditorNames.APPLICATION usage that should be migrated
rg "EditorNames.APPLICATION"

# Verify consistent usage of IDE_TYPE.App
rg "IDE_TYPE.App"

Length of output: 1755

app/client/src/pages/Editor/IntegrationEditor/DBOrMostPopularPlugins.tsx (4)

30-30: LGTM! Clean import restructuring.

The imports reflect a well-structured transition from editor-type to IDE-type based architecture.

Also applies to: 41-41, 53-54


189-198: LGTM! Consistent prop propagation.

The IDE type changes are consistently propagated through the component hierarchy.

Also applies to: 287-287


Line range hint 348-363: LGTM! Consistent Redux integration.

The dispatch mapping correctly implements the new action creator signature.


257-259: Verify hook usage and dependencies.

The transition to getIDETypeByUrl and useParentEntityInfo looks good. Let's verify the hook's usage pattern.

✅ Verification successful

✓ Hook usage verification completed successfully

The transition from useEditorType to useParentEntityInfo is complete and consistent across all components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining useEditorType usage
rg -g '*.{ts,tsx}' 'useEditorType'

# Verify consistent useParentEntityInfo usage
rg -g '*.{ts,tsx}' 'useParentEntityInfo.*ideType'

Length of output: 1116

app/client/src/ce/utils/lintRulesHelpers.ts (1)

Line range hint 3-17: Verify the empty implementation of getLintRulesBasedOnContext.

The function returns an empty object despite accepting a ContextType parameter. This might indicate incomplete implementation or missing logic after the type change.

✅ Verification successful

Empty implementation is correct as this is the CE (Community Edition) version

The empty implementation in the CE version is intentional, as the actual rules are defined in the Enterprise Edition (ee/utils/lintRulesHelpers). This follows the standard CE/EE split pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of getLintRulesBasedOnContext to understand expected behavior
rg -A 3 "getLintRulesBasedOnContext" 

Length of output: 1293

app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceInfo.tsx (1)

28-29: LGTM! The transition to IDE-type looks good.

The change from useEditorType to getIDETypeByUrl aligns with the PR's objective of standardizing IDE-type usage.

app/client/src/ce/actions/helpers.ts (1)

Line range hint 67-85: Address TODO comment and improve type safety.

The function has a TODO comment and returns any type. Consider addressing both issues.

 export const createNewApiActionBasedOnIdeType = (
   ideType: IDEType,
   editorId: string,
   parentEntityId: string,
   parentEntityType: ActionParentEntityTypeInterface,
   apiType: string,
-  // TODO: Fix this the next time the file is edited
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-): any => {
+): ReturnType<typeof createNewAPIBasedOnParentEntity> => {
   if (parentEntityId) {
     return createNewAPIBasedOnParentEntity(
       parentEntityId,
       "API_PANE",
       apiType,
       parentEntityType,
     );
   }
+  return undefined;
 };
app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (2)

55-57: LGTM! Feature flag implementation follows best practices.

The feature flag is appropriately used to control the rollout of the new EntityGroupsList component.


78-93: Well-structured component composition with proper type safety.

The EntityGroupsList implementation provides better type safety and cleaner separation of concerns.

app/client/src/pages/Editor/DataSourceEditor/hooks.ts (1)

Line range hint 144-154: Verify permission checks with new IDE type system.

The switch from editorType to ideType affects permission checks. Please ensure all permission scenarios are tested.

✅ Verification successful

Permission checks with IDE type system verified successfully

The permission system correctly handles different IDE types with appropriate permission checks for each context.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all permission check usages with the new IDE type
rg -A 3 "hasCreateDSActionPermissionInApp.*ideType"

Length of output: 53


Script:

#!/bin/bash
# Find the function definition
ast-grep --pattern 'export function hasCreateDSActionPermissionInApp($_) {
  $$$
}'

# Search for IDE type related code
rg -A 2 "getIDETypeByUrl|ideType.*=.*getIDEType"

# Broader search for the permission function
rg "hasCreateDSActionPermissionInApp"

Length of output: 18916


Script:

#!/bin/bash
# Get the implementation of hasCreateDSActionPermissionInApp
ast-grep --pattern 'export const hasCreateDSActionPermissionInApp = $_'

# Also check for any IDE type constants that might be used in the implementation
rg -A 5 "IDE_TYPE.*=.*{" 

Length of output: 78325

app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx (1)

62-63: LGTM! Consistent usage of IDE type system.

The dsUsageSelector update maintains consistency with the new IDE type pattern.

app/client/src/pages/Editor/CustomWidgetBuilder/useCustomBuilder.tsx (1)

32-33: LGTM! Clean hook implementation with IDE type.

The useParentEntityInfo hook is correctly updated to use the new IDE type system.

app/client/src/pages/Editor/DataSourceEditor/DSFormHeader.tsx (2)

30-30: LGTM! Clean transition from editor type to IDE type.

The refactoring from useEditorType to getIDETypeByUrl maintains the component's functionality while improving type safety.

Also applies to: 120-120


168-168: LGTM! Updated hook usage.

The useHeaderActions hook is correctly updated to use the new ideType parameter.

app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceTab.tsx (1)

26-26: LGTM! Consistent refactoring to IDE types.

The changes align with the codebase-wide transition from editor types to IDE types, improving type safety without affecting functionality.

Also applies to: 36-36, 61-62

app/client/src/plugins/Linting/constants.ts (2)

46-46: LGTM! Updated context parameter.

The getLintRulesBasedOnContext call correctly uses the new ideType parameter.


6-6: Verify the impact of the type change.

The parameter type change from string to IDEType improves type safety but may affect existing callers of lintOptions.

Also applies to: 16-16

✅ Verification successful

Type change verification completed - No issues found.

The change from string to IDEType is safe as the only caller in getLintingErrors.ts already uses the correct type through getIDETypeByUrl and IDE_TYPE.App.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all calls to lintOptions to verify they pass the correct type
rg -A 2 "lintOptions\(" 

Length of output: 277


Script:

#!/bin/bash
# Find lintOptions implementation
ast-grep --pattern 'const lintOptions = $_'

# Find IDEType definition
ast-grep --pattern 'type IDEType = $_'

# Check the file where lintOptions is used
cat app/client/src/plugins/Linting/utils/getLintingErrors.ts

Length of output: 82735


Script:

#!/bin/bash
# Find IDEType definition and usages
rg "IDEType" -A 3

# Find getLintRulesBasedOnContext implementation
rg "getLintRulesBasedOnContext" -A 3

Length of output: 33527

app/client/src/pages/Editor/IDE/hooks.ts (1)

30-30: LGTM! Consistent IDE type usage.

The changes in useSegmentNavigation maintain the same functionality while adopting the new IDE type system.

Also applies to: 34-34, 66-67

app/client/src/ce/utils/BusinessFeatures/permissionPageHelpers.tsx (1)

46-46: LGTM! Type safety improvement.

The transition from string-based editorType to strongly-typed IDEType enhances type safety and maintainability.

Also applies to: 96-96

app/client/src/pages/Editor/DatasourceInfo/DatasourceViewModeSchema.tsx (1)

Line range hint 85-96: LGTM! Clean transition to IDE-type.

The change from editorType to ideType is clean and maintains the existing functionality.

app/client/src/pages/Editor/IntegrationEditor/APIOrSaasPlugins.tsx (1)

Line range hint 65-71: LGTM! Well-typed function signature.

The createNewApiActionBasedOnIdeType function signature is well-defined with proper typing.

app/client/src/pages/Editor/IntegrationEditor/DatasourceCard.tsx (1)

63-63: LGTM! Clean transition from editor-type to IDE-type.

The changes correctly implement the new IDE-type based approach while maintaining the component's functionality.

Also applies to: 182-182, 193-193

app/client/src/pages/Editor/DatasourceInfo/GoogleSheetSchema.tsx (1)

Line range hint 24-24: LGTM! Consistent implementation of IDE-type transition.

The changes align with the codebase-wide refactoring from editor-type to IDE-type.

Also applies to: 69-69, 75-75

app/client/src/plugins/Linting/utils/getLintingErrors.ts (1)

48-49: LGTM! Proper integration of IDE-type in linting context.

The changes correctly integrate the IDE-type concept into the linting process while maintaining the existing error handling functionality.

Also applies to: 84-84, 143-143, 160-160, 376-376, 381-381

app/client/src/pages/Editor/DatasourceInfo/DatasourceStructure.tsx (1)

24-24: LGTM! Consistent implementation of IDE-type transition.

The changes follow the established pattern of transitioning from editor-type to IDE-type.

Also applies to: 69-69, 75-75

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

🧹 Nitpick comments (5)
app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (2)

39-46: Consider memoizing selector results.

Multiple useSelector calls could benefit from memoization to prevent unnecessary re-renders.

+const selectAction = useCallback(
+  (state: AppState) => getActionByBaseId(state, item.key),
+  [item.key]
+);
+const action = useSelector(selectAction) as Action;

+const selectDatasource = useCallback(
+  (state) => getDatasource(state, action?.datasource?.id),
+  [action?.datasource?.id]
+);
+const datasource = useSelector(selectDatasource) as Datasource;

79-94: Consider extracting analytics logic.

The switchToAction callback handles both navigation and analytics. Consider separating these concerns for better maintainability.

+const logAnalytics = useCallback((url: string) => {
+  AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", {
+    type: "QUERIES/APIs",
+    fromUrl: location.pathname,
+    toUrl: url,
+    name: action.name,
+  });
+  AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", {
+    actionId: action?.id,
+    datasourceId: datasource?.id,
+    pluginName: pluginGroups[action?.pluginId]?.name,
+    actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
+    isMock: !!datasource?.isMock,
+  });
+}, [location.pathname, action, datasource, pluginGroups]);

 const switchToAction = useCallback(() => {
   url && history.push(url, { invokedBy: NavigationMethod.EntityExplorer });
-  AnalyticsUtil.logEvent...
+  logAnalytics(url);
 }, [url, logAnalytics]);
app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (2)

78-129: Consider extracting the group rendering logic.

The conditional rendering creates duplicate group structure logic. Consider extracting this into a separate component.

+const GroupRenderer = ({ group, items, isNewTemplate, parentEntityId }) => {
+  if (isNewTemplate) {
+    return (
+      <ActionEntityItem
+        item={items}
+        parentEntityId={parentEntityId}
+      />
+    );
+  }
+  return (
+    <QueryListItem
+      isActive={items.key === activeActionBaseId}
+      item={items}
+      parentEntityId={parentEntityId}
+    />
+  );
+};

55-57: Document the feature flag's purpose.

Add a comment explaining what this feature flag controls and its implications.

+// Controls the rollout of new ADS templates for entity rendering
+// When enabled, uses EntityGroupsList for improved list organization
 const isNewADSTemplatesEnabled = useFeatureFlag(
   FEATURE_FLAG.release_ads_entity_item_enabled,
 );
app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityContextMenu.tsx (1)

132-153: Document IDE-specific copy behavior.

The copy functionality differs between App and other IDE types. Consider adding a comment explaining this distinction for better maintainability.

+    // In App IDE, copy shows a submenu of pages
+    // In other IDE types, it performs an immediate duplicate action
     menuItems.includes(ActionEntityContextMenuItemsEnum.COPY) &&
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40ba4f9 and d7b7400.

📒 Files selected for processing (8)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/index.tsx (1 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/old/ListItem.tsx (1 hunks)
  • app/client/src/ce/selectors/entitiesSelector.ts (2 hunks)
  • app/client/src/ee/pages/Editor/IDE/EditorPane/Query/ListItem/old/ListItem.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (3 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityContextMenu.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/client/src/ee/pages/Editor/IDE/EditorPane/Query/ListItem/old/ListItem.tsx
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (10)
app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx (2)

33-33: LGTM! Clean import addition.

The import of getIDETypeByUrl aligns with the PR's objective of transitioning from editor type to IDE type.


62-64: LGTM! Clean transition to IDE type.

The changes maintain proper React hooks usage order and successfully transition from editor type to IDE type.

Let's verify that all usages of useEditorType have been replaced:

✅ Verification successful

Verified: Clean transition to IDE type completed

The codebase shows no remaining instances of useEditorType and demonstrates consistent usage of getIDETypeByUrl across all relevant components. The implementation in DataSidePane.tsx follows the established pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining instances of useEditorType
rg "useEditorType" --type ts --type tsx

# Verify consistent usage of getIDETypeByUrl
rg "getIDETypeByUrl" --type ts --type tsx

Length of output: 137


Script:

#!/bin/bash
# Search for any remaining instances of useEditorType
echo "=== Searching for useEditorType ==="
rg "useEditorType" -g "*.{ts,tsx}"

# Search for imports of useEditorType
echo -e "\n=== Searching for useEditorType imports ==="
rg "import.*useEditorType" -g "*.{ts,tsx}"

# Verify consistent usage of getIDETypeByUrl
echo -e "\n=== Searching for getIDETypeByUrl ==="
rg "getIDETypeByUrl" -g "*.{ts,tsx}"

# Search for imports of getIDETypeByUrl
echo -e "\n=== Searching for getIDETypeByUrl imports ==="
rg "import.*getIDETypeByUrl" -g "*.{ts,tsx}"

Length of output: 10326

app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/index.tsx (1)

5-10: Clean implementation of the adapter pattern!

The ActionEntityItem component provides a good abstraction layer over QueryEntityItem, making future modifications easier to manage.

app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/old/ListItem.tsx (1)

12-12: Verify the impact of removing parentEntityType.

The removal of parentEntityType from props destructuring aligns with the IDE type refactoring. However, let's verify all usages are updated.

✅ Verification successful

Removal of parentEntityType is verified as safe.

The prop removal is part of an intentional refactoring where the old implementation has been replaced with new versions in both CE and EE that explicitly exclude this prop.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to parentEntityType in action-related components
rg -l 'parentEntityType.*ExplorerActionEntity' app/client/src/

Length of output: 64


Script:

#!/bin/bash
# Search for ListItem component usage
rg -l "ListItem" app/client/src/

# Search for parentEntityType in broader context
rg "parentEntityType" app/client/src/

# Find ExplorerActionEntity component definition
ast-grep --pattern 'interface ExplorerActionEntityProps {
  $$$
}'

Length of output: 9301


Script:

#!/bin/bash
# Check new ListItem implementations
cat app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/index.tsx
cat app/client/src/ee/pages/Editor/IDE/EditorPane/Query/ListItem/index.tsx

Length of output: 539

app/client/src/ce/selectors/entitiesSelector.ts (2)

67-67: LGTM!

The IDEType type import is correctly placed with other IDE-related type imports.


1705-1714: LGTM! Verify all call sites are updated.

The changes improve type safety by replacing the generic string type with the specific IDEType type.

Let's verify that all call sites have been updated to use the new type:

✅ Verification successful

Changes verified - parameter type change is properly implemented

The change from editorType: string to ideType: IDEType is correctly implemented and all usages have been updated. The type is properly defined in the constants file and imported where needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of the old parameter name
rg -l "getDatasourceUsageCountForApp.*editorType"

# Search for all current usages to verify they use the new parameter
rg -l "getDatasourceUsageCountForApp.*ideType"

Length of output: 100


Script:

#!/bin/bash
# Search for any usage of the selector
rg "getDatasourceUsageCountForApp" -A 2

# Search for any remaining editorType references in the same directory
fd ".*\.ts$" app/client/src/ce/selectors -x rg "editorType"

# Use AST to find selector usage
ast-grep --pattern 'getDatasourceUsageCountForApp($$$)'

Length of output: 67108


Script:

#!/bin/bash
# Search for IDEType definition
rg "type IDEType" -A 2

# Search for any remaining editorType in DataSidePane
rg "editorType" app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx -A 2

# Get context of the selector usage in DataSidePane
rg "dsUsageSelector" app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx -A 5

Length of output: 2374

app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityContextMenu.tsx (4)

1-50: Clean and well-structured imports and interface definition!

The imports are logically organized and the EntityContextMenuProps interface is well-defined with clear typing.


51-60: Well-implemented component setup with proper state management!

The component correctly uses the new IDE type utilities and maintains clean state management.


200-207: Clean and efficient rendering logic!

The conditional rendering and type handling are well-implemented.


84-89: Consider handling deletion failures.

The delete action callback doesn't handle potential failures. Consider adding error handling to prevent navigation on failed deletions.

@ankitakinger ankitakinger added the ok-to-test Required label for CI label Jan 17, 2025
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 comments (1)
app/client/src/pages/Editor/IntegrationEditor/APIOrSaasPlugins.tsx (1)

Line range hint 118-126: Add error handling for plugin creation.

The plugin creation process should handle potential failures and provide user feedback.

     props.createNewApiActionBasedOnIdeType(
       ideType,
       editorId,
       parentEntityId || (isOnboardingScreen && pageId) || "",
       parentEntityType,
       source === API_ACTION.CREATE_NEW_GRAPHQL_API
         ? PluginPackageName.GRAPHQL
         : PluginPackageName.REST_API,
-    );
+    ).catch((error) => {
+      // Handle error and show appropriate feedback
+      console.error("Failed to create API action:", error);
+      // Show error notification to user
+    });
🧹 Nitpick comments (9)
app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (2)

49-51: Consider moving blank state check after search functionality.

The current implementation shows the blank state before the search functionality, which might not be the optimal user experience. Consider moving the blank state check after the search component to allow users to search even when starting with no items.

-      {objectKeys(itemGroups).length === 0 && <BlankState />}

      {itemGroups.length > 0 ? (
        <SearchAndAdd
          onAdd={openAddQuery}
          onSearch={setSearchTerm}
          showAddButton={canCreateActions}
        />
      ) : null}
+      {objectKeys(itemGroups).length === 0 && searchTerm === "" && <BlankState />}

Also applies to: 62-71


72-123: Extract common group title rendering logic.

Both implementations render group titles similarly. Consider extracting this into a shared component to maintain consistency and reduce duplication.

const GroupTitle = ({ title }: { title: string }) => (
  <Text
    className="overflow-hidden overflow-ellipsis whitespace-nowrap"
    kind="body-s"
  >
    {title}
  </Text>
);

Then use it in both implementations:

 {isNewADSTemplatesEnabled ? (
   <EntityGroupsList
     groups={filteredItemGroups.map(({ group, items }) => ({
       groupTitle: group,
       items: items,
+      titleComponent: <GroupTitle title={group} />,
       className: "",
       renderList: (item: EntityItem) => (
         <ActionEntityItem
           item={item}
           parentEntityId={parentEntityId}
         />
       ),
     }))}
   />
 ) : (
   filteredItemGroups.map(({ group, items }) => (
     <Flex flexDirection={"column"} key={group}>
       <Flex py="spaces-1">
-        <Text
-          className="overflow-hidden overflow-ellipsis whitespace-nowrap"
-          kind="body-s"
-        >
-          {group}
-        </Text>
+        <GroupTitle title={group} />
       </Flex>
       // ... rest of the code
app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (4)

36-42: Consider memoizing selector results to prevent unnecessary re-renders.

The Redux selectors might trigger re-renders on unrelated state updates. Consider using createSelector from reselect for these selectors.

-  const action = useSelector((state: AppState) =>
-    getActionByBaseId(state, item.key),
-  ) as Action;
-  const datasource = useSelector((state) =>
-    getDatasource(state, (action?.datasource as StoredDatasource)?.id),
-  ) as Datasource;
+  const action = useSelector(
+    useMemo(
+      () => (state: AppState) => getActionByBaseId(state, item.key),
+      [item.key]
+    )
+  ) as Action;
+  const datasource = useSelector(
+    useMemo(
+      () => (state: AppState) =>
+        getDatasource(state, (action?.datasource as StoredDatasource)?.id),
+      [action?.datasource?.id]
+    )
+  ) as Datasource;

59-62: Add error handling for permission check.

The permission check should handle potential errors and provide appropriate feedback to users when permissions are denied.

   const canManageAction = getHasManageActionPermission(
     isFeatureEnabled,
     actionPermissions,
   );
+  const handlePermissionError = useCallback(() => {
+    // Show appropriate error message or feedback
+    AnalyticsUtil.logEvent("PERMISSION_DENIED", {
+      actionId: action.id,
+      permissionType: "manage_action",
+    });
+  }, [action.id]);

74-86: Consider consolidating analytics events.

Multiple analytics events for the same user action could be consolidated into a single event with comprehensive data.

-    AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", {
-      type: "QUERIES/APIs",
-      fromUrl: location.pathname,
-      toUrl: url,
-      name: action.name,
-    });
-    AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", {
-      actionId: action?.id,
-      datasourceId: datasource?.id,
-      pluginName: pluginGroups[action?.pluginId]?.name,
-      actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
-      isMock: !!datasource?.isMock,
-    });
+    AnalyticsUtil.logEvent("ACTION_INTERACTION", {
+      type: "QUERIES/APIs",
+      interaction: "EDIT",
+      fromUrl: location.pathname,
+      toUrl: url,
+      name: action.name,
+      actionId: action?.id,
+      datasourceId: datasource?.id,
+      pluginName: pluginGroups[action?.pluginId]?.name,
+      actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
+      isMock: !!datasource?.isMock,
+    });

89-111: Add accessibility attributes to improve user experience.

The EntityItem component should include ARIA attributes for better accessibility support.

     <EntityItem
       className="action t--action-entity"
+      role="listitem"
+      aria-label={`${item.title} action`}
       id={action.id}
       isSelected={activeActionBaseId === action.id}
       key={action.id}
app/client/src/pages/Editor/IntegrationEditor/APIOrSaasPlugins.tsx (3)

Line range hint 66-71: Add prop type validation for required parameters.

The createNewApiActionBasedOnIdeType callback props should validate its parameters.

+  const validateIdeParams = (
+    ideType: IDEType,
+    editorId: string,
+    parentEntityId: string,
+    parentEntityType: ActionParentEntityTypeInterface,
+  ) => {
+    if (!ideType || !editorId) {
+      throw new Error("Invalid IDE parameters");
+    }
+  };

Line range hint 134-182: Simplify event handling logic.

The switch statement and nested conditions could be simplified using a map of handlers.

+  const actionHandlers = {
+    [API_ACTION.CREATE_NEW_API]: () => handleCreateNew(API_ACTION.CREATE_NEW_API),
+    [API_ACTION.CREATE_NEW_GRAPHQL_API]: () => handleCreateNew(API_ACTION.CREATE_NEW_GRAPHQL_API),
+    [API_ACTION.CREATE_DATASOURCE_FORM]: (params) => {
+      if (params?.pluginId) {
+        props.createTempDatasourceFromForm({
+          pluginId: params.pluginId,
+          type: params.type!,
+        });
+      }
+    },
+    [API_ACTION.AUTH_API]: () => handleCreateAuthApiDatasource(),
+  };
+
-    switch (actionType) {
-      case API_ACTION.CREATE_NEW_API:
-      case API_ACTION.CREATE_NEW_GRAPHQL_API:
-        handleCreateNew(actionType);
-        break;
-      // ... other cases
-    }
+    const handler = actionHandlers[actionType];
+    if (handler) handler(params);

351-351: Consider using React.memo for performance optimization.

The component could benefit from memoization to prevent unnecessary re-renders.

-  createNewApiActionBasedOnIdeType,
+  createNewApiActionBasedOnIdeType: React.useCallback(
+    (...args) => createNewApiActionBasedOnIdeType(...args),
+    []
+  ),
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f86ad9 and e2719d1.

📒 Files selected for processing (7)
  • app/client/src/ce/entities/IDE/hooks/useActionContextMenuByIdeType.tsx (1 hunks)
  • app/client/src/ce/entities/IDE/hooks/useCreateActionsPermissions.ts (1 hunks)
  • app/client/src/ee/entities/IDE/hooks/useActionContextMenuByIdeType.tsx (1 hunks)
  • app/client/src/ee/entities/IDE/hooks/useCreateActionsPermissions.ts (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (3 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (1 hunks)
  • app/client/src/pages/Editor/IntegrationEditor/APIOrSaasPlugins.tsx (6 hunks)
✅ Files skipped from review due to trivial changes (2)
  • app/client/src/ee/entities/IDE/hooks/useCreateActionsPermissions.ts
  • app/client/src/ee/entities/IDE/hooks/useActionContextMenuByIdeType.tsx
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (5)
app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (2)

2-29: LGTM! Clean organization of imports and hooks.

The new imports and hooks are well-structured and follow React best practices.


36-38: Verify IDE type determination across routes.

The IDE type determination is crucial for the component's functionality. Let's verify its usage across different routes.

✅ Verification successful

IDE type determination implementation is correct and consistent

The usage of getIDETypeByUrl in List.tsx follows the established pattern used consistently across the codebase, maintaining proper type safety and route handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of getIDETypeByUrl to ensure consistent implementation
rg "getIDETypeByUrl" --type ts --type tsx -B 2 -A 2

# Check for any hardcoded IDE types that might conflict
ast-grep --pattern 'ideType = $_' -l typescript

Length of output: 256


Script:

#!/bin/bash
# Search with correct file type specifications
rg "getIDETypeByUrl" --type typescript --type tsx -B 2 -A 2

# Find the definition of getIDETypeByUrl
ast-grep --pattern 'function getIDETypeByUrl($_) {
  $$$
}'

# Look for related IDE type handling in routes
rg "IDE_TYPE" --type typescript --type tsx -B 2 -A 2

Length of output: 244


Script:

#!/bin/bash
# Search for the file and function usage with correct type arguments
rg "getIDETypeByUrl" -t js -t ts

# Find relevant files
fd -e ts -e tsx List.tsx

# Try alternative pattern for function definition
ast-grep --pattern 'export function getIDETypeByUrl($_) {
  $$$
}'

# Look for IDE type related constants
rg "IDE_TYPE" -t js -t ts

Length of output: 12422

app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (1)

64-70: 🛠️ Refactor suggestion

Add URL validation before navigation.

The URL generation should be validated to ensure it's properly formatted and safe for navigation.

   const config = getActionConfig(action.pluginType);
   const url = config?.getURL(
     parentEntityId ?? "",
     action.baseId,
     action.pluginType,
     pluginGroups[action.pluginId],
   );
+  const isValidUrl = url && /^[/][a-zA-Z0-9-/_]+$/.test(url);
+  if (!isValidUrl) {
+    console.error("Invalid URL generated:", url);
+    return;
+  }
app/client/src/ce/entities/IDE/hooks/useCreateActionsPermissions.ts (1)

12-19: Consider explicit handling of all IDE types.

The switch statement only handles IDE_TYPE.App explicitly, defaulting to true for all other cases. This might be too permissive and could lead to unintended access.

Let's verify all possible IDE types:

Consider handling each IDE type explicitly to make the permission logic more intentional:

  switch (ideType) {
    case IDE_TYPE.App: {
      return getHasCreateActionPermission(isFeatureEnabled, pagePermissions);
    }
+   case IDE_TYPE.Query: {
+     return true; // Add explicit logic if needed
+   }
+   case IDE_TYPE.API: {
+     return true; // Add explicit logic if needed
+   }
    default: {
-     return true;
+     console.warn(`Unhandled IDE type: ${ideType}`);
+     return false; // Fail safe by default
    }
  }
app/client/src/ce/entities/IDE/hooks/useActionContextMenuByIdeType.tsx (1)

34-42: Add prop types validation for QueryEntityContextMenu.

The component is being used without proper prop types validation.

Let's verify if prop types exist:

Consider creating an interface for the props and validating them:

interface QueryEntityContextMenuProps {
  canDeleteAction: boolean;
  canManageAction: boolean;
  id: string;
  name: string;
  parentEntityId: string;
  pluginType: string;
}

Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 115, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

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

🔭 Outside diff range comments (1)
app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx (1)

Line range hint 31-33: Address technical debt: Remove TODOs and type annotations.

Multiple TODOs and eslint-disable directives indicate areas needing improvement:

  1. Replace any types with proper type definitions
  2. Implement the pending fixes mentioned in TODOs

Consider this type-safe implementation:

- const [selectedOption, setSelectedOption] = useState<any>([
+ const [selectedOption, setSelectedOption] = useState<Partial<SelectOptionProps>[]>([
   {
     value: props.placeholder,
   },
 ]);

- const onSelectHandler = (value?: any, option?: any) => {
+ const onSelectHandler = (
+   value?: string,
+   option?: Partial<SelectOptionProps> | Partial<SelectOptionProps>[]
+ ) => {

- const onRemoveOptions = (value: any) => {
+ const onRemoveOptions = (value: string) => {
   const updatedItems = selectedOption.filter(
-    (option: any) => option.value !== value,
+    (option: Partial<SelectOptionProps>) => option.value !== value,
   );

Also applies to: 37-39, 52-54, 55-57

🧹 Nitpick comments (17)
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Move.tsx (2)

46-49: Consider more explicit conditional prop assignment.

While the spread operator works, a more explicit condition would improve readability.

-      <MenuSubTrigger
-        disabled={disabled}
-        {...(!hideIcon && { startIcon: "swap-horizontal" })}
-      >
+      <MenuSubTrigger
+        disabled={disabled}
+        startIcon={hideIcon ? undefined : "swap-horizontal"}
+      >

52-52: Consider moving styles to styled-components or CSS modules.

Inline styles work but could be better maintained in a separate styling solution.

const StyledMenuSubContent = styled(MenuSubContent)`
  max-height: 350px;
  width: 220px;
`;
app/client/src/ce/pages/Editor/EntityEditor/ConvertToModuleInstanceCTA/index.tsx (1)

8-8: LGTM! Consider documenting the hideIcon prop.

The addition of the optional hideIcon prop aligns with the component's purpose. Consider adding JSDoc to document its usage.

+ /** Whether to hide the icon in the UI */
  hideIcon?: boolean;
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Rename.tsx (1)

15-20: Consider extracting the timeout delay to a constant.

The setTimeout delay is hardcoded. Consider extracting it to a named constant for better maintainability.

+const RENAME_FOCUS_DELAY = 100;
 const setRename = useCallback(() => {
   // We add a delay to avoid having the focus stuck in the menu trigger
   setTimeout(() => {
     dispatch(initExplorerEntityNameEdit(action.id));
-  }, 100);
+  }, RENAME_FOCUS_DELAY);
 }, [dispatch, action.id]);
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Copy.tsx (1)

41-41: Extract style values to constants.

The hardcoded style values should be extracted to named constants for better maintainability.

+const MENU_SUB_CONTENT_STYLES = {
+  maxHeight: "350px",
+  width: "220px",
+} as const;
-<MenuSubContent style={{ maxHeight: "350px" }} width="220px">
+<MenuSubContent style={MENU_SUB_CONTENT_STYLES}>
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ConvertToModule.tsx (1)

34-37: Add a detailed comment explaining the workflow query limitation.

The early return for internal plugin types would benefit from a more detailed comment explaining the technical limitation.

-  if (action.pluginType === PluginType.INTERNAL) {
-    // Workflow queries cannot be converted to modules
-    return null;
-  }
+  // Internal plugin types represent workflow queries which have dependencies
+  // on workflow-specific features that are not supported in modules
+  if (action.pluginType === PluginType.INTERNAL) {
+    return null;
+  }
app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx (2)

Line range hint 5-22: Enhance type safety for selected values.

The DropdownWrapperProps interface is well-defined, but the component's implementation could be more type-safe.

Consider adding a generic type parameter:

interface DropdownWrapperProps<T extends string | number = string> {
  value?: T;
  options: Partial<SelectOptionProps & { value: T }>[];
  // ... rest of the props
}

Line range hint 59-71: Consider splitting component and simplifying effect logic.

The component handles both single and multi-select modes, which increases complexity. The useEffect also has multiple conditions and dependencies.

Consider:

  1. Splitting into SingleSelectDropdown and MultiSelectDropdown components
  2. Moving the selection state management to a custom hook
  3. Simplifying the effect logic by using a controlled component pattern
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ShowBindings.tsx (1)

14-34: Consider adding error handling and performance optimizations.

The component implementation is clean, but could benefit from some improvements:

+import React, { useCallback, memo } from "react";

 interface Props {
   action: Action;
+  /** Whether the menu item should be disabled */
   disabled?: boolean;
 }

-export const ShowBindings = ({ action, disabled }: Props) => {
+export const ShowBindings = memo(({ action, disabled }: Props) => {
   const dispatch = useDispatch();

   const handleSelect = useCallback(() => {
+    try {
       dispatch({
         type: ReduxActionTypes.SET_ENTITY_INFO,
         payload: {
           entityId: action.id,
           entityName: action.name,
           entityType: ENTITY_TYPE.ACTION,
           show: true,
         },
       });
+    } catch (error) {
+      console.error("Failed to show bindings:", error);
+    }
   }, [action.id, action.name]);

   return (
     <MenuItem disabled={disabled} onSelect={handleSelect}>
       {createMessage(CONTEXT_SHOW_BINDING)}
     </MenuItem>
   );
-};
+});
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Delete.tsx (1)

49-54: Consider more explicit prop spreading.

While the spread operator works, consider making the startIcon prop more explicit for better maintainability.

-      {...(!hideIcon && { startIcon: "trash" })}
+      startIcon={hideIcon ? undefined : "trash"}
app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/AppQueryContextMenuItems.tsx (3)

1-17: Consider grouping related imports.

The imports could be better organized by grouping related imports together (React, types, hooks, components).

 import React from "react";
+
 import type { Action } from "entities/Action";
+
 import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
 import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
 import {
   getHasDeleteActionPermission,
   getHasManageActionPermission,
 } from "ee/utils/BusinessFeatures/permissionPageHelpers";
+
 import {
   ConvertToModule,
   Copy,
   Delete,
   Move,
   Rename,
   ShowBindings,
 } from "pages/Editor/AppPluginActionEditor/components/ContextMenuItems";

22-48: Inconsistent use of hideIcon prop.

The hideIcon prop is applied to some menu items but not to others (Rename and ShowBindings). This inconsistency might affect the visual uniformity of the menu.

-      <Rename action={action} disabled={!canManageAction} />
-      <ShowBindings action={action} disabled={false} />
+      <Rename action={action} disabled={!canManageAction} hideIcon />
+      <ShowBindings action={action} disabled={false} hideIcon />

41-42: Consider adding a tooltip for disabled menu items.

When menu items are disabled due to insufficient permissions, it would be helpful to show a tooltip explaining why.

app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/EntityContextMenu.tsx (2)

10-12: Consider adding documentation for the Props interface.

Add JSDoc comments to explain the purpose of the menuContent prop and its optional nature.

+/**
+ * Props for EntityContextMenu component
+ * @property {React.ReactNode[] | React.ReactNode} menuContent - Optional content to be rendered inside the menu
+ */
 interface Props {
   menuContent?: React.ReactNode[] | React.ReactNode;
 }

36-42: Avoid hardcoding dimensions in the component.

The width "220px" is hardcoded in the component. Consider moving this to a constants file or making it configurable through props.

app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (1)

70-85: Memoize analytics event data.

The analytics event data object is recreated on every render. Consider memoizing it with useMemo to optimize performance.

+const analyticsData = useMemo(() => ({
+  actionId: action?.id,
+  datasourceId: datasource?.id,
+  pluginName: pluginGroups[action?.pluginId]?.name,
+  actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
+  isMock: !!datasource?.isMock,
+}), [action, datasource, pluginGroups]);

 const switchToAction = useCallback(() => {
   url && history.push(url, { invokedBy: NavigationMethod.EntityExplorer });
   AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", {
     type: "QUERIES/APIs",
     fromUrl: location.pathname,
     toUrl: url,
     name: action.name,
   });
-  AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", {
-    actionId: action?.id,
-    datasourceId: datasource?.id,
-    pluginName: pluginGroups[action?.pluginId]?.name,
-    actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
-    isMock: !!datasource?.isMock,
-  });
+  AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", analyticsData);
 }, [url, location.pathname, action, datasource, pluginGroups]);
app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (1)

72-118: Consider extracting common group rendering logic.

The group title rendering logic is duplicated between the new EntityGroupsList and the traditional mapping approach. Consider extracting this into a shared component.

+ const GroupTitle = ({ title }: { title: string }) => (
+   <Flex py="spaces-1">
+     <Text
+       className="overflow-hidden overflow-ellipsis whitespace-nowrap"
+       kind="body-s"
+     >
+       {title}
+     </Text>
+   </Flex>
+ );

  {isNewADSTemplatesEnabled ? (
    <EntityGroupsList
      groups={filteredItemGroups.map(({ group, items }) => ({
        groupTitle: group,
        items,
        className: "",
        renderList: (item: EntityItem) => (
          <ActionEntityItem item={item} />
        ),
      }))}
    />
  ) : (
    filteredItemGroups.map(({ group, items }) => (
      <Flex flexDirection="column" key={group}>
-       <Flex py="spaces-1">
-         <Text
-           className="overflow-hidden overflow-ellipsis whitespace-nowrap"
-           kind="body-s"
-         >
-           {group}
-         </Text>
-       </Flex>
+       <GroupTitle title={group} />
        <FilesContextProvider
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 007bbcb and dad304b.

📒 Files selected for processing (18)
  • app/client/src/ce/entities/IDE/utils.tsx (3 hunks)
  • app/client/src/ce/pages/Editor/EntityEditor/ConvertToModuleInstanceCTA/index.tsx (1 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/index.tsx (1 hunks)
  • app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx (1 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ConvertToModule.tsx (1 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Copy.tsx (2 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Delete.tsx (2 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Move.tsx (2 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Rename.tsx (1 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ShowBindings.tsx (1 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/index.ts (1 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ConvertToModule/index.tsx (0 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ToolbarMenu/Rename.tsx (0 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ToolbarMenu/ToolbarMenu.tsx (2 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (3 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/AppQueryContextMenuItems.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/EntityContextMenu.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (1 hunks)
💤 Files with no reviewable changes (2)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ToolbarMenu/Rename.tsx
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ConvertToModule/index.tsx
✅ Files skipped from review due to trivial changes (1)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem/index.tsx
🧰 Additional context used
📓 Learnings (1)
app/client/src/ce/entities/IDE/utils.tsx (1)
Learnt from: ankitakinger
PR: appsmithorg/appsmith#37056
File: app/client/src/pages/Editor/JSEditor/JSObjectNameEditor/JSObjectNameEditor.tsx:22-25
Timestamp: 2024-11-12T08:11:43.278Z
Learning: "constants/AppConstants" does not export "SaveActionNameParams".
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-build / client-build
🔇 Additional comments (14)
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Move.tsx (2)

14-20: LGTM! Clean type definitions.

The Props interface is well-structured with proper typing for required and optional properties.


22-22: LGTM! Clean component signature.

Props destructuring follows React best practices.

app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx (1)

83-83: LGTM! Follows HTML5 attribute naming convention.

The change from data-testId to data-testid aligns with HTML5 standards.

app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ShowBindings.tsx (2)

1-12: LGTM! Clean imports and well-defined Props interface.

The type definitions and imports are well-organized and properly typed.


19-20: Verify Redux action type definition.

Ensure that ReduxActionTypes.SET_ENTITY_INFO is properly defined in the Redux action types.

✅ Verification successful

Redux action type is properly defined and used correctly.

The SET_ENTITY_INFO action type is defined in ce/constants/ReduxActionConstants.tsx and is used consistently throughout the codebase for entity information management. The implementation in ShowBindings.tsx follows the established pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for SET_ENTITY_INFO action type definition
rg "SET_ENTITY_INFO.*=" -A 2

Length of output: 30


Script:

#!/bin/bash
# Search for files that might contain Redux action types
fd "actions|types|constants" --type f

# Search for SET_ENTITY_INFO with more flexible pattern
rg -i "SET_ENTITY_INFO" -A 2

# Search specifically in TypeScript/JavaScript files
rg "SET_ENTITY_INFO" --type ts --type js -A 2

Length of output: 47059

app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Delete.tsx (4)

8-15: LGTM! Clean type definitions and imports.

The Props interface is well-structured with proper typing for the action prop and optional flags.


18-18: LGTM! Clean component signature.

Props destructuring matches the interface definition perfectly.


35-42: LGTM! Proper event handling.

Good addition of stopPropagation to prevent event bubbling.


22-33: Add null checks for action object.

The current implementation might throw if action is undefined. Consider adding proper null checks.

-  const handleDeleteClick = useCallback(
-    ({ onSuccess }: { onSuccess?: () => void }) => {
-      dispatch(
-        deleteAction({
-          id: action?.id ?? "",
-          name: action?.name ?? "",
-          onSuccess,
-        }),
-      );
-    },
-    [action.id, action.name, dispatch],
+  const handleDeleteClick = useCallback(
+    ({ onSuccess }: { onSuccess?: () => void }) => {
+      if (!action) return;
+      dispatch(
+        deleteAction({
+          id: action.id,
+          name: action.name,
+          onSuccess,
+        }),
+      );
+    },
+    [action?.id, action?.name, dispatch],
app/client/src/pages/Editor/AppPluginActionEditor/components/ToolbarMenu/ToolbarMenu.tsx (2)

13-13: Clean import consolidation!

Good job consolidating the imports from ContextMenuItems module.


32-37: Verify component prop changes across the codebase.

The component updates look good with consistent prop passing. Let's verify the changes are applied uniformly.

✅ Verification successful

Component prop changes are consistently implemented

The search results confirm that all instances of these components in the codebase properly include the action prop and maintain consistent permission-based disabled states. No issues found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining instances of these components without the action prop
ast-grep --pattern 'ConvertToModule $$$' 
ast-grep --pattern 'Copy disabled={$_}' 
ast-grep --pattern 'Move disabled={$_}' 
ast-grep --pattern 'Delete disabled={$_}'

Length of output: 42


Script:

#!/bin/bash
# Search for component usage with ripgrep
echo "=== ConvertToModule Usage ==="
rg "<ConvertToModule" --type ts --type tsx -l

echo "=== Copy Component Usage ==="
rg "<Copy\s" --type ts --type tsx -l

echo "=== Move Component Usage ==="
rg "<Move\s" --type ts --type tsx -l

echo "=== Delete Component Usage ==="
rg "<Delete\s" --type ts --type tsx -l

# If we find the files, we can then check specific instances
for component in "ConvertToModule" "Copy" "Move" "Delete"; do
  echo "=== $component Component Instances ==="
  rg "<$component.*?>" --type ts --type tsx -A 1
done

Length of output: 1415


Script:

#!/bin/bash
# Search for component usage without type restrictions
echo "=== Component Usage with Context ==="
rg -U "<(ConvertToModule|Copy|Move|Delete).*?>" -A 1

# Search specifically for usage without action prop
echo "=== Usage without action prop ==="
rg -U "<(ConvertToModule|Copy|Move|Delete)[^>]*?(?<!action=)[^>]*?>" -A 1

Length of output: 9204

app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx (3)

31-51: Clean hooks implementation and feature flag usage.

The transition to IDE-based architecture is well implemented with proper hooks usage and clean feature flag integration.


73-84: Well-structured EntityGroupsList implementation.

The new EntityGroupsList implementation provides better component composition and cleaner rendering logic.


2-29: Verify imports after the refactor.

Let's verify that all imports are being used after the transition to IDE-based architecture.

✅ Verification successful

All imports are properly used in the component.

The verification confirms that all imported components, hooks, types and utilities are actively used within the ListQuery component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for unused imports
ast-grep --pattern 'import { $_ } from "$_"' | while read -r line; do
  import_name=$(echo "$line" | grep -o '{.*}' | tr -d '{} ')
  for name in $import_name; do
    if ! rg "\b$name\b" --type ts --type tsx > /dev/null; then
      echo "Potential unused import: $name"
    fi
  done
done

Length of output: 131070


Script:

#!/bin/bash
# Check usage of imported components and functions in the file
echo "Checking imports usage in List.tsx..."

# Check ADS components usage
ast-grep --pattern '<$_/>' app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx | grep -E 'Flex|Text|SearchAndAdd|NoSearchResults|EntityGroupsList'

# Check hooks and utility imports usage
ast-grep --pattern '$_\(' app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx | grep -E 'useSelector|useActiveActionBaseId|useFeatureFlag|useQueryAdd|useLocation|useParentEntityInfo|useCreateActionsPermissions'

# Check type usage
ast-grep --pattern ': $_' app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx | grep -E 'EntityItem|ActionParentEntityType'

Length of output: 590


Script:

#!/bin/bash

# First verify file exists and show content
echo "=== File content ==="
cat app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx

echo -e "\n=== Checking component usage ==="
# Check both self-closing and regular JSX tags
ast-grep --pattern '
  <$_>
    $$$
  </$_>' app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx

ast-grep --pattern '<$_ $$$/>
' app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx

echo -e "\n=== Checking hook usage ==="
# Check hook calls with different patterns
ast-grep --pattern '
  const $_ = $_($$$)
' app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx

Length of output: 9854

app/client/src/ce/entities/IDE/utils.tsx Outdated Show resolved Hide resolved
app/client/src/ce/entities/IDE/utils.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: 2

🧹 Nitpick comments (3)
app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (3)

70-82: Consider extracting analytics logic to a separate function.

Multiple analytics events are logged together, making the code harder to maintain. Consider extracting these into a separate analytics utility function.

+const logActionAnalytics = (action: Action, datasource: Datasource, fromUrl: string, toUrl: string, pluginGroups: Record<string, any>) => {
+  AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", {
+    type: "QUERIES/APIs",
+    fromUrl,
+    toUrl,
+    name: action.name,
+  });
+  AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", {
+    actionId: action?.id,
+    datasourceId: datasource?.id,
+    pluginName: pluginGroups[action?.pluginId]?.name,
+    actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
+    isMock: !!datasource?.isMock,
+  });
+};

30-30: Add JSDoc documentation for the component props.

Consider adding JSDoc documentation to describe the expected shape and purpose of the EntityItemProps interface.

+/**
+ * QueryEntityItem component renders a query or API entity in the IDE.
+ * @param {Object} props - Component props
+ * @param {EntityItemProps} props.item - The entity item data
+ */
 export const QueryEntityItem = ({ item }: { item: EntityItemProps }) => {

38-38: Optimize memoization dependencies.

The switchToAction callback has many dependencies that could trigger unnecessary re-renders. Consider breaking down the callback into smaller functions or moving some computations outside the component.

Also applies to: 68-83

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dad304b and 5aa02b8.

📒 Files selected for processing (3)
  • app/client/src/ce/entities/IDE/utils.ts (2 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.tsx (3 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-build / client-build
🔇 Additional comments (3)
app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.tsx (1)

Line range hint 1-18: LGTM!

The imports are well-organized and properly typed.

app/client/src/pages/Editor/IDE/EditorPane/Query/ListItem/QueryEntityItem.tsx (2)

30-37: Add error handling for missing action or datasource.

The component assumes that action and datasource will be available. Add proper error handling or fallback UI for cases where they might be undefined.


68-69: Add error handling for navigation failures.

The URL navigation lacks error handling. Consider adding user feedback for cases where the URL is invalid or navigation fails.

app/client/src/ce/entities/IDE/utils.ts Outdated Show resolved Hide resolved
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 168, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

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

🧹 Nitpick comments (2)
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/PageMenuItem.tsx (1)

14-18: Consider adding aria-label for accessibility.

While the implementation is clean, adding an aria-label would improve accessibility for screen readers.

-    <MenuItem disabled={props.disabled} onSelect={handleOnSelect}>
+    <MenuItem 
+      disabled={props.disabled} 
+      onSelect={handleOnSelect}
+      aria-label={`Page ${props.page.pageName}`}
+    >
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Copy.tsx (1)

38-38: Consider making dimensions configurable via props.

The hardcoded dimensions (maxHeight: "350px", width: "220px") in MenuSubContent might limit reusability. Consider making these configurable through props with these values as defaults.

- <MenuSubContent style={{ maxHeight: "350px" }} width="220px">
+ <MenuSubContent 
+   style={{ maxHeight: props.maxHeight ?? "350px" }} 
+   width={props.width ?? "220px"}
+ >
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5aa02b8 and 3b79140.

📒 Files selected for processing (4)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Copy.tsx (2 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Move.tsx (2 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/PageMenuItem.tsx (1 hunks)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Rename.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Rename.tsx
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (7)
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/PageMenuItem.tsx (1)

8-8: LGTM! Clean prop interface extension.

The optional disabled prop is well-typed and follows React conventions.

app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Copy.tsx (2)

1-14: LGTM! Props interface is well-defined.

The type definitions are clear and properly typed with the Action interface. Optional props are correctly marked.


Line range hint 17-34: LGTM! Component implementation is clean and reusable.

The component now receives the action directly as a prop instead of relying on context, making it more modular and easier to test.

app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/Move.tsx (4)

14-14: LGTM! Type-safe props definition.

The addition of the Action type and the Props interface update improves type safety.

Also applies to: 17-19


22-22: LGTM! Component signature matches Props interface.

The destructuring pattern correctly matches the updated Props interface.


54-54: LGTM! Consistent prop forwarding.

The disabled state is correctly propagated to the child component.


46-49: Verify the impact of fixed dimensions on MenuSubContent.

The fixed width and maxHeight might affect the component's appearance in different contexts. Please ensure these values work well across all usage scenarios.

Run this script to find other instances of MenuSubContent to compare dimensions:

✅ Verification successful

The fixed dimensions align with existing menu patterns.

The specified width (220px) and maxHeight (350px) match the standard dimensions used across other MenuSubContent components in the codebase, ensuring consistent menu appearance.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other MenuSubContent usage patterns
rg -A 2 "MenuSubContent" --type tsx

Length of output: 63


Script:

#!/bin/bash
# Search for MenuSubContent without file type restriction
rg "MenuSubContent"

# Search for style properties in menu-related components
rg -B 2 -A 2 'MenuSub.*Content.*style'

# Search for width/height properties in menu components
rg -B 2 -A 2 'Menu.*Content.*width|Menu.*Content.*height'

Length of output: 82237

Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 168, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

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

🧹 Nitpick comments (2)
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ConvertToModule.tsx (2)

21-31: Consider aligning variable names with their usage.

The permission check variables (isCreatePermitted, isDeletePermitted) could be renamed to match their usage in convertToModuleProps (canCreateModuleInstance, canDeleteEntity).

-  const isCreatePermitted = getHasCreateActionPermission(
+  const canCreateModuleInstance = getHasCreateActionPermission(
     isFeatureEnabled,
     pagePermissions,
   );

-  const isDeletePermitted = getHasDeleteActionPermission(
+  const canDeleteEntity = getHasDeleteActionPermission(
     isFeatureEnabled,
     action.userPermissions,
   );

33-36: Consider enhancing the comment for better clarity.

While the early return pattern is good, the comment could be more specific about why workflow queries cannot be converted.

-    // Workflow queries cannot be converted to modules
+    // Skip conversion for internal workflow queries as they require special handling and cannot be modularized
     return null;
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between afdd229 and f0306d5.

📒 Files selected for processing (2)
  • app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ConvertToModule.tsx (1 hunks)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/ConvertToModule.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/ConvertToModule.tsx
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (3)
app/client/src/pages/Editor/AppPluginActionEditor/components/ContextMenuItems/ConvertToModule.tsx (3)

13-13: LGTM! Clean interface definition.

The Props interface is well-defined with proper type imports.

Also applies to: 15-17


19-19: LGTM! Clean component declaration.

Good use of named exports and props destructuring.


Line range hint 38-47: LGTM! Clean props handling and rendering.

Well-structured props object with clear property names.

@ankitakinger ankitakinger added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Jan 23, 2025
@ankitakinger ankitakinger added the ok-to-test Required label for CI label Jan 23, 2025
@ankitakinger
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

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

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

🧹 Nitpick comments (6)
app/client/src/pages/Editor/IDE/EditorPane/Query/EntityItem/QueryEntityItem.tsx (4)

1-29: Consider reducing enterprise edition coupling.

The component has tight coupling with enterprise edition (ee) modules. Consider extracting shared logic to common utilities to improve maintainability.


30-50: Consider memoizing selector results.

Multiple selector calls (getActionByBaseId, getDatasource) could impact performance. Consider combining these into a single memoized selector.

// Example combined selector
const selectActionAndDatasource = createSelector(
  [
    (state: AppState, itemKey: string) => getActionByBaseId(state, itemKey),
    (state: AppState) => state,
  ],
  (action, state) => ({
    action,
    datasource: action ? getDatasource(state, action.datasource?.id) : null,
  })
);

70-85: Extract analytics logic to a separate function.

The switchToAction function handles both navigation and analytics. Consider separating these concerns for better maintainability.

const logActionAnalytics = useCallback((action: Action, datasource: Datasource) => {
  AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", {
    type: "QUERIES/APIs",
    fromUrl: location.pathname,
    toUrl: url,
    name: action.name,
  });
  AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", {
    actionId: action?.id,
    datasourceId: datasource?.id,
    pluginName: pluginGroups[action?.pluginId]?.name,
    actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
    isMock: !!datasource?.isMock,
  });
}, [location.pathname, url]);

93-101: Extract name editor configuration.

Consider extracting the nameEditorConfig object to improve readability and reusability.

const getNameEditorConfig = (
  action: Action,
  canManageAction: boolean,
  editingEntity: string,
  updatingEntity: string,
) => ({
  canEdit: canManageAction,
  isEditing: editingEntity === action.id,
  isLoading: updatingEntity === action.id,
  onEditComplete: exitEditMode,
  onNameSave: (newName: string) =>
    dispatch(saveActionNameBasedOnIdeType(action.id, newName, ideType)),
  validateName: (newName) => validateName(newName, item.title),
});
app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx (2)

78-78: Remove redundant Boolean call.

The Boolean call is unnecessary as the expression will already be coerced to a boolean.

-canEdit: canManageJSAction && !Boolean(jsAction?.isMainJSCollection),
+canEdit: canManageJSAction && !jsAction?.isMainJSCollection,
🧰 Tools
🪛 Biome (1.9.4)

[error] 78-78: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


57-69: Optimize useCallback dependencies.

The dependency array includes parentEntityId which is used in navigateToUrl, but since navigateToUrl is already computed outside the callback, it should be included in the dependencies instead.

-  }, [parentEntityId, jsAction.baseId, jsAction.name, location.pathname]);
+  }, [navigateToUrl, jsAction.baseId, jsAction.name, location.pathname]);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 216dc51 and 4e74792.

📒 Files selected for processing (3)
  • app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/EntityItem/QueryEntityItem.tsx (1 hunks)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Move.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Move.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx

[error] 78-78: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-build / client-build
🔇 Additional comments (2)
app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx (2)

1-23: LGTM! Well-organized imports.

The imports are properly structured with a clear separation between types and regular imports.


71-95: LGTM! Clean and well-structured component rendering.

The EntityItem implementation is comprehensive with proper event handling and prop management.

🧰 Tools
🪛 Biome (1.9.4)

[error] 78-78: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

Copy link

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

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

🧹 Nitpick comments (4)
app/client/src/pages/Editor/JSEditor/ContextMenuItems/Delete.tsx (4)

12-16: Consider strengthening the Props interface type safety.

The deleteJSAction callback is optional while jsAction is required, but the code uses them together at line 23. This could lead to runtime errors.

 interface Props {
   jsAction: JSCollection;
   disabled?: boolean;
-  deleteJSAction?: () => void;
+  deleteJSAction: () => void;
 }

18-21: Consider memoizing the component for better performance.

Since this component might be rendered in a list of actions, wrapping it with React.memo could prevent unnecessary re-renders.

-export const Delete = ({ deleteJSAction, disabled, jsAction }: Props) => {
+export const Delete = React.memo(({ deleteJSAction, disabled, jsAction }: Props) => {
   // ... component implementation
-};
+});

33-40: Improve event type safety.

The event parameter type should be more specific than the generic Event.

-    (e?: Event) => {
+    (e?: React.MouseEvent | React.KeyboardEvent) => {

46-55: Consider adding error handling feedback.

The delete operation should handle and communicate potential failures to users.

Consider wrapping the delete operation in a try-catch and showing a toast notification on error:

   const handleDeleteClick = useCallback(() => {
+    try {
       jsAction.isPublic && deleteJSAction
         ? deleteJSAction()
         : dispatch(
             deleteJSCollection({
               id: jsAction?.id ?? "",
               name: jsAction?.name ?? "",
             }),
           );
+    } catch (error) {
+      Toaster.show({
+        text: "Failed to delete JS collection",
+        type: "error",
+      });
+    }
   }, [jsAction.id, jsAction.name, dispatch]);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e74792 and d321cf7.

📒 Files selected for processing (1)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Delete.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check

@ankitakinger
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

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

Copy link

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

@ankitakinger
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

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

Copy link

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

@ankitakinger ankitakinger changed the title chore: Replace query entities in entity explorer with new ADS templates chore: Replace entities in entity explorer with new ADS templates Jan 24, 2025
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

🧹 Nitpick comments (15)
app/client/src/pages/Editor/JSEditor/ContextMenuItems/PageMenuItem.tsx (3)

5-9: Consider destructuring props for clarity.
Instead of referencing props, you could destructure fields in the parameter list to make the component more readable. For instance:

-export const PageMenuItem = (props: {
-  page: Page;
-  onSelect: (id: string) => void;
-  disabled?: boolean;
-}) => {
+export const PageMenuItem = ({
+  page,
+  onSelect,
+  disabled,
+}: {
+  page: Page;
+  onSelect: (id: string) => void;
+  disabled?: boolean;
+}) => {

10-12: Optimize useCallback dependency.
Using [props] as the sole dependency means the callback will re-initialize whenever any prop changes. You could destructure pageId and onSelect in the dependencies if only those fields are used.


15-17: Enhance accessibility for screen readers.
Consider adding an aria-label for the <MenuItem> to assist visually-impaired users:

-<MenuItem disabled={props.disabled} onSelect={handleOnSelect}>
+<MenuItem 
+  aria-label={`Page menu item for ${props.page.pageName}`} 
+  disabled={props.disabled} 
+  onSelect={handleOnSelect}
+>
app/client/src/pages/Editor/IDE/EditorPane/components/EntityContextMenu.tsx (3)

10-12: Consider adding role and aria-label props for better accessibility.

The Props interface could benefit from additional accessibility-related props to make the context menu more screen-reader friendly.

 interface Props {
   children?: React.ReactNode[] | React.ReactNode;
+  role?: string;
+  'aria-label'?: string;
 }

14-48: Consider memoizing the component for better performance.

Since this is a reusable component that might be rendered multiple times in a list, consider wrapping it with React.memo to prevent unnecessary re-renders.

-const EntityContextMenu = (props: Props) => {
+const EntityContextMenu = React.memo((props: Props) => {
   // ... component implementation
-};
+});

41-41: Avoid using inline styles.

The maxHeight: "unset" style should be moved to a CSS class for better maintainability.

app/client/src/pages/Editor/JSEditor/AppJSEditorContextMenu.tsx (1)

Line range hint 13-31: Consider extracting permission logic to a custom hook.

The permission checking logic could be extracted into a custom hook for better reusability and cleaner component code.

+const useJSCollectionPermissions = (
+  jsCollection: JSCollection
+) => {
+  const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
+  return {
+    isDeletePermitted: getHasDeleteActionPermission(
+      isFeatureEnabled,
+      jsCollection?.userPermissions || [],
+    ),
+    isChangePermitted: getHasManageActionPermission(
+      isFeatureEnabled,
+      jsCollection?.userPermissions || [],
+    ),
+  };
+};
app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx (2)

57-70: Include navigateToUrl in the dependency array
The useCallback references navigateToUrl but omits it from dependencies, which can lead to stale references if navigateToUrl changes.

- }, [parentEntityId, jsAction.baseId, jsAction.name, location.pathname]);
+ }, [parentEntityId, jsAction.baseId, jsAction.name, location.pathname, navigateToUrl]);

73-73: Remove redundant Boolean cast
The linter warns about unnecessary boolean coercion. Simply negate the expression directly.

- canEdit: canManageJSAction && !Boolean(jsAction.isMainJSCollection),
+ canEdit: canManageJSAction && !jsAction.isMainJSCollection,
🧰 Tools
🪛 Biome (1.9.4)

[error] 73-73: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx (3)

47-49: Consider adding a fallback for feature flag.

While the feature flag implementation is correct, consider adding error handling for cases where the flag value might be undefined.

  const isNewADSTemplatesEnabled = useFeatureFlag(
    FEATURE_FLAG.release_ads_entity_item_enabled,
+   false
  );

87-87: Extract group title logic to avoid duplication.

The group title logic is duplicated between the new and old implementations. Consider extracting it to a shared utility function.

+ const getGroupTitle = (group: string) => group === "NA" ? "" : group;

  // In new implementation
- groupTitle: group === "NA" ? "" : group,
+ groupTitle: getGroupTitle(group),

  // In old implementation
- {group !== "NA" ? (
-   <Flex py="spaces-1">
-     <Text
-       className="overflow-hidden overflow-ellipsis whitespace-nowrap"
-       kind="body-s"
-     >
-       {group}
-     </Text>
-   </Flex>
- ) : null}
+ {getGroupTitle(group) && (
+   <Flex py="spaces-1">
+     <Text
+       className="overflow-hidden overflow-ellipsis whitespace-nowrap"
+       kind="body-s"
+     >
+       {getGroupTitle(group)}
+     </Text>
+   </Flex>
+ )}

Also applies to: 100-109


90-92: Memoize the renderList callback to prevent unnecessary re-renders.

The renderList callback is recreated on every render. Consider memoizing it with useCallback.

+ const renderJSEntity = useCallback((item: EntityItem) => {
+   return <JSEntity item={item} />;
+ }, []);

  // In EntityGroupsList props
- renderList: (item: EntityItem) => {
-   return <JSEntity item={item} />;
- },
+ renderList: renderJSEntity,
app/client/src/pages/Editor/IDE/EditorPane/Query/EntityItem/QueryEntityItem.tsx (3)

1-29: Consider organizing imports for better maintainability.

Group imports into sections: external dependencies, internal utilities, types, and enterprise-specific imports.

+ // External dependencies
 import React, { useCallback, useMemo } from "react";
 import { useDispatch, useSelector } from "react-redux";
 import { useLocation } from "react-router";
 import { keyBy } from "lodash";

+ // Internal components and types
 import { EntityItem } from "@appsmith/ads";
 import type { EntityItem as EntityItemProps } from "ee/entities/IDE/constants";
 import type { Action, type StoredDatasource } from "entities/Action";
 import type { Datasource } from "entities/Datasource";
 import { PluginType } from "entities/Plugin";

+ // State management and selectors
 import type { AppState } from "ee/reducers";
 import {
   getActionByBaseId,
   getDatasource,
   getPlugins,
 } from "ee/selectors/entitiesSelector";

+ // Utilities and hooks
 import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
 import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
 import history, { NavigationMethod } from "utils/history";

30-43: Optimize selector usage and add error handling.

Consider these improvements:

  1. Combine selectors to reduce re-renders
  2. Add error handling for cases where action or datasource is undefined
-  const action = useSelector((state: AppState) =>
-    getActionByBaseId(state, item.key),
-  ) as Action;
-  const datasource = useSelector((state) =>
-    getDatasource(state, (action?.datasource as StoredDatasource)?.id),
-  ) as Datasource;
+  const { action, datasource } = useSelector((state: AppState) => ({
+    action: getActionByBaseId(state, item.key),
+    datasource: action?.datasource?.id 
+      ? getDatasource(state, (action.datasource as StoredDatasource).id)
+      : null,
+  }));
+
+  if (!action) {
+    return null; // or error state
+  }

70-85: Consider combining analytics events for better performance.

Multiple separate analytics events could be combined into a single call.

-    AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", {
-      type: "QUERIES/APIs",
-      fromUrl: location.pathname,
-      toUrl: url,
-      name: action.name,
-    });
-    AnalyticsUtil.logEvent("EDIT_ACTION_CLICK", {
-      actionId: action?.id,
-      datasourceId: datasource?.id,
-      pluginName: pluginGroups[action?.pluginId]?.name,
-      actionType: action?.pluginType === PluginType.DB ? "Query" : "API",
-      isMock: !!datasource?.isMock,
-    });
+    AnalyticsUtil.logEvent("ACTION_NAVIGATION", {
+      type: "QUERIES/APIs",
+      navigation: {
+        fromUrl: location.pathname,
+        toUrl: url,
+        name: action.name,
+      },
+      action: {
+        id: action?.id,
+        datasourceId: datasource?.id,
+        pluginName: pluginGroups[action?.pluginId]?.name,
+        type: action?.pluginType === PluginType.DB ? "Query" : "API",
+        isMock: !!datasource?.isMock,
+      }
+    });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adb532c and bf508e2.

📒 Files selected for processing (11)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils/getJSContextMenuByIdeType.tsx (1 hunks)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils/getQueryContextMenuByIdeType.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx (3 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/Query/EntityItem/QueryEntityItem.tsx (1 hunks)
  • app/client/src/pages/Editor/IDE/EditorPane/components/EntityContextMenu.tsx (1 hunks)
  • app/client/src/pages/Editor/JSEditor/AppJSEditorContextMenu.tsx (2 hunks)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Copy.tsx (1 hunks)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Move.tsx (1 hunks)
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/PageMenuItem.tsx (1 hunks)
  • app/client/src/pages/Editor/JSEditor/JSEditorContextMenu.tsx (0 hunks)
💤 Files with no reviewable changes (1)
  • app/client/src/pages/Editor/JSEditor/JSEditorContextMenu.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils/getQueryContextMenuByIdeType.tsx
  • app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils/getJSContextMenuByIdeType.tsx
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Copy.tsx
  • app/client/src/pages/Editor/JSEditor/ContextMenuItems/Move.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx

[error] 73-73: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (9)
app/client/src/pages/Editor/JSEditor/ContextMenuItems/PageMenuItem.tsx (1)

1-3: Imports look consistent with the codebase.
No issues found in the import statements. You are following best practices by using type imports in TypeScript to reduce compile-time overhead.

app/client/src/pages/Editor/JSEditor/AppJSEditorContextMenu.tsx (1)

32-42: LGTM! Clean implementation of the context menu items.

The component structure is clean and follows a good separation of concerns. Each menu item is properly configured with its permissions.

app/client/src/pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem.tsx (2)

25-27: Add runtime check for jsAction to avoid potential null/undefined issues
This reiterates a point made previously in the code review history regarding the risky type assertion.

) as JSCollection;
+ if (!jsAction) {
+   return null; // or render a fallback component
+ }

94-109: File looks good overall
Apart from the above remarks, the rest of the component design is consistent and maintainable. Great job!

app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx (1)

19-19: Verify the JSListItem import path change.

The import path includes 'old' in its structure (ee/pages/Editor/IDE/EditorPane/JS/old/ListItem). This might indicate a temporary migration state.

app/client/src/pages/Editor/IDE/EditorPane/Query/EntityItem/QueryEntityItem.tsx (4)

44-50: LGTM - Name validation implementation is correct.

The useValidateEntityName hook is properly configured with the required entityName prop.


87-105: LGTM - Name editor configuration is well implemented.

The useMemo implementation with proper dependencies and validation function composition follows React best practices.


107-122: LGTM - Component rendering implementation is clean and follows best practices.

The EntityItem implementation with proper event handling and conditional rendering is well structured.


62-69: Add validation for URL construction parameters.

The URL construction could fail silently if pluginGroups[action.pluginId] is undefined.

   const config = getActionConfig(action.pluginType);
+  const plugin = pluginGroups[action.pluginId];
+  if (!plugin) {
+    console.warn(`Plugin not found for action: ${action.name}`);
+  }
   const url = config?.getURL(
     parentEntityId ?? "",
     action.baseId,
     action.pluginType,
-    pluginGroups[action.pluginId],
+    plugin,
   );

@ankitakinger ankitakinger merged commit 8f5aad9 into release Jan 24, 2025
85 checks passed
@ankitakinger ankitakinger deleted the chore/replace-entities-in-entity-explorer branch January 24, 2025 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
IDE Pod Issues that new developers face while exploring the IDE IDE Product Issues related to the IDE Product ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog Task A simple Todo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace Group listing of entity items in Entity Explorer
2 participants