Skip to content

feat: added support for Custom GraphQL Actions for integrations that use GraphQL#41404

Merged
ashit-rath merged 5 commits intoreleasefrom
feat/support-custom-graphql-actions
Nov 25, 2025
Merged

feat: added support for Custom GraphQL Actions for integrations that use GraphQL#41404
ashit-rath merged 5 commits intoreleasefrom
feat/support-custom-graphql-actions

Conversation

@tomjose92
Copy link
Contributor

@tomjose92 tomjose92 commented Nov 22, 2025

Description

Adding support for Custom GraphQL Actions for integrations like Linear, Monday.com that use GraphQL

Fixes 41412

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/19646513282
Commit: 33c1d90
Cypress dashboard.
Tags: @tag.All
Spec:


Tue, 25 Nov 2025 03:26:44 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Added a dedicated configuration UI for custom GraphQL actions with Headers, Params, and Body (GraphQL query + variables) tabs and a new form type for GraphQL action configs.
    • Added new user-facing labels/buttons for adding custom GraphQL actions.
  • Bug Fixes

    • Dropdown now shows the appropriate "Add Custom" label when a GraphQL custom action option is present.
  • Chores

    • Updated imports/module paths and adjusted test import paths.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added the Enhancement New feature or request label Nov 22, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 22, 2025

Walkthrough

Adds a new Custom GraphQL action form control and message constants, registers the control in the form registry, updates dropdown import paths/behavior to surface GraphQL custom action option, and implements parameter↔path synchronization utilities used by custom action controls. (50 words)

Changes

Cohort / File(s) Summary
Messages
app/client/src/ce/constants/messages.ts
Added two new public message helpers: ADD_CUSTOM_GRAPHQL_ACTION() and CUSTOM_GRAPHQL_ACTION_LABEL().
Form control types
app/client/src/utils/formControl/formControlTypes.ts
Added CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM constant to form control types.
Form control registry
app/client/src/utils/formControl/FormControlRegistry.tsx
Updated import path for existing custom actions control, imported CustomGraphQLActionsControl, and registered builder mapping CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM to the new control.
New GraphQL control
app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx
New exported CustomGraphQLActionsControl component implementing a tabbed editor (HEADERS, PARAMS, BODY), with GraphQL body editor, variables editor, and useSyncParamsToPath integration.
Custom actions (common + existing control)
app/client/src/components/formControls/CustomActionControls/common.tsx, app/client/src/components/formControls/CustomActionControls/CustomActionsConfigControl.tsx
Added CUSTOM_ACTION_TABS, TabbedWrapper, useSyncParamsToPath, CustomActionFormLayout, parameter equivalence helper; existing CustomActionsControl uses the shared layout and sync utilities.
Dropdown imports & behaviour
app/client/src/components/formControls/DropDownControl/index.tsx, app/client/src/components/formControls/DropDownControl/DropDownControl.test.tsx, app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx
Adjusted relative import paths for BaseControl/ControlProps and tests; extended NoSearchCommandFound to detect GraphQL custom action option and toggle “Add Custom” button label/value between standard and GraphQL variants.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Registry as FormControlRegistry
  participant Control as CustomGraphQLActionsControl
  participant Common as CustomActionCommon (useSyncParamsToPath)
  participant Redux as Redux Store

  User->>Registry: request form for CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM
  Registry->>Control: instantiate control
  Control->>Common: init sync(formName, configProperty)
  Common->>Redux: read form data (getFormData)
  Control->>Redux: dispatch updates (autofill / setActionProperty) on user edits
  Redux->>Control: updated form values
  note right of Common `#a3be8c`: sync avoids loops via param equivalence checks
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to check closely:
    • useSyncParamsToPath: URL parsing, query-string construction, edge cases, and infinite-loop prevention
    • CustomGraphQLActionsControl: props/typed FormControl wiring and variables editor config (EXPECTED_VARIABLE)
    • NoSearchCommandFound: ensure correct value dispatched when GraphQL option selected
    • Import path adjustments: verify no broken module resolution in related builds/tests

Poem

✨ Tabs and queries knit the seam,
Paths and params hum in sync,
GraphQL joins the custom team,
New helpers, tabs — a tiny wink,
Code composes, tests will blink. 🎉

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ⚠️ Warning The PR description is missing critical template sections including motivation/context, dependencies, and has incomplete communication checkbox selection. Complete the description by adding: (1) motivation and context explaining why Custom GraphQL Actions are needed, (2) any dependencies required for this feature, (3) relevant documentation/Figma links, and (4) explicitly check the DevRel/Marketing communication checkbox.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature addition: support for Custom GraphQL Actions.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/support-custom-graphql-actions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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 (5)
app/client/src/components/formControls/DropDownControl.tsx (1)

501-530: Consider memoizing the hasCustomGraphQLAction check.

The options.some() check with case-insensitive string matching runs on every render of the dropdown. For large option lists, this could impact performance.

You could optimize this with useMemo:

+  const hasCustomGraphQLAction = useMemo(
+    () =>
+      options.some((option) =>
+        option.label
+          .toLowerCase()
+          .includes(createMessage(CUSTOM_GRAPHQL_ACTION_LABEL).toLowerCase()),
+      ),
+    [options],
+  );
+
   return (
     <Select
       ...
-      notFoundContent={(() => {
-        // Check if CUSTOM_GRAPHQL_ACTION is available in options
-        const hasCustomGraphQLAction = options.some((option) =>
-          option.label
-            .toLowerCase()
-            .includes(createMessage(CUSTOM_GRAPHQL_ACTION_LABEL).toLowerCase()),
-        );
-
+      notFoundContent={(() => {
         // Show GraphQL component if CUSTOM_GRAPHQL_ACTION is available
         if (hasCustomGraphQLAction) {
app/client/src/components/formControls/CustomGraphQLActionsConfigControl/NoSearchCommandFoundGraphQL.tsx (2)

39-42: Consider removing the non-null assertion.

While the guard on line 44 ensures customGraphQLActionOption exists, the non-null assertion (!) in onClick could be avoided by checking within the function or using optional chaining.

  const onClick = () => {
-   onSelectOptions(customGraphQLActionOption!.value);
+   if (customGraphQLActionOption) {
+     onSelectOptions(customGraphQLActionOption.value);
+   }
    document.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
  };

This makes the code more defensive without relying on external guards.


14-69: Note: Significant code duplication with NoSearchCommandFound.tsx.

This component is nearly identical to NoSearchCommandFound.tsx (referenced in the code snippets), differing only in the option label search (CUSTOM_GRAPHQL_ACTION_LABEL vs CUSTOM_ACTION_LABEL) and button text.

Consider extracting a shared base component to reduce duplication and maintenance burden.

app/client/src/components/formControls/CustomGraphQLActionsConfigControl/index.tsx (2)

163-172: Consider batching Redux dispatches.

The hook dispatches autofill and setActionProperty separately in multiple places, which could cause two re-renders per sync operation.

If performance becomes a concern, consider using batch from react-redux:

import { batch } from 'react-redux';

// Then wrap the dispatches:
batch(() => {
  dispatch(autofill(formName, `${configProperty}.params`, updatedParams));
  dispatch(setActionProperty({
    actionId: actionId,
    propertyName: `${configProperty}.params`,
    value: updatedParams,
  }));
});

Also applies to: 210-217


106-250: The bidirectional sync logic is complex but appears correct.

The useSyncParamsToPath hook handles synchronization between URL path and query parameters with proper guards against infinite loops. The use of refs and early returns is appropriate.

However, the hook is quite long (~140 lines). If you find yourself debugging sync issues in the future, consider splitting it into separate hooks for each direction (path-to-params and params-to-path).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa3fc71 and b99f593.

📒 Files selected for processing (6)
  • app/client/src/ce/constants/messages.ts (1 hunks)
  • app/client/src/components/formControls/CustomGraphQLActionsConfigControl/NoSearchCommandFoundGraphQL.tsx (1 hunks)
  • app/client/src/components/formControls/CustomGraphQLActionsConfigControl/index.tsx (1 hunks)
  • app/client/src/components/formControls/DropDownControl.tsx (2 hunks)
  • app/client/src/utils/formControl/FormControlRegistry.tsx (2 hunks)
  • app/client/src/utils/formControl/formControlTypes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-11-08T09:16:18.899Z
Learnt from: rahulbarwal
Repo: appsmithorg/appsmith PR: 37289
File: app/client/src/widgets/JSONFormWidget/fields/SelectField.tsx:201-201
Timestamp: 2024-11-08T09:16:18.899Z
Learning: In the `SelectField` component of the JSONForm widget (`app/client/src/widgets/JSONFormWidget/fields/SelectField.tsx`), the default fallback dropdown width of `100` is sufficient and does not need adjustment.

Applied to files:

  • app/client/src/components/formControls/DropDownControl.tsx
📚 Learning: 2024-10-24T08:38:20.429Z
Learnt from: ankitakinger
Repo: appsmithorg/appsmith PR: 37056
File: app/client/src/pages/Editor/JSEditor/JSObjectNameEditor/JSObjectNameEditor.tsx:22-25
Timestamp: 2024-10-24T08:38:20.429Z
Learning: "constants/AppConstants" does not export "SaveActionNameParams".

Applied to files:

  • app/client/src/ce/constants/messages.ts
🧬 Code graph analysis (4)
app/client/src/components/formControls/DropDownControl.tsx (3)
app/client/src/ce/constants/messages.ts (1)
  • CUSTOM_GRAPHQL_ACTION_LABEL (2725-2725)
app/client/src/components/formControls/CustomGraphQLActionsConfigControl/NoSearchCommandFoundGraphQL.tsx (1)
  • NoSearchCommandFoundGraphQL (14-69)
app/client/src/components/formControls/CustomActionsConfigControl/NoSearchCommandFound.tsx (1)
  • NoSearchCommandFound (14-69)
app/client/src/components/formControls/CustomGraphQLActionsConfigControl/NoSearchCommandFoundGraphQL.tsx (4)
app/client/packages/design-system/ads/src/Select/Select.types.ts (1)
  • SelectOptionProps (17-20)
app/client/src/entities/Plugin/index.ts (1)
  • Plugin (71-87)
app/client/src/ce/selectors/entitiesSelector.ts (1)
  • getPlugin (801-803)
app/client/src/ce/constants/messages.ts (5)
  • CONFIG_PROPERTY_COMMAND (2721-2721)
  • CUSTOM_GRAPHQL_ACTION_LABEL (2725-2725)
  • NO_SEARCH_COMMAND_FOUND_EXTERNAL_SAAS (2714-2715)
  • ADD_CUSTOM_GRAPHQL_ACTION (2719-2719)
  • NOT_FOUND (407-407)
app/client/src/components/formControls/CustomGraphQLActionsConfigControl/index.tsx (5)
app/client/src/actions/pluginActionActions.ts (1)
  • setActionProperty (316-323)
app/client/src/components/formControls/BaseControl.tsx (1)
  • ControlProps (52-57)
app/client/src/ce/constants/messages.ts (1)
  • API_EDITOR_TAB_TITLES (1418-1425)
app/client/src/components/editorComponents/CodeEditor/EditorConfig.ts (1)
  • EditorModes (13-24)
app/client/src/constants/PropertyControlConstants.tsx (1)
  • ControlType (17-17)
app/client/src/utils/formControl/FormControlRegistry.tsx (1)
app/client/src/components/formControls/CustomGraphQLActionsConfigControl/index.tsx (1)
  • CustomGraphQLActionsControl (368-411)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (4)
app/client/src/utils/formControl/FormControlRegistry.tsx (1)

55-55: LGTM! Clean registration of the new GraphQL control.

The import and registration follow the established patterns in the registry. The control type matches the constant defined in formControlTypes.ts.

Also applies to: 286-293

app/client/src/utils/formControl/formControlTypes.ts (1)

29-29: LGTM! Constant follows the established naming pattern.

The new form control type is properly defined and aligns with the registration in FormControlRegistry.tsx.

app/client/src/ce/constants/messages.ts (1)

2719-2720: LGTM! Message helpers are properly defined.

The new message constants follow the existing pattern and are well-placed alongside related custom action messages.

Also applies to: 2725-2726

app/client/src/components/formControls/CustomGraphQLActionsConfigControl/index.tsx (1)

368-411: LGTM! The control structure is clean.

The CustomGraphQLActionsControl class follows the expected pattern, with a simple render method that composes the method selector, path input, and tabbed controls.

@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 1, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

1 similar comment
@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 1, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

NilanshBansal
NilanshBansal previously approved these changes Nov 24, 2025
@NilanshBansal
Copy link
Contributor

@tomjose92 cyclic checks are failing on this PR, can you please check?

@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 1, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

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 (1)
app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1)

368-371: Avoid duplicating the control type string literal

getControlType() currently returns the hard‑coded string "CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM". To keep things consistent with the registry and reduce drift risk, consider reusing the shared constant (e.g., from formControlTypes) instead of a raw string literal.

-import type { ControlType } from "constants/PropertyControlConstants";
+import type { ControlType } from "constants/PropertyControlConstants";
+import formControlTypes from "utils/formControl/formControlTypes";
@@
   getControlType(): ControlType {
-    return "CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM";
+    return formControlTypes.CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM;
   }

Based on learnings, consolidating shared identifiers improves consistency across the codebase.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b99f593 and 26d845e.

📒 Files selected for processing (5)
  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1 hunks)
  • app/client/src/components/formControls/DropDownControl/DropDownControl.test.tsx (1 hunks)
  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx (3 hunks)
  • app/client/src/components/formControls/DropDownControl/index.tsx (2 hunks)
  • app/client/src/utils/formControl/FormControlRegistry.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-11-08T09:17:10.831Z
Learnt from: rahulbarwal
Repo: appsmithorg/appsmith PR: 37289
File: app/client/src/widgets/JSONFormWidget/fields/SelectField.test.tsx:137-138
Timestamp: 2024-11-08T09:17:10.831Z
Learning: In TypeScript test files like `SelectField.test.tsx`, it's acceptable to use the `delete` operator to remove mock objects such as `ResizeObserver` when their eventual removal is required.

Applied to files:

  • app/client/src/components/formControls/DropDownControl/DropDownControl.test.tsx
📚 Learning: 2024-07-26T21:12:57.228Z
Learnt from: KelvinOm
Repo: appsmithorg/appsmith PR: 29387
File: app/client/packages/design-system/widgets/src/components/TagGroup/src/Tag.tsx:9-9
Timestamp: 2024-07-26T21:12:57.228Z
Learning: The `CloseIcon` is being moved to a common directory for better reusability across components, following the suggestion to avoid importing it from the `Modal` component's directory.

Applied to files:

  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx
📚 Learning: 2024-10-08T15:32:34.115Z
Learnt from: ankitakinger
Repo: appsmithorg/appsmith PR: 36560
File: app/client/src/pages/Editor/JSEditor/JSObjectNameEditor.tsx:28-28
Timestamp: 2024-10-08T15:32:34.115Z
Learning: When type definitions like `SaveActionNameParams` are declared in multiple places, consolidating them by removing duplicates and reusing a single definition maintains consistency in the codebase.

Applied to files:

  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx
🧬 Code graph analysis (1)
app/client/src/utils/formControl/FormControlRegistry.tsx (1)
app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1)
  • CustomGraphQLActionsControl (368-411)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
🔇 Additional comments (4)
app/client/src/components/formControls/DropDownControl/DropDownControl.test.tsx (1)

3-3: Import path update for DropDownControl looks correct

The new relative import (../DropDownControl) matches the folder/module structure and keeps the test logic unchanged.

app/client/src/utils/formControl/FormControlRegistry.tsx (1)

54-55: Custom GraphQL actions control registration is consistent

The new imports and the builder for formControlTypes.CUSTOM_GRAPHQL_ACTIONS_CONFIG_FORM correctly mirror the pattern of existing controls and wire CustomGraphQLActionsControl into the registry.

Also applies to: 286-293

app/client/src/components/formControls/DropDownControl/index.tsx (1)

13-15: DropDownControl import rewiring aligns with new structure

Importing ControlProps/BaseControl from ../BaseControl and NoSearchCommandFound from ./NoSearchCommandFound matches the new layout without affecting runtime behavior.

Also applies to: 31-32

app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1)

76-250: Path/params sync hook for GraphQL actions looks robust

The combination of areParamsEquivalent, lastPathRef/lastParamsRef, and the one‑direction‑per‑run logic in useSyncParamsToPath should prevent infinite update loops while keeping path and params in sync (including clearing params when the URL loses its query part). This is a solid pattern for the GraphQL custom actions flow.

@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 2, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

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

♻️ Duplicate comments (1)
app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1)

54-157: Consider extracting shared tabbed layout between REST and GraphQL controls

Most of the tab list plus HEADERS/PARAMS TabPanel markup here is identical to TabbedControls in CustomActionsConfigControl.tsx (only the BODY content differs). You could push the common tab rendering into a helper in common.tsx so both controls stay lean and future changes don’t need to be edited in two places, echoing earlier feedback on this file.

🧹 Nitpick comments (5)
app/client/src/components/formControls/CustomActionControls/CustomActionsConfigControl.tsx (1)

16-73: TabbedControls composition and param/path sync look solid

The HEADERS/PARAMS/BODY tabs plus useSyncParamsToPath usage match the existing API editor pattern and should behave correctly. If you later want to reduce duplication between this and the GraphQL variant, you could extract the shared tab list + headers/params panels into a small helper in common.tsx.

app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (2)

47-52: GraphQL variables placeholder currently shows literal backslashes

Because the placeholder uses \\\\Take widget inputs using {{ }}, the editor will render this as \\Take widget inputs using {{ }}, which looks a bit odd. Consider changing this to plain instructional text (e.g. Take widget inputs using {{ }}) or another clearer hint instead of leading backslashes.

Also applies to: 143-143


163-183: Verify GRAPHQL_HTTP_METHOD_OPTIONS shape to avoid losing labels

Here you remap GRAPHQL_HTTP_METHOD_OPTIONS as { label: method.value, value: method.value }. If GRAPHQL_HTTP_METHOD_OPTIONS is already an array of { label, value }, this discards any custom labels and is redundant; you could likely pass the constant straight through. Conversely, if it’s an array of strings, method.value would be undefined. Please double‑check its type and adjust the mapping to preserve labels and avoid empty dropdown entries.

app/client/src/components/formControls/CustomActionControls/common.tsx (2)

44-69: Path↔params sync logic is robust; watch out only for duplicate keys

areParamsEquivalent plus useSyncParamsToPath correctly handle both “path edited” and “params edited” flows and use refs to avoid feedback loops when dispatching autofill / setActionProperty. One nuance: by collapsing params into key→value maps, multiple entries with the same key (e.g. ?a=1&a=2) will be treated as a single key; if any integration genuinely relies on duplicate query keys, you may eventually want a stricter, order‑preserving comparison.

Also applies to: 71-189


13-13: Avoid a FormControl↔control circular dependency and duplicated layout/types

This module (under components/formControls) exports controls that will be registered in FormControlRegistry, but it also imports and renders FormControl inside CustomActionFormLayout. Together with the new Custom*ActionsControl classes, that likely participates in a FormControl → registry → Custom*ActionsControl → common.tsx → FormControl cycle, which aligns with the cyclic‑check failures called out on the PR. To break the cycle and reduce duplication, consider moving CustomActionFormLayout (and the MethodOption / CustomActionFormLayoutProps definitions) into an existing non‑control module like the ActionForm/common.tsx you already have, and reuse it from there instead of re‑defining it here. Based on learnings, consolidating shared types/layouts also keeps them in one place.

Also applies to: 191-243

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26d845e and 5ffdd78.

📒 Files selected for processing (3)
  • app/client/src/components/formControls/CustomActionControls/CustomActionsConfigControl.tsx (1 hunks)
  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1 hunks)
  • app/client/src/components/formControls/CustomActionControls/common.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-09-26T06:52:44.158Z
Learnt from: ankitakinger
Repo: appsmithorg/appsmith PR: 36560
File: app/client/src/pages/Editor/JSEditor/JSObjectNameEditor.tsx:28-28
Timestamp: 2024-09-26T06:52:44.158Z
Learning: When type definitions like `SaveActionNameParams` are declared in multiple places, consolidating them by removing duplicates and reusing a single definition maintains consistency in the codebase.

Applied to files:

  • app/client/src/components/formControls/CustomActionControls/common.tsx
  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx
📚 Learning: 2024-12-03T10:13:43.282Z
Learnt from: ashit-rath
Repo: appsmithorg/appsmith PR: 37912
File: app/client/src/git/components/QuickActions/helpers.ts:22-25
Timestamp: 2024-12-03T10:13:43.282Z
Learning: In `app/client/src/git/components/QuickActions/helpers.ts`, the unnecessary `ts-ignore` comments will be removed in future PRs.

Applied to files:

  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx
📚 Learning: 2024-07-26T21:12:57.228Z
Learnt from: KelvinOm
Repo: appsmithorg/appsmith PR: 29387
File: app/client/packages/design-system/widgets/src/components/TagGroup/src/Tag.tsx:9-9
Timestamp: 2024-07-26T21:12:57.228Z
Learning: The `CloseIcon` is being moved to a common directory for better reusability across components, following the suggestion to avoid importing it from the `Modal` component's directory.

Applied to files:

  • app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx
🧬 Code graph analysis (3)
app/client/src/components/formControls/CustomActionControls/CustomActionsConfigControl.tsx (5)
app/client/src/components/formControls/BaseControl.tsx (1)
  • ControlProps (52-57)
app/client/src/components/formControls/CustomActionControls/common.tsx (1)
  • useSyncParamsToPath (71-189)
app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.styles.ts (1)
  • Tab (5-47)
app/client/src/ce/constants/messages.ts (1)
  • API_EDITOR_TAB_TITLES (1418-1425)
app/client/src/constants/PropertyControlConstants.tsx (1)
  • ControlType (17-17)
app/client/src/components/formControls/CustomActionControls/common.tsx (1)
app/client/src/actions/pluginActionActions.ts (1)
  • setActionProperty (316-323)
app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (9)
app/client/src/components/formControls/BaseControl.tsx (1)
  • ControlProps (52-57)
app/client/src/components/formControls/CustomActionControls/common.tsx (3)
  • useSyncParamsToPath (71-189)
  • TabbedWrapper (21-42)
  • CustomActionFormLayout (204-243)
app/client/src/ce/constants/messages.ts (1)
  • API_EDITOR_TAB_TITLES (1418-1425)
app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.styles.ts (1)
  • Tab (5-47)
app/client/src/PluginActionEditor/components/PluginActionForm/components/CommonEditorForm/styles.ts (1)
  • TabPanel (29-31)
app/client/src/components/editorComponents/WidgetQueryGeneratorForm/styles.tsx (1)
  • Section (25-25)
app/client/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/index.tsx (1)
  • Zone (35-35)
app/client/src/components/editorComponents/CodeEditor/EditorConfig.ts (1)
  • EditorModes (13-24)
app/client/src/constants/PropertyControlConstants.tsx (1)
  • ControlType (17-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-build / client-build
🔇 Additional comments (2)
app/client/src/components/formControls/CustomActionControls/CustomActionsConfigControl.tsx (1)

79-99: CustomActionsControl wiring into CustomActionFormLayout looks correct

Control type, HTTP method dropdown options, and the path placeholder are all wired consistently with the HTTP custom‑action use case; nothing blocking here.

app/client/src/components/formControls/CustomActionControls/CustomGraphQLActionsConfigControl.tsx (1)

112-154: GraphQL query and variables editors are wired consistently

The query and variables editors use the appropriate modes (GRAPHQL_WITH_BINDING, JSON_WITH_BINDING), dataTree paths, and evaluation labels, and they’re scoped to props.configProperty as expected, so the GraphQL BODY tab should integrate cleanly with the evaluation engine.

@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 2, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

@tomjose92 tomjose92 requested a review from ashit-rath November 24, 2025 12:08
@tomjose92 tomjose92 self-assigned this Nov 24, 2025
@tomjose92 tomjose92 added the ok-to-test Required label for CI label Nov 24, 2025
ashit-rath
ashit-rath previously approved these changes Nov 24, 2025
…lect option for customAction or customGraphQLAction.
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 (1)
app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx (1)

41-54: Remove non-null assertions and add defensive guard in onClick.

The ternary check addresses part of the previous concern, but the non-null assertions (!) on lines 50 and 51 still assume the selected option exists. While the isCustom check on line 58 prevents rendering when neither option exists, this creates tight coupling. If the guard logic changes during refactoring, the assertions could cause a runtime error.

Apply this diff for safer handling:

  const onClick = () => {
+   const selectedOption = customActionOption ?? customGraphQLActionOption;
+   if (!selectedOption) return;
+
-   onSelectOptions(
-     customActionOption
-       ? customActionOption!.value
-       : customGraphQLActionOption!.value,
-   );
+   onSelectOptions(selectedOption.value);
    document.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
  };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b0d6cd and 33c1d90.

📒 Files selected for processing (1)
  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx (3 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2024-12-10T10:53:17.146Z
Learnt from: brayn003
Repo: appsmithorg/appsmith PR: 38060
File: app/client/src/git/components/GitQuickActions/helpers/getPullButtonStatus.ts:16-24
Timestamp: 2024-12-10T10:53:17.146Z
Learning: In the `getPullBtnStatus` function (`app/client/src/git/components/GitQuickActions/helpers/getPullButtonStatus.ts`), default parameter values should be explicitly mentioned to handle component state properly, even if all props are required.

Applied to files:

  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx
📚 Learning: 2024-12-11T08:33:24.352Z
Learnt from: brayn003
Repo: appsmithorg/appsmith PR: 38088
File: app/client/src/git/components/GitQuickActions/BranchButton/index.tsx:72-74
Timestamp: 2024-12-11T08:33:24.352Z
Learning: In the 'BranchButton' component in 'app/client/src/git/components/GitQuickActions/BranchButton/index.tsx' (TypeScript, React), the `useEffect` hook that checks for label ellipsis does not need to include `currentBranch` in its dependency array.

Applied to files:

  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx
📚 Learning: 2024-12-11T08:31:10.356Z
Learnt from: brayn003
Repo: appsmithorg/appsmith PR: 38088
File: app/client/src/git/components/GitQuickActions/helpers/getPullButtonStatus.ts:16-21
Timestamp: 2024-12-11T08:31:10.356Z
Learning: In the file `app/client/src/git/components/GitQuickActions/helpers/getPullButtonStatus.ts`, when defining the function `getPullBtnStatus`, it's acceptable to use default parameters in destructuring. Do not suggest removing default parameters in this context.

Applied to files:

  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx
📚 Learning: 2024-12-03T10:13:43.282Z
Learnt from: ashit-rath
Repo: appsmithorg/appsmith PR: 37912
File: app/client/src/git/components/QuickActions/helpers.ts:22-25
Timestamp: 2024-12-03T10:13:43.282Z
Learning: In `app/client/src/git/components/QuickActions/helpers.ts`, the unnecessary `ts-ignore` comments will be removed in future PRs.

Applied to files:

  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx
📚 Learning: 2024-06-26T06:22:15.976Z
Learnt from: sharat87
Repo: appsmithorg/appsmith PR: 34471
File: app/client/src/ce/api/JSActionAPI.tsx:143-161
Timestamp: 2024-06-26T06:22:15.976Z
Learning: The `updateJSCollectionActionRefactor` method in `JSActionAPI.tsx` includes a check to ensure `action.datasource` is not null before manipulating its properties.

Applied to files:

  • app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx
🧬 Code graph analysis (1)
app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx (1)
app/client/src/ce/constants/messages.ts (3)
  • CUSTOM_GRAPHQL_ACTION_LABEL (2725-2725)
  • ADD_CUSTOM_ACTION (2717-2717)
  • ADD_CUSTOM_GRAPHQL_ACTION (2719-2719)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-build / client-build
🔇 Additional comments (1)
app/client/src/components/formControls/DropDownControl/NoSearchCommandFound.tsx (1)

47-52: Verify: Should GraphQL action be preferred over standard custom action?

When both customActionOption and customGraphQLActionOption exist, the current logic prefers the standard custom action (uses it in onClick and shows its label). Given this PR specifically adds GraphQL support, should GraphQL be the preferred choice instead?

If the current priority is intentional, this is fine. Otherwise, consider reversing the logic to prefer GraphQL:

  const onClick = () => {
+   const selectedOption = customGraphQLActionOption ?? customActionOption;
-   onSelectOptions(
-     customActionOption
-       ? customActionOption!.value
-       : customGraphQLActionOption!.value,
-   );
+   if (selectedOption) {
+     onSelectOptions(selectedOption.value);
+   }
    document.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
  };

And for the button label:

-         {customActionOption
-           ? createMessage(ADD_CUSTOM_ACTION)
-           : createMessage(ADD_CUSTOM_GRAPHQL_ACTION)}
+         {customGraphQLActionOption
+           ? createMessage(ADD_CUSTOM_GRAPHQL_ACTION)
+           : createMessage(ADD_CUSTOM_ACTION)}

Also applies to: 76-78

@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 2, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

@tomjose92 tomjose92 changed the title feat: added support for Custom GraphQL Actions for paragon integrations that use GraphQL feat: added support for Custom GraphQL Actions for integrations that use GraphQL Nov 25, 2025
@ashit-rath
Copy link
Contributor

The increase in the cyclic dependency cannot be avoided in this PR since the pattern used here is similar to existing patterns used for formControls and the scope of changes would be much larger. Force merging to bypass this check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request ok-to-test Required label for CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Support for Custom GraphQL for integrations that use GrahQL

3 participants