Fleet UI: Clarify delete VPP app pending install nuance (#38376)

This commit is contained in:
RachelElysia
2026-01-20 12:49:18 -05:00
committed by GitHub
parent 40ab729db5
commit 6d7f227a60
4 changed files with 117 additions and 26 deletions
@@ -0,0 +1 @@
- Fleet UI: Clarify what happens to pending software installs when deleting VPP apps
@@ -0,0 +1,66 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import { noop } from "lodash";
import DeleteSoftwareModal from "./DeleteSoftwareModal";
const renderModal = (
props: Partial<React.ComponentProps<typeof DeleteSoftwareModal>> = {}
) => {
return render(
<DeleteSoftwareModal
softwareId={1}
teamId={1}
onExit={noop}
onSuccess={noop}
{...props}
/>
);
};
describe("DeleteSoftwareModal", () => {
beforeEach(() => {
jest.resetAllMocks();
});
it("renders GitOps banner when gitOpsModeEnabled is true", () => {
renderModal({ gitOpsModeEnabled: true });
expect(
screen.getByText(
"You are currently in GitOps mode. If the package is defined in GitOps, it will reappear when GitOps runs."
)
).toBeVisible();
});
it("renders default platform message when not VPP app or Android app", () => {
renderModal();
expect(screen.getByText(/won't be uninstalled/i)).toBeVisible();
expect(
screen.getByText(/Pending installs and uninstalls will be canceled\./i)
).toBeVisible();
});
it("renders App Store message when isAppStoreApp is true", () => {
renderModal({ isAppStoreApp: true });
expect(screen.getByText(/won't be uninstalled/i)).toBeVisible();
expect(
screen.getByText(
/Pending or already started installs and uninstalls won't be canceled/i
)
).toBeVisible();
});
it("renders Android message when isAndroidApp is true", () => {
renderModal({ isAndroidApp: true });
expect(
screen.getByText(
/Currently, software won't be deleted from self-service \(managed Google Play\) and won't be uninstalled from the hosts\./i
)
).toBeVisible();
});
});
@@ -16,24 +16,64 @@ const DELETE_SW_USED_BY_POLICY_ERROR_MSG =
const DELETE_SW_INSTALLED_DURING_SETUP_ERROR_MSG =
"Couldn't delete. This software is installed during new host setup. Please remove software in Controls > Setup experience and try again.";
const getPlatformMessage = (isAppStoreApp: boolean, isAndroidApp: boolean) => {
// Android apps do not have pending installs/uninstalls as they are initiated through setup experience or by user
if (isAndroidApp) {
return (
<p>
Currently, software won&apos;t be deleted from self-service (managed
Google Play) and won&apos;t be uninstalled from the hosts.
</p>
);
}
// VPP apps pending installs/uninstalls commands are not cancelled (future story #25912) but results only show in activity feed, as software is removed from host's software library
if (isAppStoreApp) {
return (
<>
<p>
Software <strong>won&apos;t be uninstalled</strong> from hosts.
</p>
<p>
Pending or already started installs and uninstalls won&apos;t be
canceled, and the results won&apos;t appear in Fleet.
</p>
</>
);
}
return (
<>
<p>
Software <strong>won&apos;t be uninstalled</strong> from hosts.
</p>
<p>
Pending installs and uninstalls will be canceled. If they have already
started, they won&apos; be canceled, and the results won&apos;t appear
in Fleet.
</p>
</>
);
};
interface IDeleteSoftwareModalProps {
softwareId: number;
teamId: number;
softwareTitleName?: string;
softwareDisplayName?: string;
onExit: () => void;
onSuccess: () => void;
gitOpsModeEnabled?: boolean;
isAppStoreApp?: boolean;
isAndroidApp?: boolean;
}
const DeleteSoftwareModal = ({
softwareId,
teamId,
softwareTitleName,
softwareDisplayName,
onExit,
onSuccess,
gitOpsModeEnabled,
isAppStoreApp = false,
isAndroidApp = false,
}: IDeleteSoftwareModalProps) => {
const { renderFlash } = useContext(NotificationContext);
const [isDeleting, setIsDeleting] = useState(false);
@@ -72,26 +112,8 @@ const DeleteSoftwareModal = ({
GitOps, it will reappear when GitOps runs.
</InfoBanner>
)}
<p>
Are you sure you want to delete{" "}
<strong>{softwareDisplayName || softwareTitleName}</strong>?
</p>
<ul>
<li>
Software won&apos;t be uninstalled from existing hosts, but any
pending installs and uninstalls will be canceled.
</li>{" "}
<li>
Installs or uninstalls currently running on a host will still
complete, but results won&apos;t appear in Fleet.
</li>
<li>
Installed software will appear as{" "}
<strong>{softwareTitleName}</strong> in software inventories and
will use the default icon.
</li>
</ul>
<p>You cannot undo this action.</p>
{getPlatformMessage(isAppStoreApp, isAndroidApp)}
<p>Custom icon and display name will be deleted.</p>
<div className="modal-cta-wrap">
<Button
variant="alert"
@@ -358,11 +358,13 @@ const SoftwareInstallerCard = ({
<DeleteSoftwareModal
gitOpsModeEnabled={gitOpsModeEnabled}
softwareId={softwareId}
softwareDisplayName={softwareDisplayName}
softwareTitleName={softwareTitleName}
teamId={teamId}
onExit={() => setShowDeleteModal(false)}
onSuccess={onDeleteSuccess}
isAppStoreApp={
installerType === "app-store" && !isAndroidPlayStoreApp
}
isAndroidApp={isAndroidPlayStoreApp}
/>
)}
{showViewYamlModal && isCustomPackage && (