Skip to content

Commit 863d57e

Browse files
authored
Merge pull request #661 from Real-Dev-Squad/develop
Dev to main sync
2 parents 9ee2061 + 549b07f commit 863d57e

File tree

8 files changed

+280
-52
lines changed

8 files changed

+280
-52
lines changed

__tests__/groups/group.test.js

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { allUsersData } = require('../../mock-data/users');
33
const { discordGroups, GroupRoleData } = require('../../mock-data/groups');
44

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

78
describe('Discord Groups Page', () => {
89
let browser;
@@ -135,7 +136,7 @@ describe('Discord Groups Page', () => {
135136
interceptedRequest.continue();
136137
}
137138
});
138-
await page.goto('http://localhost:8000/groups');
139+
await page.goto(`${PAGE_URL}/groups`);
139140
await page.waitForNetworkIdle();
140141
});
141142

@@ -319,7 +320,7 @@ describe('Discord Groups Page', () => {
319320
});
320321

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

343344
test('should select the group from URL and have active-group class', async () => {
344-
await page.goto('http://localhost:8000/groups?DSA');
345+
await page.goto(`${PAGE_URL}/groups?DSA`);
345346
const activeGroup = await page.$('.active-group');
346347
const groupName = await page.evaluate(
347348
(element) => element.innerText,
348349
activeGroup,
349350
);
350351
expect(groupName).toMatch('DSA');
351352
});
353+
test('On click on "Popular within dev" will result group with most member at the top', async () => {
354+
await page.goto(`${PAGE_URL}/groups?dev=true`);
355+
await page.waitForNetworkIdle();
356+
357+
const groupsBeforeSort = await page.$$eval('.group-name', (elements) => {
358+
return elements.map((element) =>
359+
element.getAttribute('data-member-count'),
360+
);
361+
});
362+
await page.$$eval('#dropdown_main', (el) => {
363+
el[0].click();
364+
});
365+
366+
await page.$$eval('[data-list="1"]', (el) => {
367+
el[0].click();
368+
});
369+
const groupsAfterSort = await page.$$eval('.group-name', (elements) => {
370+
return elements.map((element) =>
371+
element.getAttribute('data-member-count'),
372+
);
373+
});
374+
const manualSortedGroup = groupsBeforeSort.sort((a, b) => b - a);
375+
expect(groupsAfterSort).toEqual(manualSortedGroup);
376+
});
377+
test('On click on "Recently created" will result in latest created group at the top', async () => {
378+
await page.goto(`${PAGE_URL}/groups?dev=true`);
379+
await page.waitForNetworkIdle();
380+
381+
const groupNameCreateDateLookup = {};
382+
discordGroups.groups.forEach((group) => {
383+
const grpName = group.rolename.split('-').slice(1).join('-');
384+
groupNameCreateDateLookup[grpName] = group.date._seconds;
385+
});
386+
const groupsBeforeSort = await page.$$eval('.group-name', (elements) => {
387+
return elements.map((element) => element.innerText);
388+
});
389+
390+
await page.$$eval('#dropdown_main', (el) => {
391+
el[0].click();
392+
});
393+
await page.$$eval('[data-list="2"]', (el) => {
394+
el[0].click();
395+
});
396+
const groupAfterSort = await page.$$eval('.group-name', (elements) => {
397+
return elements.map((element) => element.innerText);
398+
});
399+
const manualSortedGroup = groupsBeforeSort.sort(
400+
(a, b) => groupNameCreateDateLookup[b] - groupNameCreateDateLookup[a],
401+
);
402+
expect(groupAfterSort).toEqual(manualSortedGroup);
403+
});
404+
test('On click on "Recently used" will result in recently used group at the top', async () => {
405+
await page.goto(`${PAGE_URL}/groups?dev=true`);
406+
await page.waitForNetworkIdle();
407+
408+
const groupNameCreateDateLookup = {};
409+
discordGroups.groups.forEach((group) => {
410+
const grpName = group.rolename.split('-').slice(1).join('-');
411+
groupNameCreateDateLookup[grpName] = group.lastUsedOn
412+
? group.lastUsedOn._seconds
413+
: 0;
414+
});
415+
const groupsBeforeSort = await page.$$eval('.group-name', (elements) => {
416+
return elements.map((element) => element.innerText);
417+
});
418+
419+
await page.$$eval('#dropdown_main', (el) => {
420+
el[0].click();
421+
});
422+
await page.$$eval('[data-list="3"]', (el) => {
423+
el[0].click();
424+
});
425+
const groupAfterSort = await page.$$eval('.group-name', (elements) => {
426+
return elements.map((element) => element.innerText);
427+
});
428+
const manualSortedGroup = groupsBeforeSort.sort(
429+
(a, b) => groupNameCreateDateLookup[b] - groupNameCreateDateLookup[a],
430+
);
431+
expect(groupAfterSort).toEqual(manualSortedGroup);
432+
});
352433
});

__tests__/taskRequests/taskRequest.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ describe('Task Requests', () => {
107107
expect(
108108
await modal.evaluate((el) => el.classList.contains('hidden')),
109109
).toBe(false);
110-
await page.mouse.click(20, 20);
110+
await page.mouse.click(200, 200);
111111
expect(
112112
await modal.evaluate((el) => el.classList.contains('hidden')),
113113
).toBe(true);

groups/constants.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
const NO_SPACES_ALLOWED = 'Roles cannot have spaces';
22
const CANNOT_CONTAIN_GROUP = "Roles cannot contain 'group'.";
33
const DEV_FEATURE_FLAG = 'dev';
4+
const SortByFields = [
5+
{ id: '1', fieldName: 'memberCount' },
6+
{ id: '2', fieldName: 'date._seconds' },
7+
{ id: '3', fieldName: 'lastUsedOn._seconds' },
8+
];
49

5-
export { NO_SPACES_ALLOWED, CANNOT_CONTAIN_GROUP, DEV_FEATURE_FLAG };
10+
export {
11+
SortByFields,
12+
NO_SPACES_ALLOWED,
13+
CANNOT_CONTAIN_GROUP,
14+
DEV_FEATURE_FLAG,
15+
};

groups/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ <h3 class="not-verified-tag hidden">
3636
<ul class="groups-list"></ul>
3737
</aside>
3838
<main>
39+
<div class="dropdown hidden" id="dropdown_container">
40+
<button class="task_filter-button" id="sortby_text">Sort by</button>
41+
<div id="dropdown_main" class="dropdown-content">
42+
<a data-list="1">Popular within dev</a>
43+
<a data-list="2">Recently created</a>
44+
<a data-list="3">Recently used</a>
45+
</div>
46+
</div>
3947
<button class="btn btn-add-role" disabled>
4048
Add me to this group
4149
</button>

groups/script.js

Lines changed: 96 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
CANNOT_CONTAIN_GROUP,
44
DEV_FEATURE_FLAG,
55
NO_SPACES_ALLOWED,
6+
SortByFields,
67
} from './constants.js';
78
import {
89
removeGroupKeywordFromDiscordRoleName,
@@ -22,6 +23,19 @@ const userIsNotVerifiedText = document.querySelector('.not-verified-tag');
2223
const params = new URLSearchParams(window.location.search);
2324
const searchValue = getSearchValueFromURL();
2425
const isDev = params.get(DEV_FEATURE_FLAG) === 'true';
26+
const dropdownContainer = document.getElementById('dropdown_container');
27+
28+
//Dropdown
29+
const dropdownMain = document.getElementById('dropdown_main');
30+
const dropdownTxt = document.getElementById('sortby_text');
31+
function toggleDropDown() {
32+
dropdownMain.classList.toggle('show_filter');
33+
}
34+
dropdownTxt.addEventListener('click', toggleDropDown);
35+
if (isDev) {
36+
dropdownContainer.classList.remove('hidden');
37+
dropdownMain.addEventListener('click', onDropdownClick);
38+
}
2539
// const paragraphElement = null, paragraphContent = '';
2640

2741
const searchInput = document.getElementById('search-groups');
@@ -78,44 +92,95 @@ const memberAddRoleBody = {
7892
*/
7993
const groupsData = await getDiscordGroups();
8094
const groupRoles = document.querySelector('.groups-list');
81-
groupsData?.forEach((item) => {
82-
const group = document.createElement('li');
83-
group.setAttribute('id', item.roleid);
84-
group.classList.add('group-role');
85-
const formattedRoleName = removeGroupKeywordFromDiscordRoleName(
86-
item.rolename,
87-
);
8895

89-
//If searchValue present, filter out the list
90-
if (searchValue) {
91-
group.style.display = formattedRoleName
92-
.toUpperCase()
93-
.includes(searchValue.toUpperCase())
94-
? ''
95-
: 'none';
96-
}
96+
const renderGroups = () => {
97+
groupRoles.innerHTML = null;
98+
groupsData?.forEach((item) => {
99+
const group = document.createElement('li');
100+
group.setAttribute('id', item.roleid);
101+
group.classList.add('group-role');
102+
const formattedRoleName = removeGroupKeywordFromDiscordRoleName(
103+
item.rolename,
104+
);
105+
106+
//If searchValue present, filter out the list
107+
if (searchValue) {
108+
group.style.display = formattedRoleName
109+
.toUpperCase()
110+
.includes(searchValue.toUpperCase())
111+
? ''
112+
: 'none';
113+
}
97114

98-
const groupname = document.createElement('p');
99-
groupname.classList.add('group-name');
100-
groupname.setAttribute('id', `name-${item.roleid}`);
115+
const groupname = document.createElement('p');
116+
groupname.classList.add('group-name');
117+
groupname.setAttribute('id', `name-${item.roleid}`);
101118

102-
if (item.memberCount !== null && item.memberCount !== undefined) {
103-
groupname.setAttribute('data-member-count', item.memberCount);
104-
}
119+
if (item.memberCount !== null && item.memberCount !== undefined) {
120+
groupname.setAttribute('data-member-count', item.memberCount);
121+
}
105122

106-
groupname.textContent = formattedRoleName;
123+
groupname.textContent = formattedRoleName;
107124

108-
const createdBy = createAuthorDetailsDOM(
109-
item.firstName,
110-
item.lastName,
111-
item.image,
112-
);
125+
const createdBy = createAuthorDetailsDOM(
126+
item.firstName,
127+
item.lastName,
128+
item.image,
129+
);
113130

114-
group.appendChild(groupname);
115-
group.appendChild(createdBy);
116-
groupRoles.appendChild(group);
117-
});
131+
group.appendChild(groupname);
132+
group.appendChild(createdBy);
133+
groupRoles.appendChild(group);
134+
});
135+
};
136+
137+
const giveABForCompariosn = (a, b, field) => {
138+
let data = [0, 0];
139+
switch (field) {
140+
case 'date._seconds':
141+
data[0] = a.date._seconds;
142+
data[1] = b.date._seconds;
143+
break;
144+
case 'memberCount':
145+
data[0] = a.memberCount || 0;
146+
data[1] = b.memberCount || 0;
147+
break;
148+
case 'lastUsedOn._seconds':
149+
if (a.lastUsedOn) {
150+
data[0] = a.lastUsedOn._seconds;
151+
}
152+
if (b.lastUsedOn) {
153+
data[1] = b.lastUsedOn._seconds;
154+
}
155+
break;
156+
default:
157+
data = [0, 0];
158+
}
159+
return data;
160+
};
161+
162+
function onDropdownClick(ev) {
163+
const clickedOptionsId = ev.target.dataset.list;
164+
const fieldToSortBy = SortByFields.find(
165+
(field) => field.id === clickedOptionsId,
166+
);
167+
groupsData.sort((firstObj, secondObj) => {
168+
const [a, b] = giveABForCompariosn(
169+
firstObj,
170+
secondObj,
171+
fieldToSortBy.fieldName,
172+
);
173+
if (a > b) {
174+
return -1;
175+
} else if (b < a) {
176+
return 1;
177+
}
178+
return 0;
179+
});
180+
renderGroups();
181+
}
118182

183+
renderGroups();
119184
/**
120185
* FOR RENDERING TABS
121186
* I.E. MANAGE ROLES, CREATE GROUP

groups/style.css

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
--color-white: rgb(255, 255, 255);
1414
--color-not-verified: rgb(255, 0, 0);
1515
--color-member-count: #717171;
16+
--color-group-dropdown-background: #f6f6f6;
17+
--color-group-dropdown-border-color: #ddd;
1618
}
1719
.container {
1820
font-family: 'Roboto', sans-serif;
@@ -101,7 +103,7 @@
101103
display: flex;
102104
}
103105
.manage-groups main {
104-
padding: 1rem 4rem;
106+
padding: 1rem 2rem;
105107
flex: 1;
106108
}
107109

@@ -284,6 +286,63 @@ NOT VERIFIED TEXT ABOVE
284286
text-align: center;
285287
}
286288

289+
.dropdown {
290+
position: relative;
291+
display: inline-block;
292+
}
293+
294+
.dropdown-content {
295+
display: none;
296+
position: absolute;
297+
background-color: var(--color-group-dropdown-background);
298+
min-width: 14rem;
299+
overflow: auto;
300+
border: 1px solid var(--color-group-dropdown-border-color);
301+
z-index: 1;
302+
}
303+
304+
.dropdown-content a {
305+
padding: 0.75rem 1rem;
306+
text-decoration: none;
307+
display: block;
308+
}
309+
310+
.dropdown a:hover {
311+
background-color: var(--color-group-dropdown-border-color);
312+
}
313+
314+
.show_filter {
315+
display: block;
316+
}
317+
318+
.dropdown-content {
319+
cursor: pointer;
320+
}
321+
322+
.task_filter-button {
323+
width: 5rem;
324+
height: 2rem;
325+
border-radius: 0.27rem 0 0 0.27rem;
326+
background-color: var(--color-group-dropdown-background);
327+
color: #000;
328+
font-weight: 700;
329+
cursor: pointer;
330+
outline: none;
331+
display: flex;
332+
flex-direction: row;
333+
align-items: center;
334+
padding-left: 0.3rem;
335+
border: 1px solid var(--color-group-dropdown-border-color);
336+
}
337+
338+
.task_filter-button:after {
339+
content: '';
340+
border-left: 0.3rem solid transparent;
341+
border-right: 0.3rem solid transparent;
342+
border-top: 0.3rem solid;
343+
margin-left: 0.5rem;
344+
}
345+
287346
@media (max-width: 650px) {
288347
.btn-add-role {
289348
position: static;

0 commit comments

Comments
 (0)