mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-25 13:02:15 +03:00
feat: add useCreateOneRelationMetadata and useRelationMetadata (#2559)
Closes #2423
This commit is contained in:
parent
1deb742ac9
commit
e90beef91f
@ -15,11 +15,12 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
|
||||
const documents = {
|
||||
"\n mutation CreateOneObjectMetadataItem($input: CreateOneObjectInput!) {\n createOneObject(input: $input) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n }\n }\n": types.CreateOneObjectMetadataItemDocument,
|
||||
"\n mutation CreateOneFieldMetadataItem($input: CreateOneFieldInput!) {\n createOneField(input: $input) {\n id\n type\n name\n label\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n": types.CreateOneFieldMetadataItemDocument,
|
||||
"\n mutation CreateOneRelationMetadata($input: CreateOneRelationInput!) {\n createOneRelation(input: $input) {\n id\n relationType\n fromObjectMetadataId\n toObjectMetadataId\n fromFieldMetadataId\n toFieldMetadataId\n createdAt\n updatedAt\n }\n }\n": types.CreateOneRelationMetadataDocument,
|
||||
"\n mutation UpdateOneFieldMetadataItem(\n $idToUpdate: ID!\n $updatePayload: UpdateFieldInput!\n ) {\n updateOneField(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n type\n name\n label\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n": types.UpdateOneFieldMetadataItemDocument,
|
||||
"\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: ID!\n $updatePayload: UpdateObjectInput!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n }\n }\n": types.UpdateOneObjectMetadataItemDocument,
|
||||
"\n mutation DeleteOneObjectMetadataItem($idToDelete: ID!) {\n deleteOneObject(input: { id: $idToDelete }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n }\n }\n": types.DeleteOneObjectMetadataItemDocument,
|
||||
"\n mutation DeleteOneFieldMetadataItem($idToDelete: ID!) {\n deleteOneField(input: { id: $idToDelete }) {\n id\n type\n name\n label\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n": types.DeleteOneFieldMetadataItemDocument,
|
||||
"\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n isSystem\n createdAt\n updatedAt\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n }\n toRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n": types.ObjectMetadataItemsDocument,
|
||||
"\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n isSystem\n createdAt\n updatedAt\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n toFieldMetadataId\n }\n toRelationMetadata {\n id\n relationType\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromFieldMetadataId\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n": types.ObjectMetadataItemsDocument,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -44,6 +45,10 @@ export function graphql(source: "\n mutation CreateOneObjectMetadataItem($input
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation CreateOneFieldMetadataItem($input: CreateOneFieldInput!) {\n createOneField(input: $input) {\n id\n type\n name\n label\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n"): (typeof documents)["\n mutation CreateOneFieldMetadataItem($input: CreateOneFieldInput!) {\n createOneField(input: $input) {\n id\n type\n name\n label\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation CreateOneRelationMetadata($input: CreateOneRelationInput!) {\n createOneRelation(input: $input) {\n id\n relationType\n fromObjectMetadataId\n toObjectMetadataId\n fromFieldMetadataId\n toFieldMetadataId\n createdAt\n updatedAt\n }\n }\n"): (typeof documents)["\n mutation CreateOneRelationMetadata($input: CreateOneRelationInput!) {\n createOneRelation(input: $input) {\n id\n relationType\n fromObjectMetadataId\n toObjectMetadataId\n fromFieldMetadataId\n toFieldMetadataId\n createdAt\n updatedAt\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@ -63,7 +68,7 @@ export function graphql(source: "\n mutation DeleteOneFieldMetadataItem($idToDe
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n isSystem\n createdAt\n updatedAt\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n }\n toRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"): (typeof documents)["\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n isSystem\n createdAt\n updatedAt\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n }\n toRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"];
|
||||
export function graphql(source: "\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n isSystem\n createdAt\n updatedAt\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n toFieldMetadataId\n }\n toRelationMetadata {\n id\n relationType\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromFieldMetadataId\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"): (typeof documents)["\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n isSystem\n createdAt\n updatedAt\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n toFieldMetadataId\n }\n toRelationMetadata {\n id\n relationType\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n }\n fromFieldMetadataId\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"];
|
||||
|
||||
export function graphql(source: string) {
|
||||
return (documents as any)[source] ?? {};
|
||||
|
File diff suppressed because one or more lines are too long
@ -38,6 +38,21 @@ export const CREATE_ONE_METADATA_FIELD = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
export const CREATE_ONE_RELATION_METADATA = gql`
|
||||
mutation CreateOneRelationMetadata($input: CreateOneRelationInput!) {
|
||||
createOneRelation(input: $input) {
|
||||
id
|
||||
relationType
|
||||
fromObjectMetadataId
|
||||
toObjectMetadataId
|
||||
fromFieldMetadataId
|
||||
toFieldMetadataId
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_ONE_METADATA_FIELD = gql`
|
||||
mutation UpdateOneFieldMetadataItem(
|
||||
$idToUpdate: ID!
|
||||
|
@ -45,28 +45,18 @@ export const FIND_MANY_METADATA_OBJECTS = gql`
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
fromObjectMetadata {
|
||||
id
|
||||
dataSourceId
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
toFieldMetadataId
|
||||
}
|
||||
toRelationMetadata {
|
||||
id
|
||||
relationType
|
||||
toObjectMetadata {
|
||||
id
|
||||
dataSourceId
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
fromObjectMetadata {
|
||||
id
|
||||
dataSourceId
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
fromFieldMetadataId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
import { ApolloClient, useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
CreateOneRelationMetadataMutation,
|
||||
CreateOneRelationMetadataMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { CREATE_ONE_RELATION_METADATA } from '../graphql/mutations';
|
||||
import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
|
||||
import {
|
||||
formatRelationMetadataInput,
|
||||
FormatRelationMetadataInputParams,
|
||||
} from '../utils/formatRelationMetadataInput';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useCreateOneRelationMetadata = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
CreateOneRelationMetadataMutation,
|
||||
CreateOneRelationMetadataMutationVariables
|
||||
>(CREATE_ONE_RELATION_METADATA, {
|
||||
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
|
||||
});
|
||||
|
||||
const createOneRelationMetadata = async (
|
||||
input: FormatRelationMetadataInputParams,
|
||||
) => {
|
||||
return await mutate({
|
||||
variables: { input: { relation: formatRelationMetadataInput(input) } },
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
createOneRelationMetadata,
|
||||
};
|
||||
};
|
@ -30,6 +30,11 @@ export const useObjectMetadataItemForSettings = () => {
|
||||
getObjectSlug(activeObjectMetadataItem) === slug,
|
||||
);
|
||||
|
||||
const findObjectMetadataItemById = (id: string) =>
|
||||
objectMetadataItems.find(
|
||||
(objectMetadataItem) => objectMetadataItem.id === id,
|
||||
);
|
||||
|
||||
const { createOneObjectMetadataItem } =
|
||||
useCreateOneObjectRecordMetadataItem();
|
||||
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
||||
@ -82,6 +87,7 @@ export const useObjectMetadataItemForSettings = () => {
|
||||
editObjectMetadataItem,
|
||||
eraseObjectMetadataItem,
|
||||
findActiveObjectMetadataItemBySlug,
|
||||
findObjectMetadataItemById,
|
||||
loading,
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,49 @@
|
||||
import { RelationType } from '@/settings/data-model/types/RelationType';
|
||||
import { RelationMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { useObjectMetadataItemForSettings } from '../hooks/useObjectMetadataItemForSettings';
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
|
||||
export const useRelationMetadata = ({
|
||||
fieldMetadataItem,
|
||||
}: {
|
||||
fieldMetadataItem?: FieldMetadataItem;
|
||||
}) => {
|
||||
const { findObjectMetadataItemById } = useObjectMetadataItemForSettings();
|
||||
|
||||
const relationMetadata =
|
||||
fieldMetadataItem?.fromRelationMetadata ||
|
||||
fieldMetadataItem?.toRelationMetadata;
|
||||
|
||||
const relationType =
|
||||
relationMetadata?.relationType === RelationMetadataType.OneToMany &&
|
||||
fieldMetadataItem?.toRelationMetadata
|
||||
? 'MANY_TO_ONE'
|
||||
: (relationMetadata?.relationType as RelationType);
|
||||
|
||||
const relationObjectMetadataId =
|
||||
relationMetadata && 'toObjectMetadata' in relationMetadata
|
||||
? relationMetadata.toObjectMetadata.id
|
||||
: relationMetadata?.fromObjectMetadata.id;
|
||||
|
||||
const relationObjectMetadataItem = relationObjectMetadataId
|
||||
? findObjectMetadataItemById(relationObjectMetadataId)
|
||||
: undefined;
|
||||
|
||||
const relationFieldMetadataId =
|
||||
relationMetadata && 'toFieldMetadataId' in relationMetadata
|
||||
? relationMetadata.toFieldMetadataId
|
||||
: relationMetadata?.fromFieldMetadataId;
|
||||
|
||||
const relationFieldMetadataItem = relationFieldMetadataId
|
||||
? relationObjectMetadataItem?.fields?.find(
|
||||
(field) => field.id === relationFieldMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
relationFieldMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
relationType,
|
||||
};
|
||||
};
|
@ -4,6 +4,14 @@ export type FieldMetadataItem = Omit<
|
||||
Field,
|
||||
'fromRelationMetadata' | 'toRelationMetadata'
|
||||
> & {
|
||||
fromRelationMetadata?: Pick<Relation, 'id' | 'relationType'> | null;
|
||||
toRelationMetadata?: Pick<Relation, 'id' | 'relationType'> | null;
|
||||
fromRelationMetadata?:
|
||||
| (Pick<Relation, 'id' | 'toFieldMetadataId' | 'relationType'> & {
|
||||
toObjectMetadata: Pick<Relation['toObjectMetadata'], 'id'>;
|
||||
})
|
||||
| null;
|
||||
toRelationMetadata?:
|
||||
| (Pick<Relation, 'id' | 'fromFieldMetadataId' | 'relationType'> & {
|
||||
fromObjectMetadata: Pick<Relation['fromObjectMetadata'], 'id'>;
|
||||
})
|
||||
| null;
|
||||
};
|
||||
|
@ -0,0 +1,59 @@
|
||||
import { RelationType } from '@/settings/data-model/types/RelationType';
|
||||
import {
|
||||
CreateRelationInput,
|
||||
Field,
|
||||
RelationMetadataType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { formatFieldMetadataItemInput } from './formatFieldMetadataItemInput';
|
||||
|
||||
export type FormatRelationMetadataInputParams = {
|
||||
relationType: RelationType;
|
||||
field: Pick<Field, 'label' | 'icon' | 'description'>;
|
||||
objectMetadataId: string;
|
||||
connect: {
|
||||
field: Pick<Field, 'label' | 'icon'>;
|
||||
objectMetadataId: string;
|
||||
};
|
||||
};
|
||||
|
||||
export const formatRelationMetadataInput = (
|
||||
input: FormatRelationMetadataInputParams,
|
||||
): CreateRelationInput => {
|
||||
// /!\ MANY_TO_ONE does not exist on backend.
|
||||
// => Transform into ONE_TO_MANY and invert "from" and "to" data.
|
||||
const isManyToOne = input.relationType === 'MANY_TO_ONE';
|
||||
const relationType = isManyToOne
|
||||
? RelationMetadataType.OneToMany
|
||||
: (input.relationType as RelationMetadataType);
|
||||
const { field: fromField, objectMetadataId: fromObjectMetadataId } =
|
||||
isManyToOne ? input.connect : input;
|
||||
const { field: toField, objectMetadataId: toObjectMetadataId } = isManyToOne
|
||||
? input
|
||||
: input.connect;
|
||||
|
||||
const {
|
||||
description,
|
||||
icon: fromIcon,
|
||||
label: fromLabel,
|
||||
name: fromName,
|
||||
} = formatFieldMetadataItemInput(fromField);
|
||||
const {
|
||||
icon: toIcon,
|
||||
label: toLabel,
|
||||
name: toName,
|
||||
} = formatFieldMetadataItemInput(toField);
|
||||
|
||||
return {
|
||||
description,
|
||||
fromIcon,
|
||||
fromLabel,
|
||||
fromName,
|
||||
fromObjectMetadataId,
|
||||
relationType,
|
||||
toIcon,
|
||||
toLabel,
|
||||
toName,
|
||||
toObjectMetadataId,
|
||||
};
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
import { RelationMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
export type RelationType =
|
||||
| Exclude<RelationMetadataType, 'MANY_TO_MANY'>
|
||||
| 'MANY_TO_ONE';
|
Loading…
Reference in New Issue
Block a user