@devtron-labs/devtron-fe-common-lib 0.0.61-beta-3 → 0.0.61-beta-5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Common/Constants.d.ts +1 -14
- package/dist/Common/DraggableWrapper/types.d.ts +1 -4
- package/dist/Common/Helper.d.ts +4 -1
- package/dist/Common/Hooks/index.d.ts +0 -1
- package/dist/Common/Types.d.ts +1 -13
- package/dist/Common/index.d.ts +0 -1
- package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraConfigForm.d.ts +4 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraDescriptionField.d.ts +4 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormAction.d.ts +7 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormItem.d.ts +4 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraProfileNameField.d.ts +4 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/Descriptor.d.ts +4 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/Footer.d.ts +4 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/constants.d.ts +50 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/index.d.ts +7 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/services.d.ts +6 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/types.d.ts +286 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/utils.d.ts +12 -0
- package/dist/Pages/GlobalConfigurations/index.d.ts +1 -1
- package/dist/Shared/Components/APIResponseHandler/APIResponseHandler.d.ts +4 -0
- package/dist/Shared/Components/APIResponseHandler/constants.d.ts +4 -0
- package/dist/Shared/Components/APIResponseHandler/index.d.ts +2 -0
- package/dist/Shared/Components/APIResponseHandler/types.d.ts +37 -0
- package/dist/Shared/Components/ReactSelect/index.d.ts +1 -0
- package/dist/Shared/Components/ReactSelect/utils.d.ts +12 -0
- package/dist/Shared/Components/index.d.ts +2 -0
- package/dist/Shared/Helpers.d.ts +16 -0
- package/dist/Shared/index.d.ts +2 -0
- package/dist/Shared/validations.d.ts +8 -0
- package/dist/index.js +1183 -372
- package/package.json +1 -1
- package/src/Assets/Icon/ic-cpu.svg +4 -0
- package/src/Assets/Icon/ic-memory.svg +3 -0
- package/src/Assets/Icon/ic-timer.svg +3 -0
- package/src/Common/BreadCrumb/Types.ts +0 -1
- package/src/Common/Checkbox.tsx +1 -0
- package/src/Common/Constants.ts +3 -18
- package/src/Common/CustomInput/CustomInput.tsx +2 -1
- package/src/Common/DraggableWrapper/DraggableWrapper.tsx +3 -1
- package/src/Common/DraggableWrapper/types.ts +1 -4
- package/src/Common/Helper.tsx +30 -16
- package/src/Common/Hooks/index.ts +0 -1
- package/src/Common/RJSF/utils.ts +2 -0
- package/src/Common/SearchBar/searchBar.scss +1 -1
- package/src/Common/Types.ts +1 -13
- package/src/Common/index.ts +0 -1
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraConfigForm.tsx +128 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraDescriptionField.tsx +44 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormAction.tsx +106 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormItem.tsx +55 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraProfileNameField.tsx +32 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/Descriptor.tsx +45 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/Footer.tsx +56 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/Readme.md +4 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/constants.tsx +139 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/index.ts +7 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/services.tsx +167 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/types.tsx +339 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/utils.tsx +507 -0
- package/src/Pages/GlobalConfigurations/index.ts +1 -1
- package/src/Shared/Components/APIResponseHandler/APIResponseHandler.tsx +41 -0
- package/src/Shared/Components/APIResponseHandler/constants.tsx +5 -0
- package/src/Shared/Components/APIResponseHandler/index.ts +2 -0
- package/src/Shared/Components/APIResponseHandler/types.tsx +39 -0
- package/src/Shared/Components/BulkSelection/BulkSelectionDropdownItems.tsx +3 -1
- package/src/Shared/Components/BulkSelection/BulkSelectionProvider.tsx +5 -14
- package/src/Shared/Components/ReactSelect/index.ts +1 -0
- package/src/Shared/Components/ReactSelect/utils.tsx +97 -0
- package/src/Shared/Components/index.ts +2 -0
- package/src/Shared/Helpers.tsx +29 -0
- package/src/Shared/index.ts +2 -0
- package/src/Shared/validations.tsx +130 -0
- package/dist/Common/Hooks/useUrlFilters/constants.d.ts +0 -8
- package/dist/Common/Hooks/useUrlFilters/index.d.ts +0 -2
- package/dist/Common/Hooks/useUrlFilters/types.d.ts +0 -19
- package/dist/Common/Hooks/useUrlFilters/useUrlFilters.d.ts +0 -20
- package/dist/Common/SortableTableHeaderCell/SortableTableHeaderCell.d.ts +0 -18
- package/dist/Common/SortableTableHeaderCell/index.d.ts +0 -2
- package/dist/Common/SortableTableHeaderCell/types.d.ts +0 -25
- package/dist/Pages/GlobalConfigurations/Authorization/constants.d.ts +0 -15
- package/dist/Pages/GlobalConfigurations/Authorization/index.d.ts +0 -1
- package/src/Assets/Icon/ic-arrow-up-down.svg +0 -3
- package/src/Assets/Icon/ic-sort-arrow-down.svg +0 -3
- package/src/Common/Hooks/useUrlFilters/constants.ts +0 -9
- package/src/Common/Hooks/useUrlFilters/index.ts +0 -2
- package/src/Common/Hooks/useUrlFilters/types.ts +0 -21
- package/src/Common/Hooks/useUrlFilters/useUrlFilters.ts +0 -121
- package/src/Common/SortableTableHeaderCell/SortableTableHeaderCell.tsx +0 -44
- package/src/Common/SortableTableHeaderCell/index.ts +0 -2
- package/src/Common/SortableTableHeaderCell/types.ts +0 -26
- package/src/Pages/GlobalConfigurations/Authorization/constants.ts +0 -16
- package/src/Pages/GlobalConfigurations/Authorization/index.ts +0 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { FormEvent, useEffect, useState } from 'react'
|
|
2
|
+
import { toast } from 'react-toastify'
|
|
3
|
+
import { showError, useAsync } from '../../../Common'
|
|
4
|
+
import { getBuildInfraProfileByName, createBuildInfraProfile, updateBuildInfraProfile } from './services'
|
|
5
|
+
import {
|
|
6
|
+
BuildInfraConfigTypes,
|
|
7
|
+
BuildInfraInheritActions,
|
|
8
|
+
BuildInfraMetaConfigTypes,
|
|
9
|
+
BuildInfraProfileData,
|
|
10
|
+
HandleProfileInputChangeType,
|
|
11
|
+
ProfileInputErrorType,
|
|
12
|
+
UseBuildInfraFormProps,
|
|
13
|
+
UseBuildInfraFormResponseType,
|
|
14
|
+
ValidateRequestLimitResponseType,
|
|
15
|
+
ValidateRequestLimitType,
|
|
16
|
+
} from './types'
|
|
17
|
+
import {
|
|
18
|
+
BUILD_INFRA_INPUT_CONSTRAINTS,
|
|
19
|
+
BUILD_INFRA_TEXT,
|
|
20
|
+
DEFAULT_PROFILE_NAME,
|
|
21
|
+
PROFILE_INPUT_ERROR_FIELDS,
|
|
22
|
+
CREATE_MODE_REQUIRED_INPUT_FIELDS,
|
|
23
|
+
} from './constants'
|
|
24
|
+
import {
|
|
25
|
+
validateDescription,
|
|
26
|
+
validateName,
|
|
27
|
+
validateRequiredPositiveNumber,
|
|
28
|
+
getCommonSelectStyle,
|
|
29
|
+
validateRequiredPositiveInteger,
|
|
30
|
+
} from '../../../Shared'
|
|
31
|
+
|
|
32
|
+
export const validateRequestLimit = ({
|
|
33
|
+
request,
|
|
34
|
+
limit,
|
|
35
|
+
unitsMap,
|
|
36
|
+
}: ValidateRequestLimitType): ValidateRequestLimitResponseType => {
|
|
37
|
+
// Request <= Limit
|
|
38
|
+
// Request and Limit should be numbers can be decimals
|
|
39
|
+
// Request and Limit should be positive numbers
|
|
40
|
+
// Request and Limit should be less than Number.MAX_SAFE_INTEGER
|
|
41
|
+
// Request and Limit should can have at most BUILD_INFRA_INPUT_CONSTRAINTS.DECIMAL_PLACES
|
|
42
|
+
// Both request and limit should be there
|
|
43
|
+
const requestNumber = Number(request.value)
|
|
44
|
+
const limitNumber = Number(limit.value)
|
|
45
|
+
const requestUnit = Number(unitsMap[request.unit]?.conversionFactor)
|
|
46
|
+
const limitUnit = Number(unitsMap[limit.unit]?.conversionFactor)
|
|
47
|
+
|
|
48
|
+
const requestLimitValidationResponse: ValidateRequestLimitResponseType = {
|
|
49
|
+
request: {
|
|
50
|
+
isValid: true,
|
|
51
|
+
},
|
|
52
|
+
limit: {
|
|
53
|
+
isValid: true,
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const requestValidationMessage = validateRequiredPositiveNumber(request.value).message
|
|
58
|
+
const limitValidationMessage = validateRequiredPositiveNumber(limit.value).message
|
|
59
|
+
|
|
60
|
+
if (requestValidationMessage) {
|
|
61
|
+
requestLimitValidationResponse.request = {
|
|
62
|
+
message: requestValidationMessage,
|
|
63
|
+
isValid: false,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (limitValidationMessage) {
|
|
68
|
+
requestLimitValidationResponse.limit = {
|
|
69
|
+
message: limitValidationMessage,
|
|
70
|
+
isValid: false,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (limitValidationMessage || requestValidationMessage) {
|
|
75
|
+
return requestLimitValidationResponse
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// only two decimal places are allowed
|
|
79
|
+
const requestDecimalPlaces = String(request.value).split('.')[1]?.length ?? 0
|
|
80
|
+
const limitDecimalPlaces = String(limit.value).split('.')[1]?.length ?? 0
|
|
81
|
+
|
|
82
|
+
if (requestDecimalPlaces > BUILD_INFRA_INPUT_CONSTRAINTS.DECIMAL_PLACES) {
|
|
83
|
+
requestLimitValidationResponse.request = {
|
|
84
|
+
message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.REQUEST_DECIMAL_PLACES,
|
|
85
|
+
isValid: false,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return requestLimitValidationResponse
|
|
89
|
+
}
|
|
90
|
+
if (limitDecimalPlaces > BUILD_INFRA_INPUT_CONSTRAINTS.DECIMAL_PLACES) {
|
|
91
|
+
requestLimitValidationResponse.limit = {
|
|
92
|
+
message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.LIMIT_DECIMAL_PLACES,
|
|
93
|
+
isValid: false,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return requestLimitValidationResponse
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Assuming requestUnit and requestNumber are not 0
|
|
100
|
+
// TODO: Communicate this assumption to the backend
|
|
101
|
+
const limitRequestUnitFactor = limitUnit / requestUnit
|
|
102
|
+
const limitRequestFactor = limitNumber / requestNumber
|
|
103
|
+
|
|
104
|
+
const isDifferenceBigNumber = limitRequestUnitFactor * limitRequestFactor <= Number.MAX_SAFE_INTEGER
|
|
105
|
+
|
|
106
|
+
if (!isDifferenceBigNumber) {
|
|
107
|
+
requestLimitValidationResponse.request = {
|
|
108
|
+
message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.CAN_NOT_COMPUTE,
|
|
109
|
+
isValid: false,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return requestLimitValidationResponse
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (limitRequestUnitFactor * limitRequestFactor < 1) {
|
|
116
|
+
requestLimitValidationResponse.request = {
|
|
117
|
+
message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.REQUEST_LESS_THAN_LIMIT,
|
|
118
|
+
isValid: false,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return requestLimitValidationResponse
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return requestLimitValidationResponse
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const getInitialProfileInputErrors = (fromCreateView: boolean): ProfileInputErrorType => {
|
|
128
|
+
if (fromCreateView) {
|
|
129
|
+
const initialProfileInputErrors = { ...PROFILE_INPUT_ERROR_FIELDS }
|
|
130
|
+
CREATE_MODE_REQUIRED_INPUT_FIELDS.forEach((field) => {
|
|
131
|
+
initialProfileInputErrors[field] = ''
|
|
132
|
+
})
|
|
133
|
+
return initialProfileInputErrors
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
...PROFILE_INPUT_ERROR_FIELDS,
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const useBuildInfraForm = ({
|
|
142
|
+
name,
|
|
143
|
+
editProfile,
|
|
144
|
+
handleSuccessRedirection,
|
|
145
|
+
}: UseBuildInfraFormProps): UseBuildInfraFormResponseType => {
|
|
146
|
+
const fromCreateView = !name
|
|
147
|
+
|
|
148
|
+
const [isLoading, profileResponse, responseError, reloadRequest] = useAsync(
|
|
149
|
+
() =>
|
|
150
|
+
getBuildInfraProfileByName({
|
|
151
|
+
name: name ?? DEFAULT_PROFILE_NAME,
|
|
152
|
+
fromCreateView,
|
|
153
|
+
}),
|
|
154
|
+
[name],
|
|
155
|
+
)
|
|
156
|
+
// If configuration is existing and is active then use it else use default from profileResponse
|
|
157
|
+
const [profileInput, setProfileInput] = useState<BuildInfraProfileData>(null)
|
|
158
|
+
const [profileInputErrors, setProfileInputErrors] = useState<ProfileInputErrorType>({
|
|
159
|
+
...PROFILE_INPUT_ERROR_FIELDS,
|
|
160
|
+
})
|
|
161
|
+
const [loadingActionRequest, setLoadingActionRequest] = useState<boolean>(false)
|
|
162
|
+
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
if (!isLoading && profileResponse?.configurationUnits && profileResponse?.profile) {
|
|
165
|
+
setProfileInput({
|
|
166
|
+
...profileResponse.profile,
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
setProfileInputErrors(getInitialProfileInputErrors(fromCreateView))
|
|
170
|
+
}
|
|
171
|
+
}, [profileResponse, isLoading])
|
|
172
|
+
|
|
173
|
+
// NOTE: Currently sending and receiving values as string, but will parse it to number for payload
|
|
174
|
+
const handleProfileInputChange = ({ action, data }: HandleProfileInputChangeType) => {
|
|
175
|
+
const currentInput = { ...profileInput }
|
|
176
|
+
const currentInputErrors = { ...profileInputErrors }
|
|
177
|
+
const lastSavedConfiguration = profileResponse.profile.configurations
|
|
178
|
+
const currentConfiguration = currentInput.configurations
|
|
179
|
+
const { value, unit } = data ?? { value: null, unit: null }
|
|
180
|
+
|
|
181
|
+
switch (action) {
|
|
182
|
+
case BuildInfraMetaConfigTypes.DESCRIPTION:
|
|
183
|
+
currentInput.description = value
|
|
184
|
+
currentInputErrors.description = validateDescription(value).message
|
|
185
|
+
break
|
|
186
|
+
|
|
187
|
+
case BuildInfraMetaConfigTypes.NAME:
|
|
188
|
+
currentInput.name = value
|
|
189
|
+
currentInputErrors.name = validateName(value).message
|
|
190
|
+
break
|
|
191
|
+
|
|
192
|
+
case BuildInfraConfigTypes.CPU_LIMIT: {
|
|
193
|
+
currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT] = {
|
|
194
|
+
...currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT],
|
|
195
|
+
value,
|
|
196
|
+
unit,
|
|
197
|
+
}
|
|
198
|
+
const { request, limit } = validateRequestLimit({
|
|
199
|
+
request: {
|
|
200
|
+
value: currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST].value,
|
|
201
|
+
unit: currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST].unit,
|
|
202
|
+
},
|
|
203
|
+
limit: {
|
|
204
|
+
value,
|
|
205
|
+
unit,
|
|
206
|
+
},
|
|
207
|
+
unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.CPU_LIMIT],
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = limit.message
|
|
211
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = request.message
|
|
212
|
+
break
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
case BuildInfraConfigTypes.CPU_REQUEST: {
|
|
216
|
+
currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST] = {
|
|
217
|
+
...currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST],
|
|
218
|
+
value,
|
|
219
|
+
unit,
|
|
220
|
+
}
|
|
221
|
+
const { request, limit } = validateRequestLimit({
|
|
222
|
+
request: {
|
|
223
|
+
value,
|
|
224
|
+
unit,
|
|
225
|
+
},
|
|
226
|
+
limit: {
|
|
227
|
+
value: currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT].value,
|
|
228
|
+
unit: currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT].unit,
|
|
229
|
+
},
|
|
230
|
+
unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.CPU_LIMIT],
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = limit.message
|
|
234
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = request.message
|
|
235
|
+
break
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
case BuildInfraConfigTypes.MEMORY_LIMIT: {
|
|
239
|
+
currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT] = {
|
|
240
|
+
...currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT],
|
|
241
|
+
value,
|
|
242
|
+
unit,
|
|
243
|
+
}
|
|
244
|
+
const { request, limit } = validateRequestLimit({
|
|
245
|
+
request: {
|
|
246
|
+
value: currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].value,
|
|
247
|
+
unit: currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].unit,
|
|
248
|
+
},
|
|
249
|
+
limit: {
|
|
250
|
+
value,
|
|
251
|
+
unit,
|
|
252
|
+
},
|
|
253
|
+
unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.MEMORY_LIMIT],
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = limit.message
|
|
257
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = request.message
|
|
258
|
+
break
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
case BuildInfraConfigTypes.MEMORY_REQUEST: {
|
|
262
|
+
currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST] = {
|
|
263
|
+
...currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST],
|
|
264
|
+
value,
|
|
265
|
+
unit,
|
|
266
|
+
}
|
|
267
|
+
const { request, limit } = validateRequestLimit({
|
|
268
|
+
request: {
|
|
269
|
+
value,
|
|
270
|
+
unit,
|
|
271
|
+
},
|
|
272
|
+
limit: {
|
|
273
|
+
value: currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].value,
|
|
274
|
+
unit: currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].unit,
|
|
275
|
+
},
|
|
276
|
+
unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.MEMORY_LIMIT],
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = limit.message
|
|
280
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = request.message
|
|
281
|
+
break
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
case BuildInfraConfigTypes.BUILD_TIMEOUT: {
|
|
285
|
+
currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT] = {
|
|
286
|
+
...currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT],
|
|
287
|
+
value,
|
|
288
|
+
unit,
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
currentInputErrors[BuildInfraConfigTypes.BUILD_TIMEOUT] = validateRequiredPositiveInteger(value).message
|
|
292
|
+
break
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
case BuildInfraInheritActions.ACTIVATE_CPU:
|
|
296
|
+
currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT] = {
|
|
297
|
+
...lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT],
|
|
298
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].value,
|
|
299
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].unit,
|
|
300
|
+
active: true,
|
|
301
|
+
}
|
|
302
|
+
currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST] = {
|
|
303
|
+
...lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST],
|
|
304
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].value,
|
|
305
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].unit,
|
|
306
|
+
active: true,
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = null
|
|
310
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = null
|
|
311
|
+
break
|
|
312
|
+
|
|
313
|
+
case BuildInfraInheritActions.ACTIVATE_MEMORY:
|
|
314
|
+
currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT] = {
|
|
315
|
+
...lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT],
|
|
316
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].value,
|
|
317
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].unit,
|
|
318
|
+
active: true,
|
|
319
|
+
}
|
|
320
|
+
currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST] = {
|
|
321
|
+
...lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST],
|
|
322
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].value,
|
|
323
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].unit,
|
|
324
|
+
active: true,
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = null
|
|
328
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = null
|
|
329
|
+
break
|
|
330
|
+
|
|
331
|
+
case BuildInfraInheritActions.ACTIVATE_BUILD_TIMEOUT:
|
|
332
|
+
currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT] = {
|
|
333
|
+
...lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT],
|
|
334
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].value,
|
|
335
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].unit,
|
|
336
|
+
active: true,
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
currentInputErrors[BuildInfraConfigTypes.BUILD_TIMEOUT] = null
|
|
340
|
+
break
|
|
341
|
+
|
|
342
|
+
case BuildInfraInheritActions.DE_ACTIVATE_BUILD_TIMEOUT:
|
|
343
|
+
// Reverting the value and unit to defaultValues
|
|
344
|
+
currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT] = {
|
|
345
|
+
...currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT],
|
|
346
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].defaultValue.value,
|
|
347
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].defaultValue.unit,
|
|
348
|
+
active: false,
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
currentInputErrors[BuildInfraConfigTypes.BUILD_TIMEOUT] = null
|
|
352
|
+
break
|
|
353
|
+
|
|
354
|
+
case BuildInfraInheritActions.DE_ACTIVATE_CPU:
|
|
355
|
+
currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT] = {
|
|
356
|
+
...currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT],
|
|
357
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].defaultValue.value,
|
|
358
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].defaultValue.unit,
|
|
359
|
+
active: false,
|
|
360
|
+
}
|
|
361
|
+
currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST] = {
|
|
362
|
+
...currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST],
|
|
363
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].defaultValue.value,
|
|
364
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].defaultValue.unit,
|
|
365
|
+
active: false,
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = null
|
|
369
|
+
currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = null
|
|
370
|
+
break
|
|
371
|
+
|
|
372
|
+
case BuildInfraInheritActions.DE_ACTIVATE_MEMORY:
|
|
373
|
+
currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT] = {
|
|
374
|
+
...currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT],
|
|
375
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].defaultValue.value,
|
|
376
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].defaultValue.unit,
|
|
377
|
+
active: false,
|
|
378
|
+
}
|
|
379
|
+
currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST] = {
|
|
380
|
+
...currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST],
|
|
381
|
+
value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].defaultValue.value,
|
|
382
|
+
unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].defaultValue.unit,
|
|
383
|
+
active: false,
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = null
|
|
387
|
+
currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = null
|
|
388
|
+
break
|
|
389
|
+
|
|
390
|
+
default:
|
|
391
|
+
throw new Error(BUILD_INFRA_TEXT.getInvalidActionMessage(action))
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
setProfileInput(currentInput)
|
|
395
|
+
setProfileInputErrors(currentInputErrors)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
|
399
|
+
e.preventDefault()
|
|
400
|
+
// Since considering '' as a valid error message
|
|
401
|
+
const hasErrors =
|
|
402
|
+
Object.keys(profileInputErrors).filter(
|
|
403
|
+
(item) => profileInputErrors[item] !== null && profileInputErrors[item] !== undefined,
|
|
404
|
+
).length > 0
|
|
405
|
+
|
|
406
|
+
if (hasErrors) {
|
|
407
|
+
toast.error(BUILD_INFRA_TEXT.INVALID_FORM_MESSAGE)
|
|
408
|
+
return
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
setLoadingActionRequest(true)
|
|
412
|
+
try {
|
|
413
|
+
if (editProfile) {
|
|
414
|
+
await updateBuildInfraProfile({ name, profileInput })
|
|
415
|
+
} else {
|
|
416
|
+
await createBuildInfraProfile({ profileInput })
|
|
417
|
+
}
|
|
418
|
+
setLoadingActionRequest(false)
|
|
419
|
+
toast.success(BUILD_INFRA_TEXT.getSubmitSuccessMessage(profileInput.name, editProfile))
|
|
420
|
+
|
|
421
|
+
if (handleSuccessRedirection) {
|
|
422
|
+
handleSuccessRedirection()
|
|
423
|
+
} else {
|
|
424
|
+
reloadRequest()
|
|
425
|
+
}
|
|
426
|
+
} catch (err) {
|
|
427
|
+
showError(err)
|
|
428
|
+
setLoadingActionRequest(false)
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return {
|
|
433
|
+
isLoading,
|
|
434
|
+
profileResponse,
|
|
435
|
+
responseError,
|
|
436
|
+
reloadRequest,
|
|
437
|
+
profileInput,
|
|
438
|
+
profileInputErrors,
|
|
439
|
+
handleProfileInputChange,
|
|
440
|
+
loadingActionRequest,
|
|
441
|
+
handleSubmit,
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export const unitSelectorStyles = () =>
|
|
446
|
+
getCommonSelectStyle({
|
|
447
|
+
control: (base, state) => ({
|
|
448
|
+
...base,
|
|
449
|
+
borderRadius: 0,
|
|
450
|
+
backgroundColor: 'var(--N0)',
|
|
451
|
+
border: state.isFocused ? '1px solid var(--B500) !important' : '1px solid var(--N200)',
|
|
452
|
+
alignItems: 'center',
|
|
453
|
+
cursor: 'pointer',
|
|
454
|
+
borderTopRightRadius: '4px',
|
|
455
|
+
borderBottomRightRadius: '4px',
|
|
456
|
+
overflow: 'hidden',
|
|
457
|
+
textOverflow: 'ellipsis',
|
|
458
|
+
whiteSpace: 'nowrap',
|
|
459
|
+
outline: 'none',
|
|
460
|
+
boxShadow: 'none',
|
|
461
|
+
'&:hover': {
|
|
462
|
+
border: '1px solid var(--N400)',
|
|
463
|
+
},
|
|
464
|
+
}),
|
|
465
|
+
indicatorContainer: (base) => ({
|
|
466
|
+
...base,
|
|
467
|
+
padding: '0px',
|
|
468
|
+
}),
|
|
469
|
+
dropdownIndicator: (base, state) => ({
|
|
470
|
+
...base,
|
|
471
|
+
color: 'var(--N600)',
|
|
472
|
+
transition: 'all .2s ease',
|
|
473
|
+
transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
474
|
+
}),
|
|
475
|
+
option: (base, state) => ({
|
|
476
|
+
...base,
|
|
477
|
+
overflow: 'hidden',
|
|
478
|
+
textOverflow: 'ellipsis',
|
|
479
|
+
whiteSpace: 'nowrap',
|
|
480
|
+
cursor: 'pointer',
|
|
481
|
+
...(state.isFocused
|
|
482
|
+
? {
|
|
483
|
+
backgroundColor: 'var(--N50)',
|
|
484
|
+
}
|
|
485
|
+
: {}),
|
|
486
|
+
...(state.isSelected && {
|
|
487
|
+
backgroundColor: 'var(--B100)',
|
|
488
|
+
fontWeight: 600,
|
|
489
|
+
color: 'var(--B500)',
|
|
490
|
+
}),
|
|
491
|
+
'&:active': {
|
|
492
|
+
backgroundColor: 'var(--N50)',
|
|
493
|
+
},
|
|
494
|
+
}),
|
|
495
|
+
valueContainer: (base) => ({
|
|
496
|
+
...base,
|
|
497
|
+
color: 'var(--N900)',
|
|
498
|
+
fontSize: '13px',
|
|
499
|
+
fontWeight: '400',
|
|
500
|
+
lineHeight: '20px',
|
|
501
|
+
}),
|
|
502
|
+
menuList: (base) => ({
|
|
503
|
+
...base,
|
|
504
|
+
maxHeight: '164px',
|
|
505
|
+
height: '100%',
|
|
506
|
+
}),
|
|
507
|
+
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './BuildInfra'
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ErrorScreenNotAuthorized, GenericEmptyState, Progressing, Reload } from '../../../Common'
|
|
2
|
+
import { NOT_FOUND_DEFAULT_TEXT } from './constants'
|
|
3
|
+
import { APIResponseHandlerProps } from './types'
|
|
4
|
+
|
|
5
|
+
const APIResponseHandler = ({
|
|
6
|
+
isLoading,
|
|
7
|
+
progressingProps,
|
|
8
|
+
error,
|
|
9
|
+
notAuthorized,
|
|
10
|
+
notFoundText,
|
|
11
|
+
reloadProps,
|
|
12
|
+
children,
|
|
13
|
+
}: APIResponseHandlerProps) => {
|
|
14
|
+
// keeping it above loading since, not expected to send a call if not authorized
|
|
15
|
+
if (notAuthorized) {
|
|
16
|
+
return <ErrorScreenNotAuthorized />
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (isLoading) {
|
|
20
|
+
return <Progressing {...progressingProps} />
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (error) {
|
|
24
|
+
// TODO: Can extend ErrorScreenNotFound
|
|
25
|
+
if (error?.code === 404) {
|
|
26
|
+
return (
|
|
27
|
+
<GenericEmptyState
|
|
28
|
+
title={notFoundText?.title ?? NOT_FOUND_DEFAULT_TEXT.title}
|
|
29
|
+
subTitle={notFoundText?.subTitle ?? NOT_FOUND_DEFAULT_TEXT.subTitle}
|
|
30
|
+
/>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return <Reload {...reloadProps} />
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Had to add this since while using it is throwing ts error
|
|
37
|
+
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
38
|
+
return <>{children}</>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default APIResponseHandler
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
import { GenericEmptyStateType, ProgressingProps, ReloadType, ServerErrors } from '../../../Common'
|
|
3
|
+
|
|
4
|
+
export interface EmptyPageTextType {
|
|
5
|
+
title?: GenericEmptyStateType['title']
|
|
6
|
+
subTitle?: GenericEmptyStateType['subTitle']
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface APIResponseHandlerProps {
|
|
10
|
+
/**
|
|
11
|
+
* If true, would show Progressing component
|
|
12
|
+
*/
|
|
13
|
+
isLoading?: boolean
|
|
14
|
+
/**
|
|
15
|
+
* If loading is true, would load send these props to Progressing component
|
|
16
|
+
*/
|
|
17
|
+
progressingProps?: ProgressingProps
|
|
18
|
+
/**
|
|
19
|
+
* If true and isLoading is false would show default Reload component
|
|
20
|
+
* In case error code is 404 show default 404 page using GenericEmptyState
|
|
21
|
+
*/
|
|
22
|
+
error?: ServerErrors
|
|
23
|
+
/**
|
|
24
|
+
* Page text for 404 page
|
|
25
|
+
*/
|
|
26
|
+
notFoundText?: EmptyPageTextType
|
|
27
|
+
/**
|
|
28
|
+
* If true would show Not Authorized page
|
|
29
|
+
*/
|
|
30
|
+
notAuthorized?: boolean
|
|
31
|
+
/**
|
|
32
|
+
* If given, on Error, would load these props
|
|
33
|
+
*/
|
|
34
|
+
reloadProps?: ReloadType
|
|
35
|
+
/**
|
|
36
|
+
* If no Error and no Loading, would load this component
|
|
37
|
+
*/
|
|
38
|
+
children: ReactNode
|
|
39
|
+
}
|
|
@@ -18,7 +18,9 @@ const BulkSelectionDropdownItems = <T,>({
|
|
|
18
18
|
data-testid={`bulk-action-${locator}`}
|
|
19
19
|
onClick={handleSelect}
|
|
20
20
|
className={`dc__no-border dc__outline-none-imp w-100 flexbox h-32 dc__align-items-center pt-6 pr-8 pb-6 pl-8 dc__gap-8 ${
|
|
21
|
-
isSelected
|
|
21
|
+
isSelected
|
|
22
|
+
? 'cb-5 bcb-1 icon-stroke-b5 fs-13 fw-6 lh-20'
|
|
23
|
+
: 'dc__no-background cn-9 fs-13 fw-4 lh-20 dc__hover-n50'
|
|
22
24
|
}`}
|
|
23
25
|
type="button"
|
|
24
26
|
>
|
|
@@ -33,10 +33,6 @@ export const BulkSelectionProvider = <T,>({
|
|
|
33
33
|
}: UseBulkSelectionProps<T>) => {
|
|
34
34
|
const [selectedIdentifiers, setSelectedIdentifiers] = useState<T>({} as T)
|
|
35
35
|
|
|
36
|
-
const isBulkSelectionApplied = selectedIdentifiers[SELECT_ALL_ACROSS_PAGES_LOCATOR]
|
|
37
|
-
|
|
38
|
-
const getSelectedIdentifiersCount = () => Object.keys(selectedIdentifiers).length
|
|
39
|
-
|
|
40
36
|
const setIdentifiersAfterClear = (newIdentifiers: T, selectedIds: (number | string)[]) => {
|
|
41
37
|
const _newIdentifiers = JSON.parse(JSON.stringify(newIdentifiers))
|
|
42
38
|
selectedIds.forEach((id) => {
|
|
@@ -48,7 +44,7 @@ export const BulkSelectionProvider = <T,>({
|
|
|
48
44
|
const setIdentifiersAfterPageSelection = (baseObject: T) => {
|
|
49
45
|
const _selectedIdentifiers = JSON.parse(JSON.stringify(selectedIdentifiers))
|
|
50
46
|
// removing bulk selection across pages if present
|
|
51
|
-
if (
|
|
47
|
+
if (_selectedIdentifiers[SELECT_ALL_ACROSS_PAGES_LOCATOR]) {
|
|
52
48
|
delete _selectedIdentifiers[SELECT_ALL_ACROSS_PAGES_LOCATOR]
|
|
53
49
|
}
|
|
54
50
|
|
|
@@ -78,13 +74,10 @@ export const BulkSelectionProvider = <T,>({
|
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
case BulkSelectionEvents.SELECT_ALL_ACROSS_PAGES: {
|
|
81
|
-
if (
|
|
77
|
+
if (selectedIdentifiers[SELECT_ALL_ACROSS_PAGES_LOCATOR]) {
|
|
82
78
|
return
|
|
83
79
|
}
|
|
84
|
-
const selectedIdentifiersLength =
|
|
85
|
-
// This is for showing a modal dialog if applicable to confirm if bulk selection is to be applied
|
|
86
|
-
// Do note that the 'getSelectAllDialogStatus' should be called after the length check explicitly
|
|
87
|
-
// otherwise the modal will open each time
|
|
80
|
+
const selectedIdentifiersLength = Object.keys(selectedIdentifiers).length
|
|
88
81
|
if (selectedIdentifiersLength > 0 && getSelectAllDialogStatus() === SelectAllDialogStatus.OPEN) {
|
|
89
82
|
return
|
|
90
83
|
}
|
|
@@ -126,7 +119,7 @@ export const BulkSelectionProvider = <T,>({
|
|
|
126
119
|
}
|
|
127
120
|
|
|
128
121
|
// if selectedIdentifiers contains select all across pages locator then it means all are selected
|
|
129
|
-
if (
|
|
122
|
+
if (selectedIdentifiers[SELECT_ALL_ACROSS_PAGES_LOCATOR]) {
|
|
130
123
|
return {
|
|
131
124
|
isChecked: true,
|
|
132
125
|
checkboxValue: CHECKBOX_VALUE.BULK_CHECKED,
|
|
@@ -159,10 +152,8 @@ export const BulkSelectionProvider = <T,>({
|
|
|
159
152
|
handleBulkSelection,
|
|
160
153
|
isChecked,
|
|
161
154
|
checkboxValue,
|
|
162
|
-
isBulkSelectionApplied,
|
|
163
|
-
getSelectedIdentifiersCount,
|
|
164
155
|
}),
|
|
165
|
-
[selectedIdentifiers, handleBulkSelection, isChecked, checkboxValue
|
|
156
|
+
[selectedIdentifiers, handleBulkSelection, isChecked, checkboxValue],
|
|
166
157
|
)
|
|
167
158
|
|
|
168
159
|
return <BulkSelectionContext.Provider value={value}>{children}</BulkSelectionContext.Provider>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './utils'
|