Skip to content

Commit

Permalink
UI - Update targeted platforms display logic in the queries table (#2…
Browse files Browse the repository at this point in the history
…5037)

### Unreleased bug where queries targeting all platforms display as
targeting no platforms in the Queries table.

The below query is set to target _all_ platforms.

**Bug:**
<img width="1248" alt="Screenshot 2024-12-29 at 8 24 50 PM"
src="https://github.com/user-attachments/assets/90c9a498-f7d8-4d86-88f1-061c985fb4fa"
/>

**Fix:**
Targeting all platforms, frequency set, displays platform icons:
<img width="1248" alt="Screenshot 2024-12-29 at 8 25 25 PM"
src="https://github.com/user-attachments/assets/d03c1bba-e5ea-461a-b506-1840cf4ffa8e"
/>

Targeting all paltforms but no frequency set (i.e., no schedule), no
targeted platforms displayed:
<img width="1248" alt="Screenshot 2024-12-29 at 8 25 38 PM"
src="https://github.com/user-attachments/assets/9b08a8c3-b682-4eb0-aeb4-59a6e0144e14"
/>

- [x] Manual QA for all new/changed functionality
- [x] Updated tests

---------

Co-authored-by: Jacob Shandling <[email protected]>
  • Loading branch information
jacobshandling and Jacob Shandling authored Dec 30, 2024
1 parent ca37183 commit fea4dd7
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
import React from "react";
import { render, screen } from "@testing-library/react";

import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";

import { QueryablePlatform } from "interfaces/platform";
import { ScheduledQueryablePlatform } from "interfaces/platform";
import PlatformCell from "./PlatformCell";

const PLATFORMS: QueryablePlatform[] = ["windows", "darwin", "linux", "chrome"];
const SCHEDULED_QUERYABLE_PLATFORMS: ScheduledQueryablePlatform[] = [
"windows",
"darwin",
"linux",
];

describe("Platform cell", () => {
it("renders platform icons in correct order", () => {
render(<PlatformCell platforms={PLATFORMS} />);
render(<PlatformCell platforms={SCHEDULED_QUERYABLE_PLATFORMS} />);

const icons = screen.queryByTestId("icons");
const appleIcon = screen.queryByTestId("darwin-icon");
const linuxIcon = screen.queryByTestId("linux-icon");
const windowsIcon = screen.queryByTestId("windows-icon");
const chromeIcon = screen.queryByTestId("chrome-icon");

expect(icons?.firstChild).toBe(appleIcon);
expect(icons?.firstChild?.nextSibling).toBe(windowsIcon);
expect(icons?.firstChild?.nextSibling?.nextSibling).toBe(linuxIcon);
expect(icons?.firstChild?.nextSibling?.nextSibling?.nextSibling).toBe(
chromeIcon
);
});
it("renders empty state", () => {
it("renders all platforms targeted when no platforms passed in and scheduled", () => {
render(<PlatformCell platforms={[]} />);

const emptyText = screen.queryByText(DEFAULT_EMPTY_CELL_VALUE);
const icons = screen.queryByTestId("icons");
const appleIcon = screen.queryByTestId("darwin-icon");
const linuxIcon = screen.queryByTestId("linux-icon");
const windowsIcon = screen.queryByTestId("windows-icon");

expect(emptyText).toBeInTheDocument();
expect(icons?.firstChild).toBe(appleIcon);
expect(icons?.firstChild?.nextSibling).toBe(windowsIcon);
expect(icons?.firstChild?.nextSibling?.nextSibling).toBe(linuxIcon);
});
});
Original file line number Diff line number Diff line change
@@ -1,52 +1,43 @@
import React from "react";
import Icon from "components/Icon";
import { QueryablePlatform } from "interfaces/platform";
import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";
import { ScheduledQueryablePlatform } from "interfaces/platform";

interface IPlatformCellProps {
platforms: QueryablePlatform[];
platforms: ScheduledQueryablePlatform[];
}

const baseClass = "platform-cell";

const ICONS: Record<string, QueryablePlatform> = {
const ICONS: Record<string, ScheduledQueryablePlatform> = {
darwin: "darwin",
windows: "windows",
linux: "linux",
chrome: "chrome",
};

const DISPLAY_ORDER: QueryablePlatform[] = [
const DISPLAY_ORDER: ScheduledQueryablePlatform[] = [
"darwin",
"windows",
"linux",
"chrome",
// "None",
// "Invalid query",
];

const PlatformCell = ({ platforms }: IPlatformCellProps): JSX.Element => {
const orderedList = DISPLAY_ORDER.filter((platform) =>
platforms.includes(platform)
);
let orderedList: ScheduledQueryablePlatform[] = [];
orderedList = platforms.length
? // if no platforms, interpret as targeting all schedule-targetable platforms
DISPLAY_ORDER.filter((platform) => platforms.includes(platform))
: DISPLAY_ORDER;
return (
<span className={`${baseClass}__wrapper`} data-testid="icons">
{orderedList.length ? (
orderedList.map((platform) => {
return ICONS[platform] ? (
<Icon
className={`${baseClass}__icon`}
name={ICONS[platform]}
size="small"
key={ICONS[platform]}
/>
) : null;
})
) : (
<span className={`${baseClass}__muted`}>
{DEFAULT_EMPTY_CELL_VALUE}
</span>
)}
{orderedList.map((platform) => {
return ICONS[platform] ? (
<Icon
className={`${baseClass}__icon`}
name={ICONS[platform]}
size="small"
key={ICONS[platform]}
/>
) : null;
})}
</span>
);
};
Expand Down
16 changes: 16 additions & 0 deletions frontend/interfaces/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type QueryableDisplayPlatform = Exclude<
DisplayPlatform,
"iOS" | "iPadOS"
>;

export type QueryablePlatform = Exclude<Platform, "ios" | "ipados">;

export const QUERYABLE_PLATFORMS: QueryablePlatform[] = [
Expand All @@ -34,6 +35,21 @@ export const isQueryablePlatform = (
): platform is QueryablePlatform =>
QUERYABLE_PLATFORMS.includes(platform as QueryablePlatform);

export const SCHEDULED_QUERYABLE_PLATFORMS: ScheduledQueryablePlatform[] = [
"darwin",
"windows",
"linux",
];

export type ScheduledQueryablePlatform = Exclude<QueryablePlatform, "chrome">;

export const isScheduledQueryablePlatform = (
platform: string | undefined
): platform is ScheduledQueryablePlatform =>
SCHEDULED_QUERYABLE_PLATFORMS.includes(
platform as ScheduledQueryablePlatform
);

// TODO - add "iOS" and "iPadOS" once we support them
export const VULN_SUPPORTED_PLATFORMS: Platform[] = ["darwin", "windows"];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
ISchedulableQuery,
} from "interfaces/schedulable_query";
import {
isQueryablePlatform,
QueryablePlatform,
isScheduledQueryablePlatform,
ScheduledQueryablePlatform,
SelectedPlatformString,
} from "interfaces/platform";
import { API_ALL_TEAMS_ID } from "interfaces/team";
Expand Down Expand Up @@ -189,12 +189,18 @@ const generateTableHeaders = ({
disableSortBy: true,
accessor: "platform",
Cell: (cellProps: IPlatformCellProps): JSX.Element => {
if (!cellProps.row.original.interval) {
// if the query isn't scheduled to run, return default empty call
return <TextCell />;
}
const platforms = cellProps.cell.value
.split(",")
.map((s) => s.trim())
// this casting is necessary because make generate for some reason doesn't recognize the
// type guarding of `isQueryablePlatform` even though the language server in VSCode does
.filter((s) => isQueryablePlatform(s)) as QueryablePlatform[];
.filter((s) =>
isScheduledQueryablePlatform(s)
) as ScheduledQueryablePlatform[];
return <PlatformCell platforms={platforms} />;
},
},
Expand Down

0 comments on commit fea4dd7

Please sign in to comment.