mirror of
https://github.com/lingble/twenty.git
synced 2025-11-02 05:37:56 +00:00
feat: add creation date to notes panel (#5432)
## Description Adds a view for creation date and author to notes and tasks panel. Here is a preview of the new `ActivityCreationDate` component:  Closes #5424 ### Type of change <!-- Please delete options that are not relevant. --> - [x] New feature (non-breaking change which adds functionality) ## Checklist - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { Activity } from '@/activities/types/Activity';
|
||||||
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
|
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
|
||||||
|
|
||||||
|
const StyledCreationDisplay = styled.span`
|
||||||
|
color: ${({ theme }) => theme.font.color.light};
|
||||||
|
display: flex;
|
||||||
|
font-size: ${({ theme }) => theme.font.size.md};
|
||||||
|
user-select: none;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
type ActivityCreationDateProps = {
|
||||||
|
activityId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ActivityCreationDate = ({
|
||||||
|
activityId,
|
||||||
|
}: ActivityCreationDateProps) => {
|
||||||
|
const [activityInStore] = useRecoilState(recordStoreFamilyState(activityId));
|
||||||
|
const activity = activityInStore as Activity;
|
||||||
|
|
||||||
|
const beautifiedDate = activity.createdAt
|
||||||
|
? beautifyPastDateRelativeToNow(activity.createdAt)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const authorName = activity.author?.name
|
||||||
|
? `${activity.author.name.firstName} ${activity.author.name.lastName}`
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (!activity.createdAt || !authorName) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledCreationDisplay>
|
||||||
|
Created {beautifiedDate} by {authorName}
|
||||||
|
</StyledCreationDisplay>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -4,6 +4,7 @@ import styled from '@emotion/styled';
|
|||||||
import { ActivityBodyEditor } from '@/activities/components/ActivityBodyEditor';
|
import { ActivityBodyEditor } from '@/activities/components/ActivityBodyEditor';
|
||||||
import { ActivityBodyEffect } from '@/activities/components/ActivityBodyEffect';
|
import { ActivityBodyEffect } from '@/activities/components/ActivityBodyEffect';
|
||||||
import { ActivityComments } from '@/activities/components/ActivityComments';
|
import { ActivityComments } from '@/activities/components/ActivityComments';
|
||||||
|
import { ActivityCreationDate } from '@/activities/components/ActivityCreationDate';
|
||||||
import { ActivityEditorFields } from '@/activities/components/ActivityEditorFields';
|
import { ActivityEditorFields } from '@/activities/components/ActivityEditorFields';
|
||||||
import { ActivityTitleEffect } from '@/activities/components/ActivityTitleEffect';
|
import { ActivityTitleEffect } from '@/activities/components/ActivityTitleEffect';
|
||||||
import { ActivityTypeDropdown } from '@/activities/components/ActivityTypeDropdown';
|
import { ActivityTypeDropdown } from '@/activities/components/ActivityTypeDropdown';
|
||||||
@@ -31,6 +32,13 @@ const StyledUpperPartContainer = styled.div`
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledTitleContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
gap: ${({ theme }) => theme.spacing(3)};
|
||||||
|
`;
|
||||||
|
|
||||||
const StyledTopContainer = styled.div`
|
const StyledTopContainer = styled.div`
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
@@ -62,7 +70,10 @@ export const ActivityEditor = ({
|
|||||||
<StyledTopContainer>
|
<StyledTopContainer>
|
||||||
<ActivityTypeDropdown activityId={activityId} />
|
<ActivityTypeDropdown activityId={activityId} />
|
||||||
<ActivityTitleEffect activityId={activityId} />
|
<ActivityTitleEffect activityId={activityId} />
|
||||||
<ActivityTitle activityId={activityId} />
|
<StyledTitleContainer>
|
||||||
|
<ActivityTitle activityId={activityId} />
|
||||||
|
<ActivityCreationDate activityId={activityId} />
|
||||||
|
</StyledTitleContainer>
|
||||||
<ActivityEditorFields activityId={activityId} />
|
<ActivityEditorFields activityId={activityId} />
|
||||||
</StyledTopContainer>
|
</StyledTopContainer>
|
||||||
</StyledUpperPartContainer>
|
</StyledUpperPartContainer>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type RightDrawerActivityProps = {
|
|||||||
|
|
||||||
export const RightDrawerActivity = ({
|
export const RightDrawerActivity = ({
|
||||||
activityId,
|
activityId,
|
||||||
showComment = true,
|
showComment = false,
|
||||||
fillTitleFromBody = false,
|
fillTitleFromBody = false,
|
||||||
}: RightDrawerActivityProps) => {
|
}: RightDrawerActivityProps) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { IconCheckbox, IconInbox, IconSearch, IconSettings } from 'twenty-ui';
|
import { IconCheckbox, IconSearch, IconSettings } from 'twenty-ui';
|
||||||
|
|
||||||
import { CurrentUserDueTaskCountEffect } from '@/activities/tasks/components/CurrentUserDueTaskCountEffect';
|
import { CurrentUserDueTaskCountEffect } from '@/activities/tasks/components/CurrentUserDueTaskCountEffect';
|
||||||
import { currentUserDueTaskCountState } from '@/activities/tasks/states/currentUserTaskCountState';
|
import { currentUserDueTaskCountState } from '@/activities/tasks/states/currentUserTaskCountState';
|
||||||
@@ -36,12 +36,6 @@ export const MainNavigationDrawerItems = () => {
|
|||||||
onClick={toggleCommandMenu}
|
onClick={toggleCommandMenu}
|
||||||
keyboard={['⌘', 'K']}
|
keyboard={['⌘', 'K']}
|
||||||
/>
|
/>
|
||||||
<NavigationDrawerItem
|
|
||||||
label="Inbox"
|
|
||||||
to="/inbox"
|
|
||||||
Icon={IconInbox}
|
|
||||||
soon
|
|
||||||
/>
|
|
||||||
<NavigationDrawerItem
|
<NavigationDrawerItem
|
||||||
label="Settings"
|
label="Settings"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -30,6 +30,16 @@ const StyledEditor = styled.div`
|
|||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
font-style: normal !important;
|
font-style: normal !important;
|
||||||
}
|
}
|
||||||
|
& .editor .bn-inline-content:has(> .ProseMirror-trailingBreak):before {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
& .mantine-ActionIcon-icon {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
& .bn-container .bn-drag-handle {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const BlockEditor = ({
|
export const BlockEditor = ({
|
||||||
|
|||||||
Reference in New Issue
Block a user