mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Merge pull request #593 from nowcommunity/show-missing-fields-to-user-next-to-finalize-entry-button
show user all invalid fields next to finalize entry button
This commit is contained in:
@@ -4,7 +4,12 @@ import { DropdownOption } from '../common/editingComponents'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { ValidationObject } from '@/validators/validator'
|
||||
import { EditDataType } from '@/backendTypes'
|
||||
import { TextFieldOptions, OptionalRadioSelectionProps } from '../DetailView'
|
||||
import {
|
||||
TextFieldOptions,
|
||||
OptionalRadioSelectionProps,
|
||||
FieldsWithErrorsType,
|
||||
SetFieldsWithErrorsType,
|
||||
} from '../DetailView'
|
||||
|
||||
export type ModeOptions = 'read' | 'new' | 'edit' | 'staging-edit' | 'staging-new'
|
||||
|
||||
@@ -75,8 +80,8 @@ export type DetailContextType<T> = {
|
||||
optionalRadioSelectionProps?: OptionalRadioSelectionProps
|
||||
) => JSX.Element
|
||||
validator: (editData: EditDataType<T>, field: keyof EditDataType<T>) => ValidationObject
|
||||
fieldsWithErrors: Array<string>
|
||||
setFieldsWithErrors: (updaterFn: (prevErrors: Array<string>) => Array<string>) => void
|
||||
fieldsWithErrors: FieldsWithErrorsType
|
||||
setFieldsWithErrors: SetFieldsWithErrorsType
|
||||
}
|
||||
|
||||
export const DetailContext = createContext<DetailContextType<unknown>>(null!)
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
} from './common/editingComponents'
|
||||
import { DetailBrowser } from './DetailBrowser'
|
||||
import { StagingView } from './StagingView'
|
||||
import { ReturnButton, WriteButton } from './components'
|
||||
import { ErrorBox, ReturnButton, WriteButton } from './components'
|
||||
import { ValidationObject } from '@/validators/validator'
|
||||
import { EditDataType } from '@/backendTypes'
|
||||
import { usePageContext } from '../Page'
|
||||
@@ -46,6 +46,11 @@ export type OptionalRadioSelectionProps = {
|
||||
handleSetEditData?: (value: number | string | boolean) => void
|
||||
}
|
||||
|
||||
export type FieldsWithErrorsType = { [field: string]: ValidationObject }
|
||||
export type SetFieldsWithErrorsType = (
|
||||
updaterFn: (prevFieldsWithErrors: FieldsWithErrorsType) => FieldsWithErrorsType
|
||||
) => void
|
||||
|
||||
export const DetailView = <T extends object>({
|
||||
tabs,
|
||||
data,
|
||||
@@ -74,7 +79,7 @@ export const DetailView = <T extends object>({
|
||||
}
|
||||
const { editRights } = usePageContext()
|
||||
const [mode, setModeState] = useState<ModeType>(isNew ? modeOptionToMode['new'] : modeOptionToMode['read'])
|
||||
const [fieldsWithErrors, setFieldsWithErrors] = useState<Array<string>>([])
|
||||
const [fieldsWithErrors, setFieldsWithErrors] = useState<FieldsWithErrorsType>({})
|
||||
const [tab, setTab] = useState(getUrl())
|
||||
|
||||
useEffect(() => {
|
||||
@@ -208,6 +213,7 @@ export const DetailView = <T extends object>({
|
||||
Delete
|
||||
</Button>
|
||||
)}
|
||||
{Object.keys(fieldsWithErrors).length > 0 && <ErrorBox />}
|
||||
{(!mode.read || initialState.mode.new) && onWrite && (
|
||||
<WriteButton onWrite={onWrite} hasStagingMode={hasStagingMode} />
|
||||
)}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { useDetailContext } from '../Context/DetailContext'
|
||||
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'
|
||||
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { checkFieldErrors } from './checkFieldErrors'
|
||||
import { ActionComponent } from '@/components/TableView/ActionComponent'
|
||||
|
||||
const defaultPagination: MRT_PaginationState = { pageIndex: 0, pageSize: 15 }
|
||||
@@ -49,23 +50,12 @@ export const EditableTable = <
|
||||
const [pagination, setPagination] = useState<MRT_PaginationState>(defaultPagination)
|
||||
const { editData, setEditData, mode, data, validator, fieldsWithErrors, setFieldsWithErrors } =
|
||||
useDetailContext<ParentType>()
|
||||
const { error } = validator(editData, field)
|
||||
const errorObject = validator(editData, field)
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
checkFieldErrors(String(field), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
}, [errorObject])
|
||||
|
||||
if (tableData === null || editTableData === null) return <CircularProgress />
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ValidationObject } from '@/validators/validator'
|
||||
import { FieldsWithErrorsType, SetFieldsWithErrorsType } from '../DetailView'
|
||||
|
||||
export const checkFieldErrors = (
|
||||
field: string,
|
||||
errorObject: ValidationObject,
|
||||
fieldsWithErrors: FieldsWithErrorsType,
|
||||
setFieldsWithErrors: SetFieldsWithErrorsType
|
||||
) => {
|
||||
const fieldAsString = String(field)
|
||||
if (errorObject.error) {
|
||||
if (!(fieldAsString in fieldsWithErrors)) {
|
||||
setFieldsWithErrors(prevFieldsWithErrors => {
|
||||
return { ...prevFieldsWithErrors, [fieldAsString]: errorObject }
|
||||
})
|
||||
}
|
||||
} else if (!errorObject.error && fieldAsString in fieldsWithErrors) {
|
||||
setFieldsWithErrors(prevFieldsWithErrors => {
|
||||
const newFieldsWithErrors = { ...prevFieldsWithErrors }
|
||||
delete newFieldsWithErrors[fieldAsString]
|
||||
return newFieldsWithErrors
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import { DataValue } from './tabLayoutHelpers'
|
||||
import { modalStyle } from './misc'
|
||||
import { EditDataType } from '@/backendTypes'
|
||||
import { calculateLocalityMinAge, calculateLocalityMaxAge } from '@/util/ageCalculator'
|
||||
import { checkFieldErrors } from './checkFieldErrors'
|
||||
|
||||
const fieldWidth = '14em'
|
||||
|
||||
@@ -53,23 +54,13 @@ export const DropdownSelector = <T extends object>({
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { setEditData, editData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<T>()
|
||||
const { error } = validator(editData, field)
|
||||
const errorObject = validator(editData, field)
|
||||
const { error } = errorObject
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
checkFieldErrors(String(field), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
}, [errorObject])
|
||||
|
||||
const editingComponent = (
|
||||
<FormControl size="small" error={!!error}>
|
||||
@@ -113,27 +104,17 @@ export const DropdownSelectorWithSearch = <T extends object>({
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { setEditData, editData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<T>()
|
||||
const { error } = validator(editData, field)
|
||||
const errorObject = validator(editData, field)
|
||||
const { error } = errorObject
|
||||
|
||||
useEffect(() => {
|
||||
checkFieldErrors(String(field), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [errorObject])
|
||||
|
||||
//current state of the search, not the selected option that is set into editData
|
||||
const [inputValue, setInputValue] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
|
||||
const editingComponent = (
|
||||
<FormControl size="small" error={!!error}>
|
||||
<InputLabel id={`${name}-multiselect-label`}></InputLabel>
|
||||
@@ -222,7 +203,12 @@ export const RadioSelector = <T extends object>({
|
||||
handleSetEditData?: (value: number | string | boolean) => void
|
||||
}) => {
|
||||
const { setEditData, editData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<T>()
|
||||
const { error } = validator(editData, field)
|
||||
const errorObject = validator(editData, field)
|
||||
|
||||
useEffect(() => {
|
||||
checkFieldErrors(String(field), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [errorObject])
|
||||
|
||||
if (defaultValue === undefined) {
|
||||
defaultValue = getValue(options[0])
|
||||
@@ -235,22 +221,6 @@ export const RadioSelector = <T extends object>({
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [editData])
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
|
||||
const editingComponent = (
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
@@ -317,24 +287,13 @@ export const EditableTextField = <T extends object>({
|
||||
handleSetEditData?: (value: number | string) => void
|
||||
}) => {
|
||||
const { setEditData, editData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<T>()
|
||||
const { error } = validator(editData, field)
|
||||
const name = String(field)
|
||||
const errorObject = validator(editData, field)
|
||||
const { error } = errorObject
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
checkFieldErrors(String(field), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
}, [errorObject])
|
||||
|
||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event?.currentTarget?.value
|
||||
@@ -356,7 +315,7 @@ export const EditableTextField = <T extends object>({
|
||||
<TextField
|
||||
sx={{ width: fieldWidth, backgroundColor: disabled ? 'grey' : '' }}
|
||||
onChange={handleChange}
|
||||
id={`${name}-textfield`}
|
||||
id={`${String(field)}-textfield`}
|
||||
value={editData[field] ?? ''}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
@@ -384,7 +343,8 @@ export const FieldWithTableSelection = <T extends object, ParentType extends obj
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { editData, setEditData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<ParentType>()
|
||||
const { error } = validator(editData, targetField as keyof EditDataType<ParentType>)
|
||||
const errorObject = validator(editData, targetField as keyof EditDataType<ParentType>)
|
||||
const { error } = errorObject
|
||||
const [open, setOpen] = useState(false)
|
||||
const selectorFn = (selected: T) => {
|
||||
setEditData({ ...editData, [targetField]: selected[sourceField] })
|
||||
@@ -392,20 +352,9 @@ export const FieldWithTableSelection = <T extends object, ParentType extends obj
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(targetField)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
checkFieldErrors(String(targetField), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
}, [errorObject])
|
||||
|
||||
const selectorTableWithFn = cloneElement(selectorTable, { selectorFn })
|
||||
if (open)
|
||||
@@ -454,10 +403,11 @@ export const TimeBoundSelection = <T extends object, ParentType extends object>(
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { editData, setEditData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<ParentType>()
|
||||
const { error: boundError } = validator(
|
||||
const errorObject = validator(
|
||||
editData,
|
||||
(targetField === 'up_bnd' ? 'up_bound' : 'low_bound') as keyof EditDataType<ParentType>
|
||||
)
|
||||
const { error } = errorObject
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const selectorFn = (selected: T) => {
|
||||
@@ -470,20 +420,9 @@ export const TimeBoundSelection = <T extends object, ParentType extends object>(
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(targetField)
|
||||
if (boundError && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!boundError && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
checkFieldErrors(String(targetField), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [boundError])
|
||||
}, [errorObject])
|
||||
|
||||
const selectorTableWithFn = cloneElement(selectorTable, { selectorFn })
|
||||
if (open)
|
||||
@@ -508,8 +447,8 @@ export const TimeBoundSelection = <T extends object, ParentType extends object>(
|
||||
id={`${String(targetField)}-tableselection`}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
error={!!boundError}
|
||||
helperText={boundError ?? ''}
|
||||
error={!!error}
|
||||
helperText={error ?? ''}
|
||||
value={editData[targetField as keyof EditDataType<ParentType>] ?? undefined}
|
||||
onClick={() => setOpen(true)}
|
||||
disabled={disabled}
|
||||
@@ -538,7 +477,8 @@ export const BasisForAgeSelection = <T extends object, ParentType extends object
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { editData, setEditData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<ParentType>()
|
||||
const { error } = validator(editData, targetField as keyof EditDataType<ParentType>)
|
||||
const errorObject = validator(editData, targetField as keyof EditDataType<ParentType>)
|
||||
const { error } = errorObject
|
||||
const [open, setOpen] = useState(false)
|
||||
const selectorFn = (selected: T) => {
|
||||
if (targetField === 'bfa_min') {
|
||||
@@ -568,20 +508,9 @@ export const BasisForAgeSelection = <T extends object, ParentType extends object
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(targetField)
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
checkFieldErrors(String(targetField), errorObject, fieldsWithErrors, setFieldsWithErrors)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error])
|
||||
}, [errorObject])
|
||||
|
||||
const selectorTableWithFn = cloneElement(selectorTable, { selectorFn })
|
||||
if (open)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Button, CircularProgress } from '@mui/material'
|
||||
import { Button, Box, Typography, CircularProgress, Divider, alpha, List, ListItemText } from '@mui/material'
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
|
||||
import SaveIcon from '@mui/icons-material/Save'
|
||||
import { usePageContext } from '../Page'
|
||||
@@ -31,14 +31,18 @@ export const WriteButton = <T,>({
|
||||
if (mode.option === 'edit' || mode.option === 'new') {
|
||||
for (const field in editData) {
|
||||
const fieldAsString = String(field)
|
||||
const { error } = validator(editData, field)
|
||||
if (error && !fieldsWithErrors.includes(fieldAsString)) {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, field]
|
||||
})
|
||||
} else if (!error && fieldsWithErrors.includes(fieldAsString)) {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== fieldAsString)
|
||||
const errorObject = validator(editData, field)
|
||||
if (errorObject.error) {
|
||||
if (!(fieldAsString in fieldsWithErrors)) {
|
||||
setFieldsWithErrors(prevFieldsWithErrors => {
|
||||
return { ...prevFieldsWithErrors, [fieldAsString]: errorObject }
|
||||
})
|
||||
}
|
||||
} else if (!errorObject.error && fieldAsString in fieldsWithErrors) {
|
||||
setFieldsWithErrors(prevFieldsWithErrors => {
|
||||
const newFieldsWithErrors = { ...prevFieldsWithErrors }
|
||||
delete newFieldsWithErrors[fieldAsString]
|
||||
return newFieldsWithErrors
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -48,7 +52,7 @@ export const WriteButton = <T,>({
|
||||
|
||||
return (
|
||||
<Button
|
||||
disabled={fieldsWithErrors.length > 0}
|
||||
disabled={Object.keys(fieldsWithErrors).length > 0}
|
||||
id="write-button"
|
||||
sx={{ width: '20em' }}
|
||||
onClick={() => {
|
||||
@@ -74,6 +78,40 @@ export const WriteButton = <T,>({
|
||||
)
|
||||
}
|
||||
|
||||
export const ErrorBox = <T,>() => {
|
||||
const { fieldsWithErrors } = useDetailContext<T>()
|
||||
const fields = Object.keys(fieldsWithErrors)
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
borderRadius: 1,
|
||||
padding: '0.7em',
|
||||
boxShadow: 2,
|
||||
bgcolor: alpha('#ff0000', 0.5),
|
||||
}}
|
||||
>
|
||||
<Typography color="text.secondary" gutterBottom>
|
||||
{`${fields.length} Invalid fields`}
|
||||
</Typography>
|
||||
<List sx={{ maxHeight: '5em', maxWidth: '30em', padding: '0em 0.8em 0em 0.8em', overflow: 'auto' }}>
|
||||
{fields.map(field => (
|
||||
<>
|
||||
<ListItemText
|
||||
sx={{ color: 'text.secondary' }}
|
||||
primary={`${fieldsWithErrors[field].name}: ${fieldsWithErrors[field].error}`}
|
||||
/>
|
||||
<Divider />
|
||||
</>
|
||||
))}
|
||||
</List>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export const ReturnButton = () => {
|
||||
const navigate = useNavigate()
|
||||
const { tableUrl } = usePageContext()
|
||||
|
||||
@@ -40,7 +40,7 @@ function checkIndexes(editData: EditDataType<ReferenceDetailsType>): boolean {
|
||||
export const AuthorTab: React.FC<AuthorTabProps> = ({ field_num_param, tab_name = 'Authors' }) => {
|
||||
const { mode, editData, setEditData, fieldsWithErrors } = useDetailContext<ReferenceDetailsType>()
|
||||
const { data: authorData, isError } = useGetReferenceAuthorsQuery(mode.read ? skipToken : undefined)
|
||||
const hasError = fieldsWithErrors.includes('ref_authors')
|
||||
const hasError = !!fieldsWithErrors.ref_authors
|
||||
|
||||
useEffect(() => {
|
||||
// Check and update indexes of authors only if they are incorrect
|
||||
|
||||
@@ -17,7 +17,7 @@ interface JournalTabProps {
|
||||
export const JournalTab: React.FC<JournalTabProps> = ({ tab_name = 'Journal' }) => {
|
||||
const { mode, editData, setEditData, fieldsWithErrors } = useDetailContext<ReferenceDetailsType>()
|
||||
const { data: journalData, isError } = useGetReferenceJournalsQuery(mode.read ? skipToken : undefined)
|
||||
const hasError = fieldsWithErrors.includes('ref_journal')
|
||||
const hasError = !!fieldsWithErrors.ref_journal
|
||||
let visible_ref_journal: Array<ReferenceJournalType> = []
|
||||
if (editData.ref_journal && Object.keys(editData.ref_journal).length !== 0) {
|
||||
visible_ref_journal = [Object.assign({}, editData.ref_journal)]
|
||||
|
||||
@@ -17,12 +17,19 @@ export const ReferenceTab = () => {
|
||||
for (const field in editData) {
|
||||
const fieldAsKey = field as keyof typeof editData
|
||||
const fieldAsString = String(fieldAsKey)
|
||||
const { error } = validator(editData, fieldAsKey)
|
||||
|
||||
if (error && !fieldsWithErrors.includes(fieldAsString)) {
|
||||
setFieldsWithErrors(prevErrors => [...prevErrors, fieldAsString])
|
||||
} else if (!error && fieldsWithErrors.includes(fieldAsString)) {
|
||||
setFieldsWithErrors(prevErrors => prevErrors.filter(err => err !== fieldAsString))
|
||||
const errorObject = validator(editData, fieldAsKey)
|
||||
if (errorObject.error) {
|
||||
if (!(fieldAsString in fieldsWithErrors)) {
|
||||
setFieldsWithErrors(prevFieldsWithErrors => {
|
||||
return { ...prevFieldsWithErrors, [fieldAsString]: errorObject }
|
||||
})
|
||||
}
|
||||
} else if (!errorObject.error && fieldAsString in fieldsWithErrors) {
|
||||
setFieldsWithErrors(prevFieldsWithErrors => {
|
||||
const newFieldsWithErrors = { ...prevFieldsWithErrors }
|
||||
delete newFieldsWithErrors[fieldAsString]
|
||||
return newFieldsWithErrors
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user