Files
twenty/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx
Félix Malfait d145684966 New Timeline (#4936)
Refactored the code to introduce two different concepts:
- AuditLogs (immutable, raw data)
- TimelineActivities (user-friendly, transformed data)

Still some work needed:
- Add message, files, calendar events to timeline (~2 hours if done
naively)
- Refactor repository to try to abstract concept when we can (tbd, wait
for Twenty ORM)
- Introduce ability to display child timelines on parent timeline with
filtering (~2 days)
- Improve UI: add links to open note/task, improve diff display, etc
(half a day)
- Decide the path forward for Task vs Notes: either introduce a new
field type "Record Type" and start going into that direction ; or split
in two objects?
- Trigger updates when a field is changed (will be solved by real-time /
websockets: 2 weeks)
- Integrate behavioral events (1 day for POC, 1 week for
clean/documented)

<img width="1248" alt="Screenshot 2024-04-12 at 09 24 49"
src="https://github.com/twentyhq/twenty/assets/6399865/9428db1a-ab2b-492c-8b0b-d4d9a36e81fa">
2024-04-19 17:52:57 +02:00

153 lines
4.4 KiB
TypeScript

import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import {
IconCalendarEvent,
IconCheckbox,
IconMail,
IconNotes,
IconPaperclip,
IconTimelineEvent,
} from 'twenty-ui';
import { Calendar } from '@/activities/calendar/components/Calendar';
import { EmailThreads } from '@/activities/emails/components/EmailThreads';
import { Attachments } from '@/activities/files/components/Attachments';
import { Notes } from '@/activities/notes/components/Notes';
import { ObjectTasks } from '@/activities/tasks/components/ObjectTasks';
import { Timeline } from '@/activities/timeline/components/Timeline';
import { TimelineQueryEffect } from '@/activities/timeline/components/TimelineQueryEffect';
import { TimelineActivities } from '@/activities/timelineActivities/components/TimelineActivities';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
const StyledShowPageRightContainer = styled.div`
display: flex;
flex: 1 0 0;
flex-direction: column;
justify-content: start;
overflow: ${() => (useIsMobile() ? 'none' : 'hidden')};
width: calc(100% + 4px);
`;
const StyledTabListContainer = styled.div`
align-items: center;
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
box-sizing: border-box;
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
height: 40px;
`;
export const TAB_LIST_COMPONENT_ID = 'show-page-right-tab-list';
type ShowPageRightContainerProps = {
targetableObject: Pick<
ActivityTargetableObject,
'targetObjectNameSingular' | 'id'
>;
timeline?: boolean;
tasks?: boolean;
notes?: boolean;
emails?: boolean;
};
export const ShowPageRightContainer = ({
targetableObject,
timeline,
tasks,
notes,
emails,
}: ShowPageRightContainerProps) => {
const { activeTabIdState } = useTabList(TAB_LIST_COMPONENT_ID);
const activeTabId = useRecoilValue(activeTabIdState);
const shouldDisplayCalendarTab = useIsFeatureEnabled('IS_CALENDAR_ENABLED');
const shouldDisplayLogTab = useIsFeatureEnabled('IS_EVENT_OBJECT_ENABLED');
const shouldDisplayEmailsTab =
(emails &&
targetableObject.targetObjectNameSingular ===
CoreObjectNameSingular.Company) ||
targetableObject.targetObjectNameSingular === CoreObjectNameSingular.Person;
const TASK_TABS = [
{
id: 'timeline',
title: 'Timeline',
Icon: IconTimelineEvent,
hide: !timeline,
},
{
id: 'tasks',
title: 'Tasks',
Icon: IconCheckbox,
hide: !tasks,
},
{
id: 'notes',
title: 'Notes',
Icon: IconNotes,
hide: !notes,
},
{
id: 'files',
title: 'Files',
Icon: IconPaperclip,
hide: !notes,
},
{
id: 'emails',
title: 'Emails',
Icon: IconMail,
hide: !shouldDisplayEmailsTab,
},
{
id: 'calendar',
title: 'Calendar',
Icon: IconCalendarEvent,
hide: !shouldDisplayCalendarTab,
},
{
id: 'logs',
title: 'Logs',
Icon: IconTimelineEvent,
hide: !shouldDisplayLogTab,
hasBetaPill: true,
},
];
return (
<StyledShowPageRightContainer>
<StyledTabListContainer>
<TabList tabListId={TAB_LIST_COMPONENT_ID} tabs={TASK_TABS} />
</StyledTabListContainer>
{activeTabId === 'timeline' && (
<>
<TimelineQueryEffect targetableObject={targetableObject} />
<Timeline targetableObject={targetableObject} />
</>
)}
{activeTabId === 'tasks' && (
<ObjectTasks targetableObject={targetableObject} />
)}
{activeTabId === 'notes' && <Notes targetableObject={targetableObject} />}
{activeTabId === 'files' && (
<Attachments targetableObject={targetableObject} />
)}
{activeTabId === 'emails' && (
<EmailThreads targetableObject={targetableObject} />
)}
{activeTabId === 'calendar' && (
<Calendar targetableObject={targetableObject} />
)}
{activeTabId === 'logs' && (
<TimelineActivities targetableObject={targetableObject} />
)}
</StyledShowPageRightContainer>
);
};