Skip to content

Commit

Permalink
Merge pull request #2246 from devtron-labs/feat/mandatory-tags-cd
Browse files Browse the repository at this point in the history
feat: mandatory tags blocks trigger
  • Loading branch information
arunjaindev authored Dec 19, 2024
2 parents 97c7066 + bc72bbe commit 0bbd5b0
Show file tree
Hide file tree
Showing 22 changed files with 389 additions and 332 deletions.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ src/components/app/Overview/utils.tsx
src/components/app/ResourceTreeNodes.tsx
src/components/app/ResponsiveDrawer.tsx
src/components/app/WebWorker.ts
src/components/app/appLabelCommon.tsx
src/components/app/create/CreateApp.tsx
src/components/app/create/validationRules.ts
src/components/app/details/AboutAppInfoModal.tsx
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"homepage": "/dashboard",
"dependencies": {
"@devtron-labs/devtron-fe-common-lib": "1.3.0",
"@devtron-labs/devtron-fe-common-lib": "1.3.0-beta-7",
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@rjsf/core": "^5.13.3",
"@rjsf/utils": "^5.13.3",
Expand Down
9 changes: 8 additions & 1 deletion src/components/ApplicationGroup/AppGroup.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export interface BulkCDDetailTypeResponse {
export interface BulkCDDetailType
extends BulkTriggerAppDetailType,
Pick<CDMaterialProps, 'isTriggerBlockedDueToPlugin' | 'configurePluginURL' | 'consequence'>,
Partial<Pick<CommonNodeAttr, 'showPluginWarning'>> {
Partial<Pick<CommonNodeAttr, 'showPluginWarning' | 'triggerBlockedInfo'>> {
cdPipelineName?: string
cdPipelineId?: string
stageType?: DeploymentNodeType
Expand Down Expand Up @@ -613,4 +613,11 @@ export enum AppGroupUrlFilters {

export interface AppGroupUrlFiltersType extends Record<AppGroupUrlFilters, string[]> {}

export interface SetFiltersInLocalStorageParamsType {
filterParentType: FilterParentType
resourceId: string
resourceList: MultiValue<OptionType>
groupList: MultiValue<GroupOptionType>
}

export type AppEnvLocalStorageKeyType = `${string}__filter`
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,25 @@ import {
ToastManager,
ToastVariantType,
CommonNodeAttr,
TriggerBlockType,
RuntimePluginVariables,
uploadCDPipelineFile,
UploadFileProps,
} from '@devtron-labs/devtron-fe-common-lib'
import { useHistory, useLocation } from 'react-router-dom'
import { ReactComponent as Close } from '../../../../assets/icons/ic-cross.svg'
import { ReactComponent as DeployIcon } from '../../../../assets/icons/ic-nav-rocket.svg'
import { ReactComponent as PlayIcon } from '../../../../assets/icons/ic-play-medium.svg'
import { ReactComponent as Error } from '../../../../assets/icons/ic-warning.svg'
import { ReactComponent as UnAuthorized } from '../../../../assets/icons/ic-locked.svg'
import { ReactComponent as Tag } from '../../../../assets/icons/ic-tag.svg'
import { ReactComponent as Close } from '@Icons/ic-cross.svg'
import { ReactComponent as DeployIcon } from '@Icons/ic-nav-rocket.svg'
import { ReactComponent as PlayIcon } from '@Icons/ic-play-medium.svg'
import { ReactComponent as Error } from '@Icons/ic-warning.svg'
import { ReactComponent as UnAuthorized } from '@Icons/ic-locked.svg'
import { ReactComponent as Tag } from '@Icons/ic-tag.svg'
import emptyPreDeploy from '../../../../assets/img/empty-pre-deploy.png'
import notAuthorized from '../../../../assets/img/ic-not-authorized.svg'
import CDMaterial from '../../../app/details/triggerView/cdMaterial'
import { BulkSelectionEvents, MATERIAL_TYPE, RuntimeParamsErrorState } from '../../../app/details/triggerView/types'
import { BulkCDDetailType, BulkCDTriggerType } from '../../AppGroup.types'
import { BULK_CD_DEPLOYMENT_STATUS, BULK_CD_MATERIAL_STATUS, BULK_CD_MESSAGING, BUTTON_TITLE } from '../../Constants'
import TriggerResponseModal from './TriggerResponseModal'
import { EmptyView } from '../../../app/details/cicdHistory/History.components'
import { ReactComponent as MechanicalOperation } from '../../../../assets/img/ic-mechanical-operation.svg'
import { importComponentFromFELibrary } from '../../../common'
import { BULK_ERROR_MESSAGES } from './constants'
Expand All @@ -79,6 +79,8 @@ const getDeploymentWindowStateAppGroup = importComponentFromFELibrary(
const RuntimeParamTabs = importComponentFromFELibrary('RuntimeParamTabs', null, 'function')
const MissingPluginBlockState = importComponentFromFELibrary('MissingPluginBlockState', null, 'function')
const PolicyEnforcementMessage = importComponentFromFELibrary('PolicyEnforcementMessage')
const TriggerBlockedError = importComponentFromFELibrary('TriggerBlockedError', null, 'function')
const TriggerBlockEmptyState = importComponentFromFELibrary('TriggerBlockEmptyState', null, 'function')
const validateRuntimeParameters = importComponentFromFELibrary(
'validateRuntimeParameters',
() => ({ isValid: true, cellError: {} }),
Expand Down Expand Up @@ -389,6 +391,10 @@ export default function BulkCDTrigger({
}

const renderEmptyView = (): JSX.Element => {
if (selectedApp.triggerBlockedInfo?.blockedBy === TriggerBlockType.MANDATORY_TAG) {
return <TriggerBlockEmptyState stageType={selectedApp.stageType} appId={selectedApp.appId} />
}

if (selectedApp.isTriggerBlockedDueToPlugin) {
const commonNodeAttrType: CommonNodeAttr['type'] =
selectedApp.stageType === DeploymentNodeType.PRECD ? 'PRECD' : 'POSTCD'
Expand All @@ -403,16 +409,16 @@ export default function BulkCDTrigger({

if (unauthorizedAppList[selectedApp.appId]) {
return (
<EmptyView
imgSrc={notAuthorized}
<GenericEmptyState
image={notAuthorized}
title={BULK_CD_MESSAGING.unauthorized.title}
subTitle={BULK_CD_MESSAGING.unauthorized.subTitle}
/>
)
}
return (
<EmptyView
imgSrc={emptyPreDeploy}
<GenericEmptyState
image={emptyPreDeploy}
title={`${selectedApp.name} ${BULK_CD_MESSAGING[stage].title}`}
subTitle={BULK_CD_MESSAGING[stage].subTitle}
/>
Expand Down Expand Up @@ -457,11 +463,14 @@ export default function BulkCDTrigger({
)
}

if (app.triggerBlockedInfo?.blockedBy === TriggerBlockType.MANDATORY_TAG) {
return <TriggerBlockedError stageType={app.stageType} />
}

if (!!warningMessage && !app.showPluginWarning) {
return (
<div className="flex left top dc__gap-4">
<Error className="icon-dim-12 dc__no-shrink mt-5 warning-icon-y7" />

<span className="fw-4 fs-12 cy-7 dc__truncate">{warningMessage}</span>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ import {
ToastManager,
ToastVariantType,
BlockedStateData,
getStageTitle,
TriggerBlockType,
RuntimePluginVariables,
uploadCIPipelineFile,
} from '@devtron-labs/devtron-fe-common-lib'
import Tippy from '@tippyjs/react'
import {
Expand Down Expand Up @@ -1764,7 +1765,10 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
const stageType = DeploymentNodeType[_selectedNode.type]
const isTriggerBlockedDueToPlugin =
_selectedNode.isTriggerBlocked && _selectedNode.showPluginWarning
const stageText = stageType === DeploymentNodeType.PRECD ? 'Pre-Deployment' : 'Post-Deployment'
const isTriggerBlockedDueToMandatoryTags =
_selectedNode.isTriggerBlocked &&
_selectedNode.triggerBlockedInfo?.blockedBy === TriggerBlockType.MANDATORY_TAG
const stageText = getStageTitle(stageType)

_selectedAppWorkflowList.push({
workFlowId: wf.id,
Expand Down Expand Up @@ -1798,7 +1802,11 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
true,
),
consequence: _selectedNode.pluginBlockState,
warningMessage: isTriggerBlockedDueToPlugin ? `${stageText} is blocked` : '',
warningMessage:
isTriggerBlockedDueToPlugin || isTriggerBlockedDueToMandatoryTags
? `${stageText} is blocked`
: '',
triggerBlockedInfo: _selectedNode.triggerBlockedInfo,
})
} else {
let warningMessage = ''
Expand Down
27 changes: 15 additions & 12 deletions src/components/app/Overview/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -341,20 +341,23 @@ export default function AppOverview({ appMetaInfo, getAppMetaInfoRes, filteredEn
}

const renderLabelTags = () => (
<div className="flexbox-col dc__gap-12">
<div className="flexbox flex-justify dc__gap-10">
<div className="flexbox flex-align-center dc__gap-8 fs-13 fw-6 lh-20 cn-9">
<TagIcon className="tags-icon icon-dim-20" />
Tags
<div>
<div className="flexbox-col dc__gap-12">
<div className="flexbox flex-justify dc__gap-10">
<div className="flexbox flex-align-center dc__gap-8 fs-13 fw-6 lh-20 cn-9">
<TagIcon className="tags-icon icon-dim-20" />
Tags
</div>
<EditIcon className="icon-dim-16 cursor mw-16" onClick={toggleTagsUpdateModal} />
</div>
<EditIcon className="icon-dim-16 cursor mw-16" onClick={toggleTagsUpdateModal} />
<TagChipsContainer
appType={appType}
labelTags={currentLabelTags}
onAddTagButtonClick={toggleTagsUpdateModal}
resourceName={resourceName}
whiteBackground
/>
</div>
<TagChipsContainer
labelTags={currentLabelTags}
onAddTagButtonClick={toggleTagsUpdateModal}
resourceName={resourceName}
whiteBackground
/>
{MandatoryTagWarning && (
<MandatoryTagWarning
labelTags={currentLabelTags}
Expand Down
11 changes: 7 additions & 4 deletions src/components/app/Overview/TagChipsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@
* limitations under the License.
*/

import React from 'react'
import Tippy from '@tippyjs/react'
import { ReactComponent as InjectTag } from '../../../assets/icons/inject-tag.svg'
import { ReactComponent as InjectTag } from '@Icons/inject-tag.svg'
import { TagChipsContainerType } from '../types'
import { APP_TYPE } from '@Config/constants'

export default function TagChipsContainer({
appType,
labelTags,
onAddTagButtonClick,
resourceName,
whiteBackground = false,
}: TagChipsContainerType) {
return (
<div className="flex left flex-wrap dc__gap-8" data-testid="tag-chip-container">
<div className="flex left flex-wrap dc__gap-6" data-testid="tag-chip-container">
{labelTags.length > 0 ? (
labelTags.map((tag, index) => (
<div key={tag.id} className="display-grid grid-auto-flow-column">
Expand All @@ -37,7 +38,9 @@ export default function TagChipsContainer({
!tag.value ? ' br-4' : ' dc__left-radius-4'
}`}
>
{tag.propagate && <InjectTag className="icon-dim-16 mt-2 mr-4 mw-16" />}
{appType !== APP_TYPE.HELM_CHART && tag.propagate && (
<InjectTag className="icon-dim-16 mt-2 mr-4 mw-16" />
)}
<Tippy
className="default-tt dc__word-break-all"
arrow={false}
Expand Down
50 changes: 0 additions & 50 deletions src/components/app/appLabelCommon.tsx

This file was deleted.

Loading

0 comments on commit 0bbd5b0

Please sign in to comment.