From 5172fc18d368fa5ac760848439586c4782568d4c Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Mon, 26 Feb 2024 10:33:22 -0500 Subject: [PATCH] fix(app, app-shell, app-shell-odd): Fix host context for notifications (#14548) Closes RAUT-1018 --- app-shell-odd/src/notify.ts | 16 ++++++++-------- app-shell/src/notify.ts | 16 ++++++++-------- .../__tests__/ChooseProtocolSlideout.test.tsx | 6 ++++++ .../__tests__/ChooseRobotSlideout.test.tsx | 6 ++++++ .../ChooseRobotToRunProtocolSlideout.test.tsx | 6 ++++++ .../__tests__/SetupLabware.test.tsx | 6 ++++++ .../__tests__/SetupLiquidsList.test.tsx | 6 ++++++ .../__tests__/ProtocolRunSetup.test.tsx | 6 ++++++ .../__tests__/SetupPipetteCalibration.test.tsx | 7 +++++++ .../DropTipWizard/TipsAttachedModal.tsx | 12 ++++++++---- .../__tests__/TipsAttachedModal.test.tsx | 13 ++++++++----- .../__tests__/CalibrationDashboard.test.tsx | 6 ++++++ .../InstrumentDetailOverflowMenu.tsx | 17 ++++++++++++----- .../InstrumentDetailOverflowMenu.test.tsx | 12 ++++++++++-- app/src/pages/InstrumentDetail/index.tsx | 7 +++++-- app/src/pages/RunSummary/index.tsx | 2 ++ .../__tests__/useNotifyService.test.ts | 4 ++++ app/src/resources/runs/useNotifyAllRunsQuery.ts | 1 + app/src/resources/useNotifyService.ts | 15 +++++++++++---- 19 files changed, 126 insertions(+), 38 deletions(-) diff --git a/app-shell-odd/src/notify.ts b/app-shell-odd/src/notify.ts index be0ff21310d..0cb948e7bcb 100644 --- a/app-shell-odd/src/notify.ts +++ b/app-shell-odd/src/notify.ts @@ -193,8 +193,8 @@ const RENDER_TIMEOUT = 10000 // 10 seconds function unsubscribe(notifyParams: NotifyParams): Promise { const { hostname, topic } = notifyParams return new Promise(() => { - if (hostname in connectionStore) { - setTimeout(() => { + setTimeout(() => { + if (hostname in connectionStore) { const { client } = connectionStore[hostname] const subscriptions = connectionStore[hostname]?.subscriptions const isLastSubscription = subscriptions[topic] <= 1 @@ -215,12 +215,12 @@ function unsubscribe(notifyParams: NotifyParams): Promise { } else { subscriptions[topic] -= 1 } - }, RENDER_TIMEOUT) - } else { - log.info( - `Attempted to unsubscribe from unconnected hostname: ${hostname}` - ) - } + } else { + log.info( + `Attempted to unsubscribe from unconnected hostname: ${hostname}` + ) + } + }, RENDER_TIMEOUT) }) } diff --git a/app-shell/src/notify.ts b/app-shell/src/notify.ts index da1a580b81e..a407cb0bab2 100644 --- a/app-shell/src/notify.ts +++ b/app-shell/src/notify.ts @@ -189,8 +189,8 @@ const RENDER_TIMEOUT = 10000 // 10 seconds function unsubscribe(notifyParams: NotifyParams): Promise { const { hostname, topic } = notifyParams return new Promise(() => { - if (hostname in connectionStore) { - setTimeout(() => { + setTimeout(() => { + if (hostname in connectionStore) { const { client } = connectionStore[hostname] const subscriptions = connectionStore[hostname]?.subscriptions const isLastSubscription = subscriptions[topic] <= 1 @@ -211,12 +211,12 @@ function unsubscribe(notifyParams: NotifyParams): Promise { } else { subscriptions[topic] -= 1 } - }, RENDER_TIMEOUT) - } else { - log.info( - `Attempted to unsubscribe from unconnected hostname: ${hostname}` - ) - } + } else { + log.info( + `Attempted to unsubscribe from unconnected hostname: ${hostname}` + ) + } + }, RENDER_TIMEOUT) }) } diff --git a/app/src/organisms/ChooseProtocolSlideout/__tests__/ChooseProtocolSlideout.test.tsx b/app/src/organisms/ChooseProtocolSlideout/__tests__/ChooseProtocolSlideout.test.tsx index 2c841e4f91d..903c9025fd6 100644 --- a/app/src/organisms/ChooseProtocolSlideout/__tests__/ChooseProtocolSlideout.test.tsx +++ b/app/src/organisms/ChooseProtocolSlideout/__tests__/ChooseProtocolSlideout.test.tsx @@ -9,11 +9,13 @@ import { storedProtocolData as storedProtocolDataFixture } from '../../../redux/ import { useTrackCreateProtocolRunEvent } from '../../../organisms/Devices/hooks' import { useCreateRunFromProtocol } from '../../ChooseRobotToRunProtocolSlideout/useCreateRunFromProtocol' import { ChooseProtocolSlideout } from '../' +import { useNotifyService } from '../../../resources/useNotifyService' jest.mock('../../ChooseRobotToRunProtocolSlideout/useCreateRunFromProtocol') jest.mock('../../../redux/protocol-storage') jest.mock('../../../organisms/Devices/hooks') jest.mock('../../../redux/config') +jest.mock('../../../resources/useNotifyService') const mockGetStoredProtocols = getStoredProtocols as jest.MockedFunction< typeof getStoredProtocols @@ -24,6 +26,9 @@ const mockUseCreateRunFromProtocol = useCreateRunFromProtocol as jest.MockedFunc const mockUseTrackCreateProtocolRunEvent = useTrackCreateProtocolRunEvent as jest.MockedFunction< typeof useTrackCreateProtocolRunEvent > +const mockUseNotifyService = useNotifyService as jest.MockedFunction< + typeof useNotifyService +> const render = (props: React.ComponentProps) => { return renderWithProviders( @@ -52,6 +57,7 @@ describe('ChooseProtocolSlideout', () => { mockUseTrackCreateProtocolRunEvent.mockReturnValue({ trackCreateProtocolRunEvent: mockTrackCreateProtocolRunEvent, }) + mockUseNotifyService.mockReturnValue({} as any) }) afterEach(() => { jest.resetAllMocks() diff --git a/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx b/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx index 2a4ec6fda28..8cfa206a053 100644 --- a/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx +++ b/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx @@ -18,10 +18,12 @@ import { } from '../../../redux/discovery/__fixtures__' import { getNetworkInterfaces } from '../../../redux/networking' import { ChooseRobotSlideout } from '..' +import { useNotifyService } from '../../../resources/useNotifyService' jest.mock('../../../redux/discovery') jest.mock('../../../redux/robot-update') jest.mock('../../../redux/networking') +jest.mock('../../../resources/useNotifyService') const mockGetConnectableRobots = getConnectableRobots as jest.MockedFunction< typeof getConnectableRobots @@ -39,6 +41,9 @@ const mockStartDiscovery = startDiscovery as jest.MockedFunction< const mockGetNetworkInterfaces = getNetworkInterfaces as jest.MockedFunction< typeof getNetworkInterfaces > +const mockUseNotifyService = useNotifyService as jest.MockedFunction< + typeof useNotifyService +> const render = (props: React.ComponentProps) => { return renderWithProviders( @@ -61,6 +66,7 @@ describe('ChooseRobotSlideout', () => { mockGetScanning.mockReturnValue(false) mockStartDiscovery.mockReturnValue({ type: 'mockStartDiscovery' } as any) mockGetNetworkInterfaces.mockReturnValue({ wifi: null, ethernet: null }) + mockUseNotifyService.mockReturnValue({} as any) }) afterEach(() => { jest.resetAllMocks() diff --git a/app/src/organisms/ChooseRobotToRunProtocolSlideout/__tests__/ChooseRobotToRunProtocolSlideout.test.tsx b/app/src/organisms/ChooseRobotToRunProtocolSlideout/__tests__/ChooseRobotToRunProtocolSlideout.test.tsx index 39304bd76c7..49b3d449e6c 100644 --- a/app/src/organisms/ChooseRobotToRunProtocolSlideout/__tests__/ChooseRobotToRunProtocolSlideout.test.tsx +++ b/app/src/organisms/ChooseRobotToRunProtocolSlideout/__tests__/ChooseRobotToRunProtocolSlideout.test.tsx @@ -29,6 +29,7 @@ import { storedProtocolData as storedProtocolDataFixture } from '../../../redux/ import { useCreateRunFromProtocol } from '../useCreateRunFromProtocol' import { useOffsetCandidatesForAnalysis } from '../../ApplyHistoricOffsets/hooks/useOffsetCandidatesForAnalysis' import { ChooseRobotToRunProtocolSlideout } from '../' +import { useNotifyService } from '../../../resources/useNotifyService' import type { State } from '../../../redux/types' @@ -41,6 +42,7 @@ jest.mock('../../../redux/networking') jest.mock('../../../redux/config') jest.mock('../useCreateRunFromProtocol') jest.mock('../../ApplyHistoricOffsets/hooks/useOffsetCandidatesForAnalysis') +jest.mock('../../../resources/useNotifyService') const mockUseOffsetCandidatesForAnalysis = useOffsetCandidatesForAnalysis as jest.MockedFunction< typeof useOffsetCandidatesForAnalysis @@ -82,6 +84,9 @@ const mockUseTrackCreateProtocolRunEvent = useTrackCreateProtocolRunEvent as jes const mockGetNetworkInterfaces = getNetworkInterfaces as jest.MockedFunction< typeof getNetworkInterfaces > +const mockUseNotifyService = useNotifyService as jest.MockedFunction< + typeof useNotifyService +> const render = ( props: React.ComponentProps @@ -125,6 +130,7 @@ describe('ChooseRobotToRunProtocolSlideout', () => { }) mockUseCurrentRunId.mockReturnValue(null) mockUseCurrentRunStatus.mockReturnValue(null) + mockUseNotifyService.mockReturnValue({} as any) when(mockUseCreateRunFromProtocol) .calledWith( expect.any(Object), diff --git a/app/src/organisms/Devices/ProtocolRun/SetupLabware/__tests__/SetupLabware.test.tsx b/app/src/organisms/Devices/ProtocolRun/SetupLabware/__tests__/SetupLabware.test.tsx index 7e88284a87b..96f07219486 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupLabware/__tests__/SetupLabware.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupLabware/__tests__/SetupLabware.test.tsx @@ -18,6 +18,7 @@ import { import { SetupLabwareList } from '../SetupLabwareList' import { SetupLabwareMap } from '../SetupLabwareMap' import { SetupLabware } from '..' +import { useNotifyRunQuery } from '../../../../../resources/runs/useNotifyRunQuery' jest.mock('../SetupLabwareList') jest.mock('../SetupLabwareMap') @@ -27,6 +28,7 @@ jest.mock('../../../../RunTimeControl/hooks') jest.mock('../../../../../redux/config') jest.mock('../../../hooks') jest.mock('../../../hooks/useLPCSuccessToast') +jest.mock('../../../../../resources/runs/useNotifyRunQuery') const mockGetModuleTypesThatRequireExtraAttention = getModuleTypesThatRequireExtraAttention as jest.MockedFunction< typeof getModuleTypesThatRequireExtraAttention @@ -58,6 +60,9 @@ const mockSetupLabwareMap = SetupLabwareMap as jest.MockedFunction< const mockUseLPCDisabledReason = useLPCDisabledReason as jest.MockedFunction< typeof useLPCDisabledReason > +const mockUseNotifyRunQuery = useNotifyRunQuery as jest.MockedFunction< + typeof useNotifyRunQuery +> const ROBOT_NAME = 'otie' const RUN_ID = '1' @@ -110,6 +115,7 @@ describe('SetupLabware', () => {
mock setup labware list
) when(mockUseLPCDisabledReason).mockReturnValue(null) + mockUseNotifyRunQuery.mockReturnValue({} as any) }) afterEach(() => { diff --git a/app/src/organisms/Devices/ProtocolRun/SetupLiquids/__tests__/SetupLiquidsList.test.tsx b/app/src/organisms/Devices/ProtocolRun/SetupLiquids/__tests__/SetupLiquidsList.test.tsx index 726683aedf4..1876e81d187 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupLiquids/__tests__/SetupLiquidsList.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupLiquids/__tests__/SetupLiquidsList.test.tsx @@ -23,6 +23,7 @@ import { getTotalVolumePerLiquidLabwarePair, } from '../utils' import { LiquidsLabwareDetailsModal } from '../LiquidsLabwareDetailsModal' +import { useNotifyRunQuery } from '../../../../../resources/runs/useNotifyRunQuery' const MOCK_LIQUIDS_IN_LOAD_ORDER = [ { @@ -56,6 +57,7 @@ jest.mock('../../utils/getLocationInfoNames') jest.mock('../LiquidsLabwareDetailsModal') jest.mock('@opentrons/api-client') jest.mock('../../../../../redux/analytics') +jest.mock('../../../../../resources/runs/useNotifyRunQuery') const mockUseTrackEvent = useTrackEvent as jest.MockedFunction< typeof useTrackEvent @@ -78,6 +80,9 @@ const mockParseLabwareInfoByLiquidId = parseLabwareInfoByLiquidId as jest.Mocked const mockLiquidsLabwareDetailsModal = LiquidsLabwareDetailsModal as jest.MockedFunction< typeof LiquidsLabwareDetailsModal > +const mockUseNotifyRunQuery = useNotifyRunQuery as jest.MockedFunction< + typeof useNotifyRunQuery +> const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -107,6 +112,7 @@ describe('SetupLiquidsList', () => { partialComponentPropsMatcher({ labwareId: '123', liquidId: '0' }) ) .mockReturnValue(
Mock liquids labwaqre details modal
) + mockUseNotifyRunQuery.mockReturnValue({} as any) }) it('renders the total volume of the liquid, sample display name, and description', () => { diff --git a/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunSetup.test.tsx b/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunSetup.test.tsx index 3bd3670677e..44fe99005c6 100644 --- a/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunSetup.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunSetup.test.tsx @@ -42,6 +42,7 @@ import { SetupLiquids } from '../SetupLiquids' import { SetupModuleAndDeck } from '../SetupModuleAndDeck' import { EmptySetupStep } from '../EmptySetupStep' import { ProtocolRunSetup } from '../ProtocolRunSetup' +import { useNotifyRunQuery } from '../../../../resources/runs/useNotifyRunQuery' jest.mock('@opentrons/api-client') jest.mock('../../hooks') @@ -56,6 +57,7 @@ jest.mock('@opentrons/shared-data/js/helpers/getSimplestFlexDeckConfig') jest.mock('../../../../redux/config') jest.mock('../../../../resources/deck_configuration/utils') jest.mock('../../../../resources/deck_configuration/hooks') +jest.mock('../../../../resources/runs/useNotifyRunQuery') const mockUseIsFlex = useIsFlex as jest.MockedFunction const mockUseMostRecentCompletedAnalysis = useMostRecentCompletedAnalysis as jest.MockedFunction< @@ -113,6 +115,9 @@ const mockUseDeckConfigurationCompatibility = useDeckConfigurationCompatibility const mockGetIsFixtureMismatch = getIsFixtureMismatch as jest.MockedFunction< typeof getIsFixtureMismatch > +const mockUseNotifyRunQuery = useNotifyRunQuery as jest.MockedFunction< + typeof useNotifyRunQuery +> const ROBOT_NAME = 'otie' const RUN_ID = '1' @@ -184,6 +189,7 @@ describe('ProtocolRunSetup', () => { .calledWith(ROBOT_NAME, RUN_ID) .mockReturnValue({ missingModuleIds: [], remainingAttachedModules: [] }) when(mockGetIsFixtureMismatch).mockReturnValue(false) + mockUseNotifyRunQuery.mockReturnValue({} as any) }) afterEach(() => { resetAllWhenMocks() diff --git a/app/src/organisms/Devices/ProtocolRun/__tests__/SetupPipetteCalibration.test.tsx b/app/src/organisms/Devices/ProtocolRun/__tests__/SetupPipetteCalibration.test.tsx index da83290e178..f9a2c55905d 100644 --- a/app/src/organisms/Devices/ProtocolRun/__tests__/SetupPipetteCalibration.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/__tests__/SetupPipetteCalibration.test.tsx @@ -8,10 +8,13 @@ import { mockTipRackDefinition } from '../../../../redux/custom-labware/__fixtur import { useRunPipetteInfoByMount } from '../../hooks' import { SetupPipetteCalibrationItem } from '../SetupPipetteCalibrationItem' import { SetupInstrumentCalibration } from '../SetupInstrumentCalibration' +import { useNotifyRunQuery } from '../../../../resources/runs/useNotifyRunQuery' + import type { PipetteInfo } from '../../hooks' jest.mock('../../hooks') jest.mock('../SetupPipetteCalibrationItem') +jest.mock('../../../../resources/runs/useNotifyRunQuery') const mockUseRunPipetteInfoByMount = useRunPipetteInfoByMount as jest.MockedFunction< typeof useRunPipetteInfoByMount @@ -19,6 +22,9 @@ const mockUseRunPipetteInfoByMount = useRunPipetteInfoByMount as jest.MockedFunc const mockSetupPipetteCalibrationItem = SetupPipetteCalibrationItem as jest.MockedFunction< typeof SetupPipetteCalibrationItem > +const mockUseNotifyRunQuery = useNotifyRunQuery as jest.MockedFunction< + typeof useNotifyRunQuery +> const ROBOT_NAME = 'otie' const RUN_ID = '1' @@ -56,6 +62,7 @@ describe('SetupPipetteCalibration', () => { when(mockSetupPipetteCalibrationItem).mockReturnValue(
Mock SetupPipetteCalibrationItem
) + mockUseNotifyRunQuery.mockReturnValue({} as any) }) afterEach(() => { resetAllWhenMocks() diff --git a/app/src/organisms/DropTipWizard/TipsAttachedModal.tsx b/app/src/organisms/DropTipWizard/TipsAttachedModal.tsx index 1d18ec1b02b..a90244a9888 100644 --- a/app/src/organisms/DropTipWizard/TipsAttachedModal.tsx +++ b/app/src/organisms/DropTipWizard/TipsAttachedModal.tsx @@ -11,14 +11,16 @@ import { StyledText } from '../../atoms/text' import { Modal } from '../../molecules/Modal' import { DropTipWizard } from '.' -import type { PipetteData } from '@opentrons/api-client' +import type { HostConfig, PipetteData } from '@opentrons/api-client' import type { PipetteModelSpecs, RobotType } from '@opentrons/shared-data' import type { ModalHeaderBaseProps } from '../../molecules/Modal/types' +import { ApiHostProvider } from '@opentrons/react-api-client' interface TipsAttachedModalProps { mount: PipetteData['mount'] instrumentModelSpecs: PipetteModelSpecs robotType: RobotType + host: HostConfig | null onCloseClick?: (arg0: any) => void } @@ -26,19 +28,21 @@ export const handleTipsAttachedModal = ( mount: TipsAttachedModalProps['mount'], instrumentModelSpecs: TipsAttachedModalProps['instrumentModelSpecs'], robotType: TipsAttachedModalProps['robotType'], + host: TipsAttachedModalProps['host'], onCloseClick: TipsAttachedModalProps['onCloseClick'] ): Promise => { return NiceModal.show(TipsAttachedModal, { mount, instrumentModelSpecs, robotType, + host, onCloseClick, }) } const TipsAttachedModal = NiceModal.create( (props: TipsAttachedModalProps): JSX.Element => { - const { mount, onCloseClick, instrumentModelSpecs } = props + const { mount, onCloseClick, host, instrumentModelSpecs } = props const { t } = useTranslation(['drop_tip_wizard']) const modal = useModal() const [showWizard, setShowWizard] = React.useState(false) @@ -55,7 +59,7 @@ const TipsAttachedModal = NiceModal.create( const displayMountText = is96Channel ? '96-Channel' : capitalize(mount) return ( - <> + @@ -104,7 +108,7 @@ const TipsAttachedModal = NiceModal.create( }} /> ) : null} - + ) } ) diff --git a/app/src/organisms/DropTipWizard/__tests__/TipsAttachedModal.test.tsx b/app/src/organisms/DropTipWizard/__tests__/TipsAttachedModal.test.tsx index 3b4344bf081..77618cb170a 100644 --- a/app/src/organisms/DropTipWizard/__tests__/TipsAttachedModal.test.tsx +++ b/app/src/organisms/DropTipWizard/__tests__/TipsAttachedModal.test.tsx @@ -9,11 +9,12 @@ import { handleTipsAttachedModal } from '../TipsAttachedModal' import { LEFT } from '@opentrons/shared-data' import { mockPipetteInfo } from '../../../redux/pipettes/__fixtures__' import { ROBOT_MODEL_OT3 } from '../../../redux/discovery' -import { useNotifyCurrentMaintenanceRun } from '../../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun' +import { useNotifyService } from '../../../resources/useNotifyService' import type { PipetteModelSpecs } from '@opentrons/shared-data' +import type { HostConfig } from '@opentrons/api-client' -jest.mock('../../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun') +jest.mock('../../../resources/useNotifyService') const MOCK_ACTUAL_PIPETTE = { ...mockPipetteInfo.pipetteSpecs, @@ -24,9 +25,10 @@ const MOCK_ACTUAL_PIPETTE = { } as PipetteModelSpecs const mockOnClose = jest.fn() -const mockUseNotifyCurrentMaintenanceRun = useNotifyCurrentMaintenanceRun as jest.MockedFunction< - typeof useNotifyCurrentMaintenanceRun +const mockUseNotifyService = useNotifyService as jest.MockedFunction< + typeof useNotifyService > +const MOCK_HOST: HostConfig = { hostname: 'MOCK_HOST' } const render = (pipetteSpecs: PipetteModelSpecs) => { return renderWithProviders( @@ -37,6 +39,7 @@ const render = (pipetteSpecs: PipetteModelSpecs) => { LEFT, pipetteSpecs, ROBOT_MODEL_OT3, + MOCK_HOST, mockOnClose ) } @@ -51,7 +54,7 @@ const render = (pipetteSpecs: PipetteModelSpecs) => { describe('TipsAttachedModal', () => { beforeEach(() => { - mockUseNotifyCurrentMaintenanceRun.mockReturnValue({ + mockUseNotifyService.mockReturnValue({ data: { data: { id: 'test', diff --git a/app/src/pages/Devices/CalibrationDashboard/__tests__/CalibrationDashboard.test.tsx b/app/src/pages/Devices/CalibrationDashboard/__tests__/CalibrationDashboard.test.tsx index f75cc918a16..8c843e1e0ea 100644 --- a/app/src/pages/Devices/CalibrationDashboard/__tests__/CalibrationDashboard.test.tsx +++ b/app/src/pages/Devices/CalibrationDashboard/__tests__/CalibrationDashboard.test.tsx @@ -15,11 +15,13 @@ import { useDashboardCalibrateTipLength } from '../hooks/useDashboardCalibrateTi import { useDashboardCalibrateDeck } from '../hooks/useDashboardCalibrateDeck' import { expectedTaskList } from '../../../../organisms/Devices/hooks/__fixtures__/taskListFixtures' import { mockLeftProtoPipette } from '../../../../redux/pipettes/__fixtures__' +import { useNotifyAllRunsQuery } from '../../../../resources/runs/useNotifyAllRunsQuery' jest.mock('../../../../organisms/Devices/hooks') jest.mock('../hooks/useDashboardCalibratePipOffset') jest.mock('../hooks/useDashboardCalibrateTipLength') jest.mock('../hooks/useDashboardCalibrateDeck') +jest.mock('../../../../resources/runs/useNotifyAllRunsQuery') const mockUseCalibrationTaskList = useCalibrationTaskList as jest.MockedFunction< typeof useCalibrationTaskList @@ -36,6 +38,9 @@ const mockUseDashboardCalibrateDeck = useDashboardCalibrateDeck as jest.MockedFu const mockUseAttachedPipettes = useAttachedPipettes as jest.MockedFunction< typeof useAttachedPipettes > +const mockUseNotifyAllRunsQuery = useNotifyAllRunsQuery as jest.MockedFunction< + typeof useNotifyAllRunsQuery +> const render = (path = '/') => { return renderWithProviders( @@ -60,6 +65,7 @@ describe('CalibrationDashboard', () => { left: mockLeftProtoPipette, right: null, }) + mockUseNotifyAllRunsQuery.mockReturnValue({} as any) }) it('renders a robot calibration dashboard title', () => { diff --git a/app/src/pages/InstrumentDetail/InstrumentDetailOverflowMenu.tsx b/app/src/pages/InstrumentDetail/InstrumentDetailOverflowMenu.tsx index 5d3aedf9c8c..097d7c32211 100644 --- a/app/src/pages/InstrumentDetail/InstrumentDetailOverflowMenu.tsx +++ b/app/src/pages/InstrumentDetail/InstrumentDetailOverflowMenu.tsx @@ -15,6 +15,7 @@ import { FLEX_ROBOT_TYPE, getPipetteModelSpecs, } from '@opentrons/shared-data' +import { ApiHostProvider } from '@opentrons/react-api-client' import { StyledText } from '../../atoms/text' import { MenuList } from '../../atoms/MenuList' @@ -25,21 +26,27 @@ import { DropTipWizard } from '../../organisms/DropTipWizard' import { FLOWS } from '../../organisms/PipetteWizardFlows/constants' import { GRIPPER_FLOW_TYPES } from '../../organisms/GripperWizardFlows/constants' -import type { PipetteData, GripperData } from '@opentrons/api-client' +import type { + PipetteData, + GripperData, + HostConfig, +} from '@opentrons/api-client' interface InstrumentDetailsOverflowMenuProps { instrument: PipetteData | GripperData + host: HostConfig | null } export const handleInstrumentDetailOverflowMenu = ( - instrument: InstrumentDetailsOverflowMenuProps['instrument'] + instrument: InstrumentDetailsOverflowMenuProps['instrument'], + host: InstrumentDetailsOverflowMenuProps['host'] ): void => { NiceModal.show(InstrumentDetailsOverflowMenu, { instrument }) } const InstrumentDetailsOverflowMenu = NiceModal.create( (props: InstrumentDetailsOverflowMenuProps): JSX.Element => { - const { instrument } = props + const { instrument, host } = props const { t } = useTranslation('robot_controls') const modal = useModal() const [showDropTipWizard, setShowDropTipWizard] = React.useState(false) @@ -88,7 +95,7 @@ const InstrumentDetailsOverflowMenu = NiceModal.create( } return ( - <> + {instrument.data.calibratedOffset?.last_modified != null ? ( @@ -147,7 +154,7 @@ const InstrumentDetailsOverflowMenu = NiceModal.create( closeFlow={modal.remove} /> ) : null} - + ) } ) diff --git a/app/src/pages/InstrumentDetail/__tests__/InstrumentDetailOverflowMenu.test.tsx b/app/src/pages/InstrumentDetail/__tests__/InstrumentDetailOverflowMenu.test.tsx index 1541beed39c..96504b193a3 100644 --- a/app/src/pages/InstrumentDetail/__tests__/InstrumentDetailOverflowMenu.test.tsx +++ b/app/src/pages/InstrumentDetail/__tests__/InstrumentDetailOverflowMenu.test.tsx @@ -9,7 +9,11 @@ import { i18n } from '../../../i18n' import { handleInstrumentDetailOverflowMenu } from '../InstrumentDetailOverflowMenu' import { useNotifyCurrentMaintenanceRun } from '../../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun' -import type { PipetteData, GripperData } from '@opentrons/api-client' +import type { + PipetteData, + GripperData, + HostConfig, +} from '@opentrons/api-client' jest.mock('@opentrons/shared-data', () => ({ getAllPipetteNames: jest.fn( @@ -98,11 +102,15 @@ const MOCK_GRIPPER = { instrumentName: 'p1000_single_flex', } as GripperData +const MOCK_HOST: HostConfig = { hostname: 'TEST_HOST' } + const render = (pipetteOrGripper: PipetteData | GripperData) => { return renderWithProviders(