diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx
index b4ff6ab29a3ff..05078d8492e31 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx
@@ -28,6 +28,7 @@ export const AddPrebuiltRulesHeaderButtons = () => {
loadingRules,
isRefetching,
isUpgradingSecurityPackages,
+ isInstallingAllRules,
hasRulesToInstall,
},
actions: { installAllRules, installSelectedRules },
@@ -38,7 +39,7 @@ export const AddPrebuiltRulesHeaderButtons = () => {
const numberOfSelectedRules = selectedRules.length ?? 0;
const shouldDisplayInstallSelectedRulesButton = numberOfSelectedRules > 0;
- const isRuleInstalling = loadingRules.length > 0;
+ const isRuleInstalling = loadingRules.length > 0 || isInstallingAllRules;
const isRequestInProgress = isRuleInstalling || isRefetching || isUpgradingSecurityPackages;
const [isOverflowPopoverOpen, setOverflowPopover] = useBoolean(false);
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_install_button.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_install_button.tsx
index ea83efae768fa..fc1656ea8cdea 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_install_button.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_install_button.tsx
@@ -19,7 +19,7 @@ import React, { useCallback, useMemo } from 'react';
import { useBoolean } from 'react-use';
import type { Rule } from '../../../../rule_management/logic';
import type { RuleSignatureId } from '../../../../../../common/api/detection_engine';
-import type { AddPrebuiltRulesTableActions } from './add_prebuilt_rules_table_context';
+import { type AddPrebuiltRulesTableActions } from './add_prebuilt_rules_table_context';
import * as i18n from './translations';
export interface PrebuiltRulesInstallButtonProps {
@@ -28,6 +28,7 @@ export interface PrebuiltRulesInstallButtonProps {
installOneRule: AddPrebuiltRulesTableActions['installOneRule'];
loadingRules: RuleSignatureId[];
isDisabled: boolean;
+ isInstallingAllRules: boolean;
}
export const PrebuiltRulesInstallButton = ({
@@ -36,8 +37,9 @@ export const PrebuiltRulesInstallButton = ({
installOneRule,
loadingRules,
isDisabled,
+ isInstallingAllRules,
}: PrebuiltRulesInstallButtonProps) => {
- const isRuleInstalling = loadingRules.includes(ruleId);
+ const isRuleInstalling = loadingRules.includes(ruleId) || isInstallingAllRules;
const isInstallButtonDisabled = isRuleInstalling || isDisabled;
const [isPopoverOpen, setPopover] = useBoolean(false);
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx
index 4be2547598b5d..c8ee77040b184 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx
@@ -14,6 +14,7 @@ import { useUserData } from '../../../../../detections/components/user_info';
import { usePrebuiltRulesInstallReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_install_review';
import { useFetchPrebuiltRulesStatusQuery } from '../../../../rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_status_query';
import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
// Mock components not needed in this test suite
jest.mock('../../../../rule_management/components/rule_details/rule_details_flyout', () => ({
@@ -109,10 +110,12 @@ describe('AddPrebuiltRulesTable', () => {
]);
render(
-
-
-
-
+
+
+
+
+
+
);
const installAllButton = screen.getByTestId('installAllRulesButton');
@@ -132,10 +135,12 @@ describe('AddPrebuiltRulesTable', () => {
(useIsUpgradingSecurityPackages as jest.Mock).mockReturnValueOnce(true);
render(
-
-
-
-
+
+
+
+
+
+
);
const installAllButton = screen.getByTestId('installAllRulesButton');
@@ -153,10 +158,12 @@ describe('AddPrebuiltRulesTable', () => {
]);
render(
-
-
-
-
+
+
+
+
+
+
);
const installAllButton = screen.getByTestId('installAllRulesButton');
@@ -198,9 +205,11 @@ describe('AddPrebuiltRulesTable', () => {
});
const { findByText } = render(
-
-
-
+
+
+
+
+
);
expect(await findByText('All Elastic rules have been installed')).toBeInTheDocument();
@@ -245,9 +254,11 @@ describe('AddPrebuiltRulesTable', () => {
});
render(
-
-
-
+
+
+
+
+
);
const installRuleButton = screen.queryByTestId(`installSinglePrebuiltRuleButton-${id}`);
@@ -293,9 +304,11 @@ describe('AddPrebuiltRulesTable', () => {
});
render(
-
-
-
+
+
+
+
+
);
const installRuleButton = screen.queryByTestId(`installSinglePrebuiltRuleButton-${id}`);
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx
index 14e539ec40ae1..dca4809001971 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx
@@ -5,25 +5,27 @@
* 2.0.
*/
+import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { useIsMutating } from '@tanstack/react-query';
import type { Dispatch, SetStateAction } from 'react';
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
-import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
-import { useUserData } from '../../../../../detections/components/user_info';
-import { useFetchPrebuiltRulesStatusQuery } from '../../../../rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_status_query';
-import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages';
import type { RuleSignatureId } from '../../../../../../common/api/detection_engine';
+import type { RuleResponse } from '../../../../../../common/api/detection_engine/model/rule_schema';
import { invariant } from '../../../../../../common/utils/invariant';
+import { useUserData } from '../../../../../detections/components/user_info';
+import { useFetchPrebuiltRulesStatusQuery } from '../../../../rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_status_query';
+import { PERFORM_ALL_RULES_INSTALLATION_KEY } from '../../../../rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation';
import {
usePerformInstallAllRules,
usePerformInstallSpecificRules,
} from '../../../../rule_management/logic/prebuilt_rules/use_perform_rule_install';
import { usePrebuiltRulesInstallReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_install_review';
-import type { AddPrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_install';
-import { useFilterPrebuiltRulesToInstall } from './use_filter_prebuilt_rules_to_install';
+import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages';
import { useRulePreviewFlyout } from '../use_rule_preview_flyout';
-import type { RuleResponse } from '../../../../../../common/api/detection_engine/model/rule_schema';
-import * as i18n from './translations';
import { isUpgradeReviewRequestEnabled } from './add_prebuilt_rules_utils';
+import * as i18n from './translations';
+import type { AddPrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_install';
+import { useFilterPrebuiltRulesToInstall } from './use_filter_prebuilt_rules_to_install';
export interface AddPrebuiltRulesTableState {
/**
@@ -59,6 +61,11 @@ export interface AddPrebuiltRulesTableState {
* package in background
*/
isUpgradingSecurityPackages: boolean;
+
+ /**
+ * Is true when performing Install All Rules mutation
+ */
+ isInstallingAllRules: boolean;
/**
* List of rule IDs that are currently being upgraded
*/
@@ -112,6 +119,10 @@ export const AddPrebuiltRulesTableContextProvider = ({
const { data: prebuiltRulesStatus } = useFetchPrebuiltRulesStatusQuery();
const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages();
+ const isInstallingAllRules =
+ useIsMutating({
+ mutationKey: PERFORM_ALL_RULES_INSTALLATION_KEY,
+ }) > 0;
const {
data: { rules, stats: { tags } } = {
@@ -269,6 +280,7 @@ export const AddPrebuiltRulesTableContextProvider = ({
loadingRules,
isRefetching,
isUpgradingSecurityPackages,
+ isInstallingAllRules,
selectedRules,
lastUpdated: dataUpdatedAt,
},
@@ -284,6 +296,7 @@ export const AddPrebuiltRulesTableContextProvider = ({
loadingRules,
isRefetching,
isUpgradingSecurityPackages,
+ isInstallingAllRules,
selectedRules,
dataUpdatedAt,
actions,
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx
index eaf3af79ee360..a0a317e72b4c2 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx
@@ -110,7 +110,8 @@ const INTEGRATIONS_COLUMN: TableColumn = {
const createInstallButtonColumn = (
installOneRule: AddPrebuiltRulesTableActions['installOneRule'],
loadingRules: RuleSignatureId[],
- isDisabled: boolean
+ isDisabled: boolean,
+ isInstallingAllRules: boolean
): TableColumn => ({
field: 'rule_id',
name: ,
@@ -121,6 +122,7 @@ const createInstallButtonColumn = (
installOneRule={installOneRule}
loadingRules={loadingRules}
isDisabled={isDisabled}
+ isInstallingAllRules={isInstallingAllRules}
/>
),
width: '10%',
@@ -132,11 +134,11 @@ export const useAddPrebuiltRulesTableColumns = (): TableColumn[] => {
const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD);
const [showRelatedIntegrations] = useUiSetting$(SHOW_RELATED_INTEGRATIONS_SETTING);
const {
- state: { loadingRules, isRefetching, isUpgradingSecurityPackages },
+ state: { loadingRules, isRefetching, isUpgradingSecurityPackages, isInstallingAllRules },
actions: { installOneRule },
} = useAddPrebuiltRulesTableContext();
- const isDisabled = isRefetching || isUpgradingSecurityPackages;
+ const isDisabled = isRefetching || isUpgradingSecurityPackages || isInstallingAllRules;
return useMemo(
() => [
@@ -164,9 +166,23 @@ export const useAddPrebuiltRulesTableColumns = (): TableColumn[] => {
width: '12%',
},
...(hasCRUDPermissions
- ? [createInstallButtonColumn(installOneRule, loadingRules, isDisabled)]
+ ? [
+ createInstallButtonColumn(
+ installOneRule,
+ loadingRules,
+ isDisabled,
+ isInstallingAllRules
+ ),
+ ]
: []),
],
- [hasCRUDPermissions, installOneRule, loadingRules, isDisabled, showRelatedIntegrations]
+ [
+ hasCRUDPermissions,
+ installOneRule,
+ loadingRules,
+ isDisabled,
+ showRelatedIntegrations,
+ isInstallingAllRules,
+ ]
);
};