@@ -10,21 +10,25 @@ import {
1010 ConsequenceAction ,
1111 useAsync ,
1212 GenericEmptyState ,
13+ KeyValueListType ,
14+ KeyValueListActionType ,
15+ HandleKeyValueChangeType ,
16+ CIMaterialSidebarType ,
1317} from '@devtron-labs/devtron-fe-common-lib'
1418import Tippy from '@tippyjs/react'
1519import { importComponentFromFELibrary } from '../../../common'
1620import { ReactComponent as Close } from '../../../../assets/icons/ic-cross.svg'
1721import { ReactComponent as PlayIcon } from '../../../../assets/icons/misc/arrow-solid-right.svg'
1822import { ReactComponent as Warning } from '../../../../assets/icons/ic-warning.svg'
19- import { ReactComponent as Error } from '../../../../assets/icons/ic-alert-triangle.svg'
23+ import { ReactComponent as ICError } from '../../../../assets/icons/ic-alert-triangle.svg'
2024import { ReactComponent as Storage } from '../../../../assets/icons/ic-storage.svg'
2125import { ReactComponent as OpenInNew } from '../../../../assets/icons/ic-open-in-new.svg'
2226import { ReactComponent as InfoIcon } from '../../../../assets/icons/info-filled.svg'
2327import externalCiImg from '../../../../assets/img/external-ci.png'
2428import linkedCDBuildCIImg from '../../../../assets/img/linked-cd-bulk-ci.png'
2529import linkedCiImg from '../../../../assets/img/linked-ci.png'
2630import { getModuleConfigured } from '../../../app/details/appDetails/appDetails.service'
27- import { DOCUMENTATION , ModuleNameMap , SourceTypeMap , SOURCE_NOT_CONFIGURED , URLS } from '../../../../config'
31+ import { DOCUMENTATION , ModuleNameMap , SourceTypeMap , SOURCE_NOT_CONFIGURED , URLS , ViewType } from '../../../../config'
2832import MaterialSource from '../../../app/details/triggerView/MaterialSource'
2933import { TriggerViewContext } from '../../../app/details/triggerView/config'
3034import { getCIMaterialList } from '../../../app/service'
@@ -42,8 +46,10 @@ import { getIsAppUnorthodox } from './utils'
4246
4347const PolicyEnforcementMessage = importComponentFromFELibrary ( 'PolicyEnforcementMessage' )
4448const getCIBlockState = importComponentFromFELibrary ( 'getCIBlockState' , null , 'function' )
49+ const getRuntimeParams = importComponentFromFELibrary ( 'getRuntimeParams' , null , 'function' )
50+ const GitInfoMaterialTabs = importComponentFromFELibrary ( 'GitInfoMaterialTabs' , null , 'function' )
4551
46- export default function BulkCITrigger ( {
52+ const BulkCITrigger = ( {
4753 appList,
4854 closePopup,
4955 updateBulkInputMaterial,
@@ -57,13 +63,17 @@ export default function BulkCITrigger({
5763 responseList,
5864 isLoading,
5965 setLoading,
60- } : BulkCITriggerType ) {
66+ runtimeParams,
67+ setRuntimeParams,
68+ setPageViewType,
69+ } : BulkCITriggerType ) => {
6170 const [ showRegexModal , setShowRegexModal ] = useState ( false )
6271 const [ isChangeBranchClicked , setChangeBranchClicked ] = useState ( false )
6372 const [ regexValue , setRegexValue ] = useState < Record < number , RegexValueType > > ( { } )
6473 const [ appIgnoreCache , setAppIgnoreCache ] = useState < Record < number , boolean > > ( { } )
6574 const [ appPolicy , setAppPolicy ] = useState < Record < number , ConsequenceType > > ( { } )
6675 const [ selectedApp , setSelectedApp ] = useState < BulkCIDetailType > ( appList [ 0 ] )
76+ const [ currentSidebarTab , setCurrentSidebarTab ] = useState < string > ( CIMaterialSidebarType . CODE_SOURCE )
6777
6878 const [ blobStorageConfigurationLoading , blobStorageConfiguration ] = useAsync (
6979 ( ) => getModuleConfigured ( ModuleNameMap . BLOB_STORAGE ) ,
@@ -121,6 +131,32 @@ export default function BulkCITrigger({
121131 getMaterialData ( )
122132 } , [ ] )
123133
134+ const getRuntimeParamsData = ( _materialListMap : Record < string , any [ ] > ) : void => {
135+ const runtimeParamsPromiseList = appList . map ( ( appDetails ) => {
136+ if ( getIsAppUnorthodox ( appDetails ) || ! _materialListMap [ appDetails . appId ] ) {
137+ return {
138+ [ appDetails . ciPipelineId ] : [ ] ,
139+ }
140+ }
141+ return getRuntimeParams ( appDetails . ciPipelineId )
142+ } )
143+
144+ if ( runtimeParamsPromiseList . length ) {
145+ Promise . all ( runtimeParamsPromiseList )
146+ . then ( ( responses ) => {
147+ const _runtimeParams : Record < string , KeyValueListType [ ] > = { }
148+ responses . forEach ( ( res , index ) => {
149+ _runtimeParams [ appList [ index ] ?. ciPipelineId ] = res || [ ]
150+ } )
151+ setRuntimeParams ( _runtimeParams )
152+ } )
153+ . catch ( ( error ) => {
154+ setPageViewType ( ViewType . ERROR )
155+ showError ( error )
156+ } )
157+ }
158+ }
159+
124160 const getMaterialData = ( ) : void => {
125161 abortControllerRef . current = new AbortController ( )
126162 const _CIMaterialPromiseList = appList . map ( ( appDetails ) =>
@@ -140,9 +176,13 @@ export default function BulkCITrigger({
140176 responses . forEach ( ( res , index ) => {
141177 _materialListMap [ appList [ index ] ?. appId ] = res ?. [ 'result' ]
142178 } )
179+ // These two handlers should be imported from elsewhere
143180 if ( getCIBlockState ) {
144181 getPolicyEnforcementData ( _materialListMap )
145182 }
183+ if ( getRuntimeParams ) {
184+ getRuntimeParamsData ( _materialListMap )
185+ }
146186 updateBulkInputMaterial ( _materialListMap )
147187 if ( ! getIsAppUnorthodox ( selectedApp ) ) {
148188 setShowRegexModal (
@@ -166,6 +206,39 @@ export default function BulkCITrigger({
166206 }
167207 }
168208
209+ const handleRuntimeParametersChange = ( { action, data } : HandleKeyValueChangeType ) => {
210+ let _runtimeParams = runtimeParams [ selectedApp . ciPipelineId ] ?? [ ]
211+
212+ switch ( action ) {
213+ case KeyValueListActionType . ADD :
214+ _runtimeParams . unshift ( { key : '' , value : '' } )
215+ break
216+
217+ case KeyValueListActionType . UPDATE_KEY :
218+ _runtimeParams [ data . index ] . key = data . value
219+ break
220+
221+ case KeyValueListActionType . UPDATE_VALUE :
222+ _runtimeParams [ data . index ] . value = data . value
223+ break
224+
225+ case KeyValueListActionType . DELETE :
226+ _runtimeParams = _runtimeParams . filter ( ( _ , index ) => index !== data . index )
227+ break
228+ default :
229+ throw new Error ( `Invalid action ${ action } ` )
230+ }
231+
232+ setRuntimeParams ( {
233+ ...runtimeParams ,
234+ [ selectedApp . ciPipelineId ] : _runtimeParams ,
235+ } )
236+ }
237+
238+ const handleSidebarTabChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
239+ setCurrentSidebarTab ( e . target . value as CIMaterialSidebarType )
240+ }
241+
169242 const getPolicyEnforcementData = ( _materialListMap : Record < string , any [ ] > ) : void => {
170243 const policyPromiseList = appList . map ( ( appDetails ) => {
171244 if ( getIsAppUnorthodox ( appDetails ) || ! _materialListMap [ appDetails . appId ] ) {
@@ -210,6 +283,7 @@ export default function BulkCITrigger({
210283 className = "dc__transparent flex icon-dim-24"
211284 disabled = { isLoading }
212285 onClick = { closeBulkCIModal }
286+ aria-label = "Close modal"
213287 >
214288 < Close className = "icon-dim-24" />
215289 </ button >
@@ -337,10 +411,10 @@ export default function BulkCITrigger({
337411 savingRegexValue = { isLoading }
338412 />
339413 < div className = "flex right pr-20 pb-20" >
340- < button className = "cta cancel h-28 lh-28-imp mr-16" onClick = { hideBranchEditModal } >
414+ < button className = "cta cancel h-28 lh-28-imp mr-16" onClick = { hideBranchEditModal } type = "button" >
341415 Cancel
342416 </ button >
343- < button className = "cta h-28 lh-28-imp" onClick = { saveBranchName } >
417+ < button className = "cta h-28 lh-28-imp" onClick = { saveBranchName } type = "button" >
344418 Save
345419 </ button >
346420 </ div >
@@ -398,6 +472,11 @@ export default function BulkCITrigger({
398472 isCITriggerBlocked = { appPolicy [ selectedApp . appId ] ?. action === ConsequenceAction . BLOCK }
399473 ciBlockState = { appPolicy [ selectedApp . appId ] }
400474 isJobCI = { selectedApp . isJobCI }
475+ currentSidebarTab = { currentSidebarTab }
476+ handleSidebarTabChange = { handleSidebarTabChange }
477+ runtimeParams = { runtimeParams [ selectedApp . ciPipelineId ] || [ ] }
478+ handleRuntimeParametersChange = { handleRuntimeParametersChange }
479+ appName = { selectedApp ?. name }
401480 />
402481 )
403482 }
@@ -509,7 +588,7 @@ export default function BulkCITrigger({
509588 ) }
510589 { app . appId !== selectedApp . appId && app . errorMessage && (
511590 < span className = "flex left cr-5 fw-4 fs-12" >
512- < Error className = "icon-dim-12 mr-4 mw-14" />
591+ < ICError className = "icon-dim-12 mr-4 mw-14" />
513592 < span className = "dc__block dc__ellipsis-right" > { app . errorMessage } </ span >
514593 </ span >
515594 ) }
@@ -525,6 +604,11 @@ export default function BulkCITrigger({
525604 return < Progressing pageLoader />
526605 }
527606 const selectedMaterialList = appList . find ( ( app ) => app . appId === selectedApp . appId ) ?. material || [ ]
607+ const sidebarTabs = Object . values ( CIMaterialSidebarType ) . map ( ( tabValue ) => ( {
608+ value : tabValue ,
609+ label : tabValue ,
610+ } ) )
611+
528612 return (
529613 < div className = { `bulk-ci-trigger ${ showWebhookModal ? 'webhook-modal' : '' } ` } >
530614 { ! showWebhookModal && (
@@ -533,8 +617,17 @@ export default function BulkCITrigger({
533617 className = "dc__position-sticky dc__top-0 bcn-0 dc__border-bottom fw-6 fs-13 cn-9 p-12 "
534618 style = { { zIndex : 1 } }
535619 >
536- Applications
620+ { GitInfoMaterialTabs ? (
621+ < GitInfoMaterialTabs
622+ tabs = { sidebarTabs }
623+ initialTab = { currentSidebarTab }
624+ onChange = { handleSidebarTabChange }
625+ />
626+ ) : (
627+ 'Applications'
628+ ) }
537629 </ div >
630+
538631 { appList . map ( ( app , index ) => (
539632 < div
540633 className = { `material-list pr-12 pl-12 pb-12 ${
@@ -609,6 +702,7 @@ export default function BulkCITrigger({
609702 data-testid = "start-build"
610703 onClick = { onClickStartBuild }
611704 disabled = { isStartBuildDisabled ( ) }
705+ type = "button"
612706 >
613707 { isLoading ? (
614708 < Progressing />
@@ -644,3 +738,5 @@ export default function BulkCITrigger({
644738 </ Drawer >
645739 )
646740}
741+
742+ export default BulkCITrigger
0 commit comments