mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
Fleet UI: Fix new query bugs introduced (#14309)
This commit is contained in:
parent
ab50f0f59d
commit
11fc7edc0f
14 changed files with 137 additions and 62 deletions
|
|
@ -12,7 +12,7 @@ import {
|
|||
ISelectLabel,
|
||||
ISelectTeam,
|
||||
ISelectTargetsEntity,
|
||||
ISelectedTargets,
|
||||
ISelectedTargetsForApi,
|
||||
} from "interfaces/target";
|
||||
import { ITeam } from "interfaces/team";
|
||||
|
||||
|
|
@ -48,8 +48,8 @@ interface ISelectTargetsProps {
|
|||
targetedTeams: ITeam[];
|
||||
goToQueryEditor: () => void;
|
||||
goToRunQuery: () => void;
|
||||
setSelectedTargets:
|
||||
| React.Dispatch<React.SetStateAction<ITarget[]>> // Used for policies page level useState hook
|
||||
setSelectedTargets: // TODO: Refactor policy targets to streamline selectedTargets/selectedTargetsByType
|
||||
| React.Dispatch<React.SetStateAction<ITarget[]>> // Used for policies page level useState hook
|
||||
| ((value: ITarget[]) => void); // Used for queries app level QueryContext
|
||||
setTargetedHosts: React.Dispatch<React.SetStateAction<IHost[]>>;
|
||||
setTargetedLabels: React.Dispatch<React.SetStateAction<ILabel[]>>;
|
||||
|
|
@ -67,7 +67,7 @@ interface ITargetsQueryKey {
|
|||
scope: string;
|
||||
query_id?: number | null;
|
||||
query?: string | null;
|
||||
selected?: ISelectedTargets | null;
|
||||
selected?: ISelectedTargetsForApi | null;
|
||||
}
|
||||
|
||||
const DEBOUNCE_DELAY = 500;
|
||||
|
|
@ -381,12 +381,22 @@ const SelectTargets = ({
|
|||
}
|
||||
|
||||
const { targets_count: total, targets_online: online } = counts;
|
||||
const onlinePercentage = total > 0 ? Math.round((online / total) * 100) : 0;
|
||||
const onlinePercentage = () => {
|
||||
if (total === 0) {
|
||||
return 0;
|
||||
}
|
||||
// If at least 1 host is online, displays <1% instead of 0%
|
||||
const roundPercentage =
|
||||
Math.round((online / total) * 100) === 0
|
||||
? "<1"
|
||||
: Math.round((online / total) * 100) === 0;
|
||||
return roundPercentage;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>{total}</span> host{total > 1 ? `s` : ``} targeted (
|
||||
{onlinePercentage}
|
||||
{onlinePercentage()}
|
||||
%
|
||||
<TooltipWrapper
|
||||
tipContent={`Hosts are online if they<br /> have recently checked <br />into Fleet.`}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@ import { DEFAULT_QUERY } from "utilities/constants";
|
|||
import { DEFAULT_OSQUERY_TABLE, IOsQueryTable } from "interfaces/osquery_table";
|
||||
import { SelectedPlatformString } from "interfaces/platform";
|
||||
import { QueryLoggingOption } from "interfaces/schedulable_query";
|
||||
import { DEFAULT_TARGETS, ITarget } from "interfaces/target";
|
||||
import {
|
||||
DEFAULT_TARGETS,
|
||||
DEFAULT_TARGETS_BY_TYPE,
|
||||
ISelectedTargetsByType,
|
||||
ITarget,
|
||||
} from "interfaces/target";
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
|
|
@ -23,7 +28,8 @@ type InitialStateType = {
|
|||
lastEditedQueryPlatforms: SelectedPlatformString;
|
||||
lastEditedQueryMinOsqueryVersion: string;
|
||||
lastEditedQueryLoggingType: QueryLoggingOption;
|
||||
selectedQueryTargets: ITarget[];
|
||||
selectedQueryTargets: ITarget[]; // Mimicks old selectedQueryTargets still used for policies for SelectTargets.tsx and running a live query
|
||||
selectedQueryTargetsByType: ISelectedTargetsByType; // New format by type for cleaner app wide state
|
||||
setLastEditedQueryId: (value: number | null) => void;
|
||||
setLastEditedQueryName: (value: string) => void;
|
||||
setLastEditedQueryDescription: (value: string) => void;
|
||||
|
|
@ -35,6 +41,7 @@ type InitialStateType = {
|
|||
setLastEditedQueryLoggingType: (value: string) => void;
|
||||
setSelectedOsqueryTable: (tableName: string) => void;
|
||||
setSelectedQueryTargets: (value: ITarget[]) => void;
|
||||
setSelectedQueryTargetsByType: (value: ISelectedTargetsByType) => void;
|
||||
};
|
||||
|
||||
export type IQueryContext = InitialStateType;
|
||||
|
|
@ -52,6 +59,7 @@ const initialState = {
|
|||
lastEditedQueryMinOsqueryVersion: DEFAULT_QUERY.min_osquery_version,
|
||||
lastEditedQueryLoggingType: DEFAULT_QUERY.logging,
|
||||
selectedQueryTargets: DEFAULT_TARGETS,
|
||||
selectedQueryTargetsByType: DEFAULT_TARGETS_BY_TYPE,
|
||||
setLastEditedQueryId: () => null,
|
||||
setLastEditedQueryName: () => null,
|
||||
setLastEditedQueryDescription: () => null,
|
||||
|
|
@ -63,12 +71,14 @@ const initialState = {
|
|||
setLastEditedQueryLoggingType: () => null,
|
||||
setSelectedOsqueryTable: () => null,
|
||||
setSelectedQueryTargets: () => null,
|
||||
setSelectedQueryTargetsByType: () => null,
|
||||
};
|
||||
|
||||
const actions = {
|
||||
SET_SELECTED_OSQUERY_TABLE: "SET_SELECTED_OSQUERY_TABLE",
|
||||
SET_LAST_EDITED_QUERY_INFO: "SET_LAST_EDITED_QUERY_INFO",
|
||||
SET_SELECTED_QUERY_TARGETS: "SET_SELECTED_QUERY_TARGETS",
|
||||
SET_SELECTED_QUERY_TARGETS_BY_TYPE: "SET_SELECTED_QUERY_TARGETS_BY_TYPE",
|
||||
} as const;
|
||||
|
||||
const reducer = (state: InitialStateType, action: any) => {
|
||||
|
|
@ -128,6 +138,14 @@ const reducer = (state: InitialStateType, action: any) => {
|
|||
? state.selectedQueryTargets
|
||||
: action.selectedQueryTargets,
|
||||
};
|
||||
case actions.SET_SELECTED_QUERY_TARGETS_BY_TYPE:
|
||||
return {
|
||||
...state,
|
||||
selectedQueryTargetsByType:
|
||||
typeof action.selectedQueryTargetsByType === "undefined"
|
||||
? state.selectedQueryTargetsByType
|
||||
: action.selectedQueryTargetsByType,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
@ -150,6 +168,7 @@ const QueryProvider = ({ children }: Props) => {
|
|||
lastEditedQueryMinOsqueryVersion: state.lastEditedQueryMinOsqueryVersion,
|
||||
lastEditedQueryLoggingType: state.lastEditedQueryLoggingType,
|
||||
selectedQueryTargets: state.selectedQueryTargets,
|
||||
selectedQueryTargetsByType: state.selectedQueryTargetsByType,
|
||||
setLastEditedQueryId: (lastEditedQueryId: number | null) => {
|
||||
dispatch({
|
||||
type: actions.SET_LAST_EDITED_QUERY_INFO,
|
||||
|
|
@ -214,6 +233,14 @@ const QueryProvider = ({ children }: Props) => {
|
|||
selectedQueryTargets,
|
||||
});
|
||||
},
|
||||
setSelectedQueryTargetsByType: (
|
||||
selectedQueryTargetsByType: ISelectedTargetsByType
|
||||
) => {
|
||||
dispatch({
|
||||
type: actions.SET_SELECTED_QUERY_TARGETS_BY_TYPE,
|
||||
selectedQueryTargetsByType,
|
||||
});
|
||||
},
|
||||
setSelectedOsqueryTable: (tableName: string) => {
|
||||
dispatch({ type: actions.SET_SELECTED_OSQUERY_TABLE, tableName });
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { filter, uniqueId } from "lodash";
|
|||
import { IHost } from "interfaces/host";
|
||||
import { ILabel } from "interfaces/label";
|
||||
import { ITeam } from "interfaces/team";
|
||||
import { ISelectedTargets } from "interfaces/target";
|
||||
import { ISelectedTargetsForApi } from "interfaces/target";
|
||||
import targetsAPI from "services/entities/targets";
|
||||
|
||||
export interface ITargetsLabels {
|
||||
|
|
@ -25,7 +25,7 @@ export interface ITargetsQueryKey {
|
|||
scope: string;
|
||||
query: string;
|
||||
queryId: number | null;
|
||||
selected: ISelectedTargets;
|
||||
selected: ISelectedTargetsForApi;
|
||||
includeLabels: boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,12 +38,18 @@ export interface ISelectTeam extends ITeam {
|
|||
|
||||
export type ISelectTargetsEntity = ISelectHost | ISelectLabel | ISelectTeam;
|
||||
|
||||
export interface ISelectedTargets {
|
||||
export interface ISelectedTargetsForApi {
|
||||
hosts: number[];
|
||||
labels: number[];
|
||||
teams: number[];
|
||||
}
|
||||
|
||||
export interface ISelectedTargetsByType {
|
||||
hosts: IHost[];
|
||||
labels: ILabel[];
|
||||
teams: ITeam[];
|
||||
}
|
||||
|
||||
export interface IPackTargets {
|
||||
host_ids: (number | string)[];
|
||||
label_ids: (number | string)[];
|
||||
|
|
@ -52,3 +58,9 @@ export interface IPackTargets {
|
|||
|
||||
// TODO: Also use for testing
|
||||
export const DEFAULT_TARGETS: ITarget[] = [];
|
||||
|
||||
export const DEFAULT_TARGETS_BY_TYPE: ISelectedTargetsByType = {
|
||||
hosts: [],
|
||||
labels: [],
|
||||
teams: [],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import queryAPI from "services/entities/queries";
|
|||
import teamAPI, { ILoadTeamsResponse } from "services/entities/teams";
|
||||
import { AppContext } from "context/app";
|
||||
import { PolicyContext } from "context/policy";
|
||||
import { QueryContext } from "context/query";
|
||||
import { NotificationContext } from "context/notification";
|
||||
import {
|
||||
IHost,
|
||||
|
|
@ -26,6 +27,7 @@ import { ILabel } from "interfaces/label";
|
|||
import { IHostPolicy } from "interfaces/policy";
|
||||
import { IQueryStats } from "interfaces/query_stats";
|
||||
import { ISoftware } from "interfaces/software";
|
||||
import { DEFAULT_TARGETS_BY_TYPE } from "interfaces/target";
|
||||
import { ITeam } from "interfaces/team";
|
||||
import {
|
||||
IListQueriesResponse,
|
||||
|
|
@ -45,6 +47,7 @@ import {
|
|||
TAGGED_TEMPLATES,
|
||||
} from "utilities/helpers";
|
||||
import permissions from "utilities/permissions";
|
||||
import { DEFAULT_QUERY } from "utilities/constants";
|
||||
|
||||
import HostSummaryCard from "../cards/HostSummary";
|
||||
import AboutCard from "../cards/About";
|
||||
|
|
@ -133,6 +136,7 @@ const HostDetailsPage = ({
|
|||
setLastEditedQueryCritical,
|
||||
setPolicyTeamId,
|
||||
} = useContext(PolicyContext);
|
||||
const { setSelectedQueryTargetsByType } = useContext(QueryContext);
|
||||
const { renderFlash } = useContext(NotificationContext);
|
||||
|
||||
const handlePageError = useErrorHandler();
|
||||
|
|
@ -519,12 +523,15 @@ const HostDetailsPage = ({
|
|||
};
|
||||
|
||||
const onQueryHostCustom = () => {
|
||||
setLastEditedQueryBody(DEFAULT_QUERY.query);
|
||||
setSelectedQueryTargetsByType(DEFAULT_TARGETS_BY_TYPE);
|
||||
router.push(
|
||||
PATHS.NEW_QUERY() + TAGGED_TEMPLATES.queryByHostRoute(host?.id)
|
||||
);
|
||||
};
|
||||
|
||||
const onQueryHostSaved = (selectedQuery: ISchedulableQuery) => {
|
||||
setSelectedQueryTargetsByType(DEFAULT_TARGETS_BY_TYPE);
|
||||
router.push(
|
||||
PATHS.EDIT_QUERY(selectedQuery.id) +
|
||||
TAGGED_TEMPLATES.queryByHostRoute(host?.id)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { useQuery } from "react-query";
|
|||
import { pick } from "lodash";
|
||||
|
||||
import { AppContext } from "context/app";
|
||||
import { QueryContext } from "context/query";
|
||||
import { TableContext } from "context/table";
|
||||
import { NotificationContext } from "context/notification";
|
||||
import { performanceIndicator } from "utilities/helpers";
|
||||
|
|
@ -20,8 +21,10 @@ import {
|
|||
IQueryKeyQueriesLoadAll,
|
||||
ISchedulableQuery,
|
||||
} from "interfaces/schedulable_query";
|
||||
import { DEFAULT_TARGETS_BY_TYPE } from "interfaces/target";
|
||||
import queriesAPI from "services/entities/queries";
|
||||
import PATHS from "router/paths";
|
||||
import { DEFAULT_QUERY } from "utilities/constants";
|
||||
import { checkPlatformCompatibility } from "utilities/sql_tools";
|
||||
import Button from "components/buttons/Button";
|
||||
import Spinner from "components/Spinner";
|
||||
|
|
@ -87,6 +90,9 @@ const ManageQueriesPage = ({
|
|||
isSandboxMode,
|
||||
config,
|
||||
} = useContext(AppContext);
|
||||
const { setLastEditedQueryBody, setSelectedQueryTargetsByType } = useContext(
|
||||
QueryContext
|
||||
);
|
||||
|
||||
const { setResetSelectedRows } = useContext(TableContext);
|
||||
const { renderFlash } = useContext(NotificationContext);
|
||||
|
|
@ -178,7 +184,15 @@ const ManageQueriesPage = ({
|
|||
}
|
||||
}, [location, filteredQueriesPath, setFilteredQueriesPath]);
|
||||
|
||||
const onCreateQueryClick = () => router.push(PATHS.NEW_QUERY(currentTeamId));
|
||||
// Reset selected targets when returned to this page
|
||||
useEffect(() => {
|
||||
setSelectedQueryTargetsByType(DEFAULT_TARGETS_BY_TYPE);
|
||||
}, []);
|
||||
|
||||
const onCreateQueryClick = () => {
|
||||
setLastEditedQueryBody(DEFAULT_QUERY.query);
|
||||
router.push(PATHS.NEW_QUERY(currentTeamId));
|
||||
};
|
||||
|
||||
const toggleDeleteQueryModal = useCallback(() => {
|
||||
setShowDeleteQueryModal(!showDeleteQueryModal);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ const EditQueryPage = ({
|
|||
lastEditedQueryPlatforms,
|
||||
lastEditedQueryLoggingType,
|
||||
lastEditedQueryMinOsqueryVersion,
|
||||
selectedQueryTargets,
|
||||
setLastEditedQueryId,
|
||||
setLastEditedQueryName,
|
||||
setLastEditedQueryDescription,
|
||||
|
|
@ -89,14 +88,10 @@ const EditQueryPage = ({
|
|||
setLastEditedQueryLoggingType,
|
||||
setLastEditedQueryMinOsqueryVersion,
|
||||
setLastEditedQueryPlatforms,
|
||||
// setSelectedQueryTargets,
|
||||
} = useContext(QueryContext);
|
||||
const { currentUser, setConfig } = useContext(AppContext);
|
||||
const { renderFlash } = useContext(NotificationContext);
|
||||
|
||||
// const [queryParamHostsAdded, setQueryParamHostsAdded] = useState(false);
|
||||
// const [targetedHosts, setTargetedHosts] = useState<IHost[]>([]);
|
||||
|
||||
const [isLiveQueryRunnable, setIsLiveQueryRunnable] = useState(true);
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
|
||||
const [showOpenSchemaActionText, setShowOpenSchemaActionText] = useState(
|
||||
|
|
@ -155,7 +150,7 @@ const EditQueryPage = ({
|
|||
setLastEditedQueryId(DEFAULT_QUERY.id);
|
||||
setLastEditedQueryName(DEFAULT_QUERY.name);
|
||||
setLastEditedQueryDescription(DEFAULT_QUERY.description);
|
||||
setLastEditedQueryBody(DEFAULT_QUERY.query);
|
||||
// Persist lastEditedQueryBody through live query flow instead of resetting to DEFAULT_QUERY.query
|
||||
setLastEditedQueryObserverCanRun(DEFAULT_QUERY.observer_can_run);
|
||||
setLastEditedQueryFrequency(DEFAULT_QUERY.interval);
|
||||
setLastEditedQueryLoggingType(DEFAULT_QUERY.logging);
|
||||
|
|
@ -301,7 +296,10 @@ const EditQueryPage = ({
|
|||
<div className={`${baseClass}_wrapper`}>
|
||||
<div className={`${baseClass}__form`}>
|
||||
<div className={`${baseClass}__header-links`}>
|
||||
<BackLink text="Back to report" path={backToQueriesPath()} />
|
||||
<BackLink
|
||||
text={queryId ? "Back to report" : "Back to queries"}
|
||||
path={backToQueriesPath()}
|
||||
/>
|
||||
</div>
|
||||
<QueryForm
|
||||
router={router}
|
||||
|
|
|
|||
|
|
@ -594,11 +594,10 @@ const QueryForm = ({
|
|||
className={`${baseClass}__run`}
|
||||
variant="blue-green"
|
||||
onClick={() => {
|
||||
queryIdForEdit &&
|
||||
router.push(
|
||||
PATHS.LIVE_QUERY(queryIdForEdit) +
|
||||
TAGGED_TEMPLATES.queryByHostRoute(hostId)
|
||||
);
|
||||
router.push(
|
||||
PATHS.LIVE_QUERY(queryIdForEdit) +
|
||||
TAGGED_TEMPLATES.queryByHostRoute(hostId)
|
||||
);
|
||||
}}
|
||||
>
|
||||
Live query
|
||||
|
|
@ -800,11 +799,10 @@ const QueryForm = ({
|
|||
className={`${baseClass}__run`}
|
||||
variant="blue-green"
|
||||
onClick={() => {
|
||||
queryIdForEdit &&
|
||||
router.push(
|
||||
PATHS.LIVE_QUERY(queryIdForEdit) +
|
||||
TAGGED_TEMPLATES.queryByHostRoute(hostId)
|
||||
);
|
||||
router.push(
|
||||
PATHS.LIVE_QUERY(queryIdForEdit) +
|
||||
TAGGED_TEMPLATES.queryByHostRoute(hostId)
|
||||
);
|
||||
}}
|
||||
>
|
||||
Live query
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ const RunQueryPage = ({
|
|||
const {
|
||||
selectedQueryTargets,
|
||||
setSelectedQueryTargets,
|
||||
selectedQueryTargetsByType,
|
||||
setSelectedQueryTargetsByType,
|
||||
setLastEditedQueryId,
|
||||
setLastEditedQueryName,
|
||||
setLastEditedQueryDescription,
|
||||
|
|
@ -76,18 +78,18 @@ const RunQueryPage = ({
|
|||
|
||||
const [queryParamHostsAdded, setQueryParamHostsAdded] = useState(false);
|
||||
const [step, setStep] = useState(LIVE_QUERY_STEPS[1]);
|
||||
const [targetedHosts, setTargetedHosts] = useState<IHost[]>([]);
|
||||
const [targetedLabels, setTargetedLabels] = useState<ILabel[]>([]);
|
||||
const [targetedTeams, setTargetedTeams] = useState<ITeam[]>([]);
|
||||
const [targetedHosts, setTargetedHosts] = useState<IHost[]>(
|
||||
selectedQueryTargetsByType.hosts
|
||||
);
|
||||
const [targetedLabels, setTargetedLabels] = useState<ILabel[]>(
|
||||
selectedQueryTargetsByType.labels
|
||||
);
|
||||
const [targetedTeams, setTargetedTeams] = useState<ITeam[]>(
|
||||
selectedQueryTargetsByType.teams
|
||||
);
|
||||
const [targetsTotalCount, setTargetsTotalCount] = useState(0);
|
||||
const [isLiveQueryRunnable, setIsLiveQueryRunnable] = useState(true);
|
||||
|
||||
const TAGGED_TEMPLATES = {
|
||||
queryByHostRoute: (hostId: number | undefined | null) => {
|
||||
return `${hostId ? `?host_ids=${hostId}` : ""}`;
|
||||
},
|
||||
};
|
||||
|
||||
// disabled on page load so we can control the number of renders
|
||||
// else it will re-populate the context on occasion
|
||||
const { data: storedQuery } = useQuery<
|
||||
|
|
@ -143,19 +145,21 @@ const RunQueryPage = ({
|
|||
|
||||
useEffect(() => {
|
||||
detectIsFleetQueryRunnable();
|
||||
if (!queryId) {
|
||||
setLastEditedQueryId(DEFAULT_QUERY.id);
|
||||
setLastEditedQueryName(DEFAULT_QUERY.name);
|
||||
setLastEditedQueryDescription(DEFAULT_QUERY.description);
|
||||
setLastEditedQueryBody(DEFAULT_QUERY.query);
|
||||
setLastEditedQueryObserverCanRun(DEFAULT_QUERY.observer_can_run);
|
||||
setLastEditedQueryFrequency(DEFAULT_QUERY.interval);
|
||||
setLastEditedQueryLoggingType(DEFAULT_QUERY.logging);
|
||||
setLastEditedQueryMinOsqueryVersion(DEFAULT_QUERY.min_osquery_version);
|
||||
setLastEditedQueryPlatforms(DEFAULT_QUERY.platform);
|
||||
}
|
||||
}, [queryId]);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedQueryTargetsByType({
|
||||
hosts: targetedHosts,
|
||||
labels: targetedLabels,
|
||||
teams: targetedTeams,
|
||||
});
|
||||
}, [targetedLabels, targetedHosts, targetedTeams]);
|
||||
|
||||
console.log(
|
||||
"LiveQueryPage.tsx: selectedQueryTargetsByType",
|
||||
selectedQueryTargetsByType
|
||||
);
|
||||
|
||||
// Updates title that shows up on browser tabs
|
||||
useEffect(() => {
|
||||
// e.g., Run live query | Discover TLS certificates | Fleet for osquery
|
||||
|
|
@ -163,10 +167,12 @@ const RunQueryPage = ({
|
|||
}, [location.pathname, storedQuery?.name]);
|
||||
|
||||
const goToQueryEditor = useCallback(
|
||||
() => queryId && router.push(PATHS.EDIT_QUERY(queryId)),
|
||||
() =>
|
||||
queryId
|
||||
? router.push(PATHS.EDIT_QUERY(queryId))
|
||||
: router.push(PATHS.NEW_QUERY()),
|
||||
[]
|
||||
);
|
||||
// const params = { id: paramsQueryId };
|
||||
|
||||
const renderScreen = () => {
|
||||
const step1Props = {
|
||||
|
|
|
|||
|
|
@ -222,12 +222,15 @@ const routes = (
|
|||
<IndexRedirect to="manage" />
|
||||
<Route path="manage" component={ManageQueriesPage} />
|
||||
<Route component={AuthAnyMaintainerAdminObserverPlusRoutes}>
|
||||
<Route path="new" component={EditQueryPage} />
|
||||
<Route path="new">
|
||||
<IndexRoute component={EditQueryPage} />
|
||||
<Route path="live" component={LiveQueryPage} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path=":id">
|
||||
<IndexRoute component={QueryDetailsPage} />
|
||||
<Route path="edit" component={EditQueryPage} />
|
||||
<Route path="run" component={LiveQueryPage} />
|
||||
<Route path="live" component={LiveQueryPage} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="policies">
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ export default {
|
|||
teamId ? `?team_id=${teamId}` : ""
|
||||
}`;
|
||||
},
|
||||
LIVE_QUERY: (queryId: number, teamId?: number): string => {
|
||||
return `${URL_PREFIX}/queries/${queryId}/live${
|
||||
LIVE_QUERY: (queryId: number | null, teamId?: number): string => {
|
||||
return `${URL_PREFIX}/queries/${queryId || "new"}/live${
|
||||
teamId ? `?team_id=${teamId}` : ""
|
||||
}`;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import sendRequest, { getError } from "services";
|
||||
import endpoints from "utilities/endpoints";
|
||||
import { ISelectedTargets } from "interfaces/target";
|
||||
import { ISelectedTargetsForApi } from "interfaces/target";
|
||||
import { AxiosResponse } from "axios";
|
||||
import {
|
||||
ICreateQueryRequestBody,
|
||||
|
|
@ -52,7 +52,7 @@ export default {
|
|||
}: {
|
||||
query: string;
|
||||
queryId: number | null;
|
||||
selected: ISelectedTargets;
|
||||
selected: ISelectedTargetsForApi;
|
||||
}) => {
|
||||
const { LIVE_QUERY } = endpoints;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import sendRequest from "services";
|
||||
import { IHost } from "interfaces/host";
|
||||
import { ISelectedTargets, ITargetsAPIResponse } from "interfaces/target";
|
||||
import { ISelectedTargetsForApi, ITargetsAPIResponse } from "interfaces/target";
|
||||
import endpoints from "utilities/endpoints";
|
||||
import appendTargetTypeToTargets from "utilities/append_target_type_to_targets";
|
||||
|
||||
interface ITargetsProps {
|
||||
query?: string;
|
||||
queryId?: number | null;
|
||||
selected: ISelectedTargets;
|
||||
selected: ISelectedTargetsForApi;
|
||||
}
|
||||
|
||||
const defaultSelected = {
|
||||
|
|
@ -29,7 +29,7 @@ export interface ITargetsSearchResponse {
|
|||
|
||||
export interface ITargetsCountParams {
|
||||
query_id?: number | null;
|
||||
selected: ISelectedTargets | null;
|
||||
selected: ISelectedTargetsForApi | null;
|
||||
}
|
||||
|
||||
export interface ITargetsCountResponse {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
} from "interfaces/scheduled_query";
|
||||
import {
|
||||
ISelectTargetsEntity,
|
||||
ISelectedTargets,
|
||||
ISelectedTargetsForApi,
|
||||
IPackTargets,
|
||||
} from "interfaces/target";
|
||||
import { ITeam, ITeamSummary } from "interfaces/team";
|
||||
|
|
@ -258,7 +258,7 @@ const formatLabelResponse = (response: any): ILabel[] => {
|
|||
|
||||
export const formatSelectedTargetsForApi = (
|
||||
selectedTargets: ISelectTargetsEntity[]
|
||||
): ISelectedTargets => {
|
||||
): ISelectedTargetsForApi => {
|
||||
const targets = selectedTargets || [];
|
||||
// TODO: can flatMap be removed?
|
||||
const hostIds = flatMap(targets, filterTarget("hosts"));
|
||||
|
|
|
|||
Loading…
Reference in a new issue