From 59a62f083f4c9a6a157f54926e230fe8b56125ac Mon Sep 17 00:00:00 2001
From: Chidozie Ononiwu <31145988+chidozieononiwu@users.noreply.github.com>
Date: Thu, 27 Jul 2023 17:16:27 -0700
Subject: [PATCH] Resolve bug in Comment Auto Refresh (#6574)
---
.../Client/src/shared/comments.module.ts | 77 ++++++++++++++++++
.../APIViewWeb/Client/src/shared/comments.ts | 1 -
.../APIViewWeb/Client/src/shared/helpers.ts | 8 +-
.../APIViewWeb/Client/src/shared/signalr.ts | 80 ++-----------------
4 files changed, 89 insertions(+), 77 deletions(-)
create mode 100644 src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.module.ts
diff --git a/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.module.ts b/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.module.ts
new file mode 100644
index 00000000000..aac62ea0bc8
--- /dev/null
+++ b/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.module.ts
@@ -0,0 +1,77 @@
+
+import * as hp from "./helpers";
+
+/**
+* Updates comment thread HTML to match the current user's context
+* Remove remove/edit buttons of sender's comments
+* Add remove/edit buttons to current user's comments (if any)
+* @param commentThreadHTML
+* @returns partial view result for the current user
+*/
+export function updateCommentThreadUserContext(commentThreadHTML: string) {
+ let commentThread = $(commentThreadHTML);
+
+ // remove all delete and edit anchors
+ commentThread.find("a.dropdown-item.js-delete-comment").next().next().remove();
+ commentThread.find("a.dropdown-item.js-delete-comment").next().remove();
+ commentThread.find("a.dropdown-item.js-delete-comment").remove();
+
+ //verify name and add delete and edit anchors
+ let $commentContents = commentThread.find("div.comment-contents > span");
+ $commentContents.each((index, value) => {
+ let commenter;
+ if (value.children) {
+ commenter = value.children[0];
+ }
+ if (!commenter) {
+ return;
+ }
+
+ let commenterHref = commenter.attributes.getNamedItem('href')?.value;
+ let profileHref;
+ $('ul.navbar-nav.ms-auto > li.nav-item > a.nav-link').each((index, value) => {
+ if (value.textContent && value.textContent.trim() === 'Profile') {
+ profileHref = value.attributes.getNamedItem('href')?.value;
+ }
+ });
+
+
+ if (profileHref === commenterHref) {
+ let dropdown = commentThread.find('div.dropdown-menu.dropdown-menu-right')[index];
+ $('
').prependTo(dropdown);
+ $('').prependTo(dropdown);
+ $('').prependTo(dropdown);
+ }
+ });
+
+ let partialViewString = commentThreadHTML.split("";
+ return partialViewString;
+}
+
+
+/**
+ * Replaces the row or comment thread with partial view result (an updated comment thread)
+ * @param reviewId
+ * @param elementId
+ * @param commentThreadHTML
+ */
+export function updateCommentThreadInReviewPageDOM(reviewId: any, elementId: any, commentThreadHTML: any) {
+ if (hp.checkReviewRevisionIdAgainstCurrent(reviewId, null, false)) {
+ var rowSectionClasses = hp.getCodeRowSectionClasses(elementId);
+ hp.showCommentBox(elementId, rowSectionClasses, undefined, false);
+
+ let commentsRow = hp.getCommentsRow(elementId);
+ const replyText = commentsRow.find(".new-thread-comment-text-mirror").text();
+ hp.updateCommentThread(commentsRow, commentThreadHTML);
+ hp.updateUserIcon();
+ if (replyText) {
+ commentsRow = hp.getCommentsRow(elementId);
+ commentsRow.find(".review-thread-reply-button").click();
+ commentsRow.find(".new-thread-comment-text-mirror").text(replyText)
+ commentsRow.find(".new-thread-comment-text").html(replyText);
+ }
+ hp.addCommentThreadNavigation();
+ hp.removeCommentIconIfEmptyCommentBox(elementId);
+ }
+}
+
diff --git a/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.ts b/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.ts
index 11fcd294a39..726b1cdbd79 100644
--- a/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.ts
+++ b/src/dotnet/APIView/APIViewWeb/Client/src/shared/comments.ts
@@ -531,5 +531,4 @@ $(() => {
toggleComments(id);
}
}
-
});
diff --git a/src/dotnet/APIView/APIViewWeb/Client/src/shared/helpers.ts b/src/dotnet/APIView/APIViewWeb/Client/src/shared/helpers.ts
index 40b78104625..415c89d5ac3 100644
--- a/src/dotnet/APIView/APIViewWeb/Client/src/shared/helpers.ts
+++ b/src/dotnet/APIView/APIViewWeb/Client/src/shared/helpers.ts
@@ -153,9 +153,9 @@ export function addToastNotification(notification : Notification, id : string =
}
// Auto Refresh Comment
-export function updateCommentThread(commentBox, partialViewResult) {
- partialViewResult = $.parseHTML(partialViewResult);
- $(commentBox).replaceWith(partialViewResult);
+export function updateCommentThread(commentBox, commentThreadHTML) {
+ commentThreadHTML = $.parseHTML(commentThreadHTML);
+ $(commentBox).replaceWith(commentThreadHTML);
return false;
}
@@ -383,7 +383,7 @@ export function checkReviewRevisionIdAgainstCurrent(reviewId, revisionId, checkR
return false;
}
- if (checkRevision && currRevisionId && currRevisionId === revisionId) {
+ if (checkRevision && currRevisionId && currRevisionId != revisionId) {
return false;
}
diff --git a/src/dotnet/APIView/APIViewWeb/Client/src/shared/signalr.ts b/src/dotnet/APIView/APIViewWeb/Client/src/shared/signalr.ts
index 71ce3d498d7..af40217ab82 100644
--- a/src/dotnet/APIView/APIViewWeb/Client/src/shared/signalr.ts
+++ b/src/dotnet/APIView/APIViewWeb/Client/src/shared/signalr.ts
@@ -1,5 +1,6 @@
import * as hp from "./helpers";
import * as rvM from "../pages/review.module";
+import * as cM from "../shared/comments.module";
const signalR = require('@microsoft/signalr');
@@ -48,19 +49,19 @@ $(() => {
* solution: send to all users AND the group and raise flag
*/
let alreadyRefreshedComment = false;
- connection.on("ReceiveCommentSelf", (reviewId, elementId, partialViewResult) => {
- replaceRowWIthPartialViewResult(reviewId, elementId, partialViewResult);
+ connection.on("ReceiveCommentSelf", (reviewId, elementId, commentThreadHTML) => {
+ cM.updateCommentThreadInReviewPageDOM(reviewId, elementId, commentThreadHTML);
alreadyRefreshedComment = true;
});
- connection.on("ReceiveComment", (reviewId: string, elementId: string, partialViewResult: string) => {
+ connection.on("ReceiveComment", (reviewId: string, elementId: string, commentThreadHTML: string) => {
if (alreadyRefreshedComment == true) {
alreadyRefreshedComment = false;
return;
}
- let partialViewString = getCurrentUserPartialViewResult(partialViewResult);
- replaceRowWIthPartialViewResult(reviewId, elementId, partialViewString);
+ let commentThreadString = (commentThreadHTML && commentThreadHTML != '\r\n') ? cM.updateCommentThreadUserContext(commentThreadHTML) : commentThreadHTML;
+ cM.updateCommentThreadInReviewPageDOM(reviewId, elementId, commentThreadString);
});
let approvalPendingText = "Current Revision Approval Pending";
@@ -111,78 +112,13 @@ $(() => {
if (approvalToggle) {
rvM.addApprover(lowerTextSpan, approvedByText, approverHref, approver);
+ rvM.addApprovedBorder();
} else {
rvM.removeApprover(lowerTextSpan, approver, approvalPendingText);
+ rvM.removeApprovalBorder();
}
})
// Start the connection.
start();
});
-
-/**
-* Auto refresh's raw partial view result input is sent w.r.t. the sender's profile
-* Remove remove/edit buttons of sender's comments
-* Add remove/edit buttons to current user's comments (if any)
-* @param partialViewResult
-* @returns partial view result for the current user
-*/
-function getCurrentUserPartialViewResult(partialViewResult: string) {
- let partialView = $(partialViewResult);
-
- // remove all delete and edit anchors
- partialView.find("a.dropdown-item.js-delete-comment").next().next().remove();
- partialView.find("a.dropdown-item.js-delete-comment").next().remove();
- partialView.find("a.dropdown-item.js-delete-comment").remove();
-
- //verify name and add delete and edit anchors
- let $commentContents = partialView.find("div.comment-contents > span");
- $commentContents.each((index, value) => {
- let commenter;
- if (value.children) {
- commenter = value.children[0];
- }
- if (!commenter) {
- return;
- }
-
- let commenterHref = commenter.attributes.getNamedItem('href')?.value;
- let profileHref;
- $('ul.navbar-nav.ms-auto > li.nav-item > a.nav-link').each((index, value) => {
- if (value.textContent && value.textContent.trim() === 'Profile') {
- profileHref = value.attributes.getNamedItem('href')?.value;
- }
- });
-
-
- if (profileHref === commenterHref) {
- let dropdown = partialView.find('div.dropdown-menu.dropdown-menu-right')[index];
- $(' ').prependTo(dropdown);
- $('').prependTo(dropdown);
- $('').prependTo(dropdown);
- }
- });
-
- let partialViewString = partialViewResult.split(" | ";
- return partialViewString;
-}
-
-/**
- * Replaces the row or comment thread with partial view result
- * @param reviewId
- * @param elementId
- * @param partialViewResult
- */
-function replaceRowWIthPartialViewResult(reviewId: any, elementId: any, partialViewResult: any) {
- hp.checkReviewRevisionIdAgainstCurrent(reviewId, null, false);
-
- var rowSectionClasses = hp.getCodeRowSectionClasses(elementId);
- hp.showCommentBox(elementId, rowSectionClasses, undefined, false);
-
- let commentsRow = hp.getCommentsRow(elementId);
- hp.updateCommentThread(commentsRow, partialViewResult);
- hp.addCommentThreadNavigation();
- hp.removeCommentIconIfEmptyCommentBox(elementId);
-
- hp.updateUserIcon();
-}
|