diff --git a/treeherder/webapp/api/performance_data.py b/treeherder/webapp/api/performance_data.py
index be7b1038535..92f4d6a7e4d 100644
--- a/treeherder/webapp/api/performance_data.py
+++ b/treeherder/webapp/api/performance_data.py
@@ -571,14 +571,23 @@ def _build_duplicated_summaries_map(self, page):
for push_id, framework_id in keys:
q |= Q(push_id=push_id, framework_id=framework_id)
rows = PerformanceAlertSummary.objects.filter(q).values(
- "id", "status", "push_id", "framework_id"
+ "id", "status", "push_id", "framework_id", "alerts__related_summary_id"
)
- result = defaultdict(list)
+ result_map = defaultdict(dict)
for row in rows:
- result[(row["push_id"], row["framework_id"])].append(
- {"id": row["id"], "status": row["status"]}
- )
- return dict(result)
+ key = (row["push_id"], row["framework_id"])
+ summary_id = row["id"]
+
+ if summary_id not in result_map[key]:
+ result_map[key][summary_id] = {
+ "id": summary_id,
+ "status": row["status"],
+ "reassigned_to": row["alerts__related_summary_id"],
+ }
+ elif row["alerts__related_summary_id"]:
+ result_map[key][summary_id]["reassigned_to"] = row["alerts__related_summary_id"]
+
+ return {k: list(v.values()) for k, v in result_map.items()}
def _build_tc_metadata_map(self, page):
"""
diff --git a/treeherder/webapp/api/performance_serializers.py b/treeherder/webapp/api/performance_serializers.py
index d2ef2145670..cfcb49db58f 100644
--- a/treeherder/webapp/api/performance_serializers.py
+++ b/treeherder/webapp/api/performance_serializers.py
@@ -342,14 +342,29 @@ def get_duplicated_summaries(self, performance_alert_summary):
for summary in duplicated_summaries_map.get(key, [])
if summary["id"] != performance_alert_summary.id
]
- return list(
+
+ rows = (
PerformanceAlertSummary.objects.filter(
push=performance_alert_summary.push, framework=performance_alert_summary.framework
)
.exclude(id=performance_alert_summary.id)
- .values("id", "status")
+ .values("id", "status", "alerts__related_summary_id")
)
+ result_map = {}
+ for row in rows:
+ summary_id = row["id"]
+ if summary_id not in result_map:
+ result_map[summary_id] = {
+ "id": summary_id,
+ "status": row["status"],
+ "reassigned_to": row["alerts__related_summary_id"],
+ }
+ elif row["alerts__related_summary_id"]:
+ result_map[summary_id]["reassigned_to"] = row["alerts__related_summary_id"]
+
+ return list(result_map.values())
+
class Meta:
model = PerformanceAlertSummary
fields = [
diff --git a/ui/perfherder/alerts/AlertHeader.jsx b/ui/perfherder/alerts/AlertHeader.jsx
index 11bc4000324..29a3c7371cb 100644
--- a/ui/perfherder/alerts/AlertHeader.jsx
+++ b/ui/perfherder/alerts/AlertHeader.jsx
@@ -14,6 +14,7 @@ import {
import { getJobsUrl, getPerfCompareBaseURL } from '../../helpers/url';
import { toMercurialShortDateStr } from '../../helpers/display';
import SimpleTooltip from '../../shared/SimpleTooltip';
+import Clipboard from '../../shared/Clipboard';
import Assignee from './Assignee';
import TagsList from './TagsList';
@@ -230,19 +231,34 @@ const AlertHeader = ({
{alertSummary.duplicated_summaries.length > 0 && (
Duplicated summaries:
- {alertSummary.duplicated_summaries.map((summary, index) => (
-
- Alert #{summary.id} - {getStatus(summary.status)}
- {alertSummary.duplicated_summaries.length - 1 !== index && ', '}
-
- ))}
+ {alertSummary.duplicated_summaries.map((summary, index) => {
+ const isReassigned = getStatus(summary.status) === 'reassigned';
+ return (
+
+
+ Alert #{summary.id} - {getStatus(summary.status)}
+ {isReassigned && summary.reassigned_to && ` to #${summary.reassigned_to}`}
+
+ {isReassigned && summary.reassigned_to && (
+
+ )}
+ {alertSummary.duplicated_summaries.length - 1 !== index && ', '}
+
+ );
+ })}
)}