Skip to content

Commit 1ed98d5

Browse files
[Security Solution] Manage timeline templates user flow (#67837)
1 parent a9f82a3 commit 1ed98d5

File tree

96 files changed

+2418
-869
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+2418
-869
lines changed

x-pack/plugins/security_solution/common/constants.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,6 @@ export const showAllOthersBucket: string[] = [
165165
'user.name',
166166
];
167167

168-
/**
169-
* CreateTemplateTimelineBtn
170-
* https://github.com/elastic/kibana/pull/66613
171-
* Remove the comment here to enable template timeline
172-
*/
173-
export const disableTemplate = false;
174-
175168
/*
176169
* This should be set to true after https://github.com/elastic/kibana/pull/67496 is merged
177170
*/

x-pack/plugins/security_solution/common/types/timeline/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ const SavedDataProviderQueryMatchRuntimeType = runtimeTypes.partial({
5050
queryMatch: unionWithNullType(SavedDataProviderQueryMatchBasicRuntimeType),
5151
});
5252

53+
export enum DataProviderType {
54+
default = 'default',
55+
template = 'template',
56+
}
57+
58+
export const DataProviderTypeLiteralRt = runtimeTypes.union([
59+
runtimeTypes.literal(DataProviderType.default),
60+
runtimeTypes.literal(DataProviderType.template),
61+
]);
62+
5363
const SavedDataProviderRuntimeType = runtimeTypes.partial({
5464
id: unionWithNullType(runtimeTypes.string),
5565
name: unionWithNullType(runtimeTypes.string),
@@ -58,6 +68,7 @@ const SavedDataProviderRuntimeType = runtimeTypes.partial({
5868
kqlQuery: unionWithNullType(runtimeTypes.string),
5969
queryMatch: unionWithNullType(SavedDataProviderQueryMatchBasicRuntimeType),
6070
and: unionWithNullType(runtimeTypes.array(SavedDataProviderQueryMatchRuntimeType)),
71+
type: unionWithNullType(DataProviderTypeLiteralRt),
6172
});
6273

6374
/*
@@ -154,7 +165,7 @@ export type TimelineStatusLiteralWithNull = runtimeTypes.TypeOf<
154165
>;
155166

156167
/**
157-
* Template timeline type
168+
* Timeline template type
158169
*/
159170

160171
export enum TemplateTimelineType {

x-pack/plugins/security_solution/cypress/screens/timeline.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const CLOSE_TIMELINE_BTN = '[data-test-subj="close-timeline"]';
99
export const CREATE_NEW_TIMELINE = '[data-test-subj="timeline-new"]';
1010

1111
export const DRAGGABLE_HEADER =
12-
'[data-test-subj="headers-group"] [data-test-subj="draggable-header"]';
12+
'[data-test-subj="events-viewer-panel"] [data-test-subj="headers-group"] [data-test-subj="draggable-header"]';
1313

1414
export const HEADERS_GROUP = '[data-test-subj="headers-group"]';
1515

@@ -21,7 +21,8 @@ export const ID_TOGGLE_FIELD = '[data-test-subj="toggle-field-_id"]';
2121

2222
export const PROVIDER_BADGE = '[data-test-subj="providerBadge"]';
2323

24-
export const REMOVE_COLUMN = '[data-test-subj="remove-column"]';
24+
export const REMOVE_COLUMN =
25+
'[data-test-subj="events-viewer-panel"] [data-test-subj="remove-column"]';
2526

2627
export const RESET_FIELDS =
2728
'[data-test-subj="events-viewer-panel"] [data-test-subj="reset-fields"]';

x-pack/plugins/security_solution/cypress/tasks/timeline.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import {
2727

2828
import { drag, drop } from '../tasks/common';
2929

30-
export const hostExistsQuery = 'host.name: *';
31-
3230
export const addDescriptionToTimeline = (description: string) => {
3331
cy.get(TIMELINE_DESCRIPTION).type(`${description}{enter}`);
3432
cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE).click().invoke('text').should('not.equal', 'Updating');
@@ -79,7 +77,6 @@ export const openTimelineSettings = () => {
7977
};
8078

8179
export const populateTimeline = () => {
82-
executeTimelineKQL(hostExistsQuery);
8380
cy.get(SERVER_SIDE_EVENT_COUNT)
8481
.invoke('text')
8582
.then((strCount) => {

x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ describe('alert actions', () => {
215215
columnId: '@timestamp',
216216
sortDirection: 'desc',
217217
},
218-
status: TimelineStatus.active,
219-
title: 'Test rule - Duplicate',
218+
status: TimelineStatus.draft,
219+
title: '',
220220
timelineType: TimelineType.default,
221221
templateTimelineId: null,
222222
templateTimelineVersion: null,

x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ import moment from 'moment';
1010

1111
import { updateAlertStatus } from '../../containers/detection_engine/alerts/api';
1212
import { SendAlertToTimelineActionProps, UpdateAlertStatusActionProps } from './types';
13-
import { TimelineNonEcsData, GetOneTimeline, TimelineResult, Ecs } from '../../../graphql/types';
13+
import {
14+
TimelineNonEcsData,
15+
GetOneTimeline,
16+
TimelineResult,
17+
Ecs,
18+
TimelineStatus,
19+
TimelineType,
20+
} from '../../../graphql/types';
1421
import { oneTimelineQuery } from '../../../timelines/containers/one/index.gql_query';
1522
import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
1623
import {
@@ -122,20 +129,31 @@ export const sendAlertToTimelineAction = async ({
122129
if (!isEmpty(resultingTimeline)) {
123130
const timelineTemplate: TimelineResult = omitTypenameInTimeline(resultingTimeline);
124131
openAlertInBasicTimeline = false;
125-
const { timeline } = formatTimelineResultToModel(timelineTemplate, true);
132+
const { timeline } = formatTimelineResultToModel(
133+
timelineTemplate,
134+
true,
135+
timelineTemplate.timelineType ?? TimelineType.default
136+
);
126137
const query = replaceTemplateFieldFromQuery(
127138
timeline.kqlQuery?.filterQuery?.kuery?.expression ?? '',
128-
ecsData
139+
ecsData,
140+
timeline.timelineType
129141
);
130142
const filters = replaceTemplateFieldFromMatchFilters(timeline.filters ?? [], ecsData);
131143
const dataProviders = replaceTemplateFieldFromDataProviders(
132144
timeline.dataProviders ?? [],
133-
ecsData
145+
ecsData,
146+
timeline.timelineType
134147
);
148+
135149
createTimeline({
136150
from,
137151
timeline: {
138152
...timeline,
153+
title: '',
154+
timelineType: TimelineType.default,
155+
templateTimelineId: null,
156+
status: TimelineStatus.draft,
139157
dataProviders,
140158
eventType: 'all',
141159
filters,

0 commit comments

Comments
 (0)