fleet/frontend/pages/ManageControlsPage/Secrets/components/DeleteSecretModal/DeleteSecretModal.tsx
jacobshandling 669aaa7f2d
UI - Delete secret modal: Close modal on error/success, truncate long var names, add missing copy, fix copy alignment (#32508)
## For #32465 

Modal closes when delete errors:
<img width="1350" height="877" alt="Screenshot 2025-09-02 at 10 20
35 AM"
src="https://github.com/user-attachments/assets/daa97771-ba2f-49a7-9324-a2ce3f5bbe46"
/>

and when it succeeds:
<img width="1350" height="877" alt="Screenshot 2025-09-02 at 10 22
01 AM"
src="https://github.com/user-attachments/assets/94404529-bf8c-4c3a-bd0f-af3bab8bdc35"
/>

Short variable names render inline, additional copy underneath:
<img width="1074" height="610" alt="Screenshot 2025-09-02 at 11 33
16 AM"
src="https://github.com/user-attachments/assets/61958099-4450-4e2f-9ee8-f6ed15be8f2b"
/>

While long ones are truncated with the full value displayed in a
tooltip, also inline with additional copy underneath:
<img width="1074" height="610" alt="Screenshot 2025-09-02 at 11 33
55 AM"
src="https://github.com/user-attachments/assets/1fb45cb1-9252-45c9-a62e-c39cae05caaa"
/>

- [x] QA'd all new/changed functionality manually
- [x] Updated tests
- [x] Confirmed that the fix is not expected to adversely impact load
test results

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-09-02 12:55:47 -07:00

92 lines
2.5 KiB
TypeScript

import React, { useContext, useState } from "react";
import Modal from "components/Modal";
import Button from "components/buttons/Button";
import TooltipTruncatedText from "components/TooltipTruncatedText";
import { ISecret } from "interfaces/secrets";
import { NotificationContext } from "context/notification";
import formatErrorResponse from "utilities/format_error_response";
import secretsAPI from "services/entities/secrets";
interface DeleteSecretModalProps {
secret: ISecret | undefined;
onExit: () => void;
reloadList: () => void;
}
const baseClass = "fleet-delete-secret-modal";
const DeleteSecretModal = ({
secret,
onExit,
reloadList,
}: DeleteSecretModalProps) => {
const [isDeleting, setIsDeleting] = useState(false);
const { renderFlash } = useContext(NotificationContext);
const onClickDelete = async () => {
if (!secret) {
return;
}
setIsDeleting(true);
try {
await secretsAPI.deleteSecret(secret.id);
renderFlash("success", "Variable successfully deleted.");
reloadList();
} catch (error) {
const errorObject = formatErrorResponse(error);
const isInUseError =
errorObject.http_status === 409 &&
/used by/.test(errorObject?.base ?? "");
const message =
isInUseError && typeof errorObject?.base === "string"
? errorObject.base
: "An error occurred while deleting the custom variable. Please try again.";
renderFlash("error", message);
} finally {
setIsDeleting(false);
onExit();
}
};
return (
<Modal
title="Delete custom variable?"
onExit={onExit}
className={baseClass}
>
<>
<div className={`${baseClass}__message`}>
<span>
This will delete the
<b>
<TooltipTruncatedText value={secret?.name} />
</b>
custom variable.
</span>
<br />
<br />
If this custom variable is used in any configuration profiles or
scripts, they will fail. To resolve, edit the configuration profile or
script.
</div>
<div className="modal-cta-wrap">
<Button
variant="alert"
onClick={onClickDelete}
isLoading={isDeleting}
disabled={isDeleting}
>
Delete
</Button>
<Button variant="inverse-alert" onClick={onExit}>
Cancel
</Button>
</div>
</>
</Modal>
);
};
export default DeleteSecretModal;