Fix batch update optimistic and prevent accidental mass-update (#17213)
## Problem - ⚠️ Multi-edit could silently update ALL records of an object with no undo, no ctrl-z - After a batch update the table showed stale data — `useIncrementalUpdateManyRecords` had no explicit `findMany` refetch and `skipOptimisticEffect` was missing - Clicking inside the side panel deselected all kanban cards — `RecordBoardClickOutsideEffect` uses `refs:[]` and the side panel had no `data-click-outside-id` - Clicking a currency/select dropdown inside the panel also triggered deselection — `FloatingPortal` renders outside the side panel DOM, bypassing the click-outside-id exclusion - An empty selection silently matched every record — `computeContextStoreFilters` returned `undefined` filter when `selectedRecordIds` was `[]` ## Fix - Table refreshes correctly after batch update — `useRefetchFindManyRecords` explicitly refetches `FindMany<Object>` queries; `useIncrementalUpdateManyRecords` adds `skipOptimisticEffect: true` and calls it in `finally` - Clicking the side panel no longer deselects kanban cards — `SidePanelForDesktop` carries `data-click-outside-id`; `RecordBoardClickOutsideEffect` + `RecordTableBodyFocusClickOutsideEffect` exclude it - Clicking dropdowns inside the panel no longer deselects either — `ParentClickOutsideIdContext` propagates the side panel ID into `FloatingPortal` content via `DropdownInternalContainer` - Empty selection can no longer match all records — `computeContextStoreFilters` returns `{ id: { in: [] } }` instead of `undefined` - Apply is disabled with no selection; a confirmation modal shows the count + no-undo warning before executing — `UpdateMultipleRecordsContainer` ## Not included - Undo / snapshot restore — requires backend changes, out of scope ## Blast radius - `ParentClickOutsideIdContext` touches `DropdownInternalContainer` (207 `<Dropdown>` usages). `parentClickOutsideId` is `undefined` everywhere outside the side panel → attribute not rendered → zero behavioral change for existing consumers. --------- Co-authored-by: Samuel Arbibe <samuelarbibe@Samuels-MacBook-Pro.local> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
+7
-1
@@ -10,6 +10,7 @@ import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContaine
|
||||
import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { ClickOutsideListenerContext } from '@/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext';
|
||||
import { ParentClickOutsideIdContext } from '@/ui/utilities/pointer-event/contexts/ParentClickOutsideIdContext';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
@@ -141,6 +142,7 @@ export const DropdownInternalContainer = ({
|
||||
};
|
||||
|
||||
const { excludedClickOutsideId } = useContext(ClickOutsideListenerContext);
|
||||
const parentClickOutsideId = useContext(ParentClickOutsideIdContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -162,7 +164,11 @@ export const DropdownInternalContainer = ({
|
||||
isDropdownInModal={isDropdownInModal}
|
||||
>
|
||||
<OverlayContainer>
|
||||
<StyledDropdownInsideContainer id={dropdownId} data-select-disable>
|
||||
<StyledDropdownInsideContainer
|
||||
id={dropdownId}
|
||||
data-select-disable
|
||||
data-click-outside-id={parentClickOutsideId}
|
||||
>
|
||||
{dropdownComponents}
|
||||
</StyledDropdownInsideContainer>
|
||||
</OverlayContainer>
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
export const ParentClickOutsideIdContext = createContext<string | undefined>(
|
||||
undefined,
|
||||
);
|
||||
Reference in New Issue
Block a user