From e53226a593c89c6a540da7c6307212ebe3ef9fcb Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Thu, 25 Apr 2024 12:16:58 -0400 Subject: [PATCH] feat(app): Add GET /deck_configuration notification support (#15007) Closes EXEC-263 Refactors GET /deck_configuration to use notifications. --- .../AddFixtureModal.tsx | 4 +-- .../__tests__/AddFixtureModal.test.tsx | 6 ++-- .../DeviceDetailsDeckConfiguration.test.tsx | 9 ++++-- .../DeviceDetailsDeckConfiguration/index.tsx | 7 ++-- .../ChooseModuleToConfigureModal.tsx | 9 ++---- .../LocationConflictModal.tsx | 9 +++--- .../SetupModuleAndDeck/NotConfiguredModal.tsx | 8 ++--- .../SetupModuleAndDeck/SetupModulesMap.tsx | 4 +-- .../__tests__/LocationConflictModal.test.tsx | 8 +++-- .../__tests__/NotConfiguredModal.test.tsx | 10 +++--- ...seModuleRenderInfoForProtocolById.test.tsx | 6 ++-- .../useModuleRenderInfoForProtocolById.ts | 4 +-- app/src/organisms/DropTipWizard/index.tsx | 4 +-- .../MoveLabwareInterventionContent.tsx | 6 ++-- .../LabwarePositionCheck/PrepareSpace.tsx | 4 +-- app/src/organisms/ModuleWizardFlows/index.tsx | 12 +++---- .../PipetteWizardFlows/AttachProbe.tsx | 5 +-- .../PipetteWizardFlows/BeforeBeginning.tsx | 5 +-- .../__tests__/AttachProbe.test.tsx | 6 ++-- .../ProtocolSetupDeckConfiguration.test.tsx | 5 +-- .../ProtocolSetupDeckConfiguration/index.tsx | 8 ++--- .../__tests__/ProtocolSetupLabware.test.tsx | 6 ++-- .../organisms/ProtocolSetupLabware/index.tsx | 6 ++-- .../ModuleTable.tsx | 4 +-- .../ProtocolSetupModulesAndDeck.test.tsx | 8 ++--- .../ProtocolSetupModulesAndDeck/index.tsx | 4 +-- .../QuickTransferFlow/CreateNewTransfer.tsx | 6 ++-- .../__tests__/DeckConfiguration.test.tsx | 11 +++---- app/src/pages/DeckConfiguration/index.tsx | 8 ++--- .../__tests__/ProtocolSetup.test.tsx | 5 +-- .../Protocols/hooks/__tests__/hooks.test.tsx | 13 +++++--- app/src/pages/Protocols/hooks/index.ts | 9 +++--- app/src/redux/shell/types.ts | 1 + .../__tests__/hooks.test.ts | 7 ++-- app/src/resources/deck_configuration/hooks.ts | 8 +++-- app/src/resources/deck_configuration/index.ts | 4 +++ .../useNotifyDeckConfigurationQuery.ts | 32 +++++++++++++++++++ 37 files changed, 159 insertions(+), 112 deletions(-) create mode 100644 app/src/resources/deck_configuration/index.ts create mode 100644 app/src/resources/deck_configuration/useNotifyDeckConfigurationQuery.ts diff --git a/app/src/organisms/DeviceDetailsDeckConfiguration/AddFixtureModal.tsx b/app/src/organisms/DeviceDetailsDeckConfiguration/AddFixtureModal.tsx index 91fb38c4cf2..b8297db8f84 100644 --- a/app/src/organisms/DeviceDetailsDeckConfiguration/AddFixtureModal.tsx +++ b/app/src/organisms/DeviceDetailsDeckConfiguration/AddFixtureModal.tsx @@ -16,7 +16,6 @@ import { TYPOGRAPHY, } from '@opentrons/components' import { - useDeckConfigurationQuery, useModulesQuery, useUpdateDeckConfigurationMutation, } from '@opentrons/react-api-client' @@ -49,6 +48,7 @@ import { ODD_FOCUS_VISIBLE } from '../../atoms/buttons/constants' import { TertiaryButton } from '../../atoms/buttons' import { Modal } from '../../molecules/Modal' import { LegacyModal } from '../../molecules/LegacyModal' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration/' import type { CutoutConfig, @@ -83,7 +83,7 @@ export function AddFixtureModal({ const { t } = useTranslation(['device_details', 'shared']) const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation() const { data: modulesData } = useModulesQuery() - const deckConfig = useDeckConfigurationQuery()?.data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery()?.data ?? [] const unconfiguredMods = modulesData?.data.filter( attachedMod => diff --git a/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/AddFixtureModal.test.tsx b/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/AddFixtureModal.test.tsx index 74d150d92dc..de4538d3253 100644 --- a/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/AddFixtureModal.test.tsx +++ b/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/AddFixtureModal.test.tsx @@ -3,7 +3,6 @@ import { fireEvent, screen } from '@testing-library/react' import { describe, it, beforeEach, vi, expect, afterEach } from 'vitest' import { - useDeckConfigurationQuery, useModulesQuery, useUpdateDeckConfigurationMutation, } from '@opentrons/react-api-client' @@ -15,12 +14,15 @@ import { import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { AddFixtureModal } from '../AddFixtureModal' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { UseQueryResult } from 'react-query' import type { DeckConfiguration } from '@opentrons/shared-data' import type { Modules } from '@opentrons/api-client' vi.mock('@opentrons/react-api-client') +vi.mock('../../../resources/deck_configuration') + const mockSetShowAddFixtureModal = vi.fn() const mockUpdateDeckConfiguration = vi.fn() const mockSetCurrentDeckConfig = vi.fn() @@ -44,7 +46,7 @@ describe('Touchscreen AddFixtureModal', () => { vi.mocked(useUpdateDeckConfigurationMutation).mockReturnValue({ updateDeckConfiguration: mockUpdateDeckConfiguration, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue(({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue(({ data: [], } as unknown) as UseQueryResult) vi.mocked(useModulesQuery).mockReturnValue(({ diff --git a/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/DeviceDetailsDeckConfiguration.test.tsx b/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/DeviceDetailsDeckConfiguration.test.tsx index 5c8d3974dc8..e6d048bcf52 100644 --- a/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/DeviceDetailsDeckConfiguration.test.tsx +++ b/app/src/organisms/DeviceDetailsDeckConfiguration/__tests__/DeviceDetailsDeckConfiguration.test.tsx @@ -5,7 +5,6 @@ import { describe, it, beforeEach, vi, afterEach } from 'vitest' import { DeckConfigurator } from '@opentrons/components' import { - useDeckConfigurationQuery, useModulesQuery, useUpdateDeckConfigurationMutation, } from '@opentrons/react-api-client' @@ -17,6 +16,7 @@ import { DeckFixtureSetupInstructionsModal } from '../DeckFixtureSetupInstructio import { useIsEstopNotDisengaged } from '../../../resources/devices/hooks/useIsEstopNotDisengaged' import { DeviceDetailsDeckConfiguration } from '../' import { useNotifyCurrentMaintenanceRun } from '../../../resources/maintenance_runs' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { MaintenanceRun } from '@opentrons/api-client' import type * as OpentronsComponents from '@opentrons/components' @@ -33,6 +33,7 @@ vi.mock('../DeckFixtureSetupInstructionsModal') vi.mock('../../Devices/hooks') vi.mock('../../../resources/maintenance_runs') vi.mock('../../../resources/devices/hooks/useIsEstopNotDisengaged') +vi.mock('../../../resources/deck_configuration') const ROBOT_NAME = 'otie' const mockUpdateDeckConfiguration = vi.fn() @@ -62,7 +63,9 @@ describe('DeviceDetailsDeckConfiguration', () => { robotName: ROBOT_NAME, } vi.mocked(useModulesQuery).mockReturnValue({ data: { data: [] } } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ data: [] } as any) + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ + data: [], + } as any) vi.mocked(useUpdateDeckConfigurationMutation).mockReturnValue({ updateDeckConfiguration: mockUpdateDeckConfiguration, } as any) @@ -129,7 +132,7 @@ describe('DeviceDetailsDeckConfiguration', () => { }) it('should render no deck fixtures, if deck configs are not set', () => { - vi.mocked(useDeckConfigurationQuery).mockReturnValue([] as any) + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue([] as any) render(props) screen.getByText('No deck fixtures') }) diff --git a/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx b/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx index 0103fe25051..b6f62c8c08a 100644 --- a/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx +++ b/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx @@ -20,7 +20,6 @@ import { TYPOGRAPHY, } from '@opentrons/components' import { - useDeckConfigurationQuery, useModulesQuery, useUpdateDeckConfigurationMutation, } from '@opentrons/react-api-client' @@ -43,6 +42,7 @@ import { DeckFixtureSetupInstructionsModal } from './DeckFixtureSetupInstruction import { AddFixtureModal } from './AddFixtureModal' import { useIsRobotViewable, useRunStatuses } from '../Devices/hooks' import { useIsEstopNotDisengaged } from '../../resources/devices/hooks/useIsEstopNotDisengaged' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { CutoutFixtureId, CutoutId } from '@opentrons/shared-data' @@ -74,8 +74,9 @@ export function DeviceDetailsDeckConfiguration({ const { data: modulesData } = useModulesQuery() const deckConfig = - useDeckConfigurationQuery({ refetchInterval: DECK_CONFIG_REFETCH_INTERVAL }) - .data ?? [] + useNotifyDeckConfigurationQuery({ + refetchInterval: DECK_CONFIG_REFETCH_INTERVAL, + }).data ?? [] const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation() const { isRunRunning } = useRunStatuses() diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/ChooseModuleToConfigureModal.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/ChooseModuleToConfigureModal.tsx index 6a6264b80c7..b7b28d53f76 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/ChooseModuleToConfigureModal.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/ChooseModuleToConfigureModal.tsx @@ -2,10 +2,7 @@ import * as React from 'react' import { createPortal } from 'react-dom' import { useTranslation } from 'react-i18next' import { useHistory } from 'react-router-dom' -import { - useDeckConfigurationQuery, - useModulesQuery, -} from '@opentrons/react-api-client' +import { useModulesQuery } from '@opentrons/react-api-client' import { ALIGN_CENTER, DIRECTION_COLUMN, @@ -26,7 +23,7 @@ import { getTopPortalEl } from '../../../../App/portal' import { LegacyModal } from '../../../../molecules/LegacyModal' import { Modal } from '../../../../molecules/Modal' import { FixtureOption } from '../../../DeviceDetailsDeckConfiguration/AddFixtureModal' - +import { useNotifyDeckConfigurationQuery } from '../../../../resources/deck_configuration' import { SmallButton } from '../../../../atoms/buttons' import { useCloseCurrentRun } from '../../../ProtocolUpload/hooks' @@ -65,7 +62,7 @@ export const ChooseModuleToConfigureModal = ( const { closeCurrentRun } = useCloseCurrentRun() const attachedModules = useModulesQuery({ refetchInterval: EQUIPMENT_POLL_MS })?.data?.data ?? [] - const deckConfig = useDeckConfigurationQuery()?.data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery()?.data ?? [] const unconfiguredModuleMatches = attachedModules.filter( attachedMod => diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/LocationConflictModal.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/LocationConflictModal.tsx index 1783bd31754..f8c19df00a2 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/LocationConflictModal.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/LocationConflictModal.tsx @@ -1,10 +1,7 @@ import * as React from 'react' import { createPortal } from 'react-dom' import { Trans, useTranslation } from 'react-i18next' -import { - useDeckConfigurationQuery, - useUpdateDeckConfigurationMutation, -} from '@opentrons/react-api-client' +import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client' import { ALIGN_CENTER, BORDERS, @@ -30,10 +27,12 @@ import { getCutoutFixturesForModuleModel, getFixtureIdByCutoutIdFromModuleSlotName, } from '@opentrons/shared-data' + import { getTopPortalEl } from '../../../../App/portal' import { LegacyModal } from '../../../../molecules/LegacyModal' import { Modal } from '../../../../molecules/Modal' import { SmallButton } from '../../../../atoms/buttons/SmallButton' +import { useNotifyDeckConfigurationQuery } from '../../../../resources/deck_configuration' import type { CutoutConfig, @@ -71,7 +70,7 @@ export const LocationConflictModal = ( const { t, i18n } = useTranslation(['protocol_setup', 'shared']) const [showModuleSelect, setShowModuleSelect] = React.useState(false) - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation() const deckConfigurationAtLocationFixtureId = deckConfig.find( (deckFixture: CutoutConfig) => deckFixture.cutoutId === cutoutId diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx index daf2bc59d33..76ceaf202b6 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx @@ -1,10 +1,7 @@ import * as React from 'react' import { createPortal } from 'react-dom' import { useTranslation } from 'react-i18next' -import { - useDeckConfigurationQuery, - useUpdateDeckConfigurationMutation, -} from '@opentrons/react-api-client' +import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client' import { ALIGN_CENTER, BORDERS, @@ -20,6 +17,7 @@ import { getFixtureDisplayName } from '@opentrons/shared-data' import { TertiaryButton } from '../../../../atoms/buttons/TertiaryButton' import { getTopPortalEl } from '../../../../App/portal' import { LegacyModal } from '../../../../molecules/LegacyModal' +import { useNotifyDeckConfigurationQuery } from '../../../../resources/deck_configuration' import type { CutoutFixtureId, CutoutId } from '@opentrons/shared-data' @@ -35,7 +33,7 @@ export const NotConfiguredModal = ( const { onCloseClick, cutoutId, requiredFixtureId } = props const { t, i18n } = useTranslation(['protocol_setup', 'shared']) const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation() - const deckConfig = useDeckConfigurationQuery()?.data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery()?.data ?? [] const handleUpdateDeck = (): void => { const newDeckConfig = deckConfig.map(fixture => diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesMap.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesMap.tsx index 76aea98a8cc..976a3ae034d 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesMap.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesMap.tsx @@ -19,7 +19,7 @@ import { ModuleInfo } from '../../ModuleInfo' import { useAttachedModules, useStoredProtocolAnalysis } from '../../hooks' import { getProtocolModulesInfo } from '../utils/getProtocolModulesInfo' import { getStandardDeckViewLayerBlockList } from '../utils/getStandardDeckViewLayerBlockList' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' +import { useNotifyDeckConfigurationQuery } from '../../../../resources/deck_configuration' const ATTACHED_MODULE_POLL_MS = 5000 const DECK_CONFIG_POLL_MS = 5000 @@ -35,7 +35,7 @@ export const SetupModulesMap = ({ const robotProtocolAnalysis = useMostRecentCompletedAnalysis(runId) const storedProtocolAnalysis = useStoredProtocolAnalysis(runId) const protocolAnalysis = robotProtocolAnalysis ?? storedProtocolAnalysis - const { data: actualDeckConfig = [] } = useDeckConfigurationQuery({ + const { data: actualDeckConfig = [] } = useNotifyDeckConfigurationQuery({ refetchInterval: DECK_CONFIG_POLL_MS, }) const attachedModules = diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/LocationConflictModal.test.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/LocationConflictModal.test.tsx index d72a00a9f5f..5314acbb283 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/LocationConflictModal.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/LocationConflictModal.test.tsx @@ -12,18 +12,20 @@ import { ot3StandardDeckV5, } from '@opentrons/shared-data' import { - useDeckConfigurationQuery, useModulesQuery, useUpdateDeckConfigurationMutation, } from '@opentrons/react-api-client' + import { i18n } from '../../../../../i18n' import { mockHeaterShaker } from '../../../../../redux/modules/__fixtures__' import { useCloseCurrentRun } from '../../../../ProtocolUpload/hooks' import { LocationConflictModal } from '../LocationConflictModal' +import { useNotifyDeckConfigurationQuery } from '../../../../../resources/deck_configuration' import type { DeckConfiguration } from '@opentrons/shared-data' vi.mock('@opentrons/react-api-client') +vi.mock('../../../../../resources/deck_configuration') vi.mock('../../../../ProtocolUpload/hooks') const mockFixture = { @@ -57,7 +59,7 @@ describe('LocationConflictModal', () => { closeCurrentRun: vi.fn(), } as any) vi.mocked(useModulesQuery).mockReturnValue({ data: { data: [] } } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [mockFixture], } as UseQueryResult) vi.mocked(useUpdateDeckConfigurationMutation).mockReturnValue({ @@ -102,7 +104,7 @@ describe('LocationConflictModal', () => { expect(mockUpdate).toHaveBeenCalled() }) it('should render the modal information for a single slot fixture conflict', () => { - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [ { cutoutId: 'cutoutB1', diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/NotConfiguredModal.test.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/NotConfiguredModal.test.tsx index b124a000f53..e1a29a6a38e 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/NotConfiguredModal.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/__tests__/NotConfiguredModal.test.tsx @@ -3,17 +3,17 @@ import { fireEvent } from '@testing-library/react' import { describe, it, beforeEach, vi, expect } from 'vitest' import { renderWithProviders } from '../../../../../__testing-utils__' import { TRASH_BIN_ADAPTER_FIXTURE } from '@opentrons/shared-data' -import { - useDeckConfigurationQuery, - useUpdateDeckConfigurationMutation, -} from '@opentrons/react-api-client' +import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client' + import { i18n } from '../../../../../i18n' import { NotConfiguredModal } from '../NotConfiguredModal' +import { useNotifyDeckConfigurationQuery } from '../../../../../resources/deck_configuration' import type { UseQueryResult } from 'react-query' import type { DeckConfiguration } from '@opentrons/shared-data' vi.mock('@opentrons/react-api-client') +vi.mock('../../../../../resources/deck_configuration') const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -33,7 +33,7 @@ describe('NotConfiguredModal', () => { vi.mocked(useUpdateDeckConfigurationMutation).mockReturnValue({ updateDeckConfiguration: mockUpdate, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue(({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue(({ data: [], } as unknown) as UseQueryResult) }) diff --git a/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx b/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx index 540b1532799..50381361b9a 100644 --- a/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx +++ b/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx @@ -9,7 +9,6 @@ import { heater_shaker_commands_with_results_key, } from '@opentrons/shared-data' import { useMostRecentCompletedAnalysis } from '../../../LabwarePositionCheck/useMostRecentCompletedAnalysis' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { getProtocolModulesInfo } from '../../ProtocolRun/utils/getProtocolModulesInfo' @@ -22,6 +21,7 @@ import { useModuleRenderInfoForProtocolById, useStoredProtocolAnalysis, } from '..' +import { useNotifyDeckConfigurationQuery } from '../../../../resources/deck_configuration' import type { CutoutConfig, @@ -33,11 +33,11 @@ import type { import type { UseQueryResult } from 'react-query' import type { AttachedModule } from '../../../../redux/modules/types' -vi.mock('@opentrons/react-api-client') vi.mock('../../ProtocolRun/utils/getProtocolModulesInfo') vi.mock('../useAttachedModules') vi.mock('../useStoredProtocolAnalysis') vi.mock('../../../LabwarePositionCheck/useMostRecentCompletedAnalysis') +vi.mock('../../../../resources/deck_configuration') const heaterShakerCommandsWithResultsKey = (heater_shaker_commands_with_results_key as unknown) as ProtocolAnalysisOutput @@ -113,7 +113,7 @@ const mockCutoutConfig: CutoutConfig = { describe('useModuleRenderInfoForProtocolById hook', () => { beforeEach(() => { - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [mockCutoutConfig], } as UseQueryResult) vi.mocked(useAttachedModules).mockReturnValue([mockAttachedTempMod]) diff --git a/app/src/organisms/Devices/hooks/useModuleRenderInfoForProtocolById.ts b/app/src/organisms/Devices/hooks/useModuleRenderInfoForProtocolById.ts index e606e846d53..0190a3702dd 100644 --- a/app/src/organisms/Devices/hooks/useModuleRenderInfoForProtocolById.ts +++ b/app/src/organisms/Devices/hooks/useModuleRenderInfoForProtocolById.ts @@ -6,12 +6,12 @@ import { getDeckDefFromRobotType, OT2_ROBOT_TYPE, } from '@opentrons/shared-data' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { getProtocolModulesInfo } from '../ProtocolRun/utils/getProtocolModulesInfo' import { useMostRecentCompletedAnalysis } from '../../LabwarePositionCheck/useMostRecentCompletedAnalysis' import { useAttachedModules } from './useAttachedModules' import { useStoredProtocolAnalysis } from './useStoredProtocolAnalysis' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { CutoutConfig } from '@opentrons/shared-data' import type { AttachedModule } from '../../../redux/modules/types' @@ -33,7 +33,7 @@ export function useModuleRenderInfoForProtocolById( pollModules?: boolean ): ModuleRenderInfoById { const robotProtocolAnalysis = useMostRecentCompletedAnalysis(runId) - const { data: deckConfig = [] } = useDeckConfigurationQuery({ + const { data: deckConfig = [] } = useNotifyDeckConfigurationQuery({ refetchInterval: REFETCH_INTERVAL_5000_MS, }) const storedProtocolAnalysis = useStoredProtocolAnalysis(runId) diff --git a/app/src/organisms/DropTipWizard/index.tsx b/app/src/organisms/DropTipWizard/index.tsx index ca668cd7013..bd55591e1da 100644 --- a/app/src/organisms/DropTipWizard/index.tsx +++ b/app/src/organisms/DropTipWizard/index.tsx @@ -16,7 +16,6 @@ import { import { useCreateMaintenanceCommandMutation, useDeleteMaintenanceRunMutation, - useDeckConfigurationQuery, } from '@opentrons/react-api-client' import { useNotifyCurrentMaintenanceRun } from '../../resources/maintenance_runs' @@ -50,6 +49,7 @@ import { useDropTipErrorComponents, useWizardExitHeader, } from './utils' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { PipetteData } from '@opentrons/api-client' import type { CreateMaintenanceRunType } from '@opentrons/react-api-client' @@ -82,7 +82,7 @@ export function DropTipWizard(props: MaintenanceRunManagerProps): JSX.Element { } = useChainMaintenanceCommands() const { createMaintenanceCommand } = useCreateMaintenanceCommandMutation() - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] const [createdMaintenanceRunId, setCreatedMaintenanceRunId] = React.useState< string | null diff --git a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx index e6ae7740ffb..9a932bb697d 100644 --- a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx +++ b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx @@ -35,6 +35,7 @@ import { getModuleType, getOccludedSlotCountForModule, } from '@opentrons/shared-data' + import { getRunLabwareRenderInfo, getRunModuleRenderInfo, @@ -47,8 +48,9 @@ import { getLoadedLabware, getLoadedModule, } from '../CommandText/utils/accessors' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' + import type { RunData } from '@opentrons/api-client' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' const LABWARE_DESCRIPTION_STYLE = css` flex-direction: ${DIRECTION_COLUMN}; @@ -119,7 +121,7 @@ export function MoveLabwareInterventionContent({ const analysisCommands = analysis?.commands ?? [] const labwareDefsByUri = getLoadedLabwareDefinitionsByUri(analysisCommands) const deckDef = getDeckDefFromRobotType(robotType) - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] const moduleRenderInfo = getRunModuleRenderInfo( run, diff --git a/app/src/organisms/LabwarePositionCheck/PrepareSpace.tsx b/app/src/organisms/LabwarePositionCheck/PrepareSpace.tsx index 0ffb3bd6147..da886ccaba1 100644 --- a/app/src/organisms/LabwarePositionCheck/PrepareSpace.tsx +++ b/app/src/organisms/LabwarePositionCheck/PrepareSpace.tsx @@ -27,9 +27,9 @@ import { import { getIsOnDevice } from '../../redux/config' import { SmallButton } from '../../atoms/buttons' import { NeedHelpLink } from '../CalibrationPanels' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { CheckLabwareStep } from './types' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' const LPC_HELP_LINK_URL = 'https://support.opentrons.com/s/article/How-Labware-Offsets-work-on-the-OT-2' @@ -71,7 +71,7 @@ export const PrepareSpace = (props: PrepareSpaceProps): JSX.Element | null => { const { location, labwareDef, protocolData, header, body, robotType } = props const isOnDevice = useSelector(getIsOnDevice) - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] if (protocolData == null || robotType == null) return null diff --git a/app/src/organisms/ModuleWizardFlows/index.tsx b/app/src/organisms/ModuleWizardFlows/index.tsx index 3e0977a4f23..8c4bb1e8e97 100644 --- a/app/src/organisms/ModuleWizardFlows/index.tsx +++ b/app/src/organisms/ModuleWizardFlows/index.tsx @@ -2,11 +2,7 @@ import * as React from 'react' import { createPortal } from 'react-dom' import { useSelector } from 'react-redux' import { Trans, useTranslation } from 'react-i18next' -import { - useDeleteMaintenanceRunMutation, - useCurrentMaintenanceRun, - useDeckConfigurationQuery, -} from '@opentrons/react-api-client' +import { useDeleteMaintenanceRunMutation } from '@opentrons/react-api-client' import { COLORS, StyledText } from '@opentrons/components' import { getModuleType, @@ -37,6 +33,8 @@ import { PlaceAdapter } from './PlaceAdapter' import { SelectLocation } from './SelectLocation' import { Success } from './Success' import { DetachProbe } from './DetachProbe' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' +import { useNotifyCurrentMaintenanceRun } from '../../resources/maintenance_runs' import type { AttachedModule, CommandData } from '@opentrons/api-client' import type { @@ -75,7 +73,7 @@ export const ModuleWizardFlows = ( const moduleCalibrationSteps = getModuleCalibrationSteps() const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] const moduleCutoutConfig = deckConfig.find( cc => cc.opentronsModuleSerialNumber === attachedModule.serialNumber ) @@ -127,7 +125,7 @@ export const ModuleWizardFlows = ( setMonitorMaintenanceRunForDeletion, ] = React.useState(false) - const { data: maintenanceRunData } = useCurrentMaintenanceRun({ + const { data: maintenanceRunData } = useNotifyCurrentMaintenanceRun({ refetchInterval: RUN_REFETCH_INTERVAL, enabled: createdMaintenanceRunId != null, }) diff --git a/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx b/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx index a53d25a6d82..489269e4311 100644 --- a/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx +++ b/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx @@ -15,7 +15,6 @@ import { WASTE_CHUTE_CUTOUT, CreateCommand, } from '@opentrons/shared-data' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { Banner } from '../../atoms/Banner' import { GenericWizardTile } from '../../molecules/GenericWizardTile' import { SimpleWizardBody } from '../../molecules/SimpleWizardBody' @@ -26,6 +25,8 @@ import probing96 from '../../assets/videos/pipette-wizard-flows/Pipette_Probing_ import { BODY_STYLE, SECTIONS, FLOWS } from './constants' import { getPipetteAnimations } from './utils' import { ProbeNotAttached } from './ProbeNotAttached' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' + import type { PipetteWizardStepProps } from './types' interface AttachProbeProps extends PipetteWizardStepProps { @@ -69,7 +70,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { const is96Channel = attachedPipettes[mount]?.data.channels === 96 const calSlotNum = 'C2' const axes: MotorAxes = mount === LEFT ? ['leftZ'] : ['rightZ'] - const deckConfig = useDeckConfigurationQuery().data + const deckConfig = useNotifyDeckConfigurationQuery().data const isWasteChuteOnDeck = deckConfig?.find(fixture => fixture.cutoutId === WASTE_CHUTE_CUTOUT) ?? false diff --git a/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx b/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx index b20b1bfe4e0..6379bb74f7f 100644 --- a/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx +++ b/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx @@ -17,7 +17,6 @@ import { getPipetteNameSpecs, WASTE_CHUTE_CUTOUT, } from '@opentrons/shared-data' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { Banner } from '../../atoms/Banner' import { SimpleWizardBody } from '../../molecules/SimpleWizardBody' import { GenericWizardTile } from '../../molecules/GenericWizardTile' @@ -33,6 +32,8 @@ import { BODY_STYLE, } from './constants' import { getIsGantryEmpty } from './utils' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' + import type { AxiosError } from 'axios' import type { CreateCommand } from '@opentrons/shared-data' import type { @@ -84,7 +85,7 @@ export const BeforeBeginning = ( isGantryEmpty && selectedPipette === NINETY_SIX_CHANNEL && flowType === FLOWS.ATTACH - const deckConfig = useDeckConfigurationQuery().data + const deckConfig = useNotifyDeckConfigurationQuery().data const isWasteChuteOnDeck = deckConfig?.find(fixture => fixture.cutoutId === WASTE_CHUTE_CUTOUT) ?? false diff --git a/app/src/organisms/PipetteWizardFlows/__tests__/AttachProbe.test.tsx b/app/src/organisms/PipetteWizardFlows/__tests__/AttachProbe.test.tsx index 75af3b08f8d..2ec224707b9 100644 --- a/app/src/organisms/PipetteWizardFlows/__tests__/AttachProbe.test.tsx +++ b/app/src/organisms/PipetteWizardFlows/__tests__/AttachProbe.test.tsx @@ -2,7 +2,6 @@ import * as React from 'react' import { fireEvent, screen, waitFor } from '@testing-library/react' import { describe, it, beforeEach, vi, expect } from 'vitest' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { LEFT, SINGLE_MOUNT_PIPETTES } from '@opentrons/shared-data' import { @@ -18,13 +17,14 @@ import { import { RUN_ID_1 } from '../../RunTimeControl/__fixtures__' import { FLOWS } from '../constants' import { AttachProbe } from '../AttachProbe' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' const render = (props: React.ComponentProps) => { return renderWithProviders(, { i18nInstance: i18n, })[0] } -vi.mock('@opentrons/react-api-client') +vi.mock('../../../resources/deck_configuration') describe('AttachProbe', () => { let props: React.ComponentProps @@ -47,7 +47,7 @@ describe('AttachProbe', () => { selectedPipette: SINGLE_MOUNT_PIPETTES, isOnDevice: false, } - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [ { cutoutId: 'cutoutD3', diff --git a/app/src/organisms/ProtocolSetupDeckConfiguration/__tests__/ProtocolSetupDeckConfiguration.test.tsx b/app/src/organisms/ProtocolSetupDeckConfiguration/__tests__/ProtocolSetupDeckConfiguration.test.tsx index 892df022b5f..18c678d74e6 100644 --- a/app/src/organisms/ProtocolSetupDeckConfiguration/__tests__/ProtocolSetupDeckConfiguration.test.tsx +++ b/app/src/organisms/ProtocolSetupDeckConfiguration/__tests__/ProtocolSetupDeckConfiguration.test.tsx @@ -5,7 +5,6 @@ import { describe, it, vi, beforeEach, expect, afterEach } from 'vitest' import { BaseDeck } from '@opentrons/components' import { - useDeckConfigurationQuery, useModulesQuery, useUpdateDeckConfigurationMutation, } from '@opentrons/react-api-client' @@ -14,6 +13,7 @@ import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { useMostRecentCompletedAnalysis } from '../../LabwarePositionCheck/useMostRecentCompletedAnalysis' import { ProtocolSetupDeckConfiguration } from '..' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { UseQueryResult } from 'react-query' import type { @@ -25,6 +25,7 @@ import { Modules } from '@opentrons/api-client' vi.mock('@opentrons/components/src/hardware-sim/BaseDeck/index') vi.mock('@opentrons/react-api-client') vi.mock('../../LabwarePositionCheck/useMostRecentCompletedAnalysis') +vi.mock('../../../resources/deck_configuration') const mockSetSetupScreen = vi.fn() const mockUpdateDeckConfiguration = vi.fn() @@ -71,7 +72,7 @@ describe('ProtocolSetupDeckConfiguration', () => { vi.mocked(useUpdateDeckConfigurationMutation).mockReturnValue({ updateDeckConfiguration: mockUpdateDeckConfiguration, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue(({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue(({ data: [], } as unknown) as UseQueryResult) vi.mocked(useModulesQuery).mockReturnValue(({ diff --git a/app/src/organisms/ProtocolSetupDeckConfiguration/index.tsx b/app/src/organisms/ProtocolSetupDeckConfiguration/index.tsx index 98e977fb92a..488f53782a9 100644 --- a/app/src/organisms/ProtocolSetupDeckConfiguration/index.tsx +++ b/app/src/organisms/ProtocolSetupDeckConfiguration/index.tsx @@ -13,16 +13,14 @@ import { FLEX_ROBOT_TYPE, getSimplestDeckConfigForProtocol, } from '@opentrons/shared-data' -import { - useDeckConfigurationQuery, - useUpdateDeckConfigurationMutation, -} from '@opentrons/react-api-client' +import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client' import { ChildNavigation } from '../ChildNavigation' import { AddFixtureModal } from '../DeviceDetailsDeckConfiguration/AddFixtureModal' import { DeckConfigurationDiscardChangesModal } from '../DeviceDetailsDeckConfiguration/DeckConfigurationDiscardChangesModal' import { useMostRecentCompletedAnalysis } from '../LabwarePositionCheck/useMostRecentCompletedAnalysis' import { getTopPortalEl } from '../../App/portal' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { CutoutFixtureId, @@ -56,7 +54,7 @@ export function ProtocolSetupDeckConfiguration({ ] = React.useState(false) const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId) - const { data: deckConfig = [] } = useDeckConfigurationQuery() + const deckConfig = useNotifyDeckConfigurationQuery()?.data ?? [] const simplestDeckConfig = getSimplestDeckConfigForProtocol( mostRecentAnalysis diff --git a/app/src/organisms/ProtocolSetupLabware/__tests__/ProtocolSetupLabware.test.tsx b/app/src/organisms/ProtocolSetupLabware/__tests__/ProtocolSetupLabware.test.tsx index 18f02ec5e5c..7bfb4f63871 100644 --- a/app/src/organisms/ProtocolSetupLabware/__tests__/ProtocolSetupLabware.test.tsx +++ b/app/src/organisms/ProtocolSetupLabware/__tests__/ProtocolSetupLabware.test.tsx @@ -7,7 +7,6 @@ import { describe, it, vi, beforeEach, afterEach, expect } from 'vitest' import { useCreateLiveCommandMutation, useModulesQuery, - useDeckConfigurationQuery, } from '@opentrons/react-api-client' import { HEATERSHAKER_MODULE_V1_FIXTURE, @@ -28,6 +27,7 @@ import { mockUseModulesQueryOpening, mockUseModulesQueryUnknown, } from '../__fixtures__' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type * as ReactApiClient from '@opentrons/react-api-client' @@ -37,7 +37,6 @@ vi.mock('@opentrons/react-api-client', async importOriginal => { ...actual, useCreateLiveCommandMutation: vi.fn(), useModulesQuery: vi.fn(), - useDeckConfigurationQuery: vi.fn(), } }) @@ -45,6 +44,7 @@ vi.mock( '../../../organisms/LabwarePositionCheck/useMostRecentCompletedAnalysis' ) vi.mock('../../Devices/ProtocolRun/utils/getProtocolModulesInfo') +vi.mock('../../../resources/deck_configuration') const RUN_ID = "otie's run" const mockSetSetupScreen = vi.fn() @@ -81,7 +81,7 @@ describe('ProtocolSetupLabware', () => { vi.mocked(useCreateLiveCommandMutation).mockReturnValue({ createLiveCommand: mockCreateLiveCommand, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [ { cutoutId: 'cutoutB1', diff --git a/app/src/organisms/ProtocolSetupLabware/index.tsx b/app/src/organisms/ProtocolSetupLabware/index.tsx index 33e44ab7534..831d0a57962 100644 --- a/app/src/organisms/ProtocolSetupLabware/index.tsx +++ b/app/src/organisms/ProtocolSetupLabware/index.tsx @@ -34,7 +34,6 @@ import { import { parseInitialLoadedLabwareByAdapter } from '@opentrons/api-client' import { useCreateLiveCommandMutation, - useDeckConfigurationQuery, useModulesQuery, } from '@opentrons/react-api-client' @@ -51,6 +50,8 @@ import { getNestedLabwareInfo, NestedLabwareInfo, } from '../Devices/ProtocolRun/SetupLabware/getNestedLabwareInfo' +import { LabwareMapViewModal } from './LabwareMapViewModal' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { UseQueryResult } from 'react-query' import type { @@ -63,7 +64,6 @@ import type { HeaterShakerModule, Modules } from '@opentrons/api-client' import type { LabwareSetupItem } from '../../pages/Protocols/utils' import type { SetupScreens } from '../../pages/ProtocolSetup' import type { AttachedProtocolModuleMatch } from '../ProtocolSetupModulesAndDeck/utils' -import { LabwareMapViewModal } from './LabwareMapViewModal' const MODULE_REFETCH_INTERVAL_MS = 5000 const DECK_CONFIG_POLL_MS = 5000 @@ -99,7 +99,7 @@ export function ProtocolSetupLabware({ const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId) const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) - const { data: deckConfig = [] } = useDeckConfigurationQuery({ + const { data: deckConfig = [] } = useNotifyDeckConfigurationQuery({ refetchInterval: DECK_CONFIG_POLL_MS, }) const { offDeckItems, onDeckItems } = getLabwareSetupItemGroups( diff --git a/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx b/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx index f590eaab928..793f41dc75e 100644 --- a/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx +++ b/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx @@ -14,7 +14,6 @@ import { StyledText, TYPOGRAPHY, } from '@opentrons/components' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { getCutoutFixturesForModuleModel, getCutoutIdsFromModuleSlotName, @@ -34,6 +33,7 @@ import { ModuleWizardFlows } from '../../organisms/ModuleWizardFlows' import { useToaster } from '../../organisms/ToasterOven' import { getLocalRobot } from '../../redux/discovery' import { useChainLiveCommands } from '../../resources/runs' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { CommandData } from '@opentrons/api-client' import type { CutoutConfig, DeckDefinition } from '@opentrons/shared-data' @@ -57,7 +57,7 @@ export function ModuleTable(props: ModuleTableProps): JSX.Element { setPrepCommandErrorMessage, ] = React.useState('') - const { data: deckConfig } = useDeckConfigurationQuery({ + const { data: deckConfig } = useNotifyDeckConfigurationQuery({ refetchInterval: DECK_CONFIG_REFETCH_INTERVAL, }) const localRobot = useSelector(getLocalRobot) diff --git a/app/src/organisms/ProtocolSetupModulesAndDeck/__tests__/ProtocolSetupModulesAndDeck.test.tsx b/app/src/organisms/ProtocolSetupModulesAndDeck/__tests__/ProtocolSetupModulesAndDeck.test.tsx index bf2dfbe5dc4..2fdd6beaf9e 100644 --- a/app/src/organisms/ProtocolSetupModulesAndDeck/__tests__/ProtocolSetupModulesAndDeck.test.tsx +++ b/app/src/organisms/ProtocolSetupModulesAndDeck/__tests__/ProtocolSetupModulesAndDeck.test.tsx @@ -5,7 +5,6 @@ import { vi, it, expect, describe, beforeEach, afterEach } from 'vitest' import { when } from 'vitest-when' import { MemoryRouter } from 'react-router-dom' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { FLEX_ROBOT_TYPE, WASTE_CHUTE_RIGHT_ADAPTER_NO_COVER_FIXTURE, @@ -36,13 +35,14 @@ import { SetupInstructionsModal } from '../SetupInstructionsModal' import { FixtureTable } from '../FixtureTable' import { ModulesAndDeckMapViewModal } from '../ModulesAndDeckMapViewModal' import { ProtocolSetupModulesAndDeck } from '..' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { CutoutConfig, DeckConfiguration } from '@opentrons/shared-data' -vi.mock('@opentrons/react-api-client') vi.mock('../../../resources/runs') vi.mock('../../../redux/discovery') vi.mock('../../../organisms/Devices/hooks') +vi.mock('../../../resources/deck_configuration') vi.mock( '../../../organisms/LabwarePositionCheck/useMostRecentCompletedAnalysis' ) @@ -119,7 +119,7 @@ describe('ProtocolSetupModulesAndDeck', () => { vi.mocked(LocationConflictModal).mockReturnValue(
mock location conflict modal
) - vi.mocked(useDeckConfigurationQuery).mockReturnValue(({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue(({ data: [], } as unknown) as UseQueryResult) when(vi.mocked(useRunCalibrationStatus)) @@ -307,7 +307,7 @@ describe('ProtocolSetupModulesAndDeck', () => { }) it('should render mock Fixture table and module location conflict', () => { - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [mockFixture], } as UseQueryResult) vi.mocked(getAttachedProtocolModuleMatches).mockReturnValue([ diff --git a/app/src/organisms/ProtocolSetupModulesAndDeck/index.tsx b/app/src/organisms/ProtocolSetupModulesAndDeck/index.tsx index 86f51d42afe..98c57d69e01 100644 --- a/app/src/organisms/ProtocolSetupModulesAndDeck/index.tsx +++ b/app/src/organisms/ProtocolSetupModulesAndDeck/index.tsx @@ -30,10 +30,10 @@ import { SetupInstructionsModal } from './SetupInstructionsModal' import { FixtureTable } from './FixtureTable' import { ModuleTable } from './ModuleTable' import { ModulesAndDeckMapViewModal } from './ModulesAndDeckMapViewModal' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { CutoutId, CutoutFixtureId } from '@opentrons/shared-data' import type { SetupScreens } from '../../pages/ProtocolSetup' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' const ATTACHED_MODULE_POLL_MS = 5000 const DECK_CONFIG_POLL_MS = 5000 @@ -68,7 +68,7 @@ export function ProtocolSetupModulesAndDeck({ const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId) const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) - const { data: deckConfig = [] } = useDeckConfigurationQuery({ + const { data: deckConfig = [] } = useNotifyDeckConfigurationQuery({ refetchInterval: DECK_CONFIG_POLL_MS, }) const attachedModules = diff --git a/app/src/organisms/QuickTransferFlow/CreateNewTransfer.tsx b/app/src/organisms/QuickTransferFlow/CreateNewTransfer.tsx index 57d6ce14b54..21689fa2ceb 100644 --- a/app/src/organisms/QuickTransferFlow/CreateNewTransfer.tsx +++ b/app/src/organisms/QuickTransferFlow/CreateNewTransfer.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { useTranslation, Trans } from 'react-i18next' + import { Flex, SPACING, @@ -8,9 +9,10 @@ import { TYPOGRAPHY, DIRECTION_COLUMN, } from '@opentrons/components' + import { SmallButton } from '../../atoms/buttons' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { ChildNavigation } from '../ChildNavigation' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' interface CreateNewTransferProps { onNext: () => void @@ -19,7 +21,7 @@ interface CreateNewTransferProps { export function CreateNewTransfer(props: CreateNewTransferProps): JSX.Element { const { i18n, t } = useTranslation(['quick_transfer', 'shared']) - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] return ( { return renderWithProviders( @@ -66,7 +65,7 @@ const render = () => { describe('DeckConfigurationEditor', () => { beforeEach(() => { - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: mockDeckConfig, } as UseQueryResult) vi.mocked(useUpdateDeckConfigurationMutation).mockReturnValue({ diff --git a/app/src/pages/DeckConfiguration/index.tsx b/app/src/pages/DeckConfiguration/index.tsx index 27d0d83a25c..91a2a2d80e5 100644 --- a/app/src/pages/DeckConfiguration/index.tsx +++ b/app/src/pages/DeckConfiguration/index.tsx @@ -11,10 +11,7 @@ import { JUSTIFY_CENTER, JUSTIFY_SPACE_AROUND, } from '@opentrons/components' -import { - useDeckConfigurationQuery, - useUpdateDeckConfigurationMutation, -} from '@opentrons/react-api-client' +import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client' import { SINGLE_RIGHT_CUTOUTS, SINGLE_LEFT_SLOT_FIXTURE, @@ -31,6 +28,7 @@ import { AddFixtureModal } from '../../organisms/DeviceDetailsDeckConfiguration/ import { DeckFixtureSetupInstructionsModal } from '../../organisms/DeviceDetailsDeckConfiguration/DeckFixtureSetupInstructionsModal' import { DeckConfigurationDiscardChangesModal } from '../../organisms/DeviceDetailsDeckConfiguration/DeckConfigurationDiscardChangesModal' import { getTopPortalEl } from '../../App/portal' +import { useNotifyDeckConfigurationQuery } from '../../resources/deck_configuration' import type { CutoutFixtureId, @@ -62,7 +60,7 @@ export function DeckConfigurationEditor(): JSX.Element { ] = React.useState(false) const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) - const deckConfig = useDeckConfigurationQuery().data ?? [] + const deckConfig = useNotifyDeckConfigurationQuery().data ?? [] const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation() const [ diff --git a/app/src/pages/ProtocolSetup/__tests__/ProtocolSetup.test.tsx b/app/src/pages/ProtocolSetup/__tests__/ProtocolSetup.test.tsx index 6eec187ba66..32bc9963d0a 100644 --- a/app/src/pages/ProtocolSetup/__tests__/ProtocolSetup.test.tsx +++ b/app/src/pages/ProtocolSetup/__tests__/ProtocolSetup.test.tsx @@ -11,7 +11,6 @@ import { useProtocolQuery, useDoorQuery, useModulesQuery, - useDeckConfigurationQuery, useProtocolAnalysisAsDocumentQuery, } from '@opentrons/react-api-client' import { renderWithProviders } from '../../../__testing-utils__' @@ -57,6 +56,7 @@ import { useFeatureFlag } from '../../../redux/config' import { ViewOnlyParameters } from '../../../organisms/ProtocolSetupParameters/ViewOnlyParameters' import { mockConnectableRobot } from '../../../redux/discovery/__fixtures__' import { mockRunTimeParameterData } from '../../ProtocolDetails/fixtures' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { UseQueryResult } from 'react-query' import type * as SharedData from '@opentrons/shared-data' @@ -114,6 +114,7 @@ vi.mock('../ConfirmAttachedModal') vi.mock('../../../organisms/ToasterOven') vi.mock('../../../resources/deck_configuration/hooks') vi.mock('../../../resources/runs') +vi.mock('../../../resources/deck_configuration') const render = (path = '/') => { return renderWithProviders( @@ -273,7 +274,7 @@ describe('ProtocolSetup', () => { vi.mocked(useModulesQuery).mockReturnValue({ data: { data: [mockHeaterShaker] }, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [mockFixture], } as UseQueryResult) when(vi.mocked(useToaster)) diff --git a/app/src/pages/Protocols/hooks/__tests__/hooks.test.tsx b/app/src/pages/Protocols/hooks/__tests__/hooks.test.tsx index 7827c82175f..79e0e16a759 100644 --- a/app/src/pages/Protocols/hooks/__tests__/hooks.test.tsx +++ b/app/src/pages/Protocols/hooks/__tests__/hooks.test.tsx @@ -9,7 +9,6 @@ import { useProtocolAnalysisAsDocumentQuery, useInstrumentsQuery, useModulesQuery, - useDeckConfigurationQuery, } from '@opentrons/react-api-client' import { CompletedProtocolAnalysis, @@ -24,6 +23,7 @@ import { useRequiredProtocolLabware, useRunTimeParameters, } from '../index' +import { useNotifyDeckConfigurationQuery } from '../../../../resources/deck_configuration/useNotifyDeckConfigurationQuery' import type { Protocol } from '@opentrons/api-client' import { mockHeaterShaker } from '../../../../redux/modules/__fixtures__' @@ -31,6 +31,9 @@ import { mockHeaterShaker } from '../../../../redux/modules/__fixtures__' vi.mock('@opentrons/react-api-client') vi.mock('../../../../organisms/Devices/hooks') vi.mock('../../../../redux/config') +vi.mock( + '../../../../resources/deck_configuration/useNotifyDeckConfigurationQuery' +) const PROTOCOL_ID = 'fake_protocol_id' const mockRTPData = [ @@ -280,7 +283,7 @@ describe.only('useMissingProtocolHardware', () => { vi.mocked(useProtocolAnalysisAsDocumentQuery).mockReturnValue({ data: PROTOCOL_ANALYSIS, } as UseQueryResult) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [{}], } as UseQueryResult) }) @@ -314,7 +317,7 @@ describe.only('useMissingProtocolHardware', () => { }) }) it('should return 1 conflicted slot', () => { - vi.mocked(useDeckConfigurationQuery).mockReturnValue(({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue(({ data: [ { cutoutId: 'cutoutD3', @@ -366,7 +369,7 @@ describe.only('useMissingProtocolHardware', () => { data: { data: [mockHeaterShaker] }, isLoading: false, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [ omitBy( FLEX_SIMPLEST_DECK_CONFIG, @@ -411,7 +414,7 @@ describe.only('useMissingProtocolHardware', () => { isLoading: false, } as any) - vi.mocked(useDeckConfigurationQuery).mockReturnValue({ + vi.mocked(useNotifyDeckConfigurationQuery).mockReturnValue({ data: [ omitBy( FLEX_SIMPLEST_DECK_CONFIG, diff --git a/app/src/pages/Protocols/hooks/index.ts b/app/src/pages/Protocols/hooks/index.ts index 22e049f4ca8..7335b9482ea 100644 --- a/app/src/pages/Protocols/hooks/index.ts +++ b/app/src/pages/Protocols/hooks/index.ts @@ -1,6 +1,5 @@ import last from 'lodash/last' import { - useDeckConfigurationQuery, useInstrumentsQuery, useModulesQuery, useProtocolAnalysisAsDocumentQuery, @@ -19,6 +18,7 @@ import { import { getLabwareSetupItemGroups } from '../utils' import { getProtocolUsesGripper } from '../../../organisms/ProtocolSetupInstruments/utils' import { useDeckConfigurationCompatibility } from '../../../resources/deck_configuration/hooks' +import { useNotifyDeckConfigurationQuery } from '../../../resources/deck_configuration' import type { CompletedProtocolAnalysis, @@ -83,9 +83,10 @@ export const useRequiredProtocolHardwareFromAnalysis = ( const robotType = FLEX_ROBOT_TYPE const deckDef = getDeckDefFromRobotType(robotType) - const { data: deckConfig = [] } = useDeckConfigurationQuery({ - refetchInterval: DECK_CONFIG_REFETCH_INTERVAL, - }) + const deckConfig = + useNotifyDeckConfigurationQuery({ + refetchInterval: DECK_CONFIG_REFETCH_INTERVAL, + })?.data ?? [] const deckConfigCompatibility = useDeckConfigurationCompatibility( robotType, analysis diff --git a/app/src/redux/shell/types.ts b/app/src/redux/shell/types.ts index e5f42b864bd..276d081fc71 100644 --- a/app/src/redux/shell/types.ts +++ b/app/src/redux/shell/types.ts @@ -141,6 +141,7 @@ export type NotifyTopic = | 'robot-server/runs/current_command' | 'robot-server/runs' | `robot-server/runs/${string}` + | 'robot-server/deck_configuration' export interface NotifySubscribeAction { type: 'shell:NOTIFY_SUBSCRIBE' diff --git a/app/src/resources/deck_configuration/__tests__/hooks.test.ts b/app/src/resources/deck_configuration/__tests__/hooks.test.ts index 29e12c44bb1..fc71c602780 100644 --- a/app/src/resources/deck_configuration/__tests__/hooks.test.ts +++ b/app/src/resources/deck_configuration/__tests__/hooks.test.ts @@ -1,7 +1,6 @@ import { describe, it, vi, beforeEach } from 'vitest' import { when } from 'vitest-when' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { SINGLE_LEFT_SLOT_FIXTURE, SINGLE_RIGHT_SLOT_FIXTURE, @@ -10,10 +9,12 @@ import { WASTE_CHUTE_RIGHT_ADAPTER_COVERED_FIXTURE, } from '@opentrons/shared-data' +import { useNotifyDeckConfigurationQuery } from '../useNotifyDeckConfigurationQuery' + import type { UseQueryResult } from 'react-query' import type { DeckConfiguration } from '@opentrons/shared-data' -vi.mock('@opentrons/react-api-client') +vi.mock('../useNotifyDeckConfigurationQuery') const MOCK_DECK_CONFIG: DeckConfiguration = [ { @@ -52,7 +53,7 @@ const MOCK_DECK_CONFIG: DeckConfiguration = [ describe('useDeckConfigurationCompatibility', () => { beforeEach(() => { - when(useDeckConfigurationQuery) + when(useNotifyDeckConfigurationQuery) .calledWith() .thenReturn({ data: MOCK_DECK_CONFIG, diff --git a/app/src/resources/deck_configuration/hooks.ts b/app/src/resources/deck_configuration/hooks.ts index beae36d9821..ed48b705c5c 100644 --- a/app/src/resources/deck_configuration/hooks.ts +++ b/app/src/resources/deck_configuration/hooks.ts @@ -1,5 +1,4 @@ import { getInitialAndMovedLabwareInSlots } from '@opentrons/components' -import { useDeckConfigurationQuery } from '@opentrons/react-api-client' import { FLEX_ROBOT_TYPE, getAddressableAreasInProtocol, @@ -18,6 +17,8 @@ import type { RobotType, } from '@opentrons/shared-data' +import { useNotifyDeckConfigurationQuery } from './useNotifyDeckConfigurationQuery' + const DECK_CONFIG_REFETCH_INTERVAL = 5000 export interface CutoutConfigAndCompatibility extends CutoutConfigProtocolSpec { @@ -30,8 +31,9 @@ export function useDeckConfigurationCompatibility( protocolAnalysis: CompletedProtocolAnalysis | ProtocolAnalysisOutput | null ): CutoutConfigAndCompatibility[] { const deckConfig = - useDeckConfigurationQuery({ refetchInterval: DECK_CONFIG_REFETCH_INTERVAL }) - .data ?? [] + useNotifyDeckConfigurationQuery({ + refetchInterval: DECK_CONFIG_REFETCH_INTERVAL, + }).data ?? [] if (robotType !== FLEX_ROBOT_TYPE) return [] const deckDef = getDeckDefFromRobotType(robotType) const allAddressableAreas = diff --git a/app/src/resources/deck_configuration/index.ts b/app/src/resources/deck_configuration/index.ts new file mode 100644 index 00000000000..da47ee2de54 --- /dev/null +++ b/app/src/resources/deck_configuration/index.ts @@ -0,0 +1,4 @@ +export * from './hooks' +export * from './types' +export * from './utils' +export * from './useNotifyDeckConfigurationQuery' diff --git a/app/src/resources/deck_configuration/useNotifyDeckConfigurationQuery.ts b/app/src/resources/deck_configuration/useNotifyDeckConfigurationQuery.ts new file mode 100644 index 00000000000..3ccfd9feca5 --- /dev/null +++ b/app/src/resources/deck_configuration/useNotifyDeckConfigurationQuery.ts @@ -0,0 +1,32 @@ +import * as React from 'react' + +import { useDeckConfigurationQuery } from '@opentrons/react-api-client' + +import { useNotifyService } from '../useNotifyService' + +import type { UseQueryResult } from 'react-query' +import type { DeckConfiguration } from '@opentrons/shared-data' +import type { + QueryOptionsWithPolling, + HTTPRefetchFrequency, +} from '../useNotifyService' + +export function useNotifyDeckConfigurationQuery( + options: QueryOptionsWithPolling = {} +): UseQueryResult { + const [refetch, setRefetch] = React.useState(null) + + useNotifyService({ + topic: 'robot-server/deck_configuration', + setRefetch, + options, + }) + + const httpQueryResult = useDeckConfigurationQuery({ + ...options, + enabled: options?.enabled !== false && refetch != null, + onSettled: refetch === 'once' ? () => setRefetch(null) : () => null, + }) + + return httpQueryResult +}