|
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