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

terminal multi-input for tab #1643

Merged
merged 4 commits into from
Jan 2, 2025
Merged

terminal multi-input for tab #1643

merged 4 commits into from
Jan 2, 2025

Conversation

sawka
Copy link
Member

@sawka sawka commented Dec 27, 2024

No description provided.

Copy link

coderabbitai bot commented Dec 27, 2024

Walkthrough

The pull request updates the Wave Terminal application to implement multi-input functionality for terminal blocks. It includes modifications across several files, with the roadmap reflecting the completion of the "Multi-Input between terminal blocks on the same tab" feature. Key changes involve the addition of a global state atom isTermMultiInput, new methods in the TermViewModel for managing multi-input operations, and updates to type definitions to accommodate these enhancements.

Specifically, new methods facilitate data transmission to multiple terminal instances, a global key binding is introduced to toggle multi-input mode, and the terminal view is enhanced to support this functionality. The overall changes provide a structured approach for users to interact with multiple terminal blocks simultaneously, thereby increasing the application's flexibility and usability.


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.

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.

Copy link

@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 (3)
frontend/app/view/term/term.tsx (2)

190-201: Toggle multi-input feature
The UI logic for a "Multi Input ON" button is straightforward. For better UX, consider adding a quick visual indicator or icon to make the feature state even clearer.


682-695: getAllBasicTermModels function
Solid approach to filter out non-basic terminals. If usage grows, consider caching results if performance is critical.

frontend/app/block/blockframe.tsx (1)

293-293: Consider providing a fallback for the title prop.
If elem.title is undefined or null, you might display a default value or omit the property entirely to avoid an empty tooltip in some browsers.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6de98ac and 7743dc2.

📒 Files selected for processing (7)
  • ROADMAP.md (1 hunks)
  • frontend/app/block/blockframe.tsx (1 hunks)
  • frontend/app/store/global.ts (3 hunks)
  • frontend/app/store/keymodel.ts (3 hunks)
  • frontend/app/view/term/term.tsx (9 hunks)
  • frontend/app/view/term/termwrap.ts (5 hunks)
  • frontend/types/custom.d.ts (3 hunks)
🔇 Additional comments (24)
frontend/app/view/term/term.tsx (9)

15-15: Import reassurance
No issues: this import statement is consistent with the usage below for retrieving block models.


28-28: Confirm each utility usage
Both boundNumber and stringToBase64 appear properly utilized.


133-133: Initialize header elements array
Good approach: an empty array is a clean starting point for building dynamic UI.


318-329: isBasicTerm method
The method concisely checks if the terminal is in a simple (non-vdom, non-cmd) state. No issues identified.


330-330: Blank line
No specific comment.


331-341: multiInputHandler method
The logic for forwarding data to all other terminals is clear and correct. Optional: add debug logging in case multi-input data distribution fails or to track usage.


343-346: sendDataToController method
Straightforward data encoding and sending. Consider catching errors in case the RPC call fails for any reason.


845-847: Consistency with isBasicTerm
Defining isBasicTerm directly in the component is good, but ensure it stays consistent with the method in TermViewModel.


913-924: React.useEffect for multi-input callback
Clear logic: sets up or clears the callback depending on focus and multi-input state. No issues found.

frontend/app/view/term/termwrap.ts (6)

43-43: Added optional sendDataHandler
Allows external injection of data handling logic. This pattern increases flexibility.


59-60: New properties in TermWrap: multiInputCallback and sendDataHandler
Enhances extensibility for multi-input features. Implementation is straightforward.


70-70: Assigning sendDataHandler
Ensures we can delegate data sending externally; no concerns.


144-144: onKeyHandler registration
Positions key event handling in one place. Good approach to maintain clarity for multi-input usage.


175-177: handleTermData now calling this.sendDataHandler?.(data)
Provides a neat injection point to avoid hardcoded logic. Good usage of optional chaining.


178-181: onKeyHandler triggers multiInputCallback
This effectively routes keystroke data to multi-input. If keys become more complex, ensure key data is sanitized or validated.

frontend/types/custom.d.ts (3)

30-30: Declare isTermMultiInput in GlobalAtomsType
Accurately reflects new global state. Compatible with newly introduced multi-input features.


171-171: Added optional title in HeaderTextButton
Expands UI flexibility by allowing tooltips or extra info. No issues found.


245-247: Added isBasicTerm in ViewModel
Consistent with the terminal’s logic. Marking it optional is sensible for other view models.

frontend/app/store/keymodel.ts (3)

8-8: Import getAllBlockComponentModels
Import aligns with multi-input logic that needs to iterate over terminal blocks.


229-240: New countTermBlocks function
Effectively counts basic terminals. Quick check: ensure logic is consistent with isBasicTerm usage.


324-332: Key binding for Ctrl+Shift+i
Smart guard ensures multi-input toggles only if at least two basic terminal blocks exist. Clear user experience.

frontend/app/store/global.ts (2)

167-167: Added isTermMultiInput atom
Aligned with multi-input feature. Initializing to false is a sensible default.


500-502: New function getAllBlockComponentModels
Facilitates enumerating block models in the store. Implementation is straightforward.

ROADMAP.md (1)

27-27: Roadmap status update looks correct.
This line accurately reflects the completion of the feature in question.

Copy link

@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 (2)
frontend/types/custom.d.ts (1)

180-180: Good addition of title property!

The optional title property enhances button accessibility. Consider using ARIA labels for even better accessibility.

Consider adding aria-label support:

type HeaderTextButton = {
    elemtype: "textbutton";
    text: string;
    className?: string;
    title?: string;
+   ariaLabel?: string;
    onClick?: (e: React.MouseEvent<any>) => void;
};
frontend/app/view/term/term.tsx (1)

321-332: Consider extracting duplicated logic!

The isBasicTerm implementation is correct, but the logic is duplicated in TerminalView. Consider extracting this to a shared utility function.

+const isBasicTerm = (termMode: string, controller: string): boolean => {
+    return termMode !== "vdom" && controller !== "cmd";
+};

 isBasicTerm(getFn: jotai.Getter): boolean {
-    const termMode = getFn(this.termMode);
-    if (termMode == "vdom") {
-        return false;
-    }
-    const blockData = getFn(this.blockAtom);
-    if (blockData?.meta?.controller == "cmd") {
-        return false;
-    }
-    return true;
+    return isBasicTerm(
+        getFn(this.termMode),
+        getFn(this.blockAtom)?.meta?.controller
+    );
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7743dc2 and e6aa132.

📒 Files selected for processing (6)
  • ROADMAP.md (1 hunks)
  • frontend/app/block/blockframe.tsx (1 hunks)
  • frontend/app/store/keymodel.ts (3 hunks)
  • frontend/app/view/term/term.tsx (9 hunks)
  • frontend/app/view/term/termwrap.ts (5 hunks)
  • frontend/types/custom.d.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • ROADMAP.md
  • frontend/app/block/blockframe.tsx
  • frontend/app/store/keymodel.ts
🔇 Additional comments (9)
frontend/app/view/term/termwrap.ts (4)

44-44: Well-structured type and property additions!

The new optional sendDataHandler in TermWrapOptions and the corresponding properties in TermWrap class follow good design patterns by:

  • Using dependency injection for flexible data handling
  • Making the handler optional for backward compatibility
  • Properly typing the callbacks for type safety

Also applies to: 61-62


74-74: Clean constructor initialization!

The sendDataHandler is properly initialized from the provided options.


193-194: Clean data handling delegation!

The method elegantly delegates data handling using optional chaining, making it both safe and flexible.


196-199: Well-implemented key event handling!

The method properly checks for callback existence before forwarding key events, ensuring safe operation.

frontend/types/custom.d.ts (2)

30-30: Appropriate global state type definition!

The isTermMultiInput atom is correctly typed as a primitive boolean atom in the global state.


265-267: Clean interface extension!

The isBasicTerm method is well-defined with appropriate types and helpful documentation.

frontend/app/view/term/term.tsx (3)

334-344: Well-implemented multi-input handling!

The method correctly:

  • Filters out self to prevent echo
  • Early returns if no other terminals exist
  • Properly forwards data to all other basic terminals

689-702: Clean implementation of terminal model collection!

The function correctly filters and collects basic terminal models using appropriate type checks and filtering.


995-1005: Well-implemented React effect for multi-input setup!

The effect correctly:

  • Sets up the callback based on all required conditions
  • Cleans up by removing the callback when needed
  • Uses appropriate dependencies

Comment on lines +346 to +349
sendDataToController(data: string) {
const b64data = stringToBase64(data);
RpcApi.ControllerInputCommand(TabRpcClient, { blockid: this.blockId, inputdata64: b64data });
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for RPC call!

While the implementation is correct, it should handle potential RPC failures.

 sendDataToController(data: string) {
     const b64data = stringToBase64(data);
-    RpcApi.ControllerInputCommand(TabRpcClient, { blockid: this.blockId, inputdata64: b64data });
+    RpcApi.ControllerInputCommand(TabRpcClient, { blockid: this.blockId, inputdata64: b64data })
+        .catch(error => {
+            console.error('Failed to send data to controller:', error);
+            // Consider notifying the user or retrying
+        });
 }
📝 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
sendDataToController(data: string) {
const b64data = stringToBase64(data);
RpcApi.ControllerInputCommand(TabRpcClient, { blockid: this.blockId, inputdata64: b64data });
}
sendDataToController(data: string) {
const b64data = stringToBase64(data);
RpcApi.ControllerInputCommand(TabRpcClient, { blockid: this.blockId, inputdata64: b64data })
.catch(error => {
console.error('Failed to send data to controller:', error);
// Consider notifying the user or retrying
});
}

@sawka sawka merged commit 3fc4009 into main Jan 2, 2025
8 checks passed
@sawka sawka deleted the sawka/term-multi-input branch January 2, 2025 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant