Skip to content

Commit a591f6d

Browse files
committed
Merge branch 'develop' of https://github.com/devtron-labs/dashboard into feat/holmes-integration
2 parents fd0d3e2 + a8312d9 commit a591f6d

File tree

17 files changed

+212
-63
lines changed

17 files changed

+212
-63
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@ FEATURE_APPLICATION_TEMPLATES_ENABLE=true
6464
FEATURE_CODE_MIRROR_ENABLE=false
6565
FEATURE_DEFAULT_AUTHENTICATED_VIEW_ENABLE=false
6666
GATEKEEPER_URL=https://license.devtron.ai/dashboard
67-
FEATURE_AI_INTEGRATION_ENABLE=true
67+
FEATURE_AI_INTEGRATION_ENABLE=false

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "1.12.0-pre-3-beta-1",
7+
"@devtron-labs/devtron-fe-common-lib": "1.12.0-pre-5",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/Pages/Applications/DevtronApps/Details/AppConfigurations/MainContent/SelectMergeStrategy.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
SelectPicker,
2626
SelectPickerOptionType,
2727
SelectPickerVariantType,
28+
Tooltip,
2829
} from '@devtron-labs/devtron-fe-common-lib'
2930

3031
import { importComponentFromFELibrary } from '@Components/common'
@@ -69,10 +70,15 @@ const SelectMergeStrategy = ({
6970

7071
return (
7172
<>
72-
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
73-
<label className={`m-0 ${MERGE_STRATEGY_LABEL_CLASS}`} htmlFor="config-toolbar-select-strategy">
74-
Merge strategy
75-
</label>
73+
<Tooltip content="Merge strategy">
74+
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
75+
<label
76+
className={`m-0 dc__ellipsis-right ${MERGE_STRATEGY_LABEL_CLASS}`}
77+
htmlFor="config-toolbar-select-strategy"
78+
>
79+
Merge strategy
80+
</label>
81+
</Tooltip>
7682

7783
<SelectPicker
7884
inputId="config-toolbar-select-strategy"

src/Pages/Shared/ConfigMapSecret/ConfigMapSecretContainer.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,10 @@ export const ConfigMapSecretContainer = ({
11931193
areCommentsPresent={areCommentsPresent}
11941194
disableAllActions={isLoading || isSubmitting || !!parsingError}
11951195
isDraftPresent={isDraftAvailable}
1196-
isPublishedConfigPresent={cmSecretStateLabel !== CM_SECRET_STATE.UNPUBLISHED}
1196+
isPublishedConfigPresent={
1197+
cmSecretStateLabel !== CM_SECRET_STATE.UNPUBLISHED &&
1198+
cmSecretStateLabel !== CM_SECRET_STATE.INHERITED
1199+
}
11971200
isApprovalPending={draftData?.draftState === DraftState.AwaitApproval}
11981201
isUnpublished={cmSecretStateLabel === CM_SECRET_STATE.UNPUBLISHED}
11991202
showDeleteOverrideDraftEmptyState={

src/components/ApplicationGroup/AppGroup.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export interface BulkCDDetailType
9393
ciPipelineId?: number
9494
hideImageTaggingHardDelete?: boolean
9595
resourceFilters?: FilterConditionsListType[]
96+
isExceptionUser?: boolean
9697
}
9798

9899
export interface ResponseRowType {

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

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ import {
4747
Button,
4848
ComponentSizeType,
4949
AnimatedDeployButton,
50-
ButtonVariantType,
5150
Icon,
51+
getIsApprovalPolicyConfigured,
52+
ButtonVariantType,
5253
ButtonStyleType,
5354
useMainContext,
5455
} from '@devtron-labs/devtron-fe-common-lib'
@@ -61,13 +62,15 @@ import { ReactComponent as Tag } from '@Icons/ic-tag.svg'
6162
import emptyPreDeploy from '../../../../assets/img/empty-pre-deploy.webp'
6263
import notAuthorized from '../../../../assets/img/ic-not-authorized.svg'
6364
import CDMaterial from '../../../app/details/triggerView/cdMaterial'
65+
import { getIsMaterialApproved } from '@Components/app/details/triggerView/cdMaterials.utils'
6466
import { BulkSelectionEvents, MATERIAL_TYPE, RuntimeParamsErrorState } from '../../../app/details/triggerView/types'
6567
import { BulkCDDetailType, BulkCDTriggerType } from '../../AppGroup.types'
6668
import { BULK_CD_DEPLOYMENT_STATUS, BULK_CD_MATERIAL_STATUS, BULK_CD_MESSAGING, BUTTON_TITLE } from '../../Constants'
6769
import TriggerResponseModalBody, { TriggerResponseModalFooter } from './TriggerResponseModal'
6870
import { ReactComponent as MechanicalOperation } from '../../../../assets/img/ic-mechanical-operation.svg'
6971
import { importComponentFromFELibrary } from '../../../common'
7072
import { BULK_ERROR_MESSAGES } from './constants'
73+
import { getIsNonApprovedImageSelected, getIsImageApprovedByDeployerSelected } from './utils'
7174

7275
const DeploymentWindowInfoBar = importComponentFromFELibrary('DeploymentWindowInfoBar')
7376
const BulkDeployResistanceTippy = importComponentFromFELibrary('BulkDeployResistanceTippy')
@@ -436,6 +439,25 @@ export default function BulkCDTrigger({
436439
)
437440
}
438441

442+
const renderDeploymentWithoutApprovalWarning = (app: BulkCDDetailType) => {
443+
if (!app.isExceptionUser) {
444+
return null
445+
}
446+
447+
const selectedMaterial: CDMaterialType = app.material?.find((mat: CDMaterialType) => mat.isSelected)
448+
449+
if (!selectedMaterial || getIsMaterialApproved(selectedMaterial?.userApprovalMetadata)) {
450+
return null
451+
}
452+
453+
return (
454+
<div className="flex left dc__gap-4 mb-4">
455+
<Icon name="ic-warning" color={null} size={14} />
456+
<p className="m-0 fs-12 lh-16 fw-4 cy-7">Non-approved image selected</p>
457+
</div>
458+
)
459+
}
460+
439461
const renderAppWarningAndErrors = (app: BulkCDDetailType) => {
440462
const commonNodeAttrType: CommonNodeAttr['type'] =
441463
app.stageType === DeploymentNodeType.PRECD ? 'PRECD' : 'POSTCD'
@@ -446,7 +468,7 @@ export default function BulkCDTrigger({
446468

447469
if (unauthorizedAppList[app.appId]) {
448470
return (
449-
<div className="flex left top dc__gap-4">
471+
<div className="flex left dc__gap-4">
450472
<UnAuthorized className="icon-dim-12 warning-icon-y7 mr-4 dc__no-shrink" />
451473
<span className="cy-7 fw-4 fs-12 dc__truncate">{BULK_CD_MESSAGING.unauthorized.title}</span>
452474
</div>
@@ -481,7 +503,7 @@ export default function BulkCDTrigger({
481503
if (!!warningMessage && !app.showPluginWarning) {
482504
return (
483505
<div className="flex left top dc__gap-4">
484-
<Error className="icon-dim-12 dc__no-shrink mt-5 warning-icon-y7" />
506+
<Icon name="ic-warning" color={null} size={14} />
485507
<span className="fw-4 fs-12 cy-7 dc__truncate">{warningMessage}</span>
486508
</div>
487509
)
@@ -775,6 +797,7 @@ export default function BulkCDTrigger({
775797
onClick={changeApp}
776798
>
777799
{app.name}
800+
{renderDeploymentWithoutApprovalWarning(app)}
778801
{renderAppWarningAndErrors(app)}
779802
</div>
780803
))}
@@ -856,7 +879,10 @@ export default function BulkCDTrigger({
856879

857880
const renderFooterSection = (): JSX.Element => {
858881
const isDeployButtonDisabled: boolean = isDeployDisabled()
882+
const canDeployWithoutApproval = getIsNonApprovedImageSelected(appList)
883+
const canImageApproverDeploy = getIsImageApprovedByDeployerSelected(appList)
859884
const showSkipHibernatedCheckbox = !!SkipHibernatedCheckbox && canFetchHelmAppStatus
885+
860886
return (
861887
<div
862888
className={`dc__border-top flex ${showSkipHibernatedCheckbox ? 'dc__content-space' : 'right'} bg__primary px-20 py-16`}
@@ -873,7 +899,15 @@ export default function BulkCDTrigger({
873899
)}
874900
<div className="dc__position-rel tippy-over">
875901
{!isDeployButtonDisabled && stage === DeploymentNodeType.CD && !isLoading ? (
876-
<AnimatedDeployButton onButtonClick={onClickStartDeploy} isVirtualEnvironment={false} />
902+
<AnimatedDeployButton
903+
onButtonClick={onClickStartDeploy}
904+
isVirtualEnvironment={false}
905+
exceptionUserConfig={{
906+
canDeploy: canDeployWithoutApproval,
907+
isImageApprover: canImageApproverDeploy,
908+
}}
909+
isBulkCDTrigger
910+
/>
877911
) : (
878912
<Button
879913
dataTestId="deploy-button"

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,9 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
922922
const nodes = workflow.nodes.map((node) => {
923923
if (cdNodeId == node.id && node.type === nodeType) {
924924
// TODO: Ig not using this, can remove it
925-
node.approvalConfigData = workflow.approvalConfiguredIdsMap[cdNodeId]
925+
if (node.type === WorkflowNodeType.CD) {
926+
node.approvalConfigData = workflow.approvalConfiguredIdsMap[cdNodeId]
927+
}
926928
_selectedNode = node
927929
_workflowId = workflow.id
928930
_appID = workflow.appId
@@ -1403,6 +1405,8 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
14031405
}
14041406
wf.appReleaseTags = _materialData?.appReleaseTagNames
14051407
wf.tagsEditable = _materialData?.tagsEditable
1408+
wf.canApproverDeploy = _materialData?.canApproverDeploy ?? false
1409+
wf.isExceptionUser = _materialData?.deploymentApprovalInfo?.approvalConfigData?.isExceptionUser ?? false
14061410
}
14071411

14081412
return wf
@@ -1796,6 +1800,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
17961800
? `${stageText} is blocked`
17971801
: '',
17981802
triggerBlockedInfo: _selectedNode.triggerBlockedInfo,
1803+
isExceptionUser: wf.isExceptionUser,
17991804
})
18001805
} else {
18011806
let warningMessage = ''

src/components/ApplicationGroup/Details/TriggerView/utils.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,34 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { BulkCIDetailType } from '../../AppGroup.types'
17+
import { getIsMaterialApproved } from '@Components/app/details/triggerView/cdMaterials.utils'
18+
19+
import { BulkCDDetailType, BulkCIDetailType } from '../../AppGroup.types'
1820

1921
export const getIsAppUnorthodox = (app: BulkCIDetailType): boolean =>
2022
app.isLinkedCI || app.isWebhookCI || app.isLinkedCD
23+
24+
export const getIsNonApprovedImageSelected = (appList: BulkCDDetailType[]): boolean =>
25+
appList.some((app) => {
26+
if (!app.isExceptionUser) {
27+
return false
28+
}
29+
30+
return (app.material || []).some(
31+
(material) => material.isSelected && !getIsMaterialApproved(material.userApprovalMetadata),
32+
)
33+
})
34+
35+
export const getIsImageApprovedByDeployerSelected = (appList: BulkCDDetailType[]): boolean =>
36+
appList.some((app) => {
37+
if (!app.isExceptionUser) {
38+
return false
39+
}
40+
41+
return (app.material || []).some(
42+
(material) =>
43+
material.isSelected &&
44+
!material.canApproverDeploy &&
45+
material.userApprovalMetadata?.hasCurrentUserApproved,
46+
)
47+
})

0 commit comments

Comments
 (0)