Skip to content

Commit 426c5ca

Browse files
committed
feat: DynamicDataTable - remove validationSchema, add errorState to show error from outside
1 parent 2cc4d1e commit 426c5ca

File tree

2 files changed

+35
-29
lines changed

2 files changed

+35
-29
lines changed

src/Shared/Components/DynamicDataTable/DynamicDataTableRow.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
3939
headers,
4040
readOnly,
4141
isDeletionNotAllowed,
42-
validationSchema = () => ({ isValid: true, errorMessages: [] }),
43-
showError,
42+
cellError = {},
4443
actionButtonConfig = null,
4544
onRowEdit,
4645
onRowDelete,
@@ -86,7 +85,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
8685

8786
cellRef.current = updatedCellRef
8887
}
89-
}, [rows])
88+
}, [rows.length])
9089

9190
// METHODS
9291
const onChange =
@@ -237,12 +236,12 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
237236
)
238237

239238
const renderErrorMessages = (row: DynamicDataTableRowType<K, CustomStateType>, key: K) => {
240-
const { isValid, errorMessages } = !row.data[key].disabled
241-
? validationSchema(row.data[key].value, key, row)
242-
: { isValid: true, errorMessages: [] }
243-
const showErrorMessages = showError && !isValid
239+
const { isValid, errorMessages } =
240+
!row.data[key].disabled && cellError[row.id]?.[key]
241+
? cellError[row.id][key]
242+
: { isValid: true, errorMessages: [] }
244243

245-
if (!showErrorMessages) {
244+
if (isValid) {
246245
return null
247246
}
248247

@@ -265,7 +264,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
265264
plugins={[followCursor]}
266265
>
267266
<div
268-
className={`dynamic-data-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${isDisabled ? 'cursor-not-allowed no-hover' : ''} ${showError && !isDisabled && !validationSchema(row.data[key].value, key, row).isValid ? 'dynamic-data-table__cell--error no-hover' : ''} ${!rowTypeHasInputField(row.data[key].type) ? 'no-hover no-focus' : ''}`}
267+
className={`dynamic-data-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${isDisabled ? 'cursor-not-allowed no-hover' : ''} ${!isDisabled && !cellError[row.id]?.[key]?.isValid ? 'dynamic-data-table__cell--error no-hover' : ''} ${!rowTypeHasInputField(row.data[key].type) ? 'no-hover no-focus' : ''}`}
269268
>
270269
{renderCellIcon(row, key, true)}
271270
{renderCellContent(row, key)}
@@ -279,7 +278,13 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
279278
const actionButtonIndex = getActionButtonPosition({ headers, actionButtonConfig })
280279
if (actionButtonIndex === index) {
281280
const { renderer, position = 'start' } = actionButtonConfig
282-
const actionButtonNode = <div className="dc__overflow-hidden flex top bcn-0">{renderer(row)}</div>
281+
const actionButtonNode = (
282+
<div
283+
className={`dc__overflow-hidden flex top bcn-0 ${(position === 'start' && key === headers[0].key) || (isDeletionNotAllowed && position === 'end' && key === headers[headers.length - 1].key) ? 'dynamic-data-table__cell' : ''}`}
284+
>
285+
{renderer(row)}
286+
</div>
287+
)
283288

284289
return position === 'start' ? (
285290
<>

src/Shared/Components/DynamicDataTable/types.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,23 @@ export type DynamicDataTableRowType<K extends string, CustomStateType = Record<s
111111
disableDelete?: boolean
112112
}
113113

114+
/**
115+
* Represents the validation state of a cell in a dynamic data table.
116+
*/
117+
export type DynamicDataTableCellValidationState = {
118+
isValid: boolean
119+
errorMessages: string[]
120+
}
121+
122+
/**
123+
* Defines the structure of validation errors for a cell.
124+
*
125+
* `K` represents the column `key` of the cell (i.e., the column identifiers).
126+
*/
127+
export type DynamicDataTableCellErrorType<K extends string> = {
128+
[rowId: string | number]: Partial<Record<K, DynamicDataTableCellValidationState>>
129+
}
130+
114131
type DynamicDataTableCellIcon<K extends string, CustomStateType = Record<string, unknown>> = {
115132
[key in K]?: (row: DynamicDataTableRowType<K, CustomStateType>) => ReactNode
116133
}
@@ -192,24 +209,9 @@ export type DynamicDataTableProps<K extends string, CustomStateType = Record<str
192209
position?: 'start' | 'end'
193210
}
194211
/**
195-
* Indicates whether to show errors.
196-
*/
197-
showError?: boolean
198-
/**
199-
* Function to validate the value of a table cell.
200-
* @param value - The value to validate.
201-
* @param key - The column key of the cell.
202-
* @param row - The row containing the cell.
203-
* @returns An object with a boolean indicating validity and an array of error messages.
212+
* Validation state for a specific cell in a dynamic data table.
204213
*/
205-
validationSchema?: (
206-
value: string,
207-
key: K,
208-
row: DynamicDataTableRowType<K, CustomStateType>,
209-
) => {
210-
isValid: boolean
211-
errorMessages: string[]
212-
}
214+
cellError?: DynamicDataTableCellErrorType<K>
213215
}
214216

215217
export interface DynamicDataTableHeaderProps<K extends string, CustomStateType = Record<string, unknown>>
@@ -237,8 +239,7 @@ export interface DynamicDataTableRowProps<K extends string, CustomStateType = Re
237239
| 'onRowEdit'
238240
| 'onRowDelete'
239241
| 'actionButtonConfig'
240-
| 'showError'
241-
| 'validationSchema'
242+
| 'cellError'
242243
| 'leadingCellIcon'
243244
| 'trailingCellIcon'
244245
| 'buttonCellWrapComponent'

0 commit comments

Comments
 (0)