RICH_TEXT_V2 frontend (#10083)

Adds task and note support for the new `bodyV2` field. (Field metadata
type of `bodyV2` is `RICH_TEXT_V2`.)

Related to issue https://github.com/twentyhq/twenty/issues/7613

Upgrade commands will be in separate PRs.

Fixes https://github.com/twentyhq/twenty/issues/10084

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
eliasylonen
2025-02-11 11:21:03 +01:00
committed by GitHub
parent de91a5e39e
commit 4f06b83d7f
55 changed files with 545 additions and 4576 deletions

View File

@ -49,6 +49,10 @@ export const ActivityRichTextEditor = ({
const cache = useApolloClient().cache;
const activity = activityInStore as Task | Note | null;
const isRichTextV2Enabled = useIsFeatureEnabled(
FeatureFlagKey.IsRichTextV2Enabled,
);
const isCommandMenuV2Enabled = useIsFeatureEnabled(
FeatureFlagKey.IsCommandMenuV2Enabled,
);
@ -67,13 +71,20 @@ export const ActivityRichTextEditor = ({
activityObjectNameSingular: activityObjectNameSingular,
});
const persistBodyDebounced = useDebouncedCallback((newBody: string) => {
const persistBodyDebounced = useDebouncedCallback((blocknote: string) => {
const input = isRichTextV2Enabled
? {
bodyV2: {
blocknote,
markdown: null,
},
}
: { body: blocknote };
if (isDefined(activity)) {
upsertActivity({
activity,
input: {
body: newBody,
},
input,
});
}
}, 300);
@ -163,14 +174,18 @@ export const ActivityRichTextEditor = ({
};
const initialBody = useMemo(() => {
const blocknote = isRichTextV2Enabled
? activity?.bodyV2?.blocknote
: activity?.body;
if (
isDefined(activity) &&
isNonEmptyString(activity.body) &&
activity?.body !== '{}'
isNonEmptyString(blocknote) &&
blocknote !== '{}'
) {
return JSON.parse(activity.body);
return JSON.parse(blocknote);
}
}, [activity]);
}, [activity, isRichTextV2Enabled]);
const handleEditorBuiltInUploadFile = async (file: File) => {
const { attachmentAbsoluteURL } = await handleUploadAttachment(file);

View File

@ -94,7 +94,11 @@ const task = {
createdAt: '2023-04-26T10:12:42.33625+00:00',
updatedAt: '2023-04-26T10:23:42.33625+00:00',
title: 'Task title',
body: null,
body: '',
bodyV2: {
blocknote: null,
markdown: null,
},
assigneeId: null,
status: null,
dueAt: '2023-04-26T10:12:42.33625+00:00',

View File

@ -6,6 +6,8 @@ import { Note } from '@/activities/types/Note';
import { getActivityPreview } from '@/activities/utils/getActivityPreview';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
const StyledCard = styled.div<{ isSingleNote: boolean }>`
align-items: flex-start;
@ -71,7 +73,12 @@ export const NoteCard = ({
const openActivityRightDrawer = useOpenActivityRightDrawer({
objectNameSingular: CoreObjectNameSingular.Note,
});
const body = getActivityPreview(note.body);
const isRichTextV2Enabled = useIsFeatureEnabled(
FeatureFlagKey.IsRichTextV2Enabled,
);
const body = getActivityPreview(
isRichTextV2Enabled ? (note?.bodyV2?.blocknote ?? null) : note?.body,
);
const { FieldContextProvider: NoteTargetsContextProvider } = useFieldContext({
objectNameSingular: CoreObjectNameSingular.Note,

View File

@ -16,6 +16,8 @@ import { ActivityRow } from '@/activities/components/ActivityRow';
import { Task } from '@/activities/types/Task';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
import { useCompleteTask } from '../hooks/useCompleteTask';
const StyledTaskBody = styled.div`
@ -82,7 +84,14 @@ export const TaskRow = ({ task }: { task: Task }) => {
objectNameSingular: CoreObjectNameSingular.Task,
});
const body = getActivitySummary(task.body);
const isRichTextV2Enabled = useIsFeatureEnabled(
FeatureFlagKey.IsRichTextV2Enabled,
);
const body = getActivitySummary(
isRichTextV2Enabled ? (task?.bodyV2?.blocknote ?? null) : task?.body,
);
const { completeTask } = useCompleteTask(task);
const { FieldContextProvider: TaskTargetsContextProvider } = useFieldContext({

View File

@ -11,6 +11,10 @@ const task: Task = {
status: 'DONE',
title: 'Test',
body: 'Test',
bodyV2: {
blocknote: 'Test',
markdown: 'Test',
},
dueAt: '2024-03-15T07:33:14.212Z',
createdAt: '2024-03-15T07:33:14.212Z',
updatedAt: '2024-03-15T07:33:14.212Z',

View File

@ -4,4 +4,8 @@ export type Activity = {
updatedAt: string;
title: string;
body: string | null;
bodyV2?: {
blocknote: string | null;
markdown: string | null;
};
};