From 66c480be35a20cdeb799585560265b68e9e7cb7a Mon Sep 17 00:00:00 2001 From: DavidCurtiss Date: Wed, 8 Nov 2023 15:55:08 -0600 Subject: [PATCH] Remember which PR files are collapsed/expanded (#231) --- README.md | 4 +++- src/azdo-pr-dashboard.user.js | 45 ++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f4c6dc0..d9109f7 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ By default, Violentmonkey will auto-update scripts from the original install loc - ![Await comments are highlighted.](assets/await-comments.png) - **[Not working at the moment](https://github.com/alejandro5042/azdo-userscripts/issues/95):** Folder-level PR diffs are now syntax highlighted! > Note: Not all highlights will be correct; it can only highlight the code that appears in the diff; so multi-line strings may appear weird. Practically, these sorts of issues are rare and overshadowed by the benefit of syntax highlighting in all other cases. +- In the multi-file diff view, which diffs you have expanded/collapsed will now be remembered as you navigate between folders (or between tabs) in the same PR. ### Better owners review (NI-only) @@ -42,8 +43,9 @@ By default, Violentmonkey will auto-update scripts from the original install loc - The PR file tree will now highlight the files you need to review with a letter to represent your role (Owner, Alternate, Reviewer): - ![Files tree highlighting.](assets/owners-file-tree.png) -- Collapsed files are highlighted if they contain files you need to review: +- Collapsed folders are highlighted if they contain files you need to review: - ![Highlighted folder.](assets/owners-collapsed-folders.png) +- In the multi-file diff view, files that are not your files are automatically collapsed, unless you are the one that filed the PR - In the multi-file diff view, your files are also highlighted with a blue hedaer (vs. the typical gray) - Bypass owners reminder: For PRs into branches requiring a passing `ni/owners-approved` status, hovering over the Approve button pops up a reminder to consider bypassing owners - Some tags/labels are colored (e.g. red if the label contains "Blocked") diff --git a/src/azdo-pr-dashboard.user.js b/src/azdo-pr-dashboard.user.js index 1bc673b..c6e9eda 100644 --- a/src/azdo-pr-dashboard.user.js +++ b/src/azdo-pr-dashboard.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name More Awesome Azure DevOps (userscript) -// @version 3.6.1 +// @version 3.7.0 // @author Alejandro Barreto (NI) // @description Makes general improvements to the Azure DevOps experience, particularly around pull requests. Also contains workflow improvements for NI engineers. // @license MIT @@ -1775,26 +1775,50 @@ padding: 7px 10px; }`); + // Update expandedFilesCache when an expand-button is clicked + // TODO: Make this optional. + let expandedFilesCache = {}; + document.addEventListener('click', e => { + const collapseButton = e.target.closest('.bolt-card-expand-button'); + if (collapseButton) { + const wasExpanded = collapseButton.getAttribute('aria-expanded') === 'true'; + const isExpanded = !wasExpanded; + const pathWithLeadingSlash = collapseButton.parentElement.querySelector('.secondary-text.text-ellipsis').textContent; + expandedFilesCache[pathWithLeadingSlash] = isExpanded; + } + }); + eus.onUrl(/\/pullrequest\//gi, async (session, urlMatch) => { // Get the current iteration of the PR. const prUrl = await getCurrentPullRequestUrlAsync(); + const prCreatedBy = await getCurrentPullRequestCreatedBy(); // Get owners info for this PR. const ownersInfo = await getNationalInstrumentsPullRequestOwnersInfo(prUrl); const hasOwnersInfo = ownersInfo && ownersInfo.currentUserFileCount > 0; - if (!hasOwnersInfo) return; + const autoCollapse = hasOwnersInfo && currentUser.uniqueName !== prCreatedBy.uniqueName; + // Reset the cache for each new PR. + expandedFilesCache = {}; session.onEveryNew(document, '.repos-summary-header', diff => { const header = diff.children[0]; - const pathWithLeadingSlash = $(header).find('.secondary-text.text-ellipsis')[0].textContent; + const pathWithLeadingSlash = header.querySelector('.secondary-text.text-ellipsis').textContent; const path = pathWithLeadingSlash.substring(1); // Remove leading slash. - if (ownersInfo.isCurrentUserResponsibleForFile(path)) { - $(header).addClass('file-to-review-header'); + if (hasOwnersInfo && ownersInfo.isCurrentUserResponsibleForFile(path)) { + header.classList.add('file-to-review-header'); $('
').text(`${ownersInfo.currentUserFilesToRole[path]}:`).prependTo(header.children[1]); - } else { - // TODO: Make this optional. - $(header).find('button[aria-label="Collapse"]').click(); + } + + if (pathWithLeadingSlash in expandedFilesCache) { + if (!expandedFilesCache[pathWithLeadingSlash]) { + header.querySelector('button[aria-label="Collapse"]').click(); + } + } else if (autoCollapse) { + if (!ownersInfo.isCurrentUserResponsibleForFile(path)) { + // TODO: Make this optional. + header.querySelector('button[aria-label="Collapse"]').click(); + } } }); }); @@ -2244,6 +2268,11 @@ return (await getCurrentPullRequestAsync()).url; } + // Helper function to get the creator of the PR that's currently on screen. + async function getCurrentPullRequestCreatedBy() { + return (await getCurrentPullRequestAsync()).createdBy; + } + // Async helper function get info on a single PR. Defaults to the PR that's currently on screen. function getPullRequestAsync(id = 0) { const actualId = id || getCurrentPullRequestId();