From 6d97b0bd2405ec39e8bcd1b1e72067a13c49c2fa Mon Sep 17 00:00:00 2001 From: Tal Borenstein Date: Thu, 26 Mar 2026 14:42:13 +0200 Subject: [PATCH 1/6] feat: add alert state checkbox UI for workflow connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the UI portion of the alertStates feature — a "Run workflow for" checkbox group (New / Ongoing / Recovered alerts) in the rule action form, between the workflow selector and the action frequency switch. This is the second part of the intermediate release for #257363: - Part 1 (merged): backend schema + adapter logic (#257363) - Part 2 (this PR): UI to set alertStates on rule actions - Add AlertStates type and alertStates? to public WorkflowsActionParams - Render EuiCheckboxGroup with New/Ongoing/Recovered options - Use single editAction call in useEffect for initialization (addresses Copilot review feedback from #256289) - Use "New alerts" terminology (not "Firing") per review feedback - Add 6 new tests for checkbox rendering, defaults, and toggling Closes elastic/security-team#16239 Made-with: Cursor --- .../public/connectors/workflows/types.ts | 8 + .../workflows/workflows_params.test.tsx | 152 +++++++++++++++++- .../connectors/workflows/workflows_params.tsx | 128 +++++++++++++-- 3 files changed, 275 insertions(+), 13 deletions(-) diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts index f82ed6940fdef..b7e8d8d3b46e6 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts @@ -11,10 +11,18 @@ export type WorkflowsConfig = Record; export type WorkflowsSecrets = Record; +export interface AlertStates { + [key: string]: boolean; + new: boolean; + ongoing: boolean; + recovered: boolean; +} + export interface WorkflowsActionParams { subAction: string; subActionParams: { workflowId: string; summaryMode?: boolean; + alertStates?: AlertStates; }; } diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx index cd8f6be3cbfcd..6366c013f761d 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx @@ -120,7 +120,11 @@ describe('WorkflowsParamsFields', () => { expect(mockEditAction).toHaveBeenCalledWith('subAction', 'run', 0); expect(mockEditAction).toHaveBeenCalledWith( 'subActionParams', - { workflowId: '', summaryMode: true }, + { + workflowId: '', + summaryMode: true, + alertStates: { new: true, ongoing: false, recovered: false }, + }, 0 ); }); @@ -822,6 +826,144 @@ describe('WorkflowsParamsFields', () => { }); }); + describe('Alert state checkboxes (alertStates parameter)', () => { + test('should render alert state checkboxes', async () => { + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.getByText('Run workflow for')).toBeInTheDocument(); + expect(screen.getByLabelText('New alerts')).toBeInTheDocument(); + expect(screen.getByLabelText('Ongoing alerts')).toBeInTheDocument(); + expect(screen.getByLabelText('Recovered alerts')).toBeInTheDocument(); + }); + }); + + test('should default to new=checked, ongoing=unchecked, recovered=unchecked', async () => { + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.getByLabelText('New alerts')).toBeChecked(); + expect(screen.getByLabelText('Ongoing alerts')).not.toBeChecked(); + expect(screen.getByLabelText('Recovered alerts')).not.toBeChecked(); + }); + }); + + test('should reflect alertStates from action params', async () => { + const props = { + ...defaultProps, + actionParams: { + subAction: 'run', + subActionParams: { + workflowId: 'test-workflow', + alertStates: { new: true, ongoing: true, recovered: false }, + }, + } as WorkflowsActionParams, + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.getByLabelText('New alerts')).toBeChecked(); + expect(screen.getByLabelText('Ongoing alerts')).toBeChecked(); + expect(screen.getByLabelText('Recovered alerts')).not.toBeChecked(); + }); + }); + + test('should toggle alert state on checkbox click', async () => { + const props = { + ...defaultProps, + actionParams: { + subAction: 'run', + subActionParams: { + workflowId: 'test-workflow', + summaryMode: true, + alertStates: { new: true, ongoing: false, recovered: false }, + }, + } as WorkflowsActionParams, + }; + + await act(async () => { + renderWithIntl(); + }); + + const recoveredCheckbox = screen.getByLabelText('Recovered alerts'); + await act(async () => { + fireEvent.click(recoveredCheckbox); + }); + + await waitFor(() => { + expect(mockEditAction).toHaveBeenCalledWith( + 'subActionParams', + expect.objectContaining({ + alertStates: { new: true, ongoing: false, recovered: true }, + }), + 0 + ); + }); + }); + + test('should initialize alertStates when missing from subActionParams', async () => { + const props = { + ...defaultProps, + actionParams: { + subAction: 'run', + subActionParams: { + workflowId: 'test-workflow', + summaryMode: true, + }, + } as WorkflowsActionParams, + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(mockEditAction).toHaveBeenCalledWith( + 'subActionParams', + expect.objectContaining({ + alertStates: { new: true, ongoing: false, recovered: false }, + }), + 0 + ); + }); + }); + + test('should initialize alertStates together with summaryMode in a single editAction call', async () => { + const props = { + ...defaultProps, + actionParams: { + subAction: 'run', + subActionParams: { + workflowId: 'test-workflow', + }, + } as any, + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(mockEditAction).toHaveBeenCalledWith( + 'subActionParams', + { + workflowId: 'test-workflow', + summaryMode: true, + alertStates: { new: true, ongoing: false, recovered: false }, + }, + 0 + ); + }); + }); + }); + describe('Action frequency (summaryMode parameter)', () => { test('should render Action frequency section with switch', async () => { await act(async () => { @@ -854,7 +996,7 @@ describe('WorkflowsParamsFields', () => { await waitFor(() => { expect(mockEditAction).toHaveBeenCalledWith( 'subActionParams', - { workflowId: 'test-workflow', summaryMode: true }, + expect.objectContaining({ workflowId: 'test-workflow', summaryMode: true }), 0 ); }); @@ -876,7 +1018,11 @@ describe('WorkflowsParamsFields', () => { await waitFor(() => { expect(mockEditAction).toHaveBeenCalledWith( 'subActionParams', - { workflowId: '', summaryMode: true }, + { + workflowId: '', + summaryMode: true, + alertStates: { new: true, ongoing: false, recovered: false }, + }, 0 ); }); diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx index 11d96e52db60a..0291b6570754b 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx @@ -8,6 +8,7 @@ */ import { + EuiCheckboxGroup, EuiFlexGroup, EuiFlexItem, EuiFormRow, @@ -15,11 +16,53 @@ import { EuiSpacer, EuiSwitch, } from '@elastic/eui'; -import React, { useCallback, useEffect } from 'react'; +import type { EuiCheckboxGroupOption } from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import type { ActionParamsProps } from '@kbn/triggers-actions-ui-plugin/public'; import { WorkflowSelectorWithProvider } from '@kbn/workflows-ui'; -import type { WorkflowsActionParams } from './types'; +import type { AlertStates, WorkflowsActionParams } from './types'; + +const RUN_WORKFLOW_FOR_LABEL = i18n.translate( + 'xpack.stackConnectors.components.workflows.runWorkflowFor.label', + { + defaultMessage: 'Run workflow for', + } +); + +const RUN_WORKFLOW_FOR_HELP_TEXT = i18n.translate( + 'xpack.stackConnectors.components.workflows.runWorkflowFor.helpText', + { + defaultMessage: 'Select which alert states should trigger this workflow', + } +); + +const ALERT_STATE_OPTIONS: EuiCheckboxGroupOption[] = [ + { + id: 'new', + label: i18n.translate('xpack.stackConnectors.components.workflows.alertState.new', { + defaultMessage: 'New alerts', + }), + }, + { + id: 'ongoing', + label: i18n.translate('xpack.stackConnectors.components.workflows.alertState.ongoing', { + defaultMessage: 'Ongoing alerts', + }), + }, + { + id: 'recovered', + label: i18n.translate('xpack.stackConnectors.components.workflows.alertState.recovered', { + defaultMessage: 'Recovered alerts', + }), + }, +]; + +const DEFAULT_ALERT_STATES: AlertStates = { + new: true, + ongoing: false, + recovered: false, +}; const RUN_PER_ALERT_LABEL = i18n.translate( 'xpack.stackConnectors.components.workflows.runPerAlert.label', @@ -41,7 +84,11 @@ const WorkflowsParamsFields: React.FunctionComponent { - const { workflowId, summaryMode = true } = actionParams.subActionParams ?? {}; + const { + workflowId, + summaryMode = true, + alertStates = DEFAULT_ALERT_STATES, + } = actionParams.subActionParams ?? {}; const handleWorkflowChange = useCallback( (newWorkflowId: string) => { @@ -56,8 +103,6 @@ const WorkflowsParamsFields: React.FunctionComponent { - // When switch is ON (runPerAlert = true), summaryMode should be false (run per alert) - // When switch is OFF (runPerAlert = false), summaryMode should be true (summary mode) editAction( 'subActionParams', { ...actionParams.subActionParams, summaryMode: !runPerAlert }, @@ -67,16 +112,60 @@ const WorkflowsParamsFields: React.FunctionComponent { + const currentStates = actionParams.subActionParams?.alertStates ?? DEFAULT_ALERT_STATES; + editAction( + 'subActionParams', + { + ...actionParams.subActionParams, + alertStates: { + ...currentStates, + [optionId]: !currentStates[optionId as keyof AlertStates], + }, + }, + index + ); + }, + [editAction, index, actionParams.subActionParams] + ); + + const alertStateCheckboxIdToSelectedMap = useMemo( + () => ({ + new: alertStates.new, + ongoing: alertStates.ongoing, + recovered: alertStates.recovered, + }), + [alertStates] + ); + useEffect(() => { if (!actionParams?.subAction) { editAction('subAction', 'run', index); } if (!actionParams?.subActionParams) { - editAction('subActionParams', { workflowId: '', summaryMode: true }, index); - } else if (actionParams.subActionParams.summaryMode === undefined) { - // Ensure summaryMode defaults to true for backward compatibility - editAction('subActionParams', { ...actionParams.subActionParams, summaryMode: true }, index); + editAction( + 'subActionParams', + { workflowId: '', summaryMode: true, alertStates: DEFAULT_ALERT_STATES }, + index + ); + } else { + let nextSubActionParams = actionParams.subActionParams; + let needsUpdate = false; + + if (nextSubActionParams.summaryMode === undefined) { + nextSubActionParams = { ...nextSubActionParams, summaryMode: true }; + needsUpdate = true; + } + + if (!nextSubActionParams.alertStates) { + nextSubActionParams = { ...nextSubActionParams, alertStates: DEFAULT_ALERT_STATES }; + needsUpdate = true; + } + + if (needsUpdate) { + editAction('subActionParams', nextSubActionParams, index); + } } }, [actionParams, editAction, index]); @@ -109,6 +198,25 @@ const WorkflowsParamsFields: React.FunctionComponent + + {RUN_WORKFLOW_FOR_LABEL} + + + + + } + > + + + Date: Sun, 29 Mar 2026 12:21:04 +0300 Subject: [PATCH 2/6] fix: address PR review feedback for alert state UI - Replace AlertStates interface with AlertStateId union + Record type, removing the string index signature (@semd, Copilot) - Add normalizeAlertStates helper to merge partial states with defaults, handling cases where alertStates exists but is missing keys (Copilot) - Add hidden legend prop to EuiCheckboxGroup for accessibility (Copilot) - Remove unnecessary useMemo for idToSelectedMap, use alertStates directly (@semd) - Type optionId as AlertStateId in handleAlertStateChange (Copilot) Made-with: Cursor --- .../public/connectors/workflows/types.ts | 8 +--- .../workflows/workflows_params.test.tsx | 2 +- .../connectors/workflows/workflows_params.tsx | 43 ++++++++++--------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts index b7e8d8d3b46e6..484e02b2e5744 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/types.ts @@ -11,12 +11,8 @@ export type WorkflowsConfig = Record; export type WorkflowsSecrets = Record; -export interface AlertStates { - [key: string]: boolean; - new: boolean; - ongoing: boolean; - recovered: boolean; -} +export type AlertStateId = 'new' | 'ongoing' | 'recovered'; +export type AlertStates = Record; export interface WorkflowsActionParams { subAction: string; diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx index 6366c013f761d..d4a8a90f921ec 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx @@ -833,7 +833,7 @@ describe('WorkflowsParamsFields', () => { }); await waitFor(() => { - expect(screen.getByText('Run workflow for')).toBeInTheDocument(); + expect(screen.getAllByText('Run workflow for').length).toBeGreaterThan(0); expect(screen.getByLabelText('New alerts')).toBeInTheDocument(); expect(screen.getByLabelText('Ongoing alerts')).toBeInTheDocument(); expect(screen.getByLabelText('Recovered alerts')).toBeInTheDocument(); diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx index 0291b6570754b..03faca6c897ba 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx @@ -17,11 +17,11 @@ import { EuiSwitch, } from '@elastic/eui'; import type { EuiCheckboxGroupOption } from '@elastic/eui'; -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import type { ActionParamsProps } from '@kbn/triggers-actions-ui-plugin/public'; import { WorkflowSelectorWithProvider } from '@kbn/workflows-ui'; -import type { AlertStates, WorkflowsActionParams } from './types'; +import type { AlertStateId, AlertStates, WorkflowsActionParams } from './types'; const RUN_WORKFLOW_FOR_LABEL = i18n.translate( 'xpack.stackConnectors.components.workflows.runWorkflowFor.label', @@ -64,6 +64,11 @@ const DEFAULT_ALERT_STATES: AlertStates = { recovered: false, }; +const normalizeAlertStates = (partial?: Partial): AlertStates => ({ + ...DEFAULT_ALERT_STATES, + ...partial, +}); + const RUN_PER_ALERT_LABEL = i18n.translate( 'xpack.stackConnectors.components.workflows.runPerAlert.label', { @@ -84,11 +89,8 @@ const WorkflowsParamsFields: React.FunctionComponent { - const { - workflowId, - summaryMode = true, - alertStates = DEFAULT_ALERT_STATES, - } = actionParams.subActionParams ?? {}; + const { workflowId, summaryMode = true } = actionParams.subActionParams ?? {}; + const alertStates = normalizeAlertStates(actionParams.subActionParams?.alertStates); const handleWorkflowChange = useCallback( (newWorkflowId: string) => { @@ -114,14 +116,15 @@ const WorkflowsParamsFields: React.FunctionComponent { - const currentStates = actionParams.subActionParams?.alertStates ?? DEFAULT_ALERT_STATES; + const stateId = optionId as AlertStateId; + const currentStates = normalizeAlertStates(actionParams.subActionParams?.alertStates); editAction( 'subActionParams', { ...actionParams.subActionParams, alertStates: { ...currentStates, - [optionId]: !currentStates[optionId as keyof AlertStates], + [stateId]: !currentStates[stateId], }, }, index @@ -130,15 +133,6 @@ const WorkflowsParamsFields: React.FunctionComponent ({ - new: alertStates.new, - ongoing: alertStates.ongoing, - recovered: alertStates.recovered, - }), - [alertStates] - ); - useEffect(() => { if (!actionParams?.subAction) { editAction('subAction', 'run', index); @@ -158,8 +152,14 @@ const WorkflowsParamsFields: React.FunctionComponent From 69c6d0293dd64c32478b67607c02ee546a5acde5 Mon Sep 17 00:00:00 2001 From: Tal Borenstein Date: Sun, 12 Apr 2026 19:10:52 +0300 Subject: [PATCH 3/6] fix: hide alert state checkboxes for Security detection rules Security detection rules (siem.*) only generate new alerts and don't have ongoing/recovered states. Hide the "Run workflow for" checkbox group when ruleTypeId starts with 'siem.' since the setting is not applicable. Per feedback from @semd and @marshall.main Made-with: Cursor --- .../workflows/workflows_params.test.tsx | 51 ++++++++++++++++++ .../connectors/workflows/workflows_params.tsx | 53 ++++++++++++------- 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx index 3e17c24a7ddf5..4a30dda8afca6 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx @@ -962,6 +962,57 @@ describe('WorkflowsParamsFields', () => { ); }); }); + + test('should hide alert state checkboxes for Security detection rules', async () => { + const props = { + ...defaultProps, + ruleTypeId: 'siem.queryRule', + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.queryByLabelText('New alerts')).not.toBeInTheDocument(); + expect(screen.queryByLabelText('Ongoing alerts')).not.toBeInTheDocument(); + expect(screen.queryByLabelText('Recovered alerts')).not.toBeInTheDocument(); + }); + }); + + test('should show alert state checkboxes for non-SIEM rules', async () => { + const props = { + ...defaultProps, + ruleTypeId: 'metrics.alert.threshold', + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.getByLabelText('New alerts')).toBeInTheDocument(); + expect(screen.getByLabelText('Ongoing alerts')).toBeInTheDocument(); + expect(screen.getByLabelText('Recovered alerts')).toBeInTheDocument(); + }); + }); + + test('should show alert state checkboxes when ruleTypeId is undefined', async () => { + const props = { + ...defaultProps, + ruleTypeId: undefined, + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.getByLabelText('New alerts')).toBeInTheDocument(); + expect(screen.getByLabelText('Ongoing alerts')).toBeInTheDocument(); + expect(screen.getByLabelText('Recovered alerts')).toBeInTheDocument(); + }); + }); }); describe('Action frequency (summaryMode parameter)', () => { diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx index 03faca6c897ba..d88708ed09c04 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx @@ -83,12 +83,21 @@ const RUN_PER_ALERT_HELP_TEXT = i18n.translate( } ); +// Security detection rules (ruleTypeId: siem.*) only produce "new" alerts — +// they have no concept of "ongoing" or "recovered" states. The alert-state +// checkbox group is hidden for these rules because the setting would have +// no effect. The ruleTypeId prop is provided by the rule form when rendering +// the action params component (ActionTypeForm / SystemActionTypeForm). +const SIEM_RULE_TYPE_PREFIX = 'siem.'; + const WorkflowsParamsFields: React.FunctionComponent> = ({ actionParams, editAction, index, errors, + ruleTypeId, }) => { + const isDetectionRule = ruleTypeId?.startsWith(SIEM_RULE_TYPE_PREFIX) ?? false; const { workflowId, summaryMode = true } = actionParams.subActionParams ?? {}; const alertStates = normalizeAlertStates(actionParams.subActionParams?.alertStates); @@ -197,26 +206,30 @@ const WorkflowsParamsFields: React.FunctionComponent - - - {RUN_WORKFLOW_FOR_LABEL} - - - - - } - > - - + {!isDetectionRule && ( + <> + + + {RUN_WORKFLOW_FOR_LABEL} + + + + + } + > + + + + )} Date: Mon, 13 Apr 2026 15:19:17 +0300 Subject: [PATCH 4/6] refactor: use isSiemRuleType from @kbn/rule-data-utils Replace the inline `siem.` prefix check with the canonical `isSiemRuleType` helper, which also covers attack-discovery rules. Made-with: Cursor --- .../workflows/workflows_params.test.tsx | 17 +++++++++++++++++ .../connectors/workflows/workflows_params.tsx | 12 ++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx index 4a30dda8afca6..6755456e2e8d4 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.test.tsx @@ -980,6 +980,23 @@ describe('WorkflowsParamsFields', () => { }); }); + test('should hide alert state checkboxes for attack-discovery rules', async () => { + const props = { + ...defaultProps, + ruleTypeId: 'attack-discovery', + }; + + await act(async () => { + renderWithIntl(); + }); + + await waitFor(() => { + expect(screen.queryByLabelText('New alerts')).not.toBeInTheDocument(); + expect(screen.queryByLabelText('Ongoing alerts')).not.toBeInTheDocument(); + expect(screen.queryByLabelText('Recovered alerts')).not.toBeInTheDocument(); + }); + }); + test('should show alert state checkboxes for non-SIEM rules', async () => { const props = { ...defaultProps, diff --git a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx index d88708ed09c04..ed04245cb8d21 100644 --- a/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx +++ b/src/platform/plugins/shared/workflows_management/public/connectors/workflows/workflows_params.tsx @@ -19,6 +19,7 @@ import { import type { EuiCheckboxGroupOption } from '@elastic/eui'; import React, { useCallback, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; +import { isSiemRuleType } from '@kbn/rule-data-utils'; import type { ActionParamsProps } from '@kbn/triggers-actions-ui-plugin/public'; import { WorkflowSelectorWithProvider } from '@kbn/workflows-ui'; import type { AlertStateId, AlertStates, WorkflowsActionParams } from './types'; @@ -83,13 +84,6 @@ const RUN_PER_ALERT_HELP_TEXT = i18n.translate( } ); -// Security detection rules (ruleTypeId: siem.*) only produce "new" alerts — -// they have no concept of "ongoing" or "recovered" states. The alert-state -// checkbox group is hidden for these rules because the setting would have -// no effect. The ruleTypeId prop is provided by the rule form when rendering -// the action params component (ActionTypeForm / SystemActionTypeForm). -const SIEM_RULE_TYPE_PREFIX = 'siem.'; - const WorkflowsParamsFields: React.FunctionComponent> = ({ actionParams, editAction, @@ -97,7 +91,9 @@ const WorkflowsParamsFields: React.FunctionComponent { - const isDetectionRule = ruleTypeId?.startsWith(SIEM_RULE_TYPE_PREFIX) ?? false; + // Security detection rules only produce "new" alerts and have no concept of + // "ongoing" or "recovered" states, so the alert-state checkboxes are hidden. + const isDetectionRule = ruleTypeId ? isSiemRuleType(ruleTypeId) : false; const { workflowId, summaryMode = true } = actionParams.subActionParams ?? {}; const alertStates = normalizeAlertStates(actionParams.subActionParams?.alertStates); From ee0993fd4d4d8bab49950691ea51f27e5f00db7d Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:31:33 +0000 Subject: [PATCH 5/6] Changes from node scripts/lint_ts_projects --fix --- src/platform/plugins/shared/workflows_management/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/plugins/shared/workflows_management/tsconfig.json b/src/platform/plugins/shared/workflows_management/tsconfig.json index 4cdae06f278d5..e4ecc2bb4ed8c 100644 --- a/src/platform/plugins/shared/workflows_management/tsconfig.json +++ b/src/platform/plugins/shared/workflows_management/tsconfig.json @@ -93,7 +93,8 @@ "@kbn/core-elasticsearch-server", "@kbn/logging", "@kbn/core-saved-objects-api-server", - "@kbn/management-settings-ids" + "@kbn/management-settings-ids", + "@kbn/rule-data-utils" ], "exclude": ["target/**/*"] } From bf1975b2d84d11d0bc26400caed0d2ba2052abcf Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:44:30 +0000 Subject: [PATCH 6/6] Changes from node scripts/regenerate_moon_projects.js --update --- src/platform/plugins/shared/workflows_management/moon.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/plugins/shared/workflows_management/moon.yml b/src/platform/plugins/shared/workflows_management/moon.yml index 2b3a0bd15c8e8..b4e16ae3b8378 100644 --- a/src/platform/plugins/shared/workflows_management/moon.yml +++ b/src/platform/plugins/shared/workflows_management/moon.yml @@ -96,6 +96,7 @@ dependsOn: - '@kbn/logging' - '@kbn/core-saved-objects-api-server' - '@kbn/management-settings-ids' + - '@kbn/rule-data-utils' tags: - plugin - prod