Skip to content

Commit 57881f9

Browse files
committed
add deck and timeline sections
1 parent 430e4ef commit 57881f9

File tree

11 files changed

+906
-109
lines changed

11 files changed

+906
-109
lines changed

app/src/organisms/Desktop/ProtocolDetails/AnnotatedSteps.tsx

Lines changed: 38 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import {
99
CommandText,
1010
CURSOR_POINTER,
1111
DIRECTION_COLUMN,
12+
Divider,
1213
Flex,
1314
getLabwareDefinitionsFromCommands,
1415
Icon,
1516
LegacyStyledText,
1617
OVERFLOW_AUTO,
1718
SPACING,
19+
StyledText,
1820
TYPOGRAPHY,
1921
} from '@opentrons/components'
2022
import { FLEX_ROBOT_TYPE } from '@opentrons/shared-data'
@@ -79,13 +81,13 @@ export function AnnotatedSteps(props: AnnotatedStepsProps): JSX.Element {
7981
<Flex
8082
css={HIDE_SCROLLBAR}
8183
flexDirection={DIRECTION_COLUMN}
82-
maxHeight="82vh"
83-
flex="1 1 0"
84+
// maxHeight="82vh"
85+
// flex="1 1 0"
8486
overflowY={OVERFLOW_AUTO}
8587
>
8688
<Flex
8789
flexDirection={DIRECTION_COLUMN}
88-
marginY={SPACING.spacing16}
90+
// marginY={SPACING.spacing16}
8991
gridGap={SPACING.spacing4}
9092
>
9193
{groupedCommandsHighlightedInfo != null &&
@@ -94,19 +96,16 @@ export function AnnotatedSteps(props: AnnotatedStepsProps): JSX.Element {
9496
'annotationIndex' in c ? (
9597
<AnnotatedGroup
9698
key={`group-${i}`}
97-
stepNumber={(i + 1).toString()}
9899
analysis={analysis}
99100
annotationType={
100101
annotations[c.annotationIndex]?.machineReadableName
101102
}
102-
isHighlighted={c.isHighlighted}
103103
subCommands={c.subCommands}
104104
allRunDefs={allRunDefs}
105105
/>
106106
) : (
107107
<IndividualCommand
108108
key={c.command.id}
109-
stepNumber={(i + 1).toString()}
110109
command={c.command}
111110
isHighlighted={c.isHighlighted}
112111
analysis={analysis}
@@ -117,7 +116,6 @@ export function AnnotatedSteps(props: AnnotatedStepsProps): JSX.Element {
117116
: analysis.commands.map((c, i) => (
118117
<IndividualCommand
119118
key={i}
120-
stepNumber={(i + 1).toString()}
121119
command={c}
122120
isHighlighted={i === currentCommandIndex}
123121
analysis={analysis}
@@ -133,123 +131,71 @@ interface AnnotatedGroupProps {
133131
annotationType: string
134132
subCommands: LeafNode[]
135133
analysis: ProtocolAnalysisOutput | CompletedProtocolAnalysis
136-
stepNumber: string
137-
isHighlighted: boolean
138134
allRunDefs: LabwareDefinition[]
139135
}
140136
function AnnotatedGroup(props: AnnotatedGroupProps): JSX.Element {
141-
const {
142-
subCommands,
143-
annotationType,
144-
analysis,
145-
stepNumber,
146-
allRunDefs,
147-
isHighlighted,
148-
} = props
137+
const { subCommands, annotationType, analysis, allRunDefs } = props
149138
const [isExpanded, setIsExpanded] = useState(false)
150-
const backgroundColor = isHighlighted ? COLORS.blue30 : COLORS.grey20
151139
return (
152140
<Flex
153141
onClick={() => {
154142
setIsExpanded(!isExpanded)
155143
}}
156144
cursor={CURSOR_POINTER}
145+
width="100%"
157146
>
158-
{isExpanded ? (
159-
<Flex flexDirection={DIRECTION_COLUMN}>
160-
<Flex
161-
alignItems={ALIGN_CENTER}
162-
alignSelf={ALIGN_FLEX_START}
163-
gridGap={SPACING.spacing8}
164-
>
165-
<LegacyStyledText
166-
minWidth={SPACING.spacing16}
167-
fontSize={TYPOGRAPHY.fontSizeCaption}
168-
>
169-
{stepNumber}
170-
</LegacyStyledText>
171-
<Flex
172-
alignItems={ALIGN_CENTER}
173-
backgroundColor={backgroundColor}
174-
color={COLORS.black90}
175-
borderRadius={BORDERS.borderRadius4}
176-
padding={`${SPACING.spacing8} ${SPACING.spacing8} ${SPACING.spacing8} ${SPACING.spacing16}`}
177-
>
178-
<LegacyStyledText
179-
as="h3"
180-
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
181-
>
182-
{annotationType}
183-
</LegacyStyledText>
184-
<Icon name="chevron-up" size="2rem" />
185-
</Flex>
186-
</Flex>
187-
<Flex
188-
flexDirection={DIRECTION_COLUMN}
189-
paddingY={SPACING.spacing16}
190-
paddingX={SPACING.spacing32}
191-
gridGap={SPACING.spacing4}
192-
>
193-
{subCommands.map((c, i) => (
194-
<IndividualCommand
195-
key={c.command.id}
196-
command={c.command}
197-
analysis={analysis}
198-
isHighlighted={c.isHighlighted}
199-
stepNumber={`${stepNumber}.${(i + 1).toString()}`}
200-
allRunDefs={allRunDefs}
201-
/>
202-
))}
203-
</Flex>
147+
<Flex alignItems={ALIGN_CENTER} width="100%" flexDirection="column">
148+
<Flex
149+
alignItems={ALIGN_CENTER}
150+
borderRadius={BORDERS.borderRadius4}
151+
paddingX="16px"
152+
width="100%"
153+
justifyContent="space-between"
154+
>
155+
<StyledText desktopStyle="bodyDefaultRegular">
156+
{annotationType}
157+
</StyledText>
158+
<Icon
159+
name={isExpanded ? 'chevron-up' : 'chevron-down'}
160+
size="2rem"
161+
color={COLORS.black90}
162+
/>
204163
</Flex>
205-
) : (
206-
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing8}>
207-
<LegacyStyledText as="label">{stepNumber}</LegacyStyledText>
208-
<Flex
209-
alignItems={ALIGN_CENTER}
210-
backgroundColor={backgroundColor}
211-
borderRadius={BORDERS.borderRadius4}
212-
padding={SPACING.spacing8}
213-
>
214-
<LegacyStyledText
215-
as="h3"
216-
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
217-
marginLeft={SPACING.spacing8}
218-
>
219-
{annotationType}
220-
</LegacyStyledText>
221-
<Icon name="chevron-down" size="2rem" color={COLORS.black90} />
222-
</Flex>
164+
<Divider />
165+
<Flex flexDirection="column" gridGap={SPACING.spacing4}>
166+
{isExpanded
167+
? subCommands.map((c, i) => (
168+
<IndividualCommand
169+
key={c.command.id}
170+
command={c.command}
171+
analysis={analysis}
172+
isHighlighted={c.isHighlighted}
173+
allRunDefs={allRunDefs}
174+
/>
175+
))
176+
: null}
223177
</Flex>
224-
)}
178+
</Flex>
225179
</Flex>
226180
)
227181
}
228182

229183
interface IndividualCommandProps {
230184
command: RunTimeCommand
231185
analysis: ProtocolAnalysisOutput | CompletedProtocolAnalysis
232-
stepNumber: string
233186
isHighlighted: boolean
234187
allRunDefs: LabwareDefinition[]
235188
}
236189
function IndividualCommand({
237190
command,
238191
analysis,
239-
stepNumber,
240192
isHighlighted,
241193
allRunDefs,
242194
}: IndividualCommandProps): JSX.Element {
243195
const backgroundColor = isHighlighted ? COLORS.blue30 : COLORS.grey20
244196
const iconColor = isHighlighted ? COLORS.blue60 : COLORS.grey50
245197
return (
246-
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing8}>
247-
<LegacyStyledText
248-
minWidth={SPACING.spacing16}
249-
fontSize={TYPOGRAPHY.fontSizeCaption}
250-
>
251-
{stepNumber}
252-
</LegacyStyledText>
198+
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing8} paddingX="16px">
253199
<Flex
254200
flexDirection={DIRECTION_COLUMN}
255201
gridGap={SPACING.spacing4}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { RefObject } from 'react'
2+
import ViewportList, { ViewportListRef } from 'react-viewport-list'
3+
4+
import {
5+
COLORS,
6+
Divider,
7+
Flex,
8+
OVERFLOW_SCROLL,
9+
StyledText,
10+
} from '@opentrons/components'
11+
import { ProtocolAnalysisOutput, RunTimeCommand } from '@opentrons/shared-data'
12+
13+
import { AnnotatedSteps } from '/app/organisms/Desktop/ProtocolDetails/AnnotatedSteps'
14+
import { GroupedCommands } from '/app/redux/protocol-storage'
15+
16+
interface CommandStepsProps {
17+
// wrapperRef: RefObject<HTMLDivElement>
18+
// commandListRef: RefObject<ViewportListRef>
19+
// commands: RunTimeCommand[]
20+
groupedCommands: GroupedCommands | null
21+
analysis: ProtocolAnalysisOutput
22+
currentCommandIndex: number | undefined
23+
}
24+
export function CommandSteps(props: CommandStepsProps): JSX.Element {
25+
const { currentCommandIndex, groupedCommands, analysis } = props
26+
const commandLength = analysis.commands.length
27+
console.log(commandLength, currentCommandIndex)
28+
const percentComplete =
29+
currentCommandIndex != null
30+
? (currentCommandIndex / commandLength) * 100
31+
: 0
32+
console.log(percentComplete)
33+
return (
34+
// <Flex
35+
// ref={wrapperRef}
36+
// // alignSelf={ALIGN_STRETCH}
37+
// overflowY={OVERFLOW_SCROLL}
38+
// width="100%"
39+
// >
40+
// <ViewportList
41+
// viewportRef={wrapperRef}
42+
// ref={commandListRef}
43+
// items={commands}
44+
// axis="y"
45+
// >
46+
// {(command, index) => (
47+
// <CommandItem
48+
// index={index}
49+
// command={command}
50+
// currentCommandIndex={currentCommandIndex}
51+
// setCurrentCommandIndex={setCurrentCommandIndex}
52+
// analysis={analysis}
53+
// robotType={robotType ?? FLEX_ROBOT_TYPE}
54+
// allRunDefs={allRunDefs}
55+
// />
56+
// )}
57+
// </ViewportList>
58+
// </Flex>
59+
<div style={{ paddingRight: '16px', paddingBottom: '16px' }}>
60+
<div
61+
style={{
62+
backgroundColor: 'white',
63+
borderRadius: '8px',
64+
height: '535px',
65+
maxHeight: '535px',
66+
overflowY: 'scroll',
67+
}}
68+
>
69+
<div
70+
style={{
71+
display: 'flex',
72+
justifyContent: 'space-between',
73+
padding: '16px',
74+
}}
75+
>
76+
<StyledText desktopStyle="bodyDefaultRegular">Timeline</StyledText>
77+
<StyledText
78+
desktopStyle="bodyDefaultRegular"
79+
color={COLORS.grey60}
80+
>{`${percentComplete}% complete`}</StyledText>
81+
</div>
82+
<Divider />
83+
<AnnotatedSteps
84+
currentCommandIndex={currentCommandIndex}
85+
analysis={analysis}
86+
groupedCommands={groupedCommands}
87+
/>
88+
</div>
89+
</div>
90+
)
91+
}

app/src/pages/Desktop/Protocols/Preview/Container.tsx

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
import { useEffect, useRef, useState } from 'react'
22
import { ViewportListRef } from 'react-viewport-list'
33

4+
import { FLEX_ROBOT_TYPE } from '@opentrons/shared-data'
45
import {
56
constructInvariantContextFromRunCommands,
67
getResultingTimelineFrameFromRunCommands,
78
} from '@opentrons/step-generation'
89

10+
import { GroupedCommands } from '/app/redux/protocol-storage'
11+
12+
import { CommandSteps } from './CommandSteps'
913
import { Controls } from './Controls'
14+
import { DeckView } from './DeckView'
1015

1116
import type { ProtocolAnalysisOutput } from '@opentrons/shared-data'
1217

1318
const SEC_PER_FRAME = 3000
1419

1520
interface ContainerProps {
1621
analysis: ProtocolAnalysisOutput
22+
groupedCommands: GroupedCommands | null
1723
}
1824
export function Container(props: ContainerProps): JSX.Element {
19-
const { analysis } = props
25+
const { analysis, groupedCommands } = props
2026
const { commands, robotType, liquids } = analysis
2127

2228
const [isPlaying, setIsPlaying] = useState<boolean>(false)
29+
const [selectedSlot, setSelectedSlot] = useState<string | null>(null)
2330
const [currentCommandIndex, setCurrentCommandIndex] = useState<number>(0)
2431
const commandListRef = useRef<ViewportListRef>(null)
2532

@@ -54,13 +61,30 @@ export function Container(props: ContainerProps): JSX.Element {
5461
const { robotState } = frame
5562

5663
return (
57-
<Controls
58-
protocolName={analysis.metadata.protocolName}
59-
numErrors={analysis.errors.length}
60-
numCommandLength={commands.length}
61-
currentCommandIndex={currentCommandIndex}
62-
setCurrentCommandIndex={setCurrentCommandIndex}
63-
commandListRef={commandListRef}
64-
/>
64+
<>
65+
<Controls
66+
protocolName={analysis.metadata.protocolName}
67+
numErrors={analysis.errors.length}
68+
numCommandLength={commands.length}
69+
currentCommandIndex={currentCommandIndex}
70+
setCurrentCommandIndex={setCurrentCommandIndex}
71+
commandListRef={commandListRef}
72+
handlePlayPause={handlePlayPause}
73+
/>
74+
<div style={{ display: 'flex' }}>
75+
<DeckView
76+
invariantContext={invariantContext}
77+
robotState={robotState}
78+
robotType={robotType ?? FLEX_ROBOT_TYPE}
79+
selectedSlot={selectedSlot}
80+
setSelectedSlot={setSelectedSlot}
81+
/>
82+
<CommandSteps
83+
analysis={analysis}
84+
currentCommandIndex={currentCommandIndex}
85+
groupedCommands={groupedCommands}
86+
/>
87+
</div>
88+
</>
6589
)
6690
}

0 commit comments

Comments
 (0)