Fleet UI: Add changes to include google playstore web apps (#40716)

This commit is contained in:
RachelElysia
2026-03-03 11:21:56 -05:00
committed by GitHub
parent a1c9115ef0
commit af9f48eeb1
7 changed files with 77 additions and 11 deletions
@@ -13,11 +13,15 @@ import {
getInstallerCardInfo,
InstallerCardInfo,
} from "pages/SoftwarePage/SoftwareTitleDetailsPage/helpers";
import { isAndroidWebApp } from "pages/SoftwarePage/helpers";
import { compareVersions } from "utilities/helpers";
export interface SoftwareInstallerMeta {
installerType: InstallerType;
/** Includes both Google Play Store apps and Google Play Store web apps */
isAndroidPlayStoreApp: boolean;
/** Only includes Google Play Store web apps */
isAndroidPlayStoreWebApp: boolean;
isFleetMaintainedApp: boolean;
isLatestFmaVersion: boolean;
isCustomPackage: boolean;
@@ -64,6 +68,11 @@ export const useSoftwareInstaller = (
const isAndroidPlayStoreApp =
"platform" in softwareInstaller && isAndroid(softwareInstaller.platform);
const isAndroidPlayStoreWebApp =
isAndroidPlayStoreApp && "app_store_id" in softwareInstaller
? isAndroidWebApp(softwareInstaller.app_store_id)
: false;
const isFleetMaintainedApp =
"fleet_maintained_app_id" in softwareInstaller &&
!!softwareInstaller.fleet_maintained_app_id;
@@ -129,6 +138,7 @@ export const useSoftwareInstaller = (
meta: {
installerType,
isAndroidPlayStoreApp,
isAndroidPlayStoreWebApp,
isFleetMaintainedApp,
isLatestFmaVersion,
fmaVersions,
@@ -60,9 +60,8 @@ describe("InstallerDetailsWidget", () => {
it("renders Version (unknown) info for a non-script package with no version info", () => {
render(
<InstallerDetailsWidget
{...defaultProps}
{...defaultProps} // Includes isScriptPackage: false
version={undefined}
isScriptPackage={false}
/>
);
expect(screen.getByText(/Version \(unknown\)/i)).toBeInTheDocument();
@@ -119,6 +118,20 @@ describe("InstallerDetailsWidget", () => {
expect(screen.getByText(/latest/i)).toBeInTheDocument();
});
it("renders Web app label and does not render Version (unknown) info for a Google playstore webapp", () => {
render(
<InstallerDetailsWidget
{...defaultProps}
version={undefined}
installerType="app-store"
androidPlayStoreId="com.google.enterprise.webapp.test"
/>
);
expect(screen.getByText(/Web app/i)).toBeInTheDocument();
expect(screen.queryByText(/Version \(unknown\)/i)).not.toBeInTheDocument();
expect(screen.getByText(/2 days ago/i)).toBeInTheDocument();
});
it("InstallerName disables tooltip if not truncated", () => {
// useCheckTruncatedElement is mocked to return false
render(<InstallerDetailsWidget {...defaultProps} />);
@@ -11,6 +11,8 @@ import { LEARN_MORE_ABOUT_BASE_LINK } from "utilities/constants";
import { useCheckTruncatedElement } from "hooks/useCheckTruncatedElement";
import { InstallerType } from "interfaces/software";
import { isAndroidWebApp } from "pages/SoftwarePage/helpers";
import Graphic from "components/Graphic";
import SoftwareIcon from "pages/SoftwarePage/components/icons/SoftwareIcon";
import TooltipWrapper from "components/TooltipWrapper";
@@ -53,6 +55,10 @@ const renderInstallerDisplayText = (
return isFma ? "Fleet-maintained" : "Custom package";
}
if (androidPlayStoreId) {
if (isAndroidWebApp(androidPlayStoreId)) {
return "Web app";
}
return "Google Play Store";
}
return "App Store (VPP)";
@@ -118,7 +124,8 @@ const InstallerDetailsWidget = ({
}
const renderVersionInfo = () => {
if (isScriptPackage) {
// Hide version info from script package and Android Play Store web apps
if (isScriptPackage || isAndroidWebApp(androidPlayStoreId)) {
return null;
}
@@ -152,5 +152,31 @@ describe("Software Summary Card", () => {
expect(options).not.toContain("Edit software");
expect(options).not.toContain("Schedule auto updates");
});
it("displays Edit appearance (but not Edit configuration nor Edit software) for Android web apps", async () => {
const { user } = render(
<SoftwareSummaryCard
softwareTitle={createMockSoftwareTitle({
source: "android_apps",
app_store_app: createMockAppStoreAppAndroid({
app_store_id: "com.google.enterprise.webapp.myapp",
}),
software_package: null,
})}
softwareId={1}
teamId={1}
router={router}
refetchSoftwareTitle={jest.fn()}
onToggleViewYaml={jest.fn()}
/>
);
const options = await getDropdownOptions(user);
expect(options).toContain("Edit appearance");
expect(options).not.toContain("Edit software");
expect(options).not.toContain("Edit configuration");
expect(options).not.toContain("Schedule auto updates");
});
});
});
@@ -112,12 +112,15 @@ const SoftwareSummaryCard = ({
isIosOrIpadosApp,
isFleetMaintainedApp,
isAndroidPlayStoreApp,
isAndroidPlayStoreWebApp,
canManageSoftware,
} = meta;
const canEditAppearance = canManageSoftware;
const canEditSoftware = canManageSoftware;
const canEditConfiguration = canManageSoftware && isAndroidPlayStoreApp;
const canEditSoftware = canManageSoftware && !isAndroidPlayStoreApp;
/** Permission to manage software + Google Playstore app that's not a web app */
const canEditConfiguration =
canManageSoftware && isAndroidPlayStoreApp && !isAndroidPlayStoreWebApp;
/** Installer modals require a specific team; hidden from "All Teams" */
const hasValidTeamId = typeof teamId === "number" && teamId >= 0;
const softwareInstallerOnTeam = hasValidTeamId && softwareInstaller;
@@ -12,6 +12,8 @@ import { TooltipContent } from "interfaces/dropdownOption";
import { getPathWithQueryParams, QueryParams } from "utilities/url";
import { getGitOpsModeTipContent } from "utilities/helpers";
import { isSafeImagePreviewUrl } from "pages/SoftwarePage/helpers";
import paths from "router/paths";
import {
NO_VERSION_OR_HOST_DATA_SOURCES,
@@ -26,7 +28,6 @@ import DropdownWrapper from "components/forms/fields/DropdownWrapper";
import TooltipWrapper from "components/TooltipWrapper";
import TooltipTruncatedText from "components/TooltipTruncatedText";
import CustomLink from "components/CustomLink";
import { isSafeImagePreviewUrl } from "pages/SoftwarePage/helpers";
import TooltipWrapperArchLinuxRolling from "components/TooltipWrapperArchLinuxRolling";
import SoftwareIcon from "../../icons/SoftwareIcon";
@@ -41,7 +42,8 @@ const buildActionOptions = (
gitOpsModeEnabled: boolean | undefined,
repoURL: string | undefined,
source: string | undefined,
androidSoftwareAvailableForInstall: boolean,
canEditSoftware: boolean,
canEditConfiguration: boolean,
canConfigureAutoUpdate: boolean
): CustomOptionType[] => {
let disableEditAppearanceTooltipContent: TooltipContent | undefined;
@@ -69,8 +71,8 @@ const buildActionOptions = (
},
];
// Hides edit software option only for Android installers, as they are currently non-editable
if (!androidSoftwareAvailableForInstall) {
// Hides edit software option only for Android installers (Playstore and Web apps), as they are currently non-editable
if (canEditSoftware) {
options.push({
label: "Edit software",
value: ACTION_EDIT_SOFTWARE,
@@ -79,8 +81,8 @@ const buildActionOptions = (
});
}
// Show edit configuration option only for Android installers
if (androidSoftwareAvailableForInstall) {
// Show edit configuration option only for Android installers that are not web apps
if (canEditConfiguration) {
options.push({
label: "Edit configuration",
value: ACTION_EDIT_CONFIGURATION,
@@ -215,6 +217,7 @@ const SoftwareDetailsSummary = ({
gitOpsModeEnabled,
repoURL,
source,
!!onClickEditSoftware,
!!onClickEditConfiguration,
!!onClickEditAutoUpdateConfig
);
+4
View File
@@ -289,3 +289,7 @@ export const getDisplayedSoftwareName = (
// This should not happen
return "Software";
};
export const isAndroidWebApp = (androidPlayStoreId?: string) =>
!!androidPlayStoreId &&
androidPlayStoreId.startsWith("com.google.enterprise.webapp");