Skip to content

Commit 599e752

Browse files
Merge pull request #1646 from devtron-labs/feat/runtime-params
feat: runtime params
2 parents 872affd + 1bf0db5 commit 599e752

File tree

10 files changed

+444
-71
lines changed

10 files changed

+444
-71
lines changed

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": "0.0.65",
7+
"@devtron-labs/devtron-fe-common-lib": "0.0.67",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/components/ApplicationGroup/AppGroup.types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
CDModalTabType,
33
DeploymentNodeType,
44
FilterConditionsListType,
5+
KeyValueListType,
56
ResponseType,
67
UserApprovalConfigType,
78
WorkflowNodeType,
@@ -85,6 +86,9 @@ export interface BulkCITriggerType {
8586
responseList: ResponseRowType[]
8687
isLoading: boolean
8788
setLoading: React.Dispatch<React.SetStateAction<boolean>>
89+
runtimeParams: Record<string, KeyValueListType[]>
90+
setRuntimeParams: React.Dispatch<React.SetStateAction<Record<string, KeyValueListType[]>>>
91+
setPageViewType: React.Dispatch<React.SetStateAction<string>>
8892
}
8993

9094
export interface BulkCDTriggerType {

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

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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'
1418
import Tippy from '@tippyjs/react'
1519
import { importComponentFromFELibrary } from '../../../common'
1620
import { ReactComponent as Close } from '../../../../assets/icons/ic-cross.svg'
1721
import { ReactComponent as PlayIcon } from '../../../../assets/icons/misc/arrow-solid-right.svg'
1822
import { 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'
2024
import { ReactComponent as Storage } from '../../../../assets/icons/ic-storage.svg'
2125
import { ReactComponent as OpenInNew } from '../../../../assets/icons/ic-open-in-new.svg'
2226
import { ReactComponent as InfoIcon } from '../../../../assets/icons/info-filled.svg'
2327
import externalCiImg from '../../../../assets/img/external-ci.png'
2428
import linkedCDBuildCIImg from '../../../../assets/img/linked-cd-bulk-ci.png'
2529
import linkedCiImg from '../../../../assets/img/linked-ci.png'
2630
import { 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'
2832
import MaterialSource from '../../../app/details/triggerView/MaterialSource'
2933
import { TriggerViewContext } from '../../../app/details/triggerView/config'
3034
import { getCIMaterialList } from '../../../app/service'
@@ -42,8 +46,10 @@ import { getIsAppUnorthodox } from './utils'
4246

4347
const PolicyEnforcementMessage = importComponentFromFELibrary('PolicyEnforcementMessage')
4448
const 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

Comments
 (0)