diff --git a/CHANGELOG.md b/CHANGELOG.md index fe7bcd7abb..502279b34b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Added +- Add feature to filter by field in the events table rows [#6977](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6991) - Support for Wazuh 4.9.1 ### Fixed diff --git a/plugins/main/public/components/common/data-grid/cell-filter-actions.test.tsx b/plugins/main/public/components/common/data-grid/cell-filter-actions.test.tsx new file mode 100644 index 0000000000..8eb829a886 --- /dev/null +++ b/plugins/main/public/components/common/data-grid/cell-filter-actions.test.tsx @@ -0,0 +1,110 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import { + cellFilterActions, + filterIsAction, + filterIsNotAction, +} from './cell-filter-actions'; +import { EuiButtonEmpty } from '@elastic/eui'; + +const indexPattern = { + flattenHit: jest.fn().mockImplementation(() => ({})), +}; + +const onFilter = jest.fn(); + +const TEST_COLUMN_ID = 'test'; + +describe('cell-filter-actions', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('cellFilterActions', () => { + it('should be undefined', () => { + // @ts-expect-error Expected 4 arguments, but got 1. + expect(cellFilterActions({ filterable: false })).toBeUndefined(); + }); + }); + + describe('filterIsAction', () => { + it('should call on filter with column id and value', () => { + const TEST_VALUE = 'test-value'; + const ROW = 'row'; + + indexPattern.flattenHit.mockImplementation(() => ({ + [TEST_COLUMN_ID]: TEST_VALUE, + })); + const rows = [ROW]; + const pageSize = 15; + + render( + filterIsAction( + // @ts-expect-error Argument of type '{ flattenHit: jest.Mock; }' is not assignable to parameter of type 'IndexPattern' + indexPattern, + rows, + pageSize, + onFilter, + )({ + rowIndex: 0, + columnId: TEST_COLUMN_ID, + Component: EuiButtonEmpty, + isExpanded: false, + closePopover: () => {}, + }), + ); + + let component = screen.getByText('Filter for value'); + expect(component).toBeTruthy(); + component = screen.getByLabelText(`Filter for value: ${TEST_COLUMN_ID}`); + expect(component).toBeTruthy(); + + fireEvent.click(component); + + expect(onFilter).toHaveBeenCalledTimes(1); + expect(onFilter).toHaveBeenCalledWith(TEST_COLUMN_ID, TEST_VALUE, 'is'); + }); + }); + + describe('filterIsNotAction', () => { + it('should call on filter with column id and value', () => { + const TEST_VALUE = 'test-value'; + const ROW = 'row'; + + indexPattern.flattenHit.mockImplementation(() => ({ + [TEST_COLUMN_ID]: TEST_VALUE, + })); + const rows = [ROW]; + const pageSize = 15; + + render( + filterIsNotAction( + // @ts-expect-error Argument of type '{ flattenHit: jest.Mock; }' is not assignable to parameter of type 'IndexPattern' + indexPattern, + rows, + pageSize, + onFilter, + )({ + rowIndex: 0, + columnId: TEST_COLUMN_ID, + Component: EuiButtonEmpty, + isExpanded: false, + closePopover: () => {}, + }), + ); + + let component = screen.getByText('Filter out value'); + expect(component).toBeTruthy(); + component = screen.getByLabelText(`Filter out value: ${TEST_COLUMN_ID}`); + expect(component).toBeTruthy(); + + fireEvent.click(component); + + expect(onFilter).toHaveBeenCalledTimes(1); + expect(onFilter).toHaveBeenCalledWith( + TEST_COLUMN_ID, + TEST_VALUE, + 'is not', + ); + }); + }); +}); diff --git a/plugins/main/public/components/common/data-grid/cell-filter-actions.tsx b/plugins/main/public/components/common/data-grid/cell-filter-actions.tsx new file mode 100644 index 0000000000..6f9007dffc --- /dev/null +++ b/plugins/main/public/components/common/data-grid/cell-filter-actions.tsx @@ -0,0 +1,117 @@ +import { + EuiDataGridColumn, + EuiDataGridColumnCellActionProps, +} from '@elastic/eui'; +import { i18n } from '@osd/i18n'; +import React from 'react'; +import { + IFieldType, + IndexPattern, +} from '../../../../../../src/plugins/data/common'; +import { FILTER_OPERATOR } from '../data-source/pattern/pattern-data-source-filter-manager'; + +export const filterIsAction = ( + indexPattern: IndexPattern, + rows: any[], + pageSize: number, + onFilter: ( + columndId: string, + value: any, + operation: FILTER_OPERATOR.IS | FILTER_OPERATOR.IS_NOT, + ) => void, +) => { + return ({ + rowIndex, + columnId, + Component, + }: EuiDataGridColumnCellActionProps) => { + const filterForValueText = i18n.translate('discover.filterForValue', { + defaultMessage: 'Filter for value', + }); + const filterForValueLabel = i18n.translate('discover.filterForValueLabel', { + defaultMessage: 'Filter for value: {value}', + values: { value: columnId }, + }); + + const handleClick = () => { + const row = rows[rowIndex % pageSize]; + const flattened = indexPattern.flattenHit(row); + + if (flattened) { + onFilter(columnId, flattened[columnId], FILTER_OPERATOR.IS); + } + }; + + return ( + + {filterForValueText} + + ); + }; +}; + +export const filterIsNotAction = + ( + indexPattern: IndexPattern, + rows: any[], + pageSize: number, + onFilter: ( + columndId: string, + value: any, + operation: FILTER_OPERATOR.IS | FILTER_OPERATOR.IS_NOT, + ) => void, + ) => + ({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) => { + const filterOutValueText = i18n.translate('discover.filterOutValue', { + defaultMessage: 'Filter out value', + }); + const filterOutValueLabel = i18n.translate('discover.filterOutValueLabel', { + defaultMessage: 'Filter out value: {value}', + values: { value: columnId }, + }); + + const handleClick = () => { + const row = rows[rowIndex % pageSize]; + const flattened = indexPattern.flattenHit(row); + + if (flattened) { + onFilter(columnId, flattened[columnId], FILTER_OPERATOR.IS_NOT); + } + }; + + return ( + + {filterOutValueText} + + ); + }; + +// https://github.com/opensearch-project/OpenSearch-Dashboards/blob/2.13.0/src/plugins/discover/public/application/components/data_grid/data_grid_table_cell_actions.tsx +export function cellFilterActions( + field: IFieldType, + indexPattern: IndexPattern, + rows: any[], + pageSize: number, + onFilter: ( + columndId: string, + value: any, + operation: FILTER_OPERATOR.IS | FILTER_OPERATOR.IS_NOT, + ) => void, +) { + if (!field.filterable) return; + + return [ + filterIsAction(indexPattern, rows, pageSize, onFilter), + filterIsNotAction(indexPattern, rows, pageSize, onFilter), + ] as EuiDataGridColumn['cellActions']; +} diff --git a/plugins/main/public/components/common/data-grid/data-grid-service.test.ts b/plugins/main/public/components/common/data-grid/data-grid-service.test.ts new file mode 100644 index 0000000000..cfc58ff671 --- /dev/null +++ b/plugins/main/public/components/common/data-grid/data-grid-service.test.ts @@ -0,0 +1,47 @@ +import { parseData } from './data-grid-service'; +import { SearchResponse } from '../../../../../../src/core/server'; + +describe('describe-grid-test', () => { + describe('parseData', () => { + it('should parse data extract source fields correctly', () => { + const resultsHits: SearchResponse['hits']['hits'] = [ + { + _id: 'id-1', + _index: 'index-1', + _type: 'type-1', + _score: 1, + _source: { + test: true, + }, + }, + ]; + + const expectedResult = [ + { + _id: 'id-1', + _index: 'index-1', + _type: 'type-1', + _score: 1, + test: true, + }, + ]; + + expect(parseData(resultsHits)).toEqual(expectedResult); + }); + + it('should parse data handle invalid hits', () => { + const resultsHits: SearchResponse['hits']['hits'] = [ + // @ts-expect-error + undefined, + // @ts-expect-error + null, + // @ts-expect-error + 0, + ]; + + const expectedResult = [{}, {}, {}]; + + expect(parseData(resultsHits)).toEqual(expectedResult); + }); + }); +}); diff --git a/plugins/main/public/components/common/data-grid/data-grid-service.ts b/plugins/main/public/components/common/data-grid/data-grid-service.ts index 426f346e4f..35151a2f2d 100644 --- a/plugins/main/public/components/common/data-grid/data-grid-service.ts +++ b/plugins/main/public/components/common/data-grid/data-grid-service.ts @@ -2,19 +2,37 @@ import { SearchResponse } from '../../../../../../src/core/server'; import * as FileSaver from '../../../services/file-saver'; import { beautifyDate } from '../../agents/vuls/inventory/lib'; import { SearchParams, search } from '../search-bar/search-bar-service'; -import { IFieldType } from '../../../../../../src/plugins/data/common'; +import { + Filter, + IFieldType, + IndexPattern, +} from '../../../../../../src/plugins/data/common'; export const MAX_ENTRIES_PER_QUERY = 10000; -import { EuiDataGridColumn } from '@elastic/eui'; import { tDataGridColumn } from './use-data-grid'; +import { cellFilterActions } from './cell-filter-actions'; +import { + FILTER_OPERATOR, + PatternDataSourceFilterManager, +} from '../data-source/pattern/pattern-data-source-filter-manager'; -export const parseData = ( - resultsHits: SearchResponse['hits']['hits'], -): any[] => { +type ParseData = + | { + source: T; + _id: string; + _index: string; + _type: string; + _score: number; + } + | {}; + +export const parseData = ( + resultsHits: SearchResponse['hits']['hits'], +): ParseData[] => { const data = resultsHits.map(hit => { if (!hit) { return {}; } - const source = hit._source as object; + const source = hit._source as T; const data = { ...source, _id: hit._id, @@ -28,10 +46,10 @@ export const parseData = ( }; export const getFieldFormatted = ( - rowIndex, - columnId, - indexPattern, - rowsParsed, + rowIndex: number, + columnId: string, + indexPattern: IndexPattern, + rowsParsed: ParseData[], ) => { const field = indexPattern.fields.find(field => field.name === columnId); let fieldValue = null; @@ -169,34 +187,79 @@ export const exportSearchToCSV = async ( } }; +const onFilterCellActions = ( + indexPatternId: string, + filters: Filter[], + setFilters: (filters: Filter[]) => void, +) => { + return ( + columndId: string, + value: any, + operation: FILTER_OPERATOR.IS | FILTER_OPERATOR.IS_NOT, + ) => { + const newFilter = PatternDataSourceFilterManager.createFilter( + operation, + columndId, + value, + indexPatternId, + ); + setFilters([...filters, newFilter]); + }; +}; + +const mapToDataGridColumn = ( + field: IFieldType, + indexPattern: IndexPattern, + rows: any[], + pageSize: number, + filters: Filter[], + setFilters: (filters: Filter[]) => void, + defaultColumns: tDataGridColumn[], +): tDataGridColumn => { + const defaultColumn = defaultColumns.find(column => column.id === field.name); + return { + ...field, + id: field.name, + name: field.name, + schema: field.type, + actions: { showHide: true }, + ...defaultColumn, + cellActions: cellFilterActions( + field, + indexPattern, + rows, + pageSize, + onFilterCellActions(indexPattern.id as string, filters, setFilters), + ), + } as tDataGridColumn; +}; + export const parseColumns = ( fields: IFieldType[], defaultColumns: tDataGridColumn[] = [], + indexPattern: IndexPattern, + rows: any[], + pageSize: number, + filters: Filter[], + setFilters: (filters: Filter[]) => void, ): tDataGridColumn[] => { // remove _source field becuase is a object field and is not supported // merge the properties of the field with the default columns - if (!fields?.length) { - return defaultColumns; - } + if (!fields?.length) return defaultColumns; - const columns = fields + return fields .filter(field => field.name !== '_source') - .map(field => { - const defaultColumn = defaultColumns.find( - column => column.id === field.name, - ); - return { - ...field, - id: field.name, - name: field.name, - schema: field.type, - actions: { - showHide: true, - }, - ...defaultColumn, - }; - }) as tDataGridColumn[]; - return columns; + .map(field => + mapToDataGridColumn( + field, + indexPattern, + rows, + pageSize, + filters, + setFilters, + defaultColumns, + ), + ); }; /** diff --git a/plugins/main/public/components/common/data-grid/use-data-grid.test.tsx b/plugins/main/public/components/common/data-grid/use-data-grid.test.tsx index 3d6cdc7d5f..8e93598afb 100644 --- a/plugins/main/public/components/common/data-grid/use-data-grid.test.tsx +++ b/plugins/main/public/components/common/data-grid/use-data-grid.test.tsx @@ -3,21 +3,25 @@ import { renderHook } from '@testing-library/react-hooks'; import React from 'react'; describe('useDataGrid hook', () => { - it('should return override the numbers of rows per page', () => { - - const dataGridProps: tDataGridProps = { - indexPattern: 'mocked-index-pattern', - results: {}, - defaultColumns: [], - DocViewInspectButton: () =>
, - ariaLabelledBy: '', - pagination: { - pageSize: 10, - pageSizeOptions: [10, 20, 30], - } - } - const { result } = renderHook(() => useDataGrid(dataGridProps)); - expect(result.current.pagination.pageSize).toEqual(10); - expect(result.current.pagination.pageSizeOptions).toEqual([10, 20, 30]); - }) -}); \ No newline at end of file + it('should return override the numbers of rows per page', () => { + const dataGridProps: tDataGridProps = { + // @ts-expect-error Type 'string' is not assignable to type 'IndexPattern' + indexPattern: 'mocked-index-pattern', + // @ts-expect-error Type '{}' is missing the following properties from type 'SearchResponse': took, timed_out, _shards, hits + results: {}, + defaultColumns: [], + DocViewInspectButton: () =>
, + ariaLabelledBy: '', + pagination: { + pageIndex: 0, + pageSize: 15, + pageSizeOptions: [15, 25, 50, 100], + }, + }; + const { result } = renderHook(() => useDataGrid(dataGridProps)); + expect(result.current?.pagination?.pageSize).toEqual(15); + expect(result.current?.pagination?.pageSizeOptions).toEqual([ + 15, 25, 50, 100, + ]); + }); +}); diff --git a/plugins/main/public/components/common/data-grid/use-data-grid.ts b/plugins/main/public/components/common/data-grid/use-data-grid.ts index 5e89e16ec3..a330fc5ad1 100644 --- a/plugins/main/public/components/common/data-grid/use-data-grid.ts +++ b/plugins/main/public/components/common/data-grid/use-data-grid.ts @@ -4,7 +4,7 @@ import { EuiDataGridProps, EuiDataGridSorting, } from '@elastic/eui'; -import React, { useEffect, useMemo, useState, Fragment } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { SearchResponse } from '@opensearch-project/opensearch/api/types'; // ToDo: check how create this methods import { @@ -12,17 +12,37 @@ import { getFieldFormatted, parseColumns, } from './data-grid-service'; -import { IndexPattern } from '../../../../../../src/plugins/data/common'; +import { + Filter, + IndexPattern, +} from '../../../../../../src/plugins/data/common'; +import { EuiDataGridPaginationProps } from '@opensearch-project/oui'; + +export interface PaginationOptions + extends Pick< + EuiDataGridPaginationProps, + 'pageIndex' | 'pageSize' | 'pageSizeOptions' + > {} + +type SortingColumns = EuiDataGridSorting['columns']; const MAX_ENTRIES_PER_QUERY = 10000; -const DEFAULT_PAGE_SIZE_OPTIONS = [20, 50, 100]; +const DEFAULT_PAGE_INDEX = 0; +const DEFAULT_PAGE_SIZE = 15; +const DEFAULT_PAGE_SIZE_OPTIONS = [DEFAULT_PAGE_SIZE, 25, 50, 100]; +const DEFAULT_PAGINATION_OPTIONS: PaginationOptions = { + pageIndex: DEFAULT_PAGE_INDEX, + pageSize: DEFAULT_PAGE_SIZE, + pageSizeOptions: DEFAULT_PAGE_SIZE_OPTIONS, +}; + +export interface RenderColumn { + render: (value: any, rowItem: object) => string | React.ReactNode; +} -export type tDataGridColumn = { - render?: (value: any, rowItem: object) => string | React.ReactNode; -} & EuiDataGridColumn; +export type tDataGridColumn = Partial & EuiDataGridColumn; -export type tDataGridRenderColumn = Required> & - Omit; +export type tDataGridRenderColumn = RenderColumn & EuiDataGridColumn; export type tDataGridProps = { indexPattern: IndexPattern; @@ -33,7 +53,10 @@ export type tDataGridProps = { rowIndex, }: EuiDataGridCellValueElementProps) => React.JSX.Element; ariaLabelledBy: string; - pagination?: Partial; + useDefaultPagination?: boolean; + pagination?: typeof DEFAULT_PAGINATION_OPTIONS; + filters?: Filter[]; + setFilters?: (filters: Filter[]) => void; }; export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { @@ -41,12 +64,13 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { indexPattern, DocViewInspectButton, results, - defaultColumns, + defaultColumns: columns, renderColumns, - pagination: defaultPagination, + useDefaultPagination = false, + pagination: paginationProps = {}, + filters = [], + setFilters = () => {}, } = props; - /** Columns **/ - const [columns, setColumns] = useState(defaultColumns); const [columnVisibility, setVisibility] = useState(() => columns.map(({ id }) => id), ); @@ -68,21 +92,25 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { ] : []; }; - const defaultSorting: EuiDataGridSorting['columns'] = getDefaultSorting(); + const defaultSorting: SortingColumns = getDefaultSorting(); const [sortingColumns, setSortingColumns] = useState(defaultSorting); - const onSort = sortingColumns => { + const onSort = (sortingColumns: SortingColumns) => { setSortingColumns(sortingColumns); }; /** Pagination **/ - const [pagination, setPagination] = useState( - defaultPagination || { - pageIndex: 0, - pageSize: 20, - pageSizeOptions: DEFAULT_PAGE_SIZE_OPTIONS, - }, + const [pagination, setPagination] = useState< + typeof DEFAULT_PAGINATION_OPTIONS + >( + useDefaultPagination + ? DEFAULT_PAGINATION_OPTIONS + : { + ...DEFAULT_PAGINATION_OPTIONS, + ...paginationProps, + }, ); + const onChangeItemsPerPage = useMemo( - () => pageSize => + () => (pageSize: number) => setPagination(pagination => ({ ...pagination, pageSize, @@ -90,7 +118,7 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { })), [rows, rowCount], ); - const onChangePage = pageIndex => + const onChangePage = (pageIndex: number) => setPagination(pagination => ({ ...pagination, pageIndex })); useEffect(() => { @@ -101,7 +129,13 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { setPagination(pagination => ({ ...pagination, pageIndex: 0 })); }, [rowCount]); - const renderCellValue = ({ rowIndex, columnId, setCellProps }) => { + const renderCellValue = ({ + rowIndex, + columnId, + }: { + rowIndex: number; + columnId: string; + }) => { const rowsParsed = parseData(rows); // On the context data always is stored the current page data (pagination) // then the rowIndex is relative to the current page @@ -139,7 +173,7 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { { id: 'inspectCollapseColumn', headerCellRender: () => null, - rowCellRender: props => + rowCellRender: (props: EuiDataGridCellValueElementProps) => DocViewInspectButton({ ...props, rowIndex: props.rowIndex % pagination.pageSize, @@ -150,7 +184,15 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { }, [results]); const filterColumns = () => { - const allColumns = parseColumns(indexPattern?.fields || [], defaultColumns); + const allColumns = parseColumns( + indexPattern?.fields || [], + columns, + indexPattern, + rows, + pagination.pageSize, + filters, + setFilters, + ); const columnMatch = []; const columnNonMatch = []; @@ -181,7 +223,7 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { 'aria-labelledby': props.ariaLabelledBy, columns: filterColumns(), columnVisibility: { - visibleColumns: defaultColumnsPosition(columnVisibility, defaultColumns), + visibleColumns: defaultColumnsPosition(columnVisibility, columns), setVisibleColumns: setVisibility, }, renderCellValue: renderCellValue, @@ -194,5 +236,5 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { onChangeItemsPerPage: onChangeItemsPerPage, onChangePage: onChangePage, }, - }; + } as EuiDataGridProps; }; diff --git a/plugins/main/public/components/common/search-bar/use-search-bar.ts b/plugins/main/public/components/common/search-bar/use-search-bar.ts index 8de3137690..b11c0e5113 100644 --- a/plugins/main/public/components/common/search-bar/use-search-bar.ts +++ b/plugins/main/public/components/common/search-bar/use-search-bar.ts @@ -28,7 +28,12 @@ export type tUseSearchBarProps = Partial & // Output types type tUserSearchBarResponse = { - searchBarProps: Partial; + searchBarProps: Partial< + SearchBarProps & { + useDefaultBehaviors: boolean; + absoluteDateRange: TimeRange; + } + >; }; /** diff --git a/plugins/main/public/components/common/wazuh-data-grid/wz-data-grid.tsx b/plugins/main/public/components/common/wazuh-data-grid/wz-data-grid.tsx index fa89cda502..c5d0e83cf8 100644 --- a/plugins/main/public/components/common/wazuh-data-grid/wz-data-grid.tsx +++ b/plugins/main/public/components/common/wazuh-data-grid/wz-data-grid.tsx @@ -5,7 +5,6 @@ import { EuiButtonIcon, EuiDataGridCellValueElementProps, EuiDataGrid, - EuiButtonEmpty, EuiFlyout, EuiFlyoutHeader, EuiTitle, @@ -17,6 +16,7 @@ import { exportSearchToCSV, tDataGridColumn, getAllCustomRenders, + PaginationOptions, } from '../data-grid'; import { getWazuhCorePlugin } from '../../../kibana-services'; import { @@ -44,11 +44,7 @@ export type tWazuhDataGridProps = { results: SearchResponse; defaultColumns: tDataGridColumn[]; isLoading: boolean; - defaultPagination: { - pageIndex: number; - pageSize: number; - pageSizeOptions: number[]; - }; + defaultPagination: PaginationOptions; query: any; exportFilters: tFilter[]; dateRange: TimeRange; @@ -106,11 +102,7 @@ const WazuhDataGrid = (props: tWazuhDataGridProps) => { results, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, - pagination: defaultPagination || { - pageIndex: 0, - pageSize: 15, - pageSizeOptions: [15, 25, 50, 100], - }, + useDefaultPagination: true, }); const { pagination, sorting, columnVisibility } = dataGridProps; diff --git a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx index a57ef42b7a..e8ac8842bd 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx @@ -10,7 +10,6 @@ import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, - EuiTitle, EuiPanel, } from '@elastic/eui'; import { IntlProvider } from 'react-intl'; @@ -34,6 +33,7 @@ import useSearchBar from '../search-bar/use-search-bar'; import { getPlugins } from '../../../kibana-services'; import { histogramChartInput } from './config/histogram-chart'; import { getWazuhCorePlugin } from '../../../kibana-services'; + const DashboardByRenderer = getPlugins().dashboard.DashboardContainerByValueRenderer; import './discover.scss'; @@ -124,11 +124,9 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { results, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, - pagination: { - pageIndex: 0, - pageSize: 15, - pageSizeOptions: [15, 25, 50, 100], - }, + useDefaultPagination: true, + filters, + setFilters, }); const { pagination, sorting, columnVisibility } = dataGridProps; diff --git a/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx b/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx index 64e9081100..2cda96f4fd 100644 --- a/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx +++ b/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx @@ -32,8 +32,6 @@ import { } from '../../../common/data-grid/data-grid-service'; import { useDocViewer } from '../../../common/doc-viewer/use-doc-viewer'; import { useDataGrid } from '../../../common/data-grid/use-data-grid'; -import { HitsCounter } from '../../../../kibana-integrations/discover/application/components/hits_counter/hits_counter'; -import { formatNumWithCommas } from '../../../../kibana-integrations/discover/application/helpers/format_number_with_commas'; import DocViewer from '../../../common/doc-viewer/doc-viewer'; import { withErrorBoundary } from '../../../common/hocs/error-boundary/with-error-boundary'; import './threat_hunting_dashboard.scss'; @@ -120,15 +118,17 @@ const DashboardTH: React.FC = () => { defaultColumns: threatHuntingTableDefaultColumns, renderColumns: wzDiscoverRenderColumns, results, - indexPattern: dataSource?.indexPattern, + indexPattern: dataSource?.indexPattern as IndexPattern, DocViewInspectButton, + filters, + setFilters, }); const { pagination, sorting, columnVisibility } = dataGridProps; const docViewerProps = useDocViewer({ doc: inspectedHit, - indexPattern: dataSource?.indexPattern, + indexPattern: dataSource?.indexPattern as IndexPattern, }); const pinnedAgent = @@ -145,7 +145,7 @@ const DashboardTH: React.FC = () => { useReportingCommunicateSearchContext({ isSearching: isDataSourceLoading, totalResults: results?.hits?.total ?? 0, - indexPattern: dataSource?.indexPattern, + indexPattern: dataSource?.indexPattern as IndexPattern, filters: fetchFilters, query: query, time: absoluteDateRange, diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx index 8b8b9fd247..377438dc3e 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx @@ -111,6 +111,8 @@ const InventoryVulsComponent = () => { results, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, + filters, + setFilters, }); const { pagination, sorting, columnVisibility } = dataGridProps; diff --git a/plugins/main/tsconfig.json b/plugins/main/tsconfig.json new file mode 100644 index 0000000000..63e20a2cf0 --- /dev/null +++ b/plugins/main/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.json", + "include": ["./**/*"] +}