diff --git a/lib/ui/static/css/ansible-ui.css b/lib/ui/static/css/ansible-ui.css index 8781f49ddc..b2d1f6d1df 100644 --- a/lib/ui/static/css/ansible-ui.css +++ b/lib/ui/static/css/ansible-ui.css @@ -248,4 +248,23 @@ .well { padding-bottom: 0; - } \ No newline at end of file + } + + /* Jobs page */ + .jobs-table tbody tr:hover > td, + .jobs-table tbody tr:hover > th { + background-color: #fff; + } + + .job-error, .job-failure { + color: #da4f49; + } + + .job-new { + color: #778899; + } + + .job-pending, .job-running { + color: #5bb75b; + } + diff --git a/lib/ui/static/js/app.js b/lib/ui/static/js/app.js index 4f84992fcb..272b58a50b 100644 --- a/lib/ui/static/js/app.js +++ b/lib/ui/static/js/app.js @@ -44,10 +44,14 @@ angular.module('ansible', [ 'JobTemplatesListDefinition', 'JobTemplateFormDefinition', 'JobTemplateHelper', - 'ProjectsListDefinition' + 'ProjectsListDefinition', + 'JobsListDefinition' ]) .config(['$routeProvider', function($routeProvider) { $routeProvider. + when('/jobs', + { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobsList }). + when('/job_templates', { templateUrl: urlPrefix + 'partials/job_templates.html', controller: JobTemplatesList }). diff --git a/lib/ui/static/js/controllers/Jobs.js b/lib/ui/static/js/controllers/Jobs.js new file mode 100644 index 0000000000..952bc5897d --- /dev/null +++ b/lib/ui/static/js/controllers/Jobs.js @@ -0,0 +1,36 @@ +/************************************ + * Copyright (c) 2013 AnsibleWorks, Inc. + * + * + * Jobs.js + * + * Controller functions for the Job model. + * + */ + +'use strict'; + +function JobsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobList, + GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, + ClearScope, ProcessErrors, GetBasePath, LookUpInit) +{ + ClearScope('htmlTemplate'); + var list = JobList; + var defaultUrl = GetBasePath('jobs'); + var view = GenerateList; + var base = $location.path().replace(/^\//,'').split('/')[0]; + var scope = view.inject(list, { mode: 'edit' }); + scope.selected = []; + + SearchInit({ scope: scope, set: 'jobs', list: list, url: defaultUrl }); + PaginateInit({ scope: scope, list: list, url: defaultUrl }); + scope.search(list.iterator); + + LoadBreadCrumbs(); + +} + +JobsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', + 'ProcessErrors','GetBasePath', 'LookUpInit' + ]; \ No newline at end of file diff --git a/lib/ui/static/js/helpers/paginate.js b/lib/ui/static/js/helpers/paginate.js index 3fe99e9476..c850a436ad 100644 --- a/lib/ui/static/js/helpers/paginate.js +++ b/lib/ui/static/js/helpers/paginate.js @@ -20,7 +20,7 @@ angular.module('PaginateHelper', ['RefreshHelper']) var scope = params.scope; var list = params.list; - var defaultUrl = params.url; + var url = params.url; var mode = (params.mode) ? params.mode : null; scope[list.iterator + 'Page'] = 0; @@ -45,7 +45,8 @@ angular.module('PaginateHelper', ['RefreshHelper']) scope.changePageSize = function(set, iterator) { // Called when a new page size is selected scope[iterator + 'Page'] = 0; - Refresh({ scope: scope, set: set, iterator: iterator, url: defaultUrl }); + url += (scope[iterator + 'SearchParams']) ? scope[iterator + 'SearchParams'] : ''; + Refresh({ scope: scope, set: set, iterator: iterator, url: url }); } } }]); \ No newline at end of file diff --git a/lib/ui/static/js/helpers/refresh.js b/lib/ui/static/js/helpers/refresh.js index 07510d95f0..8f43c24b98 100644 --- a/lib/ui/static/js/helpers/refresh.js +++ b/lib/ui/static/js/helpers/refresh.js @@ -22,12 +22,9 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities']) var set = params.set; var iterator = params.iterator; var url = params.url; - - url.replace(/page_size\=\d+/,''); //stop repeatedly appending page_size - url += scope[iterator + 'SearchParams']; - + Rest.setUrl(url); - Rest.get({ params: { page_size: scope[iterator + 'PageSize'] }}) + Rest.get() .success( function(data, status, headers, config) { scope[iterator + 'NextUrl'] = data.next; scope[iterator + 'PrevUrl'] = data.previous; diff --git a/lib/ui/static/js/helpers/search.js b/lib/ui/static/js/helpers/search.js index 3a329f12c8..84bc8968bf 100644 --- a/lib/ui/static/js/helpers/search.js +++ b/lib/ui/static/js/helpers/search.js @@ -30,7 +30,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) // Set default values for (fld in list.fields) { if (list.fields[fld].key) { - default_order = fld; + default_order = (list.fields[fld].desc) ? '-' + fld : fld; scope[iterator + 'SearchField'] = fld scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label; break; @@ -78,6 +78,8 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) scope[iterator + 'SearchParams'] = ''; scope[iterator + 'SearchParams'] += (default_order) ? '?order_by=' + escape(default_order) : ''; } + url += scope[iterator + 'SearchParams']; + url += (scope[iterator + 'PageSize']) ? '&page_size=' + scope[iterator + 'PageSize'] : ""; Refresh({ scope: scope, set: set, iterator: iterator, url: url }); } } diff --git a/lib/ui/static/js/lists/Admins.js b/lib/ui/static/js/lists/Admins.js index 896aafa8e8..ed752ca598 100644 --- a/lib/ui/static/js/lists/Admins.js +++ b/lib/ui/static/js/lists/Admins.js @@ -16,6 +16,7 @@ angular.module('AdminListDefinition', []) editTitle: 'Admins', selectInstructions: 'Click on a row to select it. Click the Finished button when done.', base: 'users', + index: true, fields: { username: { diff --git a/lib/ui/static/js/lists/Credentials.js b/lib/ui/static/js/lists/Credentials.js index ff3f227990..8b2cd981d0 100644 --- a/lib/ui/static/js/lists/Credentials.js +++ b/lib/ui/static/js/lists/Credentials.js @@ -15,6 +15,7 @@ angular.module('CredentialsListDefinition', []) selectTitle: 'Add Credentials', editTitle: 'Credentials', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', + index: true, fields: { name: { @@ -44,7 +45,7 @@ angular.module('CredentialsListDefinition', []) mode: 'all', // One of: edit, select, all ngClick: 'addCredential()', basePaths: ['credentials'], // base path must be in list, or action not available - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new credential' } }, @@ -53,13 +54,14 @@ angular.module('CredentialsListDefinition', []) edit: { ngClick: "editCredential(\{\{ credential.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit credential' }, delete: { ngClick: "deleteCredential(\{\{ credential.id \}\},'\{\{ credential.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete credential' } } diff --git a/lib/ui/static/js/lists/Groups.js b/lib/ui/static/js/lists/Groups.js index 22bdfd58a3..d0d5aba1bd 100644 --- a/lib/ui/static/js/lists/Groups.js +++ b/lib/ui/static/js/lists/Groups.js @@ -15,6 +15,7 @@ angular.module('GroupListDefinition', []) selectTitle: 'Add Group', editTitle: 'Groups', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', + index: true, fields: { name: { @@ -31,7 +32,7 @@ angular.module('GroupListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addGroup()', - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new group' } }, @@ -40,13 +41,14 @@ angular.module('GroupListDefinition', []) edit: { ngClick: "editGroup(\{\{ group.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit group' }, delete: { ngClick: "deleteGroup(\{\{ group.id \}\},'\{\{ group.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete group' } } diff --git a/lib/ui/static/js/lists/Hosts.js b/lib/ui/static/js/lists/Hosts.js index 4eff843b70..bff2f3da1d 100644 --- a/lib/ui/static/js/lists/Hosts.js +++ b/lib/ui/static/js/lists/Hosts.js @@ -15,6 +15,7 @@ angular.module('HostListDefinition', []) selectTitle: 'Add Host', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', editTitle: 'Hosts', + index: true, fields: { name: { @@ -31,7 +32,7 @@ angular.module('HostListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addHost()', - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new host' } }, @@ -40,13 +41,14 @@ angular.module('HostListDefinition', []) edit: { ngClick: "editHost(\{\{ host.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit host' }, delete: { ngClick: "deleteHost(\{\{ host.id \}\},'\{\{ host.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete host' } } diff --git a/lib/ui/static/js/lists/Inventories.js b/lib/ui/static/js/lists/Inventories.js index a51d32b4ea..59b8539389 100644 --- a/lib/ui/static/js/lists/Inventories.js +++ b/lib/ui/static/js/lists/Inventories.js @@ -15,6 +15,7 @@ angular.module('InventoriesListDefinition', []) selectTitle: 'Add Inventories', editTitle: 'Inventories', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', + index: true, fields: { name: { @@ -37,7 +38,7 @@ angular.module('InventoriesListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addInventory()', - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new row' } }, @@ -46,13 +47,14 @@ angular.module('InventoriesListDefinition', []) edit: { ngClick: "editInventory(\{\{ inventory.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit' }, delete: { ngClick: "deleteInventory(\{\{ inventory.id \}\},'\{\{ inventory.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete' } } diff --git a/lib/ui/static/js/lists/JobTemplates.js b/lib/ui/static/js/lists/JobTemplates.js index 304a04b611..e92c4b40cc 100644 --- a/lib/ui/static/js/lists/JobTemplates.js +++ b/lib/ui/static/js/lists/JobTemplates.js @@ -15,6 +15,7 @@ angular.module('JobTemplatesListDefinition', []) selectTitle: 'Add Job Template', editTitle: 'Job Templates', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', + index: true, fields: { name: { @@ -31,29 +32,30 @@ angular.module('JobTemplatesListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addJobTemplate()', - class: 'btn btn-success', + class: 'btn-success', basePaths: ['job_templates'], awToolTip: 'Create a new template' } }, fieldActions: { - submit: { - icon: 'icon-play', - mode: 'all', - ngClick: 'submitJob(\{\{ job_template.id \}\})', - class: 'btn btn-mini', - awToolTip: 'Create and run a job using this template' - }, edit: { ngClick: "editJobTemplate(\{\{ job_template.id \}\})", icon: 'icon-edit', - awToolTip: 'Edit template' + awToolTip: 'Edit template', + class: 'btn-mini' + }, + submit: { + icon: 'icon-play', + mode: 'all', + class: 'btn-mini', + ngClick: 'submitJob(\{\{ job_template.id \}\})', + awToolTip: 'Create and run a job using this template' }, delete: { ngClick: "deleteJobTemplate(\{\{ job_template.id \}\},'\{\{ job_template.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-danger btn-mini', awToolTip: 'Delete template' } } diff --git a/lib/ui/static/js/lists/Jobs.js b/lib/ui/static/js/lists/Jobs.js new file mode 100644 index 0000000000..a6967aa0fa --- /dev/null +++ b/lib/ui/static/js/lists/Jobs.js @@ -0,0 +1,79 @@ +/********************************************* + * Copyright (c) 2013 AnsibleWorks, Inc. + * + * Jobs.js + * List view object for Team data model. + * + * + */ +angular.module('JobsListDefinition', []) + .value( + 'JobList', { + + name: 'jobs', + iterator: 'job', + editTitle: 'Jobs', + index: false, + hover: true, + class: 'jobs-table', + + fields: { + id: { + label: 'Job ID', + key: true, + desc: true + }, + created: { + label: 'Creation Date', + link: true + }, + name: { + label: 'Name', + link: true, + }, + status: { + label: 'Status', + icon: 'icon-circle', + class: 'job-\{\{ job.status \}\}' + } + }, + + actions: { + }, + + fieldActions: { + edit: { + ngClick: "editJob(\{\{ job.id \}\})", + icon: 'icon-edit', + class: 'btn-mini', + awToolTip: 'Edit job', + ngDisabled: "job.status != 'new'" + }, + summary: { + title: 'Summary', + icon: 'icon-filter', + ngClick: 'viewSummary()', + class: 'btn-success btn-mini', + awToolTip: 'Job summary', + ngDisabled: "job.status == 'new'" + }, + events: { + title: 'Detail', + icon: 'icon-list-ul', + mode: 'all', + ngClick: 'viewEvents()', + class: 'btn-info btn-mini', + awToolTip: 'Job event detail', + ngDisabled: "job.status == 'new'" + }, + cancel: { + title: 'Cancel', + icon: 'icon-minus-sign', + mode: 'all', + ngClick: 'cancel(\{\{ job.id \}\})', + class: 'btn-danger btn-mini', + awToolTip: 'Cancel job', + ngDisabled: "job.status == 'error' || job.status == 'failed'" + } + } + }); diff --git a/lib/ui/static/js/lists/Organizations.js b/lib/ui/static/js/lists/Organizations.js index 39bf8ffeca..772d426e3e 100644 --- a/lib/ui/static/js/lists/Organizations.js +++ b/lib/ui/static/js/lists/Organizations.js @@ -14,6 +14,7 @@ angular.module('OrganizationListDefinition', []) iterator: 'organization', selectTitle: 'Add Organizations', editTitle: 'Organizations', + index: true, fields: { name: { @@ -30,7 +31,7 @@ angular.module('OrganizationListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addOrganization()', - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new row' } }, @@ -39,13 +40,14 @@ angular.module('OrganizationListDefinition', []) edit: { ngClick: "editOrganization(\{\{ organization.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit' }, delete: { ngClick: "deleteOrganization(\{\{ organization.id \}\},'\{\{ organization.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete' } } diff --git a/lib/ui/static/js/lists/Projects.js b/lib/ui/static/js/lists/Projects.js index e6efb0f168..c757c844fb 100644 --- a/lib/ui/static/js/lists/Projects.js +++ b/lib/ui/static/js/lists/Projects.js @@ -15,6 +15,7 @@ angular.module('ProjectsListDefinition', []) selectTitle: 'Add Project', editTitle: '{{ name }}', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', + index: true, fields: { name: { @@ -31,7 +32,7 @@ angular.module('ProjectsListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addProject()', - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new project' } }, @@ -40,13 +41,14 @@ angular.module('ProjectsListDefinition', []) edit: { ngClick: "editProject(\{\{ project.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit project' }, delete: { ngClick: "deleteProject(\{\{ project.id \}\},'\{\{ project.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete project' } } diff --git a/lib/ui/static/js/lists/Teams.js b/lib/ui/static/js/lists/Teams.js index c998c4d8a9..45c2b97e3e 100644 --- a/lib/ui/static/js/lists/Teams.js +++ b/lib/ui/static/js/lists/Teams.js @@ -15,6 +15,7 @@ angular.module('TeamsListDefinition', []) selectTitle: 'Add Team', editTitle: 'Teams', selectInstructions: 'Click on a row to select it, and click Finished when done. Use the green button to create a new row.', + index: true, fields: { name: { @@ -37,7 +38,7 @@ angular.module('TeamsListDefinition', []) icon: 'icon-plus', mode: 'all', // One of: edit, select, all ngClick: 'addTeam()', - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new team' } }, @@ -46,13 +47,14 @@ angular.module('TeamsListDefinition', []) edit: { ngClick: "editTeam(\{\{ team.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit team' }, delete: { ngClick: "deleteTeam(\{\{ team.id \}\},'\{\{ team.name \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete team' } } diff --git a/lib/ui/static/js/lists/Users.js b/lib/ui/static/js/lists/Users.js index 17169af4d1..76850b078e 100644 --- a/lib/ui/static/js/lists/Users.js +++ b/lib/ui/static/js/lists/Users.js @@ -16,6 +16,7 @@ angular.module('UserListDefinition', []) editTitle: 'Users', selectInstructions: 'Check the Select checkbox next to each user to be added, and click Finished when done. Use the green button to create a new user.', editInstructions: 'Create new users from the Organizations tab. Each Organization has an associated list of Users.', + index: true, fields: { username: { @@ -36,7 +37,7 @@ angular.module('UserListDefinition', []) mode: 'select', // One of: edit, select, all ngClick: 'addUser()', basePaths: ['organizations'], // base path must be in list, or action not available - class: 'btn btn-success', + class: 'btn-success', awToolTip: 'Create a new user' } }, @@ -45,13 +46,14 @@ angular.module('UserListDefinition', []) edit: { ngClick: "editUser(\{\{ user.id \}\})", icon: 'icon-edit', + class: 'btn-mini', awToolTip: 'Edit user' }, delete: { ngClick: "deleteUser(\{\{ user.id \}\},'\{\{ user.username \}\}')", icon: 'icon-remove', - class: 'btn-danger', + class: 'btn-mini btn-danger', awToolTip: 'Delete user' } } diff --git a/lib/ui/static/lib/ansible/generator-helpers.js b/lib/ui/static/lib/ansible/generator-helpers.js index 4ac1d70a8e..335a25deed 100644 --- a/lib/ui/static/lib/ansible/generator-helpers.js +++ b/lib/ui/static/lib/ansible/generator-helpers.js @@ -30,7 +30,9 @@ angular.module('GeneratorHelpers', []) html += "