diff --git a/app/src/organisms/ErrorRecoveryFlows/hooks/useFailedLabwareUtils.ts b/app/src/organisms/ErrorRecoveryFlows/hooks/useFailedLabwareUtils.ts index bee6eb0474c..ebe8a5f9bd9 100644 --- a/app/src/organisms/ErrorRecoveryFlows/hooks/useFailedLabwareUtils.ts +++ b/app/src/organisms/ErrorRecoveryFlows/hooks/useFailedLabwareUtils.ts @@ -174,6 +174,7 @@ interface UseTipSelectionUtilsResult { tipSelectorDef: LabwareDefinition2 selectTips: (tipGroup: WellGroup) => void deselectTips: (locations: string[]) => void + areTipsSelected: boolean } // TODO(jh, 06-18-24): Enforce failure/warning when accessing tipSelectionUtils @@ -215,11 +216,15 @@ function useTipSelectionUtils( [] ) + const areTipsSelected = + selectedLocs != null && Object.keys(selectedLocs).length > 0 + return { selectedTipLocations: selectedLocs, tipSelectorDef, selectTips, deselectTips, + areTipsSelected, } } diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/SelectTips.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/SelectTips.tsx index d4012670c27..6bad4600c76 100644 --- a/app/src/organisms/ErrorRecoveryFlows/shared/SelectTips.tsx +++ b/app/src/organisms/ErrorRecoveryFlows/shared/SelectTips.tsx @@ -17,6 +17,7 @@ export function SelectTips(props: RecoveryContentProps): JSX.Element | null { routeUpdateActions, recoveryCommands, isOnDevice, + failedLabwareUtils, } = props const { ROBOT_PICKING_UP_TIPS } = RECOVERY_MAP const { pickUpTips } = recoveryCommands @@ -75,6 +76,7 @@ export function SelectTips(props: RecoveryContentProps): JSX.Element | null { + , getTopPortalEl() diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/SelectTips.test.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/SelectTips.test.tsx index 15afe841639..bccc0567d8b 100644 --- a/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/SelectTips.test.tsx +++ b/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/SelectTips.test.tsx @@ -49,6 +49,10 @@ describe('SelectTips', () => { channels: 8, }, } as any, + failedLabwareUtils: { + selectedTipLocations: { A1: null }, + areTipsSelected: true, + } as any, } vi.mocked(TipSelectionModal).mockReturnValue( @@ -138,4 +142,22 @@ describe('SelectTips', () => { }) expect(tertiaryBtn[0]).toBeDisabled() }) + + it('disables the primary button if tips are not selected', () => { + props = { + ...props, + failedLabwareUtils: { + selectedTipLocations: null, + areTipsSelected: false, + } as any, + } + + render(props) + + const primaryBtn = screen.getAllByRole('button', { + name: 'Pick up tips', + }) + + expect(primaryBtn[0]).toBeDisabled() + }) }) diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/TipSelectionModal.test.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/TipSelectionModal.test.tsx index 608c870324c..78f9666b3e0 100644 --- a/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/TipSelectionModal.test.tsx +++ b/app/src/organisms/ErrorRecoveryFlows/shared/__tests__/TipSelectionModal.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import { describe, it, vi, beforeEach } from 'vitest' +import { describe, it, vi, beforeEach, expect } from 'vitest' import { screen } from '@testing-library/react' import { mockRecoveryContentProps } from '../../__fixtures__' @@ -24,6 +24,10 @@ describe('TipSelectionModal', () => { ...mockRecoveryContentProps, allowTipSelection: true, toggleModal: vi.fn(), + failedLabwareUtils: { + selectedTipLocations: { A1: null }, + areTipsSelected: true, + } as any, } vi.mocked(TipSelection).mockReturnValue(
MOCK TIP SELECTION
) @@ -39,5 +43,17 @@ describe('TipSelectionModal', () => { render(props) screen.getByText('MOCK TIP SELECTION') + screen.getByLabelText('closeIcon') + }) + + it('prevents from users from exiting the modal if no well(s) are selected', () => { + props = { + ...props, + failedLabwareUtils: { areTipsSelected: false } as any, + } + + render(props) + + expect(screen.queryByLabelText('closeIcon')).not.toBeInTheDocument() }) })