Skip to content

Commit 51c8dbf

Browse files
authored
Display followers of a work item (#240)
* Changes to fix follower-lists in work items * Fix style warning * Reference the closest comment-editor section in the case where a work item is opened from the links section of another work item
1 parent 3191e6a commit 51c8dbf

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

src/azdo-pr-dashboard.user.js

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// ==UserScript==
22

33
// @name More Awesome Azure DevOps (userscript)
4-
// @version 3.7.5
4+
// @version 3.8.0
55
// @author Alejandro Barreto (NI)
66
// @description Makes general improvements to the Azure DevOps experience, particularly around pull requests. Also contains workflow improvements for NI engineers.
77
// @license MIT
@@ -972,23 +972,24 @@
972972
}`);
973973

974974
function watchForWorkItemForms() {
975-
eus.globalSession.onEveryNew(document, '.menu-item.follow-item-menu-item-gray', followButton => {
975+
eus.globalSession.onEveryNew(document, '#__bolt-follow', followButton => {
976976
followButton.addEventListener('click', async _ => {
977-
await eus.sleep(100); // We need to allow the other handlers to send the request to follow/unfollow. After the request is sent, we can annotate our follows list correctly.
978-
await annotateWorkItemWithFollowerList(document.querySelector('.discussion-messages-right'));
977+
await eus.sleep(1000); // We need to allow the other handlers to send the request to follow/unfollow. After the request is sent, we can annotate our follows list correctly.
978+
await annotateWorkItemWithFollowerList(document.querySelector('.comment-editor.enter-new-comment'));
979979
});
980980
});
981981
// Annotate work items (under the comment box) with who is following it.
982-
eus.globalSession.onEveryNew(document, '.discussion-messages-right', async commentEditor => {
982+
eus.globalSession.onEveryNew(document, '.comment-editor.enter-new-comment', async commentEditor => {
983983
await annotateWorkItemWithFollowerList(commentEditor);
984984
});
985985
}
986986

987987
async function annotateWorkItemWithFollowerList(commentEditor) {
988-
document.querySelectorAll('.work-item-followers-list').forEach(e => e.remove());
988+
const commentEditorContainer = commentEditor.closest('.new-comment-div');
989+
commentEditorContainer.querySelectorAll('.work-item-followers-list').forEach(e => e.remove());
989990

990-
const workItemId = commentEditor.closest('.witform-layout').querySelector('.work-item-form-id > span').innerText;
991-
const queryResponse = await fetch(`${azdoApiBaseUrl}/_apis/notification/subscriptionquery?api-version=6.0`, {
991+
const workItemId = getCurrentWorkItemId(commentEditor);
992+
const queryResponse = await fetch(`${azdoApiBaseUrl}_apis/notification/subscriptionquery?api-version=6.0`, {
992993
method: 'POST',
993994
headers: {
994995
'Content-Type': 'application/json',
@@ -1007,15 +1008,35 @@
10071008
queryFlags: 'alwaysReturnBasicInformation',
10081009
}),
10091010
});
1010-
10111011
const followers = [...(await queryResponse.json()).value].sort((a, b) => a.subscriber.displayName.localeCompare(b.subscriber.displayName));
10121012
const followerList = followers
1013-
.map(s => `<a href="mailto:${s.subscriber.uniqueName}">${s.subscriber.displayName}</a>`)
1014-
.join(', ')
1015-
|| 'Nobody';
1013+
.map(s => `<a class="bolt-link no-underline-link" target="_blank" href="https://teams.microsoft.com/l/chat/0/0?users=${s.subscriber.uniqueName}">${s.subscriber.displayName}</a>`)
1014+
.join(', ');
1015+
if (followerList) {
1016+
const annotation = `<div class="work-item-followers-list" style="margin: 1em 0em; opacity: 0.7"><span class="menu-item-icon bowtie-icon bowtie-watch-eye-fill" aria-hidden="true"></span> ${followerList}</div>`;
1017+
commentEditor.insertAdjacentHTML('afterend', annotation);
1018+
}
1019+
}
1020+
1021+
function getCurrentWorkItemId(commentEditor) {
1022+
// Try getting the link from the work item header, in case this is opened in preview view
1023+
const workItemPage = commentEditor.closest('.work-item-form-page');
1024+
const header = workItemPage.querySelector('.work-item-form-header');
1025+
const links = header.querySelectorAll('a');
1026+
// Loop through the links and check if their target matches a link for a work item
1027+
const workItemLink = Array.from(links).find(link => link.href.includes('_workitems'));
1028+
1029+
// Default to the window URL if the find operation fails
1030+
let currentUrl = window.location.href;
1031+
if (workItemLink) {
1032+
currentUrl = workItemLink.href;
1033+
}
1034+
1035+
const [baseUrl] = currentUrl.split('?');
1036+
const urlSegments = baseUrl.split('/');
1037+
const workItemId = urlSegments[urlSegments.length - 1];
10161038

1017-
const annotation = `<div class="work-item-followers-list" style="margin: 1em 0em; opacity: 0.8"><span class="menu-item-icon bowtie-icon bowtie-watch-eye-fill" aria-hidden="true"></span> ${followerList}</div>`;
1018-
commentEditor.insertAdjacentHTML('BeforeEnd', annotation);
1039+
return workItemId;
10191040
}
10201041

10211042
function watchForRepoBrowsingPages(session) {

0 commit comments

Comments
 (0)