From cb90c0a61b22aae3e47bbf42b26b37b5108f9fcd Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sun, 13 Jul 2025 01:37:57 +0530 Subject: [PATCH 1/6] repoList closing properly now Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/scripts/popup.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scripts/popup.js b/src/scripts/popup.js index fa55b5d4..87045f50 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -517,6 +517,8 @@ document.addEventListener('DOMContentLoaded', function () { if(enabled && !hasToken) { useRepoFilter.checked = false; + repoFilterContainer.classList.add('hidden'); // Explicitly hide the container + hideDropdown(); const tokenWarning = document.getElementById('tokenWarningForFilter'); if(tokenWarning) { tokenWarning.classList.remove('hidden'); From 3c08c4fee230a46e7f5b3e338482b9a4310c85d2 Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sun, 13 Jul 2025 01:46:57 +0530 Subject: [PATCH 2/6] disables the filter automatically when the token is removed Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/scripts/popup.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/scripts/popup.js b/src/scripts/popup.js index 87045f50..aba59f4a 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -73,12 +73,22 @@ document.addEventListener('DOMContentLoaded', function () { const useRepoFilter = document.getElementById('useRepoFilter'); const githubTokenInput = document.getElementById('githubToken'); const tokenWarning = document.getElementById('tokenWarningForFilter'); + const repoFilterContainer = document.getElementById('repoFilterContainer'); - if(!useRepoFilter || !githubTokenInput || !tokenWarning) { + if(!useRepoFilter || !githubTokenInput || !tokenWarning || !repoFilterContainer) { return; } const isFilterEnabled = useRepoFilter.checked; const hasToken = githubTokenInput.value.trim() != ''; + + if(isFilterEnabled && !hasToken) { + useRepoFilter.checked = false; + repoFilterContainer.classList.add('hidden'); + if(typeof hideDropdown === 'function') { + hideDropdown(); + } + chrome.storage.local.set({ useRepoFilter: false }); + } tokenWarning.classList.toggle('hidden', !isFilterEnabled || hasToken); } @@ -88,7 +98,7 @@ document.addEventListener('DOMContentLoaded', function () { body.classList.add('dark-mode'); darkModeToggle.src = 'icons/light-mode.png'; if (settingsIcon) { - settingsIcon.src = 'icons/settings-night.png'; // Changed from settings-night.png + settingsIcon.src = 'icons/settings-night.png'; } } }); From f5ca02e588815484bd09c674bb214aeb2ac23ead Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sun, 13 Jul 2025 01:50:27 +0530 Subject: [PATCH 3/6] message is removed after 4 secs Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/scripts/popup.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/scripts/popup.js b/src/scripts/popup.js index aba59f4a..dfe07d91 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -90,6 +90,10 @@ document.addEventListener('DOMContentLoaded', function () { chrome.storage.local.set({ useRepoFilter: false }); } tokenWarning.classList.toggle('hidden', !isFilterEnabled || hasToken); + setTimeout( ()=> { + tokenWarning.classList.add('hidden'); + }, 4000) + } From 6e920bd19f154f783b25ff9d1fe3f3759114364a Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sun, 13 Jul 2025 16:03:05 +0530 Subject: [PATCH 4/6] formatting Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/scripts/popup.js | 466 +++++++++++++++++++++---------------------- 1 file changed, 233 insertions(+), 233 deletions(-) diff --git a/src/scripts/popup.js b/src/scripts/popup.js index dfe07d91..ba365d50 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -1,6 +1,6 @@ function debounce(func, wait) { let timeout; - return function(...args){ + return function (...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); } @@ -75,25 +75,25 @@ document.addEventListener('DOMContentLoaded', function () { const tokenWarning = document.getElementById('tokenWarningForFilter'); const repoFilterContainer = document.getElementById('repoFilterContainer'); - if(!useRepoFilter || !githubTokenInput || !tokenWarning || !repoFilterContainer) { + if (!useRepoFilter || !githubTokenInput || !tokenWarning || !repoFilterContainer) { return; } const isFilterEnabled = useRepoFilter.checked; const hasToken = githubTokenInput.value.trim() != ''; - if(isFilterEnabled && !hasToken) { + if (isFilterEnabled && !hasToken) { useRepoFilter.checked = false; repoFilterContainer.classList.add('hidden'); - if(typeof hideDropdown === 'function') { + if (typeof hideDropdown === 'function') { hideDropdown(); } chrome.storage.local.set({ useRepoFilter: false }); } tokenWarning.classList.toggle('hidden', !isFilterEnabled || hasToken); - setTimeout( ()=> { + setTimeout(() => { tokenWarning.classList.add('hidden'); }, 4000) - + } @@ -243,12 +243,12 @@ document.addEventListener('DOMContentLoaded', function () { initializePopup(); } } - if(changes.startingDate || changes.endingDate) { + if (changes.startingDate || changes.endingDate) { console.log('[POPUP-DEBUG] Date changed in storage, triggering repo fetch.', { startingDate: changes.startingDate?.newValue, endingDate: changes.endingDate?.newValue }); - if(window.triggerRepoFetchIfEnabled){ + if (window.triggerRepoFetchIfEnabled) { window.triggerRepoFetchIfEnabled(); } } @@ -431,17 +431,17 @@ document.addEventListener('DOMContentLoaded', function () { const useRepoFilter = document.getElementById('useRepoFilter'); const repoFilterContainer = document.getElementById('repoFilterContainer'); - if(repoSearch && useRepoFilter && repoFilterContainer) { + if (repoSearch && useRepoFilter && repoFilterContainer) { repoSearch.addEventListener('click', function () { - if(!useRepoFilter.checked){ + if (!useRepoFilter.checked) { useRepoFilter.checked = true; - repoFilterContainer.classList.remove('hidden'); + repoFilterContainer.classList.remove('hidden'); chrome.storage.local.set({ useRepoFilter: true }); } }) } - if(!repoSearch || !useRepoFilter) { + if (!repoSearch || !useRepoFilter) { console.log('Repository, filter elements not found in DOM'); } else { @@ -479,9 +479,9 @@ document.addEventListener('DOMContentLoaded', function () { items.githubToken, items.orgName || '' ); - + availableRepos = repos; - + if (repoStatus) { repoStatus.textContent = `${repos.length} repositories loaded`; } @@ -514,11 +514,11 @@ document.addEventListener('DOMContentLoaded', function () { window.triggerRepoFetchIfEnabled = triggerRepoFetchIfEnabled; chrome.storage.local.get(['selectedRepos', 'useRepoFilter'], (items) => { - if(items.selectedRepos) { + if (items.selectedRepos) { selectedRepos = items.selectedRepos; updateRepoDisplay(); } - if(items.useRepoFilter){ + if (items.useRepoFilter) { useRepoFilter.checked = items.useRepoFilter; repoFilterContainer.classList.toggle('hidden', !items.useRepoFilter); } @@ -529,12 +529,12 @@ document.addEventListener('DOMContentLoaded', function () { const hasToken = githubTokenInput.value.trim() !== ''; repoFilterContainer.classList.toggle('hidden', !enabled); - if(enabled && !hasToken) { + if (enabled && !hasToken) { useRepoFilter.checked = false; repoFilterContainer.classList.add('hidden'); // Explicitly hide the container hideDropdown(); const tokenWarning = document.getElementById('tokenWarningForFilter'); - if(tokenWarning) { + if (tokenWarning) { tokenWarning.classList.remove('hidden'); tokenWarning.classList.add('shake-animation'); setTimeout(() => tokenWarning.classList.remove('shake-animation'), 620); @@ -551,72 +551,72 @@ document.addEventListener('DOMContentLoaded', function () { githubCache: null, //forces refresh }); checkTokenForFilter(); - if(enabled) { - repoStatus.textContent = 'Loading repos automatically..'; - - try{ - const cacheData = await new Promise(resolve => { - chrome.storage.local.get(['repoCache'], resolve); - }); - const items = await new Promise(resolve => { - chrome.storage.local.get(['githubUsername', 'githubToken', 'orgName'], resolve); - }); + if (enabled) { + repoStatus.textContent = 'Loading repos automatically..'; - if(!items.githubUsername){ - repoStatus.textContent = 'Github Username required'; - return; - } + try { + const cacheData = await new Promise(resolve => { + chrome.storage.local.get(['repoCache'], resolve); + }); + const items = await new Promise(resolve => { + chrome.storage.local.get(['githubUsername', 'githubToken', 'orgName'], resolve); + }); - const repoCacheKey = `repos-${items.githubUsername}-${items.orgName || ''}`; - const now = Date.now(); - const cacheAge = cacheData.repoCache?.timestamp ? now - cacheData.repoCache.timestamp : Infinity; - const cacheTTL = 10 * 60 * 1000; // 10 minutes - - if (cacheData.repoCache && - cacheData.repoCache.cacheKey === repoCacheKey && - cacheAge < cacheTTL) { - - console.log('Using cached repositories'); - availableRepos = cacheData.repoCache.data; - repoStatus.textContent = `${availableRepos.length} repositories loaded`; - - if(document.activeElement === repoSearch){ - filterAndDisplayRepos(repoSearch.value.toLowerCase()); + if (!items.githubUsername) { + repoStatus.textContent = 'Github Username required'; + return; } - return; - } - if(window.fetchUserRepositories){ - const repos = await window.fetchUserRepositories( - items.githubUsername, - items.githubToken, - items.orgName || '', - ); - availableRepos = repos; - repoStatus.textContent = `${repos.length} repositories loaded`; + const repoCacheKey = `repos-${items.githubUsername}-${items.orgName || ''}`; + const now = Date.now(); + const cacheAge = cacheData.repoCache?.timestamp ? now - cacheData.repoCache.timestamp : Infinity; + const cacheTTL = 10 * 60 * 1000; // 10 minutes - chrome.storage.local.set({ - repoCache: { - data: repos, - cacheKey: repoCacheKey, - timestamp: now + if (cacheData.repoCache && + cacheData.repoCache.cacheKey === repoCacheKey && + cacheAge < cacheTTL) { + + console.log('Using cached repositories'); + availableRepos = cacheData.repoCache.data; + repoStatus.textContent = `${availableRepos.length} repositories loaded`; + + if (document.activeElement === repoSearch) { + filterAndDisplayRepos(repoSearch.value.toLowerCase()); } - }); + return; + } - if(document.activeElement === repoSearch){ - filterAndDisplayRepos(repoSearch.value.toLowerCase()); + if (window.fetchUserRepositories) { + const repos = await window.fetchUserRepositories( + items.githubUsername, + items.githubToken, + items.orgName || '', + ); + availableRepos = repos; + repoStatus.textContent = `${repos.length} repositories loaded`; + + chrome.storage.local.set({ + repoCache: { + data: repos, + cacheKey: repoCacheKey, + timestamp: now + } + }); + + if (document.activeElement === repoSearch) { + filterAndDisplayRepos(repoSearch.value.toLowerCase()); + } + } + } catch (err) { + console.error('Auto load repos failed', err); + if (err.message?.includes('401')) { + repoStatus.textContent = 'Github token required for private repos'; + } else if (err.message?.includes('username')) { + repoStatus.textContent = 'Please enter your Github username first'; + } else { + repoStatus.textContent = `Error: ${err.message || 'Failed to load repos'}`; } } - } catch(err) { - console.error('Auto load repos failed', err); - if(err.message?.includes('401')) { - repoStatus.textContent = 'Github token required for private repos'; - } else if( err.message?.includes('username')){ - repoStatus.textContent = 'Please enter your Github username first'; - } else { - repoStatus.textContent = `Error: ${err.message || 'Failed to load repos'}`; - } - } } else { selectedRepos = []; updateRepoDisplay(); @@ -628,20 +628,20 @@ document.addEventListener('DOMContentLoaded', function () { repoSearch.addEventListener('keydown', (e) => { const items = repoDropdown.querySelectorAll('.repository-dropdown-item'); - switch(e.key) { + switch (e.key) { case 'ArrowDown': e.preventDefault(); - highlightedIndex = Math.min(highlightedIndex+ 1, items.length - 1); + highlightedIndex = Math.min(highlightedIndex + 1, items.length - 1); updateHighlight(items); break; case 'ArrowUp': e.preventDefault(); - highlightedIndex = Math.max(highlightedIndex-1, 0); + highlightedIndex = Math.max(highlightedIndex - 1, 0); updateHighlight(items); break; case 'Enter': e.preventDefault(); - if(highlightedIndex >= 0 && items[highlightedIndex]) { + if (highlightedIndex >= 0 && items[highlightedIndex]) { fnSelectedRepos(items[highlightedIndex].dataset.repoName); } break; @@ -657,7 +657,7 @@ document.addEventListener('DOMContentLoaded', function () { }) let programmaticFocus = false; repoSearch.addEventListener('focus', function () { - if(programmaticFocus){ + if (programmaticFocus) { programmaticFocus = false; return; } @@ -669,7 +669,7 @@ document.addEventListener('DOMContentLoaded', function () { }); document.addEventListener('click', (e) => { - if(!e.target.closest('#repoSearch') && !e.target.closest('#repoDropdown')) { + if (!e.target.closest('#repoSearch') && !e.target.closest('#repoDropdown')) { hideDropdown(); } }); @@ -687,8 +687,8 @@ document.addEventListener('DOMContentLoaded', function () { async function loadRepos() { console.log('window.fetchUserRepositories exists:', !!window.fetchUserRepositories); console.log('Available functions:', Object.keys(window).filter(key => key.includes('fetch'))); - - if(!window.fetchUserRepositories) { + + if (!window.fetchUserRepositories) { repoStatus.textContent = 'Repository fetching not available'; return; } @@ -699,7 +699,7 @@ document.addEventListener('DOMContentLoaded', function () { hasToken: !!items.githubToken, username: items.githubUsername }); - + if (!items.githubUsername) { repoStatus.textContent = 'GitHub username required'; return; @@ -718,7 +718,7 @@ document.addEventListener('DOMContentLoaded', function () { const cacheData = await new Promise(resolve => { chrome.storage.local.get(['repoCache'], resolve); }); - const storageItems = await new Promise( resolve => { + const storageItems = await new Promise(resolve => { chrome.storage.local.get(['githubUsername', 'githubToken', 'orgName'], resolve); }) const repoCacheKey = `repos-${storageItems.githubUsername}-${storageItems.orgName || ''}`; @@ -734,23 +734,23 @@ document.addEventListener('DOMContentLoaded', function () { isFresh: cacheAge < cacheTTL }); - if (cacheData.repoCache && - cacheData.repoCache.cacheKey === repoCacheKey && + if (cacheData.repoCache && + cacheData.repoCache.cacheKey === repoCacheKey && cacheAge < cacheTTL) { - + console.log('[POPUP-DEBUG] Using cached repositories in manual fetch'); availableRepos = cacheData.repoCache.data; repoStatus.textContent = `${availableRepos.length} repositories loaded`; - - if(document.activeElement === repoSearch){ + + if (document.activeElement === repoSearch) { filterAndDisplayRepos(repoSearch.value.toLowerCase()); } return; } console.log('[POPUP-DEBUG] No valid cache. Fetching from network.'); availableRepos = await window.fetchUserRepositories( - storageItems.githubUsername, - storageItems.githubToken, + storageItems.githubUsername, + storageItems.githubToken, storageItems.orgName || '' ); repoStatus.textContent = `${availableRepos.length} repositories loaded`; @@ -764,12 +764,12 @@ document.addEventListener('DOMContentLoaded', function () { } }); - if(document.activeElement === repoSearch){ + if (document.activeElement === repoSearch) { filterAndDisplayRepos(repoSearch.value.toLowerCase()); } } catch (err) { console.error(`Failed to load repos:`, err); - + if (err.message && err.message.includes('401')) { repoStatus.textContent = 'GitHub token required for private repos'; } else if (err.message && err.message.includes('username')) { @@ -777,23 +777,23 @@ document.addEventListener('DOMContentLoaded', function () { } else { repoStatus.textContent = `Error: ${err.message || 'Failed to load repositories'}`; } - } finally{ + } finally { repoSearch.classList.remove('repository-search-loading'); } } function filterAndDisplayRepos(query) { - if(availableRepos.length === 0) { + if (availableRepos.length === 0) { repoDropdown.innerHTML = '
Organization cleared. Click Generate button to fetch all your GitHub activities.
`; - } - chrome.storage.local.remove(['githubCache', 'repoCache']); - triggerRepoFetchIfEnabled(); - setOrgBtn.disabled = false; - setOrgBtn.innerHTML = originalText; - }); - return; - } - - setOrgBtn.disabled = true; - const originalText = setOrgBtn.innerHTML; - setOrgBtn.innerHTML = ''; - - fetch(`https://api.github.com/orgs/${org}`) - .then(res => { - if (res.status === 404) { - setOrgBtn.disabled = false; - setOrgBtn.innerHTML = originalText; - const oldToast = document.getElementById('invalid-org-toast'); - if (oldToast) oldToast.parentNode.removeChild(oldToast); - const toastDiv = document.createElement('div'); - toastDiv.id = 'invalid-org-toast'; - toastDiv.className = 'toast'; - toastDiv.style.background = '#dc2626'; - toastDiv.style.color = '#fff'; - toastDiv.style.fontWeight = 'bold'; - toastDiv.style.padding = '12px 24px'; - toastDiv.style.borderRadius = '8px'; - toastDiv.style.position = 'fixed'; - toastDiv.style.top = '24px'; - toastDiv.style.left = '50%'; - toastDiv.style.transform = 'translateX(-50%)'; - toastDiv.style.zIndex = '9999'; - toastDiv.innerText = 'Organization not found on GitHub.'; - document.body.appendChild(toastDiv); - setTimeout(() => { - if (toastDiv.parentNode) toastDiv.parentNode.removeChild(toastDiv); - }, 3000); - return; - } - const oldToast = document.getElementById('invalid-org-toast'); - if (oldToast) oldToast.parentNode.removeChild(oldToast); +// Add click event for setOrgBtn to set org +setOrgBtn.addEventListener('click', function () { + let org = orgInput.value.trim().toLowerCase(); + // Do not default to any org, allow empty string + // if (!org) { + // org = 'fossasia'; + // } + console.log('[Org Check] Checking organization:', org); + if (!org) { + // If org is empty, clear orgName in storage but don't auto-generate report + chrome.storage.local.set({ orgName: '' }, function () { + console.log('[Org Check] Organization cleared from storage'); + const scrumReport = document.getElementById('scrumReport'); + if (scrumReport) { + scrumReport.innerHTML = `Organization cleared. Click Generate button to fetch all your GitHub activities.
`; + } + chrome.storage.local.remove(['githubCache', 'repoCache']); + triggerRepoFetchIfEnabled(); + setOrgBtn.disabled = false; + setOrgBtn.innerHTML = originalText; + }); + return; + } - chrome.storage.local.set({ orgName: org }, function () { - // Always clear the scrum report and show org changed message - const scrumReport = document.getElementById('scrumReport'); - if (scrumReport) { - scrumReport.innerHTML = 'Organization changed. Click Generate button to fetch the GitHub activities.
'; - } - // Clear the githubCache for previous org - chrome.storage.local.remove('githubCache'); - setOrgBtn.disabled = false; - setOrgBtn.innerHTML = originalText; - // Always show green toast: org is set - const toastDiv = document.createElement('div'); - toastDiv.id = 'invalid-org-toast'; - toastDiv.className = 'toast'; - toastDiv.style.background = '#10b981'; - toastDiv.style.color = '#fff'; - toastDiv.style.fontWeight = 'bold'; - toastDiv.style.padding = '12px 24px'; - toastDiv.style.borderRadius = '8px'; - toastDiv.style.position = 'fixed'; - toastDiv.style.top = '24px'; - toastDiv.style.left = '50%'; - toastDiv.style.transform = 'translateX(-50%)'; - toastDiv.style.zIndex = '9999'; - toastDiv.innerText = 'Organization is set.'; - document.body.appendChild(toastDiv); - setTimeout(() => { - if (toastDiv.parentNode) toastDiv.parentNode.removeChild(toastDiv); - }, 2500); + setOrgBtn.disabled = true; + const originalText = setOrgBtn.innerHTML; + setOrgBtn.innerHTML = ''; - }); - }) - .catch((err) => { + fetch(`https://api.github.com/orgs/${org}`) + .then(res => { + if (res.status === 404) { setOrgBtn.disabled = false; setOrgBtn.innerHTML = originalText; const oldToast = document.getElementById('invalid-org-toast'); @@ -1020,43 +960,103 @@ document.addEventListener('DOMContentLoaded', function () { toastDiv.style.left = '50%'; toastDiv.style.transform = 'translateX(-50%)'; toastDiv.style.zIndex = '9999'; - toastDiv.innerText = 'Error validating organization.'; + toastDiv.innerText = 'Organization not found on GitHub.'; document.body.appendChild(toastDiv); setTimeout(() => { if (toastDiv.parentNode) toastDiv.parentNode.removeChild(toastDiv); }, 3000); - }); - }); - - let cacheInput = document.getElementById('cacheInput'); - if (cacheInput) { - chrome.storage.local.get(['cacheInput'], function (result) { - if (result.cacheInput) { - cacheInput.value = result.cacheInput; - } else { - cacheInput.value = 10; + return; } - }); + const oldToast = document.getElementById('invalid-org-toast'); + if (oldToast) oldToast.parentNode.removeChild(oldToast); - cacheInput.addEventListener('blur', function () { - let ttlValue = parseInt(this.value); - if (isNaN(ttlValue) || ttlValue <= 0 || this.value.trim() === '') { - ttlValue = 10; - this.value = ttlValue; - this.style.borderColor = '#ef4444'; - } else if (ttlValue > 1440) { - ttlValue = 1440; - this.value = ttlValue; - this.style.borderColor = '#f59e0b'; - } else { - this.style.borderColor = '#10b981'; - } + chrome.storage.local.set({ orgName: org }, function () { + // Always clear the scrum report and show org changed message + const scrumReport = document.getElementById('scrumReport'); + if (scrumReport) { + scrumReport.innerHTML = 'Organization changed. Click Generate button to fetch the GitHub activities.
'; + } + // Clear the githubCache for previous org + chrome.storage.local.remove('githubCache'); + setOrgBtn.disabled = false; + setOrgBtn.innerHTML = originalText; + // Always show green toast: org is set + const toastDiv = document.createElement('div'); + toastDiv.id = 'invalid-org-toast'; + toastDiv.className = 'toast'; + toastDiv.style.background = '#10b981'; + toastDiv.style.color = '#fff'; + toastDiv.style.fontWeight = 'bold'; + toastDiv.style.padding = '12px 24px'; + toastDiv.style.borderRadius = '8px'; + toastDiv.style.position = 'fixed'; + toastDiv.style.top = '24px'; + toastDiv.style.left = '50%'; + toastDiv.style.transform = 'translateX(-50%)'; + toastDiv.style.zIndex = '9999'; + toastDiv.innerText = 'Organization is set.'; + document.body.appendChild(toastDiv); + setTimeout(() => { + if (toastDiv.parentNode) toastDiv.parentNode.removeChild(toastDiv); + }, 2500); - chrome.storage.local.set({ cacheInput: ttlValue }, function () { - console.log('Cache TTL saved:', ttlValue, 'minutes'); }); + }) + .catch((err) => { + setOrgBtn.disabled = false; + setOrgBtn.innerHTML = originalText; + const oldToast = document.getElementById('invalid-org-toast'); + if (oldToast) oldToast.parentNode.removeChild(oldToast); + const toastDiv = document.createElement('div'); + toastDiv.id = 'invalid-org-toast'; + toastDiv.className = 'toast'; + toastDiv.style.background = '#dc2626'; + toastDiv.style.color = '#fff'; + toastDiv.style.fontWeight = 'bold'; + toastDiv.style.padding = '12px 24px'; + toastDiv.style.borderRadius = '8px'; + toastDiv.style.position = 'fixed'; + toastDiv.style.top = '24px'; + toastDiv.style.left = '50%'; + toastDiv.style.transform = 'translateX(-50%)'; + toastDiv.style.zIndex = '9999'; + toastDiv.innerText = 'Error validating organization.'; + document.body.appendChild(toastDiv); + setTimeout(() => { + if (toastDiv.parentNode) toastDiv.parentNode.removeChild(toastDiv); + }, 3000); }); - } +}); + +let cacheInput = document.getElementById('cacheInput'); +if (cacheInput) { + chrome.storage.local.get(['cacheInput'], function (result) { + if (result.cacheInput) { + cacheInput.value = result.cacheInput; + } else { + cacheInput.value = 10; + } + }); + + cacheInput.addEventListener('blur', function () { + let ttlValue = parseInt(this.value); + if (isNaN(ttlValue) || ttlValue <= 0 || this.value.trim() === '') { + ttlValue = 10; + this.value = ttlValue; + this.style.borderColor = '#ef4444'; + } else if (ttlValue > 1440) { + ttlValue = 1440; + this.value = ttlValue; + this.style.borderColor = '#f59e0b'; + } else { + this.style.borderColor = '#10b981'; + } + + chrome.storage.local.set({ cacheInput: ttlValue }, function () { + console.log('Cache TTL saved:', ttlValue, 'minutes'); + }); + }); +} // Tooltip bubble @@ -1147,12 +1147,12 @@ document.getElementById('refreshCache').addEventListener('click', async function scrumReport.innerHTML = 'Cache cleared successfully. Click "Generate Report" to fetch fresh data.
'; } - if(typeof availableRepos !== 'undefined'){ + if (typeof availableRepos !== 'undefined') { availableRepos = []; } const repoStatus = document.getElementById('repoStatus'); - if(repoStatus){ + if (repoStatus) { repoStatus.textContent = ''; } @@ -1281,7 +1281,7 @@ function toggleRadio(radio) { end: endDateInput.value, isLastWeek: radio.id === 'lastWeekContribution' }); - + triggerRepoFetchIfEnabled(); }); } From 6030da38d380b857f69a7da36e8b1c8e7c4d25ea Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:54:59 +0530 Subject: [PATCH 5/6] filtering when org is set Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/scripts/scrumHelper.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 83f472ee..dc63089d 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -714,9 +714,16 @@ function allIncluded(outputTarget = 'email') { async function processGithubData(data) { log('Processing Github data'); - githubIssuesData = data.githubIssuesData; - githubPrsReviewData = data.githubPrsReviewData; - githubUserData = data.githubUserData; + let filteredData = data; + // Always apply repo filter if it's enabled and repos are selected. + if (useRepoFilter && selectedRepos && selectedRepos.length > 0) { + log('[SCRUM-HELPER]: Filtering data by selected repos:', selectedRepos); + filteredData = filterDataByRepos(data, selectedRepos); + } + + githubIssuesData = filteredData.githubIssuesData; + githubPrsReviewData = filteredData.githubPrsReviewData; + githubUserData = filteredData.githubUserData; log('GitHub data set:', { issues: githubIssuesData?.items?.length || 0, @@ -725,6 +732,8 @@ function allIncluded(outputTarget = 'email') { filtered: useRepoFilter }); + + lastWeekArray = []; nextWeekArray = []; reviewedPrsArray = []; From fecdc9e432554796ece3ca01c19e0e664184665e Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Mon, 14 Jul 2025 19:53:04 +0530 Subject: [PATCH 6/6] help text change Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/popup.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/popup.html b/src/popup.html index 284f8614..8cfc1420 100644 --- a/src/popup.html +++ b/src/popup.html @@ -221,7 +221,9 @@Filter by repositories
- Github Token required.
+ Github Token required.
+ To force a repo list update,
+ click the Refresh Data button.