mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 00:49:03 +00:00
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>
This commit is contained in:
parent
3a6ef84b82
commit
669aaa7f2d
4 changed files with 44 additions and 30 deletions
|
|
@ -205,14 +205,7 @@ describe("Custom variables", () => {
|
|||
expect(
|
||||
screen.getByText(/Delete custom variable\?/)
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText((content, element) => {
|
||||
return (
|
||||
element?.textContent ===
|
||||
"This will delete the SECRET_UNO custom variable."
|
||||
);
|
||||
})
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/This will delete the/)).toBeInTheDocument();
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 250));
|
||||
await user.click(screen.getByRole("button", { name: "Delete" }));
|
||||
|
|
@ -354,14 +347,7 @@ describe("Custom variables", () => {
|
|||
expect(
|
||||
screen.getByText(/Delete custom variable\?/)
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText((content, element) => {
|
||||
return (
|
||||
element?.textContent ===
|
||||
"This will delete the SECRET_UNO custom variable."
|
||||
);
|
||||
})
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/This will delete the/)).toBeInTheDocument();
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 250));
|
||||
await user.click(screen.getByRole("button", { name: "Delete" }));
|
||||
|
|
|
|||
|
|
@ -105,9 +105,8 @@ const Secrets = () => {
|
|||
setShowDeleteModal(true);
|
||||
};
|
||||
|
||||
const onDeleteSecret = () => {
|
||||
const reloadList = () => {
|
||||
paginatedListRef.current?.reload();
|
||||
setShowDeleteModal(false);
|
||||
};
|
||||
|
||||
const getTokenFromSecretName = (secretName: string): string => {
|
||||
|
|
@ -277,8 +276,8 @@ const Secrets = () => {
|
|||
{showDeleteModal && (
|
||||
<DeleteSecretModal
|
||||
secret={secretToDelete}
|
||||
onCancel={() => setShowDeleteModal(false)}
|
||||
onDelete={onDeleteSecret}
|
||||
onExit={() => setShowDeleteModal(false)}
|
||||
reloadList={reloadList}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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";
|
||||
|
||||
|
|
@ -9,16 +10,16 @@ import secretsAPI from "services/entities/secrets";
|
|||
|
||||
interface DeleteSecretModalProps {
|
||||
secret: ISecret | undefined;
|
||||
onCancel: () => void;
|
||||
onDelete: () => void;
|
||||
onExit: () => void;
|
||||
reloadList: () => void;
|
||||
}
|
||||
|
||||
const baseClass = "fleet-delete-secret-modal";
|
||||
|
||||
const DeleteSecretModal = ({
|
||||
secret,
|
||||
onCancel,
|
||||
onDelete,
|
||||
onExit,
|
||||
reloadList,
|
||||
}: DeleteSecretModalProps) => {
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ const DeleteSecretModal = ({
|
|||
try {
|
||||
await secretsAPI.deleteSecret(secret.id);
|
||||
renderFlash("success", "Variable successfully deleted.");
|
||||
onDelete();
|
||||
reloadList();
|
||||
} catch (error) {
|
||||
const errorObject = formatErrorResponse(error);
|
||||
const isInUseError =
|
||||
|
|
@ -45,19 +46,31 @@ const DeleteSecretModal = ({
|
|||
renderFlash("error", message);
|
||||
} finally {
|
||||
setIsDeleting(false);
|
||||
onExit();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Delete custom variable?"
|
||||
onExit={onCancel}
|
||||
onExit={onExit}
|
||||
className={baseClass}
|
||||
>
|
||||
<>
|
||||
<p>
|
||||
This will delete the <b>{secret?.name}</b> custom variable.
|
||||
</p>
|
||||
<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"
|
||||
|
|
@ -67,7 +80,7 @@ const DeleteSecretModal = ({
|
|||
>
|
||||
Delete
|
||||
</Button>
|
||||
<Button variant="inverse-alert" onClick={onCancel}>
|
||||
<Button variant="inverse-alert" onClick={onExit}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
.fleet-delete-secret-modal {
|
||||
&__message {
|
||||
span {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
align-items: baseline;
|
||||
.tooltip-truncated-text {
|
||||
max-width: 322px; // this specific max-width facilitates the desired truncation behavior within the inline parent
|
||||
|
||||
.__react_component_tooltip {
|
||||
font-weight: $regular;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue