Commit fcea6b29 authored by Samuel GAIST's avatar Samuel GAIST

Merge branch 'reports-angular-perf-fixes' into 'master'

Performance fixes

Closes #488

See merge request !234
parents 28e4b7c8 ab5a1a28
Pipeline #25569 failed with stage
in 2 seconds
......@@ -66,7 +66,7 @@ angular.module('reportApp')
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a ng-repeat='t in filetypes' ng-click='downloadImgs($event, t)'>{{ t }}</a></li>
<li><a ng-repeat='t in filetypes track by t' ng-click='downloadImgs($event, t)'>{{ t }}</a></li>
</ul>
</div>
<a id='{{ domId }}-download'></a>
......
......@@ -124,8 +124,8 @@ angular.module('reportApp')
Add Plot
<span class="caret"></span>
</button>
<ul class='dropdown-menu' ng-repeat='(expName, plots) in plottables' ng-if='expName === group.experiments[0]'>
<li ng-repeat='plot in plots'>
<ul class='dropdown-menu' ng-repeat='(expName, plots) in plottables track by expName' ng-if='expName === group.experiments[0]'>
<li ng-repeat='plot in plots track by plot.label'>
<a ng-click='addNewPlot(plot)'>{{ plot.label }} <i>({{ plot.type }})</i></a>
</li>
</ul>
......
......@@ -49,9 +49,13 @@ angular.module('reportApp')
scope.buttonAction()();
};
scope.tableablesCache = {};
scope.tableables = () => {
// start with the tableables generated in experimentsservice
const tableables = ExperimentsService.tableables;
const cacheKey = Object.keys(tableables).length;
if(scope.tableablesCache[cacheKey])
return scope.tableablesCache[cacheKey];
const fieldArr = Object.entries(tableables)
// only look at fields that are from an experiment in the group
.filter(([e, fields]) => scope.group.experiments.includes(e))
......@@ -65,9 +69,13 @@ angular.module('reportApp')
// removing dups
const arr = Array.from(new Set(fieldArr));
scope.tableablesCache[cacheKey] = arr;
return arr;
};
/* This always returns true, because it's only called with 1 arg which is basically [expName, fieldName].join('.')
* Due to the removing dups step in scope.tableables(), I dont think this is necessary, but keep this here if it turns out to be!
* This func checks if the field name has already been given a spot in the available columns list.
// has this fieldName already been processed?
// need to look at the already-processed field names
scope.isUniqueTableable = (expName, fieldName) => {
......@@ -94,6 +102,7 @@ angular.module('reportApp')
// if it isnt a repeat, its unique!
return !isRepeat;
};
*/
// many tableable fields are fields from an analyzer, a block, or something else
// these fields have a field group name, a '.', and an actual field name
......@@ -116,10 +125,9 @@ angular.module('reportApp')
scope.subfieldName = (field) => field.includes('.') ? field.split('.').slice(1).join('.') : field;
scope.shouldShowField = (fName, gName) => {
const isUnique = scope.isUniqueTableable(fName);
const isInGroup = scope.groupName(fName) == gName;
return isUnique && isInGroup;
return isInGroup;
}
// toggle the selection of a field
......@@ -144,8 +152,8 @@ angular.module('reportApp')
<fieldset>
<h4>General</h4>
<div
ng-repeat='fName in tableables()'
ng-if="isUniqueTableable(fName) && !fName.includes('.')">
ng-repeat='fName in tableables() track by fName'
ng-if="!fName.includes('.')">
<label>
<input
type='checkbox'
......@@ -156,10 +164,10 @@ angular.module('reportApp')
</label>
</div>
</fieldset>
<fieldset ng-repeat='gName in tableablesGroups()'>
<fieldset ng-repeat='gName in tableablesGroups() track by gName'>
<h4>{{ gName }}</h4>
<div
ng-repeat='fName in tableables()'
ng-repeat='fName in tableables() track by fName'
ng-if='shouldShowField(fName, gName)'>
<label>
<input
......@@ -173,19 +181,19 @@ angular.module('reportApp')
</fieldset>
</form>
<!--
<select multiple ng-model='colsSelected'>
<select multiple ng-model='colsSelected' ng-model-options="{ debounce: 100 }">
<optgroup label='General'>
<option
ng-repeat='fName in tableables()'
ng-if="isUniqueTableable(fName) && !fName.includes('.')"
ng-repeat='fName in tableables() track by fName'
ng-if="!fName.includes('.')"
value='{{ fName }}'>
{{ fName }}
</option>
</optgroup>
<optgroup ng-repeat='gName in tableablesGroups()' label='{{ gName }}'>
<optgroup ng-repeat='gName in tableablesGroups() track by gName' label='{{ gName }}'>
<option
ng-repeat='fName in tableables()'
ng-if='isUniqueTableable(fName) && fName.startsWith(gName)'
ng-repeat='fName in tableables() track by fName'
ng-if='fName.startsWith(gName)'
value='{{ fName }}'>
{{ subfieldName(fName) }}
</option>
......
......@@ -44,7 +44,9 @@ angular.module('reportApp').directive("editableLabel", ['UrlService', function(U
type='text'
class='form-control'
placeholder='A label...'
ng-model='obj[field]'/>
ng-model='obj[field]'
ng-model-options="{ debounce: 500 }"
/>
</span>
`
};
......
......@@ -93,7 +93,7 @@ angular.module('reportApp')
</tr>
</thead>
<tbody>
<tr ng-repeat='expName in expNames'>
<tr ng-repeat='expName in expNames track by expName'>
<td ng-if='!isViewmode()'>
<div class='btn-group action-buttons'>
<span
......@@ -114,7 +114,7 @@ angular.module('reportApp')
</td>
<td><a href='{{ getExpUrl(expName) }}'>{{ expName }}</a></td>
<td>
<span ng-repeat='db in getExpDatabases(expName)'>
<span ng-repeat='db in getExpDatabases(expName) track by db'>
<a href='{{ getDatabaseUrl(db.split("@")[0]) }}'>{{ db }}</a>
&nbsp;
</span>
......
......@@ -48,6 +48,7 @@ angular.module('reportApp').directive("groupsLayout", ['GroupsService', 'UrlServ
<div ng-if='!isViewmode() || GroupsService.groups.length > 1'
ui-sortable='sortableOptions'
ng-model='GroupsService.groups'
ng-model-options="{ debounce: 500 }"
id='groupsLayout'
class='panel-group'>
<div
......
......@@ -96,7 +96,7 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
</button>
<ul class="dropdown-menu" aria-labelledby="{{ dropdownId }}">
<li
ng-repeat='exp in expsNotInGroup()'
ng-repeat='exp in expsNotInGroup() track by exp'
ng-click='group.addExperiment(exp, getAnalyzerFromExpName(exp))'>
<a>{{ exp }}</a>
</li>
......@@ -135,7 +135,7 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
</span>
</div>
</td>
<td ng-if='!isViewmode()'><input ng-model='group.aliases[expName]'></input></td>
<td ng-if='!isViewmode()'><input ng-model='group.aliases[expName]' ng-model-options="{ debounce: 500 }"></input></td>
<td ng-if='isViewmode()'><span>{{ group.aliases[expName] }}</span></td>
<td><a href='{{ getExpUrl(expName) }}'>{{ getExpName(expName) }}</a></td>
<td>
......
......@@ -40,8 +40,8 @@ angular.module('reportApp').directive("groupPanelItems", [function(){
};
},
template: `
<div ui-sortable='sortableOptions' ng-model='group._reportItems' class='panel-group'>
<div ng-repeat='item in group.reportItems'>
<div ui-sortable='sortableOptions' ng-model='group._reportItems' ng-model-options="{ debounce: 500 }" class='panel-group'>
<div ng-repeat='item in group.reportItems track by $index'>
<div group-table-item
style='margin-bottom: 5px;'
ng-if="item.id.includes('table')"
......
......@@ -125,7 +125,7 @@ angular.module('reportApp')
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-click='content.savedPlotter = p' ng-repeat='p in getPossiblePlotters()'><a>{{ p }}</a></li>
<li ng-click='content.savedPlotter = p' ng-repeat='p in getPossiblePlotters() track by p'><a>{{ p }}</a></li>
</ul>
</div>
<div class='btn-group' role='group'>
......@@ -140,7 +140,7 @@ angular.module('reportApp')
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-click='content.savedConfig = c' ng-repeat='c in getPossibleConfigs()'><a>{{ c }}</a></li>
<li ng-click='content.savedConfig = c' ng-repeat='c in getPossibleConfigs() track by c'><a>{{ c }}</a></li>
</ul>
</div>
</div>
......
......@@ -100,7 +100,7 @@ angular.module('reportApp')
</tr>
</thead>
<tbody>
<tr ng-repeat='alg in algorithms'>
<tr ng-repeat='alg in algorithms track by alg'>
<td><input type='radio' name='{{ alg }}' ng-model='radios[alg]' value='visible'></td>
<td><input type='radio' name='{{ alg }}' ng-model='radios[alg]' value='openSource' checked></td>
<td>{{ alg }}</td>
......
......@@ -86,16 +86,21 @@ angular.module('reportApp')
// get possible table entries
scope.tableables = ExperimentsService.tableables || {};
scope.fieldTypeCache = {};
// gets the field type (int, float, string, nothing)
scope.getFieldType = (field) => {
if(scope.fieldTypeCache[field])
return scope.fieldTypeCache[field];
let type;
if(field === scope.fields[0]){
return 'string';
type = 'string';
scope.fieldTypeCache[field] = type;
}
let hasFieldObj = Object.values(scope.tableables)
.find(o => o[field]);
let fVal = hasFieldObj ? hasFieldObj[field] : {};
let type;
if(fVal.type){
type = fVal.type;
} else if(Number.isSafeInteger(fVal)){
......@@ -108,6 +113,7 @@ angular.module('reportApp')
type = undefined;
}
scope.fieldTypeCache[field] = type;
return type;
};
// gets the field val for the given exp
......@@ -238,7 +244,7 @@ angular.module('reportApp')
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="{{domId}}-precision">
<li ng-click='content.precision = i' ng-repeat='i in floatingPointRange'><a>{{ i }}</a></li>
<li ng-click='content.precision = i' ng-repeat='i in floatingPointRange track by i'><a>{{ i }}</a></li>
</ul>
</div>
<button class='btn btn-default' ng-click='toggleViewingCSV()'>
......@@ -254,7 +260,7 @@ angular.module('reportApp')
<div ng-if='!isViewingCSV.val' style='height: 100%; overflow-x: auto;'>
<table class="table table-striped table-hover">
<thead>
<tr ui-sortable='sortableOptions' ng-model='fields'>
<tr ui-sortable='sortableOptions' ng-model='fields' ng-model-options="{ debounce: 500 }">
<th ng-repeat='field in fields'>
<span
ng-if="sortField.val == field"
......
......@@ -31,6 +31,7 @@
* - Rendering
*/
angular.module('reportApp').factory('PlotService', ['UrlService', function(UrlService){
console.log('in PlotService');
const ps = {
// these are provided by ReportService
plotters: [],
......
......@@ -28,6 +28,7 @@
*/
angular.module('reportApp').factory('ReportService', ['GroupsService', 'plotterFactory', 'PlotService', 'reportFactory', 'UrlService', 'ErrorService', function(GroupsService, plotterFactory, PlotService, reportFactory, UrlService, ErrorService){
const rs = {};
console.log('in reportsService');
rs.isAnonymous = undefined;
rs.isOwner = undefined;
......@@ -43,7 +44,7 @@ angular.module('reportApp').factory('ReportService', ['GroupsService', 'plotterF
// processed the report data received from the server,
// and bootstraps the state of various services
rs.processReport = (report) => {
console.log('in reportsService processReport');
// useful info about the app
rs.isAnonymous = report.anonymous;
rs.isOwner = report.is_owner;
......@@ -86,6 +87,7 @@ angular.module('reportApp').factory('ReportService', ['GroupsService', 'plotterF
// fetch the report data using either the by-name or by-number scheme,
// according to what URLService found
rs.fetchReport = () => {
console.log('in reportsService fetchReport');
const nameSeg = UrlService.getNameSegment();
const numSeg = UrlService.getNumberSegment();
......
......@@ -26,6 +26,7 @@
* Helper functionality to generate URLs for the reports app
*/
angular.module('reportApp').factory('UrlService', [function(){
console.log('in UrlService');
// const path segments
const experimentSegment = 'experiments/';
const blockSegment = 'algorithms/';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment