mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[8.11] [Security Solution] [Elastic AI Assistant] Fix Send to Timeline ESQL action changing the ESQL bar to KQL bar (#170542) (#171471)
# Backport This will backport the following commits from `main` to `8.11`: - [[Security Solution] [Elastic AI Assistant] Fix Send to Timeline ESQL action changing the ESQL bar to KQL bar (#170542)](https://github.com/elastic/kibana/pull/170542) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Garrett Spong","email":"spong@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-11-17T01:13:14Z","message":"[Security Solution] [Elastic AI Assistant] Fix Send to Timeline ESQL action changing the ESQL bar to KQL bar (#170542)\n\n## Summary\r\n\r\nIn https://github.com/elastic/kibana/pull/169478, the `Send to Timeline`\r\naction was fixed for `ES|QL` codeblocks, however while the `ES|QL`\r\ntimeline tab was being selected, and the query string was being set\r\ncorrectly, the ESQL bar would be swapped out for the KQL bar. In the\r\ngifs below, note the right two action buttons present in the query bar.\r\n\r\nThere is one remaining bug where refreshing the page clears the ESQL\r\nquery and set the default query. @logeekal is currently investigating a\r\nfix for this issue and will push to this branch once available.\r\n\r\n#### Before\r\n<p align=\"center\">\r\n<img width=\"500\"\r\nsrc=\"fdc3b2a0
-5b4b-4584-b304-c4d24de1917c\"\r\n/>\r\n</p> \r\n\r\n#### After\r\n<p align=\"center\">\r\n<img width=\"500\"\r\nsrc=\"d217b95c
-2d1c-4474-ac98-180e07a86669\"\r\n/>\r\n</p> \r\n\r\n\r\n## Test instructions\r\n\r\nEither request the assistant to generate an ESQL query or just paste\r\nthis codeblock into the conversation to test the action directly from\r\nthe user message. Be sure to declare the codeblock language as `esql` or\r\ninclude one of the [string match\r\npatterns](https://github.com/elastic/kibana/pull/169478/files#diff-f70f0b96568e024e53bfbb62adcca72051f0a2e824d4ab22664eed0e149be248R38)\r\nabove the code block so the action can be recognized.\r\n\r\n\r\n````\r\nBelow is an `Elasticsearch Query Language` query:\r\n\r\n```esql\r\nFROM logs-endpoint*\r\n| WHERE event.category == \\\"process\\\"\r\n| STATS proc_count = COUNT(process.name) BY host.name\r\n| KEEP host.name, proc_count\r\n```\r\n````\r\n\r\n\r\nThen verify that the query bar is still the ESQL query bar which has the\r\n`Expand` and `ESQL Reference` buttons to the far right.\r\n\r\n---------\r\n\r\nCo-authored-by: Jatin Kathuria <jatin.kathuria@elastic.co>","sha":"52fdd7f46fc6dd56d062a1ba55dd5caeae47c8f9","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","Team: SecuritySolution","backport:prev-minor","Feature:Elastic AI Assistant","v8.12.0","v8.11.2"],"number":170542,"url":"https://github.com/elastic/kibana/pull/170542","mergeCommit":{"message":"[Security Solution] [Elastic AI Assistant] Fix Send to Timeline ESQL action changing the ESQL bar to KQL bar (#170542)\n\n## Summary\r\n\r\nIn https://github.com/elastic/kibana/pull/169478, the `Send to Timeline`\r\naction was fixed for `ES|QL` codeblocks, however while the `ES|QL`\r\ntimeline tab was being selected, and the query string was being set\r\ncorrectly, the ESQL bar would be swapped out for the KQL bar. In the\r\ngifs below, note the right two action buttons present in the query bar.\r\n\r\nThere is one remaining bug where refreshing the page clears the ESQL\r\nquery and set the default query. @logeekal is currently investigating a\r\nfix for this issue and will push to this branch once available.\r\n\r\n#### Before\r\n<p align=\"center\">\r\n<img width=\"500\"\r\nsrc=\"fdc3b2a0
-5b4b-4584-b304-c4d24de1917c\"\r\n/>\r\n</p> \r\n\r\n#### After\r\n<p align=\"center\">\r\n<img width=\"500\"\r\nsrc=\"d217b95c
-2d1c-4474-ac98-180e07a86669\"\r\n/>\r\n</p> \r\n\r\n\r\n## Test instructions\r\n\r\nEither request the assistant to generate an ESQL query or just paste\r\nthis codeblock into the conversation to test the action directly from\r\nthe user message. Be sure to declare the codeblock language as `esql` or\r\ninclude one of the [string match\r\npatterns](https://github.com/elastic/kibana/pull/169478/files#diff-f70f0b96568e024e53bfbb62adcca72051f0a2e824d4ab22664eed0e149be248R38)\r\nabove the code block so the action can be recognized.\r\n\r\n\r\n````\r\nBelow is an `Elasticsearch Query Language` query:\r\n\r\n```esql\r\nFROM logs-endpoint*\r\n| WHERE event.category == \\\"process\\\"\r\n| STATS proc_count = COUNT(process.name) BY host.name\r\n| KEEP host.name, proc_count\r\n```\r\n````\r\n\r\n\r\nThen verify that the query bar is still the ESQL query bar which has the\r\n`Expand` and `ESQL Reference` buttons to the far right.\r\n\r\n---------\r\n\r\nCo-authored-by: Jatin Kathuria <jatin.kathuria@elastic.co>","sha":"52fdd7f46fc6dd56d062a1ba55dd5caeae47c8f9"}},"sourceBranch":"main","suggestedTargetBranches":["8.11"],"targetPullRequestStates":[{"branch":"main","label":"v8.12.0","labelRegex":"^v8.12.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/170542","number":170542,"mergeCommit":{"message":"[Security Solution] [Elastic AI Assistant] Fix Send to Timeline ESQL action changing the ESQL bar to KQL bar (#170542)\n\n## Summary\r\n\r\nIn https://github.com/elastic/kibana/pull/169478, the `Send to Timeline`\r\naction was fixed for `ES|QL` codeblocks, however while the `ES|QL`\r\ntimeline tab was being selected, and the query string was being set\r\ncorrectly, the ESQL bar would be swapped out for the KQL bar. In the\r\ngifs below, note the right two action buttons present in the query bar.\r\n\r\nThere is one remaining bug where refreshing the page clears the ESQL\r\nquery and set the default query. @logeekal is currently investigating a\r\nfix for this issue and will push to this branch once available.\r\n\r\n#### Before\r\n<p align=\"center\">\r\n<img width=\"500\"\r\nsrc=\"fdc3b2a0
-5b4b-4584-b304-c4d24de1917c\"\r\n/>\r\n</p> \r\n\r\n#### After\r\n<p align=\"center\">\r\n<img width=\"500\"\r\nsrc=\"d217b95c
-2d1c-4474-ac98-180e07a86669\"\r\n/>\r\n</p> \r\n\r\n\r\n## Test instructions\r\n\r\nEither request the assistant to generate an ESQL query or just paste\r\nthis codeblock into the conversation to test the action directly from\r\nthe user message. Be sure to declare the codeblock language as `esql` or\r\ninclude one of the [string match\r\npatterns](https://github.com/elastic/kibana/pull/169478/files#diff-f70f0b96568e024e53bfbb62adcca72051f0a2e824d4ab22664eed0e149be248R38)\r\nabove the code block so the action can be recognized.\r\n\r\n\r\n````\r\nBelow is an `Elasticsearch Query Language` query:\r\n\r\n```esql\r\nFROM logs-endpoint*\r\n| WHERE event.category == \\\"process\\\"\r\n| STATS proc_count = COUNT(process.name) BY host.name\r\n| KEEP host.name, proc_count\r\n```\r\n````\r\n\r\n\r\nThen verify that the query bar is still the ESQL query bar which has the\r\n`Expand` and `ESQL Reference` buttons to the far right.\r\n\r\n---------\r\n\r\nCo-authored-by: Jatin Kathuria <jatin.kathuria@elastic.co>","sha":"52fdd7f46fc6dd56d062a1ba55dd5caeae47c8f9"}},{"branch":"8.11","label":"v8.11.2","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Garrett Spong <spong@users.noreply.github.com> Co-authored-by: Jatin Kathuria <jatin.kathuria@elastic.co>
This commit is contained in:
parent
a094ddd412
commit
f982ca8292
5 changed files with 59 additions and 17 deletions
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiIcon, EuiToolTip } from '@elastic/eui';
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import { analyzeMarkdown } from '@kbn/elastic-assistant';
|
||||
import type { Conversation, CodeBlockDetails } from '@kbn/elastic-assistant';
|
||||
import React from 'react';
|
||||
|
@ -13,7 +13,6 @@ import React from 'react';
|
|||
import type { TimelineEventsDetailsItem } from '../../common/search_strategy';
|
||||
import type { Rule } from '../detection_engine/rule_management/logic';
|
||||
import { SendToTimelineButton } from './send_to_timeline';
|
||||
import { INVESTIGATE_IN_TIMELINE } from '../actions/add_to_timeline/constants';
|
||||
|
||||
export const LOCAL_STORAGE_KEY = `securityAssistant`;
|
||||
|
||||
|
@ -125,9 +124,7 @@ export const augmentMessageCodeBlocks = (
|
|||
]}
|
||||
keepDataView={true}
|
||||
>
|
||||
<EuiToolTip position="right" content={INVESTIGATE_IN_TIMELINE}>
|
||||
<EuiIcon type="timeline" />
|
||||
</EuiToolTip>
|
||||
<EuiIcon type="timeline" />
|
||||
</SendToTimelineButton>
|
||||
) : null,
|
||||
};
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { EuiButton, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { EuiButton, EuiButtonEmpty, EuiToolTip } from '@elastic/eui';
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { useAssistantContext } from '@kbn/elastic-assistant';
|
||||
import { useDeepEqualSelector } from '../../common/hooks/use_selector';
|
||||
import { sourcererSelectors } from '../../common/store';
|
||||
import { sourcererActions } from '../../common/store/actions';
|
||||
|
@ -19,7 +20,10 @@ import type { TimeRange } from '../../common/store/inputs/model';
|
|||
import { SourcererScopeName } from '../../common/store/sourcerer/model';
|
||||
import { TimelineTabs, TimelineId } from '../../../common/types/timeline';
|
||||
import { TimelineType } from '../../../common/api/timeline';
|
||||
import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../detections/components/alerts_table/translations';
|
||||
import {
|
||||
ACTION_CANNOT_INVESTIGATE_IN_TIMELINE,
|
||||
ACTION_INVESTIGATE_IN_TIMELINE,
|
||||
} from '../../detections/components/alerts_table/translations';
|
||||
import type { DataProvider } from '../../timelines/components/timeline/data_providers/data_provider';
|
||||
import { useCreateTimeline } from '../../timelines/components/timeline/properties/use_create_timeline';
|
||||
import {
|
||||
|
@ -31,6 +35,7 @@ import {
|
|||
updateEqlOptions,
|
||||
} from '../../timelines/store/timeline/actions';
|
||||
import { useDiscoverInTimelineContext } from '../../common/components/discover_in_timeline/use_discover_in_timeline_context';
|
||||
import { useShowTimeline } from '../../common/utils/timeline/use_show_timeline';
|
||||
|
||||
export interface SendToTimelineButtonProps {
|
||||
asEmptyButton: boolean;
|
||||
|
@ -51,7 +56,8 @@ export const SendToTimelineButton: React.FunctionComponent<SendToTimelineButtonP
|
|||
...rest
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { showAssistantOverlay } = useAssistantContext();
|
||||
const [isTimelineBottomBarVisible] = useShowTimeline();
|
||||
const { discoverStateContainer } = useDiscoverInTimelineContext();
|
||||
|
||||
const getDataViewsSelector = useMemo(
|
||||
|
@ -71,13 +77,15 @@ export const SendToTimelineButton: React.FunctionComponent<SendToTimelineButtonP
|
|||
});
|
||||
|
||||
const configureAndOpenTimeline = useCallback(() => {
|
||||
// Hide the assistant overlay so timeline can be seen (noop if using assistant in timeline)
|
||||
showAssistantOverlay({ showOverlay: false });
|
||||
|
||||
if (dataProviders || filters) {
|
||||
// If esql, don't reset filters or mess with dataview & time range
|
||||
if (dataProviders?.[0]?.queryType === 'esql' || dataProviders?.[0]?.queryType === 'sql') {
|
||||
discoverStateContainer.current?.appState.update({
|
||||
query: {
|
||||
query: dataProviders[0].kqlQuery,
|
||||
language: 'esql',
|
||||
esql: dataProviders[0].kqlQuery,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -200,6 +208,7 @@ export const SendToTimelineButton: React.FunctionComponent<SendToTimelineButtonP
|
|||
dispatch(inputsActions.removeLinkTo([InputsModelId.timeline, InputsModelId.global]));
|
||||
}
|
||||
}, [
|
||||
showAssistantOverlay,
|
||||
dataProviders,
|
||||
filters,
|
||||
timeRange,
|
||||
|
@ -211,23 +220,35 @@ export const SendToTimelineButton: React.FunctionComponent<SendToTimelineButtonP
|
|||
signalIndexName,
|
||||
]);
|
||||
|
||||
// As we work around timeline visibility issues, we will disable the button if timeline isn't available
|
||||
const toolTipText = isTimelineBottomBarVisible
|
||||
? ACTION_INVESTIGATE_IN_TIMELINE
|
||||
: ACTION_CANNOT_INVESTIGATE_IN_TIMELINE;
|
||||
const isDisabled = !isTimelineBottomBarVisible;
|
||||
|
||||
return asEmptyButton ? (
|
||||
<EuiButtonEmpty
|
||||
aria-label={ACTION_INVESTIGATE_IN_TIMELINE}
|
||||
aria-label={toolTipText}
|
||||
onClick={configureAndOpenTimeline}
|
||||
isDisabled={isDisabled}
|
||||
color="text"
|
||||
flush="both"
|
||||
size="xs"
|
||||
>
|
||||
{children}
|
||||
<EuiToolTip position="right" content={toolTipText}>
|
||||
<>{children}</>
|
||||
</EuiToolTip>
|
||||
</EuiButtonEmpty>
|
||||
) : (
|
||||
<EuiButton
|
||||
aria-label={ACTION_INVESTIGATE_IN_TIMELINE}
|
||||
aria-label={toolTipText}
|
||||
isDisabled={isDisabled}
|
||||
onClick={configureAndOpenTimeline}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
<EuiToolTip position="right" content={toolTipText}>
|
||||
<>{children}</>
|
||||
</EuiToolTip>
|
||||
</EuiButton>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -134,7 +134,7 @@ export const useDiscoverInTimelineActions = (
|
|||
* */
|
||||
const resetDiscoverAppState = useCallback(async () => {
|
||||
const defaultDiscoverAppState = await getDefaultDiscoverAppState();
|
||||
discoverStateContainer.current?.appState.set(defaultDiscoverAppState);
|
||||
discoverStateContainer.current?.appState.replaceUrlState(defaultDiscoverAppState);
|
||||
discoverStateContainer.current?.globalState.set({
|
||||
...discoverStateContainer.current?.globalState.get(),
|
||||
time: defaultDiscoverTimeRange,
|
||||
|
|
|
@ -137,6 +137,13 @@ export const ACTION_INVESTIGATE_IN_TIMELINE = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
export const ACTION_CANNOT_INVESTIGATE_IN_TIMELINE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.alerts.actions.cannotInvestigateInTimelineTitle',
|
||||
{
|
||||
defaultMessage: 'Please navigate to a page with timeline to investigate',
|
||||
}
|
||||
);
|
||||
|
||||
export const ACTION_INVESTIGATE_IN_TIMELINE_ARIA_LABEL = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineAriaLabel',
|
||||
{
|
||||
|
|
|
@ -238,8 +238,25 @@ export const DiscoverTabContent: FC<DiscoverTabContentProps> = ({ timelineId })
|
|||
const finalAppState =
|
||||
savedSearchAppState?.appState ?? discoverAppState ?? defaultDiscoverAppState;
|
||||
|
||||
stateContainer.appState.set(finalAppState);
|
||||
await stateContainer.appState.replaceUrlState(finalAppState);
|
||||
const urlAppState = stateContainer.appState.isEmptyURL()
|
||||
? undefined
|
||||
: stateContainer.appState.getState();
|
||||
|
||||
const hasESQLURlState = urlAppState?.query && 'esql' in urlAppState.query;
|
||||
|
||||
/*
|
||||
* Url state should NOT apply if there is already a saved search being loaded
|
||||
* */
|
||||
const shouldApplyESQLUrlState = !savedSearchAppState?.appState && hasESQLURlState;
|
||||
|
||||
if (!shouldApplyESQLUrlState) {
|
||||
/*
|
||||
* If url state applies, it should be a no-op and there is no need to update the state container.
|
||||
* Discover should automatically pick up url state
|
||||
* */
|
||||
stateContainer.appState.set(finalAppState);
|
||||
await stateContainer.appState.replaceUrlState(finalAppState);
|
||||
}
|
||||
|
||||
const unsubscribeState = stateContainer.appState.state$.subscribe({
|
||||
next: setDiscoverAppState,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue