@@ -8,15 +8,14 @@ import {
8
8
CiPipelineResult ,
9
9
Workflow ,
10
10
WorkflowResult ,
11
- PipelineType ,
12
- WorkflowNodeType ,
11
+ AddDimensionsToDownstreamDeploymentsParams ,
13
12
} from './types'
14
13
import { WorkflowTrigger , WorkflowCreate , Offset , WorkflowDimensions , WorkflowDimensionType } from './config'
15
14
import { TriggerType , DEFAULT_STATUS , GIT_BRANCH_NOT_CONFIGURED } from '../../../../config'
16
15
import { isEmpty } from '../../../common'
17
16
import { WebhookDetailsType } from '../../../ciPipeline/Webhook/types'
18
17
import { getExternalCIList } from '../../../ciPipeline/Webhook/webhook.service'
19
- import { TriggerTypeMap } from '@devtron-labs/devtron-fe-common-lib'
18
+ import { CommonNodeAttr , TriggerTypeMap , WorkflowNodeType , PipelineType , DownstreamNodesEnvironmentsType } from '@devtron-labs/devtron-fe-common-lib'
20
19
import { CIPipelineBuildType } from '../../../ciPipeline/types'
21
20
import { BlackListedCI } from '../../../workflowEditor/types'
22
21
@@ -272,7 +271,7 @@ function addDimensions(workflows: WorkflowType[], workflowOffset: Offset, dimens
272
271
ciNode . y = startY + workflowOffset . offsetY
273
272
274
273
if ( ( ciNode . downstreamNodes ?. length ?? 0 ) > 0 ) {
275
- addDimensionsToDownstreamDeployments ( ciNode . downstreamNodes , dimensions , ciNode . x , ciNode . y )
274
+ addDimensionsToDownstreamDeployments ( { downstreams : ciNode . downstreamNodes , dimensions, startX : ciNode . x , startY : ciNode . y } )
276
275
}
277
276
278
277
const finalWorkflow = new Array < NodeAttr > ( )
@@ -294,6 +293,7 @@ function addDimensions(workflows: WorkflowType[], workflowOffset: Offset, dimens
294
293
dimensions . type === WorkflowDimensionType . CREATE &&
295
294
node . parentPipelineType === PipelineType . WEBHOOK
296
295
) {
296
+ // Maybe need to manipulate it
297
297
node . x = node . x - 40
298
298
}
299
299
node . preNode && finalWorkflow . push ( node . preNode )
@@ -324,6 +324,7 @@ function addDimensions(workflows: WorkflowType[], workflowOffset: Offset, dimens
324
324
workflow . nodes = finalWorkflow
325
325
} )
326
326
327
+ // FIXME: This might be the key to solve scrolling workflows in case one scrolls, all other scrolls
327
328
workflows . forEach ( ( workflow ) => ( workflow . width = maxWorkflowWidth ) )
328
329
}
329
330
@@ -348,10 +349,17 @@ function addDownstreams(workflows: WorkflowType[]) {
348
349
349
350
if ( ! ! parentNode ) {
350
351
const _downstream = type + '-' + node . id
352
+ const environmentDetails : DownstreamNodesEnvironmentsType = {
353
+ environmentId : node . environmentId ,
354
+ environmentName : node . environmentName ,
355
+ }
356
+
351
357
if ( parentNode . postNode ) {
352
358
parentNode . postNode . downstreams . push ( _downstream )
359
+ parentNode . postNode . downstreamEnvironments ?. push ( environmentDetails )
353
360
} else {
354
361
parentNode . downstreams . push ( _downstream )
362
+ parentNode . downstreamEnvironments ?. push ( environmentDetails )
355
363
}
356
364
parentNode . downstreamNodes . push ( node )
357
365
}
@@ -360,16 +368,25 @@ function addDownstreams(workflows: WorkflowType[]) {
360
368
} )
361
369
}
362
370
363
- function addDimensionsToDownstreamDeployments (
364
- downstreams : Array < NodeAttr > ,
365
- dimensions : WorkflowDimensions ,
366
- startX : number ,
367
- startY : number ,
368
- ) {
369
- let lastY = startY
371
+ /**
372
+ *
373
+ * @description This function is used to add dimensions to downstream deployments, we are recursively traversing the downstream deployments and adding dimensions to them, on each iteration we are updating the lastY coordinate which is used to calculate the Y coordinate of the next deployment, this value is going to be maximum Y coordinate we have encountered so far.
374
+ * @returns maximum Y coordinate we have encountered so far
375
+ */
376
+ const addDimensionsToDownstreamDeployments = ( {
377
+ downstreams,
378
+ dimensions,
379
+ startX,
380
+ startY,
381
+ } : AddDimensionsToDownstreamDeploymentsParams ) : number => {
382
+ const cdNodesGap = dimensions . cDNodeSizes . nodeHeight + dimensions . cDNodeSizes . distanceY
383
+ // Shifting the Y coordinates here since, we are anyways adding cdNodesGap to maxY on start of each iteration and dont want to add that in the end of iteration
384
+ let maxY = startY - cdNodesGap
370
385
for ( let index = 0 ; index < downstreams . length ; index ++ ) {
371
386
const element = downstreams [ index ]
372
- let cdNodeY = lastY
387
+ maxY = maxY + cdNodesGap
388
+ const cdNodeY = maxY
389
+ // From here onwards For Y value we will only change maxY for next iteration and wont need to change current cdNodeY
373
390
let cdNodeX = startX + dimensions . cDNodeSizes . nodeWidth + dimensions . cDNodeSizes . distanceX
374
391
375
392
if ( element . preNode ) {
@@ -389,19 +406,11 @@ function addDimensionsToDownstreamDeployments(
389
406
lastX = element . postNode . x
390
407
}
391
408
392
- lastY = cdNodeY + dimensions . cDNodeSizes . nodeHeight + dimensions . cDNodeSizes . distanceY
393
-
394
409
if ( ( element . downstreamNodes ?. length ?? 0 ) > 0 ) {
395
- addDimensionsToDownstreamDeployments ( element . downstreamNodes , dimensions , lastX , cdNodeY )
396
- lastY =
397
- element . downstreamNodes [ element . downstreamNodes . length - 1 ] . y +
398
- dimensions . cDNodeSizes . nodeHeight +
399
- dimensions . cDNodeSizes . distanceY
410
+ maxY = addDimensionsToDownstreamDeployments ( { downstreams : element . downstreamNodes , dimensions, startX : lastX , startY : cdNodeY } )
400
411
}
401
-
402
- //for next iteration use Y coordinate of the last element in downstreamNodes as it will have maximum Y coordinate
403
- startY = lastY
404
412
}
413
+ return maxY
405
414
}
406
415
407
416
function toWorkflowType ( workflow : Workflow , ciResponse : CiPipelineResult ) : WorkflowType {
@@ -453,6 +462,7 @@ function ciPipelineToNode(ciPipeline: CiPipeline, dimensions: WorkflowDimensions
453
462
url : '' ,
454
463
id : `${ WorkflowNodeType . GIT } -${ materialName } -${ index } ` ,
455
464
downstreams : [ `${ WorkflowNodeType . CI } -${ ciPipeline . id } ` ] ,
465
+ downstreamEnvironments : [ ] ,
456
466
type : WorkflowNodeType . GIT ,
457
467
icon : 'git' ,
458
468
branch : getStaticCurrentBranchName ( ciMaterial ) ,
@@ -486,6 +496,7 @@ function ciPipelineToNode(ciPipeline: CiPipeline, dimensions: WorkflowDimensions
486
496
type : WorkflowNodeType . CI ,
487
497
inputMaterialList : [ ] ,
488
498
downstreams : [ ] ,
499
+ downstreamEnvironments : [ ] ,
489
500
isExternalCI : ciPipeline . isExternal ,
490
501
// Can't rely on pipelineType for legacy pipelines, so using parentCiPipeline as well
491
502
isLinkedCI : ciPipeline . pipelineType !== PipelineType . LINKED_CD && ! ! ciPipeline . parentCiPipeline ,
@@ -517,6 +528,7 @@ function webhookToNode(webhookDetails: WebhookDetailsType, dimensions: WorkflowD
517
528
type : WorkflowNodeType . WEBHOOK ,
518
529
inputMaterialList : [ ] ,
519
530
downstreams : [ ] ,
531
+ downstreamEnvironments : [ ] ,
520
532
isExternalCI : true ,
521
533
isLinkedCI : false ,
522
534
linkedCount : 0 ,
@@ -545,6 +557,7 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
545
557
activeIn : false ,
546
558
activeOut : false ,
547
559
downstreams : [ `${ WorkflowNodeType . CD } -${ cdPipeline . id } ` ] ,
560
+ downstreamEnvironments : [ ] ,
548
561
type : WorkflowNodeType . PRE_CD ,
549
562
status : cdPipeline . preDeployStage ?. status || cdPipeline . preStage ?. status || DEFAULT_STATUS ,
550
563
triggerType : TriggerTypeMap [ trigger ] ,
@@ -581,6 +594,7 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
581
594
activeIn : false ,
582
595
activeOut : false ,
583
596
downstreams : cdDownstreams ,
597
+ downstreamEnvironments : [ ] ,
584
598
type : WorkflowNodeType . CD ,
585
599
status : DEFAULT_STATUS ,
586
600
triggerType : TriggerTypeMap [ trigger ] ,
@@ -604,7 +618,8 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
604
618
isVirtualEnvironment : cdPipeline . isVirtualEnvironment ,
605
619
deploymentAppType : cdPipeline . deploymentAppType ,
606
620
helmPackageName : cdPipeline ?. helmPackageName || '' ,
607
- isLast : isLast
621
+ isLast : isLast ,
622
+ deploymentAppCreated : cdPipeline ?. deploymentAppCreated ,
608
623
} as NodeAttr
609
624
stageIndex ++
610
625
@@ -623,6 +638,7 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
623
638
activeIn : false ,
624
639
activeOut : false ,
625
640
downstreams : [ ] ,
641
+ downstreamEnvironments : [ ] ,
626
642
type : WorkflowNodeType . POST_CD ,
627
643
status : cdPipeline . postDeployStage ?. status || cdPipeline . postStage ?. status || DEFAULT_STATUS ,
628
644
triggerType : TriggerTypeMap [ trigger ] ,
@@ -675,3 +691,34 @@ function getCINodeHeight(dimensionType: WorkflowDimensionType, pipeline: CiPipel
675
691
}
676
692
return WorkflowTrigger . cINodeSizes . nodeHeight
677
693
}
694
+
695
+ export function getAllChildDownstreams ( node : CommonNodeAttr , workflow : any ) : { downstreamNodes : CommonNodeAttr [ ] } {
696
+ let downstreamNodes = [ ]
697
+ // Not using downstreamNodes since they get deleted in service itself
698
+ if ( node ?. downstreams ?. length ) {
699
+ node . downstreams . forEach ( ( downstreamData ) => {
700
+ // separating id and type from downstreamData by splitting on -
701
+ const [ type , id ] = downstreamData . split ( '-' )
702
+ const _node = workflow . nodes ?. find ( ( wfNode ) => String ( wfNode . id ) === id && wfNode . type === type )
703
+ if ( _node ) {
704
+ const { downstreamNodes : _downstreamNodes } = getAllChildDownstreams ( _node , workflow )
705
+ downstreamNodes = [ ...downstreamNodes , ..._downstreamNodes ]
706
+ }
707
+ } )
708
+ }
709
+ return { downstreamNodes : [ ...downstreamNodes , node ] }
710
+ }
711
+
712
+ export function getMaxYFromFirstLevelDownstream ( node : CommonNodeAttr , workflow : any ) : number {
713
+ let maxY = 0
714
+ if ( node ?. downstreams ?. length ) {
715
+ node . downstreams . forEach ( ( downstreamData ) => {
716
+ const [ type , id ] = downstreamData . split ( '-' )
717
+ const _node = workflow . nodes ?. find ( ( wfNode ) => String ( wfNode . id ) === id && wfNode . type === type )
718
+ if ( _node ) {
719
+ maxY = Math . max ( maxY , _node . y )
720
+ }
721
+ } )
722
+ }
723
+ return maxY
724
+ }
0 commit comments