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

Add support for cell tooltip in TableView #5152

Merged
merged 6 commits into from
Nov 19, 2024

Conversation

minhtuev
Copy link
Contributor

@minhtuev minhtuev commented Nov 19, 2024

What changes are proposed in this pull request?

Added support for cell tooltip in TableView

How is this patch tested? If it is not, please explain why.

  • Tested locally

image

(the current panel is a local version for testing, not the RC version, so a few details might be a bit off)

Example usage:

for row in range(len(all_indices), len(all_indices) + len(summary_fields)):
    table.add_tooltip(row, 1, "Summary field size not available")

Release Notes

Is this a user-facing change that should be mentioned in the release notes?

  • No. You can skip the rest of this section.
  • Yes. Give a description of this change to be included in the release
    notes for FiftyOne users.

(Details in 1-2 sentences. You can just refer to another PR with a description
if this PR is part of a larger change.)

What areas of FiftyOne does this PR affect?

  • App: FiftyOne application changes
  • Build: Build and test infrastructure changes
  • Core: Core fiftyone Python library changes
  • Documentation: FiftyOne documentation changes
  • Other

Summary by CodeRabbit

  • New Features
    • Introduced tooltips for table cells, providing additional context when hovering over data.
    • Added functionality to manage and serialize tooltips within the TableView component.
  • Bug Fixes
    • Minor adjustments made for code clarity and organization.

Copy link
Contributor

coderabbitai bot commented Nov 19, 2024

Walkthrough

The changes in this pull request enhance the TableView component by introducing tooltip functionality. A new tooltips property is added to the view object, allowing tooltips to be defined for table cells. The getTooltips function maps these tooltips based on row and column indices. The rendering logic is updated to display tooltips using Material-UI's Tooltip component. Additionally, a new Tooltip class is created in fiftyone/operators/types.py, and methods for managing tooltips are added to the TableView class.

Changes

File Path Change Summary
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx - Added tooltips property to view object.
- Introduced getTooltips function for tooltip mapping.
- Updated cell rendering to include tooltips with Material-UI's Tooltip component.
- Added hasTooltips variable.
- Minor code formatting adjustments.
fiftyone/operators/types.py - Added Tooltip class extending View.
- Added add_tooltip method to TableView.
- Introduced self.tooltips in TableView.
- Updated to_json and clone methods in TableView to handle tooltips.

Possibly related PRs

Suggested reviewers

  • ritch
  • CamronStaley

🐰 In the table where data gleams,
Tooltips now share their dreams.
Hover close, and you will see,
Context blooms so joyfully!
With every cell, a story told,
In our view, new wonders unfold! 🌟


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8f702b5 and 898d4c7.

📒 Files selected for processing (1)
  • app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/packages/core/src/plugins/SchemaIO/components/TableView.tsx

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.

@minhtuev minhtuev marked this pull request as ready for review November 19, 2024 20:39
@@ -170,13 +182,14 @@ export default function TableView(props: ViewPropsType) {
selectedCells.has(coordinate) ||
isRowSelected ||
selectedColumns.has(columnIndex);
return (

const tooltip = tooltipMap[coordinate]; // Check if there's a tooltip for the cell
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we don't check if coordinate is a valid key, the assumption is that tooltipMap will return null if the key is not in the map

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: 2

🧹 Outside diff range and nitpick comments (3)
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (2)

69-75: Improve tooltip mapping implementation

The getTooltips implementation has several areas for improvement:

  1. Missing TypeScript types
  2. Unnecessary recreation on every render due to empty dependency array
  3. Could use object literal initialization for better performance

Consider this improved implementation:

const getTooltips = useCallback((tooltipList: TooltipDefinition[]) => {
  return tooltipList.reduce((acc, { value, row, column }) => {
    acc[`${row},${column}`] = value;
    return acc;
  }, {} as Record<string, string>);
}, [/* no dependencies needed */]);

Line range hint 185-209: Simplify cell rendering logic and avoid coordinate string duplication

The current implementation duplicates the coordinate string creation logic and has nested ternary expressions that could be simplified.

Consider this cleaner implementation:

const coordinate = `${rowIndex},${columnIndex}`;
const tooltip = tooltipMap[coordinate];
const cell = (
  <TableCell
    key={key}
    sx={{
      background: isSelected ? selectedCellColor : "unset",
    }}
    onClick={() => handleCellClick(rowIndex, columnIndex)}
    {...getComponentProps(props, "tableBodyCell")}
  >
    {formatCellValue(item[key], props)}
  </TableCell>
);

return tooltip ? (
  <Tooltip key={key} title={tooltip} arrow>
    {cell}
  </Tooltip>
) : cell;

This approach:

  1. Creates the coordinate string once
  2. Improves readability by reducing nesting
  3. Maintains the same functionality
fiftyone/operators/types.py (1)

1841-1858: Enhance Tooltip class documentation and implementation.

The class documentation and implementation could be improved:

  1. Add usage examples in the docstring
  2. Define explicit attributes for row, column, and value mentioned in the docstring
 class Tooltip(View):
     """A tooltip (currently supported only in a :class:`TableView`).
 
     Args:
         value: the value of the tooltip
         row: the row of the tooltip
         column: the column of the tooltip
+
+    Examples::
+
+        import fiftyone.operators.types as types
+
+        table_view = types.TableView()
+        table_view.add_tooltip(
+            row=0,
+            column="status",
+            value="Processing complete"
+        )
     """
 
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
+        self.value = kwargs.get("value")
+        self.row = kwargs.get("row")
+        self.column = kwargs.get("column")
 
     def clone(self):
         clone = Tooltip(**self._kwargs)
         return clone
 
     def to_json(self):
-        return {**super().to_json()}
+        return {
+            **super().to_json(),
+            "value": self.value,
+            "row": self.row,
+            "column": self.column
+        }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a4e2a6b and 2d87ec8.

📒 Files selected for processing (2)
  • app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (6 hunks)
  • fiftyone/operators/types.py (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (2)
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (1)

107-107: Verify tooltip cleanup and performance

The tooltip map is recreated on every render. Let's verify there are no memory leaks or performance issues.

✅ Verification successful

Let me gather more information about the tooltip implementation and cleanup patterns.


Let me try one more search pattern to find the tooltip implementation.


No performance concerns with tooltip implementation

The implementation is well-optimized:

  • getTooltips is memoized with useCallback
  • Tooltips are stored in a simple object (not Map) with efficient key-value lookups
  • The tooltip component is only rendered when a tooltip exists for a cell
  • MUI's Tooltip component handles its own cleanup
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other tooltip implementations in the codebase for consistency
rg -g '*.{ts,tsx}' 'Tooltip.*title=' --type-add 'tsx:*.{ts,tsx}'

# Look for cleanup patterns in similar components
ast-grep --pattern 'useEffect($$$) {
  $$$
  return () => {
    $$$
  }
}'

Length of output: 2065


Script:

#!/bin/bash
# Check the implementation of getTooltips function
ast-grep --pattern 'getTooltips = ($$$) => {
  $$$
}'

# Look for tooltip cleanup or disposal patterns
rg -g '*.{ts,tsx}' 'useEffect.*tooltip' --type-add 'tsx:*.{ts,tsx}' -B 2 -A 5

# Check TableView component for any cleanup effects
rg -g '*TableView.tsx' 'useEffect' -B 2 -A 5

Length of output: 180


Script:

#!/bin/bash
# Search for getTooltips function with a more flexible pattern
rg -g '*.{ts,tsx}' 'function.*getTooltips|const.*getTooltips' --type-add 'tsx:*.{ts,tsx}' -B 2 -A 10

# Check TableView imports and tooltip-related code
rg -g '*TableView.tsx' 'tooltip|Tooltip' --type-add 'tsx:*.{ts,tsx}' -B 2 -A 2

# Look for any Map usage in TableView
rg -g '*TableView.tsx' 'new Map|Map<' --type-add 'tsx:*.{ts,tsx}' -B 2 -A 2

Length of output: 6740

fiftyone/operators/types.py (1)

1873-1873: LGTM! TableView tooltip integration is well implemented.

The changes to TableView properly integrate tooltip support:

  • Initialization of tooltips list
  • Method to add tooltips
  • Proper handling in clone and to_json methods

Also applies to: 1889-1893, 1899-1899, 1907-1907

@@ -34,11 +35,13 @@ export default function TableView(props: ViewPropsType) {
size = "small",
variant = "filled",
max_inline_actions = 1,
tooltips = []
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

Add TypeScript type definition for tooltips prop

The tooltips prop is initialized with an empty array but lacks type information. This could lead to type-safety issues.

Consider adding an interface:

interface TooltipDefinition {
  value: string;
  row: number;
  column: number;
}

Then update the prop:

-tooltips = []
+tooltips: TooltipDefinition[] = []

@CamronStaley
Copy link
Contributor

Is there a way to make the tooltip on the content of the cell and not the cell itself? Looks a bit weird so off center from the actual text

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)
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (1)

184-184: Remove unnecessary whitespace

There's an extra blank line that can be removed to maintain consistent spacing.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2d87ec8 and 8f702b5.

📒 Files selected for processing (1)
  • app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (4)
app/packages/core/src/plugins/SchemaIO/components/TableView.tsx (4)

13-13: Add type definition for tooltips prop

The existing review comment about adding TypeScript type definition for the tooltips prop is still valid. This would improve type safety and developer experience.

Also applies to: 38-38


68-74: LGTM! Well-implemented tooltip mapping function

The getTooltips implementation is clean, efficient, and properly memoized. The coordinate key format aligns well with the existing selectedCells implementation.


106-106: LGTM! Efficient tooltip map initialization

The tooltipMap is correctly initialized outside the render loop, preventing unnecessary recalculations.


Line range hint 187-208: LGTM! Clean tooltip rendering implementation

The cell rendering logic with tooltips is well-structured and maintainable. The conditional rendering approach using the ternary operator is appropriate here.

@minhtuev
Copy link
Contributor Author

@CamronStaley: updated to wrap around cell content

image

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.

2 participants