Skip to content

Commit 6131c79

Browse files
committed
fix: ConditionDetails - error state handling fix
1 parent ac20ef1 commit 6131c79

File tree

3 files changed

+53
-51
lines changed

3 files changed

+53
-51
lines changed

src/components/CIPipelineN/ConditionContainer.tsx

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@
1616

1717
import { ChangeEvent, useContext, useEffect, useState } from 'react'
1818

19-
import { ConditionDataTableHeaderKeys, ConditionType, PluginType } from '@devtron-labs/devtron-fe-common-lib'
19+
import { ConditionType, PluginType } from '@devtron-labs/devtron-fe-common-lib'
2020

2121
import { ReactComponent as Dropdown } from '../../assets/icons/ic-chevron-down.svg'
2222
import { ConditionContainerType } from '../ciPipeline/types'
2323
import { pipelineContext } from '../workflowEditor/workflowEditor'
2424
import { ConditionDataTable } from './ConditionDataTable/ConditionDataTable.component'
2525
import { CONDITION_DATA_TABLE_OPERATOR_OPTIONS } from './ConditionDataTable/constants'
26+
import { CONTAINER_CONDITION_TYPE_TO_CONDITION_TYPE_MAP } from './Constants'
2627

2728
export const ConditionContainer = ({ type }: { type: ConditionContainerType }) => {
28-
const { formData, setFormData, selectedTaskIndex, activeStageName, formDataErrorObj, setFormDataErrorObj } =
29-
useContext(pipelineContext)
29+
const { formData, setFormData, selectedTaskIndex, activeStageName, formDataErrorObj } = useContext(pipelineContext)
3030

3131
const [collapsedSection, setCollapsedSection] = useState<boolean>(true)
3232
const [conditionType, setConditionType] = useState<ConditionType>(
@@ -43,38 +43,46 @@ export const ConditionContainer = ({ type }: { type: ConditionContainerType }) =
4343
}, [activeStageName])
4444

4545
useEffect(() => {
46-
const { conditionDetails } = formDataErrorObj[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable]
47-
if (conditionDetails?.length) {
48-
const errorConditionIndexArr = []
49-
for (let i = 0; i < conditionDetails.length; i++) {
50-
if (!conditionDetails[i].isValid) {
51-
errorConditionIndexArr.push(i)
52-
}
53-
}
54-
if (errorConditionIndexArr?.length) {
55-
let derivedConditionType
56-
for (let index = 0; index < errorConditionIndexArr.length; index++) {
57-
const currentCondition =
58-
formData[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable].conditionDetails[
59-
index
60-
]
61-
if (
62-
(type === ConditionContainerType.PASS_FAILURE &&
63-
(currentCondition.conditionType === ConditionType.PASS ||
64-
currentCondition.conditionType === ConditionType.FAIL)) ||
65-
(type === ConditionContainerType.TRIGGER_SKIP &&
66-
(currentCondition.conditionType === ConditionType.TRIGGER ||
67-
currentCondition.conditionType === ConditionType.SKIP))
68-
) {
69-
derivedConditionType = currentCondition.conditionType
70-
break
71-
}
46+
const { isConditionDetailsValid, conditionDetails: conditionDetailsError } =
47+
formDataErrorObj[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable]
48+
49+
if (!isConditionDetailsValid) {
50+
const { conditionDetails } = formData[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable]
51+
52+
const invalidConditionDetailsIds = Object.keys(conditionDetailsError).reduce((acc, key) => {
53+
if (
54+
Object.keys(conditionDetailsError[key]).some(
55+
(dataKey) => !conditionDetailsError[key][dataKey].isValid,
56+
)
57+
) {
58+
acc.push(key)
7259
}
73-
if (derivedConditionType) {
74-
setConditionType(derivedConditionType)
75-
if (collapsedSection) {
76-
setCollapsedSection(false) // expand conditions in case of error
77-
}
60+
61+
return acc
62+
}, [])
63+
64+
const filteredConditionDetails = conditionDetails.filter(({ conditionType: _conditionType }) =>
65+
CONTAINER_CONDITION_TYPE_TO_CONDITION_TYPE_MAP[type].includes(_conditionType),
66+
)
67+
68+
const derivedConditionType = filteredConditionDetails.length
69+
? invalidConditionDetailsIds.reduce((acc, currId) => {
70+
const currentCondition = filteredConditionDetails.find(({ id }) =>
71+
typeof +currId === 'number' ? id === +currId : id === currId,
72+
)?.conditionType
73+
74+
if (currentCondition) {
75+
return currentCondition
76+
}
77+
78+
return acc
79+
}, null)
80+
: null
81+
82+
if (derivedConditionType) {
83+
setConditionType(derivedConditionType)
84+
if (collapsedSection) {
85+
setCollapsedSection(false) // expand conditions in case of error
7886
}
7987
}
8088
}
@@ -84,7 +92,6 @@ export const ConditionContainer = ({ type }: { type: ConditionContainerType }) =
8492
setCollapsedSection(!collapsedSection)
8593
if (collapsedSection) {
8694
const _formData = { ...formData }
87-
const updatedFormDataErrorObj = structuredClone(formDataErrorObj)
8895
let _conditionType: ConditionType
8996
let { conditionDetails } = _formData[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable]
9097
let addNewRow = false
@@ -137,22 +144,6 @@ export const ConditionContainer = ({ type }: { type: ConditionContainerType }) =
137144
_formData[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable].conditionDetails =
138145
conditionDetails
139146
setFormData(_formData)
140-
141-
const updatedConditionDetailsCellError =
142-
updatedFormDataErrorObj[activeStageName].steps[selectedTaskIndex][currentStepTypeVariable]
143-
.conditionDetails || {}
144-
145-
updatedConditionDetailsCellError[newCondition.id] = {
146-
[ConditionDataTableHeaderKeys.VARIABLE]: { isValid: true, errorMessages: [] },
147-
[ConditionDataTableHeaderKeys.OPERATOR]: { isValid: true, errorMessages: [] },
148-
[ConditionDataTableHeaderKeys.VALUE]: { isValid: true, errorMessages: [] },
149-
}
150-
151-
updatedFormDataErrorObj[activeStageName].steps[selectedTaskIndex][
152-
currentStepTypeVariable
153-
].conditionDetails = updatedConditionDetailsCellError
154-
155-
setFormDataErrorObj(updatedFormDataErrorObj)
156147
}
157148
}
158149
}

src/components/CIPipelineN/ConditionDataTable/ConditionDataTable.component.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ export const ConditionDataTable = ({ type, conditionType, handleConditionTypeCha
144144
}
145145

146146
Object.values(ConditionDataTableHeaderKeys).forEach((key: ConditionDataTableHeaderKeys) => {
147+
if (!updatedCellError[rowAction.rowId]) {
148+
updatedCellError[rowAction.rowId] = getConditionDataTableRowEmptyValidationState()
149+
}
150+
147151
if (key === rowAction.headerKey) {
148152
updatedCellError[rowAction.rowId][rowAction.headerKey] =
149153
getConditionDataTableCellValidateState({

src/components/CIPipelineN/Constants.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { ConditionContainerType, ConditionType } from '@Components/ciPipeline/types'
18+
1719
export const TIPPY_VAR_MSG = 'This is a variable. It will be replaced with the value during execution.'
1820

1921
export const excludeVariables = ['DOCKER_IMAGE_TAG', 'DOCKER_IMAGE']
@@ -22,3 +24,8 @@ export const INLINE_PLUGIN_TEXT = {
2224
TITLE: 'Execute custom task',
2325
DESCRIPTION: 'Write a script to perform custom task or create custom plugin',
2426
}
27+
28+
export const CONTAINER_CONDITION_TYPE_TO_CONDITION_TYPE_MAP = {
29+
[ConditionContainerType.TRIGGER_SKIP]: [ConditionType.TRIGGER, ConditionType.SKIP],
30+
[ConditionContainerType.PASS_FAILURE]: [ConditionType.PASS, ConditionType.FAIL],
31+
}

0 commit comments

Comments
 (0)