Skip to content

Conversation

@adolfo-pd
Copy link
Collaborator

@adolfo-pd adolfo-pd commented Dec 6, 2024

WHY

Summary by CodeRabbit

  • New Features

    • Introduced an asynchronous form submission handler to enhance form functionality.
    • Added dynamic styling for the submit button based on its state.
    • Enhanced form context with new properties for managing fields and validation.
    • Added functionality to disable the submit button when the form is incomplete.
  • Bug Fixes

    • Improved error handling and validation logic for app properties.
  • Documentation

    • Updated type definitions and added new functions to improve type safety and error handling within the app context.

@linear
Copy link

linear bot commented Dec 6, 2024

@vercel
Copy link

vercel bot commented Dec 6, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) Visit Preview Dec 10, 2024 7:29pm
pipedream-docs ⬜️ Ignored (Inspect) Dec 10, 2024 7:29pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Dec 10, 2024 7:29pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 2024

Warning

Rate limit exceeded

@adolfo-pd has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 46 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between a22d1f5 and 2226c51.

⛔ Files ignored due to path filters (1)
  • packages/connect-react/examples/nextjs/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • packages/connect-react/examples/nextjs/src/app/page.tsx (1 hunks)
  • packages/connect-react/src/components/InternalField.tsx (3 hunks)
  • packages/connect-react/src/hooks/form-context.tsx (8 hunks)
  • packages/connect-react/src/hooks/use-app.tsx (2 hunks)

Walkthrough

The pull request introduces several enhancements across multiple components and hooks related to form handling. Key updates include a new asynchronous onSubmit handler in the ComponentFormContainer, improved form submission state management in ControlSubmit, and the integration of field registration in InternalField. Additionally, the FormContext has been expanded with new properties and methods to manage form fields and their configurations. The useApp hook has also been enhanced with new types and functions for better type safety and error handling.

Changes

File Change Summary
packages/connect-react/examples/nextjs/src/app/page.tsx Introduced an asynchronous onSubmit handler in ComponentFormContainer to trigger client.actionRun on form submission.
packages/connect-react/src/components/ControlSubmit.tsx Modified form submission handling and dynamic styling for the submit button based on its state and configuration.
packages/connect-react/src/components/InternalField.tsx Added useEffect to register fields with the form context and updated destructuring to include registerField.
packages/connect-react/src/hooks/form-context.tsx Expanded FormContext with new properties (fields, propsNeedConfiguring) and methods (registerField). Updated error handling and state management logic.
packages/connect-react/src/hooks/use-app.tsx Introduced new types and functions for enhanced type safety and error handling in the useApp hook, including getCustomFields and appPropError.

Possibly related PRs

  • Fix dynamic props in the Connect demo app #14887: This PR modifies the DynamicProps and FormContext types to standardize property naming to camelCase, which is relevant to the changes in the main PR that also involve form handling and submission processes.

Suggested labels

bug, dependencies, tracked internally, prioritized

Suggested reviewers

  • jverce
  • tjk

🐇 In the meadow, forms do play,
With buttons bright and fields at bay.
A submit here, a register there,
Our hooks and contexts dance with flair!
So hop along, let’s code away,
For every change, a brighter day! 🌼


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. (Experiment)
  • @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
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: 4

🧹 Outside diff range and nitpick comments (6)
packages/connect-react/examples/nextjs/src/app/page.tsx (1)

Line range hint 11-14: Improve example code with proper authentication handling

The example uses a hard-coded userId which isn't representative of real-world authentication. Consider adding a comment explaining this is for demonstration purposes only.

-  const userId = "my-authed-user-id";
+  // NOTE: In production, userId should come from your authentication system
+  const userId = "my-authed-user-id"; // Demo purposes only
packages/connect-react/src/hooks/use-app.tsx (3)

7-7: Remove unused import 'PropValue'

The PropValue type imported from @pipedream/sdk is not used in this file. Removing unused imports helps keep the codebase clean.

Apply this diff to remove the unused import:

 import type {
   AppRequestResponse, AppResponse, ConfigurablePropApp,
-  PropValue,
 } from "@pipedream/sdk";

64-64: Remove debug statement console.log

The console.log statement appears to be leftover debugging code. It's recommended to remove it to keep the console output clean in production.

Apply this diff to remove the debug statement:

 export function appPropError(prop: ConfigurablePropApp, value: unknown, app: AppResponse | undefined): string | undefined {
-  console.log("appPropError", prop, value, app)

Line range hint 169-169: Remove unused generic type parameter 'T'

The generic type parameter <T extends ConfigurableProps> in the propErrors function is declared but not used. Removing it simplifies the function signature.

Apply this diff to remove the unused type parameter:

-const propErrors = <T extends ConfigurableProps>(prop: ConfigurableProp, value: unknown): string[] => {
+const propErrors = (prop: ConfigurableProp, value: unknown): string[] => {
packages/connect-react/src/hooks/form-context.tsx (2)

7-7: Remove unused import 'PropValue'

The PropValue type imported from @pipedream/sdk is not used in this file. Cleaning up unused imports enhances code readability.

Apply this diff to remove the unused import:

 import type {
   ComponentReloadPropsOpts, ConfigurableProp, ConfigurableProps, V1Component,
-  PropValue,
 } from "@pipedream/sdk";
🧰 Tools
🪛 eslint

[error] 7-7: 'PropValue' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 GitHub Check: Lint Code Base

[failure] 7-7:
'PropValue' is defined but never used


169-169: Remove unused generic type parameter 'T'

The generic type parameter <T extends ConfigurableProps> in the propErrors function is not utilized. Removing it simplifies the code.

Apply this diff to remove the unused type parameter:

-const propErrors = <T extends ConfigurableProps>(prop: ConfigurableProp, value: unknown): string[] => {
+const propErrors = (prop: ConfigurableProp, value: unknown): string[] => {
🧰 Tools
🪛 eslint

[error] 169-169: 'T' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 GitHub Check: Lint Code Base

[failure] 169-169:
'T' is defined but never used

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3d0e5ed and 44e42b8.

⛔ Files ignored due to path filters (1)
  • packages/connect-react/examples/nextjs/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • packages/connect-react/examples/nextjs/src/app/page.tsx (1 hunks)
  • packages/connect-react/src/components/ControlSubmit.tsx (2 hunks)
  • packages/connect-react/src/components/InternalField.tsx (3 hunks)
  • packages/connect-react/src/hooks/form-context.tsx (8 hunks)
  • packages/connect-react/src/hooks/use-app.tsx (2 hunks)
🧰 Additional context used
🪛 eslint
packages/connect-react/src/hooks/form-context.tsx

[error] 7-7: 'PropValue' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 169-169: 'T' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 GitHub Check: Lint Code Base
packages/connect-react/src/hooks/form-context.tsx

[failure] 7-7:
'PropValue' is defined but never used


[failure] 169-169:
'T' is defined but never used

🔇 Additional comments (2)
packages/connect-react/examples/nextjs/src/app/page.tsx (1)

33-38: Verify form field validation before submission

Given the PR's objective to "enable complete error checking", consider adding field validation before submitting the form.

Let's check how field validation is implemented in other examples:

packages/connect-react/src/components/InternalField.tsx (1)

Line range hint 343-344: Avoid mutating state directly when updating 'fields'

Directly mutating the fields state can lead to unexpected behavior. Instead, return a new object to maintain state immutability.

Apply this diff to avoid direct mutation:

 setFields((fields) => {
-  fields[field.prop.name] = field
-  return fields
+  return {
+    ...fields,
+    [field.prop.name]: field,
+  };
 });


function getCustomFields(app: AppResponse): AppCustomField[] {
const isOauth = app.auth_type === "oauth"
const userDefinedCustomFields = JSON.parse(app.custom_fields_json || "[]")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential JSON parsing errors

Using JSON.parse without error handling can throw exceptions if app.custom_fields_json contains invalid JSON. Consider adding error handling to prevent application crashes.

Apply this diff to add error handling:

 const isOauth = app.auth_type === "oauth"
-let userDefinedCustomFields = JSON.parse(app.custom_fields_json || "[]")
+let userDefinedCustomFields = [];
+try {
+  userDefinedCustomFields = JSON.parse(app.custom_fields_json || "[]");
+} catch (error) {
+  console.error("Failed to parse custom fields JSON:", error);
+}

Committable suggestion skipped: line range outside the PR's diff.

return <input type="submit" value={submitting
? "Submitting..."
: "Submit"} {...getProps("controlSubmit", baseStyles, props)} disabled={submitting} />;
: "Submit"} {...getProps("controlSubmit", baseStyles(propsNeedConfiguring.length || submitting), props)} disabled={propsNeedConfiguring.length || submitting} />;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the logic for 'disabled' and 'opacity' properties

The current logic may not correctly determine the disabled state due to type differences. Also, the opacity should reflect the disabled state.

Apply this diff to fix the logic:

 const disabled = propsNeedConfiguring.length > 0 || submitting;

 return <input type="submit" value={submitting
   ? "Submitting..."
-  : "Submit"} {...getProps("controlSubmit", baseStyles(propsNeedConfiguring.length || submitting), props)} disabled={propsNeedConfiguring.length || submitting} />;
+  : "Submit"} {...getProps("controlSubmit", baseStyles(disabled), props)} disabled={disabled} />;

Update the baseStyles function to use disabled for opacity:

 opacity: disabled
   ? 0.5
   : undefined,

Committable suggestion skipped: line range outside the PR's diff.

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 (3)
packages/connect-react/CHANGELOG.md (1)

4-7: Consider expanding the changelog entry with implementation details.

The changelog entry is clear and follows the established format. However, it could be more helpful to users by including:

  • What determines if a form is "incomplete"
  • Which components are affected (e.g., ControlSubmit)
  • Any breaking changes in form behavior
 # [1.0.0-preview.8] - 2024-12-09

-Disabled submit button when form is incomplete
+- Disabled submit button when form validation fails or required fields are empty
+- Enhanced ControlSubmit component to respect form state
+- Added form field registration to improve validation
packages/connect-react/src/hooks/use-app.tsx (2)

30-41: Add JSDoc comments to improve type documentation

While the types are well-structured, adding JSDoc comments would improve code maintainability and help other developers understand the purpose of each type.

Apply this diff:

+/**
+ * Extends AppResponse to include extracted custom field names
+ */
 type AppResponseWithExtractedCustomFields = AppResponse & {
   extracted_custom_fields_names: string[]
 }

+/**
+ * Represents a custom field configuration for an app
+ * @property name - The name of the custom field
+ * @property optional - Whether the field is optional during configuration
+ */
 type AppCustomField = {
   name: string
   optional?: boolean
 }

+/**
+ * Extends PropValue<"app"> to include OAuth specific properties
+ */
 type OauthAppPropValue = PropValue<"app"> & {
   oauth_access_token?: string
 }

63-89: Improve error handling and code structure

The function could benefit from:

  1. More descriptive error messages
  2. Simplified conditional logic
  3. Explicit return types for all code paths

Consider this improved implementation:

 export function appPropError(prop: ConfigurablePropApp, value: unknown, app: AppResponse | undefined): string | undefined {
   if (!app) {
-    return "app field not registered"
+    return "App configuration is missing or not registered"
   }
   if (!value) {
-    return "no app configured"
+    return "App value is not configured"
   }
   if (typeof value !== "object") {
-    return "not an app"
+    return "Invalid app value type: expected object"
   }
   const _value = value as PropValue<"app">
-  if ("authProvisionId" in _value && !_value.authProvisionId) {
-    if (app.auth_type) {
-      if (app.auth_type === "oauth" && !(_value as OauthAppPropValue).oauth_access_token) {
-        return "missing oauth token"
-      }
-      if (app.auth_type === "oauth" || app.auth_type === "keys") {
-        for (const cf of getCustomFields(app)) {
-          if (!cf.optional && !_value[cf.name]) {
-            return "missing custom field"
-          }
-        }
-      }
-      return "no auth provision configured"
+  
+  // Early return if authProvisionId is present
+  if (!("authProvisionId" in _value) || _value.authProvisionId) {
+    return undefined;
+  }
+  
+  if (!app.auth_type) {
+    return undefined;
+  }
+  
+  // OAuth specific validation
+  if (app.auth_type === "oauth" && !(_value as OauthAppPropValue).oauth_access_token) {
+    return "OAuth access token is required but missing"
+  }
+  
+  // Custom fields validation for OAuth and keys auth types
+  if (app.auth_type === "oauth" || app.auth_type === "keys") {
+    const missingField = getCustomFields(app).find(cf => !cf.optional && !_value[cf.name]);
+    if (missingField) {
+      return `Required custom field "${missingField.name}" is missing`
     }
   }
+  
+  return "Authentication provision is not configured"
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 44e42b8 and a22d1f5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/connect-react/CHANGELOG.md (1 hunks)
  • packages/connect-react/src/hooks/use-app.tsx (2 hunks)
🔇 Additional comments (2)
packages/connect-react/src/hooks/use-app.tsx (2)

5-8: LGTM: Type imports are well-structured

The imported types from @pipedream/sdk are appropriate for the functionality being implemented.


43-61: ⚠️ Potential issue

Add error handling and input validation

The function has several potential issues that need to be addressed:

  1. Unsafe JSON parsing (previously flagged)
  2. Missing validation for extracted_custom_fields_names
  3. Direct array mutation with spread operator

Apply this diff to fix these issues:

 function getCustomFields(app: AppResponse): AppCustomField[] {
   const isOauth = app.auth_type === "oauth"
-  const userDefinedCustomFields = JSON.parse(app.custom_fields_json || "[]")
+  let userDefinedCustomFields: AppCustomField[] = [];
+  try {
+    userDefinedCustomFields = JSON.parse(app.custom_fields_json || "[]");
+  } catch (error) {
+    console.error("Failed to parse custom fields JSON:", error);
+  }
+
   if ("extracted_custom_fields_names" in app && app.extracted_custom_fields_names) {
-    const extractedCustomFields = ((app as AppResponseWithExtractedCustomFields).extracted_custom_fields_names || []).map(
+    const extractedCustomFields = Array.isArray(app.extracted_custom_fields_names) 
+      ? app.extracted_custom_fields_names.map(
       (name) => ({
         name,
       }),
-    )
-    userDefinedCustomFields.push(...extractedCustomFields)
+    ) : [];
+    userDefinedCustomFields = [...userDefinedCustomFields, ...extractedCustomFields];
   }
   return userDefinedCustomFields.map((cf: AppCustomField) => {
     return {
       ...cf,
       // if oauth, treat all as optional (they are usually needed for getting access token)
       optional: cf.optional || isOauth,
     }
   })
 }

adolfo-pd and others added 2 commits December 10, 2024 10:33
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@adolfo-pd adolfo-pd merged commit 84bba87 into master Dec 10, 2024
7 of 8 checks passed
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.

4 participants