Skip to content

feat: Add support for script execution invoking dashboard form for user input#3201

Merged
mtrezza merged 9 commits intoparse-community:alphafrom
mtrezza:feat/script-modal
Feb 10, 2026
Merged

feat: Add support for script execution invoking dashboard form for user input#3201
mtrezza merged 9 commits intoparse-community:alphafrom
mtrezza:feat/script-modal

Conversation

@mtrezza
Copy link
Member

@mtrezza mtrezza commented Feb 10, 2026

Pull Request

Feature

Add support for script execution invoking dashboard form for user input.

Summary by CodeRabbit

  • New Features

    • Scripts can prompt interactive response modals (with dropdowns) when run across rows, enabling per-row payloads and targeted refreshes; batch execution now probes and handles form responses before full runs, with clearer per-object and aggregate result messages.
  • Bug Fixes

    • Prevented state updates after form modal unmount to avoid memory leaks.
  • Documentation

    • Reorganized and greatly expanded Scripts docs with examples for script responses, form payloads, and callback-driven workflows.

@parse-github-assistant
Copy link

🚀 Thanks for opening this pull request!

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Feb 10, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai
Copy link

coderabbitai bot commented Feb 10, 2026

📝 Walkthrough

Walkthrough

Adds form-response handling to script execution: cloud functions can return a ScriptResponse form for user input, shown once for the first probed object; collected form data is then applied to execute the script callback across all selected objects. Documentation for Scripts was reorganized and expanded.

Changes

Cohort / File(s) Summary
Documentation
README.md
Reorganized Scripts docs into a nested Prefetching → Scripts section; expanded with Script Response Form, Response Fields, Form Elements, examples, Cloud Function callback patterns, and notes on multi-row behavior.
Prop forwarding
src/components/BrowserRow/BrowserRow.react.js, src/components/BrowserCell/BrowserCell.react.js, src/dashboard/Data/Browser/BrowserTable.react.js
Threaded a new onScriptModalResponse prop from Browser → BrowserTable → BrowserRow → BrowserCell and updated BrowserCell to pass it into script execution calls.
Browser behavior & modal handling
src/dashboard/Data/Browser/Browser.react.js, src/dashboard/Data/Browser/ScriptResponseModal.react.js
Added scriptResponseModal state and handlers (handleScriptModalResponse, cancelScriptResponseModal, confirmScriptResponseModal) in Browser; added new ScriptResponseModal component to render returned form (dropDown elements) and collect formData for confirm.
DataBrowser integration
src/dashboard/Data/Browser/DataBrowser.react.js
Extended calls to executeScript to pass onScriptModalResponse callback in panel/header/confirm render paths.
Script utilities
src/lib/ScriptUtils.js
Added isFormResponse(response) to detect form responses; extended executeScript(...) to accept onFormResponse and invoke it when a form response is returned; added executeScriptCallback(...) to run a cloud callback across multiple objectIds with per-object notes and aggregated summary.
Form modal safety
src/components/FormModal/FormModal.react.js
Added _isMounted flag with componentDidMount/componentWillUnmount and guarded setState in submit promise paths to avoid updates after unmount.

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser as Browser Component
    participant ScriptUtils as Script Utilities
    participant CloudFn as Cloud Function
    participant Modal as ScriptResponseModal

    User->>Browser: Execute script on multiple rows
    Browser->>ScriptUtils: executeScript (probe first object, pass onFormResponse)
    ScriptUtils->>CloudFn: Invoke Cloud Function (objectId, payload)
    CloudFn-->>ScriptUtils: Return ScriptResponse (contains form)
    ScriptUtils->>Browser: onFormResponse({response, script, className, objectIds})
    Browser->>Modal: Render ScriptResponseModal with form
    User->>Modal: Fill form and submit
    Modal->>Browser: onConfirm(formData)
    Browser->>ScriptUtils: executeScriptCallback(cloudFn, className, objectIds, payload, formData)
    loop per object
        ScriptUtils->>CloudFn: Invoke callback for object with formData
        CloudFn-->>ScriptUtils: Return result / error
        ScriptUtils->>Browser: Emit per-object showNote (success/error)
    end
    ScriptUtils->>Browser: Trigger onRefresh/onRefreshObjects as needed
    Browser->>User: Update UI / notes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete; it lacks the Issue and Approach sections required by the template, only providing the Feature section without detailed explanation of changes. Add the Issue section (linking or describing the problem) and the Approach section (explaining how the changes implement the feature) to match the template structure.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main feature being added: script execution now supports invoking a dashboard form for user input collection.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉


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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/dashboard/Data/Browser/Browser.react.js (1)

2059-2076: ⚠️ Potential issue | 🟡 Minor

scriptResponseModal is not included in hasExtras().

The hasExtras() result is passed as disableKeyControls to DataBrowser. Since scriptResponseModal isn't checked here, keyboard shortcuts may fire while the ScriptResponseModal is open. Note that showExecuteScriptRowsDialog is also absent, so this may be a pre-existing gap—but worth addressing for the new modal.

♻️ Proposed fix
     return !!(
       this.state.showCreateClassDialog ||
       this.state.showAddColumnDialog ||
       this.state.showRemoveColumnDialog ||
       this.state.showDropClassDialog ||
       this.state.showExportDialog ||
       this.state.showExportSchema ||
       this.state.rowsToDelete ||
       this.state.showAttachRowsDialog ||
       this.state.showAttachSelectedRowsDialog ||
       this.state.showCloneSelectedRowsDialog ||
       this.state.showEditRowDialog ||
       this.state.showPermissionsDialog ||
-      this.state.showExportSelectedRowsDialog ||
-      this.state.showAddToConfigDialog
+      this.state.showExportSelectedRowsDialog ||
+      this.state.showAddToConfigDialog ||
+      this.state.scriptResponseModal ||
+      this.state.showExecuteScriptRowsDialog
     );
🤖 Fix all issues with AI agents
In `@README.md`:
- Around line 1382-1556: Replace the incorrect "scrips" key with "scripts" in
the examples (fix the 'scrips' → 'scripts' typo) and update the Form Elements
documentation table to list the actual properties used in the JSON example:
document "element", "name", "label", and "items" (e.g. element: "dropDown") so
the table matches the payload shape shown in the sample scripts and the
ScriptResponse examples.

In `@src/lib/ScriptUtils.js`:
- Around line 98-101: The current construction of note using
JSON.stringify(response) in executeScript and executeScriptCallback can throw on
circular refs or BigInt; wrap the serialization in a try/catch: attempt
JSON.stringify(response) and on error fall back to String(response) (or a safe
custom replacer) to produce the note, then call showNote(note); update the code
paths that build the note (referencing the variables response, note and the
showNote call) so serialization failures do not cause the whole reporting to
fail.
🧹 Nitpick comments (1)
src/dashboard/Data/Browser/Browser.react.js (1)

2210-2241: Sentinel-property pattern for probe errors is fragile.

The .catch(error => ({ __probeError: error })) pattern on line 2215 converts a rejected promise into a resolved one carrying a magic property. If a Cloud Function ever returns an object with a __probeError key, it would be misinterpreted as an error. Consider using a dedicated wrapper or a separate boolean flag instead.

♻️ Suggested alternative using a structured result
-      const probeResponse = await Parse.Cloud.run(
+      let probeResponse;
+      let probeError;
+      try {
+        probeResponse = await Parse.Cloud.run(
           script.cloudCodeFunction,
           { object: objects[0].toPointer() },
           { useMasterKey: true }
-      ).catch(error => ({ __probeError: error }));
+        );
+      } catch (error) {
+        probeError = error;
+      }

-      if (isFormResponse(probeResponse)) {
+      if (!probeError && isFormResponse(probeResponse)) {
         this.handleScriptModalResponse({
           response: probeResponse,
           script,
@@ ...
       this.setState(prevState => ({
         processedScripts: prevState.processedScripts + 1,
       }));

-      if (probeResponse?.__probeError) {
-        const error = probeResponse.__probeError;
+      if (probeError) {
+        const error = probeError;
         const errorMessage = `Error running script "${script.title}" on "${objects[0].id}": ${error.message}`;
...
-      let totalErrorCount = probeResponse?.__probeError ? 1 : 0;
+      let totalErrorCount = probeError ? 1 : 0;

@mtrezza mtrezza merged commit 159f99d into parse-community:alpha Feb 10, 2026
12 checks passed
@mtrezza mtrezza deleted the feat/script-modal branch February 10, 2026 23:41
parseplatformorg pushed a commit that referenced this pull request Feb 10, 2026
# [8.5.0-alpha.7](8.5.0-alpha.6...8.5.0-alpha.7) (2026-02-10)

### Features

* Add support for script execution invoking dashboard form for user input ([#3201](#3201)) ([159f99d](159f99d))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 8.5.0-alpha.7

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Feb 10, 2026
parseplatformorg pushed a commit that referenced this pull request Feb 12, 2026
# [8.5.0](8.4.0...8.5.0) (2026-02-12)

### Bug Fixes

* Auto-formatting not applied when Cloud Config parameter value is outdated and re-fetched from server ([#3182](#3182)) ([84eab36](84eab36))
* Clicking reload button in info panel may display fetched data in incorrect panel ([#3189](#3189)) ([b348ef5](b348ef5))
* Role linking in ACL fails with type error ([#3095](#3095)) ([2070d29](2070d29))
* Security migration from csurf to csrf-sync ([#3188](#3188)) ([a95d8a3](a95d8a3))
* View configuration dialog looses focus while typing and lacks syntax highlighting ([#3183](#3183)) ([715fe8d](715fe8d))

### Features

* Add keyboard shortcut to scroll info panels to top ([#3199](#3199)) ([7535626](7535626))
* Add option to reload all or only selected rows after invoking script ([#3200](#3200)) ([173b953](173b953))
* Add reload button to info panel on long loading time ([#3184](#3184)) ([3712d96](3712d96))
* Add support for script execution invoking dashboard form for user input ([#3201](#3201)) ([159f99d](159f99d))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 8.5.0

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

Labels

state:released Released as stable version state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants