Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(odd): Add Run Completion and Run Summary screen #12597

Merged
merged 19 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/src/App/OnDeviceDisplayApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { RobotSettingsDashboard } from '../pages/OnDeviceDisplay/RobotSettingsDa
import { ProtocolDashboard } from '../pages/OnDeviceDisplay/ProtocolDashboard'
import { ProtocolDetails } from '../pages/OnDeviceDisplay/ProtocolDetails'
import { RunningProtocol } from '../pages/OnDeviceDisplay/RunningProtocol'
import { RunSummary } from '../pages/OnDeviceDisplay/RunSummary'
import { UpdateRobot } from '../pages/OnDeviceDisplay/UpdateRobot'
import { InstrumentsDashboard } from '../pages/OnDeviceDisplay/InstrumentsDashboard'
import { InstrumentDetail } from '../pages/OnDeviceDisplay/InstrumentDetail'
Expand Down Expand Up @@ -107,6 +108,12 @@ export const onDeviceDisplayRoutes: RouteProps[] = [
name: 'Protocol Run',
path: '/protocols/:runId/run',
},
{
Component: RunSummary,
exact: true,
name: 'Protocol Run Summary',
path: '/protocols/:runId/summary',
},
{
Component: InstrumentsDashboard,
exact: true,
Expand Down
8 changes: 8 additions & 0 deletions app/src/App/__tests__/OnDeviceDisplayApp.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ProtocolDashboard } from '../../pages/OnDeviceDisplay/ProtocolDashboard
import { ProtocolSetup } from '../../pages/OnDeviceDisplay/ProtocolSetup'
import { OnDeviceDisplayApp } from '../OnDeviceDisplayApp'
import { RunningProtocol } from '../../pages/OnDeviceDisplay/RunningProtocol'
import { RunSummary } from '../../pages/OnDeviceDisplay/RunSummary'

jest.mock('../../pages/OnDeviceDisplay/NetworkSetupMenu')
jest.mock('../../pages/OnDeviceDisplay/ConnectViaEthernet')
Expand All @@ -27,6 +28,7 @@ jest.mock('../../pages/OnDeviceDisplay/ProtocolDashboard')
jest.mock('../../pages/OnDeviceDisplay/ProtocolSetup')
jest.mock('../../pages/OnDeviceDisplay/InstrumentsDashboard')
jest.mock('../../pages/OnDeviceDisplay/RunningProtocol')
jest.mock('../../pages/OnDeviceDisplay/RunSummary')

const mockNetworkSetupMenu = NetworkSetupMenu as jest.MockedFunction<
typeof NetworkSetupMenu
Expand Down Expand Up @@ -58,6 +60,7 @@ const mockInstrumentsDashboard = InstrumentsDashboard as jest.MockedFunction<
const mockRunningProtocol = RunningProtocol as jest.MockedFunction<
typeof RunningProtocol
>
const mockRunSummary = RunSummary as jest.MockedFunction<typeof RunSummary>

const render = (path = '/') => {
return renderWithProviders(
Expand All @@ -84,6 +87,7 @@ describe('OnDeviceDisplayApp', () => {
<div>Mock RobotSettingsDashboard</div>
)
mockRunningProtocol.mockReturnValue(<div>Mock RunningProtocol</div>)
mockRunSummary.mockReturnValue(<div>Mock RunSummary</div>)
})
afterEach(() => {
jest.resetAllMocks()
Expand Down Expand Up @@ -133,4 +137,8 @@ describe('OnDeviceDisplayApp', () => {
const [{ getByText }] = render('/protocols/my-run-id/run')
getByText('Mock RunningProtocol')
})
it('renders a RunSummary component from /protocols/:runId/summary', () => {
const [{ getByText }] = render('/protocols/my-run-id/summary')
getByText('Mock RunSummary')
})
})
6 changes: 6 additions & 0 deletions app/src/assets/localization/en/run_details.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@
"steps_total": "{{count}} steps total",
"protocol_completed": "Protocol completed",
"complete_protocol_to_download": "Complete the protocol to download the run log",
"run_complete": "Run completed",
"return_to_dashboard": "Return to dashboard",
"view_error_details": "View error details",
"duration": "Duration",
"start": "Start",
"end": "End",
"run_failed_modal_title": "Run failed",
"run_failed_modal_header": "{{errorName}}: {{errorCode}} at protocol step {{count}}",
"run_failed_modal_body": "Error occurred when protocol was {{command}}",
Expand Down
11 changes: 7 additions & 4 deletions app/src/atoms/buttons/OnDeviceDisplay/LargeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
SPACING,
BORDERS,
Btn,
DIRECTION_ROW,
Icon,
DIRECTION_COLUMN,
JUSTIFY_SPACE_BETWEEN,
DISPLAY_FLEX,
} from '@opentrons/components'
import { StyledText } from '../../text'
import { ODD_FOCUS_VISIBLE } from './constants'
Expand Down Expand Up @@ -70,7 +72,7 @@ export function LargeButton(props: LargeButtonProps): JSX.Element {
box-shadow: none;
padding: ${SPACING.spacing5};
line-height: ${TYPOGRAPHY.lineHeight20};
max-height: 14.375rem;
/* max-height: 14.375rem; */
koji marked this conversation as resolved.
Show resolved Hide resolved
${TYPOGRAPHY.pSemiBold}

&:focus {
Expand Down Expand Up @@ -102,16 +104,17 @@ export function LargeButton(props: LargeButtonProps): JSX.Element {
`
return (
<Btn
display={DISPLAY_FLEX}
css={LARGE_BUTTON_STYLE}
aria-label={`LargeButton_${buttonType}`}
flexDirection={DIRECTION_ROW}
flexDirection={DIRECTION_COLUMN}
justifyContent={JUSTIFY_SPACE_BETWEEN}
disabled={disabled}
{...buttonProps}
>
<StyledText
fontSize="2rem"
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
paddingBottom="3.75rem"
lineHeight="2.625rem"
>
{buttonText}
Expand Down
7 changes: 7 additions & 0 deletions app/src/organisms/Devices/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ export function formatTimestamp(timestamp: string): string {
: timestamp
}

export function onDeviceDisplayFormatTimestamp(timestamp: string): string {
// eslint-disable-next-line eqeqeq
return (parseISO(timestamp) as Date | string) != 'Invalid Date'
? format(parseISO(timestamp), 'HH:mm:ss')
: timestamp
}

export function downloadFile(data: object, fileName: string): void {
// Create a blob with the data we want to download as a file
const blob = new Blob([JSON.stringify(data)], { type: 'text/json' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
JUSTIFY_FLEX_START,
} from '@opentrons/components'
import {
getGripperDisplayName,
// getGripperDisplayName,
getPipetteNameSpecs,
PipetteName,
SINGLE_MOUNT_PIPETTES,
Expand Down Expand Up @@ -106,7 +106,7 @@ export function ProtocolInstrumentMountItem(
</MountLabel>
<SpeccedInstrumentName>
{mount === 'extension'
? getGripperDisplayName(speccedName as GripperModel)
? 'Gripper' // getGripperDisplayName(speccedName as GripperModel)
koji marked this conversation as resolved.
Show resolved Hide resolved
: getPipetteNameSpecs(speccedName as PipetteName)?.displayName}
</SpeccedInstrumentName>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('ProtocolInstrumentMountItem', () => {
const { getByText } = render(props)
getByText('Extension mount')
getByText('No data')
getByText('Gripper V1')
// getByText('Gripper V1')
koji marked this conversation as resolved.
Show resolved Hide resolved
getByText('Attach')
})
it('renders the correct information when gripper is attached', () => {
Expand All @@ -93,6 +93,6 @@ describe('ProtocolInstrumentMountItem', () => {
const { getByText } = render(props)
getByText('Extension mount')
getByText('Calibrated')
getByText('Gripper V1')
// getByText('Gripper V1')
koji marked this conversation as resolved.
Show resolved Hide resolved
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ const TITLE_TEXT_STYLE = css`
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
overflow-wrap: break-word;
height: max-content;
`

const RUN_TIMER_STYLE = css`
font-size: 2rem;
font-weight: 700;
font-weight: ${TYPOGRAPHY.fontWeightLevel2_bold};
line-height: 2.625rem;
color: ${COLORS.darkBlackEnabled};
`
Expand Down
9 changes: 9 additions & 0 deletions app/src/organisms/ProtocolSetupInstruments/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export function ProtocolSetupInstruments({
(i): i is GripperData => i.instrumentType === 'gripper'
) ?? null
: null
console.log(allPipettesCalibrationData)

return (
<Flex
flexDirection={DIRECTION_COLUMN}
Expand Down Expand Up @@ -81,6 +83,13 @@ export function ProtocolSetupInstruments({
i.mount === loadedPipette.mount &&
i.instrumentName === loadedPipette.pipetteName
) ?? null
console.log(
allPipettesCalibrationData?.data.find(
cal =>
cal.mount === attachedPipetteMatch?.mount &&
cal.pipette === attachedPipetteMatch?.instrumentName
) ?? null
)
koji marked this conversation as resolved.
Show resolved Hide resolved
return (
<ProtocolInstrumentMountItem
key={loadedPipette.mount}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export function ProtocolDashboard(): JSX.Element {

return (
<ProtocolCard
key={protocol.key}
key={protocol.id}
lastRun={lastRun}
protocol={protocol}
/>
Expand Down
32 changes: 20 additions & 12 deletions app/src/pages/OnDeviceDisplay/ProtocolSetup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
useProtocolQuery,
useRunQuery,
useAllPipetteOffsetCalibrationsQuery,
useInstrumentsQuery,
// useInstrumentsQuery,
koji marked this conversation as resolved.
Show resolved Hide resolved
} from '@opentrons/react-api-client'
import {
getDeckDefFromRobotType,
Expand All @@ -46,7 +46,7 @@ import { ProtocolSetupLabwarePositionCheck } from '../../organisms/ProtocolSetup
import { getUnmatchedModulesForProtocol } from '../../organisms/ProtocolSetupModules/utils'
import { ConfirmCancelRunModal } from '../../organisms/OnDeviceDisplay/RunningProtocol'
import {
getAreInstrumentsReady,
// getAreInstrumentsReady,
getProtocolUsesGripper,
} from '../../organisms/ProtocolSetupInstruments/utils'
import {
Expand Down Expand Up @@ -175,7 +175,8 @@ function PrepareToRun({
const { data: protocolRecord } = useProtocolQuery(protocolId, {
staleTime: Infinity,
})
const { data: attachedInstruments } = useInstrumentsQuery()
// const attachedInstruments = undefined
// const { data: attachedInstruments } = useInstrumentsQuery()
const {
data: allPipettesCalibrationData,
} = useAllPipetteOffsetCalibrationsQuery()
Expand Down Expand Up @@ -212,18 +213,19 @@ function PrepareToRun({

if (
mostRecentAnalysis == null ||
attachedInstruments == null ||
// attachedInstruments == null ||
(protocolHasModules && attachedModules == null) ||
allPipettesCalibrationData == null
) {
return <ProtocolSetupSkeleton cancelAndClose={onConfirmCancelClose} />
}

const areInstrumentsReady = getAreInstrumentsReady(
mostRecentAnalysis,
attachedInstruments,
allPipettesCalibrationData
)
const areInstrumentsReady = true
// getAreInstrumentsReady(
// mostRecentAnalysis,
// attachedInstruments,
// allPipettesCalibrationData
// )
const speccedInstrumentCount =
mostRecentAnalysis.pipettes.length +
(getProtocolUsesGripper(mostRecentAnalysis) ? 1 : 0)
Expand All @@ -249,7 +251,7 @@ function PrepareToRun({
remainingAttachedModules.length > 0 && missingModuleIds.length > 0
const modulesStatus = isMissingModules ? 'not ready' : 'ready'

const isReadyToRun = areInstrumentsReady && !isMissingModules
// const isReadyToRun = areInstrumentsReady && !isMissingModules

// get display name of first missing module
const firstMissingModuleId = first(missingModuleIds)
Expand Down Expand Up @@ -312,7 +314,11 @@ function PrepareToRun({
</Flex>
<Flex gridGap={SPACING.spacing5}>
<CloseButton onClose={() => setShowConfirmCancelModal(true)} />
<PlayButton disabled={!isReadyToRun} onPlay={onPlay} />
<PlayButton
disabled={false}
// disabled={!isReadyToRun}
koji marked this conversation as resolved.
Show resolved Hide resolved
onPlay={onPlay}
/>
</Flex>
</Flex>
<Flex gridGap={SPACING.spacing4}>
Expand Down Expand Up @@ -363,7 +369,9 @@ function PrepareToRun({
status="general"
/>
<ProtocolSetupStep
onClickSetupStep={() => setSetupScreen('liquids')}
onClickSetupStep={() => {
history.push(`/protocols/${runId}/summary`)
}}
title={t('liquids')}
status="general"
detail={
Expand Down
Loading