Skip to content

Commit d6a01f3

Browse files
authored
[REMOCK-4] PLU-471: check step again button for formsg (#1063)
## Summary Frontend implementation for FormSG check step ![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/ycT2Xb5nBEjN2kf2gy95/762dd4b7-86be-4351-9858-38b0f3b37dab.png) ### What changed? - Created a new `CheckAgainButton` component that provides specialized functionality for FormSG triggers (hardcoded for formsg for now) ### How to test? 1. Connect a fresh form 2. Click "Check step" 3. Verify that the "Check step again" button appears initially 4. After making a test submission, click on "Check step again" 5. Verify that the button text changes to "Check with last submission" 6. Test toggling between mock and real data using the dropdown menu 7. Verify that the UI is responsive on both desktop and mobile views 8. Verify that actual submission when the pipe is published is not shown here.
1 parent 4c8f492 commit d6a01f3

File tree

7 files changed

+327
-148
lines changed

7 files changed

+327
-148
lines changed

packages/frontend/src/components/EditorLayout/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ export default function EditorLayout() {
220220
value={flow?.name}
221221
onSave={onFlowNameUpdate}
222222
readOnly={loading}
223-
width={isMobile ? '40%' : undefined}
223+
width="auto"
224224
/>
225225
</Flex>
226226
</Flex>
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import { IExecutionStepMetadata, IStep } from '@plumber/types'
2+
3+
import { useCallback, useMemo } from 'react'
4+
import { IconType } from 'react-icons'
5+
import { BiChevronDown } from 'react-icons/bi'
6+
import { PiRobot, PiUser } from 'react-icons/pi'
7+
import {
8+
ButtonGroup,
9+
Flex,
10+
Icon,
11+
MenuButton,
12+
MenuItem,
13+
MenuList,
14+
Text,
15+
} from '@chakra-ui/react'
16+
import { Button, IconButton, Menu } from '@opengovsg/design-system-react'
17+
18+
interface CheckAgainButtonProps {
19+
isUnstyledInfobox: boolean
20+
onClick: (testRunMetadata?: Record<string, unknown>) => void
21+
isLoading: boolean
22+
isDisabled: boolean
23+
step: IStep
24+
executionStepMetadata?: IExecutionStepMetadata
25+
}
26+
27+
export function CheckAgainButton(props: CheckAgainButtonProps) {
28+
const { isUnstyledInfobox, onClick, isLoading, isDisabled, step } = props
29+
const isFormSgTrigger =
30+
step.appKey === 'formsg' && step.key === 'newSubmission'
31+
if (isFormSgTrigger) {
32+
return <FormSGCheckAgainButton {...props} />
33+
}
34+
return (
35+
<Button
36+
variant={isUnstyledInfobox ? 'solid' : 'outline'}
37+
onClick={() => onClick()}
38+
isLoading={isLoading}
39+
colorScheme={isUnstyledInfobox ? 'primary' : 'black'}
40+
size="sm"
41+
isDisabled={isDisabled}
42+
data-test="check-again-button"
43+
>
44+
Check step again
45+
</Button>
46+
)
47+
}
48+
49+
/**
50+
* For UX reasons, we need to have a different button for FormSG.
51+
* The user flow goes like this:
52+
* - If user first connects the form, the button should be "Check step again"
53+
* and display only mock data (no dropdown button)
54+
* - After the real submission is made, the button should be "Check again with submission"
55+
* and display the dropdown button and real submission data
56+
* - If the user clicks on the dropdown button and select "Use mock data",
57+
* the button should still show the dropdown and allow user to toggle between mock and real data
58+
*/
59+
60+
interface FormSGMenuItemProps {
61+
icon: IconType
62+
title: string
63+
description: string
64+
isSelected: boolean
65+
onClick: () => void
66+
}
67+
68+
function FormSGMenuItem({
69+
icon,
70+
title,
71+
description,
72+
isSelected,
73+
onClick,
74+
}: FormSGMenuItemProps) {
75+
return (
76+
<MenuItem
77+
display="block"
78+
bg={isSelected ? 'primary.50' : undefined}
79+
_hover={{
80+
bg: 'grey.100',
81+
}}
82+
onClick={onClick}
83+
>
84+
<Flex alignItems="center" gap={2}>
85+
<Icon as={icon} fontSize={20} mb={0.5} />
86+
<Text textStyle="body-1">{title}</Text>
87+
</Flex>
88+
<Text textStyle="body-2" mt={1} color="secondary.500">
89+
{description}
90+
</Text>
91+
</MenuItem>
92+
)
93+
}
94+
95+
function FormSGCheckAgainButton(props: CheckAgainButtonProps) {
96+
const {
97+
isUnstyledInfobox: isTransparentInfobox,
98+
onClick,
99+
isLoading,
100+
isDisabled,
101+
executionStepMetadata,
102+
} = props
103+
104+
const { isMock = false, lastTestSubmissionDate } = executionStepMetadata ?? {}
105+
106+
const buttonText = useMemo(() => {
107+
if (!lastTestSubmissionDate) {
108+
return <Text>Check step again</Text>
109+
}
110+
if (isMock) {
111+
return (
112+
<>
113+
<Icon as={PiRobot} fontSize={20} mb={0.5} />
114+
<Text>Check with mock data</Text>
115+
</>
116+
)
117+
} else {
118+
return (
119+
<>
120+
<Icon as={PiUser} fontSize={20} mb={0.5} />
121+
<Text>Check with last submission</Text>
122+
</>
123+
)
124+
}
125+
}, [lastTestSubmissionDate, isMock])
126+
127+
const onTestClick = useCallback(() => {
128+
if (!lastTestSubmissionDate) {
129+
return onClick()
130+
}
131+
if (isMock) {
132+
return onClick({ preferMock: true })
133+
}
134+
return onClick({ preferMock: false })
135+
}, [lastTestSubmissionDate, isMock, onClick])
136+
137+
return (
138+
<ButtonGroup
139+
isAttached
140+
isDisabled={isDisabled}
141+
size="sm"
142+
variant={isTransparentInfobox ? 'solid' : 'outline'}
143+
colorScheme={isTransparentInfobox ? 'primary' : 'black'}
144+
>
145+
<Button
146+
onClick={onTestClick}
147+
isLoading={isLoading}
148+
gap={2}
149+
data-test="formsg-check-again-button"
150+
>
151+
{buttonText}
152+
</Button>
153+
{lastTestSubmissionDate && (
154+
<Menu gutter={0} colorScheme="grey">
155+
<MenuButton
156+
as={IconButton}
157+
icon={<BiChevronDown />}
158+
isLoading={isLoading}
159+
data-test="formsg-check-again-button-dropdown"
160+
/>
161+
<MenuList maxW="350px">
162+
<FormSGMenuItem
163+
onClick={() => onClick({ preferMock: true })}
164+
icon={PiRobot}
165+
title="Use mock data"
166+
description="Mock responses will be generated based on your form fields"
167+
isSelected={isMock}
168+
/>
169+
<FormSGMenuItem
170+
onClick={() => onClick({ preferMock: false })}
171+
icon={PiUser}
172+
title="Use last submission"
173+
description="The last form submission when this pipe is unpublished will be used"
174+
isSelected={!isMock}
175+
/>
176+
</MenuList>
177+
</Menu>
178+
)}
179+
</ButtonGroup>
180+
)
181+
}

packages/frontend/src/components/FlowStepTestController/TestResult.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export default function TestResult(props: TestResultsProps): JSX.Element {
8484
return (
8585
<Box w="100%">
8686
{isMock && (
87-
<Infobox variant="info">
87+
<Infobox variant="info" style={{ paddingLeft: '24px' }}>
8888
<Text>{getMockDataMessage(selectedActionOrTrigger)}</Text>
8989
</Infobox>
9090
)}

0 commit comments

Comments
 (0)