d766683452c84f69648ebaad14ed7701b6bc531b
[WebKit-https.git] / Tools / BuildSlaveSupport / build.webkit.org-config / public_html / dashboard / Scripts / EWSQueueView.js
1 /*
2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 EWSQueueView = function(queues)
27 {
28     QueueView.call(this);
29
30     this.queues = queues || [];
31
32     this.queues.forEach(function(queue) {
33         if (this.platform && this.platform != queue.platform)
34             throw "A EWS view may not contain queues for multiple platforms."
35         else
36             this.platform = queue.platform;
37         queue.addEventListener(EWSQueue.Event.Updated, this._queueUpdated, this);
38     }.bind(this));
39
40     this.update();
41 };
42
43 BaseObject.addConstructorFunctions(EWSQueueView);
44
45 EWSQueueView.prototype = {
46     constructor: EWSQueueView,
47     __proto__: QueueView.prototype,
48
49     update: function()
50     {
51         QueueView.prototype.update.call(this);
52
53         this.element.removeChildren();
54
55         function appendQueue(queue)
56         {
57             var queueLabel = document.createElement("a");
58             queueLabel.classList.add("queueLabel");
59             queueLabel.textContent = queue.title;
60             queueLabel.href = queue.statusPageURL;
61             queueLabel.target = "_blank";
62             this.element.appendChild(queueLabel);
63
64             var patchCount = queue.patchCount;
65
66             var message = patchCount === 1 ? "patch in queue" : "patches in queue";
67             var status = new StatusLineView(message, StatusLineView.Status.Neutral, null, patchCount || "0");
68             this.element.appendChild(status.element);
69
70             new PopoverTracker(status.statusBubbleElement, this._presentPopoverForEWSQueue.bind(this), queue);
71         }
72
73         this.queues.forEach(function(queue) {
74             appendQueue.call(this, queue);
75         }, this);
76     },
77
78     addLinkToRow: function(rowElement, className, text, url)
79     {
80         var linkElement = document.createElement("a");
81         linkElement.className = className;
82         linkElement.textContent = text;
83         linkElement.href = url;
84         linkElement.target = "_blank";
85         rowElement.appendChild(linkElement);
86     },
87
88     addTextToRow: function(rowElement, className, text)
89     {
90         var spanElement = document.createElement("span");
91         spanElement.className = className;
92         spanElement.textContent = text;
93         rowElement.appendChild(spanElement);
94     },
95
96     _addQueueHeadingToPopover: function(queue, content)
97     {
98         var title = document.createElement("div");
99         title.className = "popover-queue-heading";
100
101         this.addTextToRow(title, "queue-name", queue.id + " ews queue");
102         this.addLinkToRow(title, "queue-status-link", "status page", queue.statusPageURL);
103         this.addLinkToRow(title, "queue-charts-link", "charts", queue.chartsPageURL);
104
105         content.appendChild(title);
106     },
107
108     _addBotsHeadingToPopover: function(queue, content)
109     {
110         var title = document.createElement("div");
111         title.className = "popover-bots-heading";
112         title.textContent = "latest bot event";
113         content.appendChild(title);
114     },
115
116     _addDividerToPopover: function(content)
117     {
118         var divider = document.createElement("div");
119         divider.className = "divider";
120         content.appendChild(divider);
121     },
122
123     _timeIntervalString: function(time)
124     {
125         var secondsInHour = 60 * 60;
126         var timeDifference = (Date.now() - time.getTime()) / 1000;
127         var hours = Math.floor(timeDifference / secondsInHour);
128         var minutes = Math.floor((timeDifference - hours * secondsInHour) / 60);
129         var hoursPart = "";
130         if (hours === 1)
131             hoursPart = "1\xa0hour and ";
132         else if (hours > 0)
133             hoursPart = hours + "\xa0hours and ";
134         if (!minutes)
135             return "less than a minute";
136         if (minutes === 1)
137             return hoursPart + "1\xa0minute";
138         return hoursPart + minutes + "\xa0minutes";
139     },
140
141     _popoverContentForEWSQueue: function(queue)
142     {
143         var content = document.createElement("div");
144         content.className = "ews-popover";
145
146         this._addQueueHeadingToPopover(queue, content);
147         this._addDividerToPopover(content);
148
149         var patches = queue.patches;
150         for (var i = 0, end = patches.length; i < end; ++i) {
151             var patch = patches[i];
152
153             var rowElement = document.createElement("div");
154
155             this.addLinkToRow(rowElement, "patch-details-link", patch.attachmentID, patch.statusPageURL);
156
157             if (patch.messageCount)
158                 this.addTextToRow(rowElement, "failure-count", patch.messageCount + "\xa0" + (patch.messageCount === 1 ? "attempt" : "attempts"));
159
160             if (patch.detailedResultsURLForLatestMessage)
161                 this.addLinkToRow(rowElement, "latest-status-with-link", patch.latestMessage, patch.detailedResultsURLForLatestMessage);
162             else if (patch.latestMessage && patch.latestMessage.length)
163                 this.addTextToRow(rowElement, "latest-status-no-link", patch.latestMessage);
164             else if (patch.active) {
165                 this.addTextToRow(rowElement, "latest-status-no-link", "Started");
166                 this.addTextToRow(rowElement, "time-since-message", this._timeIntervalString(patch.activeSince) + "\xa0ago");
167             } else
168                 this.addTextToRow(rowElement, "latest-status-no-link", "Not started yet");
169
170             if (patch.latestMessageTime)
171                 this.addTextToRow(rowElement, "time-since-message", this._timeIntervalString(patch.latestMessageTime) + "\xa0ago");
172
173             this.addLinkToRow(rowElement, "bugzilla-link", "bugzilla", bugzilla.detailsURLForAttachment(patch.attachmentID));
174
175             content.appendChild(rowElement);
176         }
177
178         this._addDividerToPopover(content);
179         this._addBotsHeadingToPopover(queue, content);
180         this._addDividerToPopover(content);
181
182         var bots = queue.bots;
183         for (var i = 0, end = bots.length; i < end; ++i) {
184             var bot = bots[i];
185
186             var rowElement = document.createElement("div");
187
188             this.addLinkToRow(rowElement, "bot-status-link", bot.id, bot.statusPageURL);
189             this.addTextToRow(rowElement, "bot-status-description", this._timeIntervalString(bot.latestMessageTime) + "\xa0ago");
190
191             content.appendChild(rowElement);
192         }
193
194         return content;
195     },
196
197     _presentPopoverForEWSQueue: function(element, popover, queue)
198     {
199         if (queue.loadedDetailedStatus)
200             var content = this._popoverContentForEWSQueue(queue);
201         else {
202             var content = document.createElement("div");
203             content.className = "ews-popover";
204
205             var loadingIndicator = document.createElement("div");
206             loadingIndicator.className = "loading-indicator";
207             loadingIndicator.textContent = "Loading\u2026";
208             content.appendChild(loadingIndicator);
209
210             queue.loadDetailedStatus(function() {
211                 popover.content = this._popoverContentForEWSQueue(queue);
212             }.bind(this));
213         }
214
215         var rect = Dashboard.Rect.rectFromClientRect(element.getBoundingClientRect());
216         popover.content = content;
217         popover.present(rect, [Dashboard.RectEdge.MIN_Y, Dashboard.RectEdge.MAX_Y, Dashboard.RectEdge.MAX_X, Dashboard.RectEdge.MIN_X]);
218         return true;
219     },
220
221     _updateQueues: function()
222     {
223         this.queues.forEach(function(queue) { queue.update(); });
224     },
225
226     _queueUpdated: function(event)
227     {
228         this.updateSoon();
229     },
230 };