mirror of
https://github.com/suitenumerique/docs.git
synced 2026-04-25 17:15:01 +02:00
🐛(frontend) Fixed side effects between comments and versionning
We fixed 2 side effects between comments and versionning: - When going from a version, it was not possible to add a comment anymore. This was due to the fact that the versionning was resetting the comment store. - When restoring a version, we now reset the comment store to avoid having comments that are not relevant anymore.
This commit is contained in:
@@ -15,6 +15,10 @@ and this project adheres to
|
|||||||
|
|
||||||
- 🐛(frontend) Fix drop cursor creating columns #2185
|
- 🐛(frontend) Fix drop cursor creating columns #2185
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- 🐛 Fixed side effects between comments and versioning #2183
|
||||||
|
|
||||||
## [v4.8.5] - 2026-04-03
|
## [v4.8.5] - 2026-04-03
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -133,14 +133,20 @@ test.describe('Doc Version', () => {
|
|||||||
const [randomDoc] = await createDoc(page, 'doc-version', browserName, 1);
|
const [randomDoc] = await createDoc(page, 'doc-version', browserName, 1);
|
||||||
await verifyDocName(page, randomDoc);
|
await verifyDocName(page, randomDoc);
|
||||||
|
|
||||||
await page.locator('.bn-block-outer').last().click();
|
const editor = await writeInEditor({ page, text: 'Hello' });
|
||||||
await page.locator('.bn-block-outer').last().fill('Hello');
|
|
||||||
|
// Add a comment
|
||||||
|
await editor.getByText('Hello').selectText();
|
||||||
|
await page.getByRole('button', { name: 'Add comment' }).click();
|
||||||
|
|
||||||
|
const thread = page.locator('.bn-thread');
|
||||||
|
await thread.getByRole('paragraph').first().fill('This is a comment');
|
||||||
|
await thread.locator('[data-test="save"]').click();
|
||||||
|
|
||||||
await goToGridDoc(page, {
|
await goToGridDoc(page, {
|
||||||
title: randomDoc,
|
title: randomDoc,
|
||||||
});
|
});
|
||||||
|
|
||||||
const editor = page.locator('.ProseMirror');
|
|
||||||
await expect(editor.getByText('Hello')).toBeVisible();
|
await expect(editor.getByText('Hello')).toBeVisible();
|
||||||
await page.locator('.bn-block-outer').last().click();
|
await page.locator('.bn-block-outer').last().click();
|
||||||
await page.keyboard.press('Enter');
|
await page.keyboard.press('Enter');
|
||||||
@@ -152,6 +158,11 @@ test.describe('Doc Version', () => {
|
|||||||
|
|
||||||
await expect(page.getByText('World')).toBeVisible();
|
await expect(page.getByText('World')).toBeVisible();
|
||||||
|
|
||||||
|
await editor.getByText('Hello').click();
|
||||||
|
await thread.getByText('This is a comment').first().hover();
|
||||||
|
await thread.locator('[data-test="resolve"]').click();
|
||||||
|
await expect(thread).toBeHidden();
|
||||||
|
|
||||||
await page.getByLabel('Open the document options').click();
|
await page.getByLabel('Open the document options').click();
|
||||||
await page.getByRole('menuitem', { name: 'Version history' }).click();
|
await page.getByRole('menuitem', { name: 'Version history' }).click();
|
||||||
|
|
||||||
@@ -175,7 +186,21 @@ test.describe('Doc Version', () => {
|
|||||||
|
|
||||||
await page.waitForTimeout(500);
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
await expect(page.getByText('Hello')).toBeVisible();
|
await expect(editor.getByText('Hello')).toBeVisible();
|
||||||
await expect(page.getByText('World')).toBeHidden();
|
await expect(editor.getByText('World')).toBeHidden();
|
||||||
|
|
||||||
|
// The old comment is not restored
|
||||||
|
await expect(editor.getByText('Hello')).toHaveCSS(
|
||||||
|
'background-color',
|
||||||
|
'rgba(0, 0, 0, 0)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// We can add a new comment
|
||||||
|
await editor.getByText('Hello').selectText();
|
||||||
|
await page.getByRole('button', { name: 'Add comment' }).click();
|
||||||
|
|
||||||
|
await thread.getByRole('paragraph').first().fill('This is a comment');
|
||||||
|
await thread.locator('[data-test="save"]').click();
|
||||||
|
await expect(editor.getByText('Hello')).toHaveClass('bn-thread-mark');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -303,11 +303,13 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
|
|||||||
interface BlockNoteReaderProps {
|
interface BlockNoteReaderProps {
|
||||||
docId: Doc['id'];
|
docId: Doc['id'];
|
||||||
initialContent: Y.XmlFragment;
|
initialContent: Y.XmlFragment;
|
||||||
|
isMainEditor?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BlockNoteReader = ({
|
export const BlockNoteReader = ({
|
||||||
docId,
|
docId,
|
||||||
initialContent,
|
initialContent,
|
||||||
|
isMainEditor = true,
|
||||||
}: BlockNoteReaderProps) => {
|
}: BlockNoteReaderProps) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { setEditor } = useEditorStore();
|
const { setEditor } = useEditorStore();
|
||||||
@@ -336,12 +338,19 @@ export const BlockNoteReader = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!isMainEditor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setEditor(editor);
|
setEditor(editor);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
if (!isMainEditor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setEditor(undefined);
|
setEditor(undefined);
|
||||||
};
|
};
|
||||||
}, [setEditor, editor]);
|
}, [setEditor, editor, isMainEditor]);
|
||||||
|
|
||||||
useHeadings(editor);
|
useHeadings(editor);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
|
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { User, avatarUrlFromName } from '@/features/auth';
|
import { User, avatarUrlFromName } from '@/features/auth';
|
||||||
|
import { useEditorStore } from '@/features/docs/doc-editor/stores';
|
||||||
import { Doc, useProviderStore } from '@/features/docs/doc-management';
|
import { Doc, useProviderStore } from '@/features/docs/doc-management';
|
||||||
|
|
||||||
import { DocsThreadStore } from './DocsThreadStore';
|
import { DocsThreadStore } from './DocsThreadStore';
|
||||||
@@ -16,6 +17,7 @@ export function useComments(
|
|||||||
const { provider } = useProviderStore();
|
const { provider } = useProviderStore();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { themeTokens } = useCunninghamTheme();
|
const { themeTokens } = useCunninghamTheme();
|
||||||
|
const { setThreadStore } = useEditorStore();
|
||||||
|
|
||||||
const threadStore = useMemo(() => {
|
const threadStore = useMemo(() => {
|
||||||
return new DocsThreadStore(
|
return new DocsThreadStore(
|
||||||
@@ -28,6 +30,18 @@ export function useComments(
|
|||||||
);
|
);
|
||||||
}, [docId, canComment, provider?.awareness, user?.full_name]);
|
}, [docId, canComment, provider?.awareness, user?.full_name]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (canComment) {
|
||||||
|
setThreadStore(threadStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (canComment) {
|
||||||
|
setThreadStore(undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [threadStore, setThreadStore, canComment]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
threadStore?.destroy();
|
threadStore?.destroy();
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
import type { DocsThreadStore } from '../components/comments/DocsThreadStore';
|
||||||
import { DocsBlockNoteEditor } from '../types';
|
import { DocsBlockNoteEditor } from '../types';
|
||||||
|
|
||||||
export interface UseEditorstore {
|
export interface UseEditorstore {
|
||||||
editor?: DocsBlockNoteEditor;
|
editor?: DocsBlockNoteEditor;
|
||||||
|
threadStore?: DocsThreadStore;
|
||||||
setEditor: (editor: DocsBlockNoteEditor | undefined) => void;
|
setEditor: (editor: DocsBlockNoteEditor | undefined) => void;
|
||||||
|
setThreadStore: (threadStore: DocsThreadStore | undefined) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useEditorStore = create<UseEditorstore>((set) => ({
|
export const useEditorStore = create<UseEditorstore>((set) => ({
|
||||||
editor: undefined,
|
editor: undefined,
|
||||||
|
threadStore: undefined,
|
||||||
setEditor: (editor) => {
|
setEditor: (editor) => {
|
||||||
set({ editor });
|
set({ editor });
|
||||||
},
|
},
|
||||||
|
setThreadStore: (threadStore) => {
|
||||||
|
set({ threadStore });
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -86,7 +86,11 @@ export const DocVersionEditor = ({
|
|||||||
<DocEditorContainer
|
<DocEditorContainer
|
||||||
docHeader={<DocVersionHeader />}
|
docHeader={<DocVersionHeader />}
|
||||||
docEditor={
|
docEditor={
|
||||||
<BlockNoteReader initialContent={initialContent} docId={version.id} />
|
<BlockNoteReader
|
||||||
|
initialContent={initialContent}
|
||||||
|
docId={version.id}
|
||||||
|
isMainEditor={false}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
isDeletedDoc={false}
|
isDeletedDoc={false}
|
||||||
readOnly={true}
|
readOnly={true}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { createGlobalStyle } from 'styled-components';
|
import { createGlobalStyle } from 'styled-components';
|
||||||
|
|
||||||
import { Box, Text } from '@/components';
|
import { Box, Text } from '@/components';
|
||||||
|
import { useEditorStore } from '@/docs/doc-editor/stores';
|
||||||
import {
|
import {
|
||||||
Doc,
|
Doc,
|
||||||
base64ToYDoc,
|
base64ToYDoc,
|
||||||
@@ -47,6 +48,7 @@ export const ModalConfirmationVersion = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { toast } = useToastProvider();
|
const { toast } = useToastProvider();
|
||||||
const { provider } = useProviderStore();
|
const { provider } = useProviderStore();
|
||||||
|
const { threadStore } = useEditorStore();
|
||||||
const { mutate: updateDoc } = useUpdateDoc({
|
const { mutate: updateDoc } = useUpdateDoc({
|
||||||
listInvalidQueries: [KEY_LIST_DOC_VERSIONS],
|
listInvalidQueries: [KEY_LIST_DOC_VERSIONS],
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@@ -66,6 +68,8 @@ export const ModalConfirmationVersion = ({
|
|||||||
base64ToYDoc(version.content),
|
base64ToYDoc(version.content),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
threadStore?.refreshThreads();
|
||||||
|
|
||||||
onDisplaySuccess();
|
onDisplaySuccess();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user