Skip to content

Commit 57cd39c

Browse files
committed
refactor: update error handling and improve type definitions in deployment components
1 parent daf2db3 commit 57cd39c

File tree

13 files changed

+146
-76
lines changed

13 files changed

+146
-76
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
@@ -492,7 +492,7 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
492492
workflows={filteredWorkflows}
493493
isVirtualEnvironment={isVirtualEnv}
494494
envId={+envId}
495-
handleSuccess={reloadTriggerView}
495+
handleSuccess={getWorkflowStatusData}
496496
/>
497497
)
498498
}
@@ -611,7 +611,6 @@ const EnvTriggerView = ({ filteredAppIds, isVirtualEnv }: AppGroupDetailDefaultT
611611

612612
return (
613613
<ApprovalMaterialModal
614-
isLoading={false}
615614
node={node ?? ({} as CommonNodeAttr)}
616615
materialType={MATERIAL_TYPE.inputMaterialList}
617616
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: 79 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,6 +8,7 @@ import {
78
ButtonStyleType,
89
CDMaterialResponseType,
910
CDMaterialServiceEnum,
11+
DEFAULT_ROUTE_PROMPT_MESSAGE,
1012
DeploymentNodeType,
1113
DeploymentStrategyTypeWithDefault,
1214
Drawer,
@@ -27,6 +29,7 @@ import {
2729
uploadCDPipelineFile,
2830
useAsync,
2931
useMainContext,
32+
usePrompt,
3033
} from '@devtron-labs/devtron-fe-common-lib'
3134

3235
import { ResponseRowType } from '@Components/ApplicationGroup/AppGroup.types'
@@ -97,6 +100,8 @@ const BulkDeployModal = ({
97100
const isSecurityModuleInstalled = moduleInfoRes && moduleInfoRes?.result?.status === ModuleStatus.INSTALLED
98101
const isCDStage = stageType === DeploymentNodeType.CD
99102

103+
usePrompt({ shouldPrompt: isDeploymentLoading })
104+
100105
useEffect(
101106
() => () => {
102107
initialDataAbortControllerRef.current.abort()
@@ -139,7 +144,7 @@ const BulkDeployModal = ({
139144
(node) => node.type === stageType && +node.environmentId === +envId,
140145
)
141146

142-
if (!currentStageNode) {
147+
if (!currentStageNode || baseBulkCDDetailMap[workflow.appId].errorMessage) {
143148
return () => null
144149
}
145150

@@ -167,7 +172,7 @@ const BulkDeployModal = ({
167172
)
168173

169174
const appEnvList = validWorkflows
170-
.filter((workflow) => !baseBulkCDDetailMap[workflow.appId].warningMessage)
175+
.filter((workflow) => !baseBulkCDDetailMap[workflow.appId].errorMessage)
171176
.map((workflow) => ({
172177
appId: workflow.appId,
173178
envId: +envId,
@@ -223,7 +228,8 @@ const BulkDeployModal = ({
223228
},
224229
}))
225230

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

228234
if (materialError) {
229235
showError(materialError)
@@ -243,7 +249,8 @@ const BulkDeployModal = ({
243249
[selectedAppId]: {
244250
...prev[selectedAppId],
245251
materialResponse: response[selectedAppId]?.materialResponse,
246-
warningMessage,
252+
errorMessage,
253+
tagsWarningMessage,
247254
materialError,
248255
deploymentWindowMetadata,
249256
deployViewState: {
@@ -385,8 +392,6 @@ const BulkDeployModal = ({
385392
return
386393
}
387394

388-
setIsDeploymentLoading(true)
389-
390395
const { cdTriggerPromiseFunctions, triggeredAppIds } = getTriggerCDPromiseMethods({
391396
appInfoMap,
392397
appsToRetry,
@@ -396,11 +401,14 @@ const BulkDeployModal = ({
396401
bulkDeploymentStrategy,
397402
})
398403

404+
setIsDeploymentLoading(true)
405+
setNumberOfAppsLoading(triggeredAppIds.length)
406+
399407
if (!triggeredAppIds.length) {
400408
setIsDeploymentLoading(false)
401409
ToastManager.showToast({
402410
variant: ToastVariantType.error,
403-
description: 'No applications selected for deployment',
411+
description: 'No valid applications are present for deployment',
404412
})
405413
return
406414
}
@@ -418,6 +426,7 @@ const BulkDeployModal = ({
418426

419427
setResponseList(newResponseList)
420428
setIsDeploymentLoading(false)
429+
setNumberOfAppsLoading(0)
421430
}
422431

423432
const setDeployViewState: DeployImageContentProps['setDeployViewState'] = (getUpdatedDeployViewState) => {
@@ -471,19 +480,13 @@ const BulkDeployModal = ({
471480
appDetails.materialResponse?.materials || [],
472481
)
473482

474-
const { tagsWarning: previousTagWarning } = getUpdatedMaterialsForTagSelection(
475-
selectedImageTagOption.value,
476-
appDetails.materialResponse?.materials || [],
477-
)
478-
479483
updatedAppInfoMap[appDetails.appId] = {
480484
...appDetails,
481485
materialResponse: {
482486
...appDetails.materialResponse,
483487
materials: updatedMaterials,
484488
},
485-
warningMessage:
486-
previousTagWarning || !appDetails.warningMessage ? tagsWarning : appDetails.warningMessage,
489+
tagsWarningMessage: tagsWarning,
487490
}
488491
})
489492
return updatedAppInfoMap
@@ -502,16 +505,37 @@ const BulkDeployModal = ({
502505
await onClickDeploy(e)
503506
}
504507

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

516540
const canDeployWithoutApproval = useMemo(
517541
() =>
@@ -632,6 +656,7 @@ const BulkDeployModal = ({
632656
handleTagChange={handleTagChange}
633657
changeApp={changeApp}
634658
selectedTagName={selectedImageTagOption.value}
659+
onImageSelection={onImageSelection}
635660
/>
636661
)
637662
}
@@ -682,7 +707,7 @@ const BulkDeployModal = ({
682707
onButtonClick={onClickStartDeploy}
683708
disabled={isDeployButtonDisabled}
684709
isLoading={isDeploymentLoading}
685-
animateStartIcon={isCDStage}
710+
animateStartIcon={isCDStage && !isDeployButtonDisabled}
686711
style={
687712
canDeployWithoutApproval || canImageApproverDeploy
688713
? ButtonStyleType.warning
@@ -701,36 +726,42 @@ const BulkDeployModal = ({
701726
}
702727

703728
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-
/>
729+
<>
730+
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px">
731+
<div
732+
className="flexbox-col dc__content-space h-100 bg__modal--primary shadow__modal dc__overflow-auto bulk-ci-trigger-container"
733+
onClick={stopPropagation}
734+
>
735+
<div className="flexbox-col dc__overflow-auto flex-grow-1">
736+
<DeployImageHeader
737+
handleClose={handleClose}
738+
envName={envName}
739+
stageType={stageType}
740+
isRollbackTrigger={false}
741+
isVirtualEnvironment={isVirtualEnvironment}
742+
handleNavigateToMaterialListView={
743+
showStrategyFeasibilityPage ? handleNavigateToListView : null
744+
}
745+
title={showStrategyFeasibilityPage ? 'Deployment feasibility for' : ''}
746+
/>
747+
748+
<div className="flex-grow-1 dc__overflow-auto bg__tertiary w-100">{renderContent()}</div>
749+
</div>
719750

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

723-
{isLoadingAppInfoMap || showStrategyFeasibilityPage ? null : renderFooter()}
724-
</div>
754+
{showResistanceBox && (
755+
<BulkDeployResistanceTippy
756+
actionHandler={onClickStartDeploy}
757+
handleOnClose={hideResistanceBox}
758+
modalType={MODAL_TYPE.DEPLOY}
759+
/>
760+
)}
761+
</Drawer>
725762

726-
{showResistanceBox && (
727-
<BulkDeployResistanceTippy
728-
actionHandler={onClickStartDeploy}
729-
handleOnClose={hideResistanceBox}
730-
modalType={MODAL_TYPE.DEPLOY}
731-
/>
732-
)}
733-
</Drawer>
763+
<Prompt when={isDeploymentLoading} message={DEFAULT_ROUTE_PROMPT_MESSAGE} />
764+
</>
734765
)
735766
}
736767

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)