🛂(frontend) only owner can make a child doc a main doc
We get some side effects when an admin tries to make a child doc a main doc. We ensure that only the owner can do this.
This commit is contained in:
@@ -276,7 +276,6 @@ export const mockedDocument = async (page: Page, data: object) => {
|
||||
ancestors_link_role: null,
|
||||
created_at: '2021-09-01T09:00:00Z',
|
||||
user_role: 'owner',
|
||||
user_roles: ['owner'],
|
||||
...doc,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -158,7 +158,7 @@ test.describe('Doc grid dnd', () => {
|
||||
|
||||
await expect(dragOverlay).toBeVisible();
|
||||
await expect(dragOverlay).toHaveText(
|
||||
'You must have admin rights to move the document',
|
||||
'You must be the owner to move the document',
|
||||
);
|
||||
|
||||
await page.mouse.up();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import {
|
||||
addNewMember,
|
||||
createDoc,
|
||||
expectLoginPage,
|
||||
keyCloakSignIn,
|
||||
@@ -12,8 +13,11 @@ import {
|
||||
import { clickOnAddRootSubPage, createRootSubPage } from './sub-pages-utils';
|
||||
|
||||
test.describe('Doc Tree', () => {
|
||||
test('create new sub pages', async ({ page, browserName }) => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
test('create new sub pages', async ({ page, browserName }) => {
|
||||
const [titleParent] = await createDoc(
|
||||
page,
|
||||
'doc-tree-content',
|
||||
@@ -58,7 +62,6 @@ test.describe('Doc Tree', () => {
|
||||
});
|
||||
|
||||
test('check the reorder of sub pages', async ({ page, browserName }) => {
|
||||
await page.goto('/');
|
||||
await createDoc(page, 'doc-tree-content', browserName, 1);
|
||||
const addButton = page.getByRole('button', { name: 'New doc' });
|
||||
await expect(addButton).toBeVisible();
|
||||
@@ -165,7 +168,6 @@ test.describe('Doc Tree', () => {
|
||||
});
|
||||
|
||||
test('it detaches a document', async ({ page, browserName }) => {
|
||||
await page.goto('/');
|
||||
const [docParent] = await createDoc(
|
||||
page,
|
||||
'doc-tree-detach',
|
||||
@@ -202,6 +204,55 @@ test.describe('Doc Tree', () => {
|
||||
await header.locator('h2').getByText('Docs').click();
|
||||
await expect(page.getByText(docChild)).toBeVisible();
|
||||
});
|
||||
|
||||
test('Only owner can detaches a document', async ({ page, browserName }) => {
|
||||
const [docParent] = await createDoc(
|
||||
page,
|
||||
'doc-tree-detach',
|
||||
browserName,
|
||||
1,
|
||||
);
|
||||
|
||||
await verifyDocName(page, docParent);
|
||||
|
||||
await page.getByRole('button', { name: 'Share' }).click();
|
||||
|
||||
await addNewMember(page, 0, 'Owner', 'impress');
|
||||
|
||||
const list = page.getByTestId('doc-share-quick-search');
|
||||
const currentUser = list.getByTestId(
|
||||
`doc-share-member-row-user@${browserName}.test`,
|
||||
);
|
||||
const currentUserRole = currentUser.getByLabel('doc-role-dropdown');
|
||||
await currentUserRole.click();
|
||||
await page.getByLabel('Administrator').click();
|
||||
await list.click();
|
||||
|
||||
await page.getByRole('button', { name: 'Ok' }).click();
|
||||
|
||||
const { name: docChild } = await createRootSubPage(
|
||||
page,
|
||||
browserName,
|
||||
'doc-tree-detach-child',
|
||||
);
|
||||
|
||||
const docTree = page.getByTestId('doc-tree');
|
||||
await expect(docTree.getByText(docChild)).toBeVisible();
|
||||
await docTree.click();
|
||||
const child = docTree
|
||||
.getByRole('treeitem')
|
||||
.locator('.--docs-sub-page-item')
|
||||
.filter({
|
||||
hasText: docChild,
|
||||
});
|
||||
await child.hover();
|
||||
const menu = child.getByText(`more_horiz`);
|
||||
await menu.click();
|
||||
|
||||
await expect(
|
||||
page.getByRole('menuitem', { name: 'Move to my docs' }),
|
||||
).toHaveAttribute('aria-disabled', 'true');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Doc Tree: Inheritance', () => {
|
||||
|
||||
@@ -70,7 +70,6 @@ export interface Doc {
|
||||
numchild: number;
|
||||
updated_at: string;
|
||||
user_role: Role;
|
||||
user_roles: Role[];
|
||||
abilities: {
|
||||
accesses_manage: boolean;
|
||||
accesses_view: boolean;
|
||||
|
||||
@@ -11,7 +11,12 @@ import { css } from 'styled-components';
|
||||
|
||||
import { Box, BoxButton, Icon } from '@/components';
|
||||
|
||||
import { Doc, ModalRemoveDoc, useCopyDocLink } from '../../doc-management';
|
||||
import {
|
||||
Doc,
|
||||
ModalRemoveDoc,
|
||||
Role,
|
||||
useCopyDocLink,
|
||||
} from '../../doc-management';
|
||||
import { useCreateChildrenDoc } from '../api/useCreateChildren';
|
||||
import { useDetachDoc } from '../api/useDetach';
|
||||
import MoveDocIcon from '../assets/doc-extract-bold.svg';
|
||||
@@ -70,7 +75,7 @@ export const DocTreeItemActions = ({
|
||||
? [
|
||||
{
|
||||
label: t('Move to my docs'),
|
||||
isDisabled: !doc.abilities.move,
|
||||
isDisabled: doc.user_role !== Role.OWNER,
|
||||
icon: (
|
||||
<Box
|
||||
$css={css`
|
||||
|
||||
@@ -136,7 +136,7 @@ export const DocGridContentList = ({ docs }: DocGridContentListProps) => {
|
||||
|
||||
const overlayText = useMemo(() => {
|
||||
if (!canDrag) {
|
||||
return t('You must have admin rights to move the document');
|
||||
return t('You must be the owner to move the document');
|
||||
}
|
||||
if (!canDrop) {
|
||||
return t('You must be at least the editor of the target document');
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from '@dnd-kit/core';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Doc } from '@/docs/doc-management';
|
||||
import { Doc, Role } from '@/docs/doc-management';
|
||||
|
||||
export type DocDragEndData = {
|
||||
sourceDocumentId: string;
|
||||
@@ -26,7 +26,7 @@ export function useDragAndDrop(onDrag: (data: DocDragEndData) => void) {
|
||||
const [selectedDoc, setSelectedDoc] = useState<Doc>();
|
||||
const [canDrop, setCanDrop] = useState<boolean>();
|
||||
|
||||
const canDrag = !!selectedDoc?.abilities.move;
|
||||
const canDrag = selectedDoc?.user_role === Role.OWNER;
|
||||
|
||||
const mouseSensor = useSensor(MouseSensor, { activationConstraint });
|
||||
const touchSensor = useSensor(TouchSensor, { activationConstraint });
|
||||
|
||||
@@ -209,7 +209,6 @@ export class ApiPlugin implements WorkboxPlugin {
|
||||
},
|
||||
link_reach: LinkReach.RESTRICTED,
|
||||
link_role: LinkRole.READER,
|
||||
user_roles: [Role.OWNER],
|
||||
user_role: Role.OWNER,
|
||||
path: '',
|
||||
computed_link_reach: LinkReach.RESTRICTED,
|
||||
|
||||
Reference in New Issue
Block a user