Skip to content

Commit 237a40c

Browse files
committed
Merge branch 'test/cd-trigger' of https://github.com/devtron-labs/dashboard into feat/common-cd-material
2 parents 3e8be4b + 9b4be29 commit 237a40c

File tree

13 files changed

+172
-79
lines changed

13 files changed

+172
-79
lines changed

src/components/ApplicationGroup/AppGroup.types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export type BulkCDDetailDerivedFromNode = Required<
7979
>
8080
> & {
8181
stageNotAvailable: boolean
82-
warningMessage: string
82+
errorMessage: string
8383
triggerBlockedInfo: TriggerBlockedInfo
8484
consequence: CommonNodeAttr['pluginBlockState']
8585
showPluginWarning: CommonNodeAttr['showPluginWarning']
@@ -92,6 +92,7 @@ export type BulkCDDetailType = BulkCDDetailDerivedFromNode &
9292
*/
9393
areMaterialsLoading: boolean
9494
materialError: ServerErrors | null
95+
tagsWarningMessage: string
9596
}
9697

9798
export interface BulkCDDetailTypeResponse {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
490490
workflows={filteredWorkflows}
491491
isVirtualEnvironment={isVirtualEnv}
492492
envId={+envId}
493-
handleSuccess={reloadTriggerView}
493+
handleSuccess={getWorkflowStatusData}
494494
/>
495495
)
496496
}
@@ -533,7 +533,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
533533

534534
return (
535535
<ApprovalMaterialModal
536-
isLoading={false}
537536
node={node ?? ({} as CommonNodeAttr)}
538537
materialType={MATERIAL_TYPE.inputMaterialList}
539538
stageType={DeploymentNodeType.CD}

src/components/app/details/appDetails/AppDetails.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,6 @@ const Details: React.FC<DetailsType> = ({
592592
environmentName={appDetails.environmentName}
593593
isVirtualEnvironment={appDetails.isVirtualEnvironment}
594594
deploymentAppType={appDetails.deploymentAppType}
595-
loadingDetails={loadingDetails}
596595
cdModal={{
597596
cdPipelineId: appDetails.cdPipelineId,
598597
ciPipelineId: appDetails.ciPipelineId,

src/components/app/details/appDetails/AppDetailsCDModal.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ const AppDetailsCDModal = ({
3434
cdModal,
3535
deploymentAppType,
3636
isVirtualEnvironment,
37-
loadingDetails,
3837
environmentName,
3938
handleSuccess,
4039
materialType,
@@ -55,7 +54,6 @@ const AppDetailsCDModal = ({
5554
ApprovalMaterialModal &&
5655
location.search.includes(TRIGGER_VIEW_PARAMS.APPROVAL_NODE) && (
5756
<ApprovalMaterialModal
58-
isLoading={loadingDetails}
5957
node={node}
6058
materialType={materialType}
6159
stageType={DeploymentNodeType.CD}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const BulkDeployEmptyState = ({
5252
return (
5353
<GenericEmptyState
5454
image={emptyPreDeploy}
55-
title={`${selectedApp?.appName} ${BULK_CD_MESSAGING[stageType].title}`}
55+
title={`${selectedApp.appName} ${BULK_CD_MESSAGING[stageType].title}`}
5656
subTitle={BULK_CD_MESSAGING[stageType].subTitle}
5757
/>
5858
)

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

Lines changed: 83 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Dispatch, SetStateAction, SyntheticEvent, useEffect, useMemo, useRef, useState } from 'react'
2+
import { Prompt } from 'react-router-dom'
23

34
import {
45
AnimatedDeployButton,
@@ -7,11 +8,13 @@ import {
78
ButtonStyleType,
89
CDMaterialResponseType,
910
CDMaterialServiceEnum,
11+
DEFAULT_ROUTE_PROMPT_MESSAGE,
1012
DeploymentNodeType,
1113
DeploymentStrategyTypeWithDefault,
1214
Drawer,
1315
genericCDMaterialsService,
1416
GenericEmptyState,
17+
getIsApprovalPolicyConfigured,
1518
Icon,
1619
MODAL_TYPE,
1720
ModuleNameMap,
@@ -27,6 +30,7 @@ import {
2730
uploadCDPipelineFile,
2831
useAsync,
2932
useMainContext,
33+
usePrompt,
3034
} from '@devtron-labs/devtron-fe-common-lib'
3135

3236
import { ResponseRowType } from '@Components/ApplicationGroup/AppGroup.types'
@@ -97,6 +101,8 @@ const BulkDeployModal = ({
97101
const isSecurityModuleInstalled = moduleInfoRes && moduleInfoRes?.result?.status === ModuleStatus.INSTALLED
98102
const isCDStage = stageType === DeploymentNodeType.CD
99103

104+
usePrompt({ shouldPrompt: isDeploymentLoading })
105+
100106
useEffect(
101107
() => () => {
102108
initialDataAbortControllerRef.current.abort()
@@ -139,7 +145,7 @@ const BulkDeployModal = ({
139145
(node) => node.type === stageType && +node.environmentId === +envId,
140146
)
141147

142-
if (!currentStageNode) {
148+
if (!currentStageNode || baseBulkCDDetailMap[workflow.appId].errorMessage) {
143149
return () => null
144150
}
145151

@@ -167,7 +173,7 @@ const BulkDeployModal = ({
167173
)
168174

169175
const appEnvList = validWorkflows
170-
.filter((workflow) => !baseBulkCDDetailMap[workflow.appId].warningMessage)
176+
.filter((workflow) => !baseBulkCDDetailMap[workflow.appId].errorMessage)
171177
.map((workflow) => ({
172178
appId: workflow.appId,
173179
envId: +envId,
@@ -223,7 +229,8 @@ const BulkDeployModal = ({
223229
},
224230
}))
225231

226-
const { deploymentWindowMetadata, materialError, warningMessage } = response[selectedAppId] || {}
232+
const { deploymentWindowMetadata, materialError, errorMessage, tagsWarningMessage } =
233+
response[selectedAppId] || {}
227234

228235
if (materialError) {
229236
showError(materialError)
@@ -243,7 +250,8 @@ const BulkDeployModal = ({
243250
[selectedAppId]: {
244251
...prev[selectedAppId],
245252
materialResponse: response[selectedAppId]?.materialResponse,
246-
warningMessage,
253+
errorMessage,
254+
tagsWarningMessage,
247255
materialError,
248256
deploymentWindowMetadata,
249257
deployViewState: {
@@ -385,8 +393,6 @@ const BulkDeployModal = ({
385393
return
386394
}
387395

388-
setIsDeploymentLoading(true)
389-
390396
const { cdTriggerPromiseFunctions, triggeredAppIds } = getTriggerCDPromiseMethods({
391397
appInfoMap,
392398
appsToRetry,
@@ -396,11 +402,14 @@ const BulkDeployModal = ({
396402
bulkDeploymentStrategy,
397403
})
398404

405+
setIsDeploymentLoading(true)
406+
setNumberOfAppsLoading(triggeredAppIds.length)
407+
399408
if (!triggeredAppIds.length) {
400409
setIsDeploymentLoading(false)
401410
ToastManager.showToast({
402411
variant: ToastVariantType.error,
403-
description: 'No applications selected for deployment',
412+
description: 'No valid applications are present for deployment',
404413
})
405414
return
406415
}
@@ -418,6 +427,7 @@ const BulkDeployModal = ({
418427

419428
setResponseList(newResponseList)
420429
setIsDeploymentLoading(false)
430+
setNumberOfAppsLoading(0)
421431
}
422432

423433
const setDeployViewState: DeployImageContentProps['setDeployViewState'] = (getUpdatedDeployViewState) => {
@@ -469,11 +479,9 @@ const BulkDeployModal = ({
469479
const { tagsWarning, updatedMaterials } = getUpdatedMaterialsForTagSelection(
470480
tagOption.value,
471481
appDetails.materialResponse?.materials || [],
472-
)
473-
474-
const { tagsWarning: previousTagWarning } = getUpdatedMaterialsForTagSelection(
475-
selectedImageTagOption.value,
476-
appDetails.materialResponse?.materials || [],
482+
!getIsApprovalPolicyConfigured(
483+
appDetails.materialResponse?.deploymentApprovalInfo?.approvalConfigData,
484+
) || getIsExceptionUser(appDetails.materialResponse),
477485
)
478486

479487
updatedAppInfoMap[appDetails.appId] = {
@@ -482,8 +490,7 @@ const BulkDeployModal = ({
482490
...appDetails.materialResponse,
483491
materials: updatedMaterials,
484492
},
485-
warningMessage:
486-
previousTagWarning || !appDetails.warningMessage ? tagsWarning : appDetails.warningMessage,
493+
tagsWarningMessage: tagsWarning,
487494
}
488495
})
489496
return updatedAppInfoMap
@@ -502,16 +509,37 @@ const BulkDeployModal = ({
502509
await onClickDeploy(e)
503510
}
504511

505-
const isDeployButtonDisabled = useMemo(
506-
() =>
512+
const onImageSelection: DeployImageContentProps['onImageSelection'] = () => {
513+
// Will just clear the tagsWarningMessage for app others are handled in DeployImageContent
514+
setAppInfoMap((prev) => ({
515+
...prev,
516+
[selectedAppId]: {
517+
...prev[selectedAppId],
518+
tagsWarningMessage: '',
519+
},
520+
}))
521+
}
522+
523+
const isDeployButtonDisabled = useMemo(() => {
524+
const atleastOneImageSelected = Object.values(appInfoMap).some((appDetails) =>
525+
(appDetails.materialResponse?.materials || []).some((material) => material.isSelected),
526+
)
527+
528+
if (!atleastOneImageSelected) {
529+
return true
530+
}
531+
532+
return (
507533
isDeploymentLoading ||
508534
isLoadingAppInfoMap ||
535+
// Not disabling deploy button even if there is a warning message, since apps with warning will not have selected materials
536+
// and hence will not be deployed
509537
Object.values(appInfoMap).some((appDetails) => {
510-
const { materialResponse, deployViewState, areMaterialsLoading } = appDetails
511-
return areMaterialsLoading || !materialResponse || !deployViewState
512-
}),
513-
[appInfoMap, isDeploymentLoading, isLoadingAppInfoMap],
514-
)
538+
const { areMaterialsLoading } = appDetails
539+
return areMaterialsLoading
540+
})
541+
)
542+
}, [appInfoMap, isDeploymentLoading, isLoadingAppInfoMap])
515543

516544
const canDeployWithoutApproval = useMemo(
517545
() =>
@@ -632,6 +660,7 @@ const BulkDeployModal = ({
632660
handleTagChange={handleTagChange}
633661
changeApp={changeApp}
634662
selectedTagName={selectedImageTagOption.value}
663+
onImageSelection={onImageSelection}
635664
/>
636665
)
637666
}
@@ -682,7 +711,7 @@ const BulkDeployModal = ({
682711
onButtonClick={onClickStartDeploy}
683712
disabled={isDeployButtonDisabled}
684713
isLoading={isDeploymentLoading}
685-
animateStartIcon={isCDStage}
714+
animateStartIcon={isCDStage && !isDeployButtonDisabled}
686715
style={
687716
canDeployWithoutApproval || canImageApproverDeploy
688717
? ButtonStyleType.warning
@@ -701,36 +730,42 @@ const BulkDeployModal = ({
701730
}
702731

703732
return (
704-
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px">
705-
<div
706-
className="flexbox-col dc__content-space h-100 bg__modal--primary shadow__modal dc__overflow-auto bulk-ci-trigger-container"
707-
onClick={stopPropagation}
708-
>
709-
<div className="flexbox-col dc__overflow-auto flex-grow-1">
710-
<DeployImageHeader
711-
handleClose={handleClose}
712-
envName={envName}
713-
stageType={stageType}
714-
isRollbackTrigger={false}
715-
isVirtualEnvironment={isVirtualEnvironment}
716-
handleNavigateToMaterialListView={showStrategyFeasibilityPage ? handleNavigateToListView : null}
717-
title={showStrategyFeasibilityPage ? 'Deployment feasibility for' : ''}
718-
/>
733+
<>
734+
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px">
735+
<div
736+
className="flexbox-col dc__content-space h-100 bg__modal--primary shadow__modal dc__overflow-auto bulk-ci-trigger-container"
737+
onClick={stopPropagation}
738+
>
739+
<div className="flexbox-col dc__overflow-auto flex-grow-1">
740+
<DeployImageHeader
741+
handleClose={handleClose}
742+
envName={envName}
743+
stageType={stageType}
744+
isRollbackTrigger={false}
745+
isVirtualEnvironment={isVirtualEnvironment}
746+
handleNavigateToMaterialListView={
747+
showStrategyFeasibilityPage ? handleNavigateToListView : null
748+
}
749+
title={showStrategyFeasibilityPage ? 'Deployment feasibility for' : ''}
750+
/>
751+
752+
<div className="flex-grow-1 dc__overflow-auto bg__tertiary w-100">{renderContent()}</div>
753+
</div>
719754

720-
<div className="flex-grow-1 dc__overflow-auto bg__tertiary w-100">{renderContent()}</div>
755+
{isLoadingAppInfoMap || showStrategyFeasibilityPage ? null : renderFooter()}
721756
</div>
722757

723-
{isLoadingAppInfoMap || showStrategyFeasibilityPage ? null : renderFooter()}
724-
</div>
758+
{showResistanceBox && (
759+
<BulkDeployResistanceTippy
760+
actionHandler={onClickStartDeploy}
761+
handleOnClose={hideResistanceBox}
762+
modalType={MODAL_TYPE.DEPLOY}
763+
/>
764+
)}
765+
</Drawer>
725766

726-
{showResistanceBox && (
727-
<BulkDeployResistanceTippy
728-
actionHandler={onClickStartDeploy}
729-
handleOnClose={hideResistanceBox}
730-
modalType={MODAL_TYPE.DEPLOY}
731-
/>
732-
)}
733-
</Drawer>
767+
<Prompt when={isDeploymentLoading} message={DEFAULT_ROUTE_PROMPT_MESSAGE} />
768+
</>
734769
)
735770
}
736771

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,25 @@ const BulkTriggerSidebar = ({
152152
return <TriggerBlockedError stageType={stageType} />
153153
}
154154

155-
if ((!!app.warningMessage && !app.showPluginWarning) || app.materialError?.errors?.length) {
155+
const isRuntimeParamsErrorPresent =
156+
app.deployViewState?.runtimeParamsErrorState && !app.deployViewState.runtimeParamsErrorState.isValid
157+
158+
if (
159+
(!!app.errorMessage && !app.showPluginWarning) ||
160+
app.materialError?.errors?.length ||
161+
app.tagsWarningMessage ||
162+
isRuntimeParamsErrorPresent
163+
) {
156164
return (
157165
<div className="flex left top dc__gap-4">
158-
<Icon name="ic-warning-fill" color="R500" size={14} />
159-
<span className="fw-4 fs-12 cr-5 dc__truncate--clamp-2">
160-
{app.warningMessage || app.materialError?.errors?.[0]?.userMessage}
166+
<div className="dc__no-shrink mt-2">
167+
<Icon name="ic-warning-fill" color="R500" size={14} />
168+
</div>
169+
<span className="fw-4 fs-12 cr-5 dc__truncate--clamp-2 lh-20">
170+
{app.errorMessage ||
171+
app.materialError?.errors?.[0]?.userMessage ||
172+
app.tagsWarningMessage ||
173+
'Invalid runtime parameters'}
161174
</span>
162175
</div>
163176
)

0 commit comments

Comments
 (0)