Skip to content

Commit

Permalink
Feature/infinite user loading (#854)
Browse files Browse the repository at this point in the history
* added the infinite user loading feature

* fixed the bugs in the loading

* altered the API_BASE_URL to original one

* added the infinite user loading feature

* fixed the bugs in the loading

* altered the API_BASE_URL to original one

* updated the loader property

* updated the test for the loading feature

---------

Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com>
  • Loading branch information
prashant67690 and vinit717 authored Sep 27, 2024
1 parent 7cb2884 commit d1726ed
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 89 deletions.
32 changes: 12 additions & 20 deletions __tests__/users/user-management-home-screen.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,32 +116,24 @@ describe('Tests the User Management User Listing Screen', () => {
expect(userCard.length).toBeGreaterThan(0);
});

it('checks the next and previous button functionality', async () => {
it('checks infinite scroll functionality to load more users', async () => {
await page.goto('http://localhost:8000/users');
await page.waitForNetworkIdle();

// Get the "next" button and check if it is enabled
const nextBtn = await page.$('#nextButton');
const isNextButtonDisabled = await page.evaluate(
(button) => button.disabled,
nextBtn,
);
expect(isNextButtonDisabled).toBe(false);
const userList = await page.$('#user-list');
let initialUserCount = await userList.$$eval('li', (items) => items.length);
expect(initialUserCount).toBeGreaterThan(0);

// Click the "next" button and wait for the page to load
await nextBtn.click();
// Scroll to the bottom of the page to trigger infinite scroll
await page.evaluate(() => {
window.scrollTo(0, document.body.scrollHeight);
});
await page.waitForNetworkIdle();

// Check that the "next" button is still present and the "previous" button is not disabled
const updatedNextButton = await page.$('#nextButton');
expect(updatedNextButton).toBeTruthy();

const prevBtn = await page.$('#prevButton');
const isPrevButtonDisabled = await page.evaluate(
(button) => button.disabled,
prevBtn,
const updatedUserCount = await userList.$$eval(
'li',
(items) => items.length,
);
expect(isPrevButtonDisabled).toBe(false);
expect(updatedUserCount).toBeGreaterThanOrEqual(initialUserCount);
});

it('Clicking on filter button should display filter modal', async () => {
Expand Down
1 change: 1 addition & 0 deletions users/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const RDS_API_USERS = `${API_BASE_URL}/users`;
const RDS_API_SKILLS = `${API_BASE_URL}/tags`;
const USER_LIST_ELEMENT = 'user-list';
const LOADER_ELEMENT = 'loader';
const USER_LOADER_ELEMENT = 'loader_tag';
const TILE_VIEW_BTN = 'tile-view-btn';
const TABLE_VIEW_BTN = 'table-view-btn';
const USER_SEARCH_ELEMENT = 'user-search';
Expand Down
2 changes: 2 additions & 0 deletions users/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ <h2>Skills</h2>
</div>
<div id="user-list">
<div id="loader"></div>
<ul id="head_list"></ul>
</div>
<div id="loader_tag" style="display: none"></div>
<div id="pagination" class="remove-element">
<button class="pagination-btn" id="prevButton">&laquo; Previous</button>
<button class="pagination-btn" id="nextButton">Next &raquo;</button>
Expand Down
132 changes: 64 additions & 68 deletions users/script.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const params = new URLSearchParams(window.location.search);
const userListElement = document.getElementById(USER_LIST_ELEMENT);
const loaderElement = document.getElementById(LOADER_ELEMENT);
const userloaderElement = document.getElementById(USER_LOADER_ELEMENT);
const tileViewBtn = document.getElementById(TILE_VIEW_BTN);
const tableViewBtn = document.getElementById(TABLE_VIEW_BTN);
const userSearchElement = document.getElementById(USER_SEARCH_ELEMENT);
Expand All @@ -15,7 +16,9 @@ const clearButton = document.getElementById(CLEAR_BUTTON);

let tileViewActive = false;
let tableViewActive = true;
let isLoading = false;
let page = 0;
let run = true;

const init = (
prevBtn,
Expand All @@ -27,26 +30,23 @@ const init = (
paginationElement,
loaderElement,
) => {
prevBtn.addEventListener('click', () => {
showUserDataList(
--page,
userListElement,
paginationElement,
loaderElement,
prevBtn,
nextBtn,
);
});

nextBtn.addEventListener('click', () => {
showUserDataList(
++page,
userListElement,
paginationElement,
loaderElement,
prevBtn,
nextBtn,
);
window.addEventListener('scroll', async () => {
console.log('Page No is: ' + page);
if (
window.innerHeight + window.scrollY >= document.body.offsetHeight - 100 &&
run
) {
if (!run) {
return;
}
run = false;
showUserDataList(
page++,
userListElement,
paginationElement,
loaderElement,
);
}
});

tileViewBtn.addEventListener('click', () => {
Expand Down Expand Up @@ -86,6 +86,8 @@ function showTileView(userListElement, tableViewBtn, tileViewBtn) {
tableViewBtn.classList.remove('btn-active');
tileViewBtn.classList.add('btn-active');
const listContainerElement = userListElement.lastChild;
const headList = document.getElementById('head_list');
headList.classList.add('tile-webview');
listContainerElement.childNodes.forEach((listElement) => {
const imgElement = listElement.firstChild;
imgElement.classList.add('remove-element');
Expand Down Expand Up @@ -149,14 +151,7 @@ function generateUserList(
userListElement,
paginationElement,
loaderElement,
prevBtn,
) {
userListElement.innerHTML = '';
if (page <= 0) {
prevBtn.classList.add('btn-disabled');
} else {
prevBtn.classList.remove('btn-disabled');
}
if (!users || !users.length) {
showErrorMessage(
'No data found',
Expand All @@ -166,40 +161,39 @@ function generateUserList(
);
return;
}
const ulElement = document.createElement('ul');
users.forEach((userData) => {
const listElement = document.createElement('li');
const imgElement = document.createElement('img');
imgElement.src = userData.picture ? userData.picture : DEFAULT_AVATAR;
imgElement.classList.add('user-img-dimension');
const pElement = document.createElement('p');
const node = document.createTextNode(
`${userData.first_name} ${userData.last_name}`,
);
pElement.appendChild(node);
listElement.appendChild(imgElement);
listElement.appendChild(pElement);

if (tileViewActive) {
let imgElement = listElement.firstChild;
listElement.classList.remove('tile-width');
imgElement.classList.add('remove-element');
}
listElement.onclick = () => {
document.getElementById('user-search').value = '';
window.location.href = `/users/details/index.html?username=${userData.username}`;
};
ulElement.appendChild(listElement);
});
loaderElement.classList.add('remove-element');
if (showPagination) {
paginationElement.classList.remove('remove-element');
paginationElement.classList.add('pagination');
} else {
paginationElement.classList.add('remove-element');
paginationElement.classList.remove('pagination');
const ulElement = document.getElementById('head_list');

if (users != null) {
users.forEach((userData) => {
const listElement = document.createElement('li');
const imgElement = document.createElement('img');
imgElement.src = userData.picture ? userData.picture : DEFAULT_AVATAR;
imgElement.classList.add('user-img-dimension');
listElement.classList.add('tile-webview');
const pElement = document.createElement('p');
const node = document.createTextNode(
`${userData.first_name} ${userData.last_name}`,
);
pElement.appendChild(node);
listElement.appendChild(imgElement);
listElement.appendChild(pElement);

if (tileViewActive) {
let imgElement = listElement.firstChild;
listElement.classList.add('tile-width');
imgElement.classList.add('remove-element');
}
listElement.onclick = () => {
document.getElementById('user-search').value = '';
window.location.href = `/users/details/index.html?username=${userData.username}`;
};
ulElement.appendChild(listElement);
});
loaderElement.classList.add('remove-element');
userListElement.appendChild(ulElement);
run = true;
}
userListElement.appendChild(ulElement);
}

async function fetchUsersData(searchInput) {
Expand Down Expand Up @@ -333,17 +327,17 @@ const showUserDataList = async (
userListElement,
paginationElement,
loaderElement,
prevBtn,
nextBtn,
) => {
try {
if (isLoading) return;
if (page != 0) {
isLoading = true;
userloaderElement.style.display = 'block';
}

const userData = await getUsersData(page);
if (userData.length) {
if (userData.length < USER_FETCH_COUNT) {
nextBtn.classList.add('btn-disabled');
} else {
nextBtn.classList.remove('btn-disabled');
}

if (userData && userData.length) {
let usersDataList = userData.filter(
(user) => user.first_name && !user.roles?.archived,
);
Expand All @@ -359,7 +353,6 @@ const showUserDataList = async (
userListElement,
paginationElement,
loaderElement,
prevBtn,
);
}
} catch (err) {
Expand All @@ -370,6 +363,9 @@ const showUserDataList = async (
paginationElement,
loaderElement,
);
} finally {
userloaderElement.style.display = 'none';
isLoading = false;
}
};

Expand Down
17 changes: 16 additions & 1 deletion users/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,12 @@ li p {
white-space: nowrap;
}

.tile-webview {
display: block;
}

.tile-width {
width: 200px;
width: 400px;
}

.error-text {
Expand All @@ -145,10 +149,21 @@ li p {
margin: 150px auto;
}

#loader_tag {
border: 5px solid var(--gray-color);
border-top: 5px solid var(--loader-blue-color);
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 2s linear infinite;
margin: 150px auto;
}

.pagination {
display: flex;
justify-content: space-between;
margin-top: auto;
visibility: hidden;
}

.pagination-btn {
Expand Down

0 comments on commit d1726ed

Please sign in to comment.