-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution] Add Discover Data View picker to Timeline (#184928)
## Summary Add new `Dataview picker` component and some initial redux setup to feed it with data. Dont expect this to work just like the original timeline sourcerer does just yet. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### Testing Do `localStorage.setItem('EXPERIMENTAL_SOURCERER_ENABLED', true)` in the browser console, reload the page, then open new timeline. You should see the new dataview picker (colored in red temporarily), that should allow data view switching. Known issues: dataview editor is showing behind the picker (to be fixed in subsequent PR).
- Loading branch information
Showing
23 changed files
with
715 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
...security_solution/public/sourcerer/experimental/components/dataview_picker/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React from 'react'; | ||
import { render, screen, fireEvent } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { useKibana } from '../../../../common/lib/kibana/kibana_react'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { selectDataView } from '../../redux/actions'; | ||
import { DataViewPicker } from '.'; | ||
|
||
// Mock the required hooks and dependencies | ||
jest.mock('../../../../common/lib/kibana/kibana_react', () => ({ | ||
useKibana: jest.fn(), | ||
})); | ||
|
||
jest.mock('react-redux', () => ({ | ||
useDispatch: jest.fn(), | ||
useSelector: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../redux/actions', () => ({ | ||
selectDataView: jest.fn(), | ||
})); | ||
|
||
jest.mock('@kbn/unified-search-plugin/public', () => ({ | ||
DataViewPicker: jest.fn((props) => ( | ||
<div> | ||
<div>{props.trigger.label}</div> | ||
<button | ||
type="button" | ||
onClick={() => props.onChangeDataView('new-id')} | ||
>{`Change DataView`}</button> | ||
<button type="button" onClick={props.onAddField}> | ||
{`Add Field`} | ||
</button> | ||
<button type="button" onClick={props.onDataViewCreated}> | ||
{`Create New DataView`} | ||
</button> | ||
</div> | ||
)), | ||
})); | ||
|
||
describe('DataViewPicker', () => { | ||
const mockDispatch = jest.fn(); | ||
const mockDataViewEditor = { | ||
openEditor: jest.fn(), | ||
}; | ||
const mockDataViewFieldEditor = { | ||
openEditor: jest.fn(), | ||
}; | ||
const mockData = { | ||
dataViews: { | ||
get: jest.fn().mockResolvedValue({}), | ||
}, | ||
}; | ||
|
||
beforeEach(() => { | ||
(useDispatch as jest.Mock).mockReturnValue(mockDispatch); | ||
(useKibana as jest.Mock).mockReturnValue({ | ||
services: { | ||
dataViewEditor: mockDataViewEditor, | ||
data: mockData, | ||
dataViewFieldEditor: mockDataViewFieldEditor, | ||
}, | ||
}); | ||
(useSelector as jest.Mock).mockReturnValue({ dataViewId: 'test-id' }); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
test('renders the DataviewPicker component', () => { | ||
render(<DataViewPicker />); | ||
expect(screen.getByText('Dataview')).toBeInTheDocument(); | ||
}); | ||
|
||
test('calls dispatch on data view change', () => { | ||
render(<DataViewPicker />); | ||
fireEvent.click(screen.getByText('Change DataView')); | ||
expect(mockDispatch).toHaveBeenCalledWith(selectDataView('new-id')); | ||
}); | ||
|
||
test('opens data view editor when creating a new data view', () => { | ||
render(<DataViewPicker />); | ||
fireEvent.click(screen.getByText('Create New DataView')); | ||
expect(mockDataViewEditor.openEditor).toHaveBeenCalled(); | ||
}); | ||
}); |
99 changes: 99 additions & 0 deletions
99
...gins/security_solution/public/sourcerer/experimental/components/dataview_picker/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { DataViewPicker as USDataViewPicker } from '@kbn/unified-search-plugin/public'; | ||
import React, { useCallback, useRef, useMemo, memo } from 'react'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
|
||
import { useKibana } from '../../../../common/lib/kibana/kibana_react'; | ||
import { DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID } from '../../constants'; | ||
import { selectDataView } from '../../redux/actions'; | ||
import { sourcererAdapterSelector } from '../../redux/selectors'; | ||
|
||
const TRIGGER_CONFIG = { | ||
label: 'Dataview', | ||
color: 'danger', | ||
title: 'Experimental data view picker', | ||
iconType: 'beaker', | ||
} as const; | ||
|
||
export const DataViewPicker = memo(() => { | ||
const dispatch = useDispatch(); | ||
|
||
const { | ||
services: { dataViewEditor, data, dataViewFieldEditor }, | ||
} = useKibana(); | ||
|
||
const closeDataViewEditor = useRef<() => void | undefined>(); | ||
const closeFieldEditor = useRef<() => void | undefined>(); | ||
|
||
// TODO: should this be implemented like that? If yes, we need to source dataView somehow or implement the same thing based on the existing state value. | ||
// const canEditDataView = | ||
// Boolean(dataViewEditor?.userPermissions.editDataView()) || !dataView.isPersisted(); | ||
const canEditDataView = true; | ||
|
||
const { dataViewId } = useSelector(sourcererAdapterSelector); | ||
|
||
const createNewDataView = useCallback(() => { | ||
closeDataViewEditor.current = dataViewEditor.openEditor({ | ||
// eslint-disable-next-line no-console | ||
onSave: () => console.log('new data view saved'), | ||
allowAdHocDataView: true, | ||
}); | ||
}, [dataViewEditor]); | ||
|
||
const onFieldEdited = useCallback(() => {}, []); | ||
|
||
const editField = useMemo(() => { | ||
if (!canEditDataView) { | ||
return; | ||
} | ||
return async (fieldName?: string, _uiAction: 'edit' | 'add' = 'edit') => { | ||
if (!dataViewId) { | ||
return; | ||
} | ||
|
||
const dataViewInstance = await data.dataViews.get(dataViewId); | ||
closeFieldEditor.current = dataViewFieldEditor.openEditor({ | ||
ctx: { | ||
dataView: dataViewInstance, | ||
}, | ||
fieldName, | ||
onSave: async () => { | ||
onFieldEdited(); | ||
}, | ||
}); | ||
}; | ||
}, [canEditDataView, dataViewId, data.dataViews, dataViewFieldEditor, onFieldEdited]); | ||
|
||
const addField = useMemo( | ||
() => (canEditDataView && editField ? () => editField(undefined, 'add') : undefined), | ||
[editField, canEditDataView] | ||
); | ||
|
||
const handleChangeDataView = useCallback( | ||
(id: string) => { | ||
dispatch(selectDataView(id)); | ||
}, | ||
[dispatch] | ||
); | ||
|
||
const handleEditDataView = useCallback(() => {}, []); | ||
|
||
return ( | ||
<USDataViewPicker | ||
currentDataViewId={dataViewId || DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID} | ||
trigger={TRIGGER_CONFIG} | ||
onChangeDataView={handleChangeDataView} | ||
onEditDataView={handleEditDataView} | ||
onAddField={addField} | ||
onDataViewCreated={createNewDataView} | ||
/> | ||
); | ||
}); | ||
|
||
DataViewPicker.displayName = 'DataviewPicker'; |
3 changes: 3 additions & 0 deletions
3
...ity_solution/public/sourcerer/experimental/components/dataview_picker/readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Dataview Picker | ||
|
||
A replacement for the Sourcerer component, based on the Discover implementation. |
8 changes: 8 additions & 0 deletions
8
x-pack/plugins/security_solution/public/sourcerer/experimental/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
export const DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID = 'security-solution-default'; |
Oops, something went wrong.