@devtron-labs/devtron-fe-common-lib 0.0.48-beta-6 → 0.0.48-beta-7

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 (133) hide show
  1. package/.eslintignore +75 -0
  2. package/.eslintrc.js +84 -16
  3. package/.github/pull_request_template.md +25 -0
  4. package/.github/workflows/ci.yml +31 -0
  5. package/.github/workflows/release-package.yml +2 -3
  6. package/.husky/pre-commit +4 -0
  7. package/.lintstagedrc +5 -0
  8. package/.nvmrc +1 -0
  9. package/dist/Common/BreadCrumb/BreadCrumb.d.ts +1 -1
  10. package/dist/Common/BreadCrumb/BreadcrumbStore.d.ts +2 -2
  11. package/dist/Common/Common.service.d.ts +0 -1
  12. package/dist/Common/Constants.d.ts +1 -2
  13. package/dist/Common/CustomInput/CustomInput.d.ts +1 -1
  14. package/dist/Common/CustomInput/Types.d.ts +2 -1
  15. package/dist/Common/CustomTagSelector/ResizableTagTextArea.d.ts +1 -1
  16. package/dist/Common/DeleteComponentModal/DeleteComponent.d.ts +1 -1
  17. package/dist/Common/DevtronProgressing/DevtronProgressing.d.ts +1 -1
  18. package/dist/Common/Dialogs/ConfirmationDialog.d.ts +6 -6
  19. package/dist/Common/Dialogs/DeleteDialog.d.ts +1 -1
  20. package/dist/Common/Dialogs/ForceDeleteDialog.d.ts +1 -1
  21. package/dist/Common/Dialogs/Types.d.ts +1 -1
  22. package/dist/Common/EmptyState/EmptyState.d.ts +20 -17
  23. package/dist/Common/EmptyState/GenericEmptyState.d.ts +1 -1
  24. package/dist/Common/Error.d.ts +2 -1
  25. package/dist/Common/ErrorScreenNotFound.d.ts +1 -1
  26. package/dist/Common/Helper.d.ts +1 -10
  27. package/dist/Common/ImageTags.d.ts +1 -1
  28. package/dist/Common/InfoColorBar/InfoColourbar.d.ts +1 -1
  29. package/dist/Common/Modals/Modal.d.ts +2 -2
  30. package/dist/Common/Modals/OpaqueModal.d.ts +3 -3
  31. package/dist/Common/Modals/VisibleModal.d.ts +3 -3
  32. package/dist/Common/Modals/VisibleModal2.d.ts +3 -3
  33. package/dist/Common/MultiSelectCustomization.d.ts +1 -1
  34. package/dist/Common/Policy.Types.d.ts +2 -2
  35. package/dist/Common/PopupMenu.d.ts +5 -5
  36. package/dist/Common/Progressing.d.ts +2 -2
  37. package/dist/Common/RadioGroup/RadioGroup.d.ts +1 -1
  38. package/dist/Common/ResizableTextarea.d.ts +1 -1
  39. package/dist/Common/TippyCustomized.d.ts +1 -1
  40. package/dist/Common/ToastBody.d.ts +5 -5
  41. package/dist/Common/Types.d.ts +0 -64
  42. package/dist/Common/index.d.ts +0 -1
  43. package/dist/index.d.ts +1 -1
  44. package/dist/index.js +380 -2083
  45. package/package.json +19 -4
  46. package/src/Common/AddCDButton/AddCDButton.tsx +1 -2
  47. package/src/Common/Api.ts +21 -26
  48. package/src/Common/AppStatus/AppStatus.tsx +12 -12
  49. package/src/Common/AppStatus/utils.ts +6 -5
  50. package/src/Common/BreadCrumb/BreadCrumb.tsx +32 -28
  51. package/src/Common/BreadCrumb/BreadcrumbStore.tsx +2 -2
  52. package/src/Common/BreadCrumb/Types.ts +11 -12
  53. package/src/Common/Checkbox.tsx +17 -19
  54. package/src/Common/ClipboardButton/ClipboardButton.tsx +1 -1
  55. package/src/Common/ClipboardButton/__tests__/ClipboardButton.test.tsx +0 -1
  56. package/src/Common/Common.service.ts +59 -68
  57. package/src/Common/Constants.ts +9 -10
  58. package/src/Common/CustomInput/CustomInput.tsx +22 -28
  59. package/src/Common/CustomInput/Types.ts +4 -3
  60. package/src/Common/CustomInput/index.ts +1 -1
  61. package/src/Common/CustomTagSelector/PropagateTagInfo.tsx +15 -18
  62. package/src/Common/CustomTagSelector/ResizableTagTextArea.tsx +9 -9
  63. package/src/Common/CustomTagSelector/TagDetails.tsx +9 -3
  64. package/src/Common/CustomTagSelector/TagLabelSelect.tsx +7 -9
  65. package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +31 -35
  66. package/src/Common/CustomTagSelector/TagSelector.utils.ts +2 -3
  67. package/src/Common/CustomTagSelector/Types.ts +1 -1
  68. package/src/Common/CustomTagSelector/ValidationRules.ts +18 -22
  69. package/src/Common/CustomTagSelector/index.ts +2 -2
  70. package/src/Common/DebouncedSearch/DebouncedSearch.tsx +2 -1
  71. package/src/Common/DebouncedSearch/__tests__/DebouncedSearch.test.tsx +0 -1
  72. package/src/Common/DeleteComponentModal/DeleteComponent.tsx +27 -32
  73. package/src/Common/DeleteComponentModal/types.ts +1 -1
  74. package/src/Common/DevtronProgressing/DevtronProgressing.tsx +5 -8
  75. package/src/Common/Dialogs/ConfirmationDialog.tsx +24 -24
  76. package/src/Common/Dialogs/DeleteDialog.tsx +3 -5
  77. package/src/Common/Dialogs/DialogForm.tsx +31 -35
  78. package/src/Common/Dialogs/ForceDeleteDialog.tsx +13 -7
  79. package/src/Common/Dialogs/Types.ts +12 -12
  80. package/src/Common/Dialogs/index.ts +1 -1
  81. package/src/Common/Drawer/Drawer.tsx +1 -1
  82. package/src/Common/EmptyState/EmptyState.tsx +13 -17
  83. package/src/Common/EmptyState/GenericEmptyState.tsx +25 -15
  84. package/src/Common/Error.tsx +5 -5
  85. package/src/Common/ErrorScreenNotFound.tsx +9 -12
  86. package/src/Common/Grid/Grid.tsx +1 -2
  87. package/src/Common/Helper.tsx +23 -125
  88. package/src/Common/Hooks/UseClickOutside/UseClickOutside.tsx +1 -1
  89. package/src/Common/Hooks/UseSuperAdmin/UseSuperAdmin.tsx +1 -1
  90. package/src/Common/ImageTags.Types.ts +2 -3
  91. package/src/Common/ImageTags.tsx +61 -66
  92. package/src/Common/InfoColorBar/InfoColourbar.tsx +10 -5
  93. package/src/Common/Modals/Modal.tsx +3 -3
  94. package/src/Common/Modals/OpaqueModal.tsx +25 -18
  95. package/src/Common/Modals/VisibleModal.tsx +7 -3
  96. package/src/Common/Modals/VisibleModal2.tsx +20 -15
  97. package/src/Common/MultiSelectCustomization.tsx +9 -13
  98. package/src/Common/Policy.Types.ts +38 -38
  99. package/src/Common/PopupMenu.tsx +10 -9
  100. package/src/Common/Progressing.tsx +15 -18
  101. package/src/Common/RJSF/Form.tsx +0 -1
  102. package/src/Common/RJSF/common/FieldRow.tsx +0 -1
  103. package/src/Common/RJSF/config.ts +0 -1
  104. package/src/Common/RJSF/templates/ArrayFieldItemTemplate.tsx +1 -1
  105. package/src/Common/RJSF/templates/ArrayFieldTemplate.tsx +0 -1
  106. package/src/Common/RJSF/templates/BaseInput.tsx +0 -1
  107. package/src/Common/RJSF/templates/ButtonTemplates/AddButton.tsx +0 -1
  108. package/src/Common/RJSF/templates/ButtonTemplates/RemoveButton.tsx +0 -1
  109. package/src/Common/RJSF/templates/ButtonTemplates/SubmitButton.tsx +1 -6
  110. package/src/Common/RJSF/templates/Description.tsx +0 -1
  111. package/src/Common/RJSF/templates/Field.tsx +14 -3
  112. package/src/Common/RJSF/templates/FieldErrorTemplate.tsx +6 -9
  113. package/src/Common/RJSF/templates/ObjectFieldTemplate.tsx +5 -7
  114. package/src/Common/RJSF/templates/TitleField.tsx +0 -1
  115. package/src/Common/RJSF/templates/WrapIfAdditionalTemplate.tsx +0 -1
  116. package/src/Common/RJSF/utils.ts +53 -57
  117. package/src/Common/RJSF/widgets/Checkbox.tsx +2 -2
  118. package/src/Common/RJSF/widgets/Select.tsx +0 -1
  119. package/src/Common/RadioGroup/RadioGroup.tsx +18 -23
  120. package/src/Common/RadioGroup.tsx +24 -23
  121. package/src/Common/Reload.tsx +0 -1
  122. package/src/Common/ResizableTextarea.tsx +18 -17
  123. package/src/Common/Security/ScanVulnerabilitiesTable.tsx +29 -34
  124. package/src/Common/ServerError.ts +5 -1
  125. package/src/Common/TippyCustomized.tsx +41 -38
  126. package/src/Common/ToastBody.tsx +6 -7
  127. package/src/Common/Toggle/Toggle.tsx +3 -3
  128. package/src/Common/Types.ts +12 -81
  129. package/src/Common/index.ts +0 -1
  130. package/src/custom.d.ts +7 -7
  131. package/src/index.ts +1 -1
  132. package/dist/Common/ChartVersionAndTypeSelector.d.ts +0 -4
  133. package/src/Common/ChartVersionAndTypeSelector.tsx +0 -78
@@ -1,14 +1,13 @@
1
1
  import * as Sentry from '@sentry/browser'
2
2
  import moment from 'moment'
3
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
4
+ import * as React from 'react'
4
5
  import { useLocation } from 'react-router-dom'
5
6
  import { toast } from 'react-toastify'
6
7
  import { ERROR_EMPTY_SCREEN, TOKEN_COOKIE_NAME } from './Constants'
7
8
  import { ServerErrors } from './ServerError'
8
9
  import { toastAccessDenied } from './ToastBody'
9
10
  import { AsyncOptions, AsyncState, UseSearchString } from './Types'
10
- import { JSONPath } from 'jsonpath-plus'
11
- import * as jsonpatch from 'fast-json-patch'
12
11
 
13
12
  toast.configure({
14
13
  autoClose: 3000,
@@ -79,16 +78,19 @@ export const stopPropagation = (event): void => {
79
78
  }
80
79
 
81
80
  export function useThrottledEffect(callback, delay, deps = []) {
82
- //function will be executed only once in a given time interval.
81
+ // function will be executed only once in a given time interval.
83
82
  const lastRan = useRef(Date.now())
84
83
 
85
84
  useEffect(() => {
86
- const handler = setTimeout(function () {
87
- if (Date.now() - lastRan.current >= delay) {
88
- callback()
89
- lastRan.current = Date.now()
90
- }
91
- }, delay - (Date.now() - lastRan.current))
85
+ const handler = setTimeout(
86
+ () => {
87
+ if (Date.now() - lastRan.current >= delay) {
88
+ callback()
89
+ lastRan.current = Date.now()
90
+ }
91
+ },
92
+ delay - (Date.now() - lastRan.current),
93
+ )
92
94
 
93
95
  return () => {
94
96
  clearTimeout(handler)
@@ -117,7 +119,7 @@ export function getRandomColor(email: string): string {
117
119
  return colors[sum % colors.length]
118
120
  }
119
121
 
120
- export const getAlphabetIcon = (str: string, rootClassName: string = "") => {
122
+ export const getAlphabetIcon = (str: string, rootClassName: string = '') => {
121
123
  if (!str) return null
122
124
  return (
123
125
  <span
@@ -129,9 +131,7 @@ export const getAlphabetIcon = (str: string, rootClassName: string = "") => {
129
131
  )
130
132
  }
131
133
 
132
- export const getEmptyArrayOfLength = (length: number) => {
133
- return Array.from({ length })
134
- }
134
+ export const getEmptyArrayOfLength = (length: number) => Array.from({ length })
135
135
 
136
136
  export function noop(...args): any {}
137
137
 
@@ -155,7 +155,7 @@ export function getCookie(sKey) {
155
155
  }
156
156
  return (
157
157
  document.cookie.replace(
158
- new RegExp('(?:(?:^|.*;)\\s*' + sKey.replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'),
158
+ new RegExp(`(?:(?:^|.*;)\\s*${sKey.replace(/[\-\.\+\*]/g, '\\$&')}\\s*\\=\\s*([^;]*).*$)|^.*$`),
159
159
  '$1',
160
160
  ) || null
161
161
  )
@@ -198,7 +198,7 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
198
198
  // in every re-render in component
199
199
  const validateState = useCallback(
200
200
  (state) => {
201
- //check errors in all fields
201
+ // check errors in all fields
202
202
  const hasErrorInState = Object.keys(validationSchema).some((key) => {
203
203
  const isInputFieldRequired = validationSchema[key].required
204
204
  const stateValue = state[key].value // state value
@@ -225,7 +225,7 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
225
225
  }
226
226
 
227
227
  // single validator
228
- let _validator = validationSchema[name].validator
228
+ const _validator = validationSchema[name].validator
229
229
  if (_validator && typeof _validator === 'object') {
230
230
  if (!_validateSingleValidator(_validator, value)) {
231
231
  return _validator.error
@@ -233,9 +233,9 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
233
233
  }
234
234
 
235
235
  // multiple validators
236
- let _validators = validationSchema[name].validators
236
+ const _validators = validationSchema[name].validators
237
237
  if (_validators && typeof _validators === 'object' && Array.isArray(_validators)) {
238
- let errors = []
238
+ const errors = []
239
239
  _validators.forEach((_validator) => {
240
240
  if (!_validateSingleValidator(_validator, value)) {
241
241
  errors.push(_validator.error)
@@ -254,7 +254,7 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
254
254
  setIsDirty(true)
255
255
 
256
256
  const { name, value } = event.target
257
- let error = validateField(name, value)
257
+ const error = validateField(name, value)
258
258
  setState((prevState) => ({
259
259
  ...prevState,
260
260
  [name]: { value, error },
@@ -282,7 +282,7 @@ export function handleUTCTime(ts: string, isRelativeTime = false) {
282
282
  let timestamp = ''
283
283
  try {
284
284
  if (ts && ts.length) {
285
- let date = moment(ts)
285
+ const date = moment(ts)
286
286
  if (isRelativeTime) timestamp = date.fromNow()
287
287
  else timestamp = date.format('ddd DD MMM YYYY HH:mm:ss')
288
288
  }
@@ -366,9 +366,7 @@ export function useAsync<T>(
366
366
  dependencies: dependencyArray,
367
367
  })
368
368
  const mounted = useRef(true)
369
- const dependencies: any[] = useMemo(() => {
370
- return [...dependencyArray, shouldRun]
371
- }, [...dependencyArray, shouldRun])
369
+ const dependencies: any[] = useMemo(() => [...dependencyArray, shouldRun], [...dependencyArray, shouldRun])
372
370
 
373
371
  const reload = () => {
374
372
  async function call() {
@@ -434,9 +432,8 @@ export function useAsync<T>(
434
432
  export const processDeployedTime = (lastDeployed, isArgoInstalled) => {
435
433
  if (lastDeployed) {
436
434
  return handleUTCTime(lastDeployed, true)
437
- } else {
438
- return isArgoInstalled ? '' : 'Not deployed'
439
435
  }
436
+ return isArgoInstalled ? '' : 'Not deployed'
440
437
  }
441
438
 
442
439
  /**
@@ -460,102 +457,3 @@ export const getUrlWithSearchParams = (url: string, params: Record<string | numb
460
457
  * Custom exception logger function for logging errors to sentry
461
458
  */
462
459
  export const logExceptionToSentry = Sentry.captureException.bind(window)
463
-
464
- export const customStyles = {
465
- control: (base, state) => ({
466
- ...base,
467
- minHeight: '32px',
468
- boxShadow: 'none',
469
- border: 'none',
470
- cursor: 'pointer',
471
- background: 'transparent',
472
- }),
473
- indicatorSeparator: (base, state) => ({
474
- ...base,
475
- width: 0,
476
- }),
477
- valueContainer: (base, state) => ({
478
- ...base,
479
- padding: '0',
480
- fontSize: '13px',
481
- fontWeight: '600',
482
- }),
483
- dropdownIndicator: (base, state) => ({
484
- ...base,
485
- color: 'var(--N400)',
486
- padding: '0 8px',
487
- transition: 'all .2s ease',
488
- transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : 'rotate(0deg)',
489
- }),
490
- }
491
-
492
- export const getFilteredChartVersions = (charts, selectedChartType) => {
493
- // Filter chart versions based on selected chart type
494
- return charts
495
- .filter((item) => item?.chartType === selectedChartType.value)
496
- .map((item) => ({
497
- value: item?.chartVersion,
498
- label: item?.chartVersion,
499
- chartRefId: item.chartRefId,
500
- }))
501
- }
502
- function removeEmptyObjectKeysAndNullValues(obj) {
503
- // It recursively removes empty object keys and array values that are null
504
- for (let key in obj) {
505
- if (Array.isArray(obj[key])) {
506
- if (obj[key].length === 0) continue
507
- obj[key] = obj[key].filter((item) => item !== null)
508
- // Check if the array is empty
509
- if (obj[key].length === 0) {
510
- delete obj[key] // Delete the key if the array is empty
511
- }
512
- } else if (obj[key] && typeof obj[key] === 'object') {
513
- if (removeEmptyObjectKeysAndNullValues(obj[key])) {
514
- delete obj[key]
515
- }
516
- } else if (obj[key] === undefined) {
517
- delete obj[key]
518
- }
519
- }
520
- return Object.keys(obj).length === 0
521
- }
522
-
523
- export function getUnlockedJSON(json, jsonPathArray) {
524
- const jsonCopy = JSON.parse(JSON.stringify(json))
525
- let patches = jsonPathArray.flatMap((jsonPath) => {
526
- const pathsToRemove = JSONPath({ path: jsonPath, json: jsonCopy, resultType: 'all' })
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
- )
532
- })
533
- let newDocument = jsonpatch.applyPatch(jsonCopy, patches).newDocument
534
-
535
- removeEmptyObjectKeysAndNullValues(newDocument)
536
- return newDocument
537
- }
538
-
539
- export function getLockedJSON(json, jsonPathArray: string[]) {
540
- const jsonCopy = JSON.parse(JSON.stringify(json))
541
- let resultJson = {}
542
- jsonPathArray.forEach((jsonPath) => {
543
- const elements = JSONPath({ path: jsonPath, json: jsonCopy, resultType: 'all' })
544
- elements.forEach((element) => {
545
- const pathArray: string[] = JSONPath.toPathArray(element.path)
546
- const lastPath = pathArray.pop()
547
- let current = resultJson
548
- for (let i = 0; i < pathArray.length; i++) {
549
- let key = isNaN(Number(pathArray[i])) ? pathArray[i] : parseInt(pathArray[i])
550
- if (!current[key]) {
551
- current[key] = isNaN(Number(pathArray[i + 1])) ? {} : []
552
- }
553
- current = current[key]
554
- }
555
- let key = isNaN(Number(lastPath)) ? lastPath : parseInt(lastPath)
556
- current[key] = element.value
557
- })
558
- })
559
- return resultJson['$']
560
- }
561
-
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react'
1
+ import { useEffect } from 'react'
2
2
 
3
3
  export const useClickOutside = (ref: any, callback: () => void) => {
4
4
  useEffect(() => {
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react'
1
+ import { useEffect, useState } from 'react'
2
2
  import { getUserRole } from '../../Common.service'
3
3
  import { useSuperAdminType } from './types'
4
4
  import { showError } from '../../Helper'
@@ -13,13 +13,12 @@ export interface ImageComment {
13
13
  artifactId: number
14
14
  }
15
15
 
16
-
17
16
  export interface ImageTaggingContainerType {
18
17
  ciPipelineId?: number
19
18
  artifactId?: number
20
19
  imageComment?: ImageComment
21
20
  imageReleaseTags?: ReleaseTag[]
22
- updateCurrentAppMaterial? : (matId:number, releaseTags?:ReleaseTag[], imageComment?:ImageComment) => void
21
+ updateCurrentAppMaterial?: (matId: number, releaseTags?: ReleaseTag[], imageComment?: ImageComment) => void
23
22
  appReleaseTagNames?: string[]
24
23
  tagsEditable?: boolean
25
24
  forceReInit?: boolean
@@ -41,4 +40,4 @@ export interface ImageButtonType {
41
40
  isSuperAdmin: any
42
41
  duplicateTag?: boolean
43
42
  hideHardDelete?: boolean
44
- }
43
+ }
@@ -1,4 +1,6 @@
1
- import React, { useEffect, useMemo, useRef, useState } from 'react'
1
+ import { useEffect, useMemo, useRef, useState } from 'react'
2
+ import { toast } from 'react-toastify'
3
+ import Tippy from '@tippyjs/react'
2
4
  import { ReactComponent as Add } from '../Assets/Icon/ic-add.svg'
3
5
  import { ReactComponent as Close } from '../Assets/Icon/ic-cross.svg'
4
6
  import { ReactComponent as QuestionFilled } from '../Assets/Icon/ic-help.svg'
@@ -7,7 +9,6 @@ import { ReactComponent as Question } from '../Assets/Icon/ic-help-outline.svg'
7
9
  import { ReactComponent as EditIcon } from '../Assets/Icon/ic-pencil.svg'
8
10
  import { ReactComponent as Redo } from '../Assets/Icon/ic-arrow-counter-clockwise.svg'
9
11
  import { ReactComponent as Minus } from '../Assets/Icon/ic-minus.svg'
10
- import { toast } from 'react-toastify'
11
12
  import { ReactComponent as Info } from '../Assets/Icon/ic-info-filled.svg'
12
13
  import { ReactComponent as Error } from '../Assets/Icon/ic-warning.svg'
13
14
  import { ReactComponent as Warning } from '../Assets/Icon/ic-error-exclamation.svg'
@@ -17,7 +18,6 @@ import { ImageButtonType, ImageTaggingContainerType, ReleaseTag } from './ImageT
17
18
  import { showError, stopPropagation } from './Helper'
18
19
  import { TippyCustomized } from './TippyCustomized'
19
20
  import { setImageTags } from './Common.service'
20
- import Tippy from '@tippyjs/react'
21
21
  import { Progressing } from './Progressing'
22
22
 
23
23
  export const ImageTagsContainer = ({
@@ -34,15 +34,15 @@ export const ImageTagsContainer = ({
34
34
  toggleCardMode,
35
35
  hideHardDelete,
36
36
  forceReInit,
37
- isSuperAdmin
37
+ isSuperAdmin,
38
38
  }: ImageTaggingContainerType) => {
39
- const [initialTags, setInitialTags] = useState<ReleaseTag[]>(imageReleaseTags ? imageReleaseTags : [])
39
+ const [initialTags, setInitialTags] = useState<ReleaseTag[]>(imageReleaseTags || [])
40
40
  const [initialDescription, setInitialDescription] = useState(imageComment ? imageComment.comment : '')
41
- const [existingTags, setExistingTags] = useState(appReleaseTagNames ? appReleaseTagNames : [])
41
+ const [existingTags, setExistingTags] = useState(appReleaseTagNames || [])
42
42
  const [newDescription, setNewDescription] = useState(imageComment ? imageComment.comment : '')
43
43
  const [isEditing, setIsEditing] = useState(false)
44
44
  const [showTagsWarning, setShowTagsWarning] = useState(false)
45
- const [displayedTags, setDisplayedTags] = useState<ReleaseTag[]>(imageReleaseTags ? imageReleaseTags : [])
45
+ const [displayedTags, setDisplayedTags] = useState<ReleaseTag[]>(imageReleaseTags || [])
46
46
  const [tagErrorMessage, setTagErrorMessage] = useState('')
47
47
  const [createTags, setCreateTags] = useState<ReleaseTag[]>([])
48
48
  const [softDeleteTags, setSoftDeleteTags] = useState<ReleaseTag[]>([])
@@ -51,22 +51,20 @@ export const ImageTagsContainer = ({
51
51
  const [textInput, setTextInput] = useState<string>('')
52
52
  const [loading, setLoading] = useState<boolean>(false)
53
53
 
54
-
55
54
  useEffect(() => {
56
55
  reInitState()
57
56
  }, [imageReleaseTags, imageComment, tagsEditable])
58
57
 
59
58
  useEffect(() => {
60
- setExistingTags(appReleaseTagNames ? appReleaseTagNames : [])
59
+ setExistingTags(appReleaseTagNames || [])
61
60
  }, [appReleaseTagNames])
62
61
 
63
-
64
62
  const reInitState = () => {
65
63
  if (forceReInit || !isEditing) {
66
- setInitialTags(imageReleaseTags ? imageReleaseTags : [])
64
+ setInitialTags(imageReleaseTags || [])
67
65
  setInitialDescription(imageComment ? imageComment.comment : '')
68
66
  setNewDescription(imageComment ? imageComment.comment : '')
69
- setDisplayedTags(imageReleaseTags ? imageReleaseTags : [])
67
+ setDisplayedTags(imageReleaseTags || [])
70
68
  setIsEditing(false)
71
69
  }
72
70
  }
@@ -97,7 +95,7 @@ export const ImageTagsContainer = ({
97
95
  setTagErrorMessage('')
98
96
  }
99
97
 
100
- const validateTag = (lowercaseValue) : boolean => {
98
+ const validateTag = (lowercaseValue): boolean => {
101
99
  if (
102
100
  lowercaseValue.length == 0 ||
103
101
  lowercaseValue.length >= 128 ||
@@ -120,9 +118,9 @@ export const ImageTagsContainer = ({
120
118
  return true
121
119
  }
122
120
 
123
- const handleTagCreate = (newValue) : ReleaseTag[] => {
121
+ const handleTagCreate = (newValue): ReleaseTag[] => {
124
122
  const lowercaseValue = newValue.toLowerCase().trim()
125
- if(validateTag(lowercaseValue)) {
123
+ if (validateTag(lowercaseValue)) {
126
124
  const newTag: ReleaseTag = {
127
125
  id: 0,
128
126
  tagName: lowercaseValue,
@@ -148,7 +146,7 @@ export const ImageTagsContainer = ({
148
146
  deleted: !updatedTags[index].deleted,
149
147
  }
150
148
  const updatedTag = updatedTags[index]
151
- let updatedSoftDeleteTags = [...softDeleteTags]
149
+ const updatedSoftDeleteTags = [...softDeleteTags]
152
150
  const tagIndex = updatedSoftDeleteTags.findIndex((tag) => tag.tagName === updatedTag.tagName)
153
151
  if (tagIndex !== -1) {
154
152
  // Tag already exists in softDeleteTags array, remove it
@@ -206,13 +204,13 @@ export const ImageTagsContainer = ({
206
204
 
207
205
  const payload = {
208
206
  createTags: tagsToBeCreated,
209
- softDeleteTags: softDeleteTags,
207
+ softDeleteTags,
210
208
  imageComment: {
211
209
  id: 0,
212
210
  comment: newDescription.trim(),
213
211
  artifactId: 0,
214
212
  },
215
- hardDeleteTags: hardDeleteTags,
213
+ hardDeleteTags,
216
214
  }
217
215
 
218
216
  // set loading state true
@@ -242,7 +240,7 @@ export const ImageTagsContainer = ({
242
240
  handleEditClick()
243
241
  setShowTagsWarning(false)
244
242
  setTagErrorMessage('')
245
- if(updateCurrentAppMaterial)updateCurrentAppMaterial(artifactId,tags,res.result?.imageComment)
243
+ if (updateCurrentAppMaterial) updateCurrentAppMaterial(artifactId, tags, res.result?.imageComment)
246
244
  })
247
245
  .catch((err) => {
248
246
  // Fix toast message
@@ -253,50 +251,45 @@ export const ImageTagsContainer = ({
253
251
  showError(err)
254
252
  }
255
253
  })
256
- .finally(()=>{
254
+ .finally(() => {
257
255
  setLoading(false)
258
256
  })
259
257
  }
260
258
 
261
- const renderInfoCard = (): JSX.Element => {
262
- return (
263
- <TippyCustomized
264
- theme={TippyTheme.white}
265
- className="w-300 fcv-5"
266
- placement="right"
267
- Icon={QuestionFilled}
268
- heading="Release tags"
269
- showCloseButton={true}
270
- trigger="click"
271
- interactive={true}
272
- additionalContent={getBuildContextAdditionalContent()}
273
- >
274
- <div className="flex">
275
- <Question className="fcn-5 ml-8 cursor icon-dim-16"/>
276
- </div>
277
- </TippyCustomized>
278
- )
279
- }
280
-
281
- const getBuildContextAdditionalContent = () => {
282
- return (
283
- <div className="h-250 fs-13 dc__overflow-scroll p-12">
284
- <div>Release tags allow you to tag container images with readable and relatable tags eg. v1.0.</div>
285
- <ul className="pl-20 mt-8">
286
- <li>
287
- A release tag can only be added if a workflow has CD pipelines deploying to Production
288
- environments.
289
- </li>
290
- <li>Multiple tags can be added to an image.</li>
291
- <li>Multiple images in an application cannot have the same tag.</li>
292
- <li>
293
- Tags cannot be deleted once saved. Although, you can soft delete a tag if an unwanted tag has
294
- been added.
295
- </li>
296
- </ul>
259
+ const renderInfoCard = (): JSX.Element => (
260
+ <TippyCustomized
261
+ theme={TippyTheme.white}
262
+ className="w-300 fcv-5"
263
+ placement="right"
264
+ Icon={QuestionFilled}
265
+ heading="Release tags"
266
+ showCloseButton
267
+ trigger="click"
268
+ interactive
269
+ additionalContent={getBuildContextAdditionalContent()}
270
+ >
271
+ <div className="flex">
272
+ <Question className="fcn-5 ml-8 cursor icon-dim-16" />
297
273
  </div>
298
- )
299
- }
274
+ </TippyCustomized>
275
+ )
276
+
277
+ const getBuildContextAdditionalContent = () => (
278
+ <div className="h-250 fs-13 dc__overflow-scroll p-12">
279
+ <div>Release tags allow you to tag container images with readable and relatable tags eg. v1.0.</div>
280
+ <ul className="pl-20 mt-8">
281
+ <li>
282
+ A release tag can only be added if a workflow has CD pipelines deploying to Production environments.
283
+ </li>
284
+ <li>Multiple tags can be added to an image.</li>
285
+ <li>Multiple images in an application cannot have the same tag.</li>
286
+ <li>
287
+ Tags cannot be deleted once saved. Although, you can soft delete a tag if an unwanted tag has been
288
+ added.
289
+ </li>
290
+ </ul>
291
+ </div>
292
+ )
300
293
 
301
294
  const creatableRef = useRef(null)
302
295
 
@@ -306,7 +299,7 @@ export const ImageTagsContainer = ({
306
299
  <AddImageButton handleEditClick={handleEditClick} />
307
300
  </div>
308
301
  ) : (
309
- <div></div>
302
+ <div />
310
303
  )
311
304
  }
312
305
 
@@ -456,8 +449,10 @@ export const ImageTagsContainer = ({
456
449
  className="flex left image-tag-left-border w-100 mt-8 mb-8 pr-10 pl-10"
457
450
  data-testid="image-tags-container-hover"
458
451
  >
459
- <div className='w-100'>
460
- {initialDescription && <div className="mb-6 fs-13 lh-20 dc__word-break-all">{initialDescription}</div>}
452
+ <div className="w-100">
453
+ {initialDescription && (
454
+ <div className="mb-6 fs-13 lh-20 dc__word-break-all">{initialDescription}</div>
455
+ )}
461
456
  <div className="flex-wrap flex left">
462
457
  {initialTags?.map((tag, index) => (
463
458
  <ImageTagButton
@@ -520,11 +515,11 @@ export const ImageTagButton = ({
520
515
  const tabColor = () => {
521
516
  if (duplicateTag) {
522
517
  return 'cr-5 bcr-1 er-2'
523
- } else if (isSoftDeleted) {
518
+ }
519
+ if (isSoftDeleted) {
524
520
  return 'cy-7 bcy-1 dc__strike-through ey-2'
525
- } else {
526
- return 'cn-9'
527
521
  }
522
+ return 'cn-9'
528
523
  }
529
524
 
530
525
  return (
@@ -538,7 +533,7 @@ export const ImageTagButton = ({
538
533
  ) : (
539
534
  <Tippy
540
535
  className="default-tt"
541
- arrow={true}
536
+ arrow
542
537
  placement="top"
543
538
  content={isInSoftDeleteTags ? 'Restore tag' : 'Soft delete tag'}
544
539
  >
@@ -556,7 +551,7 @@ export const ImageTagButton = ({
556
551
  </Tippy>
557
552
  )}
558
553
  {text}
559
- <Tippy className="default-tt" arrow={true} placement="top" content="Remove tag">
554
+ <Tippy className="default-tt" arrow placement="top" content="Remove tag">
560
555
  <div className={`action-icon ml-4 lh-16 pt-3 ${canTagBeHardDelete ? 'show-icon' : ''}`}>
561
556
  <Close
562
557
  className="icon-dim-12 fcn-6 cursor"
@@ -1,9 +1,8 @@
1
- import React from 'react'
2
1
  import { Link } from 'react-router-dom'
3
2
  import { InfoColourBarType } from '../Types'
4
3
  import './infoColourBar.scss'
5
4
 
6
- function InfoColourBar({
5
+ const InfoColourBar = ({
7
6
  message,
8
7
  classname,
9
8
  Icon,
@@ -16,11 +15,12 @@ function InfoColourBar({
16
15
  linkClass,
17
16
  internalLink,
18
17
  styles,
19
- }: InfoColourBarType) {
18
+ }: InfoColourBarType) => {
20
19
  const renderLink = () => {
21
20
  if (!linkText) {
22
21
  return null
23
- } else if (redirectLink) {
22
+ }
23
+ if (redirectLink) {
24
24
  if (internalLink) {
25
25
  return (
26
26
  <Link
@@ -41,6 +41,7 @@ function InfoColourBar({
41
41
  onClick={linkOnClick}
42
42
  data-testid="info-bar-redirectLink"
43
43
  className="cursor dc__link dc__underline-onhover mr-5"
44
+ rel="noreferrer"
44
45
  >
45
46
  {linkText}
46
47
  </a>
@@ -49,7 +50,11 @@ function InfoColourBar({
49
50
 
50
51
  return (
51
52
  linkOnClick && (
52
- <div onClick={linkOnClick} className="cursor dc__link dc__underline-onhover" data-testid="info-bar-linkText">
53
+ <div
54
+ onClick={linkOnClick}
55
+ className="cursor dc__link dc__underline-onhover"
56
+ data-testid="info-bar-linkText"
57
+ >
53
58
  {linkText}
54
59
  </div>
55
60
  )
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react'
1
+ import { useRef, useEffect } from 'react'
2
2
  import ReactDOM from 'react-dom'
3
3
  import { ModalType } from '../Types'
4
4
 
@@ -12,7 +12,7 @@ export const Modal = ({
12
12
  preventWheelDisable = false,
13
13
  noBackDrop,
14
14
  }: ModalType) => {
15
- const innerRef = React.useRef(null)
15
+ const innerRef = useRef(null)
16
16
  function handleClick(e) {
17
17
  if (typeof onClick !== 'function') return
18
18
  if (innerRef && innerRef.current?.contains(e.target)) {
@@ -35,7 +35,7 @@ export const Modal = ({
35
35
  }
36
36
  useEffect(() => {
37
37
  document.addEventListener('click', handleClick)
38
- let modal = document.getElementById('visible-modal')
38
+ const modal = document.getElementById('visible-modal')
39
39
  if (modal) modal.classList.add('show')
40
40
  if (noBackDrop) modal.classList.add('no-back-drop')
41
41
  if (!preventWheelDisable) document.body.addEventListener('wheel', disableWheel, { passive: false })
@@ -1,36 +1,43 @@
1
- import React from 'react'
2
- import ReactDOM from 'react-dom';
1
+ import { Component } from 'react'
2
+ import ReactDOM from 'react-dom'
3
3
  import closeIcon from '../../Assets/Icon/ic-cross.svg'
4
4
 
5
5
  export interface OpaqueModalProps {
6
- className?: string;
7
- onHide?: any;
8
- noBackground?: boolean;
6
+ className?: string
7
+ onHide?: any
8
+ noBackground?: boolean
9
9
  }
10
10
 
11
- export class OpaqueModal extends React.Component<OpaqueModalProps> {
12
- modalRef = document.getElementById('full-screen-modal');
11
+ export class OpaqueModal extends Component<OpaqueModalProps> {
12
+ modalRef = document.getElementById('full-screen-modal')
13
13
 
14
14
  componentDidMount() {
15
- if (this.props.noBackground)
16
- this.modalRef.classList.add("show");
17
- else this.modalRef.classList.add("show-with-bg");
15
+ if (this.props.noBackground) this.modalRef.classList.add('show')
16
+ else this.modalRef.classList.add('show-with-bg')
18
17
  }
19
18
 
20
19
  componentWillUnmount() {
21
- this.modalRef.classList.remove("show");
22
- this.modalRef.classList.remove("show-with-bg");
20
+ this.modalRef.classList.remove('show')
21
+ this.modalRef.classList.remove('show-with-bg')
23
22
  }
24
23
 
25
24
  render() {
26
- const { className = "", onHide = null } = { ...this.props };
25
+ const { className = '', onHide = null } = { ...this.props }
27
26
 
28
27
  return ReactDOM.createPortal(
29
28
  <div className={`full-screen-modal__body-container ${className}`}>
30
29
  {this.props.children}
31
- {typeof onHide === 'function' && <div className="close-btn icon-dim-24" onClick={e => onHide(false)} data-testid="opaque-modal-close">
32
- <img className="close-img" src={closeIcon} alt="close" />
33
- </div>}
34
- </div>, document.getElementById('full-screen-modal'))
30
+ {typeof onHide === 'function' && (
31
+ <div
32
+ className="close-btn icon-dim-24"
33
+ onClick={(e) => onHide(false)}
34
+ data-testid="opaque-modal-close"
35
+ >
36
+ <img className="close-img" src={closeIcon} alt="close" />
37
+ </div>
38
+ )}
39
+ </div>,
40
+ document.getElementById('full-screen-modal'),
41
+ )
35
42
  }
36
- }
43
+ }