Activity as standard object (#6219)

In this PR I layout the first steps to migrate Activity to a traditional
Standard objects

Since this is a big transition, I'd rather split it into several
deployments / PRs

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/012e2bbf-9d1b-4723-aaf6-269ef588b050">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: bosiraphael <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Faisal-imtiyaz123 <142205282+Faisal-imtiyaz123@users.noreply.github.com>
Co-authored-by: Prateek Jain <prateekj1171998@gmail.com>
This commit is contained in:
Félix Malfait
2024-07-31 15:36:11 +02:00
committed by GitHub
parent defcee2a02
commit 80c0fc7ff1
239 changed files with 18418 additions and 8671 deletions

View File

@ -1,11 +1,9 @@
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { mapFieldMetadataToGraphQLQuery } from '@/object-metadata/utils/mapFieldMetadataToGraphQLQuery';
import { normalizeGQLField } from '~/utils/normalizeGQLField';
const mockObjectMetadataItems = getObjectMetadataItemsMock();
const formatGQLString = (inputString: string) =>
inputString.replace(/^\s*[\r\n]/gm, '');
const personObjectMetadataItem = mockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
);
@ -22,7 +20,7 @@ describe('mapFieldMetadataToGraphQLQuery', () => {
(field) => field.name === 'id',
)!,
});
expect(formatGQLString(res)).toEqual('id');
expect(normalizeGQLField(res)).toEqual(normalizeGQLField('id'));
});
it('should return fieldName if composite', async () => {
const res = mapFieldMetadataToGraphQLQuery({
@ -31,11 +29,13 @@ describe('mapFieldMetadataToGraphQLQuery', () => {
(field) => field.name === 'name',
)!,
});
expect(formatGQLString(res)).toEqual(`name
expect(normalizeGQLField(res)).toEqual(
normalizeGQLField(`name
{
firstName
lastName
}`);
}`),
);
});
it('should return non relation subFields if relation', async () => {
@ -45,7 +45,8 @@ describe('mapFieldMetadataToGraphQLQuery', () => {
(field) => field.name === 'company',
)!,
});
expect(formatGQLString(res)).toEqual(`company
expect(normalizeGQLField(res)).toEqual(
normalizeGQLField(`company
{
__typename
xLink
@ -89,7 +90,8 @@ accountOwnerId
employees
id
idealCustomerProfile
}`);
}`),
);
});
it('should return only return relation subFields that are in recordGqlFields', async () => {
@ -119,7 +121,8 @@ idealCustomerProfile
(field) => field.name === 'company',
)!,
});
expect(formatGQLString(res)).toEqual(`company
expect(normalizeGQLField(res)).toEqual(
normalizeGQLField(`company
{
__typename
xLink
@ -207,6 +210,7 @@ accountOwnerId
employees
id
idealCustomerProfile
}`);
}`),
);
});
});

View File

@ -1,11 +1,9 @@
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
import { normalizeGQLQuery } from '~/utils/normalizeGQLQuery';
const mockObjectMetadataItems = getObjectMetadataItemsMock();
const formatGQLString = (inputString: string) =>
inputString.replace(/^\s*[\r\n]/gm, '');
const personObjectMetadataItem = mockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
);
@ -35,80 +33,83 @@ describe('mapObjectMetadataToGraphQLQuery', () => {
companyId: true,
},
});
expect(formatGQLString(res)).toEqual(`{
__typename
xLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
id
createdAt
company
{
__typename
xLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
linkedinLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
domainName
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
annualRecurringRevenue
{
amountMicros
currencyCode
}
createdAt
address
{
addressStreet1
addressStreet2
addressCity
addressState
addressCountry
addressPostcode
addressLat
addressLng
}
updatedAt
name
accountOwnerId
employees
id
idealCustomerProfile
}
city
email
jobTitle
name
{
firstName
lastName
}
phone
linkedinLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
updatedAt
avatarUrl
companyId
}`);
expect(normalizeGQLQuery(res)).toEqual(
normalizeGQLQuery(`{
__typename
name
{
firstName
lastName
}
email
phone
createdAt
avatarUrl
jobTitle
city
id
xLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
company
{
__typename
idealCustomerProfile
id
xLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
annualRecurringRevenue
{
amountMicros
currencyCode
}
address
{
addressStreet1
addressStreet2
addressCity
addressState
addressCountry
addressPostcode
addressLat
addressLng
}
employees
position
name
linkedinLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
createdAt
accountOwnerId
domainName
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
updatedAt
}
updatedAt
companyId
linkedinLink
{
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
}`),
);
});
it('should load only specified operation fields nested', async () => {
@ -117,7 +118,8 @@ companyId
objectMetadataItem: personObjectMetadataItem,
recordGqlFields: { company: { id: true }, id: true, name: true },
});
expect(formatGQLString(res)).toEqual(`{
expect(normalizeGQLQuery(res)).toEqual(
normalizeGQLQuery(`{
__typename
id
company
@ -130,6 +132,7 @@ name
firstName
lastName
}
}`);
}`),
);
});
});

View File

@ -16,6 +16,14 @@ export const getLabelIdentifierFieldValue = (
return `${record.name?.firstName ?? ''} ${record.name?.lastName ?? ''}`;
}
if (objectNameSingular === CoreObjectNameSingular.NoteTarget) {
return record.note?.title ?? '';
}
if (objectNameSingular === CoreObjectNameSingular.TaskTarget) {
return record.task?.title ?? '';
}
if (isDefined(labelIdentifierFieldMetadataItem?.name)) {
return String(record[labelIdentifierFieldMetadataItem.name]);
}

View File

@ -4,7 +4,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
export const getLinkToShowPage = (
objectNameSingular: string,
record: Pick<ObjectRecord, 'id'>,
record: Partial<ObjectRecord>,
) => {
const basePathToShowPage = getBasePathToShowPage({
objectNameSingular,
@ -13,6 +13,22 @@ export const getLinkToShowPage = (
const isWorkspaceMemberObjectMetadata =
objectNameSingular === CoreObjectNameSingular.WorkspaceMember;
if (objectNameSingular === CoreObjectNameSingular.NoteTarget) {
return (
getBasePathToShowPage({
objectNameSingular: CoreObjectNameSingular.Note,
}) + record.note?.id
);
}
if (objectNameSingular === CoreObjectNameSingular.TaskTarget) {
return (
getBasePathToShowPage({
objectNameSingular: CoreObjectNameSingular.Task,
}) + record.task?.id
);
}
const linkToShowPage =
isWorkspaceMemberObjectMetadata || !record.id
? ''

View File

@ -13,7 +13,8 @@ export const isLabelIdentifierField = ({
ObjectMetadataItem,
'labelIdentifierFieldMetadataId'
>;
}) =>
isDefined(objectMetadataItem.labelIdentifierFieldMetadataId)
}) => {
return isDefined(objectMetadataItem.labelIdentifierFieldMetadataId)
? fieldMetadataItem.id === objectMetadataItem.labelIdentifierFieldMetadataId
: fieldMetadataItem.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME;
};

View File

@ -40,6 +40,7 @@ export const mapFieldMetadataToGraphQLQuery = ({
FieldMetadataType.MultiSelect,
FieldMetadataType.Position,
FieldMetadataType.RawJson,
FieldMetadataType.RichText,
].includes(fieldType);
if (fieldIsSimpleValue) {