Skip to content

Commit fad5bdf

Browse files
committed
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat/combined-ci-cd-pipeline
2 parents def3bed + d7057fe commit fad5bdf

File tree

15 files changed

+222
-263
lines changed

15 files changed

+222
-263
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": "1.15.3-beta-2",
7+
"@devtron-labs/devtron-fe-common-lib": "1.16.0-pre-0",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/Pages/App/Configurations/WorkflowEditor/CreateCICDPipeline/createCICDPipeline.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
$stepper-connector-left: 18px;
44

55
min-height: 400px;
6-
max-height: 80vh;
6+
max-height: 70vh;
77

88
&__stepper-container {
99
gap: #{$stepper-gap};

src/Pages/GlobalConfigurations/ClustersAndEnvironments/ClusterForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ const ClusterForm = ({
422422
setRemoteConnectionFalse()
423423
setTlsConnectionFalse()
424424
reload()
425-
hideEditModal()
425+
if (typeof hideEditModal === 'function') hideEditModal()
426426
} catch (err) {
427427
showError(err)
428428
} finally {

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,9 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
14421442
}
14431443

14441444
// Helper to get selected CD nodes
1445-
const getSelectedCDNodesWithArtifacts = (selectedWorkflows: WorkflowType[]): { node: CommonNodeAttr; wf: WorkflowType }[] =>
1445+
const getSelectedCDNodesWithArtifacts = (
1446+
selectedWorkflows: WorkflowType[],
1447+
): { node: CommonNodeAttr; wf: WorkflowType }[] =>
14461448
selectedWorkflows
14471449
.filter((wf) => wf.isSelected)
14481450
.map((wf) => {
@@ -1452,7 +1454,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
14521454
if (!_cdNode) return null
14531455

14541456
const _selectedNode: CommonNodeAttr | undefined = getSelectedCDNode(bulkTriggerType, _cdNode)
1455-
1457+
14561458
const selectedArtifacts = _selectedNode?.[materialType]?.filter((artifact) => artifact.isSelected) ?? []
14571459
if (selectedArtifacts.length > 0) {
14581460
return { node: _selectedNode, wf }
@@ -1499,7 +1501,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
14991501
const strategy = pipelineIdVsStrategyMap[pipelineId]
15001502

15011503
// skip app if bulkDeploymentStrategy is not default and strategy is not configured for app
1502-
if (ciArtifact && (bulkDeploymentStrategy === 'DEFAULT' || !!strategy)) {
1504+
if (ciArtifact && (bulkDeploymentStrategy === 'DEFAULT' || !!strategy)) {
15031505
_CDTriggerPromiseFunctionList.push(() =>
15041506
triggerCDNode({
15051507
pipelineId,
@@ -2094,7 +2096,9 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
20942096

20952097
const { uniqueReleaseTags } = bulkCDDetailTypeResponse
20962098

2097-
const feasiblePipelineIds = new Set(getSelectedCDNodesWithArtifacts(filteredWorkflows).map(({ node }) => +node.id))
2099+
const feasiblePipelineIds = new Set(
2100+
getSelectedCDNodesWithArtifacts(filteredWorkflows).map(({ node }) => +node.id),
2101+
)
20982102

20992103
// Have to look for its each prop carefully
21002104
// No need to send uniqueReleaseTags will get those in BulkCDTrigger itself
@@ -2117,7 +2121,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
21172121
setRuntimeParamsErrorState={setRuntimeParamsErrorState}
21182122
bulkDeploymentStrategy={bulkDeploymentStrategy}
21192123
setBulkDeploymentStrategy={setBulkDeploymentStrategy}
2120-
/>
2124+
/>
21212125
)
21222126
}
21232127

src/components/ClusterNodes/NodeActions/EditTaintsModal.tsx

Lines changed: 62 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,13 @@ import {
2424
ComponentSizeType,
2525
Drawer,
2626
DynamicDataTable,
27-
GenericEmptyState,
2827
Icon,
2928
InfoIconTippy,
3029
showError,
3130
ToastManager,
3231
ToastVariantType,
3332
} from '@devtron-labs/devtron-fe-common-lib'
3433

35-
import ImgEmptyChartGroup from '@Images/[email protected]'
36-
3734
import { updateTaints } from '../clusterNodes.service'
3835
import { EDIT_TAINTS_MODAL_MESSAGING, TAINTS_TABLE_HEADERS } from '../constants'
3936
import { EditTaintsModalType, EditTaintsRequest, TaintsTableHeaderKeys, TaintsTableType } from '../types'
@@ -76,9 +73,6 @@ const EditTaintsModal = ({ name, version, kind, taints, closePopup }: EditTaints
7673
// HOOKS
7774
const { clusterId } = useParams<{ clusterId: string }>()
7875

79-
// CONSTANTS
80-
const isTaintListEmpty = taintList.length === 0
81-
8276
// HANDLERS
8377
const onClose = () => {
8478
if (!apiCallInProgress) {
@@ -100,23 +94,29 @@ const EditTaintsModal = ({ name, version, kind, taints, closePopup }: EditTaints
10094
const updatedTaintCellError = structuredClone(taintCellError)
10195
delete updatedTaintCellError[row.id]
10296

97+
if (filteredTaintList.length === 0) {
98+
const newTaintsRow = getTaintsTableRow()
99+
filteredTaintList.push(newTaintsRow)
100+
updatedTaintCellError[newTaintsRow.id] = getTaintsRowCellError()
101+
}
102+
103103
setTaintList(filteredTaintList)
104104
setTaintCellError(updatedTaintCellError)
105105
}
106106

107107
const handleEditTaint: TaintsTableType['onRowEdit'] = (row, headerKey, value) => {
108-
const updatedTaintList = taintList.map((taint) =>
109-
taint.id === row.id
110-
? { ...taint, data: { ...taint.data, [headerKey]: { ...taint.data[headerKey], value } } }
111-
: taint,
112-
)
113-
const updatedTaintCellError = {
114-
...taintCellError,
115-
[row.id]: {
116-
...taintCellError[row.id],
117-
[headerKey]: getTaintsTableCellValidateState(headerKey, value),
118-
},
108+
const indexToUpdateInTaintList = taintList.findIndex((taint) => taint.id === row.id)
109+
if (indexToUpdateInTaintList === -1) {
110+
return
119111
}
112+
113+
const updatedTaintList = taintList
114+
const updatedTaintRow = taintList[indexToUpdateInTaintList]
115+
updatedTaintRow.data[headerKey].value = value
116+
updatedTaintList[indexToUpdateInTaintList] = updatedTaintRow
117+
118+
const updatedTaintCellError = structuredClone(taintCellError)
119+
updatedTaintCellError[row.id][headerKey] = getTaintsTableCellValidateState(headerKey, updatedTaintRow)
120120
validateUniqueTaintKey({ taintCellError: updatedTaintCellError, taintList: updatedTaintList })
121121

122122
setTaintList(updatedTaintList)
@@ -173,77 +173,56 @@ const EditTaintsModal = ({ name, version, kind, taints, closePopup }: EditTaints
173173
/>
174174
</div>
175175
<div className="flex-grow-1 dc__overflow-auto flexbox-col dc__gap-16 p-20">
176-
{isTaintListEmpty ? (
177-
<GenericEmptyState
178-
title={EDIT_TAINTS_MODAL_MESSAGING.emptyState.title}
179-
subTitle={EDIT_TAINTS_MODAL_MESSAGING.emptyState.subTitle}
180-
image={ImgEmptyChartGroup}
181-
isButtonAvailable
182-
renderButton={() => (
183-
<Button
184-
dataTestId="add-taint"
185-
text={EDIT_TAINTS_MODAL_MESSAGING.addTaint}
186-
startIcon={<Icon name="ic-add" color={null} />}
187-
onClick={handleAddTaint}
188-
/>
189-
)}
190-
/>
191-
) : (
192-
<>
193-
<div className="flex dc__content-space">
194-
<div className="flex">
195-
<Icon name="ic-spray-can" color="N900" />
196-
<h3 className="fs-14 lh-20 fw-6 cn-9 mt-0 mb-0 ml-8 mr-4">
197-
{EDIT_TAINTS_MODAL_MESSAGING.infoTitle}
198-
</h3>
199-
<InfoIconTippy
200-
heading="Taints"
201-
documentationLinkText="View documentation"
202-
documentationLink="TAINT"
203-
additionalContent={<AdditionalContent />}
204-
openInNewTab
205-
/>
206-
</div>
207-
<Button
208-
dataTestId="add-taint"
209-
variant={ButtonVariantType.secondary}
210-
startIcon={<Icon name="ic-add" color={null} />}
211-
size={ComponentSizeType.small}
212-
text={EDIT_TAINTS_MODAL_MESSAGING.addTaint}
213-
onClick={handleAddTaint}
214-
/>
215-
</div>
216-
<DynamicDataTable<TaintsTableHeaderKeys>
217-
headers={TAINTS_TABLE_HEADERS}
218-
rows={taintList}
219-
onRowAdd={handleAddTaint}
220-
onRowDelete={handleDeleteTaint}
221-
onRowEdit={handleEditTaint}
222-
cellError={taintCellError}
223-
isAdditionNotAllowed
224-
shouldAutoFocusOnMount
176+
<div className="flex dc__content-space">
177+
<div className="flex">
178+
<Icon name="ic-spray-can" color="N900" />
179+
<h3 className="fs-14 lh-20 fw-6 cn-9 mt-0 mb-0 ml-8 mr-4">
180+
{EDIT_TAINTS_MODAL_MESSAGING.infoTitle}
181+
</h3>
182+
<InfoIconTippy
183+
heading="Taints"
184+
documentationLinkText="View documentation"
185+
documentationLink="TAINT"
186+
additionalContent={<AdditionalContent />}
187+
openInNewTab
225188
/>
226-
</>
227-
)}
228-
</div>
229-
{!isTaintListEmpty && (
230-
<div className="dc__border-top flex right p-16 dc__gap-12">
189+
</div>
231190
<Button
232-
dataTestId="edit-taints-modal-cancel"
191+
dataTestId="add-taint"
233192
variant={ButtonVariantType.secondary}
234-
style={ButtonStyleType.neutral}
235-
disabled={apiCallInProgress}
236-
text={EDIT_TAINTS_MODAL_MESSAGING.Actions.cancel}
237-
onClick={onClose}
238-
/>
239-
<Button
240-
dataTestId="edit-taints-modal-save"
241-
isLoading={apiCallInProgress}
242-
text={EDIT_TAINTS_MODAL_MESSAGING.Actions.save}
243-
onClick={onSave}
193+
startIcon={<Icon name="ic-add" color={null} />}
194+
size={ComponentSizeType.small}
195+
text={EDIT_TAINTS_MODAL_MESSAGING.addTaint}
196+
onClick={handleAddTaint}
244197
/>
245198
</div>
246-
)}
199+
<DynamicDataTable<TaintsTableHeaderKeys>
200+
headers={TAINTS_TABLE_HEADERS}
201+
rows={taintList}
202+
onRowAdd={handleAddTaint}
203+
onRowDelete={handleDeleteTaint}
204+
onRowEdit={handleEditTaint}
205+
cellError={taintCellError}
206+
isAdditionNotAllowed
207+
shouldAutoFocusOnMount
208+
/>
209+
</div>
210+
<div className="dc__border-top flex right p-16 dc__gap-12">
211+
<Button
212+
dataTestId="edit-taints-modal-cancel"
213+
variant={ButtonVariantType.secondary}
214+
style={ButtonStyleType.neutral}
215+
disabled={apiCallInProgress}
216+
text={EDIT_TAINTS_MODAL_MESSAGING.Actions.cancel}
217+
onClick={onClose}
218+
/>
219+
<Button
220+
dataTestId="edit-taints-modal-save"
221+
isLoading={apiCallInProgress}
222+
text={EDIT_TAINTS_MODAL_MESSAGING.Actions.save}
223+
onClick={onSave}
224+
/>
225+
</div>
247226
</div>
248227
</Drawer>
249228
)

src/components/ClusterNodes/NodeActions/utils.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const getTaintsTableRow = (taint?: TaintType, id?: number): TaintsTableTy
5353
})
5454

5555
export const getTaintsTableRows = (taints: TaintType[]): TaintsTableType['rows'] =>
56-
taints?.length ? taints.map(getTaintsTableRow) : []
56+
taints?.length ? taints.map(getTaintsTableRow) : [getTaintsTableRow()]
5757

5858
export const getTaintsRowCellError = () =>
5959
TAINTS_TABLE_HEADERS.reduce(
@@ -72,22 +72,25 @@ export const getTaintsTableCellError = (taintList: TaintsTableType['rows']): Tai
7272

7373
export const getTaintsTableCellValidateState = (
7474
headerKey: TaintsTableHeaderKeys,
75-
value: string,
75+
row: TaintsTableType['rows'][number],
7676
): DynamicDataTableCellValidationState => {
77-
if (headerKey === TaintsTableHeaderKeys.KEY) {
77+
const keyColumnValue = row.data[TaintsTableHeaderKeys.KEY].value
78+
const valueColumnValue = row.data[TaintsTableHeaderKeys.VALUE].value
79+
80+
if (headerKey === TaintsTableHeaderKeys.KEY && valueColumnValue) {
7881
const keyPrefixRegex = new RegExp(PATTERNS.KUBERNETES_KEY_PREFIX)
7982
const keyNameRegex = new RegExp(PATTERNS.KUBERNETES_KEY_NAME)
8083

81-
if (!value) {
84+
if (!keyColumnValue) {
8285
return { errorMessages: ['Key is required'], isValid: false }
8386
}
8487

85-
if (value.length > 253) {
88+
if (keyColumnValue.length > 253) {
8689
return { errorMessages: ['Maximum 253 chars are allowed'], isValid: false }
8790
}
8891

89-
if (value.indexOf('/') !== -1) {
90-
const keyArr = value.split('/')
92+
if (keyColumnValue.indexOf('/') !== -1) {
93+
const keyArr = keyColumnValue.split('/')
9194

9295
if (keyArr.length > 2 || !keyPrefixRegex.test(keyArr[0])) {
9396
return {
@@ -104,7 +107,7 @@ export const getTaintsTableCellValidateState = (
104107
isValid: false,
105108
}
106109
}
107-
} else if (!keyNameRegex.test(value)) {
110+
} else if (!keyNameRegex.test(keyColumnValue)) {
108111
return {
109112
errorMessages: [
110113
'The key must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores',
@@ -114,13 +117,13 @@ export const getTaintsTableCellValidateState = (
114117
}
115118
}
116119

117-
if (headerKey === TaintsTableHeaderKeys.VALUE && value) {
120+
if (headerKey === TaintsTableHeaderKeys.VALUE && valueColumnValue) {
118121
const valueRegex = new RegExp(PATTERNS.KUBERNETES_VALUE)
119122

120-
if (value.length > 63) {
123+
if (valueColumnValue.length > 63) {
121124
return { errorMessages: ['Maximum 63 chars are allowed'], isValid: false }
122125
}
123-
if (!valueRegex.test(value)) {
126+
if (!valueRegex.test(valueColumnValue)) {
124127
return {
125128
errorMessages: [
126129
'The value must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores',
@@ -195,7 +198,7 @@ export const getTaintTableValidateState = ({ taintList }: { taintList: TaintsTab
195198
acc[curr.id] = TAINTS_TABLE_HEADERS.reduce(
196199
(headerAcc, { key }) => ({
197200
...headerAcc,
198-
[key]: getTaintsTableCellValidateState(key, curr.data[key].value),
201+
[key]: getTaintsTableCellValidateState(key, curr),
199202
}),
200203
{},
201204
)
@@ -212,8 +215,14 @@ export const getTaintTableValidateState = ({ taintList }: { taintList: TaintsTab
212215
}
213216

214217
export const getTaintsPayload = (taintList: TaintsTableType['rows']) =>
215-
taintList.map(({ data }) => ({
216-
key: data.key.value,
217-
value: data.value.value,
218-
effect: data.effect.value as EFFECT_TYPE,
219-
}))
218+
taintList
219+
.map(({ data }) =>
220+
data.key.value
221+
? {
222+
key: data.key.value,
223+
value: data.value.value,
224+
effect: data.effect.value as EFFECT_TYPE,
225+
}
226+
: null,
227+
)
228+
.filter(Boolean)

src/components/ClusterNodes/constants.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,6 @@ export const EDIT_TAINTS_MODAL_MESSAGING = {
115115
'Combination of <key, effect> must be unique',
116116
],
117117
},
118-
emptyState: {
119-
title: 'Manage node taints',
120-
subTitle:
121-
'Add taints to nodes to prevent or discourage pods from being scheduled on them. Use tolerations on pods to let them run on nodes with matching taints.',
122-
},
123118
addTaint: 'Add taint',
124119
Actions: {
125120
cancel: 'Cancel',

0 commit comments

Comments
 (0)