From 0561320d2f9c8226a966596efa2562fda6b03524 Mon Sep 17 00:00:00 2001 From: Sunny Sahsi Date: Thu, 6 Jul 2023 23:04:12 +0530 Subject: [PATCH] FEATURE : Add sidebar and loader animation (#388) * add test and mock data * FEAT : add loader in the table container * FEAT : add sidebar for standup view * REFACTOR : refactor css and add sidebar cloising event to body * REFACTOR : change PX to REM * REFACTOR : change css of sidebar panel * FEAT : add loader in the table container * FEAT : add sidebar for standup view * REFACTOR : refactor css and add sidebar cloising event to body * REFACTOR : change PX to REM * REFACTOR : change css of sidebar panel * TEST : Add test for sidebar and loader * FIX : remove test which failed * FIX : move test in #375 PR * FIX : add deleted mock data * FIX : add variable for color in CSS * REFACTOR : change colors and fix issue --------- Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com> --- standup/script.js | 54 +++++++++++++++-- standup/style.css | 144 +++++++++++++++++++++++++++++++++++++++++++++- standup/utils.js | 59 +++++++++++++++++++ 3 files changed, 250 insertions(+), 7 deletions(-) diff --git a/standup/script.js b/standup/script.js index 419eb757..5ab99dfd 100644 --- a/standup/script.js +++ b/standup/script.js @@ -4,6 +4,7 @@ const tableContainerElement = document.getElementById('table-container'); const tableElement = document.createElement('table'); tableElement.classList.add('user-standup-table'); const tableBodyElement = document.createElement('tbody'); +const loaderElement = createLoaderElement(); const currentDateObj = new Date(); const currentYearNum = currentDateObj.getFullYear(); @@ -44,14 +45,22 @@ function processStandupData(standupItems) { return standupData; } for (let i = 0; i < standupItems.length; i++) { - const date = new Date(standupItems[i].createdAt); + const standupItem = standupItems[i]; + const date = new Date(standupItem.createdAt); const day = date.getDate(); + const month = date.getMonth(); const index = day - 1; - if (index < standupData.standupFrequency.length) { + + const isCurrentMonth = month === currentDateObj.getMonth(); + const isValidIndex = + index >= 0 && index < standupData.standupFrequency.length; + + if (isCurrentMonth && isValidIndex) { + const { completed, planned, blockers } = standupItem; standupData.standupFrequency[index] = '✅'; - standupData.completedText[index] = standupItems[i].completed; - standupData.plannedText[index] = standupItems[i].planned; - standupData.blockersText[index] = standupItems[i].blockers; + standupData.completedText[index] = completed; + standupData.plannedText[index] = planned; + standupData.blockersText[index] = blockers; } } return standupData; @@ -145,6 +154,14 @@ function createTableRowElement({ userName, imageUrl, userStandupData }) { type: 'p', classList: ['no-standup-text'], }); + const sidebarElement = createSidebarPanelElement( + completedTextData[i], + plannedText[i], + blockersText[i], + i + 1, + currentMonthName, + currentYearNum, + ); if (standupStatus[i] === '✅') { completedTextElement.textContent += `Today's: ${completedTextData[i]}`; @@ -155,6 +172,22 @@ function createTableRowElement({ userName, imageUrl, userStandupData }) { tooltipElement.appendChild(yesterdayStandupElement); tooltipElement.appendChild(blockersElement); statusCellElement.appendChild(tooltipElement); + + statusCellElement.addEventListener('click', (event) => { + event.stopPropagation(); + + if (!document.body.contains(sidebarElement)) { + if (sidebarElement) { + document.body.appendChild(sidebarElement); + sidebarElement.classList.add('openSidebar'); + document.body.style.marginRight = '20%'; + } + } else { + document.body.removeChild(sidebarElement); + sidebarElement.classList.remove('openSidebar'); + document.body.style.marginRight = '0%'; + } + }); } rowElement.addEventListener('mouseover', (mouseEvent) => { @@ -190,6 +223,7 @@ async function searchButtonHandler() { tableBodyElement.innerHTML = ''; for (const username of filteredUsernames) { + tableContainerElement.appendChild(loaderElement); const userData = await fetchUserData(username); if (userData) { const standupData = await fetchStandupData(userData.id); @@ -203,6 +237,7 @@ async function searchButtonHandler() { tableBodyElement.appendChild(tableRowElement); } } + tableContainerElement.removeChild(loaderElement); } function handleEnterKeyPress(event) { @@ -214,3 +249,12 @@ function handleEnterKeyPress(event) { setupTable(); searchButtonElement.addEventListener('click', searchButtonHandler); searchInput.addEventListener('keyup', handleEnterKeyPress); + +document.addEventListener('click', (event) => { + const sidebarElement = document.querySelector('.sidebar'); + if (sidebarElement && !sidebarElement.contains(event.target)) { + document.body.removeChild(sidebarElement); + sidebarElement.classList.remove('openSidebar'); + document.body.style.marginRight = '0%'; + } +}); diff --git a/standup/style.css b/standup/style.css index a6286a73..90801cbb 100644 --- a/standup/style.css +++ b/standup/style.css @@ -4,6 +4,15 @@ --blue-color: #1d1283; --gray-color: #e3e2e2; --dark-gray-color: #a8a8a8; + --light-blur-color: rgba(14, 12, 168, 0.691); + --loader-background-gradient: linear-gradient( + 110deg, + rgba(227, 227, 227, 0) 0%, + rgba(227, 227, 227, 0) 40%, + rgba(227, 227, 227, 0.5) 50%, + rgba(227, 227, 227, 0) 60%, + rgba(227, 227, 227, 0) 100% + ); } body { @@ -12,6 +21,7 @@ body { display: flex; flex-direction: column; height: 100vh; + transition: margin-left 0.5s; } .navbar { @@ -216,6 +226,99 @@ tr:hover { font-weight: 600; } +.loader { + position: relative; + margin-bottom: 1.5rem; + border: 1px solid var(--dark-gray-color); + padding: 1rem; + background-color: var(--white-color); + overflow: hidden; +} + +.loader:after { + content: ''; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: var(--loader-background-gradient); + animation: gradient-animation 1.2s linear infinite; +} + +.loader .wrapper { + width: 100%; + height: 100%; + position: relative; +} + +.loader .wrapper > div { + background-color: var(--dark-gray-color); +} + +.loader .circle { + width: 3.2rem; + height: 3.2rem; + border-radius: 50%; +} + +.loader .line-1 { + position: absolute; + top: 0.5rem; + left: 4rem; + height: 0.6rem; + width: 95%; +} + +.loader .line-2 { + position: absolute; + top: 2rem; + left: 4rem; + height: 0.6rem; + width: 95%; +} + +@keyframes gradient-animation { + 0% { + transform: translateX(-100%); + } + + 100% { + transform: translateX(100%); + } +} +.sidebar { + height: 100vh; + width: 0; + position: fixed; + z-index: 999; + top: 0; + right: 0; + color: var(--white-color); + overflow-x: hidden; + padding-left: 1rem; + padding-top: 6rem; + border-radius: 1rem 0 0 1rem; + background: var(--light-blur-color); + box-shadow: 0 0 0.8rem var(--blue-color); + backdrop-filter: blur(2rem); +} +.openSidebar { + width: 20%; +} + +.standup-head { + text-align: center; + border-bottom: 1px solid var(--white-color); + margin-bottom: 0.5rem; +} + +.sidebar div { + width: 100%; + padding: 0.5rem 0; + text-align: center; +} + @media screen and (max-width: 768px) { body { font-size: 0.8rem; @@ -258,11 +361,48 @@ tr:hover { } .tooltiptext { - font-size: 0.5rem; - width: 10rem; + display: none; } .info-repo { font-size: 0.8rem; } + body { + width: 100%; + } + .sidebar { + position: fixed; + top: 0; + left: 0; + right: 0; + height: auto; + border-bottom-left-radius: 1rem; + border-bottom-right-radius: 1rem; + padding: 1rem 0 1rem 0; + } + .openSidebar { + width: 100%; + animation: slideIn 0.5s ease-in-out forwards; + } + @keyframes slideIn { + from { + transform: translateY(-100%); + } + to { + transform: translateY(0); + } + } + + .closeSidebar { + animation: slideOut 0.5s ease-in-out forwards; + } + + @keyframes slideOut { + from { + transform: translateY(0); + } + to { + transform: translateY(-100%); + } + } } diff --git a/standup/utils.js b/standup/utils.js index a0ff0301..54477c65 100644 --- a/standup/utils.js +++ b/standup/utils.js @@ -19,3 +19,62 @@ function createElement({ type, classList }) { element.classList.add(...classList); return element; } + +function createLoaderElement() { + const loaderElement = document.createElement('div'); + loaderElement.classList.add('loader'); + const wrapperElement = document.createElement('div'); + wrapperElement.classList.add('wrapper'); + const circleElement = document.createElement('div'); + circleElement.classList.add('circle'); + const line1Element = document.createElement('div'); + line1Element.classList.add('line-1'); + const line2Element = document.createElement('div'); + line2Element.classList.add('line-2'); + wrapperElement.appendChild(circleElement); + wrapperElement.appendChild(line1Element); + wrapperElement.appendChild(line2Element); + loaderElement.appendChild(wrapperElement); + return loaderElement; +} + +function createSidebarPanelElement( + completed, + planned, + blockers, + day, + currentMonthName, + currentYear, +) { + const standupHeadElement = createElement({ + type: 'h4', + classList: ['standup-head'], + }); + standupHeadElement.innerHTML = `Standup for ${day} ${currentMonthName} ${currentYear}`; + const sidebarPanelElement = createElement({ + type: 'div', + classList: ['sidebar-panel', 'sidebar'], + }); + sidebarPanelElement.id = 'standupSidebar'; + const completedElement = createElement({ + type: 'div', + classList: ['completed'], + }); + const plannedElement = createElement({ + type: 'div', + classList: ['planned'], + }); + const blockersElement = createElement({ + type: 'div', + classList: ['blockers'], + }); + + completedElement.innerHTML = `Yesterday
${completed}`; + plannedElement.innerHTML = `Today
${planned}`; + blockersElement.innerHTML = `Blockers
${blockers}`; + sidebarPanelElement.appendChild(standupHeadElement); + sidebarPanelElement.appendChild(completedElement); + sidebarPanelElement.appendChild(plannedElement); + sidebarPanelElement.appendChild(blockersElement); + return sidebarPanelElement; +}