Skip to content

Commit

Permalink
Implementation of sorting of requests in Request screen (#1082)
Browse files Browse the repository at this point in the history
* requests sorting

* added missing test

* added missing test

* increased test coverage for requests screen

* added the reviewed changes and improved tests
  • Loading branch information
chandel-aman authored Dec 9, 2023
1 parent 46a337d commit 044b336
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 20 deletions.
2 changes: 2 additions & 0 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@
"noRequestFound": "No Request Found",
"sort": "Sort",
"filter": "Filter",
"Oldest": "Oldest First",
"Latest": "Latest First",
"noOrgError": "Organizations not found, please create an organization through dashboard",
"userApproved": "User Approved",
"userRejected": "User Rejected",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@
"noRequestFound": "Aucune demande trouvée",
"sort": "Trier",
"filter": "Filtre",
"Oldest": "Les plus anciennes d'abord",
"Latest": "Les plus récentes d'abord",
"userApproved": "Approuvé par l'utilisateur",
"userRejected": "Utilisateur rejeté",
"noResultsFoundFor": "Aucun résultat trouvé pour ",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@
"noRequestFound": "कोई अनुरोध नहीं मिला।",
"sort": "छांटें",
"filter": "फ़िल्टर",
"Oldest": "सबसे पुराना पहले",
"Latest": "सबसे नवीनतम पहले",
"userApproved": "उपयोगकर्ता स्वीकृत",
"userRejected": "उपयोगकर्ता अस्वीकृत",
"noResultsFoundFor": "के लिए कोई परिणाम नहीं मिला ",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/sp.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@
"noRequestFound": "No se encontró ninguna solicitud.",
"sort": "Ordenar",
"filter": "Filtrar",
"Oldest": "Más Antiguas Primero",
"Latest": "Más Recientes Primero",
"userApproved": "Aprobado por el usuario",
"userRejected": "Usuario rechazado",
"noResultsFoundFor": "No se encontraron resultados para ",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@
"noRequestFound": "找不到請求。",
"sort": "排序",
"filter": "過濾",
"Oldest": "最旧的优先",
"Latest": "最新的优先",
"userApproved": "用戶批准",
"userRejected": "用戶被拒絕",
"noResultsFoundFor": "未找到结果 ",
Expand Down
42 changes: 37 additions & 5 deletions src/screens/Requests/Requests.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { act, render, screen } from '@testing-library/react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import 'jest-localstorage-mock';
import 'jest-location-mock';
import { I18nextProvider } from 'react-i18next';
Expand Down Expand Up @@ -110,14 +110,46 @@ describe('Testing Request screen', () => {
</MockedProvider>
);

await wait();

const searchInput = screen.getByTestId('searchByName');
userEvent.type(searchInput, 'l');

const notFoundDiv = await screen.findByTestId('searchAndNotFound');

expect(notFoundDiv).toBeInTheDocument();
await screen.findByTestId('searchAndNotFound');
});

await wait();
test('Testing search latest and oldest toggle', async () => {
await act(async () => {
render(
<MockedProvider addTypename={false} link={link}>
<BrowserRouter>
<Provider store={store}>
<I18nextProvider i18n={i18nForTest}>
<Requests />
</I18nextProvider>
</Provider>
</BrowserRouter>
</MockedProvider>
);

await wait();

const searchInput = screen.getByTestId('sort');
expect(searchInput).toBeInTheDocument();

const inputText = screen.getByTestId('sortDropdown');

fireEvent.click(inputText);
const toggleText = screen.getByTestId('latest');

fireEvent.click(toggleText);

expect(searchInput).toBeInTheDocument();
fireEvent.click(inputText);
const toggleTite = screen.getByTestId('oldest');
fireEvent.click(toggleTite);
expect(searchInput).toBeInTheDocument();
});
});

test('Testing accept user functionality', async () => {
Expand Down
113 changes: 98 additions & 15 deletions src/screens/Requests/Requests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import type {
InterfaceQueryRequestListItem,
InterfaceUserType,
} from 'utils/interfaces';

import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
import styles from './Requests.module.css';

const Requests = (): JSX.Element => {
Expand All @@ -41,7 +45,10 @@ const Requests = (): JSX.Element => {
const [hasMore, sethasMore] = useState(true);
const [isLoadingMore, setIsLoadingMore] = useState(false);
const [searchByName, setSearchByName] = useState('');

const [sortingOption, setSortingOption] = useState('');
const [displayedUsers, setDisplayedUsers] = useState<
InterfaceQueryRequestListItem[]
>([]);
const [acceptAdminFunc] = useMutation(ACCEPT_ADMIN_MUTATION);
const [rejectAdminFunc] = useMutation(REJECT_ADMIN_MUTATION);
const {
Expand Down Expand Up @@ -91,13 +98,29 @@ const Requests = (): JSX.Element => {
}, []);

// To manage loading states
useEffect(() => {
if (!usersData) {
return;
const updateDisplayedUsers = (data: any): InterfaceQueryRequestListItem[] => {
if (!data) {
return [];
}
if (usersData.users.length < perPageResult) {
sethasMore(false);

const newDisplayedUsers = sortRequests(data.users, sortingOption);
return newDisplayedUsers;
};

const setHasMoreBasedOnUsers = (data: any): boolean => {
if (!data) {
return false;
}

return data.users.length >= perPageResult;
};

useEffect(() => {
const newDisplayedUsers = updateDisplayedUsers(usersData);
setDisplayedUsers(newDisplayedUsers);

const hasMoreValue = setHasMoreBasedOnUsers(usersData);
sethasMore(hasMoreValue);
}, [usersData]);

// If the user is not Superadmin, redirect to Organizations screen
Expand Down Expand Up @@ -127,6 +150,13 @@ const Requests = (): JSX.Element => {
}
}, [loading]);

useEffect(() => {
if (usersData && usersData?.users.length > 0) {
const newDisplayedUsers = sortRequests(usersData?.users, sortingOption);
setDisplayedUsers(newDisplayedUsers);
}
}, [usersData, sortingOption]);

/* istanbul ignore next */
const resetAndRefetch = (): void => {
refetchUsers({
Expand Down Expand Up @@ -233,8 +263,34 @@ const Requests = (): JSX.Element => {
t('email'),
t('accept'),
t('reject'),
'',
];

const handleSorting = (option: string): void => {
setSortingOption(option);
};

const sortRequests = (
users: InterfaceQueryRequestListItem[],
sortingOption: string
): InterfaceQueryRequestListItem[] => {
const sortedRequest = [...users];

if (sortingOption === 'latest') {
sortedRequest.sort(
(a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
} else if (sortingOption === 'oldest') {
sortedRequest.sort(
(a, b) =>
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
);
}

return sortedRequest;
};

return (
<>
<SuperAdminScreen title={t('requests')} screenName="Requests">
Expand Down Expand Up @@ -270,15 +326,35 @@ const Requests = (): JSX.Element => {
</div>
<div className={styles.btnsBlock}>
<div className="d-flex">
<Dropdown aria-expanded="false" title="Sort organizations">
<Dropdown.Toggle variant="outline-success">
<Dropdown
aria-expanded="false"
title="Sort organizations"
data-testid="sort"
>
<Dropdown.Toggle
variant={sortingOption === '' ? 'outline-success' : 'success'}
data-testid="sortDropdown"
>
<SortIcon className={'me-1'} />
{t('sort')}
{sortingOption === ''
? t('sort')
: sortingOption === 'latest'
? t('Latest')
: t('Oldest')}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#/action-1">Action 1</Dropdown.Item>
<Dropdown.Item href="#/action-2">Action 2</Dropdown.Item>
<Dropdown.Item href="#/action-3">Action 3</Dropdown.Item>
<Dropdown.Item
onClick={(): void => handleSorting('latest')}
data-testid="latest"
>
{t('Latest')}
</Dropdown.Item>
<Dropdown.Item
onClick={(): void => handleSorting('oldest')}
data-testid="oldest"
>
{t('Oldest')}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown aria-expanded="false" title="Filter organizations">
Expand Down Expand Up @@ -313,7 +389,12 @@ const Requests = (): JSX.Element => {
<InfiniteScroll
dataLength={usersData?.users.length ?? 0}
next={loadMoreRequests}
loader={<TableLoader noOfCols={5} noOfRows={perPageResult} />}
loader={
<TableLoader
noOfCols={headerTitles.length}
noOfRows={perPageResult}
/>
}
hasMore={hasMore}
className={styles.listBox}
data-testid="organizations-list"
Expand All @@ -336,8 +417,9 @@ const Requests = (): JSX.Element => {
</tr>
</thead>
<tbody>
{usersData?.users &&
usersData.users.map((user, index) => {
{displayedUsers &&
displayedUsers.length > 0 &&
displayedUsers.map((user, index) => {
return (
<tr key={user._id}>
<th scope="row">{index + 1}</th>
Expand Down Expand Up @@ -365,6 +447,7 @@ const Requests = (): JSX.Element => {
{t('reject')}
</Button>
</td>
<td>{dayjs(user.createdAt).fromNow()}</td>
</tr>
);
})}
Expand Down

0 comments on commit 044b336

Please sign in to comment.