Skip to content

Commit

Permalink
feat: rename comment thread into activity (twentyhq#939)
Browse files Browse the repository at this point in the history
* feat: rename commentThread into activity server

* feat: rename commentThread into activity front

* feat: migration only create tables

feat: migration only create tables

* Update activities

* fix: rebase partial fix

* fix: all rebase problems and drop activity target alter

* fix: lint

* Update migration

* Update migration

* Fix conflicts

* Fix conflicts

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
  • Loading branch information
2 people authored and AdityaPimpalkar committed Aug 4, 2023
1 parent cc89232 commit a06c297
Show file tree
Hide file tree
Showing 95 changed files with 2,101 additions and 1,704 deletions.
1,089 changes: 615 additions & 474 deletions front/src/generated/graphql.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';

import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';

import { CommentThreadActionBar } from '../../right-drawer/components/CommentThreadActionBar';
import { ActivityActionBar } from '../../right-drawer/components/ActivityActionBar';
import { Comment } from '../Comment';

import { mockComment, mockCommentWithLongValues } from './mock-comment';
Expand All @@ -15,7 +15,7 @@ const meta: Meta<typeof Comment> = {
actionBar: {
type: 'boolean',
mapping: {
true: <CommentThreadActionBar commentThreadId="test-id" />,
true: <ActivityActionBar activityId="test-id" />,
false: undefined,
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Meta, StoryObj } from '@storybook/react';
import { DateTime } from 'luxon';

import { CommentThreadActionBar } from '@/activities/right-drawer/components/CommentThreadActionBar';
import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { avatarUrl } from '~/testing/mock-data/users';

Expand All @@ -17,7 +17,7 @@ const meta: Meta<typeof CommentHeader> = {
actionBar: {
type: 'boolean',
mapping: {
true: <CommentThreadActionBar commentThreadId="test-id" />,
true: <ActivityActionBar activityId="test-id" />,
false: undefined,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,21 @@ import styled from '@emotion/styled';
import debounce from 'lodash.debounce';

import { BlockEditor } from '@/ui/editor/components/BlockEditor';
import {
CommentThread,
useUpdateCommentThreadMutation,
} from '~/generated/graphql';
import { Activity, useUpdateActivityMutation } from '~/generated/graphql';

import { GET_COMMENT_THREADS_BY_TARGETS } from '../queries/select';
import { GET_ACTIVITIES_BY_TARGETS } from '../queries/select';

const BlockNoteStyledContainer = styled.div`
width: 100%;
`;

type OwnProps = {
commentThread: Pick<CommentThread, 'id' | 'body'>;
onChange?: (commentThreadBody: string) => void;
activity: Pick<Activity, 'id' | 'body'>;
onChange?: (activityBody: string) => void;
};

export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) {
const [updateCommentThreadMutation] = useUpdateCommentThreadMutation();
export function ActivityBodyEditor({ activity, onChange }: OwnProps) {
const [updateActivityMutation] = useUpdateActivityMutation();

const [body, setBody] = useState<string | null>(null);

Expand All @@ -34,26 +31,22 @@ export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) {
}, [body, onChange]);

const debounceOnChange = useMemo(() => {
function onInternalChange(commentThreadBody: string) {
setBody(commentThreadBody);
updateCommentThreadMutation({
function onInternalChange(activityBody: string) {
setBody(activityBody);
updateActivityMutation({
variables: {
id: commentThread.id,
body: commentThreadBody,
id: activity.id,
body: activityBody,
},
refetchQueries: [
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
],
refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''],
});
}

return debounce(onInternalChange, 200);
}, [commentThread, updateCommentThreadMutation, setBody]);
}, [activity, updateActivityMutation, setBody]);

const editor: BlockNoteEditor | null = useBlockNote({
initialContent: commentThread.body
? JSON.parse(commentThread.body)
: undefined,
initialContent: activity.body ? JSON.parse(activity.body) : undefined,
editorDOMAttributes: { class: 'editor' },
onEditorContentChange: (editor) => {
debounceOnChange(JSON.stringify(editor.topLevelBlocks) ?? '');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { v4 } from 'uuid';
import { currentUserState } from '@/auth/states/currentUserState';
import { useIsMobile } from '@/ui/hooks/useIsMobile';
import { AutosizeTextInput } from '@/ui/input/components/AutosizeTextInput';
import { CommentThread, useCreateCommentMutation } from '~/generated/graphql';
import { Activity, useCreateCommentMutation } from '~/generated/graphql';
import { isNonEmptyString } from '~/utils/isNonEmptyString';

import { Comment } from '../comment/Comment';
import { GET_COMMENT_THREAD } from '../queries';
import { GET_ACTIVITY } from '../queries';
import { CommentForDrawer } from '../types/CommentForDrawer';

type OwnProps = {
commentThread: Pick<CommentThread, 'id'> & {
activity: Pick<Activity, 'id'> & {
comments: Array<CommentForDrawer>;
};
};
Expand Down Expand Up @@ -52,7 +52,7 @@ const StyledThreadCommentTitle = styled.div`
text-transform: uppercase;
`;

export function CommentThreadComments({ commentThread }: OwnProps) {
export function ActivityComments({ activity }: OwnProps) {
const [createCommentMutation] = useCreateCommentMutation();
const currentUser = useRecoilValue(currentUserState);

Expand All @@ -69,21 +69,21 @@ export function CommentThreadComments({ commentThread }: OwnProps) {
variables: {
commentId: v4(),
authorId: currentUser?.id ?? '',
commentThreadId: commentThread?.id ?? '',
activityId: activity?.id ?? '',
commentText: commentText,
createdAt: new Date().toISOString(),
},
refetchQueries: [getOperationName(GET_COMMENT_THREAD) ?? ''],
refetchQueries: [getOperationName(GET_ACTIVITY) ?? ''],
});
}

return (
<>
{commentThread?.comments.length > 0 && (
{activity?.comments.length > 0 && (
<>
<StyledThreadItemListContainer>
<StyledThreadCommentTitle>Comments</StyledThreadCommentTitle>
{commentThread?.comments?.map((comment) => (
{activity?.comments?.map((comment) => (
<Comment key={comment.id} comment={comment} />
))}
</StyledThreadItemListContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import { Button, ButtonVariant } from '@/ui/button/components/Button';
import { ButtonGroup } from '@/ui/button/components/ButtonGroup';
import { IconCheckbox, IconNotes, IconTimelineEvent } from '@/ui/icon/index';

type CommentThreadCreateButtonProps = {
type ActivityCreateButtonProps = {
onNoteClick?: () => void;
onTaskClick?: () => void;
onActivityClick?: () => void;
};

export function CommentThreadCreateButton({
export function ActivityCreateButton({
onNoteClick,
onTaskClick,
onActivityClick,
}: CommentThreadCreateButtonProps) {
}: ActivityCreateButtonProps) {
const theme = useTheme();
return (
<ButtonGroup variant={ButtonVariant.Secondary}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ import React, { useCallback, useState } from 'react';
import { getOperationName } from '@apollo/client/utilities';
import styled from '@emotion/styled';

import { CommentThreadBodyEditor } from '@/activities/components/CommentThreadBodyEditor';
import { CommentThreadComments } from '@/activities/components/CommentThreadComments';
import { CommentThreadRelationPicker } from '@/activities/components/CommentThreadRelationPicker';
import { CommentThreadTypeDropdown } from '@/activities/components/CommentThreadTypeDropdown';
import { GET_COMMENT_THREADS_BY_TARGETS } from '@/activities/queries';
import { ActivityBodyEditor } from '@/activities/components/ActivityBodyEditor';
import { ActivityComments } from '@/activities/components/ActivityComments';
import { ActivityRelationPicker } from '@/activities/components/ActivityRelationPicker';
import { ActivityTypeDropdown } from '@/activities/components/ActivityTypeDropdown';
import { GET_ACTIVITIES_BY_TARGETS } from '@/activities/queries';
import { PropertyBox } from '@/ui/editable-field/property-box/components/PropertyBox';
import { PropertyBoxItem } from '@/ui/editable-field/property-box/components/PropertyBoxItem';
import { useIsMobile } from '@/ui/hooks/useIsMobile';
import { IconArrowUpRight } from '@/ui/icon/index';
import {
CommentThread,
CommentThreadTarget,
useUpdateCommentThreadMutation,
Activity,
ActivityTarget,
useUpdateActivityMutation,
} from '~/generated/graphql';
import { debounce } from '~/utils/debounce';

import { CommentThreadActionBar } from '../right-drawer/components/CommentThreadActionBar';
import { ActivityActionBar } from '../right-drawer/components/ActivityActionBar';
import { CommentForDrawer } from '../types/CommentForDrawer';

import { CommentThreadTitle } from './CommentThreadTitle';
import { ActivityTitle } from './ActivityTitle';

import '@blocknote/core/style.css';

Expand Down Expand Up @@ -65,64 +65,57 @@ const StyledTopActionsContainer = styled.div`
`;

type OwnProps = {
commentThread: Pick<
CommentThread,
'id' | 'title' | 'body' | 'type' | 'completedAt'
> & {
activity: Pick<Activity, 'id' | 'title' | 'body' | 'type' | 'completedAt'> & {
comments?: Array<CommentForDrawer> | null;
} & {
commentThreadTargets?: Array<
Pick<CommentThreadTarget, 'id' | 'commentableId' | 'commentableType'>
activityTargets?: Array<
Pick<ActivityTarget, 'id' | 'commentableId' | 'commentableType'>
> | null;
};
showComment?: boolean;
autoFillTitle?: boolean;
};

export function CommentThreadEditor({
commentThread,
export function ActivityEditor({
activity,
showComment = true,
autoFillTitle = false,
}: OwnProps) {
const [hasUserManuallySetTitle, setHasUserManuallySetTitle] =
useState<boolean>(false);

const [title, setTitle] = useState<string | null>(commentThread.title ?? '');
const [title, setTitle] = useState<string | null>(activity.title ?? '');
const [completedAt, setCompletedAt] = useState<string | null>(
commentThread.completedAt ?? '',
activity.completedAt ?? '',
);

const [updateCommentThreadMutation] = useUpdateCommentThreadMutation();
const [updateActivityMutation] = useUpdateActivityMutation();

const updateTitle = useCallback(
(newTitle: string) => {
updateCommentThreadMutation({
updateActivityMutation({
variables: {
id: commentThread.id,
id: activity.id,
title: newTitle ?? '',
},
refetchQueries: [
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
],
refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''],
});
},
[commentThread, updateCommentThreadMutation],
[activity, updateActivityMutation],
);

const handleActivityCompletionChange = useCallback(
(value: boolean) => {
updateCommentThreadMutation({
updateActivityMutation({
variables: {
id: commentThread.id,
id: activity.id,
completedAt: value ? new Date().toISOString() : null,
},
refetchQueries: [
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
],
refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''],
});
setCompletedAt(value ? new Date().toISOString() : null);
},
[commentThread, updateCommentThreadMutation],
[activity, updateActivityMutation],
);

const debouncedUpdateTitle = debounce(updateTitle, 200);
Expand All @@ -135,7 +128,7 @@ export function CommentThreadEditor({
}
}

if (!commentThread) {
if (!activity) {
return <></>;
}

Expand All @@ -144,13 +137,13 @@ export function CommentThreadEditor({
<StyledUpperPartContainer>
<StyledTopContainer>
<StyledTopActionsContainer>
<CommentThreadTypeDropdown commentThread={commentThread} />
<CommentThreadActionBar commentThreadId={commentThread?.id ?? ''} />
<ActivityTypeDropdown activity={activity} />
<ActivityActionBar activityId={activity?.id ?? ''} />
</StyledTopActionsContainer>
<CommentThreadTitle
<ActivityTitle
title={title ?? ''}
completed={!!completedAt}
type={commentThread.type}
type={activity.type}
onTitleChange={(newTitle) => {
setTitle(newTitle);
setHasUserManuallySetTitle(true);
Expand All @@ -162,28 +155,27 @@ export function CommentThreadEditor({
<PropertyBoxItem
icon={<IconArrowUpRight />}
value={
<CommentThreadRelationPicker
commentThread={{
id: commentThread.id,
commentThreadTargets:
commentThread.commentThreadTargets ?? [],
<ActivityRelationPicker
activity={{
id: activity.id,
activityTargets: activity.activityTargets ?? [],
}}
/>
}
label="Relations"
/>
</PropertyBox>
</StyledTopContainer>
<CommentThreadBodyEditor
commentThread={commentThread}
<ActivityBodyEditor
activity={activity}
onChange={updateTitleFromBody}
/>
</StyledUpperPartContainer>
{showComment && (
<CommentThreadComments
commentThread={{
id: commentThread.id,
comments: commentThread.comments ?? [],
<ActivityComments
activity={{
id: activity.id,
comments: activity.comments ?? [],
}}
/>
)}
Expand Down
Loading

0 comments on commit a06c297

Please sign in to comment.