Skip to content

Commit 24bbc15

Browse files
committed
Merge branch 'develop' of github.com:devtron-labs/devtron-fe-common-lib into fix/tooltip-rerender
2 parents 69517fc + a6664bc commit 24bbc15

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2017
-246
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* vivek@devtron.ai @vikramdevtron

package-lock.json

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "0.2.22",
3+
"version": "0.3.1",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Assets/Icon/ic-arrow-right.svg

Lines changed: 7 additions & 0 deletions
Loading

src/Common/Api.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ async function handleServerError(contentType, response) {
114114
throw serverError
115115
}
116116

117-
async function fetchAPI(
117+
async function fetchAPI<K = object>(
118118
url: string,
119119
type: string,
120-
data: object,
120+
data: K,
121121
signal: AbortSignal,
122122
preventAutoLogout = false,
123123
isMultipartRequest?: boolean,
@@ -185,10 +185,10 @@ async function fetchAPI(
185185
)
186186
}
187187

188-
function fetchInTime(
188+
function fetchInTime<T = object>(
189189
url: string,
190190
type: string,
191-
data: object,
191+
data: T,
192192
options?: APIOptions,
193193
isMultipartRequest?: boolean,
194194
): Promise<ResponseType> {
@@ -227,23 +227,24 @@ function fetchInTime(
227227
})
228228
}
229229

230-
export const post = (
230+
export const post = <T = any, K = object>(
231231
url: string,
232-
data: object,
232+
data: K,
233233
options?: APIOptions,
234234
isMultipartRequest?: boolean,
235-
): Promise<ResponseType> => fetchInTime(url, 'POST', data, options, isMultipartRequest)
235+
): Promise<ResponseType<T>> => fetchInTime<K>(url, 'POST', data, options, isMultipartRequest)
236236

237-
export const put = (url: string, data: object, options?: APIOptions): Promise<ResponseType> =>
238-
fetchInTime(url, 'PUT', data, options)
237+
export const put = <T = any, K = object>(url: string, data: K, options?: APIOptions): Promise<ResponseType<T>> =>
238+
fetchInTime<K>(url, 'PUT', data, options)
239239

240-
export const patch = (url: string, data: object, options?: APIOptions): Promise<ResponseType> =>
241-
fetchInTime(url, 'PATCH', data, options)
240+
export const patch = <T = any, K = object>(url: string, data: K, options?: APIOptions): Promise<ResponseType<T>> =>
241+
fetchInTime<K>(url, 'PATCH', data, options)
242242

243-
export const get = (url: string, options?: APIOptions): Promise<ResponseType> => fetchInTime(url, 'GET', null, options)
243+
export const get = <T = any>(url: string, options?: APIOptions): Promise<ResponseType<T>> =>
244+
fetchInTime(url, 'GET', null, options)
244245

245-
export const trash = (url: string, data?: object, options?: APIOptions): Promise<ResponseType> =>
246-
fetchInTime(url, 'DELETE', data, options)
246+
export const trash = <T = any, K = object>(url: string, data?: K, options?: APIOptions): Promise<ResponseType<T>> =>
247+
fetchInTime<K>(url, 'DELETE', data, options)
247248

248249
/**
249250
* Aborts the previous request before triggering next request

src/Common/CIPipeline.Types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export interface VariableType {
104104
format: string
105105
description: string
106106
defaultValue: string
107+
allowEmptyValue: boolean
107108
variableType: RefVariableType
108109
refVariableStepIndex: number
109110
refVariableName: string
@@ -128,7 +129,7 @@ interface ConditionDetails {
128129
conditionalValue: string
129130
}
130131

131-
interface InlineStepDetailType {
132+
export interface InlineStepDetailType {
132133
scriptType: ScriptType
133134
isMountCustomScript?: boolean
134135
script?: string
@@ -147,6 +148,8 @@ interface InlineStepDetailType {
147148
inputVariables?: VariableType[]
148149
outputVariables?: VariableType[]
149150
conditionDetails: ConditionDetails[]
151+
storeScriptAt?: string
152+
mountCodeToContainerPath?: string
150153
}
151154

152155
interface PluginRefStepDetailType {

src/Common/ClipboardButton/ClipboardButton.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default function ClipboardButton({
3434
content,
3535
copiedTippyText = 'Copied!',
3636
duration = 1000,
37-
trigger = false,
37+
trigger,
3838
setTrigger = noop,
3939
rootClassName = '',
4040
iconSize = 16,
@@ -45,6 +45,8 @@ export default function ClipboardButton({
4545
const handleTextCopied = () => {
4646
setCopied(true)
4747
}
48+
const isTriggerUndefined = typeof trigger === 'undefined'
49+
4850
const handleEnableTippy = () => setEnableTippy(true)
4951
const handleDisableTippy = () => setEnableTippy(false)
5052
const handleCopyContent = useCallback(
@@ -68,7 +70,7 @@ export default function ClipboardButton({
6870
}, [copied, duration, setTrigger])
6971

7072
useEffect(() => {
71-
if (trigger) {
73+
if (!isTriggerUndefined && trigger) {
7274
setCopied(true)
7375
handleCopyContent()
7476
}
@@ -86,7 +88,7 @@ export default function ClipboardButton({
8688
className={`dc__outline-none-imp p-0 flex dc__transparent--unstyled dc__no-border ${rootClassName}`}
8789
onMouseEnter={handleEnableTippy}
8890
onMouseLeave={handleDisableTippy}
89-
onClick={handleCopyContent}
91+
onClick={isTriggerUndefined && handleCopyContent}
9092
>
9193
{copied ? <Check className={iconClassName} /> : <ICCopy className={iconClassName} />}
9294
</button>

src/Common/Common.service.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616

1717
import moment from 'moment'
18+
import { RuntimeParamsAPIResponseType, RuntimeParamsListItemType } from '@Shared/types'
19+
import { getIsManualApprovalSpecific, sanitizeUserApprovalConfig, stringComparatorBySortOrder } from '@Shared/Helpers'
1820
import { get, post } from './Api'
1921
import { ROUTES } from './Constants'
2022
import { getUrlWithSearchParams, sortCallback } from './Helper'
@@ -41,7 +43,6 @@ import {
4143
CDMaterialListModalServiceUtilProps,
4244
} from './Types'
4345
import { ApiResourceType } from '../Pages'
44-
import { getIsManualApprovalSpecific, sanitizeUserApprovalConfig, stringComparatorBySortOrder } from '@Shared/Helpers'
4546
import { API_TOKEN_PREFIX } from '@Shared/constants'
4647
import { DefaultUserKey } from '@Shared/types'
4748

@@ -317,6 +318,11 @@ const processCDMaterialsApprovalInfo = (enableApproval: boolean, cdMaterialsResu
317318
}
318319
}
319320

321+
export const parseRuntimeParams = (response: RuntimeParamsAPIResponseType): RuntimeParamsListItemType[] =>
322+
Object.entries(response?.envVariables || {})
323+
.map(([key, value], index) => ({ key, value, id: index }))
324+
.sort((a, b) => stringComparatorBySortOrder(a.key, b.key))
325+
320326
const processCDMaterialsMetaInfo = (cdMaterialsResult): CDMaterialsMetaInfo => {
321327
if (!cdMaterialsResult) {
322328
return {
@@ -326,6 +332,7 @@ const processCDMaterialsMetaInfo = (cdMaterialsResult): CDMaterialsMetaInfo => {
326332
resourceFilters: [],
327333
totalCount: 0,
328334
requestedUserId: 0,
335+
runtimeParams: [],
329336
}
330337
}
331338

@@ -336,6 +343,7 @@ const processCDMaterialsMetaInfo = (cdMaterialsResult): CDMaterialsMetaInfo => {
336343
resourceFilters: cdMaterialsResult.resourceFilters ?? [],
337344
totalCount: cdMaterialsResult.totalCount ?? 0,
338345
requestedUserId: cdMaterialsResult.requestedUserId,
346+
runtimeParams: parseRuntimeParams(cdMaterialsResult.runtimeParams),
339347
}
340348
}
341349

src/Common/Constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export const ROUTES = {
106106
PLUGIN_GLOBAL_LIST_DETAIL_V2: 'plugin/global/list/detail/v2',
107107
PLUGIN_GLOBAL_LIST_V2: 'plugin/global/list/v2',
108108
PLUGIN_GLOBAL_LIST_TAGS: 'plugin/global/list/tags',
109+
PLUGIN_LIST_MIN: 'plugin/global/list/v2/min',
109110
DEPLOYMENT_CHARTS_LIST: 'deployment/template/fetch',
110111
USER_LIST_MIN: 'user/list/min',
111112
CONFIG_DATA: 'config/data',
@@ -530,6 +531,8 @@ export const DATE_TIME_FORMATS = {
530531
DD_MMM_YYYY: 'DD MMM YYYY',
531532
}
532533

534+
export const SEMANTIC_VERSION_DOCUMENTATION_LINK = 'https://semver.org/'
535+
533536
export const VULNERABILITIES_SORT_PRIORITY = {
534537
critical: 1,
535538
high: 2,

src/Common/CustomInput/CustomInput.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import { CustomInputProps } from './Types'
1818
import { ReactComponent as Info } from '../../Assets/Icon/ic-info-filled-override.svg'
1919
import { ReactComponent as ErrorIcon } from '../../Assets/Icon/ic-warning.svg'
20+
import { useEffect, useRef } from 'react'
2021

2122
export const CustomInput = ({
2223
name,
@@ -39,7 +40,6 @@ export const CustomInput = ({
3940
handleOnBlur,
4041
readOnly = false,
4142
noTrim = false,
42-
ref,
4343
onKeyPress,
4444
defaultValue,
4545
onKeyDown,
@@ -48,6 +48,17 @@ export const CustomInput = ({
4848
inputWrapClassName = '',
4949
inputProps = {},
5050
}: CustomInputProps) => {
51+
const inputRef = useRef<HTMLInputElement>()
52+
53+
useEffect(() => {
54+
setTimeout(() => {
55+
// Added timeout to ensure the autofocus code is executed post the re-renders
56+
if (inputRef.current && autoFocus) {
57+
inputRef.current.focus()
58+
}
59+
}, 100)
60+
}, [autoFocus])
61+
5162
function handleError(error: any): any[] {
5263
if (!Array.isArray(error)) {
5364
return [error]
@@ -68,9 +79,9 @@ export const CustomInput = ({
6879
}
6980

7081
const renderFormErrorWithIcon = (error: string) => (
71-
<div className="form__error" key={error}>
72-
<ErrorIcon className="form__icon form__icon--error" />
73-
{error}
82+
<div className="flex left mt-4 mb-4 dc__gap-4 cr-5 fs-11 lh-16 fw-4" key={error}>
83+
<ErrorIcon className="icon-dim-16 p-1 form__icon--error dc__align-self-start dc__no-shrink" />
84+
<span>{error}</span>
7485
{error && typeof additionalErrorInfo === 'function' && additionalErrorInfo()}
7586
</div>
7687
)
@@ -124,18 +135,18 @@ export const CustomInput = ({
124135
tabIndex={tabIndex}
125136
autoFocus={autoFocus}
126137
readOnly={readOnly}
127-
ref={ref}
128138
onKeyPress={onKeyPress}
129139
defaultValue={defaultValue}
130140
onKeyDown={onKeyDown}
131141
required={required}
132142
// Will be passing other props like other data attributes etc from inputProps
133143
{...inputProps}
144+
ref={inputRef}
134145
/>
135146

136147
{getInputError()}
137148
{helperText && (
138-
<div className="flex left top dc__gap-4 fs-11 lh-16 cn-7 mt-4">
149+
<div className="flex left top dc__gap-4 fs-11 lh-16 cn-7 pt-4">
139150
<Info className="icon-dim-16" />
140151
<div>{helperText}</div>
141152
</div>

src/Common/CustomInput/Types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import React, { HTMLInputTypeAttribute, InputHTMLAttributes } from 'react'
17+
import React, { HTMLInputTypeAttribute, InputHTMLAttributes, ReactNode } from 'react'
1818

1919
export interface CustomInputProps {
2020
name: string
@@ -33,11 +33,10 @@ export interface CustomInputProps {
3333
autoFocus?: boolean
3434
rootClassName?: string
3535
error?: string[] | string
36-
helperText?: string
36+
helperText?: ReactNode
3737
handleOnBlur?: (e) => void
3838
readOnly?: boolean
3939
noTrim?: boolean
40-
ref?: React.LegacyRef<HTMLInputElement>
4140
onKeyPress?: (e) => void
4241
defaultValue?: string | number | ReadonlyArray<string> | undefined
4342
onKeyDown?: (e) => void

src/Common/Modals/Modal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import React, { useEffect } from 'react'
1818
import ReactDOM from 'react-dom'
1919
import { ModalType } from '../Types'
20+
import { POP_UP_MENU_MODAL_ID } from '@Shared/constants'
2021

2122
/**
2223
* @deprecated Use VisibleModal instead
@@ -78,7 +79,7 @@ export const Modal = ({
7879
innerRef.current = el
7980
}}
8081
id="popup"
81-
className={`${rootClassName} popup ${modal ? 'modal' : ''}`}
82+
className={`${rootClassName} ${POP_UP_MENU_MODAL_ID} ${modal ? 'modal' : ''}`}
8283
style={{ ...style }}
8384
>
8485
{children}

src/Common/Modals/VisibleModal.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
import React, { SyntheticEvent } from 'react'
1818
import ReactDOM from 'react-dom'
19-
import { preventBodyScroll } from '../../Shared'
19+
import { POP_UP_MENU_MODAL_ID, preventBodyScroll } from '../../Shared'
2020
import { stopPropagation } from '../Helper'
2121

2222
export class VisibleModal extends React.Component<{
23-
className: string
23+
className?: string
2424
parentClassName?: string
2525
noBackground?: boolean
2626
close?: (e) => void
@@ -46,6 +46,7 @@ export class VisibleModal extends React.Component<{
4646

4747
componentDidMount() {
4848
document.addEventListener('keydown', this.escFunction)
49+
// show is also being used in modal (i.e, pop up menu for case where we have noBackground as false, so it works in syc with VisibleModal with noBackground as false)
4950
this.modalRef.classList.add(this.props.noBackground ? 'show' : 'show-with-bg')
5051
preventBodyScroll(true)
5152

@@ -66,6 +67,10 @@ export class VisibleModal extends React.Component<{
6667
}
6768

6869
handleBodyClick = (e: SyntheticEvent) => {
70+
const isPopupMenuPresent = document.getElementById(POP_UP_MENU_MODAL_ID)
71+
if (isPopupMenuPresent) {
72+
return
73+
}
6974
e.stopPropagation()
7075

7176
this.props.close?.(e)
@@ -74,7 +79,7 @@ export class VisibleModal extends React.Component<{
7479
render() {
7580
return ReactDOM.createPortal(
7681
<div
77-
className={`visible-modal__body ${this.props.className}`}
82+
className={`visible-modal__body ${this.props.className || ''}`}
7883
onClick={this.handleBodyClick}
7984
data-testid="visible-modal-close"
8085
>

src/Common/Modals/VisibleModal2.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import ReactDOM from 'react-dom'
1919
import { preventBodyScroll } from '../../Shared'
2020
import { stopPropagation } from '../Helper'
2121

22-
export class VisibleModal2 extends React.Component<{ className: string; close?: (e) => void }> {
22+
export class VisibleModal2 extends React.Component<{ className?: string; close?: (e) => void }> {
2323
modalRef = document.getElementById('visible-modal-2')
2424

2525
constructor(props) {
@@ -55,7 +55,7 @@ export class VisibleModal2 extends React.Component<{ className: string; close?:
5555
render() {
5656
return ReactDOM.createPortal(
5757
<div
58-
className={`visible-modal__body ${this.props.className}`}
58+
className={`visible-modal__body ${this.props.className || ''}`}
5959
onClick={this.handleBodyClick}
6060
data-testid="visible-modal2-close"
6161
>

0 commit comments

Comments
 (0)