mirror of
https://github.com/fleetdm/fleet
synced 2026-05-20 23:48:52 +00:00
## Addresses second major part of #15011 (item 3) – Host query report _Note for reviewers: The most important files here are:_ - HostQueryReport.tsx - HQRTable.tsx - HQRTableConfig.tsx _The rest are associated API services, interfaces, helpers, routes, styles, and miscellanious code improvements I made along the way._ ____________ ### See linked issue for enumeration of feature-related tasks <img width="1230" alt="Screenshot 2023-12-08 at 4 23 50 PM" src="https://github.com/fleetdm/fleet/assets/61553566/4ae4b41b-9209-4afa-ae50-8844d01ff8fd"> <img width="1230" alt="collecting" src="https://github.com/fleetdm/fleet/assets/61553566/061ac2bc-899f-4b29-91ba-36ebecf5ce58"> <img width="1230" alt="Screenshot 2023-12-08 at 4 24 39 PM" src="https://github.com/fleetdm/fleet/assets/61553566/f8b25e01-fe3b-47e6-b980-eba9538b1a01"> <img width="1230" alt="Screenshot 2023-12-08 at 4 25 01 PM" src="https://github.com/fleetdm/fleet/assets/61553566/46360274-8500-494c-8fb7-3a1d45347ce0"> Re-routes to host details > queries if: - query reports are globally disabled: https://github.com/fleetdm/fleet/assets/61553566/ac67da8c-57bc-4d9b-96be-daf3b198e704 - query has `Discard data` enabled: https://github.com/fleetdm/fleet/assets/61553566/b797dd24-9893-4360-bf40-b80298848864 - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
130 lines
3.7 KiB
TypeScript
130 lines
3.7 KiB
TypeScript
import React, { useState } from "react";
|
|
|
|
import simpleSearch from "utilities/simple_search";
|
|
import { IScheduledQuery } from "interfaces/scheduled_query";
|
|
|
|
import TableContainer from "components/TableContainer";
|
|
import { ITableQueryData } from "components/TableContainer/TableContainer";
|
|
import Button from "components/buttons/Button";
|
|
import EmptyTable from "components/EmptyTable";
|
|
import Icon from "components/Icon/Icon";
|
|
import {
|
|
generateTableHeaders,
|
|
generateDataSet,
|
|
} from "./PackQueriesTable/PackQueriesTableConfig";
|
|
|
|
const baseClass = "pack-queries-table";
|
|
|
|
interface IPackQueriesTableProps {
|
|
onAddPackQuery: () => void;
|
|
onEditPackQuery: (selectedQuery: IScheduledQuery) => void;
|
|
onRemovePackQueries: (selectedTableQueryIds: number[]) => void;
|
|
scheduledQueries: IScheduledQuery[] | undefined;
|
|
isLoadingPackQueries: boolean;
|
|
}
|
|
|
|
const PackQueriesTable = ({
|
|
onAddPackQuery,
|
|
onEditPackQuery,
|
|
onRemovePackQueries,
|
|
scheduledQueries,
|
|
isLoadingPackQueries,
|
|
}: IPackQueriesTableProps): JSX.Element => {
|
|
const [querySearchText, setQuerySearchText] = useState("");
|
|
|
|
// NOTE: this is called once on the initial rendering. The initial render of
|
|
// the TableContainer child component will call this handler.
|
|
const onTableQueryChange = (queryData: ITableQueryData) => {
|
|
const { searchQuery, sortHeader, sortDirection } = queryData;
|
|
let sortBy = [];
|
|
if (sortHeader !== "") {
|
|
sortBy = [{ id: sortHeader, direction: sortDirection }];
|
|
}
|
|
|
|
if (!searchQuery) {
|
|
setQuerySearchText("");
|
|
return;
|
|
}
|
|
|
|
setQuerySearchText(searchQuery);
|
|
};
|
|
|
|
const getQueries = () => {
|
|
return simpleSearch(querySearchText, scheduledQueries);
|
|
};
|
|
|
|
const onActionSelection = (
|
|
action: string,
|
|
selectedQuery: IScheduledQuery
|
|
) => {
|
|
switch (action) {
|
|
case "edit":
|
|
onEditPackQuery(selectedQuery);
|
|
break;
|
|
case "remove":
|
|
onRemovePackQueries([selectedQuery.id]);
|
|
break;
|
|
default:
|
|
}
|
|
};
|
|
|
|
const tableHeaders = generateTableHeaders(onActionSelection);
|
|
const tableData = generateDataSet(getQueries());
|
|
|
|
return (
|
|
<div className={`${baseClass} body-wrap`}>
|
|
{scheduledQueries?.length ? (
|
|
<TableContainer
|
|
columnConfigs={tableHeaders}
|
|
data={tableData}
|
|
isLoading={isLoadingPackQueries}
|
|
defaultSortHeader={"name"}
|
|
defaultSortDirection={"asc"}
|
|
inputPlaceHolder={"Search queries"}
|
|
onQueryChange={onTableQueryChange}
|
|
resultsTitle={"queries"}
|
|
emptyComponent={() =>
|
|
EmptyTable({
|
|
header: "No queries match your search criteria.",
|
|
info: "Try a different search.",
|
|
})
|
|
}
|
|
showMarkAllPages={false}
|
|
actionButton={{
|
|
name: "add query",
|
|
buttonText: "Add query",
|
|
iconSvg: "plus",
|
|
variant: "text-icon",
|
|
onActionButtonClick: onAddPackQuery,
|
|
}}
|
|
primarySelectAction={{
|
|
name: "remove query",
|
|
buttonText: "Remove",
|
|
iconSvg: "close",
|
|
variant: "text-icon",
|
|
onActionButtonClick: onRemovePackQueries,
|
|
}}
|
|
searchable
|
|
disablePagination
|
|
isAllPagesSelected={false}
|
|
/>
|
|
) : (
|
|
<div className={`${baseClass}__no-queries`}>
|
|
<p>Your pack has no queries.</p>
|
|
<Button
|
|
onClick={onAddPackQuery}
|
|
variant={"text-icon"}
|
|
className={`${baseClass}__no-queries-action-button`}
|
|
>
|
|
<>
|
|
Add query
|
|
<Icon name="plus" />
|
|
</>
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PackQueriesTable;
|