Skip to content

Commit 5b1a0da

Browse files
committed
Merge branch 'develop' of github.com:devtron-labs/devtron-fe-common-lib into feat/plugin-policy-v2
2 parents 31a7d7b + 82057e1 commit 5b1a0da

30 files changed

+321
-77
lines changed

package-lock.json

Lines changed: 18 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: 2 additions & 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.7.3-beta-4",
3+
"version": "1.0.5",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",
@@ -40,6 +40,7 @@
4040
"@testing-library/react": "^12.1.4",
4141
"@tippyjs/react": "^4.2.0",
4242
"@typeform/embed-react": "2.20.0",
43+
"@types/dompurify": "^3.0.5",
4344
"@types/react": "17.0.39",
4445
"@types/react-dom": "17.0.13",
4546
"@types/react-router-dom": "^5.3.3",

src/Common/Api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,4 +264,4 @@ export const abortPreviousRequests = <T>(
264264
*/
265265
export const getIsRequestAborted = (error) =>
266266
// The 0 code is common for aborted and blocked requests
267-
error && error.code === 0 && error.message.search('abort|aborted')
267+
error && error.code === 0 && error.message.search('abort|aborted') > -1

src/Common/CodeEditor/codeEditor.scss

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,6 @@
105105
min-height: 300px;
106106
}
107107

108-
.code-editor__information {
109-
font-size: 12px;
110-
font-weight: 400;
111-
line-height: 1.33;
112-
letter-spacing: normal;
113-
color: var(--N900);
114-
height: auto;
115-
padding: 8px 16px;
116-
border-bottom: 1px solid #d6dbdf;
117-
background-color: var(--B100);
118-
}
119-
120108
.code-editor__information-info-icon {
121109
width: 16px;
122110
height: 16px;
@@ -140,16 +128,6 @@
140128
background: url('../../Assets/Icon/ic-compare.svg');
141129
}
142130

143-
.code-editor__error {
144-
background-color: #fde7e7;
145-
color: #862020;
146-
font-size: 12px;
147-
font-weight: 400;
148-
line-height: 1.33;
149-
padding: 8px 16px;
150-
border-bottom: 1px solid #d6dbdf;
151-
}
152-
153131
.monaco-editor-hover {
154132
margin-left: 40px;
155133
}

src/Common/Constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export const URLS = {
6767
GLOBAL_CONFIG_DEPLOYMENT_CHARTS_LIST: '/global-config/deployment-charts',
6868
NETWORK_STATUS_INTERFACE: '/network-status-interface',
6969
CONFIG_DRIFT: 'config-drift',
70+
RESOURCE_BROWSER: '/resource-browser',
7071
}
7172

7273
export const ROUTES = {
@@ -114,6 +115,7 @@ export const ROUTES = {
114115
DEPLOYMENT_CHARTS_LIST: 'deployment/template/fetch',
115116
USER_LIST_MIN: 'user/list/min',
116117
CONFIG_DATA: 'config/data',
118+
K8S_RESOURCE_LIST: 'k8s/resource/list',
117119
}
118120

119121
export enum KEY_VALUE {
@@ -510,6 +512,7 @@ export const API_STATUS_CODES = {
510512
PERMISSION_DENIED: 403,
511513
NOT_FOUND: 404,
512514
EXPECTATION_FAILED: 417,
515+
UNPROCESSABLE_ENTITY: 422,
513516
LOCKED: 423,
514517
}
515518

src/Common/DraggableWrapper/DraggableWrapper.tsx

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

17-
import React, { useEffect, useRef, useState } from 'react'
17+
import { useEffect, useRef, useState } from 'react'
1818
import Draggable, { ControlPosition, DraggableData } from 'react-draggable'
1919
import { DraggableWrapperProps, DraggablePositionVariant } from './types'
2020
import { useWindowSize } from '../Hooks'
@@ -71,6 +71,12 @@ export default function DraggableWrapper({
7171
const y = baseY - nodeRefHeight - boundaryGap
7272
return { x, y }
7373
}
74+
case DraggablePositionVariant.SCREEN_BOTTOM_RIGHT: {
75+
const x = windowSize.width - parentRect.left - nodeRefWidth - boundaryGap
76+
const y = windowSize.height - parentRect.top - nodeRefHeight - boundaryGap
77+
78+
return { x, y }
79+
}
7480
// Add more cases for other variants if needed
7581
default: {
7682
// Since need node to be in center of screen so subtracting width/2 by left of parentRect it will start the node from center but want node's midpoint at center so subtracting node's width from it.

src/Common/DraggableWrapper/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { HTMLAttributes, ReactNode, RefObject } from 'react'
1919
export enum DraggablePositionVariant {
2020
PARENT_BOTTOM_CENTER = 'PARENT_BOTTOM_CENTER',
2121
SCREEN_BOTTOM_CENTER = 'SCREEN_BOTTOM_CENTER',
22+
SCREEN_BOTTOM_RIGHT = 'SCREEN_BOTTOM_RIGHT',
2223
// Can add more based on requirement
2324
}
2425

src/Common/ErrorScreenManager.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const ErrorScreenManager = ({
2929
reloadClass,
3030
heightToDeduct,
3131
redirectURL,
32+
imageType = ImageType.Large,
3233
}: ErrorScreenManagerProps) => {
3334
const getMessage = () => {
3435
switch (code) {
@@ -39,7 +40,7 @@ const ErrorScreenManager = ({
3940
title={ERROR_EMPTY_SCREEN.BAD_REQUEST}
4041
subTitle={subtitle || ERROR_EMPTY_SCREEN.BAD_REQUEST_MESSAGE}
4142
image={badRequest}
42-
imageType={ImageType.Large}
43+
imageType={imageType}
4344
heightToDeduct={heightToDeduct}
4445
reload={reload}
4546
/>
@@ -51,7 +52,7 @@ const ErrorScreenManager = ({
5152
title={ERROR_EMPTY_SCREEN.UNAUTHORIZED}
5253
subTitle={subtitle || ERROR_EMPTY_SCREEN.UNAUTHORIZED_MESSAGE}
5354
image={unauthorized}
54-
imageType={ImageType.Large}
55+
imageType={imageType}
5556
heightToDeduct={heightToDeduct}
5657
/>
5758
)
@@ -62,7 +63,7 @@ const ErrorScreenManager = ({
6263
title={ERROR_EMPTY_SCREEN.FORBIDDEN}
6364
subTitle={subtitle || ERROR_EMPTY_SCREEN.FORBIDDEN_MESSAGE}
6465
image={unauthorized}
65-
imageType={ImageType.Large}
66+
imageType={imageType}
6667
heightToDeduct={heightToDeduct}
6768
/>
6869
)
@@ -73,7 +74,7 @@ const ErrorScreenManager = ({
7374
title={ERROR_EMPTY_SCREEN.PAGE_NOT_FOUND}
7475
subTitle={subtitle || ERROR_EMPTY_SCREEN.PAGE_NOT_EXIST}
7576
image={notFound}
76-
imageType={ImageType.Large}
77+
imageType={imageType}
7778
heightToDeduct={heightToDeduct}
7879
redirectURL={redirectURL}
7980
/>
@@ -85,7 +86,7 @@ const ErrorScreenManager = ({
8586
title={ERROR_EMPTY_SCREEN.INTERNAL_SERVER_ERROR}
8687
subTitle={subtitle || ERROR_EMPTY_SCREEN.INTERNAL_SERVER_ERROR_MESSAGE}
8788
image={badRequest}
88-
imageType={ImageType.Large}
89+
imageType={imageType}
8990
heightToDeduct={heightToDeduct}
9091
reload={reload}
9192
/>
@@ -97,7 +98,7 @@ const ErrorScreenManager = ({
9798
title={ERROR_EMPTY_SCREEN.BAD_GATEWAY}
9899
subTitle={subtitle || ERROR_EMPTY_SCREEN.BAD_GATEWAY_MESSAGE}
99100
image={badRequest}
100-
imageType={ImageType.Large}
101+
imageType={imageType}
101102
heightToDeduct={heightToDeduct}
102103
reload={reload}
103104
/>
@@ -109,7 +110,7 @@ const ErrorScreenManager = ({
109110
title={ERROR_EMPTY_SCREEN.SERVICE_TEMPORARY_UNAVAILABLE}
110111
subTitle={subtitle || ERROR_EMPTY_SCREEN.SERVICE_TEMPORARY_UNAVAILABLE_MESSAGE}
111112
image={badRequest}
112-
imageType={ImageType.Large}
113+
imageType={imageType}
113114
heightToDeduct={heightToDeduct}
114115
reload={reload}
115116
/>

src/Common/Helper.tsx

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
*/
1616

1717
import React, { SyntheticEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react'
18+
import DOMPurify from 'dompurify'
1819
import { JSONPath, JSONPathOptions } from 'jsonpath-plus'
19-
import { compare as compareJSON, applyPatch } from 'fast-json-patch'
20+
import { compare as compareJSON, applyPatch, unescapePathComponent } from 'fast-json-patch'
2021
import { components } from 'react-select'
2122
import * as Sentry from '@sentry/browser'
2223
import moment from 'moment'
@@ -594,7 +595,7 @@ const buildObjectFromPathTokens = (index: number, tokens: string[], value: any)
594595
const isKeyNumber = !Number.isNaN(numberKey)
595596
return isKeyNumber
596597
? [...Array(numberKey).fill(null), buildObjectFromPathTokens(index + 1, tokens, value)]
597-
: { [key]: buildObjectFromPathTokens(index + 1, tokens, value) }
598+
: { [unescapePathComponent(key)]: buildObjectFromPathTokens(index + 1, tokens, value) }
598599
}
599600

600601
/**
@@ -642,7 +643,8 @@ export const powerSetOfSubstringsFromStart = (strings: string[], regex: RegExp)
642643
return _keys
643644
})
644645

645-
export const convertJSONPointerToJSONPath = (pointer: string) => pointer.replace(/\/([\*0-9]+)\//g, '[$1].').replace(/\//g, '.').replace(/\./, '$.')
646+
export const convertJSONPointerToJSONPath = (pointer: string) =>
647+
unescapePathComponent(pointer.replace(/\/([\*0-9]+)\//g, '[$1].').replace(/\//g, '.').replace(/\./, '$.'))
646648

647649
export const flatMapOfJSONPaths = (
648650
paths: string[],
@@ -953,3 +955,42 @@ export const throttle = <T extends (...args: unknown[]) => unknown>(
953955
}
954956
}
955957
}
958+
959+
// TODO: Might need to expose sandbox and referrer policy
960+
export const getSanitizedIframe = (iframeString: string) =>
961+
DOMPurify.sanitize(iframeString, {
962+
ADD_TAGS: ['iframe'],
963+
ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'],
964+
})
965+
966+
/**
967+
* This method adds default attributes to iframe - title, loading ="lazy", width="100%", height="100%"
968+
*/
969+
export const getIframeWithDefaultAttributes = (iframeString: string, defaultName?: string): string => {
970+
const parentDiv = document.createElement('div')
971+
parentDiv.innerHTML = getSanitizedIframe(iframeString)
972+
973+
974+
const iframe = parentDiv.querySelector('iframe')
975+
if (iframe) {
976+
if (!iframe.hasAttribute('title') && !!defaultName) {
977+
iframe.setAttribute('title', defaultName)
978+
}
979+
980+
if (!iframe.hasAttribute('loading')) {
981+
iframe.setAttribute('loading', 'lazy')
982+
}
983+
984+
if (!iframe.hasAttribute('width')) {
985+
iframe.setAttribute('width', '100%')
986+
}
987+
988+
if (!iframe.hasAttribute('height')) {
989+
iframe.setAttribute('height', '100%')
990+
}
991+
992+
return parentDiv.innerHTML
993+
}
994+
995+
return iframeString
996+
}

src/Common/RJSF/Form.tsx

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

17+
import { forwardRef } from 'react'
1718
import RJSF from '@rjsf/core'
1819
import RJSFValidator from '@rjsf/validator-ajv8'
1920

@@ -27,7 +28,7 @@ import './rjsfForm.scss'
2728
const Form = RJSF
2829
const validator = RJSFValidator
2930

30-
export const RJSFForm = (props: FormProps) => (
31+
export const RJSFForm = forwardRef((props: FormProps, ref: FormProps['ref']) => (
3132
<Form
3233
noHtml5Validate
3334
showErrorList={false}
@@ -42,5 +43,6 @@ export const RJSFForm = (props: FormProps) => (
4243
formContext={props.formData}
4344
widgets={{ ...widgets, ...props.widgets }}
4445
translateString={translateString}
46+
ref={ref}
4547
/>
46-
)
48+
))

0 commit comments

Comments
 (0)