mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 03:51:36 +03:00
Replace block editor on page change
This commit is contained in:
parent
8bb699cbc2
commit
3c0c1722ff
@ -1,14 +1,13 @@
|
|||||||
import { useApolloClient } from '@apollo/client';
|
import { useApolloClient } from '@apollo/client';
|
||||||
import { useCreateBlockNote } from '@blocknote/react';
|
import { useCreateBlockNote } from '@blocknote/react';
|
||||||
import { isArray, isNonEmptyString } from '@sniptt/guards';
|
import { isArray, isNonEmptyString } from '@sniptt/guards';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
import { useRecoilCallback, useRecoilState } from 'recoil';
|
import { useRecoilCallback, useRecoilState } from 'recoil';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
import { useDebouncedCallback } from 'use-debounce';
|
import { useDebouncedCallback } from 'use-debounce';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
|
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
|
||||||
import { activityBodyFamilyState } from '@/activities/states/activityBodyFamilyState';
|
|
||||||
import { activityTitleHasBeenSetFamilyState } from '@/activities/states/activityTitleHasBeenSetFamilyState';
|
import { activityTitleHasBeenSetFamilyState } from '@/activities/states/activityTitleHasBeenSetFamilyState';
|
||||||
import { canCreateActivityState } from '@/activities/states/canCreateActivityState';
|
import { canCreateActivityState } from '@/activities/states/canCreateActivityState';
|
||||||
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
||||||
@ -27,6 +26,7 @@ import { useUploadAttachmentFile } from '@/activities/files/hooks/useUploadAttac
|
|||||||
import { Note } from '@/activities/types/Note';
|
import { Note } from '@/activities/types/Note';
|
||||||
import { Task } from '@/activities/types/Task';
|
import { Task } from '@/activities/types/Task';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
|
import { useReplaceBlockEditorContent } from '@/ui/input/hooks/useReplaceBlockEditorContent';
|
||||||
import '@blocknote/core/fonts/inter.css';
|
import '@blocknote/core/fonts/inter.css';
|
||||||
import '@blocknote/mantine/style.css';
|
import '@blocknote/mantine/style.css';
|
||||||
import '@blocknote/react/style.css';
|
import '@blocknote/react/style.css';
|
||||||
@ -55,12 +55,6 @@ export const RichTextEditor = ({
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [activityBody, setActivityBody] = useRecoilState(
|
|
||||||
activityBodyFamilyState({
|
|
||||||
activityId: activityId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const { objectMetadataItem: objectMetadataItemActivity } =
|
const { objectMetadataItem: objectMetadataItemActivity } =
|
||||||
useObjectMetadataItem({
|
useObjectMetadataItem({
|
||||||
objectNameSingular: activityObjectNameSingular,
|
objectNameSingular: activityObjectNameSingular,
|
||||||
@ -241,24 +235,14 @@ export const RichTextEditor = ({
|
|||||||
|
|
||||||
const handleBodyChangeDebounced = useDebouncedCallback(handleBodyChange, 500);
|
const handleBodyChangeDebounced = useDebouncedCallback(handleBodyChange, 500);
|
||||||
|
|
||||||
// See https://github.com/twentyhq/twenty/issues/6724 for explanation
|
|
||||||
const setActivityBodyDebouncedToAvoidDragBug = useDebouncedCallback(
|
|
||||||
setActivityBody,
|
|
||||||
100,
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleEditorChange = () => {
|
const handleEditorChange = () => {
|
||||||
const newStringifiedBody = JSON.stringify(editor.document) ?? '';
|
const newStringifiedBody = JSON.stringify(editor.document) ?? '';
|
||||||
|
|
||||||
setActivityBodyDebouncedToAvoidDragBug(newStringifiedBody);
|
|
||||||
|
|
||||||
handleBodyChangeDebounced(newStringifiedBody);
|
handleBodyChangeDebounced(newStringifiedBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialBody = useMemo(() => {
|
const initialBody = useMemo(() => {
|
||||||
if (isNonEmptyString(activityBody) && activityBody !== '{}') {
|
if (
|
||||||
return JSON.parse(activityBody);
|
|
||||||
} else if (
|
|
||||||
isDefined(activity) &&
|
isDefined(activity) &&
|
||||||
isNonEmptyString(activity.body) &&
|
isNonEmptyString(activity.body) &&
|
||||||
activity?.body !== '{}'
|
activity?.body !== '{}'
|
||||||
@ -267,7 +251,7 @@ export const RichTextEditor = ({
|
|||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}, [activity, activityBody]);
|
}, [activity]);
|
||||||
|
|
||||||
const handleEditorBuiltInUploadFile = async (file: File) => {
|
const handleEditorBuiltInUploadFile = async (file: File) => {
|
||||||
const { attachementAbsoluteURL } = await handleUploadAttachment(file);
|
const { attachementAbsoluteURL } = await handleUploadAttachment(file);
|
||||||
@ -282,6 +266,15 @@ export const RichTextEditor = ({
|
|||||||
uploadFile: handleEditorBuiltInUploadFile,
|
uploadFile: handleEditorBuiltInUploadFile,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { replaceBlockEditorContent } = useReplaceBlockEditorContent(
|
||||||
|
activityId,
|
||||||
|
editor,
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
replaceBlockEditorContent();
|
||||||
|
}, [replaceBlockEditorContent, activityId, editor]);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
Key.Escape,
|
Key.Escape,
|
||||||
() => {
|
() => {
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
import { isDefined } from 'twenty-ui';
|
||||||
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
|
export const useReplaceBlockEditorContent = (
|
||||||
|
activityId: string,
|
||||||
|
editor: any,
|
||||||
|
) => {
|
||||||
|
const replaceBlockEditorContent = useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
() => {
|
||||||
|
if (isDefined(editor)) {
|
||||||
|
const activityInStore = snapshot
|
||||||
|
.getLoadable(recordStoreFamilyState(activityId))
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
const content = isNonEmptyString(activityInStore?.body)
|
||||||
|
? JSON.parse(activityInStore?.body)
|
||||||
|
: [{ type: 'paragraph', content: '' }];
|
||||||
|
|
||||||
|
console.log(editor.document, content);
|
||||||
|
if (!isDeeplyEqual(editor.document, content)) {
|
||||||
|
console.log('replacing');
|
||||||
|
editor.replaceBlocks(editor.document, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[activityId, editor],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
replaceBlockEditorContent,
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user