Skip to content

Commit b87c21f

Browse files
Merge pull request #427 from devtron-labs/feat/build-infra-v2
feat: add support for generic value configuration and target platform in build infra
2 parents 4aa8d7f + eafef24 commit b87c21f

29 files changed

+1808
-886
lines changed

package-lock.json

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

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "1.3.6",
3+
"version": "1.3.7",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",
@@ -61,13 +61,13 @@
6161
"husky": "^7.0.4",
6262
"lint-staged": "^12.5.0",
6363
"moment": "^2.29.4",
64+
"monaco-editor": "0.44.0",
65+
"monaco-yaml": "5.1.1",
6466
"prettier": "^3.1.1",
6567
"react-ga4": "^1.4.1",
6668
"react-toastify": "9.1.3",
6769
"sharp": "^0.33.5",
6870
"svgo": "^3.3.2",
69-
"monaco-editor": "0.44.0",
70-
"monaco-yaml": "5.1.1",
7171
"typescript": "5.5.4",
7272
"vite": "5.4.11",
7373
"vite-plugin-dts": "4.0.3",
@@ -100,15 +100,15 @@
100100
"framer-motion": "^6.5.1",
101101
"jsonpath-plus": "^10.0.0",
102102
"marked": "^13.0.3",
103+
"nanoid": "^3.3.8",
103104
"react-dates": "^21.8.0",
104-
"react-monaco-editor": "^0.54.0",
105105
"react-diff-viewer-continued": "^3.4.0",
106+
"react-monaco-editor": "^0.54.0",
106107
"sass": "^1.69.7",
107108
"tslib": "2.7.0"
108109
},
109110
"overrides": {
110111
"cross-spawn": "^7.0.5",
111-
"nanoid": "^3.3.8",
112112
"react-dates": {
113113
"react": "^17.0.2",
114114
"react-dom": "^17.0.2"

src/Assets/Icon/ic-spray-can.svg

Lines changed: 3 additions & 0 deletions
Loading

src/Common/BreadCrumb/BreadcrumbStore.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ const initialState = {
2121
alias: {},
2222
}
2323

24-
export const BreadcrumbText = ({ heading, isActive }: BreadcrumbTextProps) => (
25-
<h2 className={`m-0 fs-16 fw-6 lh-32 ${isActive ? 'cn-9' : 'cb-5'}`}>{heading}</h2>
24+
export const BreadcrumbText = ({ heading, isActive, shouldTruncate = false }: BreadcrumbTextProps) => (
25+
<h2 className={`m-0 fs-16 fw-6 lh-32 ${shouldTruncate ? 'dc__truncate' : ''} ${isActive ? 'cn-9' : 'cb-5'}`}>{heading}</h2>
2626
)
2727

2828
const Store = ({ children }) => {

src/Common/BreadCrumb/Types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,8 @@ export type UseBreadcrumbOptionalProps = UseBreadcrumbProps | null
4747
export interface BreadcrumbTextProps {
4848
heading: string
4949
isActive?: boolean
50+
/**
51+
* @default false
52+
*/
53+
shouldTruncate?: boolean
5054
}

src/Common/CustomTagSelector/ValidationRules.ts

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

17-
import { PATTERNS } from '../Constants'
17+
import { validateLabelKey, validateLabelValue } from '@Shared/validations'
1818

19-
const validateTagValue = (value: string): string[] => {
20-
const errorList = []
21-
if (value.length > 63) {
22-
errorList.push('Can be max 63 characters')
23-
}
24-
const firstLastAlphanumeric = PATTERNS.START_END_ALPHANUMERIC.test(value)
25-
if (!firstLastAlphanumeric) {
26-
errorList.push('Must start and end with an alphanumeric character')
27-
}
28-
const validValue = PATTERNS.ALPHANUMERIC_WITH_SPECIAL_CHAR.test(value)
29-
if (!validValue) {
30-
errorList.push('Can only contain alphanumeric chars and (-), (_), (.)')
31-
}
32-
return errorList
33-
}
3419
export class ValidationRules {
35-
propagateTagKey = (key: string): { isValid: boolean; messages: string[] } => {
36-
const errorList = []
37-
if (!key) {
38-
errorList.push('Key is required')
39-
} else if (!key.startsWith('devtron.ai/')) {
40-
const re = new RegExp('/', 'g')
41-
const noOfSlashInKey = key.match(re)?.length
42-
if (noOfSlashInKey > 1) {
43-
errorList.push('Key: Max 1 ( / ) allowed')
44-
} else if (noOfSlashInKey === 1) {
45-
const [prefix, name] = key.split('/')
46-
errorList.push(...validateTagValue(name).map((error) => `Name: ${error}`))
47-
if (prefix.length > 253) {
48-
errorList.push('Prefix: Can be max 253 characters')
49-
}
50-
const validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix)
51-
if (!validPrefix) {
52-
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)')
53-
}
54-
} else {
55-
errorList.push(...validateTagValue(key).map((error) => `Name: ${error}`))
56-
}
57-
}
58-
return { isValid: errorList.length === 0, messages: errorList }
20+
propagateTagKey: typeof validateLabelKey = (key) => {
21+
return validateLabelKey(key)
5922
}
6023

6124
propagateTagValue = (value: string, key: string): { isValid: boolean; messages: string[] } => {
6225
const errorList = []
6326
if (!value) {
6427
errorList.push('Value is required')
6528
} else if (!key.startsWith('devtron.ai/')) {
66-
errorList.push(...validateTagValue(value))
29+
errorList.push(...validateLabelValue(value))
6730
}
6831
return { isValid: errorList.length === 0, messages: errorList }
6932
}

src/Common/InfoColorBar/InfoColourbar.tsx

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

17-
import React from 'react'
1817
import { Link } from 'react-router-dom'
1918
import { InfoColourBarType } from '../Types'
19+
import { Tooltip } from '@Common/Tooltip'
2020
import './infoColourBar.scss'
2121

2222
const InfoColourBar = ({
@@ -33,6 +33,7 @@ const InfoColourBar = ({
3333
internalLink,
3434
styles,
3535
hideIcon = false,
36+
textConfig,
3637
}: InfoColourBarType) => {
3738
const renderLink = () => {
3839
if (!linkText) {
@@ -79,6 +80,29 @@ const InfoColourBar = ({
7980
)
8081
}
8182

83+
const renderMessageWrapper = () => {
84+
if (textConfig) {
85+
const { heading, description } = textConfig
86+
87+
return (
88+
<div className="flexbox-col">
89+
{heading && <h6 className="m-0 cn-9 fs-13 fw-6 lh-20 dc__truncate">{heading}</h6>}
90+
91+
<Tooltip content={description}>
92+
<p className="dc__truncate--clamp-3 m-0 cn-9 fs-13 fw-4 lh-20">{description}</p>
93+
</Tooltip>
94+
</div>
95+
)
96+
}
97+
98+
return (
99+
<div className={`info-bar-message-wrapper ${linkClass || ''}`}>
100+
<span className={linkText && redirectLink ? 'mr-5' : ''}>{message}</span>
101+
{renderLink()}
102+
</div>
103+
)
104+
}
105+
82106
return (
83107
<div className="info-bar-container">
84108
<div
@@ -91,10 +115,7 @@ const InfoColourBar = ({
91115
<Icon className={`icon-dim-${iconSize ?? '20'} ${iconClass || ''} mr-8`} />
92116
</div>
93117
)}
94-
<div className={`info-bar-message-wrapper ${linkClass || ''}`}>
95-
<span className={linkText && redirectLink ? 'mr-5' : ''}>{message}</span>
96-
{renderLink()}
97-
</div>
118+
{renderMessageWrapper()}
98119
</div>
99120
{typeof renderActionButton === 'function' && renderActionButton()}
100121
</div>

src/Common/SortableTableHeaderCell/SortableTableHeaderCell.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ const SortableTableHeaderCell = ({
9898
className={`dc__transparent p-0 cn-7 flex dc__content-start dc__gap-4 dc__select-text ${!isSortable ? 'cursor-default' : ''} dc__position-rel`}
9999
onClick={isSortable ? triggerSorting : noop}
100100
disabled={disabled}
101+
tabIndex={disabled || !isSortable ? -1 : 0}
101102
>
102103
<Tooltip showOnTruncate={showTippyOnTruncate} content={title}>
103104
<span className="dc__uppercase dc__truncate">{title}</span>

src/Common/Types.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,18 +208,43 @@ export enum ImageType {
208208
SMALL = 'small',
209209
}
210210

211-
export interface InfoColourBarType {
212-
message: React.ReactNode
211+
interface InfoColourBarTextConfigType {
212+
/**
213+
* If given would be shown above the description, in bold
214+
*/
215+
heading?: string
216+
/**
217+
* If given would be shown below the heading (if given)
218+
*/
219+
description: string
220+
}
221+
222+
type InfoColourBarMessageProp = {
223+
message: ReactNode
224+
linkText?: ReactNode
225+
redirectLink?: string
226+
linkOnClick?: () => void
227+
linkClass?: string
228+
internalLink?: boolean
229+
230+
textConfig?: never
231+
} | {
232+
textConfig: InfoColourBarTextConfigType
233+
234+
message?: never
235+
linkText?: never
236+
redirectLink?: never
237+
linkOnClick?: () => never
238+
linkClass?: never
239+
internalLink?: never
240+
}
241+
242+
export type InfoColourBarType = InfoColourBarMessageProp & {
213243
classname: string
214244
Icon
215245
iconClass?: string
216246
iconSize?: number // E.g. 16, 20, etc.. Currently, there are around 12 sizes supported. Check `icons.css` or `base.scss` for supported sizes or add new size (class names starts with `icon-dim-`).
217247
renderActionButton?: () => JSX.Element
218-
linkText?: React.ReactNode
219-
redirectLink?: string
220-
linkOnClick?: () => void
221-
linkClass?: string
222-
internalLink?: boolean
223248
styles?: CSSProperties
224249
/**
225250
* If true, the icon is not shown

src/Pages/GlobalConfigurations/BuildInfra/BuildInfraConfigForm.tsx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ import BuildInfraFormAction from './BuildInfraFormAction'
2020
import BuildInfraFormItem from './BuildInfraFormItem'
2121
import BuildInfraProfileDescriptionField from './BuildInfraDescriptionField'
2222
import BuildInfraProfileNameField from './BuildInfraProfileNameField'
23-
import { BUILD_INFRA_FORM_FIELDS, BUILD_INFRA_TEXT } from './constants'
24-
import { BuildInfraActionType, BuildInfraConfigFormProps, InheritingHeaderProps } from './types'
23+
import { BUILD_INFRA_DEFAULT_PLATFORM_NAME, BUILD_INFRA_FORM_FIELDS, BUILD_INFRA_TEXT } from './constants'
24+
import {
25+
BuildInfraActionType,
26+
BuildInfraConfigFormProps,
27+
BuildInfraMetaConfigTypes,
28+
InheritingHeaderProps,
29+
} from './types'
2530

26-
const InheritingHeader = ({
27-
defaultHeading,
28-
inheritingData,
29-
isInheriting,
30-
isDefaultProfile,
31-
}: InheritingHeaderProps) => {
31+
const InheritingHeader = ({ defaultHeading, inheritingData, isInheriting, isGlobalProfile }: InheritingHeaderProps) => {
3232
const inheritingDataString = inheritingData.map((data) => `${data.value} ${data.unit ?? ''}`).join(' - ')
3333

34-
if (isDefaultProfile || !isInheriting) {
34+
if (isGlobalProfile || !isInheriting) {
3535
// For typing issues
3636
// eslint-disable-next-line react/jsx-no-useless-fragment
3737
return <>{defaultHeading}</>
@@ -58,11 +58,11 @@ const BuildInfraConfigForm: FunctionComponent<BuildInfraConfigFormProps> = ({
5858
profileInput,
5959
profileInputErrors,
6060
handleProfileInputChange,
61-
isDefaultProfile,
61+
isGlobalProfile,
6262
unitsMap,
6363
configurationContainerLabel,
6464
}) => {
65-
const currentConfigurations = profileInput?.configurations
65+
const currentConfigurations = profileInput?.configurations?.[BUILD_INFRA_DEFAULT_PLATFORM_NAME]
6666

6767
// will get the desired configuration from the currentConfigurations and then check if it is active or not
6868
const isInheritingProfileValues = (actions: BuildInfraActionType[]) =>
@@ -75,18 +75,18 @@ const BuildInfraConfigForm: FunctionComponent<BuildInfraConfigFormProps> = ({
7575

7676
return (
7777
<div className="flexbox-col dc__mxw-920 dc__gap-16">
78-
{!isDefaultProfile && (
78+
{!isGlobalProfile && (
7979
<div className="flexbox-col dc__gap-12">
8080
<BuildInfraProfileNameField
8181
handleProfileInputChange={handleProfileInputChange}
8282
currentValue={profileInput.name}
83-
error={profileInputErrors.name}
83+
error={profileInputErrors[BuildInfraMetaConfigTypes.NAME]}
8484
/>
8585

8686
<BuildInfraProfileDescriptionField
8787
handleProfileInputChange={handleProfileInputChange}
8888
currentValue={profileInput.description}
89-
error={profileInputErrors.description}
89+
error={profileInputErrors[BuildInfraMetaConfigTypes.DESCRIPTION]}
9090
/>
9191
</div>
9292
)}
@@ -106,14 +106,14 @@ const BuildInfraConfigForm: FunctionComponent<BuildInfraConfigFormProps> = ({
106106
(action) => currentConfigurations[action.actionType],
107107
)}
108108
isInheriting={isInheritingProfileValues(field.actions)}
109-
isDefaultProfile={isDefaultProfile}
109+
isGlobalProfile={isGlobalProfile}
110110
/>
111111
}
112112
showDivider={index !== BUILD_INFRA_FORM_FIELDS.length - 1}
113113
isInheriting={isInheritingProfileValues(field.actions)}
114114
handleProfileInputChange={handleProfileInputChange}
115115
locator={field.locator}
116-
isDefaultProfile={isDefaultProfile}
116+
isGlobalProfile={isGlobalProfile}
117117
>
118118
<div className="w-50 flexbox dc__gap-12 w-100 dc__align-start">
119119
{field.actions.map((action) => (
@@ -128,7 +128,7 @@ const BuildInfraConfigForm: FunctionComponent<BuildInfraConfigFormProps> = ({
128128
profileUnitsMap={unitsMap[action.actionType]}
129129
handleProfileInputChange={handleProfileInputChange}
130130
currentUnitName={currentConfigurations[action.actionType].unit}
131-
currentValue={currentConfigurations[action.actionType].value}
131+
currentValue={currentConfigurations[action.actionType].value as number}
132132
/>
133133
))}
134134
</div>

0 commit comments

Comments
 (0)