@devtron-labs/devtron-fe-common-lib 0.0.45-beta-18 → 0.0.45-beta-19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devtron-labs/devtron-fe-common-lib",
3
- "version": "0.0.45-beta-18",
3
+ "version": "0.0.45-beta-19",
4
4
  "description": "Supporting common component library",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -0,0 +1,122 @@
1
+ import { CustomInputProps } from './Types'
2
+ import { ReactComponent as Info } from '../../Assets/Icon/ic-info-filled.svg'
3
+ import { ReactComponent as FormError } from '../../Assets/Icon/ic-warning.svg'
4
+
5
+ export function CustomInput({
6
+ name,
7
+ value,
8
+ error,
9
+ onChange,
10
+ onFocus = (e) => {},
11
+ label = '',
12
+ type = 'text',
13
+ disabled = false,
14
+ labelClassName = '',
15
+ placeholder = '',
16
+ tabIndex = 1,
17
+ dataTestid = '',
18
+ isRequiredField = false,
19
+ autoFocus = false,
20
+ rootClassName = '',
21
+ autoComplete = 'off',
22
+ showLink = false,
23
+ linkText = '',
24
+ link = '',
25
+ helperText = '',
26
+ handleOnBlur,
27
+ readOnly = false,
28
+ noTrim = false,
29
+ ref
30
+ }: CustomInputProps) {
31
+ const renderLabelHelperText = () => {
32
+ return (
33
+ <span>
34
+ <a target="_blank" href={link} className="cursor fs-13 onlink ml-4">
35
+ {linkText}
36
+ </a>
37
+ </span>
38
+ )
39
+ }
40
+
41
+ function handleError(error: any): any[] {
42
+ if (!error) {
43
+ return []
44
+ }
45
+
46
+ if (!Array.isArray(error)) {
47
+ return [error]
48
+ }
49
+
50
+ return error
51
+ }
52
+
53
+ const onBlur = (event) => {
54
+ //NOTE: This is to prevent the input from being trimmed when the user do not want to trim the input
55
+ if (!noTrim) {
56
+ event.stopPropagation()
57
+ event.target.value = event.target.value?.trim()
58
+ onChange(event)
59
+ }
60
+ if (typeof handleOnBlur === 'function') {
61
+ handleOnBlur(event)
62
+ }
63
+ }
64
+
65
+ const renderFormError = () => {
66
+ if (error?.length > 0) {
67
+ if (typeof error === 'object') {
68
+ return handleError(error).map((err: string) => (
69
+ <div className="form__error" key={err}>
70
+ <FormError className="form__icon form__icon--error" />
71
+ {err}
72
+ </div>
73
+ ))
74
+ }
75
+ return (
76
+ <div className="form__error">
77
+ <FormError className="form__icon form__icon--error" />
78
+ {error}
79
+ </div>
80
+ )
81
+ }
82
+ }
83
+
84
+ return (
85
+ <div className="flex column left top">
86
+ {label && (
87
+ <label className={`form__label ${labelClassName}`} data-testid={`label-${dataTestid}`}>
88
+ <span className={`${isRequiredField ? 'dc__required-field' : ''}`}>{label}</span>
89
+ {showLink && renderLabelHelperText()}
90
+ </label>
91
+ )}
92
+ <input
93
+ data-testid={dataTestid}
94
+ type={type}
95
+ name={name}
96
+ autoComplete={autoComplete}
97
+ className={`form__input ${rootClassName}`}
98
+ onChange={(e) => {
99
+ e.persist()
100
+ onChange(e)
101
+ }}
102
+ onBlur={onBlur}
103
+ onFocus={onFocus}
104
+ placeholder={placeholder}
105
+ value={value}
106
+ disabled={disabled}
107
+ tabIndex={tabIndex}
108
+ autoFocus={autoFocus}
109
+ readOnly={readOnly}
110
+ ref={ref}
111
+ />
112
+
113
+ {renderFormError()}
114
+ {helperText && (
115
+ <div className="form__text-field-info">
116
+ <Info className="form__icon form__icon--info" />
117
+ <p className="sentence-case">{helperText}</p>
118
+ </div>
119
+ )}
120
+ </div>
121
+ )
122
+ }
@@ -0,0 +1,28 @@
1
+ import { LegacyRef } from "react"
2
+
3
+ export interface CustomInputProps {
4
+ name: string
5
+ value: string | number
6
+ onChange: (e: any) => void
7
+ onFocus?: (e: any) => void
8
+ autoComplete?: string
9
+ label?: React.ReactNode
10
+ labelClassName?: string
11
+ type?: 'text' | 'number'
12
+ disabled?: boolean
13
+ placeholder?: string
14
+ tabIndex?: number
15
+ dataTestid?: string
16
+ isRequiredField?: boolean
17
+ autoFocus?: boolean
18
+ rootClassName?: string
19
+ showLink?: boolean
20
+ link?: string
21
+ linkText?: string
22
+ error?: string[] | string
23
+ helperText?: string;
24
+ handleOnBlur?: (e) => void
25
+ readOnly?: boolean
26
+ noTrim?: boolean
27
+ ref?: LegacyRef<HTMLInputElement>
28
+ }
@@ -0,0 +1,2 @@
1
+ export * from './CustomInput'
2
+ export * from './Types'
@@ -45,7 +45,7 @@ export const DeleteDialog: React.FC<DeleteDialogProps> & { Description?: React.F
45
45
  type="button"
46
46
  className="cta delete cta-cd-delete-modal ml-16"
47
47
  onClick={handleDelete}
48
- disabled={props.apiCallInProgress || props.disabled}
48
+ disabled={props.apiCallInProgress}
49
49
  data-testid="dialog-delete"
50
50
  >
51
51
  {props.apiCallInProgress ? (
@@ -11,7 +11,6 @@ export interface DeleteDialogProps {
11
11
  dataTestId?: string
12
12
  buttonPrimaryText?: string
13
13
  shouldStopPropagation?: boolean
14
- disabled?: boolean
15
14
  }
16
15
 
17
16
  export interface ForceDeleteDialogType {
@@ -3,7 +3,6 @@ import moment from 'moment'
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
4
4
  import { useLocation } from 'react-router-dom'
5
5
  import { toast } from 'react-toastify'
6
- import { ReactComponent as FormError } from '../Assets/Icon/ic-warning.svg'
7
6
  import { ERROR_EMPTY_SCREEN, TOKEN_COOKIE_NAME } from './Constants'
8
7
  import { ServerErrors } from './ServerError'
9
8
  import { toastAccessDenied } from './ToastBody'
@@ -277,64 +276,6 @@ export function useForm(stateSchema, validationSchema = {}, callback) {
277
276
  return { state, disable, handleOnChange, handleOnSubmit }
278
277
  }
279
278
 
280
- function handleError(error: any): any[] {
281
- if (!error) {
282
- return []
283
- }
284
-
285
- if (!Array.isArray(error)) {
286
- return [error]
287
- }
288
-
289
- return error
290
- }
291
-
292
- export function CustomInput({
293
- name,
294
- value,
295
- error,
296
- onChange,
297
- onBlur = (e) => {},
298
- onFocus = (e) => {},
299
- label,
300
- type = 'text',
301
- disabled = false,
302
- autoComplete = 'off',
303
- labelClassName = '',
304
- placeholder = '',
305
- tabIndex = 1,
306
- dataTestid = '',
307
- }) {
308
- return (
309
- <div className="flex column left top">
310
- <label className={`form__label ${labelClassName}`}>{label}</label>
311
- <input
312
- data-testid={dataTestid}
313
- type={type}
314
- name={name}
315
- autoComplete="off"
316
- className="form__input"
317
- onChange={(e) => {
318
- e.persist()
319
- onChange(e)
320
- }}
321
- onBlur={onBlur}
322
- onFocus={onFocus}
323
- placeholder={placeholder}
324
- value={value}
325
- disabled={disabled}
326
- tabIndex={tabIndex}
327
- />
328
- {handleError(error).map((err) => (
329
- <div className="form__error" key={err}>
330
- <FormError className="form__icon form__icon--error" />
331
- {err}
332
- </div>
333
- ))}
334
- </div>
335
- )
336
- }
337
-
338
279
  export function handleUTCTime(ts: string, isRelativeTime = false) {
339
280
  let timestamp = ''
340
281
  try {
@@ -354,8 +354,6 @@ export interface CommonNodeAttr {
354
354
  }
355
355
  appReleaseTagNames?: string[]
356
356
  tagsEditable?: boolean
357
- deploymentAppCreated?: boolean
358
- isLast?: boolean
359
357
  }
360
358
 
361
359
  export enum DeploymentAppTypes {
@@ -624,52 +622,4 @@ export interface CiPipeline {
624
622
  }
625
623
  isOffendingMandatoryPlugin?: boolean
626
624
  pipelineType?: string
627
- }
628
-
629
- export enum PipelineType {
630
- CI_PIPELINE = 'CI_PIPELINE',
631
- CD_PIPELINE = 'CD_PIPELINE',
632
- WEBHOOK = 'WEBHOOK',
633
- LINKED_CD = 'LINKED_CD',
634
- }
635
-
636
- export enum WorkflowNodeType {
637
- GIT = 'GIT',
638
- CI = 'CI',
639
- WEBHOOK = 'WEBHOOK',
640
- PRE_CD = 'PRECD',
641
- CD = 'CD',
642
- POST_CD = 'POSTCD',
643
- }
644
-
645
- export enum AddCDPositions {
646
- LEFT = 'left',
647
- RIGHT = 'right',
648
- }
649
-
650
- export interface SelectedNode {
651
- nodeType: WorkflowNodeType
652
- id: string
653
- }
654
-
655
- export enum AddPipelineType {
656
- SEQUENTIAL = 'SEQUENTIAL',
657
- PARALLEL = 'PARALLEL',
658
- }
659
-
660
- export interface Point {
661
- x: number
662
- y: number
663
- }
664
-
665
- export interface EdgeNodeType {
666
- height: number
667
- width: number
668
- userApprovalConfig?: UserApprovalConfigType
669
- type?: any
670
- id?: number | string
671
- }
672
-
673
- export interface EdgeEndNodeType extends EdgeNodeType {
674
- userApprovalConfig?: UserApprovalConfigType
675
- }
625
+ }
@@ -42,4 +42,4 @@ export * from './Hooks'
42
42
  export { AppStatus } from './AppStatus'
43
43
  export * from './RJSF'
44
44
  export * from './DevtronProgressing'
45
- export * from './AddCDButton'
45
+ export * from './CustomInput'
@@ -1,3 +0,0 @@
1
- /// <reference types="react" />
2
- import { AddCDButtonProps } from './types';
3
- export default function AddCDButton({ position, addCDButtons, endNode, startNode, handleAddCD, }: Readonly<AddCDButtonProps>): JSX.Element;
@@ -1,2 +0,0 @@
1
- export { default as AddCDButton } from './AddCDButton';
2
- export { handleAddCD } from './utils';
@@ -1,22 +0,0 @@
1
- import { AddCDPositions, AddPipelineType, EdgeEndNodeType, EdgeNodeType, Point } from '../Types';
2
- export interface AddCDButtonProps {
3
- position: AddCDPositions;
4
- addCDButtons: AddCDPositions[];
5
- endNode: Point & EdgeEndNodeType;
6
- startNode: Point & EdgeNodeType;
7
- handleAddCD: (position: AddCDPositions) => void;
8
- }
9
- export interface HandleAddCD {
10
- position: AddCDPositions;
11
- handleCDSelect: (workflowId: number | string, ciPipelineId: number | string, parentPipelineType: string, parentPipelineId: number | string, isWebhookCD?: boolean, childPipelineId?: number | string, addType?: AddPipelineType) => void;
12
- startNode: EdgeNodeType;
13
- endNode: EdgeEndNodeType;
14
- workflowId: number | string;
15
- ciPipelineId: number | string;
16
- isWebhookCD: boolean;
17
- isParallelEdge: boolean;
18
- }
19
- export interface GetPipelineType {
20
- isWebhookCD: boolean;
21
- startNode: EdgeNodeType;
22
- }
@@ -1,2 +0,0 @@
1
- import { HandleAddCD } from './types';
2
- export declare const handleAddCD: ({ position, handleCDSelect, startNode, endNode, workflowId, ciPipelineId, isWebhookCD, isParallelEdge, }: HandleAddCD) => void;
@@ -1,44 +0,0 @@
1
- import React from 'react'
2
- import { AddCDButtonProps } from './types'
3
- import { AddCDPositions } from '../Types'
4
-
5
- export default function AddCDButton({
6
- position,
7
- addCDButtons,
8
- endNode,
9
- startNode,
10
- handleAddCD,
11
- }: Readonly<AddCDButtonProps>) {
12
- const referenceNode = position === AddCDPositions.RIGHT ? endNode : startNode
13
- const handleAddCDClick = () => {
14
- handleAddCD(position)
15
- }
16
-
17
- if (addCDButtons?.includes(position)) {
18
- return (
19
- <svg
20
- x={referenceNode.x + (position === AddCDPositions.RIGHT ? -20 - 5 : referenceNode.width + 5)}
21
- // Here 10 is the height of the button / 2
22
- y={referenceNode.y + referenceNode.height / 2 - 10}
23
- width="20"
24
- height="20"
25
- viewBox="0 0 20 20"
26
- fill="none"
27
- xmlns="http://www.w3.org/2000/svg"
28
- data-testid={`add-cd-to-${position}`}
29
- onClick={handleAddCDClick}
30
- >
31
- <rect width="20" height="20" rx="10" fill="#664BEE" className="add-cd-edge-btn" />
32
- <path
33
- d="M6.5 10H13.5M10 6.5V13.5"
34
- stroke="white"
35
- strokeWidth="1.5"
36
- strokeLinecap="round"
37
- strokeLinejoin="round"
38
- />
39
- </svg>
40
- )
41
- }
42
-
43
- return null
44
- }
@@ -1,2 +0,0 @@
1
- export { default as AddCDButton } from './AddCDButton'
2
- export { handleAddCD } from './utils'
@@ -1,33 +0,0 @@
1
- import { AddCDPositions, AddPipelineType, EdgeEndNodeType, EdgeNodeType, Point } from '../Types'
2
-
3
- export interface AddCDButtonProps {
4
- position: AddCDPositions
5
- addCDButtons: AddCDPositions[]
6
- endNode: Point & EdgeEndNodeType
7
- startNode: Point & EdgeNodeType
8
- handleAddCD: (position: AddCDPositions) => void
9
- }
10
-
11
- export interface HandleAddCD {
12
- position: AddCDPositions
13
- handleCDSelect: (
14
- workflowId: number | string,
15
- ciPipelineId: number | string,
16
- parentPipelineType: string,
17
- parentPipelineId: number | string,
18
- isWebhookCD?: boolean,
19
- childPipelineId?: number | string,
20
- addType?: AddPipelineType,
21
- ) => void
22
- startNode: EdgeNodeType
23
- endNode: EdgeEndNodeType
24
- workflowId: number | string
25
- ciPipelineId: number | string
26
- isWebhookCD: boolean
27
- isParallelEdge: boolean
28
- }
29
-
30
- export interface GetPipelineType {
31
- isWebhookCD: boolean
32
- startNode: EdgeNodeType
33
- }
@@ -1,35 +0,0 @@
1
- import { AddCDPositions, AddPipelineType, PipelineType, WorkflowNodeType } from '../Types'
2
- import { HandleAddCD, GetPipelineType } from './types'
3
-
4
- const getPipelineType = ({ isWebhookCD, startNode }: GetPipelineType) => {
5
- if (isWebhookCD) {
6
- return PipelineType.WEBHOOK
7
- }
8
-
9
- if (startNode.type === WorkflowNodeType.CI) {
10
- return PipelineType.CI_PIPELINE
11
- }
12
-
13
- return PipelineType.CD_PIPELINE
14
- }
15
-
16
- export const handleAddCD = ({
17
- position,
18
- handleCDSelect,
19
- startNode,
20
- endNode,
21
- workflowId,
22
- ciPipelineId,
23
- isWebhookCD,
24
- isParallelEdge,
25
- }: HandleAddCD) => {
26
- if (!handleCDSelect) {
27
- return
28
- }
29
- const pipelineType = getPipelineType({ isWebhookCD, startNode })
30
- const addPipelineType =
31
- isParallelEdge && position === AddCDPositions.RIGHT ? AddPipelineType.PARALLEL : AddPipelineType.SEQUENTIAL
32
- const endNodeId = !isParallelEdge && position === AddCDPositions.RIGHT ? endNode.id : null
33
-
34
- handleCDSelect(workflowId, ciPipelineId, pipelineType, startNode.id, isWebhookCD, endNodeId, addPipelineType)
35
- }