🛂(frontend) blocked edition if multiple ancestors
With child documents we need to check the parent documents to know if the parent doc are collaborative or not.
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
|||||||
overrideConfig,
|
overrideConfig,
|
||||||
verifyDocName,
|
verifyDocName,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
import { createRootSubPage } from './sub-pages-utils';
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
@@ -524,6 +525,8 @@ test.describe('Doc Editor', () => {
|
|||||||
page,
|
page,
|
||||||
browserName,
|
browserName,
|
||||||
}) => {
|
}) => {
|
||||||
|
test.slow();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The good port is 4444, but we want to simulate a not connected
|
* The good port is 4444, but we want to simulate a not connected
|
||||||
* collaborative server.
|
* collaborative server.
|
||||||
@@ -536,7 +539,12 @@ test.describe('Doc Editor', () => {
|
|||||||
|
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
|
||||||
const [title] = await createDoc(page, 'editing-blocking', browserName, 1);
|
const [parentTitle] = await createDoc(
|
||||||
|
page,
|
||||||
|
'editing-blocking',
|
||||||
|
browserName,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
const card = page.getByLabel('It is the card information');
|
const card = page.getByLabel('It is the card information');
|
||||||
await expect(
|
await expect(
|
||||||
@@ -571,12 +579,20 @@ test.describe('Doc Editor', () => {
|
|||||||
// Close the modal
|
// Close the modal
|
||||||
await page.getByRole('button', { name: 'close' }).first().click();
|
await page.getByRole('button', { name: 'close' }).first().click();
|
||||||
|
|
||||||
|
const urlParentDoc = page.url();
|
||||||
|
|
||||||
|
const { name: childTitle } = await createRootSubPage(
|
||||||
|
page,
|
||||||
|
browserName,
|
||||||
|
'editing-blocking - child',
|
||||||
|
);
|
||||||
|
|
||||||
let responseCanEdit = await responseCanEditPromise;
|
let responseCanEdit = await responseCanEditPromise;
|
||||||
expect(responseCanEdit.ok()).toBeTruthy();
|
expect(responseCanEdit.ok()).toBeTruthy();
|
||||||
let jsonCanEdit = (await responseCanEdit.json()) as { can_edit: boolean };
|
let jsonCanEdit = (await responseCanEdit.json()) as { can_edit: boolean };
|
||||||
expect(jsonCanEdit.can_edit).toBeTruthy();
|
expect(jsonCanEdit.can_edit).toBeTruthy();
|
||||||
|
|
||||||
const urlDoc = page.url();
|
const urlChildDoc = page.url();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We open another browser that will connect to the collaborative server
|
* We open another browser that will connect to the collaborative server
|
||||||
@@ -603,14 +619,14 @@ test.describe('Doc Editor', () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
await otherPage.goto(urlDoc);
|
await otherPage.goto(urlChildDoc);
|
||||||
|
|
||||||
const webSocket = await webSocketPromise;
|
const webSocket = await webSocketPromise;
|
||||||
expect(webSocket.url()).toContain(
|
expect(webSocket.url()).toContain(
|
||||||
'ws://localhost:4444/collaboration/ws/?room=',
|
'ws://localhost:4444/collaboration/ws/?room=',
|
||||||
);
|
);
|
||||||
|
|
||||||
await verifyDocName(otherPage, title);
|
await verifyDocName(otherPage, childTitle);
|
||||||
|
|
||||||
await page.reload();
|
await page.reload();
|
||||||
|
|
||||||
@@ -633,6 +649,10 @@ test.describe('Doc Editor', () => {
|
|||||||
|
|
||||||
await expect(editor).toHaveAttribute('contenteditable', 'false');
|
await expect(editor).toHaveAttribute('contenteditable', 'false');
|
||||||
|
|
||||||
|
await page.goto(urlParentDoc);
|
||||||
|
|
||||||
|
await verifyDocName(page, parentTitle);
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Share' }).click();
|
await page.getByRole('button', { name: 'Share' }).click();
|
||||||
|
|
||||||
await page.getByLabel('Visibility mode').click();
|
await page.getByLabel('Visibility mode').click();
|
||||||
@@ -641,18 +661,9 @@ test.describe('Doc Editor', () => {
|
|||||||
// Close the modal
|
// Close the modal
|
||||||
await page.getByRole('button', { name: 'close' }).first().click();
|
await page.getByRole('button', { name: 'close' }).first().click();
|
||||||
|
|
||||||
await page.reload();
|
await page.goto(urlChildDoc);
|
||||||
|
|
||||||
responseCanEditPromise = page.waitForResponse(
|
await expect(editor).toHaveAttribute('contenteditable', 'true');
|
||||||
(response) =>
|
|
||||||
response.url().includes(`/can-edit/`) && response.status() === 200,
|
|
||||||
);
|
|
||||||
|
|
||||||
responseCanEdit = await responseCanEditPromise;
|
|
||||||
expect(responseCanEdit.ok()).toBeTruthy();
|
|
||||||
|
|
||||||
jsonCanEdit = (await responseCanEdit.json()) as { can_edit: boolean };
|
|
||||||
expect(jsonCanEdit.can_edit).toBeTruthy();
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
card.getByText('Others are editing. Your network prevent changes.'),
|
card.getByText('Others are editing. Your network prevent changes.'),
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ test.describe('Doc Visibility: Authenticated', () => {
|
|||||||
const { name: childTitle } = await createRootSubPage(
|
const { name: childTitle } = await createRootSubPage(
|
||||||
page,
|
page,
|
||||||
browserName,
|
browserName,
|
||||||
'Authenticated read onlyc - child',
|
'Authenticated read only - child',
|
||||||
);
|
);
|
||||||
|
|
||||||
const urlChildDoc = page.url();
|
const urlChildDoc = page.url();
|
||||||
|
|||||||
@@ -5,15 +5,20 @@ import { useIsOffline } from '@/features/service-worker';
|
|||||||
|
|
||||||
import { KEY_CAN_EDIT, useDocCanEdit } from '../api/useDocCanEdit';
|
import { KEY_CAN_EDIT, useDocCanEdit } from '../api/useDocCanEdit';
|
||||||
import { useProviderStore } from '../stores';
|
import { useProviderStore } from '../stores';
|
||||||
import { Doc, LinkReach } from '../types';
|
import { Doc, LinkReach, LinkRole } from '../types';
|
||||||
|
|
||||||
export const useIsCollaborativeEditable = (doc: Doc) => {
|
export const useIsCollaborativeEditable = (doc: Doc) => {
|
||||||
const { isConnected } = useProviderStore();
|
const { isConnected } = useProviderStore();
|
||||||
const { data: conf } = useConfig();
|
const { data: conf } = useConfig();
|
||||||
|
|
||||||
const docIsPublic = doc.link_reach === LinkReach.PUBLIC;
|
const docIsPublic =
|
||||||
const docIsAuth = doc.link_reach === LinkReach.AUTHENTICATED;
|
doc.computed_link_reach === LinkReach.PUBLIC &&
|
||||||
const docHasMember = doc.nb_accesses_direct > 1;
|
doc.computed_link_role === LinkRole.EDITOR;
|
||||||
|
const docIsAuth =
|
||||||
|
doc.computed_link_reach === LinkReach.AUTHENTICATED &&
|
||||||
|
doc.computed_link_role === LinkRole.EDITOR;
|
||||||
|
const docHasMember =
|
||||||
|
doc.nb_accesses_direct > 1 || doc.nb_accesses_ancestors > 1;
|
||||||
const isUserReader = !doc.abilities.partial_update;
|
const isUserReader = !doc.abilities.partial_update;
|
||||||
const isShared = docIsPublic || docIsAuth || docHasMember;
|
const isShared = docIsPublic || docIsAuth || docHasMember;
|
||||||
const { isOffline } = useIsOffline();
|
const { isOffline } = useIsOffline();
|
||||||
@@ -21,23 +26,23 @@ export const useIsCollaborativeEditable = (doc: Doc) => {
|
|||||||
const [isEditable, setIsEditable] = useState(true);
|
const [isEditable, setIsEditable] = useState(true);
|
||||||
const [isLoading, setIsLoading] = useState(!_isEditable);
|
const [isLoading, setIsLoading] = useState(!_isEditable);
|
||||||
const timeout = useRef<NodeJS.Timeout | null>(null);
|
const timeout = useRef<NodeJS.Timeout | null>(null);
|
||||||
const {
|
const { data: editingRight, isLoading: isLoadingCanEdit } = useDocCanEdit(
|
||||||
data: { can_edit } = { can_edit: _isEditable },
|
doc.id,
|
||||||
isLoading: isLoadingCanEdit,
|
{
|
||||||
} = useDocCanEdit(doc.id, {
|
enabled: !_isEditable,
|
||||||
enabled: !_isEditable,
|
queryKey: [KEY_CAN_EDIT, doc.id],
|
||||||
queryKey: [KEY_CAN_EDIT, doc.id],
|
staleTime: 0,
|
||||||
staleTime: 0,
|
},
|
||||||
});
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoadingCanEdit) {
|
if (isLoadingCanEdit || _isEditable || !editingRight) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connection to the WebSocket can take some time, so we set a timeout to ensure the loading state is cleared after a reasonable time.
|
// Connection to the WebSocket can take some time, so we set a timeout to ensure the loading state is cleared after a reasonable time.
|
||||||
timeout.current = setTimeout(() => {
|
timeout.current = setTimeout(() => {
|
||||||
setIsEditable(can_edit);
|
setIsEditable(editingRight.can_edit);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
@@ -46,7 +51,7 @@ export const useIsCollaborativeEditable = (doc: Doc) => {
|
|||||||
clearTimeout(timeout.current);
|
clearTimeout(timeout.current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [can_edit, isLoadingCanEdit]);
|
}, [editingRight, isLoadingCanEdit, _isEditable]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!_isEditable) {
|
if (!_isEditable) {
|
||||||
@@ -59,7 +64,7 @@ export const useIsCollaborativeEditable = (doc: Doc) => {
|
|||||||
|
|
||||||
setIsEditable(true);
|
setIsEditable(true);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}, [_isEditable, isLoading]);
|
}, [_isEditable]);
|
||||||
|
|
||||||
if (!conf?.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY) {
|
if (!conf?.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user