From 2e3ee5b9ffce7d7197ed6ed7056fdd03dec32af5 Mon Sep 17 00:00:00 2001 From: Kelvin Tan Date: Tue, 10 Feb 2026 13:14:03 -0500 Subject: [PATCH] refactor AlertWorkflowsPanel to take multiple alerts and add new hook for bulk panel --- .../use_run_alert_workflow_panel.tsx | 28 ++++--- .../use_bulk_actions.tsx | 24 +++++- .../use_bulk_run_alert_workflow_panel.tsx | 77 +++++++++++++++++++ 3 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_run_alert_workflow_panel.tsx diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_run_alert_workflow_panel.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_run_alert_workflow_panel.tsx index e325021d315db..a922858110dd7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_run_alert_workflow_panel.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_run_alert_workflow_panel.tsx @@ -31,13 +31,19 @@ export interface UseAlertTagsActionsProps { } export const RUN_WORKFLOW_PANEL_ID = 'RUN_WORKFLOW_PANEL_ID'; +export const RUN_WORKFLOW_BULK_PANEL_ID = 'BULK_RUN_WORKFLOW_PANEL_ID'; + +export interface AlertWorkflowAlertId { + _id: string; + _index: string; +} export interface AlertWorkflowsPanelProps { - closePopover: () => void; - ecsRowData: Ecs; + alertIds: AlertWorkflowAlertId[]; + onClose: () => void; } -export const AlertWorkflowsPanel = ({ closePopover, ecsRowData }: AlertWorkflowsPanelProps) => { +export const AlertWorkflowsPanel = ({ alertIds, onClose }: AlertWorkflowsPanelProps) => { const { services: { application, rendering }, } = useKibana<{ application: ApplicationStart }>(); @@ -54,7 +60,7 @@ export const AlertWorkflowsPanel = ({ closePopover, ecsRowData }: AlertWorkflows const inputsPayload: AlertTriggerInput = { event: { triggerType: 'alert', - alertIds: [{ _id: ecsRowData._id, _index: ecsRowData._index ?? '' }], + alertIds, }, }; @@ -94,7 +100,7 @@ export const AlertWorkflowsPanel = ({ closePopover, ecsRowData }: AlertWorkflows }, onSettled: () => { setIsLoading(false); - closePopover(); + onClose(); }, } ); @@ -105,8 +111,8 @@ export const AlertWorkflowsPanel = ({ closePopover, ecsRowData }: AlertWorkflows workflowTriggerSuccess, workflowTriggerFailed, rendering, - closePopover, - ecsRowData, + onClose, + alertIds, ]); const isAlertWorkflow = (workflows: WorkflowListDto['results']): WorkflowListDto['results'] => { @@ -168,7 +174,6 @@ export const useRunAlertWorkflowPanel = ({ 'aria-label': i18n.CONTEXT_MENU_RUN_WORKFLOW, 'data-test-subj': 'run-workflow-action', key: 'run-workflow-action', - onClick: () => {}, size: 's', name: i18n.CONTEXT_MENU_RUN_WORKFLOW, panel: RUN_WORKFLOW_PANEL_ID, @@ -183,7 +188,12 @@ export const useRunAlertWorkflowPanel = ({ id: RUN_WORKFLOW_PANEL_ID, title: i18n.SELECT_WORKFLOW_PANEL_TITLE, 'data-test-subj': 'alert-workflow-context-menu-panel', - content: , + content: ( + + ), }, ], [closePopover, ecsRowData] diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_actions.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_actions.tsx index 2019b48a5f5f5..713b5f957dbf9 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_actions.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_actions.tsx @@ -16,6 +16,7 @@ import type { BulkActionsPanelConfig, ItemsPanelConfig, } from '@kbn/response-ops-alerts-table/types'; +import { useBulkRunAlertWorkflowPanel } from './use_bulk_run_alert_workflow_panel'; import { PageScope } from '../../../data_view_manager/constants'; import { useBulkAlertAssigneesItems } from '../../../common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items'; import { useBulkAlertTagsItems } from '../../../common/components/toolbar/bulk_actions/use_bulk_alert_tags_items'; @@ -132,10 +133,25 @@ export const useBulkActionsByTableType = ( const { alertTagsItems, alertTagsPanels } = useBulkAlertTagsItems(bulkAlertTagParams); + const { runWorkflowItems, runWorkflowPanels } = useBulkRunAlertWorkflowPanel(); + const items = useMemo(() => { - return [...alertActions, ...timelineActions, ...alertTagsItems, ...alertAssigneesItems]; - }, [alertActions, alertTagsItems, timelineActions, alertAssigneesItems]); + return [ + ...alertActions, + ...runWorkflowItems, + ...timelineActions, + ...alertTagsItems, + ...alertAssigneesItems, + ]; + }, [alertActions, alertTagsItems, timelineActions, alertAssigneesItems, runWorkflowItems]); + return useMemo(() => { - return [{ id: 0, items }, ...alertActionsPanels, ...alertTagsPanels, ...alertAssigneesPanels]; - }, [alertActionsPanels, alertTagsPanels, items, alertAssigneesPanels]); + return [ + { id: 0, items }, + ...alertActionsPanels, + ...runWorkflowPanels, + ...alertTagsPanels, + ...alertAssigneesPanels, + ]; + }, [alertActionsPanels, alertTagsPanels, items, alertAssigneesPanels, runWorkflowPanels]); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_run_alert_workflow_panel.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_run_alert_workflow_panel.tsx new file mode 100644 index 0000000000000..674d5b6168141 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_bulk_run_alert_workflow_panel.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + BulkActionsConfig, + ContentPanelConfig, + RenderContentPanelProps, +} from '@kbn/response-ops-alerts-table/types'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { ApplicationStart } from '@kbn/core-application-browser'; +import { WORKFLOWS_UI_SETTING_ID } from '@kbn/workflows'; +import React, { useCallback, useMemo } from 'react'; +import * as i18n from '../../components/alerts_table/translations'; +import { useAlertsPrivileges } from '../../containers/detection_engine/alerts/use_alerts_privileges'; +import { + AlertWorkflowsPanel, + RUN_WORKFLOW_BULK_PANEL_ID, +} from '../../components/alerts_table/timeline_actions/use_run_alert_workflow_panel'; + +export const useBulkRunAlertWorkflowPanel = (): { + runWorkflowItems: BulkActionsConfig[]; + runWorkflowPanels: ContentPanelConfig[]; +} => { + const { + services: { uiSettings, application }, + } = useKibana<{ application: ApplicationStart }>(); + + const workflowUIEnabled = uiSettings?.get(WORKFLOWS_UI_SETTING_ID, false) ?? false; + const canExecuteWorkflow = application.capabilities.workflowsManagement?.executeWorkflow ?? false; + const { hasIndexWrite } = useAlertsPrivileges(); + + const renderContent = useCallback((props: RenderContentPanelProps) => { + const alertIds = props.alertItems.map((item) => ({ + _id: item._id, + _index: item._index ?? '', + })); + return ; + }, []); + + const runWorkflowItems = useMemo( + () => + hasIndexWrite && workflowUIEnabled && canExecuteWorkflow + ? [ + { + key: 'bulk-run-alert-workflow', + 'data-test-subj': 'bulk-run-alert-workflow-action', + label: i18n.CONTEXT_MENU_RUN_WORKFLOW, + name: i18n.CONTEXT_MENU_RUN_WORKFLOW, + panel: RUN_WORKFLOW_BULK_PANEL_ID, + disableOnQuery: false, + }, + ] + : [], + [hasIndexWrite, workflowUIEnabled, canExecuteWorkflow] + ); + + const runWorkflowPanels = useMemo( + () => + hasIndexWrite && workflowUIEnabled && canExecuteWorkflow + ? [ + { + id: RUN_WORKFLOW_BULK_PANEL_ID, + title: i18n.SELECT_WORKFLOW_PANEL_TITLE, + 'data-test-subj': 'bulk-alert-workflow-context-menu-panel', + renderContent, + }, + ] + : [], + [hasIndexWrite, workflowUIEnabled, canExecuteWorkflow, renderContent] + ); + + return { runWorkflowItems, runWorkflowPanels }; +};