Skip to content

Commit 61a8fba

Browse files
committed
feat: frontend only - show approve reject button + refactor
1 parent 6a44877 commit 61a8fba

File tree

13 files changed

+102
-70
lines changed

13 files changed

+102
-70
lines changed

packages/backend/src/graphql/mutations/create-step.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ const createStep: MutationResolvers['createStep'] = async (
2222
input.key,
2323
)
2424

25-
if ('hiddenFromUser' in triggerOrAction && triggerOrAction.hiddenFromUser) {
25+
if (!triggerOrAction) {
26+
throw new BadUserInputError('No such trigger or action')
27+
}
28+
29+
if (triggerOrAction?.hiddenFromUser) {
2630
throw new BadUserInputError('Action can only be created by system')
2731
}
2832
}

packages/backend/src/models/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class App {
4141
static async findTriggerOrActionByKey(
4242
appKey: string,
4343
key: string,
44-
): Promise<ITrigger | IAction> {
44+
): Promise<ITrigger | IAction | null> {
4545
try {
4646
const app = await this.findOneByKey(appKey)
4747
return (

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Button, Link } from '@opengovsg/design-system-react'
88

99
import { EditorContext } from '@/contexts/Editor'
1010
import { TEST_CONNECTION } from '@/graphql/queries/test-connection'
11+
import { FORMSG_APP_KEY } from '@/helpers/formsg'
1112
import useAuthentication from '@/hooks/useAuthentication'
1213

1314
import {
@@ -111,7 +112,7 @@ function ChooseConnectionSubstep(
111112
const connectionOption = optionGenerator(connection, application.key)
112113

113114
let connectionLink: ConnectionLink | undefined
114-
if (application.key === 'formsg') {
115+
if (application.key === FORMSG_APP_KEY) {
115116
connectionLink = {
116117
url: formLinkGenerator(connectionOption),
117118
text: '(View form)',

packages/frontend/src/components/Editor/FlowStepWithAddButton.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { useContext, useMemo } from 'react'
55
import { EditorContext } from '@/contexts/Editor'
66
import { FlowStep } from '@/exports/components'
77
import { TOOLBOX_ACTIONS } from '@/helpers/toolbox'
8+
import { useStepMetadata } from '@/hooks/useStepMetadata'
9+
10+
import { ApproveReject } from '../FlowStep/components/ApproveReject'
811

912
import { AddStepButton } from './AddStepButton'
1013

@@ -23,7 +26,9 @@ export default function FlowStepWithAddButton({
2326
groupedSteps: IStep[][]
2427
showAddButton?: boolean
2528
}) {
26-
const { readOnly } = useContext(EditorContext)
29+
const { readOnly, allApps } = useContext(EditorContext)
30+
31+
const { isApprovalStep } = useStepMetadata(allApps, step)
2732

2833
const nonIfThenActionSteps = stepsBeforeGroup.filter(
2934
(step) => step.type === 'action' && step.key !== TOOLBOX_ACTIONS.IfThen,
@@ -59,12 +64,13 @@ export default function FlowStepWithAddButton({
5964
<>
6065
<FlowStep
6166
step={step}
62-
isDeletable={true}
6367
isLastStep={isLastStep}
6468
isNested={isNested}
6569
// only allow reordering if there are more than 1 action steps
6670
allowReorder={nonIfThenActionSteps.length > 1}
6771
/>
72+
{isApprovalStep && <ApproveReject />}
73+
6874
{showAddButton && (
6975
<AddStepButton {...getAddStepButtonProps(isLastStep, step.id)} />
7076
)}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useState } from 'react'
2+
import { Flex, Tab, TabList, TabProps, Tabs } from '@chakra-ui/react'
3+
4+
const tabStyle = (primaryColor: string): TabProps => {
5+
return {
6+
_selected: {
7+
color: 'white',
8+
bg: primaryColor,
9+
_hover: {
10+
color: 'white',
11+
},
12+
},
13+
_hover: {
14+
color: primaryColor,
15+
},
16+
letterSpacing: '0',
17+
fontWeight: 'medium',
18+
textTransform: 'none',
19+
px: 4,
20+
fontSize: 'medium',
21+
}
22+
}
23+
24+
export function ApproveReject() {
25+
const [isApprovedSelected, setIsApprovedSelected] = useState(true)
26+
27+
return (
28+
<Flex mt={4} mx="auto">
29+
<Tabs
30+
variant="soft-rounded"
31+
index={isApprovedSelected ? 0 : 1}
32+
backgroundColor="base.divider.medium"
33+
borderRadius="full"
34+
py={1}
35+
px={0.5}
36+
onChange={(index) => setIsApprovedSelected(index === 0)}
37+
>
38+
<TabList gap={2}>
39+
<Tab {...tabStyle('green.500')}>If approved</Tab>
40+
<Tab {...tabStyle('red.500')}>If rejected</Tab>
41+
</TabList>
42+
</Tabs>
43+
</Flex>
44+
)
45+
}

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Box, CircularProgress, Flex, useDisclosure } from '@chakra-ui/react'
66
import { Infobox } from '@opengovsg/design-system-react'
77

88
import { EditorContext } from '@/contexts/Editor'
9-
import { StepDisplayOverridesContext } from '@/contexts/StepDisplayOverrides'
109
import { MarkdownRenderer } from '@/exports/components'
1110
import { getFlowStepHeaderWidth } from '@/helpers/editor'
1211
import { replacePlaceholdersForHelpMessage } from '@/helpers/flow-templates'
@@ -31,7 +30,6 @@ import { flowStepStyles } from './styles'
3130

3231
type FlowStepProps = {
3332
step: IStep
34-
isDeletable?: boolean
3533
isLastStep: boolean
3634
isNested?: boolean
3735
allowReorder?: boolean
@@ -70,7 +68,6 @@ export default function FlowStep(
7068
setCurrentStepId,
7169
setShouldWarnOnLeave,
7270
} = useContext(EditorContext)
73-
const displayOverrides = useContext(StepDisplayOverridesContext)?.[step.id]
7471
const {
7572
app,
7673
caption,
@@ -79,6 +76,7 @@ export default function FlowStep(
7976
selectedActionOrTrigger,
8077
substeps,
8178
shouldShowDragHandle,
79+
isDeletable,
8280
} = useStepMetadata(
8381
allApps,
8482
step,
@@ -99,11 +97,6 @@ export default function FlowStep(
9997
onProceed: onModalOpen,
10098
})
10199

102-
const isDeletable =
103-
displayOverrides?.disableDelete === true
104-
? false
105-
: !readOnly && props.isDeletable
106-
107100
const { shouldTestStepAgain, isTestSuccessful } = useMemo(
108101
() => validateStepParams(step, testExecutionSteps, substeps),
109102
[step, substeps, testExecutionSteps],

packages/frontend/src/components/FlowStepGroup/components/GroupStepWithAddButton.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useContext } from 'react'
44

55
import { EditorContext } from '@/contexts/Editor'
66
import { FlowStep } from '@/exports/components'
7-
import { TOOLBOX_ACTIONS } from '@/helpers/toolbox'
87

98
import { HoverAddStepButton } from '../Content/IfThen/HoverAddStepButton'
109

@@ -27,20 +26,16 @@ export default function GroupStepWithAddButton(
2726
isLastStep,
2827
isOverlay,
2928
allowReorder,
29+
3030
showEmptyAction,
3131
canChildStepsReorder,
3232
} = props
3333
const { isDrawerOpen, readOnly } = useContext(EditorContext)
3434

35-
// cannot delete the condition step
36-
const isDeletable =
37-
step.key !== TOOLBOX_ACTIONS.IfThen && step.key !== TOOLBOX_ACTIONS.ForEach
38-
3935
return (
4036
<>
4137
<FlowStep
4238
step={step}
43-
isDeletable={isDeletable}
4439
// branch steps are always nested
4540
isNested={true}
4641
isLastStep={isLastStep}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import {
1515
} from '@chakra-ui/react'
1616
import { Button, IconButton, Menu } from '@opengovsg/design-system-react'
1717

18+
import {
19+
FORMSG_APP_KEY,
20+
FORMSG_TRIGGER_KEY,
21+
MRF_ACTION_KEY,
22+
} from '@/helpers/formsg'
23+
1824
interface CheckAgainButtonProps {
1925
isUnstyledInfobox: boolean
2026
onClick: (testRunMetadata?: Record<string, unknown>) => void
@@ -27,9 +33,9 @@ interface CheckAgainButtonProps {
2733
export function CheckAgainButton(props: CheckAgainButtonProps) {
2834
const { isUnstyledInfobox, onClick, isLoading, isDisabled, step } = props
2935
const isFormSgTrigger =
30-
step.appKey === 'formsg' && step.key === 'newSubmission'
36+
step.appKey === FORMSG_APP_KEY && step.key === FORMSG_TRIGGER_KEY
3137
const isFormSgAction =
32-
step.appKey === 'formsg' && step.key === 'mrfSubmission'
38+
step.appKey === FORMSG_APP_KEY && step.key === MRF_ACTION_KEY
3339

3440
if (isFormSgTrigger) {
3541
return <FormSGCheckAgainButton {...props} />

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,7 @@ function FlowSubstep(props: FlowSubstepProps): JSX.Element {
133133
const handleSaveAndTest = useCallback(
134134
async (testRunMetadata?: Record<string, unknown>) => {
135135
try {
136-
if (
137-
!selectedActionOrTrigger ||
138-
!('hiddenFromUser' in selectedActionOrTrigger) ||
139-
selectedActionOrTrigger.hiddenFromUser !== true
140-
) {
136+
if (!selectedActionOrTrigger?.hiddenFromUser) {
141137
await saveStep()
142138
}
143139
await executeTestStep({ testRunMetadata })

packages/frontend/src/contexts/StepDisplayOverrides.tsx

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)