diff --git a/awx/ui/static/js/controllers/Projects.js b/awx/ui/static/js/controllers/Projects.js
index ae8b02a3c9..919b7a5b07 100644
--- a/awx/ui/static/js/controllers/Projects.js
+++ b/awx/ui/static/js/controllers/Projects.js
@@ -44,50 +44,55 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
$scope.removePostRefresh();
}
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
- // Cleanup after a delete
- var j, i;
Wait('stop');
- $('#prompt-modal').modal('hide');
-
+
if ($scope.projects) {
- for (i = 0; i < $scope.projects.length; i++) {
- if ($scope.projects[i].status === 'ok') {
+ $scope.projects.forEach(function(project, i) {
+ if (project.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;
+ switch (project.status) {
+ case 'n/a':
+ case 'never updated':
+ $scope.projects[i].statusIcon = 'none';
+ $scope.projects[i].statusTip = 'No SCM updates have run for this project';
+ break;
+ case 'updating':
+ $scope.projects[i].statusIcon = 'running pulsate';
+ $scope.projects[i].statusTip = 'Running! Click for details';
+ break;
+ case 'successful':
+ $scope.projects[i].statusIcon = 'success';
+ $scope.projects[i].statusTip = 'Success! Click for details';
+ break;
+ case 'failed':
+ case 'missing':
+ $scope.projects[i].statusTip = 'Failed. Click for details';
+ $scope.projects[i].statusIcon = 'error';
+ break;
}
- $scope.projects[i].last_updated = ($scope.projects[i].last_updated !== null) ?
- FormatDate(new Date($scope.projects[i].last_updated)) : null;
- for (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;
- if ($scope.projects[i].scm_type === 'Manual') {
+ if (project.summary_fields.last_update && project.summary_fields.last_update.status === 'canceled') {
+ $scope.projects[i].statusTip = 'Canceled. Click for details';
+ }
+
+ $scope.project_scm_type_options.forEach(function(type) {
+ if (type.value === project.scm_type) {
+ $scope.projects[i].scm_type = type.label;
+ if (type.label === 'Manual') {
$scope.projects[i].scm_update_tooltip = 'Manaul projects do not require an SCM update';
$scope.projects[i].scm_schedule_tooltip = 'Manual projects do not require a schedule';
$scope.projects[i].scm_type_class = 'btn-disabled';
+ $scope.projects[i].statusTip = 'Not configured for SCM';
+ $scope.projects[i].statusIcon = 'none';
} else {
$scope.projects[i].scm_update_tooltip = "Start an SCM update";
$scope.projects[i].scm_schedule_tooltip = "Schedule future SCM updates";
$scope.projects[i].scm_type_class = "";
}
- break;
}
- }
- }
+ });
+ });
}
});
@@ -98,7 +103,7 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
var opt;
list.fields.scm_type.searchOptions = $scope.project_scm_type_options;
- list.fields.status.searchOptions = $scope.project_status_options;
+ //list.fields.status.searchOptions = $scope.project_status_options;
if ($routeParams.scm_type && $routeParams.status) {
// Request coming from home page. User wants all errors for an scm_type
@@ -188,40 +193,28 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
$scope.showSCMStatus = function (id) {
// Refresh the project list
- var i, statusCheckRemove = $scope.$on('PostRefresh', function () {
- var project;
- for (i= 0; i < $scope.projects.length; i++) {
- if ($scope.projects[i].id === id) {
- project = $scope.projects[i];
- break;
- }
- }
- if (project.scm_type !== null) {
- if (project.related.current_update) {
- Wait('start');
- ProjectStatus({
- project_id: id,
- last_update: project.related.current_update
- });
- } else if (project.related.last_update) {
- Wait('start');
- ProjectStatus({
- project_id: id,
- last_update: project.related.last_update
- });
- } else {
- Alert('No Updates Available', 'There is no SCM update information available for this project. An update has not yet been ' +
- ' completed. If you have not already done so, start an update for this project.', 'alert-info');
- }
+ var project = Find({ list: $scope.projects, key: 'id', val: id });
+ if (Empty(project.scm_type) || project.scm_type === 'Manual') {
+ Alert('No SCM Configuration', 'The selected project is not configured for SCM. To configure for SCM, edit the project and provide SCM settings, ' +
+ 'and then run an update.', 'alert-info');
+ } else {
+ if (project.related.current_update) {
+ Wait('start');
+ ProjectStatus({
+ project_id: id,
+ last_update: project.related.current_update
+ });
+ } else if (project.related.last_update) {
+ Wait('start');
+ ProjectStatus({
+ project_id: id,
+ last_update: project.related.last_update
+ });
} else {
- Alert('Missing SCM Configuration', 'The selected project is not configured for SCM. You must first edit the project, provide SCM settings, ' +
- 'and then run an update.', 'alert-info');
+ Alert('No Updates Available', 'There is no SCM update information available for this project. An update has not yet been ' +
+ ' completed. If you have not already done so, start an update for this project.', 'alert-info');
}
- statusCheckRemove();
- });
-
- // Refresh the project list so we're looking at the latest data
- $scope.search(list.iterator, null, false, true);
+ }
};
$scope.deleteProject = function (id, name) {
@@ -324,22 +317,28 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
});
};
- $scope.SCMUpdate = function (project_id) {
- var i;
- for (i = 0; i < $scope.projects.length; i++) {
- if ($scope.projects[i].id === project_id) {
- if ($scope.projects[i].scm_type === "Manual" || Empty($scope.projects[i].scm_type)) {
+ $scope.SCMUpdate = function (project_id, event) {
+ try {
+ $(event.target).tooltip('hide');
+ }
+ catch(e) {
+ // ignore
+ }
+ $scope.projects.every(function(project) {
+ if (project.id === project_id) {
+ if (project.scm_type === "Manual" || Empty(project.scm_type)) {
// Do not respond. Button appears greyed out as if it is disabled. Not disabled though, because we need mouse over event
// to work. So user can click, but we just won't do anything.
//Alert('Missing SCM Setup', 'Before running an SCM update, edit the project and provide the SCM access information.', 'alert-info');
- break;
- } else if ($scope.projects[i].status === 'updating') {
+ } else if (project.status === 'updating') {
Alert('Update in Progress', 'The SCM update process is running. Use the Refresh button to monitor the status.', 'alert-info');
} else {
- ProjectUpdate({ scope: $scope, project_id: project_id });
+ ProjectUpdate({ scope: $scope, project_id: project.id });
}
+ return false;
}
- }
+ return true;
+ });
};
$scope.editSchedules = function(id) {
diff --git a/awx/ui/static/js/helpers/Projects.js b/awx/ui/static/js/helpers/Projects.js
index 8b3edaed9a..37ee28038f 100644
--- a/awx/ui/static/js/helpers/Projects.js
+++ b/awx/ui/static/js/helpers/Projects.js
@@ -27,7 +27,6 @@ angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDef
Wait('start');
- // Using jquery dialog for its expandable property
html = "
\n";
$('#projects-modal-container').empty().append(html);
@@ -74,10 +73,13 @@ angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDef
});
},
resizeStop: function () {
- // for some reason, after resizing dialog the form and fields (the content) doesn't expand to 100%
var dialog = $('.ui-dialog[aria-describedby="status-modal-dialog"]'),
+ titleHeight = dialog.find('.ui-dialog-titlebar').outerHeight(),
+ buttonHeight = dialog.find('.ui-dialog-buttonpane').outerHeight(),
content = dialog.find('#status-modal-dialog');
content.width(dialog.width() - 28);
+ content.css({ height: (dialog.height() - titleHeight - buttonHeight - 10) });
+
},
close: function () {
// Destroy on close
@@ -124,10 +126,8 @@ angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDef
})
.error(function (data, status) {
- $('#form-modal').modal("hide");
- ProcessErrors(scope, data, status, form, {
- hdr: 'Error!',
- msg: 'Failed to retrieve status of project: ' + project_id + '. GET status: ' + status
+ ProcessErrors(scope, data, status, form, { hdr: 'Error!',
+ msg: 'Failed to retrieve project: ' + project_id + '. GET returned: ' + status
});
});
};
diff --git a/awx/ui/static/js/lists/CompletedJobs.js b/awx/ui/static/js/lists/CompletedJobs.js
index fd61197ebc..221096b18f 100644
--- a/awx/ui/static/js/lists/CompletedJobs.js
+++ b/awx/ui/static/js/lists/CompletedJobs.js
@@ -40,12 +40,6 @@ angular.module('CompletedJobsDefinition', [])
filter: "date:'MM/dd/yy HH:mm:ss'",
columnClass: "col-md-2 hidden-xs"
},
- next_job_run: {
- label: 'Next Run',
- searchable: false,
- filter: "date:'MM/dd/yy HH:mm:ss'",
- columnClass: "col-md-2 hidden-sm hidden-xs"
- },
type: {
label: 'Type',
ngBind: 'completed_job.type_label',
diff --git a/awx/ui/static/js/lists/Organizations.js b/awx/ui/static/js/lists/Organizations.js
index b34faaea30..872e4b7d91 100644
--- a/awx/ui/static/js/lists/Organizations.js
+++ b/awx/ui/static/js/lists/Organizations.js
@@ -17,7 +17,7 @@ angular.module('OrganizationListDefinition', [])
selectTitle: 'Add Organizations',
editTitle: 'Organizations',
hover: true,
- index: false,
+ index: true,
fields: {
name: {
diff --git a/awx/ui/static/js/lists/Projects.js b/awx/ui/static/js/lists/Projects.js
index 642c85fa78..8e4ad2808a 100644
--- a/awx/ui/static/js/lists/Projects.js
+++ b/awx/ui/static/js/lists/Projects.js
@@ -22,39 +22,35 @@ angular.module('ProjectsListDefinition', [])
hover: true,
fields: {
+ status: {
+ label: 'Status',
+ iconOnly: true,
+ ngClick: 'showSCMStatus(project.id)',
+ awToolTip: '{{ project.statusTip }}',
+ dataPlacement: 'top',
+ icon: "icon-job-{{ project.statusIcon }}",
+ columnClass: "col-md-1 col-sm-2 col-xs-3",
+ nosort: true
+ },
name: {
key: true,
- label: 'Name'
+ label: 'Name',
+ columnClass: "col-md-4 col-sm-3 col-xs-3"
},
- description: {
- label: 'Description',
+ last_updated: {
+ label: 'Last Updated',
+ filter: "date:'MM/dd/yy HH:mm:ss'",
+ columnClass: "col-md-2 hidden-sm hidden-xs",
excludeModal: true,
- columnClass: 'hidden-sm hidden-xs'
+ searchable: false,
+ nosort: true
},
scm_type: {
label: 'Type',
searchType: 'select',
searchOptions: [], // will be set by Options call to projects resource
excludeModal: true,
- columnClass: 'hidden-sm hidden-xs',
- nosort: true
- },
- status: {
- label: 'Status',
- ngClick: 'showSCMStatus(project.id)',
- awToolTip: 'View details of last SCM Update',
- dataPlacement: 'top',
- badgeIcon: "{{ 'fa icon-failures-' + project.badge }}",
- badgePlacement: 'left',
- searchType: 'select',
- searchOptions: [], // will be set by Options call to projects resource
- excludeModal: true
- },
- last_updated: {
- label: 'Last Updated',
- type: 'date',
- excludeModal: true,
- searchable: false
+ columnClass: 'col-md-2 hidden-sm hidden-xs'
}
},
@@ -93,7 +89,7 @@ angular.module('ProjectsListDefinition', [])
fieldActions: {
scm_update: {
- ngClick: 'SCMUpdate(project.id)',
+ ngClick: 'SCMUpdate(project.id, $event)',
awToolTip: "{{ project.scm_update_tooltip }}",
ngClass: "project.scm_type_class",
dataPlacement: 'top'
diff --git a/awx/ui/static/js/lists/QueuedJobs.js b/awx/ui/static/js/lists/QueuedJobs.js
index 39d4394263..7a4c5cd6db 100644
--- a/awx/ui/static/js/lists/QueuedJobs.js
+++ b/awx/ui/static/js/lists/QueuedJobs.js
@@ -39,12 +39,6 @@ angular.module('QueuedJobsDefinition', [])
filter: "date:'MM/dd/yy HH:mm:ss'",
columnClass: 'col-md-2 hidden-xs'
},
- next_job_run: {
- label: 'Next Run',
- searchable: false,
- filter: "date:'MM/dd/yy HH:mm:ss'",
- columnClass: "col-md-2 hidden-sm hidden-xs"
- },
type: {
label: 'Type',
ngBind: 'queued_job.type_label',
diff --git a/awx/ui/static/js/lists/RunningJobs.js b/awx/ui/static/js/lists/RunningJobs.js
index bbc8c43071..811afaefd9 100644
--- a/awx/ui/static/js/lists/RunningJobs.js
+++ b/awx/ui/static/js/lists/RunningJobs.js
@@ -39,12 +39,6 @@ angular.module('RunningJobsDefinition', [])
filter: "date:'MM/dd/yy HH:mm:ss'",
columnClass: "col-md-2 hidden-xs"
},
- next_job_run: {
- label: 'Next Run',
- searchable: false,
- filter: "date:'MM/dd/yy HH:mm:ss'",
- columnClass: "col-md-2 hidden-sm hidden-xs"
- },
type: {
label: 'Type',
ngBind: 'running_job.type_label',
diff --git a/awx/ui/static/js/lists/ScheduledJobs.js b/awx/ui/static/js/lists/ScheduledJobs.js
index c0663213c9..6b0d77b0f2 100644
--- a/awx/ui/static/js/lists/ScheduledJobs.js
+++ b/awx/ui/static/js/lists/ScheduledJobs.js
@@ -15,7 +15,7 @@ angular.module('ScheduledJobsDefinition', [])
iterator: 'scheduled_job',
editTitle: 'Scheduled Jobs',
'class': 'table-condensed',
- index: false,
+ index: true,
hover: true,
well: false,
@@ -24,27 +24,28 @@ angular.module('ScheduledJobsDefinition', [])
label: 'Next Run',
link: false,
searchable: false,
- columnClass: "col-md-2",
+ columnClass: "col-md-2 hidden-xs",
key: true,
desc: true
},
- dtend: {
- label: 'Ends On',
- searchable: false,
- filter: "date:'MM/dd/yy HH:mm:ss'",
- columnClass: "col-md-2 hidden-xs"
- },
- template_name: {
- label: 'Name',
- columnClass: "col-md-4 col-xs-5",
- sourceModel: "template",
- sourceField: "name"
- },
type: {
label: 'Type',
link: false,
columnClass: "col-md-2 hidden-sm hidden-xs"
+ },
+ template_name: {
+ label: 'Name',
+ columnClass: "col-md-3 col-xs-5",
+ sourceModel: "template",
+ sourceField: "name"
}
+ /*,
+ dtend: {
+ label: 'Ends On',
+ searchable: false,
+ filter: "date:'MM/dd/yy HH:mm:ss'",
+ columnClass: "col-md-2 hidden-xs"
+ }*/
},
actions: {
diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less
index dcaa18a9c3..993d848478 100644
--- a/awx/ui/static/less/ansible-ui.less
+++ b/awx/ui/static/less/ansible-ui.less
@@ -979,15 +979,10 @@ input[type="checkbox"].checkbox-no-label {
.job-new,
- .job-canceled {
- color: #778899;
- }
-
- .icon-failures-false,
.license-valid,
.job-success,
.job-successful {
- color: @green;
+ color: @green;
}
.icon-job-pending:before,
@@ -996,14 +991,13 @@ input[type="checkbox"].checkbox-no-label {
.icon-job-successful:before,
.icon-job-waiting:before,
.icon-job-new:before,
- .icon-job-canceled:before,
.icon-job-changed:before {
- content: "\f111";
+ content: "\f111";
}
.icon-job-error:before,
.icon-job-failed:before {
- content: "\f06a";
+ content: "\f06a";
}
.icon-job-pending,
@@ -1012,36 +1006,32 @@ input[type="checkbox"].checkbox-no-label {
.icon-job-successful,
.icon-job-waiting,
.icon-job-new {
- color: @green;
+ color: @green;
}
- .icon-job-canceled {
- color: @grey;
+ .icon-job-running {
+ .pulsate();
}
-
+
.icon-job-changed,
.job-changed {
- color: @warning;
+ color: @warning;
}
.icon-job-error,
.icon-job-failed {
- color: @red;
+ color: @red;
}
- .icon-failures-none,
- .icon-failures-na {
- color: @grey;
+ .icon-job-none,
+ .icon-job-canceled {
+ color: @grey;
+ opacity: 0.45;
}
- .icon-failures-true:before {
- content: "\f06a";
- }
-
- .icon-failures-none:before,
- .icon-failures-na:before,
- .icon-failures-false:before {
- content: "\f111";
+ .icon-job-canceled,
+ .icon-job-none:before {
+ content: "\f10c";
}
.icon-schedule-enabled-true:before {
diff --git a/awx/ui/static/lib/ansible/generator-helpers.js b/awx/ui/static/lib/ansible/generator-helpers.js
index 8c8b3af128..8f9b6e6e51 100644
--- a/awx/ui/static/lib/ansible/generator-helpers.js
+++ b/awx/ui/static/lib/ansible/generator-helpers.js
@@ -358,7 +358,7 @@ angular.module('GeneratorHelpers', [])
}
html += "";
if (field.badgeToolTip) {
@@ -454,6 +454,8 @@ angular.module('GeneratorHelpers', [])
html = DropDown(params);
} else if (field.type === 'badgeCount') {
html = BadgeCount(params);
+ } else if (field.type === 'badgeOnly') {
+ html = Badge(field);
} else {
html += "\n";
html += " | \n";
if (list.index) {
- html += "| # | \n";
+ html += "# | \n";
}
for (fld in list.fields) {
if ((list.fields[fld].searchOnly === undefined || list.fields[fld].searchOnly === false) &&