From 08d1ff4c2b236d3ebb82169853db2063d4e42cb9 Mon Sep 17 00:00:00 2001 From: Vikas4245 Date: Sun, 10 Aug 2025 17:39:59 +0530 Subject: [PATCH 1/3] Fix issue labeling: Distinguish between opened and updated issues - Add logic to determine if an issue was created or updated in the selected date range - Issues created in date range show 'Opened Issue' - Issues updated but not created in date range show 'Updated Issue' - Mirrors existing PR logic that distinguishes 'Made PR' vs 'Existing PR' - Fixes confusion where all issues were always labeled as 'Opened Issue' Resolves the issue where users couldn't differentiate between newly created issues and existing issues that were just updated during the selected period. --- src/scripts/scrumHelper.js | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 2572cba..9c4e18f 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -1507,25 +1507,51 @@ ${userReason}`; nextWeekArray.push(li2); } + // Determine if issue was created or updated in date range + const issueCreatedDate = new Date(item.created_at); + + // Get the correct date range for filtering + let startDateFilter, endDateFilter; + if (yesterdayContribution) { + const today = new Date(); + const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); + startDateFilter = new Date(yesterday.toISOString().split('T')[0] + 'T00:00:00Z'); + endDateFilter = new Date(today.toISOString().split('T')[0] + 'T23:59:59Z'); + } else if (startingDate && endingDate) { + startDateFilter = new Date(startingDate + 'T00:00:00Z'); + endDateFilter = new Date(endingDate + 'T23:59:59Z'); + } else { + // Default to last 7 days if no date range is set + const today = new Date(); + const lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); + startDateFilter = new Date(lastWeek.toISOString().split('T')[0] + 'T00:00:00Z'); + endDateFilter = new Date(today.toISOString().split('T')[0] + 'T23:59:59Z'); + } + + const isNewIssue = issueCreatedDate >= startDateFilter && issueCreatedDate <= endDateFilter; + const issueAction = isNewIssue ? 'Opened Issue' : 'Updated Issue'; + + log(`[ISSUE DEBUG] Issue #${number} - isNewIssue: ${isNewIssue}, issueAction: ${issueAction}, state: ${item.state}, created: ${item.created_at}, updated: ${item.updated_at}`); + if (item.state === 'open') { - li = `
  • (${project}) - Opened Issue(#${number}) - ${title}${showOpenLabel ? ' ' + issue_opened_button : ''}
  • `; + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}${showOpenLabel ? ' ' + issue_opened_button : ''}
  • `; } else if (item.state === 'closed') { // Use state_reason to distinguish closure reason if (item.state_reason === 'completed') { - li = `
  • (${project}) - Opened Issue(#${number}) - ${title} ${issue_closed_completed_button}
  • `; + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_completed_button}
  • `; } else if (item.state_reason === 'not_planned') { - li = `
  • (${project}) - Opened Issue(#${number}) - ${title} ${issue_closed_notplanned_button}
  • `; + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_notplanned_button}
  • `; } else { - li = `
  • (${project}) - Opened Issue(#${number}) - ${title} ${issue_closed_button}
  • `; + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_button}
  • `; } } else { // Fallback for unexpected state - li = `
  • (${project}) - Opened Issue(#${number}) - ${title}
  • `; + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}
  • `; } log('[SCRUM-DEBUG] Added issue to lastWeekArray:', li, item); From 79930dd4653c32b289efc6758f91368df20838ab Mon Sep 17 00:00:00 2001 From: Vikas4245 Date: Sun, 10 Aug 2025 19:02:42 +0530 Subject: [PATCH 2/3] Address code review feedback: Improve issue labeling implementation - Extract date range calculation into reusable getDateRangeFilters() helper - Add proper updated_at timestamp validation for 'Updated Issue' labeling - Fix timezone issues with UTC-based date handling - Use time-based arithmetic to avoid month boundary bugs - Gate debug logging to prevent production noise - Eliminate code duplication between PR and issue processing - Add comprehensive validation to prevent stale issues being labeled as 'Updated' Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- src/scripts/scrumHelper.js | 101 +++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 39 deletions(-) diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 9c4e18f..2e4783d 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -13,6 +13,47 @@ function logError(...args) { } } +/** + * Helper function to get date range filters with proper UTC handling + * @param {boolean} yesterdayContribution - Whether to use yesterday contribution mode + * @param {string} startingDate - Starting date string (YYYY-MM-DD format) + * @param {string} endingDate - Ending date string (YYYY-MM-DD format) + * @returns {Object} Object with startDateFilter and endDateFilter as Date objects + */ +function getDateRangeFilters(yesterdayContribution, startingDate, endingDate) { + let startDateFilter, endDateFilter; + + if (yesterdayContribution) { + const now = new Date(); + // Use time-based arithmetic to avoid timezone issues + const yesterdayTime = now.getTime() - 24 * 60 * 60 * 1000; + const yesterday = new Date(yesterdayTime); + + // Create UTC dates to avoid timezone inconsistencies + const yesterdayStr = yesterday.toISOString().split('T')[0]; + const todayStr = now.toISOString().split('T')[0]; + + startDateFilter = new Date(yesterdayStr + 'T00:00:00.000Z'); + endDateFilter = new Date(todayStr + 'T23:59:59.999Z'); + } else if (startingDate && endingDate) { + startDateFilter = new Date(startingDate + 'T00:00:00.000Z'); + endDateFilter = new Date(endingDate + 'T23:59:59.999Z'); + } else { + // Default to last 7 days - use time arithmetic for consistency + const now = new Date(); + const lastWeekTime = now.getTime() - 7 * 24 * 60 * 60 * 1000; + const lastWeek = new Date(lastWeekTime); + + const lastWeekStr = lastWeek.toISOString().split('T')[0]; + const todayStr = now.toISOString().split('T')[0]; + + startDateFilter = new Date(lastWeekStr + 'T00:00:00.000Z'); + endDateFilter = new Date(todayStr + 'T23:59:59.999Z'); + } + + return { startDateFilter, endDateFilter }; +} + let refreshButton_Placed = false; let enableToggle = true; @@ -1399,33 +1440,21 @@ ${userReason}`; let prAction = ''; const prCreatedDate = new Date(item.created_at); + const prUpdatedDate = new Date(item.updated_at); - // Get the correct date range for filtering - let startDateFilter, endDateFilter; - if (yesterdayContribution) { - const today = new Date(); - const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); - startDateFilter = new Date(yesterday.toISOString().split('T')[0] + 'T00:00:00Z'); - endDateFilter = new Date(today.toISOString().split('T')[0] + 'T23:59:59Z'); // Use yesterday for start and today for end - } else if (startingDate && endingDate) { - startDateFilter = new Date(startingDate + 'T00:00:00Z'); - endDateFilter = new Date(endingDate + 'T23:59:59Z'); - } else { - // Default to last 7 days if no date range is set - const today = new Date(); - const lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); - startDateFilter = new Date(lastWeek.toISOString().split('T')[0] + 'T00:00:00Z'); - endDateFilter = new Date(today.toISOString().split('T')[0] + 'T23:59:59Z'); - } + // Get date range filters using helper function + const { startDateFilter, endDateFilter } = getDateRangeFilters(yesterdayContribution, startingDate, endingDate); const isNewPR = prCreatedDate >= startDateFilter && prCreatedDate <= endDateFilter; - const prUpdatedDate = new Date(item.updated_at); const isUpdatedInRange = prUpdatedDate >= startDateFilter && prUpdatedDate <= endDateFilter; // Check if PR has commits in the date range const hasCommitsInRange = item._allCommits && item._allCommits.length > 0; - log(`[PR DEBUG] PR #${number} - isNewPR: ${isNewPR}, isUpdatedInRange: ${isUpdatedInRange}, state: ${item.state}, hasCommitsInRange: ${hasCommitsInRange}, created: ${item.created_at}, updated: ${item.updated_at}`); + // Only log in debug mode to avoid production noise + if (DEBUG) { + log(`[PR DEBUG] PR #${number} - isNewPR: ${isNewPR}, isUpdatedInRange: ${isUpdatedInRange}, state: ${item.state}, hasCommitsInRange: ${hasCommitsInRange}, created: ${item.created_at}, updated: ${item.updated_at}`); + } if (platform === 'github') { // For existing PRs (not new), they must be open AND have commits in the date range @@ -1509,29 +1538,23 @@ ${userReason}`; // Determine if issue was created or updated in date range const issueCreatedDate = new Date(item.created_at); + const issueUpdatedDate = new Date(item.updated_at); - // Get the correct date range for filtering - let startDateFilter, endDateFilter; - if (yesterdayContribution) { - const today = new Date(); - const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); - startDateFilter = new Date(yesterday.toISOString().split('T')[0] + 'T00:00:00Z'); - endDateFilter = new Date(today.toISOString().split('T')[0] + 'T23:59:59Z'); - } else if (startingDate && endingDate) { - startDateFilter = new Date(startingDate + 'T00:00:00Z'); - endDateFilter = new Date(endingDate + 'T23:59:59Z'); - } else { - // Default to last 7 days if no date range is set - const today = new Date(); - const lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); - startDateFilter = new Date(lastWeek.toISOString().split('T')[0] + 'T00:00:00Z'); - endDateFilter = new Date(today.toISOString().split('T')[0] + 'T23:59:59Z'); - } + // Get date range filters using helper function + const { startDateFilter, endDateFilter } = getDateRangeFilters(yesterdayContribution, startingDate, endingDate); const isNewIssue = issueCreatedDate >= startDateFilter && issueCreatedDate <= endDateFilter; - const issueAction = isNewIssue ? 'Opened Issue' : 'Updated Issue'; - - log(`[ISSUE DEBUG] Issue #${number} - isNewIssue: ${isNewIssue}, issueAction: ${issueAction}, state: ${item.state}, created: ${item.created_at}, updated: ${item.updated_at}`); + + // For "Updated Issue" label, verify both: + // 1. Issue was NOT created in the date range + // 2. Issue was actually updated within the date range + const isUpdatedInRange = issueUpdatedDate >= startDateFilter && issueUpdatedDate <= endDateFilter; + const issueAction = isNewIssue ? 'Opened Issue' : (isUpdatedInRange ? 'Updated Issue' : 'Opened Issue'); + + // Only log in debug mode to avoid production noise + if (DEBUG) { + log(`[ISSUE DEBUG] Issue #${number} - isNewIssue: ${isNewIssue}, isUpdatedInRange: ${isUpdatedInRange}, issueAction: ${issueAction}, state: ${item.state}, created: ${item.created_at}, updated: ${item.updated_at}`); + } if (item.state === 'open') { li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}${showOpenLabel ? ' ' + issue_opened_button : ''}
  • `; From 604dd4ee07400bc371b8fae75e01a30ee7e56e62 Mon Sep 17 00:00:00 2001 From: Vikas4245 Date: Thu, 11 Sep 2025 12:27:38 +0530 Subject: [PATCH 3/3] Fix merge conflicts and unify date range logic in scrumHelper.js --- src/scripts/scrumHelper.js | 348 ++++++++++++------------------------- 1 file changed, 111 insertions(+), 237 deletions(-) diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 2e4783d..726ec10 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -1348,29 +1348,18 @@ ${userReason}`; return; } + const headers = { 'Accept': 'application/vnd.github.v3+json' }; if (githubToken) headers['Authorization'] = `token ${githubToken}`; let useMergedStatus = false; let fallbackToSimple = false; - // Get the correct date range for days calculation - let startDateForRange, endDateForRange; - if (yesterdayContribution) { - const today = new Date(); - const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); - startDateForRange = yesterday.toISOString().split('T')[0]; - endDateForRange = today.toISOString().split('T')[0]; // Use yesterday for start and today for end - } else if (startingDate && endingDate) { - startDateForRange = startingDate; - endDateForRange = endingDate; - } else { - // Default to last 7 days if no date range is set - const today = new Date(); - const lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); - startDateForRange = lastWeek.toISOString().split('T')[0]; - endDateForRange = today.toISOString().split('T')[0]; - } + // Use helper for consistent UTC date range + const { startDateFilter, endDateFilter } = getDateRangeFilters(yesterdayContribution, startingDate, endingDate); + // For days calculation (for merged status logic) + let startDateForRange = startDateFilter.toISOString().split('T')[0]; + let endDateForRange = endDateFilter.toISOString().split('T')[0]; let daysRange = getDaysBetween(startDateForRange, endDateForRange); if (githubToken) { @@ -1379,6 +1368,7 @@ ${userReason}`; useMergedStatus = true; } + let prsToCheck = []; for (let i = 0; i < items.length; i++) { let item = items[i]; @@ -1418,238 +1408,127 @@ ${userReason}`; for (let i = 0; i < items.length; i++) { let item = items[i]; - log('[SCRUM-DEBUG] Processing item:', item); - // For GitLab, treat all items in the MRs array as MRs - let isMR = !!item.pull_request; // works for both GitHub and mapped GitLab data - log('[SCRUM-DEBUG] isMR:', isMR, 'platform:', platform, 'item:', item); - let html_url = item.html_url; - let repository_url = item.repository_url; - // Use project name for GitLab, repo extraction for GitHub - let project = (platform === 'gitlab' && item.project) ? item.project : (repository_url ? repository_url.substr(repository_url.lastIndexOf('/') + 1) : ''); - let title = item.title; - let number = item.number; - let li = ''; - - let isDraft = false; - if (isMR && typeof item.draft !== 'undefined') { - isDraft = item.draft; - } - - if (isMR) { - // Platform-specific label - let prAction = ''; - const prCreatedDate = new Date(item.created_at); - const prUpdatedDate = new Date(item.updated_at); - - // Get date range filters using helper function - const { startDateFilter, endDateFilter } = getDateRangeFilters(yesterdayContribution, startingDate, endingDate); - - const isNewPR = prCreatedDate >= startDateFilter && prCreatedDate <= endDateFilter; - const isUpdatedInRange = prUpdatedDate >= startDateFilter && prUpdatedDate <= endDateFilter; - - // Check if PR has commits in the date range - const hasCommitsInRange = item._allCommits && item._allCommits.length > 0; - - // Only log in debug mode to avoid production noise - if (DEBUG) { - log(`[PR DEBUG] PR #${number} - isNewPR: ${isNewPR}, isUpdatedInRange: ${isUpdatedInRange}, state: ${item.state}, hasCommitsInRange: ${hasCommitsInRange}, created: ${item.created_at}, updated: ${item.updated_at}`); + let isMR = !!item.pull_request; + log('[SCRUM-DEBUG] Processing item:', item); + let html_url = item.html_url; + let repository_url = item.repository_url; + let project = (platform === 'gitlab' && item.project) ? item.project : (repository_url ? repository_url.substr(repository_url.lastIndexOf('/') + 1) : ''); + let title = item.title; + let number = item.number; + let li = ''; + let isDraft = false; + if (isMR && typeof item.draft !== 'undefined') { + isDraft = item.draft; } - if (platform === 'github') { - // For existing PRs (not new), they must be open AND have commits in the date range - if (!isNewPR) { - if (item.state !== 'open') { - log(`[PR DEBUG] Skipping PR #${number} - existing PR but not open`); - continue; - } - if (!hasCommitsInRange) { - log(`[PR DEBUG] Skipping PR #${number} - existing PR but no commits in date range`); - continue; - } + if (isMR) { + // PR/MR date logic + const prCreatedDate = new Date(item.created_at); + const prUpdatedDate = new Date(item.updated_at); + const isNewPR = prCreatedDate >= startDateFilter && prCreatedDate <= endDateFilter; + const isUpdatedInRange = prUpdatedDate >= startDateFilter && prUpdatedDate <= endDateFilter; + const hasCommitsInRange = item._allCommits && item._allCommits.length > 0; + if (DEBUG) { + log(`[PR DEBUG] PR #${number} - isNewPR: ${isNewPR}, isUpdatedInRange: ${isUpdatedInRange}, state: ${item.state}, hasCommitsInRange: ${hasCommitsInRange}, created: ${item.created_at}, updated: ${item.updated_at}`); } - prAction = isNewPR ? 'Made PR' : 'Existing PR'; - log(`[PR DEBUG] Including PR #${number} as ${prAction}`); - } else if (platform === 'gitlab') { - prAction = isNewPR ? 'Made Merge Request' : 'Existing Merge Request'; - } - - if (isDraft) { - - li = `
  • (${project}) - Made PR (#${number}) - ${title}${showOpenLabel ? ' ' + pr_draft_button : ''}`; - if (showCommits && item._allCommits && item._allCommits.length && !isNewPR) { - log(`[PR DEBUG] Rendering commits for existing draft PR #${number}:`, item._allCommits); - li += '
      '; - item._allCommits.forEach(commit => { - li += `
    • ${commit.messageHeadline} (${new Date(commit.committedDate).toLocaleString()})
    • `; - }); - li += '
    '; + let prAction = ''; + if (platform === 'github') { + if (!isNewPR) { + if (item.state !== 'open') { + log(`[PR DEBUG] Skipping PR #${number} - existing PR but not open`); + continue; + } + if (!hasCommitsInRange) { + log(`[PR DEBUG] Skipping PR #${number} - existing PR but no commits in date range`); + continue; + } + } + prAction = isNewPR ? 'Made PR' : 'Updated PR'; + } else if (platform === 'gitlab') { + prAction = isNewPR ? 'Made Merge Request' : 'Updated Merge Request'; } - li += `
  • `; - } else if (item.state === 'open' || item.state === 'opened') { - li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_open_button : ''}`; - - if (showCommits && item._allCommits && item._allCommits.length && !isNewPR) { - log(`[PR DEBUG] Rendering commits for existing PR #${number}:`, item._allCommits); - li += '
      '; - item._allCommits.forEach(commit => { - li += `
    • ${commit.messageHeadline} (${new Date(commit.committedDate).toLocaleString()})
    • `; - }); - li += '
    '; + if (isDraft) { + li = `
  • (${project}) - Made PR (#${number}) - ${title}${showOpenLabel ? ' ' + pr_draft_button : ''}`; + if (showCommits && item._allCommits && item._allCommits.length && !isNewPR) { + log(`[PR DEBUG] Rendering commits for existing draft PR #${number}:`, item._allCommits); + li += '
      '; + item._allCommits.forEach(commit => { + li += `
    • ${commit.messageHeadline} (${new Date(commit.committedDate).toLocaleString()})
    • `; + }); + li += '
    '; + } + li += `
  • `; + } else if (item.state === 'open' || item.state === 'opened') { + li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_open_button : ''}`; + if (showCommits && item._allCommits && item._allCommits.length && !isNewPR) { + log(`[PR DEBUG] Rendering commits for existing PR #${number}:`, item._allCommits); + li += '
      '; + item._allCommits.forEach(commit => { + li += `
    • ${commit.messageHeadline} (${new Date(commit.committedDate).toLocaleString()})
    • `; + }); + li += '
    '; + } + li += `
  • `; + } else if (platform === 'gitlab' && item.state === 'closed') { + li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_closed_button : ''}
  • `; + } else { + let merged = null; + if ((githubToken || (useMergedStatus && !fallbackToSimple)) && mergedStatusResults) { + let repoParts = repository_url.split('/'); + let owner = repoParts[repoParts.length - 2]; + let repo = repoParts[repoParts.length - 1]; + merged = mergedStatusResults[`${owner}/${repo}#${number}`]; + } + if (merged === true) { + li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_merged_button : ''}
  • `; + } else { + li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_closed_button : ''}
  • `; + } } - li += ``; - } else if (platform === 'gitlab' && item.state === 'closed') { - li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_closed_button : ''}
  • `; + log('[SCRUM-DEBUG] Added PR/MR to lastWeekArray:', li, item); + lastWeekArray.push(li); + continue; } else { - let merged = null; - if ((githubToken || (useMergedStatus && !fallbackToSimple)) && mergedStatusResults) { - let repoParts = repository_url.split('/'); - let owner = repoParts[repoParts.length - 2]; - let repo = repoParts[repoParts.length - 1]; - merged = mergedStatusResults[`${owner}/${repo}#${number}`]; + // Only process as issue if not a PR + if (item.state === 'open' && item.body?.toUpperCase().indexOf('YES') > 0) { + let li2 = `
  • (${project}) - Work on Issue(#${number}) - ${title}${showOpenLabel ? ' ' + issue_opened_button : ''}  
  • `; + nextWeekArray.push(li2); } - if (merged === true) { - - li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_merged_button : ''}
  • `; - } else { - // Always show closed label for merged === false or merged === null/undefined - li = `
  • (${project}) - ${prAction} (#${number}) - ${title}${showOpenLabel ? ' ' + pr_closed_button : ''}
  • `; + // Issue date logic + const issueCreatedDate = new Date(item.created_at); + const issueUpdatedDate = new Date(item.updated_at); + const isNewIssue = issueCreatedDate >= startDateFilter && issueCreatedDate <= endDateFilter; + const isUpdatedInRange = issueUpdatedDate >= startDateFilter && issueUpdatedDate <= endDateFilter; + const issueAction = isNewIssue ? 'Opened Issue' : (isUpdatedInRange ? 'Updated Issue' : 'Opened Issue'); + if (DEBUG) { + log(`[ISSUE DEBUG] Issue #${number} - isNewIssue: ${isNewIssue}, isUpdatedInRange: ${isUpdatedInRange}, issueAction: ${issueAction}, state: ${item.state}, created: ${item.created_at}, updated: ${item.updated_at}`); } - } - log('[SCRUM-DEBUG] Added PR/MR to lastWeekArray:', li, item); - lastWeekArray.push(li); - continue; // Prevent issue logic from overwriting PR li - } else { - // Only process as issue if not a PR - if (item.state === 'open' && item.body?.toUpperCase().indexOf('YES') > 0) { - let li2 = - '
  • (' + - project + - ') - Work on Issue(#' + - number + - ") - " + - title + - '' + (showOpenLabel ? ' ' + issue_opened_button : '') + - '  
  • '; - nextWeekArray.push(li2); - } - - // Determine if issue was created or updated in date range - const issueCreatedDate = new Date(item.created_at); - const issueUpdatedDate = new Date(item.updated_at); - - // Get date range filters using helper function - const { startDateFilter, endDateFilter } = getDateRangeFilters(yesterdayContribution, startingDate, endingDate); - - const isNewIssue = issueCreatedDate >= startDateFilter && issueCreatedDate <= endDateFilter; - - // For "Updated Issue" label, verify both: - // 1. Issue was NOT created in the date range - // 2. Issue was actually updated within the date range - const isUpdatedInRange = issueUpdatedDate >= startDateFilter && issueUpdatedDate <= endDateFilter; - const issueAction = isNewIssue ? 'Opened Issue' : (isUpdatedInRange ? 'Updated Issue' : 'Opened Issue'); - - // Only log in debug mode to avoid production noise - if (DEBUG) { - log(`[ISSUE DEBUG] Issue #${number} - isNewIssue: ${isNewIssue}, isUpdatedInRange: ${isUpdatedInRange}, issueAction: ${issueAction}, state: ${item.state}, created: ${item.created_at}, updated: ${item.updated_at}`); - } - - if (item.state === 'open') { - li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}${showOpenLabel ? ' ' + issue_opened_button : ''}
  • `; - - } else if (item.state === 'closed') { - - - // Use state_reason to distinguish closure reason - if (item.state_reason === 'completed') { - li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_completed_button}
  • `; - } else if (item.state_reason === 'not_planned') { - li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_notplanned_button}
  • `; + if (item.state === 'open') { + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}${showOpenLabel ? ' ' + issue_opened_button : ''}
  • `; + } else if (item.state === 'closed') { + if (item.state_reason === 'completed') { + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_completed_button}
  • `; + } else if (item.state_reason === 'not_planned') { + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_notplanned_button}
  • `; + } else { + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_button}
  • `; + } } else { - li = `
  • (${project}) - ${issueAction}(#${number}) - ${title} ${issue_closed_button}
  • `; + li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}
  • `; } - - - } else { - // Fallback for unexpected state - li = `
  • (${project}) - ${issueAction}(#${number}) - ${title}
  • `; + log('[SCRUM-DEBUG] Added issue to lastWeekArray:', li, item); + lastWeekArray.push(li); } - - log('[SCRUM-DEBUG] Added issue to lastWeekArray:', li, item); - lastWeekArray.push(li); - } - } - log('[SCRUM-DEBUG] Final lastWeekArray:', lastWeekArray); - issuesDataProcessed = true; - - } - - - let intervalBody = setInterval(() => { - if (!window.emailClientAdapter) return; - - const elements = window.emailClientAdapter.getEditorElements(); - if (!elements || !elements.body) return; - - clearInterval(intervalBody); - scrumBody = elements.body; - }, 500); - - - let intervalSubject = setInterval(() => { - const userData = platform === 'gitlab' ? (githubUserData || platformUsername) : githubUserData; - if (!userData || !window.emailClientAdapter) return; - - - const elements = window.emailClientAdapter.getEditorElements(); - if (!elements || !elements.subject) return; - - if (outputTarget === 'email' && !window.emailClientAdapter.isNewConversation()) { - console.log('Not a new conversation, skipping subject interval'); - clearInterval(intervalSubject); - return; - } - - clearInterval(intervalSubject); - scrumSubject = elements.subject; - - setTimeout(() => { - scrumSubjectLoaded(); - }, 500); - }, 500); - - - // check for github safe writing - let intervalWriteGithubIssues = setInterval(() => { - if (outputTarget === 'popup') { - return; - } else { - const username = platform === 'gitlab' ? platformUsername : platformUsernameLocal; - if (scrumBody && username && githubIssuesData && githubPrsReviewData) { - clearInterval(intervalWriteGithubIssues); - clearInterval(intervalWriteGithubPrs); - writeGithubIssuesPrs(); - } - } - }, 500); - let intervalWriteGithubPrs = setInterval(() => { - if (outputTarget === 'popup') { - return; - } else { - const username = platform === 'gitlab' ? platformUsername : platformUsernameLocal; - if (scrumBody && username && githubPrsReviewData && githubIssuesData) { - clearInterval(intervalWriteGithubPrs); - clearInterval(intervalWriteGithubIssues); - writeGithubPrsReviews(); } + log('[SCRUM-DEBUG] Final lastWeekArray:', lastWeekArray); + issuesDataProcessed = true; } - }, 500); + // Place the refresh button in the UI if not already placed if (!refreshButton_Placed) { let intervalWriteButton = setInterval(() => { - if (document.getElementsByClassName('F0XO1GC-x-b').length == 3 && scrumBody && enableToggle) { + if (document.getElementsByClassName('F0XO1GC-x-b').length == 3 && typeof scrumBody !== 'undefined' && scrumBody && enableToggle) { refreshButton_Placed = true; clearInterval(intervalWriteButton); let td = document.createElement('td'); @@ -1670,11 +1549,6 @@ ${userReason}`; function handleRefresh() { hasInjectedContent = false; // Reset the flag before refresh allIncluded(); - } -} - - - async function forceGithubDataRefresh() {