Fix timelineActivity updated fields (#6494)

## Context
We recently introduced the new twenty ORM and used it in the update
methods in the query runner.
Initially we were using pg_graphql to fetch the record before updating
it allowing us to compare the before and the after and create a diff.
This diff is then used for the timeline activity creation. Now,
twentyORM is doing the fetch and pg_graphql is still doing the update
and their responses are not exactly the same, which means the diff is
not working as intended (e.g date types were always in the diff due to
one being in Date format and the other as a string)

This PR introduces a updatedFields property to the update event which
comes from the input. This is not ideal as this won't work for API users
that send the whole payload but will be sufficient enough for our FE
that only sends modified fields. We then compare only those fields in
the diff.
This commit is contained in:
Weiko
2024-08-01 18:41:28 +02:00
committed by GitHub
parent a424c63476
commit 676c902731
5 changed files with 23 additions and 12 deletions

View File

@ -28,6 +28,7 @@ export class EntityEventsToDbListener {
payload.properties.diff = objectRecordChangedValues(
payload.properties.before,
payload.properties.after,
payload.properties.updatedFields,
payload.objectMetadata,
);

View File

@ -439,6 +439,7 @@ export class WorkspaceQueryRunnerService {
recordId: existingRecord.id,
objectMetadata: objectMetadataItem,
properties: {
updatedFields: Object.keys(args.data),
before: this.removeNestedProperties(existingRecord as Record),
after: this.removeNestedProperties(parsedResults?.[0]),
},
@ -518,6 +519,7 @@ export class WorkspaceQueryRunnerService {
recordId: existingRecord.id,
objectMetadata: objectMetadataItem,
properties: {
updatedFields: Object.keys(args.data),
before: this.removeNestedProperties(existingRecord as Record),
after: this.removeNestedProperties(record),
},

View File

@ -2,6 +2,7 @@ import { ObjectRecordBaseEvent } from 'src/engine/integrations/event-emitter/typ
export class ObjectRecordUpdateEvent<T> extends ObjectRecordBaseEvent {
properties: {
updatedFields: string[];
before: T;
after: T;
diff?: Partial<T>;

View File

@ -36,6 +36,7 @@ describe('objectRecordChangedValues', () => {
const result = objectRecordChangedValues(
oldRecord,
newRecord,
['name'],
mockObjectMetadata,
);
@ -58,6 +59,7 @@ it('ignores changes to the updatedAt field', () => {
const result = objectRecordChangedValues(
oldRecord,
newRecord,
[],
mockObjectMetadata,
);
@ -79,6 +81,7 @@ it('returns an empty object when there are no changes', () => {
const result = objectRecordChangedValues(
oldRecord,
newRecord,
['name', 'value'],
mockObjectMetadata,
);
@ -108,6 +111,7 @@ it('correctly handles a mix of changed, unchanged, and special case values', ()
const result = objectRecordChangedValues(
oldRecord,
newRecord,
['name', 'config', 'status'],
mockObjectMetadata,
);

View File

@ -1,33 +1,36 @@
import deepEqual from 'deep-equal';
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
export const objectRecordChangedValues = (
oldRecord: Partial<IRecord>,
newRecord: Partial<IRecord>,
updatedKeys: string[],
objectMetadata: ObjectMetadataInterface,
) => {
const fieldsByKey = new Map(
objectMetadata.fields.map((field) => [field.name, field]),
);
const changedValues = Object.keys(newRecord).reduce(
(acc, key) => {
const field = fieldsByKey.get(key);
const oldRecordValue = oldRecord[key];
const newRecordValue = newRecord[key];
if (
objectMetadata.fields.find(
(field) =>
field.type === FieldMetadataType.RELATION && field.name === key,
)
key === 'updatedAt' ||
!updatedKeys.includes(key) ||
field?.type === FieldMetadataType.RELATION ||
deepEqual(oldRecordValue, newRecordValue)
) {
return acc;
}
if (objectMetadata.nameSingular === 'activity' && key === 'body') {
return acc;
}
if (!deepEqual(oldRecord[key], newRecord[key]) && key !== 'updatedAt') {
acc[key] = { before: oldRecord[key], after: newRecord[key] };
}
acc[key] = { before: oldRecordValue, after: newRecordValue };
return acc;
},