@devtron-labs/devtron-fe-common-lib 0.0.58-beta-3 → 0.0.58-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 +9 -0
- package/dist/Common/CustomInput/CustomInput.d.ts +1 -1
- package/dist/Common/CustomInput/Types.d.ts +1 -0
- package/dist/Common/EmptyState/GenericEmptyState.d.ts +1 -1
- package/dist/Common/Helper.d.ts +1 -4
- package/dist/Common/Types.d.ts +4 -2
- 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 +48 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/index.d.ts +7 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/services.d.ts +13 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/types.d.ts +281 -0
- package/dist/Pages/GlobalConfigurations/BuildInfra/utils.d.ts +12 -0
- package/dist/Pages/GlobalConfigurations/index.d.ts +1 -0
- package/dist/Pages/index.d.ts +1 -0
- package/dist/Shared/Components/APIResponseHandler/APIResponseHandler.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/index.d.ts +2 -0
- package/dist/Shared/validations.d.ts +7 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1161 -193
- 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 +11 -1
- package/src/Common/CustomInput/CustomInput.tsx +6 -5
- package/src/Common/CustomInput/Types.ts +1 -0
- package/src/Common/DraggableWrapper/DraggableWrapper.tsx +3 -1
- package/src/Common/EmptyState/GenericEmptyState.tsx +45 -13
- package/src/Common/Helper.tsx +16 -30
- package/src/Common/RJSF/utils.ts +3 -0
- package/src/Common/SearchBar/SearchBar.component.tsx +26 -13
- package/src/Common/SearchBar/searchBar.scss +1 -1
- package/src/Common/Types.ts +3 -1
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraConfigForm.tsx +121 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraDescriptionField.tsx +44 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/BuildInfraFormAction.tsx +99 -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 +38 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/Footer.tsx +45 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/Readme.md +4 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/constants.tsx +137 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/index.ts +7 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/services.tsx +183 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/types.tsx +334 -0
- package/src/Pages/GlobalConfigurations/BuildInfra/utils.tsx +490 -0
- package/src/Pages/GlobalConfigurations/index.ts +1 -0
- package/src/Pages/index.ts +1 -0
- package/src/Shared/Components/APIResponseHandler/APIResponseHandler.tsx +39 -0
- package/src/Shared/Components/APIResponseHandler/index.ts +2 -0
- package/src/Shared/Components/APIResponseHandler/types.tsx +39 -0
- 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/index.ts +2 -0
- package/src/Shared/validations.tsx +72 -0
- package/src/index.ts +3 -1
package/package.json
CHANGED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
2
|
+
<path d="M12.5 5.625H7.5M12.5 8.125H7.5M15.625 3.125V16.875C15.625 17.2202 15.3452 17.5 15 17.5H5C4.65482 17.5 4.375 17.2202 4.375 16.875V3.125C4.375 2.77982 4.65482 2.5 5 2.5H15C15.3452 2.5 15.625 2.77982 15.625 3.125Z" stroke="#596168" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M10 15C10.5178 15 10.9375 14.5803 10.9375 14.0625C10.9375 13.5447 10.5178 13.125 10 13.125C9.48223 13.125 9.0625 13.5447 9.0625 14.0625C9.0625 14.5803 9.48223 15 10 15Z" fill="#596168"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
2
|
+
<path d="M16.25 8.125H18.125M16.25 11.875H18.125M1.875 8.125H3.75M1.875 11.875H3.75M11.875 16.25V18.125M8.125 16.25V18.125M11.875 1.875V3.75M8.125 1.875V3.75M7.8125 7.8125H12.1875V12.1875H7.8125V7.8125ZM4.375 3.75H15.625C15.9702 3.75 16.25 4.02982 16.25 4.375V15.625C16.25 15.9702 15.9702 16.25 15.625 16.25H4.375C4.02982 16.25 3.75 15.9702 3.75 15.625V4.375C3.75 4.02982 4.02982 3.75 4.375 3.75Z" stroke="#596168" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
2
|
+
<path d="M10 11.0415L13.0936 7.94791M8.125 1.6665H11.875M16.875 11.0415C16.875 14.8385 13.797 17.9165 10 17.9165C6.20304 17.9165 3.125 14.8385 3.125 11.0415C3.125 7.24455 6.20304 4.1665 10 4.1665C13.797 4.1665 16.875 7.24455 16.875 11.0415Z" stroke="#596168" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
package/src/Common/Checkbox.tsx
CHANGED
|
@@ -10,6 +10,7 @@ Valid States of Checkbox:
|
|
|
10
10
|
5. disabled: false, checked: true, value: INTERMIDIATE
|
|
11
11
|
6. disabled: false, checked: true, value: CHECKED
|
|
12
12
|
*/
|
|
13
|
+
// TODO: Associate label with input element
|
|
13
14
|
export class Checkbox extends Component<CheckboxProps> {
|
|
14
15
|
render() {
|
|
15
16
|
let rootClassName = `${this.props.rootClassName ? this.props.rootClassName : ''}`
|
package/src/Common/Constants.ts
CHANGED
|
@@ -25,7 +25,8 @@ export const ROUTES = {
|
|
|
25
25
|
USER_CHECK_ROLE: 'user/check/roles',
|
|
26
26
|
IMAGE_TAGGING:'app/image-tagging',
|
|
27
27
|
CD_MATERIAL_GET: 'app/cd-pipeline',
|
|
28
|
-
DEPLOYMENT_TEMPLATE_LIST: 'app/template/list'
|
|
28
|
+
DEPLOYMENT_TEMPLATE_LIST: 'app/template/list',
|
|
29
|
+
INFRA_CONFIG_PROFILE: 'infra-config/profile',
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export enum KEY_VALUE {
|
|
@@ -242,4 +243,13 @@ export const RepositoryAction = {
|
|
|
242
243
|
CHART_PUSH: "CHART_PUSH"
|
|
243
244
|
}
|
|
244
245
|
|
|
246
|
+
export enum APPROVAL_MODAL_TYPE {
|
|
247
|
+
CONFIG = 'CONFIG',
|
|
248
|
+
DEPLOYMENT = 'DEPLOYMENT',
|
|
249
|
+
}
|
|
245
250
|
export const MAX_Z_INDEX = 2147483647
|
|
251
|
+
|
|
252
|
+
export const SELECTED_APPROVAL_TAB_STATE = {
|
|
253
|
+
APPROVAL: 'approval',
|
|
254
|
+
PENDING: 'pending',
|
|
255
|
+
}
|
|
@@ -2,6 +2,7 @@ import { CustomInputProps } from './Types'
|
|
|
2
2
|
import { ReactComponent as Info } from '../../Assets/Icon/ic-info-filled.svg'
|
|
3
3
|
import { ReactComponent as ErrorIcon } from '../../Assets/Icon/ic-warning.svg'
|
|
4
4
|
|
|
5
|
+
// TODO: label association with input
|
|
5
6
|
export function CustomInput({
|
|
6
7
|
name,
|
|
7
8
|
value,
|
|
@@ -13,7 +14,7 @@ export function CustomInput({
|
|
|
13
14
|
disabled = false,
|
|
14
15
|
labelClassName = '',
|
|
15
16
|
placeholder = '',
|
|
16
|
-
tabIndex =
|
|
17
|
+
tabIndex = 0,
|
|
17
18
|
dataTestid = '',
|
|
18
19
|
isRequiredField = false,
|
|
19
20
|
autoFocus = false,
|
|
@@ -28,9 +29,9 @@ export function CustomInput({
|
|
|
28
29
|
defaultValue,
|
|
29
30
|
onKeyDown,
|
|
30
31
|
required,
|
|
31
|
-
additionalErrorInfo
|
|
32
|
+
additionalErrorInfo,
|
|
33
|
+
inputWrapClassName = '',
|
|
32
34
|
}: CustomInputProps) {
|
|
33
|
-
|
|
34
35
|
function handleError(error: any): any[] {
|
|
35
36
|
if (!Array.isArray(error)) {
|
|
36
37
|
return [error]
|
|
@@ -55,7 +56,7 @@ export function CustomInput({
|
|
|
55
56
|
<div className="form__error" key={error}>
|
|
56
57
|
<ErrorIcon className="form__icon form__icon--error" />
|
|
57
58
|
{error}
|
|
58
|
-
{typeof additionalErrorInfo === 'function' && additionalErrorInfo()}
|
|
59
|
+
{error && typeof additionalErrorInfo === 'function' && additionalErrorInfo()}
|
|
59
60
|
</div>
|
|
60
61
|
)
|
|
61
62
|
}
|
|
@@ -92,7 +93,7 @@ export function CustomInput({
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
return (
|
|
95
|
-
<div className=
|
|
96
|
+
<div className={`flex column left top ${inputWrapClassName}`}>
|
|
96
97
|
{renderInputLabel()}
|
|
97
98
|
<input
|
|
98
99
|
data-testid={dataTestid}
|
|
@@ -94,8 +94,9 @@ export default function DraggableWrapper({
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
return (
|
|
97
|
+
// Since we are using position fixed so we need to disable click on the div so that it does not interfere with the click of other elements
|
|
97
98
|
<div
|
|
98
|
-
className="dc__position-fixed"
|
|
99
|
+
className="dc__position-fixed dc__disable-click"
|
|
99
100
|
style={{
|
|
100
101
|
zIndex,
|
|
101
102
|
}}
|
|
@@ -106,6 +107,7 @@ export default function DraggableWrapper({
|
|
|
106
107
|
{...childDivProps}
|
|
107
108
|
style={{
|
|
108
109
|
zIndex,
|
|
110
|
+
pointerEvents: 'auto',
|
|
109
111
|
}}
|
|
110
112
|
>
|
|
111
113
|
{children}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React from 'react'
|
|
2
2
|
import AppNotDeployed from '../../Assets/Img/app-not-deployed.png'
|
|
3
3
|
import { GenericEmptyStateType, ImageType } from '../Types'
|
|
4
4
|
|
|
@@ -19,24 +19,56 @@ function GenericEmptyState({
|
|
|
19
19
|
SvgImage,
|
|
20
20
|
noImage,
|
|
21
21
|
layout = 'column',
|
|
22
|
-
contentClassName = ''
|
|
22
|
+
contentClassName = '',
|
|
23
|
+
imageStyles = {},
|
|
23
24
|
}: GenericEmptyStateType): JSX.Element {
|
|
24
|
-
const isRowLayout = layout === 'row'
|
|
25
|
-
|
|
25
|
+
const isRowLayout = layout === 'row'
|
|
26
|
+
|
|
27
|
+
const getImageSize = () => {
|
|
28
|
+
switch (imageType) {
|
|
29
|
+
case ImageType.Large:
|
|
30
|
+
return { width: '250px', height: '200px' }
|
|
31
|
+
default:
|
|
32
|
+
return { width: '200px', height: '160px' }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
return (
|
|
27
37
|
<div
|
|
28
|
-
className={`flex ${isRowLayout ? 'dc__gap-32' : 'column dc__gap-20'} empty-state ${
|
|
38
|
+
className={`flex ${isRowLayout ? 'dc__gap-32' : 'column dc__gap-20'} empty-state ${
|
|
39
|
+
classname ? classname : ''
|
|
40
|
+
}`}
|
|
29
41
|
style={styles}
|
|
30
42
|
data-testid="generic-empty-state"
|
|
31
43
|
{...(heightToDeduct >= 0 && { style: { ...styles, height: `calc(100vh - ${heightToDeduct}px)` } })}
|
|
32
|
-
>
|
|
33
|
-
{!SvgImage ?
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
>
|
|
45
|
+
{!SvgImage ? (
|
|
46
|
+
!noImage && (
|
|
47
|
+
<img
|
|
48
|
+
className={imageClassName ? imageClassName : ''}
|
|
49
|
+
src={image || AppNotDeployed}
|
|
50
|
+
style={{
|
|
51
|
+
...imageStyles,
|
|
52
|
+
width: `${getImageSize().width}`,
|
|
53
|
+
height: `${getImageSize().height}`,
|
|
54
|
+
}}
|
|
55
|
+
alt="empty-state"
|
|
56
|
+
/>
|
|
57
|
+
)
|
|
58
|
+
) : (
|
|
59
|
+
<SvgImage
|
|
60
|
+
style={{
|
|
61
|
+
...imageStyles,
|
|
62
|
+
width: `${getImageSize().width}`,
|
|
63
|
+
height: `${getImageSize().height}`,
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
)}
|
|
67
|
+
<div
|
|
68
|
+
className={`flex column dc__gap-10 dc__mxw-300 ${
|
|
69
|
+
isRowLayout ? 'dc__align-start' : ''
|
|
70
|
+
} ${contentClassName}`}
|
|
71
|
+
>
|
|
40
72
|
<h4 className="title fw-6 cn-9 mt-0 mb-0">{title}</h4>
|
|
41
73
|
{subTitle && <p className={`subtitle ${isRowLayout ? 'subtitle--text-start' : ''}`}>{subTitle}</p>}
|
|
42
74
|
{isButtonAvailable && renderButton()}
|
package/src/Common/Helper.tsx
CHANGED
|
@@ -499,27 +499,18 @@ export const getFilteredChartVersions = (charts, selectedChartType) => {
|
|
|
499
499
|
chartRefId: item.chartRefId,
|
|
500
500
|
}))
|
|
501
501
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
// It recursively removes empty object keys and empty array keys
|
|
502
|
+
function removeEmptyObjectKeysAndNullValues(obj) {
|
|
503
|
+
// It recursively removes empty object keys and array values that are null
|
|
505
504
|
for (let key in obj) {
|
|
506
505
|
if (Array.isArray(obj[key])) {
|
|
506
|
+
if (obj[key].length === 0) continue
|
|
507
|
+
obj[key] = obj[key].filter((item) => item !== null)
|
|
507
508
|
// Check if the array is empty
|
|
508
|
-
if (obj[key].length
|
|
509
|
-
obj[key]
|
|
510
|
-
if (element === null || (typeof element === 'object' && Object.keys(element).length === 0))
|
|
511
|
-
obj[key].splice(index, 1)
|
|
512
|
-
else removeEmptyObjectKeysAndNullValues(element, originaljsonCopy[key][index])
|
|
513
|
-
})
|
|
514
|
-
}
|
|
515
|
-
if (obj[key].length === 0 && originaljsonCopy[key].length !== 0) {
|
|
516
|
-
delete obj[key]
|
|
509
|
+
if (obj[key].length === 0) {
|
|
510
|
+
delete obj[key] // Delete the key if the array is empty
|
|
517
511
|
}
|
|
518
512
|
} else if (obj[key] && typeof obj[key] === 'object') {
|
|
519
|
-
if (
|
|
520
|
-
removeEmptyObjectKeysAndNullValues(obj[key], originaljsonCopy[key]) &&
|
|
521
|
-
Object.keys(originaljsonCopy[key]).length !== 0
|
|
522
|
-
) {
|
|
513
|
+
if (removeEmptyObjectKeysAndNullValues(obj[key])) {
|
|
523
514
|
delete obj[key]
|
|
524
515
|
}
|
|
525
516
|
} else if (obj[key] === undefined) {
|
|
@@ -529,25 +520,20 @@ function removeEmptyObjectKeysAndNullValues(obj, originaljsonCopy) {
|
|
|
529
520
|
return Object.keys(obj).length === 0
|
|
530
521
|
}
|
|
531
522
|
|
|
532
|
-
export function getUnlockedJSON(json, jsonPathArray
|
|
533
|
-
if (!jsonPathArray.length) return { newDocument: json, removedPatches: [] }
|
|
534
|
-
|
|
523
|
+
export function getUnlockedJSON(json, jsonPathArray) {
|
|
535
524
|
const jsonCopy = JSON.parse(JSON.stringify(json))
|
|
536
|
-
const originaljsonCopy = JSON.parse(JSON.stringify(json))
|
|
537
|
-
let removedPatches = []
|
|
538
525
|
let patches = jsonPathArray.flatMap((jsonPath) => {
|
|
539
526
|
const pathsToRemove = JSONPath({ path: jsonPath, json: jsonCopy, resultType: 'all' })
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
return { op: 'remove', path: result.pointer }
|
|
546
|
-
})
|
|
527
|
+
return pathsToRemove.map((result) =>
|
|
528
|
+
Array.isArray(result.parent)
|
|
529
|
+
? { op: 'replace', path: result.pointer, value: null }
|
|
530
|
+
: { op: 'remove', path: result.pointer },
|
|
531
|
+
)
|
|
547
532
|
})
|
|
548
533
|
let newDocument = jsonpatch.applyPatch(jsonCopy, patches).newDocument
|
|
549
|
-
|
|
550
|
-
|
|
534
|
+
|
|
535
|
+
removeEmptyObjectKeysAndNullValues(newDocument)
|
|
536
|
+
return newDocument
|
|
551
537
|
}
|
|
552
538
|
|
|
553
539
|
export function getLockedJSON(json, jsonPathArray: string[]) {
|
package/src/Common/RJSF/utils.ts
CHANGED
|
@@ -13,12 +13,14 @@ export const translateString = (stringToTranslate: TranslatableString, params?:
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
// NOTE: If you are changing this please make sure BuildInfra selects are also working fine
|
|
16
17
|
export const getCommonSelectStyle = (styleOverrides = {}) => {
|
|
17
18
|
return {
|
|
18
19
|
menuList: (base) => ({
|
|
19
20
|
...base,
|
|
20
21
|
paddingTop: 0,
|
|
21
22
|
paddingBottom: 0,
|
|
23
|
+
cursor: 'pointer',
|
|
22
24
|
}),
|
|
23
25
|
control: (base, state) => ({
|
|
24
26
|
...base,
|
|
@@ -33,6 +35,7 @@ export const getCommonSelectStyle = (styleOverrides = {}) => {
|
|
|
33
35
|
color: 'var(--N900)',
|
|
34
36
|
backgroundColor: state.isFocused ? 'var(--N100)' : 'white',
|
|
35
37
|
padding: '10px 12px',
|
|
38
|
+
cursor: 'pointer',
|
|
36
39
|
}),
|
|
37
40
|
dropdownIndicator: (base, state) => ({
|
|
38
41
|
...base,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeEvent, useCallback, useRef, useState, KeyboardEvent } from 'react'
|
|
1
|
+
import { ChangeEvent, useCallback, useRef, useState, KeyboardEvent, useEffect } from 'react'
|
|
2
2
|
import { ReactComponent as Search } from '../../Assets/Icon/ic-search.svg'
|
|
3
3
|
import { ReactComponent as Clear } from '../../Assets/Icon/ic-error-cross.svg'
|
|
4
4
|
import { SearchBarProps } from './types'
|
|
@@ -55,9 +55,31 @@ const SearchBar = ({
|
|
|
55
55
|
debounceTimeout,
|
|
56
56
|
])
|
|
57
57
|
|
|
58
|
+
// In most case would reset the state by doing history.push('/')
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
inputRef.current.value = initialSearchText
|
|
61
|
+
}, [initialSearchText])
|
|
62
|
+
|
|
63
|
+
const _applySearch = (value: string) => {
|
|
64
|
+
handleSearchChange(value)
|
|
65
|
+
handleEnter(value)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const clearSearch = () => {
|
|
69
|
+
inputRef.current.value = ''
|
|
70
|
+
_applySearch('')
|
|
71
|
+
setShowClearButton(false)
|
|
72
|
+
}
|
|
73
|
+
|
|
58
74
|
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
59
75
|
const { value } = e.target
|
|
60
76
|
setShowClearButton(!!value)
|
|
77
|
+
|
|
78
|
+
if (!value) {
|
|
79
|
+
clearSearch()
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
61
83
|
if (shouldDebounce) {
|
|
62
84
|
debouncedSearchChange(value)
|
|
63
85
|
} else {
|
|
@@ -65,11 +87,6 @@ const SearchBar = ({
|
|
|
65
87
|
}
|
|
66
88
|
}
|
|
67
89
|
|
|
68
|
-
const _applySearch = (value: string) => {
|
|
69
|
-
handleSearchChange(value)
|
|
70
|
-
handleEnter(value)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
90
|
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
74
91
|
const { key } = e
|
|
75
92
|
|
|
@@ -80,14 +97,9 @@ const SearchBar = ({
|
|
|
80
97
|
}
|
|
81
98
|
}
|
|
82
99
|
|
|
83
|
-
const clearSearch = () => {
|
|
84
|
-
inputRef.current.value = ''
|
|
85
|
-
_applySearch('')
|
|
86
|
-
}
|
|
87
|
-
|
|
88
100
|
return (
|
|
89
101
|
<div className={containerClassName}>
|
|
90
|
-
<div className="search-bar
|
|
102
|
+
<div className="search-bar bc-n50 focus-within-border-b5 dc__hover-border-n300 dc__block w-100 min-w-200 dc__position-rel en-2 bw-1 br-4 h-32">
|
|
91
103
|
<Search className="search-bar__icon dc__position-abs icon-color-n6 icon-dim-18" />
|
|
92
104
|
<input
|
|
93
105
|
placeholder="Search"
|
|
@@ -95,13 +107,14 @@ const SearchBar = ({
|
|
|
95
107
|
type="text"
|
|
96
108
|
{...inputProps}
|
|
97
109
|
defaultValue={initialSearchText}
|
|
98
|
-
className={`search-bar__input
|
|
110
|
+
className={`search-bar__input bc-n50 dc__position-abs w-100 h-100 br-4 dc__no-border pt-6 pr-10 pb-6 pl-30 fs-13 lh-20 fw-4 cn-9 placeholder-cn5 ${
|
|
99
111
|
showClearButton ? 'pr-30' : 'pr-10'
|
|
100
112
|
}`}
|
|
101
113
|
onChange={handleChange}
|
|
102
114
|
onKeyDown={handleKeyDown}
|
|
103
115
|
ref={inputRef}
|
|
104
116
|
/>
|
|
117
|
+
{/* TODO: Sync with product since it should have ic-enter in case of not applied */}
|
|
105
118
|
{showClearButton && (
|
|
106
119
|
<button
|
|
107
120
|
className="flex search-bar__clear-button dc__position-abs dc__transparent mt-0 mb-0 mr-5 ml-5"
|
package/src/Common/Types.ts
CHANGED
|
@@ -51,11 +51,12 @@ export interface Teams {
|
|
|
51
51
|
export enum CHECKBOX_VALUE {
|
|
52
52
|
CHECKED = 'CHECKED',
|
|
53
53
|
INTERMEDIATE = 'INTERMEDIATE',
|
|
54
|
+
BULK_CHECKED = 'BULK_CHECKED',
|
|
54
55
|
}
|
|
55
56
|
export interface CheckboxProps {
|
|
56
57
|
onChange: (event) => void
|
|
57
58
|
isChecked: boolean
|
|
58
|
-
value: 'CHECKED' | 'INTERMEDIATE'
|
|
59
|
+
value: 'CHECKED' | 'INTERMEDIATE' | 'BULK_CHECKED'
|
|
59
60
|
disabled?: boolean
|
|
60
61
|
tabIndex?: number
|
|
61
62
|
rootClassName?: string
|
|
@@ -107,6 +108,7 @@ export interface GenericEmptyStateType {
|
|
|
107
108
|
imageClassName?: string
|
|
108
109
|
children?: ReactNode
|
|
109
110
|
noImage?: boolean
|
|
111
|
+
imageStyles?: CSSProperties
|
|
110
112
|
/**
|
|
111
113
|
* @default 'column'
|
|
112
114
|
*/
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { FunctionComponent } from 'react'
|
|
2
|
+
import { Progressing } from '../../../Common'
|
|
3
|
+
import BuildInfraFormAction from './BuildInfraFormAction'
|
|
4
|
+
import BuildInfraFormItem from './BuildInfraFormItem'
|
|
5
|
+
import BuildInfraProfileDescriptionField from './BuildInfraDescriptionField'
|
|
6
|
+
import BuildInfraProfileNameField from './BuildInfraProfileNameField'
|
|
7
|
+
import { BUILD_INFRA_FORM_FIELDS, BUILD_INFRA_TEXT } from './constants'
|
|
8
|
+
import { BuildInfraActionType, BuildInfraConfigFormProps, InheritingHeaderProps } from './types'
|
|
9
|
+
|
|
10
|
+
const InheritingHeader = ({
|
|
11
|
+
defaultHeading,
|
|
12
|
+
inheritingData,
|
|
13
|
+
isInheriting,
|
|
14
|
+
isDefaultProfile,
|
|
15
|
+
}: InheritingHeaderProps) => {
|
|
16
|
+
const inheritingDataString = inheritingData.map((data) => `${data.value} ${data.unit ?? ''}`).join(' - ')
|
|
17
|
+
|
|
18
|
+
if (isDefaultProfile || !isInheriting) {
|
|
19
|
+
// For typing issues
|
|
20
|
+
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
21
|
+
return <>{defaultHeading}</>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className="flexbox dc__align-items-center dc__content-space w-100">
|
|
26
|
+
{defaultHeading}
|
|
27
|
+
|
|
28
|
+
<p className="m-0 flexbox pt-0 pb-0 pl-4 pr-4 fs-13 lh-20 fw-4 cn-9">{inheritingDataString}</p>
|
|
29
|
+
|
|
30
|
+
<p className="m-0 cn-7 fs-13 fw-4 lh-20">{BUILD_INFRA_TEXT.INHERITING_HEADING_DESCRIPTION}</p>
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const BuildInfraConfigForm: FunctionComponent<BuildInfraConfigFormProps> = ({
|
|
36
|
+
profileInput,
|
|
37
|
+
profileInputErrors,
|
|
38
|
+
handleProfileInputChange,
|
|
39
|
+
isDefaultProfile,
|
|
40
|
+
unitsMap,
|
|
41
|
+
configurationContainerLabel,
|
|
42
|
+
}) => {
|
|
43
|
+
const currentConfigurations = profileInput?.configurations
|
|
44
|
+
|
|
45
|
+
// will get the desired configuration from the currentConfigurations and then check if it is active or not
|
|
46
|
+
const isInheritingProfileValues = (actions: BuildInfraActionType[]) =>
|
|
47
|
+
actions.some((action) => !currentConfigurations[action.actionType].active)
|
|
48
|
+
|
|
49
|
+
// Had to show loader for an instance due to batching of state updates not working as expected :/
|
|
50
|
+
if (!currentConfigurations) {
|
|
51
|
+
return <Progressing pageLoader />
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="flexbox-col dc__mxw-920 dc__gap-16">
|
|
56
|
+
{!isDefaultProfile && (
|
|
57
|
+
<div className="flexbox-col dc__gap-12">
|
|
58
|
+
<BuildInfraProfileNameField
|
|
59
|
+
handleProfileInputChange={handleProfileInputChange}
|
|
60
|
+
currentValue={profileInput.name}
|
|
61
|
+
error={profileInputErrors.name}
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
<BuildInfraProfileDescriptionField
|
|
65
|
+
handleProfileInputChange={handleProfileInputChange}
|
|
66
|
+
currentValue={profileInput.description}
|
|
67
|
+
error={profileInputErrors.description}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
|
|
72
|
+
<div className="flexbox-col dc__gap-12">
|
|
73
|
+
{configurationContainerLabel}
|
|
74
|
+
|
|
75
|
+
<div className="w-100 flexbox-col dc__gap-16 br-4 dc__border-n1 p-16">
|
|
76
|
+
{BUILD_INFRA_FORM_FIELDS.map((field, index) => (
|
|
77
|
+
<BuildInfraFormItem
|
|
78
|
+
key={field.locator}
|
|
79
|
+
marker={field.marker}
|
|
80
|
+
heading={
|
|
81
|
+
<InheritingHeader
|
|
82
|
+
defaultHeading={field.heading}
|
|
83
|
+
inheritingData={field.actions.map(
|
|
84
|
+
(action) => currentConfigurations[action.actionType],
|
|
85
|
+
)}
|
|
86
|
+
isInheriting={isInheritingProfileValues(field.actions)}
|
|
87
|
+
isDefaultProfile={isDefaultProfile}
|
|
88
|
+
/>
|
|
89
|
+
}
|
|
90
|
+
showDivider={index !== BUILD_INFRA_FORM_FIELDS.length - 1}
|
|
91
|
+
isInheriting={isInheritingProfileValues(field.actions)}
|
|
92
|
+
handleProfileInputChange={handleProfileInputChange}
|
|
93
|
+
locator={field.locator}
|
|
94
|
+
isDefaultProfile={isDefaultProfile}
|
|
95
|
+
>
|
|
96
|
+
<div className="w-50 flexbox dc__gap-12 w-100 dc__align-start">
|
|
97
|
+
{field.actions.map((action) => (
|
|
98
|
+
<BuildInfraFormAction
|
|
99
|
+
key={action.actionType}
|
|
100
|
+
actionType={action.actionType}
|
|
101
|
+
label={action.label}
|
|
102
|
+
placeholder={action.placeholder}
|
|
103
|
+
error={profileInputErrors[action.actionType]}
|
|
104
|
+
// Assumption is for default profiles all input fields are required
|
|
105
|
+
isRequired={isDefaultProfile}
|
|
106
|
+
profileUnitsMap={unitsMap[action.actionType]}
|
|
107
|
+
handleProfileInputChange={handleProfileInputChange}
|
|
108
|
+
currentUnitName={currentConfigurations[action.actionType].unit}
|
|
109
|
+
currentValue={currentConfigurations[action.actionType].value}
|
|
110
|
+
/>
|
|
111
|
+
))}
|
|
112
|
+
</div>
|
|
113
|
+
</BuildInfraFormItem>
|
|
114
|
+
))}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export default BuildInfraConfigForm
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { FormEvent, FunctionComponent } from 'react'
|
|
2
|
+
import { ReactComponent as ErrorIcon } from '../../../Assets/Icon/ic-warning.svg'
|
|
3
|
+
import { BuildInfraInputFieldComponentProps, BuildInfraMetaConfigTypes } from './types'
|
|
4
|
+
import { BUILD_INFRA_TEXT } from './constants'
|
|
5
|
+
|
|
6
|
+
const BuildInfraProfileDescriptionField: FunctionComponent<BuildInfraInputFieldComponentProps> = ({
|
|
7
|
+
handleProfileInputChange,
|
|
8
|
+
currentValue,
|
|
9
|
+
error,
|
|
10
|
+
}) => {
|
|
11
|
+
const handleChange = (e: FormEvent<HTMLTextAreaElement>) => {
|
|
12
|
+
handleProfileInputChange({
|
|
13
|
+
action: BuildInfraMetaConfigTypes.DESCRIPTION,
|
|
14
|
+
data: { value: e.currentTarget.value },
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="flexbox-col dc__gap-4 w-100 dc__align-start">
|
|
20
|
+
<label htmlFor="build-infra-profile-description" className="m-0 fs-13 fw-4 lh-20 cn-7">
|
|
21
|
+
{BUILD_INFRA_TEXT.DESCRIPTION_LABEL}
|
|
22
|
+
</label>
|
|
23
|
+
|
|
24
|
+
<textarea
|
|
25
|
+
data-testid="build-infra-profile-description"
|
|
26
|
+
name="profile-description"
|
|
27
|
+
className="form__textarea mxh-140 dc__hover-border-n300"
|
|
28
|
+
id="build-infra-profile-description"
|
|
29
|
+
placeholder={BUILD_INFRA_TEXT.DESCRIPTION_PLACEHOLDER}
|
|
30
|
+
value={currentValue}
|
|
31
|
+
onChange={handleChange}
|
|
32
|
+
/>
|
|
33
|
+
|
|
34
|
+
{error && (
|
|
35
|
+
<div className="form__error">
|
|
36
|
+
<ErrorIcon className="form__icon form__icon--error" />
|
|
37
|
+
{error}
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default BuildInfraProfileDescriptionField
|