mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[RAM] Bring back toggle column on alert table (#168158)
## Summary FIX -> https://github.com/elastic/kibana/issues/155243 ### Checklist - [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 --------- Co-authored-by: PhilippeOberti <philippe.oberti@elastic.co>
This commit is contained in:
parent
e9777f67bf
commit
44a9d283b2
26 changed files with 445 additions and 80 deletions
|
@ -21,7 +21,7 @@ import {
|
|||
TriggersAndActionsUIPublicPluginSetup,
|
||||
TriggersAndActionsUIPublicPluginStart,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { TypeRegistry } from '@kbn/triggers-actions-ui-plugin/public/application/type_registry';
|
||||
import { AlertTableConfigRegistry } from '@kbn/triggers-actions-ui-plugin/public/application/alert_table_config_registry';
|
||||
import {
|
||||
AlertsTableConfigurationRegistry,
|
||||
AlertsTableFlyoutBaseProps,
|
||||
|
@ -81,8 +81,7 @@ export class TriggersActionsUiExamplePlugin
|
|||
) {
|
||||
const {
|
||||
alertsTableConfigurationRegistry,
|
||||
}: { alertsTableConfigurationRegistry: TypeRegistry<AlertsTableConfigurationRegistry> } =
|
||||
triggersActionsUi;
|
||||
}: { alertsTableConfigurationRegistry: AlertTableConfigRegistry } = triggersActionsUi;
|
||||
|
||||
const columns: EuiDataGridColumn[] = [
|
||||
{
|
||||
|
|
|
@ -107,7 +107,7 @@ const registerCellActions = (
|
|||
investigateInNewTimeline: createInvestigateInNewTimelineCellActionFactory({ store, services }),
|
||||
showTopN: createShowTopNCellActionFactory({ services }),
|
||||
copyToClipboard: createCopyToClipboardCellActionFactory({ services }),
|
||||
toggleColumn: createToggleColumnCellActionFactory({ store }),
|
||||
toggleColumn: createToggleColumnCellActionFactory({ store, services }),
|
||||
};
|
||||
|
||||
const registerCellActionsTrigger = (
|
||||
|
|
|
@ -7,10 +7,19 @@
|
|||
|
||||
import type { SecurityAppStore } from '../../../common/store/types';
|
||||
import { TableId, dataTableActions } from '@kbn/securitysolution-data-table';
|
||||
import { createToggleColumnCellActionFactory } from './toggle_column';
|
||||
|
||||
import type { CellActionExecutionContext } from '@kbn/cell-actions';
|
||||
|
||||
import { createToggleColumnCellActionFactory } from './toggle_column';
|
||||
import { mockGlobalState } from '../../../common/mock';
|
||||
import { createStartServicesMock } from '../../../common/lib/kibana/kibana_react.mock';
|
||||
|
||||
const services = createStartServicesMock();
|
||||
const mockAlertConfigGetActions = jest.fn();
|
||||
services.triggersActionsUi.alertsTableConfigurationRegistry.getActions = mockAlertConfigGetActions;
|
||||
const mockToggleColumn = jest.fn();
|
||||
mockAlertConfigGetActions.mockImplementation(() => ({
|
||||
toggleColumn: mockToggleColumn,
|
||||
}));
|
||||
|
||||
const mockDispatch = jest.fn();
|
||||
const mockGetState = jest.fn().mockReturnValue(mockGlobalState);
|
||||
|
@ -34,7 +43,7 @@ const context = {
|
|||
} as unknown as CellActionExecutionContext;
|
||||
|
||||
describe('createToggleColumnCellActionFactory', () => {
|
||||
const toggleColumnActionFactory = createToggleColumnCellActionFactory({ store });
|
||||
const toggleColumnActionFactory = createToggleColumnCellActionFactory({ store, services });
|
||||
const toggleColumnAction = toggleColumnActionFactory({ id: 'testAction' });
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -71,6 +80,10 @@ describe('createToggleColumnCellActionFactory', () => {
|
|||
});
|
||||
|
||||
describe('execute', () => {
|
||||
afterEach(() => {
|
||||
mockToggleColumn.mockClear();
|
||||
mockAlertConfigGetActions.mockClear();
|
||||
});
|
||||
it('should remove column', async () => {
|
||||
await toggleColumnAction.execute(context);
|
||||
expect(mockDispatch).toHaveBeenCalledWith(
|
||||
|
@ -99,5 +112,29 @@ describe('createToggleColumnCellActionFactory', () => {
|
|||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should call triggersActionsUi.alertsTableConfigurationRegistry to add a column in alert', async () => {
|
||||
const name = 'fake-field-name';
|
||||
await toggleColumnAction.execute({
|
||||
...context,
|
||||
data: [{ ...context.data[0], field: { ...context.data[0].field, name } }],
|
||||
metadata: {
|
||||
scopeId: TableId.alertsOnAlertsPage,
|
||||
},
|
||||
});
|
||||
expect(mockAlertConfigGetActions).toHaveBeenCalledWith('securitySolution-alerts-page');
|
||||
expect(mockToggleColumn).toHaveBeenCalledWith(name);
|
||||
});
|
||||
|
||||
it('should call triggersActionsUi.alertsTableConfigurationRegistry to remove a column in alert', async () => {
|
||||
await toggleColumnAction.execute({
|
||||
...context,
|
||||
metadata: {
|
||||
scopeId: TableId.alertsOnAlertsPage,
|
||||
},
|
||||
});
|
||||
expect(mockAlertConfigGetActions).toHaveBeenCalledWith('securitySolution-alerts-page');
|
||||
expect(mockToggleColumn).toHaveBeenCalledWith(fieldName);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,6 +20,8 @@ import { timelineSelectors } from '../../../timelines/store/timeline';
|
|||
import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants';
|
||||
import type { SecurityCellAction } from '../../types';
|
||||
import { SecurityCellActionType } from '../../constants';
|
||||
import type { StartServices } from '../../../types';
|
||||
import { getAlertConfigIdByScopeId } from '../../../common/lib/triggers_actions_ui/alert_table_scope_config';
|
||||
|
||||
const ICON = 'listAdd';
|
||||
const COLUMN_TOGGLE = i18n.translate('xpack.securitySolution.actions.toggleColumnToggle.label', {
|
||||
|
@ -33,7 +35,13 @@ const NESTED_COLUMN = (field: string) =>
|
|||
});
|
||||
|
||||
export const createToggleColumnCellActionFactory = createCellActionFactory(
|
||||
({ store }: { store: SecurityAppStore }): CellActionTemplate<SecurityCellAction> => ({
|
||||
({
|
||||
store,
|
||||
services,
|
||||
}: {
|
||||
store: SecurityAppStore;
|
||||
services: StartServices;
|
||||
}): CellActionTemplate<SecurityCellAction> => ({
|
||||
type: SecurityCellActionType.TOGGLE_COLUMN,
|
||||
getIconType: () => ICON,
|
||||
getDisplayName: () => COLUMN_TOGGLE,
|
||||
|
@ -60,6 +68,14 @@ export const createToggleColumnCellActionFactory = createCellActionFactory(
|
|||
return;
|
||||
}
|
||||
|
||||
const alertTableConfigurationId = getAlertConfigIdByScopeId(scopeId);
|
||||
if (alertTableConfigurationId) {
|
||||
services.triggersActionsUi.alertsTableConfigurationRegistry
|
||||
.getActions(alertTableConfigurationId)
|
||||
.toggleColumn(field.name);
|
||||
return;
|
||||
}
|
||||
|
||||
const selector = isTimelineScope(scopeId)
|
||||
? timelineSelectors.getTimelineByIdSelector()
|
||||
: dataTableSelectors.getTableByIdSelector();
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 { TableId } from '@kbn/securitysolution-data-table';
|
||||
import { ALERTS_TABLE_REGISTRY_CONFIG_IDS } from '../../../../common/constants';
|
||||
import { getAlertConfigIdByScopeId } from './alert_table_scope_config';
|
||||
|
||||
describe('getAlertConfigIdByScopeId', () => {
|
||||
it('should return an alert configuration ID when the scope is valid', async () => {
|
||||
expect(getAlertConfigIdByScopeId(TableId.alertsOnAlertsPage)).toEqual(
|
||||
ALERTS_TABLE_REGISTRY_CONFIG_IDS.ALERTS_PAGE
|
||||
);
|
||||
expect(getAlertConfigIdByScopeId(TableId.alertsOnRuleDetailsPage)).toEqual(
|
||||
ALERTS_TABLE_REGISTRY_CONFIG_IDS.RULE_DETAILS
|
||||
);
|
||||
expect(getAlertConfigIdByScopeId(TableId.alertsOnCasePage)).toEqual(
|
||||
ALERTS_TABLE_REGISTRY_CONFIG_IDS.CASE
|
||||
);
|
||||
expect(getAlertConfigIdByScopeId(TableId.alertsRiskInputs)).toEqual(
|
||||
ALERTS_TABLE_REGISTRY_CONFIG_IDS.RISK_INPUTS
|
||||
);
|
||||
});
|
||||
|
||||
it('should return undefined when the scope is NOT valid', async () => {
|
||||
expect(getAlertConfigIdByScopeId(TableId.test)).toEqual(undefined);
|
||||
expect(getAlertConfigIdByScopeId('hereWeGo')).toEqual(undefined);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 { TableId } from '@kbn/securitysolution-data-table';
|
||||
import { ALERTS_TABLE_REGISTRY_CONFIG_IDS } from '../../../../common/constants';
|
||||
|
||||
type PickKey<T, K extends keyof T> = Extract<keyof T, K>;
|
||||
type KeysAlertTableId = PickKey<
|
||||
typeof TableId,
|
||||
'alertsOnAlertsPage' | 'alertsOnRuleDetailsPage' | 'alertsOnCasePage' | 'alertsRiskInputs'
|
||||
>;
|
||||
|
||||
type ValuesAlertTableId = typeof TableId[KeysAlertTableId];
|
||||
|
||||
type KeysAlertTableConfiguration = keyof typeof ALERTS_TABLE_REGISTRY_CONFIG_IDS;
|
||||
type ValuesAlertTableConfiguration =
|
||||
typeof ALERTS_TABLE_REGISTRY_CONFIG_IDS[KeysAlertTableConfiguration];
|
||||
|
||||
const ScopeIdLinkToAlertTableConfiguration: Record<
|
||||
ValuesAlertTableId,
|
||||
ValuesAlertTableConfiguration
|
||||
> = {
|
||||
[TableId.alertsOnAlertsPage]: ALERTS_TABLE_REGISTRY_CONFIG_IDS.ALERTS_PAGE,
|
||||
[TableId.alertsOnRuleDetailsPage]: ALERTS_TABLE_REGISTRY_CONFIG_IDS.RULE_DETAILS,
|
||||
[TableId.alertsOnCasePage]: ALERTS_TABLE_REGISTRY_CONFIG_IDS.CASE,
|
||||
[TableId.alertsRiskInputs]: ALERTS_TABLE_REGISTRY_CONFIG_IDS.RISK_INPUTS,
|
||||
};
|
||||
|
||||
export const getAlertConfigIdByScopeId = (scopeId: string) => {
|
||||
if (ScopeIdLinkToAlertTableConfiguration[scopeId as ValuesAlertTableId]) {
|
||||
return ScopeIdLinkToAlertTableConfiguration[scopeId as ValuesAlertTableId];
|
||||
}
|
||||
return undefined;
|
||||
};
|
|
@ -141,8 +141,8 @@ export const HostDetails: React.FC<HostDetailsProps> = ({ hostName, timestamp, s
|
|||
value: user,
|
||||
}}
|
||||
mode={CellActionsMode.HOVER_RIGHT}
|
||||
triggerId={SecurityCellActionsTrigger.DEFAULT} // TODO use SecurityCellActionsTrigger.DETAILS_FLYOUT when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
visibleCellActions={5} // TODO use 6 when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
triggerId={SecurityCellActionsTrigger.DETAILS_FLYOUT}
|
||||
visibleCellActions={6}
|
||||
sourcererScopeId={getSourcererScopeId(scopeId)}
|
||||
metadata={{ scopeId }}
|
||||
showActionTooltips
|
||||
|
|
|
@ -142,8 +142,8 @@ export const UserDetails: React.FC<UserDetailsProps> = ({ userName, timestamp, s
|
|||
field: 'host.name',
|
||||
}}
|
||||
mode={CellActionsMode.HOVER_RIGHT}
|
||||
triggerId={SecurityCellActionsTrigger.DEFAULT} // TODO use SecurityCellActionsTrigger.DETAILS_FLYOUT when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
visibleCellActions={5} // TODO use 6 when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
triggerId={SecurityCellActionsTrigger.DETAILS_FLYOUT}
|
||||
visibleCellActions={6}
|
||||
sourcererScopeId={getSourcererScopeId(scopeId)}
|
||||
metadata={{ scopeId }}
|
||||
showActionTooltips
|
||||
|
|
|
@ -78,8 +78,8 @@ const columns: Array<EuiBasicTableColumn<HighlightedFieldsTableRow>> = [
|
|||
value: description.values,
|
||||
}}
|
||||
mode={CellActionsMode.HOVER_RIGHT}
|
||||
triggerId={SecurityCellActionsTrigger.DEFAULT} // TODO use SecurityCellActionsTrigger.DETAILS_FLYOUT when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
visibleCellActions={5} // TODO use 6 when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
triggerId={SecurityCellActionsTrigger.DETAILS_FLYOUT}
|
||||
visibleCellActions={6}
|
||||
sourcererScopeId={getSourcererScopeId(description.scopeId)}
|
||||
metadata={{ scopeId: description.scopeId }}
|
||||
>
|
||||
|
|
|
@ -61,8 +61,8 @@ export const DocumentSeverity: FC = memo(() => {
|
|||
value: alertSeverity,
|
||||
}}
|
||||
mode={CellActionsMode.HOVER_RIGHT}
|
||||
triggerId={SecurityCellActionsTrigger.DEFAULT} // TODO use SecurityCellActionsTrigger.DETAILS_FLYOUT when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
visibleCellActions={5} // TODO use 6 when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
triggerId={SecurityCellActionsTrigger.DETAILS_FLYOUT}
|
||||
visibleCellActions={6}
|
||||
sourcererScopeId={getSourcererScopeId(scopeId)}
|
||||
metadata={{ scopeId }}
|
||||
>
|
||||
|
|
|
@ -62,8 +62,8 @@ export const DocumentStatus: FC = () => {
|
|||
value: statusData.values[0],
|
||||
}}
|
||||
mode={CellActionsMode.HOVER_RIGHT}
|
||||
triggerId={SecurityCellActionsTrigger.DEFAULT} // TODO use SecurityCellActionsTrigger.DETAILS_FLYOUT when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
visibleCellActions={5} // TODO use 6 when https://github.com/elastic/kibana/issues/155243 is fixed
|
||||
triggerId={SecurityCellActionsTrigger.DETAILS_FLYOUT}
|
||||
visibleCellActions={6}
|
||||
sourcererScopeId={getSourcererScopeId(scopeId)}
|
||||
metadata={{ scopeId }}
|
||||
>
|
||||
|
|
|
@ -73,7 +73,7 @@ export const getColumns: ColumnsProvider = ({
|
|||
}}
|
||||
triggerId={SecurityCellActionsTrigger.DETAILS_FLYOUT}
|
||||
mode={CellActionsMode.HOVER_RIGHT}
|
||||
visibleCellActions={3}
|
||||
visibleCellActions={6}
|
||||
sourcererScopeId={getSourcererScopeId(scopeId)}
|
||||
metadata={{ scopeId, isObjectArray: data.isObjectArray }}
|
||||
>
|
||||
|
@ -96,7 +96,7 @@ export const getColumns: ColumnsProvider = ({
|
|||
* Table view displayed in the document details expandable flyout right section
|
||||
*/
|
||||
export const TableTab: FC = memo(() => {
|
||||
const { browserFields, dataFormattedForFieldBrowser, eventId } = useRightPanelContext();
|
||||
const { browserFields, dataFormattedForFieldBrowser, eventId, scopeId } = useRightPanelContext();
|
||||
|
||||
return (
|
||||
<EventFieldsBrowser
|
||||
|
@ -105,7 +105,7 @@ export const TableTab: FC = memo(() => {
|
|||
eventId={eventId}
|
||||
isDraggable={false}
|
||||
timelineTabType={TimelineTabs.query}
|
||||
scopeId={'alert-details-flyout'}
|
||||
scopeId={scopeId}
|
||||
isReadOnly={false}
|
||||
columnsProvider={getColumns}
|
||||
/>
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* 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 { AlertTableConfigRegistry } from './alert_table_config_registry';
|
||||
|
||||
export const ExpressionComponent: React.FunctionComponent = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const getTestAlertTableConfig = (id?: string, iconClass?: string) => {
|
||||
return {
|
||||
id: id || 'test-alert-table-config',
|
||||
columns: [],
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(() => jest.resetAllMocks());
|
||||
|
||||
describe('register()', () => {
|
||||
test('able to register alert table config', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
alertTableConfigRegistry.register(getTestAlertTableConfig());
|
||||
expect(alertTableConfigRegistry.has('test-alert-table-config')).toEqual(true);
|
||||
});
|
||||
|
||||
test('throws error if alert table config already registered', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
alertTableConfigRegistry.register(getTestAlertTableConfig('my-test-alert-type-1'));
|
||||
expect(() =>
|
||||
alertTableConfigRegistry.register(getTestAlertTableConfig('my-test-alert-type-1'))
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Object type \\"my-test-alert-type-1\\" is already registered."`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get()', () => {
|
||||
test('returns alert table config', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
alertTableConfigRegistry.register(getTestAlertTableConfig('my-action-type-snapshot'));
|
||||
const alertTableConfig = alertTableConfigRegistry.get('my-action-type-snapshot');
|
||||
expect(alertTableConfig).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"columns": Array [],
|
||||
"id": "my-action-type-snapshot",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(`throw error when alert table config doesn't exist`, () => {
|
||||
const actionTypeRegistry = new AlertTableConfigRegistry();
|
||||
expect(() =>
|
||||
actionTypeRegistry.get('not-exist-action-type')
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Object type \\"not-exist-action-type\\" is not registered."`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('list()', () => {
|
||||
test('returns list of alert table config', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
const alertTableConfig = getTestAlertTableConfig();
|
||||
alertTableConfigRegistry.register(alertTableConfig);
|
||||
const alertTableConfigList = alertTableConfigRegistry.list();
|
||||
expect(alertTableConfigList).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"columns": Array [],
|
||||
"id": "test-alert-table-config",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('has()', () => {
|
||||
test('returns false for unregistered alert table config', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
expect(alertTableConfigRegistry.has('my-alert-type')).toEqual(false);
|
||||
});
|
||||
|
||||
test('returns true after registering an alert table config', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
alertTableConfigRegistry.register(getTestAlertTableConfig());
|
||||
expect(alertTableConfigRegistry.has('test-alert-table-config'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('update()', () => {
|
||||
test('returns object after updating for alert table config register', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
alertTableConfigRegistry.register(getTestAlertTableConfig());
|
||||
const toggleColumn = (columnId: string) => {};
|
||||
const updateObj = alertTableConfigRegistry.update('test-alert-table-config', {
|
||||
...getTestAlertTableConfig(),
|
||||
actions: {
|
||||
toggleColumn,
|
||||
},
|
||||
});
|
||||
expect(updateObj).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"actions": Object {
|
||||
"toggleColumn": [Function],
|
||||
},
|
||||
"columns": Array [],
|
||||
"id": "test-alert-table-config",
|
||||
}
|
||||
`);
|
||||
expect(alertTableConfigRegistry.getActions('test-alert-table-config').toggleColumn).toEqual(
|
||||
toggleColumn
|
||||
);
|
||||
});
|
||||
|
||||
test('throw an error in alert table config is not registred', () => {
|
||||
const alertTableConfigRegistry = new AlertTableConfigRegistry();
|
||||
const toggleColumn = (columnId: string) => {};
|
||||
expect(() =>
|
||||
alertTableConfigRegistry.update('test-alert-table-config', {
|
||||
...getTestAlertTableConfig(),
|
||||
actions: {
|
||||
toggleColumn,
|
||||
},
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Object type \\"test-alert-table-config\\" is not registered."`
|
||||
);
|
||||
});
|
||||
});
|
|
@ -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 { i18n } from '@kbn/i18n';
|
||||
import { noop } from 'lodash';
|
||||
import {
|
||||
AlertsTableConfigurationRegistry,
|
||||
AlertsTableConfigurationRegistryWithActions,
|
||||
} from '../types';
|
||||
|
||||
export class AlertTableConfigRegistry {
|
||||
private readonly objectTypes: Map<
|
||||
string,
|
||||
AlertsTableConfigurationRegistry | AlertsTableConfigurationRegistryWithActions
|
||||
> = new Map();
|
||||
|
||||
/**
|
||||
* Returns if the object type registry has the given type registered
|
||||
*/
|
||||
public has(id: string) {
|
||||
return this.objectTypes.has(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an object type to the type registry
|
||||
*/
|
||||
public register(objectType: AlertsTableConfigurationRegistry) {
|
||||
if (this.has(objectType.id)) {
|
||||
throw new Error(
|
||||
i18n.translate(
|
||||
'xpack.triggersActionsUI.typeRegistry.register.duplicateObjectTypeErrorMessage',
|
||||
{
|
||||
defaultMessage: 'Object type "{id}" is already registered.',
|
||||
values: {
|
||||
id: objectType.id,
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
this.objectTypes.set(objectType.id, objectType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object type, throw error if not registered
|
||||
*/
|
||||
public get(id: string) {
|
||||
if (!this.has(id)) {
|
||||
throw new Error(
|
||||
i18n.translate('xpack.triggersActionsUI.typeRegistry.get.missingActionTypeErrorMessage', {
|
||||
defaultMessage: 'Object type "{id}" is not registered.',
|
||||
values: {
|
||||
id,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
return this.objectTypes.get(id)!;
|
||||
}
|
||||
|
||||
public getActions(id: string): AlertsTableConfigurationRegistryWithActions['actions'] {
|
||||
return (
|
||||
(this.objectTypes.get(id) as AlertsTableConfigurationRegistryWithActions)?.actions ?? {
|
||||
toggleColumn: noop,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public list() {
|
||||
return Array.from(this.objectTypes).map(([id, objectType]) => objectType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object type, throw error if not registered
|
||||
*/
|
||||
public update(id: string, objectType: AlertsTableConfigurationRegistryWithActions) {
|
||||
if (!this.has(id)) {
|
||||
throw new Error(
|
||||
i18n.translate('xpack.triggersActionsUI.typeRegistry.get.missingActionTypeErrorMessage', {
|
||||
defaultMessage: 'Object type "{id}" is not registered.',
|
||||
values: {
|
||||
id,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
this.objectTypes.set(id, objectType);
|
||||
return this.objectTypes.get(id)!;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,7 @@ import { AlertConsumers } from '@kbn/rule-data-utils';
|
|||
import { getAlertsTableStateLazy } from '../../../../common/get_alerts_table_state';
|
||||
import { PLUGIN_ID } from '../../../../common/constants';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import { AlertsTableConfigurationRegistry } from '../../../../types';
|
||||
import { TypeRegistry } from '../../../type_registry';
|
||||
import { AlertTableConfigRegistry } from '../../../alert_table_config_registry';
|
||||
|
||||
const consumers = [
|
||||
AlertConsumers.APM,
|
||||
|
@ -24,8 +23,7 @@ const AlertsPage: React.FunctionComponent = () => {
|
|||
const { alertsTableConfigurationRegistry } = useKibana().services;
|
||||
|
||||
const alertStateProps = {
|
||||
alertsTableConfigurationRegistry:
|
||||
alertsTableConfigurationRegistry as TypeRegistry<AlertsTableConfigurationRegistry>,
|
||||
alertsTableConfigurationRegistry: alertsTableConfigurationRegistry as AlertTableConfigRegistry,
|
||||
configurationId: PLUGIN_ID,
|
||||
id: `internal-alerts-page`,
|
||||
featureIds: consumers,
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
import React, { lazy } from 'react';
|
||||
import { PLUGIN_ID } from '../../../../common/constants';
|
||||
import { AlertsTableConfigurationRegistry } from '../../../../types';
|
||||
import { TypeRegistry } from '../../../type_registry';
|
||||
import { AlertTableConfigRegistry } from '../../../alert_table_config_registry';
|
||||
|
||||
const AlertsPageFlyoutHeader = lazy(() => import('./alerts_page_flyout_header'));
|
||||
const AlertsPageFlyoutBody = lazy(() => import('./alerts_page_flyout_body'));
|
||||
|
@ -22,7 +21,7 @@ const useInternalFlyout = () => ({
|
|||
export function registerAlertsTableConfiguration({
|
||||
alertsTableConfigurationRegistry,
|
||||
}: {
|
||||
alertsTableConfigurationRegistry: TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
alertsTableConfigurationRegistry: AlertTableConfigRegistry;
|
||||
}) {
|
||||
alertsTableConfigurationRegistry.register({
|
||||
id: PLUGIN_ID,
|
||||
|
|
|
@ -20,7 +20,6 @@ import {
|
|||
FetchAlertData,
|
||||
} from '../../../types';
|
||||
import { PLUGIN_ID } from '../../../common/constants';
|
||||
import { TypeRegistry } from '../../type_registry';
|
||||
import AlertsTableState, { AlertsTableStateProps } from './alerts_table_state';
|
||||
import { useFetchAlerts } from './hooks/use_fetch_alerts';
|
||||
import { useFetchBrowserFieldCapabilities } from './hooks/use_fetch_browser_fields_capabilities';
|
||||
|
@ -32,6 +31,7 @@ import { getCasesMockMap } from './cases/index.mock';
|
|||
import { createCasesServiceMock } from './index.mock';
|
||||
import { useBulkGetMaintenanceWindows } from './hooks/use_bulk_get_maintenance_windows';
|
||||
import { getMaintenanceWindowMockMap } from './maintenance_windows/index.mock';
|
||||
import { AlertTableConfigRegistry } from '../../alert_table_config_registry';
|
||||
|
||||
jest.mock('./hooks/use_fetch_alerts');
|
||||
jest.mock('./hooks/use_fetch_browser_fields_capabilities');
|
||||
|
@ -261,10 +261,15 @@ const getMock = jest.fn().mockImplementation((plugin: string) => {
|
|||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
const updateMock = jest.fn();
|
||||
const getActionsMock = jest.fn();
|
||||
const alertsTableConfigurationRegistryMock = {
|
||||
has: hasMock,
|
||||
get: getMock,
|
||||
} as unknown as TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
getActions: getActionsMock,
|
||||
update: updateMock,
|
||||
} as unknown as AlertTableConfigRegistry;
|
||||
|
||||
const storageMock = Storage as jest.Mock;
|
||||
|
||||
|
@ -325,7 +330,8 @@ describe('AlertsTableState', () => {
|
|||
const alertsTableConfigurationRegistryWithPersistentControlsMock = {
|
||||
has: hasMock,
|
||||
get: getMockWithUsePersistentControls,
|
||||
} as unknown as TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
update: updateMock,
|
||||
} as unknown as AlertTableConfigRegistry;
|
||||
|
||||
return {
|
||||
...tableProps,
|
||||
|
@ -637,6 +643,7 @@ describe('AlertsTableState', () => {
|
|||
render(<AlertsTableWithLocale {...tableProps} />);
|
||||
expect(hasMock).toHaveBeenCalledWith(PLUGIN_ID);
|
||||
expect(getMock).toHaveBeenCalledWith(PLUGIN_ID);
|
||||
expect(updateMock).toBeCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should render an empty error state when the plugin id owner is not registered', async () => {
|
||||
|
|
|
@ -44,7 +44,6 @@ import {
|
|||
TableUpdateHandlerArgs,
|
||||
} from '../../../types';
|
||||
import { ALERTS_TABLE_CONF_ERROR_MESSAGE, ALERTS_TABLE_CONF_ERROR_TITLE } from './translations';
|
||||
import { TypeRegistry } from '../../type_registry';
|
||||
import { bulkActionsReducer } from './bulk_actions/reducer';
|
||||
import { useColumns } from './hooks/use_columns';
|
||||
import { InspectButtonContainer } from './toolbar/components/inspect';
|
||||
|
@ -52,6 +51,7 @@ import { alertsTableQueryClient } from './query_client';
|
|||
import { useBulkGetCases } from './hooks/use_bulk_get_cases';
|
||||
import { useBulkGetMaintenanceWindows } from './hooks/use_bulk_get_maintenance_windows';
|
||||
import { CasesService } from './types';
|
||||
import { AlertTableConfigRegistry } from '../../alert_table_config_registry';
|
||||
|
||||
const DefaultPagination = {
|
||||
pageSize: 10,
|
||||
|
@ -59,7 +59,7 @@ const DefaultPagination = {
|
|||
};
|
||||
|
||||
export type AlertsTableStateProps = {
|
||||
alertsTableConfigurationRegistry: TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
alertsTableConfigurationRegistry: AlertTableConfigRegistry;
|
||||
configurationId: string;
|
||||
id: string;
|
||||
featureIds: ValidFeatureId[];
|
||||
|
@ -260,6 +260,14 @@ const AlertsTableStateWithQueryProvider = ({
|
|||
skip: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
alertsTableConfigurationRegistry.update(configurationId, {
|
||||
...alertsTableConfiguration,
|
||||
actions: { toggleColumn: onToggleColumn },
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [onToggleColumn]);
|
||||
|
||||
useEffect(() => {
|
||||
if (onUpdate) {
|
||||
onUpdate({ isLoading, totalCount: alertsCount, refresh });
|
||||
|
|
|
@ -61,7 +61,9 @@ export const createStartServicesMock = (): TriggersAndActionsUiServices => {
|
|||
has: jest.fn(),
|
||||
register: jest.fn(),
|
||||
get: jest.fn(),
|
||||
getActions: jest.fn(),
|
||||
list: jest.fn(),
|
||||
update: jest.fn(),
|
||||
} as AlertsTableConfigurationRegistryContract,
|
||||
charts: chartPluginMock.createStartContract(),
|
||||
isCloud: false,
|
||||
|
|
|
@ -18,7 +18,6 @@ import {
|
|||
RuleEditProps,
|
||||
RuleTypeModel,
|
||||
AlertsTableProps,
|
||||
AlertsTableConfigurationRegistry,
|
||||
FieldBrowserProps,
|
||||
RuleTagBadgeOptions,
|
||||
RuleTagBadgeProps,
|
||||
|
@ -48,11 +47,12 @@ import { getRuleDefinitionLazy } from './common/get_rule_definition';
|
|||
import { getRuleStatusPanelLazy } from './common/get_rule_status_panel';
|
||||
import { getRuleSnoozeModalLazy } from './common/get_rule_snooze_modal';
|
||||
import { getRulesSettingsLinkLazy } from './common/get_rules_settings_link';
|
||||
import { AlertTableConfigRegistry } from './application/alert_table_config_registry';
|
||||
|
||||
function createStartMock(): TriggersAndActionsUIPublicPluginStart {
|
||||
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
|
||||
const ruleTypeRegistry = new TypeRegistry<RuleTypeModel>();
|
||||
const alertsTableConfigurationRegistry = new TypeRegistry<AlertsTableConfigurationRegistry>();
|
||||
const alertsTableConfigurationRegistry = new AlertTableConfigRegistry();
|
||||
const connectorServices = { validateEmailAddresses: jest.fn() };
|
||||
return {
|
||||
actionTypeRegistry,
|
||||
|
|
|
@ -68,7 +68,6 @@ import type {
|
|||
GlobalRuleEventLogListProps,
|
||||
RulesListProps,
|
||||
RulesListNotifyBadgePropsWithApi,
|
||||
AlertsTableConfigurationRegistry,
|
||||
CreateConnectorFlyoutProps,
|
||||
EditConnectorFlyoutProps,
|
||||
ConnectorServices,
|
||||
|
@ -90,17 +89,18 @@ import { RuleSnoozeModalProps } from './application/sections/rules_list/componen
|
|||
import { getRuleSnoozeModalLazy } from './common/get_rule_snooze_modal';
|
||||
import { getRulesSettingsLinkLazy } from './common/get_rules_settings_link';
|
||||
import { getGlobalRuleEventLogListLazy } from './common/get_global_rule_event_log_list';
|
||||
import { AlertTableConfigRegistry } from './application/alert_table_config_registry';
|
||||
|
||||
export interface TriggersAndActionsUIPublicPluginSetup {
|
||||
actionTypeRegistry: TypeRegistry<ActionTypeModel>;
|
||||
ruleTypeRegistry: TypeRegistry<RuleTypeModel<any>>;
|
||||
alertsTableConfigurationRegistry: TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
alertsTableConfigurationRegistry: AlertTableConfigRegistry;
|
||||
}
|
||||
|
||||
export interface TriggersAndActionsUIPublicPluginStart {
|
||||
actionTypeRegistry: TypeRegistry<ActionTypeModel>;
|
||||
ruleTypeRegistry: TypeRegistry<RuleTypeModel<any>>;
|
||||
alertsTableConfigurationRegistry: TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
alertsTableConfigurationRegistry: AlertTableConfigRegistry;
|
||||
getActionForm: (
|
||||
props: Omit<ActionAccordionFormProps, 'actionTypeRegistry'>
|
||||
) => ReactElement<ActionAccordionFormProps>;
|
||||
|
@ -178,7 +178,7 @@ export class Plugin
|
|||
{
|
||||
private actionTypeRegistry: TypeRegistry<ActionTypeModel>;
|
||||
private ruleTypeRegistry: TypeRegistry<RuleTypeModel>;
|
||||
private alertsTableConfigurationRegistry: TypeRegistry<AlertsTableConfigurationRegistry>;
|
||||
private alertsTableConfigurationRegistry: AlertTableConfigRegistry;
|
||||
private config: TriggersActionsUiConfigType;
|
||||
private connectorServices?: ConnectorServices;
|
||||
readonly experimentalFeatures: ExperimentalFeatures;
|
||||
|
@ -186,7 +186,7 @@ export class Plugin
|
|||
constructor(ctx: PluginInitializerContext) {
|
||||
this.actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
|
||||
this.ruleTypeRegistry = new TypeRegistry<RuleTypeModel>();
|
||||
this.alertsTableConfigurationRegistry = new TypeRegistry<AlertsTableConfigurationRegistry>();
|
||||
this.alertsTableConfigurationRegistry = new AlertTableConfigRegistry();
|
||||
this.config = ctx.config.get();
|
||||
this.experimentalFeatures = parseExperimentalConfigValue(this.config.enableExperimental || []);
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ import { RulesListVisibleColumns } from './application/sections/rules_list/compo
|
|||
import { TimelineItem } from './application/sections/alerts_table/bulk_actions/components/toolbar';
|
||||
import type { RulesListNotifyBadgePropsWithApi } from './application/sections/rules_list/components/notify_badge';
|
||||
import { Case } from './application/sections/alerts_table/hooks/apis/bulk_get_cases';
|
||||
import { AlertTableConfigRegistry } from './application/alert_table_config_registry';
|
||||
|
||||
// In Triggers and Actions we treat all `Alert`s as `SanitizedRule<RuleTypeParams>`
|
||||
// so the `Params` is a black-box of Record<string, unknown>
|
||||
|
@ -156,9 +157,7 @@ export type ActionTypeRegistryContract<
|
|||
ActionParams = unknown
|
||||
> = PublicMethodsOf<TypeRegistry<ActionTypeModel<ActionConnector, ActionParams>>>;
|
||||
export type RuleTypeRegistryContract = PublicMethodsOf<TypeRegistry<RuleTypeModel>>;
|
||||
export type AlertsTableConfigurationRegistryContract = PublicMethodsOf<
|
||||
TypeRegistry<AlertsTableConfigurationRegistry>
|
||||
>;
|
||||
export type AlertsTableConfigurationRegistryContract = PublicMethodsOf<AlertTableConfigRegistry>;
|
||||
|
||||
export interface ConnectorValidationError {
|
||||
message: ReactNode;
|
||||
|
@ -690,6 +689,13 @@ export interface AlertsTableConfigurationRegistry {
|
|||
showInspectButton?: boolean;
|
||||
}
|
||||
|
||||
export interface AlertsTableConfigurationRegistryWithActions
|
||||
extends AlertsTableConfigurationRegistry {
|
||||
actions: {
|
||||
toggleColumn: (columnId: string) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export enum BulkActionsVerbs {
|
||||
add = 'add',
|
||||
delete = 'delete',
|
||||
|
|
|
@ -10,19 +10,20 @@ import { expandFirstAlertExpandableFlyout } from '../../../../tasks/expandable_f
|
|||
import { closeTimeline, openActiveTimeline } from '../../../../tasks/timeline';
|
||||
import { PROVIDER_BADGE } from '../../../../screens/timeline';
|
||||
import { removeKqlFilter } from '../../../../tasks/search_bar';
|
||||
import { FILTER_BADGE } from '../../../../screens/alerts';
|
||||
import { COLUMN_HEADER, FILTER_BADGE, TIMESTAMP_COLUMN } from '../../../../screens/alerts';
|
||||
import {
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ID_ROW,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_COPY_TO_CLIPBOARD,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_CELL,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_ROW,
|
||||
} from '../../../../screens/expandable_flyout/alert_details_right_panel_table_tab';
|
||||
import {
|
||||
addToTimelineTableTabTable,
|
||||
clearFilterTableTabTable,
|
||||
copyToClipboardTableTabTable,
|
||||
filterInTableTabTable,
|
||||
filterOutTableTabTable,
|
||||
filterTableTabTable,
|
||||
toggleColumnTableTabTable,
|
||||
} from '../../../../tasks/expandable_flyout/alert_details_right_panel_table_tab';
|
||||
import { cleanKibana } from '../../../../tasks/common';
|
||||
import { login } from '../../../../tasks/login';
|
||||
|
@ -76,8 +77,20 @@ describe(
|
|||
|
||||
cy.log('cell actions copy to clipboard');
|
||||
|
||||
copyToClipboardTableTabTable();
|
||||
cy.get('body').realHover();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_CELL).first().realHover();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_COPY_TO_CLIPBOARD).should('be.visible');
|
||||
|
||||
cy.log('cell actions toggle column');
|
||||
|
||||
const timestampColumn = '@timestamp';
|
||||
cy.get(TIMESTAMP_COLUMN).should('be.visible');
|
||||
cy.get(COLUMN_HEADER).should('contain.text', timestampColumn);
|
||||
toggleColumnTableTabTable();
|
||||
cy.get(COLUMN_HEADER).should('not.contain.text', timestampColumn);
|
||||
toggleColumnTableTabTable();
|
||||
cy.get(TIMESTAMP_COLUMN).should('be.visible');
|
||||
cy.get(COLUMN_HEADER).should('contain.text', timestampColumn);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -43,8 +43,6 @@ export const CLOSE_SELECTED_ALERTS_BTN = '[data-test-subj="closed-alert-status"]
|
|||
|
||||
export const CLOSED_ALERTS_FILTER_BTN = '[data-test-subj="closedAlerts"]';
|
||||
|
||||
export const DESTINATION_IP = '[data-test-subj^=formatted-field][data-test-subj$=destination\\.ip]';
|
||||
|
||||
export const EMPTY_ALERT_TABLE = '[data-test-subj="alertsStateTableEmptyState"]';
|
||||
|
||||
export const EXPAND_ALERT_BTN = '[data-test-subj="expand-event"]';
|
||||
|
@ -59,10 +57,6 @@ export const GROUP_BY_TOP_INPUT = '[data-test-subj="groupByTop"] [data-test-subj
|
|||
|
||||
export const HOST_NAME = '[data-test-subj^=formatted-field][data-test-subj$=host\\.name]';
|
||||
|
||||
export const ACKNOWLEDGED_ALERTS_FILTER_BTN = '[data-test-subj="acknowledgedAlerts"]';
|
||||
|
||||
export const LOADING_ALERTS_PANEL = '[data-test-subj="loading-alerts-panel"]';
|
||||
|
||||
export const MANAGE_ALERT_DETECTION_RULES_BTN = '[data-test-subj="manage-alert-detection-rules"]';
|
||||
|
||||
export const MARK_ALERT_ACKNOWLEDGED_BTN = '[data-test-subj="acknowledged-alert-status"]';
|
||||
|
@ -71,8 +65,6 @@ export const ALERTS_REFRESH_BTN = `${GLOBAL_FILTERS_CONTAINER} [data-test-subj="
|
|||
|
||||
export const ALERTS_HISTOGRAM_PANEL_LOADER = '[data-test-subj="loadingPanelAlertsHistogram"]';
|
||||
|
||||
export const ALERTS_CONTAINER_LOADING_BAR = '[data-test-subj="events-container-loading-true"]';
|
||||
|
||||
export const OPEN_ALERT_BTN = '[data-test-subj="open-alert-status"]';
|
||||
|
||||
export const OPENED_ALERTS_FILTER_BTN = '[data-test-subj="openAlerts"]';
|
||||
|
@ -80,8 +72,8 @@ export const OPENED_ALERTS_FILTER_BTN = '[data-test-subj="openAlerts"]';
|
|||
export const OPEN_ALERT_DETAILS_PAGE_CONTEXT_MENU_BTN =
|
||||
'[data-test-subj="open-alert-details-page-menu-item"]';
|
||||
|
||||
export const PROCESS_NAME_COLUMN = '[data-test-subj="dataGridHeaderCell-process.name"]';
|
||||
export const PROCESS_NAME = '[data-test-subj="formatted-field-process.name"]';
|
||||
export const COLUMN_HEADER = '[data-test-subj="dataGridHeader"]';
|
||||
export const TIMESTAMP_COLUMN = '[data-test-subj="dataGridHeaderCell-@timestamp"]';
|
||||
export const MESSAGE = '[data-test-subj="formatted-field-message"]';
|
||||
|
||||
export const REASON =
|
||||
|
@ -109,8 +101,6 @@ export const TAKE_ACTION_POPOVER_BTN = '[data-test-subj="selectedShowBulkActions
|
|||
|
||||
export const TIMELINE_CONTEXT_MENU_BTN = '[data-test-subj="timeline-context-menu-button"]';
|
||||
|
||||
export const TIMELINE_CONTEXT_MENU = '[data-test-subj="actions-context-menu"]';
|
||||
|
||||
export const USER_NAME = '[data-test-subj^=formatted-field][data-test-subj$=user\\.name]';
|
||||
|
||||
export const ATTACH_ALERT_TO_CASE_BUTTON = '[data-test-subj="add-to-existing-case-action"]';
|
||||
|
@ -179,14 +169,10 @@ export const LEGEND_ACTIONS = {
|
|||
COPY: (ruleName: string) => `[data-test-subj="legend-${ruleName}-embeddable_copyToClipboard"]`,
|
||||
};
|
||||
|
||||
export const TREND_CHART_LEGEND = '[data-test-subj="draggable-legend"]';
|
||||
|
||||
export const SESSION_VIEWER_BUTTON = '[data-test-subj="session-view-button"]';
|
||||
|
||||
export const OVERLAY_CONTAINER = '[data-test-subj="overlayContainer"]';
|
||||
|
||||
export const CLOSE_OVERLAY = '[data-test-subj="close-overlay"]';
|
||||
|
||||
export const ALERT_SUMMARY_SEVERITY_DONUT_CHART =
|
||||
getDataTestSubjectSelector('severity-level-donut');
|
||||
|
||||
|
@ -214,10 +200,6 @@ export const EVENT_SUMMARY_ALERT_RENDERER_CONTENT = '[data-test-subj="alertRende
|
|||
|
||||
export const ALERT_TABLE_EVENT_RENDERED_VIEW_OPTION = '[data-test-subj="eventRenderedView"]';
|
||||
|
||||
export const ALERT_TABLE_ADDITIONAL_CONTROLS = '[data-test-subj="additionalFilters-popover"]';
|
||||
|
||||
export const ALERT_RENDERER_CONTENT = '[data-test-subj="alertRenderer"]';
|
||||
|
||||
export const ALERT_RENDERER_HOST_NAME =
|
||||
'[data-test-subj="alertFieldBadge"] [data-test-subj="render-content-host.name"]';
|
||||
|
||||
|
|
|
@ -22,18 +22,20 @@ export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_CELL =
|
|||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ID_ROW = getDataTestSubjectSelector(
|
||||
'event-fields-table-row-_id'
|
||||
);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_EVENT_TYPE_ROW = getDataTestSubjectSelector(
|
||||
'event-fields-table-row-event.type'
|
||||
);
|
||||
const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ACTIONS =
|
||||
'actionItem-security-detailsFlyout-cellActions-';
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_FILTER_IN = getDataTestSubjectSelector(
|
||||
'actionItem-security-detailsFlyout-cellActions-filterIn'
|
||||
`${DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ACTIONS}filterIn`
|
||||
);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_FILTER_OUT = getDataTestSubjectSelector(
|
||||
'actionItem-security-detailsFlyout-cellActions-filterOut'
|
||||
`${DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ACTIONS}filterOut`
|
||||
);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_TOGGLE_COLUMN = getDataTestSubjectSelector(
|
||||
`${DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ACTIONS}toggleColumn`
|
||||
);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_MORE_ACTIONS =
|
||||
getDataTestSubjectSelector('showExtraActionsButton');
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ADD_TO_TIMELINE =
|
||||
getDataTestSubjectSelector('actionItem-security-detailsFlyout-cellActions-addToTimeline');
|
||||
getDataTestSubjectSelector(`${DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ACTIONS}addToTimeline`);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_COPY_TO_CLIPBOARD =
|
||||
getDataTestSubjectSelector('actionItem-security-detailsFlyout-cellActions-copyToClipboard');
|
||||
getDataTestSubjectSelector(
|
||||
`${DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ACTIONS}copyToClipboard`
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ADD_TO_TIMELINE,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_FILTER_IN,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_FILTER_OUT,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_MORE_ACTIONS,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_TOGGLE_COLUMN,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_CELL,
|
||||
} from '../../screens/expandable_flyout/alert_details_right_panel_table_tab';
|
||||
|
||||
|
@ -54,17 +54,16 @@ export const filterOutTableTabTable = () => {
|
|||
export const addToTimelineTableTabTable = () => {
|
||||
cy.get('body').realHover();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_CELL).first().realHover();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_MORE_ACTIONS).first().click();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_ADD_TO_TIMELINE).click();
|
||||
};
|
||||
|
||||
/**
|
||||
* Show Copy to clipboard button in the first table row under the Table tab in the alert details expandable flyout right section
|
||||
* Show Toggle column button in the first table row under the Table tab in the alert details expandable flyout right section
|
||||
*/
|
||||
export const copyToClipboardTableTabTable = () => {
|
||||
export const toggleColumnTableTabTable = () => {
|
||||
cy.get('body').realHover();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_TIMESTAMP_CELL).first().realHover();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_MORE_ACTIONS).first().click();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ROW_CELL_TOGGLE_COLUMN).click();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue