Skip to content

Commit 537065a

Browse files
[SIEM] Fix auto save for template timeline (#65001)
* update save timeline * fix types * allow template timeline to be updated via import * fix unit tests * fix for review * handle update timeline Co-authored-by: Elastic Machine <[email protected]>
1 parent eae92e3 commit 537065a

File tree

22 files changed

+211
-34
lines changed

22 files changed

+211
-34
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ export const TimelineTypeLiteralRt = runtimeTypes.union([
144144
runtimeTypes.literal(TimelineType.default),
145145
]);
146146

147+
const TimelineTypeLiteralWithNullRt = unionWithNullType(TimelineTypeLiteralRt);
148+
149+
export type TimelineTypeLiteral = runtimeTypes.TypeOf<typeof TimelineTypeLiteralRt>;
150+
export type TimelineTypeLiteralWithNull = runtimeTypes.TypeOf<typeof TimelineTypeLiteralWithNullRt>;
151+
147152
export const SavedTimelineRuntimeType = runtimeTypes.partial({
148153
columns: unionWithNullType(runtimeTypes.array(SavedColumnHeaderRuntimeType)),
149154
dataProviders: unionWithNullType(runtimeTypes.array(SavedDataProviderRuntimeType)),

x-pack/plugins/siem/public/components/open_timeline/helpers.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { KueryFilterQueryKind } from '../../store/model';
3636
import { Note } from '../../lib/note';
3737
import moment from 'moment';
3838
import sinon from 'sinon';
39+
import { TimelineType } from '../../../common/types/timeline';
3940

4041
jest.mock('../../store/inputs/actions');
4142
jest.mock('../../store/timeline/actions');
@@ -299,6 +300,9 @@ describe('helpers', () => {
299300
sortDirection: 'desc',
300301
},
301302
title: '',
303+
timelineType: TimelineType.default,
304+
templateTimelineId: null,
305+
templateTimelineVersion: null,
302306
version: '1',
303307
width: 1100,
304308
});
@@ -393,6 +397,9 @@ describe('helpers', () => {
393397
sortDirection: 'desc',
394398
},
395399
title: '',
400+
timelineType: TimelineType.default,
401+
templateTimelineId: null,
402+
templateTimelineVersion: null,
396403
version: '1',
397404
width: 1100,
398405
});
@@ -467,6 +474,9 @@ describe('helpers', () => {
467474
},
468475
loadingEventIds: [],
469476
title: '',
477+
timelineType: TimelineType.default,
478+
templateTimelineId: null,
479+
templateTimelineVersion: null,
470480
noteIds: [],
471481
pinnedEventIds: {},
472482
pinnedEventsSaveObject: {},
@@ -632,6 +642,9 @@ describe('helpers', () => {
632642
},
633643
loadingEventIds: [],
634644
title: '',
645+
timelineType: TimelineType.default,
646+
templateTimelineId: null,
647+
templateTimelineVersion: null,
635648
noteIds: [],
636649
pinnedEventIds: {},
637650
pinnedEventsSaveObject: {},

x-pack/plugins/siem/public/components/open_timeline/helpers.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import ApolloClient from 'apollo-client';
88
import { getOr, set, isEmpty } from 'lodash/fp';
99
import { Action } from 'typescript-fsa';
1010
import uuid from 'uuid';
11-
1211
import { Dispatch } from 'redux';
12+
1313
import { oneTimelineQuery } from '../../containers/timeline/one/index.gql_query';
1414
import { TimelineResult, GetOneTimeline, NoteResult } from '../../graphql/types';
1515
import {
@@ -169,6 +169,8 @@ export const defaultTimelineToTimelineModel = (
169169
savedObjectId: duplicate ? null : timeline.savedObjectId,
170170
version: duplicate ? null : timeline.version,
171171
title: duplicate ? '' : timeline.title || '',
172+
templateTimelineId: duplicate ? null : timeline.templateTimelineId,
173+
templateTimelineVersion: duplicate ? null : timeline.templateTimelineVersion,
172174
}).reduce((acc: TimelineModel, [key, value]) => (value != null ? set(key, value, acc) : acc), {
173175
...timelineDefaults,
174176
id: '',

x-pack/plugins/siem/public/containers/timeline/one/index.gql_query.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ export const oneTimelineQuery = gql`
129129
version
130130
}
131131
title
132+
timelineType
133+
templateTimelineId
134+
templateTimelineVersion
132135
savedQueryId
133136
sort {
134137
columnId

x-pack/plugins/siem/public/graphql/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5112,6 +5112,12 @@ export namespace GetOneTimeline {
51125112

51135113
title: Maybe<string>;
51145114

5115+
timelineType: Maybe<TimelineType>;
5116+
5117+
templateTimelineId: Maybe<string>;
5118+
5119+
templateTimelineVersion: Maybe<number>;
5120+
51155121
savedQueryId: Maybe<string>;
51165122

51175123
sort: Maybe<Sort>;

x-pack/plugins/siem/public/mock/global_state.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
DEFAULT_INTERVAL_TYPE,
2424
DEFAULT_INTERVAL_VALUE,
2525
} from '../../common/constants';
26+
import { TimelineType } from '../../common/types/timeline';
2627

2728
export const mockGlobalState: State = {
2829
app: {
@@ -201,6 +202,9 @@ export const mockGlobalState: State = {
201202
kqlQuery: { filterQuery: null, filterQueryDraft: null },
202203
loadingEventIds: [],
203204
title: '',
205+
timelineType: TimelineType.default,
206+
templateTimelineId: null,
207+
templateTimelineVersion: null,
204208
noteIds: [],
205209
dateRange: {
206210
start: 0,

x-pack/plugins/siem/public/mock/timeline_results.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
* or more contributor license agreements. Licensed under the Elastic License;
44
* you may not use this file except in compliance with the Elastic License.
55
*/
6+
import { FilterStateStore } from '../../../../../src/plugins/data/common/es_query/filters/meta_filter';
7+
8+
import { TimelineType } from '../../common/types/timeline';
69

710
import { OpenTimelineResult } from '../components/open_timeline/types';
811
import { GetAllTimeline, SortFieldTimeline, TimelineResult, Direction } from '../graphql/types';
912
import { allTimelinesQuery } from '../containers/timeline/all/index.gql_query';
1013
import { CreateTimelineProps } from '../pages/detection_engine/components/signals/types';
1114
import { TimelineModel } from '../store/timeline/model';
1215
import { timelineDefaults } from '../store/timeline/defaults';
13-
import { FilterStateStore } from '../../../../../src/plugins/data/common/es_query/filters/meta_filter';
1416
export interface MockedProvidedQuery {
1517
request: {
1618
query: GetAllTimeline.Query;
@@ -168,7 +170,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
168170
'ZF0W12oB9v5HJNSHwY6L',
169171
],
170172
title: 'test 1',
171-
timelineType: null,
173+
timelineType: TimelineType.default,
172174
templateTimelineId: null,
173175
templateTimelineVersion: null,
174176
created: 1558386787614,
@@ -297,7 +299,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
297299
'ZF0W12oB9v5HJNSHwY6L',
298300
],
299301
title: 'test 2',
300-
timelineType: null,
302+
timelineType: TimelineType.default,
301303
templateTimelineId: null,
302304
templateTimelineVersion: null,
303305
created: 1558386787614,
@@ -426,7 +428,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
426428
'ZF0W12oB9v5HJNSHwY6L',
427429
],
428430
title: 'test 2',
429-
timelineType: null,
431+
timelineType: TimelineType.default,
430432
templateTimelineId: null,
431433
templateTimelineVersion: null,
432434
created: 1558386787614,
@@ -555,7 +557,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
555557
'ZF0W12oB9v5HJNSHwY6L',
556558
],
557559
title: 'test 3',
558-
timelineType: null,
560+
timelineType: TimelineType.default,
559561
templateTimelineId: null,
560562
templateTimelineVersion: null,
561563
created: 1558386787614,
@@ -684,7 +686,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
684686
'ZF0W12oB9v5HJNSHwY6L',
685687
],
686688
title: 'test 4',
687-
timelineType: null,
689+
timelineType: TimelineType.default,
688690
templateTimelineId: null,
689691
templateTimelineVersion: null,
690692
created: 1558386787614,
@@ -813,7 +815,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
813815
'ZF0W12oB9v5HJNSHwY6L',
814816
],
815817
title: 'test 5',
816-
timelineType: null,
818+
timelineType: TimelineType.default,
817819
templateTimelineId: null,
818820
templateTimelineVersion: null,
819821
created: 1558386787614,
@@ -942,7 +944,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
942944
'ZF0W12oB9v5HJNSHwY6L',
943945
],
944946
title: 'test 6',
945-
timelineType: null,
947+
timelineType: TimelineType.default,
946948
templateTimelineId: null,
947949
templateTimelineVersion: null,
948950
created: 1558386787614,
@@ -1071,7 +1073,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
10711073
'ZF0W12oB9v5HJNSHwY6L',
10721074
],
10731075
title: 'test 7',
1074-
timelineType: null,
1076+
timelineType: TimelineType.default,
10751077
templateTimelineId: null,
10761078
templateTimelineVersion: null,
10771079
created: 1558386787614,
@@ -1200,7 +1202,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
12001202
'ZF0W12oB9v5HJNSHwY6L',
12011203
],
12021204
title: 'test 7',
1203-
timelineType: null,
1205+
timelineType: TimelineType.default,
12041206
templateTimelineId: null,
12051207
templateTimelineVersion: null,
12061208
created: 1558386787614,
@@ -1329,7 +1331,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
13291331
'ZF0W12oB9v5HJNSHwY6L',
13301332
],
13311333
title: 'test 7',
1332-
timelineType: null,
1334+
timelineType: TimelineType.default,
13331335
templateTimelineId: null,
13341336
templateTimelineVersion: null,
13351337
created: 1558386787614,
@@ -1458,7 +1460,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
14581460
'ZF0W12oB9v5HJNSHwY6L',
14591461
],
14601462
title: 'test 7',
1461-
timelineType: null,
1463+
timelineType: TimelineType.default,
14621464
templateTimelineId: null,
14631465
templateTimelineVersion: null,
14641466
created: 1558386787614,
@@ -1587,7 +1589,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
15871589
'ZF0W12oB9v5HJNSHwY6L',
15881590
],
15891591
title: 'test 7',
1590-
timelineType: null,
1592+
timelineType: TimelineType.default,
15911593
templateTimelineId: null,
15921594
templateTimelineVersion: null,
15931595
created: 1558386787614,
@@ -1716,7 +1718,7 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [
17161718
'ZF0W12oB9v5HJNSHwY6L',
17171719
],
17181720
title: 'test 7',
1719-
timelineType: null,
1721+
timelineType: TimelineType.default,
17201722
templateTimelineId: null,
17211723
templateTimelineVersion: null,
17221724
created: 1558386787614,
@@ -2141,6 +2143,9 @@ export const mockTimelineModel: TimelineModel = {
21412143
sortDirection: Direction.desc,
21422144
},
21432145
title: 'Test rule',
2146+
timelineType: TimelineType.default,
2147+
templateTimelineId: null,
2148+
templateTimelineVersion: null,
21442149
version: '1',
21452150
width: 1100,
21462151
};
@@ -2164,6 +2169,9 @@ export const mockTimelineResult: TimelineResult = {
21642169
],
21652170
kqlMode: 'filter',
21662171
title: 'Test rule',
2172+
timelineType: TimelineType.default,
2173+
templateTimelineId: null,
2174+
templateTimelineVersion: null,
21672175
savedQueryId: null,
21682176
sort: { columnId: '@timestamp', sortDirection: 'desc' },
21692177
version: '1',
@@ -2235,6 +2243,9 @@ export const defaultTimelineProps: CreateTimelineProps = {
22352243
showRowRenderers: true,
22362244
sort: { columnId: '@timestamp', sortDirection: Direction.desc },
22372245
title: '',
2246+
timelineType: TimelineType.default,
2247+
templateTimelineVersion: null,
2248+
templateTimelineId: null,
22382249
version: null,
22392250
width: 1100,
22402251
},

x-pack/plugins/siem/public/pages/detection_engine/components/signals/actions.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '../../../../mock/';
1616
import { CreateTimeline, UpdateTimelineLoading } from './types';
1717
import { Ecs } from '../../../../graphql/types';
18+
import { TimelineType } from '../../../../../common/types/timeline';
1819

1920
jest.mock('apollo-client');
2021

@@ -215,6 +216,9 @@ describe('signals actions', () => {
215216
sortDirection: 'desc',
216217
},
217218
title: '',
219+
timelineType: TimelineType.default,
220+
templateTimelineId: null,
221+
templateTimelineVersion: null,
218222
version: null,
219223
width: 1100,
220224
},

x-pack/plugins/siem/public/store/timeline/defaults.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
import { TimelineType } from '../../../common/types/timeline';
8+
79
import { Direction } from '../../graphql/types';
810
import { DEFAULT_TIMELINE_WIDTH } from '../../components/timeline/body/constants';
911
import { defaultHeaders } from '../../components/timeline/body/column_headers/default_headers';
@@ -33,6 +35,9 @@ export const timelineDefaults: SubsetTimelineModel & Pick<TimelineModel, 'filter
3335
},
3436
loadingEventIds: [],
3537
title: '',
38+
timelineType: TimelineType.default,
39+
templateTimelineId: null,
40+
templateTimelineVersion: null,
3641
noteIds: [],
3742
pinnedEventIds: {},
3843
pinnedEventsSaveObject: {},

x-pack/plugins/siem/public/store/timeline/epic.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { TimelineModel } from './model';
7+
import { Filter, esFilters } from '../../../../../../src/plugins/data/public';
8+
9+
import { TimelineType } from '../../../common/types/timeline';
10+
811
import { Direction } from '../../graphql/types';
9-
import { convertTimelineAsInput } from './epic';
1012

11-
import { Filter, esFilters } from '../../../../../../src/plugins/data/public';
13+
import { TimelineModel } from './model';
14+
import { convertTimelineAsInput } from './epic';
1215

1316
describe('Epic Timeline', () => {
1417
describe('#convertTimelineAsInput ', () => {
@@ -135,6 +138,9 @@ describe('Epic Timeline', () => {
135138
},
136139
loadingEventIds: [],
137140
title: 'saved',
141+
timelineType: TimelineType.default,
142+
templateTimelineId: null,
143+
templateTimelineVersion: null,
138144
noteIds: [],
139145
pinnedEventIds: {},
140146
pinnedEventsSaveObject: {},
@@ -283,6 +289,9 @@ describe('Epic Timeline', () => {
283289
columnId: '@timestamp',
284290
sortDirection: 'desc',
285291
},
292+
templateTimelineId: null,
293+
templateTimelineVersion: null,
294+
timelineType: TimelineType.default,
286295
title: 'saved',
287296
});
288297
});

0 commit comments

Comments
 (0)