Skip to content

Commit

Permalink
feat(app,components): add intervention modal to ODD (#13135)
Browse files Browse the repository at this point in the history
makes necessary changes to the intervention modal and base modal components to display
different layout/styling on ODD and desktop. adds the intervention modal to the RunningProtocol ODD
page.

re RLAB-323, closes RLAB-321, RLAB-324, RLAB-325
  • Loading branch information
brenthagen authored Jul 27, 2023
1 parent 42cb81e commit a536c53
Show file tree
Hide file tree
Showing 14 changed files with 406 additions and 157 deletions.
6 changes: 5 additions & 1 deletion app/src/assets/localization/en/protocol_command_text.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@
"module_in_slot_plural": "{{module}}",
"module_in_slot": "{{module}} in Slot {{slot_name}}",
"move_labware_manually": "Manually move {{labware}} from {{old_location}} to {{new_location}}",
"move_labware_on": "Move labware on {{robot_name}}",
"move_labware_using_gripper": "Moving {{labware}} using gripper from {{old_location}} to {{new_location}}",
"move_labware": "Move Labware",
"move_relative": "Moving {{distance}} mm along {{axis}} axis",
"move_to_coordinates": "Moving to (X: {{x}}, Y: {{y}}, Z: {{z}})",
"move_to_slot": "Moving to Slot {{slot_name}}",
"move_to_well": "Moving to well {{well_name}} of {{labware}} in {{labware_location}}",
"notes": "notes",
"off_deck": "off deck",
"offdeck": "offdeck",
"opening_tc_lid": "Opening Thermocycler lid",
"perform_manual_step": "Perform manual step on {{robot_name}}",
"pause_on": "Pause on {{robot_name}}",
"pause": "Pause",
"pickup_tip": "Picking up tip from {{well_name}} of {{labware}} in {{labware_location}}",
"save_position": "Saving position",
"set_and_await_hs_shake": "Setting Heater-Shaker to shake at {{rpm}} rpm and waiting until reached",
Expand Down
20 changes: 11 additions & 9 deletions app/src/molecules/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import {
import { BackgroundOverlay } from '../BackgroundOverlay'
import { ModalHeader } from './ModalHeader'

import type { StyleProps } from '@opentrons/components'
import type { ModalHeaderBaseProps, ModalSize } from '../Modal/types'

interface ModalProps {
interface ModalProps extends StyleProps {
/** clicking anywhere outside of the modal closes it */
onOutsideClick?: React.MouseEventHandler
/** modal content */
Expand All @@ -24,7 +25,13 @@ interface ModalProps {
header?: ModalHeaderBaseProps
}
export function Modal(props: ModalProps): JSX.Element {
const { modalSize = 'medium', onOutsideClick, children, header } = props
const {
modalSize = 'medium',
onOutsideClick,
children,
header,
...styleProps
} = props

let modalWidth: string = '45.625rem'
switch (modalSize) {
Expand Down Expand Up @@ -61,13 +68,7 @@ export function Modal(props: ModalProps): JSX.Element {
}}
>
{header != null ? (
<ModalHeader
title={header.title}
iconName={header.iconName}
iconColor={header.iconColor}
hasExitIcon={header.hasExitIcon}
onClick={onOutsideClick}
/>
<ModalHeader {...header} onClick={onOutsideClick} />
) : null}
<Flex
backgroundColor={COLORS.white}
Expand All @@ -79,6 +80,7 @@ export function Modal(props: ModalProps): JSX.Element {
? `0px 0px ${BORDERS.borderRadiusSize3} ${BORDERS.borderRadiusSize3}`
: BORDERS.borderRadiusSize3
}
{...styleProps}
>
{children}
</Flex>
Expand Down
10 changes: 9 additions & 1 deletion app/src/molecules/Modal/ModalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ import { StyledText } from '../../atoms/text'
import type { ModalHeaderBaseProps } from '../Modal/types'

export function ModalHeader(props: ModalHeaderBaseProps): JSX.Element {
const { title, hasExitIcon, iconName, iconColor, onClick } = props
const {
title,
hasExitIcon,
iconName,
iconColor,
onClick,
...styleProps
} = props
return (
<Flex
backgroundColor={COLORS.white}
Expand All @@ -26,6 +33,7 @@ export function ModalHeader(props: ModalHeaderBaseProps): JSX.Element {
justifyContent={JUSTIFY_SPACE_BETWEEN}
alignItems={ALIGN_CENTER}
borderRadius={`${BORDERS.borderRadiusSize3} ${BORDERS.borderRadiusSize3} 0px 0px`}
{...styleProps}
>
<Flex flexDirection={DIRECTION_ROW}>
{iconName != null && iconColor != null ? (
Expand Down
4 changes: 2 additions & 2 deletions app/src/molecules/Modal/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { IconName } from '@opentrons/components'
import type { IconName, StyleProps } from '@opentrons/components'

export type ModalSize = 'small' | 'medium' | 'large'

export interface ModalHeaderBaseProps {
export interface ModalHeaderBaseProps extends StyleProps {
title: string
onClick?: React.MouseEventHandler
hasExitIcon?: boolean
Expand Down
51 changes: 44 additions & 7 deletions app/src/organisms/InterventionModal/InterventionCommandMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,66 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { COLORS } from '@opentrons/components'
import { css } from 'styled-components'

import {
COLORS,
DIRECTION_COLUMN,
Flex,
RESPONSIVENESS,
SPACING,
TEXT_TRANSFORM_CAPITALIZE,
TEXT_TRANSFORM_UPPERCASE,
TYPOGRAPHY,
} from '@opentrons/components'
import { StyledText } from '../../atoms/text'

const INTERVENTION_COMMAND_STYLE = css`
flex-direction: ${DIRECTION_COLUMN};
grid-gap: ${SPACING.spacing4};
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
grid-gap: 0;
}
`

const INTERVENTION_COMMAND_NOTES_STYLE = css`
${TYPOGRAPHY.h6Default}
color: ${COLORS.errorDisabled};
text-transform: ${TEXT_TRANSFORM_UPPERCASE};
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
${TYPOGRAPHY.smallBodyTextBold}
color: ${COLORS.darkBlack100};
text-transform: ${TEXT_TRANSFORM_CAPITALIZE};
}
`

const INTERVENTION_COMMAND_MESSAGE_STYLE = css`
${TYPOGRAPHY.pRegular}
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
${TYPOGRAPHY.smallBodyTextRegular}
}
`

export interface InterventionCommandMessageProps {
commandMessage: string | null
}

export function InterventionCommandMessage({
commandMessage,
}: InterventionCommandMessageProps): JSX.Element {
const { t, i18n } = useTranslation('protocol_command_text')
const { t } = useTranslation('protocol_command_text')

return (
<>
<StyledText as="h6" color={COLORS.errorDisabled}>
{i18n.format(t('notes'), 'upperCase')}:
<Flex css={INTERVENTION_COMMAND_STYLE}>
<StyledText css={INTERVENTION_COMMAND_NOTES_STYLE}>
{t('notes')}
</StyledText>
<StyledText as="p">
<StyledText css={INTERVENTION_COMMAND_MESSAGE_STYLE}>
{commandMessage != null && commandMessage !== ''
? commandMessage.length > 220
? `${commandMessage.substring(0, 217)}...`
: commandMessage
: t('wait_for_resume')}
</StyledText>
</>
</Flex>
)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import * as React from 'react'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import { configReducer } from '../../redux/config/reducer'
import { mockRunData } from './__fixtures__'
import { InterventionModal as InterventionModalComponent } from './'

import type { Store } from 'redux'
import type { Story, Meta } from '@storybook/react'

const dummyConfig = {
config: {
isOnDevice: false,
},
} as any

const store: Store<any> = createStore(configReducer, dummyConfig)

const now = new Date()

const pauseCommand = {
Expand All @@ -22,7 +34,11 @@ export default {

const Template: Story<
React.ComponentProps<typeof InterventionModalComponent>
> = args => <InterventionModalComponent {...args} />
> = args => (
<Provider store={store}>
<InterventionModalComponent {...args} />
</Provider>
)

export const PauseIntervention = Template.bind({})
PauseIntervention.args = {
Expand Down
Loading

0 comments on commit a536c53

Please sign in to comment.