Merge "Adapt ReindexModuleLoader to API changes"
diff --git a/polygerrit-ui/app/constants/reporting.ts b/polygerrit-ui/app/constants/reporting.ts
index abcc3ed..98dd592 100644
--- a/polygerrit-ui/app/constants/reporting.ts
+++ b/polygerrit-ui/app/constants/reporting.ts
@@ -132,6 +132,7 @@
CHECKS_RUNS_SELECTED_TRIGGERED = 'checks-runs-selected-triggered',
CHECKS_STATS = 'checks-stats',
COMMENTS_STATS = 'comments-stats',
+ THREADS_STATS = 'threads-stats',
CHANGE_ACTION_FIRED = 'change-action-fired',
BUTTON_CLICK = 'button-click',
LINK_CLICK = 'link-click',
diff --git a/polygerrit-ui/app/models/comments/comments-model.ts b/polygerrit-ui/app/models/comments/comments-model.ts
index cda93ad..4b39522 100644
--- a/polygerrit-ui/app/models/comments/comments-model.ts
+++ b/polygerrit-ui/app/models/comments/comments-model.ts
@@ -20,6 +20,7 @@
isDraft,
isNew,
PatchSetNumber,
+ CommentThread,
} from '../../types/common';
import {
addPath,
@@ -572,6 +573,14 @@
this.reportCommentStats(comments, latestPatchset);
})
);
+ this.subscriptions.push(
+ combineLatest([
+ this.threadsSaved$,
+ this.changeModel.latestPatchNum$,
+ ]).subscribe(([threads, latestPatchset]) => {
+ this.reportThreadsStats(threads, latestPatchset);
+ })
+ );
}
// Note that this does *not* reload ported comments.
@@ -619,37 +628,79 @@
if (!obj || !latestPatchset) return;
const comments = Object.values(obj).flat();
if (comments.length === 0) return;
+
const commentsLatest = comments.filter(c => c.patch_set === latestPatchset);
- const commentsFixes = comments
- .map(c => c.fix_suggestions?.length ?? 0)
- .filter(l => l > 0);
- const commentsLatestFixes = commentsLatest
- .map(c => c.fix_suggestions?.length ?? 0)
- .filter(l => l > 0);
+ const commentsUnresolved = comments.filter(c => c.unresolved);
const commentsLatestUnresolved = commentsLatest.filter(c => c.unresolved);
- const commentsLatestUnresolvedFixes = commentsLatestUnresolved
- .map(c => c.fix_suggestions?.length ?? 0)
- .filter(l => l > 0);
+
+ const hasFix = (c: CommentInfo) => (c.fix_suggestions?.length ?? 0) > 0;
+
const details = {
countLatest: commentsLatest.length,
- countLatestWithFix: commentsLatestFixes.length,
- countLatestWithUserFix: commentsLatest.filter(c => hasUserSuggestion(c))
- .length,
+ countLatestWithFix: commentsLatest.filter(hasFix).length,
+ countLatestWithUserFix: commentsLatest.filter(hasUserSuggestion).length,
countLatestUnresolved: commentsLatestUnresolved.length,
- countLatestUnresolvedWithFix: commentsLatestUnresolvedFixes.length,
- countLatestUnresolvedWithUserFix: commentsLatestUnresolved.filter(c =>
- hasUserSuggestion(c)
- ).length,
+ countLatestUnresolvedWithFix:
+ commentsLatestUnresolved.filter(hasFix).length,
+ countLatestUnresolvedWithUserFix:
+ commentsLatestUnresolved.filter(hasUserSuggestion).length,
countAll: comments.length,
- countAllUnresolved: comments.filter(c => c.unresolved).length,
- countAllWithFix: commentsFixes.length,
- countAllWithUserFix: comments.filter(c => hasUserSuggestion(c)).length,
+ countAllUnresolved: commentsUnresolved.length,
+ countAllWithFix: comments.filter(hasFix).length,
+ countAllUnresolvedWithFix: commentsUnresolved.filter(hasFix).length,
+ countAllWithUserFix: comments.filter(hasUserSuggestion).length,
+ countAllUnresolvedWithUserFix: comments.filter(
+ c => c.unresolved && hasUserSuggestion(c)
+ ).length,
};
this.reporting.reportInteraction(Interaction.COMMENTS_STATS, details, {
deduping: Deduping.EVENT_ONCE_PER_CHANGE,
});
}
+ private reportThreadsStats(
+ threads?: CommentThread[],
+ latestPatchset?: PatchSetNumber
+ ) {
+ if (!threads || !latestPatchset) return;
+ if (threads.length === 0) return;
+
+ const threadsLatest = threads.filter(
+ t => getFirstComment(t)?.patch_set === latestPatchset
+ );
+ const threadsUnresolved = threads.filter(isUnresolved);
+ const commentsLatestUnresolved = threadsLatest.filter(isUnresolved);
+
+ const hasFix = (t: CommentThread) =>
+ (getFirstComment(t)?.fix_suggestions?.length ?? 0) > 0;
+
+ const hasUserFix = (t: CommentThread) => {
+ const firstComment = getFirstComment(t);
+ return firstComment && hasUserSuggestion(firstComment);
+ };
+
+ const details = {
+ countLatest: threadsLatest.length,
+ countLatestWithFix: threadsLatest.filter(hasFix).length,
+ countLatestWithUserFix: threadsLatest.filter(hasUserFix).length,
+ countLatestUnresolved: commentsLatestUnresolved.length,
+ countLatestUnresolvedWithFix:
+ commentsLatestUnresolved.filter(hasFix).length,
+ countLatestUnresolvedWithUserFix:
+ commentsLatestUnresolved.filter(hasUserFix).length,
+ countAll: threads.length,
+ countAllUnresolved: threadsUnresolved.length,
+ countAllWithFix: threads.filter(hasFix).length,
+ countAllUnresolvedWithFix: threadsUnresolved.filter(hasFix).length,
+ countAllWithUserFix: threads.filter(hasUserFix).length,
+ countAllUnresolvedWithUserFix:
+ threadsUnresolved.filter(hasUserFix).length,
+ };
+ this.reporting.reportInteraction(Interaction.THREADS_STATS, details, {
+ deduping: Deduping.EVENT_ONCE_PER_CHANGE,
+ });
+ }
+
async restoreDraft(draftId: UrlEncodedCommentId) {
const found = this.discardedDrafts?.find(d => id(d) === draftId);
if (!found) throw new Error('discarded draft not found');