Skip to content

Commit a281a57

Browse files
committed
feat: add support for skipping hibernated apps in bulk deploy
1 parent a076ee4 commit a281a57

File tree

5 files changed

+57
-21
lines changed

5 files changed

+57
-21
lines changed

src/components/ApplicationGroup/AppGroup.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export interface BulkCDTriggerType extends BulkRuntimeParamsType {
133133
appList: BulkCDDetailType[]
134134
closePopup: (e) => void
135135
updateBulkInputMaterial: (materialList: Record<string, any>) => void
136-
onClickTriggerBulkCD: (appsToRetry?: Record<string, boolean>) => void
136+
onClickTriggerBulkCD: (skipIfHibernated: boolean, appsToRetry?: Record<string, boolean>) => void
137137
changeTab?: (
138138
materrialId: string | number,
139139
artifactId: number,

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

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
CDMaterialResponseType,
2020
DeploymentNodeType,
2121
Drawer,
22-
Progressing,
2322
ReleaseTag,
2423
ImageComment,
2524
showError,
@@ -48,9 +47,12 @@ import {
4847
Button,
4948
ComponentSizeType,
5049
AnimatedDeployButton,
50+
ButtonVariantType,
51+
Icon,
52+
ButtonStyleType,
53+
useMainContext,
5154
} from '@devtron-labs/devtron-fe-common-lib'
5255
import { useHistory, useLocation } from 'react-router-dom'
53-
import { ReactComponent as Close } from '@Icons/ic-cross.svg'
5456
import { ReactComponent as DeployIcon } from '@Icons/ic-nav-rocket.svg'
5557
import { ReactComponent as PlayIcon } from '@Icons/ic-play-outline.svg'
5658
import { ReactComponent as Error } from '@Icons/ic-warning.svg'
@@ -89,6 +91,7 @@ const validateRuntimeParameters = importComponentFromFELibrary(
8991
() => ({ isValid: true, cellError: {} }),
9092
'function',
9193
)
94+
const SkipHibernatedCheckbox = importComponentFromFELibrary('SkipHibernatedCheckbox', null, 'function')
9295

9396
// TODO: Fix release tags selection
9497
export default function BulkCDTrigger({
@@ -109,6 +112,7 @@ export default function BulkCDTrigger({
109112
runtimeParamsErrorState,
110113
setRuntimeParamsErrorState,
111114
}: BulkCDTriggerType) {
115+
const { isScoopConfigured } = useMainContext()
112116
const [selectedApp, setSelectedApp] = useState<BulkCDDetailType>(
113117
appList.find((app) => !app.warningMessage) || appList[0],
114118
)
@@ -125,6 +129,7 @@ export default function BulkCDTrigger({
125129
const [isPartialActionAllowed, setIsPartialActionAllowed] = useState(false)
126130
const [showResistanceBox, setShowResistanceBox] = useState(false)
127131
const [currentSidebarTab, setCurrentSidebarTab] = useState<CDMaterialSidebarType>(CDMaterialSidebarType.IMAGE)
132+
const [skipHibernated, setSkipHibernated] = useState<boolean>(false)
128133

129134
const location = useLocation()
130135
const history = useHistory()
@@ -351,15 +356,18 @@ export default function BulkCDTrigger({
351356
const renderHeaderSection = (): JSX.Element => {
352357
return (
353358
<div className="flex flex-align-center flex-justify dc__border-bottom bg__primary pt-16 pr-20 pb-16 pl-20">
354-
<h2 className="fs-16 fw-6 lh-1-43 m-0">Deploy to {appList[0].envName}</h2>
355-
<button
356-
type="button"
357-
className="dc__transparent flex icon-dim-24"
359+
<h2 className="fs-16 fw-6 lh-1-5 m-0">Deploy to {appList[0].envName}</h2>
360+
<Button
361+
dataTestId="bulk-cd-modal-close"
358362
disabled={isLoading}
359363
onClick={closeBulkCDModal}
360-
>
361-
<Close className="icon-dim-24" />
362-
</button>
364+
size={ComponentSizeType.xs}
365+
icon={<Icon name="ic-close-small" size={null} color={null} />}
366+
ariaLabel="close bulk cd trigger modal"
367+
showAriaLabelInTippy={false}
368+
style={ButtonStyleType.negativeGrey}
369+
variant={ButtonVariantType.borderLess}
370+
/>
363371
</div>
364372
)
365373
}
@@ -829,13 +837,15 @@ export default function BulkCDTrigger({
829837
setShowResistanceBox(false)
830838
}
831839

840+
const triggerBulkCD = () => onClickTriggerBulkCD(skipHibernated)
841+
832842
const onClickStartDeploy = (e): void => {
833843
if (isPartialActionAllowed && BulkDeployResistanceTippy && !showResistanceBox) {
834844
setShowResistanceBox(true)
835845
} else {
836846
isBulkDeploymentTriggered.current = true
837847
stopPropagation(e)
838-
onClickTriggerBulkCD()
848+
triggerBulkCD()
839849
setShowResistanceBox(false)
840850
}
841851
}
@@ -848,8 +858,21 @@ export default function BulkCDTrigger({
848858

849859
const renderFooterSection = (): JSX.Element => {
850860
const isDeployButtonDisabled: boolean = isDeployDisabled()
861+
const showSkipHibernatedCheckbox = stage === DeploymentNodeType.CD && !!SkipHibernatedCheckbox
851862
return (
852-
<div className="dc__border-top flex right bg__primary px-20 py-16">
863+
<div
864+
className={`dc__border-top flex ${showSkipHibernatedCheckbox ? 'dc__content-space' : 'right'} bg__primary px-20 py-16`}
865+
>
866+
{showSkipHibernatedCheckbox && (
867+
<SkipHibernatedCheckbox
868+
isDeploymentLoading={isLoading}
869+
envId={appList[0].envId}
870+
envName={appList[0].envName}
871+
appIds={appList.map((app) => app.appId)}
872+
skipHibernated={skipHibernated}
873+
setSkipHibernated={setSkipHibernated}
874+
/>
875+
)}
853876
<div className="dc__position-rel tippy-over">
854877
{!isDeployButtonDisabled && stage === DeploymentNodeType.CD && !isLoading ? (
855878
<AnimatedDeployButton onButtonClick={onClickStartDeploy} isVirtualEnvironment={false} />
@@ -874,7 +897,7 @@ export default function BulkCDTrigger({
874897
return (
875898
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px">
876899
<div className="bg__primary bulk-ci-trigger-container">
877-
<div className='flexbox-col flex-grow-1 dc__overflow-hidden'>
900+
<div className="flexbox-col flex-grow-1 dc__overflow-hidden">
878901
{renderHeaderSection()}
879902
{responseListLength ? (
880903
<TriggerResponseModalBody
@@ -892,7 +915,7 @@ export default function BulkCDTrigger({
892915
closePopup={closeBulkCDModal}
893916
responseList={responseList}
894917
isLoading={isLoading}
895-
onClickRetryBuild={onClickTriggerBulkCD}
918+
onClickRetryBuild={triggerBulkCD}
896919
/>
897920
) : (
898921
renderFooterSection()

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
14291429
return true
14301430
}
14311431

1432-
const onClickTriggerBulkCD = (appsToRetry?: Record<string, boolean>) => {
1432+
const onClickTriggerBulkCD = (skipIfHibernated: boolean, appsToRetry?: Record<string, boolean>) => {
14331433
if (isCDLoading || !validateBulkRuntimeParams()) {
14341434
return
14351435
}
@@ -1482,6 +1482,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
14821482
...(getRuntimeParamsPayload
14831483
? { runtimeParamsPayload: getRuntimeParamsPayload(runtimeParams[currentAppId] ?? []) }
14841484
: {}),
1485+
skipIfHibernated: skipIfHibernated,
14851486
}),
14861487
)
14871488
} else {
@@ -1941,7 +1942,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
19411942
}
19421943
if (!filteredWorkflows.length) {
19431944
return (
1944-
<div className='flex-grow-1'>
1945+
<div className="flex-grow-1">
19451946
<AppNotConfigured />
19461947
</div>
19471948
)
@@ -2099,7 +2100,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
20992100
)
21002101
}
21012102

2102-
const renderBulkSourchChange = (): JSX.Element | null => {
2103+
const renderBulkSourceChange = (): JSX.Element | null => {
21032104
if (!showBulkSourceChangeModal) {
21042105
return null
21052106
}
@@ -2452,12 +2453,12 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
24522453
{renderBulkCDMaterial()}
24532454
{renderBulkCIMaterial()}
24542455
{renderApprovalMaterial()}
2455-
{renderBulkSourchChange()}
2456+
{renderBulkSourceChange()}
24562457
</TriggerViewContext.Provider>
24572458
<div />
24582459
</div>
24592460
{!!selectedAppList.length && (
2460-
<div className="flexbox dc__gap-8 dc__content-space dc__border-top w-100 bg__primary pt-12 pr-20 pb-12 pl-20">
2461+
<div className="flexbox dc__gap-8 dc__content-space dc__border-top w-100 bg__primary px-20 py-12">
24612462
{renderSelectedApps()}
24622463
{renderBulkTriggerActionButtons()}
24632464
</div>

src/components/app/details/triggerView/cdMaterial.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ const CDMaterial = ({
894894
...(getRuntimeParamsPayload
895895
? { runtimeParamsPayload: getRuntimeParamsPayload(runtimeParamsList ?? []) }
896896
: {}),
897+
skipIfHibernated: false,
897898
})
898899
.then((response: any) => {
899900
if (response.result) {

src/components/common/navigation/NavigationRoutes.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,18 @@ export default function NavigationRoutes() {
155155
const [environmentDataState, setEnvironmentDataState] = useState<
156156
Pick<
157157
MainContext,
158-
'isAirgapped' | 'isManifestScanningEnabled' | 'canOnlyViewPermittedEnvOrgLevel' | 'featureGitOpsFlags'
158+
| 'isAirgapped'
159+
| 'isManifestScanningEnabled'
160+
| 'canOnlyViewPermittedEnvOrgLevel'
161+
| 'featureGitOpsFlags'
162+
| 'isScoopConfigured'
159163
>
160164
>({
161165
isAirgapped: false,
162166
isManifestScanningEnabled: false,
163167
canOnlyViewPermittedEnvOrgLevel: false,
164168
featureGitOpsFlags: structuredClone(DEFAULT_GIT_OPS_FEATURE_FLAGS),
169+
isScoopConfigured: false,
165170
})
166171
const [userPreferences, setUserPreferences] = useState<UserPreferencesType>(null)
167172
const [userPreferencesError, setUserPreferencesError] = useState<ServerErrors>(null)
@@ -342,6 +347,7 @@ export default function NavigationRoutes() {
342347
isManifestScanningEnabled: false,
343348
canOnlyViewPermittedEnvOrgLevel: false,
344349
featureGitOpsFlags: structuredClone(DEFAULT_GIT_OPS_FEATURE_FLAGS),
350+
isScoopConfigured: false,
345351
}
346352

347353
if (!getEnvironmentData) {
@@ -361,6 +367,7 @@ export default function NavigationRoutes() {
361367
isManifestScanningEnabled: result.isManifestScanningEnabled,
362368
canOnlyViewPermittedEnvOrgLevel: result.canOnlyViewPermittedEnvOrgLevel,
363369
featureGitOpsFlags: parsedFeatureGitOpsFlags,
370+
isScoopConfigured: result.isScoopConfigured ?? false,
364371
}
365372
} catch {
366373
return fallbackResponse
@@ -408,6 +415,7 @@ export default function NavigationRoutes() {
408415
isManifestScanningEnabled: environmentDataResponse.isManifestScanningEnabled,
409416
canOnlyViewPermittedEnvOrgLevel: environmentDataResponse.canOnlyViewPermittedEnvOrgLevel,
410417
featureGitOpsFlags: environmentDataResponse.featureGitOpsFlags,
418+
isScoopConfigured: environmentDataResponse.isScoopConfigured,
411419
})
412420

413421
setServerMode(serverModeResponse)
@@ -484,7 +492,9 @@ export default function NavigationRoutes() {
484492
}
485493
const _isOnboardingPage = isOnboardingPage()
486494

487-
const handleOpenLicenseInfoDialog = (initialDialogTab?: LicenseInfoDialogType.ABOUT | LicenseInfoDialogType.LICENSE) => {
495+
const handleOpenLicenseInfoDialog = (
496+
initialDialogTab?: LicenseInfoDialogType.ABOUT | LicenseInfoDialogType.LICENSE,
497+
) => {
488498
setLicenseInfoDialogType(initialDialogTab || LicenseInfoDialogType.ABOUT)
489499
}
490500

@@ -526,6 +536,7 @@ export default function NavigationRoutes() {
526536
handleOpenLicenseInfoDialog,
527537
licenseData,
528538
setLicenseData,
539+
isScoopConfigured: environmentDataState.isScoopConfigured,
529540
}}
530541
>
531542
<main className={_isOnboardingPage ? 'no-nav' : ''} id={DEVTRON_BASE_MAIN_ID}>

0 commit comments

Comments
 (0)