Skip to content

Commit

Permalink
feat(app): make protocol runs from history clickable
Browse files Browse the repository at this point in the history
closes #10502
  • Loading branch information
jerader committed May 31, 2022
1 parent 1c051fe commit 6965cae
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 34 deletions.
82 changes: 65 additions & 17 deletions app/src/organisms/Devices/HistoricalProtocolRun.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { css } from 'styled-components'
import { useHistory } from 'react-router-dom'
import { useSelector } from 'react-redux'
import {
Flex,
Box,
Expand All @@ -11,16 +14,24 @@ import {
BORDERS,
} from '@opentrons/components'
import { StyledText } from '../../atoms/text'
import { getStoredProtocols } from '../../redux/protocol-storage'
import { formatInterval } from '../RunTimeControl/utils'
import { formatTimestamp } from './utils'
import { HistoricalProtocolRunOverflowMenu as OverflowMenu } from './HistoricalProtocolRunOverflowMenu'
import { HistoricalProtocolRunOffsetDrawer as OffsetDrawer } from './HistoricalProtocolRunOffsetDrawer'
import type { RunData } from '@opentrons/api-client'
import type { State } from '../../redux/types'

const EMPTY_TIMESTAMP = '--:--:--'

const CLICK_STYLE = css`
cursor: pointer;
overflow-wrap: anywhere;
`

interface HistoricalProtocolRunProps {
run: RunData
protocolKey?: string
protocolName: string
robotName: string
robotIsBusy: boolean
Expand All @@ -31,8 +42,12 @@ export function HistoricalProtocolRun(
props: HistoricalProtocolRunProps
): JSX.Element | null {
const { t } = useTranslation('run_details')
const { run, protocolName, robotIsBusy, robotName } = props
const { run, protocolName, robotIsBusy, robotName, protocolKey, key } = props
const history = useHistory()
const [offsetDrawerOpen, setOffsetDrawerOpen] = React.useState(false)
const storedProtocols = useSelector((state: State) =>
getStoredProtocols(state)
)
const runStatus = run.status
const runDisplayName = formatTimestamp(run.createdAt)
let duration = EMPTY_TIMESTAMP
Expand All @@ -43,6 +58,11 @@ export function HistoricalProtocolRun(
duration = formatInterval(run.createdAt, new Date().toString())
}
}
const protocolKeys = storedProtocols.map(({ protocolKey }) => protocolKey)
const protocolKeyInStoredKeys = Object.values(protocolKeys).find(
key => key === protocolKey
)

return (
<>
<Flex
Expand All @@ -64,22 +84,50 @@ export function HistoricalProtocolRun(
marginRight={SPACING.spacing3}
/>
</Box>
<StyledText
as="p"
width="25%"
data-testid={`RecentProtocolRuns_Run_${props.key}`}
>
{runDisplayName}
</StyledText>
<StyledText
as="p"
width="35%"
css={{ 'overflow-wrap': 'anywhere' }}
paddingRight={SPACING.spacing3}
data-testid={`RecentProtocolRuns_Protocol_${props.key}`}
>
{protocolName}
</StyledText>
{protocolKeyInStoredKeys != null ? (
<>
<StyledText
as="p"
width="25%"
data-testid={`RecentProtocolRuns_Run_${key}`}
onClick={() =>
history.push(
`${robotName}/protocol-runs/${run.id}/protocolRunDetailsTab?`
)
}
css={CLICK_STYLE}
>
{runDisplayName}
</StyledText>
<StyledText
as="p"
width="35%"
data-testid={`RecentProtocolRuns_Protocol_${props.key}`}
onClick={() => history.push(`/protocols/${protocolKey}`)}
css={CLICK_STYLE}
>
{protocolName}
</StyledText>
</>
) : (
<>
<StyledText
as="p"
width="25%"
data-testid={`RecentProtocolRuns_Run_${key}`}
>
{runDisplayName}
</StyledText>
<StyledText
as="p"
width="35%"
data-testid={`RecentProtocolRuns_Protocol_${props.key}`}
css={{ 'overflow-wrap': 'anywhere' }}
>
{protocolName}
</StyledText>
</>
)}
<StyledText
as="p"
width="20%"
Expand Down
3 changes: 3 additions & 0 deletions app/src/organisms/Devices/RecentProtocolRuns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export function RecentProtocolRuns({
>
{t('run')}
</StyledText>

<StyledText
as="label"
width="35%"
Expand All @@ -79,6 +80,7 @@ export function RecentProtocolRuns({
>
{t('protocol')}
</StyledText>

<StyledText
as="label"
width="20%"
Expand Down Expand Up @@ -117,6 +119,7 @@ export function RecentProtocolRuns({
<HistoricalProtocolRun
run={run}
protocolName={protocolName}
protocolKey={protocol?.key}
robotName={robotName}
robotIsBusy={robotIsBusy}
key={index}
Expand Down
82 changes: 65 additions & 17 deletions app/src/organisms/Devices/__tests__/HistoricalProtocolRun.test.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,105 @@
import * as React from 'react'
import { fireEvent } from '@testing-library/react'
import { renderWithProviders } from '@opentrons/components'
import { i18n } from '../../../i18n'
import { getStoredProtocols } from '../../../redux/protocol-storage'
import { storedProtocolData as storedProtocolDataFixture } from '../../../redux/protocol-storage/__fixtures__'
import { useRunStatus } from '../../RunTimeControl/hooks'
import { HistoricalProtocolRun } from '../HistoricalProtocolRun'
import { HistoricalProtocolRunOverflowMenu } from '../HistoricalProtocolRunOverflowMenu'
import type { RunStatus, RunData } from '@opentrons/api-client'

const mockPush = jest.fn()

jest.mock('../../../redux/protocol-storage')
jest.mock('../../RunTimeControl/hooks')
jest.mock('../HistoricalProtocolRunOverflowMenu')
jest.mock('react-router-dom', () => {
const reactRouterDom = jest.requireActual('react-router-dom')
return {
...reactRouterDom,
useHistory: () => ({ push: mockPush } as any),
}
})

const mockUseRunStatus = useRunStatus as jest.MockedFunction<
typeof useRunStatus
>
const mockHistoricalProtocolRunOverflowMenu = HistoricalProtocolRunOverflowMenu as jest.MockedFunction<
typeof HistoricalProtocolRunOverflowMenu
>
const mockGetStoredProtocols = getStoredProtocols as jest.MockedFunction<
typeof getStoredProtocols
>

const run = {
createdAt: '2022-05-04T18:24:40.833862+00:00',
current: false,
id: 'test_id',
protocolId: 'test_protocol_id',
status: 'succeeded' as RunStatus,
} as RunData
const render = () => {
return renderWithProviders(
<HistoricalProtocolRun
robotName="otie"
protocolName="my protocol"
robotIsBusy={false}
run={run}
key={1}
/>,
{
i18nInstance: i18n,
}
)

const render = (props: React.ComponentProps<typeof HistoricalProtocolRun>) => {
return renderWithProviders(<HistoricalProtocolRun {...props} />, {
i18nInstance: i18n,
})[0]
}

describe('RecentProtocolRuns', () => {
let props: React.ComponentProps<typeof HistoricalProtocolRun>

beforeEach(() => {
props = {
robotName: 'otie',
protocolName: 'my protocol',
protocolKey: 'protocolKeyStub',
robotIsBusy: false,
run: run,
key: 1,
}
mockHistoricalProtocolRunOverflowMenu.mockReturnValue(
<div>mock HistoricalProtocolRunOverflowMenu</div>
)
mockUseRunStatus.mockReturnValue('succeeded')
mockGetStoredProtocols.mockReturnValue([storedProtocolDataFixture])
})
afterEach(() => {
jest.resetAllMocks()
})
it('renders the correct information derived from run and protocol', () => {
mockUseRunStatus.mockReturnValue('succeeded')
const [{ getByText }] = render()

getByText('my protocol')
const { getByText } = render(props)
const protocolBtn = getByText('my protocol')
getByText('Completed')
getByText('mock HistoricalProtocolRunOverflowMenu')
const runBtn = getByText('05/04/2022 14:24:40')
fireEvent.click(protocolBtn)
expect(mockPush).toHaveBeenCalledWith('/protocols/protocolKeyStub')
fireEvent.click(runBtn)
expect(mockPush).toHaveBeenCalledWith(
'otie/protocol-runs/test_id/protocolRunDetailsTab?'
)
})
it('renders buttons that are not clickable when the protocol was deleted from the app directory', () => {
mockGetStoredProtocols.mockReturnValue([storedProtocolDataFixture])
props = {
robotName: 'otie',
protocolName: 'my protocol',
protocolKey: '12345',
robotIsBusy: false,
run: run,
key: 1,
}
const { getByText } = render(props)
const protocolBtn = getByText('my protocol')
getByText('Completed')
getByText('mock HistoricalProtocolRunOverflowMenu')
const runBtn = getByText('05/04/2022 14:24:40')
fireEvent.click(protocolBtn)
expect(mockPush).not.toHaveBeenCalledWith('/protocols/12345')
fireEvent.click(runBtn)
expect(mockPush).not.toHaveBeenCalledWith(
'otie/protocol-runs/test_id/protocolRunDetailsTab?'
)
})
})

0 comments on commit 6965cae

Please sign in to comment.