Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(app): add labware selection and volume entry screens #15074

Merged
merged 10 commits into from
May 3, 2024
Prev Previous commit
Next Next commit
A few more test cases, code review cleanup
  • Loading branch information
smb2268 committed May 3, 2024
commit efa3ffd6230d5147779bf1e52c2c27658904db46
4 changes: 3 additions & 1 deletion app/src/organisms/QuickTransferFlow/VolumeEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export function VolumeEntry(props: VolumeEntryProps): JSX.Element {
const { i18n, t } = useTranslation(['quick_transfer', 'shared'])
const keyboardRef = React.useRef(null)

const [volume, setVolume] = React.useState<string>('')
const [volume, setVolume] = React.useState<string>(
state.volume ? state.volume.toString() : ''
)
const volumeRange = getVolumeLimits(state)
let headerCopy = t('set_transfer_volume')
let textEntryCopy = t('volume_per_well')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,16 @@ describe('SelectSourceLabware', () => {
render({ ...props, state: { pipette: { channels: 8 } as any } })
screen.getByText('Tube racks')
})

it('enables continue button if you select a labware', () => {
render(props)
const continueBtn = screen.getByTestId('ChildNavigation_Primary_Button')
expect(continueBtn).toBeDisabled()
const labwareOption = screen.getByText('Bio-Rad 384 Well Plate 50 µL')
fireEvent.click(labwareOption)
expect(continueBtn).toBeEnabled()
fireEvent.click(continueBtn)
expect(props.onNext).toHaveBeenCalled()
expect(props.dispatch).toHaveBeenCalled()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../i18n'
import { InputField } from '../../../atoms/InputField'
import { NumericalKeyboard } from '../../../atoms/SoftwareKeyboard'
import { getVolumeLimits } from '../utils'
import { VolumeEntry } from '../VolumeEntry'

vi.mock('../../../atoms/InputField')
vi.mock('../../../atoms/SoftwareKeyboard')
vi.mock('../utils')

const render = (props: React.ComponentProps<typeof VolumeEntry>) => {
return renderWithProviders(<VolumeEntry {...props} />, {
Expand Down Expand Up @@ -39,6 +41,7 @@ describe('VolumeEntry', () => {
},
dispatch: vi.fn(),
}
vi.mocked(getVolumeLimits).mockReturnValue({ min: 5, max: 50 })
})
afterEach(() => {
vi.resetAllMocks()
Expand Down Expand Up @@ -113,4 +116,43 @@ describe('VolumeEntry', () => {
{}
)
})

it('calls on next and dispatch if you press continue when volume is non-null and within range', () => {
render({
...props,
state: {
sourceWells: ['A1', 'A2'],
destinationWells: ['A1'],
volume: 20,
},
})
const continueBtn = screen.getByTestId('ChildNavigation_Primary_Button')
expect(continueBtn).toBeEnabled()
fireEvent.click(continueBtn)
expect(vi.mocked(props.onNext)).toHaveBeenCalled()
expect(vi.mocked(props.dispatch)).toHaveBeenCalled()
})

it('displays an error and disables continue when volume is outside of range', () => {
render({
...props,
state: {
sourceWells: ['A1', 'A2'],
destinationWells: ['A1'],
volume: 90,
},
})
const continueBtn = screen.getByTestId('ChildNavigation_Primary_Button')
expect(continueBtn).toBeDisabled()
expect(vi.mocked(InputField)).toHaveBeenCalledWith(
{
title: 'Aspirate volume per well (µL)',
error: 'Value must be between 5-50',
readOnly: true,
type: 'text',
value: '90',
},
{}
)
})
})
116 changes: 29 additions & 87 deletions app/src/organisms/QuickTransferFlow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@
cancel: cancelExit,
} = useConditionalConfirm(() => history.push('protocols'), true)

const exitButtonProps: React.ComponentProps<typeof SmallButton> = {
buttonType: 'tertiaryLowLight',
buttonText: i18n.format(t('shared:exit'), 'capitalize'),
onClick: confirmExit,
}

React.useEffect(() => {
if (state.volume != null) {
// until summary screen is implemented, log the final state and close flow
Expand All @@ -53,88 +47,36 @@
}
}, [state.volume])

let modalContent: JSX.Element | null = null
if (currentStep === 1) {
modalContent = (
<CreateNewTransfer
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 2) {
modalContent = (
<SelectPipette
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 3) {
modalContent = (
<SelectTipRack
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 4) {
modalContent = (
<SelectSourceLabware
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 5) {
modalContent = (
<SelectSourceWells
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 6) {
modalContent = (
<SelectDestLabware
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 7) {
modalContent = (
<SelectDestWells
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>
)
} else if (currentStep === 8) {
modalContent = (
<VolumeEntry
state={state}
dispatch={dispatch}
onBack={() => setCurrentStep(prevStep => prevStep - 1)}
onNext={() => {}}
exitButtonProps={exitButtonProps}
/>
)
} else {
modalContent = null
const exitButtonProps: React.ComponentProps<typeof SmallButton> = {
buttonType: 'tertiaryLowLight',
buttonText: i18n.format(t('shared:exit'), 'capitalize'),
onClick: confirmExit,
}
const sharedMiddleStepProps = {
state,
dispatch,
onBack: () => setCurrentStep(prevStep => prevStep - 1),
onNext: () => {
console.log('next step')
setCurrentStep(prevStep => prevStep + 1)
},
exitButtonProps,
}

const modalContentInOrder: JSX.Element[] = [
<CreateNewTransfer

Check failure on line 67 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 67 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
onNext={() => setCurrentStep(prevStep => prevStep + 1)}
exitButtonProps={exitButtonProps}
/>,
<SelectPipette {...sharedMiddleStepProps} />,

Check failure on line 71 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 71 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
<SelectTipRack {...sharedMiddleStepProps} />,

Check failure on line 72 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 72 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
<SelectSourceLabware {...sharedMiddleStepProps} />,

Check failure on line 73 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 73 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
<SelectSourceWells {...sharedMiddleStepProps} />,

Check failure on line 74 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 74 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
<SelectDestLabware {...sharedMiddleStepProps} />,

Check failure on line 75 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 75 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
<SelectDestWells {...sharedMiddleStepProps} />,

Check failure on line 76 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 76 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
<VolumeEntry {...sharedMiddleStepProps} onNext={() => {}} />,

Check failure on line 77 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array

Check failure on line 77 in app/src/organisms/QuickTransferFlow/index.tsx

View workflow job for this annotation

GitHub Actions / js checks

Missing "key" prop for element in array
]

return (
<>
{showConfirmExit ? (
Expand All @@ -147,7 +89,7 @@
position={POSITION_STICKY}
top="0"
/>
{modalContent}
{modalContentInOrder[currentStep]}
</>
)}
</>
Expand Down
Loading