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 on_cancel callback for operator prompt #5348

Merged
merged 5 commits into from
Jan 7, 2025
Merged

Add on_cancel callback for operator prompt #5348

merged 5 commits into from
Jan 7, 2025

Conversation

ritch
Copy link
Contributor

@ritch ritch commented Jan 6, 2025

What changes are proposed in this pull request?

Adds a new on_cancel callback when prompting for an operator. This will be called if a user cancels the operator prompt. NOTE: this behavior is not intended or available for immediately executing operators, such as when skip_prompt=True or the operator does not have input.

The example below is available as a panel example here.

class PromptExample(foo.Panel):
    def render(self, ctx):
        panel = types.Object()
        msg = ctx.panel.state.message
        result = f"message: {msg}" if msg else "..."
        panel.md(
            f"""
            ### Prompt Example

            This is an example of a prompt that can be used to gather user input.
                 
            {result}
        """
        )
        panel.btn("prompt", label="Prompt", on_click=self.on_click_prompt)
        return types.Property(
            panel,
            view=types.GridView(margin=5),
        )

    def on_success(self, ctx):
        ctx.panel.state.message = ctx.params.get("result", {}).get("message")
        ctx.ops.notify("Prompt was successful!")

    def on_cancel(self, ctx):
        ctx.ops.notify("Prompt was canceled", variant="warning")

    def on_click_prompt(self, ctx):
        ctx.prompt(
            "@voxel51/panel-examples/example_message",
            on_success=self.on_success,
            # NEW
            on_cancel=self.on_cancel,
        )

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.

Adds a new on_cancel event for ctx.prompt().

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
  • Plugins
  • Other

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added a new on_cancel parameter to prompt operations across multiple components.
    • Introduced enhanced cancellation handling for operator prompts.
    • Implemented a flexible mechanism to execute custom logic when a prompt is canceled.
    • Added new properties onCancel and prompt to relevant components for improved interaction.
  • Improvements

    • Extended prompt functionality to support more robust user interaction scenarios.
    • Improved error handling and user experience during operation cancellations.
    • Streamlined component logic for better management of operator execution and menu interactions.

Copy link
Contributor

coderabbitai bot commented Jan 6, 2025

Walkthrough

This pull request introduces a new on_cancel parameter across multiple files to enhance the prompt cancellation mechanism. The changes span TypeScript files in the operators package and a Python file in the core executor, allowing developers to specify a custom callback when a user cancels a prompt. The modification enables more flexible handling of user interactions by providing a dedicated way to execute specific actions during prompt cancellation.

Changes

File Change Summary
app/packages/operators/src/built-in-operators.ts Added on_cancel parameter to PromptUserForOperation class methods, enabling custom cancellation logic.
app/packages/operators/src/state.ts Implemented new cancel function in useOperatorPrompt hook to handle prompt cancellation.
app/packages/operators/src/usePanelEvent.ts Added optional onCancel property to HandlerOptions type.
fiftyone/operators/executor.py Updated prompt method in ExecutionContext to include on_cancel parameter.
app/packages/core/src/plugins/SchemaIO/components/OperatorExecutionButtonView.tsx Added on_cancel and prompt properties, and created handleOnCancel function for managing cancellation events.
app/packages/operators/src/components/OperatorExecutionButton/index.tsx Expanded props to include onCancel, prompt, and executorOptions, enhancing execution handling.
app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx Modified props to include executionOptions, onCancel, and prompt, streamlining execution management.
app/packages/operators/src/types-internal.ts Introduced new type ExecutionCancelCallback for cancellation handling.

Possibly related PRs

  • add original params to prompt callbacks #4862: This PR modifies the PromptUserForOperation class in built-in-operators.ts, specifically updating the execute method to include an additional parameter in the callback, which enhances the handling of contextual information.

  • add skip_prompt #4992: This PR introduces a skip_prompt parameter to the PromptUserForOperation class's resolveInput and execute methods, allowing users to bypass the prompt.

  • Feat/operator exec ctx menu #5099: This PR introduces the OperatorExecutionButtonView component, which is related to the main PR's changes in built-in-operators.ts as both involve enhancing user interaction mechanisms within the operator execution context.

  • add exec button to py panels #5119: This PR adds an execution button to Python panels, which is relevant as it likely interacts with the changes made in the main PR regarding operator execution and user prompts.

Suggested reviewers

  • lanzhenw
  • tom-vx51

Poem

🐰 A Rabbit's Cancellation Tale 🚫

When prompts arise and users flee,
A new callback sets actions free
With on_cancel now in sight,
Interactions dance just right!
Flexibility hops with glee! 🎉


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bd739fd and f6dfbe0.

📒 Files selected for processing (4)
  • app/packages/core/src/plugins/SchemaIO/components/TooltipProvider.tsx (1 hunks)
  • app/packages/operators/src/components/OperatorExecutionButton/index.tsx (2 hunks)
  • app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (3 hunks)
  • app/packages/operators/src/state.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
app/packages/core/src/plugins/SchemaIO/components/TooltipProvider.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/operators/src/state.ts (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/operators/src/components/OperatorExecutionTrigger/index.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/operators/src/components/OperatorExecutionButton/index.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.

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: test / test-app
  • GitHub Check: e2e / test-e2e
  • GitHub Check: build / build
  • GitHub Check: build
🔇 Additional comments (10)
app/packages/core/src/plugins/SchemaIO/components/TooltipProvider.tsx (1)

9-9: LGTM! Good semantic HTML improvement.

Using span instead of the default div is more appropriate for inline elements, which helps maintain proper document flow and prevents potential layout issues.

app/packages/operators/src/components/OperatorExecutionButton/index.tsx (5)

33-33: LGTM! Well-documented props extension.

The new props enhance the component's flexibility while maintaining good TypeScript type safety.

Also applies to: 36-36, 39-39, 46-47, 52-52


54-58: LGTM! Proper callback memoization.

Using useMemo for the handlers prevents unnecessary re-renders and follows React best practices.


62-86: LGTM! Well-structured execution logic.

The execution callback:

  • Properly merges options
  • Handles both prompt and non-prompt scenarios
  • Includes proper error handling

88-104: LGTM! Good user feedback implementation.

The warning message handling:

  • Shows loading state appropriately
  • Uses TooltipProvider for user feedback
  • Disables the button when showing warning

106-112: LGTM! Clean conditional rendering.

Good separation between prompt and non-prompt rendering paths, making the code easy to understand and maintain.

app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (1)

1-9: LGTM! Clean imports and type definitions.

The imports are well-organized and all imported entities are used within the component.

app/packages/operators/src/state.ts (3)

425-428: LGTM! Type definitions properly aligned with implementation.

The added return type properties accurately reflect the values returned by the useOperatorExecutionOptions hook.


590-594: Clean implementation of cancel functionality.

The cancel function properly handles the optional onCancel callback and ensures state cleanup through close().


672-672: LGTM! Cancel function properly exposed.

The cancel function is correctly exposed through the useOperatorPrompt hook's return object.


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.

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

🧹 Nitpick comments (2)
app/packages/operators/src/state.ts (1)

582-586: Consider adding TypeScript types for better maintainability.

The implementation is correct, but adding TypeScript types would improve code maintainability and prevent potential errors:

-  const onCancel = promptingOperator.options?.onCancel;
+  const onCancel: (() => void) | undefined = promptingOperator.options?.onCancel;
-  const cancel = () => {
+  const cancel = (): void => {
     if (onCancel) onCancel();
     close();
   };
app/packages/operators/src/built-in-operators.ts (1)

1049-1050: Consider adding error handling for invalid operator_uri.

The destructuring is correct, but consider adding validation for the operator_uri when handling cancellation:

-    const { params, operator_uri, on_success, on_error, on_cancel } =
-      ctx.params;
+    const { params, operator_uri, on_success, on_error, on_cancel } = ctx.params;
+    if (on_cancel && !operator_uri) {
+      console.error("Cannot handle cancellation: operator_uri is required");
+      return;
+    }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 574a577 and efb27b6.

📒 Files selected for processing (4)
  • app/packages/operators/src/built-in-operators.ts (3 hunks)
  • app/packages/operators/src/state.ts (2 hunks)
  • app/packages/operators/src/usePanelEvent.ts (3 hunks)
  • fiftyone/operators/executor.py (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
app/packages/operators/src/usePanelEvent.ts (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/operators/src/state.ts (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/operators/src/built-in-operators.ts (1)

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

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: e2e / test-e2e
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.11)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.9)
  • GitHub Check: build
🔇 Additional comments (6)
fiftyone/operators/executor.py (1)

Line range hint 747-774: LGTM! Clean implementation of the cancel callback.

The addition of the on_cancel parameter to the prompt method is well-implemented and properly documented. The parameter follows the same pattern as the existing on_success and on_error callbacks.

app/packages/operators/src/state.ts (1)

664-664: LGTM! Proper integration of the cancel function.

The cancel function is correctly exposed in the hook's return value, maintaining consistency with the existing pattern.

app/packages/operators/src/usePanelEvent.ts (2)

14-14: LGTM! Well-typed addition to HandlerOptions.

The onCancel callback is properly typed as an optional function in the HandlerOptions interface.


24-24: LGTM! Clean destructuring of the new option.

The onCancel option is correctly destructured along with other options, maintaining consistency.

app/packages/operators/src/built-in-operators.ts (2)

1040-1040: LGTM! Clean addition to input resolution.

The on_cancel parameter is properly added to the input resolution schema.


1059-1066: LGTM! Clean implementation of cancel handling.

The cancel handling logic is well-implemented, properly triggering the cancel operation with the original operator URI.

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 (8)
app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (2)

43-43: Document the executionOptions prop
The new executionOptions prop isn’t described in the component’s JSDoc, making it difficult for future maintainers to understand its role. Consider adding a brief explanation.


54-55: Include new props in JSDoc
onCancel and prompt are newly introduced but missing from the doc comment. Add them to maintain complete documentation.

app/packages/operators/src/components/OperatorExecutionButton/index.tsx (4)

25-25: Update docstring to include new parameters
The component supports prompt, executorOptions, and onCancel, but these fields are not mentioned in the doc comment. Keeping the docs aligned ensures clarity for future maintainers.


45-51: Ensure consistency with other operator-related props
onCancel, prompt, and executorOptions might need to be documented in the same style as onSuccess and onError for consistency.


61-85: Conditional operator prompt vs. direct execution
This approach cleanly accommodates both scenarios. However, consider adding error/catch handling for operator.execute(...) if rejections need to be processed.


92-98: Prompt-based execution flow
The conditional block for prompt clearly handles user prompts. Confirm that the returned promise from onExecute is used or handled upstream if needed.

app/packages/core/src/plugins/SchemaIO/components/OperatorExecutionButtonView.tsx (2)

81-87: Consider including context parameters for consistency

While the cancel handler implementation is correct, consider passing context parameters to maintain consistency with other handlers (handleOnSuccess and handleOnError). This would provide more context to the cancel operation.

-  const handleOnCancel: ExecutionCancelCallback = () => {
+  const handleOnCancel: ExecutionCancelCallback = (_, { ctx }) => {
     if (on_cancel) {
       triggerEvent(panelId, {
         operator: on_cancel,
+        params: {
+          original_params: ctx.params
+        }
       });
     }
   };

99-104: Improve clarity of the prompt condition

While the icon props refactoring is good, the condition's purpose could be more explicit. Consider using a more descriptive condition name or adding a comment explaining why icons are hidden when there's a prompt.

-  const iconProps = prompt
+  // Hide icons when showing a prompt dialog
+  const iconProps = Boolean(prompt)
     ? {}
     : {
         startIcon: icon_position === "left" ? Icon : undefined,
         endIcon: icon_position === "right" ? Icon : undefined,
       };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between efb27b6 and 5a2c696.

📒 Files selected for processing (4)
  • app/packages/core/src/plugins/SchemaIO/components/OperatorExecutionButtonView.tsx (5 hunks)
  • app/packages/operators/src/components/OperatorExecutionButton/index.tsx (2 hunks)
  • app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (4 hunks)
  • app/packages/operators/src/types-internal.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
app/packages/operators/src/types-internal.ts (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/OperatorExecutionButtonView.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/operators/src/components/OperatorExecutionTrigger/index.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/operators/src/components/OperatorExecutionButton/index.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.

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: e2e / test-e2e
  • GitHub Check: build / build
  • GitHub Check: build
🔇 Additional comments (12)
app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (2)

2-2: Adoption of MUI Box and Button looks good
These additions should simplify styling and layout for the trigger component.


58-58: Check for naming consistency
executionOptions is referenced both as a prop (line 43) and type-hinted here (line 58). Ensure consistent naming in external references for clarity.

app/packages/operators/src/types-internal.ts (1)

12-12: New ExecutionCancelCallback type provides clarity
Defining a dedicated type for the cancellation callback is a good practice for readability and reusability.

app/packages/operators/src/components/OperatorExecutionButton/index.tsx (6)

3-14: Imports are consistent with the new feature
Adding useCallback, useMemo, and the operator-related imports aligns with the new prompt and cancellation mechanics. No issues noted.


32-38: Validate destructured props
Lines 32, 35, and 38 introduce onCancel, prompt, and executorOptions. Confirm that all references in the component are typed correctly and that default values or checks are not needed.


53-60: Memoizing handler callbacks
Storing onSuccess and onError in operatorHandlers helps avoid unnecessary re-renders and ensures consistent references. Looks good.


87-91: Dynamic retrieval of executionOptions
Retrieving executionOptions from useOperatorExecutionOptions is aligned with the new approach. Ensure it reflects any changes triggered by prompt or cancellation.


99-99: Condition with no prompt
Falling back to direct execution is a logical alternative to the prompt-based flow. No immediate issues found.


106-107: Pass-through of onCancel and prompt
Ensures the OperatorExecutionTrigger can leverage the new callbacks. Looks consistent with the PR’s objectives.

app/packages/core/src/plugins/SchemaIO/components/OperatorExecutionButtonView.tsx (3)

14-14: LGTM! Type import follows best practices

The ExecutionCancelCallback type import is properly grouped with related execution callback types.


34-35: LGTM! Props follow existing conventions

The new on_cancel and prompt props are properly integrated and follow the established naming pattern.


114-115: LGTM! Button updates are well-structured

The new props are properly integrated, and the iconProps spreading is correctly implemented.

Also applies to: 119-119

@ritch ritch changed the title Add prompt on cancel Add on_cancel callback for operator prompt Jan 6, 2025
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

🧹 Nitpick comments (2)
app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (2)

Line range hint 11-36: Update JSDoc comments to reflect current props.

The component's documentation is outdated. It references removed props (operatorUri, onSuccess, onError, executionParams, executorOptions) and doesn't document new ones (onCancel, prompt, executionOptions).

Update the JSDoc to include:

  • @param executionOptions Array of execution options
  • @param onCancel Callback for when the prompt is canceled
  • @param prompt Flag to enable prompting behavior

Line range hint 69-85: Consider adding type safety for spread props.

While the implementation is correct, consider adding a type constraint for the spread operator {...props} to prevent passing unintended props to the Box component.

-  ...props
+  ...({} as Omit<React.ComponentProps<typeof Box>, keyof {
+    ref: unknown;
+    onClick: unknown;
+    children: unknown;
+  }>)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5a2c696 and bd739fd.

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

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: test / test-python (ubuntu-latest-m, 3.10)
  • GitHub Check: test / test-app
  • GitHub Check: build / build
  • GitHub Check: e2e / test-e2e
  • GitHub Check: lint / eslint
  • GitHub Check: build
🔇 Additional comments (1)
app/packages/operators/src/components/OperatorExecutionTrigger/index.tsx (1)

Line range hint 37-56: Implementation follows React best practices.

The component:

  • Correctly uses React hooks
  • Has clean separation of concerns
  • Implements proper event handling

Also applies to: 57-67

Copy link
Contributor

@imanjra imanjra left a comment

Choose a reason for hiding this comment

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

LGTM

@ritch ritch merged commit c5d3bf5 into develop Jan 7, 2025
14 checks passed
@ritch ritch deleted the prompt-on-cancel branch January 7, 2025 22:42
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