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(app): extend SectionList component for Generic Step Screen #8513

Merged
merged 12 commits into from
Oct 13, 2021
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import * as React from 'react'
import {
ALIGN_CENTER,
Box,
Flex,
JUSTIFY_SPACE_BETWEEN,
SPACING_3,
} from '@opentrons/components'
import { LabwarePositionCheckStepDetail } from './LabwarePositionCheckStepDetail'
import { SectionList } from './SectionList'
import { useIntroInfo } from './hooks'
import type { LabwarePositionCheckStep } from './types'

interface GenericStepScreenProps {
Expand All @@ -9,5 +18,24 @@ interface GenericStepScreenProps {
export const GenericStepScreen = (
props: GenericStepScreenProps
): JSX.Element | null => {
return <LabwarePositionCheckStepDetail selectedStep={props.selectedStep} />
const introInfo = useIntroInfo()
const [sectionIndex] = React.useState<number>(0)
if (introInfo == null) return null
const { sections, primaryPipetteMount, secondaryPipetteMount } = introInfo
return (
<Box margin={SPACING_3}>
<Flex justifyContent={JUSTIFY_SPACE_BETWEEN} alignItems={ALIGN_CENTER}>
<SectionList
primaryPipetteMount={primaryPipetteMount}
secondaryPipetteMount={secondaryPipetteMount}
sections={sections}
currentSection={sections[sectionIndex]}
completedSections={[sections[sectionIndex - 1]]}
/>
<Box width="60%" padding={SPACING_3}>
<LabwarePositionCheckStepDetail selectedStep={props.selectedStep} />
</Box>
</Flex>
</Box>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
SPACING_4,
FONT_SIZE_BODY_2,
} from '@opentrons/components'
import { PositionCheckNav } from './PositionCheckNav'
import { SectionList } from './SectionList'
import { DeckMap } from './DeckMap'
import { useIntroInfo, useLabwareIdsBySection } from './hooks'

Expand Down Expand Up @@ -63,7 +63,7 @@ export const IntroScreen = (props: {
}}
></Trans>
<Flex justifyContent={JUSTIFY_SPACE_BETWEEN} alignItems={ALIGN_CENTER}>
<PositionCheckNav
<SectionList
sections={sections}
currentSection={currentSection}
primaryPipetteMount={primaryPipetteMount}
Expand Down

This file was deleted.

111 changes: 111 additions & 0 deletions app/src/organisms/ProtocolSetup/LabwarePositionCheck/SectionList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import capitalize from 'lodash/capitalize'
import {
Flex,
Box,
ALIGN_CENTER,
SIZE_1,
SPACING_2,
SPACING_5,
C_WHITE,
C_NEAR_WHITE,
C_DARK_GRAY,
TEXT_ALIGN_CENTER,
FONT_SIZE_CAPTION,
Text,
C_DISABLED,
Icon,
SPACING_3,
COLOR_SUCCESS,
C_SELECTED_DARK,
} from '@opentrons/components'
import type { Section } from './types'
interface Props {
sections: Section[]
currentSection: Section
primaryPipetteMount: string
secondaryPipetteMount: string
completedSections?: Section[]
}

export function SectionList(props: Props): JSX.Element {
const {
currentSection,
sections,
primaryPipetteMount,
secondaryPipetteMount,
completedSections,
} = props
const { t } = useTranslation('labware_position_check')

return (
<Box
fontSize={FONT_SIZE_CAPTION}
padding={SPACING_3}
width="14rem"
marginLeft={SPACING_5}
boxShadow="1px 1px 1px rgba(0, 0, 0, 0.25)"
borderRadius="4px"
backgroundColor={C_NEAR_WHITE}
>
{sections.map((section, index) => {
const sectionTextColor =
completedSections != null && !completedSections.includes(section)
? C_DISABLED
: C_DARK_GRAY
const isCompleted =
completedSections != null && completedSections.includes(section)
let backgroundColor = C_DISABLED
if (section === currentSection) {
backgroundColor = C_SELECTED_DARK
} else if (isCompleted === true) {
backgroundColor = 'transparent'
} else {
backgroundColor = sectionTextColor
}
return (
<Flex key={index} padding={SPACING_2} alignItems={ALIGN_CENTER}>
<Box
width={SIZE_1}
height={SIZE_1}
lineHeight={SIZE_1}
backgroundColor={backgroundColor}
color={C_WHITE}
borderRadius="50%"
marginRight={SPACING_2}
textAlign={TEXT_ALIGN_CENTER}
>
{isCompleted ? (
<Icon
name="check-circle"
width={SIZE_1}
height={SIZE_1}
lineHeight={SIZE_1}
marginRight={SPACING_2}
color={COLOR_SUCCESS}
/>
) : (
index + 1
)}
</Box>
<Box maxWidth="85%">
<Text
color={
section === currentSection
? C_SELECTED_DARK
: sectionTextColor
}
>
{t(`${section.toLowerCase()}_section`, {
primary_mount: capitalize(primaryPipetteMount),
secondary_mount: capitalize(secondaryPipetteMount),
})}
</Text>
</Box>
</Flex>
)
})}
</Box>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,27 @@ import {
import { i18n } from '../../../../i18n'
import { GenericStepScreen } from '../GenericStepScreen'
import { LabwarePositionCheckStepDetail } from '../LabwarePositionCheckStepDetail'
import { SectionList } from '../SectionList'
import { useIntroInfo } from '../hooks'
import { Section } from '../types'

jest.mock('../LabwarePositionCheckStepDetail')
jest.mock('../SectionList')
jest.mock('../hooks')

const mockLabwarePositionCheckStepDetail = LabwarePositionCheckStepDetail as jest.MockedFunction<
typeof LabwarePositionCheckStepDetail
>
const mockSectionList = SectionList as jest.MockedFunction<typeof SectionList>
const mockUseIntroInfo = useIntroInfo as jest.MockedFunction<
typeof useIntroInfo
>

const PICKUP_TIP_LABWARE_ID = 'PICKUP_TIP_LABWARE_ID'
const PRIMARY_PIPETTE_ID = 'PRIMARY_PIPETTE_ID'
const mockLabwarePositionCheckStepTipRack = {
const MOCK_SECTIONS = ['PRIMARY_PIPETTE_TIPRACKS' as Section]

const MOCK_LABWARE_POSITION_CHECK_STEP_TIPRACK = {
labwareId:
'1d57fc10-67ad-11ea-9f8b-3b50068bd62d:opentrons/opentrons_96_filtertiprack_200ul/1',
section: '',
Expand All @@ -41,19 +53,39 @@ describe('GenericStepScreen', () => {

beforeEach(() => {
props = {
selectedStep: mockLabwarePositionCheckStepTipRack,
selectedStep: MOCK_LABWARE_POSITION_CHECK_STEP_TIPRACK,
setCurrentLabwareCheckStep: () => {},
}
when(mockLabwarePositionCheckStepDetail)
.calledWith(
partialComponentPropsMatcher({
selectedStep: mockLabwarePositionCheckStepTipRack,
selectedStep: MOCK_LABWARE_POSITION_CHECK_STEP_TIPRACK,
})
)
.mockReturnValue(<div>Mock Labware Position Check Step Detail</div>)

mockSectionList.mockReturnValue(<div>Mock SectionList </div>)
when(mockUseIntroInfo).calledWith().mockReturnValue({
primaryTipRackSlot: '1',
primaryTipRackName: 'Opentrons 96 Filter Tip Rack 200 µL',
primaryPipetteMount: 'left',
secondaryPipetteMount: '',
numberOfTips: 1,
firstStepLabwareSlot: '2',
sections: MOCK_SECTIONS,
})
})
it('renders LabwarePositionCheckStepDetail component', () => {
const { getByText } = render(props)
expect(getByText('Mock Labware Position Check Step Detail')).toBeTruthy()
})
it('renders GenericStepScreenNav component', () => {
const { getByText } = render(props)
getByText('Mock SectionList')
})
it('renders null if useIntroInfo is null', () => {
mockUseIntroInfo.mockReturnValue(null)
const { container } = render(props)
expect(container.firstChild).toBeNull()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import standardDeckDef from '@opentrons/shared-data/deck/definitions/2/ot2_stand
import { LabwareDefinition2 } from '@opentrons/shared-data'
import fixture_tiprack_300_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_300_ul.json'
import { useModuleRenderInfoById, useLabwareRenderInfoById } from '../../hooks'
import { PositionCheckNav } from '../PositionCheckNav'
import { SectionList } from '../SectionList'
import { useIntroInfo, useLabwareIdsBySection } from '../hooks'
import { IntroScreen, INTERVAL_MS } from '../IntroScreen'
import type { Section } from '../types'
import { fireEvent } from '@testing-library/dom'

jest.mock('../hooks')
jest.mock('../PositionCheckNav')
jest.mock('../SectionList')
jest.mock('../../hooks')
jest.mock('@opentrons/components', () => {
const actualComponents = jest.requireActual('@opentrons/components')
Expand All @@ -42,9 +42,7 @@ const mockUseIntroInfo = useIntroInfo as jest.MockedFunction<
typeof useIntroInfo
>
const mockUseInterval = useInterval as jest.MockedFunction<typeof useInterval>
const mockPositionCheckNav = PositionCheckNav as jest.MockedFunction<
typeof PositionCheckNav
>
const mockSectionList = SectionList as jest.MockedFunction<typeof SectionList>
const mockRobotWorkSpace = RobotWorkSpace as jest.MockedFunction<
typeof RobotWorkSpace
>
Expand Down Expand Up @@ -107,7 +105,7 @@ describe('IntroScreen', () => {
firstStepLabwareSlot: '2',
sections: MOCK_SECTIONS,
})
mockPositionCheckNav.mockReturnValue(<div>Mock Position Check Nav</div>)
mockSectionList.mockReturnValue(<div>Mock Section List</div>)
})
afterEach(() => {
resetAllWhenMocks()
Expand All @@ -125,7 +123,7 @@ describe('IntroScreen', () => {
getByText(
'When you check a labware, the OT-2’s pipette nozzle or attached tip will stop at the center of the A1 well. If the pipette nozzle or tip is not centered, you can reveal the OT-2’s jog controls to make an adjustment. This Labware Offset will be applied to the entire labware. Offset data is measured to the nearest 1/10th mm and can be made in the X, Y and/or Z directions.'
)
getByText('Mock Position Check Nav')
getByText('Mock Section List')
})
it('should call setCurrentLabwareCheckStep when the CTA button is pressed', () => {
const { getByRole } = render(props)
Expand Down
Loading