Skip to content

Commit 2007479

Browse files
committed
fix: Add validation for empty keys in KeyValueTable
1 parent be5e46a commit 2007479

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

src/Shared/Components/KeyValueTable/KeyValueTable.component.tsx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import { stringComparatorBySortOrder } from '@Shared/Helpers'
2828
import { DEFAULT_SECRET_PLACEHOLDER } from '@Shared/constants'
2929

3030
import { KeyValueRow, KeyValueTableProps } from './KeyValueTable.types'
31+
import { DUPLICATE_KEYS_VALIDATION_MESSAGE, EMPTY_KEY_VALIDATION_MESSAGE } from './constants'
3132
import './KeyValueTable.scss'
32-
import { DUPLICATE_KEYS_VALIDATION_MESSAGE } from './constants'
3333

3434
const renderWithReadOnlyTippy = (children: ReactElement) => (
3535
<Tippy
@@ -59,6 +59,7 @@ export const KeyValueTable = <K extends string>({
5959
errorMessages: parentErrorMessages = [],
6060
onError,
6161
validateDuplicateKeys = false,
62+
validateEmptyKeys = false,
6263
}: KeyValueTableProps<K>) => {
6364
// CONSTANTS
6465
const { headers, rows } = config
@@ -106,13 +107,20 @@ export const KeyValueTable = <K extends string>({
106107
[updatedRows],
107108
)
108109

109-
const validationSchema: typeof parentValidationSchema = (value, key) => {
110+
const validationSchema: typeof parentValidationSchema = (value, key, rowId) => {
110111
if (validateDuplicateKeys && key === firstHeaderKey && updatedRowsKeysFrequency[value] > 1) {
111112
return false
112113
}
113114

115+
if (validateEmptyKeys && key === firstHeaderKey && !value) {
116+
const isValuePresentAtRow = updatedRows.some(({ id }) => id === rowId && value)
117+
if (isValuePresentAtRow) {
118+
return true
119+
}
120+
}
121+
114122
if (parentValidationSchema) {
115-
return parentValidationSchema(value, key)
123+
return parentValidationSchema(value, key, rowId)
116124
}
117125

118126
return true
@@ -141,10 +149,20 @@ export const KeyValueTable = <K extends string>({
141149
}
142150
}
143151

152+
if (validateEmptyKeys) {
153+
const isEmptyKeyPresent = editedRows.some(
154+
(row) => !row.data[firstHeaderKey].value && row.data[secondHeaderKey].value,
155+
)
156+
157+
if (isEmptyKeyPresent) {
158+
return false
159+
}
160+
}
161+
144162
const isValid = editedRows.every(
145-
({ data: _data }) =>
146-
validationSchema(_data[firstHeaderKey].value, firstHeaderKey) &&
147-
validationSchema(_data[secondHeaderKey].value, secondHeaderKey),
163+
({ data: _data, id }) =>
164+
validationSchema(_data[firstHeaderKey].value, firstHeaderKey, id) &&
165+
validationSchema(_data[secondHeaderKey].value, secondHeaderKey, id),
148166
)
149167

150168
return isValid
@@ -341,15 +359,17 @@ export const KeyValueTable = <K extends string>({
341359
const renderErrorMessages = (
342360
value: Parameters<typeof validationSchema>[0],
343361
key: Parameters<typeof validationSchema>[1],
362+
rowId: KeyValueRow<K>['id'],
344363
) => {
345-
const showErrorMessages = showError && !validationSchema(value, key)
364+
const showErrorMessages = showError && !validationSchema(value, key, rowId)
346365
if (!showErrorMessages) {
347366
return null
348367
}
349368

350369
return (
351370
<div className="key-value-table__error bcn-0 dc__border br-4 py-7 px-8 flexbox-col dc__gap-4">
352371
{validateDuplicateKeys && renderErrorMessage(DUPLICATE_KEYS_VALIDATION_MESSAGE)}
372+
{validateEmptyKeys && renderErrorMessage(EMPTY_KEY_VALIDATION_MESSAGE)}
353373
{parentErrorMessages.map((error) => renderErrorMessage(error))}
354374
</div>
355375
)
@@ -391,7 +411,7 @@ export const KeyValueTable = <K extends string>({
391411
<Fragment key={key}>
392412
<ConditionalWrap wrap={renderWithReadOnlyTippy} condition={readOnly}>
393413
<div
394-
className={`key-value-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${readOnly || row.data[key].disabled ? 'cursor-not-allowed no-hover' : ''} ${showError && !validationSchema(row.data[key].value, key) ? 'key-value-table__cell--error no-hover' : ''}`}
414+
className={`key-value-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${readOnly || row.data[key].disabled ? 'cursor-not-allowed no-hover' : ''} ${showError && !validationSchema(row.data[key].value, key, row.id) ? 'key-value-table__cell--error no-hover' : ''}`}
395415
>
396416
{maskValue?.[key] && row.data[key].value ? (
397417
<div className="py-8 px-12 h-36 flex">
@@ -426,7 +446,7 @@ export const KeyValueTable = <K extends string>({
426446
*
427447
</span>
428448
)}
429-
{renderErrorMessages(row.data[key].value, key)}
449+
{renderErrorMessages(row.data[key].value, key, row.id)}
430450
</>
431451
)}
432452
</div>

src/Shared/Components/KeyValueTable/KeyValueTable.types.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,23 @@ type ErrorUIProps =
6262
*/
6363
showError: true
6464
/**
65-
* If true, would show error tooltip on the cell.
65+
* @default - false
66+
* If true, would validate for duplicate keys and if present would show error tooltip on the cell.
6667
*/
6768
validateDuplicateKeys?: boolean
69+
/**
70+
* @default - false
71+
* If true, would validate for rows having values but no key and if error would show error tooltip on the cell.
72+
*/
73+
validateEmptyKeys?: boolean
6874
}
6975
| {
7076
/**
7177
* Indicates whether to show errors.
7278
*/
7379
showError?: false
7480
validateDuplicateKeys?: never
81+
validateEmptyKeys?: never
7582
}
7683

7784
/**
@@ -120,10 +127,11 @@ export type KeyValueTableProps<K extends string> = {
120127
* The function to use to validate the value of the cell.
121128
* @param value - The value to validate.
122129
* @param key - The row key of the value.
130+
* @param rowId - The id of the row.
123131
* @returns Return true if the value is valid, otherwise false
124132
* and set `showError` to `true` and provide errorMessages array to show error message.
125133
*/
126-
validationSchema?: (value: string, key: K) => boolean
134+
validationSchema?: (value: string, key: K, rowId: string | number) => boolean
127135
/**
128136
* An array of error messages to be displayed in the cell error tooltip.
129137
*/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const DUPLICATE_KEYS_VALIDATION_MESSAGE = 'Keys must be unique'
2+
export const EMPTY_KEY_VALIDATION_MESSAGE = 'Key cannot be empty'

0 commit comments

Comments
 (0)