diff --git a/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js b/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js index 0a3ddcf57d..5e444a0eed 100644 --- a/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js +++ b/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js @@ -19,6 +19,41 @@ export default ['$scope', '$rootScope', '$log', '$stateParams', 'Rest', 'Alert', orgBase = GetBasePath('organizations'), projBase = GetBasePath('projects'); + + function updateStatus() { + if ($scope.projects) { + $scope.projects.forEach(function(project, i) { + $scope.projects[i].statusIcon = GetProjectIcon(project.status); + $scope.projects[i].statusTip = GetProjectToolTip(project.status); + $scope.projects[i].scm_update_tooltip = i18n._("Get latest SCM revision"); + $scope.projects[i].scm_type_class = ""; + + if (project.status === 'failed' && project.summary_fields.last_update && project.summary_fields.last_update.status === 'canceled') { + $scope.projects[i].statusTip = i18n._('Canceled. Click for details'); + } + + if (project.status === 'running' || project.status === 'updating') { + $scope.projects[i].scm_update_tooltip = i18n._("SCM update currently running"); + $scope.projects[i].scm_type_class = "btn-disabled"; + } + + if ($scope.project_scm_type_options) { + $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 = i18n._('Manual projects do not require an SCM update'); + $scope.projects[i].scm_type_class = 'btn-disabled'; + $scope.projects[i].statusTip = 'Not configured for SCM'; + $scope.projects[i].statusIcon = 'none'; + } + } + }); + } + }); + } + } + init(); function init() { @@ -31,35 +66,7 @@ export default ['$scope', '$rootScope', '$log', '$stateParams', 'Rest', 'Alert', $scope.$on('choicesReadyProjectList', function() { Wait('stop'); - if ($scope.projects) { - $scope.projects.forEach(function(project, i) { - $scope.projects[i].statusIcon = GetProjectIcon(project.status); - $scope.projects[i].statusTip = GetProjectToolTip(project.status); - $scope.projects[i].scm_update_tooltip = i18n._("Get latest SCM revision"); - $scope.projects[i].scm_type_class = ""; - - if (project.status === 'failed' && project.summary_fields.last_update && project.summary_fields.last_update.status === 'canceled') { - $scope.projects[i].statusTip = i18n._('Canceled. Click for details'); - } - - if (project.status === 'running' || project.status === 'updating') { - $scope.projects[i].scm_update_tooltip = i18n._("SCM update currently running"); - $scope.projects[i].scm_type_class = "btn-disabled"; - } - - $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 = i18n._('Manual projects do not require an SCM update'); - $scope.projects[i].scm_type_class = 'btn-disabled'; - $scope.projects[i].statusTip = 'Not configured for SCM'; - $scope.projects[i].statusIcon = 'none'; - } - } - }); - }); - } + updateStatus(); }); } @@ -69,9 +76,9 @@ export default ['$scope', '$rootScope', '$log', '$stateParams', 'Rest', 'Alert', }); $scope.$watchCollection(`${$scope.list.name}`, function() { - optionsRequestDataProcessing(); - } - ); + optionsRequestDataProcessing(); + updateStatus(); + }); // iterate over the list and add fields like type label, after the // OPTIONS request returns, or the list is sorted/paginated/searched diff --git a/awx/ui/client/src/projects/factories/get-project-icon.factory.js b/awx/ui/client/src/projects/factories/get-project-icon.factory.js new file mode 100644 index 0000000000..5234041e38 --- /dev/null +++ b/awx/ui/client/src/projects/factories/get-project-icon.factory.js @@ -0,0 +1,30 @@ +export default + function GetProjectIcon() { + return function(status) { + var result = ''; + switch (status) { + case 'n/a': + case 'ok': + case 'never updated': + result = 'none'; + break; + case 'pending': + case 'waiting': + case 'new': + result = 'none'; + break; + case 'updating': + case 'running': + result = 'running'; + break; + case 'successful': + result = 'success'; + break; + case 'failed': + case 'missing': + case 'canceled': + result = 'error'; + } + return result; + }; + } diff --git a/awx/ui/client/src/projects/factories/get-project-tool-tip.factory.js b/awx/ui/client/src/projects/factories/get-project-tool-tip.factory.js new file mode 100644 index 0000000000..834a6c9d99 --- /dev/null +++ b/awx/ui/client/src/projects/factories/get-project-tool-tip.factory.js @@ -0,0 +1,38 @@ +export default + function GetProjectToolTip(i18n) { + return function(status) { + var result = ''; + switch (status) { + case 'n/a': + case 'ok': + case 'never updated': + result = i18n._('No SCM updates have run for this project'); + break; + case 'pending': + case 'waiting': + case 'new': + result = i18n._('Update queued. Click for details'); + break; + case 'updating': + case 'running': + result = i18n._('Update running. Click for details'); + break; + case 'successful': + result = i18n._('Update succeeded. Click for details'); + break; + case 'failed': + result = i18n._('Update failed. Click for details'); + break; + case 'missing': + result = i18n._('Update missing. Click for details'); + break; + case 'canceled': + result = i18n._('Update canceled. Click for details'); + break; + } + return result; + }; + } + +GetProjectToolTip.$inject = + [ 'i18n' ]; diff --git a/awx/ui/client/src/projects/main.js b/awx/ui/client/src/projects/main.js index 6fd8437f38..ebb3aa7bb9 100644 --- a/awx/ui/client/src/projects/main.js +++ b/awx/ui/client/src/projects/main.js @@ -7,7 +7,10 @@ import ProjectsAdd from './add/projects-add.controller'; import ProjectsEdit from './edit/projects-edit.controller'; import ProjectsForm from './projects.form'; +import ProjectList from './projects.list'; import GetProjectPath from './factories/get-project-path.factory'; +import GetProjectIcon from './factories/get-project-icon.factory'; +import GetProjectToolTip from './factories/get-project-tool-tip.factory'; import { projectsSchedulesListRoute, projectsSchedulesAddRoute, @@ -22,7 +25,10 @@ angular.module('Projects', []) .controller('ProjectsAdd', ProjectsAdd) .controller('ProjectsEdit', ProjectsEdit) .factory('GetProjectPath', GetProjectPath) + .factory('GetProjectIcon', GetProjectIcon) + .factory('GetProjectToolTip', GetProjectToolTip) .factory('ProjectsForm', ProjectsForm) + .factory('ProjectList', ProjectList) .config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider', function($stateProvider, stateDefinitionsProvider,$stateExtenderProvider) { let stateDefinitions = stateDefinitionsProvider.$get(); diff --git a/awx/ui/client/src/projects/projects.list.js b/awx/ui/client/src/projects/projects.list.js new file mode 100644 index 0000000000..436ee5c3b6 --- /dev/null +++ b/awx/ui/client/src/projects/projects.list.js @@ -0,0 +1,128 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + + name: 'projects', + iterator: 'project', + basePath: 'projects', + selectTitle: i18n._('Add Project'), + editTitle: i18n._('PROJECTS'), + listTitle: i18n._('PROJECTS'), + selectInstructions: '
Select existing projects by clicking each project or checking the related checkbox. When finished, click the blue ' + + 'Select button, located bottom right.
Create a new project by clicking the button.
', + index: false, + hover: true, + emptyListText: i18n._('No Projects Have Been Created'), + + fields: { + status: { + label: '', + iconOnly: true, + ngClick: 'showSCMStatus(project.id)', + awToolTip: '{{ project.statusTip }}', + dataTipWatch: 'project.statusTip', + dataPlacement: 'right', + icon: "icon-job-{{ project.statusIcon }}", + columnClass: "List-staticColumn--smallStatus", + nosort: true, + excludeModal: true + }, + name: { + key: true, + label: i18n._('Name'), + columnClass: "col-lg-4 col-md-4 col-sm-4 col-xs-7 List-staticColumnAdjacent", + modalColumnClass: 'col-md-8', + awToolTip: '{{project.description | sanitize}}', + dataPlacement: 'top' + }, + scm_type: { + label: i18n._('Type'), + ngBind: 'project.type_label', + excludeModal: true, + columnClass: 'col-lg-2 col-md-2 col-sm-2 hidden-xs' + }, + scm_revision: { + label: i18n._('Revision'), + excludeModal: true, + columnClass: 'List-tableCell col-lg-2 col-md-2 hidden-sm hidden-xs', + type: 'revision' + }, + last_updated: { + label: i18n._('Last Updated'), + filter: "longDate", + columnClass: "col-lg-3 hidden-md hidden-sm hidden-xs", + excludeModal: true + } + }, + + actions: { + refresh: { + mode: 'all', + awToolTip: i18n._("Refresh the page"), + ngClick: "refresh()", + ngShow: "socketStatus === 'error'", + actionClass: 'btn List-buttonDefault', + buttonContent: i18n._('REFRESH') + }, + add: { + mode: 'all', // One of: edit, select, all + ngClick: 'addProject()', + awToolTip: i18n._('Create a new project'), + actionClass: 'at-Button--add', + actionId: 'button-add', + ngShow: "canAdd" + } + }, + + fieldActions: { + + columnClass: 'col-lg-4 col-md-3 col-sm-4 col-xs-5', + edit: { + ngClick: "editProject(project.id)", + awToolTip: i18n._('Edit the project'), + dataPlacement: 'top', + ngShow: "project.summary_fields.user_capabilities.edit" + }, + scm_update: { + ngClick: 'SCMUpdate(project.id, $event)', + awToolTip: "{{ project.scm_update_tooltip }}", + dataTipWatch: "project.scm_update_tooltip", + ngClass: "project.scm_type_class", + dataPlacement: 'top', + ngShow: "project.summary_fields.user_capabilities.start" + }, + copy: { + label: i18n._('Copy'), + ngClick: 'copyProject(project)', + "class": 'btn-danger btn-xs', + awToolTip: i18n._('Copy project'), + dataPlacement: 'top', + ngShow: 'project.summary_fields.user_capabilities.copy' + }, + view: { + ngClick: "editProject(project.id)", + awToolTip: i18n._('View the project'), + dataPlacement: 'top', + ngShow: "!project.summary_fields.user_capabilities.edit", + icon: 'fa-eye', + }, + "delete": { + ngClick: "deleteProject(project.id, project.name)", + awToolTip: i18n._('Delete the project'), + ngShow: "(project.status !== 'updating' && project.status !== 'running' && project.status !== 'pending' && project.status !== 'waiting') && project.summary_fields.user_capabilities.delete", + dataPlacement: 'top' + }, + cancel: { + ngClick: "cancelUpdate(project)", + awToolTip: i18n._('Cancel the SCM update'), + ngShow: "(project.status == 'updating' || project.status == 'running' || project.status == 'pending' || project.status == 'waiting') && project.summary_fields.user_capabilities.start", + dataPlacement: 'top', + ngDisabled: "project.pending_cancellation || project.status == 'canceled'" + } + } + };}]; \ No newline at end of file