Skip to content

Commit e4c171b

Browse files
committed
feat: extract on click rollback cd and approval common logic
1 parent c6773ca commit e4c171b

File tree

5 files changed

+122
-227
lines changed

5 files changed

+122
-227
lines changed

src/components/ApplicationGroup/AppGroup.types.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,6 @@ export interface TriggerModalRowType {
216216
isVirtualEnv?: boolean
217217
}
218218

219-
export interface WorkflowNodeSelectionType {
220-
id: number
221-
name: string
222-
type: WorkflowNodeType
223-
}
224219
export interface WorkflowAppSelectionType {
225220
id: number
226221
name: string

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

Lines changed: 46 additions & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
DeploymentStrategyTypeWithDefault,
3636
ErrorScreenManager,
3737
getStageTitle,
38+
handleAnalyticsEvent,
3839
PipelineIdsVsDeploymentStrategyMap,
3940
PopupMenu,
4041
Progressing,
@@ -82,7 +83,6 @@ import {
8283
ResponseRowType,
8384
TriggerVirtualEnvResponseRowType,
8485
WorkflowAppSelectionType,
85-
WorkflowNodeSelectionType,
8686
} from '../../AppGroup.types'
8787
import { processWorkflowStatuses } from '../../AppGroup.utils'
8888
import {
@@ -98,7 +98,7 @@ import {
9898
import BulkCDTrigger from './BulkCDTrigger'
9999
import BulkSourceChange from './BulkSourceChange'
100100
import { RenderCDMaterialContentProps } from './types'
101-
import { getSelectedCDNode } from './utils'
101+
import { getSelectedCDNode, getSelectedNodeAndAppId, getSelectedNodeAndMeta } from './utils'
102102

103103
import './EnvTriggerView.scss'
104104

@@ -126,8 +126,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
126126
const match = useRouteMatch<CIMaterialRouterProps>()
127127
const { url } = useRouteMatch()
128128

129-
// ref to make sure that on initial mount after we fetch workflows we handle modal based on url
130-
const handledLocation = useRef(false)
131129
const abortControllerRef = useRef(new AbortController())
132130

133131
const [pageViewType, setPageViewType] = useState<string>(ViewType.LOADING)
@@ -143,7 +141,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
143141
const [selectedAppList, setSelectedAppList] = useState<WorkflowAppSelectionType[]>([])
144142
const [workflows, setWorkflows] = useState<WorkflowType[]>([])
145143
const [filteredWorkflows, setFilteredWorkflows] = useState<WorkflowType[]>([])
146-
const [selectedCDNode, setSelectedCDNode] = useState<WorkflowNodeSelectionType>(null)
147144
const [filteredCIPipelines, setFilteredCIPipelines] = useState(null)
148145
const [bulkTriggerType, setBulkTriggerType] = useState<DeploymentNodeType>(null)
149146
const [materialType, setMaterialType] = useState(MATERIAL_TYPE.inputMaterialList)
@@ -160,13 +157,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
160157
const enableRoutePrompt = isBranchChangeLoading || isBulkTriggerLoading
161158
usePrompt({ shouldPrompt: enableRoutePrompt })
162159

163-
useEffect(
164-
() => () => {
165-
handledLocation.current = false
166-
},
167-
[],
168-
)
169-
170160
useEffect(() => {
171161
if (envId) {
172162
setPageViewType(ViewType.LOADING)
@@ -184,72 +174,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
184174
getWorkflowsData()
185175
}
186176

187-
useEffect(() => {
188-
if (!handledLocation.current && filteredWorkflows?.length) {
189-
handledLocation.current = true
190-
// Would have been better if filteredWorkflows had default value to null since we are using it as a flag
191-
// URL Encoding for Bulk is not planned as of now
192-
setShowBulkCDModal(false)
193-
if (location.search.includes('approval-node')) {
194-
const searchParams = new URLSearchParams(location.search)
195-
const nodeId = Number(searchParams.get('approval-node'))
196-
if (!isNaN(nodeId)) {
197-
onClickCDMaterial(nodeId, DeploymentNodeType.CD, true)
198-
} else {
199-
ToastManager.showToast({
200-
variant: ToastVariantType.error,
201-
description: 'Invalid node id',
202-
})
203-
history.push({
204-
search: '',
205-
})
206-
}
207-
} else if (location.search.includes('rollback-node')) {
208-
const searchParams = new URLSearchParams(location.search)
209-
const nodeId = Number(searchParams.get('rollback-node'))
210-
if (!isNaN(nodeId)) {
211-
onClickRollbackMaterial(nodeId)
212-
} else {
213-
ToastManager.showToast({
214-
variant: ToastVariantType.error,
215-
description: 'Invalid node id',
216-
})
217-
history.push({
218-
search: '',
219-
})
220-
}
221-
} else if (location.search.includes('cd-node')) {
222-
const searchParams = new URLSearchParams(location.search)
223-
const nodeId = Number(searchParams.get('cd-node'))
224-
const nodeType = searchParams.get('node-type') ?? DeploymentNodeType.CD
225-
226-
if (
227-
nodeType !== DeploymentNodeType.CD &&
228-
nodeType !== DeploymentNodeType.PRECD &&
229-
nodeType !== DeploymentNodeType.POSTCD
230-
) {
231-
ToastManager.showToast({
232-
variant: ToastVariantType.error,
233-
description: 'Invalid node type',
234-
})
235-
history.push({
236-
search: '',
237-
})
238-
} else if (!isNaN(nodeId)) {
239-
onClickCDMaterial(nodeId, nodeType as DeploymentNodeType)
240-
} else {
241-
ToastManager.showToast({
242-
variant: ToastVariantType.error,
243-
description: 'Invalid node id',
244-
})
245-
history.push({
246-
search: '',
247-
})
248-
}
249-
}
250-
}
251-
}, [filteredWorkflows])
252-
253177
const preserveSelection = (_workflows: WorkflowType[]) => {
254178
if (!workflows || !_workflows) {
255179
return
@@ -450,104 +374,33 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
450374
)
451375
}
452376

453-
const onClickCDMaterial = (cdNodeId, nodeType: DeploymentNodeType, isApprovalNode: boolean = false): void => {
454-
ReactGA.event(
455-
isApprovalNode ? ENV_TRIGGER_VIEW_GA_EVENTS.ApprovalNodeClicked : ENV_TRIGGER_VIEW_GA_EVENTS.ImageClicked,
456-
)
457-
458-
let _workflowId
459-
let _appID
460-
let _selectedNode
461-
462-
// FIXME: This needs to be replicated in rollback, env group since we need cipipelineid as 0 in external case
463-
const _workflows = [...filteredWorkflows].map((workflow) => {
464-
const nodes = workflow.nodes.map((node) => {
465-
if (cdNodeId == node.id && node.type === nodeType) {
466-
// TODO: Ig not using this, can remove it
467-
if (node.type === WorkflowNodeType.CD) {
468-
node.approvalConfigData = workflow.approvalConfiguredIdsMap[cdNodeId]
469-
}
470-
_selectedNode = node
471-
_workflowId = workflow.id
472-
_appID = workflow.appId
473-
}
474-
return node
475-
})
476-
workflow.nodes = nodes
477-
return workflow
478-
})
377+
const onClickApprovalNode = (cdNodeId: number) => {
378+
handleAnalyticsEvent(ENV_TRIGGER_VIEW_GA_EVENTS.ApprovalNodeClicked)
479379

480-
if (!_selectedNode) {
481-
ToastManager.showToast({
482-
variant: ToastVariantType.error,
483-
description: 'Invalid node id',
484-
})
485-
history.push({
486-
search: '',
487-
})
488-
return
489-
}
380+
const newParams = new URLSearchParams([
381+
[TRIGGER_VIEW_PARAMS.APPROVAL_NODE, cdNodeId.toString()],
382+
[TRIGGER_VIEW_PARAMS.APPROVAL_STATE, TRIGGER_VIEW_PARAMS.APPROVAL],
383+
])
384+
history.push({ search: newParams.toString() })
385+
}
490386

491-
setFilteredWorkflows(_workflows)
492-
setSelectedCDNode({ id: +cdNodeId, name: _selectedNode.name, type: _selectedNode.type })
493-
setMaterialType(MATERIAL_TYPE.inputMaterialList)
387+
const onClickCDMaterial = (cdNodeId: number, nodeType: DeploymentNodeType) => {
388+
handleAnalyticsEvent(ENV_TRIGGER_VIEW_GA_EVENTS.ImageClicked)
494389

495-
const newParams = new URLSearchParams(location.search)
496-
newParams.set(isApprovalNode ? 'approval-node' : 'cd-node', cdNodeId.toString())
497-
if (!isApprovalNode) {
498-
newParams.set('node-type', nodeType)
499-
} else {
500-
const currentApprovalState = newParams.get(TRIGGER_VIEW_PARAMS.APPROVAL_STATE)
501-
// If the current state is pending, then we should change the state to pending
502-
const approvalState =
503-
currentApprovalState === TRIGGER_VIEW_PARAMS.PENDING
504-
? TRIGGER_VIEW_PARAMS.PENDING
505-
: TRIGGER_VIEW_PARAMS.APPROVAL
506-
507-
newParams.set(TRIGGER_VIEW_PARAMS.APPROVAL_STATE, approvalState)
508-
newParams.delete(TRIGGER_VIEW_PARAMS.CD_NODE)
509-
newParams.delete(TRIGGER_VIEW_PARAMS.NODE_TYPE)
510-
}
390+
const newParams = new URLSearchParams([
391+
[TRIGGER_VIEW_PARAMS.CD_NODE, cdNodeId.toString()],
392+
[TRIGGER_VIEW_PARAMS.NODE_TYPE, nodeType],
393+
])
511394
history.push({
512395
search: newParams.toString(),
513396
})
514397
}
515398

399+
// Assuming that rollback has only CD as nodeType
516400
const onClickRollbackMaterial = (cdNodeId: number) => {
517-
ReactGA.event(ENV_TRIGGER_VIEW_GA_EVENTS.RollbackClicked)
518-
519-
let _selectedNode
520-
521-
const _workflows = [...filteredWorkflows].map((workflow) => {
522-
const nodes = workflow.nodes.map((node) => {
523-
if (node.type === 'CD' && +node.id == cdNodeId) {
524-
node.approvalConfigData = workflow.approvalConfiguredIdsMap[cdNodeId]
525-
_selectedNode = node
526-
}
527-
return node
528-
})
529-
workflow.nodes = nodes
530-
return workflow
531-
})
532-
533-
if (!_selectedNode) {
534-
ToastManager.showToast({
535-
variant: ToastVariantType.error,
536-
description: 'Invalid node id',
537-
})
538-
history.push({
539-
search: '',
540-
})
541-
return
542-
}
543-
544-
setFilteredWorkflows(_workflows)
545-
setSelectedCDNode({ id: +cdNodeId, name: _selectedNode.name, type: _selectedNode.type })
546-
setMaterialType(MATERIAL_TYPE.rollbackMaterialList)
547-
getWorkflowStatusData(_workflows)
401+
handleAnalyticsEvent(ENV_TRIGGER_VIEW_GA_EVENTS.RollbackClicked)
548402

549-
const newParams = new URLSearchParams(location.search)
550-
newParams.set('rollback-node', cdNodeId.toString())
403+
const newParams = new URLSearchParams([[TRIGGER_VIEW_PARAMS.ROLLBACK_NODE, cdNodeId.toString()]])
551404
history.push({
552405
search: newParams.toString(),
553406
})
@@ -1186,8 +1039,8 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
11861039
materialType={materialType}
11871040
appId={appId}
11881041
envId={node?.environmentId}
1189-
pipelineId={selectedCDNode?.id}
1190-
stageType={DeploymentNodeType[selectedCDNode?.type]}
1042+
pipelineId={+node.id}
1043+
stageType={node.type as DeploymentNodeType}
11911044
envName={node?.environmentName}
11921045
closeCDModal={closeCDModal}
11931046
triggerType={node?.triggerType}
@@ -1207,32 +1060,22 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
12071060
}
12081061

12091062
const renderCDMaterial = (): JSX.Element | null => {
1210-
if (!selectedCDNode?.id) {
1211-
return null
1212-
}
1063+
if (
1064+
location.search.includes(TRIGGER_VIEW_PARAMS.CD_NODE) ||
1065+
location.search.includes(TRIGGER_VIEW_PARAMS.ROLLBACK_NODE)
1066+
) {
12131067

1214-
if (location.search.includes('cd-node') || location.search.includes('rollback-node')) {
1215-
let node: CommonNodeAttr
1216-
let _appID
1217-
let selectedAppName: string
1218-
let workflowId: string
1219-
let selectedCINode: CommonNodeAttr
1220-
1221-
if (selectedCDNode?.id) {
1222-
for (const _wf of filteredWorkflows) {
1223-
node = _wf.nodes.find((el) => +el.id == selectedCDNode.id && el.type == selectedCDNode.type)
1224-
if (node) {
1225-
selectedCINode = _wf.nodes.find(
1226-
(node) => node.type === WorkflowNodeType.CI || node.type === WorkflowNodeType.WEBHOOK,
1227-
)
1228-
workflowId = _wf.id
1229-
_appID = _wf.appId
1230-
selectedAppName = _wf.name
1231-
break
1232-
}
1233-
}
1068+
const { node, appId, workflowId, appName, selectedCINode } = getSelectedNodeAndMeta(filteredWorkflows, location.search)
1069+
1070+
if (!node?.id) {
1071+
return null
12341072
}
1235-
const material = node?.[materialType] || []
1073+
1074+
const cdMaterialType = location.search.includes(TRIGGER_VIEW_PARAMS.CD_NODE)
1075+
? MATERIAL_TYPE.inputMaterialList
1076+
: MATERIAL_TYPE.rollbackMaterialList
1077+
1078+
const material = node[cdMaterialType] || []
12361079

12371080
return (
12381081
<VisibleModal parentClassName="dc__overflow-hidden" close={closeCDModal}>
@@ -1256,8 +1099,8 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
12561099
) : (
12571100
renderCDMaterialContent({
12581101
node,
1259-
appId: _appID,
1260-
selectedAppName,
1102+
appId,
1103+
selectedAppName: appName,
12611104
workflowId,
12621105
doesWorkflowContainsWebhook: selectedCINode?.type === WorkflowNodeType.WEBHOOK,
12631106
ciNodeId: selectedCINode?.id,
@@ -1273,27 +1116,22 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
12731116

12741117
const renderApprovalMaterial = () => {
12751118
if (ApprovalMaterialModal && location.search.includes(TRIGGER_VIEW_PARAMS.APPROVAL_NODE)) {
1276-
let node: CommonNodeAttr
1277-
let _appID
1278-
if (selectedCDNode?.id) {
1279-
for (const _wf of filteredWorkflows) {
1280-
node = _wf.nodes.find((el) => +el.id == selectedCDNode.id && el.type == selectedCDNode.type)
1281-
if (node) {
1282-
_appID = _wf.appId
1283-
break
1284-
}
1285-
}
1119+
const { node, appId } = getSelectedNodeAndAppId(filteredWorkflows, location.search)
1120+
1121+
if (!node?.id || !appId) {
1122+
showError('Invalid node id')
1123+
return null
12861124
}
12871125

12881126
return (
12891127
<ApprovalMaterialModal
12901128
isLoading={isCDLoading}
12911129
node={node ?? ({} as CommonNodeAttr)}
12921130
materialType={materialType}
1293-
stageType={DeploymentNodeType[selectedCDNode?.type]}
1131+
stageType={DeploymentNodeType.CD}
12941132
closeApprovalModal={closeApprovalModal}
1295-
appId={_appID}
1296-
pipelineId={selectedCDNode?.id}
1133+
appId={appId}
1134+
pipelineId={node.id}
12971135
getModuleInfo={getModuleInfo}
12981136
ciPipelineId={node?.connectingCiPipelineId}
12991137
history={history}
@@ -1503,8 +1341,7 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
15031341
onClickCDMaterial,
15041342
onClickRollbackMaterial,
15051343
reloadTriggerView,
1506-
// TODO: Update below function
1507-
onClickApprovalNode: () => {}
1344+
onClickApprovalNode,
15081345
}}
15091346
>
15101347
{renderWorkflow()}

0 commit comments

Comments
 (0)