[Discover] Include current filters into "Test query" request (#134184)

* [Discover] Include current filters into "Test query" request

* [Discover] Reset query results when criteria is changed

* [Discover] Add a comment

* [Discover] Reset "Test query" when any rule configuration changes
This commit is contained in:
Julia Rechkunova 2022-06-14 12:39:44 +02:00 committed by GitHub
parent a8d3e1140b
commit 7b17093c14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 41 deletions

View file

@ -72,26 +72,33 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp
useEffect(() => setSavedQuery(initialSavedQuery), [initialSavedQuery]);
const [{ index: dataView, query, filter: filters, threshold, timeWindowSize, size }, dispatch] =
useReducer<LocalStateReducer>(
(currentState, action) => {
if (isSearchSourceParam(action)) {
searchSource.setParent(undefined).setField(action.type, action.payload);
setParam('searchConfiguration', searchSource.getSerializedFields());
} else {
setParam(action.type, action.payload);
}
return { ...currentState, [action.type]: action.payload };
},
{
index: searchSource.getField('index')!,
query: searchSource.getField('query')!,
filter: mapAndFlattenFilters(searchSource.getField('filter') as Filter[]),
threshold: ruleParams.threshold,
timeWindowSize: ruleParams.timeWindowSize,
size: ruleParams.size,
const [ruleConfiguration, dispatch] = useReducer<LocalStateReducer>(
(currentState, action) => {
if (isSearchSourceParam(action)) {
searchSource.setParent(undefined).setField(action.type, action.payload);
setParam('searchConfiguration', searchSource.getSerializedFields());
} else {
setParam(action.type, action.payload);
}
);
return { ...currentState, [action.type]: action.payload };
},
{
index: searchSource.getField('index')!,
query: searchSource.getField('query')!,
filter: mapAndFlattenFilters(searchSource.getField('filter') as Filter[]),
threshold: ruleParams.threshold,
timeWindowSize: ruleParams.timeWindowSize,
size: ruleParams.size,
}
);
const {
index: dataView,
query,
filter: filters,
threshold,
timeWindowSize,
size,
} = ruleConfiguration;
const dataViews = useMemo(() => [dataView], [dataView]);
const onSelectDataView = useCallback(
@ -172,10 +179,13 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp
from: `now-${timeWindow}`,
to: 'now',
});
testSearchSource.setField('filter', timeFilter);
testSearchSource.setField(
'filter',
timeFilter ? [timeFilter, ...ruleConfiguration.filter] : ruleConfiguration.filter
);
const { rawResponse } = await firstValueFrom(testSearchSource.fetch$());
return { nrOfDocs: totalHitsToNumber(rawResponse.hits.total), timeWindow };
}, [searchSource, timeWindowSize, timeWindowUnit]);
}, [searchSource, timeWindowSize, timeWindowUnit, ruleConfiguration]);
return (
<Fragment>

View file

@ -5,50 +5,73 @@
* 2.0.
*/
import { useState, useCallback } from 'react';
import { useState, useCallback, useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
interface TestQueryResponse {
result: string | null;
error: string | null;
isLoading: boolean;
}
const TEST_QUERY_INITIAL_RESPONSE: TestQueryResponse = {
result: null,
error: null,
isLoading: false,
};
/**
* Hook used to test the data fetching execution by returning a number of found documents
* Or in error in case it's failing
*/
export function useTestQuery(fetch: () => Promise<{ nrOfDocs: number; timeWindow: string }>) {
const [testQueryResult, setTestQueryResult] = useState<string | null>(null);
const [testQueryError, setTestQueryError] = useState<string | null>(null);
const [testQueryLoading, setTestQueryLoading] = useState<boolean>(false);
const [testQueryResponse, setTestQueryResponse] = useState<TestQueryResponse>(
TEST_QUERY_INITIAL_RESPONSE
);
// Reset query response when criteria got changed
useEffect(() => {
setTestQueryResponse(TEST_QUERY_INITIAL_RESPONSE);
}, [fetch]);
const onTestQuery = useCallback(async () => {
setTestQueryLoading(true);
setTestQueryError(null);
setTestQueryResult(null);
setTestQueryResponse({
result: null,
error: null,
isLoading: true,
});
try {
const { nrOfDocs, timeWindow } = await fetch();
setTestQueryResult(
i18n.translate('xpack.stackAlerts.esQuery.ui.numQueryMatchesText', {
setTestQueryResponse({
result: i18n.translate('xpack.stackAlerts.esQuery.ui.numQueryMatchesText', {
defaultMessage: 'Query matched {count} documents in the last {window}.',
values: { count: nrOfDocs, window: timeWindow },
})
);
}),
error: null,
isLoading: false,
});
} catch (err) {
const message = err?.body?.attributes?.error?.root_cause[0]?.reason || err?.body?.message;
setTestQueryError(
i18n.translate('xpack.stackAlerts.esQuery.ui.queryError', {
setTestQueryResponse({
result: null,
error: i18n.translate('xpack.stackAlerts.esQuery.ui.queryError', {
defaultMessage: 'Error testing query: {message}',
values: { message: message ? `${err.message}: ${message}` : err.message },
})
);
} finally {
setTestQueryLoading(false);
}),
isLoading: false,
});
}
}, [fetch]);
return {
onTestQuery,
testQueryResult,
testQueryError,
testQueryLoading,
testQueryResult: testQueryResponse.result,
testQueryError: testQueryResponse.error,
testQueryLoading: testQueryResponse.isLoading,
};
}