Skip to content

Commit

Permalink
Activity timeline refactoring followup (twentyhq#5835)
Browse files Browse the repository at this point in the history
Following twentyhq#5697, addressing
review
  • Loading branch information
Weiko authored Jun 12, 2024
1 parent bd22bfc commit ad65479
Show file tree
Hide file tree
Showing 31 changed files with 607 additions and 293 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext'
import { useCalendarEvents } from '@/activities/calendar/hooks/useCalendarEvents';
import { getTimelineCalendarEventsFromCompanyId } from '@/activities/calendar/queries/getTimelineCalendarEventsFromCompanyId';
import { getTimelineCalendarEventsFromPersonId } from '@/activities/calendar/queries/getTimelineCalendarEventsFromPersonId';
import { FetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { CustomResolverFetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { useCustomResolver } from '@/activities/hooks/useCustomResolver';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
Expand Down Expand Up @@ -128,7 +128,7 @@ export const Calendar = ({
</Section>
);
})}
<FetchMoreLoader
<CustomResolverFetchMoreLoader
loading={isFetchingMore || firstQueryLoading}
onLastRowVisible={fetchMoreRecords}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled';
import { GRAY_SCALE } from 'twenty-ui';

type FetchMoreLoaderProps = {
type CustomResolverFetchMoreLoaderProps = {
loading: boolean;
onLastRowVisible: (...args: any[]) => any;
};
Expand All @@ -17,10 +17,10 @@ const StyledText = styled.div`
padding-left: ${({ theme }) => theme.spacing(2)};
`;

export const FetchMoreLoader = ({
export const CustomResolverFetchMoreLoader = ({
loading,
onLastRowVisible,
}: FetchMoreLoaderProps) => {
}: CustomResolverFetchMoreLoaderProps) => {
const { ref: tbodyRef } = useInView({
onChange: onLastRowVisible,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { H1Title, H1TitleFontColor } from 'twenty-ui';

import { FetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { CustomResolverFetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { EmailLoader } from '@/activities/emails/components/EmailLoader';
import { EmailThreadPreview } from '@/activities/emails/components/EmailThreadPreview';
import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from '@/activities/emails/constants/Messaging';
Expand Down Expand Up @@ -102,7 +102,7 @@ export const EmailThreads = ({
))}
</Card>
)}
<FetchMoreLoader
<CustomResolverFetchMoreLoader
loading={isFetchingMore || firstQueryLoading}
onLastRowVisible={fetchMoreRecords}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { useRecoilCallback } from 'recoil';

import { FetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { CustomResolverFetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { EmailLoader } from '@/activities/emails/components/EmailLoader';
import { EmailThreadHeader } from '@/activities/emails/components/EmailThreadHeader';
import { EmailThreadMessage } from '@/activities/emails/components/EmailThreadMessage';
Expand Down Expand Up @@ -98,7 +98,7 @@ export const RightDrawerEmailThread = () => {
sentAt={lastMessage.receivedAt}
isExpanded
/>
<FetchMoreLoader
<CustomResolverFetchMoreLoader
loading={loading}
onLastRowVisible={fetchMoreMessages}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,14 @@ import { useRecoilValue } from 'recoil';

import { useLinkedObject } from '@/activities/timeline/hooks/useLinkedObject';
import { TimelineActivityContext } from '@/activities/timelineActivities/contexts/TimelineActivityContext';
import {
EventIconDynamicComponent,
EventRowDynamicComponent,
} from '@/activities/timelineActivities/rows/components/EventRowDynamicComponent';
import { EventIconDynamicComponent } from '@/activities/timelineActivities/rows/components/EventIconDynamicComponent';
import { EventRowDynamicComponent } from '@/activities/timelineActivities/rows/components/EventRowDynamicComponent';
import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity';
import {
CurrentWorkspaceMember,
currentWorkspaceMemberState,
} from '@/auth/states/currentWorkspaceMemberState';
import { getTimelineActivityAuthorFullName } from '@/activities/timelineActivities/utils/getTimelineActivityAuthorFullName';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

const StyledIconContainer = styled.div`
Expand Down Expand Up @@ -93,18 +88,6 @@ type EventRowProps = {
event: TimelineActivity;
};

const getAuthorFullName = (
event: TimelineActivity,
currentWorkspaceMember: CurrentWorkspaceMember,
) => {
if (isDefined(event.workspaceMember)) {
return currentWorkspaceMember.id === event.workspaceMember.id
? 'You'
: `${event.workspaceMember?.name.firstName} ${event.workspaceMember?.name.lastName}`;
}
return 'Twenty';
};

export const EventRow = ({
isLastEvent,
event,
Expand All @@ -122,10 +105,13 @@ export const EventRow = ({
return null;
}

const authorFullName = getAuthorFullName(event, currentWorkspaceMember);
const authorFullName = getTimelineActivityAuthorFullName(
event,
currentWorkspaceMember,
);

if (isUndefinedOrNull(mainObjectMetadataItem)) {
return null;
throw new Error('mainObjectMetadataItem is required');
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { isNonEmptyArray } from '@sniptt/guards';

import { FetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { CustomResolverFetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { TimelineCreateButtonGroup } from '@/activities/timeline/components/TimelineCreateButtonGroup';
import { EventList } from '@/activities/timelineActivities/components/EventList';
import { useTimelineActivities } from '@/activities/timelineActivities/hooks/useTimelineActivities';
Expand Down Expand Up @@ -64,7 +64,10 @@ export const TimelineActivities = ({
title="All"
events={timelineActivities ?? []}
/>
<FetchMoreLoader loading={loading} onLastRowVisible={fetchMoreRecords} />
<CustomResolverFetchMoreLoader
loading={loading}
onLastRowVisible={fetchMoreRecords}
/>
</StyledMainContainer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import styled from '@emotion/styled';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import {
EventRowDynamicComponentProps,
StyledItemAction,
StyledItemAuthorText,
StyledEventRowItemAction,
StyledEventRowItemColumn,
} from '@/activities/timelineActivities/rows/components/EventRowDynamicComponent';

type EventRowActivityProps = EventRowDynamicComponentProps;
Expand All @@ -14,7 +14,7 @@ const StyledLinkedActivity = styled.span`
text-decoration: underline;
`;

export const EventRowActivity: React.FC<EventRowActivityProps> = ({
export const EventRowActivity = ({
event,
authorFullName,
}: EventRowActivityProps) => {
Expand All @@ -28,8 +28,8 @@ export const EventRowActivity: React.FC<EventRowActivityProps> = ({

return (
<>
<StyledItemAuthorText>{authorFullName}</StyledItemAuthorText>
<StyledItemAction>{eventAction}</StyledItemAction>
<StyledEventRowItemColumn>{authorFullName}</StyledEventRowItemColumn>
<StyledEventRowItemAction>{eventAction}</StyledEventRowItemAction>
<StyledLinkedActivity
onClick={() => openActivityRightDrawer(event.linkedRecordId)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
formatToHumanReadableDay,
formatToHumanReadableMonth,
formatToHumanReadableTime,
} from '~/utils';
} from '~/utils/format/formatDate';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

Expand Down Expand Up @@ -121,7 +121,7 @@ export const EventCardCalendarEvent = ({
return <div>Calendar event not found</div>;
}

return <div>Error loading message</div>;
return <div>Error loading calendar event</div>;
}

if (loading || isUndefined(calendarEvent)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import { useState } from 'react';
import styled from '@emotion/styled';

import { EventCardCalendarEvent } from '@/activities/timelineActivities/rows/calendar/components/EventCardCalendarEvent';
import {
EventCard,
EventCardToggleButton,
} from '@/activities/timelineActivities/rows/components/EventCard';
import { EventCard } from '@/activities/timelineActivities/rows/components/EventCard';
import { EventCardToggleButton } from '@/activities/timelineActivities/rows/components/EventCardToggleButton';
import {
EventRowDynamicComponentProps,
StyledItemAction,
StyledItemAuthorText,
StyledEventRowItemAction,
StyledEventRowItemColumn,
} from '@/activities/timelineActivities/rows/components/EventRowDynamicComponent';

type EventRowCalendarEventProps = EventRowDynamicComponentProps;
Expand All @@ -26,32 +24,25 @@ const StyledRowContainer = styled.div`
gap: ${({ theme }) => theme.spacing(1)};
`;

export const EventRowCalendarEvent: React.FC<EventRowCalendarEventProps> = ({
export const EventRowCalendarEvent = ({
event,
authorFullName,
labelIdentifierValue,
}: EventRowCalendarEventProps) => {
const [, eventAction] = event.name.split('.');
const [isOpen, setIsOpen] = useState(false);

const renderRow = () => {
switch (eventAction) {
case 'linked': {
return (
<StyledItemAction>
linked a calendar event with {labelIdentifierValue}
</StyledItemAction>
);
}
default:
throw new Error('Invalid event action for calendarEvent event type.');
}
};
if (['linked'].includes(eventAction) === false) {
throw new Error('Invalid event action for calendarEvent event type.');
}

return (
<StyledEventRowCalendarEventContainer>
<StyledRowContainer>
<StyledItemAuthorText>{authorFullName}</StyledItemAuthorText>
{renderRow()}
<StyledEventRowItemColumn>{authorFullName}</StyledEventRowItemColumn>
<StyledEventRowItemAction>
linked a calendar event with {labelIdentifierValue}
</StyledEventRowItemAction>
<EventCardToggleButton isOpen={isOpen} setIsOpen={setIsOpen} />
</StyledRowContainer>
<EventCard isOpen={isOpen}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Meta, StoryObj } from '@storybook/react';
import { graphql, HttpResponse } from 'msw';
import { ComponentDecorator } from 'twenty-ui';

import { EventCardCalendarEvent } from '@/activities/timelineActivities/rows/calendar/components/EventCardCalendarEvent';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';

const meta: Meta<typeof EventCardCalendarEvent> = {
title: 'Modules/TimelineActivities/Rows/CalendarEvent/EventCardCalendarEvent',
component: EventCardCalendarEvent,
decorators: [
ComponentDecorator,
ObjectMetadataItemsDecorator,
SnackBarDecorator,
],
};

export default meta;
type Story = StoryObj<typeof EventCardCalendarEvent>;

export const Default: Story = {
args: {
calendarEventId: '1',
},
parameters: {
msw: {
handlers: [
graphql.query('FindOneCalendarEvent', () => {
return HttpResponse.json({
data: {
calendarEvent: {
id: '1',
title: 'Mock title',
startsAt: '2022-01-01T00:00:00Z',
endsAt: '2022-01-01T01:00:00Z',
},
},
});
}),
],
},
},
};

export const NotShared: Story = {
args: {
calendarEventId: '1',
},
parameters: {
msw: {
handlers: [
graphql.query('FindOneCalendarEvent', () => {
return HttpResponse.json({
errors: [
{
message: 'Forbidden',
extensions: {
code: 'FORBIDDEN',
},
},
],
});
}),
],
},
},
};
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
import styled from '@emotion/styled';
import { IconChevronDown, IconChevronUp } from 'twenty-ui';

import { IconButton } from '@/ui/input/button/components/IconButton';
import { Card } from '@/ui/layout/card/components/Card';

type EventCardProps = {
children: React.ReactNode;
isOpen: boolean;
};

type EventCardToggleButtonProps = {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
};

const StyledButtonContainer = styled.div`
border-radius: ${({ theme }) => theme.border.radius.sm};
`;

const StyledCardContainer = styled.div`
align-items: flex-start;
display: flex;
Expand Down Expand Up @@ -52,19 +41,3 @@ export const EventCard = ({ children, isOpen }: EventCardProps) => {
)
);
};

export const EventCardToggleButton = ({
isOpen,
setIsOpen,
}: EventCardToggleButtonProps) => {
return (
<StyledButtonContainer>
<IconButton
Icon={isOpen ? IconChevronUp : IconChevronDown}
onClick={() => setIsOpen(!isOpen)}
size="small"
variant="secondary"
/>
</StyledButtonContainer>
);
};
Loading

0 comments on commit ad65479

Please sign in to comment.