import React, { useState, useEffect, useCallback } from "react"; import { pull, size } from "lodash"; import useDeepEffect from "hooks/useDeepEffect"; import Checkbox from "components/forms/fields/Checkbox"; // @ts-ignore import InputField from "components/forms/fields/InputField"; // @ts-ignore import Dropdown from "components/forms/fields/Dropdown"; import Button from "components/buttons/Button"; import Modal from "components/Modal"; import { FREQUENCY_DROPDOWN_OPTIONS, LOGGING_TYPE_OPTIONS, MIN_OSQUERY_VERSION_OPTIONS, SCHEDULE_PLATFORM_DROPDOWN_OPTIONS, } from "utilities/constants"; import RevealButton from "components/buttons/RevealButton"; import { SelectedPlatformString } from "interfaces/platform"; import { ICreateQueryRequestBody, ISchedulableQuery, QueryLoggingOption, } from "interfaces/schedulable_query"; const baseClass = "save-query-modal"; export interface ISaveQueryModalProps { queryValue: string; apiTeamIdForQuery?: number; // query will be global if omitted isLoading: boolean; saveQuery: (formData: ICreateQueryRequestBody) => void; toggleSaveQueryModal: () => void; backendValidators: { [key: string]: string }; existingQuery?: ISchedulableQuery; } const validateQueryName = (name: string) => { const errors: { [key: string]: string } = {}; if (!name) { errors.name = "Query name must be present"; } const valid = !size(errors); return { valid, errors }; }; const SaveQueryModal = ({ queryValue, apiTeamIdForQuery, isLoading, saveQuery, toggleSaveQueryModal, backendValidators, existingQuery, }: ISaveQueryModalProps): JSX.Element => { const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [selectedFrequency, setSelectedFrequency] = useState( existingQuery?.interval ?? 3600 ); const [ selectedPlatformOptions, setSelectedPlatformOptions, ] = useState(existingQuery?.platform ?? ""); const [ selectedMinOsqueryVersionOptions, setSelectedMinOsqueryVersionOptions, ] = useState(existingQuery?.min_osquery_version ?? ""); const [ selectedLoggingType, setSelectedLoggingType, ] = useState(existingQuery?.logging ?? "snapshot"); const [observerCanRun, setObserverCanRun] = useState(false); const [errors, setErrors] = useState<{ [key: string]: string }>( backendValidators ); const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); const toggleAdvancedOptions = () => { setShowAdvancedOptions(!showAdvancedOptions); }; useDeepEffect(() => { if (name) { setErrors({}); } }, [name]); useEffect(() => { setErrors(backendValidators); }, [backendValidators]); const onClickSaveQuery = (evt: React.MouseEvent) => { evt.preventDefault(); const { valid, errors: newErrors } = validateQueryName(name); setErrors({ ...errors, ...newErrors, }); if (valid) { saveQuery({ // from modal fields name, description, interval: selectedFrequency, observer_can_run: observerCanRun, platform: selectedPlatformOptions, min_osquery_version: selectedMinOsqueryVersionOptions, logging: selectedLoggingType, // from previous New query page query: queryValue, // from doubly previous ManageQueriesPage team_id: apiTeamIdForQuery, }); } }; const onChangeSelectPlatformOptions = useCallback( (values: string) => { const valArray = values.split(","); // Remove All if another OS is chosen // else if Remove OS if All is chosen if (valArray.indexOf("") === 0 && valArray.length > 1) { // TODO - inmprove type safety of all 3 options setSelectedPlatformOptions( pull(valArray, "").join(",") as SelectedPlatformString ); } else if (valArray.length > 1 && valArray.indexOf("") > -1) { setSelectedPlatformOptions(""); } else { setSelectedPlatformOptions(values as SelectedPlatformString); } }, [setSelectedPlatformOptions] ); return (
setName(value)} value={name} error={errors.name} inputClassName={`${baseClass}__name`} label="Name" placeholder="What is your query called?" autofocus ignore1password /> setDescription(value)} value={description} inputClassName={`${baseClass}__description`} label="Description" type="textarea" placeholder="What information does your query reveal? (optional)" /> { setSelectedFrequency(value); }} placeholder={"Every hour"} value={selectedFrequency} label="Frequency" wrapperClassName={`${baseClass}__form-field ${baseClass}__form-field--frequency`} />

If automations are on, this is how often your query collects data.

Observers can run

Users with the Observer role will be able to run this query as a live query.

{showAdvancedOptions && ( <>

If automations are turned on, your query collects data on compatible platforms.
If you want more control, override platforms.

)}
); }; export default SaveQueryModal;