Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4488 connect calendar tab to backend #4624

Merged
merged 25 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@ import styled from '@emotion/styled';
import { format, getYear } from 'date-fns';

import { CalendarMonthCard } from '@/activities/calendar/components/CalendarMonthCard';
import { TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE } from '@/activities/calendar/constants/Calendar';
import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext';
import { useCalendarEvents } from '@/activities/calendar/hooks/useCalendarEvents';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { getTimelineCalendarEventsFromCompanyId } from '@/activities/calendar/queries/getTimelineCalendarEventsFromCompanyId';
import { getTimelineCalendarEventsFromPersonId } from '@/activities/calendar/queries/getTimelineCalendarEventsFromPersonId';
import { FetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { useCustomResolver } from '@/activities/hooks/useCustomResolver';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { H3Title } from '@/ui/display/typography/components/H3Title';
import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder';
import {
AnimatedPlaceholderEmptyContainer,
AnimatedPlaceholderEmptySubTitle,
AnimatedPlaceholderEmptyTextContainer,
AnimatedPlaceholderEmptyTitle,
} from '@/ui/layout/animated-placeholder/components/EmptyPlaceholderStyled';
import { Section } from '@/ui/layout/section/components/Section';
import { TimelineCalendarEventsWithTotal } from '~/generated/graphql';

const StyledContainer = styled.div`
box-sizing: border-box;
Expand All @@ -17,18 +29,40 @@ const StyledContainer = styled.div`
gap: ${({ theme }) => theme.spacing(8)};
padding: ${({ theme }) => theme.spacing(6)};
width: 100%;
overflow: scroll;
`;

const StyledYear = styled.span`
color: ${({ theme }) => theme.font.color.light};
`;

export const Calendar = () => {
const { records: calendarEvents } = useFindManyRecords<CalendarEvent>({
objectNameSingular: CoreObjectNameSingular.CalendarEvent,
orderBy: { startsAt: 'DescNullsLast', endsAt: 'DescNullsLast' },
useRecordsWithoutConnection: true,
});
export const Calendar = ({
targetableObject,
}: {
targetableObject: ActivityTargetableObject;
}) => {
const [query, queryName] =
targetableObject.targetObjectNameSingular === CoreObjectNameSingular.Person
? [
getTimelineCalendarEventsFromPersonId,
'getTimelineCalendarEventsFromPersonId',
]
: [
getTimelineCalendarEventsFromCompanyId,
'getTimelineCalendarEventsFromCompanyId',
];

const { data, firstQueryLoading, isFetchingMore, fetchMoreRecords } =
useCustomResolver(
query,
queryName,
'timelineCalendarEvents',
targetableObject,
TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE,
);

const { timelineCalendarEvents }: TimelineCalendarEventsWithTotal =
data?.[queryName] ?? [];

const {
calendarEventsByDayTime,
Expand All @@ -38,13 +72,30 @@ export const Calendar = () => {
monthTimes,
monthTimesByYear,
updateCurrentCalendarEvent,
} = useCalendarEvents(
calendarEvents.map((calendarEvent) => ({
...calendarEvent,
// TODO: retrieve CalendarChannel visibility from backend
visibility: 'SHARE_EVERYTHING',
})),
);
} = useCalendarEvents(timelineCalendarEvents || []);

if (firstQueryLoading) {
// TODO: implement loader
return;
}

if (!firstQueryLoading && !timelineCalendarEvents?.length) {
// TODO: change animated placeholder
return (
<AnimatedPlaceholderEmptyContainer>
<AnimatedPlaceholder type="noMatchRecord" />
<AnimatedPlaceholderEmptyTextContainer>
<AnimatedPlaceholderEmptyTitle>
No Events
</AnimatedPlaceholderEmptyTitle>
<AnimatedPlaceholderEmptySubTitle>
No events have been scheduled with this{' '}
{targetableObject.targetObjectNameSingular} yet.
</AnimatedPlaceholderEmptySubTitle>
</AnimatedPlaceholderEmptyTextContainer>
</AnimatedPlaceholderEmptyContainer>
);
}

return (
<CalendarContext.Provider
Expand Down Expand Up @@ -78,6 +129,10 @@ export const Calendar = () => {
</Section>
);
})}
<FetchMoreLoader
loading={isFetchingMore || firstQueryLoading}
onLastRowVisible={fetchMoreRecords}
/>
</StyledContainer>
</CalendarContext.Provider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import {
import { AnimatePresence, motion } from 'framer-motion';

import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { CalendarEventOrTimelineCalendarEvent } from '@/activities/calendar/types/CalendarEventOrTimelineCalendarEvent';
import { getCalendarEventEndDate } from '@/activities/calendar/utils/getCalendarEventEndDate';
import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate';
import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEventEnded';
import { hasCalendarEventStarted } from '@/activities/calendar/utils/hasCalendarEventStarted';

type CalendarCurrentEventCursorProps = {
calendarEvent: CalendarEvent;
calendarEvent: CalendarEventOrTimelineCalendarEvent;
};

const StyledCurrentEventCursor = styled(motion.div)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import styled from '@emotion/styled';
import { differenceInSeconds, endOfDay, format } from 'date-fns';

import { CalendarEventRow } from '@/activities/calendar/components/CalendarEventRow';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { CalendarEventOrTimelineCalendarEvent } from '@/activities/calendar/types/CalendarEventOrTimelineCalendarEvent';
import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate';
import { CardContent } from '@/ui/layout/card/components/CardContent';

type CalendarDayCardContentProps = {
calendarEvents: CalendarEvent[];
calendarEvents: CalendarEventOrTimelineCalendarEvent[];
divider?: boolean;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useRecoilValue } from 'recoil';
import { CalendarCurrentEventCursor } from '@/activities/calendar/components/CalendarCurrentEventCursor';
import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext';
import { useOpenCalendarEventRightDrawer } from '@/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { CalendarEventOrTimelineCalendarEvent } from '@/activities/calendar/types/CalendarEventOrTimelineCalendarEvent';
import { getCalendarEventEndDate } from '@/activities/calendar/utils/getCalendarEventEndDate';
import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate';
import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEventEnded';
Expand All @@ -20,7 +20,7 @@ import { AvatarGroup } from '@/users/components/AvatarGroup';
import { isDefined } from '~/utils/isDefined';

type CalendarEventRowProps = {
calendarEvent: CalendarEvent;
calendarEvent: CalendarEventOrTimelineCalendarEvent;
className?: string;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE = 10;
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { createContext } from 'react';

import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { CalendarEventOrTimelineCalendarEvent } from '@/activities/calendar/types/CalendarEventOrTimelineCalendarEvent';

type CalendarContextValue = {
calendarEventsByDayTime: Record<number, CalendarEvent[] | undefined>;
currentCalendarEvent?: CalendarEvent;
calendarEventsByDayTime: Record<
number,
CalendarEventOrTimelineCalendarEvent[] | undefined
>;
currentCalendarEvent?: CalendarEventOrTimelineCalendarEvent;
displayCurrentEventCursor?: boolean;
getNextCalendarEvent: (
calendarEvent: CalendarEvent,
) => CalendarEvent | undefined;
calendarEvent: CalendarEventOrTimelineCalendarEvent,
) => CalendarEventOrTimelineCalendarEvent | undefined;
updateCurrentCalendarEvent: () => void;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { useMemo, useState } from 'react';
import { getYear, isThisMonth, startOfDay, startOfMonth } from 'date-fns';

import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { CalendarEventOrTimelineCalendarEvent } from '@/activities/calendar/types/CalendarEventOrTimelineCalendarEvent';
import { findUpcomingCalendarEvent } from '@/activities/calendar/utils/findUpcomingCalendarEvent';
import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate';
import { groupArrayItemsBy } from '~/utils/array/groupArrayItemsBy';
import { isDefined } from '~/utils/isDefined';
import { sortDesc } from '~/utils/sort';

export const useCalendarEvents = (calendarEvents: CalendarEvent[]) => {
export const useCalendarEvents = (
calendarEvents: CalendarEventOrTimelineCalendarEvent[],
) => {
const calendarEventsByDayTime = groupArrayItemsBy(
calendarEvents,
(calendarEvent) =>
Expand All @@ -29,14 +31,18 @@ export const useCalendarEvents = (calendarEvents: CalendarEvent[]) => {

const monthTimesByYear = groupArrayItemsBy(sortedMonthTimes, getYear);

const getPreviousCalendarEvent = (calendarEvent: CalendarEvent) => {
const getPreviousCalendarEvent = (
calendarEvent: CalendarEventOrTimelineCalendarEvent,
) => {
const calendarEventIndex = calendarEvents.indexOf(calendarEvent);
return calendarEventIndex < calendarEvents.length - 1
? calendarEvents[calendarEventIndex + 1]
: undefined;
};

const getNextCalendarEvent = (calendarEvent: CalendarEvent) => {
const getNextCalendarEvent = (
calendarEvent: CalendarEventOrTimelineCalendarEvent,
) => {
const calendarEventIndex = calendarEvents.indexOf(calendarEvent);
return calendarEventIndex > 0
? calendarEvents[calendarEventIndex - 1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const calendarEventFragment = gql`
startsAt
endsAt
isFullDay
visibility
attendees {
...AttendeeFragment
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
import { TimelineCalendarEvent } from '~/generated/graphql';

export type CalendarEventOrTimelineCalendarEvent =
bosiraphael marked this conversation as resolved.
Show resolved Hide resolved
| CalendarEvent
| TimelineCalendarEvent;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from '@emotion/styled';

import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale';

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

export const EmailThreadFetchMoreLoader = ({
export const FetchMoreLoader = ({
loading,
onLastRowVisible,
}: EmailThreadFetchMoreLoaderProps) => {
}: FetchMoreLoaderProps) => {
const { ref: tbodyRef } = useInView({
onChange: onLastRowVisible,
});
Expand Down
Loading
Loading