diff --git a/beat/web/reports/static/reports/app/directives/downloadLink.js b/beat/web/reports/static/reports/app/directives/downloadLink.js index 3b16d0dac7b7a582aaddf647a62620759b144210..4510f1d3ba1158589f9f3a992dc509f839b4d3f8 100644 --- a/beat/web/reports/static/reports/app/directives/downloadLink.js +++ b/beat/web/reports/static/reports/app/directives/downloadLink.js @@ -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> diff --git a/beat/web/reports/static/reports/app/directives/edit/addItemsMenu.js b/beat/web/reports/static/reports/app/directives/edit/addItemsMenu.js index d9ea7e3e6af9b039ca47d3072ab7ef0739837e0f..85e26e675bf33bb3f269795a1863d34d645c8b2e 100644 --- a/beat/web/reports/static/reports/app/directives/edit/addItemsMenu.js +++ b/beat/web/reports/static/reports/app/directives/edit/addItemsMenu.js @@ -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> diff --git a/beat/web/reports/static/reports/app/directives/edit/tableFieldSelector.js b/beat/web/reports/static/reports/app/directives/edit/tableFieldSelector.js index e621ce683958626e92c4544d9e46b7dad454a93f..89a0776295bb8318eac3f3b02160df6694884959 100644 --- a/beat/web/reports/static/reports/app/directives/edit/tableFieldSelector.js +++ b/beat/web/reports/static/reports/app/directives/edit/tableFieldSelector.js @@ -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> diff --git a/beat/web/reports/static/reports/app/directives/editableLabel.js b/beat/web/reports/static/reports/app/directives/editableLabel.js index dbc5b9ccd01fb50eed671533acc9eb29760a4a97..82f7a2f6400c65e5fabd923e68ed4e0e217c0196 100644 --- a/beat/web/reports/static/reports/app/directives/editableLabel.js +++ b/beat/web/reports/static/reports/app/directives/editableLabel.js @@ -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> ` }; diff --git a/beat/web/reports/static/reports/app/directives/experimentsTable.js b/beat/web/reports/static/reports/app/directives/experimentsTable.js index 9b96493927af12f866efc432564e2daadea13625..ae111e80d05e0b7bcd4b12abda05f2c7f1bb7d7a 100644 --- a/beat/web/reports/static/reports/app/directives/experimentsTable.js +++ b/beat/web/reports/static/reports/app/directives/experimentsTable.js @@ -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> </span> diff --git a/beat/web/reports/static/reports/app/directives/layout.js b/beat/web/reports/static/reports/app/directives/layout.js index 27ae4d1896269620ee4490e95caa78e27e59a9fc..7da4fe37eeb45c9f6be806bbad71e9c96cbca254 100644 --- a/beat/web/reports/static/reports/app/directives/layout.js +++ b/beat/web/reports/static/reports/app/directives/layout.js @@ -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 diff --git a/beat/web/reports/static/reports/app/directives/panelExperiments.js b/beat/web/reports/static/reports/app/directives/panelExperiments.js index 5ed6d3e2dfdbf9bb207dcfecfa3c3bef53003a5e..c831da8272ad0bfa0cbf3e34752e01d3f2b690a7 100644 --- a/beat/web/reports/static/reports/app/directives/panelExperiments.js +++ b/beat/web/reports/static/reports/app/directives/panelExperiments.js @@ -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> diff --git a/beat/web/reports/static/reports/app/directives/panelItems.js b/beat/web/reports/static/reports/app/directives/panelItems.js index 28df1fdd08b30633950e01e978f69deae9e06fcc..c9184b515fd20098c4c5780b7fa4ece8d02df331 100644 --- a/beat/web/reports/static/reports/app/directives/panelItems.js +++ b/beat/web/reports/static/reports/app/directives/panelItems.js @@ -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')" diff --git a/beat/web/reports/static/reports/app/directives/plotItem.js b/beat/web/reports/static/reports/app/directives/plotItem.js index 6fa23841354c290bb22246bc0424b153a65a1933..209055bdfcf5993ef21bc8765b0af67f9cb754dc 100644 --- a/beat/web/reports/static/reports/app/directives/plotItem.js +++ b/beat/web/reports/static/reports/app/directives/plotItem.js @@ -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> diff --git a/beat/web/reports/static/reports/app/directives/publish.js b/beat/web/reports/static/reports/app/directives/publish.js index fe68cb35a868895f47e0fc6bef8b3adf1d037ac1..a886f3806597df5678603ede4acf2f6a24b72fb4 100644 --- a/beat/web/reports/static/reports/app/directives/publish.js +++ b/beat/web/reports/static/reports/app/directives/publish.js @@ -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> diff --git a/beat/web/reports/static/reports/app/directives/tableItem.js b/beat/web/reports/static/reports/app/directives/tableItem.js index 036c1678d5727ca3cb4f2db75aa8fba4eb9d3834..f70b1f45570c8abc71944847bf8a5c58305a78d2 100644 --- a/beat/web/reports/static/reports/app/directives/tableItem.js +++ b/beat/web/reports/static/reports/app/directives/tableItem.js @@ -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" diff --git a/beat/web/reports/static/reports/app/services/plotService.js b/beat/web/reports/static/reports/app/services/plotService.js index b3efb372abb29fd1b5e3aa1ea404136880d43c26..bfb4c62bd8a9b7d785d906273be1f6ac4f48a844 100644 --- a/beat/web/reports/static/reports/app/services/plotService.js +++ b/beat/web/reports/static/reports/app/services/plotService.js @@ -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: [], diff --git a/beat/web/reports/static/reports/app/services/reportService.js b/beat/web/reports/static/reports/app/services/reportService.js index ff9a97f588ee5c9fe4bb9a76d7cf0758c39ee578..4d047c88bf4a7fa70e2ce15a1b5d7185efd632e4 100644 --- a/beat/web/reports/static/reports/app/services/reportService.js +++ b/beat/web/reports/static/reports/app/services/reportService.js @@ -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(); diff --git a/beat/web/reports/static/reports/app/services/urlService.js b/beat/web/reports/static/reports/app/services/urlService.js index 861f52a65de39978167dcf88ea6ad543ba268fd6..a6503dc54f4cb8fc9081301ad3194892b2233731 100644 --- a/beat/web/reports/static/reports/app/services/urlService.js +++ b/beat/web/reports/static/reports/app/services/urlService.js @@ -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/';