From c0b3a8715f598f9508f3863cc26c24748a830383 Mon Sep 17 00:00:00 2001
From: bosiraphael <71827178+bosiraphael@users.noreply.github.com>
Date: Fri, 12 Apr 2024 10:33:46 +0200
Subject: [PATCH] 4810 display participants in the right drawer of the calendar
event (#4896)
Closes #4810
- Introduces a new component `ExpandableList` which uses intersection
observers to display the maximum number of elements possible
---
.../components/CalendarEventDetails.tsx | 59 ++++++----
...alendarEventParticipantsResponseStatus.tsx | 42 +++++++
...arEventParticipantsResponseStatusField.tsx | 108 ++++++++++++++++++
.../components/RightDrawerCalendarEvent.tsx | 1 +
.../calendar/types/CalendarEvent.ts | 7 +-
.../types/CalendarEventParticipant.ts | 12 ++
.../activities/components/ParticipantChip.tsx | 80 +++++++++++++
.../components/EmailThreadMessageSender.tsx | 55 +--------
.../expandable-list/ExpandableList.tsx | 104 +++++++++++++++++
.../IntersectionObserverWrapper.tsx | 47 ++++++++
.../dropdown/components/DropdownMenu.tsx | 4 +-
.../components/RightDrawerRouter.tsx | 2 +-
.../src/testing/mock-data/calendar.ts | 26 ++++-
.../src/testing/mock-data/metadata.ts | 2 +-
.../constants/standard-field-ids.ts | 2 +-
.../calendar-event.object-metadata.ts | 4 +-
.../modules/calendar/types/calendar-event.ts | 1 -
.../display/icon/components/TablerIcons.ts | 1 +
18 files changed, 468 insertions(+), 89 deletions(-)
create mode 100644 packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatus.tsx
create mode 100644 packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx
create mode 100644 packages/twenty-front/src/modules/activities/calendar/types/CalendarEventParticipant.ts
create mode 100644 packages/twenty-front/src/modules/activities/components/ParticipantChip.tsx
create mode 100644 packages/twenty-front/src/modules/ui/display/expandable-list/ExpandableList.tsx
create mode 100644 packages/twenty-front/src/modules/ui/display/expandable-list/IntersectionObserverWrapper.tsx
diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx
index 5457fd1fed7c..363ceafeb586 100644
--- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx
+++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx
@@ -1,7 +1,9 @@
+import React from 'react';
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconCalendarEvent } from 'twenty-ui';
+import { CalendarEventParticipantsResponseStatus } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatus';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
@@ -30,6 +32,8 @@ const StyledContainer = styled.div`
flex-direction: column;
gap: ${({ theme }) => theme.spacing(6)};
padding: ${({ theme }) => theme.spacing(6)};
+ width: 100%;
+ box-sizing: border-box;
`;
const StyledEventChip = styled(Chip)`
@@ -60,11 +64,13 @@ const StyledFields = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(3)};
+ width: 100%;
`;
const StyledPropertyBox = styled(PropertyBox)`
height: ${({ theme }) => theme.spacing(6)};
padding: 0;
+ width: 100%;
`;
export const CalendarEventDetails = ({
@@ -88,6 +94,31 @@ export const CalendarEventDetails = ({
({ name }) => name,
);
+ const { calendarEventParticipants } = calendarEvent;
+
+ const Fields = fieldsToDisplay.map((fieldName) => (
+
+ [() => undefined, { loading: false }],
+ maxWidth: 300,
+ }}
+ >
+
+
+
+ ));
+
return (
- {fieldsToDisplay.map((fieldName) => (
-
- [() => undefined, { loading: false }],
- }}
- >
-
-
-
- ))}
+ {Fields.slice(0, 2)}
+ {calendarEventParticipants && (
+
+ )}
+ {Fields.slice(2)}
);
diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatus.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatus.tsx
new file mode 100644
index 000000000000..1db72c28ac34
--- /dev/null
+++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatus.tsx
@@ -0,0 +1,42 @@
+import groupBy from 'lodash.groupby';
+
+import { CalendarEventParticipantsResponseStatusField } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatusField';
+import { CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
+
+export const CalendarEventParticipantsResponseStatus = ({
+ participants,
+}: {
+ participants: CalendarEventParticipant[];
+}) => {
+ const groupedParticipants = groupBy(participants, (participant) => {
+ switch (participant.responseStatus) {
+ case 'ACCEPTED':
+ return 'Yes';
+ case 'DECLINED':
+ return 'No';
+ case 'NEEDS_ACTION':
+ case 'TENTATIVE':
+ return 'Maybe';
+ default:
+ return '';
+ }
+ });
+
+ const responseStatusOrder: ('Yes' | 'Maybe' | 'No')[] = [
+ 'Yes',
+ 'Maybe',
+ 'No',
+ ];
+
+ return (
+ <>
+ {responseStatusOrder.map((responseStatus) => (
+
+ ))}
+ >
+ );
+};
diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx
new file mode 100644
index 000000000000..6a83a6f723b5
--- /dev/null
+++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx
@@ -0,0 +1,108 @@
+import { useRef } from 'react';
+import { useTheme } from '@emotion/react';
+import styled from '@emotion/styled';
+import { IconCheck, IconQuestionMark, IconX } from 'twenty-ui';
+import { v4 } from 'uuid';
+
+import { CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
+import { ParticipantChip } from '@/activities/components/ParticipantChip';
+import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
+import { ExpandableList } from '@/ui/display/expandable-list/ExpandableList';
+import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
+
+const StyledInlineCellBaseContainer = styled.div`
+ align-items: center;
+ box-sizing: border-box;
+ width: 100%;
+ display: flex;
+
+ gap: ${({ theme }) => theme.spacing(1)};
+
+ position: relative;
+ user-select: none;
+`;
+
+const StyledPropertyBox = styled(PropertyBox)`
+ height: ${({ theme }) => theme.spacing(6)};
+ padding: 0;
+ width: 100%;
+`;
+
+const StyledIconContainer = styled.div`
+ align-items: center;
+ color: ${({ theme }) => theme.font.color.tertiary};
+ display: flex;
+ width: 16px;
+
+ svg {
+ align-items: center;
+ display: flex;
+ height: 16px;
+ justify-content: center;
+ width: 16px;
+ }
+`;
+
+const StyledLabelAndIconContainer = styled.div`
+ align-items: center;
+ color: ${({ theme }) => theme.font.color.tertiary};
+ display: flex;
+ gap: ${({ theme }) => theme.spacing(1)};
+`;
+
+const StyledLabelContainer = styled.div<{ width?: number }>`
+ color: ${({ theme }) => theme.font.color.tertiary};
+ font-size: ${({ theme }) => theme.font.size.sm};
+ width: ${({ width }) => width}px;
+`;
+
+export const CalendarEventParticipantsResponseStatusField = ({
+ responseStatus,
+ participants,
+}: {
+ responseStatus: 'Yes' | 'Maybe' | 'No';
+ participants: CalendarEventParticipant[];
+}) => {
+ const theme = useTheme();
+
+ const Icon = {
+ Yes: ,
+ Maybe: ,
+ No: ,
+ }[responseStatus];
+
+ // We want to display external participants first
+ const orderedParticipants = [
+ ...participants.filter((participant) => participant.person),
+ ...participants.filter(
+ (participant) => !participant.person && !participant.workspaceMember,
+ ),
+ ...participants.filter((participant) => participant.workspaceMember),
+ ];
+
+ const participantsContainerRef = useRef(null);
+
+ const StyledChips = orderedParticipants.map((participant) => (
+
+ ));
+
+ return (
+
+
+
+ {Icon}
+
+
+ {responseStatus}
+
+
+
+
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx b/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx
index 845885e7cd7d..f0e895dcdaa5 100644
--- a/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx
+++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx
@@ -14,6 +14,7 @@ export const RightDrawerCalendarEvent = () => {
objectNameSingular: CoreObjectNameSingular.CalendarEvent,
objectRecordId: viewableCalendarEventId ?? '',
onCompleted: (record) => setRecords([record]),
+ depth: 2,
});
if (!calendarEvent) return null;
diff --git a/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts b/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts
index 01ec2c2d5ac2..a598c23d967f 100644
--- a/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts
+++ b/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts
@@ -1,3 +1,5 @@
+import { CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
+
// TODO: use backend CalendarEvent type when ready
export type CalendarEvent = {
conferenceLink?: {
@@ -14,8 +16,5 @@ export type CalendarEvent = {
startsAt: string;
title?: string;
visibility: 'METADATA' | 'SHARE_EVERYTHING';
- participants?: {
- displayName: string;
- workspaceMemberId?: string;
- }[];
+ calendarEventParticipants?: CalendarEventParticipant[];
};
diff --git a/packages/twenty-front/src/modules/activities/calendar/types/CalendarEventParticipant.ts b/packages/twenty-front/src/modules/activities/calendar/types/CalendarEventParticipant.ts
new file mode 100644
index 000000000000..079e57c18d31
--- /dev/null
+++ b/packages/twenty-front/src/modules/activities/calendar/types/CalendarEventParticipant.ts
@@ -0,0 +1,12 @@
+import { Person } from '@/people/types/Person';
+import { WorkspaceMember } from '~/generated-metadata/graphql';
+
+export type CalendarEventParticipant = {
+ id: string;
+ handle: string;
+ isOrganizer: boolean;
+ displayName: string;
+ person?: Person;
+ workspaceMember?: WorkspaceMember;
+ responseStatus: 'ACCEPTED' | 'DECLINED' | 'NEEDS_ACTION' | 'TENTATIVE';
+};
diff --git a/packages/twenty-front/src/modules/activities/components/ParticipantChip.tsx b/packages/twenty-front/src/modules/activities/components/ParticipantChip.tsx
new file mode 100644
index 000000000000..84235d6a912e
--- /dev/null
+++ b/packages/twenty-front/src/modules/activities/components/ParticipantChip.tsx
@@ -0,0 +1,80 @@
+import styled from '@emotion/styled';
+
+import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
+import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
+import { RecordChip } from '@/object-record/components/RecordChip';
+import { Avatar } from '@/users/components/Avatar';
+
+const StyledAvatar = styled(Avatar)`
+ margin-right: ${({ theme }) => theme.spacing(1)};
+`;
+
+const StyledSenderName = styled.span<{ variant?: 'default' | 'bold' }>`
+ color: ${({ theme }) => theme.font.color.primary};
+ font-size: ${({ theme }) => theme.font.size.md};
+ font-weight: ${({ theme, variant }) =>
+ variant === 'bold' ? theme.font.weight.medium : theme.font.weight.regular};
+ overflow: hidden;
+ text-overflow: ellipsis;
+`;
+
+const StyledContainer = styled.div`
+ align-items: flex-start;
+ display: flex;
+`;
+
+const StyledRecordChip = styled(RecordChip)<{ variant: 'default' | 'bold' }>`
+ font-weight: ${({ theme, variant }) =>
+ variant === 'bold' ? theme.font.weight.medium : theme.font.weight.regular};
+`;
+
+const StyledChip = styled.div`
+ align-items: center;
+ display: flex;
+ padding: ${({ theme }) => theme.spacing(1)};
+ height: 20px;
+ box-sizing: border-box;
+`;
+
+type ParticipantChipVariant = 'default' | 'bold';
+
+export const ParticipantChip = ({
+ participant,
+ variant = 'default',
+ className,
+}: {
+ participant: any;
+ variant?: ParticipantChipVariant;
+ className?: string;
+}) => {
+ const { person, workspaceMember } = participant;
+
+ const displayName = getDisplayNameFromParticipant({
+ participant,
+ shouldUseFullName: true,
+ });
+
+ const avatarUrl = person?.avatarUrl ?? workspaceMember?.avatarUrl ?? '';
+
+ return (
+
+ {person ? (
+
+ ) : (
+
+
+ {displayName}
+
+ )}
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx
index ae2552c203b1..d58e4606aafb 100644
--- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx
+++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx
@@ -1,11 +1,7 @@
-import React from 'react';
import styled from '@emotion/styled';
+import { ParticipantChip } from '@/activities/components/ParticipantChip';
import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant';
-import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
-import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
-import { RecordChip } from '@/object-record/components/RecordChip';
-import { Avatar } from '@/users/components/Avatar';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
const StyledEmailThreadMessageSender = styled.div`
@@ -13,23 +9,6 @@ const StyledEmailThreadMessageSender = styled.div`
justify-content: space-between;
`;
-const StyledEmailThreadMessageSenderUser = styled.div`
- align-items: flex-start;
- display: flex;
-`;
-
-const StyledAvatar = styled(Avatar)`
- margin: ${({ theme }) => theme.spacing(0, 1)};
-`;
-
-const StyledSenderName = styled.span`
- color: ${({ theme }) => theme.font.color.primary};
- font-size: ${({ theme }) => theme.font.size.sm};
- font-weight: ${({ theme }) => theme.font.weight.medium};
- overflow: hidden;
- text-overflow: ellipsis;
-`;
-
const StyledThreadMessageSentAt = styled.div`
align-items: flex-end;
display: flex;
@@ -37,10 +16,6 @@ const StyledThreadMessageSentAt = styled.div`
font-size: ${({ theme }) => theme.font.size.sm};
`;
-const StyledRecordChip = styled(RecordChip)`
- font-weight: ${({ theme }) => theme.font.weight.medium};
-`;
-
type EmailThreadMessageSenderProps = {
sender: EmailThreadMessageParticipant;
sentAt: string;
@@ -50,35 +25,9 @@ export const EmailThreadMessageSender = ({
sender,
sentAt,
}: EmailThreadMessageSenderProps) => {
- const { person, workspaceMember } = sender;
-
- const displayName = getDisplayNameFromParticipant({
- participant: sender,
- shouldUseFullName: true,
- });
-
- const avatarUrl = person?.avatarUrl ?? workspaceMember?.avatarUrl ?? '';
-
return (
-
- {person ? (
-
- ) : (
- <>
-
- {displayName}
- >
- )}
-
+
{beautifyPastDateRelativeToNow(sentAt)}
diff --git a/packages/twenty-front/src/modules/ui/display/expandable-list/ExpandableList.tsx b/packages/twenty-front/src/modules/ui/display/expandable-list/ExpandableList.tsx
new file mode 100644
index 000000000000..0d7bf8c2bb8e
--- /dev/null
+++ b/packages/twenty-front/src/modules/ui/display/expandable-list/ExpandableList.tsx
@@ -0,0 +1,104 @@
+import React, { ReactElement, useRef, useState } from 'react';
+import { createPortal } from 'react-dom';
+import styled from '@emotion/styled';
+
+import { Chip, ChipVariant } from '@/ui/display/chip/components/Chip';
+import { IntersectionObserverWrapper } from '@/ui/display/expandable-list/IntersectionObserverWrapper';
+import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
+
+const StyledContainer = styled.div`
+ align-items: center;
+ display: flex;
+ flex: 1;
+ gap: ${({ theme }) => theme.spacing(1)};
+ box-sizing: border-box;
+ white-space: nowrap;
+ overflow-x: hidden;
+`;
+
+const StyledExpendableCell = styled.div`
+ align-content: center;
+ align-items: center;
+ backdrop-filter: ${({ theme }) => theme.blur.strong};
+ background: ${({ theme }) => theme.background.secondary};
+ border: 1px solid ${({ theme }) => theme.border.color.medium};
+ border-radius: ${({ theme }) => theme.border.radius.sm};
+ box-shadow: ${({ theme }) => theme.boxShadow.light};
+ box-sizing: border-box;
+ display: flex;
+ flex-wrap: wrap;
+ gap: ${({ theme }) => theme.spacing(1)};
+ padding: ${({ theme }) => theme.spacing(2)};
+`;
+
+export const ExpandableList = ({
+ listItems,
+ rootRef,
+ id,
+}: {
+ listItems: ReactElement[];
+ rootRef: React.RefObject;
+ id: string;
+}) => {
+ const [listItemsInView, setListItemsInView] = useState(new Set());
+
+ const firstListItem = listItems[0];
+
+ const dropdownId = `expandable-list-dropdown-${id}`;
+
+ const containerRef = useRef(null);
+
+ const divRef = useRef(null);
+
+ return (
+
+ {firstListItem}
+ {listItems.slice(1).map((listItem, index) => (
+
+
+ {listItem}
+
+ {index === listItemsInView.size - 1 &&
+ listItems.length - listItemsInView.size - 1 !== 0 && (
+
+ }
+ dropdownComponents={
+ <>
+ {divRef.current &&
+ createPortal(
+
+ {listItems}
+ ,
+ divRef.current as HTMLElement,
+ )}
+ >
+ }
+ />
+ )}
+
+ ))}
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/ui/display/expandable-list/IntersectionObserverWrapper.tsx b/packages/twenty-front/src/modules/ui/display/expandable-list/IntersectionObserverWrapper.tsx
new file mode 100644
index 000000000000..d4a81d2e2974
--- /dev/null
+++ b/packages/twenty-front/src/modules/ui/display/expandable-list/IntersectionObserverWrapper.tsx
@@ -0,0 +1,47 @@
+import React from 'react';
+import { useInView } from 'react-intersection-observer';
+import styled from '@emotion/styled';
+
+const StyledDiv = styled.div<{ inView?: boolean }>`
+ opacity: ${({ inView }) => (inView === undefined || inView ? 1 : 0)};
+`;
+
+export const IntersectionObserverWrapper = ({
+ set,
+ id,
+ rootRef,
+ children,
+}: {
+ set: React.Dispatch>>;
+ id: number;
+ rootRef?: React.RefObject;
+ children: React.ReactNode;
+}) => {
+ const { ref, inView } = useInView({
+ threshold: 1,
+ onChange: (inView) => {
+ if (inView) {
+ set((prev: Set) => {
+ const newSet = new Set(prev);
+ newSet.add(id);
+ return newSet;
+ });
+ }
+ if (!inView) {
+ set((prev: Set) => {
+ const newSet = new Set(prev);
+ newSet.delete(id);
+ return newSet;
+ });
+ }
+ },
+ root: rootRef?.current,
+ rootMargin: '0px 0px -50px 0px',
+ });
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx
index ac483e743306..8acfcadfaee7 100644
--- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx
+++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx
@@ -2,6 +2,7 @@ import styled from '@emotion/styled';
const StyledDropdownMenu = styled.div<{
disableBlur?: boolean;
+ disableBorder?: boolean;
width?: `${string}px` | `${number}%` | 'auto' | number;
}>`
backdrop-filter: ${({ disableBlur }) =>
@@ -14,7 +15,8 @@ const StyledDropdownMenu = styled.div<{
? theme.background.primary
: theme.background.transparent.secondary};
- border: 1px solid ${({ theme }) => theme.border.color.medium};
+ border: ${({ disableBorder, theme }) =>
+ disableBorder ? 'none' : `1px solid ${theme.border.color.medium}`};
border-radius: ${({ theme }) => theme.border.radius.md};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx
index a0eb83b409e2..77daadb0eb4c 100644
--- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx
+++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx
@@ -23,7 +23,7 @@ const StyledRightDrawerBody = styled.div`
height: calc(
100vh - ${({ theme }) => theme.spacing(14)} - 1px
); // (-1 for border)
- overflow: auto;
+ //overflow: auto;
position: relative;
`;
diff --git a/packages/twenty-front/src/testing/mock-data/calendar.ts b/packages/twenty-front/src/testing/mock-data/calendar.ts
index 7e115ddaca2b..a58f0074ec94 100644
--- a/packages/twenty-front/src/testing/mock-data/calendar.ts
+++ b/packages/twenty-front/src/testing/mock-data/calendar.ts
@@ -10,10 +10,28 @@ export const mockedCalendarEvents: CalendarEvent[] = [
isFullDay: false,
startsAt: addDays(new Date().setHours(10, 0), 1).toISOString(),
visibility: 'METADATA',
- participants: [
- { displayName: 'John Doe', workspaceMemberId: 'john-doe' },
- { displayName: 'Jane Doe', workspaceMemberId: 'jane-doe' },
- { displayName: 'Tim Apple', workspaceMemberId: 'tim-apple' },
+ calendarEventParticipants: [
+ {
+ id: '1',
+ handle: 'jdoe',
+ isOrganizer: false,
+ responseStatus: 'ACCEPTED',
+ displayName: 'John Doe',
+ },
+ {
+ id: '2',
+ handle: 'jadoe',
+ isOrganizer: false,
+ responseStatus: 'ACCEPTED',
+ displayName: 'Jane Doe',
+ },
+ {
+ id: '3',
+ handle: 'tapple',
+ isOrganizer: false,
+ responseStatus: 'ACCEPTED',
+ displayName: 'Tim Apple',
+ },
],
},
{
diff --git a/packages/twenty-front/src/testing/mock-data/metadata.ts b/packages/twenty-front/src/testing/mock-data/metadata.ts
index caa9c53f072a..1d844d43a628 100644
--- a/packages/twenty-front/src/testing/mock-data/metadata.ts
+++ b/packages/twenty-front/src/testing/mock-data/metadata.ts
@@ -1443,7 +1443,7 @@ const mockedCalendarEventsMetadata = {
__typename: 'field',
id: '07880d2d-4f08-458f-be0b-876402d2a769',
type: 'RELATION',
- name: 'eventParticipants',
+ name: 'calendarEventParticipants',
label: 'Event Participants',
description: 'Event Participants',
icon: 'IconUserCircle',
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts
index 5f6bb82271ca..f27e8f1e77ed 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts
@@ -97,7 +97,7 @@ export const calendarEventStandardFieldIds = {
conferenceLink: '20202020-35da-43ef-9ca0-e936e9dc237b',
recurringEventExternalId: '20202020-4b96-43d0-8156-4c7a9717635c',
calendarChannelEventAssociations: '20202020-bdf8-4572-a2cc-ecbb6bcc3a02',
- eventParticipants: '20202020-e07e-4ccb-88f5-6f3d00458eec',
+ calendarEventParticipants: '20202020-e07e-4ccb-88f5-6f3d00458eec',
};
export const commentStandardFieldIds = {
diff --git a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts
index 95382121dcd7..14c8b509a4e3 100644
--- a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts
+++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts
@@ -171,7 +171,7 @@ export class CalendarEventObjectMetadata extends BaseObjectMetadata {
calendarChannelEventAssociations: CalendarChannelEventAssociationObjectMetadata[];
@FieldMetadata({
- standardId: calendarEventStandardFieldIds.eventParticipants,
+ standardId: calendarEventStandardFieldIds.calendarEventParticipants,
type: FieldMetadataType.RELATION,
label: 'Event Participants',
description: 'Event Participants',
@@ -182,5 +182,5 @@ export class CalendarEventObjectMetadata extends BaseObjectMetadata {
inverseSideTarget: () => CalendarEventParticipantObjectMetadata,
onDelete: RelationOnDeleteAction.CASCADE,
})
- eventParticipants: CalendarEventParticipantObjectMetadata[];
+ calendarEventParticipants: CalendarEventParticipantObjectMetadata[];
}
diff --git a/packages/twenty-server/src/modules/calendar/types/calendar-event.ts b/packages/twenty-server/src/modules/calendar/types/calendar-event.ts
index 21a7f8433d3f..72818b13110b 100644
--- a/packages/twenty-server/src/modules/calendar/types/calendar-event.ts
+++ b/packages/twenty-server/src/modules/calendar/types/calendar-event.ts
@@ -8,7 +8,6 @@ export type CalendarEvent = Omit<
| 'updatedAt'
| 'calendarChannelEventAssociations'
| 'calendarEventParticipants'
- | 'eventParticipants'
| 'conferenceLink'
> & {
conferenceLinkLabel: string;
diff --git a/packages/twenty-ui/src/display/icon/components/TablerIcons.ts b/packages/twenty-ui/src/display/icon/components/TablerIcons.ts
index 50826f172aea..1a5f4247bf07 100644
--- a/packages/twenty-ui/src/display/icon/components/TablerIcons.ts
+++ b/packages/twenty-ui/src/display/icon/components/TablerIcons.ts
@@ -113,6 +113,7 @@ export {
IconPresentation,
IconProgressCheck,
IconPuzzle,
+ IconQuestionMark,
IconRefresh,
IconRelationManyToMany,
IconRelationOneToMany,