Skip to content

Commit

Permalink
feat: Implemented orglist sorting functionality
Browse files Browse the repository at this point in the history
Changes Made:
- Added a new state variable, `sortingOption`, to manage the current sorting preference. Default is set to 'latest'.
- Introduced a sorting mechanism using the `sortOrgs` function that sorts organizations based on creation date.
- Updated the `useEffect` hook to apply sorting when either `orgsData` or `sortingOption` changes.
- Added two sorting options - latest first and oldest first
- Also added the relevant tests for the correct functionality of the changes.

Fixes issue #1072

Signed-off-by: Akhilender <[email protected]>
  • Loading branch information
akhilender-bongirwar committed Nov 19, 2023
1 parent 816e761 commit 011ea2e
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 14 deletions.
2 changes: 2 additions & 0 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
"displayImage": "Display Image",
"enterName": "Enter Name",
"sort": "Sort",
"Latest": "Latest First",
"Oldest": "Oldest First",
"filter": "Filter",
"cancel": "Cancel",
"noOrgErrorTitle": "Organizations Not Found",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
"displayImage": "Afficher l'image",
"enterName": "Entrez le nom",
"sort": "Trier",
"Oldest": "Les plus anciennes d'abord",
"Latest": "Les plus récentes d'abord",
"filter": "Filtre",
"cancel": "Annuler",
"endOfResults": "Fin des résultats",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
"displayImage": "प्रदर्शन छवि",
"enterName": "नाम दर्ज करें",
"sort": "छांटें",
"Oldest": "सबसे पुराना पहले",
"Latest": "सबसे नवीनतम पहले",
"filter": "फ़िल्टर",
"cancel": "रद्द करना",
"endOfResults": "परिणामों का अंत",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/sp.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
"displayImage": "Mostrar imagen",
"enterName": "Ingrese su nombre",
"sort": "Ordenar",
"Oldest": "Más Antiguas Primero",
"Latest": "Más Recientes Primero",
"filter": "Filtrar",
"cancel": "Cancelar",
"endOfResults": "Fin de los resultados",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
"displayImage": "顯示圖像",
"enterName": "输入名字",
"sort": "排序",
"Oldest": "最旧的优先",
"Latest": "最新的优先",
"filter": "過濾",
"cancel": "取消",
"endOfResults": "結果結束",
Expand Down
36 changes: 35 additions & 1 deletion src/screens/OrgList/OrgList.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, render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import 'jest-localstorage-mock';
import 'jest-location-mock';
Expand Down Expand Up @@ -199,4 +199,38 @@ describe('Organisations Page testing as Admin', () => {
await wait();
expect(screen.queryByText(/Create Organization/i)).toBeNull();
});

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

await wait();

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

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

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();
});
});
});
92 changes: 79 additions & 13 deletions src/screens/OrgList/OrgList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ import type {
} from 'utils/interfaces';
import styles from './OrgList.module.css';

interface InterfaceOrgList {
_id: string;
name: string;
image: string | null;
location: string;
admins: { _id: string }[];
members: { _id: string }[];
creator: { _id: string; firstName: string; lastName: string };
createdAt: string;
}

function orgList(): JSX.Element {
const { t } = useTranslation('translation', { keyPrefix: 'orgList' });
const [dialogModalisOpen, setdialogModalIsOpen] = useState(false);
Expand All @@ -52,6 +63,7 @@ function orgList(): JSX.Element {

const perPageResult = 8;
const [isLoading, setIsLoading] = useState(true);
const [sortingOption, setSortingOption] = useState('latest');
const [hasMore, sethasMore] = useState(true);
const [isLoadingMore, setIsLoadingMore] = useState(false);
const [searchByName, setSearchByName] = useState('');
Expand Down Expand Up @@ -105,6 +117,20 @@ function orgList(): JSX.Element {
notifyOnNetworkStatusChange: true,
});

const [displayedOrgs, setDisplayedOrgs] = useState(
orgsData?.organizationsConnection || []
);

useEffect(() => {
if (orgsData && orgsData.organizationsConnection) {
const newDisplayedOrgs = sortOrgs(
orgsData.organizationsConnection,
sortingOption
);
setDisplayedOrgs(newDisplayedOrgs);
}
}, [orgsData, sortingOption]);

// To clear the search field and form fields on unmount
useEffect(() => {
return () => {
Expand Down Expand Up @@ -229,14 +255,14 @@ function orgList(): JSX.Element {
filter: value,
});
};

// console.log(orgsData);
/* istanbul ignore next */
const loadMoreOrganizations = (): void => {
console.log('loadMoreOrganizations');
setIsLoadingMore(true);
fetchMore({
variables: {
skip: orgsData?.organizationsConnection.length || 0,
skip: displayedOrgs.length || 0,
},
updateQuery: (
prev:
Expand Down Expand Up @@ -268,6 +294,31 @@ function orgList(): JSX.Element {
};

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

const sortOrgs = (
orgs: InterfaceOrgList[],
sortingOption: string
): InterfaceOrgList[] => {
const sortedOrgs = [...orgs];

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

return sortedOrgs;
};

return (
<>
<SuperAdminScreen title={t('organizations')} screenName="Organizations">
Expand All @@ -293,15 +344,31 @@ function orgList(): 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="outline-success"
data-testid="sortOrgs"
>
<SortIcon className={'me-1'} />
{t('sort')}
</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 @@ -330,8 +397,7 @@ function orgList(): JSX.Element {
</div>
{/* Text Infos for list */}
{!isLoading &&
((orgsData?.organizationsConnection.length === 0 &&
searchByName.length == 0) ||
((displayedOrgs.length === 0 && searchByName.length == 0) ||
(userData &&
userData.user.userType === 'ADMIN' &&
userData.user.adminFor.length === 0)) ? (
Expand All @@ -341,7 +407,7 @@ function orgList(): JSX.Element {
<h6 className="text-secondary">{t('noOrgErrorDescription')}</h6>
</div>
) : !isLoading &&
orgsData?.organizationsConnection.length == 0 &&
displayedOrgs.length == 0 &&
/* istanbul ignore next */
searchByName.length > 0 ? (
/* istanbul ignore next */
Expand All @@ -354,7 +420,7 @@ function orgList(): JSX.Element {
) : (
<>
<InfiniteScroll
dataLength={orgsData?.organizationsConnection?.length ?? 0}
dataLength={displayedOrgs?.length ?? 0}
next={loadMoreOrganizations}
loader={
<>
Expand Down Expand Up @@ -409,7 +475,7 @@ function orgList(): JSX.Element {
))}
</>
) : userData && userData.user.userType == 'SUPERADMIN' ? (
orgsData?.organizationsConnection.map((item) => {
displayedOrgs.map((item) => {
return (
<div key={item._id} className={styles.itemCard}>
<OrgListCard data={item} />
Expand All @@ -420,7 +486,7 @@ function orgList(): JSX.Element {
userData &&
userData.user.userType == 'ADMIN' &&
userData.user.adminFor.length > 0 &&
orgsData?.organizationsConnection.map((item) => {
displayedOrgs.map((item) => {
if (isAdminForCurrentOrg(item)) {
return (
<div key={item._id} className={styles.itemCard}>
Expand Down

0 comments on commit 011ea2e

Please sign in to comment.