diff --git a/app/src/assets/localization/en/gripper_wizard_flows.json b/app/src/assets/localization/en/gripper_wizard_flows.json index ea5da7baff7..238736cc59f 100644 --- a/app/src/assets/localization/en/gripper_wizard_flows.json +++ b/app/src/assets/localization/en/gripper_wizard_flows.json @@ -12,6 +12,7 @@ "continue_calibration": "Continue calibration", "detach_gripper": "Detach Gripper", "firmware_updating": "A firmware update is required, instrument is updating...", + "firmware_up_to_date": "Firmware is up to date.", "get_started": "Get started", "gripper_calibration": "Gripper Calibration", "gripper_recalibration": "Gripper Recalibration", diff --git a/app/src/assets/localization/en/module_wizard_flows.json b/app/src/assets/localization/en/module_wizard_flows.json index b264b29dea7..0ae3fc1badf 100644 --- a/app/src/assets/localization/en/module_wizard_flows.json +++ b/app/src/assets/localization/en/module_wizard_flows.json @@ -20,6 +20,7 @@ "error_prepping_module": "Error prepping module for calibration", "exit": "Exit", "firmware_updated": "{{module}} firmware updated!", + "firmware_up_to_date": "{{module}} firmware up to date.", "get_started": "To get started, remove labware from the deck and clean up the working area to make the calibration easier. Also gather the needed equipment shown to the right.The calibration adapter came with your module. The pipette probe came with your Flex pipette.", "install_probe_8_channel": "Take the calibration probe from its storage location. Ensure its collar is unlocked. Push the pipette ejector up and press the probe firmly onto the backmost pipette nozzle. Twist the collar to lock the probe. Test that the probe is secure by gently pulling it back and forth.", "install_probe_96_channel": "Take the calibration probe from its storage location. Ensure its collar is unlocked. Push the pipette ejector up and press the probe firmly onto the A1 (back left corner) pipette nozzle. Twist the collar to lock the probe. Test that the probe is secure by gently pulling it back and forth.", diff --git a/app/src/assets/localization/en/pipette_wizard_flows.json b/app/src/assets/localization/en/pipette_wizard_flows.json index b78f8759518..6b7f46f2210 100644 --- a/app/src/assets/localization/en/pipette_wizard_flows.json +++ b/app/src/assets/localization/en/pipette_wizard_flows.json @@ -38,6 +38,7 @@ "detach": "Detaching Pipette", "exit_cal": "Exit calibration", "firmware_updating": "A firmware update is required, instrument is updating...", + "firmware_up_to_date": "Firmware is up to date.", "gantry_empty_for_96_channel_success": "Now that both mounts are empty, you can begin the 96-Channel Pipette attachment process.", "get_started_detach": "To get started, remove labware from the deck and clean up the working area to make detachment easier. Also gather the needed equipment shown to the right.", "grab_screwdriver": "While continuing to hold in place, grab your 2.5mm driver and tighten screws as shown in the animation. Test the pipette attachment by giving it a wiggle before pressing continue", diff --git a/app/src/organisms/Devices/InstrumentsAndModules.tsx b/app/src/organisms/Devices/InstrumentsAndModules.tsx index b0e7dd71fd8..7a162d04bd7 100644 --- a/app/src/organisms/Devices/InstrumentsAndModules.tsx +++ b/app/src/organisms/Devices/InstrumentsAndModules.tsx @@ -153,6 +153,8 @@ export function InstrumentsAndModules({ subsystem={subsystemToUpdate} proceed={() => setSubsystemToUpdate(null)} description={t('updating_firmware')} + proceedDescription={t('firmware_up_to_date')} + isOnDevice={false} /> )} diff --git a/app/src/organisms/FirmwareUpdateModal/__tests__/FirmwareUpdateModal.test.tsx b/app/src/organisms/FirmwareUpdateModal/__tests__/FirmwareUpdateModal.test.tsx index bac61418eb7..885cac2f2b3 100644 --- a/app/src/organisms/FirmwareUpdateModal/__tests__/FirmwareUpdateModal.test.tsx +++ b/app/src/organisms/FirmwareUpdateModal/__tests__/FirmwareUpdateModal.test.tsx @@ -41,6 +41,8 @@ describe('FirmwareUpdateModal', () => { proceed: jest.fn(), description: 'A firmware update is required, instrument is updating', subsystem: 'pipette_left', + proceedDescription: 'Firmware is up to date.', + isOnDevice: true, } mockUseInstrumentQuery.mockReturnValue({ data: { @@ -72,7 +74,7 @@ describe('FirmwareUpdateModal', () => { updateSubsystem, } as any) }) - it('calls proceed if no update is needed', () => { + it('initially renders a spinner and text', () => { mockUseInstrumentQuery.mockReturnValue({ data: { data: [ @@ -82,15 +84,81 @@ describe('FirmwareUpdateModal', () => { } as PipetteData, ], }, + refetch, + } as any) + mockUseSubsystemUpdateQuery.mockReturnValue({ + data: { + data: { + id: 'update id', + updateStatus: null, + } as any, + } as SubsystemUpdateProgressData, + } as any) + jest.useFakeTimers() + const { getByText, getByLabelText } = render(props) + getByLabelText('spinner') + getByText('Checking for updates...') + }) + it('calls proceed if no update is needed', async () => { + mockUseInstrumentQuery.mockReturnValue({ + data: { + data: [ + { + subsystem: 'pipette_left', + ok: true, + } as PipetteData, + ], + }, + refetch, + } as any) + mockUseSubsystemUpdateQuery.mockReturnValue({ + data: { + data: { + id: 'update id', + updateStatus: null, + } as any, + } as SubsystemUpdateProgressData, } as any) - mockUseSubsystemUpdateQuery.mockReturnValue({} as any) + jest.useFakeTimers() const { getByText } = render(props) - getByText('A firmware update is required, instrument is updating') - expect(props.proceed).toHaveBeenCalled() + act(() => { + jest.advanceTimersByTime(3000) + }) + getByText('Firmware is up to date.') + await waitFor(() => expect(props.proceed).toHaveBeenCalled()) + }) + it('does not render text or a progress bar until instrument update status is known', () => { + mockUseSubsystemUpdateQuery.mockReturnValue({ + data: { + data: { + id: 'update id', + updateStatus: undefined, + } as any, + } as SubsystemUpdateProgressData, + } as any) + mockUseInstrumentQuery.mockReturnValue({ + data: undefined, + refetch, + } as any) + const { queryByText } = render(props) + expect( + queryByText('A firmware update is required, instrument is updating') + ).not.toBeInTheDocument() }) it('calls update subsystem if update is needed', () => { - mockUseSubsystemUpdateQuery.mockReturnValue({} as any) + mockUseSubsystemUpdateQuery.mockReturnValue({ + data: { + data: { + id: 'update id', + updateStatus: 'in progress', + } as any, + } as SubsystemUpdateProgressData, + } as any) + jest.useFakeTimers() const { getByText } = render(props) + act(() => { + jest.advanceTimersByTime(3000) + }) getByText('A firmware update is required, instrument is updating') expect(updateSubsystem).toHaveBeenCalled() }) diff --git a/app/src/organisms/FirmwareUpdateModal/index.tsx b/app/src/organisms/FirmwareUpdateModal/index.tsx index 069533a7886..73cbf88d297 100644 --- a/app/src/organisms/FirmwareUpdateModal/index.tsx +++ b/app/src/organisms/FirmwareUpdateModal/index.tsx @@ -6,6 +6,7 @@ import { TYPOGRAPHY, SPACING, Flex, + Icon, RESPONSIVENESS, JUSTIFY_CENTER, BORDERS, @@ -22,8 +23,10 @@ import { BadGripper, BadPipette, Subsystem } from '@opentrons/api-client' interface FirmwareUpdateModalProps { description: string + proceedDescription: string proceed: () => void subsystem: Subsystem + isOnDevice: boolean } const DESCRIPTION_STYLE = css` @@ -58,11 +61,27 @@ const OUTER_STYLES = css` width: 13.374rem; ` +const SPINNER_STYLE = css` + color: ${COLORS.darkGreyEnabled}; + opacity: 100%; + @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { + color: ${COLORS.darkBlackEnabled}; + opacity: 70%; + } +` + export const FirmwareUpdateModal = ( props: FirmwareUpdateModalProps ): JSX.Element => { - const { proceed, subsystem, description } = props + const { + proceed, + proceedDescription, + subsystem, + description, + isOnDevice, + } = props const [updateId, setUpdateId] = React.useState('') + const [firmwareText, setFirmwareText] = React.useState('') const { data: attachedInstruments, refetch: refetchInstruments, @@ -79,18 +98,27 @@ export const FirmwareUpdateModal = ( attachedInstruments?.data?.some( (i): i is BadGripper | BadPipette => !i.ok && i.subsystem === subsystem ) ?? false + React.useEffect(() => { - if (!updateNeeded) { - proceed() - } else { - updateSubsystem(subsystem) - } + setTimeout(() => { + if (!updateNeeded) { + setFirmwareText(proceedDescription) + setTimeout(() => { + proceed() + }, 2000) + } else { + updateSubsystem(subsystem) + } + }, 2000) }, []) const { data: updateData } = useSubsystemUpdateQuery(updateId) const status = updateData?.data.updateStatus const percentComplete = updateData?.data.updateProgress ?? 0 React.useEffect(() => { + if ((status != null || updateNeeded) && firmwareText !== description) { + setFirmwareText(description) + } if (status === 'done') { refetchInstruments() .then(() => { @@ -108,15 +136,28 @@ export const FirmwareUpdateModal = ( proceed() }) } - }, [status, proceed, refetchInstruments, instrumentToUpdate]) + }, [status, proceed, refetchInstruments, instrumentToUpdate, updateNeeded]) return ( - {description} - + + {firmwareText.length ? firmwareText : 'Checking for updates...'} + + {status != null || updateNeeded ? ( + + ) : null} + {firmwareText.length ? null : ( + + )} ) } diff --git a/app/src/organisms/GripperWizardFlows/getGripperWizardSteps.ts b/app/src/organisms/GripperWizardFlows/getGripperWizardSteps.ts index f7f47a24cc0..940cf29869b 100644 --- a/app/src/organisms/GripperWizardFlows/getGripperWizardSteps.ts +++ b/app/src/organisms/GripperWizardFlows/getGripperWizardSteps.ts @@ -12,8 +12,7 @@ import { import type { GripperWizardStep, GripperWizardFlowType } from './types' export const getGripperWizardSteps = ( - flowType: GripperWizardFlowType, - requiresFirmwareUpdate: boolean + flowType: GripperWizardFlowType ): GripperWizardStep[] => { switch (flowType) { case GRIPPER_FLOW_TYPES.RECALIBRATE: { @@ -32,7 +31,7 @@ export const getGripperWizardSteps = ( ] } case GRIPPER_FLOW_TYPES.ATTACH: { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING }, { section: SECTIONS.MOUNT_GRIPPER }, { section: SECTIONS.FIRMWARE_UPDATE }, @@ -48,10 +47,6 @@ export const getGripperWizardSteps = ( successfulAction: SUCCESSFULLY_ATTACHED_AND_CALIBRATED, }, ] - - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) } case GRIPPER_FLOW_TYPES.DETACH: { return [ diff --git a/app/src/organisms/GripperWizardFlows/index.tsx b/app/src/organisms/GripperWizardFlows/index.tsx index 44243e3eea0..f0001723c6f 100644 --- a/app/src/organisms/GripperWizardFlows/index.tsx +++ b/app/src/organisms/GripperWizardFlows/index.tsx @@ -209,11 +209,7 @@ export const GripperWizard = ( } = props const isOnDevice = useSelector(getIsOnDevice) const { t } = useTranslation('gripper_wizard_flows') - const requiresFirmwareUpdate = !attachedGripper?.ok - const gripperWizardSteps = getGripperWizardSteps( - flowType, - requiresFirmwareUpdate - ) + const gripperWizardSteps = getGripperWizardSteps(flowType) const [currentStepIndex, setCurrentStepIndex] = React.useState(0) const [ frontJawOffset, @@ -309,6 +305,8 @@ export const GripperWizard = ( proceed={handleProceed} subsystem="gripper" description={t('firmware_updating')} + proceedDescription={t('firmware_up_to_date')} + isOnDevice={isOnDevice} /> ) } else if (currentStep.section === SECTIONS.UNMOUNT_GRIPPER) { diff --git a/app/src/organisms/ModuleWizardFlows/getModuleCalibrationSteps.ts b/app/src/organisms/ModuleWizardFlows/getModuleCalibrationSteps.ts index 510328e20f3..f57c8683771 100644 --- a/app/src/organisms/ModuleWizardFlows/getModuleCalibrationSteps.ts +++ b/app/src/organisms/ModuleWizardFlows/getModuleCalibrationSteps.ts @@ -1,10 +1,8 @@ import { SECTIONS } from './constants' import type { ModuleCalibrationWizardStep } from './types' -export const getModuleCalibrationSteps = ( - requiresFirmwareUpdate: boolean -): ModuleCalibrationWizardStep[] => { - const ALL_STEPS = [ +export const getModuleCalibrationSteps = (): ModuleCalibrationWizardStep[] => { + return [ { section: SECTIONS.BEFORE_BEGINNING }, { section: SECTIONS.FIRMWARE_UPDATE }, { section: SECTIONS.SELECT_LOCATION }, @@ -13,8 +11,4 @@ export const getModuleCalibrationSteps = ( { section: SECTIONS.DETACH_PROBE }, { section: SECTIONS.SUCCESS }, ] - - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) } diff --git a/app/src/organisms/ModuleWizardFlows/index.tsx b/app/src/organisms/ModuleWizardFlows/index.tsx index 7cc6c8bde54..65fa45f855e 100644 --- a/app/src/organisms/ModuleWizardFlows/index.tsx +++ b/app/src/organisms/ModuleWizardFlows/index.tsx @@ -8,9 +8,9 @@ import { import { COLORS } from '@opentrons/components' import { CreateCommand, - LEFT, getModuleType, getModuleDisplayName, + LEFT, } from '@opentrons/shared-data' import { LegacyModalShell } from '../../molecules/LegacyModal' import { Portal } from '../../App/portal' @@ -61,14 +61,7 @@ export const ModuleWizardFlows = ( const { t } = useTranslation('module_wizard_flows') const attachedPipettes = useAttachedPipettesFromInstrumentsQuery() const attachedPipette = attachedPipettes.left ?? attachedPipettes.right - const requiresFirmwareUpdate = !attachedPipette?.ok - const attachedPipetteMount = - attachedPipette?.mount === LEFT ? 'pipette_left' : 'pipette_right' - - const moduleCalibrationSteps = getModuleCalibrationSteps( - requiresFirmwareUpdate - ) - + const moduleCalibrationSteps = getModuleCalibrationSteps() const availableSlotNames = FLEX_SLOT_NAMES_BY_MOD_TYPE[getModuleType(attachedModule.moduleModel)] ?? [] const [slotName, setSlotName] = React.useState( @@ -269,8 +262,14 @@ export const ModuleWizardFlows = ( modalContent = ( ) } else if (currentStep.section === SECTIONS.SELECT_LOCATION) { diff --git a/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardSteps.test.tsx b/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardSteps.test.tsx index 4e9ade83185..26871946caf 100644 --- a/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardSteps.test.tsx +++ b/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardSteps.test.tsx @@ -34,16 +34,9 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps( - FLOWS.CALIBRATE, - LEFT, - SINGLE_MOUNT_PIPETTES, - false, - true - ) + getPipetteWizardSteps(FLOWS.CALIBRATE, LEFT, SINGLE_MOUNT_PIPETTES, false) ).toStrictEqual(mockCalibrateFlowSteps) }) - it('returns the correct array of info for attach pipette flow single channel', () => { const mockAttachPipetteFlowSteps = [ { @@ -84,58 +77,7 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps( - FLOWS.ATTACH, - LEFT, - SINGLE_MOUNT_PIPETTES, - false, - true - ) - ).toStrictEqual(mockAttachPipetteFlowSteps) - }) - - it('returns the correct array of info when a firmware update is not required', () => { - const mockAttachPipetteFlowSteps = [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.ATTACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.CALIBRATE, - }, - ] as PipetteWizardStep[] - - expect( - getPipetteWizardSteps( - FLOWS.ATTACH, - LEFT, - SINGLE_MOUNT_PIPETTES, - false, - false - ) + getPipetteWizardSteps(FLOWS.ATTACH, LEFT, SINGLE_MOUNT_PIPETTES, false) ).toStrictEqual(mockAttachPipetteFlowSteps) }) @@ -159,13 +101,7 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps( - FLOWS.DETACH, - LEFT, - SINGLE_MOUNT_PIPETTES, - false, - true - ) + getPipetteWizardSteps(FLOWS.DETACH, LEFT, SINGLE_MOUNT_PIPETTES, false) ).toStrictEqual(mockDetachPipetteFlowSteps) }) @@ -219,7 +155,7 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps(FLOWS.ATTACH, LEFT, NINETY_SIX_CHANNEL, true, true) + getPipetteWizardSteps(FLOWS.ATTACH, LEFT, NINETY_SIX_CHANNEL, true) ).toStrictEqual(mockAttachPipetteFlowSteps) }) @@ -253,7 +189,7 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps(FLOWS.DETACH, LEFT, NINETY_SIX_CHANNEL, true, true) + getPipetteWizardSteps(FLOWS.DETACH, LEFT, NINETY_SIX_CHANNEL, true) ).toStrictEqual(mockDetachPipetteFlowSteps) }) it('returns the correct array when 96-channel is going to be attached and there is a pipette already on the mount', () => { @@ -312,7 +248,7 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps(FLOWS.ATTACH, LEFT, NINETY_SIX_CHANNEL, false, true) + getPipetteWizardSteps(FLOWS.ATTACH, LEFT, NINETY_SIX_CHANNEL, false) ).toStrictEqual(mockAttachPipetteFlowSteps) }) it('returns the corect array of info for calibrate pipette 96 channel', () => { @@ -340,13 +276,7 @@ describe('getPipetteWizardSteps', () => { ] as PipetteWizardStep[] expect( - getPipetteWizardSteps( - FLOWS.CALIBRATE, - LEFT, - NINETY_SIX_CHANNEL, - false, - true - ) + getPipetteWizardSteps(FLOWS.CALIBRATE, LEFT, NINETY_SIX_CHANNEL, false) ).toStrictEqual(mockCalibrateFlowSteps) }) }) diff --git a/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx b/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx index 6bbe76cfba0..5e6da52d714 100644 --- a/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx +++ b/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx @@ -36,20 +36,14 @@ describe('getPipetteWizardStepsForProtocol', () => { mount: 'left', }, ], - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) it('returns an empty array when there is no pipette attached and no pipette is needed', () => { const mockFlowSteps = [] as PipetteWizardStep[] expect( - getPipetteWizardStepsForProtocol( - { left: null, right: null }, - [], - LEFT, - true - ) + getPipetteWizardStepsForProtocol({ left: null, right: null }, [], LEFT) ).toStrictEqual(mockFlowSteps) }) it('returns the calibration flow only when correct pipette is attached but there is no pip cal data', () => { @@ -81,8 +75,7 @@ describe('getPipetteWizardStepsForProtocol', () => { } as any, }, [{ id: '123', pipetteName: 'p1000_single_flex', mount: 'right' }], - RIGHT, - true + RIGHT ) ).toStrictEqual(mockFlowSteps) }) @@ -130,55 +123,11 @@ describe('getPipetteWizardStepsForProtocol', () => { getPipetteWizardStepsForProtocol( mockSingleMountPipetteAttached, mockPipettesInProtocolMulti as any, - LEFT, - true - ) - ).toStrictEqual(mockFlowSteps) - }) - it('returns the correct array of info when the attached pipette does not require a firmware update', () => { - const mockFlowSteps = [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.DETACH }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.CALIBRATE, - }, - ] as PipetteWizardStep[] - expect( - getPipetteWizardStepsForProtocol( - mockSingleMountPipetteAttached, - mockPipettesInProtocolMulti as any, - LEFT, - false + LEFT ) ).toStrictEqual(mockFlowSteps) }) + it('returns the correct array of info when the attached 96-channel pipette needs to be switched out for single mount', () => { const mockFlowSteps = [ { @@ -233,8 +182,7 @@ describe('getPipetteWizardStepsForProtocol', () => { getPipetteWizardStepsForProtocol( { left: mock96ChannelAttachedPipetteInformation, right: null }, mockPipettesInProtocolNotEmpty as any, - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) @@ -292,8 +240,7 @@ describe('getPipetteWizardStepsForProtocol', () => { getPipetteWizardStepsForProtocol( { left: mockAttachedPipetteInformation, right: null }, mockPipetteInfo as any, - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) @@ -351,8 +298,7 @@ describe('getPipetteWizardStepsForProtocol', () => { getPipetteWizardStepsForProtocol( { left: null, right: mockAttachedPipetteInformation }, mockPipetteInfo as any, - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) @@ -419,8 +365,7 @@ describe('getPipetteWizardStepsForProtocol', () => { right: mockAttachedPipetteInformation, }, mockPipetteInfo as any, - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) @@ -462,8 +407,7 @@ describe('getPipetteWizardStepsForProtocol', () => { getPipetteWizardStepsForProtocol( { left: null, right: null }, mockPipettesInProtocolNotEmpty as any, - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) @@ -515,8 +459,7 @@ describe('getPipetteWizardStepsForProtocol', () => { getPipetteWizardStepsForProtocol( { left: null, right: null }, mockPipetteInfo as any, - LEFT, - true + LEFT ) ).toStrictEqual(mockFlowSteps) }) diff --git a/app/src/organisms/PipetteWizardFlows/getPipetteWizardSteps.ts b/app/src/organisms/PipetteWizardFlows/getPipetteWizardSteps.ts index a492822e891..c67a9e07fb4 100644 --- a/app/src/organisms/PipetteWizardFlows/getPipetteWizardSteps.ts +++ b/app/src/organisms/PipetteWizardFlows/getPipetteWizardSteps.ts @@ -11,8 +11,7 @@ export const getPipetteWizardSteps = ( flowType: PipetteWizardFlow, mount: PipetteMount, selectedPipette: SelectablePipettes, - isGantryEmpty: boolean, - requiresFirmwareUpdate: boolean + isGantryEmpty: boolean ): PipetteWizardStep[] => { switch (flowType) { case FLOWS.CALIBRATE: { @@ -33,7 +32,7 @@ export const getPipetteWizardSteps = ( } case FLOWS.ATTACH: { if (selectedPipette === SINGLE_MOUNT_PIPETTES) { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: mount, @@ -54,9 +53,6 @@ export const getPipetteWizardSteps = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) } else { // pipette needs to be detached before attached 96 channel if (!isGantryEmpty) { @@ -64,7 +60,7 @@ export const getPipetteWizardSteps = ( if (mount === LEFT) { detachMount = RIGHT } - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: detachMount, @@ -117,14 +113,9 @@ export const getPipetteWizardSteps = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter( - step => step.section !== SECTIONS.FIRMWARE_UPDATE - ) // gantry empty to attach 96 channel } else { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: mount, @@ -167,11 +158,6 @@ export const getPipetteWizardSteps = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter( - step => step.section !== SECTIONS.FIRMWARE_UPDATE - ) } } } diff --git a/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts b/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts index 8a6cd324fb6..d63fe5d34ce 100644 --- a/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts +++ b/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts @@ -7,8 +7,7 @@ import type { PipetteWizardStep } from './types' export const getPipetteWizardStepsForProtocol = ( attachedPipettes: AttachedPipettesFromInstrumentsQuery, pipetteInfo: LoadedPipette[], - mount: Mount, - requiresFirmwareUpdate: boolean + mount: Mount ): PipetteWizardStep[] => { const requiredPipette = pipetteInfo.find(pipette => pipette.mount === mount) const nintySixChannelAttached = @@ -51,7 +50,7 @@ export const getPipetteWizardStepsForProtocol = ( ) { // 96-channel pipette attached and need to attach single mount pipette if (nintySixChannelAttached) { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: LEFT, @@ -100,12 +99,9 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) // Single mount pipette attached and need to attach new single mount pipette } else { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: mount, @@ -144,9 +140,6 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) } // Single mount pipette attached to both mounts and need to attach 96-channel pipette } else if ( @@ -154,7 +147,7 @@ export const getPipetteWizardStepsForProtocol = ( attachedPipettes[LEFT] != null && attachedPipettes[RIGHT] != null ) { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: LEFT, @@ -209,16 +202,13 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) // Single mount pipette attached to left mount and need to attach 96-channel pipette } else if ( requiredPipette.pipetteName === 'p1000_96' && attachedPipettes[LEFT] != null && attachedPipettes[RIGHT] == null ) { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: LEFT, @@ -267,16 +257,13 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) // Single mount pipette attached to right mount and need to attach 96-channel pipette } else if ( requiredPipette.pipetteName === 'p1000_96' && attachedPipettes[LEFT] == null && attachedPipettes[RIGHT] != null ) { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: RIGHT, @@ -325,14 +312,11 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) // if no pipette is attached to gantry } else { // Gantry empty and need to attach 96-channel pipette if (requiredPipette.pipetteName === 'p1000_96') { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: LEFT, @@ -375,12 +359,9 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) // Gantry empty and need to attach single mount pipette } else { - const ALL_STEPS = [ + return [ { section: SECTIONS.BEFORE_BEGINNING, mount: mount, @@ -413,9 +394,6 @@ export const getPipetteWizardStepsForProtocol = ( flowType: FLOWS.CALIBRATE, }, ] - return requiresFirmwareUpdate - ? ALL_STEPS - : ALL_STEPS.filter(step => step.section !== SECTIONS.FIRMWARE_UPDATE) } } } diff --git a/app/src/organisms/PipetteWizardFlows/index.tsx b/app/src/organisms/PipetteWizardFlows/index.tsx index 46daf353743..0e40ea96b88 100644 --- a/app/src/organisms/PipetteWizardFlows/index.tsx +++ b/app/src/organisms/PipetteWizardFlows/index.tsx @@ -64,26 +64,17 @@ export const PipetteWizardFlows = ( const { t } = useTranslation('pipette_wizard_flows') const attachedPipettes = useAttachedPipettesFromInstrumentsQuery() - const attachedPipette = attachedPipettes.left ?? attachedPipettes.right - const requiresFirmwareUpdate = !attachedPipette?.ok const memoizedPipetteInfo = React.useMemo(() => props.pipetteInfo ?? null, []) const isGantryEmpty = attachedPipettes[LEFT] == null && attachedPipettes[RIGHT] == null const pipetteWizardSteps = React.useMemo( () => memoizedPipetteInfo == null - ? getPipetteWizardSteps( - flowType, - mount, - selectedPipette, - isGantryEmpty, - requiresFirmwareUpdate - ) + ? getPipetteWizardSteps(flowType, mount, selectedPipette, isGantryEmpty) : getPipetteWizardStepsForProtocol( attachedPipettes, memoizedPipetteInfo, - mount, - requiresFirmwareUpdate + mount ), [] ) @@ -351,6 +342,8 @@ export const PipetteWizardFlows = ( proceed={proceed} subsystem={mount === LEFT ? 'pipette_left' : 'pipette_right'} description={t('firmware_updating')} + proceedDescription={t('firmware_up_to_date')} + isOnDevice={isOnDevice} /> ) } else if (currentStep.section === SECTIONS.DETACH_PIPETTE) {