Skip to content

Commit 98e82df

Browse files
Merge pull request #1523 from devtron-labs/feat/add-delete-cd
feat: add delete cd
2 parents 7d9c134 + 552914c commit 98e82df

29 files changed

+1249
-457
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "0.0.47",
7+
"@devtron-labs/devtron-fe-common-lib": "0.0.48",
88
"@rjsf/core": "^5.13.3",
99
"@rjsf/utils": "^5.13.3",
1010
"@rjsf/validator-ajv8": "^5.13.3",

src/components/ApplicationGroup/AppGroup.service.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ import {
44
CiPipelineResult,
55
WorkflowResult,
66
NodeAttr,
7-
PipelineType,
8-
WorkflowNodeType,
97
CiPipeline,
108
} from '../app/details/triggerView/types'
119
import { WebhookListResponse } from '../ciPipeline/Webhook/types'
1210
import { processWorkflow } from '../app/details/triggerView/workflow.service'
1311
import { WorkflowTrigger } from '../app/details/triggerView/config'
1412
import { ModuleNameMap, Routes, URLS } from '../../config'
15-
import { get, post, put, ResponseType, trash } from '@devtron-labs/devtron-fe-common-lib'
13+
import { get, post, put, ResponseType, trash, WorkflowNodeType, PipelineType } from '@devtron-labs/devtron-fe-common-lib'
1614
import {
1715
AppGroupList,
1816
CIConfigListType,

src/components/ApplicationGroup/AppGroup.types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import {
44
FilterConditionsListType,
55
ResponseType,
66
UserApprovalConfigType,
7+
WorkflowNodeType
78
} from '@devtron-labs/devtron-fe-common-lib'
89
import { MultiValue } from 'react-select'
9-
import { WebhookPayloads, WorkflowNodeType, WorkflowType } from '../app/details/triggerView/types'
10+
import { WebhookPayloads, WorkflowType } from '../app/details/triggerView/types'
1011
import { EditDescRequest, OptionType } from '../app/types'
1112
import { AppFilterTabs, BulkResponseStatus } from './Constants'
1213

src/components/ApplicationGroup/Details/EnvCIDetails/EnvCIDetails.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useEffect, useState } from 'react'
22
import { generatePath, Route, useHistory, useParams, useRouteMatch } from 'react-router-dom'
3-
import { Progressing, showError, sortCallback, useAsync } from '@devtron-labs/devtron-fe-common-lib'
3+
import { Progressing, showError, sortCallback, useAsync, PipelineType } from '@devtron-labs/devtron-fe-common-lib'
44
import { URLS } from '../../../../config'
55
import { APP_GROUP_CI_DETAILS } from '../../../../config/constantMessaging'
66
import { EmptyView, LogResizeButton } from '../../../app/details/cicdHistory/History.components'
@@ -12,7 +12,7 @@ import {
1212
FetchIdDataStatus,
1313
} from '../../../app/details/cicdHistory/types'
1414
import { Details } from '../../../app/details/cIDetails/CIDetails'
15-
import { CiPipeline, PipelineType } from '../../../app/details/triggerView/types'
15+
import { CiPipeline } from '../../../app/details/triggerView/types'
1616
import { getTriggerHistory } from '../../../app/service'
1717
import { asyncWrap, mapByKey, useInterval } from '../../../common'
1818
import { getCIConfigList } from '../../AppGroup.service'

src/components/ApplicationGroup/Details/TriggerView/EnvTriggerView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Checkbox,
1616
CHECKBOX_VALUE,
1717
VisibleModal,
18+
WorkflowNodeType,
1819
} from '@devtron-labs/devtron-fe-common-lib'
1920
import CDMaterial from '../../../app/details/triggerView/cdMaterial'
2021
import { CIMaterial } from '../../../app/details/triggerView/ciMaterial'
@@ -24,7 +25,6 @@ import {
2425
CIMaterialRouterProps,
2526
MATERIAL_TYPE,
2627
NodeAttr,
27-
WorkflowNodeType,
2828
WorkflowType,
2929
} from '../../../app/details/triggerView/types'
3030
import { Workflow } from '../../../app/details/triggerView/workflow/Workflow'

src/components/app/details/appConfig/AppComposeRouter.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export default function AppComposeRouter({
9494
getWorkflows={getWorkflows}
9595
isJobView={isJobView}
9696
envList={environments}
97+
reloadEnvironments={reloadEnvironments}
9798
/>
9899
)}
99100
/>,
@@ -192,6 +193,7 @@ export default function AppComposeRouter({
192193
respondOnSuccess={respondOnSuccess}
193194
getWorkflows={getWorkflows}
194195
filteredEnvIds={filteredEnvIds}
196+
reloadEnvironments={reloadEnvironments}
195197
/>
196198
)}
197199
/>,

src/components/app/details/cIDetails/CIDetails.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState, useEffect, useMemo } from 'react'
2-
import { showError, Progressing, Reload, GenericEmptyState, useAsync } from '@devtron-labs/devtron-fe-common-lib'
2+
import { showError, Progressing, Reload, GenericEmptyState, useAsync, PipelineType } from '@devtron-labs/devtron-fe-common-lib'
33
import {
44
getCIPipelines,
55
getCIHistoricalStatus,
@@ -30,7 +30,6 @@ import { EMPTY_STATE_STATUS } from '../../../../config/constantMessaging'
3030
import { ReactComponent as NoVulnerability } from '../../../../assets/img/ic-vulnerability-not-found.svg'
3131
import { ScannedByToolModal } from '../../../common/security/ScannedByToolModal'
3232
import { CIPipelineBuildType } from '../../../ciPipeline/types'
33-
import { PipelineType } from '../triggerView/types'
3433

3534
const terminalStatus = new Set(['succeeded', 'failed', 'error', 'cancelled', 'nottriggered', 'notbuilt'])
3635
let statusSet = new Set(['starting', 'running', 'pending'])

src/components/app/details/triggerView/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ export const WorkflowCreate = {
3434
cINodeSizes: {
3535
nodeHeight: 64,
3636
nodeWidth: 240,
37-
distanceX: 60,
37+
distanceX: 100,
3838
distanceY: 25,
3939
} as NodeDimension,
4040
cDNodeSizes: {
4141
nodeHeight: 64,
4242
nodeWidth: 240,
43-
distanceX: 60,
43+
distanceX: 100,
4444
distanceY: 25,
4545
} as NodeDimension,
4646
workflow: {

src/components/app/details/triggerView/types.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ import {
1616
TaskErrorObj,
1717
FilterConditionsListType,
1818
CDMaterialResponseType,
19+
PipelineType,
1920
} from '@devtron-labs/devtron-fe-common-lib'
2021
import { Environment } from '../../../cdPipeline/cdPipeline.types'
22+
import { WorkflowDimensions } from './config'
2123

2224
export interface CDMaterialProps extends RouteComponentProps<{}> {
2325
material?: CDMaterialType[]
@@ -409,13 +411,6 @@ export interface ApplicationConditionResponse {
409411
message: string
410412
}
411413

412-
export enum PipelineType {
413-
CI_PIPELINE = 'CI_PIPELINE',
414-
CD_PIPELINE = 'CD_PIPELINE',
415-
WEBHOOK = 'WEBHOOK',
416-
LINKED_CD = 'LINKED_CD',
417-
}
418-
419414
export enum CIPipelineNodeType {
420415
EXTERNAL_CI = 'EXTERNAL-CI',
421416
CI = 'CI',
@@ -424,15 +419,6 @@ export enum CIPipelineNodeType {
424419
LINKED_CD = 'LINKED_CD',
425420
}
426421

427-
export enum WorkflowNodeType {
428-
GIT = 'GIT',
429-
CI = 'CI',
430-
WEBHOOK = 'WEBHOOK',
431-
PRE_CD = 'PRECD',
432-
CD = 'CD',
433-
POST_CD = 'POSTCD',
434-
}
435-
436422
export interface Task {
437423
name?: string
438424
type?: string
@@ -725,3 +711,10 @@ export interface MaterialSourceProps {
725711
fromTriggerInfo?: boolean
726712
clearSearch?: (e: any) => void
727713
}
714+
715+
export interface AddDimensionsToDownstreamDeploymentsParams {
716+
downstreams: NodeAttr[],
717+
dimensions: WorkflowDimensions,
718+
startX: number,
719+
startY: number,
720+
}

src/components/app/details/triggerView/workflow.service.ts

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ import {
88
CiPipelineResult,
99
Workflow,
1010
WorkflowResult,
11-
PipelineType,
12-
WorkflowNodeType,
11+
AddDimensionsToDownstreamDeploymentsParams,
1312
} from './types'
1413
import { WorkflowTrigger, WorkflowCreate, Offset, WorkflowDimensions, WorkflowDimensionType } from './config'
1514
import { TriggerType, DEFAULT_STATUS, GIT_BRANCH_NOT_CONFIGURED } from '../../../../config'
1615
import { isEmpty } from '../../../common'
1716
import { WebhookDetailsType } from '../../../ciPipeline/Webhook/types'
1817
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'
2019
import { CIPipelineBuildType } from '../../../ciPipeline/types'
2120
import { BlackListedCI } from '../../../workflowEditor/types'
2221

@@ -272,7 +271,7 @@ function addDimensions(workflows: WorkflowType[], workflowOffset: Offset, dimens
272271
ciNode.y = startY + workflowOffset.offsetY
273272

274273
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})
276275
}
277276

278277
const finalWorkflow = new Array<NodeAttr>()
@@ -294,6 +293,7 @@ function addDimensions(workflows: WorkflowType[], workflowOffset: Offset, dimens
294293
dimensions.type === WorkflowDimensionType.CREATE &&
295294
node.parentPipelineType === PipelineType.WEBHOOK
296295
) {
296+
// Maybe need to manipulate it
297297
node.x = node.x - 40
298298
}
299299
node.preNode && finalWorkflow.push(node.preNode)
@@ -324,6 +324,7 @@ function addDimensions(workflows: WorkflowType[], workflowOffset: Offset, dimens
324324
workflow.nodes = finalWorkflow
325325
})
326326

327+
// FIXME: This might be the key to solve scrolling workflows in case one scrolls, all other scrolls
327328
workflows.forEach((workflow) => (workflow.width = maxWorkflowWidth))
328329
}
329330

@@ -348,10 +349,17 @@ function addDownstreams(workflows: WorkflowType[]) {
348349

349350
if (!!parentNode) {
350351
const _downstream = type + '-' + node.id
352+
const environmentDetails: DownstreamNodesEnvironmentsType = {
353+
environmentId: node.environmentId,
354+
environmentName: node.environmentName,
355+
}
356+
351357
if (parentNode.postNode) {
352358
parentNode.postNode.downstreams.push(_downstream)
359+
parentNode.postNode.downstreamEnvironments?.push(environmentDetails)
353360
} else {
354361
parentNode.downstreams.push(_downstream)
362+
parentNode.downstreamEnvironments?.push(environmentDetails)
355363
}
356364
parentNode.downstreamNodes.push(node)
357365
}
@@ -360,16 +368,25 @@ function addDownstreams(workflows: WorkflowType[]) {
360368
})
361369
}
362370

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
370385
for (let index = 0; index < downstreams.length; index++) {
371386
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
373390
let cdNodeX = startX + dimensions.cDNodeSizes.nodeWidth + dimensions.cDNodeSizes.distanceX
374391

375392
if (element.preNode) {
@@ -389,19 +406,11 @@ function addDimensionsToDownstreamDeployments(
389406
lastX = element.postNode.x
390407
}
391408

392-
lastY = cdNodeY + dimensions.cDNodeSizes.nodeHeight + dimensions.cDNodeSizes.distanceY
393-
394409
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})
400411
}
401-
402-
//for next iteration use Y coordinate of the last element in downstreamNodes as it will have maximum Y coordinate
403-
startY = lastY
404412
}
413+
return maxY
405414
}
406415

407416
function toWorkflowType(workflow: Workflow, ciResponse: CiPipelineResult): WorkflowType {
@@ -453,6 +462,7 @@ function ciPipelineToNode(ciPipeline: CiPipeline, dimensions: WorkflowDimensions
453462
url: '',
454463
id: `${WorkflowNodeType.GIT}-${materialName}-${index}`,
455464
downstreams: [`${WorkflowNodeType.CI}-${ciPipeline.id}`],
465+
downstreamEnvironments: [],
456466
type: WorkflowNodeType.GIT,
457467
icon: 'git',
458468
branch: getStaticCurrentBranchName(ciMaterial),
@@ -486,6 +496,7 @@ function ciPipelineToNode(ciPipeline: CiPipeline, dimensions: WorkflowDimensions
486496
type: WorkflowNodeType.CI,
487497
inputMaterialList: [],
488498
downstreams: [],
499+
downstreamEnvironments: [],
489500
isExternalCI: ciPipeline.isExternal,
490501
// Can't rely on pipelineType for legacy pipelines, so using parentCiPipeline as well
491502
isLinkedCI: ciPipeline.pipelineType !== PipelineType.LINKED_CD && !!ciPipeline.parentCiPipeline,
@@ -517,6 +528,7 @@ function webhookToNode(webhookDetails: WebhookDetailsType, dimensions: WorkflowD
517528
type: WorkflowNodeType.WEBHOOK,
518529
inputMaterialList: [],
519530
downstreams: [],
531+
downstreamEnvironments: [],
520532
isExternalCI: true,
521533
isLinkedCI: false,
522534
linkedCount: 0,
@@ -545,6 +557,7 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
545557
activeIn: false,
546558
activeOut: false,
547559
downstreams: [`${WorkflowNodeType.CD}-${cdPipeline.id}`],
560+
downstreamEnvironments: [],
548561
type: WorkflowNodeType.PRE_CD,
549562
status: cdPipeline.preDeployStage?.status || cdPipeline.preStage?.status || DEFAULT_STATUS,
550563
triggerType: TriggerTypeMap[trigger],
@@ -581,6 +594,7 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
581594
activeIn: false,
582595
activeOut: false,
583596
downstreams: cdDownstreams,
597+
downstreamEnvironments: [],
584598
type: WorkflowNodeType.CD,
585599
status: DEFAULT_STATUS,
586600
triggerType: TriggerTypeMap[trigger],
@@ -604,7 +618,8 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
604618
isVirtualEnvironment: cdPipeline.isVirtualEnvironment,
605619
deploymentAppType: cdPipeline.deploymentAppType,
606620
helmPackageName: cdPipeline?.helmPackageName || '',
607-
isLast: isLast
621+
isLast: isLast,
622+
deploymentAppCreated: cdPipeline?.deploymentAppCreated,
608623
} as NodeAttr
609624
stageIndex++
610625

@@ -623,6 +638,7 @@ function cdPipelineToNode(cdPipeline: CdPipeline, dimensions: WorkflowDimensions
623638
activeIn: false,
624639
activeOut: false,
625640
downstreams: [],
641+
downstreamEnvironments: [],
626642
type: WorkflowNodeType.POST_CD,
627643
status: cdPipeline.postDeployStage?.status || cdPipeline.postStage?.status || DEFAULT_STATUS,
628644
triggerType: TriggerTypeMap[trigger],
@@ -675,3 +691,34 @@ function getCINodeHeight(dimensionType: WorkflowDimensionType, pipeline: CiPipel
675691
}
676692
return WorkflowTrigger.cINodeSizes.nodeHeight
677693
}
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

Comments
 (0)