Skip to content

Commit 8a016ec

Browse files
committed
chore: mostly refactor, add placeholder mrf context
1 parent 453b89b commit 8a016ec

File tree

7 files changed

+291
-177
lines changed

7 files changed

+291
-177
lines changed
Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { IStep } from '@plumber/types'
22

3-
import { useContext, useMemo } from 'react'
3+
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
import { useStepMetadata } from '@/hooks/useStepMetadata'
98

109
import { ApproveReject } from '../FlowStep/components/ApproveReject'
@@ -15,65 +14,44 @@ export default function FlowStepWithAddButton({
1514
step,
1615
isLastStep,
1716
isNested,
18-
stepsBeforeGroup,
19-
groupedSteps,
20-
showAddButton = true,
17+
addButtonProps: {
18+
isHidden = false,
19+
isDisabled = false,
20+
showEmptyAction = false,
21+
},
2122
}: {
2223
step: IStep
2324
isLastStep: boolean
2425
isNested?: boolean
2526
stepsBeforeGroup: IStep[]
2627
groupedSteps: IStep[][]
27-
showAddButton?: boolean
28+
addButtonProps: {
29+
isHidden: boolean
30+
isDisabled: boolean
31+
showEmptyAction: boolean
32+
}
2833
}) {
29-
const { readOnly, allApps } = useContext(EditorContext)
34+
const { allApps } = useContext(EditorContext)
3035

3136
const { isApprovalStep } = useStepMetadata(allApps, step)
3237

33-
const nonIfThenActionSteps = stepsBeforeGroup.filter(
34-
(step) => step.type === 'action' && step.key !== TOOLBOX_ACTIONS.IfThen,
35-
)
36-
37-
// Disables last add step and hide in-between add step buttons
38-
const hasExactlyOneEmptyActionStep =
39-
nonIfThenActionSteps.length === 1 && !nonIfThenActionSteps[0].appKey
40-
41-
// Disables last add step button but show empty action instead
42-
const hasNoActionSteps = nonIfThenActionSteps.length === 0
43-
44-
const getAddStepButtonProps = useMemo(() => {
45-
const shouldShowEmptyAction = hasNoActionSteps && !groupedSteps.length
46-
const shouldDisableButton =
47-
(hasExactlyOneEmptyActionStep || hasNoActionSteps) && !groupedSteps.length
48-
49-
return (isLastStep: boolean, stepId: string) => ({
50-
isHidden: readOnly,
51-
showEmptyAction: shouldShowEmptyAction,
52-
isDisabled: shouldDisableButton,
53-
isLastStep,
54-
stepId,
55-
})
56-
}, [
57-
readOnly,
58-
hasNoActionSteps,
59-
groupedSteps.length,
60-
hasExactlyOneEmptyActionStep,
61-
])
62-
6338
return (
6439
<>
6540
<FlowStep
6641
step={step}
6742
isLastStep={isLastStep}
6843
isNested={isNested}
6944
// only allow reordering if there are more than 1 action steps
70-
allowReorder={nonIfThenActionSteps.length > 1}
45+
allowReorder={true}
7146
/>
7247
{isApprovalStep && <ApproveReject />}
73-
74-
{showAddButton && (
75-
<AddStepButton {...getAddStepButtonProps(isLastStep, step.id)} />
76-
)}
48+
<AddStepButton
49+
isLastStep={isLastStep}
50+
stepId={step.id}
51+
isHidden={isHidden}
52+
isDisabled={isDisabled}
53+
showEmptyAction={showEmptyAction}
54+
/>
7755
</>
7856
)
7957
}

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

Lines changed: 103 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import EditorRightDrawer from '@/components/EditorRightDrawer'
77
import FlowStepGroup from '@/components/FlowStepGroup'
88
import { SortableList } from '@/components/SortableList'
99
import { EditorContext } from '@/contexts/Editor'
10+
import { MrfContextProvider } from '@/contexts/MrfContext'
1011
import { StepExecutionsToIncludeProvider } from '@/contexts/StepExecutionsToInclude'
1112
import { StepEnumType } from '@/graphql/__generated__/graphql'
1213
import { extractBranchesWithSteps, TOOLBOX_ACTIONS } from '@/helpers/toolbox'
@@ -25,7 +26,7 @@ type EditorProps = {
2526
export default function Editor(props: EditorProps): React.ReactElement {
2627
const { isNested } = props
2728

28-
const { allApps, isDrawerOpen, isMobile, currentStepId, flow } =
29+
const { allApps, isDrawerOpen, isMobile, flow, readOnly } =
2930
useContext(EditorContext)
3031

3132
const { handleReorderUpdate } = useReorderSteps(flow.id)
@@ -61,7 +62,7 @@ export default function Editor(props: EditorProps): React.ReactElement {
6162
)
6263
}, [appsWithActions])
6364

64-
const [triggerStep, stepsBeforeGroup, groupedSteps] = useMemo(() => {
65+
const [triggerStep, actionStepsBeforeGroup, groupedSteps] = useMemo(() => {
6566
if (!groupingActions) {
6667
return [null, [], []]
6768
}
@@ -100,34 +101,6 @@ export default function Editor(props: EditorProps): React.ReactElement {
100101
?.iconUrl
101102
}, [appsWithActions, groupedSteps])
102103

103-
//
104-
// Compute which steps are eligible for variable extraction.
105-
// Mainly for if-then branches where we do not want to include steps
106-
// from other branches.
107-
//
108-
// Note:
109-
// - we include some grouped steps as there is no longer a nested editor
110-
// - we identify the group by checking if the current step id is in the group
111-
// - for-each steps are always included
112-
const groupStepsToInclude = useMemo(() => {
113-
return groupedSteps.flatMap((group) =>
114-
group.some((step) => step.id === currentStepId) ||
115-
group.some((step) => step.key === TOOLBOX_ACTIONS.ForEach)
116-
? group
117-
: [],
118-
)
119-
}, [currentStepId, groupedSteps])
120-
121-
const stepExecutionsToInclude = useMemo(
122-
() =>
123-
new Set([
124-
...(triggerStep?.id ? [triggerStep.id] : []),
125-
...stepsBeforeGroup.map((step) => step.id),
126-
...groupStepsToInclude.map((s) => s.id),
127-
]),
128-
[triggerStep, stepsBeforeGroup, groupStepsToInclude],
129-
)
130-
131104
const handleReorderSteps = async (reorderedSteps: IStep[]) => {
132105
const stepPositions = reorderedSteps.map((step, index) => ({
133106
id: step.id,
@@ -146,6 +119,21 @@ export default function Editor(props: EditorProps): React.ReactElement {
146119
}
147120
}
148121

122+
const nonIfThenActionSteps = actionStepsBeforeGroup.filter(
123+
(step) => step.key !== TOOLBOX_ACTIONS.IfThen,
124+
)
125+
126+
// Disables last add step and hide in-between add step buttons
127+
const hasExactlyOneEmptyActionStep =
128+
nonIfThenActionSteps.length === 1 && !nonIfThenActionSteps[0].appKey
129+
130+
// Disables last add step button but show empty action instead
131+
const hasNoActionSteps = nonIfThenActionSteps.length === 0
132+
const shouldShowEmptyAction = hasNoActionSteps && !groupedSteps.length
133+
// for backwards compatibility where empty step is created
134+
const shouldDisableAddButton =
135+
(hasExactlyOneEmptyActionStep || hasNoActionSteps) && !groupedSteps.length
136+
149137
if (!appsWithActions || !groupingActions) {
150138
return (
151139
<Center height="100vh" position="fixed" width="full" top={0} left={0}>
@@ -172,80 +160,95 @@ export default function Editor(props: EditorProps): React.ReactElement {
172160
backgroundSize: '30px 30px',
173161
}}
174162
>
175-
<StepExecutionsToIncludeProvider value={stepExecutionsToInclude}>
176-
<Flex
177-
{...editorStyles.stepHeaderContainer}
178-
flex={isDrawerOpen ? (isMobile ? 0 : 1) : undefined}
179-
px={leftStepPadding}
180-
maxWidth={`calc(100% - ${
181-
isDrawerOpen ? EDITOR_RIGHT_DRAWER_WIDTH : '0px'
182-
})`}
163+
<MrfContextProvider steps={steps}>
164+
<StepExecutionsToIncludeProvider
165+
groupedSteps={groupedSteps}
166+
triggerStep={triggerStep}
167+
actionStepsBeforeGroup={actionStepsBeforeGroup}
183168
>
184-
{triggerStep && (
185-
<FlowStepWithAddButton
186-
step={triggerStep}
187-
isLastStep={
188-
stepsBeforeGroup.length === 0 && groupedSteps.length === 0
189-
}
190-
isNested={isNested}
191-
stepsBeforeGroup={stepsBeforeGroup}
192-
groupedSteps={groupedSteps}
193-
showAddButton={true}
169+
<Flex
170+
{...editorStyles.stepHeaderContainer}
171+
flex={isDrawerOpen ? (isMobile ? 0 : 1) : undefined}
172+
px={leftStepPadding}
173+
maxWidth={`calc(100% - ${
174+
isDrawerOpen ? EDITOR_RIGHT_DRAWER_WIDTH : '0px'
175+
})`}
176+
>
177+
{triggerStep && (
178+
<FlowStepWithAddButton
179+
step={triggerStep}
180+
isLastStep={
181+
actionStepsBeforeGroup.length === 0 &&
182+
groupedSteps.length === 0
183+
}
184+
isNested={isNested}
185+
stepsBeforeGroup={[]} // no reason to pass in for this
186+
groupedSteps={groupedSteps}
187+
addButtonProps={{
188+
isHidden: readOnly,
189+
isDisabled: shouldDisableAddButton,
190+
showEmptyAction: shouldShowEmptyAction,
191+
}}
192+
/>
193+
)}
194+
195+
<SortableList
196+
items={actionStepsBeforeGroup}
197+
onChange={handleReorderSteps}
198+
renderItem={(step, isOverlay) => {
199+
const { id, position } = step
200+
return (
201+
<SortableList.Item id={id}>
202+
<Flex
203+
key={`${id}-${position}`}
204+
width={isDrawerOpen || isMobile ? '100%' : 'auto'}
205+
flexDir="column"
206+
position="relative"
207+
>
208+
<FlowStepWithAddButton
209+
step={step}
210+
isLastStep={position === steps.length}
211+
isNested={isNested}
212+
stepsBeforeGroup={actionStepsBeforeGroup}
213+
groupedSteps={groupedSteps}
214+
addButtonProps={{
215+
isHidden: readOnly || !!isOverlay,
216+
isDisabled: shouldDisableAddButton,
217+
showEmptyAction: shouldShowEmptyAction,
218+
}}
219+
/>
220+
</Flex>
221+
</SortableList.Item>
222+
)
223+
}}
194224
/>
195-
)}
196-
197-
<SortableList
198-
items={stepsBeforeGroup}
199-
onChange={handleReorderSteps}
200-
renderItem={(step, isOverlay) => {
201-
const { id, position } = step
202-
return (
203-
<SortableList.Item id={id}>
204-
<Flex
205-
key={`${id}-${position}`}
206-
width={isDrawerOpen || isMobile ? '100%' : 'auto'}
207-
flexDir="column"
208-
position="relative"
209-
>
210-
<FlowStepWithAddButton
211-
step={step}
212-
isLastStep={position === steps.length}
213-
isNested={isNested}
214-
stepsBeforeGroup={stepsBeforeGroup}
215-
groupedSteps={groupedSteps}
216-
showAddButton={!isOverlay}
217-
/>
218-
</Flex>
219-
</SortableList.Item>
220-
)
221-
}}
225+
{groupedSteps.length > 0 && (
226+
<FlowStepGroup
227+
stepsBeforeGroup={actionStepsBeforeGroup}
228+
groupedSteps={groupedSteps}
229+
/>
230+
)}
231+
</Flex>
232+
{/** HACKFIX (kevinkim-ogp): to ensure that the transitions are smooth */}
233+
<Flex
234+
{...editorStyles.dummyRightContainer}
235+
w={rightDrawerWidth}
236+
transform={rightDrawerTransform}
222237
/>
223-
{groupedSteps.length > 0 && (
224-
<FlowStepGroup
225-
stepsBeforeGroup={stepsBeforeGroup}
226-
groupedSteps={groupedSteps}
238+
<Flex
239+
{...editorStyles.rightDrawerContainer}
240+
w={rightDrawerWidth}
241+
visibility={isDrawerOpen ? 'visible' : 'hidden'}
242+
opacity={isDrawerOpen ? 1 : 0}
243+
transform={rightDrawerTransform}
244+
>
245+
<EditorRightDrawer
246+
flowStepGroupIconUrl={flowStepGroupIconUrl}
247+
steps={steps}
227248
/>
228-
)}
229-
</Flex>
230-
{/** HACKFIX (kevinkim-ogp): to ensure that the transitions are smooth */}
231-
<Flex
232-
{...editorStyles.dummyRightContainer}
233-
w={rightDrawerWidth}
234-
transform={rightDrawerTransform}
235-
/>
236-
<Flex
237-
{...editorStyles.rightDrawerContainer}
238-
w={rightDrawerWidth}
239-
visibility={isDrawerOpen ? 'visible' : 'hidden'}
240-
opacity={isDrawerOpen ? 1 : 0}
241-
transform={rightDrawerTransform}
242-
>
243-
<EditorRightDrawer
244-
flowStepGroupIconUrl={flowStepGroupIconUrl}
245-
steps={steps}
246-
/>
247-
</Flex>
248-
</StepExecutionsToIncludeProvider>
249+
</Flex>
250+
</StepExecutionsToIncludeProvider>
251+
</MrfContextProvider>
249252
</Flex>
250253
)
251254
}

packages/frontend/src/components/EditorRightDrawer/Step.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import FlowSubstep from '@/components/FlowSubstep'
88
import Form from '@/components/Form'
99
import { EditorContext } from '@/contexts/Editor'
1010
import { StepExecutionsProvider } from '@/contexts/StepExecutions'
11-
import { StepExecutionsToIncludeContext } from '@/contexts/StepExecutionsToInclude'
1211
import { generateValidationSchema } from '@/helpers/editor'
1312
import { useStepMetadata } from '@/hooks/useStepMetadata'
1413

@@ -30,20 +29,7 @@ export default function Step(props: StepProps): React.ReactElement | null {
3029
onClose: onModalClose,
3130
} = useDisclosure()
3231

33-
const { allApps, onUpdateStep, testExecutionSteps, resetTimestamp } =
34-
useContext(EditorContext)
35-
36-
// This includes all steps that run even after the current step, but within the same branch.
37-
const stepExecutionsToInclude = useContext(StepExecutionsToIncludeContext)
38-
const priorExecutionSteps = useMemo(
39-
() =>
40-
testExecutionSteps.filter(
41-
(stepExecution) =>
42-
stepExecutionsToInclude?.has(stepExecution.stepId) &&
43-
stepExecution.step.position < step.position,
44-
),
45-
[step.position, stepExecutionsToInclude, testExecutionSteps],
46-
)
32+
const { allApps, onUpdateStep, resetTimestamp } = useContext(EditorContext)
4733

4834
const { app, hasConnection, isTrigger, selectedActionOrTrigger, substeps } =
4935
useStepMetadata(allApps, step)
@@ -67,7 +53,7 @@ export default function Step(props: StepProps): React.ReactElement | null {
6753
return (
6854
<>
6955
<Flex w="100%" flexDir="column">
70-
<StepExecutionsProvider priorExecutionSteps={priorExecutionSteps}>
56+
<StepExecutionsProvider currentStep={step}>
7157
<Form
7258
key={`${step.id}-${resetTimestamp}`}
7359
defaultValues={step}

0 commit comments

Comments
 (0)