diff --git a/__tests__/extension-requests/extension-requests.test.js b/__tests__/extension-requests/extension-requests.test.js index 4d5dc83c..ea65a9c6 100644 --- a/__tests__/extension-requests/extension-requests.test.js +++ b/__tests__/extension-requests/extension-requests.test.js @@ -37,7 +37,10 @@ describe('Tests the Extension Requests Screen', () => { page.on('request', (interceptedRequest) => { const url = interceptedRequest.url(); - if (url === 'https://api.realdevsquad.com/extension-requests') { + if ( + url === + 'https://api.realdevsquad.com/extension-requests?order=asc&size=5&q=status%3APENDING' + ) { interceptedRequest.respond({ status: 200, contentType: 'application/json', @@ -46,11 +49,24 @@ describe('Tests the Extension Requests Screen', () => { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, - body: JSON.stringify(extensionRequestsList), + body: JSON.stringify(extensionRequestsListPending), + }); + } else if ( + url === 'https://api.realdevsquad.com/users/search?role=in_discord' + ) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(allUsersData), }); } else if ( url === - 'https://api.realdevsquad.com/extension-requests?order=asc&size=5&dev=true&q=status%3APENDING' + 'https://api.realdevsquad.com/extension-requests?order=desc&size=5&q=status%3APENDING' ) { interceptedRequest.respond({ status: 200, @@ -60,11 +76,24 @@ describe('Tests the Extension Requests Screen', () => { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, - body: JSON.stringify(extensionRequestsListPending), + body: JSON.stringify(extensionRequestsListPendingDescending), + }); + } else if ( + url === 'https://api.realdevsquad.com/users?search=sunny&size=1' + ) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(userSunny), }); } else if ( url === - 'https://api.realdevsquad.com/extension-requests?assignee=jbGcfZLGYjHwxQ1Zh8ZJ&status=PENDING&size=5&order=asc' + 'https://api.realdevsquad.com/tasks/PYj79ki2agB0q5JN3kUf/details' ) { interceptedRequest.respond({ status: 200, @@ -74,11 +103,11 @@ describe('Tests the Extension Requests Screen', () => { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, - body: JSON.stringify(extensionRequestsListUserSearch), + body: JSON.stringify(taskDone), }); } else if ( url === - 'https://api.realdevsquad.com/extension-requests?status=PENDING&size=5&order=asc' + 'https://api.realdevsquad.com/tasks/GCYGDiU0lw4fwc3qljSY/details' ) { interceptedRequest.respond({ status: 200, @@ -88,11 +117,11 @@ describe('Tests the Extension Requests Screen', () => { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, - body: JSON.stringify(extensionRequestsListPending), + body: JSON.stringify(taskDone), }); } else if ( url === - 'https://api.realdevsquad.com/extension-requests?q=status%3AAPPROVED&dev=true&size=5&order=asc' + 'https://api.realdevsquad.com/extension-requests/QISvF7kAmnD9vXHwwIsG/status' ) { interceptedRequest.respond({ status: 200, @@ -102,10 +131,25 @@ describe('Tests the Extension Requests Screen', () => { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, - body: JSON.stringify(extensionRequestsListApproved), + body: JSON.stringify(extensionRequestResponse), }); } else if ( - url === 'https://api.realdevsquad.com/users/search?role=in_discord' + url === + 'https://api.realdevsquad.com/extension-requests/lGQ3AjUlgNB6Jd8jXaEC/status' + ) { + interceptedRequest.respond({ + status: 400, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(extensionRequestResponse), + }); + } else if ( + url === + 'https://api.realdevsquad.com/extension-requests/lGQ3AjUlgNB6Jd8jXaEC' ) { interceptedRequest.respond({ status: 200, @@ -115,13 +159,43 @@ describe('Tests the Extension Requests Screen', () => { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, - body: JSON.stringify(allUsersData), + body: JSON.stringify({}), + }); + } else if ( + url === + 'https://api.realdevsquad.com/extension-requests?order=asc&size=5&q=status%3APENDING%2Cassignee%3AiODXB6gfsjaZB9p0XlBw' + ) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(extensionRequestsListUserSearch), + }); + } else if ( + url === + 'https://api.realdevsquad.com/extension-requests?order=asc&size=5&q=status%3APENDING%2Cassignee%3AiODXB6gfsjaZB9p0XlBw%2B7yzVDl8s1ORNCtH9Ps7K' + ) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(extensionRequestsList), }); } else { interceptedRequest.continue(); } }); + await page.goto('http://localhost:8000/extension-requests'); + await page.waitForNetworkIdle(); title = await page.$('.header h1'); @@ -137,26 +211,31 @@ describe('Tests the Extension Requests Screen', () => { afterAll(async () => { await browser.close(); }); - - it('Checks the UI elements on Extension requests listing page.', async () => { + it('Checks the UI elements on Extension requests listing page', async () => { + title = await page.$('.header h1'); + searchBar = await page.$('#search'); + filterButton = await page.$('#filter-button'); + extensionCardsList = await page.$$('.extension-card'); + extensionRequestsElement = await page.$('.extension-requests'); expect(title).toBeTruthy(); expect(searchBar).toBeTruthy(); expect(filterButton).toBeTruthy(); + expect(extensionCardsList.length).toBe(4); expect(extensionRequestsElement).toBeTruthy(); }); it('checks the search functionality', async () => { - const ele = await page.$('input[id="assignee-search"]'); await page.type('#assignee-search', 'sunny'); await page.keyboard.press('Enter'); await page.waitForNetworkIdle(); - const cardsList = await page.$$('.extension-request'); + + const cardsList = await page.$$('.extension-card'); expect(cardsList.length).toBe(1); const cardTextContent = await page.evaluate( (element) => element.textContent, cardsList[0], ); - expect(cardTextContent).toContain('sunny'); + expect(cardTextContent).toContain('Sunny'); }); it('clicking on filter button should display filter modal', async () => { @@ -221,230 +300,7 @@ describe('Tests the Extension Requests Screen', () => { const isChecked = await currentState.jsonValue(); expect(isChecked).toBe(false); }); -}); - -describe.skip('Tests the new Extension Requests Screen', () => { - let browser; - let page; - let title; - let searchBar; - let filterButton; - let extensionRequestsElement; - jest.setTimeout(60000); - - beforeAll(async () => { - browser = await puppeteer.launch({ - headless: 'new', - ignoreHTTPSErrors: true, - args: ['--incognito', '--disable-web-security'], - devtools: false, - }); - page = await browser.newPage(); - - await page.setRequestInterception(true); - - page.on('request', (interceptedRequest) => { - const url = interceptedRequest.url(); - if ( - url === - 'https://api.realdevsquad.com/extension-requests?dev=true&size=5&order=asc' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestsList), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests?order=asc&size=5&dev=true&q=status%3APENDING' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestsListPending), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests?order=desc&size=5&dev=true&q=status%3APENDING' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestsListPendingDescending), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests?q=status%3AAPPROVED&dev=true&size=5&order=asc' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestsListApproved), - }); - } else if ( - url === 'https://api.realdevsquad.com/users?search=sunny&size=1' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(userSunny), - }); - } else if ( - url === 'https://api.realdevsquad.com/users?search=randhir&size=1' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(userRandhir), - }); - } else if ( - url === - 'https://api.realdevsquad.com/tasks/PYj79ki2agB0q5JN3kUf/details' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(taskDone), - }); - } else if ( - url === - 'https://api.realdevsquad.com/tasks/GCYGDiU0lw4fwc3qljSY/details' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(taskDone), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests/QISvF7kAmnD9vXHwwIsG/status' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestResponse), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests/lGQ3AjUlgNB6Jd8jXaEC/status' - ) { - interceptedRequest.respond({ - status: 400, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestResponse), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests/lGQ3AjUlgNB6Jd8jXaEC' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify({}), - }); - } else if ( - url === - 'https://api.realdevsquad.com/extension-requests?order=asc&size=5&dev=true&q=status%3APENDING%2Cassignee%3AiODXB6gfsjaZB9p0XlBw%2BDtR9sK7CysOVHP17zl8N' - ) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(extensionRequestsList), - }); - } else { - interceptedRequest.continue(); - } - }); - await page.goto('http://localhost:8000/extension-requests/index.html'); - - await page.waitForNetworkIdle(); - }); - - afterEach(async () => { - await page.goto('http://localhost:8000/extension-requests/index.html'); - - await page.waitForNetworkIdle(); - }); - - afterAll(async () => { - await browser.close(); - }); - - it('Checks the UI elements on Extension requests listing page', async () => { - title = await page.$('.header h1'); - searchBar = await page.$('#search'); - filterButton = await page.$('#filter-button'); - extensionCardsList = await page.$$('.extension-card'); - extensionRequestsElement = await page.$('.extension-requests-new'); - expect(title).toBeTruthy(); - expect(searchBar).toBeTruthy(); - expect(filterButton).toBeTruthy(); - expect(extensionCardsList.length).toBe(4); - expect(extensionRequestsElement).toBeTruthy(); - }); - it('should display cards of when multiple usernames are entered', async () => { - const ele = await page.$('input[id="assignee-search"]'); await page.type('#assignee-search', 'sunny,randhir'); await page.keyboard.press('Enter'); await page.waitForNetworkIdle(); @@ -586,13 +442,12 @@ describe.skip('Tests the new Extension Requests Screen', () => { const requestDaysArray = []; for (const card of extensionCards) { const requestedDays = await card.$eval( - '.requested-day', + '.requested-day > .tooltip', (requestDays) => requestDays.textContent, ); - requestDaysArray.push(requestedDays); + requestDaysArray.push(requestedDays.slice(5)); } - const sortedRequestDaysArray = [...requestDaysArray].sort().reverse(); - + const sortedRequestDaysArray = [...requestDaysArray].sort(); expect(requestDaysArray).toEqual(sortedRequestDaysArray); }); @@ -606,13 +461,13 @@ describe.skip('Tests the new Extension Requests Screen', () => { const requestDaysArray = []; for (const card of extensionCards) { const requestedDays = await card.$eval( - '.requested-day', + '.requested-day > .tooltip', (requestDays) => requestDays.textContent, ); - requestDaysArray.push(requestedDays); + requestDaysArray.push(requestedDays.slice(5)); } - const sortedRequestDaysArray = [...requestDaysArray].sort(); + const sortedRequestDaysArray = [...requestDaysArray].sort().reverse(); expect(requestDaysArray).toEqual(sortedRequestDaysArray); }); diff --git a/__tests__/groups/group.test.js b/__tests__/groups/group.test.js index 177683d3..b12d8340 100644 --- a/__tests__/groups/group.test.js +++ b/__tests__/groups/group.test.js @@ -1,6 +1,6 @@ const puppeteer = require('puppeteer'); const { allUsersData } = require('../../mock-data/users'); -const { discordGroups } = require('../../mock-data/groups'); +const { discordGroups, GroupRoleData } = require('../../mock-data/groups'); const BASE_URL = 'https://api.realdevsquad.com'; @@ -14,7 +14,7 @@ describe('Discord Groups Page', () => { beforeAll(async () => { browser = await puppeteer.launch({ - headless: true, + headless: 'new', ignoreHTTPSErrors: true, args: ['--disable-web-security'], devtools: false, @@ -62,6 +62,28 @@ describe('Discord Groups Page', () => { }, body: JSON.stringify(discordGroups), }); + } else if (url === `${BASE_URL}/discord-actions/groups?dev=true`) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(discordGroups), + }); + } else if (url === `${BASE_URL}/discord-actions/roles`) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + body: JSON.stringify(GroupRoleData), + }); } else { interceptedRequest.continue(); } @@ -156,6 +178,36 @@ describe('Discord Groups Page', () => { await page.waitForNetworkIdle(); await expect(alertMessage).toContain('Role created successfully'); }); + + test('Should show add button as user not part of the group', async () => { + await page.goto('http://localhost:8000/groups/?dev=true'); + await page.waitForNetworkIdle(); + + const group = await page.$('.group-role'); + await group.click(); + + // Wait for the btn-add-role and click it + const addRoleBtn = await page.$('.btn-add-role'); + await addRoleBtn.click(); + + // Now, check the text content of the button + const buttonText = await addRoleBtn.evaluate((node) => node.textContent); + expect(buttonText).toBe('Add me to this group'); + }); + + test('Should show remove button as user is part of the group', async () => { + await page.$$eval('.group-role', (elements) => { + elements[1].click(); + }); + // Wait for the btn-add-role and click it + const addRoleBtn = await page.$('.btn-add-role'); + await addRoleBtn.click(); + + // Now, check the text content of the button + const buttonText = await addRoleBtn.evaluate((node) => node.textContent); + expect(buttonText).toBe('Remove me from this group'); + }); + test('Should display an error message if the role name contains "group"', async () => { createGroup = await page.$('.create-groups-tab'); await createGroup.click(); @@ -180,6 +232,21 @@ describe('Discord Groups Page', () => { ); }); + test('should display a message no results found if group not exists', async () => { + const searchInput = await page.$('#search-groups'); + + await searchInput.type('dummy'); + + await page.waitForNetworkIdle(); + + const noResultFoundHeading = await page.$('#no-results-message'); + const noResultFoundHeadingText = await ( + await noResultFoundHeading.getProperty('innerText') + ).jsonValue(); + + expect(noResultFoundHeadingText).toEqual('No results found.'); + }); + test('should update the URL when a group role is clicked', async () => { await page.$$eval('.group-role', (elements) => { elements[1].click(); diff --git a/__tests__/standup/standup.test.js b/__tests__/standup/standup.test.js index d07f836b..1695af3b 100644 --- a/__tests__/standup/standup.test.js +++ b/__tests__/standup/standup.test.js @@ -40,7 +40,7 @@ describe('Standup Page', () => { beforeAll(async () => { browser = await puppeteer.launch({ - headless: true, + headless: 'new', ignoreHTTPSErrors: true, args: ['--incognito', '--disable-web-security'], devtools: false, diff --git a/__tests__/taskRequests/taskRequest.test.js b/__tests__/taskRequests/taskRequest.test.js index e4a5effb..8ae9d117 100644 --- a/__tests__/taskRequests/taskRequest.test.js +++ b/__tests__/taskRequests/taskRequest.test.js @@ -10,6 +10,8 @@ describe('Task Requests', () => { let browser; let page; + jest.setTimeout(60000); + beforeAll(async () => { browser = await puppeteer.launch({ headless: 'new', @@ -70,7 +72,10 @@ describe('createCustomElement', () => { let page; beforeAll(async () => { - browser = await puppeteer.launch(); + browser = await puppeteer.launch({ + headless: 'new', + }); + page = await browser.newPage(); await page.goto(`${SITE_URL}/taskRequests`); diff --git a/__tests__/tasks/profile-picture.test.js b/__tests__/tasks/profile-picture.test.js index d9d62d17..c06d707b 100644 --- a/__tests__/tasks/profile-picture.test.js +++ b/__tests__/tasks/profile-picture.test.js @@ -9,7 +9,7 @@ describe('Task Page - Assignee Profile Pic', () => { beforeAll(async () => { browser = await puppeteer.launch({ - headless: true, + headless: 'new', ignoreHTTPSErrors: true, args: ['--incognito', '--disable-web-security'], devtools: false, diff --git a/__tests__/tasks/task-dependency.test.js b/__tests__/tasks/task-dependency.test.js index 2af9407c..b2e3634a 100644 --- a/__tests__/tasks/task-dependency.test.js +++ b/__tests__/tasks/task-dependency.test.js @@ -10,7 +10,7 @@ describe('Input box', () => { beforeAll(async () => { browser = await puppeteer.launch({ - headless: true, + headless: 'new', ignoreHTTPSErrors: true, args: ['--incognito', '--disable-web-security'], devtools: false, diff --git a/__tests__/users/App.test.js b/__tests__/users/App.test.js index 277f3db1..44156922 100644 --- a/__tests__/users/App.test.js +++ b/__tests__/users/App.test.js @@ -5,6 +5,7 @@ const { filteredUsersData } = require('../../mock-data/users'); describe('App Component', () => { let browser; let page; + jest.setTimeout(60000); let config = { launchOptions: { headless: 'new', diff --git a/extension-requests/constants.js b/extension-requests/constants.js index 2f42f673..d3575b10 100644 --- a/extension-requests/constants.js +++ b/extension-requests/constants.js @@ -8,6 +8,8 @@ const CANCEL_ICON_WHITE = '/images/x-icon-white.svg'; const EDIT_ICON = '/images/edit-icon.svg'; const ERROR_MESSAGE_RELOAD = 'Something went wrong, Please reload'; +const DEFAULT_PAGE_SIZE = 5; + const taskInfoModelHeadings = [ { title: 'Title' }, { title: 'Ends On', key: 'endsOn', time: true }, diff --git a/extension-requests/index.html b/extension-requests/index.html index eb9eb4f0..5fcc6d1c 100644 --- a/extension-requests/index.html +++ b/extension-requests/index.html @@ -8,92 +8,6 @@ -
-
-
-

Update Extension Request

- - - - - - - - - - - - - - - - -
-
-

Update Extension Request Status

- - - - - - - - - - -
-

Extension Requests

diff --git a/extension-requests/local-utils.js b/extension-requests/local-utils.js index 3e0ea6d6..79f5e5a5 100644 --- a/extension-requests/local-utils.js +++ b/extension-requests/local-utils.js @@ -9,30 +9,9 @@ const Order = { ASCENDING: 'asc', }; -const DEFAULT_PAGE_SIZE = 5; async function getExtensionRequests(query = {}, nextLink) { - const { dev } = query; - let finalUrl; - if (dev) { - finalUrl = - API_BASE_URL + (nextLink || generateExtensionRequestParams(query)); - } else { - const initialURI = nextLink || '/extension-requests'; - - const url = new URL(API_BASE_URL + initialURI); - - queryParams = ['assignee', 'status', 'taskId', 'size', 'dev', 'order']; - queryParams.forEach((key) => { - if (query[key]) { - if (Array.isArray(query[key])) { - query[key].forEach((value) => url.searchParams.append(key, value)); - } else { - url.searchParams.append(key, query[key]); - } - } - }); - finalUrl = url.toString(); - } + let finalUrl = + API_BASE_URL + (nextLink || generateExtensionRequestParams(query)); const res = await fetch(finalUrl, { credentials: 'include', diff --git a/extension-requests/script.js b/extension-requests/script.js index b0832799..e796e050 100644 --- a/extension-requests/script.js +++ b/extension-requests/script.js @@ -2,17 +2,6 @@ const container = document.querySelector('.container'); const extensionRequestsContainer = document.querySelector( '.extension-requests', ); - -const modalParent = document.querySelector('.extension-requests-modal-parent'); -const closeModal = document.querySelectorAll('#close-modal'); - -//modal containers -const modalShowInfo = document.querySelector('.extension-requests-info'); -const modalStatusForm = document.querySelector( - '.extension-requests-status-form', -); -const modalUpdateForm = document.querySelector('.extension-requests-form'); - const filterModal = document.getElementsByClassName(FILTER_MODAL)[0]; const filterButton = document.getElementById(FILTER_BUTTON); const applyFilterButton = document.getElementById(APPLY_FILTER_BUTTON); @@ -27,10 +16,6 @@ let extensionPageVersion = 0; let nextLink = ''; let isDataLoading = false; let userMap = new Map(); -if (params.get('dev') === 'true') { - extensionRequestsContainer.classList.remove('extension-requests'); - extensionRequestsContainer.classList.add('extension-requests-new'); -} const state = { currentExtensionRequest: null, @@ -40,7 +25,6 @@ const filterStates = { status: Status.PENDING, order: Order.ASCENDING, size: DEFAULT_PAGE_SIZE, - dev: params.get('dev') === 'true', }; const updateFilterStates = (key, value) => { @@ -78,15 +62,11 @@ const render = async () => { }; const addIntersectionObserver = () => { - if (params.get('dev') === 'true') { - intersectionObserver.observe(lastElementContainer); - } + intersectionObserver.observe(lastElementContainer); }; const removeIntersectionObserver = () => { - if (params.get('dev') === 'true') { - intersectionObserver.unobserve(lastElementContainer); - } + intersectionObserver.unobserve(lastElementContainer); }; const changeFilter = () => { @@ -150,24 +130,13 @@ async function populateExtensionRequests(query = {}, newLink) { const extensionRequests = await getExtensionRequests(query, newLink); nextLink = extensionRequests.next; const allExtensionRequests = extensionRequests.allExtensionRequests; - - if (params.get('dev') === 'true') { - if (currentVersion !== extensionPageVersion) { - return; - } - for (let data of allExtensionRequests) { - createExtensionCard(data); - } - initializeAccordions(); - } else { - allExtensionRequests.forEach((data) => { - const extensionRequestCard = createExtensionRequestCard( - data, - extensionRequestCardHeadings, - ); - extensionRequestsContainer.appendChild(extensionRequestCard); - }); + if (currentVersion !== extensionPageVersion) { + return; } + for (let data of allExtensionRequests) { + createExtensionCard(data); + } + initializeAccordions(); } catch (error) { addErrorElement(extensionRequestsContainer); } finally { @@ -340,170 +309,6 @@ const toggleSortIcon = () => { } }; -const showTaskDetails = async (taskId, approved) => { - if (!taskId) return; - try { - modalShowInfo.innerHTML = '

Task Details

'; - addLoader(modalShowInfo); - const taskDetails = await getTaskDetails(taskId); - const taskData = taskDetails.taskData; - modalShowInfo.append( - createTaskInfoModal(taskData, approved, taskInfoModelHeadings), - ); - } catch (error) { - addErrorElement(extensionRequestsContainer); - reload(); - } finally { - removeLoader('loader'); - } -}; -function createTaskInfoModal(data, approved, dataHeadings) { - if (!data) return; - - const updateStatus = createElement({ - type: 'button', - attributes: { class: 'status-form' }, - innerText: 'Update Status', - }); - const closeModal = createElement({ - type: 'button', - attributes: { id: 'close-modal' }, - innerText: 'Cancel', - }); - updateStatus.addEventListener('click', () => { - showModal('status-form'); - fillStatusForm(); - }); - closeModal.addEventListener('click', () => hideModal()); - - const main = createTable(dataHeadings, data); - - if (!approved) main.appendChild(updateStatus); - main.appendChild(closeModal); - return main; -} -function createExtensionRequestCard(data, dataHeadings) { - if (!data) return; - - const updateRequestBtn = createElement({ - type: 'button', - attributes: { class: 'update_request' }, - innerText: 'Update Request', - }); - const moreInfoBtn = createElement({ - type: 'button', - attributes: { class: 'more' }, - innerText: 'More', - }); - updateRequestBtn.addEventListener('click', () => { - showModal('update-form'); - state.currentExtensionRequest = data; - fillUpdateForm(); - }); - moreInfoBtn.addEventListener('click', () => { - showModal('info'); - showTaskDetails(data.taskId, data.status === 'APPROVED'); - state.currentExtensionRequest = data; - }); - - const main = createTable(dataHeadings, data, 'extension-request'); - - const wrapperDiv = createElement({ type: 'div' }); - - wrapperDiv.appendChild(moreInfoBtn); - wrapperDiv.appendChild(updateRequestBtn); - - main.appendChild(wrapperDiv); - return main; -} - -//PATCH requests functions -async function onStatusFormSubmit(e) { - e.preventDefault(); - try { - addLoader(container); - let formData = formDataToObject(new FormData(e.target)); - await updateExtensionRequestStatus({ - id: state.currentExtensionRequest.id, - body: formData, - }); - reload(); - } catch (error) { - addErrorElement(extensionRequestsContainer); - reload(); - } finally { - removeLoader('loader'); - } -} -async function onUpdateFormSubmit(e) { - e.preventDefault(); - try { - addLoader(container); - let formData = formDataToObject(new FormData(e.target)); - formData['newEndsOn'] = new Date(formData['newEndsOn']).getTime() / 1000; - await updateExtensionRequest({ - id: state.currentExtensionRequest.id, - body: formData, - }); - addErrorElement(extensionRequestsContainer); - reload(); - } finally { - removeLoader('loader'); - } -} - -modalUpdateForm.addEventListener('submit', onUpdateFormSubmit); -modalStatusForm.addEventListener('submit', onStatusFormSubmit); - -modalParent.addEventListener('click', hideModal); -closeModal.forEach((node) => node.addEventListener('click', () => hideModal())); - -function showModal(show = 'form') { - modalParent.classList.add('visible'); - modalParent.setAttribute('show', show); -} -function hideModal(e) { - if (!e) { - modalParent.classList.remove('visible'); - return; - } - e.stopPropagation(); - if (e.target === modalParent) { - modalParent.classList.remove('visible'); - } -} -function reload() { - setTimeout(() => window.history.go(0), 2000); -} -function fillStatusForm() { - modalStatusForm.querySelector('.extensionId').value = - state.currentExtensionRequest.id; - modalStatusForm.querySelector('.extensionTitle').value = - state.currentExtensionRequest.title; - modalStatusForm.querySelector('.extensionAssignee').value = - state.currentExtensionRequest.assignee; -} -function fillUpdateForm() { - const { newEndsOn, oldEndsOn, status, id, title, assignee, reason } = - state.currentExtensionRequest; - - modalUpdateForm.querySelector('.extensionNewEndsOn').value = new Date( - newEndsOn * 1000, - ) - .toISOString() - .replace('Z', ''); - modalUpdateForm.querySelector('.extensionOldEndsOn').value = new Date( - oldEndsOn * 1000, - ) - .toISOString() - .replace('Z', ''); - - modalUpdateForm.querySelector('.extensionStatus').value = status; - modalUpdateForm.querySelector('.extensionId').value = id; - modalUpdateForm.querySelector('.extensionTitle').value = title; - modalUpdateForm.querySelector('.extensionAssignee').value = assignee; - modalUpdateForm.querySelector('.extensionReason').value = reason; -} filterButton.addEventListener('click', (event) => { event.stopPropagation(); filterModal.classList.toggle('hidden'); diff --git a/extension-requests/style.css b/extension-requests/style.css index ef4f4549..941bcff8 100644 --- a/extension-requests/style.css +++ b/extension-requests/style.css @@ -81,6 +81,7 @@ overflow: hidden; font-size: 0.9rem; } + .accordion { background-color: transparent; cursor: pointer; @@ -107,6 +108,7 @@ .accordion:hover img { transform: scale(1.25); } + .accordion.active img { transform: rotate(180deg); } @@ -116,12 +118,14 @@ align-items: center; gap: 1rem; } + .assignee-image { width: 1.875rem; height: 1.875rem; color: transparent; border-radius: 50%; } + .assignee-name { font-size: 1.3rem; font-weight: 500; @@ -132,6 +136,7 @@ overflow: hidden; text-transform: capitalize; } + .approve-button { width: 6.25rem; height: 2rem; @@ -166,6 +171,7 @@ align-items: center; justify-content: center; } + .edit-button:hover { background-color: var(--light-gray); } @@ -201,6 +207,7 @@ background-color: var(--secondary600); color: var(--white); } + .update-wrapper { display: flex; width: auto; @@ -226,6 +233,7 @@ justify-content: center; padding: 2px; } + .deny-button:hover { background-color: var(--secondary600); } @@ -246,16 +254,19 @@ display: flex; justify-content: space-between; } + .assignee-text { font-size: 1.1rem; font-weight: 500; color: var(--medium-gray); } + .extension-card-buttons { display: flex; gap: 0.5rem; margin-right: 3.5rem; } + .details-heading { width: fit-content; flex-shrink: 0; @@ -292,6 +303,7 @@ gap: 1rem; font-size: 0.9rem; } + .card-row-text { font-size: 0.9rem; font-weight: 500; @@ -313,16 +325,19 @@ border-radius: 6px; border: 1px solid var(--black-color); } + .input-text-area { width: 100%; height: 5rem; resize: none; } + .date-input { border-radius: 4px; margin-left: 4px; border: 1px solid var(--black-color); } + .reason-text { white-space: normal; } @@ -334,6 +349,7 @@ .tooltip-container { position: relative; } + .tooltip { background-color: var(--black-color); color: var(--white); @@ -355,10 +371,12 @@ width: 7rem; margin-left: -3.5rem; } + .tooltip-container:hover .tooltip { visibility: visible; transition-delay: 400ms; } + .tooltip-container:hover .sort-button-tooltip { visibility: visible; transition-delay: 200ms; @@ -395,157 +413,7 @@ body { color: var(--white); } -.extension-requests-modal-parent { - display: none; -} - -.extension-requests-modal-parent.visible { - z-index: 1; - position: fixed; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; - min-width: 100vw; - min-height: 100vh; - background-color: var(--modal-color); - overflow-y: scroll; - padding-bottom: 1rem; -} - -.extension-requests-modal-parent > * { - display: none; - flex-direction: column; - justify-content: center; - align-items: flex-start; - background-color: var(--white); - padding: 1.25rem; - border-radius: 5px; - min-width: 250px; -} - -#close-modal { - align-self: center; -} - -/* task info */ -.extension-requests-modal-parent[show='info'] .extension-requests-info { - display: flex; -} - -.extension-requests-info { - position: absolute; - left: 30%; - right: 30%; - height: fit-content; -} - -.extension-requests-info table { - text-align: left; - margin: 10px; - color: var(--black); - border-radius: 5px; -} - -.extension-requests-info button { - background-color: var(--button-proceed); - border: none; - color: var(--white); - padding: 0.5rem 1rem; - font-size: medium; - font-weight: bold; - border-radius: 5px; - margin: 10px; -} - -/* task info ends here */ - -/* update form */ -.extension-requests-modal-parent[show='update-form'] .extension-requests-form { - display: flex; -} - -.extension-requests-form { - position: absolute; - left: 30%; - right: 30%; - height: min-content; - overflow-y: scroll; - top: 10%; - bottom: 10%; -} - -.extension-requests-form input, -.extension-requests-form select { - margin: 5px 0px 15px 0px; - padding: 5px; - width: 100%; - border: none; - border-bottom: 1px solid var(--gray); -} - -.extension-requests-form input:focus { - outline: none; - border-bottom: 1px solid var(--gray); -} - -.extension-requests-form button { - background-color: var(--button-proceed); - border: none; - color: var(--white); - padding: 0.5rem 1rem; - font-size: medium; - font-weight: bold; - border-radius: 5px; - margin: 10px; -} - -/* update form ends here */ - -/* status form */ -.extension-requests-modal-parent[show='status-form'] - .extension-requests-status-form { - display: flex; -} - -.extension-requests-status-form input, -.extension-requests-status-form select { - margin: 5px 0px 15px 0px; - padding: 5px; - width: 100%; - border: none; - border-bottom: 1px solid var(--gray); -} - -.extension-requests-status-form input:focus { - outline: none; - border-bottom: 1px solid var(--gray); -} - -.extension-requests-status-form button { - background-color: var(--button-proceed); - border: none; - color: var(--white); - padding: 0.5rem 1rem; - font-size: medium; - font-weight: bold; - border-radius: 5px; - margin: 10px; -} - -/* status form ends here */ - .extension-requests { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(12.5rem, 22rem)); - grid-auto-rows: 26rem; - flex-wrap: wrap; - gap: 1.25rem; - justify-content: center; -} - -.extension-requests-new { display: flex; flex-direction: column; align-items: center; @@ -573,6 +441,7 @@ body { display: flex; justify-content: space-between; } + .extension-request > div .more, .extension-request > div .update_request { background-color: var(--button-proceed); @@ -623,6 +492,7 @@ body { height: 2.5rem; padding: 0.7rem; } + .sort-button { background-color: var(--light-gray-color); border-radius: 0.4rem; @@ -630,6 +500,7 @@ body { padding: 8px; height: 2.5rem; } + .sort-button:hover { background-color: var(--medium-gray); } @@ -675,6 +546,32 @@ body { #desc-sort-icon { display: none; } + +.success-card { + opacity: 1; + border: 1px solid var(--green-color); + background-color: var(--green-transparent); +} + +.failed-card { + opacity: 1; + border: 1px solid var(--red-color); + background-color: var(--red-transparent); +} + +.spinner { + border: 8px solid var(--white-gray); + border-radius: 50%; + border-top: 8px solid var(--dark-blue); + width: 1.5rem; + height: 1.5rem; + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; + position: absolute; + top: 50%; + right: 50%; +} + /* Filter modal */ .filter-modal { width: 20%; @@ -770,31 +667,6 @@ body { pointer-events: none; } -.success-card { - opacity: 1; - border: 1px solid var(--green-color); - background-color: var(--green-transparent); -} - -.failed-card { - opacity: 1; - border: 1px solid var(--red-color); - background-color: var(--red-transparent); -} - -.spinner { - border: 8px solid var(--white-gray); - border-radius: 50%; - border-top: 8px solid var(--dark-blue); - width: 1.5rem; - height: 1.5rem; - -webkit-animation: spin 2s linear infinite; - animation: spin 2s linear infinite; - position: absolute; - top: 50%; - right: 50%; -} - @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); @@ -834,6 +706,7 @@ body { left: 10%; right: 10%; } + .search-filter { justify-content: center; } @@ -843,16 +716,20 @@ body { .extension-card { max-width: 25rem; } + .summary-container { display: flex; flex-direction: column; } + .panel div { margin: 1.5rem; } + .extension-card-buttons { margin: 0; } + .card-assignee-button-container { flex-direction: column; gap: 0.75rem; @@ -863,6 +740,7 @@ body { .container { padding: 1.5rem; } + .filter-button { width: min-content; } @@ -870,6 +748,7 @@ body { .update-wrapper { flex-direction: column; } + .update-button { font-size: 10px; } @@ -881,12 +760,15 @@ body { .panel div { margin: 1rem; } + .assignee-text { display: none; } + .filter-text { display: none; } + .funnel-icon { margin: auto; } @@ -896,6 +778,7 @@ body { .container { padding: 1rem; } + .filter-modal { top: 12.5rem; } diff --git a/groups/index.html b/groups/index.html index 0e09b096..92e1b068 100644 --- a/groups/index.html +++ b/groups/index.html @@ -39,6 +39,7 @@

No results found.

diff --git a/groups/script.js b/groups/script.js index 531be051..3b949cce 100644 --- a/groups/script.js +++ b/groups/script.js @@ -10,16 +10,20 @@ import { addGroupRoleToMember, createDiscordGroupRole, getUserSelf, + getUserGroupRoles, } from './utils.js'; const groupTabs = document.querySelector('.groups-tab'); const tabs = document.querySelectorAll('.groups-tab div'); const sections = document.querySelectorAll('.manage-groups, .create-group'); const loader = document.querySelector('.backdrop'); const userIsNotVerifiedText = document.querySelector('.not-verified-tag'); -const userSelfData = await getUserSelf(); const params = new URLSearchParams(window.location.search); const isDev = params.get(DEV_FEATURE_FLAG) === 'true'; +//User Data +const userSelfData = await getUserSelf(); +let UserGroupData = await getUserGroupRoles(); + /** * Create DOM for "created by author" line under groupName * @@ -120,6 +124,10 @@ groupTabs.addEventListener('click', (e) => { }); if (e.target.nodeName !== 'NAV') e.target?.classList?.add('active-tab'); }); +function isRoleIdInData(data, targetRoleId) { + // Use the some() method to check if any element in data.groups has a matching roleId + return data.groups.some((group) => group.roleId === targetRoleId); +} /** * FOR SELECTING A GROUP @@ -140,11 +148,33 @@ groupRoles?.addEventListener('click', function (event) { groupListItem.classList.add('active-group'); memberAddRoleBody.roleid = groupListItem.id; if (IsUserVerified) { - buttonAddRole.disabled = false; + if (isDev) { + buttonAddRole.removeEventListener('click', addrole); + updateButtonState(); + } else { + buttonAddRole.disabled = false; + buttonAddRole.addEventListener('click', addrole); + } } } }); +// Function to update the button state based on user's group roles +function updateButtonState() { + const isRoleIdPresent = isRoleIdInData( + UserGroupData, + memberAddRoleBody.roleid, + ); + buttonAddRole.textContent = isRoleIdPresent + ? 'Remove me from this group' + : 'Add me to this group'; + buttonAddRole.disabled = false; + isRoleIdPresent + ? (buttonAddRole.removeEventListener('click', addrole), + buttonAddRole.addEventListener('click', removeRoleHandler)) + : (buttonAddRole.removeEventListener('click', removeRoleHandler), + buttonAddRole.addEventListener('click', addrole)); +} // const paragraphElement = null, paragraphContent = ''; const searchInput = document.getElementById('search-groups'); @@ -163,14 +193,21 @@ searchInput.addEventListener('keyup', () => { debounce(() => { const searchValue = searchInput.value.toUpperCase(); const groupRoles = document.querySelectorAll('.group-role'); + let foundResults = false; groupRoles.forEach((groupRole) => { const paragraphElement = groupRole.getElementsByTagName('p')[0]; const paragraphContent = paragraphElement.textContent; const displayValue = paragraphContent.toUpperCase().indexOf(searchValue) > -1 ? '' : 'none'; groupRole.style.display = displayValue; + + if (displayValue === '') { + foundResults = true; + } loader.classList.add('hidden'); }); + const noResultsMessage = document.getElementById('no-results-message'); + noResultsMessage.style.display = foundResults ? 'none' : 'block'; }, 1000)(); }); @@ -178,25 +215,45 @@ searchInput.addEventListener('keyup', () => { * TO ASSIGN YOURSELF A ROLE */ const buttonAddRole = document.querySelector('.btn-add-role'); -buttonAddRole.addEventListener('click', async function () { +async function addrole() { if (memberAddRoleBody?.userid && memberAddRoleBody?.roleid !== '') { loader.classList.remove('hidden'); - addGroupRoleToMember(memberAddRoleBody) - .then((res) => { - const groupNameElement = document.getElementById( - `name-${memberAddRoleBody.roleid}`, - ); - const currentCount = groupNameElement.getAttribute('data-member-count'); - if (currentCount !== null && currentCount !== undefined) { - groupNameElement.setAttribute('data-member-count', +currentCount + 1); - } - alert(res.message); - }) - .catch((err) => alert(err.message)) - .finally(() => loader.classList.add('hidden')); + try { + // Add the role to the member + const res = await addGroupRoleToMember(memberAddRoleBody); + + const groupNameElement = document.getElementById( + `name-${memberAddRoleBody.roleid}`, + ); + const currentCount = groupNameElement.getAttribute('data-member-count'); + if (currentCount !== null && currentCount !== undefined) { + groupNameElement.setAttribute('data-member-count', +currentCount + 1); + } + alert(res.message); + if (isDev) { + // After adding the role, re-fetch the user group data to update it + UserGroupData = await getUserGroupRoles(); + + // Update the button state with the refreshed data + updateButtonState(); + } + } catch (err) { + alert(err.message); + } finally { + loader.classList.add('hidden'); + } } -}); +} + +/** + * TO REMOVE YOURSELF OF A ROLE + */ +async function removeRoleHandler() { + console.log('Remove function to be added after this pr'); + + // TODO: REMOVE ME BUTTON FUNCTIONALITY TO BE ADDED +} /** * diff --git a/groups/style.css b/groups/style.css index be487f76..540f5dd8 100644 --- a/groups/style.css +++ b/groups/style.css @@ -63,13 +63,8 @@ display: flex; } .manage-groups main { + padding: 1rem 4rem; flex: 1; - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - gap: 10px; - position: relative; } .groups { @@ -193,9 +188,18 @@ } .btn-add-role { + margin: 5px; +} + +#no-results-message { + display: none; + width: 100%; + text-align: center; position: absolute; - top: 3%; - left: 5%; + top: 50%; + left: 50%; + transform: translate(-50%); + color: var(--color-groups-tab-background); } /* @@ -250,6 +254,11 @@ NOT VERIFIED TEXT ABOVE flex-direction: column-reverse; padding: 1.2rem; } + .manage-groups main { + padding: unset; + text-align: center; + } + .groups-list { height: 54vh; } diff --git a/groups/utils.js b/groups/utils.js index 5da4454a..9fb461a0 100644 --- a/groups/utils.js +++ b/groups/utils.js @@ -32,6 +32,17 @@ async function getUserSelf() { return err; } } +async function getUserGroupRoles() { + const res = await fetch(`${BASE_URL}/discord-actions/roles`, { + method: 'GET', + credentials: 'include', + headers: { + 'Content-type': 'application/json', + }, + }); + return await res.json(); +} + async function getDiscordGroups(isDev) { try { const devFeatureFlag = isDev ? '?dev=true' : ''; @@ -103,6 +114,7 @@ function removeGroupKeywordFromDiscordRoleName(groupName) { } export { + getUserGroupRoles, getMembers, getUserSelf, getDiscordGroups, diff --git a/images/Real-Dev-Squad@1x.png b/images/Real-Dev-Squad@1x.png new file mode 100644 index 00000000..7f10e48f Binary files /dev/null and b/images/Real-Dev-Squad@1x.png differ diff --git a/images/github.png b/images/github.png new file mode 100644 index 00000000..6c3b3cd1 Binary files /dev/null and b/images/github.png differ diff --git a/index.html b/index.html index 4461006e..1c1d701f 100644 --- a/index.html +++ b/index.html @@ -15,7 +15,31 @@
diff --git a/mock-data/extension-requests/index.js b/mock-data/extension-requests/index.js index df6b79d5..8d6384da 100644 --- a/mock-data/extension-requests/index.js +++ b/mock-data/extension-requests/index.js @@ -24,7 +24,7 @@ const extensionRequestsList = { title: 'A new title', }, ], - next: '/extension-requests?dev=true&size=5&order=asc', + next: '/extension-requests&size=5&order=asc', }; const extensionRequestsListPendingDescending = { @@ -75,7 +75,7 @@ const extensionRequestsListPendingDescending = { title: 'A title', }, ], - next: '/extension-requests?order=desc&size=5&dev=true&q=status%3APENDING', + next: '/extension-requests?order=desc&size=5&q=status%3APENDING', }; const extensionRequestsListUserSearch = { @@ -142,7 +142,7 @@ const extensionRequestsListPending = { title: 'A different title 2', }, ], - next: '/extension-requests?order=asc&size=5&dev=true&q=status%3APENDING', + next: '/extension-requests?order=asc&size=5&q=status%3APENDING', }; const extensionRequestsListApproved = { @@ -171,7 +171,7 @@ const extensionRequestsListApproved = { title: 'test title', }, ], - next: '/extension-requests?q=status%3AAPPROVED&dev=true&size=5&order=asc', + next: '/extension-requests?q=status%3AAPPROVED&size=5&order=asc', }; const extensionRequestResponse = { diff --git a/mock-data/groups/index.js b/mock-data/groups/index.js index 6478bf16..3ecb9602 100644 --- a/mock-data/groups/index.js +++ b/mock-data/groups/index.js @@ -46,4 +46,29 @@ const discordGroups = { ], }; -module.exports = { discordGroups }; +const GroupRoleData = { + message: 'User group roles Id fetched successfully!', + userId: '1234398439439989', + groups: [ + { + roleId: '1103808103641780925', + }, + { + roleId: '1151598744278667264', + }, + { + roleId: '1151808031613521951', + }, + { + roleId: '1122182070509244416', + }, + { + roleId: '1151807937149419531', + }, + { + roleId: '1151598712573939792', + }, + ], +}; + +module.exports = { discordGroups, GroupRoleData }; diff --git a/online-members/constants.js b/online-members/constants.js index 3c9f5c9c..fb4f301c 100644 --- a/online-members/constants.js +++ b/online-members/constants.js @@ -25,6 +25,8 @@ const MEMBERS_SEARCH_PLACEHOLDER = 'Search for members'; // Task Constants const TASKS_CONTAINER_ID = 'task-container'; +const TASKS_SUBCONTAINER_CLASS_LIST = ['task-subcontainer']; +const TASKS_CONTAINER_TITLE_CLASS_LIST = ['task-container-title']; const TASKS_CLASS_LIST = ['task']; const TASKS_CONTAINER_CLASS_LIST = ['tasks-container']; diff --git a/online-members/online-members.css b/online-members/online-members.css index c1fa094d..eeccc16c 100644 --- a/online-members/online-members.css +++ b/online-members/online-members.css @@ -7,28 +7,32 @@ .body { display: flex; - align-content: center; + align-content: flex-start; justify-content: space-evenly; - align-items: center; + padding-top: 4rem; } .task-container { - top: 5rem; - left: 5rem; - position: absolute; overflow: scroll; + display: none; + padding-top: 10px; max-height: 85vh; + padding: 0 1rem; + width: 50%; +} + +.task-subcontainer { + display: flex; + flex-direction: column; + gap: 1.5rem; } .task { - margin: 50px; padding: 10px; border: 2px solid black; border-radius: 5px; height: max-content; - width: 30rem; - align-items: center; - display: flex; + width: 100%; } .members-container { @@ -37,9 +41,6 @@ border-radius: 5px; height: 80vh; overflow-y: scroll; - position: absolute; - top: 5rem; - right: 5rem; min-width: 260px; } @@ -123,3 +124,33 @@ footer .info-repo { font-weight: 100; text-align: center; } + +/* MEDIA QUERY */ + +@media only screen and (max-width: 900px) { + .body { + flex-direction: column-reverse; + align-items: center; + padding-top: 2rem; + gap: 3rem; + } + .task-container { + width: 70%; + margin-bottom: 3rem; + } + .task-container-title { + text-align: center; + } +} +@media only screen and (max-width: 600px) { + .task-container { + width: 85%; + padding: 0; + } +} +@media only screen and (max-width: 400px) { + .task-container { + width: 95%; + padding: 0; + } +} diff --git a/online-members/script.js b/online-members/script.js index d4c85425..ab422ea8 100644 --- a/online-members/script.js +++ b/online-members/script.js @@ -100,8 +100,14 @@ function getMembersListContent(members, classList = []) { } function getTaskDataContent({ tasks, username, classList = [] }) { - const div = createElement({ type: 'div' }); - const h3 = createElement({ type: 'h3' }); + const div = createElement({ + type: 'div', + classList: TASKS_SUBCONTAINER_CLASS_LIST, + }); + const h3 = createElement({ + type: 'h3', + classList: TASKS_CONTAINER_TITLE_CLASS_LIST, + }); h3.appendChild(createTextNode(`TASKS - ${username}`)); const fragment = new DocumentFragment(); tasks.forEach((task) => { @@ -165,6 +171,7 @@ function addEventListenerToMembersList() { const membersList = document.querySelector(`#${MEMBERS_CONTAINER_ID} > UL`); membersList.addEventListener('click', (event) => { const memberElement = event.target.closest(`.${MEMBERS_CLASS}`); + document.getElementById(TASKS_CONTAINER_ID).style.display = 'block'; if (!memberElement) { return; } diff --git a/script.js b/script.js index 155f8fc4..db35697b 100644 --- a/script.js +++ b/script.js @@ -290,6 +290,21 @@ addClickEventListener( syncUnverifiedUsersUpdate, 'POST', ); + +const hamburgerDiv = document.querySelector('.hamburger'); +const navLinks = document.querySelector('.links'); +let toggle = true; + +hamburgerDiv.addEventListener('click', function () { + if (toggle) { + navLinks.classList.add('active'); + toggle = false; + } else { + navLinks.classList.remove('active'); + toggle = true; + } +}); + addClickEventListener( syncIdleUsersButton, '/discord-actions/group-idle', diff --git a/style.css b/style.css index 2b2e14a9..780d69c8 100644 --- a/style.css +++ b/style.css @@ -24,12 +24,84 @@ body { #tasksNav { background-color: var(--blue-color); padding: 10px; - height: 2.5rem; + display: flex; +} + +img { + height: 100%; + width: 100%; +} + +.logo { + height: 50px; + width: 50px; +} + +.nav-links { + display: flex; +} + +.nav-links .active { + top: 80px; + left: 0; + justify-content: center; + flex-direction: column; + width: 100%; + padding: 10px; +} + +.nav-links .hamburger { + display: none; + order: 1; + margin: auto; + cursor: pointer; +} + +.nav-links .hamburger .line { + width: 25px; + margin: 5px; + border: 2px solid var(--white-color); +} + +.nav-links .links { + margin: auto; +} + +.nav-links .links a { + text-decoration: none; + color: var(--white-color); + padding: 20px; +} + +.sign-in-btn { + display: flex; + justify-content: center; + order: 3; +} + +.sign-in-btn a { + position: absolute; + right: 10px; + margin: 10px; + height: 30px; + padding: 5px; + background-color: var(--blue-color); + color: var(--white-color); + cursor: pointer; + border: 2px solid var(--white-color); + border-radius: 6px; + text-decoration: none; +} + +.sign-in-btn a img { + height: 15px; + width: 15px; + position: relative; + top: 1px; } #createTask { color: var(--white-color); - padding-left: 50%; text-decoration: none; font-size: large; } @@ -295,3 +367,49 @@ footer { .element-display-remove { display: none !important; } + +/* MEDIA QUERY */ + +@media screen and (max-width: 970px) { + #tasksNav { + justify-content: space-between; + } + + .sign-in-btn a { + position: static; + } + + .sign-in-btn span { + display: none; + } + .logo { + order: 2; + } + + .nav-links .hamburger { + display: inline-block; + } + + .nav-links .links { + display: none; + } + + .nav-links .active { + position: absolute; + display: flex; + background-color: var(--white-color); + } + + .nav-links .links a { + color: var(--blue-color); + } +} + +@media only screen and (max-width: 600px) { + .buttonSection { + flex-direction: column; + } + .action-button { + text-align: center; + } +}