@devtron-labs/devtron-fe-common-lib 0.0.58-beta-3 → 0.0.58-beta-4

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.
Files changed (70) hide show
  1. package/dist/Common/Constants.d.ts +9 -0
  2. package/dist/Common/CustomInput/CustomInput.d.ts +1 -1
  3. package/dist/Common/CustomInput/Types.d.ts +1 -0
  4. package/dist/Common/EmptyState/GenericEmptyState.d.ts +1 -1
  5. package/dist/Common/Helper.d.ts +1 -4
  6. package/dist/Common/Types.d.ts +4 -2
  7. package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraConfigForm.d.ts +4 -0
  8. package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraDescriptionField.d.ts +4 -0
  9. package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormAction.d.ts +7 -0
  10. package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormItem.d.ts +4 -0
  11. package/dist/Pages/GlobalConfigurations/BuildInfra/BuildInfraProfileNameField.d.ts +4 -0
  12. package/dist/Pages/GlobalConfigurations/BuildInfra/Descriptor.d.ts +4 -0
  13. package/dist/Pages/GlobalConfigurations/BuildInfra/Footer.d.ts +4 -0
  14. package/dist/Pages/GlobalConfigurations/BuildInfra/constants.d.ts +48 -0
  15. package/dist/Pages/GlobalConfigurations/BuildInfra/index.d.ts +7 -0
  16. package/dist/Pages/GlobalConfigurations/BuildInfra/services.d.ts +13 -0
  17. package/dist/Pages/GlobalConfigurations/BuildInfra/types.d.ts +281 -0
  18. package/dist/Pages/GlobalConfigurations/BuildInfra/utils.d.ts +12 -0
  19. package/dist/Pages/GlobalConfigurations/index.d.ts +1 -0
  20. package/dist/Pages/index.d.ts +1 -0
  21. package/dist/Shared/Components/APIResponseHandler/APIResponseHandler.d.ts +4 -0
  22. package/dist/Shared/Components/APIResponseHandler/index.d.ts +2 -0
  23. package/dist/Shared/Components/APIResponseHandler/types.d.ts +37 -0
  24. package/dist/Shared/Components/ReactSelect/index.d.ts +1 -0
  25. package/dist/Shared/Components/ReactSelect/utils.d.ts +12 -0
  26. package/dist/Shared/Components/index.d.ts +2 -0
  27. package/dist/Shared/index.d.ts +2 -0
  28. package/dist/Shared/validations.d.ts +7 -0
  29. package/dist/index.d.ts +3 -1
  30. package/dist/index.js +1160 -193
  31. package/package.json +1 -1
  32. package/src/Assets/Icon/ic-cpu.svg +4 -0
  33. package/src/Assets/Icon/ic-memory.svg +3 -0
  34. package/src/Assets/Icon/ic-timer.svg +3 -0
  35. package/src/Common/BreadCrumb/Types.ts +0 -1
  36. package/src/Common/Checkbox.tsx +1 -0
  37. package/src/Common/Constants.ts +11 -1
  38. package/src/Common/CustomInput/CustomInput.tsx +6 -5
  39. package/src/Common/CustomInput/Types.ts +1 -0
  40. package/src/Common/DraggableWrapper/DraggableWrapper.tsx +3 -1
  41. package/src/Common/EmptyState/GenericEmptyState.tsx +45 -13
  42. package/src/Common/Helper.tsx +16 -30
  43. package/src/Common/RJSF/utils.ts +3 -0
  44. package/src/Common/SearchBar/SearchBar.component.tsx +26 -13
  45. package/src/Common/SearchBar/searchBar.scss +1 -1
  46. package/src/Common/Types.ts +3 -1
  47. package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraConfigForm.tsx +121 -0
  48. package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraDescriptionField.tsx +44 -0
  49. package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormAction.tsx +99 -0
  50. package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormItem.tsx +55 -0
  51. package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraProfileNameField.tsx +32 -0
  52. package/src/Pages/GlobalConfigurations/BuildInfra/Descriptor.tsx +38 -0
  53. package/src/Pages/GlobalConfigurations/BuildInfra/Footer.tsx +45 -0
  54. package/src/Pages/GlobalConfigurations/BuildInfra/Readme.md +4 -0
  55. package/src/Pages/GlobalConfigurations/BuildInfra/constants.tsx +137 -0
  56. package/src/Pages/GlobalConfigurations/BuildInfra/index.ts +7 -0
  57. package/src/Pages/GlobalConfigurations/BuildInfra/services.tsx +183 -0
  58. package/src/Pages/GlobalConfigurations/BuildInfra/types.tsx +334 -0
  59. package/src/Pages/GlobalConfigurations/BuildInfra/utils.tsx +489 -0
  60. package/src/Pages/GlobalConfigurations/index.ts +1 -0
  61. package/src/Pages/index.ts +1 -0
  62. package/src/Shared/Components/APIResponseHandler/APIResponseHandler.tsx +39 -0
  63. package/src/Shared/Components/APIResponseHandler/index.ts +2 -0
  64. package/src/Shared/Components/APIResponseHandler/types.tsx +39 -0
  65. package/src/Shared/Components/ReactSelect/index.ts +1 -0
  66. package/src/Shared/Components/ReactSelect/utils.tsx +97 -0
  67. package/src/Shared/Components/index.ts +2 -0
  68. package/src/Shared/index.ts +2 -0
  69. package/src/Shared/validations.tsx +72 -0
  70. package/src/index.ts +3 -1
@@ -0,0 +1,489 @@
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
+ REQUIRED_INPUT_FIELDS,
23
+ } from './constants'
24
+ import {
25
+ validateDescription,
26
+ validateName,
27
+ validateRequiredPositiveNumber,
28
+ getCommonSelectStyle,
29
+ } from '../../../Shared'
30
+
31
+ export const validateRequestLimit = ({
32
+ request,
33
+ limit,
34
+ unitsMap,
35
+ }: ValidateRequestLimitType): ValidateRequestLimitResponseType => {
36
+ // Request <= Limit
37
+ // Request and Limit should be numbers can be decimals
38
+ // Request and Limit should be positive numbers
39
+ // Request and Limit should be less than Number.MAX_SAFE_INTEGER
40
+ // Request and Limit should can have at most BUILD_INFRA_INPUT_CONSTRAINTS.DECIMAL_PLACES
41
+ // Both request and limit should be there
42
+ const requestNumber = Number(request.value)
43
+ const limitNumber = Number(limit.value)
44
+ const requestUnit = Number(unitsMap[request.unit].conversionFactor)
45
+ const limitUnit = Number(unitsMap[limit.unit].conversionFactor)
46
+
47
+ const requestLimitValidationResponse: ValidateRequestLimitResponseType = {
48
+ request: {
49
+ isValid: true,
50
+ },
51
+ limit: {
52
+ isValid: true,
53
+ },
54
+ }
55
+
56
+ const isRequestValidNumber = validateRequiredPositiveNumber(request.value).isValid
57
+ const isLimitValidNumber = validateRequiredPositiveNumber(limit.value).isValid
58
+
59
+ if (!isRequestValidNumber) {
60
+ requestLimitValidationResponse.request = {
61
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.NEGATIVE_REQUEST,
62
+ isValid: false,
63
+ }
64
+ }
65
+
66
+ if (!isLimitValidNumber) {
67
+ requestLimitValidationResponse.limit = {
68
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.NEGATIVE_LIMIT,
69
+ isValid: false,
70
+ }
71
+ }
72
+
73
+ if (!isRequestValidNumber || !isLimitValidNumber) {
74
+ return requestLimitValidationResponse
75
+ }
76
+
77
+ const isSafeRequestNumber = requestNumber * requestUnit < Number.MAX_SAFE_INTEGER
78
+ const isSafeLimitNumber = limitNumber * limitUnit < Number.MAX_SAFE_INTEGER
79
+
80
+ if (!isSafeRequestNumber) {
81
+ requestLimitValidationResponse.request = {
82
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.REQUEST_TOO_BIG,
83
+ isValid: false,
84
+ }
85
+
86
+ return requestLimitValidationResponse
87
+ }
88
+
89
+ if (!isSafeLimitNumber) {
90
+ requestLimitValidationResponse.limit = {
91
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.LIMIT_TOO_BIG,
92
+ isValid: false,
93
+ }
94
+
95
+ return requestLimitValidationResponse
96
+ }
97
+
98
+ // only two decimal places are allowed
99
+ const requestDecimalPlaces = String(request.value).split('.')[1]?.length ?? 0
100
+ const limitDecimalPlaces = String(limit.value).split('.')[1]?.length ?? 0
101
+
102
+ if (requestDecimalPlaces > BUILD_INFRA_INPUT_CONSTRAINTS.DECIMAL_PLACES) {
103
+ requestLimitValidationResponse.request = {
104
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.REQUEST_DECIMAL_PLACES,
105
+ isValid: false,
106
+ }
107
+
108
+ return requestLimitValidationResponse
109
+ }
110
+ if (limitDecimalPlaces > BUILD_INFRA_INPUT_CONSTRAINTS.DECIMAL_PLACES) {
111
+ requestLimitValidationResponse.limit = {
112
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.LIMIT_DECIMAL_PLACES,
113
+ isValid: false,
114
+ }
115
+
116
+ return requestLimitValidationResponse
117
+ }
118
+
119
+ if (requestNumber * requestUnit > limitNumber * limitUnit) {
120
+ requestLimitValidationResponse.request = {
121
+ message: BUILD_INFRA_TEXT.VALIDATE_REQUEST_LIMIT.REQUEST_LESS_THAN_LIMIT,
122
+ isValid: false,
123
+ }
124
+ }
125
+
126
+ return requestLimitValidationResponse
127
+ }
128
+
129
+ const getInitialProfileInputErrors = (fromCreateView: boolean): ProfileInputErrorType => {
130
+ if (fromCreateView) {
131
+ const initialProfileInputErrors = { ...PROFILE_INPUT_ERROR_FIELDS }
132
+ REQUIRED_INPUT_FIELDS.forEach((field) => {
133
+ initialProfileInputErrors[field] = ''
134
+ })
135
+ return initialProfileInputErrors
136
+ }
137
+
138
+ return {
139
+ ...PROFILE_INPUT_ERROR_FIELDS,
140
+ }
141
+ }
142
+
143
+ export const useBuildInfraForm = ({
144
+ name,
145
+ editProfile,
146
+ handleSuccessRedirection,
147
+ }: UseBuildInfraFormProps): UseBuildInfraFormResponseType => {
148
+ const fromCreateView = !name
149
+
150
+ const [isLoading, profileResponse, responseError, reloadRequest] = useAsync(
151
+ () =>
152
+ getBuildInfraProfileByName({
153
+ name: name ?? DEFAULT_PROFILE_NAME,
154
+ fromCreateView,
155
+ }),
156
+ [name],
157
+ )
158
+ // If configuration is existing and is active then use it else use default from profileResponse
159
+ const [profileInput, setProfileInput] = useState<BuildInfraProfileData>(null)
160
+ const [profileInputErrors, setProfileInputErrors] = useState<ProfileInputErrorType>({
161
+ ...PROFILE_INPUT_ERROR_FIELDS,
162
+ })
163
+ const [loadingActionRequest, setLoadingActionRequest] = useState<boolean>(false)
164
+
165
+ useEffect(() => {
166
+ if (!isLoading && profileResponse?.configurationUnits && profileResponse?.profile) {
167
+ setProfileInput({
168
+ ...profileResponse.profile,
169
+ })
170
+
171
+ setProfileInputErrors(getInitialProfileInputErrors(fromCreateView))
172
+ }
173
+ }, [profileResponse, isLoading])
174
+
175
+ const handleProfileInputChange = ({ action, data }: HandleProfileInputChangeType) => {
176
+ const currentInput = { ...profileInput }
177
+ const currentInputErrors = { ...profileInputErrors }
178
+ const lastSavedConfiguration = profileResponse.profile.configurations
179
+ const currentConfiguration = currentInput.configurations
180
+ const { value, unit } = data ?? { value: null, unit: null }
181
+
182
+ switch (action) {
183
+ case BuildInfraMetaConfigTypes.DESCRIPTION:
184
+ currentInput.description = value
185
+ currentInputErrors.description = validateDescription(value).message
186
+ break
187
+
188
+ case BuildInfraMetaConfigTypes.NAME:
189
+ currentInput.name = value
190
+ currentInputErrors.name = validateName(value).message
191
+ break
192
+
193
+ case BuildInfraConfigTypes.CPU_LIMIT: {
194
+ currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT] = {
195
+ ...currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT],
196
+ value,
197
+ unit,
198
+ }
199
+ const { request, limit } = validateRequestLimit({
200
+ request: {
201
+ value: currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST].value,
202
+ unit: currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST].unit,
203
+ },
204
+ limit: {
205
+ value,
206
+ unit,
207
+ },
208
+ unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.CPU_LIMIT],
209
+ })
210
+ currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = limit.message
211
+ currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = request.message
212
+ break
213
+ }
214
+ case BuildInfraConfigTypes.CPU_REQUEST: {
215
+ currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST] = {
216
+ ...currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST],
217
+ value,
218
+ unit,
219
+ }
220
+ const { request, limit } = validateRequestLimit({
221
+ request: {
222
+ value,
223
+ unit,
224
+ },
225
+ limit: {
226
+ value: currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT].value,
227
+ unit: currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT].unit,
228
+ },
229
+ unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.CPU_LIMIT],
230
+ })
231
+ currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = limit.message
232
+ currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = request.message
233
+ break
234
+ }
235
+
236
+ case BuildInfraConfigTypes.MEMORY_LIMIT: {
237
+ currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT] = {
238
+ ...currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT],
239
+ value,
240
+ unit,
241
+ }
242
+ const { request, limit } = validateRequestLimit({
243
+ request: {
244
+ value: currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].value,
245
+ unit: currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].unit,
246
+ },
247
+ limit: {
248
+ value,
249
+ unit,
250
+ },
251
+ unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.MEMORY_LIMIT],
252
+ })
253
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = limit.message
254
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = request.message
255
+ break
256
+ }
257
+
258
+ case BuildInfraConfigTypes.MEMORY_REQUEST: {
259
+ currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST] = {
260
+ ...currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST],
261
+ value,
262
+ unit,
263
+ }
264
+ const { request, limit } = validateRequestLimit({
265
+ request: {
266
+ value,
267
+ unit,
268
+ },
269
+ limit: {
270
+ value: currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].value,
271
+ unit: currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].unit,
272
+ },
273
+ unitsMap: profileResponse.configurationUnits[BuildInfraConfigTypes.MEMORY_LIMIT],
274
+ })
275
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = limit.message
276
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = request.message
277
+ break
278
+ }
279
+
280
+ case BuildInfraConfigTypes.BUILD_TIMEOUT: {
281
+ currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT] = {
282
+ ...currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT],
283
+ value,
284
+ unit,
285
+ }
286
+
287
+ currentInputErrors[BuildInfraConfigTypes.BUILD_TIMEOUT] = validateRequiredPositiveNumber(value).message
288
+ break
289
+ }
290
+
291
+ case BuildInfraInheritActions.ACTIVATE_CPU:
292
+ currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT] = {
293
+ ...lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT],
294
+ value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].value,
295
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].unit,
296
+ active: true,
297
+ }
298
+ currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST] = {
299
+ ...lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST],
300
+ value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].value,
301
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].unit,
302
+ active: true,
303
+ }
304
+
305
+ currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = null
306
+ currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = null
307
+ break
308
+
309
+ case BuildInfraInheritActions.ACTIVATE_MEMORY:
310
+ currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT] = {
311
+ ...lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT],
312
+ value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].value,
313
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].unit,
314
+ active: true,
315
+ }
316
+ currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST] = {
317
+ ...lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST],
318
+ value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].value,
319
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].unit,
320
+ active: true,
321
+ }
322
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = null
323
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = null
324
+ break
325
+
326
+ case BuildInfraInheritActions.ACTIVATE_BUILD_TIMEOUT:
327
+ currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT] = {
328
+ ...lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT],
329
+ value: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].value,
330
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].unit,
331
+ active: true,
332
+ }
333
+ currentInputErrors[BuildInfraConfigTypes.BUILD_TIMEOUT] = null
334
+ break
335
+
336
+ case BuildInfraInheritActions.DE_ACTIVATE_BUILD_TIMEOUT:
337
+ // Reverting the value and unit to defaultValues
338
+ currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT] = {
339
+ ...currentConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT],
340
+ value: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].defaultValue.value,
341
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.BUILD_TIMEOUT].defaultValue.unit,
342
+ active: false,
343
+ }
344
+ currentInputErrors[BuildInfraConfigTypes.BUILD_TIMEOUT] = null
345
+ break
346
+
347
+ case BuildInfraInheritActions.DE_ACTIVATE_CPU:
348
+ currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT] = {
349
+ ...currentConfiguration[BuildInfraConfigTypes.CPU_LIMIT],
350
+ value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].defaultValue.value,
351
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_LIMIT].defaultValue.unit,
352
+ active: false,
353
+ }
354
+ currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST] = {
355
+ ...currentConfiguration[BuildInfraConfigTypes.CPU_REQUEST],
356
+ value: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].defaultValue.value,
357
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.CPU_REQUEST].defaultValue.unit,
358
+ active: false,
359
+ }
360
+ currentInputErrors[BuildInfraConfigTypes.CPU_LIMIT] = null
361
+ currentInputErrors[BuildInfraConfigTypes.CPU_REQUEST] = null
362
+ break
363
+
364
+ case BuildInfraInheritActions.DE_ACTIVATE_MEMORY:
365
+ currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT] = {
366
+ ...currentConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT],
367
+ value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].defaultValue.value,
368
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_LIMIT].defaultValue.unit,
369
+ active: false,
370
+ }
371
+ currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST] = {
372
+ ...currentConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST],
373
+ value: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].defaultValue.value,
374
+ unit: lastSavedConfiguration[BuildInfraConfigTypes.MEMORY_REQUEST].defaultValue.unit,
375
+ active: false,
376
+ }
377
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_LIMIT] = null
378
+ currentInputErrors[BuildInfraConfigTypes.MEMORY_REQUEST] = null
379
+ break
380
+
381
+ default:
382
+ throw new Error(BUILD_INFRA_TEXT.getInvalidActionMessage(action))
383
+ }
384
+
385
+ setProfileInput(currentInput)
386
+ setProfileInputErrors(currentInputErrors)
387
+ }
388
+
389
+ const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
390
+ e.preventDefault()
391
+ setLoadingActionRequest(true)
392
+ try {
393
+ if (editProfile) {
394
+ await updateBuildInfraProfile({ name, profileInput })
395
+ } else {
396
+ await createBuildInfraProfile({ profileInput })
397
+ }
398
+ setLoadingActionRequest(false)
399
+ toast.success(BUILD_INFRA_TEXT.getSubmitSuccessMessage(profileInput.name, editProfile))
400
+
401
+ if (handleSuccessRedirection) {
402
+ handleSuccessRedirection()
403
+ } else {
404
+ reloadRequest()
405
+ }
406
+ } catch (err) {
407
+ showError(err)
408
+ setLoadingActionRequest(false)
409
+ }
410
+ }
411
+
412
+ return {
413
+ isLoading,
414
+ profileResponse,
415
+ responseError,
416
+ reloadRequest,
417
+ profileInput,
418
+ profileInputErrors,
419
+ handleProfileInputChange,
420
+ loadingActionRequest,
421
+ handleSubmit,
422
+ }
423
+ }
424
+
425
+ const getOptionBackgroundColor = (isFocused: boolean, isSelected: boolean): string => {
426
+ if (isSelected) {
427
+ return 'var(--B100)'
428
+ }
429
+
430
+ if (isFocused) {
431
+ return 'var(--N50)'
432
+ }
433
+ return 'var(--white)'
434
+ }
435
+
436
+ export const unitSelectorStyles = () =>
437
+ getCommonSelectStyle({
438
+ control: (base, state) => ({
439
+ ...base,
440
+ borderRadius: 0,
441
+ backgroundColor: 'var(--N0)',
442
+ border: state.isFocused ? '1px solid var(--B500)' : '1px solid var(--N200)',
443
+ alignItems: 'center',
444
+ cursor: 'pointer',
445
+ borderTopRightRadius: '4px',
446
+ borderBottomRightRadius: '4px',
447
+ overflow: 'hidden',
448
+ textOverflow: 'ellipsis',
449
+ whiteSpace: 'nowrap',
450
+ outline: 'none',
451
+ boxShadow: 'none',
452
+ '&:hover': {
453
+ border: '1px solid var(--N400)',
454
+ },
455
+ }),
456
+ indicatorContainer: (base) => ({
457
+ ...base,
458
+ padding: '0px',
459
+ }),
460
+ dropdownIndicator: (base, state) => ({
461
+ ...base,
462
+ color: 'var(--N600)',
463
+ transition: 'all .2s ease',
464
+ transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : 'rotate(0deg)',
465
+ }),
466
+ option: (base, state) => ({
467
+ ...base,
468
+ padding: '4px 12px',
469
+ backgroundColor: getOptionBackgroundColor(state.isFocused, state.isSelected),
470
+ color: 'var(--N900)',
471
+ cursor: 'pointer',
472
+ overflow: 'hidden',
473
+ textOverflow: 'ellipsis',
474
+ whiteSpace: 'nowrap',
475
+ height: '36px',
476
+ }),
477
+ valueContainer: (base) => ({
478
+ ...base,
479
+ color: 'var(--N900)',
480
+ fontSize: '13px',
481
+ fontWeight: '400',
482
+ lineHeight: '20px',
483
+ }),
484
+ menuList: (base) => ({
485
+ ...base,
486
+ maxHeight: '164px',
487
+ height: '100%',
488
+ }),
489
+ })
@@ -0,0 +1 @@
1
+ export * from './BuildInfra'
@@ -0,0 +1 @@
1
+ export * from './GlobalConfigurations'
@@ -0,0 +1,39 @@
1
+ import { ErrorScreenNotAuthorized, GenericEmptyState, Progressing, Reload } from '../../../Common'
2
+ import { APIResponseHandlerProps } from './types'
3
+
4
+ const APIResponseHandler = ({
5
+ isLoading,
6
+ progressingProps,
7
+ error,
8
+ notAuthorized,
9
+ notFoundText,
10
+ reloadProps,
11
+ children,
12
+ }: APIResponseHandlerProps) => {
13
+ // keeping it above loading since, not expected to send a call if not authorized
14
+ if (notAuthorized) {
15
+ return <ErrorScreenNotAuthorized />
16
+ }
17
+
18
+ if (isLoading) {
19
+ return <Progressing {...progressingProps} />
20
+ }
21
+
22
+ if (error) {
23
+ if (error?.code === 404) {
24
+ return (
25
+ <GenericEmptyState
26
+ title={notFoundText?.title ?? 'Data not found'}
27
+ subTitle={notFoundText?.subTitle ?? 'The data you are looking for does not exist'}
28
+ />
29
+ )
30
+ }
31
+ return <Reload {...reloadProps} />
32
+ }
33
+
34
+ // Had to add this since while using it is throwing ts error
35
+ // eslint-disable-next-line react/jsx-no-useless-fragment
36
+ return <>{children}</>
37
+ }
38
+
39
+ export default APIResponseHandler
@@ -0,0 +1,2 @@
1
+ export { default as APIResponseHandler } from './APIResponseHandler'
2
+ export * from './types'
@@ -0,0 +1,39 @@
1
+ import { ReactNode } from 'react'
2
+ import { ProgressingProps, ReloadType, ServerErrors } from '../../../Common'
3
+
4
+ export interface EmptyPageTextType {
5
+ title?: string
6
+ subTitle?: string
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
+ }
@@ -0,0 +1 @@
1
+ export * from './utils'
@@ -0,0 +1,97 @@
1
+ import Tippy from '@tippyjs/react'
2
+ import { components } from 'react-select'
3
+ import { stopPropagation } from '../../../Common'
4
+
5
+ export const getCommonSelectStyle = (styleOverrides = {}) => ({
6
+ menuList: (base) => ({
7
+ ...base,
8
+ paddingTop: 0,
9
+ paddingBottom: 0,
10
+ }),
11
+ control: (base, state) => ({
12
+ ...base,
13
+ minHeight: '32px',
14
+ boxShadow: 'none',
15
+ backgroundColor: 'var(--N50)',
16
+ border: state.isFocused ? '1px solid var(--B500)' : '1px solid var(--N200)',
17
+ cursor: 'pointer',
18
+ }),
19
+ option: (base, state) => ({
20
+ ...base,
21
+ color: 'var(--N900)',
22
+ backgroundColor: state.isFocused ? 'var(--N100)' : 'white',
23
+ padding: '10px 12px',
24
+ }),
25
+ dropdownIndicator: (base, state) => ({
26
+ ...base,
27
+ color: 'var(--N400)',
28
+ padding: '0 8px',
29
+ transition: 'all .2s ease',
30
+ transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : 'rotate(0deg)',
31
+ }),
32
+ valueContainer: (base) => ({
33
+ ...base,
34
+ padding: '0 8px',
35
+ fontWeight: '400',
36
+ }),
37
+ loadingMessage: (base) => ({
38
+ ...base,
39
+ color: 'var(--N600)',
40
+ }),
41
+ noOptionsMessage: (base) => ({
42
+ ...base,
43
+ color: 'var(--N600)',
44
+ }),
45
+ ...styleOverrides,
46
+ })
47
+
48
+ const getCustomOptionBackgroundColor = (isSelected: boolean, isFocused: boolean) => {
49
+ if (isSelected) {
50
+ return 'var(--B100)'
51
+ }
52
+
53
+ if (isFocused) {
54
+ return 'var(--N50)'
55
+ }
56
+
57
+ return 'var(--white)'
58
+ }
59
+
60
+ export const getCustomOptionSelectionStyle =
61
+ (styleOverrides = {}) =>
62
+ (base, state) => ({
63
+ ...base,
64
+ backgroundColor: getCustomOptionBackgroundColor(state.isSelected, state.isFocused),
65
+ color: state.isSelected ? 'var(--B500)' : 'var(--N900)',
66
+ textOverflow: 'ellipsis',
67
+ fontWeight: '500',
68
+ overflow: 'hidden',
69
+ textAlign: 'left',
70
+ whiteSpace: 'nowrap',
71
+ cursor: 'pointer',
72
+ fontSize: '13px',
73
+ ...styleOverrides,
74
+ })
75
+
76
+ export const SelectOption = (props: any) => {
77
+ const { selectProps, data, showTippy, style, placement, tippyContent, tippyClass } = props
78
+ selectProps.styles.option = getCustomOptionSelectionStyle(style)
79
+ const getOption = () => (
80
+ <div onClick={stopPropagation}>
81
+ <components.Option {...props} />
82
+ </div>
83
+ )
84
+
85
+ return showTippy ? (
86
+ <Tippy
87
+ className={tippyClass || 'default-white'}
88
+ arrow={false}
89
+ placement={placement || 'right'}
90
+ content={tippyContent || data.label}
91
+ >
92
+ {getOption()}
93
+ </Tippy>
94
+ ) : (
95
+ getOption()
96
+ )
97
+ }
@@ -0,0 +1,2 @@
1
+ export * from './APIResponseHandler'
2
+ export * from './ReactSelect'
@@ -0,0 +1,2 @@
1
+ export * from './Components'
2
+ export * from './validations'