Skip to content

refactor: migrate the Control story to TypeScript - #821

Merged
tbouffard merged 3 commits into
mainfrom
refactor/migrate_Control_story_to_ts
May 9, 2025
Merged

refactor: migrate the Control story to TypeScript#821
tbouffard merged 3 commits into
mainfrom
refactor/migrate_Control_story_to_ts

Conversation

@tbouffard

@tbouffard tbouffard commented May 8, 2025

Copy link
Copy Markdown
Member

Ease the maintenance and detect the errors earlier.

Extra improvements:

  • Disable the context menu to make the panning correctly work
  • Add a "reset zoom" button
  • Add more cells to better illustrate the feature
  • Add a Storybook argument to enable Graph.resizeContainer that was previously commented
  • Add documentation

Summary by CodeRabbit

  • New Features

    • Added a new interactive story demonstrating controls for deleting vertices within a graph, including UI buttons for zoom and reset actions.
  • Documentation

    • Introduced a new Storybook documentation page explaining and showcasing the graph controls feature.
  • Refactor

    • Improved story structure with enhanced typing, plugin-based graph initialization, and expanded example content.

Ease the maintenance and detect the errors earlier.

Extra improvements:
- Disable the context menu to make the panning correctly work
- Add a "reset zoom" button
- Add more cells to better illustrate the feature
- Add a Storybook argument to enable Graph.resizeContainer that was previously commented
- Add documentation
@tbouffard tbouffard added the refactor Code refactoring label May 8, 2025
@coderabbitai

coderabbitai Bot commented May 8, 2025

Copy link
Copy Markdown

Walkthrough

A new Storybook MDX story (Control.mdx) and its corresponding story implementation (Control.stories.ts) were added to demonstrate interactive controls within a graph, such as deleting vertices. The implementation introduces custom graph and cell renderer classes, enhanced typing, plugin-based initialization, and expanded UI controls. An existing MDX file was also updated to clean up unused imports.

Changes

File(s) Change Summary
packages/html/stories/Boundary.mdx Removed unused imports ArgTypes and Story from @storybook/blocks, retaining only necessary imports (Canvas, Controls, Meta).
packages/html/stories/Control.mdx Added a new Storybook MDX file that documents and demonstrates adding controls to graph cells. It imports story definitions and sets up the story metadata, description, and interactive canvas and controls.
packages/html/stories/Control.stories.ts Added a new story with reorganized and expanded imports, stronger TypeScript typings, a custom cell renderer and graph class, plugin-based graph initialization, expanded graph content and edges, additional control options (context menu toggle, container resizing), and extra UI buttons including "Reset Zoom." The story demonstrates interactive controls such as deleting vertices and improved configuration flexibility.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Storybook
    participant MyCustomGraph
    participant MyCustomCellRenderer

    User->>Storybook: Opens Control story
    Storybook->>MyCustomGraph: Initialize with container and plugins
    MyCustomGraph->>MyCustomCellRenderer: createCellRenderer()
    MyCustomGraph->>MyCustomCellRenderer: Render cells with controls
    User->>MyCustomCellRenderer: Clicks delete control on vertex
    MyCustomCellRenderer->>MyCustomGraph: Remove vertex from graph
    User->>Storybook: Uses UI buttons (Zoom In/Out, Reset Zoom)
    Storybook->>MyCustomGraph: Adjust graph view accordingly
Loading

Possibly related PRs

Suggested labels

documentation

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3056c25 and 9f38877.

📒 Files selected for processing (1)
  • packages/html/stories/Control.stories.ts (6 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/html/stories/Control.stories.ts (3)
packages/core/src/types.ts (1)
  • GraphPluginConstructor (1172-1175)
packages/core/src/view/plugins/index.ts (1)
  • getDefaultPlugins (46-55)
packages/html/stories/Layers.stories.js (1)
  • v3 (63-63)
🔇 Additional comments (15)
packages/html/stories/Control.stories.ts (15)

18-31: Good job on enhancing the imports with proper TypeScript typings.

The import statements now include essential types and utilities from '@maxgraph/core' that support the TypeScript migration. The addition of CellState, GraphPluginConstructor, and Shape types ensures proper type checking for the custom cell renderer and graph implementations.


32-39: Good addition of context menu configuration.

Adding the context menu types and values from the shared args file aligns well with the PR objective of ensuring proper panning functionality by controlling context menu behavior.


46-54: Well-structured Storybook configuration with new resizeContainer option.

The story configuration now includes the resizeContainer option, which supports the PR objective of enabling the previously commented Graph.resizeContainer functionality. The use of a boolean type with defaultValue: false is appropriate here.


55-60: Consistent default args setup.

The args configuration properly initializes all required arguments including the new resizeContainer option set to false by default, which aligns with the PR objective of making this feature opt-in.


63-63: Good type definition with proper extension.

The CustomCellState type properly extends CellState to include the deleteControl property, which is essential for type safety in the custom cell renderer. The use of null as a possible value correctly handles the case when no control exists.


65-70: Well-implemented context menu control.

The Template function now properly disables the context menu when the contextMenu argument is false, which directly addresses one of the PR objectives to ensure proper panning functionality. The use of InternalEvent.disableContextMenu is the correct approach.


76-99: Well-typed override of createControl method with proper null checks.

The createControl method now uses TypeScript's override keyword and includes proper type annotations for the state parameter. The null check on state.deleteControl before creation is a good practice to avoid duplicate controls.


102-119: Well-implemented helper method with null safety.

The private getDeleteControlBounds helper method properly encapsulates the bounds calculation logic and includes appropriate null checks. The non-null assertion on bounds is necessary here since the null check is done at the beginning of the method.


122-138: Good type-safety in redrawControl override.

The redrawControl method properly handles the type safety with the CustomCellState type and includes null checks before accessing deleteControl properties. The non-null assertion on bounds is appropriate here as it's checked within the condition.


141-148: Proper cleanup in destroy method.

The destroy method correctly handles the cleanup of the deleteControl by destroying it and setting it to null. This prevents memory leaks and ensures proper disposal of resources.


151-159: Well-structured custom graph class with plugin support.

The MyCustomGraph class now properly accepts plugins as a constructor parameter and passes them to the parent class. The override of createCellRenderer is correctly implemented to return the custom cell renderer instance.


162-166: Good implementation of plugin-based initialization.

The graph initialization now uses the plugin system with getDefaultPlugins() and conditionally adds the RubberBandHandler based on the rubberBand argument. This approach makes the code more modular and maintainable.


169-171: Well-implemented resizeContainer feature.

The code now correctly sets the resizeContainer property based on the argument, which directly implements one of the PR objectives to enable this previously commented functionality.


189-217: Great enhancement of the graph with additional cells and styles.

The addition of more vertices and edges with specific styles provides a richer demonstration of the graph capabilities, which aligns with the PR objective of adding more cells to better illustrate the feature.


234-238: Good addition of the Reset Zoom button.

The Reset Zoom button is a valuable enhancement that addresses one of the PR objectives to provide better user control. The implementation correctly uses graph.zoomActual() for the reset functionality.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @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.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 comments (2)
packages/html/stories/Control.stories.ts (2)

75-96: 🛠️ Refactor suggestion

Avoid narrowing the parameter type in overridden methods

CellRenderer.createControl expects a CellState.
By overriding it with createControl(state: CustomCellState) you’re narrowing the accepted type, which breaks the Liskov Substitution Principle and will fail to compile if --exactOptionalPropertyTypes or stricter variance checks are enabled in the consuming project.

Change the signature to accept the original super-type and down-cast internally:

-override createControl(state: CustomCellState) {
+override createControl(state: CellState) {
+  const customState = state as CustomCellState;
   super.createControl(state);
-  const { graph } = state.view;
+  const { graph } = customState.view;

121-136: ⚠️ Potential issue

Possible null dereference when comparing bounds

getDeleteControlBounds may return null, yet bounds!.equals(...) is called unconditionally, which will throw at runtime.

-const bounds = this.getDeleteControlBounds(state);
-if (
-  state.deleteControl.scale !== s ||
-  !state.deleteControl.bounds!.equals(bounds)
-) {
+const bounds = this.getDeleteControlBounds(state);
+if (
+  bounds &&                                           // ✅ guard
+  (state.deleteControl.scale !== s ||
+   !state.deleteControl.bounds!.equals(bounds))
+) {
   state.deleteControl.bounds = bounds;
   state.deleteControl.scale = s;
   state.deleteControl.redraw();
 }
🧹 Nitpick comments (3)
packages/html/stories/Control.mdx (1)

1-15: Minor MDX nit – add a trailing empty line

Storybook occasionally complains when an MDX document doesn’t end with a newline (depends on editor settings and OS).

@@
-<Controls />
+<Controls />
+
packages/html/stories/Control.stories.ts (2)

161-164: Don’t mutate the array returned by getDefaultPlugins

getDefaultPlugins() may decide to cache and reuse its array in the future.
Instead of mutating it with push, create a shallow copy before extending:

-const plugins = getDefaultPlugins();
-if (args.rubberBand) plugins.push(RubberBandHandler);
+const plugins = [
+  ...getDefaultPlugins(),
+  ...(args.rubberBand ? [RubberBandHandler] : []),
+];

65-65: Unused destructured property

label is destructured from the args but never used, producing a lint warning.

-const Template = ({ label, ...args }: Record<string, any>) => {
+const Template = ({ /* label */, ...args }: Record<string, any>) => {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c0c4c41 and 3056c25.

📒 Files selected for processing (3)
  • packages/html/stories/Boundary.mdx (1 hunks)
  • packages/html/stories/Control.mdx (1 hunks)
  • packages/html/stories/Control.stories.ts (6 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/html/stories/Control.stories.ts (3)
packages/core/src/types.ts (1)
  • GraphPluginConstructor (1172-1175)
packages/core/src/view/plugins/index.ts (1)
  • getDefaultPlugins (46-55)
packages/html/stories/Layers.stories.js (1)
  • v3 (63-63)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (windows-2022)
  • GitHub Check: build (macos-14)
  • GitHub Check: build
🔇 Additional comments (1)
packages/html/stories/Boundary.mdx (1)

1-1: Import clean-up looks good

Removing the unused ArgTypes and Story imports keeps the file lean and avoids false-positive linter warnings.

@sonarqubecloud

sonarqubecloud Bot commented May 8, 2025

Copy link
Copy Markdown

@tbouffard
tbouffard merged commit 0728231 into main May 9, 2025
@tbouffard
tbouffard deleted the refactor/migrate_Control_story_to_ts branch May 9, 2025 05:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Code refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant