blob: d447733cd8786ba5b6ae2a72bdf39ba5b4dd72be [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/base/xhr.html">
<link rel="import" href="/tracing/ui/base/dom_helpers.html">
<link rel="import" href="/tracing/ui/base/info_bar_group.html">
<link rel="import" href="/tracing/ui/base/polymer_utils.html">
<link rel="import" href="/perf_insights/ui/reports/pi_report.html">
<link rel="import" href="/perf_insights/function_handle.html">
<link rel="import" href="/perf_insights/ui/generic_results_view.html">
<polymer-element name="pi-ui-pi-app-main">
<template>
<style>
:host {
display: flex;
flex-direction: column;
}
top-controls {
display: flex;
flex: 0 0 auto;
background-color: rgb(236, 236, 236);
border-bottom: 1px solid #8e8e8e;
padding: 4px;
}
top-controls > span.spacer {
flex: 1 1 auto;
}
top-left-controls {
display: flex;
}
top-right-controls {
display: flex;
}
report-container {
display: flex;
flex: 1 1 auto;
min-height: 0;
min-width: 0;
overflow: auto;
}
report-container > * {
flex: 1 1 auto;
}
</style>
<top-controls>
<top-left-controls id="top_left_controls"></top-left-controls>
<span class="spacer"></span>
<top-right-controls id="top_right_controls"></top-right-controls>
</top-controls>
<tr-ui-b-info-bar-group id="infobars"></tr-ui-b-info-bar-group>
<report-container id="report_container"></report-container>
</template>
</polymer-element>
<script>
'use strict';
tr.exportTo('pi.ui', function() {
function areMappingStatesSame(a, b) {
for (var k in a)
if (a[k] !== b[k])
return false;
return true;
}
Polymer('pi-ui-pi-app-main', {
created: function() {
// Non-mapping state.
this.mapTracesDrivers_ = undefined;
// Mapping state.
this.currentMapTracesDriver_ = undefined;
this.corpusQuery_ = undefined;
this.piReportElementName_ = undefined;
this.showRawResults_ = false;
},
ready: function() {
var topLeftControls = this.$.top_left_controls;
var topRightControls = this.$.top_right_controls;
var mapTracesDriverSelector = document.createElement('select');
mapTracesDriverSelector.classList.add('map-traces-driver-selector');
// This selector is actually populated in the mapTracesDrivers setter.
topLeftControls.appendChild(mapTracesDriverSelector);
var cannedCorpusQueries = [
{
'label': 'All traces',
'value': 'True'
},
{
'label': 'At most one trace',
'value': 'MAX_TRACE_HANDLES=1'
},
{
'label': 'At most two traces',
'value': 'MAX_TRACE_HANDLES=2'
},
{
'label': 'At most 5 traces',
'value': 'MAX_TRACE_HANDLES=5'
},
{
'label': 'At most 10 traces',
'value': 'MAX_TRACE_HANDLES=10'
},
{
'label': 'At most 50 traces',
'value': 'MAX_TRACE_HANDLES=50'
},
{
'label': 'At most 100 traces',
'value': 'MAX_TRACE_HANDLES=100'
}
];
var corpusQuerySelector = tr.ui.b.createSelector(
this, 'corpusQuery',
'pi.app_main.corpusQuery',
cannedCorpusQueries[0].value,
cannedCorpusQueries);
topLeftControls.appendChild(corpusQuerySelector);
var piReportPolymerElementNames = tr.ui.b.getPolymerElementsThatSubclass(
'pi-ui-r-pi-report');
var piReportElementOptions = piReportPolymerElementNames.map(
function(peTagName) {
return {
label: peTagName,
value: peTagName
};
});
var reportSelector = tr.ui.b.createSelector(
this, 'piReportElementName',
'pi.app_main.piReportElementName',
piReportElementOptions[0].value,
piReportElementOptions);
topLeftControls.appendChild(reportSelector);
var showRawResultsCheckbox = tr.ui.b.createCheckBox(
this, 'showRawResults',
'pi.app_main.showRawResults', false,
'Show raw results');
topRightControls.appendChild(showRawResultsCheckbox);
},
get mapTracesDrivers() {
return this.mapTracesDrivers_;
},
set mapTracesDrivers(mapTracesDrivers) {
this.mapTracesDrivers_ = mapTracesDrivers;
var topLeftControls = this.$.top_left_controls;
var oldSelector = topLeftControls.querySelector(
'.map-traces-driver-selector');
var options = mapTracesDrivers.map(function(mapTracesDriver) {
return {
label: mapTracesDriver.name,
value: mapTracesDriver
};
});
var newSelector = tr.ui.b.createSelector(
this, 'currentMapTracesDriver',
'pi.app_main.currentMapTracesDriver',
options[0].value,
options);
newSelector.classList.add('map-traces-driver-selector');
topLeftControls.replaceChild(newSelector, oldSelector);
},
get mappingState() {
return {
currentMapTracesDriver: this.currentMapTracesDriver_,
corpusQuery: this.corpusQuery_,
piReportElementName: this.piReportElementName_,
showRawResults: this.showRawResults_
};
},
get currentMapTracesDriver() {
return this.currentMapTracesDriver_;
},
set currentMapTracesDriver(currentMapTracesDriver) {
this.currentMapTracesDriver_ = currentMapTracesDriver;
this.scheduleUpdateContents_();
this.fire('ui-state-changed');
},
get corpusQuery() {
return this.corpusQuery_;
},
set corpusQuery(corpusQuery) {
this.corpusQuery_ = corpusQuery;
this.scheduleUpdateContents_();
this.fire('ui-state-changed');
},
get piReportElementName() {
return this.piReportElementName_;
},
set piReportElementName(piReportElementName) {
this.piReportElementName_ = piReportElementName;
this.scheduleUpdateContents_();
this.fire('ui-state-changed');
},
get mapClientSide() {
return this.mapClientSide_;
},
set mapClientSide(mapClientSide) {
this.mapClientSide_ = mapClientSide;
this.scheduleUpdateContents_();
this.fire('ui-state-changed');
},
get showRawResults() {
return this.showRawResults_;
},
set showRawResults(showRawResults) {
this.showRawResults_ = showRawResults;
this.scheduleUpdateContents_();
this.fire('ui-state-changed');
},
scheduleUpdateContents_: function() {
if (this.pendingUpdateContentsPromise_)
return;
var mappingState = this.mappingState;
var p = this.beginUpdatingContents_(mappingState);
p = p.catch(function(err) {
tr.showPanic('Something is wrong', err);
});
p = p.then(updateDone.bind(this));
function updateDone() {
this.pendingUpdateContentsPromise_ = undefined;
if (!areMappingStatesSame(this.mappingState, mappingState))
this.scheduleUpdateContents_();
}
this.pendingUpdateContentsPromise_ = p;
},
beginUpdatingContents_: function(mappingState) {
var pe = tr.ui.b.getPolymerElementNamed(mappingState.piReportElementName);
var reportContainer = this.$.report_container;
var infobars = this.$.infobars;
function clearInfobarsOrUpdateWithErrors(mapResults) {
infobars.clearMessages();
if (!mapResults) {
infobars.addMessage('Cannot map');
return mapResults;
}
if (!mapResults.hadFailures)
return mapResults;
function onTellMeMore() {
var dlg = new tr.ui.b.Overlay();
dlg.dlg = 'Results summary';
var grv = document.createElement('pi-ui-generic-results-view');
grv.mapResults = mapResults;
grv.style.minHeight = '500px';
dlg.appendChild(grv);
dlg.visible = true;
}
var numFailedRuns = mapResults.failedRunInfos.length;
infobars.addMessage(
'There were ' + numFailedRuns + ' traces that did not process.',
[
{
buttonText: 'Tell me more...',
onClick: onTellMeMore
}
]);
return mapResults;
}
var p = Promise.resolve();
p = p.then(function indicateThinking() {
infobars.clearMessages();
infobars.addMessage('... thinking...');
});
p = p.then(function doMapping() {
if (mappingState.currentMapTracesDriver === undefined ||
mappingState.piReportElementName === undefined ||
mappingState.corpusQuery === undefined) {
return undefined;
}
var mapFunctionName = pe.getAttribute('map-function-name');
var mapFunctionHref = pe.getAttribute('map-function-href');
var moduleToLoad = new pi.ModuleToLoad(mapFunctionHref);
var mapFunctionHandle = new pi.FunctionHandle([moduleToLoad],
mapFunctionName);
if (mappingState.mapClientSide) {
throw new Error('Currently unsupported');
}
return mappingState.currentMapTracesDriver(mapFunctionHandle,
mappingState.corpusQuery);
});
p = p.then(function responseToResults(responseText) {
if (responseText === undefined)
return undefined;
var data = JSON.parse(responseText);
return pi.r.Results.fromDict(data);
});
p = p.then(clearInfobarsOrUpdateWithErrors);
p = p.then(function showMappingResults(mapResults) {
reportContainer.textContent = '';
if (mapResults === undefined)
return;
var reportEl;
if (mappingState.showRawResults) {
reportEl = document.createElement('pi-ui-generic-results-view');
} else {
reportEl = document.createElement(mappingState.piReportElementName);
}
reportEl.mapResults = mapResults;
reportContainer.appendChild(reportEl);
});
return p;
}
});
return {
};
});
</script>