Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import { SetupStep } from './SetupStep'
import { EmptySetupStep } from './EmptySetupStep'
import { LearnAboutOffsetsLink } from './LearnAboutOffsetsLink'
import { useLPCFlows } from '/app/organisms/LabwarePositionCheck'
import { useUpdateClientLPC } from '/app/resources/client_data'

import type { RefObject } from 'react'
import type { Dispatch, State } from '/app/redux/types'
Expand Down Expand Up @@ -129,6 +130,7 @@ export function ProtocolRunSetup({
const flexOffsetsMissing = useSelector(
selectIsAnyNecessaryDefaultOffsetMissing(runId)
)
const { updateWithRunId: updateLPCStatusWithRunId } = useUpdateClientLPC()
const flexOffsetsApplied = useSelector(selectAreOffsetsApplied(runId))
const noLwOffsetsInRun =
useSelector(selectTotalCountLocationSpecificOffsets(runId)) === 0 && isFlex
Expand Down Expand Up @@ -275,6 +277,7 @@ export function ProtocolRunSetup({
setOffsetsConfirmed={confirmed => {
if (confirmed) {
dispatch(appliedOffsetsToRun(runId))
updateLPCStatusWithRunId(runId)

setExpandedStepKey(LABWARE_SETUP_STEP_KEY)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import {
useClientDataLPC,
useUpdateClientLPC,
} from '/app/resources/client_data/'
import {
appliedOffsetsToRun,
selectAreOffsetsApplied,
} from '/app/redux/protocol-runs'
import { appliedOffsetsToRun } from '/app/redux/protocol-runs'
import { useIsRunCurrent } from '/app/resources/runs'

vi.mock('react-redux')
Expand All @@ -24,7 +21,6 @@ describe('useHandleClientAppliedOffsets', () => {

const mockDispatch = vi.fn()
const mockClearClientData = vi.fn()
const mockUpdateWithRunId = vi.fn()

beforeEach(() => {
vi.clearAllMocks()
Expand All @@ -40,18 +36,13 @@ describe('useHandleClientAppliedOffsets', () => {
(runId: string | null) => false
)

vi.mocked(
selectAreOffsetsApplied
).mockImplementation((runId: string) => (state: any) => false)

vi.mocked(useClientDataLPC).mockReturnValue({
runId: null,
userId: null,
})

vi.mocked(useUpdateClientLPC).mockReturnValue({
clearClientData: mockClearClientData,
updateWithRunId: mockUpdateWithRunId,
} as any)

vi.mocked(useSelector).mockImplementation(selector => {
Expand All @@ -74,7 +65,6 @@ describe('useHandleClientAppliedOffsets', () => {
})

expect(mockClearClientData).not.toHaveBeenCalled()
expect(mockUpdateWithRunId).not.toHaveBeenCalled()
expect(mockDispatch).not.toHaveBeenCalled()
})

Expand All @@ -90,7 +80,6 @@ describe('useHandleClientAppliedOffsets', () => {
})

expect(mockClearClientData).toHaveBeenCalledTimes(1)
expect(mockUpdateWithRunId).not.toHaveBeenCalled()
expect(mockDispatch).not.toHaveBeenCalled()
})

Expand All @@ -106,15 +95,11 @@ describe('useHandleClientAppliedOffsets', () => {
})

expect(mockClearClientData).toHaveBeenCalledTimes(1)
expect(mockUpdateWithRunId).not.toHaveBeenCalled()
expect(mockDispatch).not.toHaveBeenCalled()
})

it('should update client data when offsets are applied locally but not by another user', () => {
it('should not take any action when run IDs match but no user ID is present', () => {
vi.mocked(useIsRunCurrent).mockReturnValue(true)
vi.mocked(
selectAreOffsetsApplied
).mockImplementation((runId: string) => (state: any) => true)
vi.mocked(useClientDataLPC).mockReturnValue({
runId: RUN_ID,
userId: null,
Expand All @@ -125,15 +110,11 @@ describe('useHandleClientAppliedOffsets', () => {
})

expect(mockClearClientData).not.toHaveBeenCalled()
expect(mockUpdateWithRunId).toHaveBeenCalledWith(RUN_ID)
expect(mockDispatch).not.toHaveBeenCalled()
})

it('should dispatch applied offsets when offsets are applied by another user but not locally', () => {
it('should dispatch applied offsets when run IDs match and user ID is present', () => {
vi.mocked(useIsRunCurrent).mockReturnValue(true)
vi.mocked(
selectAreOffsetsApplied
).mockImplementation((runId: string) => (state: any) => false)
vi.mocked(useClientDataLPC).mockReturnValue({
runId: RUN_ID,
userId: USER_ID,
Expand All @@ -144,15 +125,26 @@ describe('useHandleClientAppliedOffsets', () => {
})

expect(mockClearClientData).not.toHaveBeenCalled()
expect(mockUpdateWithRunId).not.toHaveBeenCalled()
expect(mockDispatch).toHaveBeenCalledWith(appliedOffsetsToRun(RUN_ID))
})

it('should do nothing when run is current, client data has the same run ID, and offsets are already applied', () => {
it('should not dispatch applied offsets when run IDs do not match, even if user ID is present', () => {
vi.mocked(useIsRunCurrent).mockReturnValue(true)
vi.mocked(useClientDataLPC).mockReturnValue({
runId: OTHER_RUN_ID,
userId: USER_ID,
})

renderHook(() => {
useHandleClientAppliedOffsets(RUN_ID)
})

expect(mockClearClientData).toHaveBeenCalledTimes(1)
expect(mockDispatch).not.toHaveBeenCalled()
})

it('should do nothing when run is current, client data has the same run ID and user ID, and offsets are already applied', () => {
vi.mocked(useIsRunCurrent).mockReturnValue(true)
vi.mocked(
selectAreOffsetsApplied
).mockImplementation((runId: string) => (state: any) => true)
vi.mocked(useClientDataLPC).mockReturnValue({
runId: RUN_ID,
userId: USER_ID,
Expand All @@ -163,11 +155,10 @@ describe('useHandleClientAppliedOffsets', () => {
})

expect(mockClearClientData).not.toHaveBeenCalled()
expect(mockUpdateWithRunId).not.toHaveBeenCalled()
expect(mockDispatch).not.toHaveBeenCalled()
expect(mockDispatch).toHaveBeenCalledWith(appliedOffsetsToRun(RUN_ID))
})

it('should call clearClientData with null thisRunId when not current', () => {
it('should call clearClientData when not current with null thisRunId', () => {
vi.mocked(useIsRunCurrent).mockReturnValue(false)
vi.mocked(useClientDataLPC).mockReturnValue({
runId: null,
Expand All @@ -178,27 +169,22 @@ describe('useHandleClientAppliedOffsets', () => {
useHandleClientAppliedOffsets(null)
})

expect(mockClearClientData).toHaveBeenCalledTimes(1)
expect(mockUpdateWithRunId).not.toHaveBeenCalled()
expect(mockClearClientData).toHaveBeenCalled()
expect(mockDispatch).not.toHaveBeenCalled()
})

it('should call updateWithRunId with null thisRunId when current and offsets applied', () => {
it('should dispatch when run is current with null thisRunId and user ID is present', () => {
vi.mocked(useIsRunCurrent).mockReturnValue(true)
vi.mocked(
selectAreOffsetsApplied
).mockImplementation((runId: string) => (state: any) => true)
vi.mocked(useClientDataLPC).mockReturnValue({
runId: null,
userId: null,
userId: USER_ID,
})

renderHook(() => {
useHandleClientAppliedOffsets(null)
})

expect(mockClearClientData).not.toHaveBeenCalled()
expect(mockUpdateWithRunId).toHaveBeenCalledWith(null)
expect(mockDispatch).not.toHaveBeenCalled()
})
})
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import { useDispatch, useSelector } from 'react-redux'
import { useDispatch } from 'react-redux'
import { useEffect } from 'react'
import {
useClientDataLPC,
useUpdateClientLPC,
} from '/app/resources/client_data/'
import {
appliedOffsetsToRun,
selectAreOffsetsApplied,
} from '/app/redux/protocol-runs'
import { appliedOffsetsToRun } from '/app/redux/protocol-runs'
import { useIsRunCurrent } from '/app/resources/runs'

const CLIENT_DATA_INTERVAL_MS = 5000

// Keep the applied offset state in sync between various apps using the same robot.
export function useHandleClientAppliedOffsets(thisRunId: string | null): void {
const dispatch = useDispatch()
const areOffsetsApplied = useSelector(
selectAreOffsetsApplied(thisRunId ?? '')
)
const isThisRunCurrent = useIsRunCurrent(thisRunId)

const { clearClientData, updateWithRunId } = useUpdateClientLPC()
const { clearClientData } = useUpdateClientLPC()
const { runId: clientDataRunId, userId: clientDataUserId } = useClientDataLPC(
{
refetchInterval: CLIENT_DATA_INTERVAL_MS,
Expand All @@ -32,14 +26,10 @@ export function useHandleClientAppliedOffsets(thisRunId: string | null): void {
if (clientDataRunId !== thisRunId && clientDataRunId != null) {
clearClientData()
}
// Offsets applied locally but not by another user - update client data
else if (areOffsetsApplied && clientDataUserId == null) {
updateWithRunId(thisRunId)
}
// Offsets applied by another user but not locally - mark as applied locally
else if (
clientDataUserId != null &&
!areOffsetsApplied &&
clientDataRunId === thisRunId &&
thisRunId != null
) {
dispatch(appliedOffsetsToRun(thisRunId))
Expand All @@ -49,11 +39,5 @@ export function useHandleClientAppliedOffsets(thisRunId: string | null): void {
clearClientData()
}
}
}, [
isThisRunCurrent,
clientDataRunId,
areOffsetsApplied,
clientDataUserId,
thisRunId,
])
}, [isThisRunCurrent, clientDataRunId, clientDataUserId, thisRunId])
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
} from '/app/redux/protocol-runs'
import { useAddLabwareOffsetToRunMutation } from '@opentrons/react-api-client'
import { useState } from 'react'
import { useUpdateClientLPC } from '/app/resources/client_data'

export function SetupOffsetsHeader({
runId,
Expand All @@ -32,6 +33,7 @@ export function SetupOffsetsHeader({
selectIsAnyNecessaryDefaultOffsetMissing(runId)
)
const lwOffsetsForRun = useSelector(selectLabwareOffsetsToAddToRun(runId))
const { updateWithRunId } = useUpdateClientLPC()

const [isApplyOffsets, setIsApplyingOffsets] = useState(false)

Expand All @@ -48,6 +50,7 @@ export function SetupOffsetsHeader({
)
.then(() => {
dispatch(appliedOffsetsToRun(runId))
updateWithRunId(runId)
setSetupScreen('prepare to run')
})
.catch(() => {
Expand Down
Loading