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

Adds readonly property to PillBadge and Modal button #5032

Merged
merged 6 commits into from
Nov 4, 2024

Conversation

manivoxel51
Copy link
Contributor

@manivoxel51 manivoxel51 commented Nov 1, 2024

What changes are proposed in this pull request?

  • adds a readonly property to PillBadge and ModalView - needed for enforcing permissioning in teams
  • adds an optional tooltipTitle property so we can show things like "you don't have sufficient permissions." in teams context. @imanjra lmk if there is a better way and I'll followup with improvements.

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

(Details)

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 a disabled property to the ModalButtonView for enhanced button control.
    • Added readOnly and tooltipTitle properties to the PillBadge component, allowing it to render in a non-interactive state and provide additional context.
    • Updated the PillBadgeView to reflect the new readOnly prop for better schema integration.
    • Added a tooltipTitle property to the DropdownView for enhanced user guidance.
  • Improvements

    • Enhanced button interactivity based on tagging functionality.
    • Improved usability of the PillBadge component by restricting user input when in read-only mode.
    • Adjusted the default cursor style in the ImageView component to provide clearer user interaction feedback.

Copy link
Contributor

coderabbitai bot commented Nov 1, 2024

Walkthrough

The changes in this pull request introduce new optional properties disabled and readOnly to the ModalButtonView and PillBadge components, respectively. The ModalBase component's button state is now conditionally managed based on the presence of tags, while the PillBadge component can be rendered in a read-only state. Additionally, the PillBadgeView function's parameter type has been specified for better type safety, and the read_only property has been renamed to readOnly for consistency across components.

Changes

File Path Change Summary
app/packages/components/src/components/ModalBase/ModalBase.tsx Added optional property disabled to ModalButtonView interface; modified button state management.
app/packages/components/src/components/PillBadge/PillBadge.tsx Introduced optional property readOnly to control Chip and Select components' disabled state.
app/packages/core/src/plugins/SchemaIO/components/PillBadgeView.tsx Updated PillBadgeView function to use specific type for props and renamed read_only to readOnly.
app/packages/core/src/plugins/SchemaIO/components/ImageView.tsx Changed default value of cursor property from true to false for the <img> element.
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx Added Tooltip component wrapping Select; introduced tooltipTitle property to enhance UI.

Possibly related PRs

  • Adds disabled state for all button view variants #4930: This PR adds a disabled state for all button view variants, which is directly related to the changes in the main PR that also introduced a disabled property to the ModalButtonView interface and modified button behavior based on this state.
  • Fixes disabled color on buttonView when no colorCode is passed & refactor #4934: This PR fixes the disabled color on the ButtonView, which aligns with the changes in the main PR that enhance button state management, particularly regarding the disabled state.
  • ModalView quick fix #4978: This PR includes modifications to the ModalBase component, specifically related to the button's disabled state logic, which is relevant to the changes made in the main PR regarding button interactivity and state management.

Suggested labels

feature, app, plugins

Suggested reviewers

  • lanzhenw
  • imanjra

🐇 In the modal bright and clear,
Buttons dance without a fear.
Read-only chips now take their place,
With new states, they join the race.
A hop, a skip, a joyful cheer,
Code's alive, the changes here! 🎉


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 90082d7 and b66bd9b.

📒 Files selected for processing (1)
  • app/packages/components/src/components/ModalBase/ModalBase.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/packages/components/src/components/ModalBase/ModalBase.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.

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

🧹 Outside diff range and nitpick comments (5)
app/packages/core/src/plugins/SchemaIO/components/PillBadgeView.tsx (1)

9-9: Consider using object property shorthand

The renaming from read_only to readOnly aligns with React naming conventions. However, you could simplify this using object property shorthand.

-  const { text, color, variant, showIcon, read_only: readOnly } = view;
+  const { text, color, variant, showIcon, readOnly } = view;
app/packages/components/src/components/PillBadge/PillBadge.tsx (1)

Line range hint 8-21: Consider improving type safety with discriminated unions.

The current props interface allows for three different types of text prop with overlapping behavior. Consider using a discriminated union type to make the relationship between text types and their corresponding rendered components more explicit.

Consider refactoring the props interface like this:

type BasePillBadgeProps = {
  color?: string;
  variant?: "filled" | "outlined";
  showIcon?: boolean;
  operator?: () => void;
  readOnly?: boolean;
};

type StaticPillBadgeProps = BasePillBadgeProps & {
  type: "static";
  text: string;
};

type SelectPillBadgeProps = BasePillBadgeProps & {
  type: "select";
  text: string[];
};

type ColoredSelectPillBadgeProps = BasePillBadgeProps & {
  type: "coloredSelect";
  text: [string, string][];
};

type PillBadgeProps = StaticPillBadgeProps | SelectPillBadgeProps | ColoredSelectPillBadgeProps;

This would make the component's API more type-safe and self-documenting.

app/packages/components/src/components/ModalBase/ModalBase.tsx (3)

106-106: Consider using type-safe property access

While the disabled state is correctly propagated, consider using optional chaining for type-safe property access.

-    disabled: props?.disabled,
+    disabled: props?.disabled ?? false,

Line range hint 174-186: Improve button state management

There are several potential improvements for the button state management:

  1. The useEffect dependency array should include primaryButtonView.disabled to prevent stale closures.
  2. The functionality check could be simplified.
  3. The boolean operations for disabled state could be more explicit.
  useEffect(() => {
+   const isTaggingMode = functionality.toLowerCase() === "tagging";
+   const hasTags = primaryButtonView.params?.tags?.length > 0;
+   const isDisabledByProps = primaryButtonView.disabled ?? false;
+   
    if (
-     (functionality === "tagging" || functionality === "Tagging") &&
-     (!primaryButtonView.params ||
-      !primaryButtonView.params.tags ||
-      primaryButtonView.params.tags.length === 0)
+     isTaggingMode && !hasTags
    ) {
      setPrimaryButtonView({
        ...primaryButtonView,
-       disabled: primaryButtonView?.disabled || true,
+       disabled: true,
      });
    } else {
      setPrimaryButtonView({
        ...primaryButtonView,
-       disabled: primaryButtonView?.disabled || false,
+       disabled: isDisabledByProps,
      });
    }
-  }, [primaryButtonView.params]);
+  }, [primaryButtonView.params, primaryButtonView.disabled, functionality]);

Line range hint 1-270: Consider splitting button state logic into a custom hook

The button state management logic could be extracted into a custom hook (e.g., useModalButtonState) to improve reusability and maintainability. This would also make the component more focused on its primary responsibility of rendering the modal.

Example structure:

const useModalButtonState = (
  functionality: string,
  initialState: ButtonState,
  params: any
) => {
  // ... button state management logic
  return { buttonState, setButtonState };
};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7c89c13 and 025fa68.

📒 Files selected for processing (3)
  • app/packages/components/src/components/ModalBase/ModalBase.tsx (2 hunks)
  • app/packages/components/src/components/PillBadge/PillBadge.tsx (2 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/PillBadgeView.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
app/packages/components/src/components/ModalBase/ModalBase.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.

app/packages/components/src/components/PillBadge/PillBadge.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.

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

4-4: LGTM: Type safety improvements

The addition of proper TypeScript types enhances type safety and improves code maintainability.

Also applies to: 6-6


14-14: Verify readOnly prop behavior

The readOnly prop is correctly passed to PillBadge, but let's verify its integration with the permissioning system.

✅ Verification successful

Let me verify the readOnly prop integration by checking its usage and permissions handling in the codebase.


Let me try a different search pattern to verify the readOnly prop implementation.


Let me try one more search to understand how the readOnly prop is used in the PillBadge component.


Let me try one final search to understand the PillBadge component implementation.


readOnly prop implementation is correct and properly integrated

The PillBadge component correctly implements the readOnly prop with proper TypeScript typing and default value handling:

  • It's defined as an optional boolean prop with default value of false
  • The prop is properly typed in the component interface
  • The readOnly prop is passed through from SchemaIO component
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent readOnly prop usage across components
# and its integration with permission checks

# Check for readOnly prop usage patterns
rg -A 5 'readOnly[?]?: ?boolean' 

# Look for permission-related logic connected to readOnly
rg -A 10 'permission|access|role.*readOnly'

Length of output: 318216


Script:

#!/bin/bash
# Check PillBadge component implementation and readOnly prop usage
ast-grep --pattern $'const PillBadge = ({$$$, readOnly$_, $$$}) => {
  $$$
}'

# Check for readOnly prop validation and handling
rg -A 10 "readOnly.*prop" app/packages/components/src/components/PillBadge/

# Check for any permission checks related to readOnly
rg -A 5 "readOnly.*permission|permission.*readOnly"

Length of output: 210


Script:

#!/bin/bash
# Search for PillBadge component definition and readOnly usage
rg -A 20 "PillBadge.*=.*{.*readOnly" app/packages/components/src/components/PillBadge/

# Check for readOnly prop type definition
rg -A 5 "readOnly\??: ?(boolean|PropTypes\.bool)" app/packages/components/src/components/PillBadge/

# Look for readOnly prop usage in SchemaIO components
rg -A 10 "readOnly.*PillBadge" app/packages/core/src/plugins/SchemaIO/

Length of output: 935


Script:

#!/bin/bash
# Search for PillBadge component implementation
rg -A 30 "const PillBadge = \({" app/packages/components/src/components/PillBadge/

# Check for readOnly usage in component logic
rg -A 10 "readOnly.*\?" app/packages/components/src/components/PillBadge/

# Look for PillBadge usage in SchemaIO components
rg -A 5 "<PillBadge.*readOnly" app/packages/core/src/plugins/SchemaIO/

Length of output: 1355


Script:

#!/bin/bash
# Search for PillBadge component definition with fixed pattern
rg -A 30 "const PillBadge" app/packages/components/src/components/PillBadge/

# Look for PillBadge usage in SchemaIO components with broader pattern
rg -A 5 "PillBadge.*readOnly|readOnly.*PillBadge" app/packages/core/src/plugins/SchemaIO/

# Check for readOnly prop handling in component logic
rg -A 10 "const.*readOnly|readOnly.*=|readOnly.*\?" app/packages/components/src/components/PillBadge/

Length of output: 4587

app/packages/components/src/components/PillBadge/PillBadge.tsx (1)

13-13: LGTM: Props interface changes look good.

The readOnly prop is properly typed and has a sensible default value.

Also applies to: 20-20

app/packages/components/src/components/ModalBase/ModalBase.tsx (1)

47-47: LGTM: Well-typed interface extension

The addition of the optional disabled property to ModalButtonView interface is properly typed and aligns with React's button props pattern.

@@ -90,6 +92,7 @@ const PillBadge = ({
) : (
<FormControl fullWidth>
<Chip
disabled={readOnly}
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 1, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider extending readonly behavior.

While the disabled prop is correctly applied to the Chip component, the Select components within both conditional branches remain interactive even when readOnly is true.

Apply this diff to ensure consistent readonly behavior:

              Array.isArray(text[0]) ? (
                <Select
                  value={chipSelection}
                  variant={"standard"}
                  disableUnderline={true}
+                 disabled={readOnly}
                  onChange={(event) => {
                    const selectedText = text.find(
                      (t) => t[0] === event.target.value
                    );
                    setChipSelection(event.target.value);
                    setChipColor(selectedText?.[1] ?? "default");
                    if (operator) {
                      handleClick(panelId, {
                        params: { value: event.target.value },
                        operator,
                      });
                    }
                  }}
                  sx={{
                    color: "inherit",
                  }}
                >
                  {text.map((t, index) => (
                    <MenuItem key={index} value={t[0]}>
                      {t[0]}
                    </MenuItem>
                  ))}
                </Select>
              ) : (
                <Select
                  value={chipSelection}
                  variant={"standard"}
                  disableUnderline={true}
+                 disabled={readOnly}
                  onChange={(event) => {
📝 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
disabled={readOnly}
Array.isArray(text[0]) ? (
<Select
value={chipSelection}
variant={"standard"}
disableUnderline={true}
disabled={readOnly}
onChange={(event) => {
const selectedText = text.find(
(t) => t[0] === event.target.value
);
setChipSelection(event.target.value);
setChipColor(selectedText?.[1] ?? "default");
if (operator) {
handleClick(panelId, {
params: { value: event.target.value },
operator,
});
}
}}
sx={{
color: "inherit",
}}
>
{text.map((t, index) => (
<MenuItem key={index} value={t[0]}>
{t[0]}
</MenuItem>
))}
</Select>
) : (
<Select
value={chipSelection}
variant={"standard"}
disableUnderline={true}
disabled={readOnly}
onChange={(event) => {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fair point

Copy link
Contributor

Choose a reason for hiding this comment

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

@manivoxel51, glad you agree. Let me know if there's anything else I can assist with.


If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!

@@ -10,12 +10,16 @@ const PillBadge = ({
variant = "filled",
showIcon = true,
operator,
readOnly = false,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed for PillBadge?

To set a readOnly PillBadge view you simply pass down a singular string. If only a string is given to this component (with or without a color) it becomes unselectable and is no longer a writeable component

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if we simply use

schema = {"text": "Disabled", "color": "secondary"}
badge = types.PillBadgeView(**schema)

The badge doesn't reflect it is a dropdown select - the downward caret will be missing. disabled / readOnly are legit properties to use in common components. if you really don't like the readOnly prop, happy to huddle and resolve!

Copy link
Contributor

@Br2850 Br2850 Nov 4, 2024

Choose a reason for hiding this comment

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

But isn't that the point of read only functionality? If I should only be reading the state of something, I don't understand why they would need to see the dropdown caret?

Having a dropdown caret implies that they can change the state of the pill, but we don't want that

So we should just show the pill and whatever the current status is without the ability to change it - which is just the string & a color choice

Copy link
Contributor

@Br2850 Br2850 left a comment

Choose a reason for hiding this comment

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

ModalButtonView doesn't have a disabled field at the parent level so that makes sense

But I'm a bit confused as to why the changes to PillBadge & PillBadgeView are needed? If you just pass in a string, the component is automatically read-only

Here's an example:

schema = {"text": "Disabled", "color": "secondary"}
badge = types.PillBadgeView(**schema)

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

Line range hint 11-13: Add TypeScript types for props and schema

The component lacks proper TypeScript type definitions. Consider adding interfaces for the props and schema structure:

interface ImageViewProps {
  schema: {
    view?: {
      height?: number;
      width?: number;
      alt?: string;
      href?: string;
      operator?: string;
      prompt?: boolean;
      params?: any;
      cursor?: boolean;
    };
    default?: string;
  };
  data?: string;
}

Line range hint 26-43: Optimize click handler with useCallback

The onClick handler could be memoized to prevent unnecessary re-renders:

-  const onClick = () => {
+  const onClick = React.useCallback(() => {
     if (operator) {
       handleClick(panelId, {
         params: params,
         operator,
         prompt,
         callback: (result: OperatorResult) => {
           if (result?.error) {
             console.log(result?.error);
             console.log(result?.errorMessage);
           } else {
             openLink();
           }
         },
       });
     } else {
       openLink();
     }
-  };
+  }, [operator, panelId, params, prompt, handleClick, openLink]);

19-19: Document the cursor property's relationship with read-only state

Add a JSDoc comment to explain how the cursor property relates to the component's interactive state:

+  /**
+   * Whether to show a pointer cursor on hover.
+   * Defaults to false to support read-only states.
+   */
   cursor = false,

Line range hint 33-36: Improve error handling feedback

Currently, errors are only logged to the console. Consider adding user feedback:

 if (result?.error) {
-  console.log(result?.error);
-  console.log(result?.errorMessage);
+  console.error('Operator execution failed:', result.error);
+  // Add user notification
+  props.onError?.(result.errorMessage || 'Operation failed');
 } else {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9704378 and 3a902a2.

📒 Files selected for processing (2)
  • app/packages/components/src/components/PillBadge/PillBadge.tsx (5 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/ImageView.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/packages/components/src/components/PillBadge/PillBadge.tsx
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/ImageView.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.

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

160-161: Consider using span wrapper for disabled tooltip

When a MUI Select is disabled, its tooltip might not be visible. Wrap the Tooltip with a span to ensure the tooltip remains accessible in disabled state.

-      <Tooltip title={tooltipTitle}>
-        <Select
+      <Tooltip title={tooltipTitle}>
+        <span>
+          <Select

Don't forget to close the span tag after the Select component.

Also applies to: 163-163


202-210: Optimize onClick handler for disabled state

The onClick handler with addOnClickToMenuItems check is unnecessary when the MenuItem is disabled. Consider moving this logic to a separate handler for better clarity.

-              onClick={() => {
-                if (addOnClickToMenuItems) {
-                  handleOnChange(value);
-                }
-              }}
+              onClick={addOnClickToMenuItems && !readOnly ? () => handleOnChange(value) : undefined}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3a902a2 and 8c5d155.

📒 Files selected for processing (2)
  • app/packages/components/src/components/PillBadge/PillBadge.tsx (4 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/packages/components/src/components/PillBadge/PillBadge.tsx
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.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/DropdownView.tsx (2)

1-1: LGTM: Clean import and prop addition

The Tooltip import and tooltipTitle prop are well-structured and follow React/TypeScript conventions.

Also applies to: 37-37


160-217: Verify accessibility and type consistency

Please ensure:

  1. The readOnly behavior is consistent with other dropdown components
  2. The tooltipTitle prop is included in the component's TypeScript interface
✅ Verification successful

Accessibility and type safety are properly implemented

The verification shows that:

  1. The readOnly prop is correctly implemented in the DropdownView component, being passed down to both the Select and MenuItem components consistently
  2. The tooltipTitle prop is properly defined in the component's view configuration and is correctly used with MUI's Tooltip component
  3. The implementation follows the same pattern as other components in the codebase that use tooltips with selection elements

The code demonstrates good accessibility practices by:

  • Using ARIA labels for icon buttons
  • Implementing tooltips consistently
  • Maintaining keyboard navigation support through the Select component
  • Properly handling disabled states
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar dropdown components and their readOnly implementation
ast-grep --pattern 'interface $interface {
  $$$
  readOnly?: boolean;
  $$$
}'

# Search for tooltip implementations in other dropdown components
rg -l 'Tooltip.*Select' --type typescript

Length of output: 160


Script:

#!/bin/bash
# Search for similar dropdown components and their readOnly implementation
ast-grep --pattern 'interface $interface {
  $$$
  readOnly?: boolean;
  $$$
}'

# Search for tooltip implementations in other dropdown components
rg -l 'Tooltip.*Select'

# Search for type definitions related to tooltipTitle
ast-grep --pattern 'interface $_ {
  $$$
  tooltipTitle?: $_
  $$$
}'

# Search for other dropdown components with readOnly prop
rg 'readOnly.*Select' -A 2 -B 2

Length of output: 213


Script:

#!/bin/bash
# Search for Select components with props
ast-grep --pattern '<Select
  $$$
  readOnly={$_}
  $$$
>'

# Find TypeScript interfaces containing Select
ast-grep --pattern 'interface $_Props {
  $$$
}'

# Search for files containing Select components
fd Select --type f --extension tsx --extension ts

# Look for tooltip usage patterns
rg '<Tooltip' --type ts --type tsx -A 2

Length of output: 2716


Script:

#!/bin/bash
# Check the content of DropdownView.tsx and its interface definitions
cat app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx

# Check content of similar dropdown components
cat app/packages/core/src/components/GroupSliceSelector.tsx
cat app/packages/core/src/plugins/SchemaIO/components/FileExplorerView/VolumeSelector.tsx

# Look for tooltip patterns without file type specification
rg '<Tooltip.*title=' -A 1

Length of output: 11292

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

🧹 Outside diff range and nitpick comments (3)
app/packages/components/src/components/ModalBase/ModalBase.tsx (3)

47-47: LGTM! Consider adding JSDoc documentation.

The optional disabled property is a good addition for permission control. Consider adding JSDoc documentation to explain its usage and relationship with permissions.

+  /** Whether the button is disabled. Used for permission control in team environments. */
   disabled?: boolean;

Line range hint 180-187: Simplify redundant disabled state logic.

The current implementation has redundant logic as both conditions set the same disabled state. Additionally, the effect's dependency array might miss important dependencies.

  1. Simplify the redundant logic:
-    if (
-      (functionality === "tagging" || functionality === "Tagging") &&
-      (!primaryButtonView.params ||
-        !primaryButtonView.params.tags ||
-        primaryButtonView.params.tags.length === 0)
-    ) {
-      setPrimaryButtonView({
-        ...primaryButtonView,
-        disabled: primaryButtonView?.disabled || false,
-      });
-    } else {
-      setPrimaryButtonView({
-        ...primaryButtonView,
-        disabled: primaryButtonView?.disabled || false,
-      });
-    }
+    setPrimaryButtonView({
+      ...primaryButtonView,
+      disabled: primaryButtonView?.disabled || false,
+    });
  1. Update the dependency array to include all dependencies:
-  }, [primaryButtonView.params]);
+  }, [primaryButtonView.params, primaryButtonView.disabled, functionality]);

Line range hint 8-56: Consider architectural improvements for better maintainability.

  1. Extract functionality types into an enum:
enum ModalFunctionality {
  TAGGING = 'tagging',
  NONE = 'none'
}
  1. Consider splitting the component into smaller, focused components:
  • ModalHeader
  • ModalButtons
  • TaggingSection
  1. Add proper TypeScript types for all props instead of using any:
interface ModalProps {
  props: {
    variant?: string;
    label?: string;
    disabled?: boolean;
    height?: string | number;
    width?: string | number;
    padding?: number;
    icon?: string;
    iconPosition?: 'left' | 'right';
  }
}

Would you like me to help create these architectural improvements?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8c5d155 and 90082d7.

📒 Files selected for processing (1)
  • app/packages/components/src/components/ModalBase/ModalBase.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/components/src/components/ModalBase/ModalBase.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.

@Br2850 Br2850 force-pushed the panels/add-readonly branch from 90082d7 to b66bd9b Compare November 4, 2024 06:49
@Br2850 Br2850 self-requested a review November 4, 2024 17:13
Copy link
Contributor

@Br2850 Br2850 left a comment

Choose a reason for hiding this comment

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

After demo, looks good, this gives us options if we need it

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.

3 participants