-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(components, protocol-designer): add Thermocycler step details UI
Similar to viewing substeps detail for moveLiquid type steps, this PR adds UI for thermocycler substep details. Also, I move the step details toolbox to the right side of the screen as designs specify, and make a few other small styling changes to our ListItem, Toolbox, and StepOverFlowMenu components. Closes AUTH-882
- Loading branch information
Showing
8 changed files
with
202 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 110 additions & 2 deletions
112
protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ThermocyclerProfileSubsteps.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,111 @@ | ||
export function ThermocyclerProfileSubsteps(): JSX.Element { | ||
return <div>Wire this up</div> | ||
import { useSelector } from 'react-redux' | ||
import { Trans, useTranslation } from 'react-i18next' | ||
import { | ||
ALIGN_CENTER, | ||
ALIGN_FLEX_END, | ||
DIRECTION_COLUMN, | ||
FLEX_MAX_CONTENT, | ||
Flex, | ||
ListItem, | ||
SPACING, | ||
StyledText, | ||
Tag, | ||
} from '@opentrons/components' | ||
import { getSavedStepForms } from '../../../../step-forms/selectors' | ||
|
||
import type { ProfileStepItem } from '../../../../form-types' | ||
import type { ThermocyclerCycleType } from '../StepForm/StepTools/ThermocyclerTools/ThermocyclerCycle' | ||
import type { ThermocyclerStepType } from '../StepForm/StepTools/ThermocyclerTools/ThermocyclerStep' | ||
|
||
interface ThermocyclerProfileSubstepsProps { | ||
stepId: string | ||
} | ||
export function ThermocyclerProfileSubsteps( | ||
props: ThermocyclerProfileSubstepsProps | ||
): JSX.Element { | ||
const { stepId } = props | ||
|
||
const savedStepForms = useSelector(getSavedStepForms) | ||
const step = savedStepForms[stepId] | ||
const orderedSubsteps = step.orderedProfileItems.map( | ||
(id: string) => step.profileItemsById[id] | ||
) | ||
|
||
return ( | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing4} | ||
width={FLEX_MAX_CONTENT} | ||
> | ||
{orderedSubsteps.map( | ||
(substep: ThermocyclerStepType | ThermocyclerCycleType) => { | ||
const content = | ||
substep.type === 'profileCycle' ? ( | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing12} | ||
> | ||
{substep.steps.map((profileStep: ProfileStepItem) => { | ||
const { | ||
temperature, | ||
durationMinutes, | ||
durationSeconds, | ||
} = profileStep | ||
return ( | ||
<ThermocyclerSubstep | ||
Check failure on line 55 in protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ThermocyclerProfileSubsteps.tsx GitHub Actions / js checks
|
||
temperature={temperature} | ||
duration={`${durationMinutes}:${durationSeconds}`} | ||
/> | ||
) | ||
})} | ||
<StyledText | ||
desktopStyle="bodyDefaultRegular" | ||
alignSelf={ALIGN_FLEX_END} | ||
> | ||
{`Repeat ${substep.repetitions} times `} | ||
</StyledText> | ||
</Flex> | ||
) : ( | ||
<ThermocyclerSubstep | ||
temperature={substep.temperature} | ||
duration={`${substep.durationMinutes}:${substep.durationSeconds}`} | ||
/> | ||
) | ||
return ( | ||
<ListItem type="noActive" width="100%" padding={SPACING.spacing12}> | ||
Check failure on line 75 in protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ThermocyclerProfileSubsteps.tsx GitHub Actions / js checks
|
||
{content} | ||
</ListItem> | ||
) | ||
} | ||
)} | ||
</Flex> | ||
) | ||
} | ||
|
||
interface ThermocyclerSubstepProps { | ||
temperature: string | ||
duration: string | ||
} | ||
|
||
function ThermocyclerSubstep(props: ThermocyclerSubstepProps) { | ||
Check failure on line 90 in protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ThermocyclerProfileSubsteps.tsx GitHub Actions / js checks
|
||
const { temperature, duration } = props | ||
const { t } = useTranslation(['application', 'protocol_steps']) | ||
return ( | ||
<Flex gridGap={SPACING.spacing4} alignItems={ALIGN_CENTER}> | ||
<Trans | ||
t={t} | ||
i18nKey="protocol_steps:thermocycler_module.substep_settings" | ||
components={{ | ||
text: <StyledText desktopStyle="bodyDefaultRegular" />, | ||
tagTemperature: ( | ||
<Tag | ||
type="default" | ||
text={`${temperature}${t('application:units.degrees')}`} | ||
/> | ||
), | ||
tagDuration: <Tag type="default" text={duration} />, | ||
}} | ||
/> | ||
</Flex> | ||
) | ||
} |
78 changes: 78 additions & 0 deletions
78
.../src/pages/Designer/ProtocolSteps/Timeline/__tests__/ThermocyclerProfileSubsteps.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { describe, it, vi, beforeEach, expect } from 'vitest' | ||
import { screen } from '@testing-library/react' | ||
import { renderWithProviders } from '../../../../../__testing-utils__' | ||
import { i18n } from '../../../../../assets/localization' | ||
import { getSavedStepForms } from '../../../../../step-forms/selectors' | ||
import { ThermocyclerProfileSubsteps } from '../ThermocyclerProfileSubsteps' | ||
import type { FormData } from '../../../../../form-types' | ||
|
||
const render = ( | ||
props: React.ComponentProps<typeof ThermocyclerProfileSubsteps> | ||
) => { | ||
return renderWithProviders(<ThermocyclerProfileSubsteps {...props} />, { | ||
i18nInstance: i18n, | ||
})[0] | ||
} | ||
vi.mock('../../../../../step-forms/selectors') | ||
const THERMOCYCLER_STEP_ID = 'tcStep123' | ||
const MOCK_THERMOCYCLER_ORDERED_SUBSTEP_IDS = [ | ||
'292b0d70-fa06-4ab1-adc9-f26c589babf4', | ||
'0965e0de-2d01-4e4e-8fb3-1e66306fe7e5', | ||
] | ||
const MOCK_THERMOCYCLER_SUBSTEP_ITEMS = { | ||
'292b0d70-fa06-4ab1-adc9-f26c589babf4': { | ||
id: '292b0d70-fa06-4ab1-adc9-f26c589babf4', | ||
title: '', | ||
steps: [ | ||
{ | ||
durationMinutes: '00', | ||
durationSeconds: '30', | ||
id: 'f90cc374-2eeb-4205-80c6-63c5c77215a5', | ||
temperature: '10', | ||
title: 'cyclestep1', | ||
type: 'profileStep', | ||
}, | ||
{ | ||
durationMinutes: '1', | ||
durationSeconds: '30', | ||
id: '462b3d8f-bb8a-4e11-ae98-8f1d46e8507e', | ||
temperature: '55', | ||
title: 'cyclestep2', | ||
type: 'profileStep', | ||
}, | ||
], | ||
type: 'profileCycle', | ||
repetitions: '28', | ||
}, | ||
'0965e0de-2d01-4e4e-8fb3-1e66306fe7e5': { | ||
durationMinutes: '5', | ||
durationSeconds: '00', | ||
id: '0965e0de-2d01-4e4e-8fb3-1e66306fe7e5', | ||
temperature: '39', | ||
title: 'last step', | ||
type: 'profileStep', | ||
}, | ||
} | ||
|
||
describe('TimelineToolbox', () => { | ||
let props: React.ComponentProps<typeof ThermocyclerProfileSubsteps> | ||
beforeEach(() => { | ||
props = { stepId: THERMOCYCLER_STEP_ID } | ||
vi.mocked(getSavedStepForms).mockReturnValue({ | ||
[THERMOCYCLER_STEP_ID]: ({ | ||
orderedProfileItems: MOCK_THERMOCYCLER_ORDERED_SUBSTEP_IDS, | ||
profileItemsById: MOCK_THERMOCYCLER_SUBSTEP_ITEMS, | ||
} as unknown) as FormData, | ||
}) | ||
}) | ||
it('renders all profile steps, including cycles and steps', () => { | ||
render(props) | ||
expect(screen.getAllByText('Set block temperature to').length === 3) | ||
screen.getByText('10°C') | ||
screen.getByText('55°C') | ||
screen.getByText('39°C') | ||
screen.getByText('00:30') | ||
screen.getByText('1:30') | ||
screen.getByText('5:00') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters