diff --git a/src/entities/transformation/constants.ts b/src/entities/transformation/constants.ts index 4b09662f..e36fac4e 100644 --- a/src/entities/transformation/constants.ts +++ b/src/entities/transformation/constants.ts @@ -15,6 +15,11 @@ const SHOW_BUTTONS_CONTEXT_INITIAL_VALUE: ShowButtonsContextProps = { isDisplayed: true, }; +export const TRANSFORMATION_RESPONSE_LOCATION_POSITION = { + CATEGORY: 1, + TRANSFORMATION_TYPE: 3, +}; + export const ShowButtonsContext = createContext(SHOW_BUTTONS_CONTEXT_INITIAL_VALUE); export const TRANSFORMATIONS_FORM_DEFAULT_VALUE: TransformationsForm = { diff --git a/src/entities/transformation/utils/index.ts b/src/entities/transformation/utils/index.ts index 072e7b56..12d7d01f 100644 --- a/src/entities/transformation/utils/index.ts +++ b/src/entities/transformation/utils/index.ts @@ -1,2 +1,3 @@ -export * from './prepareTransformationRequest'; export * from './prepareTransformationForm'; +export * from './prepareTransformationFormError'; +export * from './prepareTransformationRequest'; diff --git a/src/entities/transformation/utils/prepareTransformationFormError/index.ts b/src/entities/transformation/utils/prepareTransformationFormError/index.ts new file mode 100644 index 00000000..2c004c6a --- /dev/null +++ b/src/entities/transformation/utils/prepareTransformationFormError/index.ts @@ -0,0 +1,28 @@ +import { FormFieldError } from '@shared/config'; + +import { TransformationType } from '../../types'; + +import { TRANSFORMATION_RESPONSE_LOCATION_POSITION } from './../../constants'; + +/** Util for preparing received errors for use on a form */ +export const prepareTransformationFormError = (errors: FormFieldError[]): FormFieldError[] => { + return errors.map((error) => { + const { location } = error; + if (location[TRANSFORMATION_RESPONSE_LOCATION_POSITION.CATEGORY] !== 'transformations') return error; + + switch ( + (location as string[])[TRANSFORMATION_RESPONSE_LOCATION_POSITION.TRANSFORMATION_TYPE] as TransformationType + ) { + case TransformationType.FILTER_SQL: + //location : ['body', 'transformations', 3, 'sql', 'query'] + /* From the backend, the error record comes in a simple form in accordance with the api. + Return it to the state it was stored in the form */ + const insertPosition = TRANSFORMATION_RESPONSE_LOCATION_POSITION.TRANSFORMATION_TYPE + 1; + const newLocation = location.slice(0, insertPosition).concat(0).concat(location.slice(insertPosition)); + return { ...error, location: newLocation } as FormFieldError; + + default: + return error; + } + }); +}; diff --git a/src/shared/config/errors/types.ts b/src/shared/config/errors/types.ts index f8dad7ce..c67c082e 100644 --- a/src/shared/config/errors/types.ts +++ b/src/shared/config/errors/types.ts @@ -6,7 +6,7 @@ interface DefaultError { type LocationTypeError = 'body' | 'query'; export interface FormFieldError extends DefaultError { - location: [Extract, string]; + location: [Extract, string | number]; } export interface MessageError { diff --git a/src/shared/ui/ManagedForm/index.tsx b/src/shared/ui/ManagedForm/index.tsx index 18d27d69..258029de 100644 --- a/src/shared/ui/ManagedForm/index.tsx +++ b/src/shared/ui/ManagedForm/index.tsx @@ -1,9 +1,9 @@ -import React, { useLayoutEffect, useState } from 'react'; +import { useLayoutEffect, useState } from 'react'; import { Form, notification, Spin } from 'antd'; import { PropsWithChildren } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { clsx } from 'clsx'; -import { checkIsFormFieldsError, getErrorMessage } from '@shared/config'; +import { checkIsFormFieldsError, FormFieldError, getErrorMessage } from '@shared/config'; import { useTranslation } from 'react-i18next'; import * as classes from './styles.module.less'; @@ -19,6 +19,7 @@ export const ManagedForm = ({ keysInvalidateQueries = [], isHiddenLoadingOnSuccess = false, onError = () => undefined, + prepareFormErrors, ...props }: PropsWithChildren>) => { const { t, i18n } = useTranslation('error'); @@ -51,7 +52,9 @@ export const ManagedForm = ({ if (checkIsFormFieldsError(error) && error.response) { message = t('formErrorHasOccurred'); - showErrorsInFields(form, error.response.data.error.details); + const errors: FormFieldError[] = error.response.data.error.details; + const preparedErrors = prepareFormErrors ? prepareFormErrors(errors) : errors; + showErrorsInFields(form, preparedErrors); } notification.error({ diff --git a/src/shared/ui/ManagedForm/types.ts b/src/shared/ui/ManagedForm/types.ts index 6071ff01..a8e8412b 100644 --- a/src/shared/ui/ManagedForm/types.ts +++ b/src/shared/ui/ManagedForm/types.ts @@ -1,3 +1,4 @@ +import { FormFieldError } from '@shared/config'; import { QueryClient } from '@tanstack/react-query'; import { FormProps } from 'antd'; @@ -20,4 +21,6 @@ export interface ManagedFormProps extends Omit, 'form' | 'onF keysInvalidateQueries?: Parameters[]; /** Flag that hides a spin if the request is successful */ isHiddenLoadingOnSuccess?: boolean; + /** Callback to prepare received errors */ + prepareFormErrors?: (errors: FormFieldError[]) => FormFieldError[]; } diff --git a/src/shared/ui/ManagedForm/utils/showErrorsInFields/index.ts b/src/shared/ui/ManagedForm/utils/showErrorsInFields/index.ts index 159b38a5..79e2ec8c 100644 --- a/src/shared/ui/ManagedForm/utils/showErrorsInFields/index.ts +++ b/src/shared/ui/ManagedForm/utils/showErrorsInFields/index.ts @@ -12,10 +12,10 @@ export const showErrorsInFields = (form: FormInstance, errors: FormFieldError[]) const fieldErrors = errors .map((field) => { // Keep only valid parts of the path - const validPath = field.location.reduce((acc, key) => { + const validPath = field.location.reduce>((acc, key) => { const currentPath = [...acc, key]; // Check if the path to the current key exists - if (typeof form.getFieldValue(currentPath) === 'object' || form.getFieldInstance(currentPath)) { + if (typeof form.getFieldValue(currentPath) === 'object' || form.isFieldTouched(currentPath)) { acc.push(key); } return acc; diff --git a/src/widgets/transfer/CreateTransfer/index.tsx b/src/widgets/transfer/CreateTransfer/index.tsx index bc9d36a4..0190767a 100644 --- a/src/widgets/transfer/CreateTransfer/index.tsx +++ b/src/widgets/transfer/CreateTransfer/index.tsx @@ -1,9 +1,8 @@ -import React from 'react'; import { ManagedForm } from '@shared/ui'; import { useNavigate } from 'react-router-dom'; import { prepareTransferResourcesRequest, Transfer, TransferQueryKey, transferService } from '@entities/transfer'; import { MutateTransferForm } from '@features/transfer'; -import { prepareTransformationRequest } from '@entities/transformation'; +import { prepareTransformationFormError, prepareTransformationRequest } from '@entities/transformation'; import { useTranslation } from 'react-i18next'; import { CreateTransferForm, CreateTransferProps } from './types'; @@ -36,6 +35,7 @@ export const CreateTransfer = ({ group }: CreateTransferProps) => { mutationFunction={handleCreateTransfer} onSuccess={onSuccess} successMessage={t('createTransferSuccess')} + prepareFormErrors={prepareTransformationFormError} keysInvalidateQueries={[[{ queryKey: [TransferQueryKey.GET_TRANSFERS, group.id] }]]} > diff --git a/src/widgets/transfer/UpdateTransfer/index.tsx b/src/widgets/transfer/UpdateTransfer/index.tsx index 64532937..8e83f14a 100644 --- a/src/widgets/transfer/UpdateTransfer/index.tsx +++ b/src/widgets/transfer/UpdateTransfer/index.tsx @@ -9,7 +9,11 @@ import { transferService, } from '@entities/transfer'; import { MutateTransferForm } from '@features/transfer'; -import { prepareTransformationForm, prepareTransformationRequest } from '@entities/transformation'; +import { + prepareTransformationForm, + prepareTransformationFormError, + prepareTransformationRequest, +} from '@entities/transformation'; import { useTranslation } from 'react-i18next'; import { UpdateTransferForm, UpdateTransferProps } from './types'; @@ -47,6 +51,7 @@ export const UpdateTransfer = ({ transfer, group }: UpdateTransferProps) => { mutationFunction={handleUpdateTransfer} onSuccess={onSuccess} successMessage={t('updateTransferSuccess')} + prepareFormErrors={prepareTransformationFormError} keysInvalidateQueries={[ [{ queryKey: [TransferQueryKey.GET_TRANSFERS, group.id] }], [{ queryKey: [TransferQueryKey.GET_TRANSFER, transfer.id] }],