Skip to content

Commit b419be4

Browse files
committed
add functionality to change event for step
1 parent f1d7f21 commit b419be4

File tree

9 files changed

+111
-33
lines changed

9 files changed

+111
-33
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ const updateStep: MutationResolvers['updateStep'] = async (
3030
}
3131

3232
const shouldInvalidate =
33-
step.key !== input.key || step.appKey !== input.appKey
33+
step.key !== input.key ||
34+
step.appKey !== input.appKey ||
35+
step.connectionId !== input.connection.id
3436

3537
return await Step.query(trx)
3638
.patchAndFetchById(input.id, {

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ import { GET_FLOW } from '@/graphql/queries/get-flow'
4040
import { replacePlaceholdersForHelpMessage } from '@/helpers/flow-templates'
4141

4242
import EmptyFlowStepHeader from '../EmptyFlowStepHeader'
43-
import FlowStepConfigurationModal from '../FlowStepConfigurationModal'
43+
import FlowStepConfigurationModal, {
44+
type ModalScreen,
45+
} from '../FlowStepConfigurationModal'
4446
import { infoboxMdComponents } from '../MarkdownRenderer/CustomMarkdownComponents'
4547

4648
type FlowStepProps = {
@@ -123,6 +125,7 @@ export default function FlowStep(
123125
const displayOverrides = useContext(StepDisplayOverridesContext)?.[step.id]
124126

125127
const [currentSubstep, setCurrentSubstep] = useState<number | null>(0)
128+
const [initialScreen, setInitialScreen] = useState<ModalScreen>('choose-app')
126129

127130
const { data } = useQuery(GET_APPS)
128131

@@ -195,6 +198,16 @@ export default function FlowStep(
195198
[deleteStep, step.id],
196199
)
197200

201+
const isEditable = actionsOrTriggers.length > 1
202+
const onEditEvent = useCallback<MouseEventHandler>(
203+
(e) => {
204+
e.stopPropagation()
205+
setInitialScreen('choose-event')
206+
onModalOpen()
207+
},
208+
[onModalOpen],
209+
)
210+
198211
// define caption description based on app and step
199212
let caption = ''
200213
if (selectedActionOrTrigger?.name) {
@@ -252,7 +265,10 @@ export default function FlowStep(
252265
{!app || !selectedActionOrTrigger ? (
253266
<EmptyFlowStepHeader
254267
isTrigger={isTrigger}
255-
onModalOpen={onModalOpen}
268+
onModalOpen={() => {
269+
setInitialScreen('choose-app')
270+
onModalOpen()
271+
}}
256272
/>
257273
) : (
258274
<FlowStepHeader
@@ -271,6 +287,7 @@ export default function FlowStep(
271287
demoVideoUrl={app?.demoVideoDetails?.url}
272288
demoVideoTitle={app?.demoVideoDetails?.title}
273289
isInfoboxPresent={shouldShowInfobox}
290+
onEditEvent={isEditable ? onEditEvent : undefined}
274291
>
275292
<StepExecutionsProvider priorExecutionSteps={priorExecutionSteps}>
276293
<Form
@@ -286,7 +303,10 @@ export default function FlowStep(
286303
<ChooseConnectionSubstep
287304
step={step}
288305
application={app}
289-
onReconnect={onModalOpen}
306+
onReconnect={() => {
307+
setInitialScreen('choose-connection')
308+
onModalOpen()
309+
}}
290310
/>
291311
)}
292312

@@ -346,6 +366,7 @@ export default function FlowStep(
346366
step={step}
347367
app={app}
348368
event={selectedActionOrTrigger}
369+
initialScreen={initialScreen}
349370
/>
350371
)}
351372
</>

packages/frontend/src/components/FlowStepConfigurationModal/ChooseAndAddConnection/ChooseConnection.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import { useMutation, useQuery } from '@apollo/client'
66
import { Flex, ModalBody, ModalHeader } from '@chakra-ui/react'
77
import { Button, ModalCloseButton } from '@opengovsg/design-system-react'
88

9-
import { ModalState } from '@/components/FlowStepConfigurationModal'
9+
import type {
10+
ModalScreen,
11+
ModalState,
12+
} from '@/components/FlowStepConfigurationModal'
1013
import { EditorContext } from '@/contexts/Editor'
1114
import { REGISTER_CONNECTION } from '@/graphql/mutations/register-connection'
1215
import { TEST_CONNECTION } from '@/graphql/queries/test-connection'
@@ -28,6 +31,7 @@ interface ChooseConnectionProps {
2831
handleSubmit: () => void
2932
mockStep?: IStep
3033
step?: IStep
34+
initialScreen?: ModalScreen
3135
}
3236

3337
export default function ChooseConnection(
@@ -43,6 +47,7 @@ export default function ChooseConnection(
4347
handleSubmit,
4448
mockStep,
4549
step,
50+
initialScreen,
4651
} = props
4752
const editorContext = useContext(EditorContext)
4853
const supportsConnectionRegistration =
@@ -106,9 +111,8 @@ export default function ChooseConnection(
106111

107112
return (
108113
<>
109-
{/* Hide back button only if step has both the key and appKey */}
110114
<ModalHeader>
111-
{(!step?.key || !step?.appKey) && (
115+
{initialScreen !== 'choose-connection' && (
112116
<Button
113117
variant="clear"
114118
colorScheme="secondary"

packages/frontend/src/components/FlowStepConfigurationModal/ChooseAndAddConnection/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import { useMutation, useQuery } from '@apollo/client'
77
import { GET_OR_CREATE_MOCK_STEP } from '@/graphql/mutations/get-or-create-mock-step'
88
import { GET_APP_CONNECTIONS } from '@/graphql/queries/get-app-connections'
99

10+
import type { ModalScreen, ModalState } from '..'
1011
import { EXCEL_APP_KEY } from '../constants'
1112
import InvalidModalScreen from '../InvalidModalScreen'
12-
import { type ModalState } from '..'
1313

1414
import AddConnection from './AddConnection'
1515
import ChooseConnection from './ChooseConnection'
@@ -26,6 +26,7 @@ interface ChooseAndAddConnectionProps {
2626
connectionId?: string,
2727
) => Promise<IStep>
2828
step?: IStep
29+
initialScreen?: ModalScreen
2930
}
3031

3132
export type ConnectionDropdownOption = {
@@ -76,6 +77,7 @@ export default function ChooseAndAddConnection(
7677
step,
7778
onUpdateStep,
7879
onCreateStep,
80+
initialScreen,
7981
} = props
8082
const { currentScreen, selectedApp, selectedEvent, selectedConnectionId } =
8183
modalState
@@ -250,6 +252,7 @@ export default function ChooseAndAddConnection(
250252
handleSubmit={handleSubmit}
251253
mockStep={mockStep ?? undefined}
252254
step={step}
255+
initialScreen={initialScreen}
253256
/>
254257
)
255258
} else if (selectedApp && currentScreen === 'add-connection') {

packages/frontend/src/components/FlowStepConfigurationModal/ChooseAppAndEvent/ChooseEvent.tsx

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {
1414
useIsIfThenSelectable,
1515
} from '@/helpers/toolbox'
1616

17+
import { type ModalScreen } from '..'
18+
1719
import FeedbackFooter from './FeedbackFooter'
1820

1921
interface ChooseEventProps {
@@ -22,10 +24,18 @@ interface ChooseEventProps {
2224
isLastStep: boolean
2325
onSelectAppEvent: (app: IApp, event: ITrigger | IAction) => void
2426
onBack: () => void
27+
initialScreen?: ModalScreen
2528
}
2629

2730
export default function ChooseEvent(props: ChooseEventProps): JSX.Element {
28-
const { selectedApp, isTrigger, isLastStep, onSelectAppEvent, onBack } = props
31+
const {
32+
selectedApp,
33+
isTrigger,
34+
isLastStep,
35+
onSelectAppEvent,
36+
onBack,
37+
initialScreen,
38+
} = props
2939

3040
const launchDarkly = useContext(LaunchDarklyContext)
3141
const [_, isInitializingIfThen] = useIfThenInitializer()
@@ -57,18 +67,22 @@ export default function ChooseEvent(props: ChooseEventProps): JSX.Element {
5767
<>
5868
<ModalHeader>
5969
<Flex gap={2} flexDir="column" alignItems="flex-start">
60-
<Button
61-
variant="clear"
62-
colorScheme="secondary"
63-
size="xs"
64-
onClick={onBack}
65-
leftIcon={<BiChevronLeft />}
66-
ml={-4}
67-
>
68-
Back
69-
</Button>
70-
<Text textStyle="h3-semibold">{selectedApp.name}</Text>
71-
<Text textStyle="body-1">{selectedApp.description}</Text>
70+
{initialScreen !== 'choose-event' && (
71+
<Button
72+
variant="clear"
73+
colorScheme="secondary"
74+
size="xs"
75+
onClick={onBack}
76+
leftIcon={<BiChevronLeft />}
77+
ml={-4}
78+
>
79+
Back
80+
</Button>
81+
)}
82+
<Box mt={2}>
83+
<Text textStyle="h3-semibold">{selectedApp.name}</Text>
84+
<Text textStyle="body-1">{selectedApp.description}</Text>
85+
</Box>
7286
</Flex>
7387
</ModalHeader>
7488
<ModalCloseButton mt={2} size="xs" />

packages/frontend/src/components/FlowStepConfigurationModal/ChooseAppAndEvent/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {
1111
useIfThenInitializer,
1212
} from '@/helpers/toolbox'
1313

14+
import type { ModalScreen, ModalState } from '..'
1415
import { APP_ALLOWING_EMPTY_CONNECTION, EXCEL_APP_KEY } from '../constants'
1516
import InvalidModalScreen from '../InvalidModalScreen'
16-
import { type ModalState } from '..'
1717

1818
import ChooseApp from './ChooseApp'
1919
import ChooseEvent from './ChooseEvent'
@@ -31,6 +31,7 @@ type ChooseAppAndEventProps = {
3131
connectionId?: string,
3232
) => Promise<IStep>
3333
step?: IStep
34+
initialScreen?: ModalScreen
3435
}
3536

3637
export default function ChooseAppAndEvent(props: ChooseAppAndEventProps) {
@@ -43,6 +44,7 @@ export default function ChooseAppAndEvent(props: ChooseAppAndEventProps) {
4344
onUpdateStep,
4445
onCreateStep,
4546
step,
47+
initialScreen,
4648
} = props
4749
const { currentScreen, selectedApp } = modalState
4850

@@ -180,6 +182,7 @@ export default function ChooseAppAndEvent(props: ChooseAppAndEventProps) {
180182
currentScreen: 'choose-app',
181183
})
182184
}}
185+
initialScreen={initialScreen}
183186
/>
184187
)
185188
} else {

packages/frontend/src/components/FlowStepConfigurationModal/InvalidModalScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default function InvalidModalScreen(): JSX.Element {
88
<Flex flexDir="column" textAlign="center" gap={2}>
99
<Text textStyle="h4">Error</Text>
1010
<Text textStyle="body-1">
11-
This should not appear, please take a screenshot and submit to{' '}
11+
This should not appear, please send a screenshot with the pipe id to{' '}
1212
<Text as="a" href={SUPPORT_FORM_LINK} target="_blank">
1313
{SUPPORT_FORM_LINK}
1414
</Text>

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface FlowStepConfigurationModalProps {
2727
step?: IStep
2828
app?: IApp
2929
event?: ITrigger | IAction
30+
initialScreen?: ModalScreen
3031
}
3132

3233
export type ModalScreen =
@@ -47,12 +48,20 @@ export type ModalState = {
4748
export default function FlowStepConfigurationModal(
4849
props: FlowStepConfigurationModalProps,
4950
): JSX.Element {
50-
const { onClose, isTrigger, isLastStep, onCreateStep, step, app, event } =
51-
props
51+
const {
52+
onClose,
53+
isTrigger,
54+
isLastStep,
55+
onCreateStep,
56+
step,
57+
app,
58+
event,
59+
initialScreen,
60+
} = props
5261
const { flowId } = useParams()
5362
// Remember to always clear the selectedConnectionId when the modal is back to the first screen
5463
const [modalState, setModalState] = useState<ModalState>({
55-
currentScreen: app && event ? 'choose-connection' : 'choose-app',
64+
currentScreen: initialScreen ?? 'choose-app',
5665
selectedApp: app ?? null,
5766
selectedEvent: event ?? null,
5867
selectedConnectionId: step?.connection?.id ?? '',
@@ -106,6 +115,7 @@ export default function FlowStepConfigurationModal(
106115
onUpdateStep={onUpdateStep}
107116
onCreateStep={onCreateStep}
108117
step={step}
118+
initialScreen={initialScreen}
109119
/>
110120
)
111121
} else if (
@@ -121,6 +131,7 @@ export default function FlowStepConfigurationModal(
121131
onUpdateStep={onUpdateStep}
122132
onCreateStep={onCreateStep}
123133
step={step}
134+
initialScreen={initialScreen}
124135
/>
125136
)
126137
} else {
@@ -135,6 +146,7 @@ export default function FlowStepConfigurationModal(
135146
onUpdateStep,
136147
onCreateStep,
137148
step,
149+
initialScreen,
138150
])
139151

140152
return (

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from 'react'
99
import {
1010
BiArrowFromRight,
11+
BiEdit,
1112
BiHelpCircle,
1213
BiSolidCheckCircle,
1314
BiSolidErrorCircle,
@@ -52,6 +53,7 @@ interface FlowStepHeaderProps {
5253
demoVideoUrl?: string
5354
demoVideoTitle?: string
5455
isInfoboxPresent?: boolean
56+
onEditEvent?: MouseEventHandler
5557
}
5658

5759
const LOCAL_STORAGE_DEMO_TOOLTIP_KEY = 'demo-tooltip-clicked'
@@ -73,6 +75,7 @@ export default function FlowStepHeader(
7375
demoVideoUrl,
7476
demoVideoTitle,
7577
isInfoboxPresent,
78+
onEditEvent,
7679
} = props
7780

7881
const handleClick = useCallback(() => {
@@ -237,11 +240,27 @@ export default function FlowStepHeader(
237240
</Flex>
238241
</Flex>
239242

240-
{/*
241-
* Delete step button
242-
*/}
243-
{onDelete && (
244-
<Flex ml="auto">
243+
<Flex ml="auto" gap={2}>
244+
{onEditEvent && (
245+
<Tooltip
246+
label="Change event"
247+
placement="top-start"
248+
openDelay={300}
249+
gutter={0}
250+
>
251+
<IconButton
252+
onClick={onEditEvent}
253+
variant="clear"
254+
aria-label="Edit Event"
255+
icon={<BiEdit />}
256+
/>
257+
</Tooltip>
258+
)}
259+
260+
{/*
261+
* Delete step button
262+
*/}
263+
{onDelete && (
245264
<IconButton
246265
onClick={(event) => {
247266
onDialogOpen()
@@ -251,8 +270,8 @@ export default function FlowStepHeader(
251270
aria-label="Delete Step"
252271
icon={<BiTrashAlt />}
253272
/>
254-
</Flex>
255-
)}
273+
)}
274+
</Flex>
256275
</Flex>
257276

258277
{/*

0 commit comments

Comments
 (0)