diff --git a/awx/ui/static/js/controllers/Projects.js b/awx/ui/static/js/controllers/Projects.js
index b771304eb3..b2cf9e1a99 100644
--- a/awx/ui/static/js/controllers/Projects.js
+++ b/awx/ui/static/js/controllers/Projects.js
@@ -13,7 +13,7 @@
function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList,
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
ClearScope, ProcessErrors, GetBasePath, SelectionInit, ProjectUpdate, ProjectStatus,
- FormatDate, Refresh, Wait, Stream)
+ FormatDate, Refresh, Wait, Stream, GetChoices)
{
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
@@ -41,34 +41,77 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
$('#prompt-modal').off();
if (scope.projects) {
- for (var i=0; i < scope.projects.length; i++) {
- if (scope.projects[i].status == 'ok') {
- scope.projects[i].status = 'n/a';
- }
- switch(scope.projects[i].status) {
- case 'n/a':
- scope.projects[i].badge = 'none';
- break;
- case 'updating':
- case 'successful':
- case 'ok':
- scope.projects[i].badge = 'false';
- break;
- case 'never updated':
- case 'failed':
- case 'missing':
- scope.projects[i].badge = 'true';
- break;
- }
- scope.projects[i].last_updated = (scope.projects[i].last_updated !== null) ?
- FormatDate(new Date(scope.projects[i].last_updated)) : null;
- }
+ for (var i=0; i < scope.projects.length; i++) {
+ if (scope.projects[i].status == 'ok') {
+ scope.projects[i].status = 'n/a';
+ }
+ switch(scope.projects[i].status) {
+ case 'n/a':
+ scope.projects[i].badge = 'none';
+ break;
+ case 'updating':
+ case 'successful':
+ case 'ok':
+ scope.projects[i].badge = 'false';
+ break;
+ case 'never updated':
+ case 'failed':
+ case 'missing':
+ scope.projects[i].badge = 'true';
+ break;
+ }
+ scope.projects[i].last_updated = (scope.projects[i].last_updated !== null) ?
+ FormatDate(new Date(scope.projects[i].last_updated)) : null;
+
+ for (var j=0; j < scope.project_scm_type_options.length; j++) {
+ if (scope.project_scm_type_options[j].value == scope.projects[i].scm_type) {
+ scope.projects[i].scm_type = scope.project_scm_type_options[j].label
+ break;
+ }
+ }
+ }
}
});
- SearchInit({ scope: scope, set: 'projects', list: list, url: defaultUrl });
- PaginateInit({ scope: scope, list: list, url: defaultUrl });
- scope.search(list.iterator);
+ if (scope.removeChoicesReady) {
+ scope.removeChoicesReady();
+ }
+ scope.removeChoicesReady = scope.$on('choicesReady', function() {
+
+ list.fields.scm_type.searchOptions = scope.project_scm_type_options;
+
+ if ($routeParams['scm_type'] && $routeParams['status']) {
+ // Request coming from home page. User wants all errors for an scm_type
+ defaultUrl += '?status=' + $routeParams['status'];
+ }
+
+ SearchInit({ scope: scope, set: 'projects', list: list, url: defaultUrl });
+ PaginateInit({ scope: scope, list: list, url: defaultUrl });
+
+ if ($routeParams['scm_type']) {
+ scope[list.iterator + 'SearchField'] = 'scm_type';
+ scope[list.iterator + 'SelectShow'] = true;
+ scope[list.iterator + 'SearchSelectOpts'] = list.fields['scm_type'].searchOptions;
+ scope[list.iterator + 'SearchFieldLabel'] = list.fields['scm_type'].label.replace(/\
/g,' ');
+ for (var opt in list.fields['scm_type'].searchOptions) {
+ if (list.fields['scm_type'].searchOptions[opt].value == $routeParams['scm_type']) {
+ scope[list.iterator + 'SearchSelectValue'] = list.fields['scm_type'].searchOptions[opt];
+ break;
+ }
+ }
+ }
+ scope.search(list.iterator);
+ });
+
+ // Load the list of options for Kind
+ GetChoices({
+ scope: scope,
+ url: defaultUrl,
+ field: 'scm_type',
+ variable: 'project_scm_type_options',
+ callback: 'choicesReady'
+ });
+
LoadBreadCrumbs();
@@ -232,7 +275,8 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
ProjectsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'GenerateList',
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
- 'GetBasePath', 'SelectionInit', 'ProjectUpdate', 'ProjectStatus', 'FormatDate', 'Refresh', 'Wait', 'Stream'];
+ 'GetBasePath', 'SelectionInit', 'ProjectUpdate', 'ProjectStatus', 'FormatDate', 'Refresh', 'Wait', 'Stream',
+ 'GetChoices' ];
function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm,
diff --git a/awx/ui/static/js/helpers/search.js b/awx/ui/static/js/helpers/search.js
index bcbfb9e423..d5583100ce 100644
--- a/awx/ui/static/js/helpers/search.js
+++ b/awx/ui/static/js/helpers/search.js
@@ -346,7 +346,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
else if ( (list.fields[scope[iterator + 'SearchField' + modifier]].searchType == 'select') &&
(scope[iterator + 'SearchSelectValue' + modifier].value == '' ||
scope[iterator + 'SearchSelectValue' + modifier].value == null) ) {
- scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier];
+ scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier] + '__';
}
else {
scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier] + '__';
diff --git a/awx/ui/static/js/lists/Credentials.js b/awx/ui/static/js/lists/Credentials.js
index fb8194840f..643cc08c74 100644
--- a/awx/ui/static/js/lists/Credentials.js
+++ b/awx/ui/static/js/lists/Credentials.js
@@ -62,6 +62,15 @@ angular.module('CredentialsListDefinition', [])
"class": 'btn-success btn-xs',
awToolTip: 'Create a new credential'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/HomeGroups.js b/awx/ui/static/js/lists/HomeGroups.js
index 80a293fd70..40f7f6824f 100644
--- a/awx/ui/static/js/lists/HomeGroups.js
+++ b/awx/ui/static/js/lists/HomeGroups.js
@@ -110,6 +110,15 @@ angular.module('HomeGroupListDefinition', [])
},
actions: {
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/HomeHosts.js b/awx/ui/static/js/lists/HomeHosts.js
index 0891c97b80..b191241abb 100644
--- a/awx/ui/static/js/lists/HomeHosts.js
+++ b/awx/ui/static/js/lists/HomeHosts.js
@@ -81,6 +81,15 @@ angular.module('HomeHostListDefinition', [])
},
actions: {
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/Inventories.js b/awx/ui/static/js/lists/Inventories.js
index c7ba2b425a..764e407c5f 100644
--- a/awx/ui/static/js/lists/Inventories.js
+++ b/awx/ui/static/js/lists/Inventories.js
@@ -89,6 +89,15 @@ angular.module('InventoriesListDefinition', [])
"class": 'btn-xs btn-success',
awToolTip: 'Create a new inventory'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/InventorySummary.js b/awx/ui/static/js/lists/InventorySummary.js
index ad44e9280b..55b1794644 100644
--- a/awx/ui/static/js/lists/InventorySummary.js
+++ b/awx/ui/static/js/lists/InventorySummary.js
@@ -136,6 +136,15 @@ angular.module('InventorySummaryDefinition', [])
ngClick: "refresh()",
iconSize: 'large'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/JobEvents.js b/awx/ui/static/js/lists/JobEvents.js
index 0e9acaffc0..d3982856ef 100644
--- a/awx/ui/static/js/lists/JobEvents.js
+++ b/awx/ui/static/js/lists/JobEvents.js
@@ -89,11 +89,20 @@ angular.module('JobEventsListDefinition', [])
dataPlacement: 'top',
icon: "icon-refresh",
mode: 'all',
- ngShow: "job_status == 'pending' || job_status == 'waiting' || job_status == 'running'",
+ //ngShow: "job_status == 'pending' || job_status == 'waiting' || job_status == 'running'",
'class': 'btn-xs btn-primary',
awToolTip: "Refresh the page",
ngClick: "refresh()",
iconSize: 'large'
+ },
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
}
},
diff --git a/awx/ui/static/js/lists/JobHosts.js b/awx/ui/static/js/lists/JobHosts.js
index 4cfd73c2b7..e5bec26d84 100644
--- a/awx/ui/static/js/lists/JobHosts.js
+++ b/awx/ui/static/js/lists/JobHosts.js
@@ -128,6 +128,15 @@ angular.module('JobHostDefinition', [])
awToolTip: "Refresh the page",
ngClick: "refresh()",
iconSize: 'large'
+ },
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
}
},
diff --git a/awx/ui/static/js/lists/JobTemplates.js b/awx/ui/static/js/lists/JobTemplates.js
index fde8d1d784..59767ecd21 100644
--- a/awx/ui/static/js/lists/JobTemplates.js
+++ b/awx/ui/static/js/lists/JobTemplates.js
@@ -38,6 +38,15 @@ angular.module('JobTemplatesListDefinition', [])
basePaths: ['job_templates'],
awToolTip: 'Create a new template'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/Jobs.js b/awx/ui/static/js/lists/Jobs.js
index 80ef8b7245..4f456ad0ab 100644
--- a/awx/ui/static/js/lists/Jobs.js
+++ b/awx/ui/static/js/lists/Jobs.js
@@ -83,6 +83,15 @@ angular.module('JobsListDefinition', [])
awToolTip: "Refresh the page",
ngClick: "refresh()",
iconSize: 'large'
+ },
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
}
},
diff --git a/awx/ui/static/js/lists/Permissions.js b/awx/ui/static/js/lists/Permissions.js
index 92296fc367..ddff5c037d 100644
--- a/awx/ui/static/js/lists/Permissions.js
+++ b/awx/ui/static/js/lists/Permissions.js
@@ -51,6 +51,15 @@ angular.module('PermissionListDefinition', [])
awToolTip: 'Add a new permission',
ngShow: 'PermissionAddAllowed'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/Projects.js b/awx/ui/static/js/lists/Projects.js
index 9abc726e86..6a660e04a9 100644
--- a/awx/ui/static/js/lists/Projects.js
+++ b/awx/ui/static/js/lists/Projects.js
@@ -29,6 +29,13 @@ angular.module('ProjectsListDefinition', [])
columnClass: 'hidden-sm hidden-xs',
excludeModal: true
},
+ scm_type: {
+ label: 'SCM Type',
+ searchType: 'select',
+ searchOptions: [], // will be set by Options call to projects resource
+ excludeModal: true,
+ nosort: true
+ },
status: {
label: 'Update Status',
ngClick: 'showSCMStatus(\{\{ project.id \}\})',
@@ -72,7 +79,7 @@ angular.module('ProjectsListDefinition', [])
dataTitle: 'Project Status',
iconSize: 'large'
},
- refresh: {
+ refresh: {
dataPlacement: 'top',
icon: "icon-refresh",
mode: 'all',
@@ -81,6 +88,15 @@ angular.module('ProjectsListDefinition', [])
ngClick: "refresh()",
iconSize: 'large'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/Teams.js b/awx/ui/static/js/lists/Teams.js
index 3e3d871fac..82e3b04c64 100644
--- a/awx/ui/static/js/lists/Teams.js
+++ b/awx/ui/static/js/lists/Teams.js
@@ -43,6 +43,15 @@ angular.module('TeamsListDefinition', [])
"class": 'btn-xs btn-success',
awToolTip: 'Create a new team'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/lists/Users.js b/awx/ui/static/js/lists/Users.js
index 46b10403e1..76e7ba1be9 100644
--- a/awx/ui/static/js/lists/Users.js
+++ b/awx/ui/static/js/lists/Users.js
@@ -43,6 +43,15 @@ angular.module('UserListDefinition', [])
"class": 'btn-success btn-xs',
awToolTip: 'Create a new user'
},
+ reset: {
+ dataPlacement: 'top',
+ icon: "icon-undo",
+ mode: 'all',
+ 'class': 'btn-xs btn-primary',
+ awToolTip: "Reset the search filter",
+ ngClick: "resetSearch()",
+ iconSize: 'large'
+ },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
diff --git a/awx/ui/static/js/widgets/ObjectCount.js b/awx/ui/static/js/widgets/ObjectCount.js
index 3aa48c2676..e06411c772 100644
--- a/awx/ui/static/js/widgets/ObjectCount.js
+++ b/awx/ui/static/js/widgets/ObjectCount.js
@@ -32,50 +32,7 @@ angular.module('ObjectCountWidget', ['RestServices', 'Utilities'])
html += "\n";
html += "\n";
html += "