🛂(frontend) right pad editor

Manage the right on the pad editor.
If a use cannot edit a pad, the pad editor will
be read-only. It will not save automatically.
A message will be displayed to the user.
This commit is contained in:
Anthony LC
2024-05-24 17:39:28 +02:00
committed by Anthony LC
parent dd33c99532
commit d5d374c311
5 changed files with 51 additions and 5 deletions

View File

@@ -168,4 +168,33 @@ test.describe('Pad Editor', () => {
await expect(page.getByText('Hello World Pad persisted 2')).toBeVisible();
});
test('it cannot edit if not the owner', async ({ page, browserName }) => {
const [padName] = await createPad(
page,
'pad-right-edit',
browserName,
1,
true,
);
await page.getByText('My account').click();
await page.getByText('Logout').first().click();
await page.getByLabel('Restart login').click();
const browserNames = ['chromium', 'webkit'];
const newBrowserName = browserNames.find((name) => name !== browserName)!;
await keyCloakSignIn(page, newBrowserName);
const panel = page.getByLabel('Pads panel').first();
await panel.getByText(padName).click();
await expect(
page.getByText(
"Read only, you don't have the right to update this document.",
),
).toBeVisible();
});
});

View File

@@ -38,7 +38,7 @@ interface BlockNoteContentProps {
export const BlockNoteContent = ({ pad, provider }: BlockNoteContentProps) => {
const { userData } = useAuthStore();
const { setEditor, padsStore } = usePadStore();
useSavePad(pad.id, provider.doc);
useSavePad(pad.id, provider.doc, pad.abilities.partial_update);
const storedEditor = padsStore?.[pad.id]?.editor;
const editor = useMemo(() => {
@@ -70,7 +70,11 @@ export const BlockNoteContent = ({ pad, provider }: BlockNoteContentProps) => {
};
`}
>
<BlockNoteView editor={editor} formattingToolbar={false}>
<BlockNoteView
editor={editor}
formattingToolbar={false}
editable={pad.abilities.partial_update}
>
<BlockNoteToolbar />
</BlockNoteView>
</Box>

View File

@@ -1,3 +1,4 @@
import { Alert, VariantType } from '@openfun/cunningham-react';
import React from 'react';
import { Box, Card, Text } from '@/components';
@@ -24,6 +25,13 @@ export const PadEditor = ({ pad }: PadEditorProps) => {
</Text>
<PadToolBox pad={pad} />
</Box>
{!pad.abilities.partial_update && (
<Box className="m-b" $css="margin-top:0;">
<Alert
type={VariantType.WARNING}
>{`Read only, you don't have the right to update this document.`}</Alert>
</Box>
)}
<Card
$margin={{ all: 'big', top: 'none' }}
$padding="big"

View File

@@ -6,12 +6,16 @@ import { useUpdatePad } from '@/features/pads/pad-management/';
import { toBase64 } from '../utils';
const useSavePad = (padId: string, doc: Y.Doc) => {
const useSavePad = (padId: string, doc: Y.Doc, canSave: boolean) => {
const { mutate: updatePad } = useUpdatePad();
const [initialDoc, setInitialDoc] = useState<string>(
toBase64(Y.encodeStateAsUpdate(doc)),
);
useEffect(() => {
setInitialDoc(toBase64(Y.encodeStateAsUpdate(doc)));
}, [doc]);
/**
* Update initial doc when doc is updated by other users,
* so only the user typing will trigger the save.
@@ -42,7 +46,7 @@ const useSavePad = (padId: string, doc: Y.Doc) => {
/**
* Save only if the doc has changed.
*/
if (initialDoc === newDoc) {
if (initialDoc === newDoc || !canSave) {
return;
}
@@ -52,7 +56,7 @@ const useSavePad = (padId: string, doc: Y.Doc) => {
id: padId,
content: newDoc,
});
}, [initialDoc, padId, doc, updatePad]);
}, [initialDoc, padId, doc, updatePad, canSave]);
const timeout = useRef<NodeJS.Timeout>();
const router = useRouter();

View File

@@ -28,6 +28,7 @@ module.exports = {
rules: {
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
],