Optimize metadata queries (#7013)

In this PR:

1. Refactor guards to avoid duplicated queries: WorkspaceAuthGuard and
UserAuthGuard only check for existence of workspace and user in the
request without querying the database
This commit is contained in:
Charles Bochet
2024-09-13 19:11:32 +02:00
committed by Charles Bochet
parent cf8b1161cc
commit 523df5398a
132 changed files with 818 additions and 6372 deletions

View File

@ -1,12 +1,12 @@
import {
IconComponent,
IconRelationManyToMany,
IconRelationManyToOne,
IconRelationOneToMany,
IconRelationOneToOne,
} from 'twenty-ui';
import { RelationMetadataType } from '~/generated-metadata/graphql';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
import OneToManySvg from '../assets/OneToMany.svg';
import OneToOneSvg from '../assets/OneToOne.svg';
import { RelationType } from '../types/RelationType';
@ -20,20 +20,27 @@ export const RELATION_TYPES: Record<
isImageFlipped?: boolean;
}
> = {
[RelationMetadataType.OneToMany]: {
[RelationDefinitionType.OneToMany]: {
label: 'Has many',
Icon: IconRelationOneToMany,
imageSrc: OneToManySvg,
},
[RelationMetadataType.OneToOne]: {
[RelationDefinitionType.OneToOne]: {
label: 'Has one',
Icon: IconRelationOneToOne,
imageSrc: OneToOneSvg,
},
MANY_TO_ONE: {
[RelationDefinitionType.ManyToOne]: {
label: 'Belongs to one',
Icon: IconRelationManyToOne,
imageSrc: OneToManySvg,
isImageFlipped: true,
},
// Not supported yet
[RelationDefinitionType.ManyToMany]: {
label: 'Belongs to many',
Icon: IconRelationManyToMany,
imageSrc: OneToManySvg,
isImageFlipped: true,
},
};

View File

@ -1,5 +1,5 @@
import { Controller, useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { Controller, useFormContext } from 'react-hook-form';
import { useIcons } from 'twenty-ui';
import { z } from 'zod';
@ -14,6 +14,7 @@ import { RelationType } from '@/settings/data-model/types/RelationType';
import { IconPicker } from '@/ui/input/components/IconPicker';
import { Select } from '@/ui/input/components/Select';
import { TextInput } from '@/ui/input/components/TextInput';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
export const settingsDataModelFieldRelationFormSchema = z.object({
relation: z.object({
@ -23,7 +24,10 @@ export const settingsDataModelFieldRelationFormSchema = z.object({
}),
objectMetadataId: z.string().uuid(),
type: z.enum(
Object.keys(RELATION_TYPES) as [RelationType, ...RelationType[]],
Object.keys(RELATION_TYPES) as [
RelationDefinitionType,
...RelationDefinitionType[],
],
),
}),
});
@ -33,10 +37,7 @@ export type SettingsDataModelFieldRelationFormValues = z.infer<
>;
type SettingsDataModelFieldRelationFormProps = {
fieldMetadataItem: Pick<
FieldMetadataItem,
'fromRelationMetadata' | 'toRelationMetadata' | 'type'
>;
fieldMetadataItem: Pick<FieldMetadataItem, 'type'>;
};
const StyledContainer = styled.div`

View File

@ -1,5 +1,5 @@
import { useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { useFormContext } from 'react-hook-form';
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';

View File

@ -5,15 +5,12 @@ import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMe
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation';
import { RelationMetadataType } from '~/generated-metadata/graphql';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
export const useRelationSettingsFormInitialValues = ({
fieldMetadataItem,
}: {
fieldMetadataItem?: Pick<
FieldMetadataItem,
'fromRelationMetadata' | 'toRelationMetadata' | 'type'
>;
fieldMetadataItem?: Pick<FieldMetadataItem, 'type' | 'relationDefinition'>;
}) => {
const { objectMetadataItems } = useFilteredObjectMetadataItems();
@ -39,7 +36,7 @@ export const useRelationSettingsFormInitialValues = ({
);
const initialRelationType =
relationTypeFromFieldMetadata ?? RelationMetadataType.OneToMany;
relationTypeFromFieldMetadata ?? RelationDefinitionType.OneToMany;
return {
disableFieldEdition:

View File

@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { Edge, Node } from 'reactflow';
import dagre from '@dagrejs/dagre';
import { useTheme } from '@emotion/react';
import { useEffect } from 'react';
import { Edge, Node } from 'reactflow';
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
@ -43,10 +43,10 @@ export const SettingsDataModelOverviewEffect = ({
for (const field of object.fields) {
if (
isDefined(field.toRelationMetadata) &&
isDefined(field.relationDefinition) &&
isDefined(
items.find(
(x) => x.id === field.toRelationMetadata?.fromObjectMetadata.id,
(x) => x.id === field.relationDefinition?.targetObjectMetadata.id,
),
)
) {
@ -59,8 +59,8 @@ export const SettingsDataModelOverviewEffect = ({
id: `${sourceObj}-${targetObj}`,
source: object.namePlural,
sourceHandle: `${field.id}-right`,
target: field.toRelationMetadata.fromObjectMetadata.namePlural,
targetHandle: `${field.toRelationMetadata.fromFieldMetadataId}-left`,
target: field.relationDefinition.targetObjectMetadata.namePlural,
targetHandle: `${field.relationDefinition.targetObjectMetadata}-left`,
type: 'smoothstep',
style: {
strokeWidth: 1,
@ -70,8 +70,8 @@ export const SettingsDataModelOverviewEffect = ({
markerStart: 'marker',
data: {
sourceField: field.id,
targetField: field.toRelationMetadata.fromFieldMetadataId,
relation: field.toRelationMetadata.relationType,
targetField: field.relationDefinition.targetFieldMetadata.id,
relation: field.relationDefinition.direction,
sourceObject: sourceObj,
targetObject: targetObj,
},

View File

@ -6,6 +6,7 @@ import { useIcons } from 'twenty-ui';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
type ObjectFieldRowProps = {
field: FieldMetadataItem;
@ -42,21 +43,33 @@ export const ObjectFieldRow = ({ field }: ObjectFieldRowProps) => {
{Icon && <Icon size={theme.icon.size.md} />}
<StyledFieldName>{relatedObject?.labelPlural ?? ''}</StyledFieldName>
<Handle
type={field.toRelationMetadata ? 'source' : 'target'}
type={
field.relationDefinition?.direction ===
RelationDefinitionType.OneToMany
? 'source'
: 'target'
}
position={Position.Right}
id={`${field.id}-right`}
className={
field.fromRelationMetadata
field.relationDefinition?.direction ===
RelationDefinitionType.OneToMany
? 'right-handle source-handle'
: 'right-handle target-handle'
}
/>
<Handle
type={field.toRelationMetadata ? 'source' : 'target'}
type={
field.relationDefinition?.direction ===
RelationDefinitionType.OneToMany
? 'source'
: 'target'
}
position={Position.Left}
id={`${field.id}-left`}
className={
field.fromRelationMetadata
field.relationDefinition?.direction ===
RelationDefinitionType.OneToMany
? 'left-handle source-handle'
: 'left-handle target-handle'
}

View File

@ -29,7 +29,7 @@ import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMe
import { View } from '@/views/types/View';
import { useNavigate } from 'react-router-dom';
import { useRecoilState } from 'recoil';
import { RelationMetadataType } from '~/generated-metadata/graphql';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
import { SettingsObjectDetailTableItem } from '~/pages/settings/data-model/types/SettingsObjectDetailTableItem';
import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType';
@ -224,8 +224,8 @@ export const SettingsObjectFieldItemTableRow = ({
<SettingsObjectFieldDataType
Icon={RelationIcon}
label={
relationType === RelationMetadataType.ManyToOne ||
relationType === RelationMetadataType.OneToOne
relationType === RelationDefinitionType.ManyToOne ||
relationType === RelationDefinitionType.OneToOne
? relationObjectMetadataItem?.labelSingular
: relationObjectMetadataItem?.labelPlural
}

View File

@ -1,5 +1,3 @@
import { RelationMetadataType } from '~/generated-metadata/graphql';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
export type RelationType =
| Exclude<RelationMetadataType, 'MANY_TO_MANY'>
| 'MANY_TO_ONE';
export type RelationType = RelationDefinitionType;