mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
UI – Render "vulns not supported" empty state for iphone/ipad host software filtered by vuln (#21029)
## #21027 <img width="1791" alt="Screenshot 2024-08-02 at 4 12 52 PM" src="https://github.com/user-attachments/assets/bda1af83-4676-484f-b10a-2ca7e2b14ae1"> - [x] Manual QA for all new/changed functionality Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
parent
a6a9a2e1c2
commit
5730c1c3c8
3 changed files with 51 additions and 7 deletions
|
|
@ -53,6 +53,8 @@ import {
|
|||
HOST_OSQUERY_DATA,
|
||||
} from "utilities/constants";
|
||||
|
||||
import { Platform } from "interfaces/platform";
|
||||
|
||||
import Spinner from "components/Spinner";
|
||||
import TabsWrapper from "components/TabsWrapper";
|
||||
import MainContent from "components/MainContent";
|
||||
|
|
@ -921,6 +923,7 @@ const HostDetailsPage = ({
|
|||
<TabPanel>
|
||||
<SoftwareCard
|
||||
id={host.id}
|
||||
platform={host.platform as Platform} // TODO - typing
|
||||
softwareUpdatedAt={host.software_updated_at}
|
||||
hostCanInstallSoftware={
|
||||
!!host.orbit_version || isIosOrIpadosHost
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import deviceAPI, {
|
|||
IGetDeviceSoftwareResponse,
|
||||
} from "services/entities/device_user";
|
||||
import { IHostSoftware, ISoftware } from "interfaces/software";
|
||||
import { Platform } from "interfaces/platform";
|
||||
import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants";
|
||||
import { NotificationContext } from "context/notification";
|
||||
import { AppContext } from "context/app";
|
||||
|
|
@ -34,6 +35,8 @@ export interface ITableSoftware extends Omit<ISoftware, "vulnerabilities"> {
|
|||
interface IHostSoftwareProps {
|
||||
/** This is the host id or the device token */
|
||||
id: number | string;
|
||||
/** The host's platform. Only used for the host details page, so can be omited on the Device User Page. */
|
||||
platform?: Platform;
|
||||
softwareUpdatedAt?: string;
|
||||
hostCanInstallSoftware: boolean;
|
||||
router: InjectedRouter;
|
||||
|
|
@ -82,6 +85,7 @@ export const parseHostSoftwareQueryParams = (queryParams: {
|
|||
|
||||
const HostSoftware = ({
|
||||
id,
|
||||
platform,
|
||||
softwareUpdatedAt,
|
||||
hostCanInstallSoftware,
|
||||
router,
|
||||
|
|
@ -93,6 +97,8 @@ const HostSoftware = ({
|
|||
isMyDevicePage = false,
|
||||
}: IHostSoftwareProps) => {
|
||||
const { renderFlash } = useContext(NotificationContext);
|
||||
const vulnFilterAndNotSupported =
|
||||
["ios", "ipados"].includes(platform ?? "") && queryParams.vulnerable;
|
||||
const {
|
||||
isGlobalAdmin,
|
||||
isGlobalMaintainer,
|
||||
|
|
@ -129,7 +135,8 @@ const HostSoftware = ({
|
|||
},
|
||||
{
|
||||
...DEFAULT_USE_QUERY_OPTIONS,
|
||||
enabled: isSoftwareEnabled && !isMyDevicePage, // if disabled, we'll always show a generic "No software detected" message
|
||||
enabled:
|
||||
isSoftwareEnabled && !isMyDevicePage && !vulnFilterAndNotSupported,
|
||||
keepPreviousData: true,
|
||||
staleTime: 7000,
|
||||
}
|
||||
|
|
@ -158,7 +165,7 @@ const HostSoftware = ({
|
|||
({ queryKey }) => deviceAPI.getDeviceSoftware(queryKey[0]),
|
||||
{
|
||||
...DEFAULT_USE_QUERY_OPTIONS,
|
||||
enabled: isSoftwareEnabled && isMyDevicePage, // if disabled, we'll always show a generic "No software detected" message
|
||||
enabled: isSoftwareEnabled && isMyDevicePage, // if disabled, we'll always show a generic "No software detected" message. No DUP for iPad/iPhone
|
||||
keepPreviousData: true,
|
||||
staleTime: 7000,
|
||||
}
|
||||
|
|
@ -251,7 +258,10 @@ const HostSoftware = ({
|
|||
if (isLoading) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
// will never be the case - to handle `platform` typing discrepancy with DeviceUserPage
|
||||
if (!platform) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{isError && <DataError />}
|
||||
|
|
@ -260,7 +270,20 @@ const HostSoftware = ({
|
|||
isLoading={
|
||||
isMyDevicePage ? deviceSoftwareFetching : hostSoftwareFetching
|
||||
}
|
||||
data={data}
|
||||
// this could be cleaner, however, we are going to revert this commit anyway once vulns are
|
||||
// supported for iPad/iPhone, by the end of next sprint
|
||||
data={
|
||||
vulnFilterAndNotSupported
|
||||
? ({
|
||||
count: 0,
|
||||
meta: {
|
||||
has_next_results: false,
|
||||
has_previous_results: false,
|
||||
},
|
||||
} as IGetHostSoftwareResponse)
|
||||
: data
|
||||
} // eshould be mpty for iPad/iPhone since API call is disabled, but to be sure to trigger empty state
|
||||
platform={platform}
|
||||
router={router}
|
||||
tableConfig={tableConfig}
|
||||
sortHeader={queryParams.order_key}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ import { QueryParams } from "utilities/url";
|
|||
|
||||
import { ISoftwareDropdownFilterVal } from "pages/SoftwarePage/SoftwareTitles/SoftwareTable/helpers";
|
||||
|
||||
import {
|
||||
ApplePlatform,
|
||||
APPLE_PLATFORM_DISPLAY_NAMES,
|
||||
Platform,
|
||||
} from "interfaces/platform";
|
||||
|
||||
import TableContainer from "components/TableContainer";
|
||||
import { ITableQueryData } from "components/TableContainer/TableContainer";
|
||||
// @ts-ignore
|
||||
|
|
@ -15,6 +21,7 @@ import Dropdown from "components/forms/fields/Dropdown";
|
|||
|
||||
import EmptySoftwareTable from "pages/SoftwarePage/components/EmptySoftwareTable";
|
||||
import TableCount from "components/TableContainer/TableCount";
|
||||
import { VulnsNotSupported } from "pages/SoftwarePage/components/SoftwareVulnerabilitiesTable/SoftwareVulnerabilitiesTable";
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 20;
|
||||
|
||||
|
|
@ -45,6 +52,7 @@ export const DROPDOWN_OPTIONS = [
|
|||
interface IHostSoftwareTableProps {
|
||||
tableConfig: any; // TODO: type
|
||||
data?: IGetHostSoftwareResponse | IGetDeviceSoftwareResponse;
|
||||
platform: Platform;
|
||||
isLoading: boolean;
|
||||
router: InjectedRouter;
|
||||
sortHeader: string;
|
||||
|
|
@ -60,6 +68,7 @@ interface IHostSoftwareTableProps {
|
|||
const HostSoftwareTable = ({
|
||||
tableConfig,
|
||||
data,
|
||||
platform,
|
||||
isLoading,
|
||||
router,
|
||||
sortHeader,
|
||||
|
|
@ -167,7 +176,7 @@ const HostSoftwareTable = ({
|
|||
[determineQueryParamChange, pagePath, generateNewQueryParams, router]
|
||||
);
|
||||
|
||||
const count = data?.count || data?.software.length || 0;
|
||||
const count = data?.count || data?.software?.length || 0;
|
||||
const isSoftwareNotDetected = count === 0 && searchQuery === "";
|
||||
|
||||
const memoizedSoftwareCount = useCallback(() => {
|
||||
|
|
@ -179,8 +188,17 @@ const HostSoftwareTable = ({
|
|||
}, [count, isSoftwareNotDetected]);
|
||||
|
||||
const memoizedEmptyComponent = useCallback(() => {
|
||||
return <EmptySoftwareTable isNotDetectingSoftware={searchQuery === ""} />;
|
||||
}, [searchQuery]);
|
||||
const vulnFilterAndNotSupported =
|
||||
["ios", "ipados"].includes(platform) &&
|
||||
hostSoftwareFilter === "vulnerableSoftware";
|
||||
return vulnFilterAndNotSupported ? (
|
||||
<VulnsNotSupported
|
||||
platformText={APPLE_PLATFORM_DISPLAY_NAMES[platform as ApplePlatform]}
|
||||
/>
|
||||
) : (
|
||||
<EmptySoftwareTable isNotDetectingSoftware={searchQuery === ""} />
|
||||
);
|
||||
}, [hostSoftwareFilter, platform, searchQuery]);
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue