There should be a way to associate bugs with analysis tasks
[WebKit-https.git] / Websites / perf.webkit.org / public / v2 / index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4     <meta charset="utf-8">
5     <title>WebKit Performance Monitor (Beta)</title>
6     <script src="js/jquery.min.js" defer></script>
7     <script src="js/handlebars.js" defer></script>
8     <script src="js/ember.js" defer></script>
9     <script src="js/ember-data.js" defer></script>
10     <script src="js/d3/d3.min.js" defer></script>
11     <script src="js/statistics.js" defer></script>
12     <script src="data.js" defer></script>
13     <script src="app.js" defer></script>
14     <script src="manifest.js" defer></script>
15     <script src="analysis.js" defer></script>
16     <script src="popup.js" defer></script>
17     <link rel="stylesheet" href="app.css">
18     <link rel="stylesheet" href="chart-pane.css">
19
20     <script type="text/x-handlebars" data-template-name="index">
21         <header id="header">
22             {{partial "navbar"}}
23             {{view App.NumberOfDaysControlView tagName="ul" numberOfDays=numberOfDays}}
24             <ul class="controls">
25                 <li>
26                     <a href="#" class="control-button" {{action toggleEditMode}}>
27                         {{#if controller.editMode}}
28                             Finish editing
29                         {{else}}
30                             Edit
31                         {{/if}}
32                     </a>
33                 </li>
34             </ul>
35         </header>
36
37         <table {{bind-attr class=":dashboard editMode:editMode:readonly"}}>
38         <thead>
39             <tr>
40                 <td></td>
41                 {{#each headerColumns}}
42                     {{#if controller.editMode}}
43                         <th>
44                             <a href="#" title="Remove column" {{action "removeColumn" index}}>
45                                 {{partial "close-button"}}
46                             </a>
47                             {{input value=label}}
48                         </th>
49                     {{else}}
50                         <th>{{label}}</th>
51                     {{/if}}
52                 {{/each}}
53                 {{#if controller.editMode}}
54                     <td>{{input value=newColumnHeader action="addColumn" placeholder="Add a column"}}</td>
55                 {{/if}}
56             </tr>
57         </thead>
58         <tbody>
59             {{#each rows}}
60                 <tr>
61                     {{#if controller.editMode}}
62                         <th>
63                             <a href="#" title="Remove row" {{action "removeRow" this}}>
64                                 {{partial "close-button"}}
65                             </a>
66                             {{input value=header}}
67                         </th>
68                     {{else}}
69                         <th><span class="label">{{header}}</span></th>
70                     {{/if}}
71                     {{#each cells}}
72                         <td>
73                             {{#if empty}}
74                                 {{#if controller.editMode}}
75                                     {{view App.PopupView list=pickerData label='Choose'}}
76                                 {{/if}}
77                             {{else}}
78                                 {{#if chartData}}
79                                     {{#link-to 'charts' (query-params paneList=paneList)}}
80                                     {{interactive-chart
81                                         chartData=chartData
82                                         domain=controller.sharedDomain
83                                         enableSelection=false}}
84                                     {{/link-to}}
85                                 {{else}}
86                                     {{#if failure}}
87                                         <div class="failure">{{failure}}</div>
88                                     {{else}}
89                                         <div class="progress">{{partial "spinner"}}</div>
90                                     {{/if}}
91                                 {{/if}}
92                                 {{#if controller.editMode}}
93                                     <a href="#" title="Reset pane" class="reset" {{action "resetPane" this}}>
94                                         {{partial "close-button"}}
95                                     </a>
96                                 {{/if}}
97                             {{/if}}
98                         </td>
99                     {{/each}}
100                     {{#if controller.editMode}}
101                         <td></td>
102                     {{/if}}
103                 </tr>
104             {{/each}}
105             {{#if controller.editMode}}
106                 <tr>
107                     <td>{{input value=newRowHeader action="addRow" placeholder="Add a row"}}</td>
108                     {{#each emptyRow}}
109                         <td></td>
110                     {{/each}}
111                     <td></td>
112                 </tr>
113             {{/if}}
114         </tbody>
115         </table>
116     </script>
117
118     <script type="text/x-handlebars" data-template-name="charts">
119         <header id="header">
120             {{partial "navbar"}}
121             <ul class="controls">
122                 <li>{{view App.PopupView list=platforms label='Add pane'}}</li>
123             </ul>
124             <ul class="controls">
125                 <li>{{view App.StartTimeSliderView startTime=startTime oldestStartTime=oldestStartTime}}</li>
126             </ul>
127         </header>
128
129         {{#each panes itemController="pane"}}
130             <section class="chart-pane" tabindex="0">
131                 <header>
132                     <h1 {{action "toggleDetails"}}>{{metric.fullName}} - {{ platform.name}}</h1>
133                     <a href="#" title="Close" class="close-button" {{action "close"}}>{{partial "close-button"}}</a>
134                     {{#if App.Manifest.bugTrackers}}
135                         <a href="#" title="Analysis" class="bugs-button" {{action "toggleBugsPane"}}>
136                             {{partial "analysis-button"}}
137                         </a>
138                     {{/if}}
139                     {{#if App.Manifest.repositoriesWithReportedCommits}}
140                         <a href="#" title="Search" class="search-button" {{action "toggleSearchPane"}}>{{partial "search-button"}}</a>
141                     {{/if}}
142                 </header>
143
144                 <div class="body">
145                     <div class="svg-container">
146                     {{#if chartData}}
147                         {{interactive-chart
148                             chartData=chartData
149                             ranges=analyticRanges
150                             domain=mainPlotDomain
151                             interactive=true
152                             chartPointRadius=2
153                             currentItem=currentItem
154                             currentTime=sharedTime
155                             selectedItem=selectedItem
156                             highlightedItems=highlightedItems
157                             rangeRoute="analysisTask"
158                             selection=timeRange
159                             sharedSelection=sharedSelection
160                             selectionChanged="rangeChanged"
161                             selectionIsLocked=timeRangeIsLocked
162                             markedPoints=markedPoints
163                             zoom="zoomed"}}
164                     {{else}}
165                         {{#if failure}}
166                             <div class="failure">{{failure}}</div>
167                         {{else}}
168                             <div class="progress">{{partial "spinner"}}</div>
169                         {{/if}}
170                     {{/if}}
171                     </div>
172                     <div class="details">
173                         <div class="overview">
174                         {{#if chartData}}
175                             {{interactive-chart
176                                 chartData=chartData
177                                 showYAxis=false
178                                 domain=overviewDomain
179                                 domainChanged="overviewDomainChanged"
180                                 selection=mainPlotDomain
181                                 selectionChanged="zoomed"}}
182                         {{/if}}
183                         </div>
184                         {{#if details}}
185                             {{partial "chart-details"}}
186                         {{/if}}
187                     </div>
188                 </div>
189
190                 <form {{bind-attr class=":search-pane showingSearchPane::hidden"}}>
191                     <span class="repositories">
192                         {{view Ember.Select content=App.Manifest.repositoriesWithReportedCommits
193                             optionLabelPath='content.id'
194                             selection=commitSearchRepository}}
195                     </span>
196                     {{input action="searchCommit" placeholder="Name or email" value=commitSearchKeyword}}
197                 </form>
198
199                 <div {{bind-attr class=":analysis-pane showingAnalysisPane::hidden"}}>
200                     <table>
201                         <tbody>
202                             <tr>
203                                 <th>
204                                     <label>Name: {{input type=text value=newAnalysisTaskName}}</label>
205                                     <button {{action "createAnalysisTask"}} {{bind-attr disabled=cannotAnalyze}}>Analyze</button>
206                                 </th>
207                             </tr>
208                         </tbody>
209                     </table>
210                 </div>
211
212             </section>
213         {{/each}}
214     </script>
215
216     <script type="text/x-handlebars" data-template-name="components/interactive-chart">
217         {{#if interactive}}
218             <div class="selection-toolbar" style="display: none;">
219                 <a href="#" class="button" {{action "zoom"}}>
220                     <svg class="zoom" viewBox="0 0 100 100">
221                         <g stroke-width="0" stroke="none">
222                             <polygon points="25,25 5,50 25,75"/>
223                             <polygon points="75,25 95,50 75,75"/>
224                         </g>
225                         <line x1="20" y1="50" x2="80" y2="50" stroke-width="10"></line>
226                     </svg>
227                 </a>
228             </div>
229         {{/if}}
230         <div class="rangeBarsContainerInlineStyle">
231             {{#each rangeBars}}
232                 {{#link-to linkRoute linkId title=label}}
233                     <span class="rangeBar" {{bind-attr style=inlineStyle}}></span>
234                 {{/link-to}}
235             {{/each}}
236         </div>
237     </script>
238
239     <script type="text/x-handlebars" data-template-name="chart-details">
240     <div class="details-table-container">
241         <table class="details-table">
242             <tbody class="bugs">
243             {{#each details.bugTrackers}}
244                 {{#if bugs}}
245                     <tr>
246                         <th>{{label}}</th>
247                         <td>
248                             {{#each bugs}}
249                                 <a {{bind-attr href=bugUrl}} target="_blank">{{bugNumber}}</a>
250                             {{/each}}
251                         </td>
252                     </tr>
253                 {{/if}}
254             {{/each}}
255             </tbody>
256             <tr><th>Current</th><td>{{details.currentValue}} {{chartData.unit}}
257             {{#if details.oldValue}}
258                 (from {{details.oldValue}})
259             {{/if}}</td></tr>
260             {{#if details.buildNumber}}
261                 <tr>
262                     <th>Build</th>
263                     <td>
264                         {{#if details.buildURL}}
265                             <a {{bind-attr href=details.buildURL}} target="_blank">{{details.buildNumber}}</a>
266                         {{else}}
267                             {{details.buildNumber}}
268                         {{/if}}
269                         ({{details.buildTime}})
270                     </td>
271                 </tr>
272             {{/if}}
273             {{#each details.revisions}}
274                 <tr>
275                     <th>{{name}}</th>
276                     <td>
277                         {{#if url}}
278                             <a {{bind-attr href=url}} target="_blank">{{label}}</a>
279                         {{else}}
280                             {{label}}
281                         {{/if}}
282                     </td>
283                 </tr>
284                 <tr>
285                     <td colspan="2">{{commits-viewer repository=repository revisionInfo=this}}</td>
286                 </tr>
287             {{/each}}
288         </table>
289     </div>
290     </script>
291
292     <script type="text/x-handlebars" data-template-name="components/commits-viewer">
293     {{#if commits}}
294         <table>
295             <tbody>
296                 {{#each commits}}
297                     <tr>
298                         <td>
299                             {{#if url}}
300                                 <a {{bind-attr href=url}} target="_blank">{{author}}</a>
301                             {{else}}
302                                 {{author}}
303                             {{/if}}
304                         </td>
305                         <td>{{message}}</td>
306                     </tr>
307                 {{/each}}
308             </tbody>
309         </table>
310     {{/if}}
311     </script>
312
313     <script type="text/x-handlebars" data-template-name="close-button">
314         <svg class="close-button icon-button" viewBox="0 0 100 100">
315             <g stroke="black" stroke-width="10">
316                 <circle cx="50" cy="50" r="45" fill="transparent"/>
317                 <polygon points="30,30 70,70" />
318                 <polygon points="30,70 70,30" />
319             </g>
320         </svg>
321     </script>
322
323     <script type="text/x-handlebars" data-template-name="analysis-button">
324         <svg class="analysis-button icon-button" viewBox="0 0 100 100">
325             <g stroke="black" stroke-width="15">
326                 <circle cx="50" cy="50" r="40" fill="transparent"/>
327                 <line x1="50" y1="25" x2="50" y2="55"/>
328                 <circle cx="50" cy="67.5" r="2.5" fill="transparent"/>
329             </g>
330         </svg>
331     </script>
332
333     <script type="text/x-handlebars" data-template-name="search-button">
334         <svg class="search-button icon-button" viewBox="0 0 100 100">
335             <g stroke="black" stroke-width="15">
336                 <circle cx="60" cy="40" r="30" fill="transparent"/>
337                 <line x1="10" y1="90" x2="40" y2="60"/>
338             </g>
339         </svg>
340     </script>
341
342     <script type="text/x-handlebars" data-template-name="spinner">
343         <svg class="spinner" viewBox="0 0 100 100">
344             <line x1="10" y1="50" x2="30" y2="50" stroke="black" stroke-width="10" stroke-linecap="round"/>
345             <line x1="21.72" y1="21.72" x2="35.86" y2="35.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
346             <line x1="50" y1="10" x2="50" y2="30" stroke="black" stroke-width="10" stroke-linecap="round"/>
347             <line x1="78.28" y1="21.72" x2="64.14" y2="35.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
348             <line x1="70" y1="50" x2="90" y2="50" stroke="black" stroke-width="10" stroke-linecap="round"/>
349             <line x1="65.86" y1="65.86" x2="78.28" y2="78.28" stroke="black" stroke-width="10" stroke-linecap="round"/>
350             <line x1="50" y1="70" x2="50" y2="90" stroke="black" stroke-width="10" stroke-linecap="round"/>
351             <line x1="21.72" y1="78.28" x2="35.86" y2="65.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
352         </svg>
353     </script>
354
355     <script type="text/x-handlebars" data-template-name="navbar">
356         <nav id="navigation" role="navigation">
357             <h1><a href="#">WebKit Perf Monitor</a></h1>
358             <ul>
359                 {{#link-to 'index' tagName='li'}}
360                     {{#link-to 'index'}}Dashboard{{/link-to}}
361                 {{/link-to}}
362                 {{#link-to 'charts' tagName='li'}}
363                     {{#link-to 'charts'}}Charts{{/link-to}}
364                 {{/link-to}}
365                 {{#link-to 'analysis' tagName='li'}}
366                     {{#link-to 'analysis'}}Analysis{{/link-to}}
367                 {{/link-to}}
368             </ul>
369         </nav>
370     </script>
371
372     <script type="text/x-handlebars" data-template-name="number-of-days-controls">
373         <li class="numberOfDaysIs1">
374             <a href="#" class="control-button" {{action "setNumberOfDays" 1}}>1D</a>
375         </li>
376         <li class="numberOfDaysIs7">
377             <a href="#" class="control-button" {{action "setNumberOfDays" 7}}>1W</a>
378         </li>
379         <li class="numberOfDaysIs30">
380             <a href="#" class="control-button" {{action "setNumberOfDays" 30}}>1M</a>
381         </li>
382         <li class="numberOfDaysIs90">
383             <a href="#" class="control-button" {{action "setNumberOfDays" 90}}>3M</a>
384         </li>
385         <li class="numberOfDaysIs183">
386             <a href="#" class="control-button" {{action "setNumberOfDays" 183}}>6M</a>
387         </li>
388         <li class="numberOfDaysIs365">
389             <a href="#" class="control-button" {{action "setNumberOfDays" 365}}>1Y</a>
390         </li>
391     </script>
392
393     <script type="text/x-handlebars" data-template-name="start-time-slider">
394         <label><input type="range"> <span class="numberOfDays">X</span> days</label>
395     </script>
396
397     <script type="text/x-handlebars" data-template-name="popup">
398         <span class="label">{{view App.PopupButtonView tagName="a" label=view.label }}</span>
399         {{view view.popupListContainerView viewName="popupListContainerViewInstance"}}
400     </script>
401
402     <script type="text/x-handlebars" data-template-name="popup-list">
403         {{#each view.list}}
404             {{#if isSeparator}}
405                 <li><hr></li>
406             {{else }} {{#if children}}
407                 <li>{{view App.PopupView list=children label=label}}</li>
408             {{else}}
409                 <li>
410                     {{#if actionName}}
411                         <a href="#" class="label" {{action actionName actionArgument}}>{{label}}</a>
412                     {{else}}
413                         <a class="label">{{label}}</a>
414                     {{/if}}
415                 </li>
416             {{/if}} {{/if}}
417         {{/each}}
418     </script>
419
420     <script type="text/x-handlebars" data-template-name="analysis">
421         <header id="header">
422             {{partial "navbar"}}
423         </header>
424
425         <table id="analysis-tasks">
426             <thead>
427                 <tr>
428                     <td>ID</td>
429                     <td>Name</td>
430                     <td>Created at</td>
431                 </tr>
432             </thead>
433             <tbody>
434                 {{#each model.tasks}}
435                     <tr>
436                         <td>{{#link-to 'analysisTask' id}}{{id}}{{/link-to}}</td>
437                         <td>{{name}}</td>
438                         <td>{{createdAt}}</td>
439                     </tr>
440                 {{/each}}
441             </tbody>
442         </table>
443     </script>
444
445     <script type="text/x-handlebars" data-template-name="analysisTask">
446         <header id="header">
447             {{partial "navbar"}}
448         </header>
449
450         <h2 id="analysis-task-title">{{label}}</h2>
451         {{#if platform.label}}
452             <h3 id="analysis-task-testname">{{metric.fullName}} - {{platform.label}}</h3>
453         {{/if}}
454
455         {{#if chartData}}
456             <section class="analysis-chart-pane chart-pane">
457                 <div class="svg-container">
458                     {{interactive-chart
459                         chartData=chartData
460                         enableSelection=false
461                         chartPointRadius=2
462                         domain=chartDomain
463                         markedPoints=markedPoints}}
464                 </div>
465                 <div class="details">
466                     <table class="analysis-bugs">
467                         <tbody>
468                             {{#each bugTrackers}}
469                                 <tr>
470                                     <th>{{label}}</th>
471                                     <td>
472                                         <form {{action "associateBug" this editedBugNumber on="submit"}}>
473                                             {{input type=text value=editedBugNumber}}
474                                         </form>
475                                     </td>
476                                 </tr>
477                             {{/each}}
478                         </tbody>
479                     </table>
480                     <table>
481                         <tbody>
482                             {{#each analysisPoints}}
483                                 <tr><td>{{label}}</td><td>{{value}}</td></tr>
484                             {{/each}}
485                         </tbody>
486                     </table>
487                 </div>
488             </section>
489
490             {{#each testGroups}}
491                 <section class="analysis-group">
492                     <table>
493                         <caption>{{name}}</caption>
494                         <thead>
495                             <tr>
496                                 <td>Configuration</td>
497                                 <td>Build</td>
498                                 <td>Build Time</td>
499                                 <td>{{../metric.fullName}}</td>
500                             </tr>
501                         </thead>
502                         <tbody>
503                             {{#each buildRequests}}
504                                 <tr>
505                                     <td>{{id}}</td>
506                                     <td>{{buildNumber}}</td>
507                                     <td>{{buildTime}}</td>
508                                     <td>{{mean}}</td>
509                                 </tr>
510                             {{/each}}
511                         </tbody>
512                     </table>
513                 </section>
514             {{/each}}
515
516             <form class="analysis-group">
517                 <table>
518                     <caption><input name="name" placeholder="Test group name" required></caption>
519                     <thead>
520                         <tr>
521                             <th>Root</th>
522                             {{#each testSets}}
523                                 <th>
524                                     {{name}}
525                                     {{view Ember.Select
526                                         content=options
527                                         optionValuePath="content.value"
528                                         optionLabelPath="content.label"
529                                         selection=selection}}
530                                 </th>
531                             {{/each}}
532                         </tr>
533                     </thead>
534                     <tbody>
535                         {{#each roots}}
536                             <tr>
537                                 <th>{{name}}</th>
538                                 {{#each sets}}
539                                     <td>{{view Ember.Select name=name content=revisions
540                                         optionValuePath="content.value" optionLabelPath="content.label"
541                                         selection=selection}}</td>
542                                 {{/each}}
543                             </tr>
544                         {{/each}}
545                     </tbody>
546                     <tbody>
547                         <tr>
548                             <th>Number of runs</th>
549                             <td colspan=2>
550                                 <select>
551                                     <option>1</option>
552                                     <option>2</option>
553                                     <option>3</option>
554                                     <option>4</option>
555                                     <option>5</option>
556                                     <option>6</option>
557                                 </select>
558                             </td>
559                         </tr>
560                     </tbody>
561                 </table>
562
563                 <button type="submit">Start A/B testing</button>
564             </form>
565         {{/if}}
566     </script>
567
568 </head>
569 <body>
570 </body>
571 </html>