mirror of
https://github.com/fleetdm/fleet
synced 2026-05-18 22:49:19 +00:00
306 lines
8.2 KiB
TypeScript
306 lines
8.2 KiB
TypeScript
/* eslint-disable react/prop-types */
|
|
// disable this rule as it was throwing an error in Header and Cell component
|
|
// definitions for the selection row for some reason when we dont really need it.
|
|
import React from "react";
|
|
import { find } from "lodash";
|
|
|
|
import { performanceIndicator } from "fleet/helpers";
|
|
import { IScheduledQuery } from "interfaces/scheduled_query";
|
|
import { IDropdownOption } from "interfaces/dropdownOption";
|
|
|
|
import Checkbox from "components/forms/fields/Checkbox";
|
|
import DropdownCell from "components/TableContainer/DataTable/DropdownCell";
|
|
import HeaderCell from "components/TableContainer/DataTable/HeaderCell/HeaderCell";
|
|
import PillCell from "components/TableContainer/DataTable/PillCell";
|
|
import TextCell from "components/TableContainer/DataTable/TextCell";
|
|
import TooltipWrapper from "components/TooltipWrapper";
|
|
|
|
interface IGetToggleAllRowsSelectedProps {
|
|
checked: boolean;
|
|
indeterminate: boolean;
|
|
title: string;
|
|
onChange: () => void;
|
|
style: { cursor: string };
|
|
}
|
|
interface IHeaderProps {
|
|
column: {
|
|
title: string;
|
|
isSortedDesc: boolean;
|
|
};
|
|
getToggleAllRowsSelectedProps: () => IGetToggleAllRowsSelectedProps;
|
|
toggleAllRowsSelected: () => void;
|
|
}
|
|
|
|
interface IRowProps {
|
|
row: {
|
|
original: IScheduledQuery;
|
|
getToggleRowSelectedProps: () => IGetToggleAllRowsSelectedProps;
|
|
toggleRowSelected: () => void;
|
|
};
|
|
}
|
|
|
|
interface ICellProps extends IRowProps {
|
|
cell: {
|
|
value: string | number | boolean;
|
|
};
|
|
}
|
|
|
|
interface IPillCellProps extends IRowProps {
|
|
cell: {
|
|
value: [string, number];
|
|
};
|
|
}
|
|
|
|
interface IDropdownCellProps extends IRowProps {
|
|
cell: {
|
|
value: IDropdownOption[];
|
|
};
|
|
}
|
|
|
|
interface IDataColumn {
|
|
id?: string;
|
|
title?: string;
|
|
Header: ((props: IHeaderProps) => JSX.Element) | string;
|
|
accessor?: string;
|
|
Cell:
|
|
| ((props: ICellProps) => JSX.Element)
|
|
| ((props: IPillCellProps) => JSX.Element)
|
|
| ((props: IDropdownCellProps) => JSX.Element);
|
|
disableHidden?: boolean;
|
|
disableSortBy?: boolean;
|
|
}
|
|
|
|
interface IPackQueriesTableData extends IScheduledQuery {
|
|
loggingTypeString: string;
|
|
}
|
|
|
|
// NOTE: cellProps come from react-table
|
|
// more info here https://react-table.tanstack.com/docs/api/useTable#cell-properties
|
|
const generateTableHeaders = (
|
|
actionSelectHandler: (value: string, scheduled_query: IScheduledQuery) => void
|
|
): IDataColumn[] => {
|
|
return [
|
|
{
|
|
id: "selection",
|
|
Header: (cellProps: IHeaderProps): JSX.Element => {
|
|
const props = cellProps.getToggleAllRowsSelectedProps();
|
|
const checkboxProps = {
|
|
value: props.checked,
|
|
indeterminate: props.indeterminate,
|
|
onChange: () => cellProps.toggleAllRowsSelected(),
|
|
};
|
|
return <Checkbox {...checkboxProps} />;
|
|
},
|
|
Cell: (cellProps: ICellProps): JSX.Element => {
|
|
const props = cellProps.row.getToggleRowSelectedProps();
|
|
const checkboxProps = {
|
|
value: props.checked,
|
|
onChange: () => cellProps.row.toggleRowSelected(),
|
|
};
|
|
return <Checkbox {...checkboxProps} />;
|
|
},
|
|
disableHidden: true,
|
|
},
|
|
{
|
|
title: "Query name",
|
|
Header: (cellProps) => (
|
|
<HeaderCell
|
|
value={cellProps.column.title}
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "name",
|
|
Cell: (cellProps: ICellProps) => (
|
|
<TextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
{
|
|
title: "Frequency",
|
|
Header: "Frequency",
|
|
disableSortBy: false,
|
|
accessor: "interval",
|
|
Cell: (cellProps: ICellProps) => (
|
|
<TextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
{
|
|
title: "Platform",
|
|
Header: (cellProps) => (
|
|
<HeaderCell
|
|
value={cellProps.column.title}
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "platformTypeString",
|
|
Cell: (cellProps: ICellProps) => (
|
|
<TextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
{
|
|
title: "Logging",
|
|
Header: "Logging",
|
|
disableSortBy: false,
|
|
accessor: "loggingTypeString",
|
|
Cell: (cellProps: ICellProps) => (
|
|
<TextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
{
|
|
title: "Performance impact",
|
|
Header: () => {
|
|
return (
|
|
<div className="column-with-tooltip">
|
|
<span className="queries-table__performance-impact-header">
|
|
<TooltipWrapper tipContent="This is the average performance impact across all hosts where this query was scheduled.">
|
|
Performance impact
|
|
</TooltipWrapper>
|
|
</span>
|
|
</div>
|
|
);
|
|
},
|
|
disableSortBy: true,
|
|
accessor: "performance",
|
|
Cell: (cellProps: IPillCellProps) => (
|
|
<PillCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
{
|
|
title: "Actions",
|
|
Header: "",
|
|
disableSortBy: true,
|
|
accessor: "actions",
|
|
Cell: (cellProps: IDropdownCellProps) => (
|
|
<DropdownCell
|
|
options={cellProps.cell.value}
|
|
onChange={(value: string) =>
|
|
actionSelectHandler(value, cellProps.row.original)
|
|
}
|
|
placeholder={"Actions"}
|
|
/>
|
|
),
|
|
},
|
|
];
|
|
};
|
|
|
|
const generateLoggingTypeString = (
|
|
snapshot: boolean,
|
|
removed: boolean
|
|
): string => {
|
|
if (snapshot) {
|
|
return "Snapshot";
|
|
}
|
|
|
|
// Default is differential with removals, so we treat null as removed = true
|
|
if (removed !== false) {
|
|
return "Differential";
|
|
}
|
|
|
|
return "Differential (ignore removal)";
|
|
};
|
|
|
|
const generatePlatformTypeString = (platforms: string | undefined): string => {
|
|
const ALL_PLATFORMS = [
|
|
{ text: "All", value: "all" },
|
|
{ text: "Windows", value: "windows" },
|
|
{ text: "Linux", value: "linux" },
|
|
{ text: "macOS", value: "darwin" },
|
|
];
|
|
|
|
if (platforms) {
|
|
const platformsArray = platforms.split(",");
|
|
|
|
const textArray = platformsArray.map((platform) => {
|
|
// Trim spaces from the platform
|
|
const trimmedPlatform = platform.trim();
|
|
const platformObject = find(ALL_PLATFORMS, { value: trimmedPlatform });
|
|
// Convert trimmed value to the corresponding text if the value exists
|
|
// in the ALL_PLATFORMS array.
|
|
// Otherwise, just use the trimmed value.
|
|
const text = platformObject ? platformObject.text : trimmedPlatform;
|
|
|
|
return text;
|
|
});
|
|
|
|
const displayText = textArray.join(", ");
|
|
|
|
return displayText;
|
|
}
|
|
|
|
return "All";
|
|
};
|
|
|
|
const generateVersionString = (version: string | undefined): string => {
|
|
if (version) {
|
|
return version;
|
|
}
|
|
return "Any";
|
|
};
|
|
|
|
const generateActionDropdownOptions = (): IDropdownOption[] => {
|
|
const dropdownOptions = [
|
|
{
|
|
label: "Edit",
|
|
disabled: false,
|
|
value: "edit",
|
|
},
|
|
{
|
|
label: "Remove",
|
|
disabled: false,
|
|
value: "remove",
|
|
},
|
|
];
|
|
return dropdownOptions;
|
|
};
|
|
|
|
const enhancePackQueriesData = (
|
|
packQueries: IScheduledQuery[]
|
|
): IPackQueriesTableData[] => {
|
|
return packQueries.map((query) => {
|
|
const scheduledQueryPerformance = {
|
|
user_time_p50: query.stats?.user_time_p50,
|
|
system_time_p50: query.stats?.system_time_p50,
|
|
total_executions: query.stats?.total_executions,
|
|
};
|
|
return {
|
|
id: query.id,
|
|
name: query.name,
|
|
interval: query.interval,
|
|
pack_id: query.pack_id,
|
|
platform: query.platform || undefined,
|
|
query: query.query,
|
|
query_id: query.query_id,
|
|
removed: query.removed,
|
|
snapshot: query.snapshot,
|
|
loggingTypeString: generateLoggingTypeString(
|
|
query.snapshot,
|
|
query.removed
|
|
),
|
|
platformTypeString: generatePlatformTypeString(query.platform),
|
|
shard: query.shard,
|
|
version: query.version,
|
|
versionString: generateVersionString(query.version),
|
|
created_at: query.created_at,
|
|
updated_at: query.updated_at,
|
|
query_name: query.query_name,
|
|
actions: generateActionDropdownOptions(),
|
|
performance: [
|
|
performanceIndicator(scheduledQueryPerformance),
|
|
query.query_id,
|
|
],
|
|
stats: query.stats,
|
|
};
|
|
});
|
|
};
|
|
|
|
const generateDataSet = (
|
|
queries: IScheduledQuery[]
|
|
): IPackQueriesTableData[] => {
|
|
// Cannot pass undefined to enhancePackQueriesData
|
|
if (!queries) {
|
|
return queries;
|
|
}
|
|
|
|
return [...enhancePackQueriesData(queries)];
|
|
};
|
|
|
|
export { generateTableHeaders, generateDataSet };
|