From e761543262f41fd7a40be80ab9daac096a85b1e3 Mon Sep 17 00:00:00 2001 From: Sarah Gillespie <73313222+gillespi314@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:08:30 -0500 Subject: [PATCH] Fix unreleased bugs related to VPP app install details UI (#20952) --- .../AppInstallDetails/AppInstallDetails.tsx | 39 +++++++++++-------- .../InstallDetails/constants.ts | 2 +- .../HostDetailsPage/HostDetailsPage.tsx | 20 ++++++++-- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx b/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx index dd1de5a727..f6ed1a97be 100644 --- a/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx +++ b/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx @@ -13,7 +13,6 @@ import Spinner from "components/Spinner/Spinner"; import { IMdmCommandResult } from "interfaces/mdm"; import { IActivityDetails } from "interfaces/activity"; -import { IconNames } from "components/icons"; import { getInstallDetailsStatusPredicate, INSTALL_DETAILS_STATUS_ICONS, @@ -46,7 +45,10 @@ export const AppInstallDetails = ({ return mdmApi.getCommandResults(command_uuid).then((response) => { const results = response.results?.[0]; if (!results) { - return Promise.reject(new Error("No data returned")); + // FIXME: It's currently possible that the command results API response is empty for pending + // commands. As a temporary workaround to handle this case, we'll ignore the empty response and + // display some minimal pending UI. This should be removed once the API response is fixed. + return {} as IMdmCommandResult; } return { ...results, @@ -66,27 +68,28 @@ export const AppInstallDetails = ({ } else if (isError) { return ; } else if (!result) { - // FIXME: Find a better solution for this. - return ; + // FIXME: It's currently possible that the command results API response is empty for pending + // commands. As a temporary workaround to handle this case, we'll ignore the empty response and + // display some minimal pending UI. This should be updated once the API response is fixed. } + const displayStatus = (status as SoftwareInstallStatus) || "pending"; + const iconName = INSTALL_DETAILS_STATUS_ICONS[displayStatus]; + // Note: We need to reconcile status values from two different sources. From props, we // get the status from the activity item details (which can be "failed", "pending", or // "installed"). From the command results API response, we also receive the raw status // from the MDM protocol, e.g., "NotNow" or "Acknowledged". We need to display some special // messaging for the "NotNow" status, which otherwise would be treated as "pending". - const isStatusNotNow = result.status === "NotNow"; - let iconName: IconNames; + const isStatusNotNow = result?.status === "NotNow"; let predicate: string; let subordinate: string; if (isStatusNotNow) { - iconName = INSTALL_DETAILS_STATUS_ICONS.pending; predicate = "tried to install"; subordinate = " but couldn’t because the host was locked or was running on battery power while in Power Nap. Fleet will try again"; } else { - iconName = INSTALL_DETAILS_STATUS_ICONS[status as SoftwareInstallStatus]; - predicate = getInstallDetailsStatusPredicate(status); + predicate = getInstallDetailsStatusPredicate(displayStatus); subordinate = status === "pending" ? " when it comes online" : ""; } @@ -96,7 +99,9 @@ export const AppInstallDetails = ({ "the host" ); - const showCommandResponse = isStatusNotNow || status !== "pending"; + const showCommandPayload = !!result?.payload; + const showCommandResponse = + !!result?.result && (isStatusNotNow || status !== "pending"); return ( <> @@ -108,12 +113,14 @@ export const AppInstallDetails = ({ {subordinate}. -
- Request payload: - -
+ {showCommandPayload && ( +
+ Request payload: + +
+ )} {showCommandResponse && (
The response from {formattedHost}: diff --git a/frontend/components/ActivityDetails/InstallDetails/constants.ts b/frontend/components/ActivityDetails/InstallDetails/constants.ts index b3cd75cf79..c4c1ae8cb7 100644 --- a/frontend/components/ActivityDetails/InstallDetails/constants.ts +++ b/frontend/components/ActivityDetails/InstallDetails/constants.ts @@ -14,7 +14,7 @@ const INSTALL_DETAILS_STATUS_PREDICATES: Record< SoftwareInstallStatus, string > = { - pending: "will install", + pending: "is installing or will install", installed: "installed", failed: "failed to install", } as const; diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx index a55744bc33..0c4b9c9c3c 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx @@ -583,15 +583,29 @@ const HostDetailsPage = ({ setScriptDetailsId(details?.script_execution_id || ""); break; case "installed_software": - setPackageInstallDetails({ ...details }); + setPackageInstallDetails({ + ...details, + // FIXME: It seems like the backend is not using the correct display name when it returns + // upcoming install activities. As a workaround, we'll prefer the display name from + // the host object if it's available. + host_display_name: + host?.display_name || details?.host_display_name || "", + }); break; case "installed_app_store_app": - setAppInstallDetails({ ...details }); + setAppInstallDetails({ + ...details, + // FIXME: It seems like the backend is not using the correct display name when it returns + // upcoming install activities. As a workaround, we'll prefer the display name from + // the host object if it's available. + host_display_name: + host?.display_name || details?.host_display_name || "", + }); break; default: // do nothing } }, - [] + [host?.display_name] ); const onLabelClick = (label: ILabel) => {