Skip to content

chore: Fix layout issues for UI package editor #40349

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

Merged
merged 3 commits into from
Apr 26, 2025

Conversation

ashit-rath
Copy link
Contributor

@ashit-rath ashit-rath commented Apr 23, 2025

Description

🏗 Architecture

  • Moved mainCanvasReducer from Community Edition (CE) to Enterprise Edition (EE) structure
  • Added proper export structure in EE to maintain backward compatibility
  • Added RESET_EDITOR_REQUEST handler to reset canvas state when needed

🐛 Bug Fixes

  • Fixed widget tag grouping in groupWidgetCardsByTags to properly handle tags that aren't predefined
  • Implemented support for overrideRenderMode in both LayoutSystemBasedCanvas and withWidgetProps
  • Added emptyMessage prop in UIEntitySidebar for improved user experience

PR for https://github.com/appsmithorg/appsmith-ee/pull/7245

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/14610885832
Commit: 54916f7
Cypress dashboard.
Tags: @tag.All
Spec:


Wed, 23 Apr 2025 07:02:40 UTC

Communication

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

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Added support for customizing the empty message in the widget sidebar when no widgets are found.
    • Introduced an option to override the widget render mode in both the canvas and widget components, enabling more flexible widget behavior in the editor.
  • Bug Fixes

    • Improved grouping of widget cards by tags to prevent potential errors when encountering new tags.
  • Refactor

    • Updated internal reducer structure and export patterns for improved maintainability.
    • Adjusted import paths for better modularization and separation between core and enterprise code.

@ashit-rath ashit-rath requested a review from brayn003 April 23, 2025 04:33
@ashit-rath ashit-rath self-assigned this Apr 23, 2025
@ashit-rath ashit-rath requested review from a team as code owners April 23, 2025 04:33
@ashit-rath ashit-rath requested review from jacquesikot and removed request for a team April 23, 2025 04:33
Copy link
Contributor

coderabbitai bot commented Apr 23, 2025

Walkthrough

This set of changes primarily refactors how the mainCanvasReducer and its associated types are imported and exported, moving their source from a general to an enterprise-specific directory and introducing a proxy module in the enterprise edition. The mainCanvasReducer itself is refactored to export its initial state and handlers, and a reset handler is added. Additionally, widget rendering logic is updated to allow an override of the render mode, and the widget sidebar is enhanced to support a customizable empty message. Minor improvements are made to utility functions to handle edge cases.

Changes

File(s) Change Summary
app/client/src/ce/reducers/index.tsx
app/client/src/ce/reducers/uiReducers/index.tsx
app/client/src/ce/sagas/PageSagas.tsx
app/client/src/sagas/AutoLayoutUpdateSagas.tsx
app/client/src/sagas/CanvasSagas/DraggingCanvasSagas.ts
app/client/src/selectors/editorSelectors.tsx
Updated import paths for MainCanvasReduxState and/or mainCanvasReducer to reference the enterprise edition (ee) directory instead of the general reducers directory.
app/client/src/ee/reducers/uiReducers/mainCanvasReducer.ts Added a new proxy module that re-exports all exports and the default export from the CE version of mainCanvasReducer, enabling enterprise-specific overrides if needed.
app/client/src/ce/reducers/uiReducers/mainCanvasReducer.ts Refactored to export initialState and handlers separately; added a handler for RESET_EDITOR_REQUEST to reset state using a deep clone. Reducer creation now uses the exported handlers object.
app/client/src/layoutSystems/CanvasFactory.tsx
app/client/src/widgets/withWidgetProps.tsx
Modified widget render logic to allow renderMode to be overridden via a new prop, enabling widgets to load in page mode from UI modules even in edit mode.
app/client/src/pages/AppIDE/components/WidgetAdd/WidgetsList.tsx Added support for a customizable empty message in the widget panel by importing and passing a new message constant to the sidebar component.
app/client/src/pages/Editor/widgetSidebar/UIEntitySidebar.tsx Removed hardcoded empty message import; added an optional emptyMessage prop to the sidebar component and its interface, allowing the message to be set externally.
app/client/src/pages/Editor/utils.tsx Improved the grouping utility to initialize arrays for new tags, preventing potential undefined behavior when grouping widget cards by tags.

Sequence Diagram(s)

sequenceDiagram
    participant UI_Module
    participant Widget
    participant Redux_Store

    UI_Module->>Widget: Render Widget with overrideRenderMode (optional)
    Widget->>Redux_Store: Select renderMode (if no override)
    Widget->>Widget: Use overrideRenderMode if provided
    Widget->>UI_Module: Render with determined renderMode
Loading
sequenceDiagram
    participant Sidebar
    participant ParentComponent

    ParentComponent->>Sidebar: Render with emptyMessage prop
    Sidebar->>Sidebar: Display emptyMessage when no results
Loading

Suggested labels

Frontend, Task, Packages Pod, Packages & Git Pod, skip-changelog, ok-to-test

Suggested reviewers

  • brayn003

Poem

In the land of reducers, a shuffle occurred,
Imports now point where enterprise is preferred.
Widgets gain wisdom, their modes they can choose,
And sidebars say more, with messages they use.
Arrays grow robust, no undefined fright—
Code refactored and ready, all shining bright! ✨


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between e65fa85 and 54916f7.

📒 Files selected for processing (1)
  • app/client/src/widgets/withWidgetProps.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/widgets/withWidgetProps.tsx
⏰ 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-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

🪧 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 sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

Documentation and Community

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

@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Apr 23, 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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d7d59c6 and e65fa85.

📒 Files selected for processing (13)
  • app/client/src/ce/reducers/index.tsx (1 hunks)
  • app/client/src/ce/reducers/uiReducers/index.tsx (1 hunks)
  • app/client/src/ce/reducers/uiReducers/mainCanvasReducer.ts (2 hunks)
  • app/client/src/ce/sagas/PageSagas.tsx (1 hunks)
  • app/client/src/ee/reducers/uiReducers/mainCanvasReducer.ts (1 hunks)
  • app/client/src/layoutSystems/CanvasFactory.tsx (1 hunks)
  • app/client/src/pages/AppIDE/components/WidgetAdd/WidgetsList.tsx (2 hunks)
  • app/client/src/pages/Editor/utils.tsx (1 hunks)
  • app/client/src/pages/Editor/widgetSidebar/UIEntitySidebar.tsx (2 hunks)
  • app/client/src/sagas/AutoLayoutUpdateSagas.tsx (1 hunks)
  • app/client/src/sagas/CanvasSagas/DraggingCanvasSagas.ts (1 hunks)
  • app/client/src/selectors/editorSelectors.tsx (1 hunks)
  • app/client/src/widgets/withWidgetProps.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
app/client/src/pages/AppIDE/components/WidgetAdd/WidgetsList.tsx (1)
app/client/src/ce/constants/messages.ts (1)
  • WIDGET_PANEL_EMPTY_MESSAGE (2523-2524)
app/client/src/ce/reducers/uiReducers/mainCanvasReducer.ts (2)
app/client/src/ce/constants/ReduxActionConstants.tsx (1)
  • ReduxActionTypes (1282-1325)
app/client/src/utils/ReducerUtils.ts (1)
  • createImmerReducer (23-52)
app/client/src/layoutSystems/CanvasFactory.tsx (2)
app/client/src/selectors/editorSelectors.tsx (1)
  • getRenderMode (233-237)
app/client/src/ce/selectors/applicationSelectors.tsx (1)
  • getAppThemeSettings (196-200)
app/client/src/widgets/withWidgetProps.tsx (1)
app/client/src/selectors/editorSelectors.tsx (1)
  • getRenderMode (233-237)
⏰ 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-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (19)
app/client/src/selectors/editorSelectors.tsx (1)

28-28: Import path updated to reference the enterprise edition module.

The import for MainCanvasReduxState has been updated to use the enterprise edition path. This aligns with the broader refactoring where the canvas reducer was moved from CE to EE.

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

129-129: Import path updated for enterprise edition consistency.

The import for MainCanvasReduxState now correctly points to the enterprise edition reducer, maintaining consistency with the architectural refactoring.

app/client/src/sagas/CanvasSagas/DraggingCanvasSagas.ts (1)

29-29: Import path updated for mainCanvasReducer type.

Updated the import path for MainCanvasReduxState to use the enterprise edition module, consistent with other import path updates in the codebase.

app/client/src/pages/AppIDE/components/WidgetAdd/WidgetsList.tsx (2)

8-8: Added import for empty message constant.

Added the WIDGET_PANEL_EMPTY_MESSAGE constant import to support customizing the empty state message.


21-21: Added customizable empty message to UI sidebar.

Added the emptyMessage prop to the UIEntitySidebar component, improving the user experience by providing a contextual message when no widgets match the search criteria.

app/client/src/sagas/AutoLayoutUpdateSagas.tsx (1)

41-41: Import path correctly updated to reflect architectural changes.

The import path for MainCanvasReduxState now points to the enterprise edition module, consistent with the architectural improvements mentioned in the PR objectives.

app/client/src/ce/reducers/uiReducers/index.tsx (1)

36-36: Import path updated correctly for architectural consistency.

The import path for mainCanvasReducer has been properly updated to use the enterprise edition module, aligning with the architectural refactoring described in the PR objectives.

app/client/src/ce/reducers/index.tsx (1)

51-51: Import path correctly updated for architectural consistency.

The import path for MainCanvasReduxState now references the enterprise edition module, maintaining consistency with the architectural changes in this PR.

app/client/src/ee/reducers/uiReducers/mainCanvasReducer.ts (1)

1-3: LGTM: Clean proxy implementation for mainCanvasReducer

The implementation correctly re-exports all exports from the CE module and the default export with a clear alias. This supports the architectural migration from CE to EE structure while maintaining backward compatibility.

app/client/src/layoutSystems/CanvasFactory.tsx (1)

19-30: Implementation of render mode override looks good

The change properly allows for conditional override of the render mode, which helps address the widget behavior inconsistencies in edit mode. The detailed comments explain the rationale behind this change and potential future improvements.

app/client/src/widgets/withWidgetProps.tsx (1)

85-93: Consistent implementation of render mode override

This change mirrors the implementation in CanvasFactory.tsx, providing a consistent pattern for overriding render mode. The comments clearly explain the purpose and context.

app/client/src/pages/Editor/widgetSidebar/UIEntitySidebar.tsx (3)

22-22: Added customizable empty message property

Adding the optional emptyMessage prop to the interface enhances component flexibility and reusability.


27-27: Correctly added emptyMessage to component parameters

The component parameter list has been properly updated to include the new prop.


134-134: Implemented custom empty message display

The implementation correctly uses the provided emptyMessage prop, concatenated with the current search value, for a more customizable user experience.

app/client/src/ce/reducers/uiReducers/mainCanvasReducer.ts (5)

10-10: Good addition of the klona library for deep cloning.

The klona package is a lightweight and efficient deep cloning utility that's perfect for the use case below.


12-17: Proper export of initialState.

Exporting the initialState is a good practice for maintainability and testability, especially since you're moving the reducer to EE.


19-45: Well-structured extraction of handlers.

Extracting handlers into a separate exported object improves modularity and makes the code more maintainable. This approach will allow for better testing and potential extension in the EE version.

🧰 Tools
🪛 Biome (1.9.4)

[error] 27-28: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


47-47: Clean reducer implementation.

The refactored reducer creation is concise and follows best practices by clearly separating the initial state and handlers.


42-44:

❓ Verification inconclusive

Good implementation of reset functionality.

The reset handler provides a clean way to restore the initial state. Using klona ensures a proper deep copy without reference issues.

One consideration: verify that all consuming components handle this reset properly, especially if they depend on specific canvas state.


🏁 Script executed:

#!/bin/bash
# Search for components that might be affected by canvas reset
echo "Searching for components that consume mainCanvasReducer state..."
rg -l "useSelector.*(\s*state\s*=>\s*state\.entities\.canvas|\s*selectMainCanvasProps|MainCanvasReduxState)" --type ts --type tsx

Length of output: 298


🏁 Script executed:

#!/bin/bash
# Searching for components that consume mainCanvasReducer state across .ts and .tsx files
echo "Searching for useSelector patterns and selectors..."
rg -l "useSelector.*\bstate\s*=>\s*state\.entities\.canvas" -g "*.ts" -g "*.tsx"
rg -l "selectMainCanvasProps" -g "*.ts" -g "*.tsx"
rg -l "MainCanvasReduxState" -g "*.ts" -g "*.tsx"

Length of output: 622


🏁 Script executed:

#!/bin/bash
# 1. Determine where mainCanvasReducer is mounted in the root reducer
echo "Locating combineReducers in root reducer..."
rg -n -C2 "combineReducers" -g "app/client/src/ce/reducers/index.tsx"

# 2. Search for any useSelector calls that reference 'canvas' in TS/TSX files
echo "Searching for useSelector patterns referencing 'canvas'..."
rg -n "useSelector.*canvas" -g "*.ts" -g "*.tsx"

Length of output: 348


Verify canvas reset integration in root reducer and sagas

Good implementation of reset functionality using klona to deep‑copy initialState.

Before approving, please manually confirm:

  • Root reducer mounting
    Ensure mainCanvasReducer is combined under the correct key (e.g. entities.canvas) in
    app/client/src/ce/reducers/index.tsx

  • Saga handlers and selectors
    Sagas and selectors that reference MainCanvasReduxState may assume a populated canvas. After reset they should handle the default shape without errors. Check in:
    app/client/src/sagas/AutoLayoutUpdateSagas.tsx
    app/client/src/sagas/WidgetDeletionSagas.ts
    app/client/src/sagas/CanvasSagas/DraggingCanvasSagas.ts
    app/client/src/ce/sagas/PageSagas.tsx
    app/client/src/selectors/editorSelectors.tsx

Comment on lines +332 to 334
} else {
groupedCards[tag] = [item];
}
Copy link
Contributor

@coderabbitai coderabbitai bot Apr 23, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug fix for handling non-predefined widget tags.

This change correctly handles the case where a widget has tags that aren't predefined in the WIDGET_TAGS constant, ensuring all tags are properly processed regardless of whether they're in the predefined list.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What is the issue?

Copy link
Contributor

Choose a reason for hiding this comment

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

@ashit-rath The issue is in the groupWidgetCardsByTags function. Before this fix, if a widget had a tag that wasn't predefined in WIDGET_TAGS, the code would ignore that tag without creating an entry for it in groupedCards.

Consider a scenario where a widget has a custom tag "newFeature" that isn't in WIDGET_TAGS. Without the fix, groupedCards["newFeature"] would remain undefined, potentially causing errors when accessing it elsewhere in the code.

The fix ensures that even non-predefined tags get properly initialized with an array containing the widget, preventing potential undefined access errors and making sure all tagged widgets are properly grouped regardless of whether their tags are predefined.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that's what we want

Copy link
Contributor

Choose a reason for hiding this comment

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

@ashit-rath Got it! Thanks for confirming that the change to handle non-predefined widget tags is intentional and desired.

@ashit-rath ashit-rath added the ok-to-test Required label for CI label Apr 23, 2025
@ashit-rath ashit-rath removed the request for review from a team April 23, 2025 05:44
@ashit-rath ashit-rath added Frontend This label marks the issue or pull request to reference client code Packages Pod issues that belong to the packages pod UI module Issues affecting UI modules or its instances Packages & Git Pod All issues belonging to Packages and Git labels Apr 23, 2025
@ashit-rath ashit-rath merged commit 76b1ff1 into release Apr 26, 2025
96 of 98 checks passed
@ashit-rath ashit-rath deleted the chore/ui-mod-test-party-fixes-2-ce branch April 26, 2025 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Frontend This label marks the issue or pull request to reference client code ok-to-test Required label for CI Packages & Git Pod All issues belonging to Packages and Git Packages Pod issues that belong to the packages pod skip-changelog Adding this label to a PR prevents it from being listed in the changelog UI module Issues affecting UI modules or its instances
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants