Skip to content

Commit

Permalink
Added sort by for groups by creation date and member groups. (#659)
Browse files Browse the repository at this point in the history
* Added sort by creation date and members.

* Reduced padding

* Remove dead code

* Made small modification

* Changed the dropdown opening lines in test

* Changed the variables name

* Changed the variabled name

* Changed variabled name

* Changed variable names

* Added sort by last used on

---------

Co-authored-by: Shubham Sharma <[email protected]>
  • Loading branch information
skv93-coder and Shubham Sharma authored Dec 27, 2023
1 parent f512d39 commit 549b07f
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 36 deletions.
87 changes: 84 additions & 3 deletions __tests__/groups/group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { allUsersData } = require('../../mock-data/users');
const { discordGroups, GroupRoleData } = require('../../mock-data/groups');

const BASE_URL = 'https://api.realdevsquad.com';
const PAGE_URL = 'http://localhost:8000';

describe('Discord Groups Page', () => {
let browser;
Expand Down Expand Up @@ -135,7 +136,7 @@ describe('Discord Groups Page', () => {
interceptedRequest.continue();
}
});
await page.goto('http://localhost:8000/groups');
await page.goto(`${PAGE_URL}/groups`);
await page.waitForNetworkIdle();
});

Expand Down Expand Up @@ -319,7 +320,7 @@ describe('Discord Groups Page', () => {
});

test('should update input field and filter group list with search value in URL', async () => {
await page.goto('http://localhost:8000/groups/?dev=true&DSA');
await page.goto(`${PAGE_URL}/groups/?dev=true&DSA`);
manageGroup = await page.$('.manage-groups-tab');
await manageGroup.click();
const searchInput = await page.$('#search-groups');
Expand All @@ -341,12 +342,92 @@ describe('Discord Groups Page', () => {
});

test('should select the group from URL and have active-group class', async () => {
await page.goto('http://localhost:8000/groups?DSA');
await page.goto(`${PAGE_URL}/groups?DSA`);
const activeGroup = await page.$('.active-group');
const groupName = await page.evaluate(
(element) => element.innerText,
activeGroup,
);
expect(groupName).toMatch('DSA');
});
test('On click on "Popular within dev" will result group with most member at the top', async () => {
await page.goto(`${PAGE_URL}/groups?dev=true`);
await page.waitForNetworkIdle();

const groupsBeforeSort = await page.$$eval('.group-name', (elements) => {
return elements.map((element) =>
element.getAttribute('data-member-count'),
);
});
await page.$$eval('#dropdown_main', (el) => {
el[0].click();
});

await page.$$eval('[data-list="1"]', (el) => {
el[0].click();
});
const groupsAfterSort = await page.$$eval('.group-name', (elements) => {
return elements.map((element) =>
element.getAttribute('data-member-count'),
);
});
const manualSortedGroup = groupsBeforeSort.sort((a, b) => b - a);
expect(groupsAfterSort).toEqual(manualSortedGroup);
});
test('On click on "Recently created" will result in latest created group at the top', async () => {
await page.goto(`${PAGE_URL}/groups?dev=true`);
await page.waitForNetworkIdle();

const groupNameCreateDateLookup = {};
discordGroups.groups.forEach((group) => {
const grpName = group.rolename.split('-').slice(1).join('-');
groupNameCreateDateLookup[grpName] = group.date._seconds;
});
const groupsBeforeSort = await page.$$eval('.group-name', (elements) => {
return elements.map((element) => element.innerText);
});

await page.$$eval('#dropdown_main', (el) => {
el[0].click();
});
await page.$$eval('[data-list="2"]', (el) => {
el[0].click();
});
const groupAfterSort = await page.$$eval('.group-name', (elements) => {
return elements.map((element) => element.innerText);
});
const manualSortedGroup = groupsBeforeSort.sort(
(a, b) => groupNameCreateDateLookup[b] - groupNameCreateDateLookup[a],
);
expect(groupAfterSort).toEqual(manualSortedGroup);
});
test('On click on "Recently used" will result in recently used group at the top', async () => {
await page.goto(`${PAGE_URL}/groups?dev=true`);
await page.waitForNetworkIdle();

const groupNameCreateDateLookup = {};
discordGroups.groups.forEach((group) => {
const grpName = group.rolename.split('-').slice(1).join('-');
groupNameCreateDateLookup[grpName] = group.lastUsedOn
? group.lastUsedOn._seconds
: 0;
});
const groupsBeforeSort = await page.$$eval('.group-name', (elements) => {
return elements.map((element) => element.innerText);
});

await page.$$eval('#dropdown_main', (el) => {
el[0].click();
});
await page.$$eval('[data-list="3"]', (el) => {
el[0].click();
});
const groupAfterSort = await page.$$eval('.group-name', (elements) => {
return elements.map((element) => element.innerText);
});
const manualSortedGroup = groupsBeforeSort.sort(
(a, b) => groupNameCreateDateLookup[b] - groupNameCreateDateLookup[a],
);
expect(groupAfterSort).toEqual(manualSortedGroup);
});
});
12 changes: 11 additions & 1 deletion groups/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
const NO_SPACES_ALLOWED = 'Roles cannot have spaces';
const CANNOT_CONTAIN_GROUP = "Roles cannot contain 'group'.";
const DEV_FEATURE_FLAG = 'dev';
const SortByFields = [
{ id: '1', fieldName: 'memberCount' },
{ id: '2', fieldName: 'date._seconds' },
{ id: '3', fieldName: 'lastUsedOn._seconds' },
];

export { NO_SPACES_ALLOWED, CANNOT_CONTAIN_GROUP, DEV_FEATURE_FLAG };
export {
SortByFields,
NO_SPACES_ALLOWED,
CANNOT_CONTAIN_GROUP,
DEV_FEATURE_FLAG,
};
8 changes: 8 additions & 0 deletions groups/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ <h3 class="not-verified-tag hidden">
<ul class="groups-list"></ul>
</aside>
<main>
<div class="dropdown hidden" id="dropdown_container">
<button class="task_filter-button" id="sortby_text">Sort by</button>
<div id="dropdown_main" class="dropdown-content">
<a data-list="1">Popular within dev</a>
<a data-list="2">Recently created</a>
<a data-list="3">Recently used</a>
</div>
</div>
<button class="btn btn-add-role" disabled>
Add me to this group
</button>
Expand Down
127 changes: 96 additions & 31 deletions groups/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CANNOT_CONTAIN_GROUP,
DEV_FEATURE_FLAG,
NO_SPACES_ALLOWED,
SortByFields,
} from './constants.js';
import {
removeGroupKeywordFromDiscordRoleName,
Expand All @@ -22,6 +23,19 @@ const userIsNotVerifiedText = document.querySelector('.not-verified-tag');
const params = new URLSearchParams(window.location.search);
const searchValue = getSearchValueFromURL();
const isDev = params.get(DEV_FEATURE_FLAG) === 'true';
const dropdownContainer = document.getElementById('dropdown_container');

//Dropdown
const dropdownMain = document.getElementById('dropdown_main');
const dropdownTxt = document.getElementById('sortby_text');
function toggleDropDown() {
dropdownMain.classList.toggle('show_filter');
}
dropdownTxt.addEventListener('click', toggleDropDown);
if (isDev) {
dropdownContainer.classList.remove('hidden');
dropdownMain.addEventListener('click', onDropdownClick);
}
// const paragraphElement = null, paragraphContent = '';

const searchInput = document.getElementById('search-groups');
Expand Down Expand Up @@ -78,44 +92,95 @@ const memberAddRoleBody = {
*/
const groupsData = await getDiscordGroups();
const groupRoles = document.querySelector('.groups-list');
groupsData?.forEach((item) => {
const group = document.createElement('li');
group.setAttribute('id', item.roleid);
group.classList.add('group-role');
const formattedRoleName = removeGroupKeywordFromDiscordRoleName(
item.rolename,
);

//If searchValue present, filter out the list
if (searchValue) {
group.style.display = formattedRoleName
.toUpperCase()
.includes(searchValue.toUpperCase())
? ''
: 'none';
}
const renderGroups = () => {
groupRoles.innerHTML = null;
groupsData?.forEach((item) => {
const group = document.createElement('li');
group.setAttribute('id', item.roleid);
group.classList.add('group-role');
const formattedRoleName = removeGroupKeywordFromDiscordRoleName(
item.rolename,
);

//If searchValue present, filter out the list
if (searchValue) {
group.style.display = formattedRoleName
.toUpperCase()
.includes(searchValue.toUpperCase())
? ''
: 'none';
}

const groupname = document.createElement('p');
groupname.classList.add('group-name');
groupname.setAttribute('id', `name-${item.roleid}`);
const groupname = document.createElement('p');
groupname.classList.add('group-name');
groupname.setAttribute('id', `name-${item.roleid}`);

if (item.memberCount !== null && item.memberCount !== undefined) {
groupname.setAttribute('data-member-count', item.memberCount);
}
if (item.memberCount !== null && item.memberCount !== undefined) {
groupname.setAttribute('data-member-count', item.memberCount);
}

groupname.textContent = formattedRoleName;
groupname.textContent = formattedRoleName;

const createdBy = createAuthorDetailsDOM(
item.firstName,
item.lastName,
item.image,
);
const createdBy = createAuthorDetailsDOM(
item.firstName,
item.lastName,
item.image,
);

group.appendChild(groupname);
group.appendChild(createdBy);
groupRoles.appendChild(group);
});
group.appendChild(groupname);
group.appendChild(createdBy);
groupRoles.appendChild(group);
});
};

const giveABForCompariosn = (a, b, field) => {
let data = [0, 0];
switch (field) {
case 'date._seconds':
data[0] = a.date._seconds;
data[1] = b.date._seconds;
break;
case 'memberCount':
data[0] = a.memberCount || 0;
data[1] = b.memberCount || 0;
break;
case 'lastUsedOn._seconds':
if (a.lastUsedOn) {
data[0] = a.lastUsedOn._seconds;
}
if (b.lastUsedOn) {
data[1] = b.lastUsedOn._seconds;
}
break;
default:
data = [0, 0];
}
return data;
};

function onDropdownClick(ev) {
const clickedOptionsId = ev.target.dataset.list;
const fieldToSortBy = SortByFields.find(
(field) => field.id === clickedOptionsId,
);
groupsData.sort((firstObj, secondObj) => {
const [a, b] = giveABForCompariosn(
firstObj,
secondObj,
fieldToSortBy.fieldName,
);
if (a > b) {
return -1;
} else if (b < a) {
return 1;
}
return 0;
});
renderGroups();
}

renderGroups();
/**
* FOR RENDERING TABS
* I.E. MANAGE ROLES, CREATE GROUP
Expand Down
61 changes: 60 additions & 1 deletion groups/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
--color-white: rgb(255, 255, 255);
--color-not-verified: rgb(255, 0, 0);
--color-member-count: #717171;
--color-group-dropdown-background: #f6f6f6;
--color-group-dropdown-border-color: #ddd;
}
.container {
font-family: 'Roboto', sans-serif;
Expand Down Expand Up @@ -101,7 +103,7 @@
display: flex;
}
.manage-groups main {
padding: 1rem 4rem;
padding: 1rem 2rem;
flex: 1;
}

Expand Down Expand Up @@ -284,6 +286,63 @@ NOT VERIFIED TEXT ABOVE
text-align: center;
}

.dropdown {
position: relative;
display: inline-block;
}

.dropdown-content {
display: none;
position: absolute;
background-color: var(--color-group-dropdown-background);
min-width: 14rem;
overflow: auto;
border: 1px solid var(--color-group-dropdown-border-color);
z-index: 1;
}

.dropdown-content a {
padding: 0.75rem 1rem;
text-decoration: none;
display: block;
}

.dropdown a:hover {
background-color: var(--color-group-dropdown-border-color);
}

.show_filter {
display: block;
}

.dropdown-content {
cursor: pointer;
}

.task_filter-button {
width: 5rem;
height: 2rem;
border-radius: 0.27rem 0 0 0.27rem;
background-color: var(--color-group-dropdown-background);
color: #000;
font-weight: 700;
cursor: pointer;
outline: none;
display: flex;
flex-direction: row;
align-items: center;
padding-left: 0.3rem;
border: 1px solid var(--color-group-dropdown-border-color);
}

.task_filter-button:after {
content: '';
border-left: 0.3rem solid transparent;
border-right: 0.3rem solid transparent;
border-top: 0.3rem solid;
margin-left: 0.5rem;
}

@media (max-width: 650px) {
.btn-add-role {
position: static;
Expand Down
Loading

0 comments on commit 549b07f

Please sign in to comment.