From 8800508d55630f263a678ac59dfd18b5b3cdc0cd Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:51:07 -0800 Subject: [PATCH] [Security Solution][EuiInMemoryTable] Replace usage of deprecated ref method with controlled `selection.selected` API (#175726) ## Summary **Please help us QA your affected tables to confirm that your plugin's table selection still works as before!** EUI will shortly be removing this deprecated ref `setSelection` method in favor of the new controlled `selection.selected` prop. This PR converts basic usages of controlled selection, which should not suffer any UI/UX regressions. See also: - https://github.com/elastic/eui/pull/7321 - https://github.com/elastic/kibana/pull/175722 (examples of basic conversions) Co-authored-by: Tomasz Ciecierski --- .../components/rules_table/rules_tables.tsx | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx index 3c2c79ef20d3f..707846c8a492a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx @@ -10,7 +10,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React, { useCallback, useMemo, useRef } from 'react'; import { Loader } from '../../../../common/components/loader'; import { useBoolState } from '../../../../common/hooks/use_bool_state'; -import { useValueChanged } from '../../../../common/hooks/use_value_changed'; import { PrePackagedRulesPrompt } from '../../../../detections/components/rules/pre_packaged_rules/load_empty_prompt'; import type { Rule } from '../../../rule_management/logic'; import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; @@ -61,7 +60,6 @@ export const RulesTables = React.memo(({ selectedTab }) => { const hasPermissions = hasUserCRUDPermission(canUserCRUD); const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages(); - const tableRef = useRef(null); const rulesTableContext = useRulesTableContext(); const { data: ruleManagementFilters } = useRuleManagementFilters(); @@ -171,14 +169,6 @@ export const RulesTables = React.memo(({ selectedTab }) => { const isSelectAllCalled = useRef(false); - // TODO Remove this synchronization logic after https://github.com/elastic/eui/issues/6184 is implemented - // Synchronize selectedRuleIds with EuiBasicTable's selected rows - useValueChanged((ruleIds) => { - if (tableRef.current != null) { - tableRef.current.setSelection(rules.filter((rule) => ruleIds.includes(rule.id))); - } - }, selectedRuleIds); - const isTableSelectable = hasPermissions && (selectedTab === AllRulesTabs.management || selectedTab === AllRulesTabs.monitoring); @@ -187,30 +177,12 @@ export const RulesTables = React.memo(({ selectedTab }) => { () => ({ selectable: (item: Rule) => !loadingRuleIds.includes(item.id), onSelectionChange: (selected: Rule[]) => { - /** - * EuiBasicTable doesn't provide declarative API to control selected rows. - * This limitation requires us to synchronize selection state manually using setSelection(). - * But it creates a chain reaction when the user clicks Select All: - * selectAll() -> setSelection() -> onSelectionChange() -> setSelection(). - * To break the chain we should check whether the onSelectionChange was triggered - * by the Select All action or not. - * - */ - if (isSelectAllCalled.current) { - isSelectAllCalled.current = false; - // Handle special case of unselecting all rules via checkbox - // after all rules were selected via Bulk select. - if (selected.length === 0) { - setIsAllSelected(false); - setSelectedRuleIds([]); - } - } else { - setSelectedRuleIds(selected.map(({ id }) => id)); - setIsAllSelected(false); - } + setSelectedRuleIds(selected.map(({ id }) => id)); + setIsAllSelected(false); }, + selected: selectedRuleIds.map((id) => ({ id } as Rule)), // EuiBasicTable only needs the itemId }), - [loadingRuleIds, setIsAllSelected, setSelectedRuleIds] + [loadingRuleIds, setIsAllSelected, setSelectedRuleIds, selectedRuleIds] ); const toggleSelectAll = useCallback(() => { @@ -329,7 +301,6 @@ export const RulesTables = React.memo(({ selectedTab }) => { noItemsMessage={NO_ITEMS_MESSAGE} onChange={tableOnChangeCallback} pagination={paginationMemo} - ref={tableRef} selection={isTableSelectable ? euiBasicTableSelectionProps : undefined} sorting={{ sort: {