@devtron-labs/devtron-fe-common-lib 0.0.7 → 0.0.9-beta-1

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 (86) hide show
  1. package/dist/Common/BreadCrumb/BreadCrumb.d.ts +1 -29
  2. package/dist/Common/BreadCrumb/Types.d.ts +28 -0
  3. package/dist/Common/CIPipeline.Types.d.ts +263 -0
  4. package/dist/Common/Checkbox.d.ts +1 -14
  5. package/dist/Common/Constants.d.ts +18 -0
  6. package/dist/Common/CustomTagSelector/ResizableTagTextArea.d.ts +1 -1
  7. package/dist/Common/CustomTagSelector/TagLabelValueSelector.d.ts +1 -1
  8. package/dist/Common/CustomTagSelector/Types.d.ts +11 -3
  9. package/dist/Common/CustomTagSelector/ValidationRules.d.ts +1 -1
  10. package/dist/Common/DeleteComponentModal/DeleteComponent.d.ts +4 -0
  11. package/dist/Common/DeleteComponentModal/types.d.ts +15 -0
  12. package/dist/Common/Dialogs/ConfirmationDialog.d.ts +5 -16
  13. package/dist/Common/Dialogs/DialogForm.d.ts +1 -9
  14. package/dist/Common/Dialogs/Types.d.ts +28 -0
  15. package/dist/Common/EmptyState/EmptyState.d.ts +2 -1
  16. package/dist/Common/EmptyState/GenericEmptyState.d.ts +5 -0
  17. package/dist/Common/Error.d.ts +2 -2
  18. package/dist/Common/Helper.d.ts +31 -1
  19. package/dist/Common/InfoColorBar/InfoColourbar.d.ts +2 -15
  20. package/dist/Common/Modals/Modal.d.ts +2 -9
  21. package/dist/Common/MultiSelectCustomization.d.ts +1 -2
  22. package/dist/Common/PopupMenu.d.ts +4 -21
  23. package/dist/Common/Progressing.d.ts +4 -13
  24. package/dist/Common/RadioGroup/RadioGroup.d.ts +17 -0
  25. package/dist/Common/RadioGroup.d.ts +1 -10
  26. package/dist/Common/Reload.d.ts +2 -4
  27. package/dist/Common/Security/ScanVulnerabilitiesTable.d.ts +4 -0
  28. package/dist/Common/TippyCustomized.d.ts +2 -30
  29. package/dist/Common/Toggle/Toggle.d.ts +12 -0
  30. package/dist/Common/Types.d.ts +293 -0
  31. package/dist/Common/index.d.ts +7 -1
  32. package/dist/index.js +2472 -1948
  33. package/package.json +2 -2
  34. package/rollup.config.js +3 -3
  35. package/src/Assets/Icon/ic-help.svg +3 -0
  36. package/src/Assets/Icon/ic-info-filled.svg +7 -0
  37. package/src/Assets/Icon/ic-warning.svg +7 -0
  38. package/src/Assets/Img/app-not-deployed.png +0 -0
  39. package/src/Common/Api.ts +7 -1
  40. package/src/Common/BreadCrumb/BreadCrumb.tsx +1 -30
  41. package/src/Common/BreadCrumb/Types.ts +30 -0
  42. package/src/Common/CIPipeline.Types.ts +275 -0
  43. package/src/Common/Checkbox.tsx +3 -16
  44. package/src/Common/Constants.ts +21 -0
  45. package/src/Common/CustomTagSelector/ResizableTagTextArea.tsx +6 -4
  46. package/src/Common/CustomTagSelector/TagDetails.tsx +15 -2
  47. package/src/Common/CustomTagSelector/TagLabelSelect.tsx +7 -3
  48. package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +66 -26
  49. package/src/Common/CustomTagSelector/Types.ts +11 -3
  50. package/src/Common/CustomTagSelector/ValidationRules.ts +21 -18
  51. package/src/Common/DeleteComponentModal/DeleteComponent.tsx +95 -0
  52. package/src/Common/DeleteComponentModal/types.ts +15 -0
  53. package/src/Common/Dialogs/ConfirmationDialog.tsx +6 -4
  54. package/src/Common/Dialogs/DeleteDialog.tsx +45 -27
  55. package/src/Common/Dialogs/DialogForm.tsx +2 -11
  56. package/src/Common/Dialogs/Types.ts +29 -0
  57. package/src/Common/Drawer/Drawer.scss +12 -11
  58. package/src/Common/EmptyState/EmptyState.tsx +5 -5
  59. package/src/Common/EmptyState/GenericEmptyState.tsx +41 -0
  60. package/src/Common/EmptyState/emptyState.scss +4 -15
  61. package/src/Common/Error.tsx +13 -16
  62. package/src/Common/ErrorScreenNotFound.tsx +23 -30
  63. package/src/Common/Helper.tsx +258 -2
  64. package/src/Common/InfoColorBar/InfoColourbar.tsx +6 -18
  65. package/src/Common/Modals/Modal.tsx +7 -1
  66. package/src/Common/Modals/OpaqueModal.tsx +2 -2
  67. package/src/Common/Modals/VisibleModal.tsx +1 -1
  68. package/src/Common/Modals/VisibleModal2.tsx +1 -1
  69. package/src/Common/MultiSelectCustomization.tsx +3 -3
  70. package/src/Common/PopupMenu.tsx +23 -6
  71. package/src/Common/Progressing.tsx +8 -15
  72. package/src/Common/RadioGroup/RadioGroup.tsx +88 -0
  73. package/src/Common/RadioGroup/radioGroup.scss +46 -0
  74. package/src/Common/RadioGroup.tsx +3 -13
  75. package/src/Common/Reload.tsx +15 -10
  76. package/src/Common/Security/ScanVulnerabilitiesTable.tsx +55 -0
  77. package/src/Common/Security/scanVulnerabilities.css +67 -0
  78. package/src/Common/TippyCustomized.tsx +29 -31
  79. package/src/Common/Toggle/Toggle.scss +70 -0
  80. package/src/Common/Toggle/Toggle.tsx +38 -0
  81. package/src/Common/Types.ts +319 -0
  82. package/src/Common/index.ts +7 -1
  83. package/dist/27bfa7a87d0b7039.png +0 -0
  84. package/dist/b5d52f036bdcd3ed.png +0 -0
  85. package/src/Assets/Icon/ic-close.svg +0 -9
  86. /package/src/Assets/Img/{warning-medium.svg → delete-medium.svg} +0 -0
@@ -1,12 +1,13 @@
1
1
  import React, { useState, useEffect } from 'react'
2
2
  import PopupMenu from '../PopupMenu'
3
- import { ValidationRules } from './ValidationRules'
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'
6
5
  import { KEY_VALUE } from '../Constants'
7
6
  import { stopPropagation } from '../Helper'
8
7
  import { ResizableTagTextArea } from './ResizableTagTextArea'
9
- import { TagLabelValueSelectorType } from './Types'
8
+ import { SuggestedTagOptionType, TagLabelValueSelectorType } from './Types'
9
+ import Tippy from '@tippyjs/react'
10
+ import { ValidationRules } from './ValidationRules'
10
11
 
11
12
  export const TagLabelValueSelector = ({
12
13
  selectedTagIndex,
@@ -19,6 +20,7 @@ export const TagLabelValueSelector = ({
19
20
  tabIndex = null,
20
21
  refVar,
21
22
  dependentRef,
23
+ noBackDrop,
22
24
  }: TagLabelValueSelectorType) => {
23
25
  const [selectedValue, setSelectedValue] = useState<string>('')
24
26
  const [activeElement, setActiveElement] = useState<string>('')
@@ -43,11 +45,12 @@ export const TagLabelValueSelector = ({
43
45
  const _tagData = { ...tagData }
44
46
  _tagData[tagInputType] = selectedValue
45
47
  if (tagInputType === KEY_VALUE.KEY) {
46
- _tagData.isInvalidKey = selectedValue
47
- ? !validationRules.propagateTagKey(selectedValue).isValid
48
- : _tagData.value !== ''
49
- } else if (selectedValue || isRequired) {
50
- _tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue).isValid
48
+ _tagData.isInvalidKey =
49
+ selectedValue || _tagData.propagate
50
+ ? !validationRules.propagateTagKey(selectedValue).isValid
51
+ : _tagData.value !== ''
52
+ } else if (selectedValue || isRequired || _tagData.propagate) {
53
+ _tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue, _tagData.key).isValid
51
54
  _tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey
52
55
  } else {
53
56
  _tagData.isInvalidValue = false
@@ -65,7 +68,9 @@ export const TagLabelValueSelector = ({
65
68
  stopPropagation(e)
66
69
  const _tagData = { ...tagData }
67
70
  _tagData[tagInputType] = e.currentTarget.dataset.key
71
+ _tagData.propagate = e.currentTarget.dataset.propagate === 'true'
68
72
  setTagData(selectedTagIndex, _tagData)
73
+ setActiveElement('')
69
74
  }
70
75
 
71
76
  const renderValidationsSuggestions = (): JSX.Element => {
@@ -74,12 +79,12 @@ export const TagLabelValueSelector = ({
74
79
  if (selectedValue || tagData.value) {
75
80
  field = validationRules.propagateTagKey(selectedValue)
76
81
  }
77
- } else if (isRequired || selectedValue) {
78
- field = validationRules.propagateTagValue(selectedValue)
82
+ } else if (isRequired || selectedValue || tagData.propagate) {
83
+ field = validationRules.propagateTagValue(selectedValue, tagData.key)
79
84
  }
80
85
  if (!field.isValid) {
81
86
  return (
82
- <div className="p-4" onClick={stopPropagation}>
87
+ <div className="p-4" onClick={stopPropagation} data-testid="tag-label-cross-stop-propagation">
83
88
  {field.messages.map((error) => (
84
89
  <div key={error} className="flexbox pr-4 pl-4">
85
90
  <span>
@@ -102,22 +107,48 @@ export const TagLabelValueSelector = ({
102
107
  return null
103
108
  }
104
109
 
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
+ }
124
+
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
+ }
142
+
105
143
  const renderSuggestions = (): JSX.Element => {
106
144
  if (tagOptions?.length) {
107
- const filteredTags = tagOptions.filter((tag) => tag.value.indexOf(selectedValue) >= 0)
145
+ const filteredTags = tagOptions.filter((tag) => tag.label.indexOf(selectedValue) >= 0)
108
146
  if (filteredTags.length) {
109
147
  return (
110
148
  <div>
111
- {filteredTags.map((tag, index) => (
112
- <div
113
- key={`${tag.value}-${index}`}
114
- data-key={tag.label}
115
- className="dc__hover-n50 lh-20 fs-13 fw-4 pt-6 pr-8 pb-6 pl-8 cursor"
116
- onClick={onSelectValue}
117
- >
118
- {tag.label}
119
- </div>
120
- ))}
149
+ {filteredTags.map((tag, index) =>
150
+ tag.description ? optionWithTippy(tag, index) : option(tag, index),
151
+ )}
121
152
  </div>
122
153
  )
123
154
  }
@@ -125,13 +156,14 @@ export const TagLabelValueSelector = ({
125
156
  return renderValidationsSuggestions()
126
157
  }
127
158
 
159
+ const popupMenuBody = activeElement === `tag-${tagInputType}-${selectedTagIndex}` ? renderSuggestions() : null
128
160
  return (
129
161
  <PopupMenu autoClose autoPosition>
130
- <PopupMenu.Button rootClassName="dc__bg-n50 flex top dc__no-border">
162
+ <PopupMenu.Button rootClassName="dc__bg-n50 flex top dc__no-border-imp">
131
163
  <ResizableTagTextArea
132
164
  minHeight={30}
133
165
  maxHeight={80}
134
- className={`form__input pt-4-imp pb-4-imp fs-13 ${
166
+ className={`form__input tag-input pt-4-imp pb-4-imp fs-13 ${
135
167
  tagInputType === KEY_VALUE.KEY
136
168
  ? `dc__no-right-radius`
137
169
  : `dc__no-border-radius dc__no-right-border dc__no-left-border`
@@ -148,11 +180,19 @@ export const TagLabelValueSelector = ({
148
180
  tabIndex={tabIndex}
149
181
  refVar={refVar}
150
182
  dependentRef={dependentRef}
183
+ dataTestId={`tag-${tagInputType === KEY_VALUE.KEY ? 'key' : 'value'}-${selectedTagIndex}`}
151
184
  />
152
185
  </PopupMenu.Button>
153
- <PopupMenu.Body rootClassName={`tag-${selectedTagIndex}-class`} autoWidth={true} preventWheelDisable={true}>
154
- {activeElement === `tag-${tagInputType}-${selectedTagIndex}` && renderSuggestions()}
155
- </PopupMenu.Body>
186
+ {popupMenuBody && (
187
+ <PopupMenu.Body
188
+ rootClassName={`mxh-210 dc__overflow-auto tag-${selectedTagIndex}-class`}
189
+ autoWidth={true}
190
+ preventWheelDisable={true}
191
+ noBackDrop={noBackDrop}
192
+ >
193
+ {popupMenuBody}
194
+ </PopupMenu.Body>
195
+ )}
156
196
  </PopupMenu>
157
197
  )
158
198
  }
@@ -1,6 +1,10 @@
1
1
  import { KEY_VALUE } from '../Constants'
2
2
  import { OptionType } from '../Types'
3
3
 
4
+ export interface SuggestedTagOptionType extends OptionType {
5
+ description: string
6
+ propagate: boolean
7
+ }
4
8
  export interface TagType {
5
9
  id?: number
6
10
  key: string
@@ -11,6 +15,7 @@ export interface TagType {
11
15
  isInvalidKey?: boolean
12
16
  isInvalidValue?: boolean
13
17
  isSuggested?: boolean
18
+ isPropagateDisabled?: boolean
14
19
  }
15
20
 
16
21
  export interface TagErrorType {
@@ -23,7 +28,8 @@ export interface TagLabelSelectType {
23
28
  setLabelTags: (tagList: TagType[]) => void
24
29
  tabIndex?: number
25
30
  selectedProjectId?: number
26
- suggestedTagsOptions?: OptionType[]
31
+ suggestedTagsOptions?: SuggestedTagOptionType[]
32
+ reloadProjectTags?: boolean
27
33
  }
28
34
 
29
35
  export interface TagDetailType {
@@ -32,20 +38,21 @@ export interface TagDetailType {
32
38
  setTagData: (index: number, tagData: TagType) => void
33
39
  removeTag?: (index: number) => void
34
40
  tabIndex?: number
35
- suggestedTagsOptions?: OptionType[]
41
+ suggestedTagsOptions?: SuggestedTagOptionType[]
36
42
  }
37
43
 
38
44
  export interface TagLabelValueSelectorType {
39
45
  selectedTagIndex: number
40
46
  tagData: TagType
41
47
  setTagData: (index: number, tagData: TagType) => void
42
- tagOptions?: OptionType[]
48
+ tagOptions?: SuggestedTagOptionType[]
43
49
  isRequired?: boolean
44
50
  tagInputType?: KEY_VALUE
45
51
  placeholder?: string
46
52
  tabIndex?: number
47
53
  refVar?: React.MutableRefObject<HTMLTextAreaElement>
48
54
  dependentRef?: React.MutableRefObject<HTMLTextAreaElement>
55
+ noBackDrop?: boolean
49
56
  }
50
57
 
51
58
  export interface ResizableTagTextAreaProps {
@@ -60,4 +67,5 @@ export interface ResizableTagTextAreaProps {
60
67
  tabIndex?: number
61
68
  refVar?: React.MutableRefObject<HTMLTextAreaElement>
62
69
  dependentRef?: React.MutableRefObject<HTMLTextAreaElement>
70
+ dataTestId?: string
63
71
  }
@@ -16,39 +16,42 @@ const validateTagValue = (value: string): string[] => {
16
16
  return errorList
17
17
  }
18
18
  export class ValidationRules {
19
-
20
19
  propagateTagKey = (key: string): { isValid: boolean; messages: string[] } => {
21
20
  const errorList = []
22
21
  if (!key) {
23
22
  errorList.push('Key is required')
24
23
  } else {
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 (.)')
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}`))
38
41
  }
39
- } else {
40
- errorList.push(...validateTagValue(key).map((error) => `Name: ${error}`))
41
42
  }
42
43
  }
43
44
  return { isValid: errorList.length === 0, messages: errorList }
44
45
  }
45
46
 
46
- propagateTagValue = (value: string): { isValid: boolean; messages: string[] } => {
47
+ propagateTagValue = (value: string, key: string): { isValid: boolean; messages: string[] } => {
47
48
  const errorList = []
48
49
  if (!value) {
49
50
  errorList.push('Value is required')
50
51
  } else {
51
- errorList.push(...validateTagValue(value))
52
+ if(!key.startsWith("devtron.ai/")){
53
+ errorList.push(...validateTagValue(value))
54
+ }
52
55
  }
53
56
  return { isValid: errorList.length === 0, messages: errorList }
54
57
  }
@@ -0,0 +1,95 @@
1
+ import React, { useState } from 'react'
2
+ import { useHistory } from 'react-router-dom'
3
+ import { toast } from 'react-toastify'
4
+ import info from '../../Assets/Icon/ic-info-filled.svg'
5
+ import { ConfirmationDialog, DeleteDialog } from '../Dialogs'
6
+ import { ServerErrors } from '../ServerError'
7
+ import { DeleteComponentProps } from './types'
8
+
9
+
10
+ function DeleteComponent({
11
+ setDeleting,
12
+ toggleConfirmation,
13
+ deleteComponent,
14
+ title,
15
+ component,
16
+ payload,
17
+ confirmationDialogDescription = '',
18
+ redirectTo = false,
19
+ url = '',
20
+ reload,
21
+ configuration = '',
22
+ closeCustomComponent,
23
+ }: DeleteComponentProps) {
24
+ const [showCannotDeleteDialogModal, setCannotDeleteDialogModal] = useState(false)
25
+ const { push } = useHistory()
26
+
27
+ async function handleDelete() {
28
+ setDeleting(true)
29
+ try {
30
+ await deleteComponent(payload)
31
+ toast.success('Successfully deleted')
32
+ toggleConfirmation(false)
33
+ if (redirectTo) {
34
+ push(url)
35
+ } else {
36
+ reload()
37
+ }
38
+ if (typeof closeCustomComponent === 'function') {
39
+ closeCustomComponent()
40
+ }
41
+ } catch (serverError) {
42
+ if (serverError instanceof ServerErrors && serverError.code === 500) {
43
+ setCannotDeleteDialogModal(true)
44
+ }
45
+ } finally {
46
+ setDeleting(false)
47
+ }
48
+ }
49
+
50
+ const handleConfirmation = () => {
51
+ setCannotDeleteDialogModal(false)
52
+ toggleConfirmation(false)
53
+ if (typeof closeCustomComponent === 'function') {
54
+ closeCustomComponent()
55
+ }
56
+ }
57
+
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
+ }
72
+
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
+ }
87
+ return (
88
+ <div>
89
+ {!showCannotDeleteDialogModal && renderDeleteDialog()}
90
+ {showCannotDeleteDialogModal && renderCannotDeleteDialogModal()}
91
+ </div>
92
+ )
93
+ }
94
+
95
+ export default DeleteComponent
@@ -0,0 +1,15 @@
1
+ export interface DeleteComponentProps {
2
+ setDeleting: (boolean) => void
3
+ toggleConfirmation: any
4
+ deleteComponent: (any) => Promise<any>
5
+ title: string
6
+ component: string
7
+ payload: any
8
+ confirmationDialogDescription?: string
9
+ redirectTo?: boolean
10
+ url?: string
11
+ reload?: () => void
12
+ configuration?: string
13
+ dataTestid?: string
14
+ closeCustomComponent?: () => void
15
+ }
@@ -1,6 +1,8 @@
1
1
  import React from 'react'
2
2
  import { VisibleModal2 } from '../Modals/VisibleModal2'
3
- function ConfirmationDialog({ className = '', children }) {
3
+ import { ConfirmationDialogBodyType, ConfirmationDialogButtonGroupType, ConfirmationDialogIconType, ConfirmationDialogType } from './Types'
4
+
5
+ function ConfirmationDialog({ className = '', children }: ConfirmationDialogType) {
4
6
  return (
5
7
  <VisibleModal2 className="confirmation-dialog">
6
8
  <div className={`confirmation-dialog__body ${className}`}>{children}</div>
@@ -8,11 +10,11 @@ function ConfirmationDialog({ className = '', children }) {
8
10
  )
9
11
  }
10
12
 
11
- function Icon({ src, className = '' }) {
13
+ function Icon({ src, className = '' }: ConfirmationDialogIconType) {
12
14
  return <img src={src} className={`confirmation-dialog__icon ${className}`} alt="" />
13
15
  }
14
16
 
15
- function Body({ title, subtitle = null, children = null }) {
17
+ function Body({ title, subtitle = null, children = null }: ConfirmationDialogBodyType) {
16
18
  return (
17
19
  <div className="flex left column ">
18
20
  <h3 className="confirmation-dialog__title lh-1-25 dc__break-word w-100">{title}</h3>
@@ -22,7 +24,7 @@ function Body({ title, subtitle = null, children = null }) {
22
24
  )
23
25
  }
24
26
 
25
- function ButtonGroup({ children }) {
27
+ function ButtonGroup({ children }: ConfirmationDialogButtonGroupType) {
26
28
  return <div className="flex right confirmation-dialog__button-group">{children}</div>
27
29
  }
28
30
 
@@ -1,35 +1,53 @@
1
- import React from 'react';
2
- import warn from '../../Assets/Img/warning-medium.svg';
1
+ import React from 'react'
2
+ import warn from '../../Assets/Img/delete-medium.svg'
3
3
  import { Progressing } from '../Progressing'
4
- import ConfirmationDialog from './ConfirmationDialog';
5
- import { DeleteDialogProps } from './Types';
4
+ import ConfirmationDialog from './ConfirmationDialog'
5
+ import { DeleteDialogProps } from './Types'
6
6
 
7
7
  export const DeleteDialog: React.FC<DeleteDialogProps> & { Description?: React.FC<any> } = function (props) {
8
-
9
- return <ConfirmationDialog className="confirmation-dialog__body--w-400">
10
- <ConfirmationDialog.Icon src={warn} />
11
- <ConfirmationDialog.Body title={props.title}>
12
- <div className="fs-13 cn-7 lh-1-54 w-100">
13
- {props.description ? props.description : null}
14
- {props.children}
15
- </div>
16
- </ConfirmationDialog.Body>
17
- <ConfirmationDialog.ButtonGroup>
18
- <div className="flex right">
19
- <button type="button" className="cta cancel cta-cd-delete-modal ml-16" onClick={props.closeDelete} disabled={props.apiCallInProgress}>Cancel</button>
20
- <button type="button" className="cta delete cta-cd-delete-modal ml-16" onClick={() => props.delete()} disabled={props.apiCallInProgress}>
21
- {props.apiCallInProgress ? <Progressing /> : `${props.deletePrefix || ''}Delete${props.deletePostfix || ''}`}
22
- </button>
23
- </div>
24
- </ConfirmationDialog.ButtonGroup>
25
- </ConfirmationDialog >
8
+ return (
9
+ <ConfirmationDialog className="confirmation-dialog__body--w-400">
10
+ <ConfirmationDialog.Icon src={warn} />
11
+ <ConfirmationDialog.Body title={props.title}>
12
+ <div className="fs-13 cn-7 lh-1-54 w-100">
13
+ {props.description ? props.description : null}
14
+ {props.children}
15
+ </div>
16
+ </ConfirmationDialog.Body>
17
+ <ConfirmationDialog.ButtonGroup>
18
+ <div className="flex right">
19
+ <button
20
+ type="button"
21
+ className="cta cancel cta-cd-delete-modal ml-16"
22
+ onClick={props.closeDelete}
23
+ disabled={props.apiCallInProgress}
24
+ data-testid="dialog-cancel"
25
+ >
26
+ Cancel
27
+ </button>
28
+ <button
29
+ type="button"
30
+ className="cta delete cta-cd-delete-modal ml-16"
31
+ onClick={() => props.delete()}
32
+ disabled={props.apiCallInProgress}
33
+ data-testid="dialog-delete"
34
+ >
35
+ {props.apiCallInProgress ? (
36
+ <Progressing />
37
+ ) : (
38
+ `${props.deletePrefix || ''}${
39
+ props.buttonPrimaryText ? props.buttonPrimaryText : 'Delete'
40
+ }${props.deletePostfix || ''}`
41
+ )}
42
+ </button>
43
+ </div>
44
+ </ConfirmationDialog.ButtonGroup>
45
+ </ConfirmationDialog>
46
+ )
26
47
  }
27
48
 
28
49
  function DeleteDialogDescription(props) {
29
-
30
- return <>
31
- {props.children}
32
- </>
50
+ return <>{props.children}</>
33
51
  }
34
52
 
35
- DeleteDialog.Description = DeleteDialogDescription;
53
+ DeleteDialog.Description = DeleteDialogDescription
@@ -1,20 +1,11 @@
1
1
  import React, { Component, createContext } from 'react';
2
2
  import { VisibleModal } from '../Modals/VisibleModal';
3
- import close from '../../Assets/Icon/ic-close.svg';
3
+ import close from '../../Assets/Icon/ic-cross.svg';
4
4
  import { Progressing } from '../Progressing'
5
+ import { DialogFormProps } from './Types';
5
6
  //TODO: may not need context
6
7
  const DialogFormContext = createContext({ title: '', isLoading: false, close: (event) => {}, onSave: (event) => {} });
7
8
 
8
- export interface DialogFormProps {
9
- className: string;
10
- title: string;
11
- isLoading: boolean;
12
- closeOnESC?: boolean;
13
- close: (event) => void;
14
- onSave: (event) => void;
15
- headerClassName?: string;
16
- }
17
-
18
9
  export class DialogForm extends Component<DialogFormProps> {
19
10
  constructor(props) {
20
11
  super(props);
@@ -1,3 +1,5 @@
1
+ import { ReactNode } from "react"
2
+
1
3
  export interface DeleteDialogProps {
2
4
  title: string
3
5
  description?: string
@@ -6,6 +8,8 @@ export interface DeleteDialogProps {
6
8
  deletePrefix?: string
7
9
  deletePostfix?: string
8
10
  apiCallInProgress?: boolean
11
+ dataTestId?: string
12
+ buttonPrimaryText?: string
9
13
  }
10
14
 
11
15
  export interface ForceDeleteDialogType {
@@ -14,3 +18,28 @@ export interface ForceDeleteDialogType {
14
18
  forceDeleteDialogTitle: string
15
19
  forceDeleteDialogMessage: string
16
20
  }
21
+ export interface ConfirmationDialogType {
22
+ className?: string
23
+ children: any
24
+ }
25
+ export interface ConfirmationDialogIconType {
26
+ src: string
27
+ className?: string
28
+ }
29
+ export interface ConfirmationDialogBodyType {
30
+ title: string
31
+ subtitle?: ReactNode
32
+ children?: any
33
+ }
34
+ export interface ConfirmationDialogButtonGroupType {
35
+ children: any
36
+ }
37
+ export interface DialogFormProps {
38
+ className: string;
39
+ title: string;
40
+ isLoading: boolean;
41
+ closeOnESC?: boolean;
42
+ close: (event) => void;
43
+ onSave: (event) => void;
44
+ headerClassName?: string;
45
+ }
@@ -1,39 +1,40 @@
1
- .drawer{
1
+ .drawer {
2
2
  position: absolute;
3
3
  overflow: hidden;
4
- &.left, &.right{
4
+ &.left,
5
+ &.right {
5
6
  top: 0;
6
7
  bottom: 0;
7
8
  width: 0;
8
9
  transition: width 200ms;
9
- &.show{
10
+ &.show {
10
11
  min-width: var(--minWidth);
11
12
  width: var(--width);
12
13
  max-width: var(--maxWidth);
13
14
  }
14
15
  }
15
16
 
16
- &.top, &.bottom{
17
+ &.top,
18
+ &.bottom {
17
19
  left: 0;
18
20
  right: 0;
19
21
  height: 0;
20
22
  transition: height 200ms;
21
- &.show{
23
+ &.show {
22
24
  height: var(--height);
23
25
  }
24
26
  }
25
- &.right{
27
+ &.right {
26
28
  right: 0;
27
29
  }
28
- &.left{
30
+ &.left {
29
31
  left: 0;
30
-
31
32
  }
32
- &.top{
33
+ &.top {
33
34
  top: 0;
34
35
  }
35
36
 
36
- &.bottom{
37
+ &.bottom {
37
38
  bottom: 0;
38
39
  }
39
- }
40
+ }
@@ -2,9 +2,9 @@ import React from 'react'
2
2
  import './emptyState.scss';
3
3
  import { ReactComponent as Progressing } from '../../Assets/Icon/ic-progressing.svg';
4
4
 
5
- function EmptyState({ children }) {
5
+ function EmptyState({ children, className = '' }) {
6
6
  return (
7
- <div className="flex column empty-state" style={{ width: '100%', height: '100%' }}>
7
+ <div className={`flex column empty-state w-100 h-100 ${className}`}>
8
8
  {children}
9
9
  </div>
10
10
  )
@@ -18,8 +18,8 @@ function Title({ children }) {
18
18
  return children
19
19
  }
20
20
 
21
- function Subtitle({ children, className }:{children: any, className?: string}) {
22
- return <p className={`subtitle ${className}`}>{children}</p>
21
+ function Subtitle({ children, className }: { children: any; className?: string }) {
22
+ return <p className={`subtitle ${className || ''}`}>{children}</p>
23
23
  }
24
24
 
25
25
  function Button({ children }) {
@@ -39,4 +39,4 @@ EmptyState.Subtitle = Subtitle
39
39
  EmptyState.Button = Button
40
40
  EmptyState.Loading = Loading
41
41
 
42
- export default EmptyState
42
+ export default EmptyState