mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.9`: - [[RAM] Alert table all column fix 2 (#161054)](https://github.com/elastic/kibana/pull/161054) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Xavier Mouligneau","email":"xavier.mouligneau@elastic.co"},"sourceCommit":{"committedDate":"2023-07-07T15:57:22Z","message":"[RAM] Alert table all column fix 2 (#161054)\n\nhttps://github.com/elastic/kibana/pull/160455\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"bed184b8299e6e859ce1f3b8443361d181ed43b6","branchLabelMapping":{"^v8.10.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","Team:ResponseOps","ci:all-cypress-suites","v8.9.0","v8.10.0","v8.8.3"],"number":161054,"url":"https://github.com/elastic/kibana/pull/161054","mergeCommit":{"message":"[RAM] Alert table all column fix 2 (#161054)\n\nhttps://github.com/elastic/kibana/pull/160455\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"bed184b8299e6e859ce1f3b8443361d181ed43b6"}},"sourceBranch":"main","suggestedTargetBranches":["8.9","8.8"],"targetPullRequestStates":[{"branch":"8.9","label":"v8.9.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.10.0","labelRegex":"^v8.10.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/161054","number":161054,"mergeCommit":{"message":"[RAM] Alert table all column fix 2 (#161054)\n\nhttps://github.com/elastic/kibana/pull/160455\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"bed184b8299e6e859ce1f3b8443361d181ed43b6"}},{"branch":"8.8","label":"v8.8.3","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>
This commit is contained in:
parent
40d06d1c4e
commit
1a0df226cc
12 changed files with 256 additions and 169 deletions
|
@ -66,6 +66,7 @@ const uploadPipeline = (pipelineContent: string | object) => {
|
|||
/^x-pack\/plugins\/security_solution/,
|
||||
/^x-pack\/plugins\/timelines/,
|
||||
/^x-pack\/plugins\/triggers_actions_ui\/public\/application\/sections\/action_connector_form/,
|
||||
/^x-pack\/plugins\/triggers_actions_ui\/public\/application\/sections\/alerts_table/,
|
||||
/^x-pack\/plugins\/triggers_actions_ui\/public\/application\/context\/actions_connectors_context\.tsx/,
|
||||
/^x-pack\/test\/defend_workflows_cypress/,
|
||||
/^x-pack\/test\/security_solution_cypress/,
|
||||
|
|
|
@ -140,6 +140,7 @@ def functionalXpack(Map params = [:]) {
|
|||
'x-pack/test/security_solution_cypress/',
|
||||
'x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/',
|
||||
'x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx',
|
||||
'x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/',
|
||||
]) {
|
||||
if (githubPr.isPr()) {
|
||||
task(kibanaPipeline.functionalTestProcess('xpack-securitySolutionCypressChrome', './test/scripts/jenkins_security_solution_cypress_chrome.sh'))
|
||||
|
|
|
@ -1261,66 +1261,17 @@ describe('SiemLocalStorage', () => {
|
|||
],
|
||||
sort: [{ '@timestamp': { order: 'desc' } }],
|
||||
visibleColumns: [
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: '@timestamp',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Rule',
|
||||
id: 'kibana.alert.rule.name',
|
||||
initialWidth: 180,
|
||||
linkField: 'kibana.alert.rule.uuid',
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Severity',
|
||||
id: 'kibana.alert.severity',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Risk Score',
|
||||
id: 'kibana.alert.risk_score',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Reason',
|
||||
id: 'kibana.alert.reason',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'host.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'user.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'process.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'file.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'source.ip',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'destination.ip',
|
||||
initialWidth: 180,
|
||||
},
|
||||
'@timestamp',
|
||||
'kibana.alert.rule.name',
|
||||
'kibana.alert.severity',
|
||||
'kibana.alert.risk_score',
|
||||
'kibana.alert.reason',
|
||||
'host.name',
|
||||
'user.name',
|
||||
'process.name',
|
||||
'file.name',
|
||||
'source.ip',
|
||||
'destination.ip',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -1393,66 +1344,17 @@ describe('SiemLocalStorage', () => {
|
|||
{ 'kibana.alert.rule.name': { order: 'desc' } },
|
||||
],
|
||||
visibleColumns: [
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: '@timestamp',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Rule',
|
||||
id: 'kibana.alert.rule.name',
|
||||
initialWidth: 180,
|
||||
linkField: 'kibana.alert.rule.uuid',
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Severity',
|
||||
id: 'kibana.alert.severity',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Risk Score',
|
||||
id: 'kibana.alert.risk_score',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: 'Reason',
|
||||
id: 'kibana.alert.reason',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'host.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'user.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'process.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'file.name',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'source.ip',
|
||||
initialWidth: 180,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
id: 'destination.ip',
|
||||
initialWidth: 180,
|
||||
},
|
||||
'@timestamp',
|
||||
'kibana.alert.rule.name',
|
||||
'kibana.alert.severity',
|
||||
'kibana.alert.risk_score',
|
||||
'kibana.alert.reason',
|
||||
'host.name',
|
||||
'user.name',
|
||||
'process.name',
|
||||
'file.name',
|
||||
'source.ip',
|
||||
'destination.ip',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -100,7 +100,7 @@ export const migrateAlertTableStateToTriggerActionsState = (
|
|||
sort: legacyDataTableState[tableKey].sort.map((sortCandidate) => ({
|
||||
[sortCandidate.columnId]: { order: sortCandidate.sortDirection },
|
||||
})),
|
||||
visibleColumns: legacyDataTableState[tableKey].columns,
|
||||
visibleColumns: legacyDataTableState[tableKey].columns.map((c) => c.id),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -110,6 +110,7 @@ export const migrateAlertTableStateToTriggerActionsState = (
|
|||
storage.set(key, stateObj[key]);
|
||||
})
|
||||
);
|
||||
return Object.assign(legacyDataTableState, triggersActionsState);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -154,7 +155,7 @@ export const getDataTablesInStorageByIds = (storage: Storage, tableIds: TableIdL
|
|||
}
|
||||
}
|
||||
|
||||
migrateAlertTableStateToTriggerActionsState(storage, allDataTables);
|
||||
allDataTables = migrateAlertTableStateToTriggerActionsState(storage, allDataTables);
|
||||
|
||||
return tableIds.reduce((acc, tableId) => {
|
||||
const tableModel = allDataTables[tableId];
|
||||
|
|
|
@ -329,7 +329,6 @@ describe('AlertsTable', () => {
|
|||
updatedAt: Date.now(),
|
||||
onToggleColumn: () => {},
|
||||
onResetColumns: () => {},
|
||||
onColumnsChange: () => {},
|
||||
onChangeVisibleColumns: () => {},
|
||||
browserFields,
|
||||
query: {},
|
||||
|
|
|
@ -142,6 +142,7 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab
|
|||
updatedAt,
|
||||
browserFields,
|
||||
onChangeVisibleColumns,
|
||||
onColumnResize,
|
||||
showAlertStatusWithFlapping = false,
|
||||
showInspectButton = false,
|
||||
} = props;
|
||||
|
@ -486,6 +487,7 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab
|
|||
onChangePage: onChangePageIndex,
|
||||
}}
|
||||
rowHeightsOptions={props.rowHeightsOptions}
|
||||
onColumnResize={onColumnResize}
|
||||
ref={dataGridRef}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -761,9 +761,15 @@ describe('AlertsTableState', () => {
|
|||
storageMock.mockImplementation(() => ({
|
||||
get: () => {
|
||||
return {
|
||||
columns: [{ displayAsText: 'Reason', id: 'kibana.alert.reason', schema: undefined }],
|
||||
sort: [],
|
||||
visibleColumns: ['kibana.alert.reason'],
|
||||
columns: [{ displayAsText: 'Reason', id: AlertsField.reason, schema: undefined }],
|
||||
sort: [
|
||||
{
|
||||
[AlertsField.reason]: {
|
||||
order: 'asc',
|
||||
},
|
||||
},
|
||||
],
|
||||
visibleColumns: [AlertsField.reason],
|
||||
};
|
||||
},
|
||||
set: jest.fn(),
|
||||
|
@ -779,11 +785,11 @@ describe('AlertsTableState', () => {
|
|||
|
||||
await waitFor(() => {
|
||||
expect(queryByTestId(`dataGridHeaderCell-${AlertsField.name}`)).not.toBe(null);
|
||||
expect(
|
||||
getByTestId('dataGridHeader')
|
||||
.querySelectorAll('.euiDataGridHeaderCell__content')[1]
|
||||
.getAttribute('title')
|
||||
).toBe('Name');
|
||||
const titles: string[] = [];
|
||||
getByTestId('dataGridHeader')
|
||||
.querySelectorAll('.euiDataGridHeaderCell__content')
|
||||
.forEach((n) => titles.push(n?.getAttribute('title') ?? ''));
|
||||
expect(titles).toContain('Name');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -219,13 +219,13 @@ const AlertsTableStateWithQueryProvider = ({
|
|||
|
||||
const {
|
||||
columns,
|
||||
onColumnsChange,
|
||||
browserFields,
|
||||
isBrowserFieldDataLoading,
|
||||
onToggleColumn,
|
||||
onResetColumns,
|
||||
visibleColumns,
|
||||
onChangeVisibleColumns,
|
||||
onColumnResize,
|
||||
fields,
|
||||
} = useColumns({
|
||||
featureIds,
|
||||
|
@ -393,8 +393,8 @@ const AlertsTableStateWithQueryProvider = ({
|
|||
browserFields,
|
||||
onToggleColumn,
|
||||
onResetColumns,
|
||||
onColumnsChange,
|
||||
onChangeVisibleColumns,
|
||||
onColumnResize,
|
||||
query,
|
||||
rowHeightsOptions,
|
||||
renderCellValue,
|
||||
|
@ -410,7 +410,7 @@ const AlertsTableStateWithQueryProvider = ({
|
|||
memoizedMaintenanceWindows,
|
||||
columns,
|
||||
flyoutSize,
|
||||
pagination,
|
||||
pagination.pageSize,
|
||||
id,
|
||||
leadingControlColumns,
|
||||
showExpandToDetails,
|
||||
|
@ -421,8 +421,8 @@ const AlertsTableStateWithQueryProvider = ({
|
|||
browserFields,
|
||||
onToggleColumn,
|
||||
onResetColumns,
|
||||
onColumnsChange,
|
||||
onChangeVisibleColumns,
|
||||
onColumnResize,
|
||||
query,
|
||||
rowHeightsOptions,
|
||||
renderCellValue,
|
||||
|
|
|
@ -171,7 +171,6 @@ describe('AlertsTable.BulkActions', () => {
|
|||
updatedAt: Date.now(),
|
||||
onToggleColumn: () => {},
|
||||
onResetColumns: () => {},
|
||||
onColumnsChange: () => {},
|
||||
onChangeVisibleColumns: () => {},
|
||||
browserFields: {},
|
||||
query: {},
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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 { EuiDataGridColumn } from '@elastic/eui';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import { act, renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { useColumns, UseColumnsArgs, UseColumnsResp } from './use_columns';
|
||||
|
||||
jest.mock('../../../../../common/lib/kibana');
|
||||
|
||||
const setItemStorageMock = jest.fn();
|
||||
const mockStorage = {
|
||||
getItem: jest.fn(),
|
||||
setItem: setItemStorageMock,
|
||||
removeItem: jest.fn(),
|
||||
clear: jest.fn(),
|
||||
};
|
||||
|
||||
describe('useColumn', () => {
|
||||
const id = 'useColumnTest';
|
||||
const featureIds: AlertConsumers[] = [AlertConsumers.LOGS, AlertConsumers.APM];
|
||||
let storage = { current: new Storage(mockStorage) };
|
||||
const storageAlertsTable = {
|
||||
current: {
|
||||
columns: [],
|
||||
visibleColumns: [],
|
||||
sort: [],
|
||||
},
|
||||
};
|
||||
const defaultColumns: EuiDataGridColumn[] = [
|
||||
{
|
||||
id: 'event.action',
|
||||
displayAsText: 'Alert status',
|
||||
initialWidth: 150,
|
||||
},
|
||||
{
|
||||
id: '@timestamp',
|
||||
displayAsText: 'Last updated',
|
||||
initialWidth: 250,
|
||||
schema: 'datetime',
|
||||
},
|
||||
{
|
||||
id: 'kibana.alert.duration.us',
|
||||
displayAsText: 'Duration',
|
||||
initialWidth: 150,
|
||||
schema: 'numeric',
|
||||
},
|
||||
{
|
||||
id: 'kibana.alert.reason',
|
||||
displayAsText: 'Reason',
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
setItemStorageMock.mockClear();
|
||||
storage = { current: new Storage(mockStorage) };
|
||||
});
|
||||
|
||||
test('hide all columns with onChangeVisibleColumns', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook<UseColumnsArgs, UseColumnsResp>(() =>
|
||||
useColumns({ defaultColumns, featureIds, id, storageAlertsTable, storage })
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.onChangeVisibleColumns([]);
|
||||
});
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.visibleColumns).toEqual([]);
|
||||
expect(result.current.columns).toEqual(defaultColumns);
|
||||
});
|
||||
|
||||
test('show all columns with onChangeVisibleColumns', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook<UseColumnsArgs, UseColumnsResp>(() =>
|
||||
useColumns({ defaultColumns, featureIds, id, storageAlertsTable, storage })
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.onChangeVisibleColumns([]);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
result.current.onChangeVisibleColumns(defaultColumns.map((dc) => dc.id));
|
||||
});
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.visibleColumns).toEqual([
|
||||
'event.action',
|
||||
'@timestamp',
|
||||
'kibana.alert.duration.us',
|
||||
'kibana.alert.reason',
|
||||
]);
|
||||
expect(result.current.columns).toEqual(defaultColumns);
|
||||
});
|
||||
|
||||
test('onColumnResize', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook<UseColumnsArgs, UseColumnsResp>(() =>
|
||||
useColumns({ defaultColumns, featureIds, id, storageAlertsTable, storage })
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.onColumnResize({ columnId: '@timestamp', width: 100 });
|
||||
});
|
||||
|
||||
await waitForNextUpdate();
|
||||
expect(setItemStorageMock).toHaveBeenCalledWith(
|
||||
'useColumnTest',
|
||||
'{"columns":[{"id":"event.action","displayAsText":"Alert status","initialWidth":150},{"id":"@timestamp","displayAsText":"Last updated","initialWidth":100,"schema":"datetime"},{"id":"kibana.alert.duration.us","displayAsText":"Duration","initialWidth":150,"schema":"numeric"},{"id":"kibana.alert.reason","displayAsText":"Reason"}],"visibleColumns":["event.action","@timestamp","kibana.alert.duration.us","kibana.alert.reason"],"sort":[]}'
|
||||
);
|
||||
expect(result.current.columns.find((c) => c.id === '@timestamp')).toEqual({
|
||||
displayAsText: 'Last updated',
|
||||
id: '@timestamp',
|
||||
initialWidth: 100,
|
||||
schema: 'datetime',
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiDataGridColumn } from '@elastic/eui';
|
||||
import { EuiDataGridColumn, EuiDataGridOnColumnResizeData } from '@elastic/eui';
|
||||
import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public';
|
||||
import { BrowserField, BrowserFields } from '@kbn/rule-registry-plugin/common';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
@ -15,7 +15,7 @@ import { AlertsTableStorage } from '../../alerts_table_state';
|
|||
import { toggleColumn } from './toggle_column';
|
||||
import { useFetchBrowserFieldCapabilities } from '../use_fetch_browser_fields_capabilities';
|
||||
|
||||
interface UseColumnsArgs {
|
||||
export interface UseColumnsArgs {
|
||||
featureIds: AlertConsumers[];
|
||||
storageAlertsTable: React.MutableRefObject<AlertsTableStorage>;
|
||||
storage: React.MutableRefObject<IStorageWrapper>;
|
||||
|
@ -24,6 +24,21 @@ interface UseColumnsArgs {
|
|||
initialBrowserFields?: BrowserFields;
|
||||
}
|
||||
|
||||
export interface UseColumnsResp {
|
||||
columns: EuiDataGridColumn[];
|
||||
visibleColumns: string[];
|
||||
isBrowserFieldDataLoading: boolean | undefined;
|
||||
browserFields: BrowserFields;
|
||||
onToggleColumn: (columnId: string) => void;
|
||||
onResetColumns: () => void;
|
||||
onChangeVisibleColumns: (columnIds: string[]) => void;
|
||||
onColumnResize: (args: EuiDataGridOnColumnResizeData) => void;
|
||||
fields: Array<{
|
||||
field: string;
|
||||
include_unmapped: boolean;
|
||||
}>;
|
||||
}
|
||||
|
||||
const EMPTY_FIELDS = [{ field: '*', include_unmapped: true }];
|
||||
|
||||
const fieldTypeToDataGridColumnTypeMapper = (fieldType: string | undefined) => {
|
||||
|
@ -114,26 +129,23 @@ const getColumnByColumnId = (columns: EuiDataGridColumn[], columnId: string) =>
|
|||
return columns.find(({ id }: { id: string }) => id === columnId);
|
||||
};
|
||||
|
||||
const getColumnsByColumnIds = (columns: EuiDataGridColumn[], columnIds: string[]) => {
|
||||
return columnIds
|
||||
.map((columnId: string) => columns.find((column: EuiDataGridColumn) => column.id === columnId))
|
||||
.filter(Boolean) as EuiDataGridColumn[];
|
||||
};
|
||||
|
||||
const persist = ({
|
||||
id,
|
||||
storageAlertsTable,
|
||||
columns,
|
||||
storage,
|
||||
visibleColumns,
|
||||
}: {
|
||||
id: string;
|
||||
storageAlertsTable: React.MutableRefObject<AlertsTableStorage>;
|
||||
storage: React.MutableRefObject<IStorageWrapper>;
|
||||
columns: EuiDataGridColumn[];
|
||||
visibleColumns: string[];
|
||||
}) => {
|
||||
storageAlertsTable.current = {
|
||||
...storageAlertsTable.current,
|
||||
columns,
|
||||
visibleColumns,
|
||||
};
|
||||
storage.current.set(id, storageAlertsTable.current);
|
||||
};
|
||||
|
@ -145,7 +157,7 @@ export const useColumns = ({
|
|||
id,
|
||||
defaultColumns,
|
||||
initialBrowserFields,
|
||||
}: UseColumnsArgs) => {
|
||||
}: UseColumnsArgs): UseColumnsResp => {
|
||||
const [isBrowserFieldDataLoading, browserFields] = useFetchBrowserFieldCapabilities({
|
||||
featureIds,
|
||||
initialBrowserFields,
|
||||
|
@ -156,10 +168,16 @@ export const useColumns = ({
|
|||
// before restoring from storage, enrich the column data
|
||||
if (initialBrowserFields && defaultColumns) {
|
||||
cols = populateColumns(cols, initialBrowserFields, defaultColumns);
|
||||
} else if (cols && cols.length === 0) {
|
||||
cols = defaultColumns;
|
||||
}
|
||||
return cols;
|
||||
});
|
||||
|
||||
const [visibleColumns, setVisibleColumns] = useState(
|
||||
storageAlertsTable.current.visibleColumns ?? getColumnIds(columns)
|
||||
);
|
||||
|
||||
const [isColumnsPopulated, setColumnsPopulated] = useState<boolean>(false);
|
||||
|
||||
const defaultColumnsRef = useRef<typeof defaultColumns>(defaultColumns);
|
||||
|
@ -190,13 +208,14 @@ export const useColumns = ({
|
|||
}, [browserFields, defaultColumns, isBrowserFieldDataLoading, isColumnsPopulated, columns]);
|
||||
|
||||
const setColumnsAndSave = useCallback(
|
||||
(newColumns: EuiDataGridColumn[]) => {
|
||||
(newColumns: EuiDataGridColumn[], newVisibleColumns: string[]) => {
|
||||
setColumns(newColumns);
|
||||
persist({
|
||||
id,
|
||||
storage,
|
||||
storageAlertsTable,
|
||||
columns: newColumns,
|
||||
visibleColumns: newVisibleColumns,
|
||||
});
|
||||
},
|
||||
[id, storage, storageAlertsTable]
|
||||
|
@ -204,10 +223,16 @@ export const useColumns = ({
|
|||
|
||||
const setColumnsByColumnIds = useCallback(
|
||||
(columnIds: string[]) => {
|
||||
const newColumns = getColumnsByColumnIds(columns, columnIds);
|
||||
setColumnsAndSave(newColumns);
|
||||
setVisibleColumns(columnIds);
|
||||
persist({
|
||||
id,
|
||||
storage,
|
||||
storageAlertsTable,
|
||||
columns,
|
||||
visibleColumns: columnIds,
|
||||
});
|
||||
},
|
||||
[setColumnsAndSave, columns]
|
||||
[columns, id, storage, storageAlertsTable]
|
||||
);
|
||||
|
||||
const onToggleColumn = useCallback(
|
||||
|
@ -219,17 +244,37 @@ export const useColumns = ({
|
|||
columns,
|
||||
defaultColumns,
|
||||
});
|
||||
|
||||
setColumnsAndSave(newColumns);
|
||||
let newVisibleColumns = visibleColumns;
|
||||
if (visibleColumns.includes(columnId)) {
|
||||
newVisibleColumns = visibleColumns.filter((vc) => vc !== columnId);
|
||||
} else {
|
||||
newVisibleColumns = [visibleColumns[0], columnId, ...visibleColumns.slice(1)];
|
||||
}
|
||||
setVisibleColumns(newVisibleColumns);
|
||||
setColumnsAndSave(newColumns, newVisibleColumns);
|
||||
},
|
||||
[browserFields, columns, defaultColumns, setColumnsAndSave]
|
||||
[browserFields, columns, defaultColumns, setColumnsAndSave, visibleColumns]
|
||||
);
|
||||
|
||||
const onResetColumns = useCallback(() => {
|
||||
const populatedDefaultColumns = populateColumns(defaultColumns, browserFields, defaultColumns);
|
||||
setColumnsAndSave(populatedDefaultColumns);
|
||||
setColumnsAndSave(
|
||||
populatedDefaultColumns,
|
||||
populatedDefaultColumns.map((pdc) => pdc.id)
|
||||
);
|
||||
}, [browserFields, defaultColumns, setColumnsAndSave]);
|
||||
|
||||
const onColumnResize = useCallback(
|
||||
({ columnId, width }: EuiDataGridOnColumnResizeData) => {
|
||||
const colIndex = columns.findIndex((c) => c.id === columnId);
|
||||
if (colIndex > -1) {
|
||||
columns.splice(colIndex, 1, { ...columns[colIndex], initialWidth: width });
|
||||
setColumnsAndSave(columns, visibleColumns);
|
||||
}
|
||||
},
|
||||
[columns, setColumnsAndSave, visibleColumns]
|
||||
);
|
||||
|
||||
/*
|
||||
* In some case such security, we need some special fields such as threat.enrichments which are
|
||||
* not fetched when passing only EMPTY_FIELDS. Hence, we will fetch all the fields that user has added to the table.
|
||||
|
@ -243,19 +288,28 @@ export const useColumns = ({
|
|||
[columns]
|
||||
);
|
||||
|
||||
const visibleColumns = useMemo(() => {
|
||||
return getColumnIds(columns);
|
||||
}, [columns]);
|
||||
|
||||
return {
|
||||
columns,
|
||||
visibleColumns,
|
||||
isBrowserFieldDataLoading,
|
||||
browserFields,
|
||||
onColumnsChange: setColumnsAndSave,
|
||||
onToggleColumn,
|
||||
onResetColumns,
|
||||
onChangeVisibleColumns: setColumnsByColumnIds,
|
||||
fields: fieldsToFetch,
|
||||
};
|
||||
return useMemo(
|
||||
() => ({
|
||||
columns,
|
||||
visibleColumns,
|
||||
isBrowserFieldDataLoading,
|
||||
browserFields,
|
||||
onToggleColumn,
|
||||
onResetColumns,
|
||||
onChangeVisibleColumns: setColumnsByColumnIds,
|
||||
onColumnResize,
|
||||
fields: fieldsToFetch,
|
||||
}),
|
||||
[
|
||||
browserFields,
|
||||
columns,
|
||||
fieldsToFetch,
|
||||
isBrowserFieldDataLoading,
|
||||
onColumnResize,
|
||||
onResetColumns,
|
||||
onToggleColumn,
|
||||
setColumnsByColumnIds,
|
||||
visibleColumns,
|
||||
]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ import type {
|
|||
EuiDataGridColumnCellAction,
|
||||
EuiDataGridToolBarVisibilityOptions,
|
||||
EuiSuperSelectOption,
|
||||
EuiDataGridOnColumnResizeHandler,
|
||||
} from '@elastic/eui';
|
||||
import { EuiDataGridColumn, EuiDataGridControlColumn, EuiDataGridSorting } from '@elastic/eui';
|
||||
import { HttpSetup } from '@kbn/core/public';
|
||||
|
@ -536,8 +537,8 @@ export type AlertsTableProps = {
|
|||
browserFields: any;
|
||||
onToggleColumn: (columnId: string) => void;
|
||||
onResetColumns: () => void;
|
||||
onColumnsChange: (columns: EuiDataGridColumn[], visibleColumns: string[]) => void;
|
||||
onChangeVisibleColumns: (newColumns: string[]) => void;
|
||||
onColumnResize?: EuiDataGridOnColumnResizeHandler;
|
||||
query: Pick<QueryDslQueryContainer, 'bool' | 'ids'>;
|
||||
controls?: EuiDataGridToolBarAdditionalControlsOptions;
|
||||
showInspectButton?: boolean;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue