Skip to content

Commit

Permalink
[Security Solution][EuiInMemoryTable] Replace usage of deprecated ref…
Browse files Browse the repository at this point in the history
… method with controlled `selection.selected` API (elastic#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: 
- elastic/eui#7321
- elastic#175722 (examples of basic
conversions)

Co-authored-by: Tomasz Ciecierski <tomasz.ciecierski@elastic.co>
  • Loading branch information
2 people authored and WafaaNasr committed Feb 5, 2024
1 parent 9b8ef39 commit 010437a
Showing 1 changed file with 4 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -61,7 +60,6 @@ export const RulesTables = React.memo<RulesTableProps>(({ selectedTab }) => {
const hasPermissions = hasUserCRUDPermission(canUserCRUD);
const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages();

const tableRef = useRef<EuiBasicTable>(null);
const rulesTableContext = useRulesTableContext();
const { data: ruleManagementFilters } = useRuleManagementFilters();

Expand Down Expand Up @@ -171,14 +169,6 @@ export const RulesTables = React.memo<RulesTableProps>(({ 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);
Expand All @@ -187,30 +177,12 @@ export const RulesTables = React.memo<RulesTableProps>(({ 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(() => {
Expand Down Expand Up @@ -329,7 +301,6 @@ export const RulesTables = React.memo<RulesTableProps>(({ selectedTab }) => {
noItemsMessage={NO_ITEMS_MESSAGE}
onChange={tableOnChangeCallback}
pagination={paginationMemo}
ref={tableRef}
selection={isTableSelectable ? euiBasicTableSelectionProps : undefined}
sorting={{
sort: {
Expand Down

0 comments on commit 010437a

Please sign in to comment.