@devtron-labs/devtron-fe-common-lib 0.0.48-beta-7 → 0.0.48-beta-9
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/.eslintrc.js +16 -84
- package/.github/workflows/release-package.yml +3 -2
- package/dist/Common/BreadCrumb/BreadCrumb.d.ts +1 -1
- package/dist/Common/BreadCrumb/BreadcrumbStore.d.ts +2 -2
- package/dist/Common/Constants.d.ts +5 -1
- package/dist/Common/CustomInput/CustomInput.d.ts +1 -1
- package/dist/Common/CustomInput/Types.d.ts +2 -2
- package/dist/Common/CustomTagSelector/ResizableTagTextArea.d.ts +1 -1
- package/dist/Common/DeleteComponentModal/DeleteComponent.d.ts +1 -1
- package/dist/Common/DevtronProgressing/DevtronProgressing.d.ts +1 -1
- package/dist/Common/Dialogs/ConfirmationDialog.d.ts +6 -6
- package/dist/Common/Dialogs/DeleteDialog.d.ts +1 -1
- package/dist/Common/Dialogs/ForceDeleteDialog.d.ts +1 -1
- package/dist/Common/Dialogs/Types.d.ts +1 -1
- package/dist/Common/EmptyState/EmptyState.d.ts +17 -20
- package/dist/Common/EmptyState/GenericEmptyState.d.ts +1 -1
- package/dist/Common/Error.d.ts +1 -2
- package/dist/Common/ErrorScreenNotFound.d.ts +1 -1
- package/dist/Common/Helper.d.ts +1 -1
- package/dist/Common/ImageTags.d.ts +1 -1
- package/dist/Common/InfoColorBar/InfoColourbar.d.ts +1 -1
- package/dist/Common/Modals/Modal.d.ts +2 -2
- package/dist/Common/Modals/OpaqueModal.d.ts +3 -3
- package/dist/Common/Modals/VisibleModal.d.ts +3 -3
- package/dist/Common/Modals/VisibleModal2.d.ts +3 -3
- package/dist/Common/MultiSelectCustomization.d.ts +1 -1
- package/dist/Common/Policy.Types.d.ts +2 -2
- package/dist/Common/PopupMenu.d.ts +5 -5
- package/dist/Common/Progressing.d.ts +2 -2
- package/dist/Common/RadioGroup/RadioGroup.d.ts +1 -1
- package/dist/Common/ResizableTextarea.d.ts +1 -1
- package/dist/Common/TippyCustomized.d.ts +1 -1
- package/dist/Common/ToastBody.d.ts +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +351 -266
- package/package.json +2 -19
- package/src/Common/AddCDButton/AddCDButton.tsx +2 -1
- package/src/Common/Api.ts +26 -21
- package/src/Common/AppStatus/AppStatus.tsx +12 -12
- package/src/Common/AppStatus/utils.ts +5 -6
- package/src/Common/BreadCrumb/BreadCrumb.tsx +28 -32
- package/src/Common/BreadCrumb/BreadcrumbStore.tsx +2 -2
- package/src/Common/BreadCrumb/Types.ts +12 -11
- package/src/Common/Checkbox.tsx +19 -17
- package/src/Common/ClipboardButton/ClipboardButton.tsx +1 -1
- package/src/Common/ClipboardButton/__tests__/ClipboardButton.test.tsx +1 -0
- package/src/Common/Common.service.ts +64 -59
- package/src/Common/Constants.ts +14 -9
- package/src/Common/CustomInput/CustomInput.tsx +29 -22
- package/src/Common/CustomInput/Types.ts +4 -4
- package/src/Common/CustomInput/index.ts +1 -1
- package/src/Common/CustomTagSelector/PropagateTagInfo.tsx +18 -15
- package/src/Common/CustomTagSelector/ResizableTagTextArea.tsx +9 -9
- package/src/Common/CustomTagSelector/TagDetails.tsx +3 -9
- package/src/Common/CustomTagSelector/TagLabelSelect.tsx +9 -7
- package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +35 -31
- package/src/Common/CustomTagSelector/TagSelector.utils.ts +3 -2
- package/src/Common/CustomTagSelector/Types.ts +1 -1
- package/src/Common/CustomTagSelector/ValidationRules.ts +22 -18
- package/src/Common/CustomTagSelector/index.ts +2 -2
- package/src/Common/DebouncedSearch/DebouncedSearch.tsx +1 -2
- package/src/Common/DebouncedSearch/__tests__/DebouncedSearch.test.tsx +1 -0
- package/src/Common/DeleteComponentModal/DeleteComponent.tsx +32 -27
- package/src/Common/DeleteComponentModal/types.ts +1 -1
- package/src/Common/DevtronProgressing/DevtronProgressing.tsx +8 -5
- package/src/Common/Dialogs/ConfirmationDialog.tsx +24 -24
- package/src/Common/Dialogs/DeleteDialog.tsx +5 -3
- package/src/Common/Dialogs/DialogForm.tsx +35 -31
- package/src/Common/Dialogs/ForceDeleteDialog.tsx +7 -13
- package/src/Common/Dialogs/Types.ts +12 -12
- package/src/Common/Dialogs/index.ts +1 -1
- package/src/Common/Drawer/Drawer.tsx +1 -1
- package/src/Common/EmptyState/EmptyState.tsx +17 -13
- package/src/Common/EmptyState/GenericEmptyState.tsx +21 -7
- package/src/Common/Error.tsx +5 -5
- package/src/Common/ErrorScreenNotFound.tsx +12 -9
- package/src/Common/Grid/Grid.tsx +2 -1
- package/src/Common/Helper.tsx +24 -23
- package/src/Common/Hooks/UseClickOutside/UseClickOutside.tsx +1 -1
- package/src/Common/Hooks/UseSuperAdmin/UseSuperAdmin.tsx +1 -1
- package/src/Common/ImageTags.Types.ts +3 -2
- package/src/Common/ImageTags.tsx +66 -61
- package/src/Common/InfoColorBar/InfoColourbar.tsx +5 -10
- package/src/Common/Modals/Modal.tsx +3 -3
- package/src/Common/Modals/OpaqueModal.tsx +18 -25
- package/src/Common/Modals/VisibleModal.tsx +3 -7
- package/src/Common/Modals/VisibleModal2.tsx +15 -20
- package/src/Common/MultiSelectCustomization.tsx +13 -9
- package/src/Common/Policy.Types.ts +38 -38
- package/src/Common/PopupMenu.tsx +9 -10
- package/src/Common/Progressing.tsx +18 -15
- package/src/Common/RJSF/Form.tsx +1 -0
- package/src/Common/RJSF/common/FieldRow.tsx +1 -0
- package/src/Common/RJSF/config.ts +1 -0
- package/src/Common/RJSF/templates/ArrayFieldItemTemplate.tsx +1 -1
- package/src/Common/RJSF/templates/ArrayFieldTemplate.tsx +1 -0
- package/src/Common/RJSF/templates/BaseInput.tsx +1 -0
- package/src/Common/RJSF/templates/ButtonTemplates/AddButton.tsx +1 -0
- package/src/Common/RJSF/templates/ButtonTemplates/RemoveButton.tsx +1 -0
- package/src/Common/RJSF/templates/ButtonTemplates/SubmitButton.tsx +6 -1
- package/src/Common/RJSF/templates/Description.tsx +1 -0
- package/src/Common/RJSF/templates/Field.tsx +3 -14
- package/src/Common/RJSF/templates/FieldErrorTemplate.tsx +9 -6
- package/src/Common/RJSF/templates/ObjectFieldTemplate.tsx +7 -5
- package/src/Common/RJSF/templates/TitleField.tsx +1 -0
- package/src/Common/RJSF/templates/WrapIfAdditionalTemplate.tsx +1 -0
- package/src/Common/RJSF/utils.ts +57 -53
- package/src/Common/RJSF/widgets/Checkbox.tsx +2 -2
- package/src/Common/RJSF/widgets/Select.tsx +1 -0
- package/src/Common/RadioGroup/RadioGroup.tsx +23 -18
- package/src/Common/RadioGroup.tsx +23 -24
- package/src/Common/Reload.tsx +1 -0
- package/src/Common/ResizableTextarea.tsx +17 -18
- package/src/Common/Security/ScanVulnerabilitiesTable.tsx +34 -29
- package/src/Common/ServerError.ts +1 -5
- package/src/Common/TippyCustomized.tsx +38 -41
- package/src/Common/ToastBody.tsx +7 -6
- package/src/Common/Toggle/Toggle.tsx +3 -3
- package/src/Common/Types.ts +12 -12
- package/src/custom.d.ts +7 -7
- package/src/index.ts +1 -1
- package/.eslintignore +0 -75
- package/.github/pull_request_template.md +0 -25
- package/.github/workflows/ci.yml +0 -31
- package/.husky/pre-commit +0 -4
- package/.lintstagedrc +0 -5
- package/.nvmrc +0 -1
package/src/Common/Constants.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RegistryTypeDetailType } from
|
|
1
|
+
import { RegistryTypeDetailType } from "./Types"
|
|
2
2
|
|
|
3
3
|
export const RequestTimeout = 60000
|
|
4
4
|
export const Host = process.env.REACT_APP_ORCHESTRATOR_ROOT
|
|
@@ -23,8 +23,8 @@ export const URLS = {
|
|
|
23
23
|
export const ROUTES = {
|
|
24
24
|
PROJECT_LIST_MIN: 'team/autocomplete',
|
|
25
25
|
USER_CHECK_ROLE: 'user/check/roles',
|
|
26
|
-
IMAGE_TAGGING:
|
|
27
|
-
CD_MATERIAL_GET: 'app/cd-pipeline'
|
|
26
|
+
IMAGE_TAGGING:'app/image-tagging',
|
|
27
|
+
CD_MATERIAL_GET: 'app/cd-pipeline'
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export enum KEY_VALUE {
|
|
@@ -65,9 +65,9 @@ export const TriggerTypeMap = {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
export const BuildStageVariable = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
PreBuild: 'preBuildStage',
|
|
69
|
+
Build: 'buildStage',
|
|
70
|
+
PostBuild: 'postBuildStage',
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
export const REGISTRY_TYPE_MAP: Record<string, RegistryTypeDetailType> = {
|
|
@@ -236,7 +236,12 @@ export const REGISTRY_TYPE_MAP: Record<string, RegistryTypeDetailType> = {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
export const RepositoryAction = {
|
|
239
|
-
CONTAINER:
|
|
240
|
-
CHART_PULL:
|
|
241
|
-
CHART_PUSH:
|
|
239
|
+
CONTAINER: "CONTAINER",
|
|
240
|
+
CHART_PULL: "CHART_PULL",
|
|
241
|
+
CHART_PUSH: "CHART_PUSH"
|
|
242
242
|
}
|
|
243
|
+
|
|
244
|
+
export enum APPROVAL_MODAL_TYPE {
|
|
245
|
+
CONFIG = 'CONFIG',
|
|
246
|
+
IMAGE = 'IMAGE',
|
|
247
|
+
}
|
|
@@ -2,7 +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
|
-
export
|
|
5
|
+
export function CustomInput({
|
|
6
6
|
name,
|
|
7
7
|
value,
|
|
8
8
|
error,
|
|
@@ -29,7 +29,9 @@ export const CustomInput = ({
|
|
|
29
29
|
onKeyDown,
|
|
30
30
|
required,
|
|
31
31
|
additionalErrorInfo,
|
|
32
|
-
|
|
32
|
+
inputWrapClassname = '',
|
|
33
|
+
}: CustomInputProps) {
|
|
34
|
+
|
|
33
35
|
function handleError(error: any): any[] {
|
|
34
36
|
if (!Array.isArray(error)) {
|
|
35
37
|
return [error]
|
|
@@ -38,7 +40,7 @@ export const CustomInput = ({
|
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
const onBlur = (event) => {
|
|
41
|
-
//
|
|
43
|
+
//NOTE: This is to prevent the input from being trimmed when the user do not want to trim the input
|
|
42
44
|
if (!noTrim) {
|
|
43
45
|
event.stopPropagation()
|
|
44
46
|
event.target.value = event.target.value?.trim()
|
|
@@ -49,45 +51,50 @@ export const CustomInput = ({
|
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
const renderFormErrorWithIcon = (error: string) =>
|
|
53
|
-
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
const renderFormErrorWithIcon = (error: string) => {
|
|
55
|
+
return (
|
|
56
|
+
<div className="form__error" key={error}>
|
|
57
|
+
<ErrorIcon className="form__icon form__icon--error" />
|
|
58
|
+
{error}
|
|
59
|
+
{typeof additionalErrorInfo === 'function' && additionalErrorInfo()}
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
59
63
|
|
|
60
64
|
const getInputError = () => {
|
|
61
65
|
if (!error?.length) {
|
|
62
66
|
return null
|
|
67
|
+
} else {
|
|
68
|
+
if (typeof error === 'object') {
|
|
69
|
+
return handleError(error).map((err: string) => renderFormErrorWithIcon(err))
|
|
70
|
+
}
|
|
71
|
+
return renderFormErrorWithIcon(error)
|
|
63
72
|
}
|
|
64
|
-
if (typeof error === 'object') {
|
|
65
|
-
return handleError(error).map((err: string) => renderFormErrorWithIcon(err))
|
|
66
|
-
}
|
|
67
|
-
return renderFormErrorWithIcon(error)
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
const renderInputLabelConditionally = () => {
|
|
71
76
|
if (typeof label === 'string') {
|
|
72
77
|
return <span className={`${isRequiredField ? 'dc__required-field' : ''}`}>{label}</span>
|
|
78
|
+
} else {
|
|
79
|
+
return label
|
|
73
80
|
}
|
|
74
|
-
return label
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
const renderInputLabel = () => {
|
|
78
84
|
if (!label) {
|
|
79
85
|
return null
|
|
86
|
+
} else {
|
|
87
|
+
return (
|
|
88
|
+
<label className={`form__label ${labelClassName}`} data-testid={`label-${dataTestid}`}>
|
|
89
|
+
{renderInputLabelConditionally()}
|
|
90
|
+
</label>
|
|
91
|
+
)
|
|
80
92
|
}
|
|
81
|
-
return (
|
|
82
|
-
<label className={`form__label ${labelClassName}`} data-testid={`label-${dataTestid}`}>
|
|
83
|
-
{renderInputLabelConditionally()}
|
|
84
|
-
</label>
|
|
85
|
-
)
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
return (
|
|
89
|
-
<div className=
|
|
90
|
-
|
|
96
|
+
<div className={`flex column left top ${inputWrapClassname}`}>
|
|
97
|
+
{renderInputLabel()}
|
|
91
98
|
<input
|
|
92
99
|
data-testid={dataTestid}
|
|
93
100
|
type={type}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { HTMLInputTypeAttribute } from 'react'
|
|
2
|
-
import * as React from 'react'
|
|
1
|
+
import React, { HTMLInputTypeAttribute } from 'react'
|
|
3
2
|
|
|
4
3
|
export interface CustomInputProps {
|
|
5
4
|
name: string
|
|
@@ -7,7 +6,7 @@ export interface CustomInputProps {
|
|
|
7
6
|
onChange: (e: any) => void
|
|
8
7
|
onFocus?: (e: any) => void
|
|
9
8
|
autoComplete?: string
|
|
10
|
-
label?: string |
|
|
9
|
+
label?: string | React.ReactNode
|
|
11
10
|
labelClassName?: string
|
|
12
11
|
type?: HTMLInputTypeAttribute
|
|
13
12
|
disabled?: boolean
|
|
@@ -28,4 +27,5 @@ export interface CustomInputProps {
|
|
|
28
27
|
onKeyDown?: (e) => void
|
|
29
28
|
required?: boolean
|
|
30
29
|
additionalErrorInfo?: React.ReactNode
|
|
31
|
-
|
|
30
|
+
inputWrapClassname?: string
|
|
31
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './CustomInput'
|
|
2
|
-
export * from './Types'
|
|
2
|
+
export * from './Types'
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react'
|
|
1
2
|
import { ReactComponent as InjectTag } from '../../Assets/Icon/inject-tag.svg'
|
|
2
3
|
import { ReactComponent as Help } from '../../Assets/Icon/ic-help-outline.svg'
|
|
3
4
|
import { TippyCustomized } from '../TippyCustomized'
|
|
@@ -5,31 +6,33 @@ import { TippyTheme } from '../Types'
|
|
|
5
6
|
import { DOCUMENTATION } from '../Constants'
|
|
6
7
|
|
|
7
8
|
export default function PropagateTagInfo({ isCreateApp }: { isCreateApp: boolean }) {
|
|
8
|
-
const additionalInfo = () =>
|
|
9
|
-
|
|
10
|
-
<div className="
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
const additionalInfo = () => {
|
|
10
|
+
return (
|
|
11
|
+
<div className="p-12 fs-13">
|
|
12
|
+
<div className="mb-20">
|
|
13
|
+
<span className="flex left">
|
|
14
|
+
Add a tag and click on the
|
|
15
|
+
<InjectTag className="icon-dim-16 ml-4 mr-4" />
|
|
16
|
+
icon to
|
|
17
|
+
</span>
|
|
18
|
+
propagate tags as labels to Kubernetes resources
|
|
19
|
+
</div>
|
|
20
|
+
<div>Use these tags to filter/identify resources via CLI or in other Kubernetes tools.</div>
|
|
17
21
|
</div>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
22
|
+
)
|
|
23
|
+
}
|
|
21
24
|
return (
|
|
22
25
|
<TippyCustomized
|
|
23
26
|
theme={TippyTheme.white}
|
|
24
27
|
className="w-300"
|
|
25
28
|
placement="top"
|
|
26
29
|
Icon={InjectTag}
|
|
27
|
-
heading=
|
|
30
|
+
heading={'Propagate tags to K8s resources'}
|
|
28
31
|
infoText=""
|
|
29
32
|
additionalContent={additionalInfo()}
|
|
30
|
-
showCloseButton
|
|
33
|
+
showCloseButton={true}
|
|
31
34
|
trigger="click"
|
|
32
|
-
interactive
|
|
35
|
+
interactive={true}
|
|
33
36
|
documentationLink={isCreateApp ? DOCUMENTATION.APP_TAGS : DOCUMENTATION.APP_OVERVIEW_TAGS}
|
|
34
37
|
documentationLinkText="View Documentation"
|
|
35
38
|
>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react'
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
2
|
import { useThrottledEffect } from '../Helper'
|
|
3
3
|
import { ResizableTagTextAreaProps } from './Types'
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export function ResizableTagTextArea({
|
|
6
6
|
className,
|
|
7
7
|
minHeight,
|
|
8
8
|
maxHeight,
|
|
@@ -16,7 +16,7 @@ export const ResizableTagTextArea = ({
|
|
|
16
16
|
dependentRef,
|
|
17
17
|
dataTestId,
|
|
18
18
|
handleKeyDown,
|
|
19
|
-
}: ResizableTagTextAreaProps)
|
|
19
|
+
}: ResizableTagTextAreaProps) {
|
|
20
20
|
const [text, setText] = useState('')
|
|
21
21
|
|
|
22
22
|
useEffect(() => {
|
|
@@ -30,9 +30,9 @@ export const ResizableTagTextArea = ({
|
|
|
30
30
|
|
|
31
31
|
const reInitHeight = () => {
|
|
32
32
|
if (document.activeElement !== refVar.current) return
|
|
33
|
-
refVar.current.style.height =
|
|
33
|
+
refVar.current.style.height = minHeight + 'px'
|
|
34
34
|
if (dependentRef) {
|
|
35
|
-
dependentRef.current.style.height =
|
|
35
|
+
dependentRef.current.style.height = minHeight + 'px'
|
|
36
36
|
}
|
|
37
37
|
let nextHeight = refVar.current.scrollHeight
|
|
38
38
|
if (dependentRef && nextHeight < dependentRef.current.scrollHeight) {
|
|
@@ -44,18 +44,18 @@ export const ResizableTagTextArea = ({
|
|
|
44
44
|
if (maxHeight && nextHeight > maxHeight) {
|
|
45
45
|
nextHeight = maxHeight
|
|
46
46
|
}
|
|
47
|
-
refVar.current.style.height =
|
|
47
|
+
refVar.current.style.height = nextHeight + 'px'
|
|
48
48
|
if (dependentRef) {
|
|
49
|
-
dependentRef.current.style.height =
|
|
49
|
+
dependentRef.current.style.height = nextHeight + 'px'
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
useThrottledEffect(reInitHeight, 500, [text])
|
|
54
54
|
|
|
55
55
|
const handleOnBlur = (event) => {
|
|
56
|
-
refVar.current.style.height =
|
|
56
|
+
refVar.current.style.height = minHeight + 'px'
|
|
57
57
|
if (dependentRef) {
|
|
58
|
-
dependentRef.current.style.height =
|
|
58
|
+
dependentRef.current.style.height = minHeight + 'px'
|
|
59
59
|
}
|
|
60
60
|
onBlur && onBlur(event)
|
|
61
61
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef } from 'react'
|
|
1
|
+
import React, { useRef } from 'react'
|
|
2
2
|
import { ReactComponent as DeleteCross } from '../../Assets/Icon/ic-cross.svg'
|
|
3
3
|
import { ReactComponent as InjectTag } from '../../Assets/Icon/inject-tag.svg'
|
|
4
4
|
import { TagLabelValueSelector } from './TagLabelValueSelector'
|
|
@@ -41,9 +41,7 @@ export const TagDetails = ({
|
|
|
41
41
|
return (
|
|
42
42
|
<div className="flexbox mb-8">
|
|
43
43
|
<div
|
|
44
|
-
className={`dc__border h-30 pl-4 pr-4 br-4 mr-8 pointer ${tagData.propagate ? 'bcn-7' : ''} ${
|
|
45
|
-
tagData.key.startsWith('devtron.ai/') ? 'cursor-not-allowed bcn-1' : ''
|
|
46
|
-
}`}
|
|
44
|
+
className={`dc__border h-30 pl-4 pr-4 br-4 mr-8 pointer ${tagData.propagate ? 'bcn-7' : ''} ${tagData.key.startsWith("devtron.ai/") ? 'cursor-not-allowed bcn-1' : ''}`}
|
|
47
45
|
onClick={propagateTagToResource}
|
|
48
46
|
data-testid={`propagate-tag-${index}`}
|
|
49
47
|
>
|
|
@@ -70,11 +68,7 @@ export const TagDetails = ({
|
|
|
70
68
|
refVar={valueRef}
|
|
71
69
|
dependentRef={keyRef}
|
|
72
70
|
/>
|
|
73
|
-
<div
|
|
74
|
-
className="dc__border pl-4 pr-4 dc__right-radius-4 pointer flex top"
|
|
75
|
-
onClick={deleteTag}
|
|
76
|
-
data-testid={`delete-tag-${index}`}
|
|
77
|
-
>
|
|
71
|
+
<div className="dc__border pl-4 pr-4 dc__right-radius-4 pointer flex top" onClick={deleteTag} data-testid={`delete-tag-${index}`}>
|
|
78
72
|
<DeleteCross className="icon-dim-20 mt-4" />
|
|
79
73
|
</div>
|
|
80
74
|
</div>
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import React from 'react'
|
|
1
2
|
import PropagateTagInfo from './PropagateTagInfo'
|
|
2
3
|
import { ReactComponent as Add } from '../../Assets/Icon/ic-add.svg'
|
|
3
4
|
import { DEFAULT_TAG_DATA } from '../Constants'
|
|
4
5
|
import { TagLabelSelectType } from './Types'
|
|
5
6
|
import { TagDetails } from './TagDetails'
|
|
6
7
|
|
|
7
|
-
export const TagLabelSelect = ({
|
|
8
|
+
export const TagLabelSelect = ({
|
|
9
|
+
isCreateApp,
|
|
10
|
+
labelTags,
|
|
11
|
+
setLabelTags,
|
|
12
|
+
tabIndex = 0
|
|
13
|
+
}: TagLabelSelectType) => {
|
|
8
14
|
const setTagData = (index, tagValue): void => {
|
|
9
15
|
const _tags = [...labelTags]
|
|
10
16
|
const _tagValue = tagValue
|
|
11
|
-
if
|
|
17
|
+
if(_tagValue.key.startsWith("devtron.ai/")){
|
|
12
18
|
_tagValue.propagate = false
|
|
13
19
|
}
|
|
14
20
|
_tags[index] = _tagValue
|
|
@@ -34,11 +40,7 @@ export const TagLabelSelect = ({ isCreateApp, labelTags, setLabelTags, tabIndex
|
|
|
34
40
|
<PropagateTagInfo isCreateApp={isCreateApp} />
|
|
35
41
|
</div>
|
|
36
42
|
<div>
|
|
37
|
-
<div
|
|
38
|
-
className="dc_width-max-content cb-5 fw-6 fs-13 flexbox mr-20 mb-8 cursor"
|
|
39
|
-
onClick={addNewTag}
|
|
40
|
-
data-testid="add-tag-button"
|
|
41
|
-
>
|
|
43
|
+
<div className="dc_width-max-content cb-5 fw-6 fs-13 flexbox mr-20 mb-8 cursor" onClick={addNewTag} data-testid="add-tag-button">
|
|
42
44
|
<Add className="icon-dim-20 fcb-5" /> Add tag
|
|
43
45
|
</div>
|
|
44
46
|
<div className="mb-8" data-testid="tag-rows-container">
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react'
|
|
2
|
-
import Tippy from '@tippyjs/react'
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
|
3
2
|
import PopupMenu from '../PopupMenu'
|
|
4
3
|
import { ReactComponent as ErrorCross } from '../../Assets/Icon/ic-cross.svg'
|
|
5
4
|
import { ReactComponent as Info } from '../../Assets/Icon/ic-info-outlined.svg'
|
|
@@ -7,6 +6,7 @@ import { KEY_VALUE } from '../Constants'
|
|
|
7
6
|
import { stopPropagation } from '../Helper'
|
|
8
7
|
import { ResizableTagTextArea } from './ResizableTagTextArea'
|
|
9
8
|
import { SuggestedTagOptionType, TagLabelValueSelectorType } from './Types'
|
|
9
|
+
import Tippy from '@tippyjs/react'
|
|
10
10
|
import { ValidationRules } from './ValidationRules'
|
|
11
11
|
|
|
12
12
|
export const TagLabelValueSelector = ({
|
|
@@ -107,34 +107,38 @@ export const TagLabelValueSelector = ({
|
|
|
107
107
|
return null
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
const option = (tag: SuggestedTagOptionType, index: number): JSX.Element =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
110
|
+
const option = (tag: SuggestedTagOptionType, index: number): JSX.Element => {
|
|
111
|
+
return (
|
|
112
|
+
<div
|
|
113
|
+
key={`${tag.value}-${index}`}
|
|
114
|
+
data-key={tag.label}
|
|
115
|
+
data-propagate={tag.propagate}
|
|
116
|
+
className="dc__hover-n50 dc__ellipsis-right lh-20 fs-13 fw-4 pt-6 pr-8 pb-6 pl-8 cursor"
|
|
117
|
+
onClick={onSelectValue}
|
|
118
|
+
data-testid={`tag-label-value-${index}`}
|
|
119
|
+
>
|
|
120
|
+
{tag.label}
|
|
121
|
+
</div>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
122
124
|
|
|
123
|
-
const optionWithTippy = (tag: SuggestedTagOptionType, index: number): JSX.Element =>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<div
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
125
|
+
const optionWithTippy = (tag: SuggestedTagOptionType, index: number): JSX.Element => {
|
|
126
|
+
return (
|
|
127
|
+
<Tippy
|
|
128
|
+
className="default-tt"
|
|
129
|
+
arrow={false}
|
|
130
|
+
placement="right"
|
|
131
|
+
content={
|
|
132
|
+
<div>
|
|
133
|
+
<div className="mb-10 fs-12 fw-6 cn-0 dc__break-word">{tag.label}</div>
|
|
134
|
+
<div className="fs-12 fw-4 cn-0 dc__break-word">{tag.description}</div>
|
|
135
|
+
</div>
|
|
136
|
+
}
|
|
137
|
+
>
|
|
138
|
+
{option(tag, index)}
|
|
139
|
+
</Tippy>
|
|
140
|
+
)
|
|
141
|
+
}
|
|
138
142
|
|
|
139
143
|
const renderSuggestions = (): JSX.Element => {
|
|
140
144
|
if (tagOptions?.length) {
|
|
@@ -182,8 +186,8 @@ export const TagLabelValueSelector = ({
|
|
|
182
186
|
{popupMenuBody && (
|
|
183
187
|
<PopupMenu.Body
|
|
184
188
|
rootClassName={`mxh-210 dc__overflow-auto tag-${selectedTagIndex}-class`}
|
|
185
|
-
autoWidth
|
|
186
|
-
preventWheelDisable
|
|
189
|
+
autoWidth={true}
|
|
190
|
+
preventWheelDisable={true}
|
|
187
191
|
noBackDrop={noBackDrop}
|
|
188
192
|
>
|
|
189
193
|
{popupMenuBody}
|
|
@@ -59,9 +59,10 @@ export const validateKubernetesKey = (key: string) => {
|
|
|
59
59
|
if (noOfSlashInKey > 1) {
|
|
60
60
|
invalidMessageList.push('Key: Max 1 ( / ) allowed')
|
|
61
61
|
} else {
|
|
62
|
-
|
|
62
|
+
let name = key
|
|
63
63
|
if (noOfSlashInKey === 1) {
|
|
64
|
-
|
|
64
|
+
const [prefix, name]=key.split('/')
|
|
65
|
+
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -20,23 +20,25 @@ export class ValidationRules {
|
|
|
20
20
|
const errorList = []
|
|
21
21
|
if (!key) {
|
|
22
22
|
errorList.push('Key is required')
|
|
23
|
-
} else
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
} else {
|
|
24
|
+
if(!key.startsWith("devtron.ai/")){
|
|
25
|
+
const re = new RegExp('/', 'g')
|
|
26
|
+
const noOfSlashInKey = key.match(re)?.length
|
|
27
|
+
if (noOfSlashInKey > 1) {
|
|
28
|
+
errorList.push('Key: Max 1 ( / ) allowed')
|
|
29
|
+
} else if (noOfSlashInKey === 1) {
|
|
30
|
+
const [prefix, name] = key.split('/')
|
|
31
|
+
errorList.push(...validateTagValue(name).map((error) => `Name: ${error}`))
|
|
32
|
+
if (prefix.length > 253) {
|
|
33
|
+
errorList.push('Prefix: Can be max 253 characters')
|
|
34
|
+
}
|
|
35
|
+
const validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix)
|
|
36
|
+
if (!validPrefix) {
|
|
37
|
+
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)')
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
errorList.push(...validateTagValue(key).map((error) => `Name: ${error}`))
|
|
33
41
|
}
|
|
34
|
-
const validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix)
|
|
35
|
-
if (!validPrefix) {
|
|
36
|
-
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)')
|
|
37
|
-
}
|
|
38
|
-
} else {
|
|
39
|
-
errorList.push(...validateTagValue(key).map((error) => `Name: ${error}`))
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
return { isValid: errorList.length === 0, messages: errorList }
|
|
@@ -46,8 +48,10 @@ export class ValidationRules {
|
|
|
46
48
|
const errorList = []
|
|
47
49
|
if (!value) {
|
|
48
50
|
errorList.push('Value is required')
|
|
49
|
-
} else
|
|
50
|
-
|
|
51
|
+
} else {
|
|
52
|
+
if(!key.startsWith("devtron.ai/")){
|
|
53
|
+
errorList.push(...validateTagValue(value))
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
return { isValid: errorList.length === 0, messages: errorList }
|
|
53
57
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {default as PropagateTagInfo} from './PropagateTagInfo'
|
|
2
2
|
export * from './TagDetails'
|
|
3
3
|
export * from './TagLabelSelect'
|
|
4
4
|
export * from './TagLabelValueSelector'
|
|
5
5
|
export * from './ResizableTagTextArea'
|
|
6
|
-
export * from './Types'
|
|
6
|
+
export * from './Types'
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react'
|
|
2
|
-
import * as React from 'react'
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
3
2
|
import { useDebouncedEffect } from './Utils'
|
|
4
3
|
import { ReactComponent as ICClear } from '../../Assets/Icon/ic-error-cross.svg'
|
|
5
4
|
import { DebouncedSearchProps } from './Types'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
2
|
import { useHistory } from 'react-router-dom'
|
|
3
3
|
import { toast } from 'react-toastify'
|
|
4
4
|
import info from '../../Assets/Icon/ic-info-filled.svg'
|
|
@@ -6,7 +6,8 @@ import { ConfirmationDialog, DeleteDialog } from '../Dialogs'
|
|
|
6
6
|
import { ServerErrors } from '../ServerError'
|
|
7
7
|
import { DeleteComponentProps } from './types'
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
function DeleteComponent({
|
|
10
11
|
setDeleting,
|
|
11
12
|
toggleConfirmation,
|
|
12
13
|
deleteComponent,
|
|
@@ -19,7 +20,7 @@ const DeleteComponent = ({
|
|
|
19
20
|
reload,
|
|
20
21
|
configuration = '',
|
|
21
22
|
closeCustomComponent,
|
|
22
|
-
}: DeleteComponentProps)
|
|
23
|
+
}: DeleteComponentProps) {
|
|
23
24
|
const [showCannotDeleteDialogModal, setCannotDeleteDialogModal] = useState(false)
|
|
24
25
|
const { push } = useHistory()
|
|
25
26
|
|
|
@@ -54,31 +55,35 @@ const DeleteComponent = ({
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
const renderCannotDeleteDialogModal = () =>
|
|
58
|
-
|
|
59
|
-
<ConfirmationDialog
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
const renderCannotDeleteDialogModal = () => {
|
|
59
|
+
return (
|
|
60
|
+
<ConfirmationDialog className="confirmation-dialog__body--w-360">
|
|
61
|
+
<ConfirmationDialog.Icon src={info} />
|
|
62
|
+
<ConfirmationDialog.Body title={`Cannot delete ${component} '${title}'`} />
|
|
63
|
+
<p className="fs-13 cn-7 ">{confirmationDialogDescription}</p>
|
|
64
|
+
<ConfirmationDialog.ButtonGroup>
|
|
65
|
+
<button type="button" className="cta" onClick={handleConfirmation}>
|
|
66
|
+
Okay
|
|
67
|
+
</button>
|
|
68
|
+
</ConfirmationDialog.ButtonGroup>
|
|
69
|
+
</ConfirmationDialog>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
const renderDeleteDialog = () =>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
const renderDeleteDialog = () => {
|
|
74
|
+
return (
|
|
75
|
+
<DeleteDialog
|
|
76
|
+
title={`Delete ${component} '${title}'`}
|
|
77
|
+
delete={handleDelete}
|
|
78
|
+
closeDelete={() => toggleConfirmation(false)}
|
|
79
|
+
dataTestId="delete-dialog"
|
|
80
|
+
>
|
|
81
|
+
<DeleteDialog.Description>
|
|
82
|
+
<p>Are you sure you want to delete this {configuration ? configuration : component}? </p>
|
|
83
|
+
</DeleteDialog.Description>
|
|
84
|
+
</DeleteDialog>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
82
87
|
return (
|
|
83
88
|
<div>
|
|
84
89
|
{!showCannotDeleteDialogModal && renderDeleteDialog()}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import React from 'react'
|
|
1
2
|
import { ReactComponent as ICRotateDevtron } from '../../Assets/Icon/ic-rotate-devtron.svg'
|
|
2
3
|
import { DevtronProgressingProps } from './types'
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export function DevtronProgressing({ classes, parentClasses }: DevtronProgressingProps): JSX.Element {
|
|
6
|
+
return (
|
|
7
|
+
<div className={parentClasses ? parentClasses : ''}>
|
|
8
|
+
<ICRotateDevtron className={classes ? classes : ''} />
|
|
9
|
+
</div>
|
|
10
|
+
)
|
|
11
|
+
}
|