Skip to content

Commit ef93ba8

Browse files
Merge pull request #222 from devtron-labs/feat/create-plugin
feat: create plugin
2 parents e2cea1a + b2a1cb5 commit ef93ba8

35 files changed

+545
-82
lines changed

package-lock.json

Lines changed: 2 additions & 2 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.2.23",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

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/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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export const CustomInput = ({
135135

136136
{getInputError()}
137137
{helperText && (
138-
<div className="flex left top dc__gap-4 fs-11 lh-16 cn-7 mt-4">
138+
<div className="flex left top dc__gap-4 fs-11 lh-16 cn-7 pt-4">
139139
<Info className="icon-dim-16" />
140140
<div>{helperText}</div>
141141
</div>

src/Common/CustomInput/Types.ts

Lines changed: 2 additions & 2 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,7 +33,7 @@ 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

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
>

src/Common/MultiSelectCustomization.tsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,23 @@
1616

1717
import React from 'react'
1818
import Select, { components } from 'react-select'
19+
import Tippy from '@tippyjs/react'
20+
import { ReactComponent as ICErrorCross } from '@Icons/ic-error-cross.svg'
1921
import { ReactComponent as ClearIcon } from '../Assets/Icon/ic-appstatus-cancelled.svg'
2022
import { ReactComponent as Check } from '../Assets/Icon/ic-check.svg'
2123
import { ReactComponent as RedWarning } from '../Assets/Icon/ic-error-medium.svg'
2224
import { Checkbox } from './Checkbox'
2325
import { CHECKBOX_VALUE } from './Types'
26+
import { ConditionalWrap } from './Helper'
2427

2528
export const Option = (props) => {
26-
const { selectOption, data, isDisabled } = props
29+
const { selectOption, data, isDisabled, showTippy, tippyPlacement } = props
2730

2831
const handleChange = (e) => {
2932
selectOption(data)
3033
}
3134

32-
return (
35+
const renderOption = () => (
3336
<div
3437
className={`flex left pl-12 cursor dc__gap-8 ${isDisabled ? 'dc__disabled' : ''}`}
3538
style={{ background: props.isFocused ? 'var(--N100)' : 'transparent' }}
@@ -44,6 +47,26 @@ export const Option = (props) => {
4447
<components.Option {...props} />
4548
</div>
4649
)
50+
51+
const renderTippy = (children) => {
52+
const placement = tippyPlacement === 'left' || tippyPlacement === 'right' ? tippyPlacement : 'auto'
53+
return (
54+
<Tippy
55+
content={data.label}
56+
className="default-tt dc__mxw-200 dc__word-break"
57+
placement={placement}
58+
arrow={false}
59+
>
60+
{children}
61+
</Tippy>
62+
)
63+
}
64+
65+
return (
66+
<ConditionalWrap condition={showTippy} wrap={renderTippy}>
67+
{renderOption()}
68+
</ConditionalWrap>
69+
)
4770
}
4871

4972
export const SingleSelectOption = (props) => {
@@ -116,14 +139,14 @@ export const MultiValueRemove = (props) => {
116139
const {
117140
data,
118141
innerProps: { onClick, onMouseDown },
119-
selectProps,
120142
} = props
121143
return (
122144
<components.MultiValueRemove {...props}>
123-
<ClearIcon
145+
<ICErrorCross
124146
{...{ onClick, onMouseDown }}
125147
onClick={(e) => onClick(data)}
126-
style={{ height: '18px', width: '18px' }}
148+
className="icon-n5"
149+
style={{ height: '14px', width: '14px' }}
127150
/>
128151
</components.MultiValueRemove>
129152
)
@@ -139,7 +162,7 @@ export const MultiValueChipContainer = ({ validator, isAllSelected = false, ...p
139162
return (
140163
<components.MultiValueContainer {...{ data, innerProps, selectProps }}>
141164
<div className="flex left fs-12 pl-4 pr-4 dc__ellipsis-right">
142-
{!isValidEmail && <RedWarning className="mr-4 icon-dim-16" />}
165+
{!isValidEmail && <RedWarning className="mr-4 icon-dim-16 dc__no-shrink" />}
143166
<div className={`dc__ellipsis-right ${isValidEmail ? 'cn-9' : 'cr-5'}`}>{label}</div>
144167
</div>
145168
{children[1]}

src/Common/Toggle/Toggle.scss

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,31 @@ input:checked + .toggle__slider {
9292
input:focus + .toggle__slider {
9393
box-shadow: 0 0 1px var(--color);
9494
}
95+
96+
.dc__toggle-square-toggle {
97+
.toggle__slider {
98+
border-color: var(--color);
99+
background-color: var(--color) !important;
100+
101+
&:before {
102+
background-color: transparent;
103+
}
104+
105+
&.with-icon svg {
106+
height: 16px;
107+
width: 16px;
108+
margin-top: 1px;
109+
background-color: var(--N0);
110+
left: 0;
111+
padding: 0;
112+
border-radius: 3px;
113+
}
114+
}
115+
116+
input:checked + .toggle__slider {
117+
&.with-icon svg {
118+
left: -6px;
119+
background-color: var(--N0);
120+
}
121+
}
122+
}

src/Common/Types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ export interface RadioGroupItemProps {
224224
export interface RadioGroupInterface {
225225
name: string
226226
onChange: any
227-
className?: string
228227
initialTab: string
229-
disabled: boolean
230228
children: ReactNode
229+
disabled?: boolean
230+
className?: string
231231
}
232232

233233
export interface RadioInterface {

src/Shared/Components/CICDHistory/CDEmptyState.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import React from 'react'
18-
import { GenericEmptyState } from '../../../Common'
18+
import { GenericEmptyState, ImageType } from '../../../Common'
1919
import AppNotDeployed from '../../../Assets/Img/app-not-deployed.png'
2020
import { EMPTY_STATE_STATUS } from '../../constants'
2121

@@ -42,17 +42,16 @@ const CDEmptyState = ({
4242
}) => {
4343
const handleCDEmptyStateButton = () =>
4444
actionButtonText ? (
45-
<div
46-
className={`${
47-
actionButtonClass || 'cb-5 bcn-0 en-2'
48-
} fcn-0 fw-6 fs-13 flexbox br-4 pl-16 pr-16 pt-8 pb-8 pointer`}
45+
<button
46+
type="button"
47+
className={`${actionButtonClass || ''} cta secondary flex h-32`}
4948
onClick={actionHandler}
5049
data-testid={dataTestId}
5150
>
5251
{ActionButtonIcon && !actionButtonIconRight && <ActionButtonIcon className="add-icon" />}
5352
{actionButtonText}
5453
{ActionButtonIcon && actionButtonIconRight && <ActionButtonIcon className="icon-dim-16 ml-8" />}
55-
</div>
54+
</button>
5655
) : null
5756
return (
5857
<div className="dc__position-rel" style={{ backgroundColor: 'var(--window-bg)' }}>
@@ -62,6 +61,7 @@ const CDEmptyState = ({
6261
title={title || EMPTY_STATE_STATUS.CD_EMPTY_STATE.TITLE}
6362
subTitle={subtitle || EMPTY_STATE_STATUS.CD_EMPTY_STATE.SUBTITLE}
6463
isButtonAvailable
64+
imageType={ImageType.Large}
6565
renderButton={handleCDEmptyStateButton}
6666
/>
6767
</div>

0 commit comments

Comments
 (0)