diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index 0602ee6390629..32df8ac3240c4 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -174,9 +174,6 @@ export const SECURITY_SOLUTION_ENABLE_CCS_WARNING_ID = 'securitySolution:enableC export const SECURITY_SOLUTION_SHOW_RELATED_INTEGRATIONS_ID = 'securitySolution:showRelatedIntegrations'; export const SECURITY_SOLUTION_DEFAULT_ALERT_TAGS_KEY = 'securitySolution:alertTags' as const; -/** This Kibana Advanced Setting allows users to enable/disable the Expandable Flyout */ -export const SECURITY_SOLUTION_ENABLE_EXPANDABLE_FLYOUT_SETTING = - 'securitySolution:enableExpandableFlyout' as const; /** This Kibana Advanced Setting allows users to enable/disable querying cold and frozen data tiers in analyzer */ export const SECURITY_SOLUTION_EXCLUDE_COLD_AND_FROZEN_TIERS_IN_ANALYZER = 'securitySolution:excludeColdAndFrozenTiersInAnalyzer' as const; diff --git a/packages/serverless/settings/security_project/index.ts b/packages/serverless/settings/security_project/index.ts index 70b2305610aea..98dbaac5303a6 100644 --- a/packages/serverless/settings/security_project/index.ts +++ b/packages/serverless/settings/security_project/index.ts @@ -23,7 +23,6 @@ export const SECURITY_PROJECT_SETTINGS = [ settings.SECURITY_SOLUTION_NEWS_FEED_URL_ID, settings.SECURITY_SOLUTION_ENABLE_NEWS_FEED_ID, settings.SECURITY_SOLUTION_DEFAULT_ALERT_TAGS_KEY, - settings.SECURITY_SOLUTION_ENABLE_EXPANDABLE_FLYOUT_SETTING, settings.SECURITY_SOLUTION_ENABLE_ASSET_CRITICALITY_SETTING, settings.SECURITY_SOLUTION_EXCLUDE_COLD_AND_FROZEN_TIERS_IN_ANALYZER, ]; diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index 3a81a37dba189..cf62f45ce3156 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -110,10 +110,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, - 'securitySolution:enableExpandableFlyout': { - type: 'boolean', - _meta: { description: 'Non-default value of setting.' }, - }, 'securitySolution:enableAssetCriticality': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 82f31eb629a89..6a5983df9ccfd 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -73,7 +73,6 @@ export interface UsageStats { 'securitySolution:defaultAnomalyScore': number; 'securitySolution:refreshIntervalDefaults': string; 'securitySolution:enableNewsFeed': boolean; - 'securitySolution:enableExpandableFlyout': boolean; 'securitySolution:enableAssetCriticality': boolean; 'securitySolution:excludeColdAndFrozenTiersInAnalyzer': boolean; 'securitySolution:enableCcsWarning': boolean; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 991536dd61078..417a59ad71bf7 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -9630,12 +9630,6 @@ "description": "Non-default value of setting." } }, - "securitySolution:enableExpandableFlyout": { - "type": "boolean", - "_meta": { - "description": "Non-default value of setting." - } - }, "securitySolution:enableAssetCriticality": { "type": "boolean", "_meta": { diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index c477a069c9c2e..1822e6be5cb81 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -168,9 +168,6 @@ export const DEFAULT_INDEX_PATTERN = [...INCLUDE_INDEX_PATTERN, ...EXCLUDE_ELAST /** This Kibana Advanced Setting enables the `Security news` feed widget */ export const ENABLE_NEWS_FEED_SETTING = 'securitySolution:enableNewsFeed' as const; -/** This Kibana Advanced Setting allows users to enable/disable the Expandable Flyout */ -export const ENABLE_EXPANDABLE_FLYOUT_SETTING = 'securitySolution:enableExpandableFlyout' as const; - /** This Kibana Advanced Setting allows users to enable/disable querying cold and frozen data tiers in analyzer */ export const EXCLUDE_COLD_AND_FROZEN_TIERS_IN_ANALYZER = 'securitySolution:excludeColdAndFrozenTiersInAnalyzer' as const; diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index a3248bc4374ba..0e0065e6823ea 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -110,20 +110,9 @@ export const allowedExperimentalValues = Object.freeze({ alertTypeEnabled: false, /** - * Enables expandable flyout in create rule page, alert preview + * Disables expandable flyout */ - expandableFlyoutInCreateRuleEnabled: true, - - /** - * Enables expandable flyout for event type documents - */ - expandableEventFlyoutEnabled: true, - - /** - * Enables expandable flyout in timeline - */ - expandableTimelineFlyoutEnabled: true, - /* + expandableFlyoutDisabled: false, /** * Enables the Assistant Model Evaluation advanced setting and API endpoint, introduced in `8.11.0`. @@ -135,22 +124,12 @@ export const allowedExperimentalValues = Object.freeze({ */ assistantKnowledgeBaseByDefault: false, - /** - * Enables the new user details flyout displayed on the Alerts table. - */ - newUserDetailsFlyout: true, - /** * Enables the Managed User section inside the new user details flyout. - * To see this section you also need newUserDetailsFlyout flag enabled. + * To see this section you also need expandableFlyoutDisabled flag set to false. */ newUserDetailsFlyoutManagedUser: false, - /** - * Enables the new host details flyout displayed on the Alerts table. - */ - newHostDetailsFlyout: true, - /** * Enable risk engine client and initialisation of datastream, component templates and mappings */ diff --git a/x-pack/plugins/security_solution/public/cases/pages/index.tsx b/x-pack/plugins/security_solution/public/cases/pages/index.tsx index 7f242e5968811..e3eb2290e6e77 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/index.tsx @@ -9,8 +9,8 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; import type { CaseViewRefreshPropInterface } from '@kbn/cases-plugin/common'; import { CaseMetricsFeature } from '@kbn/cases-plugin/common'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; +import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import { DocumentDetailsRightPanelKey } from '../../flyout/document_details/shared/constants/panel_keys'; import { useTourContext } from '../../common/components/guided_onboarding_tour'; import { @@ -22,12 +22,7 @@ import { TimelineId } from '../../../common/types/timeline'; import { getRuleDetailsUrl, useFormatUrl } from '../../common/components/link_to'; import { useKibana, useNavigation } from '../../common/lib/kibana'; -import { - APP_ID, - CASES_PATH, - ENABLE_EXPANDABLE_FLYOUT_SETTING, - SecurityPageName, -} from '../../../common/constants'; +import { APP_ID, CASES_PATH, SecurityPageName } from '../../../common/constants'; import { timelineActions } from '../../timelines/store'; import { useSourcererDataView } from '../../sourcerer/containers'; import { SourcererScopeName } from '../../sourcerer/store/model'; @@ -63,7 +58,7 @@ const CaseContainerComponent: React.FC = () => { SecurityPageName.rules ); const { openFlyout } = useExpandableFlyoutApi(); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const getDetectionsRuleDetailsHref = useCallback( (ruleId) => detectionsFormatUrl(getRuleDetailsUrl(ruleId ?? '', detectionsUrlSearch)), @@ -74,7 +69,7 @@ const CaseContainerComponent: React.FC = () => { const showAlertDetails = useCallback( (alertId: string, index: string) => { - if (isSecurityFlyoutEnabled) { + if (!expandableFlyoutDisabled) { openFlyout({ right: { id: DocumentDetailsRightPanelKey, @@ -105,7 +100,7 @@ const CaseContainerComponent: React.FC = () => { ); } }, - [dispatch, isSecurityFlyoutEnabled, openFlyout, telemetry] + [dispatch, expandableFlyoutDisabled, openFlyout, telemetry] ); const endpointDetailsHref = (endpointId: string) => diff --git a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.test.tsx index a6500a2ba5d10..a680590d3752a 100644 --- a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.test.tsx @@ -15,6 +15,7 @@ import { useRouteSpy } from '../../../utils/route/use_route_spy'; import type { RouteSpyState } from '../../../utils/route/types'; import { SecurityPageName } from '@kbn/deeplinks-security'; import { createTelemetryServiceMock } from '../../../lib/telemetry/telemetry_service.mock'; +import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; const mockDispatch = jest.fn(); jest.mock('react-redux', () => { @@ -114,18 +115,7 @@ describe('RowAction', () => { expect(wrapper.getAllByTestId('expand-event')).not.toBeNull(); }); - test('Uses the old flyout when the experimental feature returns false', () => { - const wrapper = render( - - - - ); - fireEvent.click(wrapper.getByTestId('expand-event')); - expect(mockDispatch).toHaveBeenCalled(); - expect(mockOpenFlyout).not.toHaveBeenCalled(); - }); - - test('Uses the new flyout when the experimental feature returns false but the page is attackDiscovery', () => { + test('should always show expandable flyout if the page is attackDiscovery', () => { (useRouteSpy as jest.Mock).mockReturnValue([ { ...mockRouteSpy, pageName: SecurityPageName.attackDiscovery }, ]); @@ -136,6 +126,15 @@ describe('RowAction', () => { ); fireEvent.click(wrapper.getByTestId('expand-event')); expect(mockDispatch).not.toHaveBeenCalled(); - expect(mockOpenFlyout).toHaveBeenCalled(); + expect(mockOpenFlyout).toHaveBeenCalledWith({ + right: { + id: DocumentDetailsRightPanelKey, + params: { + id: '1', + indexName: undefined, + scopeId: 'table-test', + }, + }, + }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx index 181b707e88d2d..c586e887ce5e7 100644 --- a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx @@ -10,14 +10,10 @@ import React, { useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { dataTableActions, TableId } from '@kbn/securitysolution-data-table'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { useRouteSpy } from '../../../utils/route/use_route_spy'; import { useKibana } from '../../../lib/kibana'; import { timelineActions } from '../../../../timelines/store'; -import { - ENABLE_EXPANDABLE_FLYOUT_SETTING, - SecurityPageName, -} from '../../../../../common/constants'; +import { SecurityPageName } from '../../../../../common/constants'; import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; import type { SetEventsDeleted, @@ -81,10 +77,6 @@ const RowActionComponent = ({ const dispatch = useDispatch(); const [{ pageName }] = useRouteSpy(); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); - const isExpandableFlyoutInCreateRuleEnabled = useIsExperimentalFeatureEnabled( - 'expandableFlyoutInCreateRuleEnabled' - ); const { activeStep, isTourShown } = useTourContext(); const shouldFocusOnOverviewTab = (activeStep === AlertsCasesTourSteps.expandEvent || @@ -106,16 +98,10 @@ const RowActionComponent = ({ [columnHeaders, timelineNonEcsData] ); - let showExpandableFlyout: boolean; - - // disable the old flyout on attack discovery page - if (pageName === SecurityPageName.attackDiscovery) { - showExpandableFlyout = true; - } else if (tableId === TableId.rulePreview) { - showExpandableFlyout = isSecurityFlyoutEnabled && isExpandableFlyoutInCreateRuleEnabled; - } else { - showExpandableFlyout = isSecurityFlyoutEnabled; - } + // TODO remove when https://github.com/elastic/security-team/issues/7462 is merged + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); + const showExpandableFlyout = + pageName === SecurityPageName.attackDiscovery ? true : !expandableFlyoutDisabled; const handleOnEventDetailPanelOpened = useCallback(() => { const updatedExpandedDetail: ExpandedDetailType = { diff --git a/x-pack/plugins/security_solution/public/common/hooks/flyout/use_init_flyout_url_param.ts b/x-pack/plugins/security_solution/public/common/hooks/flyout/use_init_flyout_url_param.ts index 81d7e9e906ba8..659fc15ca5ea5 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/flyout/use_init_flyout_url_param.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/flyout/use_init_flyout_url_param.ts @@ -14,12 +14,11 @@ import { tableDefaults, dataTableActions, } from '@kbn/securitysolution-data-table'; -import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../common/constants'; +import { useIsExperimentalFeatureEnabled } from '../use_experimental_features'; import { useInitializeUrlParam } from '../../utils/global_query_string'; import { URL_PARAM_KEY } from '../use_url_state'; import type { FlyoutUrlState } from './types'; import { useShallowEqualSelector } from '../use_selector'; -import { useUiSetting$ } from '../../lib/kibana'; import { getQueryStringKeyValue } from '../timeline/use_query_timeline_by_id_on_url_change'; /** @@ -31,7 +30,7 @@ import { getQueryStringKeyValue } from '../timeline/use_query_timeline_by_id_on_ export const useInitFlyoutFromUrlParam = () => { const { search } = useLocation(); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const [urlDetails, setUrlDetails] = useState(null); const [hasLoadedUrlDetails, updateHasLoadedUrlDetails] = useState(false); const dispatch = useDispatch(); @@ -45,15 +44,15 @@ export const useInitFlyoutFromUrlParam = () => { const onInitialize = useCallback( (initialState: FlyoutUrlState | null) => { - if (!isSecurityFlyoutEnabled && initialState != null && initialState.panelView) { + if (expandableFlyoutDisabled && initialState != null && initialState.panelView) { setUrlDetails(initialState); } }, - [isSecurityFlyoutEnabled] + [expandableFlyoutDisabled] ); const loadExpandedDetailFromUrl = useCallback(() => { - if (isSecurityFlyoutEnabled) return; + if (!expandableFlyoutDisabled) return; const { initialized, isLoading, totalCount, additionalFilters } = dataTableCurrent; const isTableLoaded = initialized && !isLoading && totalCount > 0; @@ -78,21 +77,21 @@ export const useInitFlyoutFromUrlParam = () => { ); } } - }, [dataTableCurrent, dispatch, isSecurityFlyoutEnabled, urlDetails]); + }, [dataTableCurrent, dispatch, expandableFlyoutDisabled, urlDetails]); // The alert page creates a default dataTable slice in redux initially that is later overriden when data is retrieved // We use the below to store the urlDetails on app load, and then set it when the table is done loading and has data useEffect(() => { - if (!isSecurityFlyoutEnabled && !hasLoadedUrlDetails) { + if (expandableFlyoutDisabled && !hasLoadedUrlDetails) { loadExpandedDetailFromUrl(); } - }, [hasLoadedUrlDetails, isSecurityFlyoutEnabled, loadExpandedDetailFromUrl]); + }, [hasLoadedUrlDetails, expandableFlyoutDisabled, loadExpandedDetailFromUrl]); // We check the url for the presence of the old `evenFlyout` parameter. If it exists replace it with the new `flyout` key. const eventFlyoutKey = getQueryStringKeyValue({ urlKey: URL_PARAM_KEY.eventFlyout, search }); let currentKey = ''; let newKey = ''; - if (!isSecurityFlyoutEnabled) { + if (expandableFlyoutDisabled) { if (eventFlyoutKey) { currentKey = URL_PARAM_KEY.eventFlyout; newKey = URL_PARAM_KEY.flyout; diff --git a/x-pack/plugins/security_solution/public/common/hooks/flyout/use_sync_flyout_url_param.ts b/x-pack/plugins/security_solution/public/common/hooks/flyout/use_sync_flyout_url_param.ts index 45b55a3106eef..a6f4904d37cd9 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/flyout/use_sync_flyout_url_param.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/flyout/use_sync_flyout_url_param.ts @@ -14,8 +14,8 @@ import { tableDefaults, TableId, } from '@kbn/securitysolution-data-table'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; -import { ALERTS_PATH, ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../common/constants'; +import { useIsExperimentalFeatureEnabled } from '../use_experimental_features'; +import { ALERTS_PATH } from '../../../../common/constants'; import { useUpdateUrlParam } from '../../utils/global_query_string'; import { useShallowEqualSelector } from '../use_selector'; import { URL_PARAM_KEY } from '../use_url_state'; @@ -28,7 +28,7 @@ import type { FlyoutUrlState } from './types'; * // TODO remove this hook entirely when we delete the old flyout code */ export const useSyncFlyoutUrlParam = () => { - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const updateUrlParam = useUpdateUrlParam(URL_PARAM_KEY.flyout); const { pathname } = useLocation(); const dispatch = useDispatch(); @@ -40,7 +40,7 @@ export const useSyncFlyoutUrlParam = () => { ); useEffect(() => { - if (isSecurityFlyoutEnabled) return; + if (!expandableFlyoutDisabled) return; const isOnAlertsPage = pathname === ALERTS_PATH; if (isOnAlertsPage && expandedDetail != null && expandedDetail?.query) { @@ -55,5 +55,5 @@ export const useSyncFlyoutUrlParam = () => { // Clear the reference from the url updateUrlParam(null); } - }, [dispatch, expandedDetail, isSecurityFlyoutEnabled, pathname, updateUrlParam]); + }, [dispatch, expandedDetail, expandableFlyoutDisabled, pathname, updateUrlParam]); }; diff --git a/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.test.tsx index 57b170913ef0b..509d59338fe4d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.test.tsx @@ -60,7 +60,8 @@ describe('AlertDetailsRedirect', () => { "(global:(linkTo:!(timeline,socTrends),timerange:(from:'2023-04-20T12:00:00.000Z',kind:absolute,to:'2023-04-20T12:05:00.000Z')),timeline:(linkTo:!(global,socTrends),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now/d,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now/d)))", pageFilters: '!((exclude:!f,existsSelected:!f,fieldName:kibana.alert.workflow_status,hideActionBar:!f,selectedOptions:!(),title:Status))', - flyout: '(panelView:eventDetail,params:(eventId:test-alert-id,indexName:.someTestIndex))', + flyout: + '(preview:!(),right:(id:document-details-right,params:(id:test-alert-id,indexName:.someTestIndex,scopeId:alerts-page)))', }); expect(historyMock.replace).toHaveBeenCalledWith({ @@ -98,7 +99,8 @@ describe('AlertDetailsRedirect', () => { "(global:(linkTo:!(timeline,socTrends),timerange:(from:'2020-07-07T08:20:18.966Z',kind:absolute,to:'2020-07-08T08:25:18.966Z')),timeline:(linkTo:!(global,socTrends),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now/d,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now/d)))", pageFilters: '!((exclude:!f,existsSelected:!f,fieldName:kibana.alert.workflow_status,hideActionBar:!f,selectedOptions:!(),title:Status))', - flyout: '(panelView:eventDetail,params:(eventId:test-alert-id,indexName:.someTestIndex))', + flyout: + '(preview:!(),right:(id:document-details-right,params:(id:test-alert-id,indexName:.someTestIndex,scopeId:alerts-page)))', }); expect(historyMock.replace).toHaveBeenCalledWith({ @@ -136,7 +138,7 @@ describe('AlertDetailsRedirect', () => { pageFilters: '!((exclude:!f,existsSelected:!f,fieldName:kibana.alert.workflow_status,hideActionBar:!f,selectedOptions:!(),title:Status))', flyout: - '(panelView:eventDetail,params:(eventId:test-alert-id,indexName:.internal.alerts-security.alerts-default))', + '(preview:!(),right:(id:document-details-right,params:(id:test-alert-id,indexName:.internal.alerts-security.alerts-default,scopeId:alerts-page)))', }); expect(historyMock.replace).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.tsx b/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.tsx index eebc8c4408759..9655e6fb84f92 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.tsx @@ -12,13 +12,9 @@ import { Redirect, useLocation, useParams } from 'react-router-dom'; import moment from 'moment'; import { encode } from '@kbn/rison'; import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import type { FilterControlConfig } from '@kbn/alerts-ui-shared'; -import { - ALERTS_PATH, - DEFAULT_ALERTS_INDEX, - ENABLE_EXPANDABLE_FLYOUT_SETTING, -} from '../../../../common/constants'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; +import { ALERTS_PATH, DEFAULT_ALERTS_INDEX } from '../../../../common/constants'; import { URL_PARAM_KEY } from '../../../common/hooks/use_url_state'; import { inputsSelectors } from '../../../common/store'; import { formatPageFilterSearchParam } from '../../../../common/utils/format_page_filter_search_param'; @@ -73,14 +69,14 @@ export const AlertDetailsRedirect = () => { const currentFlyoutParams = searchParams.get(URL_PARAM_KEY.flyout); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const urlParams = new URLSearchParams({ [URL_PARAM_KEY.appQuery]: kqlAppQuery, [URL_PARAM_KEY.timerange]: timerange, [URL_PARAM_KEY.pageFilter]: pageFiltersQuery, [URL_PARAM_KEY.flyout]: resolveFlyoutParams( - { index, alertId, isSecurityFlyoutEnabled }, + { index, alertId, expandableFlyoutDisabled }, currentFlyoutParams ), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/alerts/utils.ts b/x-pack/plugins/security_solution/public/detections/pages/alerts/utils.ts index fbc9c2723d45a..ac1d2a862b92c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/alerts/utils.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/alerts/utils.ts @@ -11,7 +11,7 @@ import { expandableFlyoutStateFromEventMeta } from '../../../flyout/document_det export interface ResolveFlyoutParamsConfig { index: string; alertId: string; - isSecurityFlyoutEnabled: boolean; + expandableFlyoutDisabled: boolean; } /** @@ -21,10 +21,10 @@ export interface ResolveFlyoutParamsConfig { * with Share Button on the Expandable Flyout */ export const resolveFlyoutParams = ( - { index, alertId, isSecurityFlyoutEnabled }: ResolveFlyoutParamsConfig, + { index, alertId, expandableFlyoutDisabled }: ResolveFlyoutParamsConfig, currentParamsString: string | null ) => { - if (!isSecurityFlyoutEnabled) { + if (expandableFlyoutDisabled) { const legacyFlyoutString = encode({ panelView: 'eventDetail', params: { diff --git a/x-pack/plugins/security_solution/public/explore/users/containers/users/observed_details/index.tsx b/x-pack/plugins/security_solution/public/explore/users/containers/users/observed_details/index.tsx index 12e6e583c9a41..d1148af03a41a 100644 --- a/x-pack/plugins/security_solution/public/explore/users/containers/users/observed_details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/containers/users/observed_details/index.tsx @@ -43,7 +43,7 @@ export const useObservedUserDetails = ({ skip = false, startDate, }: UseUserDetails): [boolean, UserDetailsArgs] => { - const isNewUserDetailsFlyoutEnabled = useIsExperimentalFeatureEnabled('newUserDetailsFlyout'); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const { loading, result: response, @@ -81,9 +81,9 @@ export const useObservedUserDetails = ({ from: startDate, to: endDate, }, - filterQuery: isNewUserDetailsFlyoutEnabled ? NOT_EVENT_KIND_ASSET_FILTER : undefined, + filterQuery: !expandableFlyoutDisabled ? NOT_EVENT_KIND_ASSET_FILTER : undefined, }), - [endDate, indexNames, startDate, userName, isNewUserDetailsFlyoutEnabled] + [endDate, indexNames, startDate, userName, expandableFlyoutDisabled] ); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_flyout_is_expandable.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_flyout_is_expandable.ts index 8e465b31ce8e0..f1f762fa9abdb 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_flyout_is_expandable.ts +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_flyout_is_expandable.ts @@ -12,7 +12,6 @@ import type { GetFieldsData } from '../../../../common/hooks/use_get_fields_data import { getRowRenderer } from '../../../../timelines/components/timeline/body/renderers/get_row_renderer'; import { defaultRowRenderers } from '../../../../timelines/components/timeline/body/renderers'; import { isEcsAllowedValue } from '../utils/event_utils'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { EventKind } from '../../shared/constants/event_kinds'; export interface UseShowEventOverviewParams { @@ -45,24 +44,16 @@ export const useFlyoutIsExpandable = ({ isEcsAllowedValue('event.category', category) ); - const expandableEventFlyoutEnabled = useIsExperimentalFeatureEnabled( - 'expandableEventFlyoutEnabled' - ); - return useMemo(() => { // alert document: always show overview if (eventKind === EventKind.signal) { return true; } - // do not show overview for non-alert if feature flag is disabled - if (!expandableEventFlyoutEnabled) { - return false; - } // event document: show overview when event category is ecs compliant or event renderer is available if (eventKind === EventKind.event) { return eventCategoryInECS || renderer != null; } // non-event document: show overview when event kind is ecs compliant or event renderer is available return eventKindInECS || renderer != null; - }, [expandableEventFlyoutEnabled, eventKind, eventCategoryInECS, eventKindInECS, renderer]); + }, [eventKind, eventCategoryInECS, eventKindInECS, renderer]); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts index c587c9b9cf8e2..a46cc515ce7fc 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_details.cy.ts @@ -14,19 +14,12 @@ import { setCustomProtectionUpdatesNote, } from '../../tasks/endpoint_policy'; import { login, ROLE } from '../../tasks/login'; -import { disableExpandableFlyoutAdvancedSettings, loadPage } from '../../tasks/common'; +import { loadPage } from '../../tasks/common'; describe( 'Policy Details', { - tags: [ - '@ess', - '@serverless', - // Not supported in serverless! - // The `disableExpandableFlyoutAdvancedSettings()` fails because the API - // `internal/kibana/settings` is not accessible in serverless - '@brokenInServerless', - ], + tags: ['@ess', '@serverless'], env: { ftrConfig: { kbnServerArgs: [ @@ -63,7 +56,6 @@ describe( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); getEndpointIntegrationVersion().then((version) => { createAgentPolicyTask(version).then((data) => { indexedPolicy = data; @@ -171,7 +163,6 @@ describe( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); getEndpointIntegrationVersion().then((version) => { createAgentPolicyTask(version).then((data) => { indexedPolicy = data; @@ -225,7 +216,6 @@ describe( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); getEndpointIntegrationVersion().then((version) => { createAgentPolicyTask(version).then((data) => { indexedPolicy = data; @@ -275,7 +265,6 @@ describe( beforeEach(() => { login(ROLE.t3_analyst); - disableExpandableFlyoutAdvancedSettings(); getEndpointIntegrationVersion().then((version) => { createAgentPolicyTask(version).then((data) => { indexedPolicy = data; @@ -323,7 +312,6 @@ describe( beforeEach(() => { login(ROLE.t3_analyst); - disableExpandableFlyoutAdvancedSettings(); getEndpointIntegrationVersion().then((version) => { createAgentPolicyTask(version).then((data) => { indexedPolicy = data; @@ -374,7 +362,6 @@ describe( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); getEndpointIntegrationVersion().then((version) => { createAgentPolicyTask(version).then((data) => { indexedPolicy = data; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_experimental_features_disabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_experimental_features_disabled.cy.ts index 2e791b23f0d46..49b2ef8d44df4 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_experimental_features_disabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_experimental_features_disabled.cy.ts @@ -6,7 +6,7 @@ */ import type { PolicyData } from '../../../../../common/endpoint/types'; -import { disableExpandableFlyoutAdvancedSettings, loadPage } from '../../tasks/common'; +import { loadPage } from '../../tasks/common'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { login } from '../../tasks/login'; @@ -16,14 +16,7 @@ import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../task describe.skip( 'Disabled experimental features on: ', { - tags: [ - '@ess', - '@serverless', - // Not supported in serverless! - // The `disableExpandableFlyoutAdvancedSettings()` fails because the API - // `internal/kibana/settings` is not accessible in serverless - '@brokenInServerless', - ], + tags: ['@ess', '@serverless'], }, () => { describe('Policy list', () => { @@ -32,7 +25,6 @@ describe.skip( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); }); before(() => { @@ -71,7 +63,6 @@ describe.skip( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); }); before(() => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_list.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_list.cy.ts index aae3a1f289a6f..fb258bc04efa8 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_list.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/policy/policy_list.cy.ts @@ -7,7 +7,7 @@ import moment from 'moment'; import { setCustomProtectionUpdatesManifestVersion } from '../../tasks/endpoint_policy'; -import { disableExpandableFlyoutAdvancedSettings, loadPage } from '../../tasks/common'; +import { loadPage } from '../../tasks/common'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { login } from '../../tasks/login'; @@ -16,10 +16,7 @@ import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../task describe( 'Policy List', { - // Not supported in serverless! - // The `disableExpandableFlyoutAdvancedSettings()` fails because the API - // `internal/kibana/settings` is not accessible in serverless - tags: ['@ess', '@serverless', '@brokenInServerless'], + tags: ['@ess', '@serverless'], env: { ftrConfig: { kbnServerArgs: [ @@ -46,7 +43,6 @@ describe( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); }); before(() => { @@ -85,7 +81,6 @@ describe( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); }); before(() => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate.cy.ts index a81a921c39702..8c93be6680e10 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate.cy.ts @@ -23,7 +23,7 @@ import { } from '../../tasks/isolate'; import { cleanupCase, cleanupRule, loadCase, loadRule } from '../../tasks/api_fixtures'; import { login } from '../../tasks/login'; -import { disableExpandableFlyoutAdvancedSettings, loadPage } from '../../tasks/common'; +import { loadPage } from '../../tasks/common'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../tasks/fleet'; import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services'; @@ -34,15 +34,7 @@ import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; describe.skip( 'Isolate command', { - tags: [ - '@ess', - '@serverless', - - // Not supported in serverless! - // The `disableExpandableFlyoutAdvancedSettings()` fails because the API - // `internal/kibana/settings` is not accessible in serverless - '@brokenInServerless', - ], + tags: ['@ess', '@serverless'], }, () => { let isolateComment: string; @@ -85,7 +77,6 @@ describe.skip( beforeEach(() => { login(); - disableExpandableFlyoutAdvancedSettings(); }); describe('From manage', () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate_mocked_data.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate_mocked_data.cy.ts index 33a45c17cdadf..9af118eb1de47 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate_mocked_data.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/isolate_mocked_data.cy.ts @@ -24,7 +24,7 @@ import type { ReturnTypeFromChainable } from '../../types'; import { addAlertsToCase } from '../../tasks/add_alerts_to_case'; import { APP_ALERTS_PATH, APP_CASES_PATH, APP_PATH } from '../../../../../common/constants'; import { login } from '../../tasks/login'; -import { disableExpandableFlyoutAdvancedSettings, loadPage } from '../../tasks/common'; +import { loadPage } from '../../tasks/common'; import { indexNewCase } from '../../tasks/index_new_case'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { indexEndpointRuleAlerts } from '../../tasks/index_endpoint_rule_alerts'; @@ -92,9 +92,6 @@ describe('Isolate command', { tags: ['@ess', '@serverless', '@brokenInServerless describe.skip( 'from Alerts', { - // Not supported in serverless! - // The `disableExpandableFlyoutAdvancedSettings()` fails because the API - // `internal/kibana/settings` is not accessible in serverless tags: ['@brokenInServerless'], }, () => { @@ -103,7 +100,6 @@ describe('Isolate command', { tags: ['@ess', '@serverless', '@brokenInServerless let hostname: string; before(() => { - disableExpandableFlyoutAdvancedSettings(); indexEndpointHosts({ withResponseActions: false, isolation: false }).then( (indexEndpoints) => { endpointData = indexEndpoints; @@ -201,7 +197,8 @@ describe('Isolate command', { tags: ['@ess', '@serverless', '@brokenInServerless } ); - describe('from Cases', () => { + // TODO re-enable when https://github.com/elastic/security-team/issues/9625 is merged + describe.skip('from Cases', () => { let endpointData: ReturnTypeFromChainable | undefined; let caseData: ReturnTypeFromChainable | undefined; let alertData: ReturnTypeFromChainable | undefined; @@ -211,7 +208,6 @@ describe('Isolate command', { tags: ['@ess', '@serverless', '@brokenInServerless let hostname: string; before(() => { - disableExpandableFlyoutAdvancedSettings(); indexNewCase().then((indexCase) => { caseData = indexCase; caseUrlPath = `${APP_CASES_PATH}/${indexCase.data.id}`; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/sentinelone/isolate.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/sentinelone/isolate.cy.ts index 216d85f0b4516..6605df6403e2c 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/sentinelone/isolate.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/sentinelone/isolate.cy.ts @@ -11,21 +11,12 @@ import { closeAllToasts } from '../../tasks/toasts'; import { toggleRuleOffAndOn, visitRuleAlerts } from '../../tasks/isolate'; import { cleanupRule, loadRule } from '../../tasks/api_fixtures'; import { ROLE, login } from '../../tasks/login'; -import { disableExpandableFlyoutAdvancedSettings } from '../../tasks/common'; import { waitForAlertsToPopulate } from '../../tasks/alerts'; describe.skip( 'Isolate command', { - tags: [ - '@ess', - '@serverless', - - // Not supported in serverless! - // The `disableExpandableFlyoutAdvancedSettings()` fails because the API - // `internal/kibana/settings` is not accessible in serverless - '@brokenInServerless', - ], + tags: ['@ess', '@serverless'], env: { ftrConfig: { kbnServerArgs: [ @@ -77,7 +68,6 @@ describe.skip( beforeEach(() => { login(ROLE.soc_manager); - disableExpandableFlyoutAdvancedSettings(); }); describe('From alerts', () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts index ceba06f142f35..da6a197d9ed99 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts @@ -45,13 +45,3 @@ export const rootRequest = ( headers: API_HEADERS, ...options, }); - -export const disableExpandableFlyoutAdvancedSettings = () => { - const body = { changes: { 'securitySolution:enableExpandableFlyout': false } }; - rootRequest({ - method: 'POST', - url: 'internal/kibana/settings', - body, - headers: { 'kbn-xsrf': 'cypress-creds' }, - }); -}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx index 305bf3daa1f76..116cddf36f5f5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx @@ -20,7 +20,6 @@ import React, { useCallback, useMemo, useState } from 'react'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useKibana } from '../../../../common/lib/kibana'; import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; @@ -36,7 +35,6 @@ import { SourcererScopeName } from '../../../../sourcerer/store/model'; import { useSourcererDataView } from '../../../../sourcerer/containers'; import { useDeleteNote } from './hooks/use_delete_note'; import { getTimelineNoteSelector } from '../../timeline/tabs/notes/selectors'; -import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../../common/constants'; export const NotePreviewsContainer = styled.section` padding-top: ${({ theme }) => `${theme.eui.euiSizeS}`}; @@ -58,15 +56,12 @@ const ToggleEventDetailsButtonComponent: React.FC const { telemetry } = useKibana().services; const { openFlyout } = useExpandableFlyoutApi(); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); - const expandableTimelineFlyoutEnabled = useIsExperimentalFeatureEnabled( - 'expandableTimelineFlyoutEnabled' - ); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const handleClick = useCallback(() => { const indexName = selectedPatterns.join(','); - if (isSecurityFlyoutEnabled && expandableTimelineFlyoutEnabled) { + if (!expandableFlyoutDisabled) { openFlyout({ right: { id: DocumentDetailsRightPanelKey, @@ -97,8 +92,7 @@ const ToggleEventDetailsButtonComponent: React.FC }, [ dispatch, eventId, - expandableTimelineFlyoutEnabled, - isSecurityFlyoutEnabled, + expandableFlyoutDisabled, openFlyout, selectedPatterns, telemetry, diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx index 4defbdc683254..f0b22e4f48359 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx @@ -14,11 +14,26 @@ import { SourcererScopeName } from '../../../../sourcerer/store/model'; import { TimelineId, TimelineTabs } from '../../../../../common/types/timeline'; import { ExpandableFlyoutProvider } from '@kbn/expandable-flyout'; import { TestProviders } from '../../../../common/mock'; +import { createTelemetryServiceMock } from '../../../../common/lib/telemetry/telemetry_service.mock'; -const mockDispatch = jest.fn(); -jest.mock('../../../../common/lib/kibana'); +const mockedTelemetry = createTelemetryServiceMock(); +jest.mock('../../../../common/lib/kibana', () => { + const original = jest.requireActual('../../../../common/lib/kibana'); + return { + ...original, + useKibana: () => ({ + ...original.useKibana(), + services: { + ...original.useKibana().services, + telemetry: mockedTelemetry, + }, + }), + }; +}); jest.mock('../../../../common/hooks/use_selector'); jest.mock('../../../store'); + +const mockDispatch = jest.fn(); jest.mock('react-redux', () => { const original = jest.requireActual('react-redux'); return { @@ -80,8 +95,8 @@ describe('useDetailPanel', () => { result.current?.openEventDetailsPanel('123'); - expect(mockDispatch).toHaveBeenCalled(); - expect(timelineActions.toggleDetailPanel).toHaveBeenCalled(); + expect(mockDispatch).not.toHaveBeenCalled(); + expect(timelineActions.toggleDetailPanel).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx index f09462eb8e096..d66053c1128e4 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx @@ -10,7 +10,7 @@ import { useDispatch } from 'react-redux'; import type { EntityType } from '@kbn/timelines-plugin/common'; import { dataTableSelectors } from '@kbn/securitysolution-data-table'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; +import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useKibana } from '../../../../common/lib/kibana'; import type { ExpandedDetailType } from '../../../../../common/types'; import { getScopedActions, isInTableScope, isTimelineScope } from '../../../../helpers'; @@ -21,7 +21,6 @@ import { TimelineTabs } from '../../../../../common/types/timeline'; import { timelineDefaults } from '../../../store/defaults'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; import { DetailsPanel as DetailsPanelComponent } from '..'; -import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../../common/constants'; import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; export interface UseDetailPanelConfig { @@ -49,7 +48,7 @@ export const useDetailPanel = ({ const dispatch = useDispatch(); const { openFlyout } = useExpandableFlyoutApi(); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const getScope = useMemo(() => { if (isTimelineScope(scopeId)) { @@ -98,7 +97,7 @@ export const useDetailPanel = ({ const openEventDetailsPanel = useCallback( (eventId?: string, onClose?: () => void) => { - if (isSecurityFlyoutEnabled) { + if (!expandableFlyoutDisabled) { openFlyout({ right: { id: DocumentDetailsRightPanelKey, @@ -121,16 +120,16 @@ export const useDetailPanel = ({ onPanelClose.current = onClose ?? noopPanelClose; } }, - [isSecurityFlyoutEnabled, openFlyout, eventDetailsIndex, scopeId, telemetry, loadDetailsPanel] + [expandableFlyoutDisabled, openFlyout, eventDetailsIndex, scopeId, telemetry, loadDetailsPanel] ); const handleOnDetailsPanelClosed = useCallback(() => { - if (isSecurityFlyoutEnabled) return; + if (!expandableFlyoutDisabled) return; if (onPanelClose.current) onPanelClose.current(); if (scopedActions) { dispatch(scopedActions.toggleDetailPanel({ tabType, id: scopeId })); } - }, [isSecurityFlyoutEnabled, scopedActions, dispatch, tabType, scopeId]); + }, [expandableFlyoutDisabled, scopedActions, dispatch, tabType, scopeId]); const DetailsPanel = useMemo( () => diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx index 4c9c40712d719..8d46d5438dcbc 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx @@ -10,11 +10,9 @@ import type { PropsWithChildren } from 'react'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { isEventBuildingBlockType } from '@kbn/securitysolution-data-table'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; import { DocumentDetailsRightPanelKey } from '../../../../../flyout/document_details/shared/constants/panel_keys'; -import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../../../common/constants'; import { useDeepEqualSelector } from '../../../../../common/hooks/use_selector'; import type { ColumnHeaderOptions, @@ -111,12 +109,8 @@ const StatefulEventComponent: React.FC = ({ const trGroupRef = useRef(null); const dispatch = useDispatch(); - const expandableTimelineFlyoutEnabled = useIsExperimentalFeatureEnabled( - 'expandableTimelineFlyoutEnabled' - ); - + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const { openFlyout } = useExpandableFlyoutApi(); - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); // Store context in state rather than creating object in provider value={} to prevent re-renders caused by a new object being created const [activeStatefulEventContext] = useState({ @@ -213,7 +207,7 @@ const StatefulEventComponent: React.FC = ({ }, }; - if (isSecurityFlyoutEnabled && expandableTimelineFlyoutEnabled) { + if (!expandableFlyoutDisabled) { openFlyout({ right: { id: DocumentDetailsRightPanelKey, @@ -238,8 +232,7 @@ const StatefulEventComponent: React.FC = ({ dispatch, eventId, event._index, - expandableTimelineFlyoutEnabled, - isSecurityFlyoutEnabled, + expandableFlyoutDisabled, openFlyout, refetch, tabType, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index eb8aa54168461..77bc18fe05802 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -38,6 +38,7 @@ import type { DroppableProvided, DroppableStateSnapshot, } from '@hello-pangea/dnd'; +import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; jest.mock('../../../../common/hooks/use_app_toasts'); jest.mock('../../../../common/components/guided_onboarding_tour/tour_step'); @@ -97,6 +98,13 @@ jest.mock('react-redux', () => { }; }); +const mockOpenFlyout = jest.fn(); +jest.mock('@kbn/expandable-flyout', () => { + return { + useExpandableFlyoutApi: () => ({ openFlyout: mockOpenFlyout }), + }; +}); + jest.mock('../../../../common/components/link_to', () => { const originalModule = jest.requireActual('../../../../common/components/link_to'); return { @@ -415,66 +423,58 @@ describe('Body', () => { beforeEach(() => { mockDispatch.mockReset(); }); - test('call the right reduce action to show event details for query tab', async () => { + + test('open the expandable flyout to show event details for query tab', async () => { const wrapper = await getWrapper(); wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); wrapper.update(); - expect(mockDispatch).toBeCalledTimes(1); - expect(mockDispatch.mock.calls[0][0]).toEqual({ - payload: { - id: 'timeline-test', - panelView: 'eventDetail', + expect(mockDispatch).not.toHaveBeenCalled(); + expect(mockOpenFlyout).toHaveBeenCalledWith({ + right: { + id: DocumentDetailsRightPanelKey, params: { - eventId: '1', + id: '1', indexName: undefined, - refetch: mockRefetch, + scopeId: 'timeline-test', }, - tabType: 'query', }, - type: 'x-pack/security_solution/local/timeline/TOGGLE_DETAIL_PANEL', }); }); - test('call the right reduce action to show event details for pinned tab', async () => { + test('open the expandable flyout to show event details for pinned tab', async () => { const wrapper = await getWrapper(); wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); wrapper.update(); - expect(mockDispatch).toBeCalledTimes(1); - expect(mockDispatch.mock.calls[0][0]).toEqual({ - payload: { - id: 'timeline-test', - panelView: 'eventDetail', + expect(mockDispatch).not.toHaveBeenCalled(); + expect(mockOpenFlyout).toHaveBeenCalledWith({ + right: { + id: DocumentDetailsRightPanelKey, params: { - eventId: '1', + id: '1', indexName: undefined, - refetch: mockRefetch, + scopeId: 'timeline-test', }, - tabType: 'pinned', }, - type: 'x-pack/security_solution/local/timeline/TOGGLE_DETAIL_PANEL', }); }); - test('call the right reduce action to show event details for notes tab', async () => { + test('open the expandable flyout to show event details for notes tab', async () => { const wrapper = await getWrapper(); wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); wrapper.update(); - expect(mockDispatch).toBeCalledTimes(1); - expect(mockDispatch.mock.calls[0][0]).toEqual({ - payload: { - id: 'timeline-test', - panelView: 'eventDetail', + expect(mockDispatch).not.toHaveBeenCalled(); + expect(mockOpenFlyout).toHaveBeenCalledWith({ + right: { + id: DocumentDetailsRightPanelKey, params: { - eventId: '1', + id: '1', indexName: undefined, - refetch: mockRefetch, + scopeId: 'timeline-test', }, - tabType: 'notes', }, - type: 'x-pack/security_solution/local/timeline/TOGGLE_DETAIL_PANEL', }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx index 4514409184ba5..0a9c53a88d689 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx @@ -185,8 +185,7 @@ describe('HostName', () => { test('should open old flyout on table', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newHostDetailsFlyout') return false; - if (feature === 'expandableTimelineFlyoutEnabled') return false; + if (feature === 'expandableFlyoutDisabled') return true; }); const context = { enableHostDetailsFlyout: true, @@ -219,8 +218,7 @@ describe('HostName', () => { test('should open old flyout in timeline', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newHostDetailsFlyout') return false; - if (feature === 'expandableTimelineFlyoutEnabled') return false; + if (feature === 'expandableFlyoutDisabled') return true; }); const context = { enableHostDetailsFlyout: true, @@ -253,8 +251,7 @@ describe('HostName', () => { test('should open expandable flyout on table', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newHostDetailsFlyout') return true; - if (feature === 'expandableTimelineFlyoutEnabled') return false; + if (feature === 'expandableFlyoutDisabled') return false; }); const context = { enableHostDetailsFlyout: true, @@ -288,8 +285,7 @@ describe('HostName', () => { test('should open expandable flyout in timeline', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newHostDetailsFlyout') return true; - if (feature === 'expandableTimelineFlyoutEnabled') return true; + if (feature === 'expandableFlyoutDisabled') return false; }); const context = { enableHostDetailsFlyout: true, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx index 69e0b34b4b3d3..42c5344c7445c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx @@ -14,7 +14,7 @@ import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use import { HostPanelKey } from '../../../../../flyout/entity_details/host_right'; import type { ExpandedDetailType } from '../../../../../../common/types'; import { StatefulEventContext } from '../../../../../common/components/events_viewer/stateful_event_context'; -import { getScopedActions, isTimelineScope } from '../../../../../helpers'; +import { getScopedActions } from '../../../../../helpers'; import { HostDetailsLink } from '../../../../../common/components/links'; import type { TimelineTabs } from '../../../../../../common/types/timeline'; import { DefaultDraggable } from '../../../../../common/components/draggables'; @@ -48,10 +48,7 @@ const HostNameComponent: React.FC = ({ title, value, }) => { - const isNewHostDetailsFlyoutEnabled = useIsExperimentalFeatureEnabled('newHostDetailsFlyout'); - const expandableTimelineFlyoutEnabled = useIsExperimentalFeatureEnabled( - 'expandableTimelineFlyoutEnabled' - ); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const { openRightPanel } = useExpandableFlyoutApi(); const dispatch = useDispatch(); @@ -74,7 +71,7 @@ const HostNameComponent: React.FC = ({ const { timelineID, tabType } = eventContext; - const openNewFlyout = () => + if (!expandableFlyoutDisabled) { openRightPanel({ id: HostPanelKey, params: { @@ -84,7 +81,7 @@ const HostNameComponent: React.FC = ({ isDraggable, }, }); - const openOldFlyout = () => { + } else { const updatedExpandedDetail: ExpandedDetailType = { panelView: 'hostDetail', params: { @@ -101,28 +98,16 @@ const HostNameComponent: React.FC = ({ }) ); } - }; - - if ( - (isTimelineScope(timelineID) && - isNewHostDetailsFlyoutEnabled && - expandableTimelineFlyoutEnabled) || - isNewHostDetailsFlyoutEnabled - ) { - openNewFlyout(); - } else { - openOldFlyout(); } }, [ contextId, dispatch, eventContext, - expandableTimelineFlyoutEnabled, + expandableFlyoutDisabled, hostName, isDraggable, isInTimelineContext, - isNewHostDetailsFlyoutEnabled, onClick, openRightPanel, ] diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx index 426839056e51a..16f881fe90130 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx @@ -159,8 +159,7 @@ describe('UserName', () => { test('should open old flyout on table', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newUserDetailsFlyout') return false; - if (feature === 'expandableTimelineFlyoutEnabled') return false; + if (feature === 'expandableFlyoutDisabled') return true; }); const context = { enableHostDetailsFlyout: true, @@ -193,8 +192,7 @@ describe('UserName', () => { test('should open old flyout in timeline', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newUserDetailsFlyout') return false; - if (feature === 'expandableTimelineFlyoutEnabled') return false; + if (feature === 'expandableFlyoutDisabled') return true; }); const context = { enableHostDetailsFlyout: true, @@ -227,8 +225,7 @@ describe('UserName', () => { test('should open expandable flyout on table', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newUserDetailsFlyout') return true; - if (feature === 'expandableTimelineFlyoutEnabled') return false; + if (feature === 'expandableFlyoutDisabled') return false; }); const context = { enableHostDetailsFlyout: true, @@ -262,8 +259,7 @@ describe('UserName', () => { test('should open expandable flyout in timeline', async () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation((feature: string) => { - if (feature === 'newUserDetailsFlyout') return true; - if (feature === 'expandableTimelineFlyoutEnabled') return true; + if (feature === 'expandableFlyoutDisabled') return false; }); const context = { enableHostDetailsFlyout: true, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx index 39069fc7320bb..78d9ad9c3bdfd 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx @@ -14,7 +14,7 @@ import { UserPanelKey } from '../../../../../flyout/entity_details/user_right'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; import { StatefulEventContext } from '../../../../../common/components/events_viewer/stateful_event_context'; import type { ExpandedDetailType } from '../../../../../../common/types'; -import { getScopedActions, isTimelineScope } from '../../../../../helpers'; +import { getScopedActions } from '../../../../../helpers'; import type { TimelineTabs } from '../../../../../../common/types/timeline'; import { DefaultDraggable } from '../../../../../common/components/draggables'; import { getEmptyTagValue } from '../../../../../common/components/empty_value'; @@ -50,10 +50,7 @@ const UserNameComponent: React.FC = ({ }) => { const dispatch = useDispatch(); const eventContext = useContext(StatefulEventContext); - const isNewUserDetailsFlyoutEnable = useIsExperimentalFeatureEnabled('newUserDetailsFlyout'); - const expandableTimelineFlyoutEnabled = useIsExperimentalFeatureEnabled( - 'expandableTimelineFlyoutEnabled' - ); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const userName = `${value}`; const isInTimelineContext = userName && eventContext?.timelineID; const { openRightPanel } = useExpandableFlyoutApi(); @@ -72,7 +69,7 @@ const UserNameComponent: React.FC = ({ const { timelineID, tabType } = eventContext; - const openNewFlyout = () => + if (!expandableFlyoutDisabled) { openRightPanel({ id: UserPanelKey, params: { @@ -82,8 +79,7 @@ const UserNameComponent: React.FC = ({ isDraggable, }, }); - - const openOldFlyout = () => { + } else { const updatedExpandedDetail: ExpandedDetailType = { panelView: 'userDetail', params: { @@ -100,27 +96,15 @@ const UserNameComponent: React.FC = ({ }) ); } - }; - - if ( - (isTimelineScope(timelineID) && - isNewUserDetailsFlyoutEnable && - expandableTimelineFlyoutEnabled) || - isNewUserDetailsFlyoutEnable - ) { - openNewFlyout(); - } else { - openOldFlyout(); } }, [ contextId, dispatch, eventContext, - expandableTimelineFlyoutEnabled, + expandableFlyoutDisabled, isDraggable, isInTimelineContext, - isNewUserDetailsFlyoutEnable, onClick, openRightPanel, userName, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx index 6095429b2a942..d7e22f116511a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx @@ -149,10 +149,11 @@ export const TimelineDataTableComponent: React.FC = memo( setExpandedDoc((prev) => (!prev ? prev : undefined)); }, []); - const { openFlyout, closeFlyout, isTimelineExpandableFlyoutEnabled } = - useUnifiedTableExpandableFlyout({ + const { openFlyout, closeFlyout, isExpandableFlyoutDisabled } = useUnifiedTableExpandableFlyout( + { onClose: onCloseExpandableFlyout, - }); + } + ); const { browserFields, runtimeMappings } = useSourcererDataView(SourcererScopeName.timeline); @@ -178,7 +179,7 @@ export const TimelineDataTableComponent: React.FC = memo( }, }; - if (isTimelineExpandableFlyoutEnabled) { + if (!isExpandableFlyoutDisabled) { openFlyout({ right: { id: DocumentDetailsRightPanelKey, @@ -201,7 +202,7 @@ export const TimelineDataTableComponent: React.FC = memo( activeTimeline.toggleExpandedDetail({ ...updatedExpandedDetail }); }, - [activeTab, dispatch, refetch, timelineId, isTimelineExpandableFlyoutEnabled, openFlyout] + [activeTab, dispatch, refetch, timelineId, isExpandableFlyoutDisabled, openFlyout] ); const onTimelineLegacyFlyoutClose = useCallback(() => { @@ -225,7 +226,7 @@ export const TimelineDataTableComponent: React.FC = memo( handleOnEventDetailPanelOpened(timelineDoc); } } else { - if (isTimelineExpandableFlyoutEnabled) { + if (!isExpandableFlyoutDisabled) { closeFlyout(); return; } @@ -237,7 +238,7 @@ export const TimelineDataTableComponent: React.FC = memo( handleOnEventDetailPanelOpened, onTimelineLegacyFlyoutClose, closeFlyout, - isTimelineExpandableFlyoutEnabled, + isExpandableFlyoutDisabled, ] ); @@ -462,7 +463,7 @@ export const TimelineDataTableComponent: React.FC = memo( externalControlColumns={leadingControlColumns} cellContext={cellContext} /> - {showExpandedDetails && !isTimelineExpandableFlyoutEnabled && ( + {showExpandedDetails && isExpandableFlyoutDisabled && ( { - beforeEach(() => { + it('should disable expandable flyout when expandableFlyoutDisabled flag is true', () => { (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true); - (useUiSetting$ as jest.Mock).mockReturnValue([true, jest.fn()]); (useLocation as jest.Mock).mockReturnValue({ search: `?${URL_PARAM_KEY.timelineFlyout}=(test:value)`, }); @@ -35,33 +33,25 @@ describe('useUnifiedTimelineExpandableFlyout', () => { openFlyout: jest.fn(), closeFlyout: jest.fn(), }); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - it('should have expandable flyout disabled when flyout is disabled in Advanced Settings', () => { - (useUiSetting$ as jest.Mock).mockReturnValue([false, jest.fn()]); const { result } = renderHook(() => useUnifiedTableExpandableFlyout({ onClose: onFlyoutCloseMock, }) ); - expect(result.current.isTimelineExpandableFlyoutEnabled).toBe(false); + expect(result.current.isExpandableFlyoutDisabled).toBe(true); }); - it('should have expandable flyout disabled when flyout is disabled in Experimental Features', () => { - (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false); - const { result } = renderHook(() => - useUnifiedTableExpandableFlyout({ - onClose: onFlyoutCloseMock, - }) - ); - expect(result.current.isTimelineExpandableFlyoutEnabled).toBe(false); - }); - describe('when flyout is enabled', () => { + describe('when expandable flyout is enabled', () => { + beforeEach(() => { + (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + it('should mark flyout as closed when location is empty', () => { (useLocation as jest.Mock).mockReturnValue({ search: '', @@ -73,20 +63,21 @@ describe('useUnifiedTimelineExpandableFlyout', () => { }) ); - expect(result.current.isTimelineExpandableFlyoutOpen).toBe(false); + expect(result.current.isExpandableFlyoutDisabled).toBe(false); }); it('should mark flyout as open when location has `timelineFlyout`', () => { (useLocation as jest.Mock).mockReturnValue({ search: `${URL_PARAM_KEY.timelineFlyout}=(test:value)`, }); + const { result } = renderHook(() => useUnifiedTableExpandableFlyout({ onClose: onFlyoutCloseMock, }) ); - expect(result.current.isTimelineExpandableFlyoutOpen).toBe(true); + expect(result.current.isExpandableFlyoutDisabled).toBe(false); }); it('should mark flyout as close when location has empty `timelineFlyout`', () => { @@ -95,7 +86,8 @@ describe('useUnifiedTimelineExpandableFlyout', () => { onClose: onFlyoutCloseMock, }) ); - expect(result.current.isTimelineExpandableFlyoutOpen).toBe(true); + + expect(result.current.isExpandableFlyoutDisabled).toBe(false); (useLocation as jest.Mock).mockReturnValue({ search: `${URL_PARAM_KEY.timelineFlyout}=()`, @@ -115,6 +107,7 @@ describe('useUnifiedTimelineExpandableFlyout', () => { ); result.current.closeFlyout(); + expect(onFlyoutCloseMock).toHaveBeenCalledTimes(1); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/hooks/use_unified_timeline_expandable_flyout.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/hooks/use_unified_timeline_expandable_flyout.tsx index 31433d54a5cd0..83050110eb090 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/hooks/use_unified_timeline_expandable_flyout.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/hooks/use_unified_timeline_expandable_flyout.tsx @@ -6,11 +6,9 @@ */ import { useCallback, useEffect, useMemo, useState } from 'react'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { useLocation } from 'react-router-dom'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../../../common/constants'; import { URL_PARAM_KEY } from '../../../../../common/hooks/use_url_state'; const EMPTY_TIMELINE_FLYOUT_SEARCH_PARAMS = '()'; @@ -22,11 +20,7 @@ interface UseUnifiedTableExpandableFlyoutArgs { export const useUnifiedTableExpandableFlyout = ({ onClose, }: UseUnifiedTableExpandableFlyoutArgs) => { - const expandableTimelineFlyoutEnabled = useIsExperimentalFeatureEnabled( - 'expandableTimelineFlyoutEnabled' - ); - - const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableFlyoutDisabled = useIsExperimentalFeatureEnabled('expandableFlyoutDisabled'); const location = useLocation(); @@ -77,6 +71,6 @@ export const useUnifiedTableExpandableFlyout = ({ isTimelineExpandableFlyoutOpen, openFlyout, closeFlyout: closeFlyoutWithEffect, - isTimelineExpandableFlyoutEnabled: expandableTimelineFlyoutEnabled && isSecurityFlyoutEnabled, + isExpandableFlyoutDisabled: expandableFlyoutDisabled, }; }; diff --git a/x-pack/plugins/security_solution/server/ui_settings.ts b/x-pack/plugins/security_solution/server/ui_settings.ts index 238fb1655728a..1c946ec2cefdd 100644 --- a/x-pack/plugins/security_solution/server/ui_settings.ts +++ b/x-pack/plugins/security_solution/server/ui_settings.ts @@ -36,7 +36,6 @@ import { EXTENDED_RULE_EXECUTION_LOGGING_MIN_LEVEL_SETTING, DEFAULT_ALERT_TAGS_KEY, DEFAULT_ALERT_TAGS_VALUE, - ENABLE_EXPANDABLE_FLYOUT_SETTING, EXCLUDE_COLD_AND_FROZEN_TIERS_IN_ANALYZER, ENABLE_ASSET_CRITICALITY_SETTING, } from '../common/constants'; @@ -177,23 +176,6 @@ export const initUiSettings = ( requiresPageReload: true, schema: schema.boolean(), }, - [ENABLE_EXPANDABLE_FLYOUT_SETTING]: { - name: i18n.translate('xpack.securitySolution.uiSettings.enableExpandableFlyoutLabel', { - defaultMessage: 'Expandable flyout', - }), - value: true, - description: i18n.translate( - 'xpack.securitySolution.uiSettings.enableExpandableFlyoutDescription', - { - defaultMessage: '

Enables the expandable flyout

', - values: { p: (chunks) => `

${chunks}

` }, - } - ), - type: 'boolean', - category: [APP_ID], - requiresPageReload: true, - schema: schema.boolean(), - }, [ENABLE_ASSET_CRITICALITY_SETTING]: { name: i18n.translate('xpack.securitySolution.uiSettings.enableAssetCriticalityTitle', { defaultMessage: 'Asset Criticality', diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index f232799d9e1ef..11ed11bd9a763 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -33198,7 +33198,6 @@ "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

Période de temps par défaut dans le filtre de temps Security.

", "xpack.securitySolution.uiSettings.enableAssetCriticalityDescription": "

Permet des flux de travail pour l'affectation de l'état critique des actifs et ses contributions au risque de l'entité

", "xpack.securitySolution.uiSettings.enableCcsWarningDescription": "

Active les avertissements de vérification des privilèges dans les règles relatives aux index CCS

", - "xpack.securitySolution.uiSettings.enableExpandableFlyoutDescription": "

Active le menu déroulant

", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

Active le fil d'actualités

", "xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzerDescription": "

Lorsque cette option est activée, les niveaux \"cold\" et \"frozen\" sont ignorés dans les requêtes de l'analyseur

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledDescription": "

Active l'exécution de règle étendue pour le logging dans les index .kibana-event-log-*. Affiche les événements d'exécution simples sur la page Détails de la règle.

", @@ -37844,7 +37843,6 @@ "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "Période du filtre de temps", "xpack.securitySolution.uiSettings.enableAssetCriticalityTitle": "Criticité des ressources", "xpack.securitySolution.uiSettings.enableCcsReadWarningLabel": "Avertissement lié aux privilèges de la règle CCS", - "xpack.securitySolution.uiSettings.enableExpandableFlyoutLabel": "Menu volant déroulant", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "Fil d'actualités", "xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzer": "Exclure les niveaux froids de l'analyseur", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledLabel": "Logging étendu de l’exécution des règles", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c900fb526b19e..1875ea6d86efc 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -33169,7 +33169,6 @@ "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

セキュリティ時間フィルダーのデフォルトの期間です。

", "xpack.securitySolution.uiSettings.enableAssetCriticalityDescription": "

アセット重要度割り当てワークフローとエンティティリスクへの寄与を有効化します

", "xpack.securitySolution.uiSettings.enableCcsWarningDescription": "

CCSインデックスのルールで権限チェック警告を有効にします

", - "xpack.securitySolution.uiSettings.enableExpandableFlyoutDescription": "

展開可能なフライアウトを有効にします

", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

ニュースフィードを有効にします

", "xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzerDescription": "

有効にすると、アナライザークエリでコールドティアとフローズンティアがスキップされます

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledDescription": "

.kibana-event-log-*インデックスへの拡張ルール実行ログを有効にします。[ルール詳細]ページでプレーン実行イベントが表示されます。

", @@ -37815,7 +37814,6 @@ "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "時間フィルターの期間", "xpack.securitySolution.uiSettings.enableAssetCriticalityTitle": "アセット重要度", "xpack.securitySolution.uiSettings.enableCcsReadWarningLabel": "CCSルール権限警告", - "xpack.securitySolution.uiSettings.enableExpandableFlyoutLabel": "展開可能なフライアウト", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "ニュースフィード", "xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzer": "アナライザーでコールドティアとフローズンティアを除外", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledLabel": "拡張ルール実行ログ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 895881c1758ec..95b7203e9d1dc 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -33212,7 +33212,6 @@ "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

Security 时间筛选中的默认时段。

", "xpack.securitySolution.uiSettings.enableAssetCriticalityDescription": "

启用资产关键度分配工作流及其对实体风险的贡献率

", "xpack.securitySolution.uiSettings.enableCcsWarningDescription": "

在规则中为 CCS 索引启用权限检查警告

", - "xpack.securitySolution.uiSettings.enableExpandableFlyoutDescription": "

启用可展开的浮出控件

", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

启用新闻源

", "xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzerDescription": "

启用后,将在分析器查询中跳过冷层和冻结层

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledDescription": "

对 .kibana-event-log-* 索引启用扩展规则执行日志记录。在“规则详情”页面上显示纯执行事件。

", @@ -37858,7 +37857,6 @@ "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "时间筛选时段", "xpack.securitySolution.uiSettings.enableAssetCriticalityTitle": "资产关键度", "xpack.securitySolution.uiSettings.enableCcsReadWarningLabel": "CCS 规则权限警告", - "xpack.securitySolution.uiSettings.enableExpandableFlyoutLabel": "可展开的浮出控件", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "新闻源", "xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzer": "在分析器中排除冷层和冻结层", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledLabel": "扩展规则执行日志记录", diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/enrichments/alert_threat_enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/enrichments/alert_threat_enrichments.cy.ts index 383abd2e12d42..71dd0387a6451 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/enrichments/alert_threat_enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/enrichments/alert_threat_enrichments.cy.ts @@ -5,28 +5,28 @@ * 2.0. */ -import { disableExpandableFlyout } from '../../../../../tasks/api_calls/kibana_advanced_settings'; import { getNewThreatIndicatorRule, indicatorRuleMatchingDoc } from '../../../../../objects/rule'; import { login } from '../../../../../tasks/login'; import { - JSON_TEXT, TABLE_CELL, TABLE_ROWS, THREAT_DETAILS_VIEW, - ENRICHMENT_COUNT_NOTIFICATION, INDICATOR_MATCH_ENRICHMENT_SECTION, INVESTIGATION_TIME_ENRICHMENT_SECTION, THREAT_DETAILS_ACCORDION, } from '../../../../../screens/alerts_details'; import { TIMELINE_FIELD } from '../../../../../screens/rule_details'; -import { - expandFirstAlert, - setEnrichmentDates, - viewThreatIntelTab, -} from '../../../../../tasks/alerts'; +import { expandFirstAlert, setEnrichmentDates } from '../../../../../tasks/alerts'; import { createRule } from '../../../../../tasks/api_calls/rules'; -import { openJsonView, openThreatIndicatorDetails } from '../../../../../tasks/alerts_details'; import { addsFieldsToTimeline, visitRuleDetailsPage } from '../../../../../tasks/rule_details'; +import { + expandDocumentDetailsExpandableFlyoutLeftSection, + openTableTab, +} from '../../../../../tasks/expandable_flyout/alert_details_right_panel'; +import { filterTableTabTable } from '../../../../../tasks/expandable_flyout/alert_details_right_panel_table_tab'; +import { DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_THREAT_ENRICHMENTS } from '../../../../../screens/expandable_flyout/alert_details_right_panel_table_tab'; +import { openThreatIntelligenceTab } from '../../../../../tasks/expandable_flyout/alert_details_left_panel_threat_intelligence_tab'; +import { openInsightsTab } from '../../../../../tasks/expandable_flyout/alert_details_left_panel'; // TODO: https://github.com/elastic/kibana/issues/161539 describe('Threat Match Enrichment', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { @@ -35,8 +35,6 @@ describe('Threat Match Enrichment', { tags: ['@ess', '@serverless', '@skipInServ cy.task('esArchiverLoad', { archiveName: 'threat_indicator' }); cy.task('esArchiverLoad', { archiveName: 'suspicious_source_event' }); login(); - - disableExpandableFlyout(); }); after(() => { @@ -71,39 +69,37 @@ describe('Threat Match Enrichment', { tags: ['@ess', '@serverless', '@skipInServ }); }); - it('Displays persisted enrichments on the JSON view', () => { - const expectedEnrichment = [ - { - 'indicator.file.hash.md5': ['9b6c3518a91d23ed77504b5416bfb5b3'], - 'matched.index': ['logs-ti_abusech.malware'], - 'indicator.file.type': ['elf'], - 'indicator.file.hash.tlsh': [ - '6D7312E017B517CC1371A8353BED205E9128223972AE35302E97528DF957703BAB2DBE', - ], - 'feed.name': ['AbuseCH malware'], - 'indicator.file.hash.ssdeep': [ - '1536:87vbq1lGAXSEYQjbChaAU2yU23M51DjZgSQAvcYkFtZTjzBht5:8D+CAXFYQChaAUk5ljnQssL', - ], - 'indicator.file.hash.sha256': [ - 'a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3', - ], - 'indicator.first_seen': ['2021-03-10T08:02:14.000Z'], - 'matched.field': ['myhash.mysha256'], - 'indicator.type': ['file'], - 'matched.type': ['indicator_match_rule'], - 'matched.id': ['84cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f'], - 'matched.atomic': ['a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3'], - 'indicator.file.size': [80280], - }, - ]; + it('Displays persisted enrichments on the Table tab', () => { + const expectedEnrichment = { + 'indicator.file.hash.md5': ['9b6c3518a91d23ed77504b5416bfb5b3'], + 'matched.index': ['logs-ti_abusech.malware'], + 'indicator.file.type': ['elf'], + 'indicator.file.hash.tlsh': [ + '6D7312E017B517CC1371A8353BED205E9128223972AE35302E97528DF957703BAB2DBE', + ], + 'feed.name': ['AbuseCH malware'], + 'indicator.file.hash.ssdeep': [ + '1536:87vbq1lGAXSEYQjbChaAU2yU23M51DjZgSQAvcYkFtZTjzBht5:8D+CAXFYQChaAUk5ljnQssL', + ], + 'indicator.file.hash.sha256': [ + 'a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3', + ], + 'indicator.first_seen': ['2021-03-10T08:02:14.000Z'], + 'matched.field': ['myhash.mysha256'], + 'indicator.type': ['file'], + 'matched.type': ['indicator_match_rule'], + 'matched.id': ['84cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f'], + 'matched.atomic': ['a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3'], + 'indicator.file.size': [80280], + }; expandFirstAlert(); - openJsonView(); + openTableTab(); + filterTableTabTable('threat.enrichments'); - cy.get(JSON_TEXT).then((x) => { - const parsed = JSON.parse(x.text()); - expect(parsed.fields['threat.enrichments']).to.deep.equal(expectedEnrichment); - }); + cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_THREAT_ENRICHMENTS).contains( + JSON.stringify(expectedEnrichment) + ); }); it('Displays threat indicator details on the threat intel tab', () => { @@ -140,9 +136,10 @@ describe('Threat Match Enrichment', { tags: ['@ess', '@serverless', '@skipInServ ]; expandFirstAlert(); - openThreatIndicatorDetails(); + expandDocumentDetailsExpandableFlyoutLeftSection(); + openInsightsTab(); + openThreatIntelligenceTab(); - cy.get(ENRICHMENT_COUNT_NOTIFICATION).should('have.text', '1'); cy.get(THREAT_DETAILS_VIEW).within(() => { cy.get(TABLE_ROWS).should('have.length', expectedThreatIndicatorData.length); expectedThreatIndicatorData.forEach((row, index) => { @@ -178,7 +175,9 @@ describe('Threat Match Enrichment', { tags: ['@ess', '@serverless', '@skipInServ }; expandFirstAlert(); - viewThreatIntelTab(); + expandDocumentDetailsExpandableFlyoutLeftSection(); + openInsightsTab(); + openThreatIntelligenceTab(); setEnrichmentDates('08/05/2018 10:00 AM'); cy.get(`${INDICATOR_MATCH_ENRICHMENT_SECTION} ${THREAT_DETAILS_ACCORDION}`) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts index 3bd09ee00000f..aff9307111beb 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts @@ -23,7 +23,6 @@ import { scrollAlertTableColumnIntoView, closeAlertFlyout, } from '../../tasks/alerts'; -import { disableExpandableFlyout } from '../../tasks/api_calls/kibana_advanced_settings'; import { login } from '../../tasks/login'; import { visitWithTimeRange } from '../../tasks/navigation'; @@ -34,96 +33,109 @@ import { mockRiskEngineEnabled } from '../../tasks/entity_analytics'; const CURRENT_HOST_RISK_LEVEL = 'Current host risk level'; const ORIGINAL_HOST_RISK_LEVEL = 'Original host risk level'; -describe('Enrichment', { tags: ['@ess', '@serverless'] }, () => { - before(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_updated' }); - cy.task('esArchiverLoad', { archiveName: 'risk_users' }); - }); +describe( + 'Enrichment', + { + tags: ['@ess', '@serverless'], + env: { + ftrConfig: { + kbnServerArgs: [ + `--xpack.securitySolution.enableExperimental=${JSON.stringify([ + 'expandableFlyoutDisabled', + ])}`, + ], + }, + }, + }, + () => { + before(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_updated' }); + cy.task('esArchiverLoad', { archiveName: 'risk_users' }); + }); - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_users' }); - }); + after(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_users' }); + }); - describe('Custom query rule', () => { - // FLAKY: https://github.com/elastic/kibana/issues/176965 - describe.skip('from legacy risk scores', () => { - beforeEach(() => { - disableExpandableFlyout(); - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - deleteAlertsAndRules(); - createRule(getNewRule({ rule_id: 'rule1' })); - login(); - visitWithTimeRange(ALERTS_URL); - waitForAlertsToPopulate(); - }); + describe('Custom query rule', () => { + // FLAKY: https://github.com/elastic/kibana/issues/176965 + describe.skip('from legacy risk scores', () => { + beforeEach(() => { + cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); + deleteAlertsAndRules(); + createRule(getNewRule({ rule_id: 'rule1' })); + login(); + visitWithTimeRange(ALERTS_URL); + waitForAlertsToPopulate(); + }); - afterEach(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - cy.task('esArchiverUnload', { archiveName: 'risk_hosts_updated' }); - }); + afterEach(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); + cy.task('esArchiverUnload', { archiveName: 'risk_hosts_updated' }); + }); - it('Should has enrichment fields from legacy risk', function () { - cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); - cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); - scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); - cy.get(HOST_RISK_COLUMN).contains('Low'); - scrollAlertTableColumnIntoView(USER_RISK_COLUMN); - cy.get(USER_RISK_COLUMN).contains('Low'); - scrollAlertTableColumnIntoView(ACTION_COLUMN); - expandFirstAlert(); - cy.get(ENRICHED_DATA_ROW).contains('Low'); - cy.get(ENRICHED_DATA_ROW).contains(CURRENT_HOST_RISK_LEVEL); - cy.get(ENRICHED_DATA_ROW).contains('Critical').should('not.exist'); - cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL).should('not.exist'); + it('Should has enrichment fields from legacy risk', function () { + cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); + cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); + scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); + cy.get(HOST_RISK_COLUMN).contains('Low'); + scrollAlertTableColumnIntoView(USER_RISK_COLUMN); + cy.get(USER_RISK_COLUMN).contains('Low'); + scrollAlertTableColumnIntoView(ACTION_COLUMN); + expandFirstAlert(); + cy.get(ENRICHED_DATA_ROW).contains('Low'); + cy.get(ENRICHED_DATA_ROW).contains(CURRENT_HOST_RISK_LEVEL); + cy.get(ENRICHED_DATA_ROW).contains('Critical').should('not.exist'); + cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL).should('not.exist'); - closeAlertFlyout(); - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - cy.task('esArchiverLoad', { archiveName: 'risk_hosts_updated' }); - expandFirstAlert(); - cy.get(ENRICHED_DATA_ROW).contains('Critical'); - cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL); + closeAlertFlyout(); + cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); + cy.task('esArchiverLoad', { archiveName: 'risk_hosts_updated' }); + expandFirstAlert(); + cy.get(ENRICHED_DATA_ROW).contains('Critical'); + cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL); + }); }); - }); - describe('from new risk scores', () => { - beforeEach(() => { - disableExpandableFlyout(); - cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); - deleteAlertsAndRules(); - createRule(getNewRule({ rule_id: 'rule1' })); - login(); - mockRiskEngineEnabled(); - visitWithTimeRange(ALERTS_URL); - waitForAlertsToPopulate(); - }); + describe('from new risk scores', () => { + beforeEach(() => { + cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); + deleteAlertsAndRules(); + createRule(getNewRule({ rule_id: 'rule1' })); + login(); + mockRiskEngineEnabled(); + visitWithTimeRange(ALERTS_URL); + waitForAlertsToPopulate(); + }); - afterEach(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_updated' }); - }); + afterEach(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_updated' }); + }); - it('Should has enrichment fields from legacy risk', function () { - cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); - cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); - scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); - cy.get(HOST_RISK_COLUMN).contains('Critical'); - scrollAlertTableColumnIntoView(USER_RISK_COLUMN); - cy.get(USER_RISK_COLUMN).contains('High'); - scrollAlertTableColumnIntoView(ACTION_COLUMN); - expandFirstAlert(); - cy.get(ENRICHED_DATA_ROW).contains('Critical'); - cy.get(ENRICHED_DATA_ROW).contains(CURRENT_HOST_RISK_LEVEL); - cy.get(ENRICHED_DATA_ROW).contains('Low').should('not.exist'); - cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL).should('not.exist'); + it('Should has enrichment fields from legacy risk', function () { + cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); + cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); + scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); + cy.get(HOST_RISK_COLUMN).contains('Critical'); + scrollAlertTableColumnIntoView(USER_RISK_COLUMN); + cy.get(USER_RISK_COLUMN).contains('High'); + scrollAlertTableColumnIntoView(ACTION_COLUMN); + expandFirstAlert(); + cy.get(ENRICHED_DATA_ROW).contains('Critical'); + cy.get(ENRICHED_DATA_ROW).contains(CURRENT_HOST_RISK_LEVEL); + cy.get(ENRICHED_DATA_ROW).contains('Low').should('not.exist'); + cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL).should('not.exist'); - closeAlertFlyout(); - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); - cy.task('esArchiverLoad', { archiveName: 'risk_scores_new_updated' }); - expandFirstAlert(); - cy.get(ENRICHED_DATA_ROW).contains('Low'); - cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL); + closeAlertFlyout(); + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); + cy.task('esArchiverLoad', { archiveName: 'risk_scores_new_updated' }); + expandFirstAlert(); + cy.get(ENRICHED_DATA_ROW).contains('Low'); + cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL); + }); }); }); - }); -}); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/guided_onboarding/tour.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/guided_onboarding/tour.cy.ts index cebc67a78d2ef..39dd027bdd86d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/guided_onboarding/tour.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/guided_onboarding/tour.cy.ts @@ -6,7 +6,6 @@ */ import { AlertsCasesTourSteps } from '@kbn/security-solution-plugin/public/common/components/guided_onboarding_tour/tour_config'; -import { disableExpandableFlyout } from '../../../tasks/api_calls/kibana_advanced_settings'; import { navigateFromHeaderTo } from '../../../tasks/security_header'; import { ALERTS, TIMELINES } from '../../../screens/security_header'; import { closeAlertFlyout, expandFirstAlert } from '../../../tasks/alerts'; @@ -35,7 +34,6 @@ describe('Guided onboarding tour', { tags: ['@ess'] }, () => { deleteAlertsAndRules(); createRule(getNewRule({ query: 'user.name:*' })); login(); - disableExpandableFlyout(); startAlertsCasesTour(); visit(ALERTS_URL); waitForAlertsToPopulate(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts index 241add1703248..b9655de8eab03 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { disableExpandableFlyout } from '../../../tasks/api_calls/kibana_advanced_settings'; import { ALERT_FLYOUT, CELL_TEXT, @@ -38,13 +37,14 @@ import { waitForPageToBeLoaded as waitForRuleDetailsPageToBeLoaded, } from '../../../tasks/rule_details'; -describe('Alert details flyout', { tags: ['@ess', '@serverless'] }, () => { +// this functionality is now not used anymore (though still accessible if customers turn the `expandableFlyoutDisabled` feature flag on +// the code will be removed entirely for `8.16 (see https://github.com/elastic/security-team/issues/7462) +describe.skip('Alert details flyout', { tags: ['@ess', '@serverless'] }, () => { describe('Basic functions', () => { beforeEach(() => { deleteAlertsAndRules(); createRule(getNewRule()); login(); - disableExpandableFlyout(); visit(ALERTS_URL); waitForAlertsToPopulate(); expandFirstAlert(); @@ -70,7 +70,6 @@ describe('Alert details flyout', { tags: ['@ess', '@serverless'] }, () => { deleteAlertsAndRules(); createRule({ ...getUnmappedRule(), investigation_fields: { field_names: ['event.kind'] } }); login(); - disableExpandableFlyout(); visit(ALERTS_URL); waitForAlertsToPopulate(); expandFirstAlert(); @@ -143,7 +142,6 @@ describe('Alert details flyout', { tags: ['@ess', '@serverless'] }, () => { deleteAlertsAndRules(); createRule(getNewRule()); login(); - disableExpandableFlyout(); visitWithTimeRange(ALERTS_URL); waitForAlertsToPopulate(); expandFirstAlert(); @@ -196,7 +194,6 @@ describe('Alert details flyout', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { createRule(getNewRule()); login(); - disableExpandableFlyout(); visitWithTimeRange(ALERTS_URL); waitForAlertsToPopulate(); expandFirstAlert(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/investigate_in_timeline.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/investigate_in_timeline.cy.ts index dcff07d7d9ced..b763260f4da3e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/investigate_in_timeline.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/investigate_in_timeline.cy.ts @@ -5,105 +5,123 @@ * 2.0. */ -import { disableExpandableFlyout } from '../../../tasks/api_calls/kibana_advanced_settings'; import { getNewRule } from '../../../objects/rule'; import { + ANALYZER_GRAPH_TAB_BUTTON, PROVIDER_BADGE, QUERY_TAB_BUTTON, - TIMELINE_FILTER_BADGE, TIMELINE_TITLE, } from '../../../screens/timeline'; - -import { expandFirstAlert, investigateFirstAlertInTimeline } from '../../../tasks/alerts'; +import { closeTimeline } from '../../../tasks/timeline'; +import { investigateFirstAlertInTimeline } from '../../../tasks/alerts'; import { createRule } from '../../../tasks/api_calls/rules'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visitWithTimeRange } from '../../../tasks/navigation'; - import { ALERTS_URL } from '../../../urls/navigation'; -import { - ALERT_FLYOUT, - INSIGHTS_INVESTIGATE_ANCESTRY_ALERTS_IN_TIMELINE_BUTTON, - INSIGHTS_INVESTIGATE_IN_TIMELINE_BUTTON, - INSIGHTS_RELATED_ALERTS_BY_ANCESTRY, - INSIGHTS_RELATED_ALERTS_BY_SESSION, - SUMMARY_VIEW_INVESTIGATE_IN_TIMELINE_BUTTON, -} from '../../../screens/alerts_details'; -import { verifyInsightCount } from '../../../tasks/alerts_details'; import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; +import { expandAlertAtIndexExpandableFlyout } from '../../../tasks/expandable_flyout/common'; +import { + clickAnalyzerPreviewTitleToOpenTimeline, + toggleOverviewTabAboutSection, + toggleOverviewTabInvestigationSection, + toggleOverviewTabVisualizationsSection, +} from '../../../tasks/expandable_flyout/alert_details_right_panel_overview_tab'; +import { + expandDocumentDetailsExpandableFlyoutLeftSection, + openTakeActionButton, + selectTakeActionItem, +} from '../../../tasks/expandable_flyout/alert_details_right_panel'; +import { DOCUMENT_DETAILS_FLYOUT_FOOTER_INVESTIGATE_IN_TIMELINE } from '../../../screens/expandable_flyout/alert_details_right_panel'; +import { + openTimelineFromPrevalenceTableCell, + openPrevalenceTab, +} from '../../../tasks/expandable_flyout/alert_details_left_panel_prevalence_tab'; +import { + openCorrelationsTab, + openTimelineFromRelatedByAncestry, + openTimelineFromRelatedBySession, + openTimelineFromRelatedSourceEvent, +} from '../../../tasks/expandable_flyout/alert_details_left_panel_correlations_tab'; -describe('Investigate in timeline', { tags: ['@ess', '@serverless'] }, () => { - beforeEach(() => { - deleteAlertsAndRules(); - createRule(getNewRule()); - }); - - describe('From alerts table', () => { +describe( + 'Investigate in timeline', + { + tags: ['@ess', '@serverless'], + }, + () => { beforeEach(() => { + deleteAlertsAndRules(); + createRule(getNewRule()); login(); visitWithTimeRange(ALERTS_URL); waitForAlertsToPopulate(); }); - it('should open new timeline from alerts table', () => { - investigateFirstAlertInTimeline(); - cy.get(PROVIDER_BADGE) - .first() - .invoke('text') - .then((eventId) => { - cy.get(PROVIDER_BADGE).filter(':visible').should('have.text', eventId); - }); + describe('From alerts table', () => { + it('should open new timeline from alerts table', () => { + investigateFirstAlertInTimeline(); + cy.get(PROVIDER_BADGE) + .first() + .invoke('text') + .then((eventId) => { + cy.get(PROVIDER_BADGE).filter(':visible').should('have.text', eventId); + }); + }); }); - }); - describe('From alerts details flyout', () => { - beforeEach(() => { - login(); - disableExpandableFlyout(); - visitWithTimeRange(ALERTS_URL); - waitForAlertsToPopulate(); - expandFirstAlert(); - }); + describe('From alerts details flyout', () => { + beforeEach(() => { + expandAlertAtIndexExpandableFlyout(); + }); - it('should open a new timeline from a prevalence field', () => { - // Only one alert matches the exact process args in this case - const alertCount = 1; - - // Click on the last button that lets us investigate in timeline. - // We expect this to be the `process.args` row. - cy.get(ALERT_FLYOUT).find(SUMMARY_VIEW_INVESTIGATE_IN_TIMELINE_BUTTON).eq(5).scrollIntoView(); - cy.get(ALERT_FLYOUT) - .find(SUMMARY_VIEW_INVESTIGATE_IN_TIMELINE_BUTTON) - .eq(5) - .should('be.visible') - .and('have.text', alertCount) - .click(); - - // Make sure a new timeline is created and opened - cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); - - // The alert count in this timeline should match the count shown on the alert flyout - cy.get(QUERY_TAB_BUTTON).should('contain.text', alertCount); - - // The correct filter is applied to the timeline query - cy.get(TIMELINE_FILTER_BADGE).should( - 'have.text', - ' {"bool":{"must":[{"term":{"process.args":"-zsh"}},{"term":{"process.args":"unique"}}]}}' - ); - }); + it('should open a new timeline from take action button', () => { + openTakeActionButton(); + selectTakeActionItem(DOCUMENT_DETAILS_FLYOUT_FOOTER_INVESTIGATE_IN_TIMELINE); - it('should open a new timeline from an insights module', () => { - verifyInsightCount({ - tableSelector: INSIGHTS_RELATED_ALERTS_BY_SESSION, - investigateSelector: INSIGHTS_INVESTIGATE_IN_TIMELINE_BUTTON, + cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); + cy.get(QUERY_TAB_BUTTON).should('have.class', 'euiTab-isSelected'); }); - }); - it('should open a new timeline with alert ids from the process ancestry', () => { - verifyInsightCount({ - tableSelector: INSIGHTS_RELATED_ALERTS_BY_ANCESTRY, - investigateSelector: INSIGHTS_INVESTIGATE_ANCESTRY_ALERTS_IN_TIMELINE_BUTTON, + it('should open a new timeline from analyzer graph preview', () => { + toggleOverviewTabAboutSection(); + toggleOverviewTabInvestigationSection(); + toggleOverviewTabVisualizationsSection(); + clickAnalyzerPreviewTitleToOpenTimeline(); + + cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); + cy.get(ANALYZER_GRAPH_TAB_BUTTON).should('have.class', 'euiTab-isSelected'); + }); + + it('should open a new timeline from the prevalence detail table', () => { + expandDocumentDetailsExpandableFlyoutLeftSection(); + openPrevalenceTab(); + openTimelineFromPrevalenceTableCell(); + + cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); + cy.get(QUERY_TAB_BUTTON).should('have.class', 'euiTab-isSelected'); + }); + + it('should open a new timeline from the correlations tab', () => { + expandDocumentDetailsExpandableFlyoutLeftSection(); + openCorrelationsTab(); + openTimelineFromRelatedSourceEvent(); + + cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); + cy.get(QUERY_TAB_BUTTON).should('have.class', 'euiTab-isSelected'); + + closeTimeline(); + openTimelineFromRelatedBySession(); + + cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); + cy.get(QUERY_TAB_BUTTON).should('have.class', 'euiTab-isSelected'); + + closeTimeline(); + openTimelineFromRelatedByAncestry(); + + cy.get(TIMELINE_TITLE).should('have.text', 'Untitled timeline'); + cy.get(QUERY_TAB_BUTTON).should('have.class', 'euiTab-isSelected'); }); }); - }); -}); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/alerts_details.ts b/x-pack/test/security_solution_cypress/cypress/screens/alerts_details.ts index 70f43b35d1211..6f9ee7b4aea77 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/alerts_details.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/alerts_details.ts @@ -9,8 +9,6 @@ export const ALERT_FLYOUT = '[data-test-subj="timeline:details-panel:flyout"]'; export const CELL_TEXT = '.euiText'; -export const ENRICHMENT_COUNT_NOTIFICATION = '[data-test-subj="enrichment-count-notification"]'; - export const ENRICHMENT_QUERY_RANGE_PICKER = '[data-test-subj="enrichment-query-range-picker"]'; export const ENRICHMENT_QUERY_START_INPUT = '.start-picker'; @@ -26,7 +24,7 @@ export const INVESTIGATION_TIME_ENRICHMENT_SECTION = export const JSON_VIEW_TAB = '[data-test-subj="jsonViewTab"]'; -export const JSON_TEXT = '[data-test-subj="jsonView"]'; +export const JSON_TEXT = '[data-test-subj="kibanaCodeEditor"]'; export const OVERVIEW_RULE = '[data-test-subj="eventDetails"] [data-test-subj="ruleName"]'; @@ -41,10 +39,6 @@ export const TABLE_CELL = '.euiTableRowCell'; export const CELL_EXPAND_VALUE = '[data-test-subj="euiDataGridCellExpandButton"]'; -export const CELL_EXPANSION_POPOVER = '[data-test-subj="euiDataGridExpansionPopover"]'; - -export const USER_DETAILS_LINK = '[data-test-subj="users-link-anchor"]'; - export const TABLE_TAB = '[data-test-subj="tableTab"]'; export const TABLE_CONTAINER = '[data-test-subj="event-fields-browser"]'; @@ -59,16 +53,6 @@ export const THREAT_INTEL_TAB = '[data-test-subj="threatIntelTab"]'; export const UPDATE_ENRICHMENT_RANGE_BUTTON = '[data-test-subj="enrichment-button"]'; -export const SUMMARY_VIEW_INVESTIGATE_IN_TIMELINE_BUTTON = `${SUMMARY_VIEW} [aria-label='Investigate in timeline']`; - -export const INSIGHTS_RELATED_ALERTS_BY_SESSION = `[data-test-subj='related-alerts-by-session']`; - -export const INSIGHTS_INVESTIGATE_IN_TIMELINE_BUTTON = `${INSIGHTS_RELATED_ALERTS_BY_SESSION} [aria-label='Investigate in timeline']`; - -export const INSIGHTS_RELATED_ALERTS_BY_ANCESTRY = `[data-test-subj='related-alerts-by-ancestry']`; - -export const INSIGHTS_INVESTIGATE_ANCESTRY_ALERTS_IN_TIMELINE_BUTTON = `[data-test-subj='investigate-ancestry-in-timeline']`; - export const ENRICHED_DATA_ROW = `[data-test-subj='EnrichedDataRow']`; export const COPY_ALERT_FLYOUT_LINK = `[data-test-subj="copy-alert-flyout-link"]`; diff --git a/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts b/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts index 0a0a7e0edbe38..33e625d1db89a 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts @@ -104,6 +104,8 @@ export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_VISUALIZATIONS_SECTION_HEADER getDataTestSubjectSelector('securitySolutionFlyoutVisualizationsHeader'); export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_VISUALIZATIONS_SECTION_CONTENT = getDataTestSubjectSelector('securitySolutionFlyoutVisualizationsContent'); +export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_ANALYZER_PREVIEW_TITLE_LINK = + getDataTestSubjectSelector('securitySolutionFlyoutAnalyzerPreviewTitleLink'); export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_ANALYZER_PREVIEW_CONTAINER = getDataTestSubjectSelector('securitySolutionFlyoutAnalyzerPreviewContent'); export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_SESSION_PREVIEW_CONTAINER = diff --git a/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_table_tab.ts b/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_table_tab.ts index 18c0bd9029ff6..3a0eec9391437 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_table_tab.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout/alert_details_right_panel_table_tab.ts @@ -19,6 +19,9 @@ export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_ID_ROW = getDataTestSubjectSelect export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_HOST_OS_BUILD_ROW = getDataTestSubjectSelector( 'event-fields-table-row-host.os.build' ); +export const DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_THREAT_ENRICHMENTS = getDataTestSubjectSelector( + 'event-fields-table-row-threat.enrichments' +); 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( diff --git a/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts b/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts index 8d24d64a38cd6..cac84384ed8d1 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts @@ -106,6 +106,8 @@ export const INDICATOR_MATCH_ROW_RENDER = '[data-test-subj="threat-match-row"]'; export const QUERY_TAB_BUTTON = '[data-test-subj="timelineTabs-query"]'; +export const ANALYZER_GRAPH_TAB_BUTTON = getDataTestSubjectSelector('timelineTabs-graph'); + export const SERVER_SIDE_EVENT_COUNT = '[data-test-subj="server-side-event-count"]'; export const ALERTS_TABLE_COUNT = `[data-test-subj="toolbar-alerts-count"]`; @@ -303,8 +305,6 @@ export const TIMELINE_DATE_PICKER_CONTAINER = getDataTestSubjectSelector( 'timeline-date-picker-container' ); -export const TIMELINE_FILTER_BADGE = `[data-test-subj^='timeline-filters-container'] [data-test-subj^="filter-badge"]`; - export const NEW_TIMELINE_ACTION = getDataTestSubjectSelector( 'timeline-modal-new-timeline-dropdown-button' ); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/alerts_details.ts b/x-pack/test/security_solution_cypress/cypress/tasks/alerts_details.ts index 7444f7580186c..3806c2c6e3af9 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/alerts_details.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/alerts_details.ts @@ -7,15 +7,12 @@ import { CLOSE_ALERT_BTN, MARK_ALERT_ACKNOWLEDGED_BTN, OPEN_ALERT_BTN } from '../screens/alerts'; import { - ALERT_FLYOUT, - ENRICHMENT_COUNT_NOTIFICATION, JSON_VIEW_TAB, TABLE_TAB, FILTER_INPUT, OVERVIEW_STATUS, EVENT_DETAILS_ALERT_STATUS_POPOVER, } from '../screens/alerts_details'; -import { TIMELINE_TITLE, QUERY_TAB_BUTTON } from '../screens/timeline'; export const filterBy = (value: string) => { cy.get(FILTER_INPUT).type(value); @@ -29,42 +26,6 @@ export const openTable = () => { cy.get(TABLE_TAB).click(); }; -export const openThreatIndicatorDetails = () => { - cy.get(ENRICHMENT_COUNT_NOTIFICATION).click(); -}; - -export const verifyInsightCount = ({ - tableSelector, - investigateSelector, -}: { - tableSelector: string; - investigateSelector: string; -}) => { - cy.get(tableSelector).click(); - - // Make sure the table containing data has loaded before parsing the text for the alert count - cy.get(investigateSelector); - cy.get(tableSelector) - .invoke('text') - .then((relatedAlertsByAncestryText) => { - // Extract the count from the text - const alertCount = relatedAlertsByAncestryText.match(/(\d)/); - const actualCount = alertCount && alertCount[0]; - - // Make sure we can see the table - cy.contains('New Rule Test').should('be.visible'); - - // Click on the first button that lets us investigate in timeline - cy.get(ALERT_FLYOUT).find(investigateSelector).click(); - - // Make sure a new timeline is created and opened - cy.get(TIMELINE_TITLE).should('contain.text', 'Untitled timeline'); - - // The alert count in this timeline should match the count shown on the alert flyout - cy.get(QUERY_TAB_BUTTON).should('contain.text', actualCount); - }); -}; - export const changeAlertStatusTo = (status: 'open' | 'closed' | 'acknowledged') => { cy.get(OVERVIEW_STATUS).click(); cy.get(EVENT_DETAILS_ALERT_STATUS_POPOVER).should('be.visible'); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts index e5b905f163666..7307fa2418b68 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts @@ -6,10 +6,7 @@ */ import { SECURITY_SOLUTION_SHOW_RELATED_INTEGRATIONS_ID } from '@kbn/management-settings-ids'; -import { - ENABLE_ASSET_CRITICALITY_SETTING, - ENABLE_EXPANDABLE_FLYOUT_SETTING, -} from '@kbn/security-solution-plugin/common/constants'; +import { ENABLE_ASSET_CRITICALITY_SETTING } from '@kbn/security-solution-plugin/common/constants'; import { rootRequest } from './common'; export const setKibanaSetting = (key: string, value: boolean | number | string) => { @@ -28,10 +25,6 @@ export const disableRelatedIntegrations = () => { setKibanaSetting(SECURITY_SOLUTION_SHOW_RELATED_INTEGRATIONS_ID, false); }; -export const disableExpandableFlyout = () => { - setKibanaSetting(ENABLE_EXPANDABLE_FLYOUT_SETTING, false); -}; - export const enableAssetCriticality = () => { setKibanaSetting(ENABLE_ASSET_CRITICALITY_SETTING, true); }; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_correlations_tab.ts b/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_correlations_tab.ts index 8900e86a4524e..a86f9a74b18d0 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_correlations_tab.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_correlations_tab.ts @@ -5,7 +5,12 @@ * 2.0. */ -import { DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_CORRELATIONS_BUTTON } from '../../screens/expandable_flyout/alert_details_left_panel_correlations_tab'; +import { + CORRELATIONS_ANCESTRY_SECTION_INVESTIGATE_IN_TIMELINE_BUTTON, + CORRELATIONS_SESSION_SECTION_INVESTIGATE_IN_TIMELINE_BUTTON, + CORRELATIONS_SOURCE_SECTION_INVESTIGATE_IN_TIMELINE_BUTTON, + DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_CORRELATIONS_BUTTON, +} from '../../screens/expandable_flyout/alert_details_left_panel_correlations_tab'; /** * Open the Correlations tab under the Visuablize tab in the document details expandable flyout left section @@ -13,3 +18,24 @@ import { DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_CORRELATIONS_BUTTON } from '../../ export const openCorrelationsTab = () => { cy.get(DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_CORRELATIONS_BUTTON).click(); }; + +/** + * Open timeline from the related by source event + */ +export const openTimelineFromRelatedSourceEvent = () => { + cy.get(CORRELATIONS_SOURCE_SECTION_INVESTIGATE_IN_TIMELINE_BUTTON).click(); +}; + +/** + * Open timeline from the related by source event + */ +export const openTimelineFromRelatedByAncestry = () => { + cy.get(CORRELATIONS_ANCESTRY_SECTION_INVESTIGATE_IN_TIMELINE_BUTTON).click(); +}; + +/** + * Open timeline from the related by source event + */ +export const openTimelineFromRelatedBySession = () => { + cy.get(CORRELATIONS_SESSION_SECTION_INVESTIGATE_IN_TIMELINE_BUTTON).click(); +}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_prevalence_tab.ts b/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_prevalence_tab.ts index a81a7d8031855..f24a673e75a0e 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_prevalence_tab.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_left_panel_prevalence_tab.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_PREVALENCE_BUTTON } from '../../screens/expandable_flyout/alert_details_left_panel_prevalence_tab'; +import { + DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_PREVALENCE_BUTTON, + DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_PREVALENCE_TABLE_TYPE_CELL, +} from '../../screens/expandable_flyout/alert_details_left_panel_prevalence_tab'; /** * Open the Prevalence tab under the Visualize tab in the document details expandable flyout left section @@ -13,3 +16,10 @@ import { DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_PREVALENCE_BUTTON } from '../../sc export const openPrevalenceTab = () => { cy.get(DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_PREVALENCE_BUTTON).click(); }; + +/** + * Open timeline from a prevalence detail table cell + */ +export const openTimelineFromPrevalenceTableCell = () => { + cy.get(DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_PREVALENCE_TABLE_TYPE_CELL).first().click(); +}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts b/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts index aade383f2d846..be9b29a842e0e 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts @@ -21,6 +21,7 @@ import { DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INSIGHTS_ENTITIES_HEADER, DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INSIGHTS_PREVALENCE_HEADER, DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_BUTTON, + DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_ANALYZER_PREVIEW_TITLE_LINK, } from '../../screens/expandable_flyout/alert_details_right_panel_overview_tab'; /* About section */ @@ -125,3 +126,10 @@ export const clickAlertReasonButton = () => { export const navigateToResponseDetails = () => { cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_BUTTON).should('be.visible').click(); }; + +/** + * Click the Response button to open the response detail tab in the left section + */ +export const clickAnalyzerPreviewTitleToOpenTimeline = () => { + cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_ANALYZER_PREVIEW_TITLE_LINK).click(); +};