@@ -56,15 +56,20 @@ export async function createMrfSteps(
5656 const deletedStep = await Step . query ( trx ) . patchAndFetchById ( step . id , {
5757 deletedAt : new Date ( ) . toISOString ( ) ,
5858 } )
59- // Shift up all steps after the deleted one
59+ // Delete all steps in the reject branch
6060 await Step . query ( trx )
6161 . where ( 'flow_id' , $ . flow . id )
6262 . where ( 'position' , '>' , deletedStep . position )
63- . decrement ( 'position' , 1 )
63+ . andWhereRaw ( `steps.config->'approval'->>'stepId' = ?` , [
64+ deletedStep . id ,
65+ ] )
66+ . delete ( )
6467 }
6568
66- // we start from after the trigger step first
67- let newStepPosition = 2
69+ let newMrfStepPositionToInsert = 2
70+ // Track all the newly added mrf step positions
71+ const newMrfSteps = [ ]
72+
6873 // Create or update steps for each action
6974 for ( let i = 0 ; i < actions . length ; i ++ ) {
7075 const action = actions [ i ]
@@ -96,29 +101,80 @@ export async function createMrfSteps(
96101 ) ,
97102 } ,
98103 )
99- newStepPosition = updatedStep . position + 1
104+ // there could be a case where it changed from an approval step to a normal steps
105+ if ( ! action . approvalField ) {
106+ // Delete all steps in the reject branch (if any)
107+ await Step . query ( trx )
108+ . where ( 'flow_id' , $ . flow . id )
109+ . where ( 'position' , '>' , updatedStep . position )
110+ . andWhereRaw ( `steps.config->'approval'->>'stepId' = ?` , [
111+ updatedStep . id ,
112+ ] )
113+ . delete ( )
114+ }
115+ newMrfStepPositionToInsert = updatedStep . position + 1
116+ continue
117+ }
118+ // Create new mrf steps after the last created mrf step (if any)
119+ const newStep = await Step . query ( trx ) . insert ( {
120+ flowId : $ . flow . id ,
121+ type : 'action' ,
122+ appKey : MRF_APP_KEY ,
123+ key : MRF_KEY ,
124+ position : newMrfStepPositionToInsert ,
125+ connectionId : updatedTriggerStep . connectionId ,
126+ parameters,
127+ config : {
128+ stepName,
129+ } ,
130+ } )
131+ newMrfSteps . push ( newStep )
132+ newMrfStepPositionToInsert = newStep . position + 1
133+ }
134+
135+ /**
136+ * Handle steps after the last newly created mrf step
137+ * CAVEAT: this relies heavily on the fact that new MRF steps are always added at the end of the formsg workflow
138+ * If last created mrf step has approval field, we need to update the steps in the reject branch to point to the last created mrf step
139+ * If last created mrf step does not have approval field, we need to delete the steps in the reject branch
140+ */
141+ if ( newMrfSteps . length > 0 ) {
142+ // Shift down all steps after the newly added mrf steps
143+ await Step . query ( trx )
144+ . where ( 'flow_id' , $ . flow . id )
145+ . where ( 'position' , '>=' , newMrfSteps [ 0 ] . position )
146+ . andWhereNot ( 'key' , MRF_KEY )
147+ . andWhereNot ( 'app_key' , MRF_APP_KEY )
148+ . increment ( 'position' , newMrfSteps . length )
149+ const stepIdsInRejectBranch = await Step . query ( trx )
150+ . select ( 'steps.id as id' )
151+ . where ( 'flow_id' , $ . flow . id )
152+ . where ( 'position' , '>=' , newMrfStepPositionToInsert )
153+ . andWhereRaw ( `steps.config->'approval'->>'branch' = ?` , [ 'reject' ] )
154+ const finalMrfStep = newMrfSteps [ newMrfSteps . length - 1 ]
155+ if ( actions [ actions . length - 1 ] . approvalField ) {
156+ await Step . query ( trx )
157+ . whereIn (
158+ 'steps.id' ,
159+ stepIdsInRejectBranch . map ( ( step ) => step . id ) ,
160+ )
161+ . patch ( {
162+ config : raw (
163+ `jsonb_set(config, '{approval,stepId}', to_jsonb(?::text), true)` ,
164+ finalMrfStep . id ,
165+ ) ,
166+ } )
100167 } else {
101- // Shift all steps after this position down
102168 await Step . query ( trx )
103- . where ( 'flow_id' , $ . flow . id )
104- . where ( 'position' , '>=' , newStepPosition )
105- . increment ( 'position' , 1 )
106-
107- // Create new step at the correct position
108- const newStep = await Step . query ( trx ) . insert ( {
109- flowId : $ . flow . id ,
110- type : 'action' ,
111- appKey : MRF_APP_KEY ,
112- key : MRF_KEY ,
113- position : newStepPosition ,
114- connectionId : updatedTriggerStep . connectionId ,
115- parameters,
116- config : {
117- stepName,
118- } ,
119- } )
120- newStepPosition = newStep . position + 1
169+ . whereIn (
170+ 'steps.id' ,
171+ stepIdsInRejectBranch . map ( ( step ) => step . id ) ,
172+ )
173+ . delete ( )
121174 }
122175 }
176+
177+ // this is to fill the gaps in the step positions
178+ await Step . resetStepOrdering ( $ . flow . id , trx )
123179 } )
124180}
0 commit comments