Skip to content

Commit d1a26a7

Browse files
DISTMYSQL-170: Orchestrator GUI: group multiple errantgtidstructure warning icons
https://jira.percona.com/browse/DISTMYSQL-170 Problem: Warning icon is displayed for every cluster analysis problem detected. If there is a lot of problems, a lot of warning icons in row is displayed making GUI unreadable. Solution: Group 'warings', 'dangers', and 'muted' notifications, display small number next to the icon indicating that grouping took place. Display all warnings list when mouse pointer is hoofed over the icon. Additionally fixed the way cluster analysis problems (clustersAnalysisProblems map) were collected. When analysis entry contained one or several structure analysis entries, adding them to the array caused overwriting of all previously added entries. It was because the loop always modified the same object's 'Analysis' member instead of assigning structureAnalysis to the new object's 'Analysis' member. Fixed by shallow cloning of the original object. Shallow copy is enough because 'AnalyzedInstanceKey' can point to the same object. Only what was pointed by 'Analysis' was problematic.
1 parent eb84360 commit d1a26a7

File tree

2 files changed

+47
-11
lines changed

2 files changed

+47
-11
lines changed

resources/public/css/orchestrator.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,3 +1011,9 @@ body {
10111011
.instance.instance-search p {
10121012
margin: 8px 0px;
10131013
}
1014+
1015+
.overlay-counter {
1016+
margin-left:-5px;
1017+
font-size: 0.65em;
1018+
font-weight: bold;
1019+
}

resources/public/js/clusters.js

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ $(document).ready(function() {
6161
}
6262
analysisEntry.StructureAnalysis = analysisEntry.StructureAnalysis || [];
6363
analysisEntry.StructureAnalysis.forEach(function(structureAnalysis) {
64-
analysisEntry.Analysis = structureAnalysis;
65-
analysisEntry.IsStructureAnalysis = true;
66-
clustersAnalysisProblems[analysisEntry.ClusterDetails.ClusterName].push(analysisEntry);
64+
// We don't need a deep clone. Shallow copy is enough.
65+
const analysisEntryClone = {...analysisEntry};
66+
analysisEntryClone.Analysis = structureAnalysis;
67+
analysisEntryClone.IsStructureAnalysis = true;
68+
clustersAnalysisProblems[analysisEntryClone.ClusterDetails.ClusterName].push(analysisEntryClone);
6769
});
6870
});
6971

@@ -112,18 +114,46 @@ $(document).ready(function() {
112114
compactClusterUri = appUrl('/web/cluster/alias/' + encodeURIComponent(cluster.ClusterAlias) + '?compact=true');
113115
}
114116
if (clustersAnalysisProblems[cluster.ClusterName]) {
115-
clustersAnalysisProblems[cluster.ClusterName].forEach(function(analysisEntry) {
116-
var analysisLabel = "text-danger";
117-
if (analysisEntry.IsStructureAnalysis) {
118-
analysisLabel = "text-warning";
119-
}
117+
var mutedMsg = ""
118+
var mutedCnt = 0
119+
var warningMsg = ""
120+
var warningCnt = 0
121+
var dangerMsg = ""
122+
var dangerCnt = 0
123+
124+
clustersAnalysisProblems[cluster.ClusterName].forEach(function(analysisEntry) {
125+
var msg = analysisEntry.Analysis + ': ' + getInstanceTitle(analysisEntry.AnalyzedInstanceKey.Hostname, analysisEntry.AnalyzedInstanceKey.Port)
126+
120127
var hasDowntime = analysisEntry.IsDowntimed || analysisEntry.IsReplicasDowntimed
121128
if (hasDowntime) {
122-
analysisLabel = "text-muted";
129+
mutedMsg = mutedMsg.concat(msg, '\n');
130+
mutedCnt++;
131+
} else if (analysisEntry.IsStructureAnalysis) {
132+
warningMsg = warningMsg.concat(msg, '\n');
133+
warningCnt++;
134+
} else {
135+
dangerMsg = dangerMsg.concat(msg, '\n');
136+
dangerCnt++;
123137
}
124-
popoverElement.find("h3 .pull-left").prepend('<span class="glyphicon glyphicon-exclamation-sign ' + analysisLabel + '" title="' + analysisEntry.Analysis + ': ' + getInstanceTitle(analysisEntry.AnalyzedInstanceKey.Hostname, analysisEntry.AnalyzedInstanceKey.Port) + '"></span>');
125138
});
126-
139+
if (mutedCnt > 0) {
140+
if (mutedCnt > 1) {
141+
popoverElement.find("h3 .pull-left").prepend('<span class="overlay-counter">' + mutedCnt +' </span>');
142+
}
143+
popoverElement.find("h3 .pull-left").prepend('<span class="glyphicon glyphicon-exclamation-sign text-muted"' + ' title="' + mutedMsg + '"></span>');
144+
}
145+
if (warningCnt > 0) {
146+
if (warningCnt > 1) {
147+
popoverElement.find("h3 .pull-left").prepend('<span class="overlay-counter">' + warningCnt +' </span>');
148+
}
149+
popoverElement.find("h3 .pull-left").prepend('<span class="glyphicon glyphicon-exclamation-sign text-warning"' + ' title="' + warningMsg + '"></span>');
150+
}
151+
if (dangerCnt > 0) {
152+
if (dangerCnt > 1) {
153+
popoverElement.find("h3 .pull-left").prepend('<span class="overlay-counter">' + dangerCnt +' </span>');
154+
}
155+
popoverElement.find("h3 .pull-left").prepend('<span class="glyphicon glyphicon-exclamation-sign text-danger"' + ' title="' + dangerMsg + '"></span>');
156+
}
127157
}
128158
popoverElement.find("h3 .pull-right").append('<a href="' + compactClusterUri + '"><span class="glyphicon glyphicon-compressed" title="Compact display"></span></a>');
129159
if (cluster.HasAutomatedIntermediateMasterRecovery === true) {

0 commit comments

Comments
 (0)