Remove custom widget from calendarEvent page layout (#22046)

## Before
<img width="608" height="759" alt="image"
src="https://github.com/user-attachments/assets/e75f6cc9-aef8-4247-a88d-6992b3936d3d"
/>

## After
<img width="844" height="658" alt="image"
src="https://github.com/user-attachments/assets/446a13f2-e40c-4e1c-a1ed-0920fe5065b3"
/>


remove https://github.com/twentyhq/twenty/pull/22016 custom widget and
replace with regular field widget
does not match figma design but avoid introducing specific behavior for
calendarEvent


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22046?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
martmull
2026-06-24 08:59:14 +02:00
committed by GitHub
parent 5ec98d3d84
commit 3943898642
4 changed files with 0 additions and 200 deletions
@@ -1,43 +0,0 @@
import groupBy from 'lodash.groupby';
import { CalendarEventParticipantsResponseStatusField } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatusField';
import { type CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
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: Array<'Yes' | 'Maybe' | 'No'> = [
'Yes',
'Maybe',
'No',
];
return (
<PropertyBox>
{responseStatusOrder.map((responseStatus) => (
<CalendarEventParticipantsResponseStatusField
key={responseStatus}
responseStatus={responseStatus}
participants={groupedParticipants[responseStatus] ?? []}
/>
))}
</PropertyBox>
);
};
@@ -1,95 +0,0 @@
import { styled } from '@linaria/react';
import { useContext, useRef } from 'react';
import { ParticipantChip } from '@/activities/components/ParticipantChip';
import { type CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
import { IconCheck, IconQuestionMark, IconX } from 'twenty-ui/icon';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledResponseStatusRow = styled.div`
align-items: center;
box-sizing: border-box;
display: flex;
gap: ${themeCssVariables.spacing[1]};
min-height: ${themeCssVariables.spacing[6]};
position: relative;
user-select: none;
width: 100%;
`;
const StyledIconContainer = styled.div`
align-items: center;
color: ${themeCssVariables.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: ${themeCssVariables.font.color.tertiary};
display: flex;
gap: ${themeCssVariables.spacing[1]};
`;
const StyledLabelContainer = styled.div<{ width?: number }>`
color: ${themeCssVariables.font.color.tertiary};
font-size: ${themeCssVariables.font.size.sm};
width: ${({ width }) => (width !== undefined ? `${width}px` : 'auto')};
`;
const StyledParticipantsContainer = styled.div`
max-width: 70%;
`;
export const CalendarEventParticipantsResponseStatusField = ({
responseStatus,
participants,
}: {
responseStatus: 'Yes' | 'Maybe' | 'No';
participants: CalendarEventParticipant[];
}) => {
const { theme } = useContext(ThemeContext);
const Icon = {
Yes: <IconCheck stroke={theme.icon.stroke.sm} />,
Maybe: <IconQuestionMark stroke={theme.icon.stroke.sm} />,
No: <IconX stroke={theme.icon.stroke.sm} />,
}[responseStatus];
const orderedParticipants = [
...participants.filter((participant) => participant.person),
...participants.filter((participant) => participant.workspaceMember),
...participants.filter(
(participant) => !participant.person && !participant.workspaceMember,
),
];
const participantsContainerRef = useRef<HTMLDivElement>(null);
const styledChips = orderedParticipants.map((participant) => (
<ParticipantChip key={participant.id} participant={participant} />
));
return (
<StyledResponseStatusRow>
<StyledLabelAndIconContainer>
<StyledIconContainer>{Icon}</StyledIconContainer>
<StyledLabelContainer width={72}>
<EllipsisDisplay>{responseStatus}</EllipsisDisplay>
</StyledLabelContainer>
</StyledLabelAndIconContainer>
<StyledParticipantsContainer ref={participantsContainerRef}>
<ExpandableList isChipCountDisplayed>{styledChips}</ExpandableList>
</StyledParticipantsContainer>
</StyledResponseStatusRow>
);
};
@@ -1,47 +0,0 @@
import { CalendarEventParticipantsResponseStatus } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatus';
import { type CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
const CALENDAR_EVENT_PARTICIPANT_OBJECT_NAME_SINGULAR =
'calendarEventParticipant';
type CalendarEventParticipantsFieldWidgetProps = {
recordId: string;
};
type CalendarEventParticipantRecord = CalendarEventParticipant & {
__typename: 'CalendarEventParticipant';
};
export const CalendarEventParticipantsFieldWidget = ({
recordId,
}: CalendarEventParticipantsFieldWidgetProps) => {
const { records: calendarEventParticipants } =
useFindManyRecords<CalendarEventParticipantRecord>({
objectNameSingular: CALENDAR_EVENT_PARTICIPANT_OBJECT_NAME_SINGULAR,
filter: {
calendarEventId: {
eq: recordId,
},
},
recordGqlFields: {
id: true,
person: true,
workspaceMember: true,
isOrganizer: true,
responseStatus: true,
handle: true,
displayName: true,
},
});
if (calendarEventParticipants.length === 0) {
return null;
}
return (
<CalendarEventParticipantsResponseStatus
participants={calendarEventParticipants}
/>
);
};
@@ -9,7 +9,6 @@ import { hasJunctionConfig } from '@/object-record/record-field/ui/utils/junctio
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { useResolveFieldMetadataIdFromNameOrId } from '@/page-layout/hooks/useResolveFieldMetadataIdFromNameOrId';
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
import { CalendarEventParticipantsFieldWidget } from '@/page-layout/widgets/field/components/CalendarEventParticipantsFieldWidget';
import { FieldWidgetDisplay } from '@/page-layout/widgets/field/components/FieldWidgetDisplay';
import { FieldWidgetJunctionRelationCard } from '@/page-layout/widgets/field/components/FieldWidgetJunctionRelationCard';
import { FieldWidgetJunctionRelationField } from '@/page-layout/widgets/field/components/FieldWidgetJunctionRelationField';
@@ -27,7 +26,6 @@ import { SidePanelProvider } from '@/ui/layout/side-panel/contexts/SidePanelCont
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import {
AnimatedPlaceholder,
@@ -101,19 +99,6 @@ export const FieldWidget = ({ widget }: FieldWidgetProps) => {
const fieldDisplayMode = widget.configuration.fieldDisplayMode;
const isCalendarEventParticipantsField =
targetRecord.targetObjectNameSingular ===
CoreObjectNameSingular.CalendarEvent &&
fieldMetadataItem.name === 'calendarEventParticipants';
if (isCalendarEventParticipantsField) {
return (
<SidePanelProvider value={{ isInSidePanel }}>
<CalendarEventParticipantsFieldWidget recordId={targetRecord.id} />
</SidePanelProvider>
);
}
if (isFieldMorphRelation(fieldDefinition)) {
if (fieldDisplayMode === FieldDisplayMode.CARD) {
return (