@devtron-labs/devtron-fe-common-lib 0.0.52-beta-2 → 0.0.52-beta-3

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 (130) hide show
  1. package/.eslintignore +79 -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 +5 -0
  7. package/.lintstagedrc +3 -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/Constants.d.ts +1 -5
  12. package/dist/Common/CustomInput/CustomInput.d.ts +1 -1
  13. package/dist/Common/CustomInput/Types.d.ts +2 -2
  14. package/dist/Common/CustomTagSelector/ResizableTagTextArea.d.ts +1 -1
  15. package/dist/Common/DeleteComponentModal/DeleteComponent.d.ts +1 -1
  16. package/dist/Common/DevtronProgressing/DevtronProgressing.d.ts +1 -1
  17. package/dist/Common/Dialogs/ConfirmationDialog.d.ts +6 -6
  18. package/dist/Common/Dialogs/DeleteDialog.d.ts +1 -1
  19. package/dist/Common/Dialogs/ForceDeleteDialog.d.ts +1 -1
  20. package/dist/Common/Dialogs/Types.d.ts +1 -1
  21. package/dist/Common/EmptyState/EmptyState.d.ts +20 -17
  22. package/dist/Common/EmptyState/GenericEmptyState.d.ts +1 -1
  23. package/dist/Common/Error.d.ts +2 -1
  24. package/dist/Common/ErrorScreenNotFound.d.ts +1 -1
  25. package/dist/Common/Helper.d.ts +1 -1
  26. package/dist/Common/ImageTags.d.ts +1 -1
  27. package/dist/Common/InfoColorBar/InfoColourbar.d.ts +1 -1
  28. package/dist/Common/Modals/Modal.d.ts +2 -2
  29. package/dist/Common/Modals/OpaqueModal.d.ts +3 -3
  30. package/dist/Common/Modals/VisibleModal.d.ts +3 -3
  31. package/dist/Common/Modals/VisibleModal2.d.ts +3 -3
  32. package/dist/Common/MultiSelectCustomization.d.ts +1 -1
  33. package/dist/Common/Policy.Types.d.ts +2 -2
  34. package/dist/Common/PopupMenu.d.ts +5 -5
  35. package/dist/Common/Progressing.d.ts +2 -2
  36. package/dist/Common/RadioGroup/RadioGroup.d.ts +1 -1
  37. package/dist/Common/ResizableTextarea.d.ts +1 -1
  38. package/dist/Common/TippyCustomized.d.ts +1 -1
  39. package/dist/Common/ToastBody.d.ts +5 -5
  40. package/dist/Common/Types.d.ts +0 -1
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.js +286 -370
  43. package/package.json +19 -2
  44. package/src/Common/AddCDButton/AddCDButton.tsx +1 -2
  45. package/src/Common/Api.ts +20 -25
  46. package/src/Common/AppStatus/AppStatus.tsx +12 -12
  47. package/src/Common/AppStatus/utils.ts +6 -5
  48. package/src/Common/BreadCrumb/BreadCrumb.tsx +32 -28
  49. package/src/Common/BreadCrumb/BreadcrumbStore.tsx +2 -2
  50. package/src/Common/BreadCrumb/Types.ts +11 -12
  51. package/src/Common/ChartVersionAndTypeSelector.tsx +1 -1
  52. package/src/Common/Checkbox.tsx +17 -19
  53. package/src/Common/ClipboardButton/ClipboardButton.tsx +1 -1
  54. package/src/Common/ClipboardButton/__tests__/ClipboardButton.test.tsx +0 -1
  55. package/src/Common/Common.service.ts +60 -65
  56. package/src/Common/Constants.ts +9 -13
  57. package/src/Common/CustomInput/CustomInput.tsx +22 -29
  58. package/src/Common/CustomInput/Types.ts +4 -4
  59. package/src/Common/CustomInput/index.ts +1 -1
  60. package/src/Common/CustomTagSelector/PropagateTagInfo.tsx +15 -18
  61. package/src/Common/CustomTagSelector/ResizableTagTextArea.tsx +9 -9
  62. package/src/Common/CustomTagSelector/TagDetails.tsx +9 -3
  63. package/src/Common/CustomTagSelector/TagLabelSelect.tsx +7 -9
  64. package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +31 -35
  65. package/src/Common/CustomTagSelector/TagSelector.utils.ts +2 -3
  66. package/src/Common/CustomTagSelector/Types.ts +1 -1
  67. package/src/Common/CustomTagSelector/ValidationRules.ts +18 -22
  68. package/src/Common/CustomTagSelector/index.ts +2 -2
  69. package/src/Common/DebouncedSearch/DebouncedSearch.tsx +2 -1
  70. package/src/Common/DebouncedSearch/__tests__/DebouncedSearch.test.tsx +0 -1
  71. package/src/Common/DeleteComponentModal/DeleteComponent.tsx +27 -32
  72. package/src/Common/DeleteComponentModal/types.ts +1 -1
  73. package/src/Common/DevtronProgressing/DevtronProgressing.tsx +5 -8
  74. package/src/Common/Dialogs/ConfirmationDialog.tsx +24 -24
  75. package/src/Common/Dialogs/DeleteDialog.tsx +3 -5
  76. package/src/Common/Dialogs/DialogForm.tsx +31 -35
  77. package/src/Common/Dialogs/ForceDeleteDialog.tsx +13 -7
  78. package/src/Common/Dialogs/Types.ts +12 -12
  79. package/src/Common/Dialogs/index.ts +1 -1
  80. package/src/Common/Drawer/Drawer.tsx +1 -1
  81. package/src/Common/EmptyState/EmptyState.tsx +13 -17
  82. package/src/Common/EmptyState/GenericEmptyState.tsx +7 -29
  83. package/src/Common/Error.tsx +5 -5
  84. package/src/Common/ErrorScreenNotFound.tsx +9 -12
  85. package/src/Common/Grid/Grid.tsx +1 -2
  86. package/src/Common/Helper.tsx +36 -37
  87. package/src/Common/Hooks/UseClickOutside/UseClickOutside.tsx +1 -1
  88. package/src/Common/Hooks/UseSuperAdmin/UseSuperAdmin.tsx +1 -1
  89. package/src/Common/Hooks/UseWindowSize/UseWindowSize.tsx +5 -7
  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 +19 -20
  129. package/src/custom.d.ts +7 -7
  130. package/src/index.ts +1 -1
@@ -1,14 +1,15 @@
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'
7
+ import { JSONPath } from 'jsonpath-plus'
8
+ import * as jsonpatch from 'fast-json-patch'
6
9
  import { ERROR_EMPTY_SCREEN, TOKEN_COOKIE_NAME } from './Constants'
7
10
  import { ServerErrors } from './ServerError'
8
11
  import { toastAccessDenied } from './ToastBody'
9
12
  import { AsyncOptions, AsyncState, UseSearchString } from './Types'
10
- import { JSONPath } from 'jsonpath-plus'
11
- import * as jsonpatch from 'fast-json-patch'
12
13
 
13
14
  toast.configure({
14
15
  autoClose: 3000,
@@ -79,16 +80,19 @@ export const stopPropagation = (event): void => {
79
80
  }
80
81
 
81
82
  export function useThrottledEffect(callback, delay, deps = []) {
82
- //function will be executed only once in a given time interval.
83
+ // function will be executed only once in a given time interval.
83
84
  const lastRan = useRef(Date.now())
84
85
 
85
86
  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))
87
+ const handler = setTimeout(
88
+ () => {
89
+ if (Date.now() - lastRan.current >= delay) {
90
+ callback()
91
+ lastRan.current = Date.now()
92
+ }
93
+ },
94
+ delay - (Date.now() - lastRan.current),
95
+ )
92
96
 
93
97
  return () => {
94
98
  clearTimeout(handler)
@@ -117,7 +121,7 @@ export function getRandomColor(email: string): string {
117
121
  return colors[sum % colors.length]
118
122
  }
119
123
 
120
- export const getAlphabetIcon = (str: string, rootClassName: string = "") => {
124
+ export const getAlphabetIcon = (str: string, rootClassName: string = '') => {
121
125
  if (!str) return null
122
126
  return (
123
127
  <span
@@ -129,9 +133,7 @@ export const getAlphabetIcon = (str: string, rootClassName: string = "") => {
129
133
  )
130
134
  }
131
135
 
132
- export const getEmptyArrayOfLength = (length: number) => {
133
- return Array.from({ length })
134
- }
136
+ export const getEmptyArrayOfLength = (length: number) => Array.from({ length })
135
137
 
136
138
  export function noop(...args): any {}
137
139
 
@@ -155,7 +157,7 @@ export function getCookie(sKey) {
155
157
  }
156
158
  return (
157
159
  document.cookie.replace(
158
- new RegExp('(?:(?:^|.*;)\\s*' + sKey.replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'),
160
+ new RegExp(`(?:(?:^|.*;)\\s*${sKey.replace(/[\-\.\+\*]/g, '\\$&')}\\s*\\=\\s*([^;]*).*$)|^.*$`),
159
161
  '$1',
160
162
  ) || null
161
163
  )
@@ -198,7 +200,7 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
198
200
  // in every re-render in component
199
201
  const validateState = useCallback(
200
202
  (state) => {
201
- //check errors in all fields
203
+ // check errors in all fields
202
204
  const hasErrorInState = Object.keys(validationSchema).some((key) => {
203
205
  const isInputFieldRequired = validationSchema[key].required
204
206
  const stateValue = state[key].value // state value
@@ -225,7 +227,7 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
225
227
  }
226
228
 
227
229
  // single validator
228
- let _validator = validationSchema[name].validator
230
+ const _validator = validationSchema[name].validator
229
231
  if (_validator && typeof _validator === 'object') {
230
232
  if (!_validateSingleValidator(_validator, value)) {
231
233
  return _validator.error
@@ -233,9 +235,9 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
233
235
  }
234
236
 
235
237
  // multiple validators
236
- let _validators = validationSchema[name].validators
238
+ const _validators = validationSchema[name].validators
237
239
  if (_validators && typeof _validators === 'object' && Array.isArray(_validators)) {
238
- let errors = []
240
+ const errors = []
239
241
  _validators.forEach((_validator) => {
240
242
  if (!_validateSingleValidator(_validator, value)) {
241
243
  errors.push(_validator.error)
@@ -254,7 +256,7 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
254
256
  setIsDirty(true)
255
257
 
256
258
  const { name, value } = event.target
257
- let error = validateField(name, value)
259
+ const error = validateField(name, value)
258
260
  setState((prevState) => ({
259
261
  ...prevState,
260
262
  [name]: { value, error },
@@ -282,7 +284,7 @@ export function handleUTCTime(ts: string, isRelativeTime = false) {
282
284
  let timestamp = ''
283
285
  try {
284
286
  if (ts && ts.length) {
285
- let date = moment(ts)
287
+ const date = moment(ts)
286
288
  if (isRelativeTime) timestamp = date.fromNow()
287
289
  else timestamp = date.format('ddd DD MMM YYYY HH:mm:ss')
288
290
  }
@@ -366,9 +368,7 @@ export function useAsync<T>(
366
368
  dependencies: dependencyArray,
367
369
  })
368
370
  const mounted = useRef(true)
369
- const dependencies: any[] = useMemo(() => {
370
- return [...dependencyArray, shouldRun]
371
- }, [...dependencyArray, shouldRun])
371
+ const dependencies: any[] = useMemo(() => [...dependencyArray, shouldRun], [...dependencyArray, shouldRun])
372
372
 
373
373
  const reload = () => {
374
374
  async function call() {
@@ -434,9 +434,8 @@ export function useAsync<T>(
434
434
  export const processDeployedTime = (lastDeployed, isArgoInstalled) => {
435
435
  if (lastDeployed) {
436
436
  return handleUTCTime(lastDeployed, true)
437
- } else {
438
- return isArgoInstalled ? '' : 'Not deployed'
439
437
  }
438
+ return isArgoInstalled ? '' : 'Not deployed'
440
439
  }
441
440
 
442
441
  /**
@@ -489,19 +488,19 @@ export const customStyles = {
489
488
  }),
490
489
  }
491
490
 
492
- export const getFilteredChartVersions = (charts, selectedChartType) => {
491
+ export const getFilteredChartVersions = (charts, selectedChartType) =>
493
492
  // Filter chart versions based on selected chart type
494
- return charts
493
+ charts
495
494
  .filter((item) => item?.chartType === selectedChartType.value)
496
495
  .map((item) => ({
497
496
  value: item?.chartVersion,
498
497
  label: item?.chartVersion,
499
498
  chartRefId: item.chartRefId,
500
499
  }))
501
- }
500
+
502
501
  function removeEmptyObjectKeysAndNullValues(obj) {
503
502
  // It recursively removes empty object keys and array values that are null
504
- for (let key in obj) {
503
+ for (const key in obj) {
505
504
  if (Array.isArray(obj[key])) {
506
505
  if (obj[key].length === 0) continue
507
506
  obj[key] = obj[key].filter((item) => item !== null)
@@ -522,7 +521,7 @@ function removeEmptyObjectKeysAndNullValues(obj) {
522
521
 
523
522
  export function getUnlockedJSON(json, jsonPathArray) {
524
523
  const jsonCopy = JSON.parse(JSON.stringify(json))
525
- let patches = jsonPathArray.flatMap((jsonPath) => {
524
+ const patches = jsonPathArray.flatMap((jsonPath) => {
526
525
  const pathsToRemove = JSONPath({ path: jsonPath, json: jsonCopy, resultType: 'all' })
527
526
  return pathsToRemove.map((result) =>
528
527
  Array.isArray(result.parent)
@@ -530,7 +529,7 @@ export function getUnlockedJSON(json, jsonPathArray) {
530
529
  : { op: 'remove', path: result.pointer },
531
530
  )
532
531
  })
533
- let newDocument = jsonpatch.applyPatch(jsonCopy, patches).newDocument
532
+ const { newDocument } = jsonpatch.applyPatch(jsonCopy, patches)
534
533
 
535
534
  removeEmptyObjectKeysAndNullValues(newDocument)
536
535
  return newDocument
@@ -538,7 +537,7 @@ export function getUnlockedJSON(json, jsonPathArray) {
538
537
 
539
538
  export function getLockedJSON(json, jsonPathArray: string[]) {
540
539
  const jsonCopy = JSON.parse(JSON.stringify(json))
541
- let resultJson = {}
540
+ const resultJson = {}
542
541
  jsonPathArray.forEach((jsonPath) => {
543
542
  const elements = JSONPath({ path: jsonPath, json: jsonCopy, resultType: 'all' })
544
543
  elements.forEach((element) => {
@@ -546,16 +545,16 @@ export function getLockedJSON(json, jsonPathArray: string[]) {
546
545
  const lastPath = pathArray.pop()
547
546
  let current = resultJson
548
547
  for (let i = 0; i < pathArray.length; i++) {
549
- let key = isNaN(Number(pathArray[i])) ? pathArray[i] : parseInt(pathArray[i])
548
+ const key = isNaN(Number(pathArray[i])) ? pathArray[i] : parseInt(pathArray[i])
550
549
  if (!current[key]) {
551
- current[key] = isNaN(Number(pathArray[i + 1]??lastPath)) ? {} : []
550
+ current[key] = isNaN(Number(pathArray[i + 1] ?? lastPath)) ? {} : []
552
551
  }
553
552
  current = current[key]
554
553
  }
555
- let key = isNaN(Number(lastPath)) ? lastPath : parseInt(lastPath)
554
+ const key = isNaN(Number(lastPath)) ? lastPath : parseInt(lastPath)
556
555
  current[key] = element.value
557
556
  })
558
557
  })
558
+ // eslint-disable-next-line dot-notation
559
559
  return resultJson['$']
560
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'
@@ -2,12 +2,10 @@ import { useState, useEffect } from 'react'
2
2
 
3
3
  let timeout
4
4
 
5
- const getSize = () => {
6
- return {
7
- width: window.innerWidth,
8
- height: window.innerHeight,
9
- }
10
- }
5
+ const getSize = () => ({
6
+ width: window.innerWidth,
7
+ height: window.innerHeight,
8
+ })
11
9
 
12
10
  export const useWindowSize = () => {
13
11
  const [windowSize, setWindowSize] = useState(getSize)
@@ -17,7 +15,7 @@ export const useWindowSize = () => {
17
15
  window.cancelAnimationFrame(timeout)
18
16
  }
19
17
 
20
- timeout = window.requestAnimationFrame(function () {
18
+ timeout = window.requestAnimationFrame(() => {
21
19
  setWindowSize(getSize())
22
20
  })
23
21
  }
@@ -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
+ }