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 Screenshot 2024-10-07 at 3 09 47 PM - [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,