@@ -38,6 +38,7 @@ import {
3838 stopPropagation ,
3939 ButtonStyleType ,
4040 Icon ,
41+ SelectPicker ,
4142} from '@devtron-labs/devtron-fe-common-lib'
4243import { useParams } from 'react-router-dom'
4344import Tippy from '@tippyjs/react'
@@ -53,12 +54,15 @@ import { createGeneratedAPIToken } from '@Pages/GlobalConfigurations/Authorizati
5354import {
5455 CURL_PREFIX ,
5556 GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS ,
57+ getWebhookTokenListOptions ,
5658 PLAYGROUND_TAB_LIST ,
5759 REQUEST_BODY_TAB_LIST ,
5860 RESPONSE_TAB_LIST ,
61+ SELECT_AUTO_GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS ,
62+ TOKEN_TAB_LIST ,
5963} from './webhook.utils'
60- import { SchemaType , TabDetailsType , WebhookDetailsType , WebhookDetailType } from './types'
61- import { executeWebhookAPI , getExternalCIConfig } from './webhook.service'
64+ import { SchemaType , TabDetailsType , TokenListOptionsType , WebhookDetailsType , WebhookDetailType } from './types'
65+ import { executeWebhookAPI , getExternalCIConfig , getWebhookAPITokenList } from './webhook.service'
6266import { GENERATE_TOKEN_NAME_VALIDATION } from '../../../config/constantMessaging'
6367import { createUserPermissionPayload } from '@Pages/GlobalConfigurations/Authorization/utils'
6468import { ChartGroupPermissionsFilter } from '@Pages/GlobalConfigurations/Authorization/types'
@@ -67,6 +71,8 @@ import {
6771 getDefaultStatusAndTimeout ,
6872 getDefaultUserStatusAndTimeout ,
6973} from '@Pages/GlobalConfigurations/Authorization/libUtils'
74+ import { getApiTokenHeader } from '@Pages/GlobalConfigurations/Authorization/APITokens/apiToken.utils'
75+ import { TokenListType } from '@Pages/GlobalConfigurations/Authorization/APITokens/apiToken.type'
7076
7177export const WebhookDetailsModal = ( { close, isTemplateView } : WebhookDetailType ) => {
7278 const { appId, webhookId } = useParams < {
@@ -84,6 +90,7 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
8490 const [ selectedRequestBodyTab , setRequestBodyPlaygroundTab ] = useState < string > ( REQUEST_BODY_TAB_LIST [ 0 ] . key )
8591 const [ webhookResponse , setWebhookResponse ] = useState < Object > ( null )
8692 const [ generatedAPIToken , setGeneratedAPIToken ] = useState < string > ( null )
93+ const [ selectedTokenTab , setSelectedTokenTab ] = useState < string > ( TOKEN_TAB_LIST [ 0 ] . key )
8794 const [ showTokenSection , setShowTokenSection ] = useState ( false )
8895 const [ isSuperAdmin , setIsSuperAdmin ] = useState ( false )
8996 const [ samplePayload , setSamplePayload ] = useState < any > ( null )
@@ -94,11 +101,14 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
94101 const [ tryoutAPIToken , setTryoutAPIToken ] = useState < string > ( null )
95102 const [ showTryoutAPITokenError , setTryoutAPITokenError ] = useState ( false )
96103 const [ webhookDetails , setWebhookDetails ] = useState < WebhookDetailsType > ( null )
104+ const [ selectedToken , setSelectedToken ] = useState < TokenListOptionsType > ( null )
105+ const [ tokenList , setTokenList ] = useState < TokenListType [ ] > ( undefined )
97106 const [ selectedSchema , setSelectedSchema ] = useState < string > ( '' )
98107 const [ errorInGetData , setErrorInGetData ] = useState ( false )
99108 const [ copyToClipboardPromise , setCopyToClipboardPromise ] = useState < ReturnType < typeof copyToClipboard > > ( null )
100109 const schemaRef = useRef < Array < HTMLDivElement | null > > ( [ ] )
101110
111+
102112 const clipboardContent = window . location . href
103113
104114 const handleCopyButtonClick = async ( ) => {
@@ -184,13 +194,30 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
184194 setSampleCURL (
185195 CURL_PREFIX . replace ( '{webhookURL}' , _webhookDetails . webhookUrl ) . replace ( '{data}' , modifiedJSONString ) ,
186196 )
197+ if ( _isSuperAdmin ) {
198+ const { result } = await getWebhookAPITokenList (
199+ _webhookDetails . projectName ,
200+ _webhookDetails . environmentIdentifier ,
201+ _webhookDetails . appName ,
202+ )
203+ const sortedResult =
204+ result
205+ ?. sort ( ( a , b ) => a [ 'name' ] . localeCompare ( b [ 'name' ] ) )
206+ . map ( ( tokenData ) => {
207+ return { label : tokenData . name , value : tokenData . id , ...tokenData }
208+ } ) || [ ]
209+ setTokenList ( sortedResult )
210+ }
187211 setLoader ( false )
188212 } catch ( error ) {
189213 setIsSuperAdmin ( false )
190214 setLoader ( false )
191215 setErrorInGetData ( true )
192216 }
193217 }
218+
219+ const hideApiToken = ! tokenList ?. [ 0 ] ?. token
220+
194221 const generateToken = async ( ) : Promise < void > => {
195222 if ( ! tokenName ) {
196223 setTokenNameError ( true )
@@ -208,6 +235,7 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
208235 const userPermissionPayload = createUserPermissionPayload ( {
209236 id : result . userId ,
210237 userIdentifier : result . userIdentifier ,
238+ hideApiToken : result . hideApiToken ,
211239 userRoleGroups : [ ] ,
212240 serverMode : SERVER_MODE . FULL ,
213241 directPermission : [ ] ,
@@ -367,7 +395,7 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
367395 return (
368396 < div className = "mt-16" >
369397 < InfoBlock
370- heading = "Copy and store this token safely, you won’t be able to view it again."
398+ heading = { getApiTokenHeader ( hideApiToken ) }
371399 description = {
372400 < div className = "fs-13 font-roboto flexbox dc__word-break" data-testid = "generated-api-token" >
373401 { token }
@@ -424,6 +452,49 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
424452 )
425453 }
426454
455+ const renderSelectTokenSection = ( ) : JSX . Element => {
456+ const handleSelectedTokenChange = ( selectedToken ) : void => {
457+ setSelectedToken ( selectedToken )
458+ }
459+
460+ return (
461+ < >
462+ < div className = "w-400 h-32 mt-16" >
463+ < SelectPicker
464+ inputId = "select-token"
465+ name = "select-token"
466+ classNamePrefix = "select-token"
467+ placeholder = "Select API token"
468+ isClearable = { false }
469+ options = { getWebhookTokenListOptions ( tokenList ) }
470+ value = { selectedToken }
471+ onChange = { handleSelectedTokenChange }
472+ isSearchable = { false }
473+ />
474+ </ div >
475+ { selectedToken ?. name && renderSelectedToken ( selectedToken . token ) }
476+ </ >
477+ )
478+ }
479+
480+ const renderGeneratedTokenDetails = ( ) => {
481+ if ( hideApiToken ) {
482+ return (
483+ < div className = "cn-9 fs-13 mb-8" >
484+ < span className = "fs-13 lh-1-5 fw-6" > { GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS } </ span >
485+ { renderGenerateTokenSection ( ) }
486+ </ div >
487+ )
488+ }
489+ return (
490+ < div >
491+ { generateTabHeader ( TOKEN_TAB_LIST , selectedTokenTab , setSelectedTokenTab ) }
492+ { selectedTokenTab === TOKEN_TAB_LIST [ 0 ] . key && renderSelectTokenSection ( ) }
493+ { selectedTokenTab === TOKEN_TAB_LIST [ 1 ] . key && renderGenerateTokenSection ( ) }
494+ </ div >
495+ )
496+ }
497+
427498 const renderTokenSection = ( ) : JSX . Element | null => {
428499 if ( ! isSuperAdmin ) {
429500 return (
@@ -440,13 +511,10 @@ export const WebhookDetailsModal = ({ close, isTemplateView }: WebhookDetailType
440511 dataTestId = "select-or-generate-token"
441512 variant = { ButtonVariantType . text }
442513 onClick = { toggleTokenSection }
443- text = { GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS }
514+ text = { hideApiToken ? GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS : SELECT_AUTO_GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS }
444515 />
445516 ) : (
446- < div className = "cn-9 fs-13 mb-8" >
447- < span className = "fs-13 lh-1-5 fw-6" > { GENERATE_TOKEN_WITH_REQUIRED_PERMISSIONS } </ span >
448- { renderGenerateTokenSection ( ) }
449- </ div >
517+ renderGeneratedTokenDetails ( )
450518 )
451519 }
452520
0 commit comments