[PAGE LAYOUTS] Add widgets validation (#16635)
- Add widget validation - Remove 'None' option for primary axis group by - Fix error message parsing by passing the operation type in `useMetadataErrorHandler`
This commit is contained in:
+86
-79
@@ -1,6 +1,5 @@
|
||||
import { type ApolloError } from '@apollo/client';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { classifyMetadataError } from '@/metadata-error-handler/utils/classify-metadata-error.util';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
@@ -8,9 +7,19 @@ import {
|
||||
type AllMetadataName,
|
||||
WorkspaceMigrationV2ExceptionCode,
|
||||
} from 'twenty-shared/metadata';
|
||||
import { CrudOperationType } from 'twenty-shared/types';
|
||||
|
||||
export const useMetadataErrorHandler = () => {
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
|
||||
const TRANSLATED_OPERATION_TYPE = {
|
||||
[CrudOperationType.CREATE]: t`create`,
|
||||
[CrudOperationType.UPDATE]: t`update`,
|
||||
[CrudOperationType.DELETE]: t`delete`,
|
||||
[CrudOperationType.RESTORE]: t`restore`,
|
||||
[CrudOperationType.DESTROY]: t`destroy`,
|
||||
} as const satisfies Record<CrudOperationType, string>;
|
||||
|
||||
const TRANSLATED_METADATA_NAME = {
|
||||
objectMetadata: t`object`,
|
||||
fieldMetadata: t`field`,
|
||||
@@ -35,85 +44,83 @@ export const useMetadataErrorHandler = () => {
|
||||
viewFilterGroup: t`view filter group`,
|
||||
} as const satisfies Record<AllMetadataName, string>;
|
||||
|
||||
const handleMetadataError = useCallback(
|
||||
(
|
||||
error: ApolloError,
|
||||
options: {
|
||||
primaryMetadataName: AllMetadataName;
|
||||
},
|
||||
) => {
|
||||
const classification = classifyMetadataError({
|
||||
error,
|
||||
primaryMetadataName: options.primaryMetadataName,
|
||||
});
|
||||
|
||||
const translatedMetadataName =
|
||||
TRANSLATED_METADATA_NAME[options.primaryMetadataName];
|
||||
|
||||
switch (classification.type) {
|
||||
case 'v1':
|
||||
enqueueErrorSnackBar({ apolloError: classification.error });
|
||||
break;
|
||||
|
||||
case 'v2-validation': {
|
||||
const {
|
||||
extensions,
|
||||
primaryMetadataName,
|
||||
relatedFailingMetadataNames,
|
||||
} = classification;
|
||||
|
||||
const targetErrors = extensions.errors[primaryMetadataName] ?? [];
|
||||
if (targetErrors.length > 0) {
|
||||
targetErrors.forEach((entityError) => {
|
||||
entityError.errors.forEach((validationError) =>
|
||||
enqueueErrorSnackBar({
|
||||
message:
|
||||
validationError.userFriendlyMessage ??
|
||||
validationError.message,
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
targetErrors.length === 0 &&
|
||||
relatedFailingMetadataNames.length > 0
|
||||
) {
|
||||
const relatedEntityNames = relatedFailingMetadataNames
|
||||
.map((metadataName) => TRANSLATED_METADATA_NAME[metadataName])
|
||||
.join(', ');
|
||||
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Failed to create ${translatedMetadataName}. Related ${relatedEntityNames} validation failed. Please check your configuration and try again.`,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
targetErrors.length === 0 &&
|
||||
relatedFailingMetadataNames.length === 0
|
||||
) {
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Failed to create ${translatedMetadataName}. Please try again.`,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v2-internal': {
|
||||
const { code } = classification;
|
||||
const errorMessage =
|
||||
code ===
|
||||
WorkspaceMigrationV2ExceptionCode.BUILDER_INTERNAL_SERVER_ERROR
|
||||
? t`An internal error occurred while validating your changes. Please contact support.`
|
||||
: t`An internal error occurred while applying your changes. Please contact support and try again later.`;
|
||||
|
||||
enqueueErrorSnackBar({ message: errorMessage });
|
||||
break;
|
||||
}
|
||||
}
|
||||
const handleMetadataError = (
|
||||
error: ApolloError,
|
||||
options: {
|
||||
primaryMetadataName: AllMetadataName;
|
||||
operationType: CrudOperationType;
|
||||
},
|
||||
[enqueueErrorSnackBar, TRANSLATED_METADATA_NAME],
|
||||
);
|
||||
) => {
|
||||
const classification = classifyMetadataError({
|
||||
error,
|
||||
primaryMetadataName: options.primaryMetadataName,
|
||||
});
|
||||
|
||||
const translatedMetadataName =
|
||||
TRANSLATED_METADATA_NAME[options.primaryMetadataName];
|
||||
|
||||
switch (classification.type) {
|
||||
case 'v1':
|
||||
enqueueErrorSnackBar({ apolloError: classification.error });
|
||||
break;
|
||||
|
||||
case 'v2-validation': {
|
||||
const { extensions, primaryMetadataName, relatedFailingMetadataNames } =
|
||||
classification;
|
||||
|
||||
const targetErrors = extensions.errors[primaryMetadataName] ?? [];
|
||||
if (targetErrors.length > 0) {
|
||||
targetErrors.forEach((entityError) => {
|
||||
entityError.errors.forEach((validationError) =>
|
||||
enqueueErrorSnackBar({
|
||||
message:
|
||||
validationError.userFriendlyMessage ??
|
||||
validationError.message,
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const translatedOperationType =
|
||||
TRANSLATED_OPERATION_TYPE[options.operationType];
|
||||
|
||||
if (
|
||||
targetErrors.length === 0 &&
|
||||
relatedFailingMetadataNames.length > 0
|
||||
) {
|
||||
const relatedEntityNames = relatedFailingMetadataNames
|
||||
.map((metadataName) => TRANSLATED_METADATA_NAME[metadataName])
|
||||
.join(', ');
|
||||
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Failed to ${translatedOperationType} ${translatedMetadataName}. Related ${relatedEntityNames} validation failed. Please check your configuration and try again.`,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
targetErrors.length === 0 &&
|
||||
relatedFailingMetadataNames.length === 0
|
||||
) {
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Failed to ${translatedOperationType} ${translatedMetadataName}. Please try again.`,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v2-internal': {
|
||||
const { code } = classification;
|
||||
const errorMessage =
|
||||
code ===
|
||||
WorkspaceMigrationV2ExceptionCode.BUILDER_INTERNAL_SERVER_ERROR
|
||||
? t`An internal error occurred while validating your changes. Please contact support.`
|
||||
: t`An internal error occurred while applying your changes. Please contact support and try again later.`;
|
||||
|
||||
enqueueErrorSnackBar({ message: errorMessage });
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
handleMetadataError,
|
||||
|
||||
Reference in New Issue
Block a user