♻️(frontend) stop to use provider with version
Version are not editable, we don't need to activate the collaboration provider for them. Simplify the code by removing the provider from the version.
This commit is contained in:
@@ -6,6 +6,7 @@ import { useCreateBlockNote } from '@blocknote/react';
|
||||
import { HocuspocusProvider } from '@hocuspocus/provider';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { Box, TextErrors } from '@/components';
|
||||
import { useAuthStore } from '@/core/auth';
|
||||
@@ -65,19 +66,14 @@ const cssEditor = (readonly: boolean) => `
|
||||
interface BlockNoteEditorProps {
|
||||
doc: Doc;
|
||||
provider: HocuspocusProvider;
|
||||
storeId: string;
|
||||
}
|
||||
|
||||
export const BlockNoteEditor = ({
|
||||
doc,
|
||||
provider,
|
||||
storeId,
|
||||
}: BlockNoteEditorProps) => {
|
||||
const isVersion = doc.id !== storeId;
|
||||
export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
|
||||
const { userData } = useAuthStore();
|
||||
const { setEditor } = useEditorStore();
|
||||
const { t } = useTranslation();
|
||||
const readOnly = !doc.abilities.partial_update || isVersion;
|
||||
|
||||
const readOnly = !doc.abilities.partial_update;
|
||||
useSaveDoc(doc.id, provider.document, !readOnly);
|
||||
const { setHeadings, resetHeadings } = useHeadingStore();
|
||||
const { i18n } = useTranslation();
|
||||
@@ -174,3 +170,46 @@ export const BlockNoteEditor = ({
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
interface BlockNoteEditorVersionProps {
|
||||
initialContent: Y.XmlFragment;
|
||||
}
|
||||
|
||||
export const BlockNoteEditorVersion = ({
|
||||
initialContent,
|
||||
}: BlockNoteEditorVersionProps) => {
|
||||
const readOnly = true;
|
||||
const { setHeadings, resetHeadings } = useHeadingStore();
|
||||
|
||||
const editor = useCreateBlockNote(
|
||||
{
|
||||
collaboration: {
|
||||
fragment: initialContent,
|
||||
user: {
|
||||
name: '',
|
||||
color: '',
|
||||
},
|
||||
provider: undefined,
|
||||
},
|
||||
},
|
||||
[initialContent],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setHeadings(editor);
|
||||
|
||||
editor?.onEditorContentChange(() => {
|
||||
setHeadings(editor);
|
||||
});
|
||||
|
||||
return () => {
|
||||
resetHeadings();
|
||||
};
|
||||
}, [editor, resetHeadings, setHeadings]);
|
||||
|
||||
return (
|
||||
<Box $css={cssEditor(readOnly)}>
|
||||
<BlockNoteView editor={editor} editable={!readOnly} theme="light" />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
import { Alert, Loader, VariantType } from '@openfun/cunningham-react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { Box, Card, Text, TextErrors } from '@/components';
|
||||
import { useCollaborationUrl } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { DocHeader } from '@/features/docs/doc-header';
|
||||
import { Doc, useDocStore } from '@/features/docs/doc-management';
|
||||
import {
|
||||
Doc,
|
||||
base64ToBlocknoteXmlFragment,
|
||||
useDocStore,
|
||||
} from '@/features/docs/doc-management';
|
||||
import { Versions, useDocVersion } from '@/features/docs/doc-versioning/';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { useHeadingStore } from '../stores';
|
||||
|
||||
import { BlockNoteEditor } from './BlockNoteEditor';
|
||||
import { BlockNoteEditor, BlockNoteEditorVersion } from './BlockNoteEditor';
|
||||
import { IconOpenPanelEditor, PanelEditor } from './PanelEditor';
|
||||
|
||||
interface DocEditorProps {
|
||||
@@ -41,7 +45,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<DocHeader doc={doc} versionId={versionId as Versions['version_id']} />
|
||||
<DocHeader doc={doc} />
|
||||
{!doc.abilities.partial_update && (
|
||||
<Box $margin={{ all: 'small', top: 'none' }}>
|
||||
<Alert type={VariantType.WARNING}>
|
||||
@@ -71,9 +75,9 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
|
||||
$position="relative"
|
||||
>
|
||||
{isVersion ? (
|
||||
<DocVersionEditor doc={doc} versionId={versionId} />
|
||||
<DocVersionEditor docId={doc.id} versionId={versionId} />
|
||||
) : (
|
||||
<BlockNoteEditor doc={doc} storeId={doc.id} provider={provider} />
|
||||
<BlockNoteEditor doc={doc} provider={provider} />
|
||||
)}
|
||||
{!isMobile && <IconOpenPanelEditor headings={headings} />}
|
||||
</Card>
|
||||
@@ -84,35 +88,34 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
|
||||
};
|
||||
|
||||
interface DocVersionEditorProps {
|
||||
doc: Doc;
|
||||
docId: Doc['id'];
|
||||
versionId: Versions['version_id'];
|
||||
}
|
||||
|
||||
export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => {
|
||||
export const DocVersionEditor = ({
|
||||
docId,
|
||||
versionId,
|
||||
}: DocVersionEditorProps) => {
|
||||
const {
|
||||
data: version,
|
||||
isLoading,
|
||||
isError,
|
||||
error,
|
||||
} = useDocVersion({
|
||||
docId: doc.id,
|
||||
docId,
|
||||
versionId,
|
||||
});
|
||||
const { createProvider, providers } = useDocStore();
|
||||
const collaborationUrl = useCollaborationUrl(versionId);
|
||||
|
||||
const { replace } = useRouter();
|
||||
const [initialContent, setInitialContent] = useState<Y.XmlFragment>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!version?.id || !collaborationUrl) {
|
||||
if (!version?.content) {
|
||||
return;
|
||||
}
|
||||
|
||||
const provider = providers?.[version.id];
|
||||
if (!provider || provider.document.guid !== version.id) {
|
||||
createProvider(collaborationUrl, version.id, version.content);
|
||||
}
|
||||
}, [createProvider, providers, version, collaborationUrl]);
|
||||
setInitialContent(base64ToBlocknoteXmlFragment(version.content));
|
||||
}, [version?.content]);
|
||||
|
||||
if (isError && error) {
|
||||
if (error.status === 404) {
|
||||
@@ -136,7 +139,7 @@ export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoading || !version) {
|
||||
if (isLoading || !version || !initialContent) {
|
||||
return (
|
||||
<Box $align="center" $justify="center" $height="100%">
|
||||
<Loader />
|
||||
@@ -144,11 +147,5 @@ export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => {
|
||||
);
|
||||
}
|
||||
|
||||
const provider = providers?.[version.id];
|
||||
|
||||
if (!provider) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <BlockNoteEditor doc={doc} storeId={version.id} provider={provider} />;
|
||||
return <BlockNoteEditorVersion initialContent={initialContent} />;
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import { css } from 'styled-components';
|
||||
import { Box, Card, StyledLink, Text } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { Doc, currentDocRole, useTrans } from '@/features/docs/doc-management';
|
||||
import { Versions } from '@/features/docs/doc-versioning';
|
||||
import { useDate } from '@/hook';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
@@ -15,10 +14,9 @@ import { DocToolBox } from './DocToolBox';
|
||||
|
||||
interface DocHeaderProps {
|
||||
doc: Doc;
|
||||
versionId?: Versions['version_id'];
|
||||
}
|
||||
|
||||
export const DocHeader = ({ doc, versionId }: DocHeaderProps) => {
|
||||
export const DocHeader = ({ doc }: DocHeaderProps) => {
|
||||
const { colorsTokens } = useCunninghamTheme();
|
||||
const { t } = useTranslation();
|
||||
const { formatDate } = useDate();
|
||||
@@ -69,7 +67,7 @@ export const DocHeader = ({ doc, versionId }: DocHeaderProps) => {
|
||||
$align="center"
|
||||
>
|
||||
<DocTitle doc={doc} />
|
||||
<DocToolBox doc={doc} versionId={versionId} />
|
||||
<DocToolBox doc={doc} />
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
VariantType,
|
||||
useToastProvider,
|
||||
} from '@openfun/cunningham-react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -17,17 +18,19 @@ import {
|
||||
ModalRemoveDoc,
|
||||
ModalShare,
|
||||
} from '@/features/docs/doc-management';
|
||||
import { ModalVersion, Versions } from '@/features/docs/doc-versioning';
|
||||
import { ModalVersion } from '@/features/docs/doc-versioning';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { ModalPDF } from './ModalExport';
|
||||
|
||||
interface DocToolBoxProps {
|
||||
doc: Doc;
|
||||
versionId?: Versions['version_id'];
|
||||
}
|
||||
|
||||
export const DocToolBox = ({ doc, versionId }: DocToolBoxProps) => {
|
||||
export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
const {
|
||||
query: { versionId },
|
||||
} = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const [isModalShareOpen, setIsModalShareOpen] = useState(false);
|
||||
const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false);
|
||||
@@ -194,7 +197,7 @@ export const DocToolBox = ({ doc, versionId }: DocToolBoxProps) => {
|
||||
<ModalVersion
|
||||
onClose={() => setIsModalVersionOpen(false)}
|
||||
docId={doc.id}
|
||||
versionId={versionId}
|
||||
versionId={versionId as string}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -28,3 +28,14 @@ export const blocksToYDoc = (blocks: BasicBlock[], doc: Y.Doc) => {
|
||||
xmlFragment.push([xmlElement]);
|
||||
});
|
||||
};
|
||||
|
||||
export const base64ToYDoc = (base64: string) => {
|
||||
const uint8Array = Buffer.from(base64, 'base64');
|
||||
const ydoc = new Y.Doc();
|
||||
Y.applyUpdate(ydoc, uint8Array);
|
||||
return ydoc;
|
||||
};
|
||||
|
||||
export const base64ToBlocknoteXmlFragment = (base64: string) => {
|
||||
return base64ToYDoc(base64).getXmlFragment('document-store');
|
||||
};
|
||||
|
||||
@@ -8,12 +8,16 @@ import {
|
||||
} from '@openfun/cunningham-react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { Box, Text } from '@/components';
|
||||
import { toBase64 } from '@/features/docs/doc-editor';
|
||||
import { Doc, useDocStore, useUpdateDoc } from '@/features/docs/doc-management';
|
||||
import {
|
||||
Doc,
|
||||
base64ToYDoc,
|
||||
useDocStore,
|
||||
useUpdateDoc,
|
||||
} from '@/features/docs/doc-management';
|
||||
|
||||
import { useDocVersion } from '../api';
|
||||
import { KEY_LIST_DOC_VERSIONS } from '../api/useDocVersions';
|
||||
import { Versions } from '../types';
|
||||
import { revertUpdate } from '../utils';
|
||||
@@ -21,7 +25,6 @@ import { revertUpdate } from '../utils';
|
||||
interface ModalVersionProps {
|
||||
onClose: () => void;
|
||||
docId: Doc['id'];
|
||||
|
||||
versionId: Versions['version_id'];
|
||||
}
|
||||
|
||||
@@ -30,6 +33,10 @@ export const ModalVersion = ({
|
||||
docId,
|
||||
versionId,
|
||||
}: ModalVersionProps) => {
|
||||
const { data: version } = useDocVersion({
|
||||
docId,
|
||||
versionId,
|
||||
});
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToastProvider();
|
||||
const { push } = useRouter();
|
||||
@@ -42,7 +49,7 @@ export const ModalVersion = ({
|
||||
void push(`/docs/${docId}`);
|
||||
};
|
||||
|
||||
if (!providers?.[docId] || !providers?.[versionId]) {
|
||||
if (!providers?.[docId] || !version?.content) {
|
||||
onDisplaySuccess();
|
||||
return;
|
||||
}
|
||||
@@ -50,7 +57,7 @@ export const ModalVersion = ({
|
||||
revertUpdate(
|
||||
providers[docId].document,
|
||||
providers[docId].document,
|
||||
providers[versionId].document,
|
||||
base64ToYDoc(version.content),
|
||||
);
|
||||
|
||||
onDisplaySuccess();
|
||||
@@ -79,13 +86,13 @@ export const ModalVersion = ({
|
||||
color="primary"
|
||||
fullWidth
|
||||
onClick={() => {
|
||||
const newDoc = toBase64(
|
||||
Y.encodeStateAsUpdate(providers?.[versionId].document),
|
||||
);
|
||||
if (!version?.content) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateDoc({
|
||||
id: docId,
|
||||
content: newDoc,
|
||||
content: version.content,
|
||||
});
|
||||
|
||||
onClose();
|
||||
|
||||
Reference in New Issue
Block a user