|
1 | 1 | // ==UserScript== |
2 | 2 |
|
3 | 3 | // @name More Awesome Azure DevOps (userscript) |
4 | | -// @version 3.6.1 |
| 4 | +// @version 3.7.0 |
5 | 5 | // @author Alejandro Barreto (NI) |
6 | 6 | // @description Makes general improvements to the Azure DevOps experience, particularly around pull requests. Also contains workflow improvements for NI engineers. |
7 | 7 | // @license MIT |
|
1775 | 1775 | padding: 7px 10px; |
1776 | 1776 | }`); |
1777 | 1777 |
|
| 1778 | + // Update expandedFilesCache when an expand-button is clicked |
| 1779 | + // TODO: Make this optional. |
| 1780 | + let expandedFilesCache = {}; |
| 1781 | + document.addEventListener('click', e => { |
| 1782 | + const collapseButton = e.target.closest('.bolt-card-expand-button'); |
| 1783 | + if (collapseButton) { |
| 1784 | + const wasExpanded = collapseButton.getAttribute('aria-expanded') === 'true'; |
| 1785 | + const isExpanded = !wasExpanded; |
| 1786 | + const pathWithLeadingSlash = collapseButton.parentElement.querySelector('.secondary-text.text-ellipsis').textContent; |
| 1787 | + expandedFilesCache[pathWithLeadingSlash] = isExpanded; |
| 1788 | + } |
| 1789 | + }); |
| 1790 | + |
1778 | 1791 | eus.onUrl(/\/pullrequest\//gi, async (session, urlMatch) => { |
1779 | 1792 | // Get the current iteration of the PR. |
1780 | 1793 | const prUrl = await getCurrentPullRequestUrlAsync(); |
| 1794 | + const prCreatedBy = await getCurrentPullRequestCreatedBy(); |
1781 | 1795 | // Get owners info for this PR. |
1782 | 1796 | const ownersInfo = await getNationalInstrumentsPullRequestOwnersInfo(prUrl); |
1783 | 1797 | const hasOwnersInfo = ownersInfo && ownersInfo.currentUserFileCount > 0; |
1784 | | - if (!hasOwnersInfo) return; |
| 1798 | + const autoCollapse = hasOwnersInfo && currentUser.uniqueName !== prCreatedBy.uniqueName; |
| 1799 | + // Reset the cache for each new PR. |
| 1800 | + expandedFilesCache = {}; |
1785 | 1801 |
|
1786 | 1802 | session.onEveryNew(document, '.repos-summary-header', diff => { |
1787 | 1803 | const header = diff.children[0]; |
1788 | | - const pathWithLeadingSlash = $(header).find('.secondary-text.text-ellipsis')[0].textContent; |
| 1804 | + const pathWithLeadingSlash = header.querySelector('.secondary-text.text-ellipsis').textContent; |
1789 | 1805 | const path = pathWithLeadingSlash.substring(1); // Remove leading slash. |
1790 | 1806 |
|
1791 | | - if (ownersInfo.isCurrentUserResponsibleForFile(path)) { |
1792 | | - $(header).addClass('file-to-review-header'); |
| 1807 | + if (hasOwnersInfo && ownersInfo.isCurrentUserResponsibleForFile(path)) { |
| 1808 | + header.classList.add('file-to-review-header'); |
1793 | 1809 |
|
1794 | 1810 | $('<div class="file-owners-role-header" />').text(`${ownersInfo.currentUserFilesToRole[path]}:`).prependTo(header.children[1]); |
1795 | | - } else { |
1796 | | - // TODO: Make this optional. |
1797 | | - $(header).find('button[aria-label="Collapse"]').click(); |
| 1811 | + } |
| 1812 | + |
| 1813 | + if (pathWithLeadingSlash in expandedFilesCache) { |
| 1814 | + if (!expandedFilesCache[pathWithLeadingSlash]) { |
| 1815 | + header.querySelector('button[aria-label="Collapse"]').click(); |
| 1816 | + } |
| 1817 | + } else if (autoCollapse) { |
| 1818 | + if (!ownersInfo.isCurrentUserResponsibleForFile(path)) { |
| 1819 | + // TODO: Make this optional. |
| 1820 | + header.querySelector('button[aria-label="Collapse"]').click(); |
| 1821 | + } |
1798 | 1822 | } |
1799 | 1823 | }); |
1800 | 1824 | }); |
|
2244 | 2268 | return (await getCurrentPullRequestAsync()).url; |
2245 | 2269 | } |
2246 | 2270 |
|
| 2271 | + // Helper function to get the creator of the PR that's currently on screen. |
| 2272 | + async function getCurrentPullRequestCreatedBy() { |
| 2273 | + return (await getCurrentPullRequestAsync()).createdBy; |
| 2274 | + } |
| 2275 | + |
2247 | 2276 | // Async helper function get info on a single PR. Defaults to the PR that's currently on screen. |
2248 | 2277 | function getPullRequestAsync(id = 0) { |
2249 | 2278 | const actualId = id || getCurrentPullRequestId(); |
|
0 commit comments