Skip to content

Commit 1a8b52d

Browse files
authored
Merge pull request #1530 from devtron-labs/custom-input-v2
feat: Custom input v2
2 parents efef56f + 2b6ffd2 commit 1a8b52d

File tree

21 files changed

+211
-193
lines changed

21 files changed

+211
-193
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "0.0.56",
7+
"@devtron-labs/devtron-fe-common-lib": "0.0.58",
88
"@rjsf/core": "^5.13.3",
99
"@rjsf/utils": "^5.13.3",
1010
"@rjsf/validator-ajv8": "^5.13.3",

src/components/ApplicationGroup/CreateAppGroup.tsx

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Checkbox,
44
CHECKBOX_VALUE,
55
ConditionalWrap,
6+
CustomInput,
67
Drawer,
78
GenericEmptyState,
89
Progressing,
@@ -327,25 +328,17 @@ export default function CreateAppGroup({
327328
return (
328329
<div className="p-20 bcn-0 dc__overflow-auto" style={{ height: 'calc(100vh - 128px)' }}>
329330
<div className="form__row mb-16">
330-
<span className="form__label dc__required-field">Name</span>
331-
<input
331+
<CustomInput
332+
label="Name"
332333
tabIndex={1}
333-
className="form__input"
334-
autoComplete="off"
335334
placeholder="Enter filter name"
336-
type="text"
337335
value={appGroupName}
338336
name="name"
339337
onChange={onInputChange}
340338
disabled={selectedAppGroup && !!selectedAppGroup.value}
339+
isRequiredField={true}
340+
error={showErrorMsg && nameErrorMessage()}
341341
/>
342-
343-
{showErrorMsg && (
344-
<span className="form__error">
345-
<Error className="form__icon form__icon--error" />
346-
{nameErrorMessage()}
347-
</span>
348-
)}
349342
</div>
350343
<div className="form__row mb-16">
351344
<span className="form__label">Description (Max 50 characters)</span>

src/components/CustomChart/UploadChartModal.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useRef, useState } from 'react'
22
import { ButtonWithLoader } from '../common'
3-
import { showError, VisibleModal } from '@devtron-labs/devtron-fe-common-lib'
3+
import { CustomInput, noop, showError, VisibleModal } from '@devtron-labs/devtron-fe-common-lib'
44
import { ReactComponent as CloseIcon } from '../../assets/icons/ic-close.svg'
55
import { uploadChart, validateChart } from './customChart.service'
66
import errorImage from '../../assets/img/ic_upload_chart_error.png'
@@ -121,14 +121,14 @@ export default function UploadChartModal({ closeUploadPopup }: UploadChartModalT
121121
)}
122122
<div>
123123
<div>
124-
<span className="fs-13 fw-4 cn-7 dc__required-field">
125-
Chart Name
126-
</span>
127-
<input
128-
type="text"
129-
className="w-100 br-4 en-2 bw-1 mt-6 form__input"
124+
<CustomInput
125+
label="Chart Name"
126+
name="chartName"
127+
onChange={noop}
128+
rootClassName="w-100 br-4 en-2 bw-1 mt-6 form__input"
130129
disabled
131130
value={chartDetail.chartName}
131+
isRequiredField={true}
132132
/>
133133
</div>
134134
<div className="mt-16">

src/components/app/create/CreateApp.tsx

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
RadioGroup,
1515
RadioGroupItem,
1616
noop,
17+
CustomInput,
1718
} from '@devtron-labs/devtron-fe-common-lib'
1819
import { AddNewAppProps, AddNewAppState } from '../types'
1920
import { ViewType, getAppComposeURL, APP_COMPOSE_STAGE, AppCreationType } from '../../../config'
@@ -307,31 +308,19 @@ export class AddNewApp extends Component<AddNewAppProps, AddNewAppState> {
307308
<div className="scrollable-content p-20">
308309
<div className="form__row">
309310
<div className={`${this.props.isJobView ? 'mb-12' : ''}`}>
310-
<span className="form__label dc__required-field">
311-
{this.props.isJobView ? 'Job' : 'App'} Name
312-
</span>
313-
<input
311+
<CustomInput
314312
ref={(node) => (this._inputAppName = node)}
315313
data-testid={`${this.props.isJobView ? 'job' : 'app'}-name-textbox`}
316-
className="form__input"
317-
type="text"
318314
name="app-name"
315+
label={`${this.props.isJobView ? 'Job' : 'App'} Name`}
319316
value={this.state.form.appName}
320317
placeholder={`e.g. my-first-${this.props.isJobView ? 'job' : 'app'}`}
321-
autoComplete="off"
322318
autoFocus={true}
323319
tabIndex={1}
324320
onChange={this.handleAppname}
325-
required
321+
isRequiredField={true}
322+
error={appNameErrors && !this.state.isValid.appName && errorObject[0].message}
326323
/>
327-
<span className="form__error">
328-
{appNameErrors && !this.state.isValid.appName ? (
329-
<>
330-
<Error className="form__icon form__icon--error" />
331-
{errorObject[0].message} <br />
332-
</>
333-
) : null}
334-
</span>
335324
</div>
336325
{!this.props.isJobView && (
337326
<span className="form__text-field-info form__text-field-info--create-app">

src/components/cdPipeline/DeleteCDNode.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState } from 'react'
2-
import { DeleteDialog, DeploymentAppTypes, ForceDeleteDialog } from '@devtron-labs/devtron-fe-common-lib'
2+
import { CustomInput, DeleteDialog, DeploymentAppTypes, ForceDeleteDialog } from '@devtron-labs/devtron-fe-common-lib'
33
import ClusterNotReachableDailog from '../common/ClusterNotReachableDailog/ClusterNotReachableDialog'
44
import { DELETE_ACTION } from '../../config'
55
import { DeleteCDNodeProps, DeleteDialogType } from './types'
@@ -83,13 +83,13 @@ export default function DeleteCDNode({
8383
disabled={showConfirmationBar && deleteInput !== deleteTitleName}
8484
>
8585
{showConfirmationBar && (
86-
<input
87-
type="text"
86+
<CustomInput
8887
disabled={isLoading}
89-
className="form__input mt-12"
88+
rootClassName="mt-12"
9089
data-testId="delete-dialog-input"
9190
placeholder={`Please type ${deleteTitleName} to confirm`}
9291
value={deleteInput}
92+
name="delete-input"
9393
onChange={handleDeleteInputChange}
9494
/>
9595
)}

src/components/charts/AdvancedConfig.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState, useEffect, useMemo } from 'react'
2-
import { showError, Progressing, VisibleModal, useAsync } from '@devtron-labs/devtron-fe-common-lib'
2+
import { showError, Progressing, VisibleModal, useAsync, CustomInput } from '@devtron-labs/devtron-fe-common-lib'
33
import { Select, mapByKey, useKeyDown, Info, Pencil } from '../common'
44
import CodeEditor from '../CodeEditor/CodeEditor'
55
import { getEnvironmentListMin } from '../../services/service'
@@ -11,6 +11,7 @@ import { ReactComponent as LockIcon } from '../../assets/icons/ic-locked.svg'
1111
import { ReactComponent as WarningIcon } from '../../assets/icons/ic-alert-triangle.svg';
1212
import { useHistory } from 'react-router'
1313
import { getSavedValuesListURL } from './charts.helper'
14+
import { renderAdditionalErrorInfo } from './charts.util'
1415

1516
interface AdvancedConfig extends AdvancedConfigHelpers {
1617
chart: ChartGroupEntry;
@@ -141,14 +142,18 @@ const AdvancedConfig: React.FC<AdvancedConfig> = ({ chart, index, fetchChartValu
141142
<div className="advanced-config flex">
142143
<form action="" className="advanced-config__form">
143144
<h1 className="form__title form__title--mb-24" data-testid="advanced-option-heading">{chartName}</h1>
144-
{handleNameChange && <div className="flex column left top mb-16">
145-
<label htmlFor="" className="form__label" data-testid="advanced-option-app-name">App name*</label>
146-
<input type="text" autoComplete="off" className={`form__input ${appName?.error ? 'form__input--error' : ''}`} value={appName.value} onChange={e => handleNameChange(index, e.target.value)} data-testid="advanced-option-app-name-box"/>
147-
{appName?.error &&
148-
<span className="form__error flex left">
149-
<WarningIcon className="mr-5 icon-dim-16" />{appName?.error || ""}
150-
{appName.suggestedName && <span>. Suggested name: <span className="anchor pointer" onClick={e => handleNameChange(index, appName.suggestedName)}>{appName.suggestedName}</span></span>}
151-
</span>}
145+
{handleNameChange && <div className="mb-16">
146+
<CustomInput
147+
name="appName"
148+
label="App name"
149+
rootClassName={`${appName?.error ? 'form__input--error' : ''}`}
150+
value={appName.value}
151+
onChange={(e) => handleNameChange(index, e.target.value)}
152+
data-testid="advanced-option-app-name-box"
153+
isRequiredField={true}
154+
error={appName?.error}
155+
additionalErrorInfo={renderAdditionalErrorInfo(handleNameChange, appName.suggestedName, index)}
156+
/>
152157
</div>}
153158
{handleEnvironmentChange && <div className="flex top mb-16">
154159
<div className="flex column half left top">

src/components/charts/charts.util.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,21 @@ export const QueryParams = {
9999
export const PaginationParams = {
100100
pageOffset: 0,
101101
pageSize: 20
102-
}
102+
}
103+
104+
export const renderAdditionalErrorInfo = (
105+
handleNameChange: (index: number, suggestedName: string) => void,
106+
suggestedName: string,
107+
index: number,
108+
): JSX.Element => {
109+
return (
110+
suggestedName && (
111+
<>
112+
. Suggested Name:
113+
<span className="anchor pointer" onClick={(e) => handleNameChange(index, suggestedName)}>
114+
{suggestedName}
115+
</span>
116+
</>
117+
)
118+
)
119+
}

src/components/charts/modal/ChartGroupBasicDeploy.tsx

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React, { Component } from 'react';
2-
import { DialogForm, DialogFormSubmit, showError } from '@devtron-labs/devtron-fe-common-lib'
2+
import { CustomInput, DialogForm, DialogFormSubmit, showError } from '@devtron-labs/devtron-fe-common-lib'
33
import { ProjectType, ChartGroupEntry, EnvironmentType } from '../charts.types';
44
import { ReactComponent as Edit } from '../../../assets/icons/ic-edit.svg';
55
import { ReactComponent as Error } from '../../../assets/icons/ic-warning.svg';
6-
import { styles, smallMenuList, menuList, DropdownIndicator } from '../charts.util';
6+
import { styles, smallMenuList, menuList, DropdownIndicator, renderAdditionalErrorInfo } from '../charts.util';
77
import { Option } from '../../v2/common/ReactSelect.utils';
88
import placeHolder from '../../../assets/icons/ic-plc-chart.svg';
99
import ReactSelect from 'react-select';
@@ -192,38 +192,41 @@ function ApplicationNameList({ charts, handleNameChange, showAppNames }) {
192192
}
193193

194194
let listClassNames = "deploy-selected-chart__list";
195-
if (showAppNames) { listClassNames = `${listClassNames} show` };
195+
if (showAppNames) {
196+
listClassNames = `${listClassNames} show`
197+
}
198+
196199
return (
197200
<div
198201
className={listClassNames}>
199202
{charts.map((chart, index) => {
200-
if (chart.isEnabled) return <div key={index} className="form__row deploy-selected-chart__list-item">
201-
<img onError={handleImageError} src={chart.chartMetaData.icon || ""} alt="" className="dc__chart-grid-item__icon" />
202-
<div className="w-100">
203-
<span className="form__label form__label--lower">{chart.chartMetaData.chartRepoName}/{chart.chartMetaData.chartName}</span>
204-
<input autoComplete="off" className={`form__input ${chart?.name?.error ? 'form__input--error' : ''}`} type="text" data-testid={`chart-name-edit-input-${index}`} tabIndex={index + 1} value={chart.name.value}
205-
onChange={(event) => {
206-
handleNameChange(index, event.target.value)
207-
}} />
208-
<span className={`form__error`}>
209-
{chart.name.error &&
210-
<><Error className="form__icon form__icon--error" />
211-
<>{chart.name.error}.
212-
{chart.name.suggestedName &&
213-
<> Suggested Name:
214-
<span className="anchor pointer"
215-
onClick={(e) => handleNameChange(index, chart.name.suggestedName)}>
216-
{chart.name.suggestedName}
217-
</span>
218-
</>
219-
}
220-
</>
221-
<br />
222-
</>
223-
}
224-
</span>
203+
if (chart.isEnabled) return (
204+
<div key={index} className="form__row deploy-selected-chart__list-item">
205+
<img
206+
onError={handleImageError}
207+
src={chart.chartMetaData.icon || ''}
208+
alt=""
209+
className="dc__chart-grid-item__icon"
210+
/>
211+
<div className="w-100">
212+
<CustomInput
213+
name="name"
214+
label={`${chart.chartMetaData.chartRepoName}/${chart.chartMetaData.chartName}`}
215+
labelClassName="form__label--lower"
216+
rootClassName={`form__input ${chart?.name?.error ? 'form__input--error' : ''}`}
217+
data-testid={`chart-name-edit-input-${index}`}
218+
tabIndex={index + 1}
219+
value={chart.name.value}
220+
onChange={(event) => {
221+
handleNameChange(index, event.target.value)
222+
}}
223+
error={chart.name.error}
224+
isRequiredField={true}
225+
additionalErrorInfo={renderAdditionalErrorInfo(handleNameChange, chart.name.suggestedName, index)}
226+
/>
227+
</div>
225228
</div>
226-
</div>
229+
)
227230
else return null
228231
})}
229232
</div>

src/components/charts/modal/CreateChartGroup.tsx

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react'
22
import { ChartGroup, CreateChartGroupProps } from '../charts.types'
3-
import { showError, Progressing, DialogForm } from '@devtron-labs/devtron-fe-common-lib'
3+
import { showError, Progressing, DialogForm, CustomInput } from '@devtron-labs/devtron-fe-common-lib'
44
import { getChartGroups, saveChartGroup, updateChartGroup } from '../charts.service'
55
import { getChartGroupEditURL } from '../charts.helper'
66
import { toast } from 'react-toastify'
@@ -163,29 +163,18 @@ export default class CreateChartGroup extends Component<CreateChartGroupProps, C
163163
onSave={this.saveChartGroup}
164164
>
165165
<label className="form__row">
166-
<span className="form__label dc__required-field" data-testid="create-group-name-heading">Name</span>
167-
<input
168-
className="form__input"
169-
autoComplete="off"
170-
type="text"
166+
<CustomInput
171167
name="name"
168+
label="Name"
172169
value={this.state.name.value}
173170
data-testid="create-group-name-value"
174171
placeholder="e.g. elastic-stack"
175172
autoFocus={true}
176173
tabIndex={1}
177174
onChange={this.handleNameChange}
178-
required
175+
isRequiredField={true}
176+
error={this.state.name.error}
179177
/>
180-
<span className="form__error">
181-
{this.state.name.error.map((err) => {
182-
return (
183-
<div data-testid="chart-group-min-5-char">
184-
<Error className="form__icon form__icon--error" /> {err}
185-
</div>
186-
)
187-
})}
188-
</span>
189178
</label>
190179

191180
<label className="form__row">

src/components/charts/modal/DeployChart.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
DropdownIcon,
66
useJsonYaml,
77
} from '../../common'
8-
import { ServerErrors, showError, Progressing, DeleteDialog, ForceDeleteDialog, sortCallback, getTeamListMin, ResponseType, DeploymentAppTypes } from '@devtron-labs/devtron-fe-common-lib'
8+
import { ServerErrors, showError, Progressing, DeleteDialog, ForceDeleteDialog, sortCallback, getTeamListMin, ResponseType, DeploymentAppTypes, CustomInput } from '@devtron-labs/devtron-fe-common-lib'
99
import { getEnvironmentListHelmApps, getEnvironmentListMin } from '../../../services/service'
1010
import { toast } from 'react-toastify'
1111
import { DeployChartProps } from './deployChart.types'
@@ -522,12 +522,11 @@ const DeployChart: React.FC<DeployChartProps> = ({
522522
<div className="overflown" ref={deployChartForm}>
523523
<div className="hide-scroll">
524524
<label className="form__row form__row--w-100">
525-
<span className="form__label">App Name</span>
526-
<input
527-
autoComplete="off"
525+
<CustomInput
526+
name="appName"
527+
label="App Name"
528528
tabIndex={1}
529529
placeholder="App name"
530-
className="form__input"
531530
value={appName}
532531
autoFocus
533532
disabled={!!isUpdate}

0 commit comments

Comments
 (0)