Skip to content

Commit aa2dfd9

Browse files
committed
Breakout util to grab labware details for list view on odd and desktop, show lid details on ODD
1 parent 04f0ba3 commit aa2dfd9

File tree

7 files changed

+165
-176
lines changed

7 files changed

+165
-176
lines changed

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

+18-87
Original file line numberDiff line numberDiff line change
@@ -18,92 +18,23 @@ import {
1818
StyledText,
1919
useMenuHandleClickOutside,
2020
} from '@opentrons/components'
21-
import { getLabwareDefURI } from '@opentrons/shared-data'
2221
import { Divider } from '/app/atoms/structure'
2322
import { getTopPortalEl } from '/app/App/portal'
2423
import { LabwareDetails } from '/app/organisms/Desktop/Labware/LabwareDetails'
25-
24+
import { getRequiredLabwareDetailsFromLoadCommands } from '/app/transformations/commands'
2625
import type { MouseEventHandler } from 'react'
27-
import type {
28-
LoadLabwareRunTimeCommand,
29-
LoadLidStackRunTimeCommand,
30-
LoadLidRunTimeCommand,
31-
LabwareDefinition2,
32-
} from '@opentrons/shared-data'
26+
import type { RunTimeCommand } from '@opentrons/shared-data'
3327
import type { LabwareDefAndDate } from '/app/local-resources/labware'
3428

35-
interface ProtocolLabwareDetailsProps {
36-
loadLabwareCommands: Array<
37-
| LoadLabwareRunTimeCommand
38-
| LoadLidStackRunTimeCommand
39-
| LoadLidRunTimeCommand
40-
> | null
41-
}
42-
43-
export const ProtocolLabwareDetails = (
44-
props: ProtocolLabwareDetailsProps
45-
): JSX.Element => {
46-
const { loadLabwareCommands } = props
29+
export const ProtocolLabwareDetails = (props: {
30+
commands: RunTimeCommand[]
31+
}): JSX.Element => {
32+
const { commands } = props
4733
const { t } = useTranslation('protocol_details')
4834

49-
const labwareAndLidDetails =
50-
loadLabwareCommands != null
51-
? [
52-
...loadLabwareCommands
53-
.reduce((acc, command) => {
54-
if (command.result?.definition == null) return acc
55-
else if (command.commandType === 'loadLid') return acc
56-
else if (command.commandType === 'loadLidStack') {
57-
if (!acc.has(getLabwareDefURI(command.result.definition))) {
58-
acc.set(getLabwareDefURI(command.result.definition), {
59-
...command,
60-
quantity: 0,
61-
})
62-
}
63-
acc.get(
64-
getLabwareDefURI(command.result?.definition)
65-
).quantity += command.result?.labwareIds.length
66-
return acc
67-
} else {
68-
let defUri = getLabwareDefURI(command.result?.definition)
69-
const lidCommand = loadLabwareCommands.find(
70-
c =>
71-
c.commandType === 'loadLid' &&
72-
c.params.location !== 'offDeck' &&
73-
c.params.location !== 'systemLocation' &&
74-
'labwareId' in c.params.location &&
75-
c.params.location.labwareId === command.result?.labwareId
76-
)
77-
if (
78-
lidCommand != null &&
79-
lidCommand.result?.definition != null
80-
) {
81-
defUri = `${defUri}_${getLabwareDefURI(
82-
lidCommand.result.definition
83-
)}`
84-
85-
if (!acc.has(defUri)) {
86-
acc.set(defUri, {
87-
...command,
88-
quantity: 0,
89-
lid: lidCommand.result.definition,
90-
})
91-
}
92-
} else {
93-
if (!acc.has(defUri)) {
94-
acc.set(defUri, {
95-
...command,
96-
quantity: 0,
97-
})
98-
}
99-
}
100-
acc.get(defUri).quantity++
101-
return acc
102-
}
103-
}, new Map())
104-
.values(),
105-
]
106-
: []
35+
const labwareAndLidDetails = getRequiredLabwareDetailsFromLoadCommands(
36+
commands
37+
)
10738

10839
return (
10940
<>
@@ -130,11 +61,11 @@ export const ProtocolLabwareDetails = (
13061
{labwareAndLidDetails?.map((labware, index) => (
13162
<ProtocolLabwareDetailItem
13263
key={index}
133-
namespace={labware.params.namespace}
134-
displayName={labware.result?.definition?.metadata?.displayName}
64+
namespace={labware.namespace}
65+
displayName={labware.displayName}
13566
quantity={labware.quantity}
136-
labware={{ definition: labware.result?.definition }}
137-
lid={labware.lid}
67+
labware={{ definition: labware.labwareDef }}
68+
lidDisplayName={labware.lidDisplayName}
13869
data-testid={`ProtocolLabwareDetails_item_${index}`}
13970
/>
14071
))}
@@ -149,16 +80,16 @@ export const ProtocolLabwareDetails = (
14980
interface ProtocolLabwareDetailItemProps {
15081
namespace: string
15182
displayName: string
152-
quantity: string
153-
lid?: LabwareDefinition2
83+
quantity: number
84+
lidDisplayName?: string
15485
labware: LabwareDefAndDate
15586
}
15687

15788
export const ProtocolLabwareDetailItem = (
15889
props: ProtocolLabwareDetailItemProps
15990
): JSX.Element => {
16091
const { t } = useTranslation('protocol_details')
161-
const { namespace, displayName, quantity, labware, lid } = props
92+
const { namespace, displayName, quantity, labware, lidDisplayName } = props
16293
return (
16394
<>
16495
<Divider width="100%" />
@@ -192,13 +123,13 @@ export const ProtocolLabwareDetailItem = (
192123
>
193124
{displayName}
194125
</StyledText>
195-
{lid != null ? (
126+
{lidDisplayName != null ? (
196127
<StyledText
197128
desktopStyle="bodyDefaultRegular"
198129
color={COLORS.grey60}
199130
paddingRight={SPACING.spacing32}
200131
>
201-
{t('with_lid_name', { lid: lid.metadata.displayName })}
132+
{t('with_lid_name', { lid: lidDisplayName })}
202133
</StyledText>
203134
) : null}
204135
</Flex>

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

+1-16
Original file line numberDiff line numberDiff line change
@@ -279,21 +279,6 @@ export function ProtocolDetails(
279279
: null
280280
)
281281

282-
const loadLabwareCommands =
283-
mostRecentAnalysis?.commands.filter(
284-
(
285-
command
286-
): command is
287-
| LoadLabwareRunTimeCommand
288-
| LoadLidRunTimeCommand
289-
| LoadLidStackRunTimeCommand =>
290-
['loadLabware', 'loadLid', 'loadLidStack'].includes(
291-
command.commandType
292-
) &&
293-
command.result?.definition != null &&
294-
command.result?.definition.parameters.format !== 'trash'
295-
) ?? []
296-
297282
const protocolDisplayName = getProtocolDisplayName(
298283
protocolKey,
299284
srcFileNames,
@@ -341,7 +326,7 @@ export function ProtocolDetails(
341326

342327
const contentsByTabName = {
343328
labware: (
344-
<ProtocolLabwareDetails loadLabwareCommands={loadLabwareCommands} />
329+
<ProtocolLabwareDetails commands={mostRecentAnalysis?.commands ?? []} />
345330
),
346331
robot_config: (
347332
<RobotConfigurationDetails

app/src/pages/ODD/ProtocolDetails/Labware.tsx

+32-33
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import {
88
Flex,
99
Icon,
1010
SPACING,
11-
LegacyStyledText,
11+
StyledText,
1212
TYPOGRAPHY,
1313
WRAP,
14+
DIRECTION_COLUMN,
1415
} from '@opentrons/components'
15-
import { getLabwareDisplayName } from '@opentrons/shared-data'
1616

1717
import { useRequiredProtocolLabware } from '/app/resources/protocols'
1818
import { EmptySection } from './EmptySection'
@@ -52,21 +52,8 @@ const TableDatum = styled('td')`
5252

5353
export const Labware = (props: { protocolId: string }): JSX.Element => {
5454
const labwareItems = useRequiredProtocolLabware(props.protocolId)
55-
const labwareNames = labwareItems.map(li =>
56-
getLabwareDisplayName(li.definition)
57-
)
5855

59-
const countedNames = labwareNames.reduce(
60-
(allNames: Record<string, number>, name: string) => {
61-
const currCount: number = allNames[name] ?? 0
62-
return {
63-
...allNames,
64-
[name]: currCount + 1,
65-
}
66-
},
67-
{}
68-
)
69-
const { t, i18n } = useTranslation('protocol_setup')
56+
const { t, i18n } = useTranslation('protocol_details')
7057

7158
return labwareItems.length === 0 ? (
7259
<EmptySection section="labware" />
@@ -75,17 +62,17 @@ export const Labware = (props: { protocolId: string }): JSX.Element => {
7562
<thead>
7663
<tr>
7764
<TableHeader>
78-
<LegacyStyledText
65+
<StyledText
7966
color={COLORS.grey60}
8067
fontSize={TYPOGRAPHY.fontSize20}
8168
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
8269
paddingLeft={SPACING.spacing24}
8370
>
8471
{i18n.format(t('labware_name'), 'titleCase')}
85-
</LegacyStyledText>
72+
</StyledText>
8673
</TableHeader>
8774
<TableHeader>
88-
<LegacyStyledText
75+
<StyledText
8976
alignItems={ALIGN_CENTER}
9077
color={COLORS.grey60}
9178
fontSize={TYPOGRAPHY.fontSize20}
@@ -94,23 +81,21 @@ export const Labware = (props: { protocolId: string }): JSX.Element => {
9481
textAlign={TYPOGRAPHY.textAlignCenter}
9582
>
9683
{i18n.format(t('quantity'), 'sentenceCase')}
97-
</LegacyStyledText>
84+
</StyledText>
9885
</TableHeader>
9986
</tr>
10087
</thead>
10188
<tbody>
102-
{Object.entries(countedNames).map(([name, count]) => {
103-
const definition = labwareItems.find(
104-
li => getLabwareDisplayName(li.definition) === name
105-
)?.definition
89+
{labwareItems.map(labware => {
10690
return (
107-
<TableRow key={name}>
91+
<TableRow key={labware.displayName}>
10892
<TableDatum>
10993
<Flex
11094
flexDirection={DIRECTION_ROW}
11195
paddingLeft={SPACING.spacing24}
96+
alignItems={ALIGN_CENTER}
11297
>
113-
{definition?.namespace === 'opentrons' ? (
98+
{labware.namespace === 'opentrons' ? (
11499
<Icon
115100
color={COLORS.blue50}
116101
name="check-decagram"
@@ -122,19 +107,33 @@ export const Labware = (props: { protocolId: string }): JSX.Element => {
122107
) : (
123108
<Flex marginLeft={SPACING.spacing20} />
124109
)}
125-
<LegacyStyledText as="p" alignItems={ALIGN_CENTER}>
126-
{name}
127-
</LegacyStyledText>
110+
<Flex flexDirection={DIRECTION_COLUMN}>
111+
<StyledText
112+
oddStyle="bodyTextRegular"
113+
alignItems={ALIGN_CENTER}
114+
>
115+
{labware.displayName}
116+
</StyledText>
117+
{labware.lidDisplayName ? (
118+
<StyledText
119+
oddStyle="smallBodyTextRegular"
120+
alignItems={ALIGN_CENTER}
121+
color={COLORS.grey60}
122+
>
123+
{t('with_lid_name', { lid: labware.lidDisplayName })}
124+
</StyledText>
125+
) : null}
126+
</Flex>
128127
</Flex>
129128
</TableDatum>
130129
<TableDatum>
131-
<LegacyStyledText
132-
as="p"
130+
<StyledText
131+
oddStyle="bodyTextRegular"
133132
alignItems={ALIGN_CENTER}
134133
textAlign={TYPOGRAPHY.textAlignCenter}
135134
>
136-
{count}
137-
</LegacyStyledText>
135+
{labware.quantity}
136+
</StyledText>
138137
</TableDatum>
139138
</TableRow>
140139
)

0 commit comments

Comments
 (0)