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:
committed by
Charles Bochet
parent
cf8b1161cc
commit
523df5398a
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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,
|
||||
},
|
||||
|
||||
@ -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'
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user