mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Fix UI bug with host software install/uninstall actions (#24510)
This commit is contained in:
parent
f2fc2bc0ea
commit
5ee939c2c0
3 changed files with 41 additions and 4 deletions
2
changes/24487-host-software-actions
Normal file
2
changes/24487-host-software-actions
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
- Fixed UI bug where "Actions" dropdown on host software page included "Install" and "Uninstall"
|
||||
options for software that is not able to be installed via Fleet.
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { createMockHostSoftwarePackage } from "__mocks__/hostMock";
|
||||
|
||||
import {
|
||||
generateActions,
|
||||
DEFAULT_ACTION_OPTIONS,
|
||||
|
|
@ -17,20 +19,38 @@ describe("generateActions", () => {
|
|||
hostMDMEnrolled: false,
|
||||
};
|
||||
|
||||
it("returns default actions when user has write permission and scripts are enabled", () => {
|
||||
const defaultPackage = createMockHostSoftwarePackage();
|
||||
|
||||
it("returns only view details when software does not have software package or app store app", () => {
|
||||
const actions = generateActions(defaultProps);
|
||||
expect(actions).toEqual([DEFAULT_ACTION_OPTIONS[0]]);
|
||||
});
|
||||
|
||||
it("returns default actions for software package when user has write permission and scripts are enabled", () => {
|
||||
const actions = generateActions({
|
||||
...defaultProps,
|
||||
software_package: defaultPackage,
|
||||
});
|
||||
expect(actions).toEqual(DEFAULT_ACTION_OPTIONS);
|
||||
});
|
||||
|
||||
it("removes install and uninstall actions when user has no write permission", () => {
|
||||
const props = { ...defaultProps, userHasSWWritePermission: false };
|
||||
const props = {
|
||||
...defaultProps,
|
||||
software_package: defaultPackage,
|
||||
userHasSWWritePermission: false,
|
||||
};
|
||||
const actions = generateActions(props);
|
||||
expect(actions.find((a) => a.value === "install")).toBeUndefined();
|
||||
expect(actions.find((a) => a.value === "uninstall")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("disables install and uninstall actions when host scripts are disabled", () => {
|
||||
const props = { ...defaultProps, hostScriptsEnabled: false };
|
||||
const props = {
|
||||
...defaultProps,
|
||||
software_package: defaultPackage,
|
||||
hostScriptsEnabled: false,
|
||||
};
|
||||
const actions = generateActions(props);
|
||||
expect(actions.find((a) => a.value === "install")?.disabled).toBe(true);
|
||||
expect(actions.find((a) => a.value === "uninstall")?.disabled).toBe(true);
|
||||
|
|
@ -41,6 +61,7 @@ describe("generateActions", () => {
|
|||
...defaultProps,
|
||||
softwareIdActionPending: 1,
|
||||
softwareId: 1,
|
||||
software_package: defaultPackage,
|
||||
};
|
||||
const actions = generateActions(props);
|
||||
expect(actions.find((a) => a.value === "install")?.disabled).toBe(true);
|
||||
|
|
@ -50,6 +71,7 @@ describe("generateActions", () => {
|
|||
it("disables install and uninstall actions when pending install status", () => {
|
||||
const props: generateActionsProps = {
|
||||
...defaultProps,
|
||||
software_package: defaultPackage,
|
||||
status: "pending_install",
|
||||
};
|
||||
const actions = generateActions(props);
|
||||
|
|
@ -60,6 +82,7 @@ describe("generateActions", () => {
|
|||
it("disables install and uninstall actions when pending uninstall status", () => {
|
||||
const props: generateActionsProps = {
|
||||
...defaultProps,
|
||||
software_package: defaultPackage,
|
||||
status: "pending_uninstall",
|
||||
};
|
||||
const actions = generateActions(props);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ export const generateActions = ({
|
|||
softwareIdActionPending,
|
||||
softwareId,
|
||||
status,
|
||||
software_package,
|
||||
app_store_app,
|
||||
hostMDMEnrolled,
|
||||
}: generateActionsProps) => {
|
||||
|
|
@ -77,6 +78,11 @@ export const generateActions = ({
|
|||
// the options.
|
||||
const actions = cloneDeep(DEFAULT_ACTION_OPTIONS);
|
||||
|
||||
// we want to hide the install/uninstall actions if (1) this item doesn't have a
|
||||
// software_package or app_store_app or (2) the user doens't have write permission
|
||||
const hideActions =
|
||||
(!app_store_app && !software_package) || !userHasSWWritePermission;
|
||||
|
||||
const indexInstallAction = actions.findIndex((a) => a.value === "install");
|
||||
if (indexInstallAction === -1) {
|
||||
// this should never happen unless the default actions change, but if it does we'll throw an
|
||||
|
|
@ -92,7 +98,13 @@ export const generateActions = ({
|
|||
throw new Error("Uninstall action not found in default actions");
|
||||
}
|
||||
|
||||
if (!userHasSWWritePermission) {
|
||||
if (indexInstallAction > indexUninstallAction) {
|
||||
// subsquent code depends on relative index order; this shouldn't change, but if it does we'll throw an
|
||||
// error to fail loudly so that we know to update this function
|
||||
throw new Error("Order of install/uninstall actions changed");
|
||||
}
|
||||
|
||||
if (hideActions) {
|
||||
// Reverse order to not change index of subsequent array element before removal
|
||||
actions.splice(indexUninstallAction, 1);
|
||||
actions.splice(indexInstallAction, 1);
|
||||
|
|
|
|||
Loading…
Reference in a new issue