mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-25 21:13:01 +03:00
fix timeline activity deleted field (#6433)
Fixes https://github.com/twentyhq/twenty/issues/6362
This commit is contained in:
parent
fed12ddfcd
commit
4389e81e64
@ -1,8 +1,9 @@
|
|||||||
import { ReactElement } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
import { EventsGroup } from '@/activities/timelineActivities/components/EventsGroup';
|
import { EventsGroup } from '@/activities/timelineActivities/components/EventsGroup';
|
||||||
import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity';
|
import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity';
|
||||||
|
import { filterOutInvalidTimelineActivities } from '@/activities/timelineActivities/utils/filterOutInvalidTimelineActivities';
|
||||||
import { groupEventsByMonth } from '@/activities/timelineActivities/utils/groupEventsByMonth';
|
import { groupEventsByMonth } from '@/activities/timelineActivities/utils/groupEventsByMonth';
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
@ -29,12 +30,17 @@ const StyledTimelineContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const EventList = ({ events, targetableObject }: EventListProps) => {
|
export const EventList = ({ events, targetableObject }: EventListProps) => {
|
||||||
const groupedEvents = groupEventsByMonth(events);
|
|
||||||
|
|
||||||
const mainObjectMetadataItem = useObjectMetadataItem({
|
const mainObjectMetadataItem = useObjectMetadataItem({
|
||||||
objectNameSingular: targetableObject.targetObjectNameSingular,
|
objectNameSingular: targetableObject.targetObjectNameSingular,
|
||||||
}).objectMetadataItem;
|
}).objectMetadataItem;
|
||||||
|
|
||||||
|
const filteredEvents = filterOutInvalidTimelineActivities(
|
||||||
|
events,
|
||||||
|
mainObjectMetadataItem,
|
||||||
|
);
|
||||||
|
|
||||||
|
const groupedEvents = groupEventsByMonth(filteredEvents);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollWrapper>
|
<ScrollWrapper>
|
||||||
<StyledTimelineContainer>
|
<StyledTimelineContainer>
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity';
|
||||||
|
import { filterOutInvalidTimelineActivities } from '@/activities/timelineActivities/utils/filterOutInvalidTimelineActivities';
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
|
||||||
|
describe('filterOutInvalidTimelineActivities', () => {
|
||||||
|
it('should filter out TimelineActivities with deleted fields from the properties diff', () => {
|
||||||
|
const events = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
properties: {
|
||||||
|
diff: {
|
||||||
|
field1: { before: 'value1', after: 'value2' },
|
||||||
|
field2: { before: 'value3', after: 'value4' },
|
||||||
|
field3: { before: 'value5', after: 'value6' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
properties: {
|
||||||
|
diff: {
|
||||||
|
field1: { before: 'value7', after: 'value8' },
|
||||||
|
field2: { before: 'value9', after: 'value10' },
|
||||||
|
field4: { before: 'value11', after: 'value12' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as TimelineActivity[];
|
||||||
|
|
||||||
|
const mainObjectMetadataItem = {
|
||||||
|
fields: [{ name: 'field1' }, { name: 'field2' }, { name: 'field3' }],
|
||||||
|
} as ObjectMetadataItem;
|
||||||
|
|
||||||
|
const filteredEvents = filterOutInvalidTimelineActivities(
|
||||||
|
events,
|
||||||
|
mainObjectMetadataItem,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(filteredEvents).toEqual([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
properties: {
|
||||||
|
diff: {
|
||||||
|
field1: { before: 'value1', after: 'value2' },
|
||||||
|
field2: { before: 'value3', after: 'value4' },
|
||||||
|
field3: { before: 'value5', after: 'value6' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
properties: {
|
||||||
|
diff: {
|
||||||
|
field1: { before: 'value7', after: 'value8' },
|
||||||
|
field2: { before: 'value9', after: 'value10' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array if all TimelineActivities have deleted fields in the properties diff', () => {
|
||||||
|
const events = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
properties: {
|
||||||
|
diff: {
|
||||||
|
field3: { before: 'value5', after: 'value6' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
properties: {
|
||||||
|
diff: {
|
||||||
|
field4: { before: 'value11', after: 'value12' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as TimelineActivity[];
|
||||||
|
|
||||||
|
const mainObjectMetadataItem = {
|
||||||
|
fields: [{ name: 'field1' }, { name: 'field2' }],
|
||||||
|
} as ObjectMetadataItem;
|
||||||
|
|
||||||
|
const filteredEvents = filterOutInvalidTimelineActivities(
|
||||||
|
events,
|
||||||
|
mainObjectMetadataItem,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(filteredEvents).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the same TimelineActivities if there are no properties diffs', () => {
|
||||||
|
const events = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
] as TimelineActivity[];
|
||||||
|
|
||||||
|
const mainObjectMetadataItem = {
|
||||||
|
fields: [{ name: 'field1' }, { name: 'field2' }],
|
||||||
|
} as ObjectMetadataItem;
|
||||||
|
|
||||||
|
const filteredEvents = filterOutInvalidTimelineActivities(
|
||||||
|
events,
|
||||||
|
mainObjectMetadataItem,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(filteredEvents).toEqual(events);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,35 @@
|
|||||||
|
import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity';
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
|
||||||
|
export const filterOutInvalidTimelineActivities = (
|
||||||
|
timelineActivities: TimelineActivity[],
|
||||||
|
mainObjectMetadataItem: ObjectMetadataItem,
|
||||||
|
): TimelineActivity[] => {
|
||||||
|
const fieldMetadataItemMap = new Map(
|
||||||
|
mainObjectMetadataItem.fields.map((field) => [field.name, field]),
|
||||||
|
);
|
||||||
|
|
||||||
|
return timelineActivities.filter((timelineActivity) => {
|
||||||
|
const diff = timelineActivity.properties?.diff;
|
||||||
|
const canSkipValidation = !diff;
|
||||||
|
|
||||||
|
if (canSkipValidation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validDiffEntries = Object.entries(diff).filter(([diffKey]) =>
|
||||||
|
fieldMetadataItemMap.has(diffKey),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (validDiffEntries.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
timelineActivity.properties = {
|
||||||
|
...timelineActivity.properties,
|
||||||
|
diff: Object.fromEntries(validDiffEntries),
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user