From 88fe04ebdf91fc72dfccee9c43df94242fa68768 Mon Sep 17 00:00:00 2001
From: jacobshandling <61553566+jacobshandling@users.noreply.github.com>
Date: Tue, 8 Oct 2024 12:19:32 -0700
Subject: [PATCH] UI - Show installer extension in select options (#22720)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## #22656
- Tighten software `source` and `browser` types
- Include package extensions, when present, in help text
- [x] Manual QA for all new/changed functionality
---------
Co-authored-by: Jacob Shandling
---
frontend/__mocks__/softwareMock.ts | 6 ++--
frontend/interfaces/software.ts | 28 +++++++++++--------
.../Software/DeviceSoftwareTableConfig.tsx | 8 ++++--
.../Software/HostSoftwareTableConfig.tsx | 7 ++++-
.../SoftwareDetailsModal.tsx | 3 +-
.../InstallSoftwareModal.tsx | 17 ++++++-----
6 files changed, 41 insertions(+), 28 deletions(-)
diff --git a/frontend/__mocks__/softwareMock.ts b/frontend/__mocks__/softwareMock.ts
index a40589a099..ff0e8d17e0 100644
--- a/frontend/__mocks__/softwareMock.ts
+++ b/frontend/__mocks__/softwareMock.ts
@@ -71,8 +71,8 @@ const DEFAULT_SOFTWARE_VERSION_MOCK: ISoftwareVersion = {
name: "test.app",
version: "1.2.3",
bundle_identifier: "com.test.Desktop",
- source: "test_package",
- browser: "",
+ source: "apps",
+ browser: "chrome",
release: "1",
vendor: "test_vendor",
arch: "x86_64",
@@ -161,7 +161,7 @@ const DEFAULT_SOFTWARE_TITLE_DETAILS_MOCK: ISoftwareTitleDetails = {
name: "test.app",
software_package: null,
app_store_app: null,
- source: "test_package",
+ source: "apps",
hosts_count: 1,
versions: [createMockSoftwareTitleVersion()],
bundle_identifier: "com.test.Desktop",
diff --git a/frontend/interfaces/software.ts b/frontend/interfaces/software.ts
index 5db289051a..c81db2921f 100644
--- a/frontend/interfaces/software.ts
+++ b/frontend/interfaces/software.ts
@@ -95,12 +95,12 @@ export interface ISoftwareTitle {
id: number;
name: string;
versions_count: number;
- source: string; // "apps" | "ios_apps" | "ipados_apps" | ?
+ source: SoftwareSource;
hosts_count: number;
versions: ISoftwareTitleVersion[] | null;
software_package: ISoftwarePackage | null;
app_store_app: IAppStoreApp | null;
- browser?: string;
+ browser?: BrowserType;
}
export interface ISoftwareTitleDetails {
@@ -108,12 +108,12 @@ export interface ISoftwareTitleDetails {
name: string;
software_package: ISoftwarePackage | null;
app_store_app: IAppStoreApp | null;
- source: string; // "apps" | "ios_apps" | "ipados_apps" | ?
+ source: SoftwareSource;
hosts_count: number;
versions: ISoftwareTitleVersion[] | null;
versions_updated_at?: string;
bundle_identifier?: string;
- browser?: string;
+ browser?: BrowserType;
versions_count?: number;
}
@@ -134,8 +134,8 @@ export interface ISoftwareVersion {
name: string; // e.g., "Figma.app"
version: string; // e.g., "2.1.11"
bundle_identifier?: string; // e.g., "com.figma.Desktop"
- source: string; // "apps" | "ipados_apps" | "ios_apps" | ?
- browser: string; // e.g., "chrome"
+ source: SoftwareSource;
+ browser: BrowserType;
release: string; // TODO: on software/verions/:id?
vendor: string;
arch: string; // e.g., "x86_64" // TODO: on software/verions/:id?
@@ -144,7 +144,7 @@ export interface ISoftwareVersion {
hosts_count?: number;
}
-export const SOURCE_TYPE_CONVERSION: Record = {
+export const SOURCE_TYPE_CONVERSION = {
apt_sources: "Package (APT)",
deb_packages: "Package (deb)",
portage_packages: "Package (Portage)",
@@ -167,7 +167,9 @@ export const SOURCE_TYPE_CONVERSION: Record = {
vscode_extensions: "IDE extension (VS Code)",
} as const;
-const BROWSER_TYPE_CONVERSION: Record = {
+export type SoftwareSource = keyof typeof SOURCE_TYPE_CONVERSION;
+
+const BROWSER_TYPE_CONVERSION = {
chrome: "Chrome",
chromium: "Chromium",
opera: "Opera",
@@ -177,14 +179,16 @@ const BROWSER_TYPE_CONVERSION: Record = {
edge_beta: "Edge Beta",
} as const;
+export type BrowserType = keyof typeof BROWSER_TYPE_CONVERSION;
+
export const formatSoftwareType = ({
source,
browser,
}: {
- source: string;
- browser?: string;
+ source: SoftwareSource;
+ browser?: BrowserType;
}) => {
- let type = SOURCE_TYPE_CONVERSION[source] || "Unknown";
+ let type: string = SOURCE_TYPE_CONVERSION[source] || "Unknown";
if (browser) {
type = `Browser plugin (${
BROWSER_TYPE_CONVERSION[browser] || startCase(browser)
@@ -310,7 +314,7 @@ export interface IHostSoftware {
name: string;
software_package: IHostSoftwarePackage | null;
app_store_app: IHostAppStoreApp | null;
- source: string;
+ source: SoftwareSource;
bundle_identifier?: string;
status: Exclude | null;
installed_versions: ISoftwareInstallVersion[] | null;
diff --git a/frontend/pages/hosts/details/cards/Software/DeviceSoftwareTableConfig.tsx b/frontend/pages/hosts/details/cards/Software/DeviceSoftwareTableConfig.tsx
index 98a0c8b131..ea9e7cfb69 100644
--- a/frontend/pages/hosts/details/cards/Software/DeviceSoftwareTableConfig.tsx
+++ b/frontend/pages/hosts/details/cards/Software/DeviceSoftwareTableConfig.tsx
@@ -1,7 +1,11 @@
import React from "react";
import { CellProps, Column } from "react-table";
-import { IHostSoftware, SOURCE_TYPE_CONVERSION } from "interfaces/software";
+import {
+ IHostSoftware,
+ SoftwareSource,
+ SOURCE_TYPE_CONVERSION,
+} from "interfaces/software";
import { IHeaderProps, IStringCellProps } from "interfaces/datatable_config";
import HeaderCell from "components/TableContainer/DataTable/HeaderCell/HeaderCell";
@@ -21,7 +25,7 @@ type IInstalledVersionsCellProps = CellProps<
>;
type IVulnerabilitiesCellProps = IInstalledVersionsCellProps;
-const formatSoftwareType = (source: string) => {
+const formatSoftwareType = (source: SoftwareSource) => {
const DICT = SOURCE_TYPE_CONVERSION;
return DICT[source] || "Unknown";
};
diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
index c6a07ce7fa..e52b93ea12 100644
--- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
+++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
@@ -8,6 +8,7 @@ import {
IHostSoftware,
IHostSoftwarePackage,
SoftwareInstallStatus,
+ SoftwareSource,
formatSoftwareType,
isIpadOrIphoneSoftwareSource,
} from "interfaces/software";
@@ -201,7 +202,11 @@ export const generateSoftwareTableHeaders = ({
Cell: (cellProps: ITableStringCellProps) => (
formatSoftwareType({ source: cellProps.cell.value })}
+ formatter={() =>
+ formatSoftwareType({
+ source: cellProps.cell.value as SoftwareSource,
+ })
+ }
/>
),
},
diff --git a/frontend/pages/hosts/details/cards/Software/SoftwareDetailsModal/SoftwareDetailsModal.tsx b/frontend/pages/hosts/details/cards/Software/SoftwareDetailsModal/SoftwareDetailsModal.tsx
index 2fff0a4fb4..33726b8081 100644
--- a/frontend/pages/hosts/details/cards/Software/SoftwareDetailsModal/SoftwareDetailsModal.tsx
+++ b/frontend/pages/hosts/details/cards/Software/SoftwareDetailsModal/SoftwareDetailsModal.tsx
@@ -4,6 +4,7 @@ import { Tab, TabList, TabPanel, Tabs } from "react-tabs";
import {
IHostSoftware,
ISoftwareInstallVersion,
+ SoftwareSource,
formatSoftwareType,
hasHostSoftwareAppLastInstall,
hasHostSoftwarePackageLastInstall,
@@ -37,7 +38,7 @@ const generateVulnerabilitiesValue = (vulnerabilities: string[]) => {
interface ISoftwareDetailsInfoProps {
installedVersion: ISoftwareInstallVersion;
- source: string;
+ source: SoftwareSource;
bundleIdentifier?: string;
}
diff --git a/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx b/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx
index 7af8236593..0d9681c203 100644
--- a/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx
+++ b/frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx
@@ -21,17 +21,14 @@ import CustomLink from "components/CustomLink";
import Button from "components/buttons/Button";
import { ISoftwareTitle } from "interfaces/software";
-const getPlatformDisplayFromPackageSuffix = (packageName: string) => {
- const split = packageName.split(".");
- const suff = split[split.length - 1];
- switch (suff) {
+const getPlatformDisplayFromPackageExtension = (ext: string | undefined) => {
+ switch (ext) {
case "pkg":
return "macOS";
case "deb":
case "rpm":
return "Linux";
case "exe":
- return "Windows";
case "msi":
return "Windows";
default:
@@ -153,10 +150,12 @@ const InstallSoftwareModal = ({
);
const availableSoftwareOptions = titlesAFI?.map((title) => {
- const platformDisplay = getPlatformDisplayFromPackageSuffix(
- title.software_package?.name ?? ""
- );
- const platformString = platformDisplay ? `${platformDisplay} • ` : "";
+ const splitName = title.software_package?.name.split(".") ?? "";
+ const ext =
+ splitName.length > 1 ? splitName[splitName.length - 1] : undefined;
+ const platformString = ext
+ ? `${getPlatformDisplayFromPackageExtension(ext)} (.${ext}) • `
+ : "";
return {
label: title.name,
value: title.id,