Always use v3 UI for dashboards and analysis task pages
[WebKit.git] / Websites / perf.webkit.org / public / v2 / index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4     <meta charset="utf-8">
5     <title>Performance Dashboard is Loading...</title>
6
7     <link rel="prefetch" href="../data/manifest.json">
8     <script type="application/json" src="../data/manifest.json"></script>
9     <script>
10
11         function redirectToV3IfNeeded()
12         {
13             var hash = window.location.hash;
14             if (hash.startsWith('#/analysis') || hash.startsWith('#/dashboard'))
15                 window.location.pathname = '/v3/';
16         }
17
18         window.onhashchange = redirectToV3IfNeeded;
19         redirectToV3IfNeeded();
20
21     </script>
22
23     <link rel="stylesheet" href="app.css">
24     <link rel="stylesheet" href="chart-pane.css">
25
26     <script src="js/jquery.min.js" defer></script>
27     <script src="js/jquery.min.js" defer></script>
28     <script src="js/handlebars.js" defer></script>
29     <script src="js/ember.js" defer></script>
30     <script src="js/ember-data.js" defer></script>
31     <script src="js/d3/d3.min.js" defer></script>
32     <script src="../shared/statistics.js" defer></script>
33     <script src="statistics-strategies.js" defer></script>
34     <script src="data.js" defer></script>
35     <script src="app.js" defer></script>
36     <script src="manifest.js" defer></script>
37     <script src="analysis.js" defer></script>
38     <script src="popup.js" defer></script>
39     <script src="interactive-chart.js" defer></script>
40     <script src="commits-viewer.js" defer></script>
41
42     <script type="text/x-handlebars" data-template-name="dashboard">
43         <header id="header">
44             {{partial "navbar"}}
45             {{view App.NumberOfDaysControlView tagName="ul" numberOfDays=numberOfDays}}
46             <ul class="controls">
47                 <li>
48                     <a href="javascript:false" class="control-button" {{action toggleEditMode}}>
49                         {{#if controller.editMode}}
50                             Finish editing
51                         {{else}}
52                             Edit
53                         {{/if}}
54                     </a>
55                 </li>
56             </ul>
57         </header>
58
59         <table {{bind-attr class=":dashboard editMode:editMode:readonly"}}>
60         <thead>
61             <tr>
62                 <td></td>
63                 {{#each headerColumns}}
64                     {{#if controller.editMode}}
65                         <th>
66                             <a href="javascript:false" title="Remove column" {{action "removeColumn" index}}>
67                                 {{partial "close-button"}}
68                             </a>
69                             {{input value=label}}
70                         </th>
71                     {{else}}
72                         <th>{{label}}</th>
73                     {{/if}}
74                 {{/each}}
75                 {{#if controller.editMode}}
76                     <td>{{input value=newColumnHeader action="addColumn" placeholder="Add a column"}}</td>
77                 {{/if}}
78             </tr>
79         </thead>
80         <tbody>
81             {{#each rows}}
82                 <tr>
83                     {{#if controller.editMode}}
84                         <th>
85                             <a href="javascript:false" title="Remove row" {{action "removeRow" this}}>
86                                 {{partial "close-button"}}
87                             </a>
88                             {{input value=header}}
89                         </th>
90                     {{else}}
91                         <th><span class="label">{{header}}</span></th>
92                     {{/if}}
93                     {{#each cells}}
94                         <td>
95                             {{#if empty}}
96                                 {{#if controller.editMode}}
97                                     {{view App.PopupView list=pickerData label='Choose'}}
98                                 {{/if}}
99                             {{else}}
100                                 {{#if chartData}}
101                                     <div class="dashboard-status">
102                                         {{#if latestStatus}}
103                                             {{latestStatus.currentValue}}{{chartData.unit}}
104                                             {{#if latestStatus.label}}
105                                                 <span {{bind-attr class=":status-label latestStatus.className"}}>{{latestStatus.label}}</span>
106                                             {{/if}}
107                                         {{/if}}
108                                     </div>
109                                     {{#link-to 'charts' (query-params paneList=paneList since=controller.since)}}
110                                         {{interactive-chart
111                                             chartData=chartData
112                                             domain=controller.sharedDomain
113                                             enableSelection=false}}
114                                     {{/link-to}}
115                                 {{else}}
116                                     {{#if failure}}
117                                         <div class="failure">{{failure}}</div>
118                                     {{else}}
119                                         <div class="progress">{{partial "spinner"}}</div>
120                                     {{/if}}
121                                 {{/if}}
122                                 {{#if controller.editMode}}
123                                     <a href="javascript:false" title="Reset pane" class="reset" {{action "resetPane" this}}>
124                                         {{partial "close-button"}}
125                                     </a>
126                                 {{/if}}
127                             {{/if}}
128                         </td>
129                     {{/each}}
130                     {{#if controller.editMode}}
131                         <td></td>
132                     {{/if}}
133                 </tr>
134             {{/each}}
135             {{#if controller.editMode}}
136                 <tr>
137                     <td>{{input value=newRowHeader action="addRow" placeholder="Add a row"}}</td>
138                     {{#each emptyRow}}
139                         <td></td>
140                     {{/each}}
141                     <td></td>
142                 </tr>
143             {{/if}}
144         </tbody>
145         </table>
146     </script>
147
148     <script type="text/x-handlebars" data-template-name="charts">
149         <header id="header">
150             {{partial "navbar"}}
151             <ul class="controls">
152                 <li>{{view App.PopupView list=platforms label='Add pane'}}</li>
153             </ul>
154             <ul class="controls">
155                 <li>{{view App.StartTimeSliderView startTime=startTime oldestStartTime=oldestStartTime}}</li>
156             </ul>
157         </header>
158
159         {{#each panes itemController="pane"}}
160             <section class="chart-pane in-charts" tabindex="0">
161                 <header>
162                     <h1 {{action "toggleDetails"}}>{{metric.fullName}} - {{platform.name}}</h1>
163                     <a href="javascript:false" title="Close" class="close-button" {{action "close"}}>{{partial "close-button"}}</a>
164                     {{#if movingAverageStrategies}}
165                         <a href="javascript:false" title="Statistical Tools" class="stat-button" {{action "toggleStatPane"}}>{{partial "stat-button"}}</a>
166                     {{/if}}
167                     <a href="javascript:false" {{bind-attr title=showOutlierTitle class=":outlier-button showOutlier:show:hide"}}
168                         {{action "toggleShowOutlier"}}>
169                         {{partial "outlier-button"}}
170                     </a>
171                     <a href="javascript:false" title="Analyze the selected range" class="analysis-button" {{action "toggleBugsPane"}}>
172                         {{partial "analysis-button"}}
173                     </a>
174                     {{#if App.Manifest.repositoriesWithReportedCommits}}
175                         <a href="javascript:false" title="Search commits by a keyword" class="search-button" {{action "toggleSearchPane"}}>{{partial "search-button"}}</a>
176                     {{/if}}
177                 </header>
178
179                 <div class="body">
180                     <div class="svg-container">
181                     {{#if chartData}}
182                         {{interactive-chart
183                             chartData=chartData
184                             ranges=ranges
185                             domain=mainPlotDomain
186                             interactive=true
187                             currentItem=hoveredOrSelectedItem
188                             currentTime=sharedTime
189                             selectedItem=selectedItem
190                             highlightedItems=highlightedItems
191                             rangeRoute="analysisTask"
192                             selection=timeRange
193                             selectedPoints=selectedPoints
194                             showFullYAxis=showFullYAxis
195                             zoomable=true
196                             zoom="zoomed"}}
197                     {{else}}
198                         {{#if failure}}
199                             <div class="failure">{{failure}}</div>
200                         {{else}}
201                             <div class="progress">{{partial "spinner"}}</div>
202                         {{/if}}
203                     {{/if}}
204                     </div>
205                     <div class="details">
206                         <div class="overview">
207                         {{#if chartData}}
208                             {{interactive-chart
209                                 chartData=chartData
210                                 showYAxis=false
211                                 domain=overviewDomain
212                                 selection=overviewSelection}}
213                         {{/if}}
214                         </div>
215                         <div class="details-table-container">
216                             {{partial "chart-details"}}
217                         </div>
218                     </div>
219                 </div>
220
221                 <div {{bind-attr class=":popup-pane :analysis-pane showingAnalysisPane::hidden"}}>
222                     <section class="analysis-option-option">
223                         <h1>Start A/B testing or associate bugs</h1>
224                         <label>Name: {{input type=text value=newAnalysisTaskName}} <button {{action "createAnalysisTask"}} {{bind-attr disabled=cannotAnalyze}}>Analyze</button></label>
225                     </section>
226                     <section class="analysis-option-option">
227                         <h1>Marking outliers</h1>
228                         <label>{{input type=checkbox checked=selectedItemIsMarkedOutlier disabled=cannotMarkOutlier}} Mark as an outlier and hide it.</label>
229                     </section>
230                 </div>
231
232                 <form {{bind-attr class=":popup-pane :search-pane showingSearchPane::hidden"}}>
233                     <span class="repositories">
234                         {{view Ember.Select
235                             content=App.Manifest.repositoriesWithReportedCommits
236                             optionValuePath='content.id'
237                             optionLabelPath='content.name'
238                             selection=commitSearchRepository}}
239                     </span>
240                     {{input action="searchCommit" placeholder="Name or email" value=commitSearchKeyword}}
241                 </form>
242
243                 {{partial "stat-pane"}}
244
245                 <nav class="alternative-pane-actions">
246                     <ul>
247                         {{#each alternativePanes}}
248                             <li><a href="javascript:false" {{action "addAlternativePanes" pane platform metrics}}>{{label}}</a></li>
249                         {{/each}}
250                     </ul>
251                 </nav>
252             </section>
253         {{/each}}
254     </script>
255
256     <script type="text/x-handlebars" data-template-name="components/interactive-chart">
257         {{#if interactive}}
258             <div class="selection-toolbar" style="display: none;">
259                 <a href="javascript:false" class="button" {{action "zoom"}}>
260                     <svg class="zoom" viewBox="0 0 100 100">
261                         <g stroke-width="0" stroke="none">
262                             <polygon points="25,25 5,50 25,75"/>
263                             <polygon points="75,25 95,50 75,75"/>
264                         </g>
265                         <line x1="20" y1="50" x2="80" y2="50" stroke-width="10"></line>
266                     </svg>
267                 </a>
268             </div>
269         {{/if}}
270         <div class="rangeBarsContainerInlineStyle">
271             {{#each rangeBars}}
272                 {{#link-to linkRoute linkId title=label}}
273                     <span {{bind-attr class=":rangeBar status" style=inlineStyle}}></span>
274                 {{/link-to}}
275             {{/each}}
276         </div>
277     </script>
278
279     <script type="text/x-handlebars" data-template-name="chart-details">
280     {{#if details}}
281         <table class="details-table">
282             <tbody class="bugs">
283             {{#each details.bugTrackers}}
284                 {{#if bugs}}
285                     <tr>
286                         <th>{{label}}</th>
287                         <td>
288                         [{{bugUrl}}]
289                         <a {{bind-attr href=bugUrl}} target="_blank">{{bugNumber}}</a>
290                         </td>
291                     </tr>
292                 {{/if}}
293             {{/each}}
294             </tbody>
295             <tbody class="status">
296                 <tr>
297                     <th>Current</th>
298                     <td>
299                         {{details.status.currentValue}} {{chartData.unit}}
300                         {{#if details.status.valueDelta}}
301                             ({{details.status.valueDelta}} {{chartData.unit}} / {{details.status.relativeDelta}})
302                         {{/if}}
303                         {{#if details.status.label}}
304                             <br>
305                             <span {{bind-attr class=details.status.className}}>{{details.status.label}}</span>
306                         {{/if}}
307                     </td>
308                 </tr>
309             </tbody>
310             <tbody>
311             {{#if details.buildNumber}}
312                 <tr>
313                     <th>Build</th>
314                     <td>
315                         {{#if details.buildURL}}
316                             <a {{bind-attr href=details.buildURL}} target="_blank">{{details.buildNumber}}</a>
317                         {{else}}
318                             {{details.buildNumber}}
319                         {{/if}}
320                         ({{details.buildTime}})
321                     </td>
322                 </tr>
323             {{/if}}
324             {{#each details.revisions}}
325                 <tr>
326                     <th>{{name}}</th>
327                     <td>
328                         {{#if url}}
329                             <a {{bind-attr href=url}} target="_blank">{{label}}</a>
330                         {{else}}
331                             {{label}}
332                         {{/if}}
333                     </td>
334                 </tr>
335             {{/each}}
336             </tbody>
337         </table>
338         <div class="commits">
339             {{#each details.revisions}}
340                 {{commits-viewer repository=repository revisionInfo=this caption=name}}
341             {{/each}}
342         </div>
343     {{/if}}
344     </script>
345
346     <script type="text/x-handlebars" data-template-name="components/commits-viewer">
347     {{#if commits}}
348         <table {{bind-attr class=":commits-viewer visible::hidden"}}>
349             {{#if caption}}
350                 <caption {{action toggleVisibility}}>{{caption}} commits</caption>
351             {{/if}}
352             {{#if visible}}
353                 <tbody>
354                     {{#each commits}}
355                         <tr>
356                             <th>
357                                 {{#if url}}
358                                     <a {{bind-attr href=url}} target="_blank">{{revision}}</a>
359                                 {{else}}
360                                     {{revision}}
361                                 {{/if}}
362                             </th>
363                             <th>{{author}}</th>
364                             <td>{{message}}</td>
365                         </tr>
366                     {{/each}}
367                 </tbody>
368             {{/if}}
369         </table>
370     {{/if}}
371     </script>
372
373     <script type="text/x-handlebars" data-template-name="close-button">
374         <svg class="close-button icon-button" viewBox="0 0 100 100">
375             <g stroke="black" stroke-width="10">
376                 <circle cx="50" cy="50" r="45" fill="transparent"/>
377                 <polygon points="30,30 70,70" />
378                 <polygon points="30,70 70,30" />
379             </g>
380         </svg>
381     </script>
382
383     <script type="text/x-handlebars" data-template-name="stat-button">
384         <svg class="stat-button icon-button" viewBox="10 0 110 100">
385             <g stroke="none" stroke-width="0" fill="black">
386                 <path id="upper-sigma" d="M 5 5 H 95 V 40 h -10 c -5 -20 -5 -20 -25 -20 H 35 L 60 50 l -20 0" />
387                 <use xlink:href="#upper-sigma" transform="translate(0, 100) scale(1, -1)" />
388             </g>
389         </svg>
390     </script>
391
392     <script type="text/x-handlebars" data-template-name="stat-pane">
393         <section {{bind-attr class=":popup-pane :stat-pane showingStatPane::hidden"}}>
394             <section class="stat-option">
395                 <h1>Moving average</h1>
396                 <label>Type: {{view Ember.Select
397                     content=movingAverageStrategies
398                     optionValuePath='content'
399                     optionLabelPath='content.label'
400                     selection=chosenMovingAverageStrategy}}</label>
401                     {{#if chosenMovingAverageStrategy.description}}
402                         <p class="description">{{chosenMovingAverageStrategy.description}}</p>
403                     {{/if}}
404                 {{#each chosenMovingAverageStrategy.parameterList}}
405                     <label>{{label}}: {{input type="number" value=value min=min max=max step=step}}</label>
406                 {{/each}}
407             </section>
408             {{#if chosenMovingAverageStrategy.execute}}
409                 <section class="stat-option">
410                     <h1>Envelope</h1>
411                     <label>Type: {{view Ember.Select
412                         content=envelopingStrategies
413                         optionValuePath='content'
414                         optionLabelPath='content.label'
415                         selection=chosenEnvelopingStrategy}}</label>
416                     {{#if chosenEnvelopingStrategy.description}}
417                         <p class="description">{{chosenEnvelopingStrategy.description}}</p>
418                     {{/if}}
419                     {{#each chosenEnvelopingStrategy.parameterList}}
420                         <label>{{label}}: <input type="number" {{bind-attr value=value min=min max=max step=step}}></label>
421                     {{/each}}
422                 </section>
423             {{/if}}
424             {{#if chosenMovingAverageStrategy.isSegmentation}}
425                 <section class="stat-option">
426                     <h1>A/B Test Range Selection</h1>
427                     <label>Type: {{view Ember.Select
428                         content=testRangeSelectionStrategies
429                         optionValuePath='content'
430                         optionLabelPath='content.label'
431                         selection=chosenTestRangeSelectionStrategy}}</label>
432                     {{#if chosenTestRangeSelectionStrategy.description}}
433                         <p class="description">{{chosenTestRangeSelectionStrategy.description}}</p>
434                     {{/if}}
435                 </section>
436             {{/if}}
437             {{#if chosenEnvelopingStrategy.execute}}
438                 <section class="stat-option">
439                     <h1>Anomaly Detection</h1>
440                     {{#each anomalyDetectionStrategies}}
441                         <label {{bind-attr title=description}}>{{input type="checkbox" name=id checked=enabled}}{{label}}</label>
442                     {{/each}}
443                 </section>
444             {{/if}}
445         </section>
446     </script>
447
448     <script type="text/x-handlebars" data-template-name="outlier-button">
449         <svg class="outlier-button icon-button" viewBox="0 0 100 100">
450             <g stroke="black" fill="black" stroke-width="15">
451                 <line x1="0" y1="70" x2="40" y2="70"/>
452                 <circle cx="15" cy="70" r="8"/>
453                 <circle cx="45" cy="70" r="8"/>
454                 <circle cx="85" cy="70" r="8"/>
455                 <line x1="85" y1="70" x2="100" y2="70"/>
456                 <g class="show-outlier-icon">
457                     <line x1="45" y1="70" x2="65" y2="20"/>
458                     <line x1="65" y1="20" x2="85" y2="70"/>
459                     <circle cx="65" cy="20" r="8"/>
460                 </g>
461                 <g class="hide-outlier-icon">
462                     <line x1="45" y1="70" x2="85" y2="70"/>
463                 </g>
464             </g>
465         </svg>
466     </script>
467
468     <script type="text/x-handlebars" data-template-name="analysis-button">
469         <svg class="analysis-button icon-button" viewBox="0 0 100 100">
470             <g stroke="black" fill="black" stroke-width="15">
471                 <circle cx="50" cy="50" r="40" fill="transparent"/>
472                 <line x1="50" y1="25" x2="50" y2="55"/>
473                 <circle cx="50" cy="67.5" r="10" stroke="none"/>
474             </g>
475         </svg>
476     </script>
477
478     <script type="text/x-handlebars" data-template-name="search-button">
479         <svg class="search-button icon-button" viewBox="0 0 100 100">
480             <g stroke="black" stroke-width="15">
481                 <circle cx="60" cy="40" r="30" fill="transparent"/>
482                 <line x1="10" y1="90" x2="40" y2="60"/>
483             </g>
484         </svg>
485     </script>
486
487     <script type="text/x-handlebars" data-template-name="spinner">
488         <svg class="spinner" viewBox="0 0 100 100">
489             <line x1="10" y1="50" x2="30" y2="50" stroke="black" stroke-width="10" stroke-linecap="round"/>
490             <line x1="21.72" y1="21.72" x2="35.86" y2="35.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
491             <line x1="50" y1="10" x2="50" y2="30" stroke="black" stroke-width="10" stroke-linecap="round"/>
492             <line x1="78.28" y1="21.72" x2="64.14" y2="35.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
493             <line x1="70" y1="50" x2="90" y2="50" stroke="black" stroke-width="10" stroke-linecap="round"/>
494             <line x1="65.86" y1="65.86" x2="78.28" y2="78.28" stroke="black" stroke-width="10" stroke-linecap="round"/>
495             <line x1="50" y1="70" x2="50" y2="90" stroke="black" stroke-width="10" stroke-linecap="round"/>
496             <line x1="21.72" y1="78.28" x2="35.86" y2="65.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
497         </svg>
498     </script>
499
500     <script type="text/x-handlebars" data-template-name="navbar">
501         <nav id="navigation" role="navigation">
502             <h1><a href="#">{{App.Manifest.siteTitle}}</a></h1>
503             <ul>
504                 {{#each App.Manifest.dashboards}}
505                     {{#if name}}
506                         {{#link-to 'dashboard' name tagName='li'}}
507                             {{#link-to 'dashboard' name}}{{label}}{{/link-to}}
508                         {{/link-to}}
509                     {{/if}}
510                 {{/each}}
511                 {{#link-to 'charts' tagName='li'}}
512                     {{#link-to 'charts'}}Charts{{/link-to}}
513                 {{/link-to}}
514                 {{#link-to 'analysis' tagName='li'}}
515                     {{#link-to 'analysis'}}Analysis{{/link-to}}
516                 {{/link-to}}
517             </ul>
518         </nav>
519     </script>
520
521     <script type="text/x-handlebars" data-template-name="number-of-days-controls">
522         <li class="numberOfDaysIs1">
523             <a href="javascript:false" class="control-button" {{action "setNumberOfDays" 1}}>1D</a>
524         </li>
525         <li class="numberOfDaysIs7">
526             <a href="javascript:false" class="control-button" {{action "setNumberOfDays" 7}}>1W</a>
527         </li>
528         <li class="numberOfDaysIs30">
529             <a href="javascript:false" class="control-button" {{action "setNumberOfDays" 30}}>1M</a>
530         </li>
531         <li class="numberOfDaysIs90">
532             <a href="javascript:false" class="control-button" {{action "setNumberOfDays" 90}}>3M</a>
533         </li>
534         <li class="numberOfDaysIs183">
535             <a href="javascript:false" class="control-button" {{action "setNumberOfDays" 183}}>6M</a>
536         </li>
537         <li class="numberOfDaysIs365">
538             <a href="javascript:false" class="control-button" {{action "setNumberOfDays" 365}}>1Y</a>
539         </li>
540     </script>
541
542     <script type="text/x-handlebars" data-template-name="start-time-slider">
543         <label><input type="range"> <span class="numberOfDays">X</span> days</label>
544     </script>
545
546     <script type="text/x-handlebars" data-template-name="popup">
547         <span class="label">{{view App.PopupButtonView tagName="a" label=view.label }}</span>
548         {{view view.popupListContainerView viewName="popupListContainerViewInstance"}}
549     </script>
550
551     <script type="text/x-handlebars" data-template-name="popup-list">
552         {{#each view.list}}
553             {{#if isSeparator}}
554                 <li><hr></li>
555             {{else }} {{#if children}}
556                 <li>{{view App.PopupView list=children label=label}}</li>
557             {{else}}
558                 <li>
559                     {{#if actionName}}
560                         <a href="javascript:false" class="label" {{action actionName actionArgument}}>{{label}}</a>
561                     {{else}}
562                         <a class="label">{{label}}</a>
563                     {{/if}}
564                 </li>
565             {{/if}} {{/if}}
566         {{/each}}
567     </script>
568
569     <script type="text/x-handlebars" data-template-name="analysis">
570         <header id="header">
571             {{partial "navbar"}}
572         </header>
573
574         <table id="analysis-tasks">
575             <thead>
576                 <tr>
577                     <td>Name</td>
578                     <td>Status</td>
579                     <td>Author</td>
580                     <td>Created at</td>
581                     <td>Platform</td>
582                     <td>Test</td>
583                 </tr>
584             </thead>
585             <tbody>
586                 {{#each model.tasks}}
587                     <tr>
588                         <td class="task-name">{{#link-to 'analysisTask' id}}{{name}}{{/link-to}}</td>
589                         <td class="status">{{statusLabel}}</td>
590                         <td class="author">{{author}}</td>
591                         <td class="created-at">{{formattedCreatedAt}}</td>
592                         <td class="platform-name">{{platform.label}}</td>
593                         <td class="test-name">{{metric.fullName}}</td>
594                     </tr>
595                 {{/each}}
596             </tbody>
597         </table>
598     </script>
599
600     <script type="text/x-handlebars" data-template-name="analysisTask">
601         <header id="header">
602             {{partial "navbar"}}
603         </header>
604
605         <h2 id="analysis-task-title">{{label}}</h2>
606         {{#if platform.label}}
607             <h3 id="analysis-task-testname">{{metric.fullName}} - {{platform.label}}</h3>
608         {{/if}}
609
610         {{#if pane}}
611             <section class="analysis-chart-pane chart-pane" tabindex="0">
612                 <div class="svg-container">
613                     {{interactive-chart
614                         chartData=pane.chartData
615                         ranges=pane.ranges
616                         domain=overviewDomain
617                         interactive=true
618                         currentItem=pane.hoveredOrSelectedItem
619                         selectedPoints=pane.selectedPoints
620                         selection=timeRange
621                         highlightedItems=highlightedItems
622                         rangeRoute="analysisTask"}}
623                 </div>
624                 <div class="details">
625                     <div class="details-table-container">
626                         {{#if details}}
627                             {{partial "chart-details"}}
628                         {{else}}
629                             {{partial "analysisStatusForm"}}
630                         {{/if}}
631                     </div>
632                 </div>
633             </section>
634         {{/if}}
635
636         {{partial "testGroupForm"}}
637
638         {{#each testGroupPanes}}
639             {{partial "testGroup"}}
640         {{/each}}
641     </script>
642
643     <script type="text/x-handlebars" data-template-name="testGroup">
644         <section class="analysis-group">
645             <h1>{{name}}</h1>
646             <div class="table-container">
647                 <table class="results">
648                     <thead>
649                         <tr>
650                             <td colspan="2">Configuration</td>
651                             <td>Results</td>
652                             <td>Status</td>
653                             {{#each repositories}}
654                                 <td>{{name}}</td>
655                             {{/each}}
656                         </tr>
657                     </thead>
658                     {{#each configurations}}
659                         <tbody {{bind-attr class="showRequestList::hideRequests"}}>
660                             <tr class="summary" {{action toggleShowRequestList this}}>
661                                 <td class="config-letter" colspan="2">{{summary.configLetter}}</td>
662                                 {{#with summary}}
663                                     {{partial "testGroupRow"}}
664                                 {{/with}}
665                             </tr>
666                             {{#each requests}}
667                                 <tr class="request">
668                                     {{#with ../this}}
669                                         <td class="config-letter" {{action toggleShowRequestList this}}></td>
670                                     {{/with}}
671                                     <td>Run {{orderLabel}}</td>
672                                     {{partial "testGroupRow"}}
673                                 </tr>
674                             {{/each}}
675                         </tbody>
676                     {{/each}}
677                     {{#each comparisons}}
678                         <tbody>
679                             <tr>
680                                 <td colspan="2">{{label}}</td>
681                                 <td>{{difference}}</td>
682                                 <td>{{result}}</td>
683                                 {{#with ../this}}
684                                     {{#each repositories}}
685                                         <td></td>
686                                     {{/each}}
687                                 {{/with}}
688                             </tr>
689                         </tbody>
690                     {{/each}}
691                 </table>
692             </div>
693             <div class="reference-chart">
694                 {{#if referenceChart}}
695                     {{interactive-chart
696                         chartData=referenceChart.data
697                         domain=overviewDomain
698                         showYAxis=false
699                         enableSelection=false
700                         highlightedItems=referenceChart.highlightedItems}}
701                 {{/if}}
702             </div>
703         </section>
704     </script>
705
706     <script type="text/x-handlebars" data-template-name="testGroupRow">
707         <td>
708             {{#if value}}
709                 {{box-plot range=valueRange value=value delta=delta}}
710             {{/if}}
711             {{formattedValue}}
712         </td>
713         <td>
714             <a {{bind-attr href=url title=buildLabel}}>{{statusLabel}}</a>
715         </td>
716         {{#each revisionList}}
717             <td>{{this}}</td>
718         {{/each}}
719     </script>
720
721     <script type="text/x-handlebars" data-template-name="testGroupForm">
722     {{#if rootConfigurations}}
723         <form method="POST" {{action "createTestGroup" newTestGroupName repetitionCount on="submit"}}>
724             <section class="analysis-group">
725                 <h1>{{input name="name" value=newTestGroupName placeholder="Test group name" required=true type="text"}}</h1>
726                 <table>
727                     <thead>
728                         <tr>
729                             <th>Configuration</th>
730                             {{#each configurations}}
731                                 <th>{{this}}</th>
732                             {{/each}}
733                         </tr>
734                     </thead>
735                     <tbody>
736                         {{#each rootConfigurations}}
737                             <tr>
738                                 <th>{{name}}</th>
739                                 {{#each sets}}
740                                     <td>
741                                         {{view Ember.Select name=name content=options
742                                             optionValuePath="content.value" optionLabelPath="content.label"
743                                             selection=selection}}
744                                         {{#if selection.isCustom}}
745                                             {{input name="customValue" type=text value=customValue}}
746                                         {{/if}}
747                                         </td>
748                                 {{/each}}
749                             </tr>
750                         {{/each}}
751                     </tbody>
752                 </table>
753                 <label>Number of runs {{view Ember.Select content=possibleRepetitionCounts value=repetitionCount}}</label>
754                 <button type="submit">Start A/B testing</button>
755             </section>
756         </form>
757     {{/if}}
758     </script>
759
760     <script type="text/x-handlebars" data-template-name="analysisStatusForm">
761         <table class="analysis-bugs">
762             <tbody>
763                 {{#each model.bugs}}
764                     <tr>
765                         <th>{{bugTracker.name}}</th>
766                         <td>
767                             <a {{bind-attr href=url}} target="_blank">{{number}}</a>
768                             <a href="javascript:false" {{action "deleteBug" this}}>{{partial "close-button"}}</a>
769                         </td>
770                     </tr>
771                 {{/each}}
772                 {{#if bugTrackers}}
773                     <tr>
774                         <td>
775                             {{view Ember.Select content=bugTrackers optionValuePath="content" optionLabelPath="content.name" value=chosenBugTracker}}
776                         </td>
777                         <td>
778                             {{input id=elementId type=text value=editedBugNumber}}
779                             <button {{action "addBug" chosenBugTracker editedBugNumber}}>Add</button>
780                         </td>
781                     </tr>
782                 {{/if}}
783             </tbody>
784             <tbody>
785                 <tr>
786                     <th><label for="analysis-status">Status<label></th>
787                     <td>
788                         <form class="analysis-bugs" {{action "saveStatus" on="submit"}}>
789                             {{view Ember.Select id="analysis-status" content=analysisResultOptions optionValuePath="content"
790                                 optionLabelPath="content.label" selection=chosenAnalysisResult}}
791                             <input type="submit" value="Save"><br>
792                             <label {{bind-attr class="needsFeedback::hidden"}}>{{input type=checkbox checked=notNeeded}} This should not have been created</label>
793                         </form>
794                     </td>
795                 </tr>
796             </tbody>
797         </table>
798     </script>
799
800 </head>
801 <body>
802 </body>
803 </html>