From ef02d66403b2e9adb1dfa2083d0039b308139ed3 Mon Sep 17 00:00:00 2001 From: Relacosm Date: Tue, 8 Apr 2025 23:35:13 +0530 Subject: [PATCH] The SCRUM Helper tool helps prefill the SCRUM updates in Google Groups with your FOSSASIA contributions. Users can input their GitHub username, project details, and specify the date range to fetch contributions. The tool also provides an option to display open/closed labels for issues and PRs, and allows the user to share what might be stopping them from completing their work. After entering the details, users can preview and copy the generated SCRUM report to their clipboard. --- src/index.css | 44 ++++++++++ src/popup.html | 65 +++++++++++---- src/scripts/main.js | 192 +++++++++++++++++++++++++++++++------------- 3 files changed, 228 insertions(+), 73 deletions(-) diff --git a/src/index.css b/src/index.css index 2a5ca72..68e50cc 100644 --- a/src/index.css +++ b/src/index.css @@ -7,46 +7,90 @@ body { * { box-sizing: border-box; } + .datepicker { margin-bottom: 5px !important; } + .tabs .tab a:hover, .tabs .tab a.active { background-color: transparent; color: #3f51b5; } + .tabs { background-color: transparent; } + .tabs .tab a { color: #3f51b5; } + .tabs .indicator { background-color: #3f51b5; } + .switch label input[type="checkbox"]:checked + .lever { background-color: #3f51b5; } + .switch label input[type="checkbox"]:checked + .lever:after { background-color: #fcfcfc; left: 24px; } + [type="checkbox"].filled-in:checked + label:after { border: 2px solid #3f51b5; background-color: #3f51b5; } + .btn:hover, .btn-large:hover { background-color: #3f51b5; } + a { color: #3f51b5; } + .btn, .btn-large { background-color: #3f51b5; } + li { list-style-type: disc !important; margin-left: 1rem; } + +/* Add these styles for the preview functionality */ +.scrum-preview { + max-height: 400px; + overflow-y: auto; + padding: 10px; + border: 1px solid #e0e0e0; + border-radius: 4px; + background-color: #f9f9f9; + margin-bottom: 10px; + font-family: monospace; + white-space: pre-wrap; +} + +.modal { + max-height: 80% !important; + width: 90% !important; +} + +#copyPreview { + margin-right: 10px; +} + +.label-open { + color: #2e7d32; + font-weight: bold; +} + +.label-closed { + color: #c62828; + font-weight: bold; +} diff --git a/src/popup.html b/src/popup.html index 6390d99..2346c6f 100644 --- a/src/popup.html +++ b/src/popup.html @@ -8,13 +8,13 @@ + html,body { + width: 350px !important; + height: 600px !important; + max-height: 600px !important; + overflow-y: scroll; + } +
@@ -33,6 +33,7 @@
+
    @@ -41,6 +42,7 @@
+
@@ -58,7 +60,6 @@
Starting Date:
-
Ending Date
@@ -74,28 +75,62 @@
-
Note:
    -
  • The PRs fetched are according to the date last reviewed by anyone. So if you reviewed a PR 10 days back, and someone reviewed it 2 days back, it will appear in your last week's activity. See this issue. -
  • -
  • By using the extension you understand that there might be discrepancies in the SCRUM generated. You are advised to edit the SCRUM afterwards to remove any discrepancies. -
  • +
  • The PRs fetched are according to the date last reviewed by anyone. So if you reviewed a PR 10 days back, and someone reviewed it 2 days back, it will appear in your last week's activity. See this issue.
  • +
  • By using the extension you understand that there might be discrepancies in the SCRUM generated. You are advised to edit the SCRUM afterwards to remove any discrepancies.
+ +
+ +
+ + + +
+ - + + diff --git a/src/scripts/main.js b/src/scripts/main.js index f1ff385..32b1f1f 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,4 +1,4 @@ -/* global $,Materialize*/ +/* global $,Materialize */ var enableToggleElement = document.getElementById('enable'); var githubUsernameElement = document.getElementById('githubUsername'); var projectNameElement = document.getElementById('projectName'); @@ -7,9 +7,12 @@ var startingDateElement = document.getElementById('startingDate'); var endingDateElement = document.getElementById('endingDate'); var showOpenLabelElement = document.getElementById('showOpenLabel'); var userReasonElement = document.getElementById('userReason'); -var gsoc = 0; //0 means gsoc. 1 means gsoc +var previewButtonElement = document.getElementById('previewScrum'); +var copyPreviewElement = document.getElementById('copyPreview'); + +var gsoc = 0; // 0 means Codeheat, 1 means GSoC + function handleBodyOnLoad() { - // prefill name chrome.storage.local.get( [ 'githubUsername', @@ -24,35 +27,23 @@ function handleBodyOnLoad() { 'gsoc', ], (items) => { - if (items.githubUsername) { - githubUsernameElement.value = items.githubUsername; - } - if (items.projectName) { - projectNameElement.value = items.projectName; - } + if (items.githubUsername) githubUsernameElement.value = items.githubUsername; + if (items.projectName) projectNameElement.value = items.projectName; if (items.enableToggle) { enableToggleElement.checked = items.enableToggle; } else if (items.enableToggle !== false) { - // undefined enableToggleElement.checked = true; handleEnableChange(); } - if (items.endingDate) { - endingDateElement.value = items.endingDate; - } - if (items.startingDate) { - startingDateElement.value = items.startingDate; - } + if (items.endingDate) endingDateElement.value = items.endingDate; + if (items.startingDate) startingDateElement.value = items.startingDate; if (items.showOpenLabel) { showOpenLabelElement.checked = items.showOpenLabel; } else if (items.showOpenLabel !== false) { - // undefined showOpenLabelElement.checked = true; handleOpenLabelChange(); } - if (items.userReason) { - userReasonElement.value = items.userReason; - } + if (items.userReason) userReasonElement.value = items.userReason; if (items.lastWeekContribution) { lastWeekContributionElement.checked = items.lastWeekContribution; handleLastWeekContributionChange(); @@ -65,21 +56,22 @@ function handleBodyOnLoad() { } else { handleCodeheatClick(); } - }, + } ); } + function handleEnableChange() { - var value = enableToggleElement.checked; - chrome.storage.local.set({ enableToggle: value }); + chrome.storage.local.set({ enableToggle: enableToggleElement.checked }); } + function handleStartingDateChange() { - var value = startingDateElement.value; - chrome.storage.local.set({ startingDate: value }); + chrome.storage.local.set({ startingDate: startingDateElement.value }); } + function handleEndingDateChange() { - var value = endingDateElement.value; - chrome.storage.local.set({ endingDate: value }); + chrome.storage.local.set({ endingDate: endingDateElement.value }); } + function handleLastWeekContributionChange() { var value = lastWeekContributionElement.checked; if (value) { @@ -95,53 +87,45 @@ function handleLastWeekContributionChange() { } chrome.storage.local.set({ lastWeekContribution: value }); } + function getLastWeek() { var today = new Date(); - var noDays_to_goback = gsoc == 0 ? 7 : 1; - var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - noDays_to_goback); - var lastWeekMonth = lastWeek.getMonth() + 1; - var lastWeekDay = lastWeek.getDate(); - var lastWeekYear = lastWeek.getFullYear(); - var lastWeekDisplayPadded = - ('0000' + lastWeekYear.toString()).slice(-4) + - '-' + - ('00' + lastWeekMonth.toString()).slice(-2) + - '-' + - ('00' + lastWeekDay.toString()).slice(-2); - return lastWeekDisplayPadded; + var daysBack = gsoc === 0 ? 7 : 1; + var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - daysBack); + return formatDate(lastWeek); } + function getToday() { - var today = new Date(); - var Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); - var WeekMonth = Week.getMonth() + 1; - var WeekDay = Week.getDate(); - var WeekYear = Week.getFullYear(); - var WeekDisplayPadded = - ('0000' + WeekYear.toString()).slice(-4) + + return formatDate(new Date()); +} + +function formatDate(date) { + return ( + ('0000' + date.getFullYear()).slice(-4) + '-' + - ('00' + WeekMonth.toString()).slice(-2) + + ('00' + (date.getMonth() + 1)).slice(-2) + '-' + - ('00' + WeekDay.toString()).slice(-2); - return WeekDisplayPadded; + ('00' + date.getDate()).slice(-2) + ); } function handleGithubUsernameChange() { - var value = githubUsernameElement.value; - chrome.storage.local.set({ githubUsername: value }); + chrome.storage.local.set({ githubUsername: githubUsernameElement.value }); } + function handleProjectNameChange() { - var value = projectNameElement.value; - chrome.storage.local.set({ projectName: value }); + chrome.storage.local.set({ projectName: projectNameElement.value }); } + function handleOpenLabelChange() { var value = showOpenLabelElement.checked; - chrome.storage.local.set({ showOpenLabel: value }); - chrome.storage.local.set({ showClosedLabel: value }); + chrome.storage.local.set({ showOpenLabel: value, showClosedLabel: value }); } + function handleUserReasonChange() { - var value = userReasonElement.value; - chrome.storage.local.set({ userReason: value }); + chrome.storage.local.set({ userReason: userReasonElement.value }); } + function handleCodeheatClick() { gsoc = 0; $('#codeheatTab').addClass('active'); @@ -150,6 +134,7 @@ function handleCodeheatClick() { chrome.storage.local.set({ gsoc: 0 }); handleLastWeekContributionChange(); } + function handleGsocClick() { gsoc = 1; $('#gsocTab').addClass('active'); @@ -158,6 +143,96 @@ function handleGsocClick() { chrome.storage.local.set({ gsoc: 1 }); handleLastWeekContributionChange(); } + +// Preview Scrum logic +function handlePreviewClick() { + var username = githubUsernameElement.value; + var projectName = projectNameElement.value; + var startDate = startingDateElement.value; + var endDate = endingDateElement.value; + var showLabels = showOpenLabelElement.checked; + var reason = userReasonElement.value; + + if (!username) { + Materialize.toast('Please enter your GitHub username', 3000); + return; + } + + $('#previewModal').modal('open'); + $('#previewContent').html('

Loading your GitHub data...

'); + + fetchGitHubData(username, startDate, endDate) + .then((data) => { + var preview = generateScrumReport(data, projectName, showLabels, reason); + $('#previewContent').html(preview); + }) + .catch((error) => { + $('#previewContent').html('

Error loading data: ' + error.message + '

'); + }); +} + +function fetchGitHubData(username, startDate, endDate) { + var apiUrl = `https://api.github.com/search/issues?q=author:${username}+org:fossasia+updated:${startDate}..${endDate}`; + return fetch(apiUrl) + .then((response) => { + if (!response.ok) throw new Error('GitHub API request failed'); + return response.json(); + }) + .then((data) => ({ items: data.items || [] })); +} + +function generateScrumReport(data, projectName, showLabels, reason) { + var items = data.items || []; + var prs = items.filter((item) => item.pull_request); + var issues = items.filter((item) => !item.pull_request); + var html = `
Project: ${projectName || 'N/A'}
`; + html += '
What did I do last week?
What am I going to do this week?
'; + html += `
What is stopping me?
`; + + return html; +} + +function handleCopyPreview() { + var previewText = document.getElementById('previewContent').innerText; + var textarea = document.createElement('textarea'); + textarea.value = previewText; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + document.body.removeChild(textarea); + Materialize.toast('Copied to clipboard!', 2000); +} + +function initializeModal() { + $('.modal').modal(); +} + +document.addEventListener('DOMContentLoaded', function () { + initializeModal(); + handleBodyOnLoad(); +}); + enableToggleElement.addEventListener('change', handleEnableChange); githubUsernameElement.addEventListener('keyup', handleGithubUsernameChange); projectNameElement.addEventListener('keyup', handleProjectNameChange); @@ -166,6 +241,7 @@ endingDateElement.addEventListener('change', handleEndingDateChange); lastWeekContributionElement.addEventListener('change', handleLastWeekContributionChange); showOpenLabelElement.addEventListener('change', handleOpenLabelChange); userReasonElement.addEventListener('keyup', handleUserReasonChange); -document.addEventListener('DOMContentLoaded', handleBodyOnLoad); document.getElementById('codeheatTab').addEventListener('click', handleCodeheatClick); document.getElementById('gsocTab').addEventListener('click', handleGsocClick); +previewButtonElement.addEventListener('click', handlePreviewClick); +copyPreviewElement.addEventListener('click', handleCopyPreview);