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

fix(ui): Navigation arrow logic node history added. #716

Closed
wants to merge 2 commits into from

Conversation

billcookie
Copy link
Contributor

@billcookie billcookie commented Dec 19, 2024

Overview

In the right panel for the parameter menu on a selected node the next and prev arrows did not

What I've done

  • Created a hook called useNodeHistory that handles this next/prev knowledge

What I haven't done

How I tested

manually

Screenshot

Which point I want you to review particularly

  • Possible refactors or any improvements.
  • Possibly moving the hook location into a different directory

Memo

Summary by CodeRabbit

  • New Features

    • Introduced a custom hook for managing node history in the canvas editor.
    • Enhanced the ParamEditor component with navigation buttons for node history.
    • Integrated node history management into the RightPanel component.
  • Bug Fixes

    • Updated navigation logic to prevent errors when navigating out of bounds in node history.
  • Documentation

    • Updated prop types to include new properties for better clarity and functionality.

Copy link
Contributor

coderabbitai bot commented Dec 19, 2024

Walkthrough

This pull request introduces a new custom React hook useNodeHistory to manage node history navigation in a canvas editor. The changes span multiple components, including RightPanel, ParamEditor, and Editor. The hook allows users to navigate through previously selected nodes by maintaining a history state with an array of nodes and a current index. The implementation adds navigation buttons to the ParamEditor and updates the component props to support this new functionality.

Changes

File Change Summary
ui/src/features/Editor/components/Canvas/useNodeHistory.ts New custom hook to manage node history navigation
ui/src/features/Editor/components/RightPanel/components/ParamEditor/index.tsx Added navigation props and buttons for node history
ui/src/features/Editor/components/RightPanel/index.tsx Integrated useNodeHistory hook, updated component logic
ui/src/features/Editor/index.tsx Added nodes prop to RightPanel component

Sequence Diagram

sequenceDiagram
    participant User
    participant ParamEditor
    participant RightPanel
    participant useNodeHistory

    User->>ParamEditor: Click Navigate Buttons
    ParamEditor->>RightPanel: Call onNavigateNodeHistory
    RightPanel->>useNodeHistory: Trigger handleNavigateNodeHistory
    useNodeHistory-->>RightPanel: Update Selected Node
    RightPanel-->>ParamEditor: Update Node History Position
    ParamEditor->>User: Render Updated Node
Loading

Possibly related PRs

Suggested reviewers

  • KaWaite

Poem

🐰 Hop through history, node by node,
A rabbit's journey, a coding ode!
Prev and next, with buttons so bright,
Navigating nodes with pure delight!
Code flows smooth, no bounds too tight! 🚀


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

Documentation and Community

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

Copy link

netlify bot commented Dec 19, 2024

Deploy Preview for reearth-flow ready!

Name Link
🔨 Latest commit 87657f1
🔍 Latest deploy log https://app.netlify.com/sites/reearth-flow/deploys/676509e2cae31b0008ca39df
😎 Deploy Preview https://deploy-preview-716--reearth-flow.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@billcookie billcookie marked this pull request as ready for review December 19, 2024 07:20
@billcookie billcookie requested a review from KaWaite as a code owner December 19, 2024 07:20
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)
ui/src/features/Editor/components/Canvas/useNodeHistory.ts (1)

5-22: Types could be more strictly defined

The type definitions look good overall, but could benefit from some improvements:

  • The Node type is imported but its shape is unclear
  • any type in setSelectedNode could be more specific

Consider updating the types:

type NavigateNodeHistoryProps = {
  direction: "prev" | "next";
  history: HistoryState;  // Use HistoryState type instead of object literal
-  setSelectedNode: (node: Node) => void;
+  setSelectedNode: React.Dispatch<React.SetStateAction<Node | undefined>>;
};
ui/src/features/Editor/components/RightPanel/index.tsx (1)

Line range hint 26-40: Consider extracting click event dispatch logic

The click event dispatch logic for node unlocking is marked as "hacky" in the comments.

Consider extracting this into a utility function:

const dispatchPaneClick = () => {
  const paneElement = document.getElementsByClassName("react-flow__pane")[0];
  if (!paneElement) return;
  const clickEvent = new Event("click", { bubbles: true, cancelable: true });
  paneElement.dispatchEvent(clickEvent);
};
ui/src/features/Editor/components/RightPanel/components/ParamEditor/index.tsx (2)

15-19: Consider type improvements and add JSDoc documentation

The new props would benefit from better type definitions and documentation:

+/** Direction type for node history navigation */
+type NavigationDirection = "prev" | "next";
+
+/** Position state for node history navigation */
+type NodeHistoryPosition = {
+  canGoBack: boolean;
+  canGoForward: boolean;
+};
+
 type Props = {
   nodeId: string;
   nodeMeta: NodeData;
   nodeType: string;
   nodeParameters?: unknown; // TODO: define type
   onSubmit: (nodeId: string, data: any) => void;
-  onNavigateNodeHistory: (direction: "prev" | "next") => void;
+  /** Callback for navigating through node history */
+  onNavigateNodeHistory: (direction: NavigationDirection) => void;
-  nodeHistoryPosition: {
-    canGoBack: boolean;
-    canGoForward: boolean;
-  };
+  /** Current position state in node history */
+  nodeHistoryPosition: NodeHistoryPosition;
 };

44-56: Enhance accessibility and optimize performance

While the navigation implementation is functionally correct, consider these improvements:

+const ParamEditor: React.FC<Props> = memo(({
   nodeId,
   nodeMeta,
   onSubmit,
   onNavigateNodeHistory,
   nodeHistoryPosition,
 }) => {
+  const handlePrevClick = useCallback(() => onNavigateNodeHistory("prev"), [onNavigateNodeHistory]);
+  const handleNextClick = useCallback(() => onNavigateNodeHistory("next"), [onNavigateNodeHistory]);

   return (
     <div>
       <div className="mb-3 flex justify-between gap-4">
         <div className="flex gap-2">
           <IconButton
             className={actionButtonClasses}
             icon={<ArrowLeft />}
             tooltipText="Previous selection"
-            onClick={() => onNavigateNodeHistory("prev")}
+            onClick={handlePrevClick}
             disabled={!nodeHistoryPosition.canGoBack}
+            aria-label="Go to previous node"
           />
           <IconButton
             className={actionButtonClasses}
             icon={<ArrowRight />}
             tooltipText="Next selection"
-            onClick={() => onNavigateNodeHistory("next")}
+            onClick={handleNextClick}
             disabled={!nodeHistoryPosition.canGoForward}
+            aria-label="Go to next node"
           />
         </div>
       </div>

This improves:

  1. Accessibility with proper aria-labels
  2. Performance by memoizing event handlers
  3. Component re-render efficiency by wrapping the entire component in memo
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f53d08c and d4ebb12.

📒 Files selected for processing (4)
  • ui/src/features/Editor/components/Canvas/useNodeHistory.ts (1 hunks)
  • ui/src/features/Editor/components/RightPanel/components/ParamEditor/index.tsx (3 hunks)
  • ui/src/features/Editor/components/RightPanel/index.tsx (4 hunks)
  • ui/src/features/Editor/index.tsx (1 hunks)
🔇 Additional comments (7)
ui/src/features/Editor/components/Canvas/useNodeHistory.ts (2)

24-40: Navigation handler implementation is robust

The navigation logic correctly:

  • Handles direction-based index calculation
  • Performs bounds checking
  • Updates both history and selected node

49-73: Verify history cleanup logic

The history cleanup logic in useEffect looks correct but complex. Let's verify the implementation:

  1. Filters history to only include valid nodes
  2. Checks for duplicate entries
  3. Updates history state
✅ Verification successful

The executed scripts show that there are no similar patterns of history cleanup logic in the codebase. The history cleanup implementation in useNodeHistory.ts is unique and follows a clear pattern:

  1. Creates a Set of valid node IDs from current nodes
  2. Filters history to only include valid nodes
  3. Checks for duplicates before adding new entries
  4. Updates the history state with proper indices

The implementation is correct and follows best practices

  • The cleanup logic efficiently uses Set for O(1) lookups of valid nodes
  • Properly handles edge cases by checking for duplicates
  • Maintains history integrity by slicing at the current index when adding new entries
  • Memory efficient by removing invalid nodes that no longer exist
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar patterns of history cleanup in the codebase
rg -U "validNodeIds.*filter.*has.*id"

# Look for potential memory leaks in useEffect dependencies
ast-grep --pattern 'useEffect($$$, [$$$])'

Length of output: 35109

ui/src/features/Editor/index.tsx (1)

102-102: Prop addition looks correct

The nodes prop is correctly passed to RightPanel, enabling node history functionality.

ui/src/features/Editor/components/RightPanel/index.tsx (2)

71-79: Verify ParamEditor prop updates

The changes to ParamEditor props look correct, using the new selectedNode state.

✅ Verification successful

The verification is complete based on the shell script results. I'll generate the final response:

ParamEditor props are correctly typed and match usage

The provided props in the code match exactly with the ParamEditor component's type definition:

  • nodeId (string)
  • nodeMeta (NodeData)
  • nodeType (string)
  • onSubmit (callback)
  • onNavigateNodeHistory (direction callback)
  • nodeHistoryPosition (object with canGoBack/canGoForward)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check ParamEditor prop types
ast-grep --pattern 'type Props = {
  $$$
  onNavigateNodeHistory: $$$;
  nodeHistoryPosition: $$$;
  $$$
}'

Length of output: 1400


17-22: Hook integration looks good but verify prop types

The useNodeHistory hook is correctly integrated, but let's verify the prop types match.

✅ Verification successful

Let me analyze the prop types from the output. I can see that the useNodeHistory hook in Canvas/useNodeHistory.ts has matching prop types with the RightPanel component:

// useNodeHistory.ts
type Props = {
  selected?: Node;
  nodes: Node[];
};

// RightPanel/index.tsx
type Props = {
  selected?: Node;
  onParamsSubmit: (nodeId: string, data: any) => void;
  nodes: Node[];
};

Props match correctly with useNodeHistory hook

The prop types in RightPanel perfectly align with the requirements of useNodeHistory hook. The selected and nodes props are correctly typed and match the hook's interface, while onParamsSubmit is an additional prop specific to RightPanel's functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for consistent prop types across components
ast-grep --pattern 'type Props = {
  $$$
  nodes: Node[];
  $$$
}'

Length of output: 5763

ui/src/features/Editor/components/RightPanel/components/ParamEditor/index.tsx (2)

30-31: LGTM!

Props destructuring is clean and follows consistent patterns.


Line range hint 8-14: Consider improving type safety

There are two areas that could benefit from better type definitions:

  1. The nodeParameters prop has a TODO comment about defining its type
  2. The onSubmit callback uses any type for its data parameter

Let's check if we can find the correct types from usage:

Comment on lines +75 to +85
const memoizedNodeHistory = useCallback(
(direction: "prev" | "next") => {
handleNavigateNodeHistory({
direction,
history,
setHistory,
setSelectedNode,
});
},
[history],
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Memoization could be improved

The memoized callback only depends on history but uses setHistory and setSelectedNode inside.

Add missing dependencies to useCallback:

  const memoizedNodeHistory = useCallback(
    (direction: "prev" | "next") => {
      handleNavigateNodeHistory({
        direction,
        history,
        setHistory,
        setSelectedNode,
      });
    },
-    [history],
+    [history, setHistory, setSelectedNode],
  );
📝 Committable suggestion

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

Suggested change
const memoizedNodeHistory = useCallback(
(direction: "prev" | "next") => {
handleNavigateNodeHistory({
direction,
history,
setHistory,
setSelectedNode,
});
},
[history],
);
const memoizedNodeHistory = useCallback(
(direction: "prev" | "next") => {
handleNavigateNodeHistory({
direction,
history,
setHistory,
setSelectedNode,
});
},
[history, setHistory, setSelectedNode],
);

@billcookie billcookie closed this Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant