diff --git a/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx b/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx index 9dd78d764..76b797488 100644 --- a/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx +++ b/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx @@ -5,6 +5,7 @@ import userEvent from '@testing-library/user-event'; import { VirtuosoMockContext } from 'react-virtuoso'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { GetTaskIdsForMassSelectionQuery } from 'src/hooks/GetIdsForMassSelection.generated'; import useTaskModal from 'src/hooks/useTaskModal'; import { dispatch } from 'src/lib/analytics'; import theme from 'src/theme'; @@ -141,7 +142,10 @@ describe('tasks page', () => { it('should dispatch one analytics event per task', async () => { const { getAllByTestId, getByRole, findByRole } = render( - + mocks={{ Tasks: { tasks: { @@ -154,6 +158,11 @@ describe('tasks page', () => { pageInfo: { hasNextPage: false }, }, }, + GetTaskIdsForMassSelection: { + tasks: { + nodes: [{ id: '1' }, { id: '2' }, { id: '3' }], + }, + }, }} > diff --git a/src/hooks/useMassSelection.test.ts b/src/hooks/useMassSelection.test.ts index bbe5aaca8..10a146d7f 100644 --- a/src/hooks/useMassSelection.test.ts +++ b/src/hooks/useMassSelection.test.ts @@ -1,6 +1,6 @@ import { renderHook } from '@testing-library/react'; import { ListHeaderCheckBoxState } from 'src/components/Shared/Header/ListHeader'; -import { useMassSelection } from './useMassSelection'; +import { UseMassSelectionResult, useMassSelection } from './useMassSelection'; const defaultIdsList = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; @@ -117,4 +117,18 @@ describe('useMassSelection', () => { expect(result.current.ids).toEqual(['1', '2', '3', '7', '8', '9', '10']); }); }); + + it('deselects removed ids', () => { + const { result, rerender } = renderHook< + UseMassSelectionResult, + { ids: string[] } + >(({ ids }) => useMassSelection(ids), { + initialProps: { ids: defaultIdsList }, + }); + + result.current.selectMultipleIds(['1', '2', '3']); + + rerender({ ids: ['2', '3', '4'] }); + expect(result.current.ids).toEqual(['2', '3']); + }); }); diff --git a/src/hooks/useMassSelection.ts b/src/hooks/useMassSelection.ts index d9a849e3a..91366e1d0 100644 --- a/src/hooks/useMassSelection.ts +++ b/src/hooks/useMassSelection.ts @@ -1,9 +1,7 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { ListHeaderCheckBoxState } from '../components/Shared/Header/ListHeader'; -export const useMassSelection = ( - idsList: string[], -): { +export interface UseMassSelectionResult { ids: string[]; selectionType: ListHeaderCheckBoxState; isRowChecked: (id: string) => boolean; @@ -12,11 +10,18 @@ export const useMassSelection = ( toggleSelectionById: (id: string) => void; selectMultipleIds: (ids: string[]) => void; deselectMultipleIds: (ids: string[]) => void; -} => { +} + +export const useMassSelection = (idsList: string[]): UseMassSelectionResult => { const totalCount = idsList.length; const [ids, setIds] = useState([]); + // When the idsList change, deselect any ids that were removed + useEffect(() => { + setIds((previousIds) => previousIds.filter((id) => idsList.includes(id))); + }, [idsList]); + const toggleSelectionById = (id: string) => { if (ids.includes(id)) { setIds((previousIds) =>