AC-665 Added governor to object type searches, limiting objects to 30. Now using 'working' spinner in place of small spinner. No more auto search. Replaced the auto search with Go button and Enter key.

This commit is contained in:
Chris Houseknecht
2013-11-20 09:03:01 +00:00
parent 6f652d801a
commit 5b6eba7f93
7 changed files with 65 additions and 51 deletions

View File

@@ -15,7 +15,7 @@
*/ */
angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities']) angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities'])
.factory('RefreshRelated', ['ProcessErrors', 'Rest', function(ProcessErrors, Rest) { .factory('RefreshRelated', ['ProcessErrors', 'Rest', 'Wait', function(ProcessErrors, Rest, Wait) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
@@ -26,12 +26,13 @@ angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities'])
Rest.setUrl(url); Rest.setUrl(url);
Rest.get() Rest.get()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
Wait('stop');
scope[set] = data['results']; scope[set] = data['results'];
scope[iterator + 'NextUrl'] = data.next; scope[iterator + 'NextUrl'] = data.next;
scope[iterator + 'PrevUrl'] = data.previous; scope[iterator + 'PrevUrl'] = data.previous;
scope[iterator + 'Count'] = data.count; scope[iterator + 'Count'] = data.count;
scope[iterator + 'PageCount'] = Math.ceil((data.count / scope[iterator + 'PageSize'])); scope[iterator + 'PageCount'] = Math.ceil((data.count / scope[iterator + 'PageSize']));
scope[iterator + 'SearchSpin'] = false; //scope[iterator + 'SearchSpin'] = false;
scope[iterator + 'Loading'] = false; scope[iterator + 'Loading'] = false;
scope[iterator + 'HoldInput'] = false; scope[iterator + 'HoldInput'] = false;
scope.$emit('related' + set); scope.$emit('related' + set);
@@ -40,7 +41,8 @@ angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities'])
} }
}) })
.error ( function(data, status, headers, config) { .error ( function(data, status, headers, config) {
scope[iterator + 'SearchSpin'] = true; Wait('stop');
//scope[iterator + 'SearchSpin'] = true;
ProcessErrors(scope, data, status, null, ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status }); { hdr: 'Error!', msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status });
}); });

View File

@@ -15,7 +15,7 @@
*/ */
angular.module('RefreshHelper', ['RestServices', 'Utilities']) angular.module('RefreshHelper', ['RestServices', 'Utilities'])
.factory('Refresh', ['ProcessErrors', 'Rest', function(ProcessErrors, Rest) { .factory('Refresh', ['ProcessErrors', 'Rest', 'Wait', function(ProcessErrors, Rest, Wait) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
@@ -27,11 +27,12 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities'])
Rest.setUrl(url); Rest.setUrl(url);
Rest.get() Rest.get()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
Wait('stop');
scope[iterator + 'NextUrl'] = data.next; scope[iterator + 'NextUrl'] = data.next;
scope[iterator + 'PrevUrl'] = data.previous; scope[iterator + 'PrevUrl'] = data.previous;
scope[iterator + 'Count'] = data.count; scope[iterator + 'Count'] = data.count;
scope[iterator + 'PageCount'] = Math.ceil((data.count / scope[iterator + 'PageSize'])); scope[iterator + 'PageCount'] = Math.ceil((data.count / scope[iterator + 'PageSize']));
scope[iterator + 'SearchSpin'] = false; //scope[iterator + 'SearchSpin'] = false;
scope[iterator + 'Loading'] = false; scope[iterator + 'Loading'] = false;
for (var i=1; i <= 3; i++) { for (var i=1; i <= 3; i++) {
var modifier = (i == 1) ? '' : i; var modifier = (i == 1) ? '' : i;
@@ -41,7 +42,8 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities'])
scope.$emit('PostRefresh'); scope.$emit('PostRefresh');
}) })
.error ( function(data, status, headers, config) { .error ( function(data, status, headers, config) {
scope[iterator + 'SearchSpin'] = false; Wait('stop');
//scope[iterator + 'SearchSpin'] = false;
scope[iterator + 'HoldInput'] = false; scope[iterator + 'HoldInput'] = false;
ProcessErrors(scope, data, status, null, ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status }); { hdr: 'Error!', msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status });

View File

@@ -16,7 +16,8 @@
*/ */
angular.module('RelatedSearchHelper', ['RestServices', 'Utilities','RefreshRelatedHelper']) angular.module('RelatedSearchHelper', ['RestServices', 'Utilities','RefreshRelatedHelper'])
.factory('RelatedSearchInit', ['$timeout', 'Alert', 'Rest', 'RefreshRelated', function($timeout, Alert, Rest, RefreshRelated) { .factory('RelatedSearchInit', ['$timeout', 'Alert', 'Rest', 'RefreshRelated', 'Wait',
function($timeout, Alert, Rest, RefreshRelated, Wait) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
@@ -103,21 +104,16 @@ angular.module('RelatedSearchHelper', ['RestServices', 'Utilities','RefreshRelat
scope.search(model); scope.search(model);
} }
scope.startSearch = function(iterator) { scope.startSearch = function(e,iterator) {
//Called on each keydown event for seachValue field. Using a timer // If use clicks enter while on input field, start the search
//to prevent executing a search until user is finished typing. if (e.keyCode == 13) {
if (scope.searchTimer) { scope.search(iterator);
$timeout.cancel(scope.searchTimer);
} }
scope.searchTimer = $timeout(
function() {
scope.search(iterator);
}
, 1000);
} }
scope.search = function(iterator) { scope.search = function(iterator) {
scope[iterator + 'SearchSpin'] = true; //scope[iterator + 'SearchSpin'] = true;
Wait('start');
scope[iterator + 'Loading'] = true; scope[iterator + 'Loading'] = true;
scope[iterator + 'HoldInput'] = true; scope[iterator + 'HoldInput'] = true;

View File

@@ -16,8 +16,8 @@
*/ */
angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
.factory('SearchInit', ['Alert', 'Rest', 'Refresh', '$location', 'GetBasePath', 'Empty', '$timeout', .factory('SearchInit', ['Alert', 'Rest', 'Refresh', '$location', 'GetBasePath', 'Empty', '$timeout', 'Wait',
function(Alert, Rest, Refresh, $location, GetBasePath, Empty, $timeout) { function(Alert, Rest, Refresh, $location, GetBasePath, Empty, $timeout, Wait) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
@@ -190,7 +190,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
// //
// Execute the search // Execute the search
// //
scope[iterator + 'SearchSpin'] = (spin == undefined || spin == true) ? true : false; //scope[iterator + 'SearchSpin'] = (spin == undefined || spin == true) ? true : false;
scope[iterator + 'Loading'] = (load == undefined || load == true) ? true : false; scope[iterator + 'Loading'] = (load == undefined || load == true) ? true : false;
var url = defaultUrl; var url = defaultUrl;
@@ -233,6 +233,15 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
} }
}); });
if (scope.removeResultWarning) {
scope.removeResultWarning();
}
scope.removeResultWarning = scope.$on('resultWarning', function(e, objs, length) {
// Alert the user that the # of objects was greater than 30
var label = (objs == 'inventory') ? 'inventories' : objs.replace(/s$/,'');
Alert('Warning', 'The number of matching ' + label + ' was too large. We limited your search to the first 30.', 'alert-info');
});
if (scope.removePrepareSearch) { if (scope.removePrepareSearch) {
scope.removePrepareSearch(); scope.removePrepareSearch();
} }
@@ -241,6 +250,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
// Start build the search key/value pairs. This will process search widget, if the // Start build the search key/value pairs. This will process search widget, if the
// selected field is an object type (used on activity stream). // selected field is an object type (used on activity stream).
// //
Wait('start');
scope[iterator + 'SearchParams'] = ''; scope[iterator + 'SearchParams'] = '';
var widgets = (list.searchWidgets) ? list.searchWidgets : 1; var widgets = (list.searchWidgets) ? list.searchWidgets : 1;
var modifier; var modifier;
@@ -258,7 +268,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
expected_objects++; expected_objects++;
} }
} }
for (var i=1; i <= widgets; i++) { for (var i=1; i <= widgets; i++) {
var modifier = (i == 1) ? '' : i; var modifier = (i == 1) ? '' : i;
if ( $('#search-widget-container' + modifier) ) { if ( $('#search-widget-container' + modifier) ) {
@@ -270,18 +280,25 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
var objUrl = GetBasePath('base') + objs + '/?name__icontains=' + scope[iterator + 'SearchValue' + modifier]; var objUrl = GetBasePath('base') + objs + '/?name__icontains=' + scope[iterator + 'SearchValue' + modifier];
Rest.setUrl(objUrl); Rest.setUrl(objUrl);
Rest.setHeader({ widget: i }); Rest.setHeader({ widget: i });
Rest.setHeader({ object: objs });
Rest.get() Rest.get()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
var pk=''; var pk='';
for (var j=0; j < data.results.length; j++) { //limit result set to 30
var len = (data.results.length > 30) ? 30 : data.results.length;
for (var j=0; j < len; j++) {
pk += "," + data.results[j].id; pk += "," + data.results[j].id;
} }
pk = pk.replace(/^\,/,''); pk = pk.replace(/^\,/,'');
scope.$emit('foundObject', iterator, page, load, spin, config.headers['widget'], pk); scope.$emit('foundObject', iterator, page, load, spin, config.headers['widget'], pk);
if (data.results.length > 30) {
scope.$emit('resultWarning', config.headers['object'], data.results.length);
}
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
Wait('stop');
ProcessErrors(scope, data, status, null, ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Retrieving list of ' + obj + ' where name contains: ' + scope[iterator + 'SearchValue'] + { hdr: 'Error!', msg: 'Retrieving list of ' + objs + ' where name contains: ' + scope[iterator + 'SearchValue' + modifier] +
' GET returned status: ' + status }); ' GET returned status: ' + status });
}); });
} }
@@ -395,17 +412,11 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
scope.$emit('doSearch', iterator, page, load, spin); scope.$emit('doSearch', iterator, page, load, spin);
}); });
scope.startSearch = function(iterator) { scope.startSearch = function(e,iterator) {
//Called on each keydown event for seachValue field. Using a timer // If use clicks enter while on input field, start the search
//to prevent executing a search until user is finished typing. if (e.keyCode == 13) {
if (scope.searchTimer) { scope.search(iterator);
$timeout.cancel(scope.searchTimer);
} }
scope.searchTimer = $timeout(
function() {
scope.$emit('prepareSearch', iterator);
}
, 1000);
} }
scope.search = function(iterator, page, load, spin) { scope.search = function(iterator, page, load, spin) {

View File

@@ -1500,7 +1500,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
html += "<div class=\"well\">\n"; html += "<div class=\"well\">\n";
html += SearchWidget({ iterator: form.related[itm].iterator, template: form.related[itm], mini: true }); html += SearchWidget({ iterator: form.related[itm].iterator, template: form.related[itm], mini: true });
html += "<div class=\"col-lg-7\">\n"; html += "<div class=\"col-lg-8\">\n";
html += "<div class=\"list-actions\">\n"; html += "<div class=\"list-actions\">\n";
for (var act in form.related[itm].actions) { for (var act in form.related[itm].actions) {
var action = form.related[itm].actions[act]; var action = form.related[itm].actions[act];

View File

@@ -524,26 +524,29 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
html += "\"></select>\n"; html += "\"></select>\n";
html += "<input id=\"search_value_input\" type=\"text\" ng-hide=\"" + iterator + "SelectShow || " + iterator + "InputHide\" " + html += "<input id=\"search_value_input\" type=\"text\" ng-hide=\"" + iterator + "SelectShow || " + iterator + "InputHide\" " +
"class=\"form-control\" ng-model=\"" + iterator + "SearchValue" + modifier + "\" ng-keydown=\"startSearch('" + iterator + "class=\"form-control\" ng-model=\"" + iterator + "SearchValue" + modifier + "\" " +
"')\" aw-placeholder=\"" + iterator + "SearchPlaceholder" + modifier + "\" type=\"text\" ng-disabled=\"" + iterator + "aw-placeholder=\"" + iterator + "SearchPlaceholder" + modifier + "\" type=\"text\" ng-disabled=\"" + iterator +
"InputDisable" + modifier + " || " + iterator + "HoldInput" + modifier + "\">\n"; "InputDisable" + modifier + " || " + iterator + "HoldInput" + modifier + "\" ng-keypress=\"startSearch($event,'" +
iterator + "')\">\n";
// Reset button // Go button
//html += "<div class=\"input-group-btn\">\n"; html += "<div class=\"input-group-btn\">\n";
//html += "<button type=\"button\" class=\"btn btn-default btn-small\" ng-click=\"resetSearch('" + iterator + "', 1)\" " + html += "<button type=\"button\" class=\"btn btn-default btn-small\" ng-click=\"search('" + iterator + "')\" " +
// "aw-tool-tip=\"Reset filter\" data-placement=\"top\" " + "aw-tool-tip=\"Start the search\" data-placement=\"top\" ng-hide=\"" + iterator + "SelectShow || " + iterator +
// "><i class=\"icon-undo\"></i></button>\n"; "InputHide\" ng-disabled=\"" + iterator + "InputDisable" + modifier + " || " + iterator + "HoldInput" + modifier +
//html += "</div><!-- input-group-btn -->\n"; "\">Go!</button>\n";
html += "</div><!-- input-group-btn -->\n";
html += "</div><!-- input-group -->\n"; html += "</div><!-- input-group -->\n";
html += "</div><!-- col-lg-x -->\n"; html += "</div><!-- col-lg-x -->\n";
} }
// Reset button and spinner // Reset button and spinner
html += "<div class=\"col-lg-1 col-md-1 col-sm-1 col-xs-1\">\n"; //html += "<div class=\"col-lg-1 col-md-1 col-sm-1 col-xs-1\">\n";
//html += "<button type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"resetSearch('" + iterator + "')\" " + //html += "<button type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"resetSearch('" + iterator + "')\" " +
// "aw-tool-tip=\"Reset filter\" data-placement=\"top\"><i class=\"icon-undo\"></i></button>\n"; // "aw-tool-tip=\"Reset filter\" data-placement=\"top\"><i class=\"icon-undo\"></i></button>\n";
html += "<i class=\"icon-spinner icon-spin icon-large\" ng-show=\"" + iterator + "SearchSpin == true\"></i>\n"; //html += "<i class=\"icon-spinner icon-spin icon-large\" ng-show=\"" + iterator + "SearchSpin == true\"></i>\n";
html += "</div>\n"; //html += "</div>\n";
return html; return html;

View File

@@ -227,16 +227,16 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
// User supplied searchSize, calc the remaining // User supplied searchSize, calc the remaining
var size = parseInt(options.searchSize.replace(/([A-Z]|[a-z]|\-)/g,'')); var size = parseInt(options.searchSize.replace(/([A-Z]|[a-z]|\-)/g,''));
size = (list.searchWidgets) ? list.searchWidgets * size : size; size = (list.searchWidgets) ? list.searchWidgets * size : size;
html += 'col-lg-' + (12 - size - 1); html += 'col-lg-' + (12 - size);
} }
else if (options.mode == 'summary') { else if (options.mode == 'summary') {
html += 'col-lg-5'; html += 'col-lg-6';
} }
else if (options.id != undefined) { else if (options.id != undefined) {
html += "col-lg-3"; html += "col-lg-4";
} }
else { else {
html += "col-lg-7 col-md-5"; html += "col-lg-8 col-md-6";
} }
html += "\">\n"; html += "\">\n";