Skip to content

Conversation

ankitakinger
Copy link
Contributor

@ankitakinger ankitakinger commented Jun 3, 2025

Description

Adding debounce to onValueChange for input widgets to fix multiple Execute API calls happening in reactive queries flow.

Fixes #40813

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/15486342735
Commit: 6943ba5
Cypress dashboard.
Tags: @tag.All
Spec:


Fri, 06 Jun 2025 09:40:52 UTC

Communication

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

  • Yes
  • No

Summary by CodeRabbit

  • New Features
    • Input widgets now update their displayed values instantly while saving changes in the background with a short delay, improving typing responsiveness.
    • Input changes are grouped and saved after a brief pause, reducing unnecessary updates and enhancing performance.
  • Bug Fixes
    • Input fields now stay in sync with external updates and clear any pending background updates when needed, preventing outdated or duplicate changes.
  • Chores
    • Improved cleanup of background processes when input widgets are removed, ensuring smoother operation.
  • Tests
    • Added typing delays in input simulation during Cypress tests to better mimic real user input timing.

@ankitakinger ankitakinger requested a review from a team as a code owner June 3, 2025 11:48
@ankitakinger ankitakinger requested review from vivek-appsmith and removed request for a team June 3, 2025 11:48
Copy link
Contributor

coderabbitai bot commented Jun 3, 2025

Walkthrough

This change introduces internal state management and debounced input handling for several input-related widgets. Each widget now maintains its own inputValue state, synchronizes it with external prop changes, and updates meta properties and events using a debounced function. This decouples immediate UI response from meta property updates, ensuring consistency and reducing redundant updates.

Changes

Files Change Summary
app/client/src/widgets/CurrencyInputWidget/widget/index.tsx
app/client/src/widgets/InputWidget/widget/index.tsx
app/client/src/widgets/InputWidgetV2/widget/index.tsx
app/client/src/widgets/PhoneInputWidget/widget/index.tsx
app/client/src/widgets/RichTextEditorWidget/widget/index.tsx
Added internal inputValue state, debounced input handling, lifecycle methods for synchronization and cleanup, and updated rendering to use internal state.
app/client/src/widgets/wds/WDSCurrencyInputWidget/widget/index.tsx
app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx
app/client/src/widgets/wds/WDSPhoneInputWidget/widget/index.tsx
Added internal state for input value, debounced meta property updates, synchronization with props, and cleanup on unmount.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Widget
    participant MetaProps

    User->>Widget: Type input
    Widget->>Widget: Update internal inputValue state
    Widget-->>User: UI updates immediately
    Widget->>Widget: Start debounce timer (300ms)
    Note over Widget: User may continue typing<br>debounce resets
    Widget->>MetaProps: (After 300ms) Update meta properties & trigger events
Loading

Assessment against linked issues

Objective Addressed Explanation
Prevent UI from showing widgets being updated multiple times after query execution (#40813) The changes improve input widget state management and debouncing, but it is unclear if they directly resolve the issue with table/query UI updates described in the linked issue.

Suggested labels

Widgets Product, Enhancement, Task, ok-to-test

Suggested reviewers

  • AmanAgarwal041
  • rahulbarwal

Poem

Widgets now wait, no rush in their flow,
Debounced and steady, their updates now go.
Internal state keeps the UI bright,
While props and events sync out of sight.
No more double flashes—just input delight!
⏳✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

@ankitakinger ankitakinger removed the request for review from vivek-appsmith June 3, 2025 11:48
@ankitakinger ankitakinger added the ok-to-test Required label for CI label Jun 3, 2025
@github-actions github-actions bot added Bug Something isn't working Integrations Pod General Issues related to the Integrations Pod that don't fit into other tags. Integrations Pod Integrations Product Issues related to a specific integration Needs Triaging Needs attention from maintainers to triage Query Widgets & IDE Pod All issues related to Query, JS, Eval, Widgets & IDE labels Jun 3, 2025
@ankitakinger
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions github-actions bot added skip-changelog Adding this label to a PR prevents it from being listed in the changelog and removed Bug Something isn't working labels Jun 3, 2025
Copy link

github-actions bot commented Jun 3, 2025

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/15416479456.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40849.
recreate: .

@github-actions github-actions bot added Bug Something isn't working and removed Bug Something isn't working labels Jun 3, 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: 3

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a98198d and 12ac137.

📒 Files selected for processing (1)
  • app/client/src/widgets/BaseInputWidget/component/index.tsx (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (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-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (4)
app/client/src/widgets/BaseInputWidget/component/index.tsx (4)

12-12: LGTM!

The debounce import is correctly added for the new functionality.


489-491: LGTM!

The event handlers correctly update the internal state immediately for UI responsiveness while debouncing the actual value change callback.

Also applies to: 494-496


579-579: LGTM!

All input components consistently use the internal inputValue state, which is necessary for the debouncing mechanism to work correctly.

Also applies to: 601-601, 630-630


778-778: LGTM!

The interface is correctly updated to include the new state property.

Copy link

github-actions bot commented Jun 3, 2025

Deploy-Preview-URL: https://ce-40849.dp.appsmith.com

@github-actions github-actions bot added the Bug Something isn't working label Jun 3, 2025
@ankitakinger
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

github-actions bot commented Jun 3, 2025

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/15418443754.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40849.
recreate: .

@github-actions github-actions bot removed the Bug Something isn't working label Jun 3, 2025
Copy link

github-actions bot commented Jun 3, 2025

Deploy-Preview-URL: https://ce-40849.dp.appsmith.com

@github-actions github-actions bot added the Bug Something isn't working label Jun 3, 2025
@ankitakinger ankitakinger requested a review from a team as a code owner June 4, 2025 08:21
@github-actions github-actions bot removed the Bug Something isn't working label Jun 4, 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: 2

🧹 Nitpick comments (7)
app/client/src/widgets/wds/WDSPhoneInputWidget/widget/index.tsx (1)

241-258: Debounced updates implemented correctly.

The 300ms delay should effectively batch updates and reduce API calls. Consider making this delay configurable in the future if different widgets need different responsiveness.

app/client/src/widgets/InputWidgetV2/widget/index.tsx (1)

21-21: Consider the static analysis warning about toString.

While importing toString from lodash works, it shadows the global toString property. Since you're not using it in this file, consider removing it from the imports to avoid confusion.

-import { debounce, isNil, isNumber, merge, toString } from "lodash";
+import { debounce, isNil, isNumber, merge } from "lodash";
🧰 Tools
🪛 Biome (1.9.4)

[error] 21-21: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (1)

208-231: Consider making the debounce delay configurable.

The 300ms delay works well for most cases, but different use cases might benefit from different delays. Consider extracting this as a configurable constant or prop in the future.

app/client/src/widgets/InputWidget/widget/index.tsx (1)

898-910: Note the TODO about converting text to derived property.

The comment indicates future refactoring plans. This debounced approach will need adjustment when text becomes a derived property for List widget compatibility.

app/client/src/widgets/RichTextEditorWidget/widget/index.tsx (1)

1-625: Consider extracting the debouncing pattern into a reusable hook.

Since this exact pattern is duplicated across multiple input widgets (InputWidget, WDSInputWidget, RichTextEditor, and others mentioned in the PR), consider creating a custom hook like useDebounedInput to reduce code duplication and ensure consistency.

Example implementation:

function useDebouncedInput(
  initialValue: string,
  externalValue: string,
  onDebouncedChange: (value: string) => void,
  delay: number = 300
) {
  const [inputValue, setInputValue] = useState(initialValue);
  const debouncedChange = useMemo(
    () => debounce(onDebouncedChange, delay),
    [onDebouncedChange, delay]
  );

  useEffect(() => {
    setInputValue(externalValue);
    debouncedChange.cancel();
  }, [externalValue]);

  useEffect(() => {
    return () => debouncedChange.cancel();
  }, []);

  const handleChange = useCallback((value: string) => {
    setInputValue(value);
    debouncedChange(value);
  }, [debouncedChange]);

  return [inputValue, handleChange] as const;
}
app/client/src/widgets/PhoneInputWidget/widget/index.tsx (1)

427-443: Consider making debounce delay configurable

The 300ms delay is hardcoded. Different use cases might benefit from different delays.

Consider extracting the delay as a constant or making it configurable:

+const DEBOUNCE_DELAY = 300;
+
 debouncedOnValueChange = debounce((value: string) => {
   this.props.updateWidgetMetaProperty(
     "value",
     parseIncompletePhoneNumber(value),
   );
   this.props.updateWidgetMetaProperty("text", value, {
     triggerPropertyName: "onTextChanged",
     dynamicString: this.props.onTextChanged,
     event: {
       type: EventType.ON_TEXT_CHANGE,
     },
   });
 
   if (!this.props.isDirty) {
     this.props.updateWidgetMetaProperty("isDirty", true);
   }
-}, 300);
+}, DEBOUNCE_DELAY);
app/client/src/widgets/CurrencyInputWidget/widget/index.tsx (1)

528-541: Consider extracting debounce delay constant

Same as PhoneInputWidget, the 300ms delay should be configurable or at least extracted as a constant for maintainability.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e326886 and 8e5d3fa.

📒 Files selected for processing (8)
  • app/client/src/widgets/CurrencyInputWidget/widget/index.tsx (7 hunks)
  • app/client/src/widgets/InputWidget/widget/index.tsx (5 hunks)
  • app/client/src/widgets/InputWidgetV2/widget/index.tsx (6 hunks)
  • app/client/src/widgets/PhoneInputWidget/widget/index.tsx (7 hunks)
  • app/client/src/widgets/RichTextEditorWidget/widget/index.tsx (5 hunks)
  • app/client/src/widgets/wds/WDSCurrencyInputWidget/widget/index.tsx (6 hunks)
  • app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (6 hunks)
  • app/client/src/widgets/wds/WDSPhoneInputWidget/widget/index.tsx (6 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/client/src/widgets/InputWidget/widget/index.tsx (1)
app/client/src/widgets/BaseWidget.tsx (1)
  • WidgetState (453-453)
🪛 Biome (1.9.4)
app/client/src/widgets/InputWidgetV2/widget/index.tsx

[error] 21-21: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx

[error] 2-2: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-build / client-build
🔇 Additional comments (31)
app/client/src/widgets/wds/WDSPhoneInputWidget/widget/index.tsx (4)

24-37: State management looks good.

The addition of the internal state interface and initialization properly manages the input value locally, allowing for immediate UI updates while deferring meta property updates.


183-189: Proper synchronization with external prop changes.

Good implementation of canceling pending debounced calls when the value is updated externally. This prevents race conditions and stale updates.


224-227: Essential cleanup on unmount.

Canceling the debounced function prevents memory leaks and side effects after the component unmounts.


259-271: Clean separation of UI updates from meta updates.

The immediate state update ensures responsive UI while the debounced function handles the meta property updates, effectively addressing the multiple API calls issue.

Also applies to: 328-328

app/client/src/widgets/InputWidgetV2/widget/index.tsx (4)

302-313: State management properly implemented.

The internal state structure and initialization follow the same pattern as other input widgets, ensuring consistency across the codebase.


714-719: Lifecycle method correctly handles prop synchronization.

Good implementation of state synchronization and cleanup of pending debounced calls when the input value is updated externally.


746-773: Debounced updates with proper cleanup.

Good implementation with helpful context about why text isn't a derived property. The cleanup in componentWillUnmount prevents memory leaks.


775-778: UI responsiveness maintained with debounced meta updates.

The separation of immediate state updates from debounced meta property updates ensures a responsive user experience while reducing API calls.

Also applies to: 813-813

app/client/src/widgets/wds/WDSCurrencyInputWidget/widget/index.tsx (4)

34-45: State management follows established pattern.

Good consistency with other input widgets while maintaining the currency input's specific initialization from rawText.


163-196: Lifecycle methods properly handle cleanup and synchronization.

The implementation correctly maintains currency-specific logic while adding the debounced update pattern. Good cleanup in both componentDidUpdate and componentWillUnmount.


197-212: Debounced function correctly handles raw and formatted values.

Good separation of concerns by passing both the raw value and formatted value to the debounced function, maintaining the widget's dual-value nature.


213-233: Currency formatting preserved with debounced updates.

The implementation successfully maintains decimal limiting and formatting logic while adding the debounce pattern. Good error handling with telemetry capture.

Also applies to: 349-349

🧰 Tools
🪛 Biome (1.9.4)

[error] 218-218: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (6)

2-2: Import looks good.

The debounce import from lodash is appropriate for the debouncing functionality being added.

🧰 Tools
🪛 Biome (1.9.4)

[error] 2-2: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


18-30: State management implementation is well-structured.

The internal state for inputValue provides proper decoupling between UI updates and meta property changes. Good use of nullish coalescing for the fallback value.


170-175: Excellent handling of prop synchronization.

The cancellation of pending debounced calls when props change externally prevents race conditions and stale updates. This ensures data consistency.


204-207: Good cleanup practice.

Canceling debounced calls on unmount prevents memory leaks and potential errors from updates after component destruction.


232-235: Clean separation of concerns.

Immediate state update ensures responsive UI while debounced meta updates reduce unnecessary API calls.


256-259: Correct use of internal state for rendering.

Using the internal inputValue state ensures immediate UI updates without waiting for prop updates.

app/client/src/widgets/InputWidget/widget/index.tsx (3)

158-169: Lifecycle methods properly implemented.

State synchronization and cleanup follow the same robust pattern as other input widgets.


912-915: Consistent implementation of value change handler.

Follows the established pattern for immediate UI updates with debounced meta updates.


992-999: Proper state usage in formatting logic.

All value references correctly use the internal inputValue state, ensuring consistent display even during debounced updates.

app/client/src/widgets/RichTextEditorWidget/widget/index.tsx (4)

52-66: State management consistent with other input widgets.

The RichTextEditor follows the same internal state pattern for managing input values.


506-522: Lifecycle methods handle RTE-specific logic well.

The implementation maintains the debouncing pattern while properly handling the widget's defaultText and isDirty state management.


523-540: Debouncing implementation adapted for RTE.

The implementation correctly handles the RichTextEditor's state updates with the same debouncing benefits.


562-566: Render correctly uses internal state.

The markdown conversion is properly applied to the internal state value before rendering.

app/client/src/widgets/PhoneInputWidget/widget/index.tsx (3)

87-100: State initialization looks good

The internal state management pattern is correctly implemented with proper initialization from props.


369-375: Proper state synchronization with external updates

Good implementation of syncing internal state when props change externally and canceling pending debounced calls to prevent stale updates.


410-413: Correct cleanup on unmount

Properly canceling debounced calls prevents memory leaks and unexpected behavior.

app/client/src/widgets/CurrencyInputWidget/widget/index.tsx (3)

157-168: Consistent state management implementation

Good implementation following the same pattern as PhoneInputWidget.


469-474: Proper state sync and cleanup

Correctly handles external prop changes and cancels pending debounced calls.


650-650: Good null safety handling

Using nullish coalescing operator ensures the value is always a string.

@ankitakinger ankitakinger removed the ok-to-test Required label for CI label Jun 5, 2025
@github-actions github-actions bot added the Bug Something isn't working label Jun 5, 2025
@github-actions github-actions bot removed the Bug Something isn't working label Jun 5, 2025
@ankitakinger ankitakinger added the ok-to-test Required label for CI label Jun 5, 2025
@github-actions github-actions bot added the Bug Something isn't working label Jun 5, 2025
@ankitakinger ankitakinger requested review from sneha122 and removed request for a team June 6, 2025 07:40
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 (3)
app/client/src/widgets/InputWidgetV2/widget/index.tsx (1)

21-21: Address the shadowing of global toString property.

The static analysis tool correctly identifies that importing toString from lodash shadows the global toString property, which can lead to confusion about the origin of the function.

Consider using a more specific import or aliasing:

-import { debounce, isNil, isNumber, merge, toString } from "lodash";
+import { debounce, isNil, isNumber, merge, toString as toStr } from "lodash";

Then update usage throughout the file from toString to toStr.

🧰 Tools
🪛 Biome (1.9.4)

[error] 21-21: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (1)

2-2: Address the shadowing of global toString property.

Same issue as in InputWidgetV2 - importing toString from lodash shadows the global property.

Apply the same fix:

-import { debounce, isNumber, merge, toString } from "lodash";
+import { debounce, isNumber, merge, toString as toStr } from "lodash";
🧰 Tools
🪛 Biome (1.9.4)

[error] 2-2: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

app/client/src/widgets/CurrencyInputWidget/widget/index.tsx (1)

15-15: Address the shadowing of global toString property.

Same static analysis issue - the lodash toString import shadows the global property.

Apply the same fix as other files:

-import _, { debounce } from "lodash";
+import _, { debounce, toString as toStr } from "lodash";

And update any toString usage to toStr.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 75a9ad7 and 6943ba5.

📒 Files selected for processing (13)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_spec.js (2 hunks)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js (3 hunks)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_Nested_EventBindings_spec.js (3 hunks)
  • app/client/cypress/support/Pages/AggregateHelper.ts (4 hunks)
  • app/client/src/constants/WidgetConstants.tsx (1 hunks)
  • app/client/src/widgets/CurrencyInputWidget/widget/index.tsx (8 hunks)
  • app/client/src/widgets/InputWidget/widget/index.tsx (6 hunks)
  • app/client/src/widgets/InputWidgetV2/widget/index.tsx (7 hunks)
  • app/client/src/widgets/PhoneInputWidget/widget/index.tsx (8 hunks)
  • app/client/src/widgets/RichTextEditorWidget/widget/index.tsx (5 hunks)
  • app/client/src/widgets/wds/WDSCurrencyInputWidget/widget/index.tsx (6 hunks)
  • app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (6 hunks)
  • app/client/src/widgets/wds/WDSPhoneInputWidget/widget/index.tsx (6 hunks)
✅ Files skipped from review due to trivial changes (2)
  • app/client/src/constants/WidgetConstants.tsx
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_spec.js
🚧 Files skipped from review as they are similar to previous changes (8)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_Nested_EventBindings_spec.js
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js
  • app/client/cypress/support/Pages/AggregateHelper.ts
  • app/client/src/widgets/wds/WDSCurrencyInputWidget/widget/index.tsx
  • app/client/src/widgets/InputWidget/widget/index.tsx
  • app/client/src/widgets/PhoneInputWidget/widget/index.tsx
  • app/client/src/widgets/wds/WDSPhoneInputWidget/widget/index.tsx
  • app/client/src/widgets/RichTextEditorWidget/widget/index.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
app/client/src/widgets/InputWidgetV2/widget/index.tsx (3)
app/client/src/widgets/BaseWidget.tsx (1)
  • WidgetState (453-453)
app/client/src/widgets/InputWidget/widget/index.tsx (1)
  • InputWidgetProps (1114-1156)
app/client/src/constants/WidgetConstants.tsx (1)
  • DEBOUNCE_WAIT_TIME_ON_INPUT_CHANGE (284-284)
app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (3)
app/client/src/widgets/BaseWidget.tsx (1)
  • WidgetState (453-453)
app/client/src/widgets/InputWidget/widget/index.tsx (1)
  • InputWidgetProps (1114-1156)
app/client/src/constants/WidgetConstants.tsx (1)
  • DEBOUNCE_WAIT_TIME_ON_INPUT_CHANGE (284-284)
🪛 Biome (1.9.4)
app/client/src/widgets/InputWidgetV2/widget/index.tsx

[error] 21-21: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx

[error] 2-2: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (16)
app/client/src/widgets/InputWidgetV2/widget/index.tsx (7)

305-307: LGTM on the state interface extension.

The interface correctly extends WidgetState with the inputValue property needed for internal state management.


314-314: Good initialization of internal state.

The constructor properly initializes inputValue from the inputText prop with appropriate fallback to empty string.


717-721: Excellent external prop synchronization logic.

The componentDidUpdate implementation correctly:

  • Syncs internal state when external inputText prop changes
  • Cancels pending debounced calls to prevent stale updates

This ensures the widget stays in sync with external changes while preventing conflicts.


749-751: Good cleanup practice.

Properly canceling the debounced function in componentWillUnmount prevents memory leaks and unwanted updates after unmounting.


754-777: Well-implemented debounced update function.

The debounced function correctly:

  • Updates meta properties (text, inputText, isDirty)
  • Triggers events only when necessary
  • Uses the appropriate debounce delay constant

This addresses the core issue of multiple Execute API calls in reactive queries.


779-782: Perfect separation of immediate UI updates and debounced meta updates.

The onValueChange method correctly:

  • Updates internal state immediately for responsive UI
  • Defers meta property updates via debounced function

This approach provides the best of both worlds - immediate visual feedback and optimized API calls.


817-817: Correct usage of internal state for rendering.

Using this.state.inputValue instead of the prop ensures the input displays the most current user input before meta property updates are processed.

app/client/src/widgets/wds/WDSInputWidget/widget/index.tsx (4)

19-21: Consistent state management implementation.

The state interface and constructor follow the same solid pattern as InputWidgetV2, appropriately using rawText for the WDS variant.

Also applies to: 23-30


171-175: Proper external prop synchronization.

Correctly syncs inputValue with rawText prop changes and cancels pending debounced calls, maintaining consistency with the other widget implementations.


205-207: Well-implemented lifecycle management and debounced updates.

The cleanup in componentWillUnmount and the debounced function implementation are consistent with the pattern established in other widgets.

Also applies to: 210-232


234-237: Excellent implementation of immediate state updates with debounced meta updates.

The onValueChange and getWidgetView methods correctly implement the pattern of immediate UI responsiveness with optimized backend updates.

Also applies to: 260-260

app/client/src/widgets/CurrencyInputWidget/widget/index.tsx (5)

160-162: Consistent state management for currency input.

The state interface and constructor correctly follow the established pattern, appropriately using the text prop for currency widgets.

Also applies to: 168-171


472-476: Proper synchronization with currency text property.

The componentDidUpdate logic correctly syncs with the text prop and cancels pending debounced calls, maintaining consistency with other widget implementations.


502-504: Well-implemented debounced updates for currency input.

The cleanup and debounced function correctly handle currency-specific meta property updates while following the established pattern.

Also applies to: 532-545


565-566: Excellent integration of currency formatting with debounced updates.

The onValueChange method correctly:

  • Applies currency-specific formatting (decimal separator handling)
  • Updates internal state immediately for UI responsiveness
  • Triggers debounced meta property updates

The currency formatting logic is appropriately preserved while implementing the debounce optimization.


654-654: Correct usage of internal state for currency display.

Using this.state.inputValue ensures the currency input shows the most current formatted value before meta updates are processed.

Copy link
Contributor

@sneha122 sneha122 left a comment

Choose a reason for hiding this comment

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

LGTM

@ankitakinger ankitakinger merged commit fde8d01 into release Jun 6, 2025
83 checks passed
@ankitakinger ankitakinger deleted the chore/debounce-input-change branch June 6, 2025 10:21
ankitakinger added a commit that referenced this pull request Jun 11, 2025
…t widgets (#40922)

## Description

Reverting the change to add debounce to `onValueChange` for input
widgets. (Reverting PR:
[#40849](#40849))

Fixes [#40912](#40912)

## Automation

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

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!IMPORTANT]
> 🟣 🟣 🟣 Your tests are running.
> Tests running at:
<https://github.com/appsmithorg/appsmith/actions/runs/15583889634>
> Commit: 49e570b
> Workflow: `PR Automation test suite`
> Tags: `@tag.All`
> Spec: ``
> <hr>Wed, 11 Jun 2025 11:41:27 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Improved input widgets and related components to update values
instantly without delay, removing internal state management and
debounced input handling. All text and value changes are now immediately
reflected in the UI and underlying data.
- **Chores**
- Updated automated tests to use immediate typing actions, removing
artificial delays previously used for input events.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Integrations Pod General Issues related to the Integrations Pod that don't fit into other tags. Integrations Pod Integrations Product Issues related to a specific integration Needs Triaging Needs attention from maintainers to triage ok-to-test Required label for CI Query Widgets & IDE Pod All issues related to Query, JS, Eval, Widgets & IDE skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: UI shows table being updated twice after Query execution
2 participants