@@ -2,9 +2,9 @@ import React, { useEffect, useMemo, useState } from 'react'
2
2
import { useParams } from 'react-router-dom'
3
3
import { toast } from 'react-toastify'
4
4
import YAML from 'yaml'
5
- import { Progressing } from '@devtron-labs/devtron-fe-common-lib'
5
+ import { Progressing , getLockedJSON , getUnlockedJSON } from '@devtron-labs/devtron-fe-common-lib'
6
6
import { FloatingVariablesSuggestions , importComponentFromFELibrary , useJsonYaml } from '../common'
7
- import { DeploymentConfigStateActionTypes } from '../deploymentConfig/types'
7
+ import { ConfigKeysWithLockType , DeploymentConfigStateActionTypes } from '../deploymentConfig/types'
8
8
import { EDITOR_VIEW } from '../deploymentConfig/constants'
9
9
import { DEPLOYMENT , ROLLOUT_DEPLOYMENT } from '../../config'
10
10
import { createDeploymentTemplate , updateDeploymentTemplate } from './service'
@@ -14,6 +14,7 @@ import DeploymentTemplateOptionsTab from '../deploymentConfig/DeploymentTemplate
14
14
import DeploymentTemplateEditorView from '../deploymentConfig/DeploymentTemplateView/DeploymentTemplateEditorView'
15
15
import DeploymentConfigFormCTA from '../deploymentConfig/DeploymentTemplateView/DeploymentConfigFormCTA'
16
16
import { DeploymentConfigContext } from '../deploymentConfig/DeploymentConfig'
17
+ import { getDeploymentManisfest , getIfLockedConfigProtected } from '../deploymentConfig/service'
17
18
import { DeleteOverrideDialog } from '../deploymentConfig/DeploymentTemplateView/DeploymentTemplateView.component'
18
19
import DeploymentTemplateReadOnlyEditorView from '../deploymentConfig/DeploymentTemplateView/DeploymentTemplateReadOnlyEditorView'
19
20
import DeploymentConfigToolbar from '../deploymentConfig/DeploymentTemplateView/DeploymentConfigToolbar'
@@ -25,12 +26,12 @@ import {
25
26
updateTemplateFromBasicValue ,
26
27
validateBasicView ,
27
28
} from '../deploymentConfig/DeploymentConfig.utils'
28
- import { getDeploymentManisfest } from '../deploymentConfig/service '
29
+ import CodeEditor from '../CodeEditor/CodeEditor '
29
30
30
31
const ConfigToolbar = importComponentFromFELibrary ( 'ConfigToolbar' , DeploymentConfigToolbar )
31
32
const SaveChangesModal = importComponentFromFELibrary ( 'SaveChangesModal' )
32
33
const DeleteOverrideDraftModal = importComponentFromFELibrary ( 'DeleteOverrideDraftModal' )
33
-
34
+ const DeploymentTemplateLockedDiff = importComponentFromFELibrary ( 'DeploymentTemplateLockedDiff' )
34
35
export default function DeploymentTemplateOverrideForm ( {
35
36
state,
36
37
isConfigProtectionEnabled,
@@ -52,10 +53,19 @@ export default function DeploymentTemplateOverrideForm({
52
53
setManifestDataRHS,
53
54
setManifestDataLHS,
54
55
convertVariablesOverride,
56
+ isSuperAdmin,
55
57
} ) {
56
58
const [ obj , , , error ] = useJsonYaml ( state . tempFormData , 4 , 'yaml' , true )
57
59
const { appId, envId } = useParams < { appId ; envId } > ( )
58
60
const readOnlyPublishedMode = state . selectedTabIndex === 1 && isConfigProtectionEnabled && ! ! state . latestDraft
61
+ const [ saveEligibleChangesCb , setSaveEligibleChangesCb ] = useState ( false )
62
+ const [ showLockedDiffForApproval , setShowLockedDiffForApproval ] = useState ( false )
63
+ const [ lockedOverride , setLockedOverride ] = useState ( { } )
64
+ const [ lockedConfigKeysWithLockType , setLockedConfigKeysWithLockType ] = useState < ConfigKeysWithLockType > ( {
65
+ config : [ ] ,
66
+ allowed : false ,
67
+ } )
68
+ const [ disableSaveEligibleChanges , setDisableSaveEligibleChanges ] = useState ( false )
59
69
60
70
useEffect ( ( ) => {
61
71
// Reset editor value on delete override action
@@ -94,14 +104,25 @@ export default function DeploymentTemplateOverrideForm({
94
104
}
95
105
96
106
const prepareDataToSave = ( envOverrideValuesWithBasic , includeInDraft ?: boolean ) => {
107
+ let valuesOverride = envOverrideValuesWithBasic || obj || state . duplicate
108
+ if ( state . showLockedTemplateDiff ) {
109
+ // if locked keys
110
+ if ( ! lockedConfigKeysWithLockType . allowed ) {
111
+ valuesOverride = getUnlockedJSON ( lockedOverride , lockedConfigKeysWithLockType . config )
112
+ } else {
113
+ // if allowed keys
114
+ valuesOverride = getLockedJSON ( lockedOverride , lockedConfigKeysWithLockType . config )
115
+ }
116
+ }
97
117
const payload = {
98
118
environmentId : + envId ,
99
- envOverrideValues : envOverrideValuesWithBasic || obj || state . duplicate ,
119
+ envOverrideValues : valuesOverride ,
100
120
chartRefId : state . selectedChartRefId ,
101
121
IsOverride : true ,
102
122
isAppMetricsEnabled : state . latestDraft ? state . isAppMetricsEnabled : state . data . appMetrics ,
103
123
currentViewEditor : state . isBasicLocked ? EDITOR_VIEW . ADVANCED : state . currentEditorView ,
104
124
isBasicLocked : state . isBasicLocked ,
125
+ saveEligibleChanges : saveEligibleChangesCb ,
105
126
...( state . data . environmentConfig . id > 0
106
127
? {
107
128
id : state . data . environmentConfig . id ,
@@ -124,8 +145,20 @@ export default function DeploymentTemplateOverrideForm({
124
145
return payload
125
146
}
126
147
127
- async function handleSubmit ( e ) {
128
- e . preventDefault ( )
148
+ const closeLockedDiffDrawerWithChildModal = ( ) => {
149
+ state . showSaveChangesModal && toggleSaveChangesModal ( )
150
+ handleLockedDiffDrawer ( false )
151
+ setSaveEligibleChangesCb ( false )
152
+ }
153
+
154
+ const handleLockedDiffDrawer = ( value ) => {
155
+ dispatch ( {
156
+ type : DeploymentConfigStateActionTypes . toggleShowLockedTemplateDiff ,
157
+ payload : value ,
158
+ } )
159
+ }
160
+
161
+ const checkForSaveAsDraft = ( ) => {
129
162
if ( ! obj && state . yamlMode ) {
130
163
toast . error ( error )
131
164
return
@@ -140,7 +173,35 @@ export default function DeploymentTemplateOverrideForm({
140
173
toggleSaveChangesModal ( )
141
174
return
142
175
}
176
+ }
143
177
178
+ const handleSaveChanges = ( e ) => {
179
+ e . preventDefault ( )
180
+ handleSubmit ( false )
181
+ }
182
+
183
+ const handleChangeCheckbox = ( ) => {
184
+ if ( ! saveEligibleChangesCb ) {
185
+ checkForSaveAsDraft ( )
186
+ } else {
187
+ state . showSaveChangesModal && toggleSaveChangesModal ( )
188
+ }
189
+ setSaveEligibleChangesCb ( ! saveEligibleChangesCb )
190
+ }
191
+
192
+ const checkForProtectedLockedChanges = async ( ) => {
193
+ const data = prepareDataToSaveDraft ( )
194
+ const action = data [ 'id' ] > 0 ? 2 : 1
195
+ const requestPayload = {
196
+ appId : Number ( appId ) ,
197
+ envId : Number ( envId ) ,
198
+ action,
199
+ data : JSON . stringify ( data ) ,
200
+ }
201
+ return await getIfLockedConfigProtected ( requestPayload )
202
+ }
203
+
204
+ const handleSubmit = async ( saveEligibleChanges : boolean = false ) => {
144
205
const api =
145
206
state . data . environmentConfig && state . data . environmentConfig . id > 0
146
207
? updateDeploymentTemplate
@@ -149,8 +210,26 @@ export default function DeploymentTemplateOverrideForm({
149
210
! state . yamlMode && patchBasicData ( obj || state . duplicate , state . basicFieldValues )
150
211
151
212
try {
152
- dispatch ( { type : DeploymentConfigStateActionTypes . loading , payload : true } )
153
- await api ( + appId , + envId , prepareDataToSave ( envOverrideValuesWithBasic ) )
213
+ if ( saveEligibleChanges ) {
214
+ dispatch ( { type : DeploymentConfigStateActionTypes . loading , payload : true } )
215
+ } else {
216
+ //loading state for checking locked changes
217
+ dispatch ( { type : DeploymentConfigStateActionTypes . lockChangesLoading , payload : true } )
218
+ }
219
+ const deploymentTemplateResp = isConfigProtectionEnabled
220
+ ? await checkForProtectedLockedChanges ( )
221
+ : await api ( + appId , + envId , prepareDataToSave ( envOverrideValuesWithBasic , false ) )
222
+ if ( deploymentTemplateResp . result . isLockConfigError && ! saveEligibleChanges ) {
223
+ //checking if any locked changes and opening drawer to show eligible and locked ones
224
+ setLockedOverride ( deploymentTemplateResp . result ?. lockedOverride )
225
+ setDisableSaveEligibleChanges ( deploymentTemplateResp . result ?. disableSaveEligibleChanges )
226
+ handleLockedDiffDrawer ( true )
227
+ return
228
+ } else if ( isConfigProtectionEnabled ) {
229
+ toggleSaveChangesModal ( )
230
+ return
231
+ }
232
+
154
233
if ( envOverrideValuesWithBasic ) {
155
234
editorOnChange ( YAML . stringify ( envOverrideValuesWithBasic , { indent : 2 } ) , true )
156
235
}
@@ -174,7 +253,17 @@ export default function DeploymentTemplateOverrideForm({
174
253
} catch ( err ) {
175
254
handleConfigProtectionError ( 2 , err , dispatch , reloadEnvironments )
176
255
} finally {
177
- dispatch ( { type : DeploymentConfigStateActionTypes . loading , payload : false } )
256
+ if ( saveEligibleChanges ) {
257
+ //closing drawer if selected save eligible changes
258
+ handleLockedDiffDrawer ( false )
259
+ }
260
+ dispatch ( {
261
+ type : DeploymentConfigStateActionTypes . multipleOptions ,
262
+ payload : {
263
+ loading : false ,
264
+ lockChangesLoading : false ,
265
+ } ,
266
+ } )
178
267
}
179
268
}
180
269
@@ -532,7 +621,7 @@ export default function DeploymentTemplateOverrideForm({
532
621
className = { `deployment-template-override-form h-100 ${ state . openComparison ? 'comparison-view' : '' } ${
533
622
state . showReadme ? 'readme-view' : ''
534
623
} `}
535
- onSubmit = { handleSubmit }
624
+ onSubmit = { handleSaveChanges }
536
625
>
537
626
< div className = "variables-widget-position" >
538
627
< FloatingVariablesSuggestions zIndex = { 1004 } appId = { appId } envId = { envId } clusterId = { clusterId } />
@@ -544,7 +633,7 @@ export default function DeploymentTemplateOverrideForm({
544
633
/>
545
634
{ renderEditorComponent ( ) }
546
635
< DeploymentConfigFormCTA
547
- loading = { state . loading || state . chartConfigLoading }
636
+ loading = { state . loading || state . chartConfigLoading || state . lockChangesLoading }
548
637
isEnvOverride = { true }
549
638
disableButton = { ! state . duplicate }
550
639
disableCheckbox = { ! state . duplicate }
@@ -565,6 +654,12 @@ export default function DeploymentTemplateOverrideForm({
565
654
reload = { reload }
566
655
isValues = { isValuesOverride }
567
656
convertVariables = { convertVariablesOverride }
657
+ handleLockedDiffDrawer = { handleLockedDiffDrawer }
658
+ setShowLockedDiffForApproval = { setShowLockedDiffForApproval }
659
+ isSuperAdmin = { isSuperAdmin }
660
+ checkForProtectedLockedChanges = { checkForProtectedLockedChanges }
661
+ showLockedDiffForApproval = { showLockedDiffForApproval }
662
+ setLockedOverride = { setLockedOverride }
568
663
/>
569
664
</ form >
570
665
)
@@ -603,11 +698,13 @@ export default function DeploymentTemplateOverrideForm({
603
698
convertVariables = { convertVariablesOverride }
604
699
setConvertVariables = { setConvertVariables }
605
700
componentType = { 3 }
701
+ setShowLockedDiffForApproval = { setShowLockedDiffForApproval }
702
+ setLockedConfigKeysWithLockType = { setLockedConfigKeysWithLockType }
606
703
/>
607
704
{ state . selectedTabIndex !== 2 && ! state . showReadme && renderOverrideInfoStrip ( ) }
608
705
{ renderValuesView ( ) }
609
706
{ state . dialog && < DeleteOverrideDialog appId = { appId } envId = { envId } initialise = { initialise } /> }
610
- { SaveChangesModal && state . showSaveChangsModal && (
707
+ { SaveChangesModal && state . showSaveChangesModal && (
611
708
< SaveChangesModal
612
709
appId = { Number ( appId ) }
613
710
envId = { Number ( envId ) }
@@ -617,6 +714,9 @@ export default function DeploymentTemplateOverrideForm({
617
714
toggleModal = { toggleSaveChangesModal }
618
715
latestDraft = { state . latestDraft }
619
716
reload = { reload }
717
+ closeLockedDiffDrawerWithChildModal = { closeLockedDiffDrawerWithChildModal }
718
+ showAsModal = { ! state . showLockedTemplateDiff }
719
+ saveEligibleChangesCb = { saveEligibleChangesCb }
620
720
/>
621
721
) }
622
722
{ DeleteOverrideDraftModal && state . showDeleteOverrideDraftModal && (
@@ -631,6 +731,20 @@ export default function DeploymentTemplateOverrideForm({
631
731
reload = { reload }
632
732
/>
633
733
) }
734
+ { DeploymentTemplateLockedDiff && state . showLockedTemplateDiff && (
735
+ < DeploymentTemplateLockedDiff
736
+ CodeEditor = { CodeEditor }
737
+ closeModal = { closeLockedDiffDrawerWithChildModal }
738
+ handleChangeCheckbox = { handleChangeCheckbox }
739
+ saveEligibleChangesCb = { saveEligibleChangesCb }
740
+ showLockedDiffForApproval = { showLockedDiffForApproval }
741
+ onSave = { handleSubmit }
742
+ lockedOverride = { lockedOverride }
743
+ lockedConfigKeysWithLockType = { lockedConfigKeysWithLockType }
744
+ disableSaveEligibleChanges = { disableSaveEligibleChanges }
745
+ setLockedConfigKeysWithLockType = { setLockedConfigKeysWithLockType }
746
+ />
747
+ ) }
634
748
</ DeploymentConfigContext . Provider >
635
749
)
636
750
}
0 commit comments