Skip to content

UI: Confirm before running scripts#33679

Merged
jacobshandling merged 10 commits into
mainfrom
28711-confirm-before-script-run
Oct 1, 2025
Merged

UI: Confirm before running scripts#33679
jacobshandling merged 10 commits into
mainfrom
28711-confirm-before-script-run

Conversation

@jacobshandling
Copy link
Copy Markdown
Contributor

@jacobshandling jacobshandling commented Sep 30, 2025

Related issue: Resolves #28711 and #33685

  • Adds a confirmation step to 2 run script user flows:
    • Host details > Actions > Run script > Actions > Run
    • Host details > Actions > Run script > Click script name for script details > More actions > Run
  • For each user flow, canceling / going back takes the user to wherever they came from, e.g., to the run script (scripts table) modal or to the script details modal
  • Confirming the script run always redirects to the run script (scripts table) modal
  • Consolidates and streamlines logic of the script modal group
  • Clarify + solidify modal options in script modal group
Screenshot 2025-09-30 at 4 12 46 PM

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Changes file added for user-visible changes in `changes/
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

  • New Features
    • Added a confirmation dialog before running a script from a host’s details, clearly showing the script and host names.
  • Improvements
    • Streamlined script run flow with clearer loading indicators and smoother transitions between modals.
    • Enhanced modal behavior: consistent close/cancel handling and the ability to return to the previous view after canceling a run.
    • More consistent actions in script details and run views, reducing unexpected refreshes and interruptions.
  • Chores
    • Internal test updates to improve reliability of user interaction simulations.

@codecov
Copy link
Copy Markdown

codecov Bot commented Sep 30, 2025

Codecov Report

❌ Patch coverage is 2.40964% with 81 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.00%. Comparing base (e235fda) to head (9a90665).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...sPage/modals/ScriptModalGroup/ScriptModalGroup.tsx 0.00% 50 Missing ⚠️
...tailsPage/modals/RunScriptModal/RunScriptModal.tsx 0.00% 14 Missing ⚠️
...mponents/ScriptDetailsModal/ScriptDetailsModal.tsx 0.00% 12 Missing ⚠️
...ls/ConfirmRunScriptModal/ConfirmRunScriptModal.tsx 40.00% 3 Missing ⚠️
...components/DeleteScriptModal/DeleteScriptModal.tsx 0.00% 1 Missing ⚠️
...sPage/modals/RunScriptModal/ScriptsTableConfig.tsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #33679      +/-   ##
==========================================
- Coverage   64.00%   64.00%   -0.01%     
==========================================
  Files        2067     2068       +1     
  Lines      207188   207209      +21     
  Branches     6847     6766      -81     
==========================================
+ Hits       132608   132617       +9     
- Misses      64147    64159      +12     
  Partials    10433    10433              
Flag Coverage Δ
frontend 53.34% <2.40%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@sgress454 sgress454 left a comment

Choose a reason for hiding this comment

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

LGTM, tested 👍

It's worth siccing Coderabbit on this to catch any inconsistencies with the renaming and shuffling around of vars, in case there's any cases I missed.

@jacobshandling
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 1, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 1, 2025

Walkthrough

Adds a confirmation step to running scripts from the host details flow by introducing a ConfirmRunScriptModal and refactoring modal orchestration. Updates RunScriptModal and ScriptDetailsModal APIs and control flow to delegate run actions via callbacks. Renames DeleteScriptModal’s completion prop (onDone → afterDelete). Adjusts related table config and tests.

Changes

Cohort / File(s) Summary of changes
Host details script flow refactor
frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/RunScriptModal.tsx, frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/ScriptsTableConfig.tsx, frontend/pages/hosts/components/ScriptDetailsModal/ScriptDetailsModal.tsx, frontend/pages/hosts/details/HostDetailsPage/modals/ScriptModalGroup/ScriptModalGroup.tsx
Introduces callback-based run flow with confirmation; replaces host with hostTeamId; adds isRunningScript; updates onClickViewScript signature; shifts run initiation to callbacks; adds enum-driven modal state; wires confirm-before-run path; updates loading/error flags and table config.
New confirmation modal
frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/ConfirmRunScriptModal.tsx, frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/index.ts
Adds ConfirmRunScriptModal with Run/Cancel actions and loading state; re-export via index.
DeleteScriptModal prop rename
frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx, frontend/pages/ManageControlsPage/Scripts/cards/ScriptLibrary/ScriptLibrary.tsx
Renames public prop onDone to afterDelete; updates internal invocation and usage site in ScriptLibrary.
Tests: interaction and time phrasing
frontend/pages/ManageControlsPage/Scripts/components/ScriptListItem/ScriptListItem.tests.tsx, frontend/pages/ManageControlsPage/Scripts/cards/ScriptBatchProgress/ScriptBatchProgress.tests.tsx
Switches tests from fireEvent to user interactions; removes fake timers; updates scheduled date to year 9999; relaxes regex to accept “about” or “over” years.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant SMG as ScriptModalGroup
  participant RSM as RunScriptModal
  participant SDM as ScriptDetailsModal
  participant CRM as ConfirmRunScriptModal
  participant API as Scripts API (via callback)

  U->>SMG: Open "Run script" actions
  SMG->>RSM: Show scripts (hostTeamId, loading flags)
  U->>RSM: Select "Run" on a script
  RSM-->>SMG: onClickRun(script)
  note right of SMG: New step: confirmation before execution
  SMG->>CRM: Open confirm modal (scriptName, hostName, isRunningScript)

  alt User confirms
    U->>CRM: Click "Run"
    CRM-->>SMG: onConfirmRunScript()
    SMG->>API: Execute run (set isRunningScript)
    API-->>SMG: Result (success/error)
    SMG->>CRM: Close modal
    SMG->>RSM: Refresh/reflect state
  else User cancels
    U->>CRM: Click "Cancel"
    CRM-->>SMG: onCancel()
    SMG->>RSM: Return to previous modal
  end

  U->>RSM: Click a script name
  RSM-->>SMG: onClickViewScript(scriptDetails)
  SMG->>SDM: Open details (with onClickRun → confirmation)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • sgress454
  • dantecatalfamo

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The pull request includes unrelated changes such as renaming props in DeleteScriptModal, refactoring ScriptListItem and ScriptBatchProgress tests, and adjusting ScriptLibrary component usage, which are not required to implement the confirmation step feature described in the linked issue. Please separate unrelated API prop renames and test framework refactors into distinct pull requests so this one remains focused solely on adding the confirmation modal for running scripts.
Description Check ⚠️ Warning The pull request description outlines the related issues and summarizes the added confirmation step and workflow logic but omits the required checklist entry for added or updated automated tests even though several test files were modified, making it incomplete relative to the repository’s description template. Please update the description checklist to include entries for added or updated automated tests and any other relevant testing steps so it fully aligns with the repository’s required template.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title “UI: Confirm before running scripts” clearly and concisely conveys the primary change of adding a confirmation step before running scripts, matching the main user-facing functionality introduced in this changeset.
Linked Issues Check ✅ Passed The changes introduce a ConfirmRunScriptModal component and integrate it into both run-script workflows on the Host Details page, thereby fulfilling issue #28711’s requirement to add a confirmation step before executing scripts and preventing accidental runs on Linux.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 28711-confirm-before-script-run

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
Copy Markdown
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)
frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/ScriptsTableConfig.tsx (1)

108-110: Tiny cleanup: avoid unnecessary template literal.

-            <span className={`script-info-text`}>
+            <span className="script-info-text">
               {cellProps.row.original.name}
             </span>
frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/ConfirmRunScriptModal.tsx (1)

34-53: Form wrapper not needed; use a div.

There’s no submit. Dropping the form avoids enter‑key submits and simplifies semantics.

-      <form className={`${baseClass}__form`}>
+      <div className={`${baseClass}__form`}>
         ...
-      </form>
+      </div>
frontend/pages/hosts/details/HostDetailsPage/modals/ScriptModalGroup/ScriptModalGroup.tsx (4)

103-110: Use boolean for isScriptContentError and drop magic fallback ID.

  • error is an Error object; pass a boolean to isScriptContentError to match the name/intent.
  • With enabled guarding, fallback ?? 1 isn’t needed.
  } = useQuery<string, Error>(
-    ["scriptContent", selectedScript?.script_id],
-    () => scriptsAPI.downloadScript(selectedScript?.script_id ?? 1),
+    ["scriptContent", selectedScript?.script_id],
+    () => scriptsAPI.downloadScript(selectedScript!.script_id),
     {
       refetchOnWindowFocus: false,
       enabled:
         !!selectedScript && currentModal === ModalGroupOption.ViewScriptDetails,
     }
  );

And when passing to the child:

- isScriptContentError={isSelectedScriptContentError}
+ isScriptContentError={!!isSelectedScriptContentError}

112-116: goBack safety fallback.

If previousModal is ever null, default to Run to avoid setting null currentModal.

-  const goBack = useCallback(() => {
-    setCurrentModal(previousModal);
-    setPreviousModal(null);
-  }, [previousModal]);
+  const goBack = useCallback(() => {
+    setCurrentModal(previousModal ?? ModalGroupOption.Run);
+    setPreviousModal(null);
+  }, [previousModal]);

117-140: Guard against rapid double‑click on “Run”.

Early‑return if already running to prevent duplicate submissions.

  const onConfirmRunScript = useCallback(async () => {
-    // will always be truthy at this point
-    if (selectedScript) {
+    if (isRunningScript) return;
+    if (selectedScript) {
       try {
         setIsRunningScript(true);
         await scriptsAPI.runScript({
           host_id: host.id,
           // will be defined when this is being called
           script_id: selectedScript.script_id,
         });
         ...
       } finally {
         setIsRunningScript(false);
         setSelectedScript(null);
         setCurrentModal(ModalGroupOption.Run);
       }
     }
-  }, [host.id, refetchHostScripts, renderFlash, selectedScript]);
+  }, [host.id, isRunningScript, refetchHostScripts, renderFlash, selectedScript]);

If Button already disables on isLoading, this is belt‑and‑suspenders.


142-149: Rename typo: onClikRunBeforeConfirmation → onClickRunBeforeConfirmation.

Improves readability and searchability.

-  const onClikRunBeforeConfirmation = useCallback(
+  const onClickRunBeforeConfirmation = useCallback(
     (script: IHostScript) => {
       setPreviousModal(currentModal);
       setCurrentModal(ModalGroupOption.ConfirmRun);
       setSelectedScript(script);
     },
     [currentModal]
   );

And update call sites in this file.

frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/RunScriptModal.tsx (1)

78-80: Add setPage to callback deps.

State setters are stable, but adding it silences lint and is clearer.

-  const onQueryChange = useCallback(({ pageIndex }: ITableQueryData) => {
-    setPage(pageIndex);
-  }, []);
+  const onQueryChange = useCallback(({ pageIndex }: ITableQueryData) => {
+    setPage(pageIndex);
+  }, [setPage]);
📜 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 e235fda and 9a90665.

📒 Files selected for processing (11)
  • changes/28711-confirm-script-runs (1 hunks)
  • frontend/pages/ManageControlsPage/Scripts/cards/ScriptBatchProgress/ScriptBatchProgress.tests.tsx (2 hunks)
  • frontend/pages/ManageControlsPage/Scripts/cards/ScriptLibrary/ScriptLibrary.tsx (1 hunks)
  • frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx (2 hunks)
  • frontend/pages/ManageControlsPage/Scripts/components/ScriptListItem/ScriptListItem.tests.tsx (6 hunks)
  • frontend/pages/hosts/components/ScriptDetailsModal/ScriptDetailsModal.tsx (5 hunks)
  • frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/ConfirmRunScriptModal.tsx (1 hunks)
  • frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/index.ts (1 hunks)
  • frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/RunScriptModal.tsx (5 hunks)
  • frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/ScriptsTableConfig.tsx (3 hunks)
  • frontend/pages/hosts/details/HostDetailsPage/modals/ScriptModalGroup/ScriptModalGroup.tsx (4 hunks)
🔇 Additional comments (23)
frontend/pages/ManageControlsPage/Scripts/components/ScriptListItem/ScriptListItem.tests.tsx (5)

1-2: LGTM!

The addition of renderWithSetup alongside the existing render import is appropriate for migrating interaction tests to use user-event.


58-70: LGTM!

The test has been correctly converted to use async user interactions with proper async/await patterns.


72-86: LGTM!

The test correctly validates click handler isolation using async user interactions.


88-102: LGTM!

The test correctly validates the delete handler with proper async user interactions.


104-118: LGTM!

The test correctly validates the edit handler with proper async user interactions.

frontend/pages/ManageControlsPage/Scripts/cards/ScriptBatchProgress/ScriptBatchProgress.tests.tsx (2)

62-62: LGTM: Test date updated to push scheduled time further into the future.

The change from year 2099 to 9999 ensures the test consistently exercises the "many years in the future" rendering path, reducing brittleness as time advances.


201-201: LGTM: Regex updated to accommodate relative time phrasing variation.

The updated pattern accepts both "about" and "over" in the relative time string, making the test more resilient to changes in the date-formatting library's output.

frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx (1)

18-18: LGTM: Prop renamed for clarity.

The prop rename from onDone to afterDelete improves semantic clarity and intention-revealing API design. The change is consistently applied across the interface, destructuring, and invocation.

Also applies to: 26-26, 48-48

frontend/pages/ManageControlsPage/Scripts/cards/ScriptLibrary/ScriptLibrary.tsx (1)

186-186: LGTM: Usage updated to match DeleteScriptModal API change.

The prop usage correctly reflects the rename from onDone to afterDelete in DeleteScriptModal's public interface.

frontend/pages/hosts/components/ScriptDetailsModal/ScriptDetailsModal.tsx (5)

40-41: LGTM: Public API expanded with delegation callbacks.

The new optional props onClose and onClickRun improve composability by allowing parent components to control exit behavior and script execution flow. The JSDoc comment clearly explains the dual-purpose exit handling.

Also applies to: 45-45, 61-63


48-48: LGTM: Type signature expanded to allow null.

Adding | null to selectedScriptDetails improves type safety and flexibility for cases where script details may not be immediately available.


287-287: LGTM: Exit behavior now supports dual-purpose close/cancel.

The onExit handler correctly delegates to onClose when provided, falling back to onCancel otherwise. This allows parent components to distinguish between "go back" and "close" semantics.


292-292: LGTM: Footer rendering now conditional.

The footer is now only rendered when shouldShowFooter is true, eliminating unnecessary rendering when script details are unavailable.


153-172: Resolved: onClickRun is always passed when showHostScriptActions is true
In ScriptModalGroup.tsx, the <ScriptDetailsModal … /> invocation at lines 207–216 includes both showHostScriptActions and onClickRun={onClikRunBeforeConfirmation}, ensuring the “run” action callback is never undefined.

changes/28711-confirm-script-runs (1)

1-2: LGTM: Changelog entry clearly documents the feature.

The changelog entry concisely describes the addition of confirmation steps to the two script run flows, aligning with the PR objectives.

frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/index.ts (1)

1-1: Barrel re‑export looks good.

Keeps imports clean and aligns with local component default export.

frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/ScriptsTableConfig.tsx (2)

54-64: Confirm role gating for “Run” action.

Observers (global/team) currently have run permission. If this is unintended, tighten to admin/maintainer only.


82-88: Approve onClickViewScript signature change. All call sites now use the single-argument form; no stale two-argument invocations remain.

frontend/pages/hosts/details/HostDetailsPage/modals/ConfirmRunScriptModal/ConfirmRunScriptModal.tsx (1)

28-33: LGTM on modal wiring and loading flags.

Title, isLoading/isHidden, and close behavior look correct.

frontend/pages/hosts/details/HostDetailsPage/modals/ScriptModalGroup/ScriptModalGroup.tsx (2)

177-190: Confirm modal wiring matches UX spec.

Cancel returns to origin; confirm resets to table; loading state flows down. Good.


236-247: Run details modal back‑nav logic looks correct.

Transitions respect previous modal (details vs run list).

frontend/pages/hosts/details/HostDetailsPage/modals/RunScriptModal/RunScriptModal.tsx (2)

105-112: Confirm Enter‑key behavior.

onEnter={onClose} means pressing Enter closes the modal. Validate this is intended for this modal (no text inputs); otherwise consider removing to avoid accidental closure.


116-145: Loading/empty/error states are well handled.

Spinner during initial load, error fallback, and empty state copy read well.

@jacobshandling jacobshandling merged commit 956ba0a into main Oct 1, 2025
15 checks passed
@jacobshandling jacobshandling deleted the 28711-confirm-before-script-run branch October 1, 2025 17:15
@coderabbitai coderabbitai Bot mentioned this pull request Apr 27, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants