@@ -17,15 +17,27 @@ import MessageUI, { MsgUIType } from '../../../../common/message.ui'
17
17
import { AppType , ManifestActionPropsType , NodeType } from '../../../appDetails.type'
18
18
import YAML from 'yaml'
19
19
import { toast } from 'react-toastify'
20
- import { DeploymentAppTypes , showError , ToastBody } from '@devtron-labs/devtron-fe-common-lib'
20
+ import {
21
+ Checkbox ,
22
+ CHECKBOX_VALUE ,
23
+ ConditionalWrap ,
24
+ DeploymentAppTypes ,
25
+ noop ,
26
+ showError ,
27
+ ToastBody ,
28
+ } from '@devtron-labs/devtron-fe-common-lib'
21
29
import { appendRefetchDataToUrl } from '../../../../../util/URLUtil'
22
30
import {
23
31
EA_MANIFEST_SECRET_EDIT_MODE_INFO_TEXT ,
24
32
EA_MANIFEST_SECRET_INFO_TEXT ,
25
33
} from '../../../../../../config/constantMessaging'
26
34
import { MODES } from '../../../../../../config'
27
- import { EMPTY_YAML_ERROR , SAVE_DATA_VALIDATION_ERROR_MSG } from '../../../../values/chartValuesDiff/ChartValuesView.constants'
28
- import { getTrimmedManifestData } from '../nodeDetail.util'
35
+ import {
36
+ EMPTY_YAML_ERROR ,
37
+ SAVE_DATA_VALIDATION_ERROR_MSG ,
38
+ } from '../../../../values/chartValuesDiff/ChartValuesView.constants'
39
+ import { getDecodedEncodedSecretManifestData , getTrimmedManifestData } from '../nodeDetail.util'
40
+ import Tippy from '@tippyjs/react'
29
41
30
42
function ManifestComponent ( {
31
43
selectedTab,
@@ -39,7 +51,14 @@ function ManifestComponent({
39
51
const history = useHistory ( )
40
52
const [ { tabs, activeTab } , dispatch ] = useTab ( ManifestTabJSON )
41
53
const { url } = useRouteMatch ( )
42
- const params = useParams < { actionName : string ; podName : string ; nodeType : string ; node : string ; group : string , namespace : string } > ( )
54
+ const params = useParams < {
55
+ actionName : string
56
+ podName : string
57
+ nodeType : string
58
+ node : string
59
+ group : string
60
+ namespace : string
61
+ } > ( )
43
62
const [ manifest , setManifest ] = useState ( '' )
44
63
const [ modifiedManifest , setModifiedManifest ] = useState ( '' )
45
64
const [ activeManifestEditorData , setActiveManifestEditorData ] = useState ( '' )
@@ -54,6 +73,8 @@ function ManifestComponent({
54
73
const [ showDesiredAndCompareManifest , setShowDesiredAndCompareManifest ] = useState ( false )
55
74
const [ isResourceMissing , setIsResourceMissing ] = useState ( false )
56
75
const [ showInfoText , setShowInfoText ] = useState ( false )
76
+ const [ showDecodedData , setShowDecodedData ] = useState ( false )
77
+ const [ secretViewAccess , setSecretViewAccess ] = useState ( false )
57
78
58
79
useEffect ( ( ) => {
59
80
selectedTab ( NodeDetailTab . MANIFEST , url )
@@ -84,8 +105,7 @@ function ManifestComponent({
84
105
if (
85
106
isResourceBrowserView ||
86
107
appDetails . appType === AppType . EXTERNAL_HELM_CHART ||
87
- ( appDetails . deploymentAppType === DeploymentAppTypes . GITOPS &&
88
- appDetails . deploymentAppDeleteRequest )
108
+ ( appDetails . deploymentAppType === DeploymentAppTypes . GITOPS && appDetails . deploymentAppDeleteRequest )
89
109
) {
90
110
markActiveTab ( 'Live manifest' )
91
111
}
@@ -104,8 +124,8 @@ function ManifestComponent({
104
124
] )
105
125
. then ( ( response ) => {
106
126
let _manifest : string
107
-
108
- _manifest = JSON . stringify ( response [ 0 ] ?. result ?. manifest )
127
+ setSecretViewAccess ( response [ 0 ] ?. result ?. secretViewAccess || false )
128
+ _manifest = JSON . stringify ( response [ 0 ] ?. result ?. manifestResponse ?. manifest || '' )
109
129
setDesiredManifest ( response [ 1 ] ?. result ?. manifest || '' )
110
130
111
131
if ( _manifest ) {
@@ -177,13 +197,14 @@ function ManifestComponent({
177
197
const handleApplyChanges = ( ) => {
178
198
setLoading ( true )
179
199
setLoadingMsg ( 'Applying changes' )
200
+ setShowDecodedData ( false )
180
201
181
202
let manifestString
182
203
try {
183
204
if ( ! modifiedManifest ) {
184
205
setErrorText ( `${ SAVE_DATA_VALIDATION_ERROR_MSG } "${ EMPTY_YAML_ERROR } "` )
185
206
// Handled for blocking API call
186
- manifestString = ""
207
+ manifestString = ''
187
208
} else {
188
209
manifestString = JSON . stringify ( YAML . parse ( modifiedManifest ) )
189
210
}
@@ -224,7 +245,7 @@ function ManifestComponent({
224
245
className : 'devtron-toast unauthorized' ,
225
246
} ,
226
247
)
227
- } else if ( err . code === 400 || err . code === 409 || err . code === 422 ) {
248
+ } else if ( err . code === 400 || err . code === 409 || err . code === 422 ) {
228
249
const error = err [ 'errors' ] && err [ 'errors' ] [ 0 ]
229
250
if ( error && error . code && error . userMessage ) {
230
251
setErrorText ( `ERROR ${ err . code } > Message: “${ error . userMessage } ”` )
@@ -264,6 +285,7 @@ function ManifestComponent({
264
285
setModifiedManifest ( manifest )
265
286
setActiveManifestEditorData ( '' )
266
287
setErrorText ( '' )
288
+ setShowDecodedData ( false )
267
289
}
268
290
269
291
const markActiveTab = ( _tabName : string ) => {
@@ -299,6 +321,56 @@ function ManifestComponent({
299
321
updateEditor ( _tab . name )
300
322
}
301
323
324
+ const onChangeToggleShowDecodedValue = ( jsonManifestData ) => {
325
+ if ( ! jsonManifestData ?. data ) return
326
+ setShowDecodedData ( ! showDecodedData )
327
+ if ( ! showDecodedData ) {
328
+ setTrimedManifestEditorData (
329
+ getDecodedEncodedSecretManifestData ( jsonManifestData , true , showDecodedData ) as string ,
330
+ )
331
+ } else {
332
+ setTrimedManifestEditorData ( getDecodedEncodedSecretManifestData ( jsonManifestData , true , true ) as string )
333
+ }
334
+ }
335
+
336
+ const renderShowDecodedValueCheckbox = ( ) => {
337
+ const jsonManifestData = YAML . parse ( trimedManifestEditorData )
338
+ if ( jsonManifestData ?. kind === 'Secret' && ! isEditmode && secretViewAccess ) {
339
+ return (
340
+ < ConditionalWrap
341
+ condition = { ! jsonManifestData ?. data }
342
+ wrap = { ( children ) => (
343
+ < Tippy
344
+ className = "default-tt w-200"
345
+ arrow = { false }
346
+ placement = "top-start"
347
+ content = "Nothing to decode, data field not found."
348
+ >
349
+ { children }
350
+ </ Tippy >
351
+ ) }
352
+ >
353
+ < div
354
+ className = { `${
355
+ ! jsonManifestData ?. data ? 'dc__opacity-0_5 cursor-not-allowed' : ''
356
+ } flex left ml-8`}
357
+ >
358
+ < Checkbox
359
+ rootClassName = { `${
360
+ ! jsonManifestData ?. data ? 'dc__opacity-0_5 cursor-not-allowed' : 'cursor'
361
+ } mb-0-imp h-18`}
362
+ id = "showDecodedValue"
363
+ isChecked = { showDecodedData }
364
+ onChange = { ( ) => onChangeToggleShowDecodedValue ( jsonManifestData ) }
365
+ value = { CHECKBOX_VALUE . CHECKED }
366
+ />
367
+ Show decoded Value
368
+ </ div >
369
+ </ ConditionalWrap >
370
+ )
371
+ }
372
+ }
373
+
302
374
return isDeleted ? (
303
375
< div >
304
376
< MessageUI
@@ -415,7 +487,10 @@ function ManifestComponent({
415
487
? EA_MANIFEST_SECRET_EDIT_MODE_INFO_TEXT
416
488
: EA_MANIFEST_SECRET_INFO_TEXT
417
489
}
418
- />
490
+ className = "flex left"
491
+ >
492
+ { renderShowDecodedValueCheckbox ( ) }
493
+ </ CodeEditor . Information >
419
494
) }
420
495
{ activeTab === 'Compare' && (
421
496
< CodeEditor . Header hideDefaultSplitHeader = { true } >
0 commit comments