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

refactor(app): add InterventionModal to Error Recovery #15277

Merged
merged 8 commits into from
May 29, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
refactor the interventionmodal to support new designs
mjhuff committed May 28, 2024
commit 192f12f3af5fdfbfbe306be753b15710a6e12da8
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ describe('InterventionModal', () => {

beforeEach(() => {
props = {
heading: 'mock intervention heading',
iconHeading: 'mock intervention heading',
children: 'mock intervention children',
iconName: 'alert-circle',
type: 'intervention-required',
55 changes: 43 additions & 12 deletions app/src/molecules/InterventionModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as React from 'react'
import { useSelector } from 'react-redux'

import {
ALIGN_CENTER,
BORDERS,
@@ -7,6 +9,7 @@ import {
Flex,
Icon,
JUSTIFY_CENTER,
JUSTIFY_SPACE_BETWEEN,
OVERFLOW_AUTO,
POSITION_ABSOLUTE,
POSITION_RELATIVE,
@@ -15,6 +18,8 @@ import {
} from '@opentrons/components'
import type { IconName } from '@opentrons/components'

import { getIsOnDevice } from '../../redux/config'

Comment on lines +21 to +22
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move this import before import type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh woops, I'll refactor this in my next PR 👍

export type ModalType = 'intervention-required' | 'error'

const BASE_STYLE = {
@@ -32,20 +37,29 @@ const BASE_STYLE = {

const BORDER_STYLE_BASE = `6px ${BORDERS.styleSolid}`

const MODAL_STYLE = {
const MODAL_BASE_STYLE = {
backgroundColor: COLORS.white,
position: POSITION_RELATIVE,
overflowY: OVERFLOW_AUTO,
maxHeight: '100%',
width: '47rem',
borderRadius: BORDERS.borderRadius8,
boxShadow: BORDERS.smallDropShadow,
'data-testid': '__otInterventionModal',
} as const

const MODAL_DESKTOP_STYLE = {
...MODAL_BASE_STYLE,
maxHeight: '100%',
width: '47rem',
} as const

const MODAL_ODD_STYLE = {
...MODAL_BASE_STYLE,
width: '62rem',
height: '35.5rem',
} as const

const HEADER_STYLE = {
alignItems: ALIGN_CENTER,
gridGap: SPACING.spacing12,
padding: `${SPACING.spacing20} ${SPACING.spacing32}`,
color: COLORS.white,
position: POSITION_STICKY,
@@ -69,8 +83,12 @@ const INTERVENTION_REQUIRED_COLOR = COLORS.blue50
const ERROR_COLOR = COLORS.red50

export interface InterventionModalProps {
/** optional modal heading **/
heading?: React.ReactNode
/** Optional modal title heading. Aligned to the left. */
titleHeading?: React.ReactNode
/** Optional modal heading right of the icon. Aligned right if titleHeading is supplied, otherwise aligned left. **/
iconHeading?: React.ReactNode
/** Optional onClick for the icon heading and icon. */
iconHeadingOnClick?: () => void
/** overall style hint */
type?: ModalType
/** optional icon name */
@@ -86,21 +104,34 @@ export function InterventionModal(props: InterventionModalProps): JSX.Element {
const border = `${BORDER_STYLE_BASE} ${
modalType === 'error' ? ERROR_COLOR : INTERVENTION_REQUIRED_COLOR
}`
const headerJustifyContent =
props.titleHeading != null ? JUSTIFY_SPACE_BETWEEN : undefined

const isOnDevice = useSelector(getIsOnDevice)
const modalStyle = isOnDevice ? MODAL_ODD_STYLE : MODAL_DESKTOP_STYLE

return (
<Flex {...WRAPPER_STYLE}>
<Flex {...BASE_STYLE} zIndex={10}>
<Box
{...MODAL_STYLE}
{...modalStyle}
border={border}
onClick={(e: React.MouseEvent) => {
e.stopPropagation()
}}
>
<Flex {...HEADER_STYLE} backgroundColor={headerColor}>
{props.iconName != null ? (
<Icon name={props.iconName} size={SPACING.spacing32} />
) : null}
{props.heading != null ? props.heading : null}
<Flex
{...HEADER_STYLE}
backgroundColor={headerColor}
justifyContent={headerJustifyContent}
>
{props.titleHeading}
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing12}>
{props.iconName != null ? (
<Icon name={props.iconName} size={SPACING.spacing32} />
) : null}
{props.iconHeading != null ? props.iconHeading : null}
</Flex>
</Flex>
{props.children}
</Box>