diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx
index 4428d6cca6de6b..984f0f5dee9261 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx
@@ -169,11 +169,11 @@ export const getSourceEventTimeRangeColumns = () => [
return backfill ? (
) : (
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx
index 1444dc8e0fd40f..981f80f36f7440 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx
@@ -78,7 +78,7 @@ import {
getSourceEventTimeRangeColumns,
} from './execution_log_columns';
import { ExecutionLogSearchBar } from './execution_log_search_bar';
-import { RuleBackfillsInfo } from '../../../../rule_gaps/components/rule_backfills_info';
+
import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features';
const EXECUTION_UUID_FIELD_NAME = 'kibana.alert.rule.execution.uuid';
@@ -594,9 +594,6 @@ const ExecutionLogTableComponent: React.FC = ({
itemIdToExpandedRowMap={rows.itemIdToExpandedRowMap}
data-test-subj="executionsTable"
/>
-
-
-
);
};
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/translations.ts
index f84e0b6b859c25..76b3f5483baadb 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/translations.ts
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/translations.ts
@@ -93,7 +93,8 @@ export const COLUMN_SOURCE_EVENT_TIME_RANGE = i18n.translate(
export const COLUMN_SOURCE_EVENT_TIME_RANGE_TOOLTIP = i18n.translate(
'xpack.securitySolution.detectionEngine.ruleDetails.ruleExecutionLog.sourceEventTimeRangeTooltip',
{
- defaultMessage: "Only for manual rule runs. Don't include additional lookback time.",
+ defaultMessage:
+ "Only applies to manual rule executions. If the rule has look-back time, it's included in the logged time range.",
}
);
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx
index 43491a1969fffa..da80b8ff6d0154 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx
@@ -112,6 +112,7 @@ import {
} from '../../../../detections/components/rules/rule_execution_status';
import { ExecutionEventsTable } from '../../../rule_monitoring';
import { ExecutionLogTable } from './execution_log_table/execution_log_table';
+import { RuleBackfillsInfo } from '../../../rule_gaps/components/rule_backfills_info';
import * as ruleI18n from '../../../../detections/pages/detection_engine/rules/translations';
@@ -785,13 +786,17 @@ const RuleDetailsPageComponent: React.FC = ({
/>
-
+ <>
+
+
+
+ >
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/api/hooks/use_schedule_rule_run_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/api/hooks/use_schedule_rule_run_mutation.ts
index 78e3c5cbe6ca5d..98c8a436393add 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/api/hooks/use_schedule_rule_run_mutation.ts
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/api/hooks/use_schedule_rule_run_mutation.ts
@@ -9,6 +9,7 @@ import type { UseMutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import type { ScheduleBackfillProps } from '../../types';
import { scheduleRuleRun } from '../api';
+import { useInvalidateFindBackfillQuery } from './use_find_backfills_for_rules';
export const SCHEDULE_RULE_RUN_MUTATION_KEY = [
'POST',
@@ -18,8 +19,15 @@ export const SCHEDULE_RULE_RUN_MUTATION_KEY = [
export const useScheduleRuleRunMutation = (
options?: UseMutationOptions
) => {
+ const invalidateBackfillQuery = useInvalidateFindBackfillQuery();
return useMutation((scheduleOptions: ScheduleBackfillProps) => scheduleRuleRun(scheduleOptions), {
...options,
+ onSettled: (...args) => {
+ invalidateBackfillQuery();
+ if (options?.onSettled) {
+ options.onSettled(...args);
+ }
+ },
mutationKey: SCHEDULE_RULE_RUN_MUTATION_KEY,
});
};
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/index.tsx
index 00a3e4b262aa75..37a47622543293 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/index.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/index.tsx
@@ -14,6 +14,8 @@ import {
EuiForm,
EuiFormRow,
useGeneratedHtmlId,
+ EuiCallOut,
+ EuiSpacer,
} from '@elastic/eui';
import moment from 'moment';
import React, { useCallback, useMemo, useState } from 'react';
@@ -118,6 +120,18 @@ const ManualRuleRunModalComponent = ({ onCancel, onConfirm }: ManualRuleRunModal
/>
+
+
+
+
+
+
+
+
);
};
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/translations.ts
index 737a992b3a5a37..d9833232deb11f 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/translations.ts
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/manual_rule_run/translations.ts
@@ -68,3 +68,18 @@ export const MANUAL_RULE_RUN_START_DATE_OUT_OF_RANGE_ERROR = (maxDaysLookback: n
defaultMessage:
'Manual rule run cannot be scheduled earlier than {maxDaysLookback, plural, =1 {# day} other {# days}} ago',
});
+
+export const MANUAL_RULE_RUN_ALERT_LIMITATIONS = i18n.translate(
+ 'xpack.securitySolution.manualRuleRun.alertLimitations',
+ {
+ defaultMessage:
+ 'To view alerts generated by this run, filter the Alerts page by the time range that was selected for this manual rule run.',
+ }
+);
+
+export const MANUAL_RULE_RUN_NOTIFIACTIONS_LIMITATIONS = i18n.translate(
+ 'xpack.securitySolution.manualRuleRun.notificationsLimitations',
+ {
+ defaultMessage: 'Rule actions are not performed during manual rule runs.',
+ }
+);
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx
index 1c8a180207d2aa..3a2a608d844312 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx
@@ -6,12 +6,15 @@
*/
import React, { useState } from 'react';
-import { EuiAutoRefresh, EuiBasicTable, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
-import type {
- EuiBasicTableColumn,
- CriteriaWithPagination,
- OnRefreshChangeProps,
+import {
+ EuiButton,
+ EuiBasicTable,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPanel,
+ EuiBetaBadge,
} from '@elastic/eui';
+import type { EuiBasicTableColumn, CriteriaWithPagination } from '@elastic/eui';
import { useFindBackfillsForRules } from '../../api/hooks/use_find_backfills_for_rules';
import { StopBackfill } from './stop_backfill';
import { BackfillStatusInfo } from './backfill_status';
@@ -23,12 +26,15 @@ import { useUserData } from '../../../../detections/components/user_info';
import { getBackfillRowsFromResponse } from './utils';
import { HeaderSection } from '../../../../common/components/header_section';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
+import { TableHeaderTooltipCell } from '../../../rule_management_ui/components/rules_table/table_header_tooltip_cell';
+import { TECHNICAL_PREVIEW, TECHNICAL_PREVIEW_TOOLTIP } from '../../../../common/translations';
+import { useKibana } from '../../../../common/lib/kibana';
-const AUTO_REFRESH_INTERVAL = 3000;
const DEFAULT_PAGE_SIZE = 10;
const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => {
const stopAction = {
+ name: i18n.BACKFILLS_TABLE_COLUMN_ACTION,
render: (item: BackfillRow) => ,
width: '10%',
};
@@ -36,18 +42,33 @@ const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => {
const columns: Array> = [
{
field: 'status',
- name: i18n.BACKFILLS_TABLE_COLUMN_STATUS,
+ name: (
+
+ ),
render: (value: BackfillStatus) => ,
width: '10%',
},
{
field: 'created_at',
- name: i18n.BACKFILLS_TABLE_COLUMN_CREATED_AT,
+ name: (
+
+ ),
render: (value: 'string') => ,
width: '20%',
},
{
- name: i18n.BACKFILLS_TABLE_COLUMN_SOURCE_TIME_RANCE,
+ name: (
+
+ ),
render: (value: BackfillRow) => (
<>
@@ -60,31 +81,56 @@ const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => {
{
field: 'error',
align: 'right',
- name: i18n.BACKFILLS_TABLE_COLUMN_ERROR,
+ name: (
+
+ ),
'data-test-subj': 'rule-backfills-column-error',
},
{
field: 'pending',
align: 'right',
- name: i18n.BACKFILLS_TABLE_COLUMN_PENDING,
+ name: (
+
+ ),
'data-test-subj': 'rule-backfills-column-pending',
},
{
field: 'running',
align: 'right',
- name: i18n.BACKFILLS_TABLE_COLUMN_RUNNING,
+ name: (
+
+ ),
'data-test-subj': 'rule-backfills-column-running',
},
{
field: 'complete',
align: 'right',
- name: i18n.BACKFILLS_TABLE_COLUMN_COMPLETED,
+ name: (
+
+ ),
'data-test-subj': 'rule-backfills-column-completed',
},
{
field: 'total',
align: 'right',
- name: i18n.BACKFILLS_TABLE_COLUMN_TOTAL,
+ name: (
+
+ ),
'data-test-subj': 'rule-backfills-column-total',
},
];
@@ -98,21 +144,18 @@ const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => {
export const RuleBackfillsInfo = React.memo<{ ruleId: string }>(({ ruleId }) => {
const isManualRuleRunEnabled = useIsExperimentalFeatureEnabled('manualRuleRunEnabled');
- const [autoRefreshInterval, setAutoRefreshInterval] = useState(AUTO_REFRESH_INTERVAL);
- const [isAutoRefresh, setIsAutoRefresh] = useState(false);
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
const [{ canUserCRUD }] = useUserData();
const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD);
-
- const { data, isLoading, isError } = useFindBackfillsForRules(
+ const { timelines } = useKibana().services;
+ const { data, isLoading, isError, refetch, dataUpdatedAt } = useFindBackfillsForRules(
{
ruleIds: [ruleId],
page: pageIndex + 1,
perPage: pageSize,
},
{
- refetchInterval: isAutoRefresh ? autoRefreshInterval : false,
enabled: isManualRuleRunEnabled,
}
);
@@ -131,13 +174,6 @@ export const RuleBackfillsInfo = React.memo<{ ruleId: string }>(({ ruleId }) =>
totalItemCount: data?.total ?? 0,
};
- if (data?.total === 0) return null;
-
- const handleRefreshChange = ({ isPaused, refreshInterval }: OnRefreshChangeProps) => {
- setIsAutoRefresh(!isPaused);
- setAutoRefreshInterval(refreshInterval);
- };
-
const handleTableChange: (params: CriteriaWithPagination) => void = ({
page,
sort,
@@ -148,23 +184,39 @@ export const RuleBackfillsInfo = React.memo<{ ruleId: string }>(({ ruleId }) =>
}
};
+ const handleRefresh = () => {
+ refetch();
+ };
+
return (
-
-
+
+
-
+
+
+
+
+
+
+
+
+ {i18n.BACKFILL_TABLE_REFRESH}
+
+
+
+
-
+ {timelines.getLastUpdated({
+ showUpdating: isLoading,
+ updatedAt: dataUpdatedAt,
+ })}
+
(({ ruleId }) =>
error={isError ? 'error' : undefined}
loading={isLoading}
onChange={handleTableChange}
- noItemsMessage={'not found'}
/>
-
+
);
});
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/translations.ts
index cb77ec89524fce..c2297e237100be 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/translations.ts
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_gaps/translations.ts
@@ -14,6 +14,13 @@ export const BACKFILLS_TABLE_COLUMN_STATUS = i18n.translate(
}
);
+export const BACKFILLS_TABLE_COLUMN_STATUS_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.statusTooltip',
+ {
+ defaultMessage: 'Overall status of execution',
+ }
+);
+
export const BACKFILLS_TABLE_COLUMN_CREATED_AT = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.createdAt',
{
@@ -21,13 +28,27 @@ export const BACKFILLS_TABLE_COLUMN_CREATED_AT = i18n.translate(
}
);
-export const BACKFILLS_TABLE_COLUMN_SOURCE_TIME_RANCE = i18n.translate(
+export const BACKFILLS_TABLE_COLUMN_CREATED_AT_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.createdAtTooltip',
+ {
+ defaultMessage: 'When the manual run started',
+ }
+);
+
+export const BACKFILLS_TABLE_COLUMN_SOURCE_TIME_RANGE = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.sourceTimeRange',
{
defaultMessage: 'Source event time range',
}
);
+export const BACKFILLS_TABLE_COLUMN_SOURCE_TIME_RANGE_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.sourceTimeRangeTooltip',
+ {
+ defaultMessage: 'The date and time range selected for the manual run',
+ }
+);
+
export const BACKFILLS_TABLE_COLUMN_ERROR = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.error',
{
@@ -35,6 +56,13 @@ export const BACKFILLS_TABLE_COLUMN_ERROR = i18n.translate(
}
);
+export const BACKFILLS_TABLE_COLUMN_ERROR_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.errorTooltip',
+ {
+ defaultMessage: 'The number of failed manual run rule executions',
+ }
+);
+
export const BACKFILLS_TABLE_COLUMN_COMPLETED = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.completed',
{
@@ -42,6 +70,13 @@ export const BACKFILLS_TABLE_COLUMN_COMPLETED = i18n.translate(
}
);
+export const BACKFILLS_TABLE_COLUMN_COMPLETED_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.completedTooltip',
+ {
+ defaultMessage: 'The number of completed manual run rule executions',
+ }
+);
+
export const BACKFILLS_TABLE_COLUMN_RUNNING = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.running',
{
@@ -49,6 +84,13 @@ export const BACKFILLS_TABLE_COLUMN_RUNNING = i18n.translate(
}
);
+export const BACKFILLS_TABLE_COLUMN_RUNNING_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.runningTooltip',
+ {
+ defaultMessage: 'The number of manual run rule executions that are in progress',
+ }
+);
+
export const BACKFILLS_TABLE_COLUMN_PENDING = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.pending',
{
@@ -56,6 +98,13 @@ export const BACKFILLS_TABLE_COLUMN_PENDING = i18n.translate(
}
);
+export const BACKFILLS_TABLE_COLUMN_PENDING_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.pendingTooltip',
+ {
+ defaultMessage: 'The number of manual run rule executions that are waiting to execute',
+ }
+);
+
export const BACKFILLS_TABLE_COLUMN_TOTAL = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.column.total',
{
@@ -63,17 +112,25 @@ export const BACKFILLS_TABLE_COLUMN_TOTAL = i18n.translate(
}
);
+export const BACKFILLS_TABLE_COLUMN_TOTAL_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.totalTooltip',
+ {
+ defaultMessage:
+ 'The total number of rule executions that will occur during the selected date and time range',
+ }
+);
+
export const BACKFILLS_TABLE_STOP = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.stop',
{
- defaultMessage: 'Stop',
+ defaultMessage: 'Stop run',
}
);
export const BACKFILLS_TABLE_STOP_CONFIRMATION_TITLE = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.stop.confirmationTitle',
{
- defaultMessage: 'Are you sure you want to stop this run?',
+ defaultMessage: 'Stop this rule run',
}
);
@@ -87,42 +144,49 @@ export const BACKFILLS_TABLE_STOP_CONFIRMATION_CANCEL = i18n.translate(
export const BACKFILLS_TABLE_STOP_CONFIRMATION_STOP_RUNS = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.stop.stopRuns',
{
- defaultMessage: 'Stop runs',
+ defaultMessage: 'Stop run',
}
);
export const BACKFILLS_TABLE_STOP_CONFIRMATION_BODY = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.stop.description',
{
- defaultMessage: 'All remaining rule runs will be stopped',
+ defaultMessage: 'All the pending rule executions for this manual rule run will be stopped',
}
);
export const BACKFILLS_TABLE_STOP_CONFIRMATION_SUCCESS = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.stop.confirmationSuccess',
{
- defaultMessage: 'Run stopped',
+ defaultMessage: 'Rule run stopped',
}
);
export const BACKFILLS_TABLE_STOP_CONFIRMATION_ERROR = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillsTable.stop.confirmationError',
{
- defaultMessage: 'Error stopping run',
+ defaultMessage: 'Error stopping rule run',
}
);
export const BACKFILL_TABLE_TITLE = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillTable.title',
{
- defaultMessage: 'Backfill runs',
+ defaultMessage: 'Manual runs',
+ }
+);
+
+export const BACKFILL_TABLE_REFRESH = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillTable.refresh',
+ {
+ defaultMessage: 'Refresh',
}
);
export const BACKFILL_TABLE_SUBTITLE = i18n.translate(
'xpack.securitySolution.rule_gaps.backfillTable.subtitle',
{
- defaultMessage: 'View and manage backfill runs',
+ defaultMessage: 'View and manage active manual runs',
}
);
@@ -132,13 +196,20 @@ export const BACKFILL_SCHEDULE_SUCCESS = (numRules: number) =>
{
values: { numRules },
defaultMessage:
- 'Successfully scheduled backfill for {numRules, plural, =1 {# rule} other {# rules}}',
+ 'Successfully scheduled manual run for {numRules, plural, =1 {# rule} other {# rules}}',
}
);
export const BACKFILL_SCHEDULE_ERROR_TITLE = i18n.translate(
'xpack.securitySolution.containers.detectionEngine.backfillSchedule.scheduleRuleRunErrorTitle',
{
- defaultMessage: 'Error while scheduling backfill',
+ defaultMessage: 'Error while scheduling manual run',
+ }
+);
+
+export const BACKFILLS_TABLE_COLUMN_ACTION = i18n.translate(
+ 'xpack.securitySolution.rule_gaps.backfillsTable.column.action',
+ {
+ defaultMessage: 'Action',
}
);
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx
index dc4a0cb429b87b..4af2fdd7ef3562 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx
@@ -122,7 +122,8 @@ export const useRulesTableActions = ({
{
type: 'icon',
'data-test-subj': 'manualRuleRunAction',
- description: i18n.MANUAL_RULE_RUN,
+ description: (rule) =>
+ !rule.enabled ? i18n.MANUAL_RULE_RUN_TOOLTIP : i18n.MANUAL_RULE_RUN,
icon: 'play',
name: i18n.MANUAL_RULE_RUN,
onClick: async (rule: Rule) => {
diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx
index 5be000d508195b..6ed110483ecc4c 100644
--- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx
@@ -155,6 +155,11 @@ const RuleActionsOverflowComponent = ({
key={i18nActions.MANUAL_RULE_RUN}
icon="play"
disabled={!userHasPermissions || !rule.enabled}
+ toolTipContent={
+ !userHasPermissions || !rule.enabled
+ ? i18nActions.MANUAL_RULE_RUN_TOOLTIP
+ : ''
+ }
data-test-subj="rules-details-manual-rule-run"
onClick={async () => {
startTransaction({ name: SINGLE_RULE_ACTIONS.MANUAL_RULE_RUN });
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts
index eb2d6b01b492ff..b8e4063abb600a 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts
@@ -584,6 +584,13 @@ export const MANUAL_RULE_RUN = i18n.translate(
}
);
+export const MANUAL_RULE_RUN_TOOLTIP = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunTooltip',
+ {
+ defaultMessage: 'Manual run available only for enabled rules',
+ }
+);
+
export const COLUMN_RULE = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.allRules.columns.ruleTitle',
{
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_gaps/manual_rule_run.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_gaps/manual_rule_run.cy.ts
index 28eaef22cc2e7d..29e2379367c0b1 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_gaps/manual_rule_run.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_gaps/manual_rule_run.cy.ts
@@ -32,7 +32,7 @@ describe('Manual rule run', { tags: ['@ess', '@serverless', '@skipInServerlessMK
);
manualRuleRunFromDetailsPage();
- cy.get(TOASTER).should('have.text', 'Successfully scheduled backfill for 1 rule');
+ cy.get(TOASTER).should('have.text', 'Successfully scheduled manual run for 1 rule');
});
it('schedule from rules management table', () => {
@@ -42,7 +42,7 @@ describe('Manual rule run', { tags: ['@ess', '@serverless', '@skipInServerlessMK
disableAutoRefresh();
manuallyRunFirstRule();
- cy.get(TOASTER).should('have.text', 'Successfully scheduled backfill for 1 rule');
+ cy.get(TOASTER).should('have.text', 'Successfully scheduled manual run for 1 rule');
}
);
});
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/backfill_group.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/backfill_group.cy.ts
index 7413b8a8f02c71..2f97e2f3c07217 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/backfill_group.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/backfill_group.cy.ts
@@ -58,7 +58,7 @@ describe(
interceptFindBackfills();
goToExecutionLogTab();
- cy.get(RULE_BACKFILLS_INFO_HEADEAR).contains('Backfill runs');
+ cy.get(RULE_BACKFILLS_INFO_HEADEAR).contains('Manual runs');
getBackfillsTableRows().should('have.length', 2);
getBackfillsTableRows().eq(0).contains('Pending');
getBackfillsTableRows().eq(0).find(RULE_BACKFILLS_COLUMN_ERROR).contains('1');
@@ -76,11 +76,11 @@ describe(
getBackfillsTableRows().eq(0).find(RULE_BACKFILLS_DELETE_BUTTON).click();
- cy.get(RULE_BACKFILLS_DELETE_MODAL).contains('Are you sure you want to stop this run?');
+ cy.get(RULE_BACKFILLS_DELETE_MODAL).contains('Stop this rule run');
interceptDeleteBackfill(FIRST_BACKFILL_ID, 'deleteBackfill');
cy.get(RULE_BACKFILL_DELETE_MODAL_CONFIRM_BUTTON).click();
cy.wait('@deleteBackfill');
- cy.get(TOASTER).contains('Run stopped');
+ cy.get(TOASTER).contains('Rule run stopped');
});
}
);