Skip to content

Commit ffbdd0c

Browse files
committed
chore: allow ifthen and foreach in different branches
1 parent 65a2c41 commit ffbdd0c

File tree

4 files changed

+49
-67
lines changed

4 files changed

+49
-67
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export default function DuplicateStepButton(props: DuplicateStepButtonProps) {
2323
const { flow, isMobile, onDrawerOpen, setCurrentStepId } =
2424
useContext(EditorContext)
2525

26+
// TODO: use onCreateStep from EditorContext instead
2627
const [createStep] = useMutation(CREATE_STEP, { refetchQueries: [GET_FLOW] })
2728
const onDuplicateStep = useCallback(async () => {
2829
const duplicateConfig = {
Lines changed: 32 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { IFlow, IStep } from '@plumber/types'
1+
import { IStep } from '@plumber/types'
22

33
import { useContext } from 'react'
44

55
import { BranchContext } from '@/components/FlowStepGroup/Content/IfThen/BranchContext'
66
import { NESTED_IFTHEN_FEATURE_FLAG } from '@/config/flags'
7-
import { EditorContext } from '@/contexts/Editor'
87
import { LaunchDarklyContext } from '@/contexts/LaunchDarkly'
8+
import { StepsToDisplayContext } from '@/contexts/StepsToDisplay'
99
import { TOOLBOX_ACTIONS } from '@/helpers/toolbox'
1010

1111
/**
@@ -16,68 +16,26 @@ import { TOOLBOX_ACTIONS } from '@/helpers/toolbox'
1616
*
1717
*/
1818
function isDelaySelectable({
19-
flow,
19+
hasForEach,
20+
groupedSteps,
2021
step,
2122
prevStepId,
2223
}: {
23-
flow: IFlow
24+
hasForEach: boolean
25+
groupedSteps: IStep[][]
2426
step?: IStep
2527
prevStepId?: string
2628
}) {
27-
const forEachStepPosition = flow?.steps.find(
28-
(s) => s.key === TOOLBOX_ACTIONS.ForEach,
29-
)?.position
30-
31-
let prevStepPosition = null
32-
if (step) {
33-
prevStepPosition = step.position
34-
} else if (prevStepId) {
35-
prevStepPosition = flow?.steps?.find((s) => s.id === prevStepId)?.position
36-
}
37-
38-
let isDelaySelectable: boolean
39-
if (!forEachStepPosition) {
40-
isDelaySelectable = true
41-
} else if (forEachStepPosition && prevStepPosition) {
42-
isDelaySelectable = prevStepPosition < forEachStepPosition
43-
} else {
44-
isDelaySelectable = false
29+
if (!hasForEach) {
30+
return true
4531
}
46-
47-
return isDelaySelectable
48-
}
49-
50-
/**
51-
* Helper function to check if For-each action should be selectable; supports edge
52-
* case in ChooseEvent component.
53-
*
54-
* For-each should only be selectable if:
55-
* - We're the last step.
56-
* - We are not inside a for-each action.
57-
* - We are not inside an if-then action.
58-
* - There is no if-then action in the flow,
59-
*
60-
* Using many consts as purpose of the conditions may not be immediately
61-
* apparent.
62-
*/
63-
function isForEachSelectable({
64-
flow,
65-
hasIfThen,
66-
isLastStep,
67-
}: {
68-
flow: IFlow
69-
hasIfThen: boolean
70-
isLastStep: boolean
71-
}) {
72-
const hasForEach = flow?.steps?.some(
73-
(step: IStep) => step.key === TOOLBOX_ACTIONS.ForEach,
74-
)
75-
76-
if (hasForEach || hasIfThen || !isLastStep) {
32+
const isStepWithinForEach = groupedSteps.flat().some((groupedStep) => {
33+
if (step?.id === groupedStep.id || prevStepId === groupedStep.id) {
34+
return true
35+
}
7736
return false
78-
}
79-
80-
return true
37+
})
38+
return !isStepWithinForEach
8139
}
8240

8341
/**
@@ -116,6 +74,7 @@ function isIfThenSelectable({
11674
}
11775

11876
const isNestedBranch = depth > 0
77+
11978
return !isNestedBranch
12079
}
12180

@@ -129,21 +88,31 @@ export const useIsAppSelectable = ({
12988
prevStepId?: string
13089
}): Record<string, boolean> => {
13190
const { depth } = useContext(BranchContext)
132-
const { flow, hasIfThen } = useContext(EditorContext)
91+
const { groupedSteps } = useContext(StepsToDisplayContext)
13392
const { getFlagValue } = useContext(LaunchDarklyContext)
13493

94+
const hasIfThen = groupedSteps.some((group) =>
95+
group.some((step) => step.key === TOOLBOX_ACTIONS.IfThen),
96+
)
97+
98+
const hasForEach = groupedSteps.some((group) =>
99+
group.some((step) => step.key === TOOLBOX_ACTIONS.ForEach),
100+
)
101+
135102
return {
136103
[TOOLBOX_ACTIONS.IfThen]: isIfThenSelectable({
137104
depth,
138105
hasIfThen,
139106
isLastStep,
140107
getFlagValue,
141108
}),
142-
[TOOLBOX_ACTIONS.ForEach]: isForEachSelectable({
143-
flow,
144-
hasIfThen,
145-
isLastStep,
146-
}),
147-
delay: isDelaySelectable({ flow, step, prevStepId }),
109+
/**
110+
* For-each should only be selectable if:
111+
* - We're the last step.
112+
* - There's no other for-each action
113+
* - There's no other if-then action
114+
*/
115+
[TOOLBOX_ACTIONS.ForEach]: isLastStep && !hasIfThen && !hasForEach,
116+
delay: isDelaySelectable({ hasForEach, groupedSteps, step, prevStepId }),
148117
}
149118
}

packages/frontend/src/components/FlowStepGroup/Content/IfThen/index.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import { Flex } from '@chakra-ui/react'
77
import { Button } from '@opengovsg/design-system-react'
88

99
import { EditorContext } from '@/contexts/Editor'
10+
import { MrfContext } from '@/contexts/MrfContext'
1011
import { CREATE_STEP } from '@/graphql/mutations/create-step'
1112
import { GET_FLOW } from '@/graphql/queries/get-flow'
13+
import { getMrfApprovalConfig } from '@/helpers/formsg'
1214
import { TOOLBOX_ACTIONS, TOOLBOX_APP_KEY } from '@/helpers/toolbox'
1315

1416
import Branch from './Branch'
@@ -24,6 +26,7 @@ export default function IfThen(props: IfThenProps): JSX.Element {
2426
const { groupedSteps, stepsBeforeGroup } = props
2527

2628
const { depth } = useContext(BranchContext)
29+
const { approvalBranches } = useContext(MrfContext)
2730
const {
2831
flow,
2932
flowId,
@@ -51,6 +54,11 @@ export default function IfThen(props: IfThenProps): JSX.Element {
5154
const lastGroup = groupedSteps[groupedSteps.length - 1]
5255
const lastStep = lastGroup[lastGroup.length - 1]
5356

57+
const approvalConfig = getMrfApprovalConfig({
58+
previousStep: lastStep,
59+
approvalBranches,
60+
})
61+
5462
const branchStep = await createStep({
5563
variables: {
5664
input: {
@@ -67,6 +75,9 @@ export default function IfThen(props: IfThenProps): JSX.Element {
6775
depth,
6876
branchName: `Branch ${numBranches + 1}`,
6977
},
78+
config: {
79+
approval: approvalConfig,
80+
},
7081
},
7182
},
7283
})
@@ -83,6 +94,9 @@ export default function IfThen(props: IfThenProps): JSX.Element {
8394
id: flowId,
8495
updatedAt: branchStep.data.createStep.flow.updatedAt,
8596
},
97+
config: {
98+
approval: approvalConfig,
99+
},
86100
},
87101
},
88102
})
@@ -95,6 +109,7 @@ export default function IfThen(props: IfThenProps): JSX.Element {
95109
createStep,
96110
flowId,
97111
depth,
112+
approvalBranches,
98113
numBranches,
99114
onDrawerOpen,
100115
setCurrentStepId,

packages/frontend/src/hooks/useStepMetadata.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,8 @@ export function useStepMetadata(
119119
break
120120
}
121121
}
122-
// if is approval step, return whether
122+
// this means that the step is after the trigger step
123123
if (!immediatePriorMrfStep) {
124-
console.warn(
125-
'No immediate prior mrf step found... this should not happen tho',
126-
)
127124
return null
128125
}
129126
/**

0 commit comments

Comments
 (0)