@devtron-labs/devtron-fe-common-lib 0.0.7-beta-49 → 0.0.7-beta-51

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.
@@ -0,0 +1,275 @@
1
+ export interface MaterialType {
2
+ name: string
3
+ type: string
4
+ value: string
5
+ gitMaterialId: number
6
+ id: number
7
+ isSelected: boolean
8
+ gitHostId: number
9
+ gitProviderId: number
10
+ regex?: string
11
+ isRegex: boolean
12
+ }
13
+
14
+ export interface Githost {
15
+ id: number
16
+ name: string
17
+ active: boolean
18
+ webhookSecret: string
19
+ webhookUrl: string
20
+ }
21
+
22
+ export interface WebhookEvent {
23
+ id: number
24
+ gitHostId: number
25
+ name: string
26
+ isActive: boolean
27
+ selectors: WebhookEventSelectors[]
28
+ }
29
+
30
+ interface WebhookEventSelectors {
31
+ id: number
32
+ eventId: number
33
+ name: string
34
+ selector: string
35
+ toShowInCiFilter: boolean
36
+ fixValue: string
37
+ toShow: boolean
38
+ possibleValues: string
39
+ isActive: boolean
40
+ }
41
+
42
+ export interface CiPipelineSourceTypeOption {
43
+ label: string
44
+ value: string
45
+ isDisabled: boolean
46
+ isSelected: boolean
47
+ isWebhook: boolean
48
+ }
49
+
50
+ export enum RefVariableType {
51
+ GLOBAL = 'GLOBAL',
52
+ FROM_PREVIOUS_STEP = 'FROM_PREVIOUS_STEP',
53
+ NEW = 'NEW',
54
+ }
55
+
56
+ export enum PluginType {
57
+ INLINE = 'INLINE',
58
+ PLUGIN_REF = 'REF_PLUGIN',
59
+ }
60
+
61
+ export enum ScriptType {
62
+ SHELL = 'SHELL',
63
+ DOCKERFILE = 'DOCKERFILE',
64
+ CONTAINERIMAGE = 'CONTAINER_IMAGE',
65
+ }
66
+
67
+ export enum MountPath {
68
+ TRUE = 'Yes',
69
+ FALSE = 'No',
70
+ }
71
+
72
+ export enum ConditionType {
73
+ SKIP = 'SKIP',
74
+ TRIGGER = 'TRIGGER',
75
+ PASS = 'PASS',
76
+ FAIL = 'FAIL',
77
+ }
78
+
79
+ export enum RefVariableStageType {
80
+ PRE_CI = 'PRE_CI',
81
+ POST_CI = 'POST_CI',
82
+ }
83
+
84
+ export interface VariableType {
85
+ id: number
86
+ name: string
87
+ value: string
88
+ format: string
89
+ description: string
90
+ defaultValue: string
91
+ variableType: RefVariableType
92
+ refVariableStepIndex: number
93
+ refVariableName: string
94
+ refVariableStage?: RefVariableStageType
95
+ variableStepIndexInPlugin?: number
96
+ }
97
+
98
+ interface CommandArgsMap {
99
+ command: string
100
+ args: string[]
101
+ }
102
+
103
+ export interface PortMapType {
104
+ portOnLocal: number
105
+ portOnContainer: number
106
+ }
107
+ interface ConditionDetails {
108
+ id: number
109
+ conditionOnVariable: string
110
+ conditionOperator: string
111
+ conditionType: ConditionType
112
+ conditionalValue: string
113
+ }
114
+
115
+ interface InlineStepDetailType {
116
+ scriptType: ScriptType
117
+ isMountCustomScript?: boolean
118
+ script?: string
119
+ dockerFileExists?: boolean
120
+ mountPath?: string
121
+ mountCodeToContainer?: boolean
122
+ mountDirectoryFromHost?: boolean
123
+ containerImagePath?: string
124
+ imagePullSecret?: string
125
+ commandArgsMap?: CommandArgsMap[]
126
+ portMap?: PortMapType[]
127
+ mountPathMap?: {
128
+ filePathOnDisk: string
129
+ filePathOnContainer: string
130
+ }[]
131
+ inputVariables?: VariableType[]
132
+ outputVariables?: VariableType[]
133
+ conditionDetails: ConditionDetails[]
134
+ }
135
+
136
+ interface PluginRefStepDetailType {
137
+ id: number
138
+ pluginId: number
139
+ inputVariables?: VariableType[]
140
+ outputVariables?: VariableType[]
141
+ conditionDetails?: ConditionDetails[]
142
+ }
143
+
144
+ export interface StepType {
145
+ id: number
146
+ index: number
147
+ name: string
148
+ description: string
149
+ stepType: PluginType
150
+ outputDirectoryPath: string[]
151
+ inlineStepDetail?: InlineStepDetailType
152
+ pluginRefStepDetail?: PluginRefStepDetailType
153
+ triggerIfParentStageFail: boolean
154
+ isMandatory?: boolean
155
+ }
156
+
157
+ export interface BuildStageType {
158
+ id: number
159
+ steps: StepType[]
160
+ }
161
+
162
+ export enum CIBuildType {
163
+ SELF_DOCKERFILE_BUILD_TYPE = 'self-dockerfile-build',
164
+ MANAGED_DOCKERFILE_BUILD_TYPE = 'managed-dockerfile-build',
165
+ BUILDPACK_BUILD_TYPE = 'buildpack-build',
166
+ }
167
+
168
+ export interface BuildPackConfigType {
169
+ builderId: string
170
+ language: string
171
+ languageVersion: string
172
+ projectPath: string
173
+ builderLangEnvParam?: string
174
+ currentBuilderLangEnvParam?: string
175
+ buildPacks?: any
176
+ args?: Record<string, string>
177
+ }
178
+
179
+ export interface DockerBuildConfigType {
180
+ dockerfileContent: string
181
+ dockerfileRelativePath: string
182
+ buildContext: string
183
+ dockerfilePath?: string
184
+ dockerfileRepository?: string
185
+ args?: Record<string, string>
186
+ targetPlatform?: any
187
+ language?: string
188
+ languageFramework?: string
189
+ }
190
+
191
+ export interface CIBuildConfigType {
192
+ buildPackConfig: BuildPackConfigType
193
+ ciBuildType: CIBuildType
194
+ dockerBuildConfig: DockerBuildConfigType
195
+ gitMaterialId: number
196
+ buildContextGitMaterialId: number
197
+ id?: number
198
+ }
199
+
200
+ export interface DockerConfigOverrideType {
201
+ dockerRegistry: string
202
+ dockerRepository: string
203
+ ciBuildConfig: CIBuildConfigType
204
+ }
205
+
206
+ export interface FormType {
207
+ name: string
208
+ args: { key: string; value: string }[]
209
+ materials: MaterialType[]
210
+ gitHost: Githost
211
+ webhookEvents: WebhookEvent[]
212
+ ciPipelineSourceTypeOptions: CiPipelineSourceTypeOption[]
213
+ webhookConditionList: { selectorId: number; value: string }[]
214
+ triggerType: string
215
+ scanEnabled?: boolean
216
+ beforeDockerBuildScripts?: {
217
+ id: number
218
+ name: string
219
+ outputLocation: string
220
+ script: string
221
+ isCollapsed: boolean
222
+ index: number
223
+ }[]
224
+ afterDockerBuildScripts?: {
225
+ id: number
226
+ name: string
227
+ outputLocation: string
228
+ script: string
229
+ isCollapsed: boolean
230
+ index: number
231
+ }[]
232
+ ciPipelineEditable: true
233
+ preBuildStage?: BuildStageType
234
+ postBuildStage?: BuildStageType
235
+ isDockerConfigOverridden?: boolean
236
+ dockerConfigOverride?: DockerConfigOverrideType
237
+ }
238
+
239
+ export interface ErrorObj {
240
+ isValid: boolean
241
+ message: string | null
242
+ }
243
+ export interface TaskErrorObj {
244
+ isValid: boolean
245
+ name: ErrorObj
246
+ inlineStepDetail?: { inputVariables?: ErrorObj[]; outputVariables?: ErrorObj[] }
247
+ pluginRefStepDetail?: { inputVariables?: ErrorObj[]; outputVariables?: ErrorObj[] }
248
+ }
249
+ export interface FormErrorObjectType {
250
+ name: ErrorObj
251
+ materials?: MaterialType[]
252
+ preBuildStage?: {
253
+ isValid: boolean
254
+ steps: TaskErrorObj[]
255
+ }
256
+ buildStage?: {
257
+ isValid: boolean
258
+ name: ErrorObj
259
+ }
260
+ postBuildStage?: {
261
+ isValid: boolean
262
+ steps: TaskErrorObj[]
263
+ }
264
+ }
265
+
266
+ export interface PluginDetailType {
267
+ id: number
268
+ name: string
269
+ type: string
270
+ description: string
271
+ icon: string
272
+ tags: string[]
273
+ inputVariables?: VariableType[]
274
+ outputVariables?: VariableType[]
275
+ }
@@ -57,4 +57,10 @@ export const TOKEN_COOKIE_NAME = 'argocd.token'
57
57
  export const TriggerTypeMap = {
58
58
  automatic: 'Auto',
59
59
  manual: 'Manual',
60
+ }
61
+
62
+ export const BuildStageVariable = {
63
+ PreBuild: 'preBuildStage',
64
+ Build: 'buildStage',
65
+ PostBuild: 'postBuildStage',
60
66
  }
@@ -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} data-testid="dialog-cancel">Cancel</button>
20
- <button type="button" className="cta delete cta-cd-delete-modal ml-16" onClick={() => props.delete()} disabled={props.apiCallInProgress} data-testid="dialog-delete">
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
@@ -9,6 +9,7 @@ export interface DeleteDialogProps {
9
9
  deletePostfix?: string
10
10
  apiCallInProgress?: boolean
11
11
  dataTestId?: string
12
+ buttonPrimaryText?: string
12
13
  }
13
14
 
14
15
  export interface ForceDeleteDialogType {
@@ -1,49 +1,48 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react'
1
+ import React, { useEffect, useRef } from 'react'
2
2
  import { ServerErrors } from './ServerError'
3
3
  import { toast } from 'react-toastify'
4
4
  import * as Sentry from '@sentry/browser'
5
5
  import { toastAccessDenied } from './ToastBody'
6
6
  import { ERROR_EMPTY_SCREEN, TOKEN_COOKIE_NAME } from './Constants'
7
- import { ReactComponent as FormError } from '../Assets/Icon/ic-warning.svg'
8
7
 
9
8
  toast.configure({
10
- autoClose: 3000,
11
- hideProgressBar: true,
12
- pauseOnHover: true,
13
- pauseOnFocusLoss: true,
14
- closeOnClick: false,
15
- newestOnTop: true,
16
- toastClassName: 'devtron-toast',
17
- bodyClassName: 'devtron-toast__body',
9
+ autoClose: 3000,
10
+ hideProgressBar: true,
11
+ pauseOnHover: true,
12
+ pauseOnFocusLoss: true,
13
+ closeOnClick: false,
14
+ newestOnTop: true,
15
+ toastClassName: 'devtron-toast',
16
+ bodyClassName: 'devtron-toast__body',
18
17
  })
19
18
 
20
19
  export function showError(serverError, showToastOnUnknownError = true, hideAccessError = false) {
21
- if (serverError instanceof ServerErrors && Array.isArray(serverError.errors)) {
22
- serverError.errors.map(({ userMessage, internalMessage }) => {
23
- if (
24
- serverError.code === 403 &&
25
- (userMessage === ERROR_EMPTY_SCREEN.UNAUTHORIZED || userMessage === ERROR_EMPTY_SCREEN.FORBIDDEN)
26
- ) {
27
- if (!hideAccessError) {
28
- toastAccessDenied()
29
- }
30
- } else {
31
- toast.error(userMessage || internalMessage)
32
- }
33
- })
34
- } else {
35
- if (serverError.code !== 403 && serverError.code !== 408) {
36
- Sentry.captureException(serverError)
37
- }
38
-
39
- if (showToastOnUnknownError) {
40
- if (serverError.message) {
41
- toast.error(serverError.message)
42
- } else {
43
- toast.error('Some Error Occurred')
44
- }
45
- }
46
- }
20
+ if (serverError instanceof ServerErrors && Array.isArray(serverError.errors)) {
21
+ serverError.errors.map(({ userMessage, internalMessage }) => {
22
+ if (
23
+ serverError.code === 403 &&
24
+ (userMessage === ERROR_EMPTY_SCREEN.UNAUTHORIZED || userMessage === ERROR_EMPTY_SCREEN.FORBIDDEN)
25
+ ) {
26
+ if (!hideAccessError) {
27
+ toastAccessDenied()
28
+ }
29
+ } else {
30
+ toast.error(userMessage || internalMessage)
31
+ }
32
+ })
33
+ } else {
34
+ if (serverError.code !== 403 && serverError.code !== 408) {
35
+ Sentry.captureException(serverError)
36
+ }
37
+
38
+ if (showToastOnUnknownError) {
39
+ if (serverError.message) {
40
+ toast.error(serverError.message)
41
+ } else {
42
+ toast.error('Some Error Occurred')
43
+ }
44
+ }
45
+ }
47
46
  }
48
47
 
49
48
  interface ConditionalWrapper<T> {
@@ -168,166 +167,4 @@ export function getLoginInfo() {
168
167
  return null
169
168
  }
170
169
  }
171
- }
172
-
173
- export function useForm(stateSchema, validationSchema = {}, callback) {
174
- const [state, setState] = useState(stateSchema)
175
- const [disable, setDisable] = useState(true)
176
- const [isDirty, setIsDirty] = useState(false)
177
-
178
- // Disable button in initial render.
179
- useEffect(() => {
180
- setDisable(true)
181
- }, [])
182
-
183
- // For every changed in our state this will be fired
184
- // To be able to disable the button
185
- useEffect(() => {
186
- if (isDirty) {
187
- setDisable(validateState(state))
188
- }
189
- }, [state, isDirty])
190
-
191
- // Used to disable submit button if there's an error in state
192
- // or the required field in state has no value.
193
- // Wrapped in useCallback to cached the function to avoid intensive memory leaked
194
- // in every re-render in component
195
- const validateState = useCallback(
196
- (state) => {
197
- //check errors in all fields
198
- const hasErrorInState = Object.keys(validationSchema).some((key) => {
199
- const isInputFieldRequired = validationSchema[key].required
200
- const stateValue = state[key].value // state value
201
- const stateError = state[key].error // state error
202
- return (isInputFieldRequired && !stateValue) || stateError
203
- })
204
- return hasErrorInState
205
- },
206
- [state, validationSchema],
207
- )
208
-
209
- function validateField(name, value): string | string[] {
210
- if (validationSchema[name].required) {
211
- if (!value) {
212
- return 'This is a required field.'
213
- }
214
- }
215
-
216
- function _validateSingleValidator(validator, value) {
217
- if (value && !validator.regex.test(value)) {
218
- return false
219
- }
220
- return true
221
- }
222
-
223
- // single validator
224
- let _validator = validationSchema[name].validator
225
- if (_validator && typeof _validator === 'object') {
226
- if (!_validateSingleValidator(_validator, value)) {
227
- return _validator.error
228
- }
229
- }
230
-
231
- // multiple validators
232
- let _validators = validationSchema[name].validators
233
- if (_validators && typeof _validators === 'object' && Array.isArray(_validators)) {
234
- let errors = []
235
- _validators.forEach((_validator) => {
236
- if (!_validateSingleValidator(_validator, value)) {
237
- errors.push(_validator.error)
238
- }
239
- })
240
- if (errors.length > 0) {
241
- return errors
242
- }
243
- }
244
-
245
- return ''
246
- }
247
-
248
- const handleOnChange = useCallback(
249
- (event) => {
250
- setIsDirty(true)
251
-
252
- const { name, value } = event.target
253
- let error = validateField(name, value)
254
- setState((prevState) => ({
255
- ...prevState,
256
- [name]: { value, error },
257
- }))
258
- },
259
- [validationSchema],
260
- )
261
-
262
- const handleOnSubmit = (event) => {
263
- event.preventDefault()
264
- const newState = Object.keys(validationSchema).reduce((agg, curr) => {
265
- agg[curr] = { ...state[curr], error: validateField(curr, state[curr].value) }
266
- return agg
267
- }, state)
268
- if (!validateState(newState)) {
269
- callback(state)
270
- } else {
271
- setState({ ...newState })
272
- }
273
- }
274
- return { state, disable, handleOnChange, handleOnSubmit }
275
- }
276
-
277
- function handleError(error: any): any[] {
278
- if (!error) {
279
- return []
280
- }
281
-
282
- if (!Array.isArray(error)) {
283
- return [error]
284
- }
285
-
286
- return error
287
- }
288
-
289
- export function CustomInput({
290
- name,
291
- value,
292
- error,
293
- onChange,
294
- onBlur = (e) => {},
295
- onFocus = (e) => {},
296
- label,
297
- type = 'text',
298
- disabled = false,
299
- autoComplete = 'off',
300
- labelClassName = '',
301
- placeholder = '',
302
- tabIndex = 1,
303
- dataTestid = '',
304
- }) {
305
- return (
306
- <div className="flex column left top">
307
- <label className={`form__label ${labelClassName}`}>{label}</label>
308
- <input
309
- data-testid={dataTestid}
310
- type={type}
311
- name={name}
312
- autoComplete="off"
313
- className="form__input"
314
- onChange={(e) => {
315
- e.persist()
316
- onChange(e)
317
- }}
318
- onBlur={onBlur}
319
- onFocus={onFocus}
320
- placeholder={placeholder}
321
- value={value}
322
- disabled={disabled}
323
- tabIndex={tabIndex}
324
- />
325
- {handleError(error).map((err) => (
326
- <div className="form__error">
327
- <FormError className="form__icon form__icon--error" />
328
- {err}
329
- </div>
330
- ))}
331
- </div>
332
- )
333
- }
170
+ }