-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app): add protocol analysis failed modal for RTP (#14705)
* feat(app): add protocol analysis failed modal for RTP
- Loading branch information
Showing
4 changed files
with
170 additions
and
1 deletion.
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
26 changes: 26 additions & 0 deletions
26
app/src/organisms/ProtocolSetupParameters/AnalysisFailed.stories.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,26 @@ | ||
import * as React from 'react' | ||
|
||
import { touchScreenViewport } from '../../DesignTokens/constants' | ||
import { AnalysisFailedModal } from './AnalysisFailedModal' | ||
|
||
import type { Story, Meta } from '@storybook/react' | ||
|
||
export default { | ||
title: 'ODD/Organisms/AnalysisFailedModal', | ||
component: AnalysisFailedModal, | ||
parameters: touchScreenViewport, | ||
} as Meta | ||
|
||
const Template: Story< | ||
React.ComponentProps<typeof AnalysisFailedModal> | ||
> = args => <AnalysisFailedModal {...args} /> | ||
|
||
export const AnalysisFailed = Template.bind({}) | ||
AnalysisFailed.args = { | ||
errors: [ | ||
'analysis failed reason message 1', | ||
'analysis failed reason message 2', | ||
], | ||
protocolId: 'mockProtocolId', | ||
setShowAnalysisFailedModal: () => {}, | ||
} |
77 changes: 77 additions & 0 deletions
77
app/src/organisms/ProtocolSetupParameters/AnalysisFailedModal.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,77 @@ | ||
import * as React from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { useHistory } from 'react-router-dom' | ||
import { | ||
BORDERS, | ||
COLORS, | ||
DIRECTION_COLUMN, | ||
Flex, | ||
SPACING, | ||
} from '@opentrons/components' | ||
|
||
import { StyledText } from '../../atoms/text' | ||
import { SmallButton } from '../../atoms/buttons' | ||
import { Modal } from '../../molecules/Modal' | ||
|
||
import type { ModalHeaderBaseProps } from '../../molecules/Modal/types' | ||
|
||
interface AnalysisFailedModalProps { | ||
errors: string[] | ||
protocolId: string | ||
setShowAnalysisFailedModal: (showAnalysisFailedModal: boolean) => void | ||
} | ||
|
||
export function AnalysisFailedModal({ | ||
errors, | ||
protocolId, | ||
setShowAnalysisFailedModal, | ||
}: AnalysisFailedModalProps): JSX.Element { | ||
const { t } = useTranslation('protocol_setup') | ||
const history = useHistory() | ||
const modalHeader: ModalHeaderBaseProps = { | ||
title: t('protocol_analysis_failed'), | ||
iconName: 'information', | ||
iconColor: COLORS.black90, | ||
hasExitIcon: true, | ||
} | ||
|
||
const handleRestartSetup = (): void => { | ||
history.push(`/protocols/${protocolId}`) | ||
} | ||
|
||
return ( | ||
<Modal | ||
header={modalHeader} | ||
onOutsideClick={() => setShowAnalysisFailedModal(false)} | ||
> | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing32} | ||
width="100%" | ||
> | ||
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing16}> | ||
<StyledText as="p">{t('with_the_chosen_value')}</StyledText> | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
borderRadius={BORDERS.borderRadius8} | ||
backgroundColor={COLORS.grey35} | ||
padding={`${SPACING.spacing16} ${SPACING.spacing20}`} | ||
overflowY="auto" | ||
> | ||
{errors.map((error, index) => ( | ||
<StyledText key={index} as="p"> | ||
{error} | ||
</StyledText> | ||
))} | ||
</Flex> | ||
<StyledText as="p">{t('restart_setup_and_try')}</StyledText> | ||
</Flex> | ||
<SmallButton | ||
onClick={handleRestartSetup} | ||
buttonText={t('restart_setup')} | ||
buttonType="alert" | ||
/> | ||
</Flex> | ||
</Modal> | ||
) | ||
} |
63 changes: 63 additions & 0 deletions
63
app/src/organisms/ProtocolSetupParameters/__tests__/AnalysisFailedModa.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,63 @@ | ||
import * as React from 'react' | ||
import { describe, it, vi, beforeEach, expect } from 'vitest' | ||
import { fireEvent, screen } from '@testing-library/react' | ||
|
||
import { renderWithProviders } from '../../../__testing-utils__' | ||
import { i18n } from '../../../i18n' | ||
import { AnalysisFailedModal } from '../AnalysisFailedModal' | ||
import type * as ReactRouterDom from 'react-router-dom' | ||
|
||
const mockPush = vi.fn() | ||
const PROTOCOL_ID = 'mockId' | ||
const mockSetShowAnalysisFailedModal = vi.fn() | ||
|
||
vi.mock('react-router-dom', async importOriginal => { | ||
const reactRouterDom = await importOriginal<typeof ReactRouterDom>() | ||
return { | ||
...reactRouterDom, | ||
useHistory: () => ({ push: mockPush } as any), | ||
} | ||
}) | ||
|
||
const render = (props: React.ComponentProps<typeof AnalysisFailedModal>) => { | ||
return renderWithProviders(<AnalysisFailedModal {...props} />, { | ||
i18nInstance: i18n, | ||
}) | ||
} | ||
|
||
describe('AnalysisFailedModal', () => { | ||
let props: React.ComponentProps<typeof AnalysisFailedModal> | ||
|
||
beforeEach(() => { | ||
props = { | ||
errors: [ | ||
'analysis failed reason message 1', | ||
'analysis failed reason message 2', | ||
], | ||
protocolId: PROTOCOL_ID, | ||
setShowAnalysisFailedModal: mockSetShowAnalysisFailedModal, | ||
} | ||
}) | ||
|
||
it('should render text and button', () => { | ||
render(props) | ||
screen.getByText('Protocol analysis failed') | ||
screen.getByText('With the chosen values, the following error occurred:') | ||
screen.getByText('analysis failed reason message 1') | ||
screen.getByText('analysis failed reason message 2') | ||
screen.getByText('Restart setup and try using different parameter values.') | ||
screen.getByText('Restart setup') | ||
}) | ||
|
||
it('should call a mock function when tapping close button', () => { | ||
render(props) | ||
fireEvent.click(screen.getByLabelText('closeIcon')) | ||
expect(mockSetShowAnalysisFailedModal).toHaveBeenCalled() | ||
}) | ||
|
||
it('should call a mock function when tapping restart setup button', () => { | ||
render(props) | ||
fireEvent.click(screen.getByText('Restart setup')) | ||
expect(mockPush).toHaveBeenCalledWith(`/protocols/${PROTOCOL_ID}`) | ||
}) | ||
}) |