From 4a80de23f2996bac6c73b2868193320a7298f0b0 Mon Sep 17 00:00:00 2001
From: RachelElysia <71795832+RachelElysia@users.noreply.github.com>
Date: Fri, 24 Oct 2025 09:42:55 -0400
Subject: [PATCH] Fleet UI: Hide version unknown, hide advanced options help
text from script packages (#34647)
---
.../InstallerDetailsWidget.tests.tsx | 27 ++++++++-
.../InstallerDetailsWidget.tsx | 56 +++++++++++++++++--
.../SoftwareInstallerCard.tsx | 34 +----------
.../ViewYamlModal/ViewYamlModal.tsx | 5 +-
.../ViewYamlModal/helpers.tests.ts | 14 +++++
.../ViewYamlModal/helpers.tsx | 15 +++--
6 files changed, 110 insertions(+), 41 deletions(-)
diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tests.tsx b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tests.tsx
index e2021da338..5ea27486a1 100644
--- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tests.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tests.tsx
@@ -21,8 +21,9 @@ describe("InstallerDetailsWidget", () => {
softwareName: "Test Software",
installerType: "package" as const,
addedTimestamp: "2024-05-06T10:00:00Z",
- versionInfo: v1.2.3,
+ version: "v1.2.3",
isFma: false,
+ isScriptPackage: false,
};
it("renders the package icon when installerType is 'package'", () => {
@@ -42,6 +43,30 @@ describe("InstallerDetailsWidget", () => {
expect(screen.getByText(/2 days ago/i)).toBeInTheDocument();
});
+ it("does not render Version (unknown) info for a script package", () => {
+ render(
+
+ );
+ expect(screen.queryByText(/Version \(unknown\)/i)).not.toBeInTheDocument();
+ expect(screen.getByText(/2 days ago/i)).toBeInTheDocument();
+ });
+
+ it("renders Version (unknown) info for a non-script package with no version info", () => {
+ render(
+
+ );
+ expect(screen.getByText(/Version \(unknown\)/i)).toBeInTheDocument();
+ expect(screen.getByText(/2 days ago/i)).toBeInTheDocument();
+ });
+
it("renders only version info when addedTimestamp is not present", () => {
render(
diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tsx b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tsx
index 139f5c204f..76ac3ed0df 100644
--- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerDetailsWidget/InstallerDetailsWidget.tsx
@@ -3,10 +3,11 @@
import React, { useState } from "react";
import classnames from "classnames";
-import { stringToClipboard } from "utilities/copy_text";
+import { stringToClipboard } from "utilities/copy_text";
import { internationalTimeFormat } from "utilities/helpers";
import { addedFromNow } from "utilities/date_format";
+import { LEARN_MORE_ABOUT_BASE_LINK } from "utilities/constants";
import { useCheckTruncatedElement } from "hooks/useCheckTruncatedElement";
import Graphic from "components/Graphic";
@@ -14,6 +15,7 @@ import SoftwareIcon from "pages/SoftwarePage/components/icons/SoftwareIcon";
import TooltipWrapper from "components/TooltipWrapper";
import Button from "components/buttons/Button";
import Icon from "components/Icon";
+import CustomLink from "components/CustomLink";
const baseClass = "installer-details-widget";
@@ -52,9 +54,10 @@ interface IInstallerDetailsWidgetProps {
softwareName: string;
installerType: "package" | "vpp";
addedTimestamp?: string;
- versionInfo?: JSX.Element;
+ version?: string | null;
sha256?: string | null;
isFma: boolean;
+ isScriptPackage: boolean;
}
const InstallerDetailsWidget = ({
@@ -63,8 +66,9 @@ const InstallerDetailsWidget = ({
installerType,
addedTimestamp,
sha256,
- versionInfo,
+ version,
isFma,
+ isScriptPackage,
}: IInstallerDetailsWidgetProps) => {
const classNames = classnames(baseClass, className);
@@ -92,6 +96,49 @@ const InstallerDetailsWidget = ({
};
const renderDetails = () => {
+ const renderVersionInfo = () => {
+ if (isScriptPackage) {
+ return null;
+ }
+
+ let versionInfo = {version};
+
+ if (installerType === "vpp") {
+ versionInfo = (
+ Updated every hour.}>
+ {version}
+
+ );
+ }
+
+ if (!version) {
+ versionInfo = (
+
+ Fleet couldn't read the version from {softwareName}.
+ {installerType === "package" && (
+ <>
+ {" "}
+
+ >
+ )}
+
+ }
+ >
+ Version (unknown)
+
+ );
+ }
+
+ return <> • {versionInfo}>;
+ };
+
const renderTimeStamp = () =>
addedTimestamp ? (
<>
@@ -143,7 +190,8 @@ const InstallerDetailsWidget = ({
return (
<>
- {renderInstallerDisplayText(installerType, isFma)} • {versionInfo}
+ {renderInstallerDisplayText(installerType, isFma)}
+ {renderVersionInfo()}
{renderTimeStamp()}
{renderSha256()}
>
diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/SoftwareInstallerCard.tsx b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/SoftwareInstallerCard.tsx
index 993b451648..c8070c229c 100644
--- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/SoftwareInstallerCard.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/SoftwareInstallerCard.tsx
@@ -266,36 +266,6 @@ const SoftwareInstallerCard = ({
}
}, [renderFlash, softwareId, name, teamId]);
- let versionInfo = {version};
-
- if (installerType === "vpp") {
- versionInfo = (
- Updated every hour.}>
- {version}
-
- );
- }
-
- if (installerType === "package" && !version) {
- versionInfo = (
-
- Fleet couldn't read the version from {name}.{" "}
-
-
- }
- >
- Version (unknown)
-
- );
- }
-
const showActions =
isGlobalAdmin || isGlobalMaintainer || isTeamAdmin || isTeamMaintainer;
@@ -307,10 +277,11 @@ const SoftwareInstallerCard = ({
{Array.isArray(automaticInstallPolicies) &&
@@ -411,6 +382,7 @@ const SoftwareInstallerCard = ({
iconUrl={iconUrl}
softwarePackage={softwareInstaller as ISoftwarePackage}
onExit={onToggleViewYaml}
+ isScriptPackage={isScriptPackage}
/>
)}
diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/ViewYamlModal.tsx b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/ViewYamlModal.tsx
index 0844ec8785..85aaf77835 100644
--- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/ViewYamlModal.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/ViewYamlModal.tsx
@@ -6,7 +6,7 @@ import { NotificationContext } from "context/notification";
import { LEARN_MORE_ABOUT_BASE_LINK } from "utilities/constants";
import { getExtensionFromFileName } from "utilities/file/fileUtils";
import FileSaver from "file-saver";
-import { ISoftwarePackage } from "interfaces/software";
+import { ISoftwarePackage, SCRIPT_PACKAGE_SOURCES } from "interfaces/software";
import softwareAPI from "services/entities/software";
import Modal from "components/Modal";
@@ -29,6 +29,7 @@ interface IViewYamlModalProps {
iconUrl?: string | null;
softwarePackage: ISoftwarePackage;
onExit: () => void;
+ isScriptPackage?: boolean;
}
interface HandleDownloadParams {
@@ -47,6 +48,7 @@ const ViewYamlModal = ({
iconUrl,
softwarePackage,
onExit,
+ isScriptPackage = false,
}: IViewYamlModalProps) => {
const { renderFlash } = useContext(NotificationContext);
const { config } = useContext(AppContext);
@@ -227,6 +229,7 @@ const ViewYamlModal = ({
? onDownloadUninstallScript
: undefined,
onClickIcon: iconUrl ? onDownloadIcon : undefined,
+ hasAdvancedOptionsAvailable: !isScriptPackage,
})}
diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tests.ts b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tests.ts
index 2930be55b9..4b7dd81564 100644
--- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tests.ts
+++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tests.ts
@@ -285,4 +285,18 @@ describe("renderYamlHelperText", () => {
)
).toBeInTheDocument();
});
+
+ it("does not render advanced options help text when hasAdvancedOptionsAvailable is false", () => {
+ render(
+ renderDownloadFilesText({
+ installScript: "echo install",
+ onClickInstallScript: noop,
+ hasAdvancedOptionsAvailable: false,
+ })
+ );
+
+ // Should not show the "Advanced options" instructional text
+ expect(screen.queryByText(/If you edited/i)).not.toBeInTheDocument();
+ expect(screen.queryByText(/Advanced options/i)).not.toBeInTheDocument();
+ });
});
diff --git a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tsx b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tsx
index 534bcaf022..74b2c0fbde 100644
--- a/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/ViewYamlModal/helpers.tsx
@@ -14,6 +14,7 @@ interface RenderYamlHelperText {
onClickPostInstallScript?: (evt: MouseEvent) => void;
onClickUninstallScript?: (evt: MouseEvent) => void;
onClickIcon?: (evt: MouseEvent) => void;
+ hasAdvancedOptionsAvailable?: boolean;
}
// Helper to join items with commas and Oxford comma before "and"
@@ -48,6 +49,7 @@ export const renderDownloadFilesText = ({
onClickPostInstallScript,
onClickUninstallScript,
onClickIcon,
+ hasAdvancedOptionsAvailable = true,
}: RenderYamlHelperText): JSX.Element => {
const items: { key: string; element: JSX.Element }[] = [];
@@ -120,10 +122,15 @@ export const renderDownloadFilesText = ({
<>
Next, download your {joinWithCommasAnd(items)} and add{" "}
{items.length === 1 ? "it" : "them"} to your repository using the{" "}
- {items.length === 1 ? "path" : "paths"} above. If you edited{" "}
- Advanced options, download and replace the{" "}
- {items.length === 1 ? "file" : "files"} in your repository with the
- updated {items.length === 1 ? "one" : "ones"}.
+ {items.length === 1 ? "path" : "paths"} above.
+ {hasAdvancedOptionsAvailable && (
+ <>
+ {" "}
+ If you edited Advanced options, download and replace the{" "}
+ {items.length === 1 ? "file" : "files"} in your repository with the
+ updated {items.length === 1 ? "one" : "ones"}.
+ >
+ )}
>
);
};