Skip to content

Commit 98b60eb

Browse files
committed
🐛(frontend) fix infinity scroll on invitation list
The infinity scroll had some difficulties to load the next page of invitations because the ref could be not init. This commit fixes the issue.
1 parent 0b15ebb commit 98b60eb

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,61 @@ test.describe('Document list members', () => {
6666
).toBeVisible();
6767
});
6868

69+
test('it checks a big list of invitations', async ({ page }) => {
70+
await page.route(
71+
/.*\/documents\/.*\/invitations\/\?page=.*/,
72+
async (route) => {
73+
const request = route.request();
74+
const url = new URL(request.url());
75+
const pageId = url.searchParams.get('page');
76+
const accesses = {
77+
count: 100,
78+
next: 'http://anything/?page=2',
79+
previous: null,
80+
results: Array.from({ length: 20 }, (_, i) => ({
81+
id: `2ff1ec07-86c1-4534-a643-f41824a6c53a-${pageId}-${i}`,
82+
email: `[email protected]${pageId}-${i}`,
83+
team: '',
84+
role: 'editor',
85+
abilities: {
86+
destroy: true,
87+
update: true,
88+
partial_update: true,
89+
retrieve: true,
90+
},
91+
})),
92+
};
93+
94+
if (request.method().includes('GET')) {
95+
await route.fulfill({
96+
json: accesses,
97+
});
98+
} else {
99+
await route.continue();
100+
}
101+
},
102+
);
103+
104+
await goToGridDoc(page);
105+
106+
await page.getByRole('button', { name: 'Share' }).click();
107+
108+
const list = page.getByLabel('List invitation card').locator('ul');
109+
await expect(list.locator('li')).toHaveCount(20);
110+
await list.getByText(`[email protected]${1}-18`).hover();
111+
await page.mouse.wheel(0, 10);
112+
113+
await waitForElementCount(list.locator('li'), 21, 10000);
114+
115+
expect(await list.locator('li').count()).toBeGreaterThan(20);
116+
await expect(
117+
list.getByText(`[email protected]`),
118+
).toBeVisible();
119+
await expect(
120+
list.getByText(`[email protected]`),
121+
).toBeVisible();
122+
});
123+
69124
test('it checks the role rules', async ({ page, browserName }) => {
70125
const [docTitle] = await createDoc(page, 'Doc role rules', browserName, 1);
71126

src/frontend/apps/impress/src/features/docs/members/invitation-list/components/InvitationList.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Loader } from '@openfun/cunningham-react';
2-
import React, { useMemo, useRef } from 'react';
2+
import React, { useEffect, useMemo, useRef, useState } from 'react';
33
import { useTranslation } from 'react-i18next';
44

55
import { APIError } from '@/api';
@@ -73,6 +73,7 @@ interface InvitationListProps {
7373
export const InvitationList = ({ doc }: InvitationListProps) => {
7474
const { t } = useTranslation();
7575
const containerRef = useRef<HTMLDivElement>(null);
76+
const [, setRefInitialized] = useState(false);
7677
const {
7778
data,
7879
isLoading,
@@ -90,6 +91,17 @@ export const InvitationList = ({ doc }: InvitationListProps) => {
9091
}, [] as Invitation[]);
9192
}, [data?.pages]);
9293

94+
/**
95+
* The "return null;" statement below blocks a necessary rerender
96+
* for the InfiniteScroll component to work properly.
97+
* This useEffect is a workaround to force the rerender.
98+
*/
99+
useEffect(() => {
100+
if (containerRef.current) {
101+
setRefInitialized(true);
102+
}
103+
}, [invitations?.length]);
104+
93105
if (!invitations?.length) {
94106
return null;
95107
}

0 commit comments

Comments
 (0)