fleet/frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx
jacobshandling 956ba0a8b1
UI: Confirm before running scripts (#33679)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**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

<img width="1208" height="693" alt="Screenshot 2025-09-30 at 4 12 46 PM"
src="https://github.com/user-attachments/assets/160d4105-cbd1-48f5-9d52-1e11f81f87f5"
/>

# Checklist for submitter

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

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

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

## 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.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-10-01 10:15:30 -07:00

89 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useContext, useState } from "react";
import scriptAPI from "services/entities/scripts";
import { NotificationContext } from "context/notification";
import Modal from "components/Modal";
import Button from "components/buttons/Button";
import { AxiosResponse } from "axios";
import { IApiError } from "../../../../../interfaces/errors";
import { getErrorMessage } from "../ScriptUploader/helpers";
const baseClass = "delete-script-modal";
interface IDeleteScriptModalProps {
scriptName: string;
scriptId: number;
onCancel: () => void;
afterDelete: () => void;
isHidden?: boolean;
}
const DeleteScriptModal = ({
scriptName,
scriptId,
onCancel,
afterDelete,
isHidden = false,
}: IDeleteScriptModalProps) => {
const { renderFlash } = useContext(NotificationContext);
const [isDeleting, setIsDeleting] = useState(false);
const onClickDelete = async (id: number) => {
setIsDeleting(true);
try {
await scriptAPI.deleteScript(id);
renderFlash("success", "Successfully deleted!");
} catch (e) {
const error = e as AxiosResponse<IApiError>;
const apiErrMessage = getErrorMessage(error);
renderFlash(
"error",
apiErrMessage.includes("Policy automation")
? apiErrMessage
: "Couldnt delete. Please try again."
);
}
setIsDeleting(false);
afterDelete();
};
return (
<Modal
className={baseClass}
title="Delete script"
onExit={onCancel}
onEnter={() => onClickDelete(scriptId)}
isHidden={isHidden}
isContentDisabled={isDeleting}
>
<>
<p>
This action will cancel any pending script execution for{" "}
<span className={`${baseClass}__script-name`}>{scriptName}</span>
</p>
<p>
If the script is currently running on a host it will still complete,
but results won&apos;t appear in Fleet.
</p>
<p>You cannot undo this action.</p>
<div className="modal-cta-wrap">
<Button
type="button"
onClick={() => onClickDelete(scriptId)}
variant="alert"
className="delete-loading"
isLoading={isDeleting}
>
Delete
</Button>
<Button onClick={onCancel} variant="inverse-alert">
Cancel
</Button>
</div>
</>
</Modal>
);
};
export default DeleteScriptModal;