mirror of
https://github.com/fleetdm/fleet
synced 2026-05-22 08:28:52 +00:00
## Addresses #12636 ### See issue for list work done   ### Notes for review: - Because other work is based on this branch, TODOs / fixes are noted here until the team comes to a strategy for merging all of the work: - Add missing space in the Performance impact column "Undetermined" tooltip text - I'm having trouble confirming that the inherited queries table is working right with the mock hard-coded data, though I did see it working correctly previously. There's an issue with the page reverting to "All teams" when trying to show the inherited table, though it does show the table before re-rendering. - This work is organized clearly by commit, so that might be a manageable way to go through this code. - Since the updated API for this work is not yet complete, this work can be manually tested by either: - Using mock API infrastructure, or - in `ManageQueriesPage.tsx`, comment out the two `useQuery` calls and add appropriate mock data. You can then modify any fields of interest to test their related UI functionality. For example, lines 119 -242 might read: ``` // const { // data: curTeamEnhancedQueries, // error: curTeamQueriesError, // isFetching: isFetchingCurTeamQueries, // refetch: refetchCurTeamQueries, // } = useQuery<IListQueriesResponse, Error, IEnhancedQuery[]>( // [{ scope: "queries", teamId: teamIdForApi }], // () => queriesAPI.loadAll(teamIdForApi), // { // refetchOnWindowFocus: false, // enabled: isRouteOk, // select: (data) => data.queries.map(enhanceQuery), // } // ); // // If a team is selected, fetch inherited global queries as well // const { // data: globalEnhancedQueries, // error: globalQueriesError, // isFetching: isFetchingGlobalQueries, // refetch: refetchGlobalQueries, // } = useQuery<IListQueriesResponse, Error, IEnhancedQuery[]>( // [{ scope: "queries", teamId: -1 }], // () => queriesAPI.loadAll(), // { // refetchOnWindowFocus: false, // enabled: isRouteOk && isAnyTeamSelected, // select: (data) => data.queries.map(enhanceQuery), // } // ); const [ curTeamEnhancedQueries, curTeamQueriesError, isFetchingCurTeamQueries, refetchCurTeamQueries, ] = useMemo(() => { return [ [ { created_at: "2023-06-08T15:31:35Z", updated_at: "2023-06-08T15:31:35Z", id: 2, name: "test", description: "", query: "SELECT * FROM osquery_info;", team_id: 43, platform: "darwin", min_osquery_version: "", automations_enabled: true, logging: "snapshot", saved: true, // interval: 300, interval: 0, observer_can_run: false, author_id: 1, author_name: "Jacob", author_email: "jacob@fleetdm.com", packs: [], stats: { // system_time_p50: 1, // system_time_p95: null, // user_time_p50: 1, // user_time_p95: null, // total_executions: 1, }, performance: "Undetermined", platforms: ["darwin"], }, ] as IEnhancedQuery[], undefined, false, () => { console.log("got the new queries"); }, ]; }, []); const [ globalEnhancedQueries, globalQueriesError, isFetchingGlobalQueries, refetchGlobalQueries, ] = useMemo(() => { return [ [ { created_at: "2023-06-08T15:31:35Z", updated_at: "2023-06-08T15:31:35Z", id: 200, name: "test", description: "", query: "SELECT * FROM osquery_info;", team_id: null, platform: "darwin", min_osquery_version: "", automations_enabled: true, logging: "snapshot", saved: true, // interval: 300, interval: 0, observer_can_run: false, author_id: 1, author_name: "Jacob", author_email: "jacob@fleetdm.com", packs: [], stats: { // system_time_p50: 1, // system_time_p95: null, // user_time_p50: 1, // user_time_p95: null, // total_executions: 1, }, performance: "Undetermined", platforms: ["darwin"], }, ] as IEnhancedQuery[], undefined, false, () => { console.log("got the new inherited queries"); }, ]; }, []); ``` - [x] Changes file added for user-visible changes in `changes/` - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
111 lines
2.7 KiB
TypeScript
111 lines
2.7 KiB
TypeScript
import React from "react";
|
||
import classnames from "classnames";
|
||
import { uniqueId } from "lodash";
|
||
|
||
import ReactTooltip from "react-tooltip";
|
||
|
||
interface IPillCellProps {
|
||
value: { indicator: string; id: number };
|
||
customIdPrefix?: string;
|
||
}
|
||
|
||
const generateClassTag = (rawValue: string): string => {
|
||
return rawValue.replace(" ", "-").toLowerCase();
|
||
};
|
||
|
||
const PillCell = ({ value, customIdPrefix }: IPillCellProps): JSX.Element => {
|
||
const { indicator, id } = value;
|
||
const pillClassName = classnames(
|
||
"data-table__pill",
|
||
`data-table__pill--${generateClassTag(indicator || "")}`,
|
||
"tooltip"
|
||
);
|
||
|
||
const disable = () => {
|
||
switch (indicator) {
|
||
case "Minimal":
|
||
return false;
|
||
case "Considerable":
|
||
return false;
|
||
case "Excessive":
|
||
return false;
|
||
case "Undetermined":
|
||
return false;
|
||
default:
|
||
return true;
|
||
}
|
||
};
|
||
|
||
const tooltipText = () => {
|
||
switch (indicator) {
|
||
case "Minimal":
|
||
return (
|
||
<>
|
||
Running this query very <br />
|
||
frequently has little to no <br /> impact on your device’s <br />
|
||
performance.
|
||
</>
|
||
);
|
||
case "Considerable":
|
||
return (
|
||
<>
|
||
Running this query <br /> frequently can have a <br /> noticeable
|
||
impact on your <br /> device’s performance.
|
||
</>
|
||
);
|
||
case "Excessive":
|
||
return (
|
||
<>
|
||
Running this query, even <br /> infrequently, can have a <br />
|
||
significant impact on your <br /> device’s performance.
|
||
</>
|
||
);
|
||
case "Denylisted":
|
||
return (
|
||
<>
|
||
This query has been <br /> stopped from running <br /> because of
|
||
excessive <br /> resource consumption.
|
||
</>
|
||
);
|
||
case "Undetermined":
|
||
return (
|
||
<>
|
||
To see performance impact, this query must have run with
|
||
<b>automations</b> on at least one host.
|
||
</>
|
||
);
|
||
default:
|
||
return null;
|
||
}
|
||
};
|
||
const tooltipId = uniqueId();
|
||
|
||
return (
|
||
<>
|
||
<span
|
||
data-tip
|
||
data-for={`${customIdPrefix || "pill"}__${id?.toString() || tooltipId}`}
|
||
data-tip-disable={disable()}
|
||
>
|
||
<span className={pillClassName}>{indicator}</span>
|
||
</span>
|
||
<ReactTooltip
|
||
place="top"
|
||
effect="solid"
|
||
backgroundColor="#3e4771"
|
||
id={`${customIdPrefix || "pill"}__${id?.toString() || tooltipId}`}
|
||
data-html
|
||
>
|
||
<span
|
||
className={`tooltip ${generateClassTag(
|
||
indicator || ""
|
||
)}__tooltip-text`}
|
||
>
|
||
{tooltipText()}
|
||
</span>
|
||
</ReactTooltip>
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default PillCell;
|