Skip to content

Commit 2cbe363

Browse files
committed
🛂(frontend) block drag n drop when not desktop
Scrolling on mobile devices was causing issues with drag and drop functionality, documents were being moved unintentionally. This commit disables drag and drop on mobile devices to prevent this issue.
1 parent 7f450e8 commit 2cbe363

File tree

8 files changed

+97
-9
lines changed

8 files changed

+97
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to
2323
- 🔧(project) change env.d system by using local files #1200
2424
- ⚡️(frontend) improve tree stability #1207
2525
- ⚡️(frontend) improve accessibility #1232
26+
- 🛂(frontend) block drag n drop when not desktop #1239
2627

2728
### Fixed
2829

src/frontend/apps/e2e/__tests__/app-impress/doc-grid-dnd.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expect, test } from '@playwright/test';
22

33
import { createDoc, mockedListDocs } from './utils-common';
4+
import { createRootSubPage } from './utils-sub-pages';
45

56
test.describe('Doc grid dnd', () => {
67
test('it creates a doc', async ({ page, browserName }) => {
@@ -165,6 +166,40 @@ test.describe('Doc grid dnd', () => {
165166
});
166167
});
167168

169+
test.describe('Doc grid dnd mobile', () => {
170+
test.use({ viewport: { width: 500, height: 1200 } });
171+
172+
test('DND is deactivated on mobile', async ({ page, browserName }) => {
173+
await page.goto('/');
174+
175+
const docsGrid = page.getByTestId('docs-grid');
176+
await expect(page.getByTestId('docs-grid')).toBeVisible();
177+
await expect(page.getByTestId('grid-loader')).toBeHidden();
178+
179+
await expect(docsGrid.getByRole('row').first()).toBeVisible();
180+
await expect(docsGrid.locator('.--docs--grid-droppable')).toHaveCount(0);
181+
182+
await createDoc(page, 'Draggable doc mobile', browserName, 1, false, true);
183+
184+
await createRootSubPage(
185+
page,
186+
browserName,
187+
'Draggable doc mobile child',
188+
true,
189+
);
190+
191+
await page
192+
.getByRole('button', { name: 'Open the header menu' })
193+
.getByText('menu')
194+
.click();
195+
196+
await expect(page.locator('.--docs-sub-page-item').first()).toHaveAttribute(
197+
'draggable',
198+
'false',
199+
);
200+
});
201+
});
202+
168203
const data = [
169204
{
170205
id: 'can-drop-and-drag',

src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,23 @@ export const createDoc = async (
7979
browserName: string,
8080
length: number = 1,
8181
isChild: boolean = false,
82+
isMobile: boolean = false,
8283
) => {
8384
const randomDocs = randomName(docName, browserName, length);
8485

8586
for (let i = 0; i < randomDocs.length; i++) {
86-
if (!isChild) {
87+
if (!isChild && !isMobile) {
8788
const header = page.locator('header').first();
8889
await header.locator('h2').getByText('Docs').click();
8990
}
9091

92+
if (isMobile) {
93+
await page
94+
.getByRole('button', { name: 'Open the header menu' })
95+
.getByText('menu')
96+
.click();
97+
}
98+
9199
await page
92100
.getByRole('button', {
93101
name: 'New doc',

src/frontend/apps/e2e/__tests__/app-impress/utils-sub-pages.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,29 @@ export const createRootSubPage = async (
1010
page: Page,
1111
browserName: string,
1212
docName: string,
13+
isMobile: boolean = false,
1314
) => {
15+
if (isMobile) {
16+
await page
17+
.getByRole('button', { name: 'Open the header menu' })
18+
.getByText('menu')
19+
.click();
20+
}
21+
1422
// Get response
1523
const responsePromise = waitForResponseCreateDoc(page);
1624
await clickOnAddRootSubPage(page);
1725
const response = await responsePromise;
1826
expect(response.ok()).toBeTruthy();
1927
const subPageJson = (await response.json()) as { id: string };
2028

29+
if (isMobile) {
30+
await page
31+
.getByRole('button', { name: 'Open the header menu' })
32+
.getByText('menu')
33+
.click();
34+
}
35+
2136
// Get doc tree
2237
const docTree = page.getByTestId('doc-tree');
2338
await expect(docTree).toBeVisible();
@@ -29,6 +44,13 @@ export const createRootSubPage = async (
2944
await expect(subPageItem).toBeVisible();
3045
await subPageItem.click();
3146

47+
if (isMobile) {
48+
await page
49+
.getByRole('button', { name: 'Open the header menu' })
50+
.getByText('close')
51+
.click();
52+
}
53+
3254
// Update sub page name
3355
const randomDocs = randomName(docName, browserName, 1);
3456
await updateDocTitle(page, randomDocs[0]);

src/frontend/apps/impress/src/features/docs/doc-tree/components/DocSubPageItem.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export const DocSubPageItem = (props: TreeViewNodeProps<Doc>) => {
7171
return (
7272
<Box
7373
className="--docs-sub-page-item"
74+
draggable={doc.abilities.move && isDesktop}
7475
$position="relative"
7576
$css={css`
7677
background-color: ${actionsOpen

src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTree.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
OpenMap,
33
TreeView,
44
TreeViewMoveResult,
5+
useResponsive,
56
useTreeContext,
67
} from '@gouvfr-lasuite/ui-kit';
78
import { useRouter } from 'next/navigation';
@@ -29,6 +30,7 @@ export const DocTree = ({ currentDoc }: DocTreeProps) => {
2930
const [rootActionsOpen, setRootActionsOpen] = useState(false);
3031
const treeContext = useTreeContext<Doc | null>();
3132
const router = useRouter();
33+
const { isDesktop } = useResponsive();
3234

3335
const [initialOpenState, setInitialOpenState] = useState<OpenMap | undefined>(
3436
undefined,
@@ -243,13 +245,13 @@ export const DocTree = ({ currentDoc }: DocTreeProps) => {
243245
canDrop={({ parentNode }) => {
244246
const parentDoc = parentNode?.data.value as Doc;
245247
if (!parentDoc) {
246-
return currentDoc.abilities.move;
248+
return currentDoc.abilities.move && isDesktop;
247249
}
248-
return parentDoc.abilities.move;
250+
return parentDoc.abilities.move && isDesktop;
249251
}}
250252
canDrag={(node) => {
251253
const doc = node.value as Doc;
252-
return doc.abilities.move;
254+
return doc.abilities.move && isDesktop;
253255
}}
254256
rootNodeId={treeContext.root.id}
255257
renderNode={DocSubPageItem}

src/frontend/apps/impress/src/features/docs/docs-grid/components/DocGridContentList.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ type DocGridContentListProps = {
5151
docs: Doc[];
5252
};
5353

54-
export const DocGridContentList = ({ docs }: DocGridContentListProps) => {
54+
export const DraggableDocGridContentList = ({
55+
docs,
56+
}: DocGridContentListProps) => {
5557
const { mutateAsync: handleMove, isError } = useMoveDoc();
5658
const queryClient = useQueryClient();
5759
const modalConfirmation = useModal();
@@ -223,7 +225,7 @@ export const DocGridContentList = ({ docs }: DocGridContentListProps) => {
223225
);
224226
};
225227

226-
interface DocGridItemProps {
228+
interface DraggableDocGridItemProps {
227229
doc: Doc;
228230
dragMode: boolean;
229231
canDrag: boolean;
@@ -235,7 +237,7 @@ export const DraggableDocGridItem = ({
235237
dragMode,
236238
canDrag,
237239
updateCanDrop,
238-
}: DocGridItemProps) => {
240+
}: DraggableDocGridItemProps) => {
239241
const canDrop = doc.abilities.move;
240242

241243
return (
@@ -252,3 +254,13 @@ export const DraggableDocGridItem = ({
252254
</Droppable>
253255
);
254256
};
257+
258+
export const DocGridContentList = ({ docs }: DocGridContentListProps) => {
259+
if (docs.length === 0) {
260+
return null;
261+
}
262+
263+
return docs.map((doc) => (
264+
<DocsGridItem dragMode={false} doc={doc} key={doc.id} />
265+
));
266+
};

src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import { useResponsiveStore } from '@/stores';
99

1010
import { useResponsiveDocGrid } from '../hooks/useResponsiveDocGrid';
1111

12-
import { DocGridContentList } from './DocGridContentList';
12+
import {
13+
DocGridContentList,
14+
DraggableDocGridContentList,
15+
} from './DocGridContentList';
1316
import { DocsGridLoader } from './DocsGridLoader';
1417

1518
type DocsGridProps = {
@@ -118,7 +121,11 @@ export const DocsGrid = ({
118121
)}
119122
</Box>
120123

121-
<DocGridContentList docs={docs} />
124+
{isDesktop ? (
125+
<DraggableDocGridContentList docs={docs} />
126+
) : (
127+
<DocGridContentList docs={docs} />
128+
)}
122129

123130
{hasNextPage && !loading && (
124131
<InView

0 commit comments

Comments
 (0)