From de39cbebd44808d37df5abd300700f4b81bee875 Mon Sep 17 00:00:00 2001 From: vegano1 Date: Thu, 24 Oct 2024 10:18:01 -0400 Subject: [PATCH] refactor estopPressed --- app/src/App/OnDeviceDisplayApp.tsx | 2 +- .../EmergencyStop/EstopPressedModal.tsx | 134 ++++++------------ .../organisms/EmergencyStop/EstopTakeover.tsx | 95 +++++-------- .../modules/hooks/usePlacePlateReaderLid.ts | 9 +- 4 files changed, 86 insertions(+), 154 deletions(-) diff --git a/app/src/App/OnDeviceDisplayApp.tsx b/app/src/App/OnDeviceDisplayApp.tsx index d72eabf3bc9..5ab0598587a 100644 --- a/app/src/App/OnDeviceDisplayApp.tsx +++ b/app/src/App/OnDeviceDisplayApp.tsx @@ -189,7 +189,7 @@ export const OnDeviceDisplayApp = (): JSX.Element => { <> - + diff --git a/app/src/organisms/EmergencyStop/EstopPressedModal.tsx b/app/src/organisms/EmergencyStop/EstopPressedModal.tsx index 191ba1c5e05..7c78de6b8e2 100644 --- a/app/src/organisms/EmergencyStop/EstopPressedModal.tsx +++ b/app/src/organisms/EmergencyStop/EstopPressedModal.tsx @@ -41,21 +41,15 @@ import type { ModalProps } from '@opentrons/components' interface EstopPressedModalProps { isEngaged: boolean closeModal: () => void - isDismissedModal?: boolean - setIsDismissedModal?: (isDismissedModal: boolean) => void - isWaitingForLogicalDisengage: boolean - isWaitingForPlateReaderLidPlacement: boolean - setShouldSeeLogicalDisengage: () => void + isWaitingForResumeOperation: boolean + setIsWaitingForResumeOperation: () => void } export function EstopPressedModal({ isEngaged, closeModal, - isDismissedModal, - setIsDismissedModal, - isWaitingForLogicalDisengage, - isWaitingForPlateReaderLidPlacement, - setShouldSeeLogicalDisengage, + isWaitingForResumeOperation, + setIsWaitingForResumeOperation, }: EstopPressedModalProps): JSX.Element { const isOnDevice = useSelector(getIsOnDevice) return createPortal( @@ -63,26 +57,17 @@ export function EstopPressedModal({ ) : ( <> - {isDismissedModal === false ? ( - - ) : null} + ), getTopPortalEl() @@ -92,16 +77,18 @@ export function EstopPressedModal({ function TouchscreenModal({ isEngaged, closeModal, - isWaitingForLogicalDisengage, - isWaitingForPlateReaderLidPlacement, - setShouldSeeLogicalDisengage, + isWaitingForResumeOperation, + setIsWaitingForResumeOperation, }: EstopPressedModalProps): JSX.Element { const { t } = useTranslation(['device_settings', 'branded']) const [isResuming, setIsResuming] = React.useState(false) const { acknowledgeEstopDisengage } = useAcknowledgeEstopDisengageMutation() - const { handlePlaceReaderLid, isPlacing } = usePlacePlateReaderLid({ - onSettled: undefined, + const { + handlePlaceReaderLid, + isValidPlateReaderMove, + } = usePlacePlateReaderLid({ + onSettled: closeModal, }) const modalHeader: OddModalHeaderBaseProps = { title: t('estop_pressed'), @@ -114,10 +101,12 @@ function TouchscreenModal({ } const handleClick = (): void => { setIsResuming(true) + setIsWaitingForResumeOperation() acknowledgeEstopDisengage(null) - setShouldSeeLogicalDisengage() handlePlaceReaderLid() - closeModal() + if (!isValidPlateReaderMove) { + closeModal() + } } return ( @@ -146,29 +135,13 @@ function TouchscreenModal({ data-testid="Estop_pressed_button" width="100%" iconName={ - isResuming || - isPlacing || - isWaitingForLogicalDisengage || - isWaitingForPlateReaderLidPlacement - ? 'ot-spinner' - : undefined + isResuming || isWaitingForResumeOperation ? 'ot-spinner' : undefined } iconPlacement={ - isResuming || - isPlacing || - isWaitingForLogicalDisengage || - isWaitingForPlateReaderLidPlacement - ? 'startIcon' - : undefined + isResuming || isWaitingForResumeOperation ? 'startIcon' : undefined } buttonText={t('resume_robot_operations')} - disabled={ - isEngaged || - isResuming || - isPlacing || - isWaitingForLogicalDisengage || - isWaitingForPlateReaderLidPlacement - } + disabled={isEngaged || isResuming || isWaitingForResumeOperation} onClick={handleClick} /> @@ -179,29 +152,23 @@ function TouchscreenModal({ function DesktopModal({ isEngaged, closeModal, - setIsDismissedModal, - isWaitingForLogicalDisengage, - isWaitingForPlateReaderLidPlacement, - setShouldSeeLogicalDisengage, + isWaitingForResumeOperation, + setIsWaitingForResumeOperation, }: EstopPressedModalProps): JSX.Element { const { t } = useTranslation('device_settings') const [isResuming, setIsResuming] = React.useState(false) const { acknowledgeEstopDisengage } = useAcknowledgeEstopDisengageMutation() - const { placeReaderLid, isPlacing } = usePlacePlateReaderLid({ - pipetteInfo: null, + const { + handlePlaceReaderLid, + isValidPlateReaderMove, + } = usePlacePlateReaderLid({ + onSettled: closeModal, }) - const handleCloseModal = (): void => { - if (setIsDismissedModal != null) { - setIsDismissedModal(true) - } - closeModal() - } - const modalProps: ModalProps = { type: 'error', title: t('estop_pressed'), - onClose: handleCloseModal, + onClose: closeModal, closeOnOutsideClick: false, childrenPadding: SPACING.spacing24, width: '47rem', @@ -210,20 +177,12 @@ function DesktopModal({ const handleClick: React.MouseEventHandler = (e): void => { e.preventDefault() setIsResuming(true) - acknowledgeEstopDisengage( - {}, - { - onSuccess: () => { - setShouldSeeLogicalDisengage() - placeReaderLid() - closeModal() - }, - onError: (error: any) => { - setIsResuming(false) - console.error(error) - }, - } - ) + setIsWaitingForResumeOperation() + acknowledgeEstopDisengage(null) + handlePlaceReaderLid() + if (!isValidPlateReaderMove) { + closeModal() + } } return ( @@ -238,23 +197,14 @@ function DesktopModal({ - {isResuming || - isPlacing || - isWaitingForLogicalDisengage || - isWaitingForPlateReaderLidPlacement ? ( + {isResuming || isWaitingForResumeOperation ? ( ) : null} {t('resume_robot_operations')} diff --git a/app/src/organisms/EmergencyStop/EstopTakeover.tsx b/app/src/organisms/EmergencyStop/EstopTakeover.tsx index 716511df7c0..dbc0d38b024 100644 --- a/app/src/organisms/EmergencyStop/EstopTakeover.tsx +++ b/app/src/organisms/EmergencyStop/EstopTakeover.tsx @@ -4,15 +4,10 @@ import { useEstopQuery } from '@opentrons/react-api-client' import { EstopPressedModal } from './EstopPressedModal' import { EstopMissingModal } from './EstopMissingModal' -import { useEstopContext } from './hooks' import { useIsUnboxingFlowOngoing } from '/app/redux-resources/config' import { getLocalRobot } from '/app/redux/discovery' -import { - PHYSICALLY_ENGAGED, - LOGICALLY_ENGAGED, - NOT_PRESENT, - DISENGAGED, -} from './constants' +import { PHYSICALLY_ENGAGED, NOT_PRESENT, DISENGAGED } from './constants' +import { EstopState } from '@opentrons/api-client' const ESTOP_CURRENTLY_DISENGAGED_REFETCH_INTERVAL_MS = 10000 const ESTOP_CURRENTLY_ENGAGED_REFETCH_INTERVAL_MS = 1000 @@ -22,78 +17,60 @@ interface EstopTakeoverProps { } export function EstopTakeover({ robotName }: EstopTakeoverProps): JSX.Element { - const [estopEngaged, setEstopEngaged] = useState(false) + const [isDismissedModal, setIsDismissedModal] = useState(false) const [ - isWaitingForLogicalDisengage, - setIsWaitingForLogicalDisengage, + isWaitingForResumeOperation, + setIsWatingForResumeOperation, ] = useState(false) - const [ - isWaitingForPlateReaderLidPlacement, - setisWaitingForPlateReaderLidPlacement, - ] = useState(false) - const { data: estopStatus } = useEstopQuery({ - refetchInterval: estopEngaged + + const [estopState, setEstopState] = useState(DISENGAGED) + const [showEmergencyStopModal, setShowEmergencyStopModal] = useState( + false + ) + + // TODO: (ba, 2024-10-24): Use notifications instead of polling + useEstopQuery({ + refetchInterval: showEmergencyStopModal ? ESTOP_CURRENTLY_ENGAGED_REFETCH_INTERVAL_MS : ESTOP_CURRENTLY_DISENGAGED_REFETCH_INTERVAL_MS, onSuccess: response => { - setEstopEngaged( - [PHYSICALLY_ENGAGED || LOGICALLY_ENGAGED].includes( - response?.data.status - ) + setEstopState(response?.data.status) + setShowEmergencyStopModal( + response.data.status !== DISENGAGED || isWaitingForResumeOperation ) - setIsWaitingForLogicalDisengage(false) }, }) - const { - isEmergencyStopModalDismissed, - setIsEmergencyStopModalDismissed, - } = useEstopContext() const isUnboxingFlowOngoing = useIsUnboxingFlowOngoing() const closeModal = (): void => { - if (estopStatus?.data.status === DISENGAGED) { - setIsEmergencyStopModalDismissed(false) - } + setIsWatingForResumeOperation(false) } const localRobot = useSelector(getLocalRobot) const localRobotName = localRobot?.name ?? 'no name' const TargetEstopModal = (): JSX.Element | null => { - switch (estopStatus?.data.status) { - case PHYSICALLY_ENGAGED: - case LOGICALLY_ENGAGED: - return ( - { - setIsWaitingForLogicalDisengage(true) - }} - /> - ) - case NOT_PRESENT: - return ( - - ) - default: - return null - } + return estopState === NOT_PRESENT ? ( + + ) : estopState !== DISENGAGED || isWaitingForResumeOperation ? ( + { + setIsWatingForResumeOperation(true) + }} + /> + ) : null } return ( <> - {estopStatus?.data.status !== DISENGAGED && !isUnboxingFlowOngoing ? ( + {showEmergencyStopModal && !isUnboxingFlowOngoing ? ( ) : null} diff --git a/app/src/resources/modules/hooks/usePlacePlateReaderLid.ts b/app/src/resources/modules/hooks/usePlacePlateReaderLid.ts index 721f4fe4a97..532ce54b612 100644 --- a/app/src/resources/modules/hooks/usePlacePlateReaderLid.ts +++ b/app/src/resources/modules/hooks/usePlacePlateReaderLid.ts @@ -10,7 +10,8 @@ import { useRobotControlCommands } from '/app/resources/maintenance_runs' interface UsePlacePlateReaderLidResult { handlePlaceReaderLid: () => Promise - isPlacing: boolean + isExecuting: boolean + isValidPlateReaderMove: boolean } type UsePlacePlateReaderLidProps = Pick< @@ -55,7 +56,11 @@ export function usePlacePlateReaderLid( } } - return { handlePlaceReaderLid, isPlacing: isExecuting } + return { + handlePlaceReaderLid, + isExecuting: isExecuting, + isValidPlateReaderMove, + } } const buildLoadModuleCommand = (location: ModuleLocation): CreateCommand => {