Skip to content

feat: Right Sidebar Menu and Layout Settings#804

Merged
hexqi merged 3 commits intoopentiny:ospp-2024/002-plugin-layoutfrom
STATICHIT:cj-action-menu
Sep 26, 2024
Merged

feat: Right Sidebar Menu and Layout Settings#804
hexqi merged 3 commits intoopentiny:ospp-2024/002-plugin-layoutfrom
STATICHIT:cj-action-menu

Conversation

@STATICHIT
Copy link

@STATICHIT STATICHIT commented Sep 19, 2024

English | 简体中文

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • Built its own designer, fully self-validated

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

Background and solution

feat: Right Sidebar Menu and Layout Settings

  1. 实现右键菜单及其方法
    a.右击插件:支持隐藏当前插件/切换插件位置到另一侧/切换当前侧所有插件显示状态/隐藏当前侧活动栏
    b.右键空白区域:切换当前侧所有插件显示状态/隐藏当前侧活动栏
  2. 布局设置菜单及其方法
    a.切换活动栏显示状态
  3. 实现插件和活动栏显示状态持久化
  4. 封装右键菜单组件

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced dynamic visibility management for left and right menus.
    • Added context menu functionality for plugins and settings, allowing users to hide or switch alignment.
    • Enhanced toolbar with a new "Publish Application" menu item and improved submenu interactions.
    • Implemented a new context menu component for managing plugin actions.
  • Improvements

    • Improved user interface responsiveness with conditional rendering based on menu visibility.
    • Enhanced plugin management with new retrieval options based on unique identifiers.
  • Style

    • Updated styling for the help plugin to ensure it appears above other elements.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 19, 2024

Walkthrough

The changes introduced in this pull request enhance the layout management capabilities of the application by adding functionality for managing the visibility of menus and plugins. New properties and methods for tracking and toggling visibility states are implemented across various components, including context menus for improved user interaction. Additionally, styling adjustments and state management improvements ensure that the layout reflects user preferences dynamically.

Changes

File Change Summary
packages/controller/src/useLayout.js Added new properties and functions for managing menu visibility and plugin states.
packages/design-core/config/plugin.js Introduced getPluginById function for retrieving plugins by their unique identifier.
packages/design-core/src/App.vue Implemented conditional rendering for components based on menu visibility; added alignment methods.
packages/design-core/src/DesignPlugins.vue Added context menu for plugin items to enhance user interaction.
packages/design-core/src/DesignSettings.vue Introduced context menu functionality for the plugin list with new reactive properties.
packages/design-core/src/RightMenu.vue Implemented a new context menu component for managing plugin actions.
packages/plugins/help/src/HelpIcon.vue Added a CSS rule to adjust the z-index for the help plugin component.
packages/toolbars/logo/src/Main.vue Enhanced toolbar interactivity with new menu structures and submenu visibility controls.

Possibly related PRs

Poem

In the meadow where the plugins play,
Menus toggle, bright as day.
With a hop and a skip, they come alive,
Dynamic layouts help us thrive!
So let’s cheer for changes, oh so grand,
A happy rabbit's joyful stand! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

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

@github-actions github-actions bot added enhancement New feature or request ospp ospp labels Sep 19, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Outside diff range and nitpick comments (6)
packages/design-core/src/DesignSettings.vue (3)

204-204: Translate inline comments for consistency

The inline comment is in Chinese. Translating it to English will maintain consistency and improve readability for all contributors.

Apply this diff to translate the comment:

-const activating = computed(() => settingsState.activating) //高亮显示
+const activating = computed(() => settingsState.activating) // Highlight display

197-202: Consider using Vue's event handling for clicks outside

Instead of manually adding event listeners to the document, use Vue's built-in directives or external libraries like v-click-outside to handle clicks outside the component. This makes the code cleaner and ensures proper unbinding of events.

Example using v-click-outside directive:

+import vClickOutside from 'v-click-outside'

 export default {
+ directives: {
+   clickOutside: vClickOutside.directive
+ },
  // ...
}

And in your template:

 <div
   // other attributes
-  // manually handling clicks
-  @click="handleClickOutside"
+  v-click-outside="hideContextMenu"
 >
   <!-- context menu content -->
 </div>

Alternatively, you can use Vue's native <div @click.self="hideContextMenu"> if applicable.


403-441: Ensure styles are scoped or use unique class names

The styles added for the context menu and related classes may affect other components if not scoped. Consider adding the scoped attribute to the <style> tag or use more specific class names to prevent CSS leakage.

Apply this diff to scope the styles:

-<style lang="less" scoped>
+<style lang="less" scoped>
 // existing styles
 </style>

If the styles are already intended to be scoped, ensure the scoped attribute is present.

packages/design-core/src/DesignPlugins.vue (3)

53-53: Consistency in Event Modifiers

In the @contextmenu.prevent="showContextMenu($event, true, item, index, PLUGIN_POSITION.leftBottom)" directive, you use .prevent. Ensure that all similar event handlers consistently use event modifiers where appropriate for consistency and to prevent default browser behavior.


185-185: Emit Event Documentation

You've added changeLeftAlign to the emits array. Ensure that this new event is documented so that other developers understand its purpose and usage.


296-298: Event Listener Optimization

In handleClickOutside, using event.target.closest('.context-menu') may not work as expected if the event originates from within a shadow DOM or if the structure changes.

Consider adding a ref to the context menu and using that for a more reliable check.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 970eb76 and 1ad2ec6.

Files selected for processing (7)
  • packages/controller/src/useLayout.js (4 hunks)
  • packages/design-core/config/plugin.js (1 hunks)
  • packages/design-core/src/App.vue (3 hunks)
  • packages/design-core/src/DesignPlugins.vue (9 hunks)
  • packages/design-core/src/DesignSettings.vue (6 hunks)
  • packages/plugins/help/src/HelpIcon.vue (1 hunks)
  • packages/toolbars/logo/src/Main.vue (7 hunks)
Files skipped from review due to trivial changes (1)
  • packages/plugins/help/src/HelpIcon.vue
Additional comments not posted (13)
packages/design-core/config/plugin.js (1)

11-13: LGTM!

The getPluginById function is a great addition to the plugin management system. It provides a convenient way to retrieve plugins by their unique identifier, complementing the existing getPlugin function.

The implementation is efficient and handles the case when no matching plugin is found by returning null.

Overall, this change improves the flexibility and usability of the plugin system without introducing any breaking changes.

packages/design-core/src/App.vue (6)

8-14: LGTM!

The conditional rendering of the design-plugins component based on leftMenuShownStorage enhances the user interface by dynamically controlling its visibility. The ref attribute and emitted events enable interaction and alignment changes with other components.


21-22: LGTM!

The conditional rendering of the design-settings component based on rightMenuShownStorage enhances the user interface by dynamically controlling its visibility. The ref attribute enables interaction and alignment changes with other components.


25-25: LGTM!

The emitted event for alignment changes enables interaction and facilitates communication between components.


110-111: LGTM!

The addition of the index and isShow properties to the plugin object enables ordering the plugins based on their alignment and controlling their visibility.


117-127: LGTM!

The destructured properties from useLayout() provide access to the layout state and menu visibility states, enabling management of the overall layout and visibility of components. The left and right refs, along with the changeLeftAlign and changeRightAlign methods, facilitate interaction and synchronization between the left and right components.


192-203: LGTM!

The returned properties from the setup function enable interaction and synchronization between components. The left and right refs, layoutState, designSmbConfig, changeLeftAlign, changeRightAlign, leftMenuShownStorage, and rightMenuShownStorage provide access to the necessary data and methods for managing the layout, visibility, and alignment of components.

packages/controller/src/useLayout.js (6)

65-65: LGTM!

The addition of the isShow property to the plugins section of the layoutState object is a good way to track the visibility state of the plugins menu. Setting the default value to true ensures that the plugins menu is visible by default.


73-73: LGTM!

Similar to the plugins section, the addition of the isShow property to the settings section of the layoutState object is a good way to track the visibility state of the settings menu. Setting the default value to true ensures that the settings menu is visible by default.


85-98: LGTM!

The introduction of the leftMenuShownStorage and rightMenuShownStorage storage hooks using the useStorage function is a good approach to persist the visibility state of the left and right menus. The changeMenuShown function provides a convenient way to toggle the visibility of the menus dynamically based on the provided menuName argument. The switch statement handles the toggling logic effectively.


277-283: LGTM!

The addition of the getPluginShown and changePluginShown functions is a good way to manage the visibility of plugins. getPluginShown allows querying the visibility state of a specific plugin, while changePluginShown provides a convenient way to toggle the visibility state. These functions enhance the control over plugin visibility by interacting with the pluginStorageReactive object.


304-305: LGTM!

Adding the leftMenuShownStorage and rightMenuShownStorage variables to the exported object is a good way to make them accessible for use in other parts of the application. This allows other modules to access and potentially modify the visibility state of the left and right menus as needed.


312-316: LGTM!

Adding the isSameSide, getPluginShown, changePluginShown, and changeMenuShown functions to the exported object is a good way to make them accessible for use in other parts of the application. This allows other modules to utilize these functions for various purposes related to plugin and menu visibility management, enhancing the overall functionality and flexibility of the layout management system.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
packages/toolbars/logo/src/Main.vue (1)

11-13: Simplify the conditional expression for better readability.

Consider simplifying the conditional expression !(getGlobalConfig()?.dslMode === 'Angular') to getGlobalConfig()?.dslMode !== 'Angular' for improved clarity.

Apply this diff to enhance readability:

-<li v-if="!(getGlobalConfig()?.dslMode === 'Angular')" @click="handleClick({ code: 'publishApp' })">
+<li v-if="getGlobalConfig()?.dslMode !== 'Angular'" @click="handleClick({ code: 'publishApp' })">
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1ad2ec6 and 75c7207.

Files selected for processing (2)
  • packages/design-core/src/DesignPlugins.vue (9 hunks)
  • packages/toolbars/logo/src/Main.vue (6 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/design-core/src/DesignPlugins.vue
Additional comments not posted (5)
packages/toolbars/logo/src/Main.vue (5)

16-16: ** Correct the component usage in the template.**

As mentioned in the previous review, the component IconRight is imported and instantiated in the script but incorrectly used as <icon-right> in the template. In Vue with <script setup>, you should use the PascalCase variable name directly in the template.

Apply this diff to fix the component reference:

-  <icon-right></icon-right>
+  <IconRight></IconRight>

171-183: LGTM!

The watchers for leftMenuShownStorage and rightMenuShownStorage correctly update the isShow property of the corresponding submenu items based on the storage values. This ensures that the submenu visibility stays in sync with the user's preferences.


191-194: LGTM!

The changeShowState function correctly toggles the isShow property of the provided item and calls the changeMenuShown function with the item.code to update the corresponding storage value. This ensures that the submenu visibility is properly updated when the user interacts with the menu.


329-329: LGTM!

Setting state.showSubMenu to false within the handleCloseMenu function ensures that the submenu is properly closed when the main menu is closed due to a click event outside the menu. This maintains consistency in the menu behavior.


166-169: ** Initialize subMenus with reactive stored values.**

As mentioned in the previous review, subMenus is currently initialized with hardcoded isShow values set to true. To ensure consistency with the user's preferences stored in leftMenuShownStorage and rightMenuShownStorage, initialize isShow based on these reactive storage values.

Apply this diff to synchronize initial states:

 const subMenus = ref([
-  { name: '左侧活动栏', code: 'left', isShow: true },
-  { name: '右侧活动栏', code: 'right', isShow: true }
+  { name: '左侧活动栏', code: 'left', isShow: leftMenuShownStorage.value },
+  { name: '右侧活动栏', code: 'right', isShow: rightMenuShownStorage.value }
 ])

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
packages/design-core/src/RightMenu.vue (2)

1-27: LGTM! Well-structured template with proper conditional rendering.

The template is well-organized and makes good use of Vue directives for conditional rendering and list iteration. The dynamic positioning and different types of menu items are handled effectively.

Consider adding ARIA attributes for improved accessibility.

To enhance accessibility, consider adding appropriate ARIA attributes to the menu and its items. For example:

-  <ul
+  <ul
+    role="menu"
+    aria-label="Context Menu"
   v-if="contextMenu.visible"
   class="context-menu"
   :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
 >
-    <li v-if="contextMenu.type" @click="hidePlugin">隐藏 "{{ contextMenu.item.title }}"</li>
+    <li v-if="contextMenu.type" @click="hidePlugin" role="menuitem">隐藏 "{{ contextMenu.item.title }}"</li>

127-167: Good use of scoped styling for component-specific CSS.

The use of scoped styling prevents unintended style leaks and keeps the component's styles isolated. The styles effectively define the appearance and behavior of the context menu.

Clarify the comment about importing styles.

The comment "引入B的CSS样式" (Import B's CSS style) is unclear and may cause confusion. Consider removing it if it's not relevant, or provide more context if it is.

Consider optimizing and consolidating styles.

Some styles could be optimized for better maintainability:

  1. Use CSS variables for repeated values like colors and sizes.
  2. Consolidate repeated styles, for example:
.context-menu li,
.context-menu-header {
  padding: 8px 12px;
}

.context-menu-header,
.bottom-li {
  border-bottom: 1px solid #ccc;
}
  1. Consider using shorthand properties where applicable, e.g., box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 75c7207 and 06e35ea.

📒 Files selected for processing (3)
  • packages/design-core/src/DesignPlugins.vue (7 hunks)
  • packages/design-core/src/DesignSettings.vue (4 hunks)
  • packages/design-core/src/RightMenu.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/design-core/src/DesignPlugins.vue
🔇 Additional comments not posted (12)
packages/design-core/src/RightMenu.vue (2)

1-167: Overall, well-implemented Vue.js component with minor suggestions for improvement.

This new RightMenu.vue component is generally well-structured and follows Vue.js best practices, making good use of the Composition API. The component effectively implements a context menu with dynamic content and positioning. Here's a summary of the main points for improvement:

  1. Enhance accessibility by adding ARIA attributes to the menu elements.
  2. Strengthen prop validation for better error handling and documentation.
  3. Verify and ensure proper sanitization of dynamic content to prevent potential XSS vulnerabilities.
  4. Optimize and consolidate CSS styles for improved maintainability.
  5. Clarify or remove the ambiguous comment about importing styles.

Addressing these points will further improve the component's robustness, accessibility, and maintainability.


29-125: Well-structured script using Composition API.

The script section makes good use of the Composition API, with clear separation of concerns and well-defined methods. The use of lifecycle hooks for event listener management is appropriate.

Consider adding more detailed prop validation.

While prop types are defined, consider adding more detailed validation for better error handling and documentation.

For example:

props: {
  list: {
    type: Array,
    required: true,
    validator: (value) => value.every(item => 'id' in item && 'title' in item)
  },
  align: {
    type: String,
    default: 'left',
    validator: (value) => ['left', 'right'].includes(value)
  }
}

Potential security concern: Use of innerHTML

While not visible in the provided script, if innerHTML is used in the template to render dynamic content (e.g., item.title), it could pose a security risk. Ensure that all dynamic content is properly sanitized before rendering.

To check for potential use of v-html or innerHTML, run the following command:

packages/design-core/src/DesignSettings.vue (10)

29-30: LGTM: Enhanced user interaction with click and context menu events.

The addition of click and context menu event handlers improves user interaction with the plugin list items. The showContextMenu method will be reviewed in the script section to ensure proper implementation.


32-36: LGTM: Improved visual representation of plugin visibility.

The conditional rendering of item icons based on the getPluginShown method enhances the user interface by visually indicating which plugins are currently shown. We'll review the getPluginShown method in the script section to ensure proper implementation.


37-37: Clarify the purpose of the empty div with context menu.

An empty div with flex: 1 and a context menu event handler has been added. Could you please clarify the purpose of this element? It seems to be a placeholder area that still responds to context menu events, but its exact function is not immediately clear.


41-46: LGTM: Added right-menu component for context menu functionality.

The addition of the right-menu component enhances the user interface by providing context menu functionality. The switchAlign event handler will be reviewed in the script section to ensure proper implementation.


54-65: LGTM: Added necessary imports and components for new functionality.

The addition of new imports and components, particularly VueDraggableNext and RightMenu, supports the enhanced functionality of the component.

Please ensure that the drag-and-drop functionality implemented with VueDraggableNext works as expected across different browsers and devices.


72-72: LGTM: Added emit for changeRightAlign event.

The addition of the changeRightAlign emit enhances the component's ability to communicate changes in alignment to its parent component.


89-96: Review the showContextMenu method implementation.

The showContextMenu method seems to handle both general and item-specific context menus. Please ensure that:

  1. The method correctly differentiates between general and item-specific context menus.
  2. The positioning of the context menu is appropriate and doesn't cause issues on different screen sizes.
  3. The method handles edge cases, such as when the menu would appear off-screen.

Test the context menu functionality on various screen sizes and positions to ensure it always appears within the viewport.


117-121: Review the switchAlign method implementation.

The switchAlign method handles changing the alignment of plugins. Please ensure that:

  1. The removal and addition of plugins to the list are handled correctly.
  2. The emit event is called with the correct parameters.
  3. The dragPluginLayout function is called with the correct arguments.

Test the alignment switching functionality to ensure it works as expected and doesn't cause any unexpected side effects in the layout.


125-128: Review the changeAlign method implementation.

The changeAlign method adds a plugin to the beginning of the list. Please ensure that:

  1. The getPluginById function returns the expected plugin object.
  2. Adding the item to the beginning of the list is the intended behavior.
  3. This change doesn't cause any unexpected visual or functional issues in the UI.

Test the changeAlign functionality with various plugins to ensure it consistently works as expected.


169-175: LGTM: Updated return object with new methods and properties.

The return object has been updated to include the new methods and properties. This ensures that they are available in the template and for child components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ospp ospp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants