Skip to content

Commit

Permalink
fix(app): Fix RunFailed modal WhiteScreen and plus alpha (#13312)
Browse files Browse the repository at this point in the history
* fix(app): fix run failed modal for desktop white screen issue and add utc label to timestamp
  • Loading branch information
koji authored Aug 23, 2023
1 parent 7699771 commit f359e83
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export function ProtocolRunHeader({
const [showRunFailedModal, setShowRunFailedModal] = React.useState(false)
const { data: runRecord } = useRunQuery(runId, { staleTime: Infinity })
const highestPriorityError =
runRecord?.data?.errors != null
runRecord?.data.errors?.[0] != null
? getHighestPriorityError(runRecord?.data?.errors)
: undefined
const { data: estopStatus, error: estopError } = useEstopQuery({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const mockGripperDataWithCalData: GripperData = {
calibratedOffset: {
offset: { x: 1, y: 2, z: 1 },
source: 'mockSource',
last_modified: 'mockLastModified',
last_modified: '2023-08-15T20:25',
},
},
firmwareVersion: '12',
Expand Down Expand Up @@ -97,7 +97,7 @@ describe('InstrumentInfo', () => {
}
const { getByText, getByRole } = render(props)
getByText('last calibrated')
getByText('mockLastModified')
getByText('8/15/23 20:25 UTC')
getByText('firmware version')
getByText('12')
getByText('serial number')
Expand All @@ -114,7 +114,7 @@ describe('InstrumentInfo', () => {
}
const { getByText, getByRole } = render(props)
getByText('last calibrated')
getByText('08/25/2020 20:25:00')
getByText('8/25/20 20:25 UTC')
getByText('serial number')
getByText('abc')
getByRole('button', { name: 'MediumButton_secondary' }).click()
Expand Down
4 changes: 2 additions & 2 deletions app/src/organisms/InstrumentInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { StyledText } from '../../atoms/text'
import { MediumButton } from '../../atoms/buttons'
import { FLOWS } from '../PipetteWizardFlows/constants'
import { useMaintenanceRunTakeover } from '../TakeoverModal'
import { formatTimestamp } from '../Devices/utils'
import { GRIPPER_FLOW_TYPES } from '../GripperWizardFlows/constants'
import { formatTimeWithUtcLabel } from '../../resources/runs/utils'

import type { InstrumentData } from '@opentrons/api-client'
import type { PipetteMount } from '@opentrons/shared-data'
Expand Down Expand Up @@ -128,7 +128,7 @@ export const InstrumentInfo = (props: InstrumentInfoProps): JSX.Element => {
label={t('last_calibrated')}
value={
instrument.data.calibratedOffset?.last_modified != null
? formatTimestamp(
? formatTimeWithUtcLabel(
instrument.data.calibratedOffset?.last_modified
)
: i18n.format(t('no_cal_data'), 'capitalize')
Expand Down
4 changes: 2 additions & 2 deletions app/src/organisms/InstrumentMountItem/LabeledMount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface LabeledMountProps {
export function LabeledMount(props: LabeledMountProps): JSX.Element {
const { t } = useTranslation('device_details')
const { mount, instrumentName, handleClick } = props
const ninetySixDislayName = 'Flex 96-Channel 1000 μL'
const ninetySixDisplayName = 'Flex 96-Channel 1000 μL'

return (
<MountButton onClick={handleClick} isAttached={instrumentName != null}>
Expand All @@ -62,7 +62,7 @@ export function LabeledMount(props: LabeledMountProps): JSX.Element {
fontSize={TYPOGRAPHY.fontSize28}
width="15.625rem"
>
{instrumentName === ninetySixDislayName
{instrumentName === ninetySixDisplayName
? t('left_right')
: t('mount', { side: mount })}
</StyledText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as React from 'react'
import { when, resetAllWhenMocks } from 'jest-when'
import { Route } from 'react-router'
import { MemoryRouter } from 'react-router-dom'
import { format } from 'date-fns'
import '@testing-library/jest-dom'
import { renderWithProviders } from '@opentrons/components'
import {
Expand All @@ -21,6 +20,7 @@ import { i18n } from '../../../../i18n'
import { useMissingHardwareText } from '../../../../organisms/OnDeviceDisplay/RobotDashboard/hooks'
import { useOffsetCandidatesForAnalysis } from '../../../../organisms/ApplyHistoricOffsets/hooks/useOffsetCandidatesForAnalysis'
import { useMissingProtocolHardware } from '../../../Protocols/hooks'
import { formatTimeWithUtcLabel } from '../../../../resources/runs/utils'
import { ProtocolDetails } from '..'
import { Deck } from '../Deck'
import { Hardware } from '../Hardware'
Expand Down Expand Up @@ -171,9 +171,8 @@ describe('ODDProtocolDetails', () => {
it('renders the protocol date added', () => {
const [{ getByText }] = render()
getByText(
`Date Added: ${format(
new Date('2022-05-03T21:36:12.494778+00:00'),
'MM/dd/yy k:mm'
`Date Added: ${formatTimeWithUtcLabel(
'2022-05-03T21:36:12.494778+00:00'
)}`
)
})
Expand Down
6 changes: 2 additions & 4 deletions app/src/pages/OnDeviceDisplay/ProtocolDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useQueryClient } from 'react-query'
import { deleteProtocol, deleteRun, getProtocol } from '@opentrons/api-client'
import { useDispatch, useSelector } from 'react-redux'
import { useHistory, useParams } from 'react-router-dom'
import { format } from 'date-fns'
import {
ALIGN_CENTER,
BORDERS,
Expand Down Expand Up @@ -49,6 +48,7 @@ import { Deck } from './Deck'
import { Hardware } from './Hardware'
import { Labware } from './Labware'
import { Liquids } from './Liquids'
import { formatTimeWithUtcLabel } from '../../../resources/runs/utils'

import type { Protocol } from '@opentrons/api-client'
import type { ModalHeaderBaseProps } from '../../../molecules/Modal/types'
Expand Down Expand Up @@ -224,9 +224,7 @@ const Summary = ({ author, description, date }: SummaryProps): JSX.Element => {
padding={`${SPACING.spacing8} ${SPACING.spacing12}`}
>
<StyledText as="p">{`${t('protocol_info:date_added')}: ${
date != null
? format(new Date(date), 'MM/dd/yy k:mm')
: t('shared:no_data')
date != null ? formatTimeWithUtcLabel(date) : t('shared:no_data')
}`}</StyledText>
</Flex>
</Flex>
Expand Down
30 changes: 19 additions & 11 deletions app/src/pages/OnDeviceDisplay/RunSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
OVERFLOW_HIDDEN,
POSITION_ABSOLUTE,
POSITION_RELATIVE,
WRAP,
SPACING,
TYPOGRAPHY,
} from '@opentrons/components'
Expand Down Expand Up @@ -51,11 +52,12 @@ import {
ANALYTICS_PROTOCOL_RUN_AGAIN,
ANALYTICS_PROTOCOL_RUN_FINISH,
} from '../../redux/analytics'
import { getLocalRobot } from '../../redux/discovery'
import { RunFailedModal } from '../../organisms/OnDeviceDisplay/RunningProtocol'
import { formatTimeWithUtcLabel } from '../../resources/runs/utils'

import type { Run } from '@opentrons/api-client'
import type { OnDeviceRouteParams } from '../../App/types'
import { getLocalRobot } from '../../redux/discovery'

export function RunSummary(): JSX.Element {
const { runId } = useParams<OnDeviceRouteParams>()
Expand Down Expand Up @@ -204,10 +206,10 @@ export function RunSummary(): JSX.Element {
<SummaryHeader>{headerText}</SummaryHeader>
</Flex>
<ProtocolName>{protocolName}</ProtocolName>
<Flex gridGap={SPACING.spacing8}>
<SummaryDatum>{`${t(
'run'
)}: ${createdAtTimestamp}`}</SummaryDatum>
<Flex gridGap={SPACING.spacing8} flexWrap={WRAP}>
<SummaryDatum>
{`${t('run')}: ${formatTimeWithUtcLabel(createdAtTimestamp)}`}
</SummaryDatum>
<SummaryDatum>
{`${t('duration')}: `}
<RunTimer
Expand All @@ -220,12 +222,18 @@ export function RunSummary(): JSX.Element {
style={DURATION_TEXT_STYLE}
/>
</SummaryDatum>
<SummaryDatum>{`${t(
'start'
)}: ${startedAtTimestamp}`}</SummaryDatum>
<SummaryDatum>{`${t(
'end'
)}: ${completedAtTimestamp}`}</SummaryDatum>
<SummaryDatum>
{`${t('start')}: ${formatTimeWithUtcLabel(
startedAtTimestamp,
true
)}`}
</SummaryDatum>
<SummaryDatum>
{`${t('end')}: ${formatTimeWithUtcLabel(
completedAtTimestamp,
true
)}`}
</SummaryDatum>
</Flex>
</Flex>
<Flex alignSelf={ALIGN_STRETCH} gridGap={SPACING.spacing16}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { useInstrumentsQuery } from '@opentrons/react-api-client'
import { i18n } from '../../../i18n'
import { ChoosePipette } from '../../../organisms/PipetteWizardFlows/ChoosePipette'
import { Navigation } from '../../../organisms/Navigation'
import { formatTimestamp } from '../../../organisms/Devices/utils'
import { PipetteWizardFlows } from '../../../organisms/PipetteWizardFlows'
import { GripperWizardFlows } from '../../../organisms/GripperWizardFlows'
import { InstrumentsDashboard } from '../InstrumentsDashboard'
import { formatTimeWithUtcLabel } from '../../../resources/runs/utils'
import { InstrumentDetail } from '../InstrumentDetail'

jest.mock('@opentrons/react-api-client')
Expand Down Expand Up @@ -140,7 +140,9 @@ describe('InstrumentsDashboard', () => {
getByText('serial number')
getByText(mockLeftPipetteData.serialNumber)
getByText(
formatTimestamp(mockLeftPipetteData.data.calibratedOffset.last_modified)
formatTimeWithUtcLabel(
mockLeftPipetteData.data.calibratedOffset.last_modified
)
)
})
it('should route to right mount detail when instrument attached and clicked', async () => {
Expand All @@ -149,7 +151,9 @@ describe('InstrumentsDashboard', () => {
getByText('serial number')
getByText(mockRightPipetteData.serialNumber)
getByText(
formatTimestamp(mockRightPipetteData.data.calibratedOffset.last_modified)
formatTimeWithUtcLabel(
mockRightPipetteData.data.calibratedOffset.last_modified
)
)
})
it('should route to extension mount detail when instrument attached and clicked', async () => {
Expand Down
5 changes: 3 additions & 2 deletions app/src/pages/ProtocolDashboard/PinnedProtocol.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { useHistory } from 'react-router-dom'
import { format, formatDistance } from 'date-fns'
import { formatDistance } from 'date-fns'
import styled, { css } from 'styled-components'

import {
Expand All @@ -19,6 +19,7 @@ import {

import { StyledText } from '../../atoms/text'
import { LongPressModal } from './LongPressModal'
import { formatTimeWithUtcLabel } from '../../resources/runs/utils'

import type { UseLongPressResult } from '@opentrons/components'
import type { ProtocolResource } from '@opentrons/shared-data'
Expand Down Expand Up @@ -131,7 +132,7 @@ export function PinnedProtocol(props: {
: t('no_history')}
</StyledText>
<StyledText as="p">
{format(new Date(protocol.createdAt), 'M/d/yy HH:mm')}
{formatTimeWithUtcLabel(protocol.createdAt)}
</StyledText>
</Flex>
{longpress.isLongPressed && (
Expand Down
12 changes: 6 additions & 6 deletions app/src/pages/ProtocolDashboard/ProtocolCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react'
import { useHistory } from 'react-router-dom'
import { Trans, useTranslation } from 'react-i18next'
import { useQueryClient } from 'react-query'
import { format, formatDistance } from 'date-fns'
import { formatDistance } from 'date-fns'
import last from 'lodash/last'
import { css } from 'styled-components'

Expand All @@ -15,7 +15,6 @@ import {
DIRECTION_ROW,
Flex,
Icon,
JUSTIFY_CENTER,
SPACING,
TYPOGRAPHY,
useLongPress,
Expand All @@ -27,6 +26,7 @@ import { StyledText } from '../../atoms/text'
import { SmallButton } from '../../atoms/buttons'
import { Modal } from '../../molecules/Modal'
import { LongPressModal } from './LongPressModal'
import { formatTimeWithUtcLabel } from '../../resources/runs/utils'

import type { UseLongPressResult } from '@opentrons/components'
import type { ProtocolResource } from '@opentrons/shared-data'
Expand Down Expand Up @@ -149,7 +149,7 @@ export function ProtocolCard(props: {
css={PUSHED_STATE_STYLE}
>
<Flex
width="30.75rem"
width="28.9375rem"
overflowWrap="anywhere"
flexDirection={DIRECTION_COLUMN}
gridGap={SPACING.spacing8}
Expand All @@ -174,7 +174,7 @@ export function ProtocolCard(props: {
{protocolName}
</StyledText>
</Flex>
<Flex width="9.25rem" justifyContent={JUSTIFY_CENTER}>
<Flex width="9.25rem">
<StyledText as="p" color={COLORS.darkBlack70}>
{lastRun != null
? formatDistance(new Date(lastRun), new Date(), {
Expand All @@ -183,9 +183,9 @@ export function ProtocolCard(props: {
: t('no_history')}
</StyledText>
</Flex>
<Flex width="10rem">
<Flex width="12.5rem" whiteSpace="nowrap">
<StyledText as="p" color={COLORS.darkBlack70}>
{format(new Date(protocol.createdAt), 'M/d/yy HH:mm')}
{formatTimeWithUtcLabel(protocol.createdAt)}
</StyledText>
{longpress.isLongPressed && !isFailedAnalysis && (
<LongPressModal
Expand Down
5 changes: 2 additions & 3 deletions app/src/pages/ProtocolDashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
DIRECTION_COLUMN,
DIRECTION_ROW,
Flex,
JUSTIFY_CENTER,
SPACING,
POSITION_STICKY,
POSITION_STATIC,
Expand Down Expand Up @@ -210,7 +209,7 @@ export function ProtocolDashboard(): JSX.Element {
onClick={handleSortByName}
/>
</Flex>
<Flex justifyContent={JUSTIFY_CENTER} width="12rem">
<Flex width="12rem">
<SmallButton
buttonText={t('last_run')}
buttonType={
Expand All @@ -229,7 +228,7 @@ export function ProtocolDashboard(): JSX.Element {
onClick={handleSortByLastRun}
/>
</Flex>
<Flex justifyContent={JUSTIFY_CENTER} width="14.625rem">
<Flex width="14.625rem">
<SmallButton
buttonText={t('date_added')}
buttonType={
Expand Down
17 changes: 17 additions & 0 deletions app/src/resources/runs/__tests__/util.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { formatTimeWithUtcLabel } from '../utils'

describe('formatTimeWithUtc', () => {
it('return formatted time with UTC', () => {
const result = formatTimeWithUtcLabel('2023-08-20T20:25')
expect(result).toEqual('8/20/23 20:25 UTC')
})
it('return formatted time with UTC without T', () => {
const result = formatTimeWithUtcLabel('08/22/2023 21:35:04')
expect(result).toEqual('8/22/23 21:35 UTC')
})

it('return formatted time with UTC only hh:mm', () => {
const result = formatTimeWithUtcLabel('21:35:04', true)
expect(result).toEqual('21:35:04 UTC')
})
})
13 changes: 13 additions & 0 deletions app/src/resources/runs/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react'
import { format } from 'date-fns'
import type { CommandData } from '@opentrons/api-client'
import type { CreateCommand } from '@opentrons/shared-data'
import type { CreateMaintenanceCommand, CreateRunCommand } from './hooks'
Expand Down Expand Up @@ -85,3 +86,15 @@ export const chainMaintenanceCommandsRecursive = (
return Promise.reject(error)
})
}

export const formatTimeWithUtcLabel = (
time: string,
noFormat?: boolean
): string => {
const UTC_LABEL = 'UTC'
const TIME_FORMAT = 'M/d/yy HH:mm'

return noFormat
? `${time} ${UTC_LABEL}`
: `${format(new Date(time), TIME_FORMAT)} ${UTC_LABEL}`
}

0 comments on commit f359e83

Please sign in to comment.