Skip to content

Commit 52aa805

Browse files
Merge pull request #2871 from devtron-labs/fix/build-deploy-trigger
feat: refactor trigger view component
2 parents d3a05ad + ff0d2fe commit 52aa805

File tree

15 files changed

+578
-666
lines changed

15 files changed

+578
-666
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ src/components/app/details/testViewer/TestRunDetails.tsx
102102
src/components/app/details/testViewer/TestRunList.tsx
103103
src/components/app/details/triggerView/EmptyStateCIMaterial.tsx
104104
src/components/app/details/triggerView/MaterialSource.tsx
105-
src/components/app/details/triggerView/TriggerView.tsx
106105
src/components/app/details/triggerView/__tests__/triggerview.test.tsx
107106
src/components/app/details/triggerView/cdMaterial.tsx
108107
src/components/app/details/triggerView/ciMaterial.tsx

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

Lines changed: 22 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ import { ReactComponent as Pencil } from '../../../../assets/icons/ic-pencil.svg
5454
import { URLS, ViewType } from '../../../../config'
5555
import { LinkedCIDetail } from '../../../../Pages/Shared/LinkedCIDetailsModal'
5656
import { AppNotConfigured } from '../../../app/details/appDetails/AppDetails'
57-
import { TriggerViewContext } from '../../../app/details/triggerView/config'
5857
import { TRIGGER_VIEW_PARAMS } from '../../../app/details/triggerView/Constants'
5958
import { CIMaterialRouterProps, MATERIAL_TYPE } from '../../../app/details/triggerView/types'
6059
import { Workflow } from '../../../app/details/triggerView/workflow/Workflow'
@@ -337,38 +336,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
337336
)
338337
}
339338

340-
const onClickApprovalNode = (cdNodeId: number) => {
341-
handleAnalyticsEvent(ENV_TRIGGER_VIEW_GA_EVENTS.ApprovalNodeClicked)
342-
343-
const newParams = new URLSearchParams([
344-
[TRIGGER_VIEW_PARAMS.APPROVAL_NODE, cdNodeId.toString()],
345-
[TRIGGER_VIEW_PARAMS.APPROVAL_STATE, TRIGGER_VIEW_PARAMS.APPROVAL],
346-
])
347-
history.push({ search: newParams.toString() })
348-
}
349-
350-
const onClickCDMaterial = (cdNodeId: number, nodeType: DeploymentNodeType) => {
351-
handleAnalyticsEvent(ENV_TRIGGER_VIEW_GA_EVENTS.ImageClicked)
352-
353-
const newParams = new URLSearchParams([
354-
[TRIGGER_VIEW_PARAMS.CD_NODE, cdNodeId.toString()],
355-
[TRIGGER_VIEW_PARAMS.NODE_TYPE, nodeType],
356-
])
357-
history.push({
358-
search: newParams.toString(),
359-
})
360-
}
361-
362-
// Assuming that rollback has only CD as nodeType
363-
const onClickRollbackMaterial = (cdNodeId: number) => {
364-
handleAnalyticsEvent(ENV_TRIGGER_VIEW_GA_EVENTS.RollbackClicked)
365-
366-
const newParams = new URLSearchParams([[TRIGGER_VIEW_PARAMS.ROLLBACK_NODE, cdNodeId.toString()]])
367-
history.push({
368-
search: newParams.toString(),
369-
})
370-
}
371-
372339
const isBuildAndBranchTriggerAllowed = (node: CommonNodeAttr): boolean =>
373340
!node.isLinkedCI && !node.isLinkedCD && node.type !== WorkflowNodeType.WEBHOOK
374341

@@ -525,6 +492,7 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
525492
workflows={filteredWorkflows}
526493
isVirtualEnvironment={isVirtualEnv}
527494
envId={+envId}
495+
handleSuccess={reloadTriggerView}
528496
/>
529497
)
530498
}
@@ -600,7 +568,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
600568
configurePluginURL={configurePluginURL}
601569
isTriggerBlockedDueToPlugin={node?.showPluginWarning && node?.isTriggerBlocked}
602570
triggerType={node?.triggerType}
603-
isRedirectedFromAppDetails={false}
604571
parentEnvironmentName={node?.parentEnvironmentName}
605572
/>
606573
)
@@ -824,6 +791,7 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
824791
index={index}
825792
handleWebhookAddImageClick={handleWebhookAddImageClick(workflow.appId)}
826793
openCIMaterialModal={openCIMaterialModal}
794+
reloadTriggerView={reloadTriggerView}
827795
/>
828796
))}
829797
<LinkedCIDetail workflows={filteredWorkflows} handleClose={revertToPreviousURL} />
@@ -848,35 +816,26 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
848816

849817
<Prompt when={enableRoutePrompt} message={DEFAULT_ROUTE_PROMPT_MESSAGE} />
850818

851-
<TriggerViewContext.Provider
852-
value={{
853-
onClickCDMaterial,
854-
onClickRollbackMaterial,
855-
reloadTriggerView,
856-
onClickApprovalNode,
857-
}}
858-
>
859-
{renderWorkflow()}
860-
861-
<Switch>
862-
<Route path={`${url}${URLS.BUILD}/:ciNodeId`}>
863-
<BuildImageModal
864-
handleClose={revertToPreviousURL}
865-
isJobView={false}
866-
filteredCIPipelineMap={filteredCIPipelines}
867-
workflows={workflows}
868-
reloadWorkflows={getWorkflowsData}
869-
reloadWorkflowStatus={getWorkflowStatusData}
870-
environmentLists={[]}
871-
/>
872-
</Route>
873-
</Switch>
874-
{renderCDMaterial()}
875-
{renderBulkCDMaterial()}
876-
{renderBulkCIMaterial()}
877-
{renderApprovalMaterial()}
878-
{renderBulkSourceChange()}
879-
</TriggerViewContext.Provider>
819+
{renderWorkflow()}
820+
821+
<Switch>
822+
<Route path={`${url}${URLS.BUILD}/:ciNodeId`}>
823+
<BuildImageModal
824+
handleClose={revertToPreviousURL}
825+
isJobView={false}
826+
filteredCIPipelineMap={filteredCIPipelines}
827+
workflows={workflows}
828+
reloadWorkflows={getWorkflowsData}
829+
reloadWorkflowStatus={getWorkflowStatusData}
830+
environmentLists={[]}
831+
/>
832+
</Route>
833+
</Switch>
834+
{renderCDMaterial()}
835+
{renderBulkCDMaterial()}
836+
{renderBulkCIMaterial()}
837+
{renderApprovalMaterial()}
838+
{renderBulkSourceChange()}
880839
<div />
881840
</div>
882841
{!!selectedAppList.length && (

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ import {
1919
BuildImageModalProps,
2020
CIPipelineMaterialDTO,
2121
FilteredCIPipelineMapType,
22+
FilteredCIPipelinesType,
2223
HandleRuntimeParamChange,
2324
MaterialSourceProps,
2425
RuntimeParamsErrorState,
25-
TriggerViewState,
2626
} from '../types'
2727

2828
export interface TriggerBuildSidebarProps {
@@ -55,7 +55,7 @@ export type GitInfoMaterialProps = Pick<BuildImageModalProps, 'isJobView'> & {
5555
handleRuntimeParamError: (errorState: RuntimeParamsErrorState) => void
5656
runtimeParams: RuntimePluginVariables[]
5757
handleDisplayWebhookModal: () => void
58-
selectedCIPipeline: TriggerViewState['filteredCIPipelines'][number]
58+
selectedCIPipeline: FilteredCIPipelinesType
5959
handleReloadWithWorkflows: () => Promise<void>
6060
appId: number
6161
/**
@@ -80,8 +80,9 @@ export type GitInfoMaterialProps = Pick<BuildImageModalProps, 'isJobView'> & {
8080
)
8181

8282
export interface BulkBuildImageModalProps
83-
extends Pick<BuildImageModalProps, 'handleClose' | 'workflows' | 'reloadWorkflows' | 'reloadWorkflowStatus'> {
83+
extends Pick<BuildImageModalProps, 'handleClose' | 'workflows' | 'reloadWorkflowStatus'> {
8484
filteredCIPipelineMap: FilteredCIPipelineMapType
85+
reloadWorkflows: () => Promise<WorkflowType[]>
8586
}
8687

8788
export interface BuildImageHeaderProps {

src/components/app/details/triggerView/DeployImageModal/BulkDeployModal.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ const validateRuntimeParameters = importComponentFromFELibrary(
6666
'function',
6767
)
6868

69-
const BulkDeployModal = ({ handleClose, stageType, workflows, isVirtualEnvironment, envId }: BuildDeployModalProps) => {
69+
const BulkDeployModal = ({
70+
handleClose: handleCloseProp,
71+
handleSuccess,
72+
stageType,
73+
workflows,
74+
isVirtualEnvironment,
75+
envId,
76+
}: BuildDeployModalProps) => {
7077
const { currentEnvironmentName: envName } = useAppContext()
7178
const { canFetchHelmAppStatus } = useMainContext()
7279

@@ -537,6 +544,13 @@ const BulkDeployModal = ({ handleClose, stageType, workflows, isVirtualEnvironme
537544
[appInfoMap],
538545
)
539546

547+
const handleClose = () => {
548+
handleCloseProp()
549+
if (responseList.length) {
550+
handleSuccess()
551+
}
552+
}
553+
540554
const renderContent = () => {
541555
if (BulkCDStrategy && showStrategyFeasibilityPage) {
542556
return (
@@ -600,7 +614,6 @@ const BulkDeployModal = ({ handleClose, stageType, workflows, isVirtualEnvironme
600614
deploymentWindowMetadata={deploymentWindowMetadata}
601615
pipelineId={pipelineId}
602616
handleClose={handleClose}
603-
isRedirectedFromAppDetails={false}
604617
onSearchApply={reloadOrSearchSelectedApp}
605618
stageType={stageType}
606619
uploadRuntimeParamsFile={uploadRuntimeParamsFile}

src/components/app/details/triggerView/DeployImageModal/DeployImageContent.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useContext } from 'react'
21
import { useHistory } from 'react-router-dom'
32

43
import {
@@ -31,9 +30,9 @@ import {
3130

3231
import { importComponentFromFELibrary } from '@Components/common'
3332

34-
import { TriggerViewContext } from '../config'
3533
import { TRIGGER_VIEW_PARAMS } from '../Constants'
36-
import { FilterConditionViews, HandleRuntimeParamChange, TriggerViewContextType } from '../types'
34+
import { getCDNodeActionSearch } from '../TriggerView.utils'
35+
import { CDNodeActions, FilterConditionViews, HandleRuntimeParamChange } from '../types'
3736
import BulkDeployEmptyState from './BulkDeployEmptyState'
3837
import BulkTriggerSidebar from './BulkTriggerSidebar'
3938
import ImageSelectionCTA from './ImageSelectionCTA'
@@ -96,7 +95,6 @@ const DeployImageContent = ({
9695
// WARNING: Pls try not to create a useState in this component, it is supposed to be a dumb component.
9796
const history = useHistory()
9897
const { isSuperAdmin } = useMainContext()
99-
const { onClickApprovalNode } = useContext<TriggerViewContextType>(TriggerViewContext)
10098

10199
// Assumption: isExceptionUser is a global trait
102100
const isExceptionUser = getIsExceptionUser(materialResponse)
@@ -238,7 +236,12 @@ const DeployImageContent = ({
238236
})
239237
} else {
240238
handleClose()
241-
onClickApprovalNode(pipelineId)
239+
const search = getCDNodeActionSearch({
240+
actionType: CDNodeActions.APPROVAL,
241+
cdNodeId: pipelineId,
242+
fromAppGroup: isBulkTrigger,
243+
})
244+
history.push({ search })
242245
}
243246
}
244247

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ export type DeployImageModalProps = {
4343
/**
4444
* If opening pre/post cd make sure BE sends plugin details as well, otherwise those props will be undefined
4545
*/
46-
isRedirectedFromAppDetails: boolean
4746
parentEnvironmentName: string
4847
triggerType: CommonNodeAttr['triggerType']
48+
isRedirectedFromAppDetails?: boolean
4949
} & (
5050
| {
5151
showPluginWarningBeforeTrigger: boolean
@@ -231,6 +231,7 @@ export interface BuildDeployModalProps {
231231
workflows: WorkflowType[]
232232
isVirtualEnvironment: boolean
233233
envId: number
234+
handleSuccess: () => void
234235
}
235236

236237
export type GetInitialAppListProps =
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { useRef } from 'react'
2+
3+
import { DEFAULT_ENV, getEnvironmentListMinPublic, useQuery, useQueryClient } from '@devtron-labs/devtron-fe-common-lib'
4+
5+
import { getWorkflowStatus } from '@Components/app/service'
6+
import { processWorkflowStatuses } from '@Components/ApplicationGroup/AppGroup.utils'
7+
import { sortObjectArrayAlphabetically } from '@Components/common'
8+
import { getHostURLConfiguration } from '@Services/service'
9+
10+
import { UseTriggerViewServicesParams } from './types'
11+
import { getTriggerWorkflows } from './workflow.service'
12+
13+
const DEFAULT_POLLING_INTERVAL = 30000
14+
const PROGRESSING_POLLING_INTERVAL = 10000
15+
16+
export const useTriggerViewServices = ({ appId, isJobView, filteredEnvIds }: UseTriggerViewServicesParams) => {
17+
const queryClient = useQueryClient()
18+
const refetchIntervalRef = useRef<number>(DEFAULT_POLLING_INTERVAL)
19+
20+
const { data: hostUrlConfig } = useQuery({
21+
queryKey: ['hostUrlConfig'],
22+
queryFn: () => getHostURLConfiguration(),
23+
select: (response) => response.result,
24+
})
25+
26+
const { isFetching: isEnvListLoading, data: environmentList } = useQuery({
27+
queryKey: ['triggerViewEnvList'],
28+
queryFn: ({ signal }) => getEnvironmentListMinPublic(false, { signal }),
29+
select: (response) => {
30+
const list = []
31+
list.push({
32+
id: 0,
33+
clusterName: '',
34+
name: DEFAULT_ENV,
35+
active: false,
36+
isClusterActive: false,
37+
description: 'System default',
38+
})
39+
response.result?.forEach((env) => {
40+
if (env.cluster_name !== 'default_cluster' && env.isClusterCdActive) {
41+
list.push({
42+
id: env.id,
43+
clusterName: env.cluster_name,
44+
name: env.environment_name,
45+
active: false,
46+
isClusterActive: env.isClusterActive,
47+
description: env.description,
48+
})
49+
}
50+
})
51+
sortObjectArrayAlphabetically(list, 'name')
52+
return list
53+
},
54+
})
55+
56+
const {
57+
isFetching: isWorkflowsLoading,
58+
data: wfData,
59+
error: workflowsError,
60+
} = useQuery({
61+
queryKey: [appId, isJobView, filteredEnvIds, 'triggerViewWorkflowList'],
62+
queryFn: async () => {
63+
const result = await getTriggerWorkflows(appId, !isJobView, isJobView, filteredEnvIds)
64+
return {
65+
code: 200,
66+
status: 'OK',
67+
result,
68+
}
69+
},
70+
select: (response) => ({
71+
appName: response.result?.appName || '',
72+
workflows: response.result?.workflows || [],
73+
filteredCIPipelines: response.result?.filteredCIPipelines || [],
74+
}),
75+
})
76+
77+
const { workflows, filteredCIPipelines } = wfData ?? { workflows: [], filteredCIPipelines: [] }
78+
79+
const { data: updatedWfWithStatus } = useQuery({
80+
queryKey: [appId, 'triggerViewWorkflowStatus'],
81+
queryFn: ({ signal }) => getWorkflowStatus(+appId, { signal }),
82+
select: (response) => {
83+
const processedWorkflowsData = processWorkflowStatuses(
84+
response.result?.ciWorkflowStatus ?? [],
85+
response.result?.cdWorkflowStatus ?? [],
86+
workflows,
87+
)
88+
refetchIntervalRef.current = processedWorkflowsData.cicdInProgress
89+
? PROGRESSING_POLLING_INTERVAL
90+
: DEFAULT_POLLING_INTERVAL
91+
92+
return processedWorkflowsData.workflows || []
93+
},
94+
refetchInterval: refetchIntervalRef.current,
95+
enabled: !!appId && !!workflows.length,
96+
})
97+
98+
const isLoading = isEnvListLoading || isWorkflowsLoading
99+
100+
const reloadWorkflowStatus = async () => {
101+
await queryClient.invalidateQueries({ queryKey: [appId, 'triggerViewWorkflowStatus'] })
102+
}
103+
104+
const reloadWorkflows = async () => {
105+
await queryClient.invalidateQueries({ queryKey: [appId, isJobView, filteredEnvIds, 'triggerViewWorkflowList'] })
106+
// Invalidate status query to refetch workflow status
107+
await reloadWorkflowStatus()
108+
}
109+
110+
return {
111+
isLoading,
112+
hostUrlConfig,
113+
environmentList,
114+
workflows: updatedWfWithStatus ?? workflows,
115+
filteredCIPipelines,
116+
workflowsError,
117+
reloadWorkflows,
118+
reloadWorkflowStatus,
119+
}
120+
}

0 commit comments

Comments
 (0)