import * as React from 'react' import styled, { css } from 'styled-components' import { useTranslation } from 'react-i18next' import { Flex, Icon, JUSTIFY_CENTER, ALIGN_CENTER, SPACING, COLORS, BORDERS, DIRECTION_COLUMN, POSITION_ABSOLUTE, TYPOGRAPHY, OVERFLOW_WRAP_BREAK_WORD, DISPLAY_FLEX, JUSTIFY_SPACE_BETWEEN, TEXT_ALIGN_CENTER, StyledText, JUSTIFY_END, PrimaryButton, ALIGN_FLEX_END, SecondaryButton, } from '@opentrons/components' import { useErrorName } from './hooks' import { getErrorKind } from './utils' import { LargeButton } from '../../atoms/buttons' import { RECOVERY_MAP } from './constants' import { RecoveryInterventionModal, RecoverySingleColumnContentDesktop, StepInfo, } from './shared' import type { RobotType } from '@opentrons/shared-data' import type { ErrorRecoveryFlowsProps } from '.' import type { ERUtilsResults } from './hooks' import { useHost } from '@opentrons/react-api-client' export function useRunPausedSplash( isOnDevice: boolean, showERWizard: boolean ): boolean { // Don't show the splash when desktop ER wizard is active. return isOnDevice && !showERWizard } type RunPausedSplashProps = ERUtilsResults & { isOnDevice: boolean failedCommand: ErrorRecoveryFlowsProps['failedCommand'] protocolAnalysis: ErrorRecoveryFlowsProps['protocolAnalysis'] robotType: RobotType toggleERWiz: (launchER: boolean) => Promise } export function RunPausedSplash( props: RunPausedSplashProps ): JSX.Element | null { const { toggleERWiz, routeUpdateActions, failedCommand } = props const { t } = useTranslation('error_recovery') const errorKind = getErrorKind(failedCommand?.error?.errorType) const title = useErrorName(errorKind) const host = useHost() const { proceedToRouteAndStep } = routeUpdateActions const buildTitleHeadingDesktop = (): JSX.Element => { return ( {t('error_on_robot', { robot: host?.robotName ?? '' })} ) } // Do not launch error recovery, but do utilize the wizard's cancel route. const onCancelClick = (): Promise => { return toggleERWiz(false).then(() => proceedToRouteAndStep(RECOVERY_MAP.CANCEL_RUN.ROUTE) ) } const onLaunchERClick = (): Promise => toggleERWiz(true) // TODO(jh 05-22-24): The hardcoded Z-indexing is non-ideal but must be done to keep the splash page above // several components in the RunningProtocol page. Investigate why these components have seemingly arbitrary zIndex values // and devise a better solution to layering modals. // TODO(jh 06-07-24): Although unlikely, it's possible that the server doesn't return a failedCommand. Need to handle // this here or within ER flows. // TODO(jh 06-18-24): Instead of passing stepCount internally, we probably want to // pass it in as a prop to ErrorRecoveryFlows to ameliorate blippy "step = ? -> step = 24" behavior. if (props.isOnDevice) { return ( {title} ) } else { return ( {title} {t('cancel_run')} {t('launch_recovery_mode')} ) } } const SplashHeader = styled.h1` font-weight: ${TYPOGRAPHY.fontWeightBold}; text-align: ${TYPOGRAPHY.textAlignCenter}; font-size: ${TYPOGRAPHY.fontSize80}; line-height: ${TYPOGRAPHY.lineHeight96}; color: ${COLORS.white}; ` const SplashFrame = styled(Flex)` width: 100%; height: 100%; flex-direction: ${DIRECTION_COLUMN}; justify-content: ${JUSTIFY_CENTER}; align-items: ${ALIGN_CENTER}; grid-gap: ${SPACING.spacing40}; padding: ${SPACING.spacing24}; padding-bottom: 0px; ` const SHARED_BUTTON_STYLE_ODD = css` width: 29rem; height: 13.5rem; ` const PRIMARY_BTN_STYLES_DESKTOP = css` background-color: ${COLORS.red50}; color: ${COLORS.white}; &:active, &:focus, &:hover { background-color: ${COLORS.red55}; } `