From f891c30ebbbed05fbedfe05ef2086b3a1caa597d Mon Sep 17 00:00:00 2001 From: Chris Houseknecht Date: Fri, 7 Feb 2014 15:33:07 -0500 Subject: [PATCH 01/27] Ran all controller files through jsbeautifier.org and applied jsHint. --- awx/ui/static/js/controllers/Admins.js | 50 +- .../static/js/controllers/Authentication.js | 250 +-- awx/ui/static/js/controllers/Credentials.js | 967 ++++++------ awx/ui/static/js/controllers/Home.js | 445 +++--- awx/ui/static/js/controllers/Inventories.js | 866 +++++----- awx/ui/static/js/controllers/JobEvents.js | 558 +++---- awx/ui/static/js/controllers/JobHosts.js | 228 +-- awx/ui/static/js/controllers/JobTemplates.js | 1399 +++++++++-------- awx/ui/static/js/controllers/Jobs.js | 290 ++-- awx/ui/static/js/controllers/Organizations.js | 531 ++++--- awx/ui/static/js/controllers/Permissions.js | 535 ++++--- awx/ui/static/js/controllers/Projects.js | 1139 +++++++------- awx/ui/static/js/controllers/Teams.js | 654 ++++---- awx/ui/static/js/controllers/Users.js | 803 +++++----- 14 files changed, 4659 insertions(+), 4056 deletions(-) diff --git a/awx/ui/static/js/controllers/Admins.js b/awx/ui/static/js/controllers/Admins.js index 223551f601..798db73940 100644 --- a/awx/ui/static/js/controllers/Admins.js +++ b/awx/ui/static/js/controllers/Admins.js @@ -3,33 +3,49 @@ * * * Admins.js - * + * * Controller functions for ading Admins to an Organization. * */ 'use strict'; -function AdminsList ($scope, $rootScope, $location, $log, $routeParams, Rest, - Alert, AdminList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, - ReturnToCaller,GetBasePath, SelectionInit) -{ - var list = AdminList; - var defaultUrl = GetBasePath('organizations') + $routeParams.organization_id + '/users/' ; - var view = GenerateList; - var mode = 'select'; - var scope = view.inject(AdminList, { mode: mode }); // Inject our view +function AdminsList($scope, $rootScope, $location, $log, $routeParams, Rest, + Alert, AdminList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, + ReturnToCaller, GetBasePath, SelectionInit) { - var url = GetBasePath('organizations') + $routeParams.organization_id + '/admins/'; - SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); + var list = AdminList, + defaultUrl = GetBasePath('organizations') + $routeParams.organization_id + '/users/', + view = GenerateList, + mode = 'select', + scope = view.inject(AdminList, { mode: mode }), + url = GetBasePath('organizations') + $routeParams.organization_id + '/admins/'; + + SelectionInit({ + scope: scope, + list: list, + url: url, + returnToCaller: 1 + }); + + SearchInit({ + scope: scope, + set: 'admins', + list: list, + url: defaultUrl + }); + + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); - SearchInit({ scope: scope, set: 'admins', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); scope.search(list.iterator); LoadBreadCrumbs(); } -AdminsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'AdminList', 'GenerateList', - 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'GetBasePath', 'SelectionInit']; - +AdminsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'AdminList', 'GenerateList', + 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'GetBasePath', 'SelectionInit' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Authentication.js b/awx/ui/static/js/controllers/Authentication.js index ca102a4fbf..2ee4bd7f6b 100644 --- a/awx/ui/static/js/controllers/Authentication.js +++ b/awx/ui/static/js/controllers/Authentication.js @@ -8,139 +8,145 @@ * */ + /* globals console:false */ + 'use strict'; -function Authenticate($cookieStore, $window, $scope, $rootScope, $location, Authorization, ToggleClass, Alert, Wait, - Timer, Empty) -{ - var setLoginFocus = function() { - $('#login-username').focus(); - }; +function Authenticate($cookieStore, $window, $scope, $rootScope, $location, Authorization, ToggleClass, Alert, Wait, + Timer, Empty) { + + var setLoginFocus, lastPath, sessionExpired, scope; - var sessionExpired = (Empty($rootScope.sessionExpired)) ? $cookieStore.get('sessionExpired') : $rootScope.sessionExpired; - - var lastPath = function() { - return (Empty($rootScope.lastPath)) ? $cookieStore.get('lastPath') : $rootScope.lastPath; - } + setLoginFocus = function () { + $('#login-username').focus(); + }; - if ($AnsibleConfig.debug_mode && console) { - console.log('User session expired: ' + sessionExpired); - console.log('Last URL: ' + lastPath()); - } - - // Hide any lingering modal dialogs - $('.modal[aria-hidden=false]').each( function() { - if ($(this).attr('id') !== 'login-modal') { - $(this).modal('hide'); - } - }); + sessionExpired = (Empty($rootScope.sessionExpired)) ? $cookieStore.get('sessionExpired') : $rootScope.sessionExpired; - // Just in case, make sure the wait widget is not active - Wait('stop'); - - // Display the login dialog - $('#login-modal').modal({ show: true, keyboard: false, backdrop: 'static' }); - - // Set focus to username field - $('#login-modal').on('shown.bs.modal', function() { - setLoginFocus(); - }); + lastPath = function () { + return (Empty($rootScope.lastPath)) ? $cookieStore.get('lastPath') : $rootScope.lastPath; + }; - var scope = angular.element(document.getElementById('login-modal')).scope(); - - // Reset the login form - scope['login_username'] = null; - scope['login_password'] = null; - scope['loginForm']['login_username'].$setPristine(); - scope['loginForm']['login_password'].$setPristine(); + if ($AnsibleConfig.debug_mode && console) { + console.log('User session expired: ' + sessionExpired); + console.log('Last URL: ' + lastPath()); + } - if ($location.path() == '/logout') { - //if logout request, clear AuthToken and user session data - Authorization.logout(); - } - - $rootScope.userLoggedIn = false; //hide the logout link. if you got here, you're logged out. - $cookieStore.put('userLoggedIn', false); //gets set back to true by Authorization.setToken(). + // Hide any lingering modal dialogs + $('.modal[aria-hidden=false]').each(function () { + if ($(this).attr('id') !== 'login-modal') { + $(this).modal('hide'); + } + }); - $('#login-password').bind('keypress', function(e) { - var code = (e.keyCode ? e.keyCode : e.which); - if (code == 13) { - $('#login-button').click(); - } - }); - - scope.reset = function() { - $('#login-form input').each( function(index) { $(this).val(''); }); - }; + // Just in case, make sure the wait widget is not active + Wait('stop'); - // Call the API to get an auth token - scope.systemLogin = function(username, password) { - $('.api-error').empty(); - var token; - if (username == null || username == undefined || username == '' || - password == null || password == undefined || password == '' ) { - Alert('Error!', 'Please provide a username and password before attempting to login.', 'alert-danger', setLoginFocus); - } - else { - Wait('start'); - Authorization.retrieveToken(username, password) - .success( function(data, status, headers, config) { - $('#login-modal').modal('hide'); - token = data.token; - Authorization.setToken(data.token, data.expires); - $rootScope.sessionTimer = Timer.init(); - // Get all the profile/access info regarding the logged in user - Authorization.getUser() - .success(function(data, status, headers, config) { - Authorization.setUserInfo(data); - $rootScope['user_is_superuser'] = data.results[0].is_superuser; - Authorization.getLicense() - .success(function(data, status, headers, config) { - Authorization.setLicense(data['license_info']); - if (lastPath()) { - // Go back to most recent navigation path - $location.path(lastPath()); - } - else { - $location.url('/home?login=true'); - } - }) - .error(function(data, status, headers, config) { - Wait('stop'); - Alert('Error', 'Failed to access user information. GET returned status: ' + status, 'alert-danger', setLoginFocus); - }); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - Alert('Error', 'Failed to access license information. GET returned status: ' + status, 'alert-danger', setLoginFocus); - }); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - if ( data.non_field_errors && data.non_field_errors.length == 0 ) { - // show field specific errors returned by the API - for (var key in data) { - scope[key + 'Error'] = data[key][0]; + // Display the login dialog + $('#login-modal').modal({ + show: true, + keyboard: false, + backdrop: 'static' + }); + + // Set focus to username field + $('#login-modal').on('shown.bs.modal', function () { + setLoginFocus(); + }); + + scope = angular.element(document.getElementById('login-modal')).scope(); + + // Reset the login form + scope.login_username = null; + scope.login_password = null; + scope.loginForm.login_username.$setPristine(); + scope.loginForm.login_password.$setPristine(); + + if ($location.path() === '/logout') { + //if logout request, clear AuthToken and user session data + Authorization.logout(); + } + + $rootScope.userLoggedIn = false; //hide the logout link. if you got here, you're logged out. + $cookieStore.put('userLoggedIn', false); //gets set back to true by Authorization.setToken(). + + $('#login-password').bind('keypress', function (e) { + var code = (e.keyCode ? e.keyCode : e.which); + if (code === 13) { + $('#login-button').click(); + } + }); + + scope.reset = function () { + $('#login-form input').each(function () { + $(this).val(''); + }); + }; + + // Call the API to get an auth token + scope.systemLogin = function (username, password) { + $('.api-error').empty(); + var token; + if (Empty(username) || Empty(password)) { + Alert('Error!', 'Please provide a username and password before attempting to login.', 'alert-danger', setLoginFocus); + } else { + Wait('start'); + Authorization.retrieveToken(username, password) + .success(function (data, status) { + $('#login-modal').modal('hide'); + token = data.token; + Authorization.setToken(data.token, data.expires); + $rootScope.sessionTimer = Timer.init(); + // Get all the profile/access info regarding the logged in user + Authorization.getUser() + .success(function (data) { + Authorization.setUserInfo(data); + $rootScope.user_is_superuser = data.results[0].is_superuser; + Authorization.getLicense() + .success(function (data) { + Authorization.setLicense(data.license_info); + if (lastPath()) { + // Go back to most recent navigation path + $location.path(lastPath()); + } else { + $location.url('/home?login=true'); + } + }) + .error(function () { + Wait('stop'); + Alert('Error', 'Failed to access user information. GET returned status: ' + status, 'alert-danger', setLoginFocus); + }); + }) + .error(function (data, status) { + Wait('stop'); + Alert('Error', 'Failed to access license information. GET returned status: ' + status, 'alert-danger', setLoginFocus); + }); + }) + .error(function (data, status) { + var hdr, msg, key; + Wait('stop'); + if (data.non_field_errors && data.non_field_errors.length === 0) { + // show field specific errors returned by the API + for (key in data) { + scope[key + 'Error'] = data[key][0]; + } + } else { + if (data.non_field_errors && data.non_field_errors.length > 0) { + hdr = 'Error'; + msg = data.non_field_errors[0]; + } else { + hdr = 'Error'; + msg = 'The login attempt failed with a status of: ' + status; + } + scope.reset(); + Alert(hdr, msg, 'alert-danger', setLoginFocus); } - } - else { - var hdr, msg; - if ( data.non_field_errors && data.non_field_errors.length > 0 ) { - hdr = 'Error'; - msg = data.non_field_errors[0]; - } - else { - hdr = 'Error'; - msg = 'The login attempt failed with a status of: ' + status; - } - scope.reset(); - Alert(hdr, msg, 'alert-danger', setLoginFocus); - } - }); - } - } + }); + } + }; } Authenticate.$inject = ['$cookieStore', '$window', '$scope', '$rootScope', '$location', 'Authorization', 'ToggleClass', 'Alert', 'Wait', - 'Timer', 'Empty']; + 'Timer', 'Empty' +]; diff --git a/awx/ui/static/js/controllers/Credentials.js b/awx/ui/static/js/controllers/Credentials.js index a8bbedc751..ef4a636035 100644 --- a/awx/ui/static/js/controllers/Credentials.js +++ b/awx/ui/static/js/controllers/Credentials.js @@ -3,72 +3,80 @@ * * * Credentials.js - * + * * Controller functions for the Credential model. * */ - 'use strict'; -function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList, + GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, + ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices, Wait, Stream) { + + ClearScope('htmlTemplate'); + Wait('start'); - var list = CredentialList; - var defaultUrl = GetBasePath('credentials'); - var view = GenerateList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var mode = (base == 'credentials') ? 'edit' : 'select'; // if base path 'credentials', we're here to add/edit - var scope = view.inject(list, { mode: mode }); // Inject our view + var list = CredentialList, + defaultUrl = GetBasePath('credentials'), + view = GenerateList, + base = $location.path().replace(/^\//, '').split('/')[0], + mode = (base === 'credentials') ? 'edit' : 'select', // if base path 'credentials', we're here to add/edit + scope = view.inject(list, { mode: mode }), + url; + scope.selected = []; scope.credentialLoading = true; - - var url = GetBasePath(base); - url += (base == 'users') ? $routeParams.user_id + '/credentials/' : $routeParams.team_id + '/credentials/'; - SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); - + url = GetBasePath(base) + ( (base === 'users') ? $routeParams.user_id + '/credentials/' : $routeParams.team_id + '/credentials/' ); + + SelectionInit({ + scope: scope, + list: list, + url: url, + returnToCaller: 1 + }); + if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Cleanup after a delete + var i, j; + Wait('stop'); $('#prompt-modal').off(); list.fields.kind.searchOptions = scope.credential_kind_options; - + // Translate the kind value - for(var i=0; i < scope.credentials.length; i++) { - /* - if (scope.credentials[i].summary_fields.user) { - scope.credentials[i].user_username = scope.credentials[i].summary_fields.user.username; - } - if (scope.credentials[i].summary_fields.team) { - scope.credentials[i].team_name = scope.credentials[i].summary_fields.team.name; - } - */ - for (var j=0; j < scope.credential_kind_options.length; j++) { - if (scope.credential_kind_options[j].value == scope.credentials[i].kind) { - scope.credentials[i].kind = scope.credential_kind_options[j].label - break; - } - } + for (i = 0; i < scope.credentials.length; i++) { + for (j = 0; j < scope.credential_kind_options.length; j++) { + if (scope.credential_kind_options[j].value === scope.credentials[i].kind) { + scope.credentials[i].kind = scope.credential_kind_options[j].label; + break; + } + } } - }); + }); if (scope.removeChoicesReady) { - scope.removeChoicesReady(); + scope.removeChoicesReady(); } - scope.removeChoicesReady = scope.$on('choicesReadyCredential', function() { - SearchInit({ scope: scope, set: 'credentials', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); - scope.search(list.iterator); + scope.removeChoicesReady = scope.$on('choicesReadyCredential', function () { + SearchInit({ + scope: scope, + set: 'credentials', + list: list, + url: defaultUrl }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); + scope.search(list.iterator); + }); // Load the list of options for Kind GetChoices({ @@ -77,434 +85,499 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res field: 'kind', variable: 'credential_kind_options', callback: 'choicesReadyCredential' - }); + }); LoadBreadCrumbs(); - scope.showActivity = function() { Stream({ scope: scope }); } - - scope.addCredential = function() { - $location.path($location.path() + '/add'); - } + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - scope.editCredential = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deleteCredential = function(id, name) { - - var action = function() { - $('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); }); - $('#prompt-modal').modal('hide'); - var url = defaultUrl + id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + scope.addCredential = function () { + $location.path($location.path() + '/add'); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action + scope.editCredential = function (id) { + $location.path($location.path() + '/' + id); + }; + + scope.deleteCredential = function (id, name) { + + var action = function () { + $('#prompt-modal').on('hidden.bs.modal', function () { + Wait('start'); + }); + $('#prompt-modal').modal('hide'); + var url = defaultUrl + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function (data, status, headers, config) { + scope.search(list.iterator); + }) + .error(function (data, status, headers, config) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status + }); }); - } + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + }; } -CredentialsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'CredentialList', 'GenerateList', - 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'SelectionInit', 'GetChoices', 'Wait', 'Stream' ]; +CredentialsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'CredentialList', 'GenerateList', + 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', + 'GetBasePath', 'SelectionInit', 'GetChoices', 'Wait', 'Stream' +]; -function CredentialsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GenerateList, SearchInit, PaginateInit, LookUpInit, UserList, TeamList, GetBasePath, - GetChoices, Empty, KindChange, OwnerChange, FormSave, DebugForm) -{ - ClearScope('tree-form'); - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, + GenerateList, SearchInit, PaginateInit, LookUpInit, UserList, TeamList, GetBasePath, + GetChoices, Empty, KindChange, OwnerChange, FormSave, DebugForm) { + ClearScope('tree-form'); + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - // Inject dynamic view - var defaultUrl = GetBasePath('credentials'); - var form = CredentialForm; - var generator = GenerateForm; - var scope = generator.inject(form, {mode: 'add', related: false}); - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath('credentials'); - generator.reset(); - LoadBreadCrumbs(); + // Inject dynamic view + var form = CredentialForm, + generator = GenerateForm, + scope = generator.inject(form, { mode: 'add', related: false }), + base = $location.path().replace(/^\//, '').split('/')[0], + defaultUrl = GetBasePath('credentials'), + url; + + generator.reset(); + LoadBreadCrumbs(); - // Load the list of options for Kind - GetChoices({ + // Load the list of options for Kind + GetChoices({ scope: scope, url: defaultUrl, field: 'kind', variable: 'credential_kind_options' + }); + + LookUpInit({ + scope: scope, + form: form, + current_item: (!Empty($routeParams.user_id)) ? $routeParams.user_id : null, + list: UserList, + field: 'user' + }); + + LookUpInit({ + scope: scope, + form: form, + current_item: (!Empty($routeParams.team_id)) ? $routeParams.team_id : null, + list: TeamList, + field: 'team' + }); + + if (!Empty($routeParams.user_id)) { + // Get the username based on incoming route + scope.owner = 'user'; + scope.user = $routeParams.user_id; + OwnerChange({ + scope: scope + }); + url = GetBasePath('users') + $routeParams.user_id + '/'; + Rest.setUrl(url); + Rest.get() + .success(function (data, status, headers, config) { + scope.user_username = data.username; + }) + .error(function (data, status, headers, config) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve user. GET status: ' + status + }); + }); + } else if (!Empty($routeParams.team_id)) { + // Get the username based on incoming route + scope.owner = 'team'; + scope.team = $routeParams.team_id; + OwnerChange({ + scope: scope + }); + url = GetBasePath('teams') + $routeParams.team_id + '/'; + Rest.setUrl(url); + Rest.get() + .success(function (data, status, headers, config) { + scope.team_name = data.name; + }) + .error(function (data, status, headers, config) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve team. GET status: ' + status + }); + }); + } else { + // default type of owner to a user + scope.owner = 'user'; + OwnerChange({ + scope: scope + }); + } + + // Handle Kind change + scope.kindChange = function () { + KindChange({ + scope: scope, + form: form, + reset: true + }); + }; + + // Save + scope.formSave = function () { + generator.clearApiErrors(); + FormSave({ + scope: scope, + mode: 'add' + }); + }; + + // Handle Owner change + scope.ownerChange = function () { + OwnerChange({ + scope: scope + }); + }; + + // Reset defaults + scope.formReset = function () { + generator.reset(); + //DebugForm({ form: CredentialForm, scope: scope }); + }; + + // Password change + scope.clearPWConfirm = function (fld) { + // If password value changes, make sure password_confirm must be re-entered + scope[fld] = ''; + scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); + }; + + // Respond to 'Ask at runtime?' checkbox + scope.ask = function (fld, associated) { + if (scope[fld + '_ask']) { + scope[fld] = 'ASK'; + scope[associated] = ''; + scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); + } else { + scope[fld] = ''; + scope[associated] = ''; + scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); + } + }; + + // Click clear button + scope.clear = function (fld, associated) { + scope[fld] = ''; + scope[associated] = ''; + scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); + scope[form.name + '_form'].$setDirty(); + }; + +} + +CredentialsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'CredentialForm', 'GenerateForm', + 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', + 'SearchInit', 'PaginateInit', 'LookUpInit', 'UserList', 'TeamList', 'GetBasePath', 'GetChoices', 'Empty', + 'KindChange', 'OwnerChange', 'FormSave', 'DebugForm' +]; + + +function CredentialsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, + RelatedPaginateInit, ReturnToCaller, ClearScope, Prompt, GetBasePath, GetChoices, + KindChange, UserList, TeamList, LookUpInit, Empty, OwnerChange, FormSave, Stream, + Wait +) { + + ClearScope('htmlTemplate'); + + var defaultUrl = GetBasePath('credentials'), + generator = GenerateForm, + form = CredentialForm, + scope = generator.inject(form, { mode: 'edit', related: true }), + base = $location.path().replace(/^\//, '').split('/')[0], + master = {}, + id = $routeParams.credential_id; + + generator.reset(); + scope.id = id; + + function setAskCheckboxes() { + var fld, i; + for (fld in form.fields) { + if (form.fields[fld].type === 'password' && scope[fld] === 'ASK') { + // turn on 'ask' checkbox for password fields with value of 'ASK' + $("#" + fld + "-clear-btn").attr("disabled", "disabled"); + scope[fld + '_ask'] = true; + } else { + scope[fld + '_ask'] = false; + $("#" + fld + "-clear-btn").removeAttr("disabled"); + } + master[fld + '_ask'] = scope[fld + '_ask']; + } + + // Set kind field to the correct option + for (i = 0; i < scope.credential_kind_options.length; i++) { + if (scope.kind === scope.credential_kind_options[i].value) { + scope.kind = scope.credential_kind_options[i]; + break; + } + } + } + + if (scope.removeCredentialLoaded) { + scope.removeCredentialLoaded(); + } + scope.removeCredentialLoaded = scope.$on('credentialLoaded', function () { + LookUpInit({ + scope: scope, + form: form, + current_item: (!Empty($scope.user_id)) ? scope.user_id : null, + list: UserList, + field: 'user' }); - LookUpInit({ - scope: scope, - form: form, - current_item: (!Empty($routeParams.user_id)) ? $routeParams.user_id : null, - list: UserList, - field: 'user' - }); + LookUpInit({ + scope: scope, + form: form, + current_item: (!Empty($scope.team_id)) ? scope.team_id : null, + list: TeamList, + field: 'team' + }); - LookUpInit({ - scope: scope, - form: form, - current_item: (!Empty($routeParams.team_id)) ? $routeParams.team_id : null, - list: TeamList, - field: 'team' - }); + setAskCheckboxes(); + KindChange({ + scope: scope, + form: form, + reset: false + }); + OwnerChange({ + scope: scope + }); + Wait('stop'); + }); - if (!Empty($routeParams.user_id)) { - // Get the username based on incoming route - scope['owner'] = 'user'; - scope['user'] = $routeParams.user_id; - OwnerChange({ scope: scope }); - var url = GetBasePath('users') + $routeParams.user_id + '/'; - Rest.setUrl(url); - Rest.get() - .success( function(data, status, headers, config) { - scope['user_username'] = data.username; - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to retrieve user. GET status: ' + status }); - }); - } - else if (!Empty($routeParams.team_id)) { - // Get the username based on incoming route - scope['owner'] = 'team'; - scope['team'] = $routeParams.team_id; - OwnerChange({ scope: scope }); - var url = GetBasePath('teams') + $routeParams.team_id + '/'; - Rest.setUrl(url); - Rest.get() - .success( function(data, status, headers, config) { - scope['team_name'] = data.name; - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to retrieve team. GET status: ' + status }); - }); - } - else { - // default type of owner to a user - scope['owner'] = 'user'; - OwnerChange({ scope: scope }); - } - - // Handle Kind change - scope.kindChange = function () { - KindChange({ scope: scope, form: form, reset: true }); - } - - // Save - scope.formSave = function() { generator.clearApiErrors(); FormSave({ scope: scope, mode: 'add' }) }; - - // Handle Owner change - scope.ownerChange = function() { - OwnerChange({ scope: scope }); - } - - // Reset defaults - scope.formReset = function() { - generator.reset(); - //DebugForm({ form: CredentialForm, scope: scope }); - }; - - // Password change - scope.clearPWConfirm = function(fld) { - // If password value changes, make sure password_confirm must be re-entered - scope[fld] = ''; - scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); - } - - // Respond to 'Ask at runtime?' checkbox - scope.ask = function(fld, associated) { - if (scope[fld + '_ask']) { - scope[fld] = 'ASK'; - scope[associated] = ''; - scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); - } - else { - scope[fld] = ''; - scope[associated] = ''; - scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); - } - } - - // Click clear button - scope.clear = function(fld, associated) { - scope[fld] = ''; - scope[associated] = ''; - scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); - scope[form.name + '_form'].$setDirty(); - } - -} - -CredentialsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'CredentialForm', 'GenerateForm', - 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', - 'SearchInit', 'PaginateInit', 'LookUpInit', 'UserList', 'TeamList', 'GetBasePath', 'GetChoices', 'Empty', - 'KindChange', 'OwnerChange', 'FormSave', 'DebugForm']; - - -function CredentialsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, ReturnToCaller, ClearScope, Prompt, GetBasePath, GetChoices, - KindChange, UserList, TeamList, LookUpInit, Empty, OwnerChange, FormSave, Stream, - Wait - ) -{ - ClearScope('tree-form'); - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - - var defaultUrl=GetBasePath('credentials'); - var generator = GenerateForm; - var form = CredentialForm; - var scope = generator.inject(form, {mode: 'edit', related: true}); - generator.reset(); - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath('credentials'); - - var master = {}; - var id = $routeParams.credential_id; - scope['id'] = id; - - var relatedSets = {}; - - function setAskCheckboxes() { - for (var fld in form.fields) { - if (form.fields[fld].type == 'password' && scope[fld] == 'ASK') { - // turn on 'ask' checkbox for password fields with value of 'ASK' - $("#" + fld + "-clear-btn").attr("disabled","disabled"); - scope[fld + '_ask'] = true; - } - else { - scope[fld + '_ask'] = false; - $("#" + fld + "-clear-btn").removeAttr("disabled"); - } - master[fld + '_ask'] = scope[fld + '_ask']; - } - - // Set kind field to the correct option - for (var i=0; i < scope['credential_kind_options'].length; i++) { - if (scope['kind'] == scope['credential_kind_options'][i].value) { - scope['kind'] = scope['credential_kind_options'][i]; - break; - } - } - } - - if (scope.removeCredentialLoaded) { - scope.removeCredentialLoaded(); - } - scope.removeCredentialLoaded = scope.$on('credentialLoaded', function() { - LookUpInit({ - scope: scope, - form: form, - current_item: (!Empty($scope['user_id'])) ? scope['user_id'] : null, - list: UserList, - field: 'user' - }); - - LookUpInit({ - scope: scope, - form: form, - current_item: (!Empty($scope['team_id'])) ? scope['team_id'] : null, - list: TeamList, - field: 'team' - }); - - setAskCheckboxes(); - KindChange({ scope: scope, form: form, reset: false }); - OwnerChange({ scope: scope }); - Wait('stop'); - }); - - if (scope.removeChoicesReady) { - scope.removeChoicesReady(); - } - scope.removeChoicesReady = scope.$on('choicesReadyCredential', function() { - // Retrieve detail record and prepopulate the form - Rest.setUrl(defaultUrl + ':id/'); - Rest.get({ params: {id: id} }) - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/credentials/' + id, title: data.name }); - for (var fld in form.fields) { - if (data[fld] !== null && data[fld] !== undefined) { - scope[fld] = data[fld]; - master[fld] = scope[fld]; - } - if (form.fields[fld].type == 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) { - scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; - master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField]; - } - } - - if (!Empty(scope['user'])) { - scope['owner'] = 'user'; - } - else { - scope['owner'] = 'team'; - } - master['owner'] = scope['owner']; - - for (var i=0; i < scope.credential_kind_options.length; i++) { - if (scope.credential_kind_options[i].value == data.kind) { - scope.kind = scope.credential_kind_options[i]; - break; - } - } - master['kind'] = scope['kind']; - - switch (data.kind) { - case 'aws': - scope['access_key'] = data.username; - scope['secret_key'] = data.password; - master['access_key'] = scope['access_key']; - master['secret_key'] = scope['secret_key']; - break; - case 'ssh': - scope['ssh_password'] = data.password; - master['ssh_password'] = scope['ssh_password']; - break; - case 'rax': - scope['api_key'] = data['password']; - master['api_key'] = scope['api_key']; - break; - } - - scope.$emit('credentialLoaded'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve Credential: ' + $routeParams.id + '. GET status: ' + status }); - }); - }); - - Wait('start'); - - GetChoices({ - scope: scope, - url: defaultUrl, - field: 'kind', - variable: 'credential_kind_options', - callback: 'choicesReadyCredential' - }); - - scope.showActivity = function() { Stream({ scope: scope }); } - - // Save changes to the parent - scope.formSave = function() { generator.clearApiErrors(); FormSave({ scope: scope, mode: 'edit' }) }; - - // Handle Owner change - scope.ownerChange = function() { - OwnerChange({ scope: scope }); - } - - // Handle Kind change - scope.kindChange = function () { - KindChange({ scope: scope, form: form, reset: true }); - } - - // Cancel - scope.formReset = function() { - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - setAskCheckboxes(); - KindChange({ scope: scope, form: form, reset: false }); - OwnerChange({ scope: scope }); - }; - - // Related set: Add button - scope.add = function(set) { - $rootScope.flashMessage = null; - $location.path('/' + base + '/' + $routeParams.id + '/' + set + '/add'); - }; - - // Related set: Edit button - scope.edit = function(set, id, name) { - $rootScope.flashMessage = null; - $location.path('/' + base + '/' + $routeParams.id + '/' + set + '/' + id); - }; - - // Related set: Delete button - scope['delete'] = function(set, itm_id, name, title) { - $rootScope.flashMessage = null; - - var action = function() { - var url = defaultUrl + id + '/' + set + '/'; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - }; - - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', - action: action + if (scope.removeChoicesReady) { + scope.removeChoicesReady(); + } + scope.removeChoicesReady = scope.$on('choicesReadyCredential', function () { + // Retrieve detail record and prepopulate the form + Rest.setUrl(defaultUrl + ':id/'); + Rest.get({ + params: { + id: id + } + }) + .success(function (data) { + + var i, fld; + + LoadBreadCrumbs({ + path: '/credentials/' + id, + title: data.name }); - - } - // Password change - scope.clearPWConfirm = function(fld) { - // If password value changes, make sure password_confirm must be re-entered - scope[fld] = ''; - scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); - } - - // Respond to 'Ask at runtime?' checkbox - scope.ask = function(fld, associated) { - if (scope[fld + '_ask']) { - $("#" + fld + "-clear-btn").attr("disabled","disabled"); - scope[fld] = 'ASK'; - scope[associated] = ''; - scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); - } - else { - $("#" + fld + "-clear-btn").removeAttr("disabled"); - scope[fld] = ''; - scope[associated] = ''; - scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); - } - } + for (fld in form.fields) { + if (data[fld] !== null && data[fld] !== undefined) { + scope[fld] = data[fld]; + master[fld] = scope[fld]; + } + if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) { + scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = + data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; + master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = + scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField]; + } + } - scope.clear = function(fld, associated) { - scope[fld] = ''; - scope[associated] = ''; - scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); - scope[form.name + '_form'].$setDirty(); - } + if (!Empty(scope.user)) { + scope.owner = 'user'; + } else { + scope.owner = 'team'; + } + master.owner = scope.owner; + + for (i = 0; i < scope.credential_kind_options.length; i++) { + if (scope.credential_kind_options[i].value === data.kind) { + scope.kind = scope.credential_kind_options[i]; + break; + } + } + master.kind = scope.kind; + + switch (data.kind) { + case 'aws': + scope.access_key = data.username; + scope.secret_key = data.password; + master.access_key = scope.access_key; + master.secret_key = scope.secret_key; + break; + case 'ssh': + scope.ssh_password = data.password; + master.ssh_password = scope.ssh_password; + break; + case 'rax': + scope.api_key = data.password; + master.api_key = scope.api_key; + break; + } + + scope.$emit('credentialLoaded'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to retrieve Credential: ' + $routeParams.id + '. GET status: ' + status + }); + }); + }); + + Wait('start'); + + GetChoices({ + scope: scope, + url: defaultUrl, + field: 'kind', + variable: 'credential_kind_options', + callback: 'choicesReadyCredential' + }); + + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; + + // Save changes to the parent + scope.formSave = function () { + generator.clearApiErrors(); + FormSave({ + scope: scope, + mode: 'edit' + }); + }; + + // Handle Owner change + scope.ownerChange = function () { + OwnerChange({ + scope: scope + }); + }; + + // Handle Kind change + scope.kindChange = function () { + KindChange({ + scope: scope, + form: form, + reset: true + }); + }; + + // Cancel + scope.formReset = function () { + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + setAskCheckboxes(); + KindChange({ + scope: scope, + form: form, + reset: false + }); + OwnerChange({ + scope: scope + }); + }; + + // Related set: Add button + scope.add = function (set) { + $rootScope.flashMessage = null; + $location.path('/' + base + '/' + $routeParams.id + '/' + set + '/add'); + }; + + // Related set: Edit button + scope.edit = function (set, id) { + $rootScope.flashMessage = null; + $location.path('/' + base + '/' + $routeParams.id + '/' + set + '/' + id); + }; + + // Related set: Delete button + scope['delete'] = function (set, itm_id, name, title) { + $rootScope.flashMessage = null; + + var action = function () { + var url = defaultUrl + id + '/' + set + '/'; + Rest.setUrl(url); + Rest.post({ + id: itm_id, + disassociate: 1 + }) + .success(function () { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. POST returned status: ' + status + }); + }); + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', + action: action + }); + + }; + + // Password change + scope.clearPWConfirm = function (fld) { + // If password value changes, make sure password_confirm must be re-entered + scope[fld] = ''; + scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); + }; + + // Respond to 'Ask at runtime?' checkbox + scope.ask = function (fld, associated) { + if (scope[fld + '_ask']) { + $("#" + fld + "-clear-btn").attr("disabled", "disabled"); + scope[fld] = 'ASK'; + scope[associated] = ''; + scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); + } else { + $("#" + fld + "-clear-btn").removeAttr("disabled"); + scope[fld] = ''; + scope[associated] = ''; + scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); + } + }; + + scope.clear = function (fld, associated) { + scope[fld] = ''; + scope[associated] = ''; + scope[form.name + '_form'][associated].$setValidity('awpassmatch', true); + scope[form.name + '_form'].$setDirty(); + }; } -CredentialsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'CredentialForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'Prompt', 'GetBasePath', 'GetChoices', - 'KindChange', 'UserList', 'TeamList', 'LookUpInit', 'Empty', 'OwnerChange', 'FormSave', 'Stream', - 'Wait']; - +CredentialsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'CredentialForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', + 'ReturnToCaller', 'ClearScope', 'Prompt', 'GetBasePath', 'GetChoices', 'KindChange', 'UserList', 'TeamList', 'LookUpInit', + 'Empty', 'OwnerChange', 'FormSave', 'Stream', 'Wait' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Home.js b/awx/ui/static/js/controllers/Home.js index 2851d17631..66b97e22ab 100644 --- a/awx/ui/static/js/controllers/Home.js +++ b/awx/ui/static/js/controllers/Home.js @@ -3,43 +3,55 @@ * * * Home.js - * + * * Controller functions for Home tab * */ 'use strict'; -function Home ($scope, $compile, $routeParams, $rootScope, $location, Wait, ObjectCount, JobStatus, InventorySyncStatus, SCMSyncStatus, +function Home($scope, $compile, $routeParams, $rootScope, $location, Wait, ObjectCount, JobStatus, InventorySyncStatus, SCMSyncStatus, ClearScope, Stream, Rest, GetBasePath, ProcessErrors, Button) { - - ClearScope('home'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - + + ClearScope('home'); + + var buttons, html, e, waitCount, loadedCount; + // Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons() // to build buttons dynamically and insure all styling and icons match the rest of the application. - var buttons = { + buttons = { refresh: { mode: 'all', awToolTip: "Refresh the page", ngClick: "refresh()" - }, + }, stream: { ngClick: "showActivity()", awToolTip: "View Activity Stream", mode: 'all' - } - }; - var html = Button({ btn: buttons.refresh, action: 'refresh', toolbar: true }); - html += Button({ btn: buttons.stream, action: 'stream', toolbar: true }); - var e = angular.element(document.getElementById('home-list-actions')); + } + }; + + html = Button({ + btn: buttons.refresh, + action: 'refresh', + toolbar: true + }); + + html += Button({ + btn: buttons.stream, + action: 'stream', + toolbar: true + }); + + e = angular.element(document.getElementById('home-list-actions')); e.html(html); $compile(e)($scope); - var waitCount = 4; - var loadedCount = 0; - - if (!$routeParams['login']) { + waitCount = 4; + loadedCount = 0; + + if (!$routeParams.login) { // If we're not logging in, start the Wait widget. Otherwise, it's already running. Wait('start'); } @@ -47,297 +59,366 @@ function Home ($scope, $compile, $routeParams, $rootScope, $location, Wait, Obje if ($scope.removeWidgetLoaded) { $scope.removeWidgetLoaded(); } - $scope.removeWidgetLoaded = $scope.$on('WidgetLoaded', function() { + $scope.removeWidgetLoaded = $scope.$on('WidgetLoaded', function () { // Once all the widgets report back 'loaded', turn off Wait widget - loadedCount++; - if ( loadedCount == waitCount ) { + loadedCount++; + if (loadedCount === waitCount) { Wait('stop'); } - }); + }); if ($scope.removeDashboardReady) { $scope.removeDashboardReady(); } - $scope.removeDashboardReady = $scope.$on('dashboardReady', function(e, data) { - JobStatus({ scope: $scope, target: 'container1', dashboard: data}); - InventorySyncStatus({ scope: $scope, target: 'container2', dashboard: data}); - SCMSyncStatus({ scope: $scope, target: 'container4', dashboard: data}); - ObjectCount({ scope: $scope, target: 'container3', dashboard: data}); + $scope.removeDashboardReady = $scope.$on('dashboardReady', function (e, data) { + JobStatus({ + scope: $scope, + target: 'container1', + dashboard: data }); - - $scope.showActivity = function() { Stream({ scope: $scope }); } + InventorySyncStatus({ + scope: $scope, + target: 'container2', + dashboard: data + }); + SCMSyncStatus({ + scope: $scope, + target: 'container4', + dashboard: data + }); + ObjectCount({ + scope: $scope, + target: 'container3', + dashboard: data + }); + }); - $scope.refresh = function() { + $scope.showActivity = function () { + Stream({ + scope: $scope + }); + }; + + $scope.refresh = function () { Wait('start'); loadedCount = 0; Rest.setUrl(GetBasePath('dashboard')); Rest.get() - .success( function(data, status, headers, config) { + .success(function (data) { $scope.$emit('dashboardReady', data); }) - .error ( function(data, status, headers, config) { + .error(function (data, status) { Wait('stop'); - ProcessErrors($scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status }); - }) - } - + ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status }); + }); + }; + $scope.refresh(); - - } -Home.$inject=['$scope', '$compile', '$routeParams', '$rootScope', '$location', 'Wait', 'ObjectCount', 'JobStatus', 'InventorySyncStatus', - 'SCMSyncStatus', 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', 'Button']; +} + +Home.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location', 'Wait', 'ObjectCount', 'JobStatus', 'InventorySyncStatus', + 'SCMSyncStatus', 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', 'Button' +]; -function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, +function HomeGroups($location, $routeParams, HomeGroupList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GetBasePath, SearchInit, PaginateInit, FormatDate, GetHostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Stream, GroupsEdit, Wait, Alert, Rest, Empty, InventoryUpdate, Find) { - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - var generator = GenerateList; - var list = HomeGroupList; - var defaultUrl=GetBasePath('groups'); - - var scope = generator.inject(list, { mode: 'edit' }); - var base = $location.path().replace(/^\//,'').split('/')[0]; + var generator = GenerateList, + list = HomeGroupList, + defaultUrl = GetBasePath('groups'), + scope = generator.inject(list, { mode: 'edit' }), + opt; if (scope.removePostRefresh) { scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { - var hosts_status, update_status, last_update, stat; - for (var i=0; i < scope.home_groups.length; i++) { - - scope['home_groups'][i]['inventory_name'] = scope['home_groups'][i]['summary_fields']['inventory']['name']; + scope.removePostRefresh = scope.$on('PostRefresh', function () { + var i, hosts_status, stat; + for (i = 0; i < scope.home_groups.length; i++) { - stat = GetSyncStatusMsg({ + scope.home_groups[i].inventory_name = scope.home_groups[i].summary_fields.inventory.name; + + stat = GetSyncStatusMsg({ status: scope.home_groups[i].summary_fields.inventory_source.status - }); // from helpers/Groups.js - + }); // from helpers/Groups.js + hosts_status = GetHostsStatusMsg({ active_failures: scope.home_groups[i].hosts_with_active_failures, total_hosts: scope.home_groups[i].total_hosts, inventory_id: scope.home_groups[i].inventory, group_id: scope.home_groups[i].id - }); - - scope['home_groups'][i].status_class = stat['class'], - scope['home_groups'][i].status_tooltip = stat['tooltip'], - scope['home_groups'][i].launch_tooltip = stat['launch_tip'], - scope['home_groups'][i].launch_class = stat['launch_class'], - scope['home_groups'][i].hosts_status_tip = hosts_status['tooltip'], - scope['home_groups'][i].show_failures = hosts_status['failures'], - scope['home_groups'][i].hosts_status_class = hosts_status['class'], - - + }); + + scope.home_groups[i].status_class = stat['class']; + scope.home_groups[i].status_tooltip = stat.tooltip; + scope.home_groups[i].launch_tooltip = stat.launch_tip; + scope.home_groups[i].launch_class = stat.launch_class; + scope.home_groups[i].hosts_status_tip = hosts_status.tooltip; + scope.home_groups[i].show_failures = hosts_status.failures; + scope.home_groups[i].hosts_status_class = hosts_status['class']; scope.home_groups[i].status = scope.home_groups[i].summary_fields.inventory_source.status; - scope.home_groups[i].source = (scope.home_groups[i].summary_fields.inventory_source) ? + scope.home_groups[i].source = (scope.home_groups[i].summary_fields.inventory_source) ? scope.home_groups[i].summary_fields.inventory_source.source : null; - } - }); + }); - SearchInit({ scope: scope, set: 'home_groups', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + SearchInit({ + scope: scope, + set: 'home_groups', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); // Process search params - if ($routeParams['name']) { + if ($routeParams.name) { scope[list.iterator + 'InputDisable'] = false; - scope[list.iterator + 'SearchValue'] = $routeParams['name']; + scope[list.iterator + 'SearchValue'] = $routeParams.name; scope[list.iterator + 'SearchField'] = 'name'; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['name'].label; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.name.label; scope[list.iterator + 'SearchSelectValue'] = null; } - if ($routeParams['id']) { + if ($routeParams.id) { scope[list.iterator + 'InputDisable'] = false; - scope[list.iterator + 'SearchValue'] = $routeParams['id']; + scope[list.iterator + 'SearchValue'] = $routeParams.id; scope[list.iterator + 'SearchField'] = 'id'; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['id'].label; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.id.label; scope[list.iterator + 'SearchSelectValue'] = null; } - if ($routeParams['has_active_failures']) { + if ($routeParams.has_active_failures) { scope[list.iterator + 'InputDisable'] = true; - scope[list.iterator + 'SearchValue'] = $routeParams['has_active_failures']; + scope[list.iterator + 'SearchValue'] = $routeParams.has_active_failures; scope[list.iterator + 'SearchField'] = 'has_active_failures'; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['has_active_failures'].label; - scope[list.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 }; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.has_active_failures.label; + scope[list.iterator + 'SearchSelectValue'] = ($routeParams.has_active_failures === 'true') ? { value: 1 } : { value: 0 }; } - if ($routeParams['status'] && !$routeParams['source']) { + if ($routeParams.status && !$routeParams.source) { scope[list.iterator + 'SearchField'] = 'status'; scope[list.iterator + 'SelectShow'] = true; - scope[list.iterator + 'SearchSelectOpts'] = list.fields['status'].searchOptions; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['status'].label.replace(/\/g,' '); - for (var opt in list.fields['status'].searchOptions) { - if (list.fields['status'].searchOptions[opt].value == $routeParams['status']) { - scope[list.iterator + 'SearchSelectValue'] = list.fields['status'].searchOptions[opt]; - break; - } + scope[list.iterator + 'SearchSelectOpts'] = list.fields.status.searchOptions; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.status.label.replace(//g, ' '); + for (opt in list.fields.status.searchOptions) { + if (list.fields.status.searchOptions[opt].value === $routeParams.status) { + scope[list.iterator + 'SearchSelectValue'] = list.fields.status.searchOptions[opt]; + break; + } } } - if ($routeParams['source']) { + if ($routeParams.source) { scope[list.iterator + 'SearchField'] = 'source'; scope[list.iterator + 'SelectShow'] = true; - scope[list.iterator + 'SearchSelectOpts'] = list.fields['source'].searchOptions; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['source'].label.replace(/\/g,' '); - for (var opt in list.fields['source'].searchOptions) { - if (list.fields['source'].searchOptions[opt].value == $routeParams['source']) { - scope[list.iterator + 'SearchSelectValue'] = list.fields['source'].searchOptions[opt]; - break; - } + scope[list.iterator + 'SearchSelectOpts'] = list.fields.source.searchOptions; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.source.label.replace(//g, ' '); + for (opt in list.fields.source.searchOptions) { + if (list.fields.source.searchOptions[opt].value === $routeParams.source) { + scope[list.iterator + 'SearchSelectValue'] = list.fields.source.searchOptions[opt]; + break; + } } - if ($routeParams['status']) { - scope[list.iterator + 'ExtraParms'] = '&inventory_source__status__icontains=' + $routeParams['status']; + if ($routeParams.status) { + scope[list.iterator + 'ExtraParms'] = '&inventory_source__status__icontains=' + $routeParams.status; } } - if ($routeParams['has_external_source']) { + if ($routeParams.has_external_source) { scope[list.iterator + 'SearchField'] = 'has_external_source'; - scope[list.iterator + 'SearchValue'] = list.fields['has_external_source'].searchValue; + scope[list.iterator + 'SearchValue'] = list.fields.has_external_source.searchValue; scope[list.iterator + 'InputDisable'] = true; scope[list.iterator + 'SearchType'] = 'in'; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['has_external_source'].label; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.has_external_source.label; } - - scope.search(list.iterator); - - LoadBreadCrumbs(); - - scope.showActivity = function() { Stream({ scope: scope }); } - scope.editGroup = function(group_id, inventory_id) { - GroupsEdit({ scope: scope, group_id: group_id, inventory_id: inventory_id, groups_reload: false }); - } - - scope.viewUpdateStatus = function(id) { + scope.search(list.iterator); + + LoadBreadCrumbs(); + + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; + + scope.editGroup = function (group_id, inventory_id) { + GroupsEdit({ + scope: scope, + group_id: group_id, + inventory_id: inventory_id, + groups_reload: false + }); + }; + + scope.viewUpdateStatus = function (id) { scope.groups = scope.home_groups; - ViewUpdateStatus({ scope: scope, tree_id: id }) - }; + ViewUpdateStatus({ + scope: scope, + tree_id: id + }); + }; // Launch inventory sync - scope.updateGroup = function(id) { - var group = Find({ list: scope.home_groups, key: 'id', val: id}); + scope.updateGroup = function (id) { + var group = Find({ list: scope.home_groups, key: 'id', val: id }); if (group) { if (Empty(group.source)) { // if no source, do nothing. - } - else if (group.status == 'updating') { + } else if (group.status === 'updating') { Alert('Update in Progress', 'The inventory update process is currently running for group ' + - scope.home_groups[i].name + '. Use the Refresh button to monitor the status.', 'alert-info'); - } - else { + group.name + '. Use the Refresh button to monitor the status.', 'alert-info'); + } else { Wait('start'); Rest.setUrl(group.related.inventory_source); Rest.get() - .success( function(data, status, headers, config) { + .success(function (data) { InventoryUpdate({ - scope: scope, + scope: scope, url: data.related.update, - group_name: data.summary_fields.group.name, + group_name: data.summary_fields.group.name, group_source: data.source, tree_id: group.id, group_id: group.id - }); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source + - ' POST returned status: ' + status }); }); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source + ' POST returned status: ' + status + }); + }); } - } } + }; - scope.refresh = function() { scope.search(list.iterator, null, false, true); } + scope.refresh = function () { + scope.search(list.iterator, null, false, true); + }; - } +} -HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', +HomeGroups.$inject = ['$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'GetHostsStatusMsg', 'GetSyncStatusMsg', 'ViewUpdateStatus', 'Stream', 'GroupsEdit', 'Wait', 'Alert', 'Rest', 'Empty', 'InventoryUpdate', 'Find' - ]; +]; -function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, +function HomeHosts($location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GetBasePath, SearchInit, PaginateInit, FormatDate, SetStatus, ToggleHostEnabled, HostsEdit, Stream, Find, ShowJobSummary) { - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - var generator = GenerateList; - var list = HomeHostList; - var defaultUrl=GetBasePath('hosts'); - - var scope = generator.inject(list, { mode: 'edit' }); - var base = $location.path().replace(/^\//,'').split('/')[0]; + var generator = GenerateList, + list = HomeHostList, + defaultUrl = GetBasePath('hosts'), + scope = generator.inject(list, { mode: 'edit' }); if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { - for (var i=0; i < scope.hosts.length; i++) { - scope['hosts'][i]['inventory_name'] = scope['hosts'][i]['summary_fields']['inventory']['name']; + scope.removePostRefresh = scope.$on('PostRefresh', function () { + for (var i = 0; i < scope.hosts.length; i++) { + scope.hosts[i].inventory_name = scope.hosts[i].summary_fields.inventory.name; //SetHostStatus(scope['hosts'][i]); - SetStatus({ scope: scope, host: scope['hosts'][i] }); + SetStatus({ + scope: scope, + host: scope.hosts[i] + }); } - }); + }); + + SearchInit({ + scope: scope, + set: 'hosts', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); - SearchInit({ scope: scope, set: 'hosts', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); - // Process search params - if ($routeParams['name']) { + if ($routeParams.name) { scope[HomeHostList.iterator + 'InputDisable'] = false; - scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['name']; + scope[HomeHostList.iterator + 'SearchValue'] = $routeParams.name; scope[HomeHostList.iterator + 'SearchField'] = 'name'; - scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields['name'].label; + scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields.name.label; } - - if ($routeParams['id']) { + + if ($routeParams.id) { scope[HomeHostList.iterator + 'InputDisable'] = false; - scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['id']; + scope[HomeHostList.iterator + 'SearchValue'] = $routeParams.id; scope[HomeHostList.iterator + 'SearchField'] = 'id'; - scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields['id'].label; + scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields.id.label; scope[HomeHostList.iterator + 'SearchSelectValue'] = null; } - if ($routeParams['has_active_failures']) { + if ($routeParams.has_active_failures) { scope[HomeHostList.iterator + 'InputDisable'] = true; - scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['has_active_failures']; + scope[HomeHostList.iterator + 'SearchValue'] = $routeParams.has_active_failures; scope[HomeHostList.iterator + 'SearchField'] = 'has_active_failures'; - scope[HomeHostList.iterator + 'SearchFieldLabel'] = HomeHostList.fields['has_active_failures'].label; - scope[HomeHostList.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 }; + scope[HomeHostList.iterator + 'SearchFieldLabel'] = HomeHostList.fields.has_active_failures.label; + scope[HomeHostList.iterator + 'SearchSelectValue'] = ($routeParams.has_active_failures === 'true') ? { value: 1 } : { value: 0 }; } - + scope.search(list.iterator); - + LoadBreadCrumbs(); - - scope.showActivity = function() { Stream({ scope: scope }); } - scope.toggle_host_enabled = function(id, sources) { ToggleHostEnabled({ host_id: id, external_source: sources, scope: scope }); } + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - scope.editHost = function(host_id, host_name) { - var host = Find({ list: scope.hosts, key: 'id', val: host_id }); + scope.toggle_host_enabled = function (id, sources) { + ToggleHostEnabled({ + host_id: id, + external_source: sources, + scope: scope + }); + }; + + scope.editHost = function (host_id) { + var host = Find({ + list: scope.hosts, + key: 'id', + val: host_id + }); if (host) { - HostsEdit({ scope: scope, host_id: host_id, inventory_id: host.inventory, group_id: null, hostsReload: false }); - } + HostsEdit({ + scope: scope, + host_id: host_id, + inventory_id: host.inventory, + group_id: null, + hostsReload: false + }); } + }; - scope.showJobSummary = function(job_id) { - ShowJobSummary({ job_id: job_id }); - } + scope.showJobSummary = function (job_id) { + ShowJobSummary({ + job_id: job_id + }); + }; - } +} -HomeHosts.$inject = [ '$location', '$routeParams', 'HomeHostList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', +HomeHosts.$inject = ['$location', '$routeParams', 'HomeHostList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'SetStatus', 'ToggleHostEnabled', 'HostsEdit', 'Stream', 'Find', 'ShowJobSummary' - ]; +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index 64de7d27ac..35cf1f183e 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -3,61 +3,78 @@ * * * Inventories.js - * + * * Controller functions for the Inventory model. * */ - + 'use strict'; -function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, InventoryList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, Wait, Stream, EditInventoryProperties) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - var list = InventoryList; - var defaultUrl = GetBasePath('inventory'); - var view = GenerateList; - var paths = $location.path().replace(/^\//,'').split('/'); - var mode = (paths[0] == 'inventories') ? 'edit' : 'select'; // if base path 'users', we're here to add/edit users - var scope = view.inject(InventoryList, { mode: mode }); // Inject our view +function InventoriesList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, InventoryList, + GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, + GetBasePath, Wait, Stream, EditInventoryProperties) { + ClearScope('htmlTemplate'); + + var list = InventoryList, + defaultUrl = GetBasePath('inventory'), + view = GenerateList, + paths = $location.path().replace(/^\//, '').split('/'), + mode = (paths[0] === 'inventories') ? 'edit' : 'select', // if base path 'users', we're here to add/edit users + scope = view.inject(InventoryList, { mode: mode }); + $rootScope.flashMessage = null; - SearchInit({ scope: scope, set: 'inventories', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); - - if ($routeParams['name']) { + SearchInit({ + scope: scope, + set: 'inventories', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); + + if ($routeParams.name) { scope[InventoryList.iterator + 'InputDisable'] = false; - scope[InventoryList.iterator + 'SearchValue'] = $routeParams['name']; + scope[InventoryList.iterator + 'SearchValue'] = $routeParams.name; scope[InventoryList.iterator + 'SearchField'] = 'name'; - scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['name'].label; + scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.name.label; scope[InventoryList.iterator + 'SearchSelectValue'] = null; } - if ($routeParams['has_active_failures']) { + if ($routeParams.has_active_failures) { scope[InventoryList.iterator + 'InputDisable'] = true; - scope[InventoryList.iterator + 'SearchValue'] = $routeParams['has_active_failures']; + scope[InventoryList.iterator + 'SearchValue'] = $routeParams.has_active_failures; scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures'; - scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['has_active_failures'].label; - scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 }; + scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_active_failures.label; + scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams.has_active_failures === 'true') ? { + value: 1 + } : { + value: 0 + }; } - if ($routeParams['has_inventory_sources']) { + if ($routeParams.has_inventory_sources) { scope[InventoryList.iterator + 'InputDisable'] = true; - scope[InventoryList.iterator + 'SearchValue'] = $routeParams['has_inventory_sources']; + scope[InventoryList.iterator + 'SearchValue'] = $routeParams.has_inventory_sources; scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources'; - scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['has_inventory_sources'].label; - scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams['has_inventory_sources'] == 'true') ? { value: 1 } : { value: 0 }; + scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_inventory_sources.label; + scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams.has_inventory_sources === 'true') ? { + value: 1 + } : { + value: 0 + }; } - if ($routeParams['inventory_sources_with_failures']) { + if ($routeParams.inventory_sources_with_failures) { // pass a value of true, however this field actually contains an integer value scope[InventoryList.iterator + 'InputDisable'] = true; - scope[InventoryList.iterator + 'SearchValue'] = $routeParams['inventory_sources_with_failures']; + scope[InventoryList.iterator + 'SearchValue'] = $routeParams.inventory_sources_with_failures; scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures'; - scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['inventory_sources_with_failures'].label; + scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.inventory_sources_with_failures.label; scope[InventoryList.iterator + 'SearchType'] = 'gtzero'; } @@ -66,282 +83,300 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res LoadBreadCrumbs(); if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { //If we got here by deleting an inventory, stop the spinner and cleanup events Wait('stop'); $('#prompt-modal').off(); - for (var i=0; i < scope.inventories.length; i++) { - + for (var i = 0; i < scope.inventories.length; i++) { + // Set values for Failed Hosts column //scope.inventories[i].failed_hosts = scope.inventories[i].hosts_with_active_failures + ' / ' + scope.inventories[i].total_hosts; - + if (scope.inventories[i].hosts_with_active_failures > 0) { - scope.inventories[i].failed_hosts_tip = scope.inventories[i].hosts_with_active_failures + - ( (scope.inventories[i].hosts_with_active_failures == 1) ? ' host' : ' hosts' ) + ' with job failures. Click to view details.'; - scope.inventories[i].failed_hosts_link = '/#/inventories/' + scope.inventories[i].id + '/'; - scope.inventories[i].failed_hosts_class = 'true'; - } - else { - if (scope.inventories[i].total_hosts == 0) { - // no hosts - scope.inventories[i].failed_hosts_tip = "No hosts defined. Click to add."; - scope.inventories[i].failed_hosts_link = '/#/inventories/' + scope.inventories[i].id + '/'; - scope.inventories[i].failed_hosts_class = 'na'; - } - else { - // many hosts with 0 failures - scope.inventories[i].failed_hosts_tip = scope.inventories[i].total_hosts + - ( (scope.inventories[i].total_hosts > 1) ? ' hosts' : ' host' ) + " with no job failures. Click to view details."; - scope.inventories[i].failed_hosts_link = '/#/inventories/' + scope.inventories[i].id + '/'; - scope.inventories[i].failed_hosts_class = 'false'; - } + scope.inventories[i].failed_hosts_tip = scope.inventories[i].hosts_with_active_failures + + ((scope.inventories[i].hosts_with_active_failures === 1) ? ' host' : ' hosts') + ' with job failures. Click to view details.'; + scope.inventories[i].failed_hosts_link = '/#/inventories/' + scope.inventories[i].id + '/'; + scope.inventories[i].failed_hosts_class = 'true'; + } else { + if (scope.inventories[i].total_hosts === 0) { + // no hosts + scope.inventories[i].failed_hosts_tip = "No hosts defined. Click to add."; + scope.inventories[i].failed_hosts_link = '/#/inventories/' + scope.inventories[i].id + '/'; + scope.inventories[i].failed_hosts_class = 'na'; + } else { + // many hosts with 0 failures + scope.inventories[i].failed_hosts_tip = scope.inventories[i].total_hosts + + ((scope.inventories[i].total_hosts > 1) ? ' hosts' : ' host') + " with no job failures. Click to view details."; + scope.inventories[i].failed_hosts_link = '/#/inventories/' + scope.inventories[i].id + '/'; + scope.inventories[i].failed_hosts_class = 'false'; + } } // Set values for Status column - scope.inventories[i].status = scope.inventories[i].inventory_sources_with_failures + ' / ' + scope.inventories[i].total_inventory_sources; + scope.inventories[i].status = scope.inventories[i].inventory_sources_with_failures + ' / ' + scope.inventories[i].total_inventory_sources; if (scope.inventories[i].inventory_sources_with_failures > 0) { - scope.inventories[i].status_tip = scope.inventories[i].inventory_sources_with_failures + ' cloud ' + - ( (scope.inventories[i].inventory_sources_with_failures == 1) ? 'source' : 'sources' ) + - ' with failures. Click to view details.'; - scope.inventories[i].status_link = '/#/inventories/' + scope.inventories[i].id + '/'; - scope.inventories[i].status_class = 'failed'; - } - else { - if (scope.inventories[i].total_inventory_sources == 0) { - // no groups are reporting a source - scope.inventories[i].status_tip = "Not synced with a cloud source. Click to edit."; - scope.inventories[i].status_link = '/#/inventories/' + scope.inventories[i].id + '/'; - scope.inventories[i].status_class = 'na'; - } - else { - // many hosts with 0 failures - scope.inventories[i].status_tip = scope.inventories[i].total_inventory_sources + - ' cloud ' + ( (scope.inventories[i].total_inventory_sources > 1) ? 'sources' : 'source' ) + - ' with no failures. Click to view details.'; - scope.inventories[i].status_link = '/#/inventories/' + scope.inventories[i].id + '/'; - scope.inventories[i].status_class = 'successful'; - } + scope.inventories[i].status_tip = scope.inventories[i].inventory_sources_with_failures + ' cloud ' + + ((scope.inventories[i].inventory_sources_with_failures === 1) ? 'source' : 'sources') + + ' with failures. Click to view details.'; + scope.inventories[i].status_link = '/#/inventories/' + scope.inventories[i].id + '/'; + scope.inventories[i].status_class = 'failed'; + } else { + if (scope.inventories[i].total_inventory_sources === 0) { + // no groups are reporting a source + scope.inventories[i].status_tip = "Not synced with a cloud source. Click to edit."; + scope.inventories[i].status_link = '/#/inventories/' + scope.inventories[i].id + '/'; + scope.inventories[i].status_class = 'na'; + } else { + // many hosts with 0 failures + scope.inventories[i].status_tip = scope.inventories[i].total_inventory_sources + + ' cloud ' + ((scope.inventories[i].total_inventory_sources > 1) ? 'sources' : 'source') + + ' with no failures. Click to view details.'; + scope.inventories[i].status_link = '/#/inventories/' + scope.inventories[i].id + '/'; + scope.inventories[i].status_class = 'successful'; + } } } - }); + }); if (scope.removeRefreshInventories) { scope.removeRefreshInventories(); } - scope.removeRefreshInventories = scope.$on('RefreshInventories', function() { + scope.removeRefreshInventories = scope.$on('RefreshInventories', function () { // Reflect changes after inventory properties edit completes scope.search(list.iterator); + }); + + scope.showActivity = function () { + Stream({ + scope: scope }); - - scope.showActivity = function() { Stream({ scope: scope }); } + }; - scope.editInventoryProperties = function(inventory_id) { - EditInventoryProperties({ scope: scope, inventory_id: inventory_id }); - } + scope.editInventoryProperties = function (inventory_id) { + EditInventoryProperties({ + scope: scope, + inventory_id: inventory_id + }); + }; - scope.addInventory = function() { + scope.addInventory = function () { $location.path($location.path() + '/add'); - } + }; - scope.editInventory = function(id) { + scope.editInventory = function (id) { $location.path($location.path() + '/' + id); - } - - scope.deleteInventory = function(id, name) { - - var action = function() { + }; + + scope.deleteInventory = function (id, name) { + + var action = function () { var url = defaultUrl + id + '/'; - $('#prompt-modal').on('hidden.bs.modal', function() { + $('#prompt-modal').on('hidden.bs.modal', function () { Wait('start'); - }); + }); $('#prompt-modal').modal('hide'); Rest.setUrl(url); Rest.destroy() - .success( function(data, status, headers, config) { - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { + .success(function () { + scope.search(list.iterator); + }) + .error(function (data, status) { Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status + }); + }); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action - }); - } - - scope.lookupOrganization = function(organization_id) { + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + }; + + scope.lookupOrganization = function (organization_id) { Rest.setUrl(GetBasePath('organizations') + organization_id + '/'); Rest.get() - .success( function(data, status, headers, config) { + .success(function (data) { return data.name; - }); - } + }); + }; - // Failed jobs link. Go to the jobs tabs, find all jobs for the inventory and sort by status - scope.viewJobs = function(id) { + // Failed jobs link. Go to the jobs tabs, find all jobs for the inventory and sort by status + scope.viewJobs = function (id) { $location.url('/jobs/?inventory__int=' + id); - } + }; - scope.viewFailedJobs = function(id) { + scope.viewFailedJobs = function (id) { $location.url('/jobs/?inventory__int=' + id + '&status=failed'); + }; +} + +InventoriesList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'InventoryList', 'GenerateList', + 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', + 'GetBasePath', 'Wait', 'Stream', 'EditInventoryProperties' +]; + + +function InventoriesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, + GenerateList, OrganizationList, SearchInit, PaginateInit, LookUpInit, GetBasePath, + ParseTypeChange, Wait) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + + // Inject dynamic view + var defaultUrl = GetBasePath('inventory'), + form = InventoryForm, + generator = GenerateForm, + scope; + + form.well = true; + form.formLabelSize = null; + form.formFieldSize = null; + + scope = generator.inject(form, { + mode: 'add', + related: false + }); + scope.inventoryParseType = 'yaml'; + + generator.reset(); + LoadBreadCrumbs(); + ParseTypeChange(scope, 'inventory_variables', 'inventoryParseType'); + + LookUpInit({ + scope: scope, + form: form, + current_item: ($routeParams.organization_id) ? $routeParams.organization_id : null, + list: OrganizationList, + field: 'organization' + }); + + // Save + scope.formSave = function () { + generator.clearApiErrors(); + Wait('start'); + try { + var fld, json_data, data; + + // Make sure we have valid variable data + if (scope.inventoryParseType === 'json') { + json_data = JSON.parse(scope.inventory_variables); //make sure JSON parses + } else { + json_data = jsyaml.load(scope.inventory_variables); //parse yaml + } + + // Make sure our JSON is actually an object + if (typeof json_data !== 'object') { + throw "failed to return an object!"; + } + + data = {}; + for (fld in form.fields) { + if (fld !== 'inventory_variables') { + if (form.fields[fld].realName) { + data[form.fields[fld].realName] = scope[fld]; + } else { + data[fld] = scope[fld]; + } + } + } + + Rest.setUrl(defaultUrl); + Rest.post(data) + .success(function (data) { + var inventory_id = data.id; + if (scope.inventory_variables) { + Rest.setUrl(data.related.variable_data); + Rest.put(json_data) + .success(function () { + Wait('stop'); + $location.path('/inventories/' + inventory_id + '/'); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to add inventory varaibles. PUT returned status: ' + status + }); + }); + } else { + Wait('stop'); + $location.path('/inventories/' + inventory_id + '/'); + } + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to add new inventory. Post returned status: ' + status + }); + }); + } catch (err) { + Wait('stop'); + Alert("Error", "Error parsing inventory variables. Parser returned: " + err); } + + }; + + // Reset + scope.formReset = function () { + // Defaults + generator.reset(); + }; } -InventoriesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'InventoryList', 'GenerateList', - 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'Wait', 'Stream', 'EditInventoryProperties']; - - -function InventoriesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GenerateList, OrganizationList, SearchInit, PaginateInit, LookUpInit, GetBasePath, - ParseTypeChange, Wait) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'); - var form = InventoryForm; - var generator = GenerateForm; - - form.well = true, - form.formLabelSize = null; - form.formFieldSize = null; - - var scope = generator.inject(form, {mode: 'add', related: false}); - scope.inventoryParseType = 'yaml'; - - generator.reset(); - LoadBreadCrumbs(); - ParseTypeChange(scope,'inventory_variables', 'inventoryParseType'); - - LookUpInit({ - scope: scope, - form: form, - current_item: ($routeParams.organization_id) ? $routeParams.organization_id : null, - list: OrganizationList, - field: 'organization' - }); - - // Save - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - try { - // Make sure we have valid variable data - if (scope.inventoryParseType == 'json') { - var json_data = JSON.parse(scope.inventory_variables); //make sure JSON parses - } - else { - var json_data = jsyaml.load(scope.inventory_variables); //parse yaml - } - - // Make sure our JSON is actually an object - if (typeof json_data !== 'object') { - throw "failed to return an object!"; - } - - var data = {} - for (var fld in form.fields) { - if (fld != 'inventory_variables') { - if (form.fields[fld].realName) { - data[form.fields[fld].realName] = scope[fld]; - } - else { - data[fld] = scope[fld]; - } - } - } - - Rest.setUrl(defaultUrl); - Rest.post(data) - .success( function(data, status, headers, config) { - var inventory_id = data.id; - if (scope.inventory_variables) { - Rest.setUrl(data.related.variable_data); - Rest.put(json_data) - .success( function(data, status, headers, config) { - Wait('stop'); - $location.path('/inventories/' + inventory_id + '/'); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to add inventory varaibles. PUT returned status: ' + status }); - }); - } - else { - Wait('stop'); - $location.path('/inventories/' + inventory_id + '/'); - } - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to add new inventory. Post returned status: ' + status }); - }); - } - catch(err) { - Wait('stop'); - Alert("Error", "Error parsing inventory variables. Parser returned: " + err); - } - - }; - - // Reset - scope.formReset = function() { - // Defaults - generator.reset(); - }; -} - -InventoriesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryForm', 'GenerateForm', - 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', - 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait' - ]; +InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryForm', 'GenerateForm', + 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', + 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait' +]; -function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait, - GetSyncStatusMsg, InjectHosts, HostsReload, GroupsAdd, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, - Rest, ProcessErrors, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find, - HostsCreate, EditInventoryProperties, HostsEdit, HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost, - Stream, GetBasePath, ShowJobSummary, ApplyEllipsis, WatchInventoryWindowResize, HelpDialog, InventoryGroupsHelp, - Store) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function InventoriesEdit($scope, $location, $routeParams, $compile, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait, + GetSyncStatusMsg, InjectHosts, HostsReload, GroupsAdd, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, + Rest, ProcessErrors, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find, + HostsCreate, EditInventoryProperties, HostsEdit, HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost, + Stream, GetBasePath, ShowJobSummary, ApplyEllipsis, WatchInventoryWindowResize, HelpDialog, InventoryGroupsHelp, + Store) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + + var generator = GenerateList, + list = InventoryGroups; - var generator = GenerateList; - var list = InventoryGroups; - var base = $location.path().replace(/^\//,'').split('/')[0]; - $scope.inventory_id = $routeParams.inventory_id; - - LoadBreadCrumbs({ path: $location.path(), title: '{{ inventory_name }}' }); + + LoadBreadCrumbs({ + path: $location.path(), + title: '{{ inventory_name }}' + }); // After the tree data loads for the first time, generate the groups and hosts lists if ($scope.removeGroupTreeLoaded) { $scope.removeGroupTreeLoaded(); } - $scope.removeGroupTreeLoaded = $scope.$on('GroupTreeLoaded', function(e, inventory_name, groups) { + $scope.removeGroupTreeLoaded = $scope.$on('GroupTreeLoaded', function (event, inventory_name, groups) { // Add breadcrumbs - var e = angular.element(document.getElementById('breadcrumbs')); + var e, inventoryAutoHelp; + e = angular.element(document.getElementById('breadcrumbs')); e.html(Breadcrumbs({ list: list, mode: 'edit' })); $compile(e)($scope); - + // Add groups view - generator.inject(list, { mode: 'edit', id: 'groups-container', breadCrumbs: false, searchSize: 'col-lg-5 col-md-5 col-sm-5' }); + generator.inject(list, { + mode: 'edit', + id: 'groups-container', + breadCrumbs: false, + searchSize: 'col-lg-5 col-md-5 col-sm-5' + }); $scope.groups = groups; $scope.inventory_name = inventory_name; @@ -352,235 +387,324 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis $scope.groups[0].selected_class = 'selected'; $scope.groups[0].active_class = 'active-row'; $scope.selected_group_name = $scope.groups[0].name; - } - else { + } else { $scope.selected_tree_id = null; $scope.selected_group_id = null; - } + } // Add hosts view $scope.show_failures = false; - InjectHosts({ scope: $scope, inventory_id: $scope.inventory_id, tree_id: $scope.selected_tree_id, group_id: $scope.selected_group_id }); - + InjectHosts({ + scope: $scope, + inventory_id: $scope.inventory_id, + tree_id: $scope.selected_tree_id, + group_id: $scope.selected_group_id + }); + // As the window shrinks and expands, apply ellipsis - setTimeout(function() { + setTimeout(function () { // Hack to keep group name from slipping to a new line - $('#groups_table .name-column').each( function() { - var td_width = $(this).width(); - var level_width = $(this).find('.level').width(); - var level_padding = parseInt($(this).find('.level').css('padding-left').replace(/px/,'')); - var level = level_width + level_padding; - var pct = ( 100 - Math.ceil((level / td_width)*100) ) + '%'; - $(this).find('.group-name').css({ width: pct }); + $('#groups_table .name-column').each(function () { + var td_width, level_width, level_padding, level, pct; + td_width = $(this).width(); + level_width = $(this).find('.level').width(); + level_padding = parseInt($(this).find('.level').css('padding-left').replace(/px/, '')); + level = level_width + level_padding; + pct = (100 - Math.ceil((level / td_width) * 100)) + '%'; + $(this).find('.group-name').css({ + width: pct }); + }); ApplyEllipsis('#groups_table .group-name a'); ApplyEllipsis('#hosts_table .host-name a'); - }, 2500); //give the window time to display + }, 2500); //give the window time to display WatchInventoryWindowResize(); - - var inventoryAutoHelp = Store('inventoryAutoHelp'); + + inventoryAutoHelp = Store('inventoryAutoHelp'); if (inventoryAutoHelp !== 'off' && $scope.autoShowGroupHelp) { - $scope.showGroupHelp({ autoShow: true }); + $scope.showGroupHelp({ + autoShow: true + }); } - }); - + }); + // Called after tree data is reloaded on refresh button click. if ($scope.removeGroupTreeRefreshed) { $scope.removeGroupTreeRefreshed(); } - $scope.removeGroupTreeRefreshed = $scope.$on('GroupTreeRefreshed', function(e, inventory_name, groups) { + $scope.removeGroupTreeRefreshed = $scope.$on('GroupTreeRefreshed', function () { // Reapply ellipsis to groups - setTimeout(function() { ApplyEllipsis('#groups_table .group-name a'); }, 2500); + setTimeout(function () { + ApplyEllipsis('#groups_table .group-name a'); + }, 2500); // Reselect the preveiously selected group node, causing host view to refresh. $scope.showHosts($scope.selected_tree_id, $scope.selected_group_id, false); - }); - + }); + // Group was deleted. Now we need to refresh the group view. if ($scope.removeGroupDeleteCompleted) { $scope.removeGroupDeleteCompleted(); } - $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', function(e) { + $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', function () { $scope.selected_tree_id = 1; $scope.selected_group_id = null; - BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: true }); + BuildTree({ + scope: $scope, + inventory_id: $scope.inventory_id, + refresh: true }); + }); // Respond to a group drag-n-drop if ($scope.removeCopMoveGroup) { $scope.removeCopyMoveGroup(); } - $scope.removeCopyMoveGroup = $scope.$on('CopyMoveGroup', function(e, inbound_tree_id, target_tree_id) { - CopyMoveGroup({ scope: $scope, target_tree_id: target_tree_id, inbound_tree_id: inbound_tree_id }); + $scope.removeCopyMoveGroup = $scope.$on('CopyMoveGroup', function (e, inbound_tree_id, target_tree_id) { + CopyMoveGroup({ + scope: $scope, + target_tree_id: target_tree_id, + inbound_tree_id: inbound_tree_id }); + }); // Respond to a host drag-n-drop if ($scope.removeCopMoveHost) { $scope.removeCopyMoveHost(); } - $scope.removeCopyMoveHost = $scope.$on('CopyMoveHost', function(e, target_tree_id, host_id) { - CopyMoveHost({ scope: $scope, target_tree_id: target_tree_id, host_id: host_id }); + $scope.removeCopyMoveHost = $scope.$on('CopyMoveHost', function (e, target_tree_id, host_id) { + CopyMoveHost({ + scope: $scope, + target_tree_id: target_tree_id, + host_id: host_id }); + }); - $scope.showHosts = function(tree_id, group_id, show_failures) { + $scope.showHosts = function (tree_id, group_id, show_failures) { // Clicked on group if (tree_id !== null) { Wait('start'); - $scope.selected_tree_id = tree_id; + $scope.selected_tree_id = tree_id; $scope.selected_group_id = group_id; $scope.hosts = []; - $scope.show_failures = show_failures; // turn on failed hosts filter in hosts view - for (var i=0; i < $scope.groups.length; i++) { - if ($scope.groups[i].id == tree_id) { + $scope.show_failures = show_failures; // turn on failed hosts filter in hosts view + for (var i = 0; i < $scope.groups.length; i++) { + if ($scope.groups[i].id === tree_id) { $scope.groups[i].selected_class = 'selected'; $scope.groups[i].active_class = 'active-row'; $scope.selected_group_name = $scope.groups[i].name; - } - else { + } else { $scope.groups[i].selected_class = ''; $scope.groups[i].active_class = ''; } } - HostsReload({ scope: $scope, group_id: group_id, tree_id: tree_id, inventory_id: $scope.inventory_id }); - } - else { + HostsReload({ + scope: $scope, + group_id: group_id, + tree_id: tree_id, + inventory_id: $scope.inventory_id + }); + } else { Wait('stop'); } - } + }; - $scope.createGroup = function() { - GroupsAdd({ scope: $scope, inventory_id: $scope.inventory_id, group_id: $scope.selected_group_id }); - } - - $scope.editGroup = function(group_id, tree_id) { - GroupsEdit({ scope: $scope, inventory_id: $scope.inventory_id, group_id: group_id, tree_id: tree_id, groups_reload: true }); - } + $scope.createGroup = function () { + GroupsAdd({ + scope: $scope, + inventory_id: $scope.inventory_id, + group_id: $scope.selected_group_id + }); + }; + + $scope.editGroup = function (group_id, tree_id) { + GroupsEdit({ + scope: $scope, + inventory_id: $scope.inventory_id, + group_id: group_id, + tree_id: tree_id, + groups_reload: true + }); + }; // Launch inventory sync - $scope.updateGroup = function(id) { - var group = Find({ list: $scope.groups, key: 'id', val: id}); + $scope.updateGroup = function (id) { + var group = Find({ list: $scope.groups, key: 'id', val: id }); if (group) { if (Empty(group.source)) { // if no source, do nothing. - } - else if (group.status == 'updating') { + } else if (group.status === 'updating') { Alert('Update in Progress', 'The inventory update process is currently running for group ' + - $scope.groups[i].name + '. Use the Refresh button to monitor the status.', 'alert-info'); - } - else { + group.name + '. Use the Refresh button to monitor the status.', 'alert-info'); + } else { Wait('start'); Rest.setUrl(group.related.inventory_source); Rest.get() - .success( function(data, status, headers, config) { + .success(function (data) { InventoryUpdate({ - scope: $scope, + scope: $scope, url: data.related.update, - group_name: data.summary_fields.group.name, + group_name: data.summary_fields.group.name, group_source: data.source, tree_id: group.id, group_id: group.group_id - }); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source + - ' POST returned status: ' + status }); }); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + + group.related.inventory_source + ' POST returned status: ' + status }); + }); } - } } + }; - $scope.cancelUpdate = function(tree_id) { - GroupsCancelUpdate({ scope: $scope, tree_id: tree_id }); - } - - $scope.toggle = function(tree_id) { + $scope.cancelUpdate = function (tree_id) { + GroupsCancelUpdate({ + scope: $scope, + tree_id: tree_id + }); + }; + + $scope.toggle = function (tree_id) { // Expand/collapse nodes - ToggleChildren({ scope: $scope, list: list, id: tree_id }); - } + ToggleChildren({ + scope: $scope, + list: list, + id: tree_id + }); + }; - $scope.refreshGroups = function(tree_id, group_id) { + $scope.refreshGroups = function (tree_id, group_id) { // Refresh the tree data when refresh button cicked if (tree_id) { $scope.selected_tree_id = tree_id; $scope.selected_group_id = group_id; } - BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: true }); - } + BuildTree({ + scope: $scope, + inventory_id: $scope.inventory_id, + refresh: true + }); + }; - $scope.viewUpdateStatus = function(tree_id, group_id) { - ViewUpdateStatus({ scope: $scope, tree_id: tree_id, group_id: group_id }); - } + $scope.viewUpdateStatus = function (tree_id, group_id) { + ViewUpdateStatus({ + scope: $scope, + tree_id: tree_id, + group_id: group_id + }); + }; - $scope.deleteGroup = function(tree_id, group_id) { - GroupsDelete({ scope: $scope, tree_id: tree_id, group_id: group_id, inventory_id: $scope.inventory_id }); - } + $scope.deleteGroup = function (tree_id, group_id) { + GroupsDelete({ + scope: $scope, + tree_id: tree_id, + group_id: group_id, + inventory_id: $scope.inventory_id + }); + }; - $scope.createHost = function() { - HostsCreate({ scope: $scope }); - } - - $scope.editInventoryProperties = function() { - EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory_id }); - } + $scope.createHost = function () { + HostsCreate({ + scope: $scope + }); + }; - $scope.editHost = function(host_id) { - HostsEdit({ scope: $scope, host_id: host_id, inventory_id: $scope.inventory_id }); - } + $scope.editInventoryProperties = function () { + EditInventoryProperties({ + scope: $scope, + inventory_id: $scope.inventory_id + }); + }; - $scope.deleteHost = function(host_id, host_name) { - HostsDelete({ scope: $scope, host_id: host_id, host_name: host_name }); - } + $scope.editHost = function (host_id) { + HostsEdit({ + scope: $scope, + host_id: host_id, + inventory_id: $scope.inventory_id + }); + }; - $scope.toggleHostEnabled = function(host_id, external_source) { - ToggleHostEnabled({ scope: $scope, host_id: host_id, external_source: external_source }); - } + $scope.deleteHost = function (host_id, host_name) { + HostsDelete({ + scope: $scope, + host_id: host_id, + host_name: host_name + }); + }; - $scope.showGroupActivity = function() { + $scope.toggleHostEnabled = function (host_id, external_source) { + ToggleHostEnabled({ + scope: $scope, + host_id: host_id, + external_source: external_source + }); + }; + + $scope.showGroupActivity = function () { var url, title, group; if ($scope.selected_group_id) { - group = Find({ list: $scope.groups, key: 'id', val: $scope.selected_tree_id }); + group = Find({ + list: $scope.groups, + key: 'id', + val: $scope.selected_tree_id + }); url = GetBasePath('activity_stream') + '?group__id=' + $scope.selected_group_id; title = 'Showing all activities for group ' + group.name; - } - else { + } else { title = 'Showing all activities for all ' + $scope.inventory_name + ' groups'; url = GetBasePath('activity_stream') + '?group__inventory__id=' + $scope.inventory_id; } - Stream({ scope: $scope, inventory_name: $scope.inventory_name, url: url, title: title }); - } - - $scope.showHostActivity = function() { + Stream({ + scope: $scope, + inventory_name: $scope.inventory_name, + url: url, + title: title + }); + }; + + $scope.showHostActivity = function () { var url, title; title = 'Showing all activities for all ' + $scope.inventory_name + ' hosts'; url = GetBasePath('activity_stream') + '?host__inventory__id=' + $scope.inventory_id; - Stream({ scope: $scope, inventory_name: $scope.inventory_name, url: url, title: title }); - } + Stream({ + scope: $scope, + inventory_name: $scope.inventory_name, + url: url, + title: title + }); + }; - $scope.showJobSummary = function(job_id) { - ShowJobSummary({ job_id: job_id }); - } + $scope.showJobSummary = function (job_id) { + ShowJobSummary({ + job_id: job_id + }); + }; - $scope.showGroupHelp = function(params) { - var opts = { defn: InventoryGroupsHelp }; + $scope.showGroupHelp = function (params) { + var opts = { + defn: InventoryGroupsHelp + }; if (params) { opts.autoShow = params.autoShow || false; } HelpDialog(opts); - } + }; //Load tree data for the first time - BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: false }); + BuildTree({ + scope: $scope, + inventory_id: $scope.inventory_id, + refresh: false + }); - } +} -InventoriesEdit.$inject = [ '$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts', - 'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsAdd', 'GroupsEdit', 'GroupsDelete', - 'Breadcrumbs', 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', - 'ViewUpdateStatus', 'GroupsCancelUpdate', 'Find', 'HostsCreate', 'EditInventoryProperties', 'HostsEdit', - 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost', 'Stream', 'GetBasePath', 'ShowJobSummary', - 'ApplyEllipsis', 'WatchInventoryWindowResize', 'HelpDialog', 'InventoryGroupsHelp', 'Store' - ]; - +InventoriesEdit.$inject = ['$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts', + 'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsAdd', 'GroupsEdit', 'GroupsDelete', 'Breadcrumbs', + 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', 'ViewUpdateStatus', 'GroupsCancelUpdate', + 'Find', 'HostsCreate', 'EditInventoryProperties', 'HostsEdit', 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost', + 'Stream', 'GetBasePath', 'ShowJobSummary', 'ApplyEllipsis', 'WatchInventoryWindowResize', 'HelpDialog', 'InventoryGroupsHelp', 'Store' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/JobEvents.js b/awx/ui/static/js/controllers/JobEvents.js index 735fe2eaee..7c9406dd0d 100644 --- a/awx/ui/static/js/controllers/JobEvents.js +++ b/awx/ui/static/js/controllers/JobEvents.js @@ -3,180 +3,168 @@ * * * JobEvents.js - * + * * Controller functions for the Job Events model. * */ 'use strict'; -function JobEventsList ($filter, $scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobEventList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, LookUpInit, ToggleChildren, - FormatDate, EventView, Refresh, Wait) -{ +function JobEventsList($filter, $scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobEventList, GenerateList, + LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, LookUpInit, ToggleChildren, + FormatDate, EventView, Refresh, Wait) { + ClearScope('htmlTemplate'); - var list = JobEventList; + + var list = JobEventList, + defaultUrl = GetBasePath('jobs') + $routeParams.id + '/job_events/', //?parent__isnull=1'; + view = GenerateList, + scope = view.inject(list, { mode: 'edit' }), + page; + list.base = $location.path(); - - var defaultUrl = GetBasePath('jobs') + $routeParams.id + '/job_events/'; //?parent__isnull=1'; - - var view = GenerateList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var scope = view.inject(list, { mode: 'edit' }); - scope.job_id = $routeParams.id; $rootScope.flashMessage = null; scope.selected = []; - scope.expand = true; //on load, automatically expand all nodes + scope.expand = true; //on load, automatically expand all nodes + + scope.parentNode = 'parent-event'; // used in ngClass to dynamically set row level class and control + scope.childNode = 'child-event'; // link color and cursor - scope.parentNode = 'parent-event'; // used in ngClass to dynamically set row level class and control - scope.childNode = 'child-event'; // link color and cursor - if (scope.removeSetHostLinks) { - scope.removeSetHostLinks(); + scope.removeSetHostLinks(); } - scope.removeSetHostLinks = scope.$on('SetHostLinks', function(e, inventory_id) { - for (var i=0; i < scope.jobevents.length; i++) { + scope.removeSetHostLinks = scope.$on('SetHostLinks', function (e, inventory_id) { + for (var i = 0; i < scope.jobevents.length; i++) { if (scope.jobevents[i].summary_fields.host) { - scope.jobevents[i].hostLink = "/#/inventories/" + inventory_id + "/hosts/?name=" + - escape(scope.jobevents[i].summary_fields.host.name); + scope.jobevents[i].hostLink = "/#/inventories/" + inventory_id + "/hosts/?name=" + + encodeURI(scope.jobevents[i].summary_fields.host.name); } } - }); + }); function formatJSON(eventData) { //turn JSON event data into an html form - var html = ''; - if (eventData['res']) { - var n, rows; - var found = false; - if (typeof eventData.res == 'string') { - n = eventData['res'].match(/\n/g); - rows = (n) ? n.length : 1; - rows = (rows > 10) ? 10 : rows; - found = true; - html += "
\n"; - html += "\n"; - html += "\n"; - html += "
\n"; - } - else { - for (var fld in eventData.res) { - if ( (fld == 'msg' || fld == 'stdout' || fld == 'stderr') && - (eventData.res[fld] !== null && eventData.res[fld] !== '') ) { - html += "
\n"; - html += "\n"; - n = eventData['res'][fld].match(/\n/g); - rows = (n) ? n.length : 1; - rows = (rows > 10) ? 10 : rows; - html += "\n"; - html += "
\n"; - found = true; - } - if ( fld == "results" && Array.isArray(eventData.res[fld]) && eventData.res[fld].length > 0 ) { - //html += "\n"; + html += "\n"; + } else { + for (fld in eventData.res) { + if ((fld === 'msg' || fld === 'stdout' || fld === 'stderr') && + (eventData.res[fld] !== null && eventData.res[fld] !== '')) { html += "
\n"; - html += "\n"; - html += "\n"; + html += "\n"; + n = eventData.res[fld].match(/\n/g); + rows = (n) ? n.length : 1; + rows = (rows > 10) ? 10 : rows; + html += "\n"; html += "
\n"; found = true; - } - } - if (fld == "rc" && eventData.res[fld] != '') { - html += "
\n"; - html += "\n"; - html += "\n"; - html += "
\n"; - found = true; - } - } - } - html = (found) ? "
\n" + html + "
\n" : ''; + } + if (fld === "results" && Array.isArray(eventData.res[fld]) && eventData.res[fld].length > 0) { + //html += "\n"; + html += "\n"; + found = true; + } + } + if (fld === "rc" && eventData.res[fld] !== '') { + html += "
\n"; + html += "\n"; + html += "\n"; + html += "
\n"; + found = true; + } + } + } + html = (found) ? "
\n" + html + "
\n" : ''; } - if (eventData['host']) { - html = "" + eventData['host'] + "\n" + html; - } - else { - html = (html == '' ) ? null : html; + if (eventData.hosts) { + html = "" + eventData.host + "\n" + html; + } else { + html = (html === '') ? null : html; } return html; - } + } if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Initialize the parent levels - var set = scope[list.name]; - var cDate; - for (var i=0; i < set.length; i++) { - set[i].event_display = set[i].event_display.replace(/^\u00a0*/g,''); - if (set[i].event_level < 3 ) { - set[i]['ngclick'] = "toggleChildren(" + set[i].id + ", \"" + set[i].related.children + "\")"; - set[i]['ngicon'] = 'fa fa-minus-square-o node-toggle'; - set[i]['class'] = 'parentNode'; + var set = scope[list.name], i; + for (i = 0; i < set.length; i++) { + set[i].event_display = set[i].event_display.replace(/^\u00a0*/g, ''); + if (set[i].event_level < 3) { + set[i].ngclick = "toggleChildren(" + set[i].id + ", \"" + set[i].related.children + "\")"; + set[i].ngicon = 'fa fa-minus-square-o node-toggle'; + set[i]['class'] = 'parentNode'; + } else { + set[i].ngicon = 'fa fa-square-o node-no-toggle'; + set[i]['class'] = 'childNode'; + set[i].event_detail = formatJSON(set[i].event_data); } - else { - set[i]['ngicon'] = 'fa fa-square-o node-no-toggle'; - set[i]['class'] = 'childNode'; - set[i]['event_detail'] = formatJSON(set[i].event_data); - } - set[i]['show'] = true; - set[i]['spaces'] = set[i].event_level * 24; + set[i].show = true; + set[i].spaces = set[i].event_level * 24; if (scope.jobevents[i].failed) { - scope.jobevents[i].status = 'error'; - if (i == set.length - 1) { - scope.jobevents[i].statusBadgeToolTip = "A failure occurred durring one or more playbook tasks."; - } - else if (set[i].event_level < 3) { - scope.jobevents[i].statusBadgeToolTip = "A failure occurred within the children of this event."; - } - else { - scope.jobevents[i].statusBadgeToolTip = "A failure occurred. Click to view details"; - } - } - else if (scope.jobevents[i].changed) { - scope.jobevents[i].status = 'changed'; - if (i == set.length - 1) { - scope.jobevents[i].statusBadgeToolTip = "A change was completed durring one or more playbook tasks."; - } - else if (set[i].event_level < 3) { - scope.jobevents[i].statusBadgeToolTip = "A change was completed by one or more children of this event."; - } - else { - scope.jobevents[i].statusBadgeToolTip = "A change was completed. Click to view details"; - } - } - else { - scope.jobevents[i].status = 'success'; - if (i == set.length - 1) { - scope.jobevents[i].statusBadgeToolTip = "All playbook tasks completed successfully."; - } - else if (set[i].event_level < 3) { - scope.jobevents[i].statusBadgeToolTip = "All the children of this event completed successfully."; - } - else { - scope.jobevents[i].statusBadgeToolTip = "No errors occurred. Click to view details"; - } + scope.jobevents[i].status = 'error'; + if (i === set.length - 1) { + scope.jobevents[i].statusBadgeToolTip = "A failure occurred durring one or more playbook tasks."; + } else if (set[i].event_level < 3) { + scope.jobevents[i].statusBadgeToolTip = "A failure occurred within the children of this event."; + } else { + scope.jobevents[i].statusBadgeToolTip = "A failure occurred. Click to view details"; + } + } else if (scope.jobevents[i].changed) { + scope.jobevents[i].status = 'changed'; + if (i === set.length - 1) { + scope.jobevents[i].statusBadgeToolTip = "A change was completed durring one or more playbook tasks."; + } else if (set[i].event_level < 3) { + scope.jobevents[i].statusBadgeToolTip = "A change was completed by one or more children of this event."; + } else { + scope.jobevents[i].statusBadgeToolTip = "A change was completed. Click to view details"; + } + } else { + scope.jobevents[i].status = 'success'; + if (i === set.length - 1) { + scope.jobevents[i].statusBadgeToolTip = "All playbook tasks completed successfully."; + } else if (set[i].event_level < 3) { + scope.jobevents[i].statusBadgeToolTip = "All the children of this event completed successfully."; + } else { + scope.jobevents[i].statusBadgeToolTip = "No errors occurred. Click to view details"; + } } //cDate = new Date(set[i].created); //set[i].created = FormatDate(cDate); @@ -187,160 +175,180 @@ function JobEventsList ($filter, $scope, $rootScope, $location, $log, $routePara // from job in the event that there are no job event records Rest.setUrl(GetBasePath('jobs') + scope.job_id); Rest.get() - .success( function(data, status, headers, config) { + .success(function (data) { scope.job_status = data.status; scope.job_name = data.summary_fields.job_template.name; - LoadBreadCrumbs({ path: '/jobs/' + scope.job_id, title: scope.job_id + ' - ' + data.summary_fields.job_template.name }); - scope.$emit('SetHostLinks', data.inventory); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get job status for job: ' + scope.job_id + '. GET status: ' + status }); + LoadBreadCrumbs({ + path: '/jobs/' + scope.job_id, + title: scope.job_id + ' - ' + data.summary_fields.job_template.name }); - }); + scope.$emit('SetHostLinks', data.inventory); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Failed to get job status for job: ' + scope.job_id + '. GET status: ' + status + }); + }); + }); - SearchInit({ scope: scope, set: 'jobevents', list: list, url: defaultUrl }); - - var page = ($routeParams.page) ? parseInt($routeParams.page) - 1 : null; - PaginateInit({ scope: scope, list: list, url: defaultUrl, page: page }); + SearchInit({ + scope: scope, + set: 'jobevents', + list: list, + url: defaultUrl + }); + + page = ($routeParams.page) ? parseInt($routeParams.page,10) - 1 : null; + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl, + page: page + }); // Called from Inventories tab, host failed events link: if ($routeParams.host) { - scope[list.iterator + 'SearchField'] = 'host'; - scope[list.iterator + 'SearchValue'] = $routeParams.host; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['host'].label; + scope[list.iterator + 'SearchField'] = 'host'; + scope[list.iterator + 'SearchValue'] = $routeParams.host; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.host.label; } - + scope.search(list.iterator, $routeParams.page); - - scope.toggleChildren = function(id, children) { + + scope.toggleChildren = function (id, children) { ToggleChildren({ - scope: scope, + scope: scope, list: list, id: id, children: children - }); - } - - scope.viewJobEvent = function(id) { - EventView({ event_id: id }); - } + }); + }; - scope.refresh = function() { - scope['jobSearchSpin'] = true; - scope['jobLoading'] = true; - Wait('start'); - Refresh({ scope: scope, set: 'jobevents', iterator: 'jobevent', url: scope['current_url'] }); - } + scope.viewJobEvent = function (id) { + EventView({ + event_id: id + }); + }; + + scope.refresh = function () { + scope.jobSearchSpin = true; + scope.jobLoading = true; + Wait('start'); + Refresh({ + scope: scope, + set: 'jobevents', + iterator: 'jobevent', + url: scope.current_url + }); + }; } -JobEventsList.$inject = [ '$filter', '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobEventList', - 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', - 'ProcessErrors','GetBasePath', 'LookUpInit', 'ToggleChildren', 'FormatDate', 'EventView', 'Refresh', 'Wait' - ]; +JobEventsList.$inject = ['$filter', '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobEventList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', + 'ProcessErrors', 'GetBasePath', 'LookUpInit', 'ToggleChildren', 'FormatDate', 'EventView', 'Refresh', 'Wait' +]; -function JobEventsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventForm, GenerateForm, - Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, FormatDate, EventView, - Wait) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - // Inject dynamic view - var form = JobEventForm; - var generator = GenerateForm; - var scope = GenerateForm.inject(form, {mode: 'edit', related: true}); - generator.reset(); - - var defaultUrl = GetBasePath('base') + 'job_events/' + $routeParams.event_id + '/'; - var base = $location.path().replace(/^\//,'').split('/')[0]; - - // Retrieve detail record and prepopulate the form - Wait('start'); - Rest.setUrl(defaultUrl); - Rest.get() - .success( function(data, status, headers, config) { - scope['event_display'] = data['event_display'].replace(/^\u00a0*/g,''); - LoadBreadCrumbs({ path: '/jobs/' + $routeParams.job_id + '/job_events/' + $routeParams.event_id, - title: scope['event_display'] }); - for (var fld in form.fields) { - switch(fld) { - case 'status': - if (data['failed']) { - scope['status'] = 'error'; - } - else if (data['changed']) { - scope['status'] = 'changed'; - } - else { - scope['status'] = 'success'; - } - break; - case 'created': - var cDate = new Date(data['created']); - scope['created'] = FormatDate(cDate); - break; - case 'host': - if (data['summary_fields'] && data['summary_fields']['host']) { - scope['host'] = data['summary_fields']['host']['name']; - } - break; - case 'id': - case 'task': - case 'play': - scope[fld] = data[fld]; - break; - case 'start': - case 'end': - if (data['event_data'] && data['event_data']['res'] && data['event_data']['res'][fld] !== undefined) { - var cDate = new Date(data['event_data']['res'][fld]); - scope[fld] = FormatDate(cDate); +function JobEventsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventForm, GenerateForm, + Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, FormatDate, EventView, + Wait) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + // Inject dynamic view + var form = JobEventForm, + generator = GenerateForm, + scope = GenerateForm.inject(form, { mode: 'edit', related: true }), + defaultUrl = GetBasePath('base') + 'job_events/' + $routeParams.event_id + '/'; + + generator.reset(); + + // Retrieve detail record and prepopulate the form + Wait('start'); + Rest.setUrl(defaultUrl); + Rest.get() + .success(function (data) { + var cDate, fld, n, rows; + scope.event_display = data.event_display.replace(/^\u00a0*/g, ''); + LoadBreadCrumbs({ path: '/jobs/' + $routeParams.job_id + '/job_events/' + $routeParams.event_id, title: scope.event_display }); + for (fld in form.fields) { + switch (fld) { + case 'status': + if (data.failed) { + scope.status = 'error'; + } else if (data.changed) { + scope.status = 'changed'; + } else { + scope.status = 'success'; } break; - case 'msg': - case 'stdout': - case 'stderr': - case 'delta': - case 'rc': - if (data['event_data'] && data['event_data']['res'] && data['event_data']['res'][fld] !== undefined) { - scope[fld] = data['event_data']['res'][fld]; - if (form.fields[fld].type == 'textarea') { - var n = data['event_data']['res'][fld].match(/\n/g); - var rows = (n) ? n.length : 1; - rows = (rows > 15) ? 5 : rows; - $('textarea[name="' + fld + '"]').attr('rows',rows); + case 'created': + cDate = new Date(data.created); + scope.created = FormatDate(cDate); + break; + case 'host': + if (data.summary_fields && data.summary_fields.host) { + scope.host = data.summary_fields.host.name; + } + break; + case 'id': + case 'task': + case 'play': + scope[fld] = data[fld]; + break; + case 'start': + case 'end': + if (data.event_data && data.event_data.res && data.event_data.res[fld] !== undefined) { + cDate = new Date(data.event_data.res[fld]); + scope[fld] = FormatDate(cDate); + } + break; + case 'msg': + case 'stdout': + case 'stderr': + case 'delta': + case 'rc': + if (data.event_data && data.event_data.res && data.event_data.res[fld] !== undefined) { + scope[fld] = data.event_data.res[fld]; + if (form.fields[fld].type === 'textarea') { + n = data.event_data.res[fld].match(/\n/g); + rows = (n) ? n.length : 1; + rows = (rows > 15) ? 5 : rows; + $('textarea[name="' + fld + '"]').attr('rows', rows); } - } - break; - case 'module_name': - case 'module_args': - if (data['event_data']['res'] && data['event_data']['res']['invocation']) { - scope[fld] = data['event_data']['res']['invocation'][fld]; - } - break; - } - } - Wait('stop'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to retrieve host: ' + $routeParams.event_id + '. GET status: ' + status }); - }); + } + break; + case 'module_name': + case 'module_args': + if (data.event_data.res && data.event_data.res.invocation) { + scope[fld] = data.event_data.res.invocation.fld; + } + break; + } + } + Wait('stop'); + }) + .error(function (data) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve host: ' + $routeParams.event_id + + '. GET status: ' + status }); + }); - scope.navigateBack = function() { - var url = '/jobs/' + $routeParams.job_id + '/job_events'; - if ($routeParams.page) { - url += '?page=' + $routeParams.page; - } - $location.url(url); - } + scope.navigateBack = function () { + var url = '/jobs/' + $routeParams.job_id + '/job_events'; + if ($routeParams.page) { + url += '?page=' + $routeParams.page; + } + $location.url(url); + }; + + scope.rawView = function () { + EventView({ + "event_id": scope.id + }); + }; - scope.rawView = function() { - EventView({"event_id": scope.id }); - } - } -JobEventsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobEventForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', - 'FormatDate', 'EventView', 'Wait' - ]; +JobEventsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobEventForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', 'FormatDate', + 'EventView', 'Wait' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/JobHosts.js b/awx/ui/static/js/controllers/JobHosts.js index 5c94a29274..94f3da0cfd 100644 --- a/awx/ui/static/js/controllers/JobHosts.js +++ b/awx/ui/static/js/controllers/JobHosts.js @@ -3,145 +3,165 @@ * * * JobHosts.js - * + * * Controller functions for the Job Hosts Summary model. * */ 'use strict'; -function JobHostSummaryList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobHostList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, Refresh, JobStatusToolTip, Wait) -{ +function JobHostSummaryList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobHostList, GenerateList, + LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, Refresh, + JobStatusToolTip, Wait) { + ClearScope('htmlTemplate'); - var list = JobHostList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath(base) + $routeParams.id + '/job_host_summaries/'; - var inventory_id; + + var list = JobHostList, + base = $location.path().replace(/^\//, '').split('/')[0], + defaultUrl = GetBasePath(base) + $routeParams.id + '/job_host_summaries/', + view = GenerateList, + scope = view.inject(list, { mode: 'edit' }); // When viewing all summaries for a particular host, show job ID, otherwise row ID. - if (base == 'hosts') { - list.index = false; + if (base === 'hosts') { + list.index = false; + } else { + list.index = true; } - else { - list.index = true; - } - - var view = GenerateList; - var scope = view.inject(list, { mode: 'edit' }); scope.selected = []; - + // control enable/disable/show of job specific view elements - if (base == 'hosts') { - scope.job_id = null; - scope.host_id = $routeParams.id; + if (base === 'hosts') { + scope.job_id = null; + scope.host_id = $routeParams.id; + } else { + scope.job_id = $routeParams.id; + scope.host_id = null; } - else { - scope.job_id = $routeParams.id; - scope.host_id = null; - } - + if (scope.RemoveSetHostLink) { - scope.RemoveSetHostLink(); + scope.RemoveSetHostLink(); } - scope.RemoveSetHostLink = scope.$on('setHostLink', function(e, inventory_id) { - for (var i=0; i < scope.jobhosts.length; i++) { - scope.jobhosts[i].hostLinkTo = '/#/inventories/' + inventory_id + '/?host_name=' + - escape(scope.jobhosts[i].summary_fields.host.name); + scope.RemoveSetHostLink = scope.$on('setHostLink', function (e, inventory_id) { + for (var i = 0; i < scope.jobhosts.length; i++) { + scope.jobhosts[i].hostLinkTo = '/#/inventories/' + inventory_id + '/?host_name=' + + encodeURI(scope.jobhosts[i].summary_fields.host.name); } - }); + }); // After a refresh, populate any needed summary field values on each row if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { - + scope.removePostRefresh = scope.$on('PostRefresh', function () { + // Set status, tooltips, badget icons, etc. - for( var i=0; i < scope.jobhosts.length; i++) { - scope.jobhosts[i].host_name = scope.jobhosts[i].summary_fields.host.name; - scope.jobhosts[i].status = (scope.jobhosts[i].failed) ? 'failed' : 'success'; - scope.jobhosts[i].statusBadgeToolTip = JobStatusToolTip(scope.jobhosts[i].status) + - " Click to view details."; - scope.jobhosts[i].statusLinkTo = '/#/jobs/' + scope.jobhosts[i].job + '/job_events/?host=' + - escape(scope.jobhosts[i].summary_fields.host.name); + for (var i = 0; i < scope.jobhosts.length; i++) { + scope.jobhosts[i].host_name = scope.jobhosts[i].summary_fields.host.name; + scope.jobhosts[i].status = (scope.jobhosts[i].failed) ? 'failed' : 'success'; + scope.jobhosts[i].statusBadgeToolTip = JobStatusToolTip(scope.jobhosts[i].status) + + " Click to view details."; + scope.jobhosts[i].statusLinkTo = '/#/jobs/' + scope.jobhosts[i].job + '/job_events/?host=' + + encodeURI(scope.jobhosts[i].summary_fields.host.name); } if (scope.job_id !== null && scope.job_id !== undefined && scope.job_id !== '') { - // need job_status so we can show/hide refresh button - Rest.setUrl(GetBasePath('jobs') + scope.job_id); - Rest.get() - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/jobs/' + data.id, title: data.id + ' - ' + - data.summary_fields.job_template.name }); - scope.job_status = data.status; - if (!(data.status == 'pending' || data.status == 'waiting' || data.status == 'running')) { - if ($rootScope.timer) { - clearInterval($rootScope.timer); - } - } - scope.$emit('setHostLink', data.inventory); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get job status for job: ' + scope.job_id + '. GET status: ' + status }); - }); + // need job_status so we can show/hide refresh button + Rest.setUrl(GetBasePath('jobs') + scope.job_id); + Rest.get() + .success(function (data) { + LoadBreadCrumbs({ + path: '/jobs/' + data.id, + title: data.id + ' - ' + + data.summary_fields.job_template.name + }); + scope.job_status = data.status; + if (!(data.status === 'pending' || data.status === 'waiting' || data.status === 'running')) { + if ($rootScope.timer) { + clearInterval($rootScope.timer); + } + } + scope.$emit('setHostLink', data.inventory); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Failed to get job status for job: ' + scope.job_id + '. GET status: ' + status + }); + }); + } else { + // Make the host name appear in breadcrumbs + LoadBreadCrumbs({ + path: '/hosts/' + scope.host_id, + title: ((scope.jobhosts.length > 0) ? scope.jobhosts[0].summary_fields.host.name : 'Host') + }); + if ($routeParams.inventory) { + scope.$emit('setHostLink', $routeParams.inventory); + } } - else { - // Make the host name appear in breadcrumbs - LoadBreadCrumbs({ path: '/hosts/' + scope['host_id'], - title: ( (scope.jobhosts.length > 0) ? scope.jobhosts[0].summary_fields.host.name : 'Host' ) }); - if ($routeParams['inventory']) { - scope.$emit('setHostLink', $routeParams['inventory']); - } - } - }); - - SearchInit({ scope: scope, set: 'jobhosts', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + }); + + SearchInit({ + scope: scope, + set: 'jobhosts', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); // Called from Inventories tab, host failed events link: - if ($routeParams['host_name']) { - scope[list.iterator + 'SearchField'] = 'host'; - scope[list.iterator + 'SearchValue'] = $routeParams['host_name']; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['host'].label; + if ($routeParams.host_name) { + scope[list.iterator + 'SearchField'] = 'host'; + scope[list.iterator + 'SearchValue'] = $routeParams.host_name; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.host.label; } - + scope.search(list.iterator); - - - scope.showEvents = function(host_name, last_job) { + + + scope.showEvents = function (host_name, last_job) { // When click on !Failed Events link, redirect to latest job/job_events for the host Rest.setUrl(last_job); Rest.get() - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/jobs/' + data.id, title: data.name }); - $location.url('/jobs/' + data.id + '/job_events/?host=' + escape(host_name)); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to lookup last job: ' + last_job + '. GET status: ' + status }); - }); - } + .success(function (data) { + LoadBreadCrumbs({ + path: '/jobs/' + data.id, + title: data.name + }); + $location.url('/jobs/' + data.id + '/job_events/?host=' + encodeURI(host_name)); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to lookup last job: ' + last_job + + '. GET status: ' + status }); + }); + }; - scope.showJob = function(id) { - $location.path('/jobs/' + id); - } + scope.showJob = function (id) { + $location.path('/jobs/' + id); + }; - scope.refresh = function() { - if (scope.host_id == null) { - scope['jobSearchSpin'] = true; - scope['jobLoading'] = true; - Wait('start'); - Refresh({ scope: scope, set: 'jobhosts', iterator: 'jobhost', url: scope['current_url'] }); + scope.refresh = function () { + if (scope.host_id === null) { + scope.jobSearchSpin = true; + scope.jobLoading = true; + Wait('start'); + Refresh({ + scope: scope, + set: 'jobhosts', + iterator: 'jobhost', + url: scope.current_url + }); } - } - + }; + } -JobHostSummaryList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobHostList', - 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', - 'ProcessErrors', 'GetBasePath', 'Refresh', 'JobStatusToolTip', 'Wait' - ]; +JobHostSummaryList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobHostList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', + 'ProcessErrors', 'GetBasePath', 'Refresh', 'JobStatusToolTip', 'Wait' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/JobTemplates.js b/awx/ui/static/js/controllers/JobTemplates.js index 0fb999e30c..7c00029440 100644 --- a/awx/ui/static/js/controllers/JobTemplates.js +++ b/awx/ui/static/js/controllers/JobTemplates.js @@ -3,716 +3,771 @@ * * * JobTemplates.js - * + * * Controller functions for the Job Template model. * */ - 'use strict'; -function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobTemplateList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, PromptPasswords, JobTemplateForm, CredentialList, - LookUpInit, SubmitJob, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - var list = JobTemplateList; - var defaultUrl = GetBasePath('job_templates'); - var view = GenerateList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var mode = (base == 'job_templates') ? 'edit' : 'select'; - var scope = view.inject(list, { mode: mode }); +function JobTemplatesList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobTemplateList, + GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, + ClearScope, ProcessErrors, GetBasePath, PromptPasswords, JobTemplateForm, CredentialList, + LookUpInit, SubmitJob, Wait, Stream) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + var list = JobTemplateList, + defaultUrl = GetBasePath('job_templates'), + view = GenerateList, + base = $location.path().replace(/^\//, '').split('/')[0], + mode = (base === 'job_templates') ? 'edit' : 'select', + scope = view.inject(list, { mode: mode }); + $rootScope.flashMessage = null; - + if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Cleanup after a delete Wait('stop'); $('#prompt-modal').off(); - }); - - SearchInit({ scope: scope, set: 'job_templates', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + }); + + SearchInit({ + scope: scope, + set: 'job_templates', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); // Called from Inventories tab, host failed events link: - if ($routeParams['name']) { - scope[list.iterator + 'SearchField'] = 'name'; - scope[list.iterator + 'SearchValue'] = $routeParams['name']; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['name'].label; + if ($routeParams.name) { + scope[list.iterator + 'SearchField'] = 'name'; + scope[list.iterator + 'SearchValue'] = $routeParams.name; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.name.label; } scope.search(list.iterator); LoadBreadCrumbs(); - - scope.showActivity = function() { Stream({ scope: scope }); } - scope.addJobTemplate = function() { - $location.path($location.path() + '/add'); - } + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - scope.editJobTemplate = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deleteJobTemplate = function(id, name) { - var action = function() { - $('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); }); - $('#prompt-modal').modal('hide'); - var url = defaultUrl + id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + scope.addJobTemplate = function () { + $location.path($location.path() + '/add'); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action + scope.editJobTemplate = function (id) { + $location.path($location.path() + '/' + id); + }; + + scope.deleteJobTemplate = function (id, name) { + var action = function () { + $('#prompt-modal').on('hidden.bs.modal', function () { + Wait('start'); + }); + $('#prompt-modal').modal('hide'); + var url = defaultUrl + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + scope.search(list.iterator); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status + }); }); - } - - scope.submitJob = function(id) { - SubmitJob({ scope: scope, id: id }); - } + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + }; + + scope.submitJob = function (id) { + SubmitJob({ scope: scope, id: id }); + }; } -JobTemplatesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobTemplateList', - 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', - 'ProcessErrors','GetBasePath', 'PromptPasswords', 'JobTemplateForm', 'CredentialList', 'LookUpInit', - 'SubmitJob', 'Wait', 'Stream' - ]; +JobTemplatesList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobTemplateList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', + 'ProcessErrors', 'GetBasePath', 'PromptPasswords', 'JobTemplateForm', 'CredentialList', 'LookUpInit', + 'SubmitJob', 'Wait', 'Stream' +]; -function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit, - md5Setup, ParseTypeChange, Wait, Empty) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, + GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit, + md5Setup, ParseTypeChange, Wait, Empty) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - // Inject dynamic view - var defaultUrl = GetBasePath('job_templates'); - var form = JobTemplateForm; - var generator = GenerateForm; - var scope = generator.inject(form, {mode: 'add', related: false}); - var master = {}; - - scope.parseType = 'yaml'; - ParseTypeChange(scope); + // Inject dynamic view + var defaultUrl = GetBasePath('job_templates'), + form = JobTemplateForm, + generator = GenerateForm, + scope = generator.inject(form, { mode: 'add', related: false }), + master = {}, + CloudCredentialList = {}, + selectPlaybook, checkSCMStatus; - scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }]; - scope.verbosity_options = [ - { value: '0', label: 'Default' }, - { value: '1', label: 'Verbose' }, - { value: '3', label: 'Debug' }]; - scope.playbook_options = []; - scope.allow_callbacks = 'false'; + scope.parseType = 'yaml'; + ParseTypeChange(scope); - generator.reset(); - LoadBreadCrumbs(); + scope.job_type_options = [ + { value: 'run', label: 'Run' }, + { value: 'check', label: 'Check' } + ]; - md5Setup({ - scope: scope, - master: master, - check_field: 'allow_callbacks', - default_val: false - }); + scope.verbosity_options = [ + { value: '0', label: 'Default' }, + { value: '1', label: 'Verbose' }, + { value: '3', label: 'Debug' } + ]; - LookUpInit({ - scope: scope, - form: form, - current_item: null, - list: InventoryList, - field: 'inventory' - }); + scope.playbook_options = []; + scope.allow_callbacks = 'false'; - // Clone the CredentialList object for use with cloud_credential. Cloning - // and changing properties to avoid collision. - var CloudCredentialList = {}; - jQuery.extend(true, CloudCredentialList, CredentialList); - CloudCredentialList.name = 'cloudcredentials', - CloudCredentialList.iterator = 'cloudcredential', - - LookUpInit({ - url: GetBasePath('credentials') + '?cloud=true', - scope: scope, - form: form, - current_item: null, - list: CloudCredentialList, - field: 'cloud_credential', - hdr: 'Select Cloud Credential' - }); - - LookUpInit({ - url: GetBasePath('credentials') + '?kind=ssh', - scope: scope, - form: form, - current_item: null, - list: CredentialList, - field: 'credential', - hdr: 'Select Machine Credential' - }); + generator.reset(); + LoadBreadCrumbs(); - // Update playbook select whenever project value changes - var selectPlaybook = function(oldValue, newValue) { - if (oldValue != newValue) { - if (scope.project) { - Wait('start'); - var url = GetBasePath('projects') + scope.project + '/playbooks/'; - Rest.setUrl(url); - Rest.get() - .success( function(data, status, headers, config) { - var opts = []; - for (var i=0; i < data.length; i++) { - opts.push(data[i]); - } - scope.playbook_options = opts; - Wait('stop'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to get playbook list for ' + url +'. GET returned status: ' + status }); - }); - } - } - }; - - // Detect and alert user to potential SCM status issues - var checkSCMStatus = function(oldValue, newValue) { - if (oldValue !== newValue && !Empty(scope.project)) { - Rest.setUrl(GetBasePath('projects') + scope.project + '/'); - Rest.get() - .success( function(data, status, headers, config) { - var msg; - switch(data.status) { - case 'failed': - msg = "The selected project has a failed status. Review the project's SCM settings" + - " and run an update before adding it to a template."; - break; - case 'never updated': - msg = 'The selected project has a never updated status. You will need to run a successful' + - ' update in order to selected a playbook. Without a valid playbook you will not be able ' + - ' to save this template.'; - break; - case 'missing': - msg = 'The selected project has a status of missing. Please check the server and make sure ' + - ' the directory exists and file permissions are set correctly.'; - break; - } - if (msg) { - Alert('Waning', msg, 'alert-info'); - } - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to get project ' + scope.project +'. GET returned status: ' + status }); - }); - } - } - - // Register a watcher on project_name - if (scope.selectPlaybookUnregister) { - scope.selectPlaybookUnregister(); - } - scope.selectPlaybookUnregister = scope.$watch('project_name', function(oldval, newval) { - selectPlaybook(oldval, newval); - checkSCMStatus(oldval, newval); - }); + md5Setup({ + scope: scope, + master: master, + check_field: 'allow_callbacks', + default_val: false + }); - LookUpInit({ - scope: scope, - form: form, - current_item: null, - list: ProjectList, - field: 'project' - }); + LookUpInit({ + scope: scope, + form: form, + current_item: null, + list: InventoryList, + field: 'inventory' + }); - // Save - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - var data = {} - try { - // Make sure we have valid variable data - if (scope.parseType == 'json') { - var json_data = JSON.parse(scope.variables); //make sure JSON parses - } - else { - var json_data = jsyaml.load(scope.variables); //parse yaml - } - - // Make sure our JSON is actually an object - if (typeof json_data !== 'object') { - throw "failed to return an object!"; - } + // Clone the CredentialList object for use with cloud_credential. Cloning + // and changing properties to avoid collision. + jQuery.extend(true, CloudCredentialList, CredentialList); + CloudCredentialList.name = 'cloudcredentials'; + CloudCredentialList.iterator = 'cloudcredential'; - for (var fld in form.fields) { - if (form.fields[fld].type == 'select' && fld != 'playbook') { - data[fld] = scope[fld].value; - } - else { - if (fld != 'variables') { - data[fld] = scope[fld]; - } - } - } - - data.extra_vars = JSON.stringify(json_data, undefined, '\t'); - if (data.extra_vars == "null" || data.extra_vars == null) { - data.extra_vars = ""; - } + LookUpInit({ + url: GetBasePath('credentials') + '?cloud=true', + scope: scope, + form: form, + current_item: null, + list: CloudCredentialList, + field: 'cloud_credential', + hdr: 'Select Cloud Credential' + }); - Rest.setUrl(defaultUrl); - Rest.post(data) - .success( function(data, status, headers, config) { - Wait('stop'); - var base = $location.path().replace(/^\//,'').split('/')[0]; - (base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to add new job template. POST returned status: ' + status }); - }); + LookUpInit({ + url: GetBasePath('credentials') + '?kind=ssh', + scope: scope, + form: form, + current_item: null, + list: CredentialList, + field: 'credential', + hdr: 'Select Machine Credential' + }); - } - catch(err) { - Wait('stop'); - Alert("Error", "Error parsing extra variables. Parser returned: " + err); - } - }; + // Update playbook select whenever project value changes + selectPlaybook = function (oldValue, newValue) { + var url; + if (oldValue !== newValue) { + if (scope.project) { + Wait('start'); + url = GetBasePath('projects') + scope.project + '/playbooks/'; + Rest.setUrl(url); + Rest.get() + .success(function (data) { + var i, opts = []; + for (i = 0; i < data.length; i++) { + opts.push(data[i]); + } + scope.playbook_options = opts; + Wait('stop'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to get playbook list for ' + url + '. GET returned status: ' + status + }); + }); + } + } + }; - // Reset - scope.formReset = function() { - // Defaults - generator.reset(); - //$('#forks-slider').slider("option", "value", scope.forks); - for (var fld in master) { - scope[fld] = master[fld]; - } - }; -} - -JobTemplatesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', - 'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', - 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty' ]; - - -function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList, - ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, ParseTypeChange, - JobStatusToolTip, FormatDate, Wait, Stream, Empty) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - - var defaultUrl= GetBasePath('job_templates'); - var generator = GenerateForm; - var form = JobTemplateForm; - var scope = generator.inject(form, {mode: 'edit', related: true}); - var loadingFinishedCount = 0; - - scope.parseType = 'yaml'; - ParseTypeChange(scope); - - // Our job type options - scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }]; - scope.verbosity_options = [ - { value: '0', label: 'Default' }, - { value: '1', label: 'Verbose' }, - { value: '3', label: 'Debug' }]; - scope.playbook_options = null; - scope.playbook = null; - - generator.reset(); - - var base = $location.path().replace(/^\//,'').split('/')[0]; - var master = {}; - var id = $routeParams.id; - var relatedSets = {}; - - function getPlaybooks(project) { - if (project !== null && project !== '' && project !== undefined) { - var url = GetBasePath('projects') + project + '/playbooks/'; - Wait('start'); - Rest.setUrl(url); - Rest.get() - .success( function(data, status, headers, config) { - scope.playbook_options = []; - for (var i=0; i < data.length; i++) { - scope.playbook_options.push(data[i]); - if (data[i] == scope.playbook) { - scope['job_templates_form']['playbook'].$setValidity('required',true); - } - } - if (scope.playbook) { - scope.$emit('jobTemplateLoadFinished'); - } - else { - Wait('stop'); - } - }) - .error( function(data, status, headers, config) { - Wait('stop'); - Alert('Missing Playbooks', 'Unable to retrieve the list of playbooks for this project. Choose a different ' + - ' project or make the playbooks available on the file system.', 'alert-info'); - }); - } - } - - // Detect and alert user to potential SCM status issues - var checkSCMStatus = function() { - if (!Empty(scope.project)) { - Wait('start'); - Rest.setUrl(GetBasePath('projects') + scope.project + '/'); - Rest.get() - .success( function(data, status, headers, config) { - var msg; - switch(data.status) { - case 'failed': - msg = "The selected project has a failed status. Review the project's SCM settings" + - " and run an update before adding it to a template."; - break; - case 'never updated': - msg = 'The selected project has a never updated status. You will need to run a successful' + - ' update in order to selected a playbook. Without a valid playbook you will not be able ' + - ' to save this template.'; - break; - case 'missing': - msg = 'The selected project has a status of missing. Please check the server and make sure ' + - ' the directory exists and file permissions are set correctly.'; - break; - } - Wait('stop'); - if (msg) { - Alert('Waning', msg, 'alert-info'); - } - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to get project ' + scope.project +'. GET returned status: ' + status }); - }); - } - } - - - // Register a watcher on project_name. Refresh the playbook list on change. - if (scope.watchProjectUnregister) { - scope.watchProjectUnregister(); - } - scope.watchProjectUnregister = scope.$watch('project_name', function(oldValue, newValue) { - if (oldValue !== newValue && newValue !== '' && newValue !== null && newValue !== undefined) { - scope.playbook = null; - getPlaybooks(scope.project); - checkSCMStatus(); - } - }); - - // Turn off 'Wait' after both cloud credential and playbook list come back - if (scope.removeJobTemplateLoadFinished) { - scope.removeJobTemplateLoadFinished(); - } - scope.removeJobTemplateLoadFinished = scope.$on('jobTemplateLoadFinished', function() { - loadingFinishedCount++; - if (loadingFinishedCount >= 2) { - // The initial template load finished. Now load related jobs, which - // will turn off the 'working' spinner. - for (var set in relatedSets) { - scope.search(relatedSets[set].iterator); - } - - } - }); - - // Set the status/badge for each related job - if (scope.removeRelatedJobs) { - scope.removeRelatedJobs(); - } - scope.removeRelatedJobs = scope.$on('relatedjobs', function() { - if (scope['jobs'] && scope['jobs'].length) { - var cDate; - for (var i=0; i < scope['jobs'].length; i++) { - // Convert created date to local time zone - cDate = new Date(scope['jobs'][i].created); - scope['jobs'][i].created = FormatDate(cDate); - // Set tooltip and link - scope['jobs'][i].statusBadgeToolTip = JobStatusToolTip(scope['jobs'][i].status) + - " Click to view status details."; - scope['jobs'][i].statusLinkTo = '/#/jobs/' + scope['jobs'][i].id; - } - } - }); - - if (scope.cloudCredentialReadyRemove) { - scope.cloudCredentialReadyRemove(); - } - scope.cloudCredentialReadyRemove = scope.$on('cloudCredentialReady', function(e, name) { - scope['cloud_credential_name'] = name; - master['cloud_credential_name'] = name; - // Clone the CredentialList object for use with cloud_credential. Cloning - // and changing properties to avoid collision. - var CloudCredentialList = {}; - jQuery.extend(true, CloudCredentialList, CredentialList); - CloudCredentialList.name = 'cloudcredentials', - CloudCredentialList.iterator = 'cloudcredential', - LookUpInit({ - url: GetBasePath('credentials') + '?cloud=true', - scope: scope, - form: form, - current_item: scope['cloud_credential'], - list: CloudCredentialList, - field: 'cloud_credential', - hdr: 'Select Cloud Credential' - }); - scope.$emit('jobTemplateLoadFinished'); - }); - - - // Retrieve each related set and populate the playbook list - if (scope.jobTemplateLoadedRemove) { - scope.jobTemplateLoadedRemove(); - } - scope.jobTemplateLoadedRemove = scope.$on('jobTemplateLoaded', function(e, related_cloud_credential) { - - getPlaybooks(scope.project); - - var dft = (scope['host_config_key'] === "" || scope['host_config_key'] === null) ? 'false' : 'true'; - md5Setup({ - scope: scope, - master: master, - check_field: 'allow_callbacks', - default_val: dft - }); - - if (related_cloud_credential) { - Rest.setUrl(related_cloud_credential); - Rest.get() - .success( function(data, status, headers, config) { - scope.$emit('cloudCredentialReady', data.name); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to related cloud credential. GET returned status: ' + status }); - }); - } - else { - // No existing cloud credential - scope.$emit('cloudCredentialReady', null); - } - }); - - Wait('start'); - // Retrieve detail record and prepopulate the form - Rest.setUrl(defaultUrl + ':id/'); - Rest.get({ params: {id: id} }) - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/job_templates/' + id, title: data.name }); - for (var fld in form.fields) { - if (fld != 'variables' && data[fld] !== null && data[fld] !== undefined) { - if (form.fields[fld].type == 'select') { - if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) { - for (var i=0; i < scope[fld + '_options'].length; i++) { - if (data[fld] == scope[fld + '_options'][i].value) { - scope[fld] = scope[fld + '_options'][i]; - } - } - } - else { - scope[fld] = data[fld]; - } - } - else { - scope[fld] = data[fld]; - } - master[fld] = scope[fld]; - } - if (fld == 'variables') { - // Parse extra_vars, converting to YAML. - if ($.isEmptyObject(data.extra_vars) || data.extra_vars == "\{\}" || data.extra_vars == "null" - || data.extra_vars == "" || data.extra_vars == null) { - scope.variables = "---"; - } - else { - var json_obj = JSON.parse(data.extra_vars); - scope.variables = jsyaml.safeDump(json_obj); - } - master.variables = scope.variables; - } - if (form.fields[fld].type == 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) { - scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; - master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField]; - } - } - - scope.url = data.url; - var related = data.related; - for (var set in form.related) { - if (related[set]) { - relatedSets[set] = { url: related[set], iterator: form.related[set].iterator }; - } - } - - scope['callback_url'] = data.related['callback']; - master['callback_url'] = scope['callback_url']; - - LookUpInit({ - scope: scope, - form: form, - current_item: data.inventory, - list: InventoryList, - field: 'inventory' - }); - - LookUpInit({ - url: GetBasePath('credentials') + '?kind=ssh', - scope: scope, - form: form, - current_item: data.credential, - list: CredentialList, - field: 'credential', - hdr: 'Select Machine Credential' - }); - - LookUpInit({ - scope: scope, - form: form, - current_item: data.project, - list: ProjectList, - field: 'project' - }); - - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); - RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); - scope.$emit('jobTemplateLoaded', data.related.cloud_credential); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve job template: ' + $routeParams.id + '. GET status: ' + status }); - }); - - // Save changes to the parent - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - var data = {} - try { - // Make sure we have valid variable data - if (scope.parseType == 'json') { - var json_data = JSON.parse(scope.variables); //make sure JSON parses - } - else { - var json_data = jsyaml.load(scope.variables); //parse yaml - } - - // Make sure our JSON is actually an object - if (typeof json_data !== 'object') { - throw "failed to return an object!"; - } - - for (var fld in form.fields) { - if (form.fields[fld].type == 'select' && fld != 'playbook') { - data[fld] = scope[fld].value; - } - else { - if (fld != 'variables' && fld != 'callback_url') { - data[fld] = scope[fld]; - } - } - } - - data.extra_vars = JSON.stringify(json_data, undefined, '\t'); - if (data.extra_vars == "null" || data.extra_vars == null) { - data.extra_vars = ""; - } - - Rest.setUrl(defaultUrl + id + '/'); - Rest.put(data) - .success( function(data, status, headers, config) { - Wait('stop'); - var base = $location.path().replace(/^\//,'').split('/')[0]; - (base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to update job template. PUT returned status: ' + status }); - }); - - } - catch(err) { - Wait('stop'); - Alert("Error", "Error parsing extra variables. Parser returned: " + err); - } - }; - - scope.showActivity = function() { Stream({ scope: scope }); } - - // Cancel - scope.formReset = function() { - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - scope.parseType = 'yaml'; - $('#forks-slider').slider("option", "value", scope.forks); - }; - - // Related set: Add button - scope.add = function(set) { - $rootScope.flashMessage = null; - $location.path('/' + base + '/' + $routeParams.id + '/' + set); - }; - - // Related set: Edit button - scope.edit = function(set, id, name) { - $rootScope.flashMessage = null; - $location.path('/' + set + '/' + id); - }; - - // Related set: Delete button - scope['delete'] = function(set, itm_id, name, title) { - $rootScope.flashMessage = null; - - var action = function() { - var url = defaultUrl + id + '/' + set + '/'; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - }; - - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', - action: action + // Detect and alert user to potential SCM status issues + checkSCMStatus = function (oldValue, newValue) { + if (oldValue !== newValue && !Empty(scope.project)) { + Rest.setUrl(GetBasePath('projects') + scope.project + '/'); + Rest.get() + .success(function (data) { + var msg; + switch (data.status) { + case 'failed': + msg = "The selected project has a failed status. Review the project's SCM settings" + + " and run an update before adding it to a template."; + break; + case 'never updated': + msg = 'The selected project has a never updated status. You will need to run a successful' + + ' update in order to selected a playbook. Without a valid playbook you will not be able ' + + ' to save this template.'; + break; + case 'missing': + msg = 'The selected project has a status of missing. Please check the server and make sure ' + + ' the directory exists and file permissions are set correctly.'; + break; + } + if (msg) { + Alert('Waning', msg, 'alert-info'); + } + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to get project ' + scope.project + '. GET returned status: ' + status + }); }); - - } + } + }; + + // Register a watcher on project_name + if (scope.selectPlaybookUnregister) { + scope.selectPlaybookUnregister(); + } + scope.selectPlaybookUnregister = scope.$watch('project_name', function (oldval, newval) { + selectPlaybook(oldval, newval); + checkSCMStatus(oldval, newval); + }); + + LookUpInit({ + scope: scope, + form: form, + current_item: null, + list: ProjectList, + field: 'project' + }); + + // Save + scope.formSave = function () { + generator.clearApiErrors(); + Wait('start'); + var data = {}, json_data, fld; + try { + // Make sure we have valid variable data + if (scope.parseType === 'json') { + json_data = JSON.parse(scope.variables); //make sure JSON parses + } else { + json_data = jsyaml.load(scope.variables); //parse yaml + } + + // Make sure our JSON is actually an object + if (typeof json_data !== 'object') { + throw "failed to return an object!"; + } + + for (fld in form.fields) { + if (form.fields[fld].type === 'select' && fld !== 'playbook') { + data[fld] = scope[fld].value; + } else { + if (fld !== 'variables') { + data[fld] = scope[fld]; + } + } + } + + data.extra_vars = JSON.stringify(json_data, undefined, '\t'); + if (Empty(data.extra_vars)) { + data.extra_vars = ""; + } + + Rest.setUrl(defaultUrl); + Rest.post(data) + .success(function () { + Wait('stop'); + var base = $location.path().replace(/^\//, '').split('/')[0]; + if (base === 'job_templates') { + ReturnToCaller(); + } + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to add new job template. POST returned status: ' + status + }); + }); + + } catch (err) { + Wait('stop'); + Alert("Error", "Error parsing extra variables. Parser returned: " + err); + } + }; + + // Reset + scope.formReset = function () { + // Defaults + generator.reset(); + //$('#forks-slider').slider("option", "value", scope.forks); + for (var fld in master) { + scope[fld] = master[fld]; + } + }; } -JobTemplatesEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', - 'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup', 'ParseTypeChange', - 'JobStatusToolTip', 'FormatDate', 'Wait', 'Stream', 'Empty' - ]; +JobTemplatesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', + 'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', + 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty' +]; + + +function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, GenerateForm, Rest, + Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, + CredentialList, ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, ParseTypeChange, JobStatusToolTip, FormatDate, + Wait, Stream, Empty, Prompt) { + + ClearScope('htmlTemplate'); + + var defaultUrl = GetBasePath('job_templates'), + generator = GenerateForm, + form = JobTemplateForm, + scope = generator.inject(form, { mode: 'edit', related: true }), + loadingFinishedCount = 0, + base = $location.path().replace(/^\//, '').split('/')[0], + master = {}, + id = $routeParams.id, + relatedSets = {}, + checkSCMStatus, getPlaybooks; + + scope.parseType = 'yaml'; + ParseTypeChange(scope); + + // Our job type options + scope.job_type_options = [ + { value: 'run', label: 'Run' }, + { value: 'check', label: 'Check' } + ]; + + scope.verbosity_options = [ + { value: '0', label: 'Default' }, + { value: '1', label: 'Verbose' }, + { value: '3', label: 'Debug' } + ]; + + scope.playbook_options = null; + scope.playbook = null; + generator.reset(); + + getPlaybooks = function (project) { + var url; + if (!Empty(project)) { + url = GetBasePath('projects') + project + '/playbooks/'; + Wait('start'); + Rest.setUrl(url); + Rest.get() + .success(function (data) { + var i; + scope.playbook_options = []; + for (i = 0; i < data.length; i++) { + scope.playbook_options.push(data[i]); + if (data[i] === scope.playbook) { + scope.job_templates_form.playbook.$setValidity('required', true); + } + } + if (scope.playbook) { + scope.$emit('jobTemplateLoadFinished'); + } else { + Wait('stop'); + } + }) + .error(function () { + Wait('stop'); + Alert('Missing Playbooks', 'Unable to retrieve the list of playbooks for this project. Choose a different ' + + ' project or make the playbooks available on the file system.', 'alert-info'); + }); + } + }; + + // Detect and alert user to potential SCM status issues + checkSCMStatus = function () { + if (!Empty(scope.project)) { + Wait('start'); + Rest.setUrl(GetBasePath('projects') + scope.project + '/'); + Rest.get() + .success(function (data) { + var msg; + switch (data.status) { + case 'failed': + msg = "The selected project has a failed status. Review the project's SCM settings" + + " and run an update before adding it to a template."; + break; + case 'never updated': + msg = 'The selected project has a never updated status. You will need to run a successful' + + ' update in order to selected a playbook. Without a valid playbook you will not be able ' + + ' to save this template.'; + break; + case 'missing': + msg = 'The selected project has a status of missing. Please check the server and make sure ' + + ' the directory exists and file permissions are set correctly.'; + break; + } + Wait('stop'); + if (msg) { + Alert('Waning', msg, 'alert-info'); + } + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to get project ' + scope.project + + '. GET returned status: ' + status }); + }); + } + }; + + + // Register a watcher on project_name. Refresh the playbook list on change. + if (scope.watchProjectUnregister) { + scope.watchProjectUnregister(); + } + scope.watchProjectUnregister = scope.$watch('project_name', function (oldValue, newValue) { + if (oldValue !== newValue && newValue !== '' && newValue !== null && newValue !== undefined) { + scope.playbook = null; + getPlaybooks(scope.project); + checkSCMStatus(); + } + }); + + // Turn off 'Wait' after both cloud credential and playbook list come back + if (scope.removeJobTemplateLoadFinished) { + scope.removeJobTemplateLoadFinished(); + } + scope.removeJobTemplateLoadFinished = scope.$on('jobTemplateLoadFinished', function () { + loadingFinishedCount++; + if (loadingFinishedCount >= 2) { + // The initial template load finished. Now load related jobs, which + // will turn off the 'working' spinner. + for (var set in relatedSets) { + scope.search(relatedSets[set].iterator); + } + + } + }); + + // Set the status/badge for each related job + if (scope.removeRelatedJobs) { + scope.removeRelatedJobs(); + } + scope.removeRelatedJobs = scope.$on('relatedjobs', function () { + var i, cDate; + if (scope.jobs && scope.jobs.length) { + for (i = 0; i < scope.jobs.length; i++) { + // Convert created date to local time zone + cDate = new Date(scope.jobs[i].created); + scope.jobs[i].created = FormatDate(cDate); + // Set tooltip and link + scope.jobs[i].statusBadgeToolTip = JobStatusToolTip(scope.jobs[i].status) + + " Click to view status details."; + scope.jobs[i].statusLinkTo = '/#/jobs/' + scope.jobs[i].id; + } + } + }); + + if (scope.cloudCredentialReadyRemove) { + scope.cloudCredentialReadyRemove(); + } + scope.cloudCredentialReadyRemove = scope.$on('cloudCredentialReady', function (e, name) { + var CloudCredentialList = {}; + scope.cloud_credential_name = name; + master.cloud_credential_name = name; + // Clone the CredentialList object for use with cloud_credential. Cloning + // and changing properties to avoid collision. + jQuery.extend(true, CloudCredentialList, CredentialList); + CloudCredentialList.name = 'cloudcredentials'; + CloudCredentialList.iterator = 'cloudcredential'; + LookUpInit({ + url: GetBasePath('credentials') + '?cloud=true', + scope: scope, + form: form, + current_item: scope.cloud_credential, + list: CloudCredentialList, + field: 'cloud_credential', + hdr: 'Select Cloud Credential' + }); + scope.$emit('jobTemplateLoadFinished'); + }); + + + // Retrieve each related set and populate the playbook list + if (scope.jobTemplateLoadedRemove) { + scope.jobTemplateLoadedRemove(); + } + scope.jobTemplateLoadedRemove = scope.$on('jobTemplateLoaded', function (e, related_cloud_credential) { + var dft; + getPlaybooks(scope.project); + + dft = (scope.host_config_key === "" || scope.host_config_key === null) ? 'false' : 'true'; + md5Setup({ + scope: scope, + master: master, + check_field: 'allow_callbacks', + default_val: dft + }); + + if (related_cloud_credential) { + Rest.setUrl(related_cloud_credential); + Rest.get() + .success(function (data) { + scope.$emit('cloudCredentialReady', data.name); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, {hdr: 'Error!', + msg: 'Failed to related cloud credential. GET returned status: ' + status }); + }); + } else { + // No existing cloud credential + scope.$emit('cloudCredentialReady', null); + } + }); + + Wait('start'); + // Retrieve detail record and prepopulate the form + Rest.setUrl(defaultUrl + ':id/'); + Rest.get({ params: { id: id } }) + .success(function (data) { + var fld, i, json_obj, related, set; + LoadBreadCrumbs({ path: '/job_templates/' + id, title: data.name }); + for (fld in form.fields) { + if (fld !== 'variables' && data[fld] !== null && data[fld] !== undefined) { + if (form.fields[fld].type === 'select') { + if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) { + for (i = 0; i < scope[fld + '_options'].length; i++) { + if (data[fld] === scope[fld + '_options'][i].value) { + scope[fld] = scope[fld + '_options'][i]; + } + } + } else { + scope[fld] = data[fld]; + } + } else { + scope[fld] = data[fld]; + } + master[fld] = scope[fld]; + } + if (fld === 'variables') { + // Parse extra_vars, converting to YAML. + if ($.isEmptyObject(data.extra_vars) || data.extra_vars === "{}" || data.extra_vars === "null" || + data.extra_vars === "" || data.extra_vars === null) { + scope.variables = "---"; + } else { + json_obj = JSON.parse(data.extra_vars); + scope.variables = jsyaml.safeDump(json_obj); + } + master.variables = scope.variables; + } + if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) { + scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = + data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; + master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = + scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField]; + } + } + + scope.url = data.url; + related = data.related; + for (set in form.related) { + if (related[set]) { + relatedSets[set] = { + url: related[set], + iterator: form.related[set].iterator + }; + } + } + + scope.callback_url = data.related.callback; + master.callback_url = scope.callback_url; + + LookUpInit({ + scope: scope, + form: form, + current_item: data.inventory, + list: InventoryList, + field: 'inventory' + }); + + LookUpInit({ + url: GetBasePath('credentials') + '?kind=ssh', + scope: scope, + form: form, + current_item: data.credential, + list: CredentialList, + field: 'credential', + hdr: 'Select Machine Credential' + }); + + LookUpInit({ + scope: scope, + form: form, + current_item: data.project, + list: ProjectList, + field: 'project' + }); + + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: scope, + relatedSets: relatedSets + }); + scope.$emit('jobTemplateLoaded', data.related.cloud_credential); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to retrieve job template: ' + $routeParams.id + '. GET status: ' + status + }); + }); + + // Save changes to the parent + scope.formSave = function () { + generator.clearApiErrors(); + Wait('start'); + var data = {}, json_data, fld; + try { + // Make sure we have valid variable data + if (scope.parseType === 'json') { + json_data = JSON.parse(scope.variables); //make sure JSON parses + } else { + json_data = jsyaml.load(scope.variables); //parse yaml + } + + // Make sure our JSON is actually an object + if (typeof json_data !== 'object') { + throw "failed to return an object!"; + } + + for (fld in form.fields) { + if (form.fields[fld].type === 'select' && fld !== 'playbook') { + data[fld] = scope[fld].value; + } else { + if (fld !== 'variables' && fld !== 'callback_url') { + data[fld] = scope[fld]; + } + } + } + + data.extra_vars = JSON.stringify(json_data, undefined, '\t'); + if (data.extra_vars === "null" || data.extra_vars === null) { + data.extra_vars = ""; + } + + Rest.setUrl(defaultUrl + id + '/'); + Rest.put(data) + .success(function () { + Wait('stop'); + var base = $location.path().replace(/^\//, '').split('/')[0]; + if (base === 'job_templates') { + ReturnToCaller(); + } + ReturnToCaller(1); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to update job template. PUT returned status: ' + status + }); + }); + + } catch (err) { + Wait('stop'); + Alert("Error", "Error parsing extra variables. Parser returned: " + err); + } + }; + + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; + + // Cancel + scope.formReset = function () { + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + scope.parseType = 'yaml'; + $('#forks-slider').slider("option", "value", scope.forks); + }; + + // Related set: Add button + scope.add = function (set) { + $rootScope.flashMessage = null; + $location.path('/' + base + '/' + $routeParams.id + '/' + set); + }; + + // Related set: Edit button + scope.edit = function (set, id) { + $rootScope.flashMessage = null; + $location.path('/' + set + '/' + id); + }; + + // Related set: Delete button + scope['delete'] = function (set, itm_id, name, title) { + $rootScope.flashMessage = null; + + var action = function () { + var url = defaultUrl + id + '/' + set + '/'; + Rest.setUrl(url); + Rest.post({ + id: itm_id, + disassociate: 1 + }) + .success(function () { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. POST returned status: ' + status + }); + }); + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', + action: action + }); + + }; +} + +JobTemplatesEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', + 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'PromptPasswords', + 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'JobStatusToolTip', 'FormatDate', 'Wait', 'Stream', 'Empty', 'Prompt' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Jobs.js b/awx/ui/static/js/controllers/Jobs.js index e652b3b886..1335709118 100644 --- a/awx/ui/static/js/controllers/Jobs.js +++ b/awx/ui/static/js/controllers/Jobs.js @@ -3,21 +3,19 @@ * * * Jobs.js - * + * * Controller functions for the Job model. * */ - /* global jsyaml:false */ - 'use strict'; -function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobList, GenerateList, LoadBreadCrumbs, Prompt, +function JobsListCtrl($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, LookUpInit, SubmitJob, FormatDate, Refresh, JobStatusToolTip, Empty, Wait) { ClearScope('htmlTemplate'); - + var list = JobList, defaultUrl = GetBasePath('jobs'), view = GenerateList, @@ -26,19 +24,19 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, $rootScope.flashMessage = null; scope.selected = []; - + if (scope.removePostRefresh) { scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { - var i,cDate; - $("tr.success").each(function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { + var i, cDate; + $("tr.success").each(function () { // Make sure no rows have a green background var ngc = $(this).attr('ng-class'); scope[ngc] = ""; }); if (scope.jobs && scope.jobs.length) { - for (i=0; i < scope.jobs.length; i++) { + for (i = 0; i < scope.jobs.length; i++) { // Convert created date to local time zone cDate = new Date(scope.jobs[i].created); scope.jobs[i].created = FormatDate(cDate); @@ -49,17 +47,25 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, } } }); - + if ($routeParams.job_host_summaries__host) { defaultUrl += '?job_host_summaries__host=' + $routeParams.job_host_summaries__host; - } - else if ($routeParams.inventory__int && $routeParams.status) { + } else if ($routeParams.inventory__int && $routeParams.status) { defaultUrl += '?inventory__int=' + $routeParams.inventory__int + '&status=' + $routeParams.status; } - SearchInit({ scope: scope, set: 'jobs', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + SearchInit({ + scope: scope, + set: 'jobs', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); // Called from Inventories page, failed jobs link. Find jobs for selected inventory. if ($routeParams.inventory__int) { @@ -76,7 +82,7 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, scope[list.iterator + 'SearchField'] = 'status'; scope[list.iterator + 'SelectShow'] = true; scope[list.iterator + 'SearchSelectOpts'] = list.fields.status.searchOptions; - scope[list.iterator + 'SearchFieldLabel'] = list.fields.status.label.replace(/
/g,' '); + scope[list.iterator + 'SearchFieldLabel'] = list.fields.status.label.replace(/
/g, ' '); for (opt in list.fields.status.searchOptions) { if (list.fields.status.searchOptions[opt].value === $routeParams.status) { scope[list.iterator + 'SearchSelectValue'] = list.fields.status.searchOptions[opt]; @@ -89,71 +95,83 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, LoadBreadCrumbs(); - scope.refresh = function() { + scope.refresh = function () { Wait('start'); scope.jobLoading = false; - Refresh({ scope: scope, set: 'jobs', iterator: 'job', url: scope.current_url }); + Refresh({ + scope: scope, + set: 'jobs', + iterator: 'job', + url: scope.current_url + }); }; scope.refreshJob = scope.refresh; - scope.editJob = function(id, name) { - LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name }); + scope.editJob = function (id, name) { + LoadBreadCrumbs({ + path: '/jobs/' + id, + title: id + ' - ' + name + }); $location.path($location.path() + '/' + id); }; - scope.viewEvents = function(id, name) { - LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name }); + scope.viewEvents = function (id, name) { + LoadBreadCrumbs({ + path: '/jobs/' + id, + title: id + ' - ' + name + }); $location.path($location.path() + '/' + id + '/job_events'); }; - scope.viewSummary = function(id, name) { - LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name }); + scope.viewSummary = function (id, name) { + LoadBreadCrumbs({ + path: '/jobs/' + id, + title: id + ' - ' + name + }); $location.path($location.path() + '/' + id + '/job_host_summaries'); }; - scope.deleteJob = function(id) { + scope.deleteJob = function (id) { Rest.setUrl(defaultUrl + id + '/'); Rest.get() - .success( function(data) { - + .success(function (data) { + var action, url, action_label, hdr; - + if (data.status === 'pending' || data.status === 'running' || data.status === 'waiting') { url = data.related.cancel; action_label = 'cancel'; hdr = 'Cancel Job'; - } - else { + } else { url = defaultUrl + id + '/'; action_label = 'delete'; hdr = 'Delete Job'; } - action = function() { + action = function () { Rest.setUrl(url); if (action_label === 'cancel') { Rest.post() - .success( function() { + .success(function () { $('#prompt-modal').modal('hide'); scope.search(list.iterator); }) - .error( function(data, status) { + .error(function (data, status) { $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + + ' failed. POST returned status: ' + status }); }); - } - else { + } else { Rest.destroy() - .success( function() { + .success(function () { $('#prompt-modal').modal('hide'); scope.search(list.iterator); }) - .error( function(data, status) { + .error(function (data, status) { $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + + ' failed. DELETE returned status: ' + status }); }); } }; @@ -164,40 +182,46 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, action: action }); }) - .error( function(data, status) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get job details. GET returned status: ' + status }); + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get job details. GET returned status: ' + status }); }); }; - - scope.submitJob = function(id, template) { - SubmitJob({ scope: scope, id: id, template: template }); + + scope.submitJob = function (id, template) { + SubmitJob({ + scope: scope, + id: id, + template: template + }); }; } -JobsListCtrl.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobList', - 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', - 'ProcessErrors','GetBasePath', 'LookUpInit', 'SubmitJob', 'FormatDate', 'Refresh', 'JobStatusToolTip', - 'Empty', 'Wait' - ]; +JobsListCtrl.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', + 'ProcessErrors', 'GetBasePath', 'LookUpInit', 'SubmitJob', 'FormatDate', 'Refresh', 'JobStatusToolTip', + 'Empty', 'Wait' +]; -function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobForm, GenerateForm, Rest, Alert, ProcessErrors, - LoadBreadCrumbs, RelatedSearchInit,RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList, +function JobsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobForm, GenerateForm, Rest, Alert, ProcessErrors, + LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList, ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, FormatDate, JobStatusToolTip, Wait) { - - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - var defaultUrl= GetBasePath('jobs'), + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + + var defaultUrl = GetBasePath('jobs'), generator = GenerateForm, form = JobForm, - scope = generator.inject(form, {mode: 'edit', related: true}), + scope = generator.inject(form, { + mode: 'edit', + related: true + }), master = {}, id = $routeParams.id, relatedSets = {}, loadingFinishedCount = 0; - + generator.reset(); scope.job_id = id; @@ -209,18 +233,17 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, var url = GetBasePath('projects') + project + '/playbooks/'; Rest.setUrl(url); Rest.get() - .success( function(data) { + .success(function (data) { scope.playbook_options = []; - for (var i=0; i < data.length; i++) { + for (var i = 0; i < data.length; i++) { scope.playbook_options.push(data[i]); } scope.$emit('jobTemplateLoadFinished'); }) - .error( function() { + .error(function () { scope.$emit('jobTemplateLoadFinished'); }); - } - else { + } else { scope.$emit('jobTemplateLoadFinished'); } } @@ -230,23 +253,23 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, if (scope.jobLoadedRemove) { scope.jobLoadedRemove(); } - scope.jobLoadedRemove = scope.$on('jobLoaded', function(e, related_cloud_credential) { - + scope.jobLoadedRemove = scope.$on('jobLoaded', function (e, related_cloud_credential) { + getPlaybooks(scope.project); scope[form.name + 'ReadOnly'] = (scope.status === 'new') ? false : true; - + $('#forks-slider').slider("option", "value", scope.forks); $('#forks-slider').slider("disable"); - $('input[type="checkbox"]').attr('disabled','disabled'); - $('input[type="radio"]').attr('disabled','disabled'); - $('#host_config_key-gen-btn').attr('disabled','disabled'); - $('textarea').attr('readonly','readonly'); + $('input[type="checkbox"]').attr('disabled', 'disabled'); + $('input[type="radio"]').attr('disabled', 'disabled'); + $('#host_config_key-gen-btn').attr('disabled', 'disabled'); + $('textarea').attr('readonly', 'readonly'); // Get job template and display/hide host callback fields Rest.setUrl(scope.template_url); Rest.get() - .success( function(data) { + .success(function (data) { var dft = (data.host_config_key) ? 'true' : 'false'; scope.host_config_key = data.host_config_key; md5Setup({ @@ -258,7 +281,7 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, scope.callback_url = (data.related) ? data.related.callback : '<< Job template not found >>'; scope.$emit('jobTemplateLoadFinished'); }) - .error( function() { + .error(function () { Wait('stop'); scope.callback_url = '<< Job template not found >>'; }); @@ -267,16 +290,17 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, //Get the name of the cloud credential Rest.setUrl(related_cloud_credential); Rest.get() - .success( function(data) { + .success(function (data) { scope.cloud_credential_name = data.name; scope.$emit('jobTemplateLoadFinished'); }) - .error( function(data, status) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to related cloud credential. GET returned status: ' + status }); + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Failed to related cloud credential. GET returned status: ' + status + }); }); - } - else { + } else { scope.$emit('jobTemplateLoadFinished'); } }); @@ -285,7 +309,7 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, if (scope.removeJobTemplateLoadFinished) { scope.removeJobTemplateLoadFinished(); } - scope.removeJobTemplateLoadFinished = scope.$on('jobTemplateLoadFinished', function() { + scope.removeJobTemplateLoadFinished = scope.$on('jobTemplateLoadFinished', function () { loadingFinishedCount++; if (loadingFinishedCount >= 3) { // The initial template load finished. Now load related jobs, which @@ -295,16 +319,27 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, }); // Our job type options - scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }]; - scope.verbosity_options = [ - { value: '0', label: 'Default' }, - { value: '1', label: 'Verbose' }, - { value: '3', label: 'Debug' } - ]; + scope.job_type_options = [{ + value: 'run', + label: 'Run' + }, { + value: 'check', + label: 'Check' + }]; + scope.verbosity_options = [{ + value: '0', + label: 'Default' + }, { + value: '1', + label: 'Verbose' + }, { + value: '3', + label: 'Debug' + }]; scope.playbook_options = null; scope.playbook = null; - function calcRows (content) { + function calcRows(content) { var n = content.match(/\n/g), rows = (n) ? n.length : 1; return (rows > 15) ? 15 : rows; @@ -313,8 +348,8 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, // Retrieve detail record and prepopulate the form Wait('start'); Rest.setUrl(defaultUrl + ':id/'); - Rest.get({ params: {id: id} }) - .success( function(data) { + Rest.get({ params: { id: id } }) + .success(function (data) { //LoadBreadCrumbs({ path: '/jobs/' + id, title: data.id + ' - ' + data.summary_fields.job_template.name }); var i, cDate, fld, json_obj, related, set; LoadBreadCrumbs(); @@ -322,23 +357,21 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, if (fld !== 'variables' && data[fld] !== null && data[fld] !== undefined) { if (form.fields[fld].type === 'select') { if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) { - for (i=0; i < scope[fld + '_options'].length; i++) { + for (i = 0; i < scope[fld + '_options'].length; i++) { if (data[fld] === scope[fld + '_options'][i].value) { scope[fld] = scope[fld + '_options'][i]; } } - } - else { + } else { scope[fld] = data[fld]; } } - } - else { + } else { scope[fld] = data[fld]; } master[fld] = scope[fld]; } - + scope.id = data.id; scope.name = (data.summary_fields && data.summary_fields.job_template) ? data.summary_fields.job_template.name : ''; @@ -347,8 +380,7 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, if ($.isEmptyObject(data.extra_vars) || data.extra_vars === "{}" || data.extra_vars === "null" || data.extra_vars === "" || data.extra_vars === null) { scope.variables = "---"; - } - else { + } else { json_obj = JSON.parse(data.extra_vars); scope.variables = jsyaml.safeDump(json_obj); } @@ -360,23 +392,22 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField]; } - + for (fld in form.statusFields) { if (data[fld] !== null && data[fld] !== undefined) { if (fld === 'created') { // Convert created date to local time zone cDate = new Date(data.created); scope.created = FormatDate(cDate); - } - else { + } else { scope[fld] = data[fld]; } } } scope.statusToolTip = JobStatusToolTip(data.status); - - $('form[name="jobs_form"] input[type="text"], form[name="jobs_form"] jobs_form textarea').attr('readonly','readonly'); + + $('form[name="jobs_form"] input[type="text"], form[name="jobs_form"] jobs_form textarea').attr('readonly', 'readonly'); $('form[name="jobs_form"] select').prop('disabled', 'disabled'); $('form[name="jobs_form"] .lookup-btn').prop('disabled', 'disabled'); $('form[name="jobs_form"] .buttons, form[name="jobs_form"] hr').hide(); @@ -385,12 +416,15 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, related = data.related; for (set in form.related) { if (related[set]) { - relatedSets[set] = { url: related[set], iterator: form.related[set].iterator }; + relatedSets[set] = { + url: related[set], + iterator: form.related[set].iterator + }; } } scope.stdout_rows = calcRows(scope.result_stdout); - + scope.traceback_rows = calcRows(scope.result_traceback); LookUpInit({ @@ -418,21 +452,30 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, }); // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); - RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); + RelatedSearchInit({ + scope: scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: scope, + relatedSets: relatedSets + }); scope.template_url = data.related.job_template; scope.$emit('jobLoaded', data.related.cloud_credential); }) - .error( function(data, status) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve job: ' + $routeParams.id + '. GET status: ' + status }); + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to retrieve job: ' + $routeParams.id + '. GET status: ' + status + }); }); - scope.refresh = function() { + scope.refresh = function () { Wait('start'); Rest.setUrl(defaultUrl + id + '/'); Rest.get() - .success( function(data) { + .success(function (data) { scope.status = data.status; scope.result_stdout = data.result_stdout; scope.result_traceback = data.result_traceback; @@ -440,25 +483,26 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, scope.traceback_rows = calcRows(scope.result_traceback); Wait('stop'); }) - .error( function(data, status) { + .error(function (data, status) { Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Attempt to load job failed. GET returned status: ' + status }); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Attempt to load job failed. GET returned status: ' + status + }); }); }; - scope.jobSummary = function() { + scope.jobSummary = function () { $location.path('/jobs/' + id + '/job_host_summaries'); }; - scope.jobEvents = function() { + scope.jobEvents = function () { $location.path('/jobs/' + id + '/job_events'); }; } -JobsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', - 'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup', 'FormatDate', - 'JobStatusToolTip', 'Wait' - ]; +JobsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', + 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'PromptPasswords', + 'GetBasePath', 'md5Setup', 'FormatDate', 'JobStatusToolTip', 'Wait' +]; diff --git a/awx/ui/static/js/controllers/Organizations.js b/awx/ui/static/js/controllers/Organizations.js index 6e78ccd111..6ebfce7ac6 100644 --- a/awx/ui/static/js/controllers/Organizations.js +++ b/awx/ui/static/js/controllers/Organizations.js @@ -3,276 +3,327 @@ * * * Organizations.js - * + * * Controller functions for Organization model. * */ 'use strict'; -function OrganizationsList ($routeParams, $scope, $rootScope, $location, $log, Rest, Alert, LoadBreadCrumbs, Prompt, - GenerateList, OrganizationList, SearchInit, PaginateInit, ClearScope, ProcessErrors, - GetBasePath, SelectionInit, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function OrganizationsList($routeParams, $scope, $rootScope, $location, $log, Rest, Alert, LoadBreadCrumbs, Prompt, + GenerateList, OrganizationList, SearchInit, PaginateInit, ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait, Stream) { + + ClearScope('htmlTemplate'); - var list = OrganizationList; - var generate = GenerateList; - var paths = $location.path().replace(/^\//,'').split('/'); - var mode = (paths[0] == 'organizations') ? 'edit' : 'select'; // if base path 'users', we're here to add/edit users - var scope = generate.inject(OrganizationList, { mode: mode }); // Inject our view - var defaultUrl = GetBasePath('organizations'); - var iterator = list.iterator; + var list = OrganizationList, + generate = GenerateList, + paths = $location.path().replace(/^\//, '').split('/'), + mode = (paths[0] === 'organizations') ? 'edit' : 'select', // if base path 'users', we're here to add/edit users + scope = generate.inject(OrganizationList, { mode: mode }), + defaultUrl = GetBasePath('organizations'), + url; + $rootScope.flashMessage = null; LoadBreadCrumbs(); - - var url = GetBasePath('projects') + $routeParams.project_id + '/organizations/'; - SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); + + url = GetBasePath('projects') + $routeParams.project_id + '/organizations/'; + SelectionInit({ + scope: scope, + list: list, + url: url, + returnToCaller: 1 + }); if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Cleanup after a delete Wait('stop'); $('#prompt-modal').off(); - }); - + }); + // Initialize search and paginate pieces and load data - SearchInit({ scope: scope, set: list.name, list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + SearchInit({ + scope: scope, + set: list.name, + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); scope.search(list.iterator); - scope.showActivity = function() { Stream({ scope: scope }); } + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - scope.addOrganization = function() { - $location.path($location.path() + '/add'); - } + scope.addOrganization = function () { + $location.path($location.path() + '/add'); + }; - scope.editOrganization = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deleteOrganization = function(id, name) { - - var action = function() { - $('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); }); - $('#prompt-modal').modal('hide'); - var url = defaultUrl + id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + scope.editOrganization = function (id) { + $location.path($location.path() + '/' + id); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action + scope.deleteOrganization = function (id, name) { + + var action = function () { + $('#prompt-modal').on('hidden.bs.modal', function () { + Wait('start'); + }); + $('#prompt-modal').modal('hide'); + var url = defaultUrl + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + scope.search(list.iterator); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status + }); }); - } + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + }; } -OrganizationsList.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', '$log', 'Rest', 'Alert', 'LoadBreadCrumbs', 'Prompt', - 'GenerateList', 'OrganizationList', 'SearchInit', 'PaginateInit', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'SelectionInit', 'Wait', 'Stream']; +OrganizationsList.$inject = ['$routeParams', '$scope', '$rootScope', '$location', '$log', 'Rest', 'Alert', 'LoadBreadCrumbs', 'Prompt', + 'GenerateList', 'OrganizationList', 'SearchInit', 'PaginateInit', 'ClearScope', 'ProcessErrors', + 'GetBasePath', 'SelectionInit', 'Wait', 'Stream' +]; -function OrganizationsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, - ReturnToCaller, Wait) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function OrganizationsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, + ReturnToCaller, Wait) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - // Inject dynamic view - var generator = GenerateForm; - var form = OrganizationForm; - var scope = generator.inject(form, {mode: 'add', related: false}); - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath('organizations'); - generator.reset(); + // Inject dynamic view + var generator = GenerateForm, + form = OrganizationForm, + scope = generator.inject(form, { mode: 'add', related: false }), + base = $location.path().replace(/^\//, '').split('/')[0]; + + generator.reset(); - LoadBreadCrumbs(); + LoadBreadCrumbs(); - // Save - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - var url = GetBasePath(base); - url += (base != 'organizations') ? $routeParams['project_id'] + '/organizations/' : ''; - Rest.setUrl(url); - Rest.post({ name: $scope.name, - description: $scope.description }) - .success( function(data, status, headers, config) { - Wait('stop'); - if (base == 'organizations') { - $rootScope.flashMessage = "New organization successfully created!"; - $location.path('/organizations/' + data.id); - } - else { - ReturnToCaller(1); - } - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to add new organization. Post returned status: ' + status }); - }); - }; - - // Cancel - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - }; -} - -OrganizationsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', - 'ReturnToCaller', 'Wait']; - - -function OrganizationsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, Prompt, ClearScope, GetBasePath, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - - // Inject dynamic view - var form = OrganizationForm; - var generator = GenerateForm; - var scope = GenerateForm.inject(form, {mode: 'edit', related: true}); - generator.reset(); - - var defaultUrl = GetBasePath('organizations'); - var base = $location.path().replace(/^\//,'').split('/')[0]; - var master = {}; - var id = $routeParams.organization_id; - var relatedSets = {}; - - // After the Organization is loaded, retrieve each related set - if (scope.organizationLoadedRemove) { - scope.organizationLoadedRemove(); - } - scope.organizationLoadedRemove = scope.$on('organizationLoaded', function() { - for (var set in relatedSets) { - scope.search(relatedSets[set].iterator); - } - Wait('stop'); - }); - - // Retrieve detail record and prepopulate the form - Wait('start'); - Rest.setUrl(defaultUrl + id + '/'); - Rest.get() - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/organizations/' + id, title: data.name }); - for (var fld in form.fields) { - if (data[fld]) { - scope[fld] = data[fld]; - master[fld] = data[fld]; - } - } - var related = data.related; - for (var set in form.related) { - if (related[set]) { - relatedSets[set] = { url: related[set], iterator: form.related[set].iterator }; - } - } - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); - RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); - scope.$emit('organizationLoaded'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve organization: ' + $routeParams.id + '. GET status: ' + status }); - }); - - - // Save changes to the parent - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - var params = {}; - for (var fld in form.fields) { - params[fld] = scope[fld]; - } - Rest.setUrl(defaultUrl + id + '/'); - Rest.put(params) - .success( function(data, status, headers, config) { - Wait('stop'); - master = params; - $rootScope.flashMessage = "Your changes were successfully saved!"; - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, OrganizationForm, - { hdr: 'Error!', msg: 'Failed to update organization: ' + id + '. PUT status: ' + status }); - }); - }; - - scope.showActivity = function() { Stream({ scope: scope }); } - - // Reset the form - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - }; - - // Related set: Add button - scope.add = function(set) { - $rootScope.flashMessage = null; - $location.path('/' + base + '/' + $routeParams.organization_id + '/' + set); - }; - - // Related set: Edit button - scope.edit = function(set, id, name) { - $rootScope.flashMessage = null; - $location.path('/' + set + '/' + id); - }; - - // Related set: Delete button - scope['delete'] = function(set, itm_id, name, title) { - $rootScope.flashMessage = null; - - var action = function() { - Wait('start'); - var url = defaultUrl + $routeParams.organization_id + '/' + set + '/'; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - Wait('stop'); - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - }; - - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', - action: action + // Save + scope.formSave = function () { + generator.clearApiErrors(); + Wait('start'); + var url = GetBasePath(base); + url += (base !== 'organizations') ? $routeParams.project_id + '/organizations/' : ''; + Rest.setUrl(url); + Rest.post({ + name: $scope.name, + description: $scope.description + }) + .success(function (data) { + Wait('stop'); + if (base === 'organizations') { + $rootScope.flashMessage = "New organization successfully created!"; + $location.path('/organizations/' + data.id); + } else { + ReturnToCaller(1); + } + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to add new organization. Post returned status: ' + status }); - - } + }); + }; + + // Cancel + scope.formReset = function () { + $rootScope.flashMessage = null; + generator.reset(); + }; } -OrganizationsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath', 'Wait', 'Stream']; +OrganizationsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', + 'ReturnToCaller', 'Wait' +]; + + +function OrganizationsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, + RelatedPaginateInit, Prompt, ClearScope, GetBasePath, Wait, Stream) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + + // Inject dynamic view + var form = OrganizationForm, + generator = GenerateForm, + scope = GenerateForm.inject(form, { mode: 'edit', related: true }), + defaultUrl = GetBasePath('organizations'), + base = $location.path().replace(/^\//, '').split('/')[0], + master = {}, + id = $routeParams.organization_id, + relatedSets = {}; + + generator.reset(); + + // After the Organization is loaded, retrieve each related set + if (scope.organizationLoadedRemove) { + scope.organizationLoadedRemove(); + } + scope.organizationLoadedRemove = scope.$on('organizationLoaded', function () { + for (var set in relatedSets) { + scope.search(relatedSets[set].iterator); + } + Wait('stop'); + }); + + // Retrieve detail record and prepopulate the form + Wait('start'); + Rest.setUrl(defaultUrl + id + '/'); + Rest.get() + .success(function (data) { + var fld, related, set; + LoadBreadCrumbs({ path: '/organizations/' + id, title: data.name }); + for (fld in form.fields) { + if (data[fld]) { + scope[fld] = data[fld]; + master[fld] = data[fld]; + } + } + related = data.related; + for (set in form.related) { + if (related[set]) { + relatedSets[set] = { + url: related[set], + iterator: form.related[set].iterator + }; + } + } + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: scope, + relatedSets: relatedSets + }); + scope.$emit('organizationLoaded'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to retrieve organization: ' + $routeParams.id + '. GET status: ' + status + }); + }); + + + // Save changes to the parent + scope.formSave = function () { + var fld, params = {}; + generator.clearApiErrors(); + Wait('start'); + for (fld in form.fields) { + params[fld] = scope[fld]; + } + Rest.setUrl(defaultUrl + id + '/'); + Rest.put(params) + .success(function () { + Wait('stop'); + master = params; + $rootScope.flashMessage = "Your changes were successfully saved!"; + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, OrganizationForm, { + hdr: 'Error!', + msg: 'Failed to update organization: ' + id + '. PUT status: ' + status + }); + }); + }; + + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; + + // Reset the form + scope.formReset = function () { + $rootScope.flashMessage = null; + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + }; + + // Related set: Add button + scope.add = function (set) { + $rootScope.flashMessage = null; + $location.path('/' + base + '/' + $routeParams.organization_id + '/' + set); + }; + + // Related set: Edit button + scope.edit = function (set, id) { + $rootScope.flashMessage = null; + $location.path('/' + set + '/' + id); + }; + + // Related set: Delete button + scope['delete'] = function (set, itm_id, name, title) { + $rootScope.flashMessage = null; + + var action = function () { + Wait('start'); + var url = defaultUrl + $routeParams.organization_id + '/' + set + '/'; + Rest.setUrl(url); + Rest.post({ + id: itm_id, + disassociate: 1 + }) + .success(function () { + Wait('stop'); + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + Wait('stop'); + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. POST returned status: ' + status + }); + }); + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', + action: action + }); + + }; +} + +OrganizationsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', + 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath', 'Wait', 'Stream' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Permissions.js b/awx/ui/static/js/controllers/Permissions.js index 5bacac093a..14b018d442 100644 --- a/awx/ui/static/js/controllers/Permissions.js +++ b/awx/ui/static/js/controllers/Permissions.js @@ -3,310 +3,331 @@ * * * Permissions.js - * + * * Controller functions for Permissions model. * */ - + 'use strict'; -function PermissionsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, PermissionList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, CheckAccess, Wait) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - var list = PermissionList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath(base); - defaultUrl += ($routeParams['user_id'] !== undefined) ? $routeParams['user_id'] : $routeParams['team_id']; +function PermissionsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, PermissionList, + GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, + GetBasePath, CheckAccess, Wait) { + + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + + //scope. + var list = PermissionList, + base = $location.path().replace(/^\//, '').split('/')[0], + defaultUrl = GetBasePath(base), + view = GenerateList, + scope = view.inject(list, { mode: 'edit' }); // Inject our view + + defaultUrl += ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id; defaultUrl += '/permissions/'; - - var view = GenerateList; - var scope = view.inject(list, { mode: 'edit' }); // Inject our view + scope.selected = []; - - CheckAccess({ scope: scope }); - + + CheckAccess({ + scope: scope + }); + if (scope.removePostRefresh) { scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Cleanup after a delete Wait('stop'); $('#prompt-modal').off(); - }); + }); - SearchInit({ scope: scope, set: 'permissions', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + SearchInit({ + scope: scope, + set: 'permissions', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); scope.search(list.iterator); LoadBreadCrumbs(); - scope.addPermission = function() { - if (scope.PermissionAddAllowed) { - $location.path($location.path() + '/add'); - } - } + scope.addPermission = function () { + if (scope.PermissionAddAllowed) { + $location.path($location.path() + '/add'); + } + }; - scope.editPermission = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deletePermission = function(id, name) { - var action = function() { - $('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); }); - $('#prompt-modal').modal('hide'); - var url = GetBasePath('base') + 'permissions/' + id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; - - if (scope.PermissionAddAllowed) { - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action + scope.editPermission = function (id) { + $location.path($location.path() + '/' + id); + }; + + scope.deletePermission = function (id, name) { + var action = function () { + $('#prompt-modal').on('hidden.bs.modal', function () { + Wait('start'); + }); + $('#prompt-modal').modal('hide'); + var url = GetBasePath('base') + 'permissions/' + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + scope.search(list.iterator); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - } - } + }); + }; + + if (scope.PermissionAddAllowed) { + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + } + }; } -PermissionsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'PermissionList', - 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', - 'ClearScope', 'ProcessErrors', 'GetBasePath', 'CheckAccess', 'Wait' - ]; +PermissionsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'PermissionList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', + 'ClearScope', 'ProcessErrors', 'GetBasePath', 'CheckAccess', 'Wait' +]; -function PermissionsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, - GetBasePath, ReturnToCaller, InventoryList, ProjectList, LookUpInit, CheckAccess, - Wait, PermissionCategoryChange) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function PermissionsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, + GetBasePath, ReturnToCaller, InventoryList, ProjectList, LookUpInit, CheckAccess, + Wait, PermissionCategoryChange) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - // Inject dynamic view - var form = PermissionsForm; - var generator = GenerateForm; - var id = ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath(base) + id + '/permissions'; - var scope = generator.inject(form, {mode: 'add', related: false}); - var master = {}; - - CheckAccess({ scope: scope }) - generator.reset(); - LoadBreadCrumbs(); - - scope['inventoryrequired'] = true; - scope['projectrequired'] = false; - scope.category = 'Inventory'; - master.category = 'Inventory'; - master.inventoryrequired = true; - master.projectrequired = false; - - LookUpInit({ - scope: scope, - form: form, - current_item: null, - list: InventoryList, - field: 'inventory' - }); + // Inject dynamic view + var form = PermissionsForm, + generator = GenerateForm, + id = ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id, + base = $location.path().replace(/^\//, '').split('/')[0], + scope = generator.inject(form, { mode: 'add', related: false }), + master = {}; - LookUpInit({ - scope: scope, - form: form, - current_item: null, - list: ProjectList, - field: 'project' - }); + CheckAccess({ scope: scope }); + generator.reset(); + LoadBreadCrumbs(); - // Save - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - if (scope.PermissionAddAllowed) { - var data = {}; - for (var fld in form.fields) { - data[fld] = scope[fld]; - } - var url = (base == 'teams') ? GetBasePath('teams') + id + '/permissions/' : GetBasePath('users') + id + '/permissions/'; - Rest.setUrl(url); - Rest.post(data) - .success( function(data, status, headers, config) { - Wait('stop'); - ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, PermissionsForm, - { hdr: 'Error!', msg: 'Failed to create new permission. Post returned status: ' + status }); - }); - } - else { - Alert('Access Denied', 'You do not have access to create new permission objects. Please contact a system administrator.', 'alert-danger'); - } - }; + scope.inventoryrequired = true; + scope.projectrequired = false; + scope.category = 'Inventory'; + master.category = 'Inventory'; + master.inventoryrequired = true; + master.projectrequired = false; - // Cancel - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - scope.selectCategory(); - }; - - scope.selectCategory = function() { PermissionCategoryChange({ scope: scope, reset: true }); }; - + LookUpInit({ + scope: scope, + form: form, + current_item: null, + list: InventoryList, + field: 'inventory' + }); - scope.selectCategory(); + LookUpInit({ + scope: scope, + form: form, + current_item: null, + list: ProjectList, + field: 'project' + }); + + // Save + scope.formSave = function () { + var fld, url, data = {}; + generator.clearApiErrors(); + Wait('start'); + if (scope.PermissionAddAllowed) { + data = {}; + for (fld in form.fields) { + data[fld] = scope[fld]; + } + url = (base === 'teams') ? GetBasePath('teams') + id + '/permissions/' : GetBasePath('users') + id + '/permissions/'; + Rest.setUrl(url); + Rest.post(data) + .success(function () { + Wait('stop'); + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, PermissionsForm, { + hdr: 'Error!', + msg: 'Failed to create new permission. Post returned status: ' + status + }); + }); + } else { + Alert('Access Denied', 'You do not have access to create new permission objects. Please contact a system administrator.', + 'alert-danger'); + } + }; + + // Cancel + scope.formReset = function () { + $rootScope.flashMessage = null; + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + scope.selectCategory(); + }; + + scope.selectCategory = function () { + PermissionCategoryChange({ + scope: scope, + reset: true + }); + }; + + + scope.selectCategory(); } -PermissionsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionsForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', - 'ReturnToCaller', 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', - 'PermissionCategoryChange' - ]; +PermissionsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionsForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', 'ReturnToCaller', + 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', 'PermissionCategoryChange' +]; -function PermissionsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, - ClearScope, Prompt, GetBasePath, InventoryList, ProjectList, LookUpInit, CheckAccess, - Wait, PermissionCategoryChange) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function PermissionsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, + ClearScope, Prompt, GetBasePath, InventoryList, ProjectList, LookUpInit, CheckAccess, + Wait, PermissionCategoryChange) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - var generator = GenerateForm; - var form = PermissionsForm; - var scope = generator.inject(form, {mode: 'edit', related: true}); - var base_id = ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var id = $routeParams.permission_id; - var defaultUrl = GetBasePath('base') + 'permissions/' + id + '/'; - generator.reset(); + var generator = GenerateForm, + form = PermissionsForm, + scope = generator.inject(form, { mode: 'edit', related: true }), + base_id = ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id, + id = $routeParams.permission_id, + defaultUrl = GetBasePath('base') + 'permissions/' + id + '/', + master = {}; - var master = {}; - var relatedSets = {}; - - CheckAccess({ scope: scope }); + generator.reset(); - scope.selectCategory = function(resetIn) { - var reset = (resetIn == false) ? false : true; - PermissionCategoryChange({ scope: scope, reset: reset }); } + + CheckAccess({ + scope: scope + }); - // Retrieve detail record and prepopulate the form - Wait('start'); - Rest.setUrl(defaultUrl); - Rest.get() - .success( function(data, status, headers, config) { - - LoadBreadCrumbs({ path: '/users/' + base_id + '/permissions/' + id, title: data.name }); + scope.selectCategory = function (resetIn) { + var reset = (resetIn === false) ? false : true; + PermissionCategoryChange({ scope: scope, reset: reset }); + }; - for (var fld in form.fields) { - if (data[fld]) { - if (form.fields[fld].sourceModel) { - var sourceModel = form.fields[fld].sourceModel; - var sourceField = form.fields[fld].sourceField; - scope[sourceModel + '_' + sourceField] = data.summary_fields[sourceModel][sourceField]; - master[sourceModel + '_' + sourceField] = data.summary_fields[sourceModel][sourceField]; - } - scope[fld] = data[fld]; - master[fld] = scope[fld]; - } - } + // Retrieve detail record and prepopulate the form + Wait('start'); + Rest.setUrl(defaultUrl); + Rest.get() + .success(function (data) { + var fld, sourceModel, sourceField; + LoadBreadCrumbs({ path: '/users/' + base_id + '/permissions/' + id, title: data.name }); + for (fld in form.fields) { + if (data[fld]) { + if (form.fields[fld].sourceModel) { + sourceModel = form.fields[fld].sourceModel; + sourceField = form.fields[fld].sourceField; + scope[sourceModel + '_' + sourceField] = data.summary_fields[sourceModel][sourceField]; + master[sourceModel + '_' + sourceField] = data.summary_fields[sourceModel][sourceField]; + } + scope[fld] = data[fld]; + master[fld] = scope[fld]; + } + } - scope.category = 'Deploy'; - if (data['permission_type'] != 'run' && data['permission_type'] != 'check' ) { - scope.category = 'Inventory'; - } - master['category'] = scope.category; - scope.selectCategory(false); //call without resetting scope.category value + scope.category = 'Deploy'; + if (data.permission_type !== 'run' && data.permission_type !== 'check') { + scope.category = 'Inventory'; + } + master.category = scope.category; + scope.selectCategory(false); //call without resetting scope.category value - LookUpInit({ - scope: scope, - form: form, - current_item: data.inventory, - list: InventoryList, - field: 'inventory' - }); + LookUpInit({ + scope: scope, + form: form, + current_item: data.inventory, + list: InventoryList, + field: 'inventory' + }); - LookUpInit({ - scope: scope, - form: form, - current_item: data.project, - list: ProjectList, - field: 'project' - }); + LookUpInit({ + scope: scope, + form: form, + current_item: data.project, + list: ProjectList, + field: 'project' + }); - if (!scope.PermissionAddAllowed) { - // If not a privileged user, disable access - $('form[name="permission_form"]').find('select, input, button').each(function(index){ - if ($(this).is('input') || $(this).is('select')) { - $(this).attr('readonly','readonly'); - } - if ( $(this).is('input[type="checkbox"]') || - $(this).is('input[type="radio"]') || - $(this).is('button') ) { - $(this).attr('disabled','disabled'); - } - }); - } - Wait('stop'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve Permission: ' + id + '. GET status: ' + status }); - }); + if (!scope.PermissionAddAllowed) { + // If not a privileged user, disable access + $('form[name="permission_form"]').find('select, input, button').each(function () { + if ($(this).is('input') || $(this).is('select')) { + $(this).attr('readonly', 'readonly'); + } + if ($(this).is('input[type="checkbox"]') || + $(this).is('input[type="radio"]') || + $(this).is('button')) { + $(this).attr('disabled', 'disabled'); + } + }); + } + Wait('stop'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { hdr: 'Error!', + msg: 'Failed to retrieve Permission: ' + id + '. GET status: ' + status }); + }); - // Save changes to the parent - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - var data = {} - for (var fld in form.fields) { - data[fld] = scope[fld]; - } - Rest.setUrl(defaultUrl); - Rest.put(data) - .success( function(data, status, headers, config) { - Wait('stop'); - ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to update Permission: ' + $routeParams.id + '. PUT status: ' + status }); - }); - }; + // Save changes to the parent + scope.formSave = function () { + var fld, data = {}; + generator.clearApiErrors(); + Wait('start'); + for (fld in form.fields) { + data[fld] = scope[fld]; + } + Rest.setUrl(defaultUrl); + Rest.put(data) + .success(function () { + Wait('stop'); + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to update Permission: ' + + $routeParams.id + '. PUT status: ' + status }); + }); + }; - // Cancel - scope.formReset = function() { - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - scope.selectCategory(false); - }; + // Cancel + scope.formReset = function () { + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + scope.selectCategory(false); + }; } -PermissionsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionsForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', - 'ClearScope', 'Prompt', 'GetBasePath', 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', - 'Wait', 'PermissionCategoryChange' - ]; - +PermissionsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionsForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt', 'GetBasePath', + 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', 'PermissionCategoryChange' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Projects.js b/awx/ui/static/js/controllers/Projects.js index 2fb4c0bff7..85de2ac90a 100644 --- a/awx/ui/static/js/controllers/Projects.js +++ b/awx/ui/static/js/controllers/Projects.js @@ -3,77 +3,81 @@ * * * Projects.js - * + * * Controller functions for the Projects model. * */ 'use strict'; -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, GetChoices) -{ +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, GetChoices, Empty) { + ClearScope('htmlTemplate'); - + Wait('start'); - - var list = ProjectList; - var defaultUrl = GetBasePath('projects'); - var view = GenerateList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var mode = (base == 'projects') ? 'edit' : 'select'; - var scope = view.inject(list, { mode: mode }); - + + var list = ProjectList, + defaultUrl = GetBasePath('projects'), + view = GenerateList, + base = $location.path().replace(/^\//, '').split('/')[0], + mode = (base === 'projects') ? 'edit' : 'select', + scope = view.inject(list, { mode: mode }), + url = (base === 'teams') ? GetBasePath('teams') + $routeParams.team_id + '/projects/' : defaultUrl, + choiceCount = 0; + $rootScope.flashMessage = null; scope.projectLoading = true; - var url = (base == 'teams') ? GetBasePath('teams') + $routeParams.team_id + '/projects/' : defaultUrl; - - if (mode == 'select') { - SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); + if (mode === 'select') { + SelectionInit({ + scope: scope, + list: list, + url: url, + returnToCaller: 1 + }); } if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Cleanup after a delete + var j, i; Wait('stop'); $('#prompt-modal').off(); if (scope.projects) { - for (var i=0; i < scope.projects.length; i++) { - if (scope.projects[i].status == 'ok') { + for (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; + 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; + 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 - if (scope.projects[i].scm_type == 'Manual') { + 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') { scope.projects[i].scm_update_tooltip = 'Manaul projects do not require an SCM update'; scope.projects[i].scm_type_class = 'btn-disabled'; - } - else { + } else { scope.projects[i].scm_update_tooltip = "Start an SCM update"; scope.projects[i].scm_type_class = ""; } @@ -82,64 +86,71 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, } } } - }); + }); if (scope.removeChoicesHere) { - scope.removeChoicesHere(); + scope.removeChoicesHere(); } - scope.removeChoicesHere = scope.$on('choicesCompleteProject', function() { - + scope.removeChoicesHere = scope.$on('choicesCompleteProject', function () { + var opt; + list.fields.scm_type.searchOptions = scope.project_scm_type_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 - defaultUrl += '?status=' + $routeParams['status']; + + 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']) { + 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]; + scope[list.iterator + 'SearchSelectOpts'] = list.fields.scm_type.searchOptions; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.scm_type.label.replace(//g, ' '); + for (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; } } - } - else if ($routeParams['status']) { - scope[list.iterator + 'SearchValue'] = $routeParams['status']; + } else if ($routeParams.status) { + scope[list.iterator + 'SearchValue'] = $routeParams.status; scope[list.iterator + 'SearchField'] = 'status'; scope[list.iterator + 'SelectShow'] = true; - scope[list.iterator + 'SearchFieldLabel'] = list.fields['status'].label; - scope[list.iterator + 'SearchSelectOpts'] = list.fields['status'].searchOptions; - for (var opt in list.fields['status'].searchOptions) { - if (list.fields['status'].searchOptions[opt].value == $routeParams['status']) { - scope[list.iterator + 'SearchSelectValue'] = list.fields['status'].searchOptions[opt]; + scope[list.iterator + 'SearchFieldLabel'] = list.fields.status.label; + scope[list.iterator + 'SearchSelectOpts'] = list.fields.status.searchOptions; + for (opt in list.fields.status.searchOptions) { + if (list.fields.status.searchOptions[opt].value === $routeParams.status) { + scope[list.iterator + 'SearchSelectValue'] = list.fields.status.searchOptions[opt]; break; } } } scope.search(list.iterator); - }); - - var choiceCount = 0; + }); if (scope.removeChoicesReady) { - scope.removeChoicesReady(); + scope.removeChoicesReady(); } - scope.removeChoicesReady = scope.$on('choicesReadyProject', function() { + scope.removeChoicesReady = scope.$on('choicesReadyProject', function () { choiceCount++; - if (choiceCount == 2) { - scope.$emit('choicesCompleteProject'); + if (choiceCount === 2) { + scope.$emit('choicesCompleteProject'); } - }); - + }); + // Load options for status --used in search GetChoices({ scope: scope, @@ -147,8 +158,8 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, field: 'status', variable: 'project_status_options', callback: 'choicesReadyProject' - }); - + }); + // Load the list of options for Kind GetChoices({ scope: scope, @@ -156,555 +167,591 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, field: 'scm_type', variable: 'project_scm_type_options', callback: 'choicesReadyProject' - }); + }); LoadBreadCrumbs(); - scope.showActivity = function() { Stream({ scope: scope }); } - - scope.addProject = function() { - $location.path($location.path() + '/add'); - } + scope.showActivity = function () { + Stream({ scope: scope }); + }; - scope.editProject = function(id) { - $location.path($location.path() + '/' + id); - } + scope.addProject = function () { + $location.path($location.path() + '/add'); + }; - scope.showSCMStatus = function(id) { - // Refresh the project list - var statusCheckRemove = scope.$on('PostRefresh', function() { - var project; - for (var 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'); - } - } - 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'); - } - 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) { - var action = function() { - $('#prompt-modal').on('hiden.bs.modal', function(){ Wait('start'); }); + scope.editProject = function (id) { + $location.path($location.path() + '/' + id); + }; + + 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'); + } + } 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'); + } + 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) { + var action = function () { + $('#prompt-modal').on('hiden.bs.modal', function () { + Wait('start'); + }); $('#prompt-modal').modal('hide'); var url = defaultUrl + id + '/'; Rest.setUrl(url); Rest.destroy() - .success( function(data, status, headers, config) { + .success(function () { scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { + }) + .error(function (data, status) { Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status + }); + }); + }; - Prompt({ hdr: 'Delete', + Prompt({ + hdr: 'Delete', body: 'Are you sure you want to delete ' + name + '?', action: action - }); - } + }); + }; if (scope.removeCancelUpdate) { - scope.removeCancelUpdate(); + scope.removeCancelUpdate(); } - scope.removeCancelUpdate = scope.$on('Cancel_Update', function(e, url) { + scope.removeCancelUpdate = scope.$on('Cancel_Update', function (e, url) { // Cancel the project update process - Rest.setUrl(url) + Rest.setUrl(url); Rest.post() - .success( function(data, status, headers, config) { + .success(function () { Alert('SCM Update Cancel', 'Your request to cancel the update was submitted to the task maanger.', 'alert-info'); scope.refresh(); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status }); - }); - }); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status }); + }); + }); if (scope.removeCheckCancel) { - scope.removeCheckCancel(); + scope.removeCheckCancel(); } - scope.removeCheckCancel = scope.$on('Check_Cancel', function(e, data) { + scope.removeCheckCancel = scope.$on('Check_Cancel', function (e, data) { // Check that we 'can' cancel the update var url = data.related.cancel; Rest.setUrl(url); Rest.get() - .success( function(data, status, headers, config) { + .success(function (data) { if (data.can_cancel) { - scope.$emit('Cancel_Update', url); + scope.$emit('Cancel_Update', url); + } else { + Alert('Cancel Not Allowed', 'Either you do not have access or the SCM update process completed. ' + + 'Click the Refresh button to view the latest status.', 'alert-info'); } - else { - Alert('Cancel Not Allowed', 'Either you do not have access or the SCM update process completed. Click the Refresh button to' + - ' view the latest status.', 'alert-info'); - } - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. GET status: ' + status }); - }); - }); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. GET status: ' + status }); + }); + }); - scope.cancelUpdate = function(id, name) { + scope.cancelUpdate = function (id, name) { // Start the cancel process - var project; - var found = false; - for (var i=0; i < scope.projects.length; i++) { - if (scope.projects[i].id == id) { - project = scope.projects[i]; - found = true; - break; + var i, project, found = false; + for (i = 0; i < scope.projects.length; i++) { + if (scope.projects[i].id === id) { + project = scope.projects[i]; + found = true; + break; } } if (found && project.related.current_update) { - Rest.setUrl(project.related.current_update); - Rest.get() - .success( function(data, status, headers, config) { - scope.$emit('Check_Cancel', data); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + project.related.current_update + ' failed. GET status: ' + status }); - }); - } - else { - Alert('Update Not Found', 'An SCM update does not appear to be running for project: ' + name + '. Click the Refresh ' + - 'button to view the latet status.', 'alert-info'); - } + Rest.setUrl(project.related.current_update); + Rest.get() + .success(function (data) { + scope.$emit('Check_Cancel', data); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + project.related.current_update + ' failed. GET status: ' + status + }); + }); + } else { + Alert('Update Not Found', 'An SCM update does not appear to be running for project: ' + name + '. Click the Refresh ' + + 'button to view the latet status.', 'alert-info'); } + }; - scope.refresh = function() { + scope.refresh = function () { Wait('start'); - scope['projectLoading'] = false; - Refresh({ scope: scope, set: 'projects', iterator: 'project', url: scope['current_url'] }); - } + scope.projectLoading = false; + Refresh({ + scope: scope, + set: 'projects', + iterator: 'project', + url: scope.current_url + }); + }; - scope.SCMUpdate = function(project_id) { - for (var i=0; i < scope.projects.length; i++) { - if (scope.projects[i].id == project_id) { - if (scope.projects[i].scm_type == "Manual" || scope.projects[i].scm_type == "" || scope.projects[i].scm_type == null ) { - // 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') { - 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 }); - } - } - } - } + 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)) { + // 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') { + 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 + }); + } + } + } + }; } -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', - 'GetChoices' ]; +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', 'GetChoices', 'Empty' +]; -function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, - GetBasePath, ReturnToCaller, GetProjectPath, LookUpInit, OrganizationList, - CredentialList, GetChoices, DebugForm, Wait) -{ - ClearScope('tree-form'); - ClearScope('htmlTemplate'); +function ProjectsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, + GetBasePath, ReturnToCaller, GetProjectPath, LookUpInit, OrganizationList, + CredentialList, GetChoices, DebugForm, Wait) { + ClearScope('tree-form'); + ClearScope('htmlTemplate'); - // Inject dynamic view - var form = ProjectsForm; - var generator = GenerateForm; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var defaultUrl = GetBasePath('projects'); - var scope = generator.inject(form, {mode: 'add', related: false}); - var id = $routeParams.id; - var master = {}; + // Inject dynamic view + var form = ProjectsForm, + generator = GenerateForm, + base = $location.path().replace(/^\//, '').split('/')[0], + defaultUrl = GetBasePath('projects'), + scope = generator.inject(form, { mode: 'add', related: false }), + master = {}; - generator.reset(); - LoadBreadCrumbs(); - - GetProjectPath({ scope: scope, master: master }); - - if (scope.removeChoicesReady) { - scope.removeChoicesReady(); - } - scope.removeChoicesReady = scope.$on('choicesReady', function() { - for (var i=0; i < scope.scm_type_options.length; i++) { - if (scope.scm_type_options[i].value == '') { - scope['scm_type'] = scope.scm_type_options[i]; - break; - } - } - scope.scmRequired = false; - master['scm_type'] = scope['scm_type']; - }); + generator.reset(); + LoadBreadCrumbs(); - // Load the list of options for Kind - GetChoices({ + GetProjectPath({ + scope: scope, + master: master + }); + + if (scope.removeChoicesReady) { + scope.removeChoicesReady(); + } + scope.removeChoicesReady = scope.$on('choicesReady', function () { + var i; + for (i = 0; i < scope.scm_type_options.length; i++) { + if (scope.scm_type_options[i].value === '') { + scope.scm_type = scope.scm_type_options[i]; + break; + } + } + scope.scmRequired = false; + master.scm_type = scope.scm_type; + }); + + // Load the list of options for Kind + GetChoices({ scope: scope, url: defaultUrl, field: 'scm_type', variable: 'scm_type_options', callback: 'choicesReady' - }); + }); - LookUpInit({ - scope: scope, - form: form, - list: OrganizationList, - field: 'organization' - }); + LookUpInit({ + scope: scope, + form: form, + list: OrganizationList, + field: 'organization' + }); - LookUpInit({ - scope: scope, - url: GetBasePath('credentials') + '?kind=scm', - form: form, - list: CredentialList, - field: 'credential' - }); + LookUpInit({ + scope: scope, + url: GetBasePath('credentials') + '?kind=scm', + form: form, + list: CredentialList, + field: 'credential' + }); - // Save - scope.formSave = function() { - generator.clearApiErrors(); - var data = {}; - for (var fld in form.fields) { - if (form.fields[fld].type == 'checkbox_group') { - for (var i=0; i < form.fields[fld].fields.length; i++) { - data[form.fields[fld].fields[i].name] = scope[form.fields[fld].fields[i].name]; - } - } - else { - if (form.fields[fld].type !== 'alertblock') { - data[fld] = scope[fld]; - } - } - } - data.scm_type = scope.scm_type.value; - if (scope.scm_type.value !== '') { - delete data.local_path; - } - else { - data.local_path = scope.local_path.value; - } + // Save + scope.formSave = function () { + var i, fld, url, data={}; + generator.clearApiErrors(); + data = {}; + for (fld in form.fields) { + if (form.fields[fld].type === 'checkbox_group') { + for (i = 0; i < form.fields[fld].fields.length; i++) { + data[form.fields[fld].fields[i].name] = scope[form.fields[fld].fields[i].name]; + } + } else { + if (form.fields[fld].type !== 'alertblock') { + data[fld] = scope[fld]; + } + } + } + data.scm_type = scope.scm_type.value; + if (scope.scm_type.value !== '') { + delete data.local_path; + } else { + data.local_path = scope.local_path.value; + } - var url = (base == 'teams') ? GetBasePath('teams') + $routeParams.team_id + '/projects/' : defaultUrl; - Wait('start'); - Rest.setUrl(url); - Rest.post(data) - .success( function(data, status, headers, config) { - var id = data.id; - var url = GetBasePath('projects') + id + '/organizations/'; - var org = { id: scope.organization }; - Rest.setUrl(url); - Rest.post(org) - .success( function(data, status, headers, config) { - Wait('stop'); - $rootScope.flashMessage = "New project successfully created!"; - (base == 'projects') ? ReturnToCaller() : ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, ProjectsForm, - { hdr: 'Error!', msg: 'Failed to add organization to project. POST returned status: ' + status }); - }); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, ProjectsForm, - { hdr: 'Error!', msg: 'Failed to create new project. POST returned status: ' + status }); - }); - }; + url = (base === 'teams') ? GetBasePath('teams') + $routeParams.team_id + '/projects/' : defaultUrl; + Wait('start'); + Rest.setUrl(url); + Rest.post(data) + .success(function (data) { + var id = data.id, + url = GetBasePath('projects') + id + '/organizations/', + org = { id: scope.organization }; + Rest.setUrl(url); + Rest.post(org) + .success(function () { + Wait('stop'); + $rootScope.flashMessage = "New project successfully created!"; + if (base === 'projects') { + ReturnToCaller(); + } + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, ProjectsForm, { + hdr: 'Error!', + msg: 'Failed to add organization to project. POST returned status: ' + status + }); + }); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, ProjectsForm, { + hdr: 'Error!', + msg: 'Failed to create new project. POST returned status: ' + status + }); + }); + }; - scope.scmChange = function() { - // When an scm_type is set, path is not required - if (scope.scm_type) { - scope.pathRequired = (scope.scm_type.value == '') ? true : false; - scope.scmRequired = (scope.scm_type.value !== '') ? true : false; - scope.scmBranchLabel = (scope.scm_type.value == 'svn') ? 'Revision #' : 'SCM Branch'; - } - } + scope.scmChange = function () { + // When an scm_type is set, path is not required + if (scope.scm_type) { + scope.pathRequired = (scope.scm_type.value === '') ? true : false; + scope.scmRequired = (scope.scm_type.value !== '') ? true : false; + scope.scmBranchLabel = (scope.scm_type.value === 'svn') ? 'Revision #' : 'SCM Branch'; + } + }; - // Cancel - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - scope.scmChange(); - }; + // Cancel + scope.formReset = function () { + var fld; + $rootScope.flashMessage = null; + generator.reset(); + for (fld in master) { + scope.fld = master.fld; + } + scope.scmChange(); + }; } -ProjectsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'ProjectsForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', - 'ReturnToCaller', 'GetProjectPath', 'LookUpInit', 'OrganizationList', 'CredentialList', 'GetChoices', - 'DebugForm', 'Wait' - ]; +ProjectsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'ProjectsForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', + 'ReturnToCaller', 'GetProjectPath', 'LookUpInit', 'OrganizationList', 'CredentialList', 'GetChoices', + 'DebugForm', 'Wait' +]; -function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, Prompt, ClearScope, GetBasePath, ReturnToCaller, GetProjectPath, - Authorization, CredentialList, LookUpInit, GetChoices, Empty, DebugForm, Wait, Stream) -{ - ClearScope('tree-form'); - ClearScope('htmlTemplate'); +function ProjectsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, Prompt, + ClearScope, GetBasePath, ReturnToCaller, GetProjectPath, Authorization, CredentialList, LookUpInit, GetChoices, + Empty, DebugForm, Wait, Stream) { + + ClearScope('htmlTemplate'); - // Inject dynamic view - var form = ProjectsForm; - var generator = GenerateForm; - var scope = generator.inject(form, {mode: 'edit', related: true}); - generator.reset(); - - var defaultUrl = GetBasePath('projects') + $routeParams.id + '/'; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var master = {}; - var id = $routeParams.id; - var relatedSets = {}; + // Inject dynamic view + var form = ProjectsForm, + generator = GenerateForm, + scope = generator.inject(form, { mode: 'edit', related: true }), + defaultUrl = GetBasePath('projects') + $routeParams.id + '/', + base = $location.path().replace(/^\//, '').split('/')[0], + master = {}, + id = $routeParams.id, + relatedSets = {}; - scope.project_local_paths = []; - scope.base_dir = ''; + generator.reset(); - // After the project is loaded, retrieve each related set - if (scope.projectLoadedRemove) { - scope.projectLoadedRemove(); - } - scope.projectLoadedRemove = scope.$on('projectLoaded', function() { - for (var set in relatedSets) { - scope.search(relatedSets[set].iterator); - } - - if (Authorization.getUserInfo('is_superuser') == true) { - GetProjectPath({ scope: scope, master: master }); - } - else { - var opts = []; - opts.push({ label: scope['local_path'], value: scope['local_path'] }); - scope.project_local_paths = opts; - scope.local_path = scope['project_local_paths'][0]; - scope.base_dir = 'You do not have access to view this property'; - } + scope.project_local_paths = []; + scope.base_dir = ''; - LookUpInit({ - url: GetBasePath('credentials') + '?kind=scm', - scope: scope, - form: form, - list: CredentialList, - field: 'credential' - }); + // After the project is loaded, retrieve each related set + if (scope.projectLoadedRemove) { + scope.projectLoadedRemove(); + } + scope.projectLoadedRemove = scope.$on('projectLoaded', function () { + var set, opts=[]; - scope.pathRequired = (scope.scm_type.value == '') ? true : false; - scope.scmRequired = (scope.scm_type.value !== '') ? true : false; - scope.scmBranchLabel = (scope.scm_type.value == 'svn') ? 'Revision #' : 'SCM Branch'; - Wait('stop'); - }); + for (set in relatedSets) { + scope.search(relatedSets[set].iterator); + } - if (scope.removeChoicesReady) { - scope.removeChoicesReady(); - } - scope.removeChoicesReady = scope.$on('choicesReady', function() { - // Retrieve detail record and prepopulate the form - Rest.setUrl(defaultUrl); - Rest.get({ params: {id: id} }) - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/projects/' + id, title: data.name }); - for (var fld in form.fields) { - if (form.fields[fld].type == 'checkbox_group') { - for (var i=0; i < form.fields[fld].fields.length; i++) { - scope[form.fields[fld].fields[i].name] = data[form.fields[fld].fields[i].name]; - master[form.fields[fld].fields[i].name] = data[form.fields[fld].fields[i].name]; - } - } - else { - if (data[fld]) { - scope[fld] = data[fld]; - master[fld] = data[fld]; - } - } - if (fld !== 'organization' && form.fields[fld].sourceModel && - data.summary_fields && data.summary_fields[form.fields[fld].sourceModel]) { - scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; - master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; - } - } - var related = data.related; - for (var set in form.related) { - if (related[set]) { - relatedSets[set] = { url: related[set], iterator: form.related[set].iterator }; - } - } - - data.scm_type = (Empty(data.scm_type)) ? '' : data.scm_type; - - for (var i=0; i < scope.scm_type_options.length; i++) { - if (scope.scm_type_options[i].value == data.scm_type) { - scope.scm_type = scope.scm_type_options[i]; - break; - } - } - - if (scope.scm_type.value !== '') { - scope.pathRequired = false; - scope.scmRequired = true; - } - else { - scope.pathRequired = true; - scope.scmRequired = false; - } + if (Authorization.getUserInfo('is_superuser') === true) { + GetProjectPath({ scope: scope, master: master }); + } else { + opts.push({ + label: scope.local_path, + value: scope.local_path + }); + scope.project_local_paths = opts; + scope.local_path = scope.project_local_paths[0]; + scope.base_dir = 'You do not have access to view this property'; + } - master['scm_type'] = scope['scm_type']; - scope.scmBranchLabel = (scope.scm_type.value == 'svn') ? 'Revision #' : 'SCM Branch'; - - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); - RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); - scope.$emit('projectLoaded'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve project: ' + id + '. GET status: ' + status }); - }); - }); + LookUpInit({ + url: GetBasePath('credentials') + '?kind=scm', + scope: scope, + form: form, + list: CredentialList, + field: 'credential' + }); - // Load the list of options for Kind - Wait('start'); - GetChoices({ + scope.pathRequired = (scope.scm_type.value === '') ? true : false; + scope.scmRequired = (scope.scm_type.value !== '') ? true : false; + scope.scmBranchLabel = (scope.scm_type.value === 'svn') ? 'Revision #' : 'SCM Branch'; + Wait('stop'); + }); + + if (scope.removeChoicesReady) { + scope.removeChoicesReady(); + } + scope.removeChoicesReady = scope.$on('choicesReady', function () { + // Retrieve detail record and prepopulate the form + Rest.setUrl(defaultUrl); + Rest.get({ params: { id: id } }) + .success(function (data) { + var related, set, fld, i; + LoadBreadCrumbs({ path: '/projects/' + id, title: data.name }); + for (fld in form.fields) { + if (form.fields[fld].type === 'checkbox_group') { + for (i = 0; i < form.fields[fld].fields.length; i++) { + scope[form.fields[fld].fields[i].name] = data[form.fields[fld].fields[i].name]; + master[form.fields[fld].fields[i].name] = data[form.fields[fld].fields[i].name]; + } + } else { + if (data[fld]) { + scope[fld] = data[fld]; + master[fld] = data[fld]; + } + } + if (fld !== 'organization' && form.fields[fld].sourceModel && + data.summary_fields && data.summary_fields[form.fields[fld].sourceModel]) { + scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = + data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; + master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = + data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; + } + } + related = data.related; + for (set in form.related) { + if (related[set]) { + relatedSets[set] = { + url: related[set], + iterator: form.related[set].iterator + }; + } + } + + data.scm_type = (Empty(data.scm_type)) ? '' : data.scm_type; + + for (i = 0; i < scope.scm_type_options.length; i++) { + if (scope.scm_type_options[i].value === data.scm_type) { + scope.scm_type = scope.scm_type_options[i]; + break; + } + } + + if (scope.scm_type.value !== '') { + scope.pathRequired = false; + scope.scmRequired = true; + } else { + scope.pathRequired = true; + scope.scmRequired = false; + } + + master.scm_type = scope.scm_type; + scope.scmBranchLabel = (scope.scm_type.value === 'svn') ? 'Revision #' : 'SCM Branch'; + + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: scope, + relatedSets: relatedSets + }); + scope.$emit('projectLoaded'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to retrieve project: ' + id + '. GET status: ' + status + }); + }); + }); + + // Load the list of options for Kind + Wait('start'); + GetChoices({ url: GetBasePath('projects'), scope: scope, field: 'scm_type', variable: 'scm_type_options', callback: 'choicesReady' - }); + }); - // Save changes to the parent - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - $rootScope.flashMessage = null; - var params = {}; - for (var fld in form.fields) { - if (form.fields[fld].type == 'checkbox_group') { - for (var i=0; i < form.fields[fld].fields.length; i++) { - params[form.fields[fld].fields[i].name] = scope[form.fields[fld].fields[i].name]; - } - } - else { - if (form.fields[fld].type !== 'alertblock') { - params[fld] = scope[fld]; - } - } - } - - params.scm_type = scope.scm_type.value; - if (scope.scm_type.value !== '') { - delete params.local_path; - } - else { - params.local_path = scope.local_path.value; - } + // Save changes to the parent + scope.formSave = function () { + var fld, i, params; + generator.clearApiErrors(); + Wait('start'); + $rootScope.flashMessage = null; + params = {}; + for (fld in form.fields) { + if (form.fields[fld].type === 'checkbox_group') { + for (i = 0; i < form.fields[fld].fields.length; i++) { + params[form.fields[fld].fields[i].name] = scope[form.fields[fld].fields[i].name]; + } + } else { + if (form.fields[fld].type !== 'alertblock') { + params[fld] = scope[fld]; + } + } + } - Rest.setUrl(defaultUrl); - Rest.put(params) - .success( function(data, status, headers, config) { + params.scm_type = scope.scm_type.value; + if (scope.scm_type.value !== '') { + delete params.local_path; + } else { + params.local_path = scope.local_path.value; + } + + Rest.setUrl(defaultUrl); + Rest.put(params) + .success(function() { Wait('stop'); ReturnToCaller(); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to update project: ' + id + '. PUT status: ' + status }); - }); - }; + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to update project: ' + id + '. PUT status: ' + status }); + }); + }; - scope.showActivity = function() { Stream({ scope: scope }); } + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - // Related set: Add button - scope.add = function(set) { - $rootScope.flashMessage = null; - $location.path('/' + base + '/' + $routeParams.id + '/' + set); - }; + // Related set: Add button + scope.add = function (set) { + $rootScope.flashMessage = null; + $location.path('/' + base + '/' + $routeParams.id + '/' + set); + }; - // Related set: Edit button - scope.edit = function(set, id, name) { - $rootScope.flashMessage = null; - $location.path('/' + set + '/' + id); - }; + // Related set: Edit button + scope.edit = function (set, id) { + $rootScope.flashMessage = null; + $location.path('/' + set + '/' + id); + }; - // Related set: Delete button - scope['delete'] = function(set, itm_id, name, title) { - var action = function() { - var url = GetBasePath('projects') + id + '/' + set + '/'; - $rootScope.flashMessage = null; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - }; + // Related set: Delete button + scope['delete'] = function (set, itm_id, name, title) { + var action = function () { + var url = GetBasePath('projects') + id + '/' + set + '/'; + $rootScope.flashMessage = null; + Rest.setUrl(url); + Rest.post({ id: itm_id, disassociate: 1 }) + .success(function () { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); + }); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', - action: action - }); - } - - scope.scmChange = function() { - if (scope.scm_type) { - scope.pathRequired = (scope.scm_type.value == '') ? true : false; - scope.scmRequired = (scope.scm_type.value !== '') ? true : false; - scope.scmBranchLabel = (scope.scm_type.value == 'svn') ? 'Revision #' : 'SCM Branch'; - } - } + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', + action: action + }); + }; - // Reset the form - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - scope.scmChange(); - //DebugForm({ scope: scope, form: form }); - }; + scope.scmChange = function () { + if (scope.scm_type) { + scope.pathRequired = (scope.scm_type.value === '') ? true : false; + scope.scmRequired = (scope.scm_type.value !== '') ? true : false; + scope.scmBranchLabel = (scope.scm_type.value === 'svn') ? 'Revision #' : 'SCM Branch'; + } + }; + + // Reset the form + scope.formReset = function () { + $rootScope.flashMessage = null; + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + scope.scmChange(); + }; } -ProjectsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'ProjectsForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath', 'ReturnToCaller', - 'GetProjectPath', 'Authorization', 'CredentialList', 'LookUpInit', 'GetChoices', 'Empty', - 'DebugForm', 'Wait', 'Stream' - ]; +ProjectsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'ProjectsForm', 'GenerateForm', + 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', 'ClearScope', + 'GetBasePath', 'ReturnToCaller', 'GetProjectPath', 'Authorization', 'CredentialList', 'LookUpInit', 'GetChoices', 'Empty', + 'DebugForm', 'Wait', 'Stream' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Teams.js b/awx/ui/static/js/controllers/Teams.js index bc85bf9eb5..74d68afa2e 100644 --- a/awx/ui/static/js/controllers/Teams.js +++ b/awx/ui/static/js/controllers/Teams.js @@ -3,353 +3,383 @@ * * * Teams.js - * + * * Controller functions for the Team model. * */ - + 'use strict'; -function TeamsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, TeamList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, SetTeamListeners, GetBasePath, SelectionInit, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - var list = TeamList; - var defaultUrl = GetBasePath('teams'); - var view = GenerateList; - var paths = $location.path().replace(/^\//,'').split('/'); - var mode = (paths[0] == 'teams') ? 'edit' : 'select'; // if base path 'teams', we're here to add/edit teams - var scope = view.inject(list, { mode: mode }); // Inject our view - scope.selected = []; +function TeamsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, TeamList, GenerateList, LoadBreadCrumbs, + Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, SetTeamListeners, GetBasePath, SelectionInit, Wait, + Stream) { - var url = GetBasePath('base') + $location.path() + '/'; - SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); - - if (scope.removePostRefresh) { - scope.removePostRefresh(); - } - scope.removePostRefresh = scope.$on('PostRefresh', function() { - // After a refresh, populate the organization name on each row - if (scope.teams) { - for ( var i=0; i < scope.teams.length; i++) { - scope.teams[i].organization_name = scope.teams[i].summary_fields.organization.name; - } - } - }); + ClearScope('htmlTemplate'); - SearchInit({ scope: scope, set: 'teams', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + var list = TeamList, + defaultUrl = GetBasePath('teams'), + view = GenerateList, + paths = $location.path().replace(/^\//, '').split('/'), + mode = (paths[0] === 'teams') ? 'edit' : 'select', // if base path 'teams', we're here to add/edit teams + scope = view.inject(list, { mode: mode }), + url; + + scope.selected = []; + + url = GetBasePath('base') + $location.path() + '/'; + SelectionInit({ + scope: scope, + list: list, + url: url, + returnToCaller: 1 + }); + + if (scope.removePostRefresh) { + scope.removePostRefresh(); + } + scope.removePostRefresh = scope.$on('PostRefresh', function () { + // After a refresh, populate the organization name on each row + var i; + if (scope.teams) { + for (i = 0; i < scope.teams.length; i++) { + scope.teams[i].organization_name = scope.teams[i].summary_fields.organization.name; + } + } + }); + + SearchInit({ + scope: scope, + set: 'teams', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); scope.search(list.iterator); LoadBreadCrumbs(); - scope.showActivity = function() { Stream({ scope: scope }); } - - scope.addTeam = function() { - $location.path($location.path() + '/add'); - } + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - scope.editTeam = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deleteTeam = function(id, name) { - - var action = function() { - Wait('start'); - var url = defaultUrl + id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - Wait('stop'); - $('#prompt-modal').modal('hide'); - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + scope.addTeam = function () { + $location.path($location.path() + '/add'); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action + scope.editTeam = function (id) { + $location.path($location.path() + '/' + id); + }; + + scope.deleteTeam = function (id, name) { + + var action = function () { + Wait('start'); + var url = defaultUrl + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + Wait('stop'); + $('#prompt-modal').modal('hide'); + scope.search(list.iterator); + }) + .error(function (data, status) { + Wait('stop'); + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status + }); }); - } - - /* - scope.lookupOrganization = function(organization_id) { - Rest.setUrl(GetBasePath('organizations') + organization_id + '/'); - Rest.get() - .success( function(data, status, headers, config) { - return data.name; - }); - } - */ - + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + }; } -TeamsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'TeamList', 'GenerateList', - 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'SetTeamListeners', 'GetBasePath', 'SelectionInit', 'Wait', 'Stream' ]; +TeamsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'TeamList', 'GenerateList', + 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', + 'SetTeamListeners', 'GetBasePath', 'SelectionInit', 'Wait', 'Stream' +]; -function TeamsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, - Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateList, - OrganizationList, SearchInit, PaginateInit, GetBasePath, LookUpInit, Wait) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function TeamsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, + Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateList, + OrganizationList, SearchInit, PaginateInit, GetBasePath, LookUpInit, Wait) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - // Inject dynamic view - var defaultUrl = GetBasePath('teams'); - var form = TeamForm; - var generator = GenerateForm; - var scope = generator.inject(form, {mode: 'add', related: false}); - $rootScope.flashMessage = null; - generator.reset(); - LoadBreadCrumbs(); - - LookUpInit({ - scope: scope, - form: form, - current_item: null, - list: OrganizationList, - field: 'organization' - }); - - // Save - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - Rest.setUrl(defaultUrl); - var data = {} - for (var fld in form.fields) { - data[fld] = scope[fld]; - } - Rest.post(data) - .success( function(data, status, headers, config) { - Wait('stop'); - $rootScope.flashMessage = "New team successfully created!"; - $location.path('/teams/' + data.id); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to add new team. Post returned status: ' + status }); - }); - }; + // Inject dynamic view + var defaultUrl = GetBasePath('teams'), + form = TeamForm, + generator = GenerateForm, + scope = generator.inject(form, { mode: 'add', related: false }); + + $rootScope.flashMessage = null; + generator.reset(); + LoadBreadCrumbs(); - // Reset - scope.formReset = function() { - // Defaults - generator.reset(); - }; + LookUpInit({ + scope: scope, + form: form, + current_item: null, + list: OrganizationList, + field: 'organization' + }); + + // Save + scope.formSave = function () { + var fld, data; + generator.clearApiErrors(); + Wait('start'); + Rest.setUrl(defaultUrl); + data = {}; + for (fld in form.fields) { + data[fld] = scope[fld]; + } + Rest.post(data) + .success(function (data) { + Wait('stop'); + $rootScope.flashMessage = "New team successfully created!"; + $location.path('/teams/' + data.id); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to add new team. Post returned status: ' + + status }); + }); + }; + + // Reset + scope.formReset = function () { + // Defaults + generator.reset(); + }; } -TeamsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm', 'GenerateForm', - 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', - 'OrganizationList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'LookUpInit', 'Wait']; +TeamsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm', 'GenerateForm', + 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', + 'OrganizationList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'LookUpInit', 'Wait' +]; -function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, - GetBasePath, CheckAccess, OrganizationList, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, + RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, + GetBasePath, CheckAccess, OrganizationList, Wait, Stream) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - var defaultUrl=GetBasePath('teams'); - var generator = GenerateForm; - var form = TeamForm; - var scope = generator.inject(form, {mode: 'edit', related: true}); - generator.reset(); - - var base = $location.path().replace(/^\//,'').split('/')[0]; - var master = {}; - var id = $routeParams.team_id; - var relatedSets = {}; + var defaultUrl = GetBasePath('teams'), + generator = GenerateForm, + form = TeamForm, + scope = generator.inject(form, { mode: 'edit', related: true }), + base = $location.path().replace(/^\//, '').split('/')[0], + master = {}, + id = $routeParams.team_id, + relatedSets = {}; - scope.PermissionAddAllowed = false; - - // Retrieve each related set and any lookups - if (scope.teamLoadedRemove) { - scope.teamLoadedRemove(); - } - scope.teamLoadedRemove = scope.$on('teamLoaded', function() { - CheckAccess({ scope: scope }); - Rest.setUrl(scope['organization_url']); - Rest.get() - .success( function(data, status, headers, config) { - scope['organization_name'] = data.name; - master['organization_name'] = data.name; - Wait('stop'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to retrieve organization: ' + scope.orgnization_url + '. GET status: ' + status }); - }); - for (var set in relatedSets) { - scope.search(relatedSets[set].iterator); - } - }); + generator.reset(); - // Retrieve detail record and prepopulate the form - Wait('start'); - Rest.setUrl(defaultUrl + ':id/'); - Rest.get({ params: {id: id} }) - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/teams/' + id, title: data.name }); - for (var fld in form.fields) { - if (data[fld]) { - scope[fld] = data[fld]; - master[fld] = scope[fld]; - } - } - var related = data.related; - for (var set in form.related) { - if (related[set]) { - relatedSets[set] = { url: related[set], iterator: form.related[set].iterator }; - } - } - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); - RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); + scope.PermissionAddAllowed = false; - LookUpInit({ - scope: scope, - form: form, - current_item: data['organization'], - list: OrganizationList, - field: 'organization' - }); + // Retrieve each related set and any lookups + if (scope.teamLoadedRemove) { + scope.teamLoadedRemove(); + } + scope.teamLoadedRemove = scope.$on('teamLoaded', function () { + CheckAccess({ scope: scope }); + Rest.setUrl(scope.organization_url); + Rest.get() + .success(function (data) { + scope.organization_name = data.name; + master.organization_name = data.name; + Wait('stop'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve organization: ' + + scope.orgnization_url + '. GET status: ' + status }); + }); + for (var set in relatedSets) { + scope.search(relatedSets[set].iterator); + } + }); - scope['organization_url'] = data.related.organization; - scope.$emit('teamLoaded'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve team: ' + $routeParams.team_id + '. GET status: ' + status }); - }); + // Retrieve detail record and prepopulate the form + Wait('start'); + Rest.setUrl(defaultUrl + ':id/'); + Rest.get({ + params: { + id: id + } + }) + .success(function (data) { + var fld, related, set; + LoadBreadCrumbs({ path: '/teams/' + id, title: data.name }); + for (fld in form.fields) { + if (data[fld]) { + scope[fld] = data[fld]; + master[fld] = scope[fld]; + } + } + related = data.related; + for (set in form.related) { + if (related[set]) { + relatedSets[set] = { + url: related[set], + iterator: form.related[set].iterator + }; + } + } + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: scope, + relatedSets: relatedSets + }); - scope.showActivity = function() { Stream({ scope: scope }); } - - // Save changes to the parent - scope.formSave = function() { - generator.clearApiErrors(); - Wait('start'); - $rootScope.flashMessage = null; - Rest.setUrl(defaultUrl + $routeParams.team_id +'/'); - var data = {} - for (var fld in form.fields) { - data[fld] = scope[fld]; - } - Rest.put(data) - .success( function(data, status, headers, config) { - Wait('stop'); - var base = $location.path().replace(/^\//,'').split('/')[0]; - (base == 'teams') ? ReturnToCaller() : ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to update team: ' + $routeParams.team_id + '. PUT status: ' + status }); - }); - }; + LookUpInit({ + scope: scope, + form: form, + current_item: data.organization, + list: OrganizationList, + field: 'organization' + }); - // Cancel - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - }; + scope.organization_url = data.related.organization; + scope.$emit('teamLoaded'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to retrieve team: ' + $routeParams.team_id + + '. GET status: ' + status }); + }); - // Related set: Add button - scope.add = function(set) { - $rootScope.flashMessage = null; - if (set == 'permissions') { - if (scope.PermissionAddAllowed) { - $location.path('/' + base + '/' + $routeParams.team_id + '/' + set + '/add'); - } - else { - Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); - } - } - else { - $location.path('/' + base + '/' + $routeParams.team_id + '/' + set); - } - }; + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - // Related set: Edit button - scope.edit = function(set, id, name) { - $rootScope.flashMessage = null; - if (set == 'permissions') { - $location.path('/' + base + '/' + $routeParams.team_id + '/' + set + '/' + id); - } - else { - $location.path('/' + set + '/' + id); - } - }; + // Save changes to the parent + scope.formSave = function () { + var data = {}, fld; + generator.clearApiErrors(); + Wait('start'); + $rootScope.flashMessage = null; + Rest.setUrl(defaultUrl + $routeParams.team_id + '/'); + for (fld in form.fields) { + data[fld] = scope[fld]; + } + Rest.put(data) + .success(function () { + Wait('stop'); + var base = $location.path().replace(/^\//, '').split('/')[0]; + if (base === 'teams') { + ReturnToCaller(); + } + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { hdr: 'Error!', + msg: 'Failed to update team: ' + $routeParams.team_id + '. PUT status: ' + status }); + }); + }; - // Related set: Delete button - scope['delete'] = function(set, itm_id, name, title) { - $rootScope.flashMessage = null; - - var action = function() { - var url; - if (set == 'permissions') { - if (scope.PermissionAddAllowed) { - url = GetBasePath('base') + 'permissions/' + itm_id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + // Cancel + scope.formReset = function () { + $rootScope.flashMessage = null; + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + }; + + // Related set: Add button + scope.add = function (set) { + $rootScope.flashMessage = null; + if (set === 'permissions') { + if (scope.PermissionAddAllowed) { + $location.path('/' + base + '/' + $routeParams.team_id + '/' + set + '/add'); + } else { + Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); + } + } else { + $location.path('/' + base + '/' + $routeParams.team_id + '/' + set); + } + }; + + // Related set: Edit button + scope.edit = function (set, id) { + $rootScope.flashMessage = null; + if (set === 'permissions') { + $location.path('/' + base + '/' + $routeParams.team_id + '/' + set + '/' + id); + } else { + $location.path('/' + set + '/' + id); + } + }; + + // Related set: Delete button + scope['delete'] = function (set, itm_id, name, title) { + $rootScope.flashMessage = null; + + var action = function () { + var url; + if (set === 'permissions') { + if (scope.PermissionAddAllowed) { + url = GetBasePath('base') + 'permissions/' + itm_id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + + ' failed. DELETE returned status: ' + status }); }); - } - else { - Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); - } - } - else { - var url = defaultUrl + $routeParams.team_id + '/' + set + '/'; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - } - }; - - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', - action: action - }); - } + } else { + Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); + } + } else { + url = defaultUrl + $routeParams.team_id + '/' + set + '/'; + Rest.setUrl(url); + Rest.post({ id: itm_id, disassociate: 1 }) + .success(function () { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + + ' failed. POST returned status: ' + status }); + }); + } + }; + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', + action: action + }); + }; } -TeamsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt', - 'GetBasePath', 'CheckAccess', 'OrganizationList', 'Wait', 'Stream' - ]; - +TeamsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', + 'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt', 'GetBasePath', 'CheckAccess', 'OrganizationList', 'Wait', 'Stream' +]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Users.js b/awx/ui/static/js/controllers/Users.js index 50b157a2f9..0c981247f8 100644 --- a/awx/ui/static/js/controllers/Users.js +++ b/awx/ui/static/js/controllers/Users.js @@ -3,453 +3,480 @@ * * * Users.js - * + * * Controller functions for User model. * */ - 'use strict'; -function UsersList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, UserList, - GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function UsersList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, UserList, GenerateList, LoadBreadCrumbs, + Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait, Stream) { + + ClearScope('htmlTemplate'); + + var list = UserList, + defaultUrl = GetBasePath('users'), + view = GenerateList, + base = $location.path().replace(/^\//, '').split('/')[0], + mode = (base === 'users') ? 'edit' : 'select', // if base path 'users', we're here to add/edit users + scope = view.inject(UserList, { mode: mode }), + url = (base === 'organizations') ? GetBasePath('organizations') + $routeParams.organization_id + '/users/' : + GetBasePath('teams') + $routeParams.team_id + '/users/'; - var list = UserList; - var defaultUrl = GetBasePath('users'); - var view = GenerateList; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var mode = (base == 'users') ? 'edit' : 'select'; // if base path 'users', we're here to add/edit users - var scope = view.inject(UserList, { mode: mode }); // Inject our view scope.selected = []; - var url = (base == 'organizations') ? GetBasePath('organizations') + $routeParams.organization_id + '/users/' : - GetBasePath('teams') + $routeParams.team_id + '/users/'; - SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); + SelectionInit({ + scope: scope, + list: list, + url: url, + returnToCaller: 1 + }); if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.removePostRefresh = scope.$on('PostRefresh', function() { + scope.removePostRefresh = scope.$on('PostRefresh', function () { // Cleanup after a delete Wait('stop'); $('#prompt-modal').off(); - }); + }); $rootScope.flashMessage = null; - SearchInit({ scope: scope, set: 'users', list: list, url: defaultUrl }); - PaginateInit({ scope: scope, list: list, url: defaultUrl }); + SearchInit({ + scope: scope, + set: 'users', + list: list, + url: defaultUrl + }); + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl + }); scope.search(list.iterator); LoadBreadCrumbs(); - - scope.showActivity = function() { Stream({ scope: scope }); } - - scope.addUser = function() { - $location.path($location.path() + '/add'); - } - scope.editUser = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deleteUser = function(id, name) { - - var action = function() { - $('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); }); - $('#prompt-modal').modal('hide'); - var url = defaultUrl + id + '/'; - Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', - action: action + scope.addUser = function () { + $location.path($location.path() + '/add'); + }; + + scope.editUser = function (id) { + $location.path($location.path() + '/' + id); + }; + + scope.deleteUser = function (id, name) { + + var action = function () { + $('#prompt-modal').on('hidden.bs.modal', function () { + Wait('start'); + }); + $('#prompt-modal').modal('hide'); + var url = defaultUrl + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + scope.search(list.iterator); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + + status }); }); - } + }; + + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + }; } -UsersList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'UserList', 'GenerateList', - 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'SelectionInit', 'Wait', 'Stream']; +UsersList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'UserList', 'GenerateList', + 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'GetBasePath', + 'SelectionInit', 'Wait', 'Stream' +]; -function UsersAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GetBasePath, LookUpInit, OrganizationList, ResetForm, Wait) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function UsersAdd($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert, ProcessErrors, + LoadBreadCrumbs, ReturnToCaller, ClearScope, GetBasePath, LookUpInit, OrganizationList, ResetForm, Wait) { + + ClearScope('htmlTemplate'); - // Inject dynamic view - var defaultUrl = GetBasePath('organizations'); - var form = UserForm; - ResetForm(); - var generator = GenerateForm; - var scope = generator.inject(form, {mode: 'add', related: false}); - - scope.ldap_user = false; - scope.not_ldap_user = !scope.ldap_user; - scope.ldap_dn = null; + // Inject dynamic view + var defaultUrl = GetBasePath('organizations'), + form = UserForm, + generator = GenerateForm, + scope = generator.inject(form, { mode: 'add', related: false }); + + ResetForm(); + + scope.ldap_user = false; + scope.not_ldap_user = !scope.ldap_user; + scope.ldap_dn = null; - generator.reset(); + generator.reset(); - LoadBreadCrumbs(); + LoadBreadCrumbs(); - // Configure the lookup dialog. If we're adding a user through the Organizations tab, - // default the Organization value. - LookUpInit({ - scope: scope, - form: form, - current_item: ($routeParams.organization_id !== undefined) ? $routeParams.organization_id : null, - list: OrganizationList, - field: 'organization' - }); + // Configure the lookup dialog. If we're adding a user through the Organizations tab, + // default the Organization value. + LookUpInit({ + scope: scope, + form: form, + current_item: ($routeParams.organization_id !== undefined) ? $routeParams.organization_id : null, + list: OrganizationList, + field: 'organization' + }); - if ($routeParams.organization_id) { - scope.organization = $routeParams.organization_id; - Rest.setUrl(GetBasePath('organizations') + $routeParams.organization_id + '/'); - Rest.get() - .success( function(data, status, headers, config) { - scope['organization_name'] = data.name; - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to lookup Organization: ' + data.id + '. GET returned status: ' + status }); - }); - } + if ($routeParams.organization_id) { + scope.organization = $routeParams.organization_id; + Rest.setUrl(GetBasePath('organizations') + $routeParams.organization_id + '/'); + Rest.get() + .success(function (data) { + scope.organization_name = data.name; + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to lookup Organization: ' + data.id + '. GET returned status: ' + status + }); + }); + } - // Save - scope.formSave = function() { - generator.clearApiErrors(); - if (scope.organization !== undefined && scope.organization !== null && scope.organization !== '') { - Rest.setUrl(defaultUrl + scope.organization + '/users/'); - var data = {} - for (var fld in form.fields) { - if (form.fields[fld].realName) { - data[form.fields[fld].realName] = scope[fld]; - } - else { - data[fld] = scope[fld]; - } - } - - data.is_superuser = (data.is_superuser == null || data.is_superuser == undefined || data.is_superuser == '') ? false : - data.is_superuser; - Wait('start'); - Rest.post(data) - .success( function(data, status, headers, config) { - var base = $location.path().replace(/^\//,'').split('/')[0]; - if (base == 'users') { - $rootScope.flashMessage = 'New user successfully created!'; - $location.path('/users/' + data.id); - } - else { - ReturnToCaller(1); - } - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to add new user. POST returned status: ' + status }); - }); - } - else { - scope.organization_name_api_error = 'A value is required'; - } - }; + // Save + scope.formSave = function () { + generator.clearApiErrors(); + var fld, data = {}; + if (scope.organization !== undefined && scope.organization !== null && scope.organization !== '') { + Rest.setUrl(defaultUrl + scope.organization + '/users/'); + for (fld in form.fields) { + if (form.fields[fld].realName) { + data[form.fields[fld].realName] = scope[fld]; + } else { + data[fld] = scope[fld]; + } + } + data.is_superuser = data.is_superuser || false; + Wait('start'); + Rest.post(data) + .success(function (data) { + var base = $location.path().replace(/^\//, '').split('/')[0]; + if (base === 'users') { + $rootScope.flashMessage = 'New user successfully created!'; + $location.path('/users/' + data.id); + } + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to add new user. POST returned status: ' + status }); + }); + } else { + scope.organization_name_api_error = 'A value is required'; + } + }; - // Cancel - scope.formReset = function() { - // Defaults - generator.reset(); - scope.ldap_user = false; - }; + // Cancel + scope.formReset = function () { + // Defaults + generator.reset(); + scope.ldap_user = false; + }; - // Password change - scope.clearPWConfirm = function(fld) { - // If password value changes, make sure password_confirm must be re-entered - scope[fld] = ''; - scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); - } + // Password change + scope.clearPWConfirm = function (fld) { + // If password value changes, make sure password_confirm must be re-entered + scope[fld] = ''; + scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); + }; } -UsersAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm', - 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GetBasePath', - 'LookUpInit', 'OrganizationList', 'ResetForm', 'Wait' ]; +UsersAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm', + 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GetBasePath', + 'LookUpInit', 'OrganizationList', 'ResetForm', 'Wait' +]; -function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, - GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath, Prompt, CheckAccess, - ResetForm, Wait, Stream) -{ - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. +function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, + RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath, Prompt, CheckAccess, + ResetForm, Wait, Stream) { + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - var defaultUrl=GetBasePath('users'); - var generator = GenerateForm; - var form = UserForm; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var master = {}; - var id = $routeParams.user_id; - var relatedSets = {}; + var defaultUrl = GetBasePath('users'), + generator = GenerateForm, + form = UserForm, + base = $location.path().replace(/^\//, '').split('/')[0], + master = {}, + id = $routeParams.user_id, + relatedSets = {}; + + if ($scope.removeFormReady) { + $scope.removeFormReady(); + } + $scope.removeFormReady = $scope.$on('formReady', function () { + var scope = generator.inject(form, { mode: 'edit', related: true }); + generator.reset(); - if ($scope.removeFormReady) { - $scope.removeFormReady(); - } - $scope.removeFormReady = $scope.$on('formReady', function() { - var scope = generator.inject(form, {mode: 'edit', related: true}); - generator.reset(); - if (scope.removePostRefresh) { - scope.removePostRefresh(); + scope.removePostRefresh(); } - scope.PermissionAddAllowed = false; + scope.PermissionAddAllowed = false; - // After the Organization is loaded, retrieve each related set - if (scope.removeUserLoaded) { - scope.removeUserLoaded(); - } - scope.removeUserLoaded = scope.$on('userLoaded', function() { - for (var set in relatedSets) { - scope.search(relatedSets[set].iterator); - } - CheckAccess({ scope: scope }); //Does the user have access to add/edit Permissions? - Wait('stop'); - }); + // After the Organization is loaded, retrieve each related set + if (scope.removeUserLoaded) { + scope.removeUserLoaded(); + } + scope.removeUserLoaded = scope.$on('userLoaded', function () { + for (var set in relatedSets) { + scope.search(relatedSets[set].iterator); + } + CheckAccess({ + scope: scope + }); //Does the user have access to add/edit Permissions? + Wait('stop'); + }); - // Retrieve detail record and prepopulate the form - Rest.setUrl(defaultUrl + ':id/'); - Rest.get({ params: {id: id} }) - .success( function(data, status, headers, config) { - LoadBreadCrumbs({ path: '/users/' + id, title: data.username }); - for (var fld in form.fields) { - if (data[fld]) { - if (fld == 'is_superuser') { - scope[fld] = (data[fld] == 'true' || data[fld] == true) ? 'true' : 'false'; - } - else { - scope[fld] = data[fld]; - } - master[fld] = scope[fld]; - } - } - var related = data.related; - for (var set in form.related) { - if (related[set]) { - relatedSets[set] = { url: related[set], iterator: form.related[set].iterator }; - } - } - - scope.ldap_user = (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') ? true : false; - scope.not_ldap_user = !scope.ldap_user; - master.ldap_user = scope.ldap_user; - - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); - RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); - scope.$emit('userLoaded'); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve user: ' + $routeParams.id + '. GET status: ' + status }); - }); - - // Save changes to the parent - scope.formSave = function() { - generator.clearApiErrors(); - $rootScope.flashMessage = null; - Rest.setUrl(defaultUrl + id + '/'); - var data = {} - for (var fld in form.fields) { - if (form.fields[fld].realName) { - data[form.fields[fld].realName] = scope[fld]; - } - else { - data[fld] = scope[fld]; - } - } + // Retrieve detail record and prepopulate the form + Rest.setUrl(defaultUrl + ':id/'); + Rest.get({ params: { id: id } }) + .success(function (data) { + LoadBreadCrumbs({ path: '/users/' + id, title: data.username }); + var fld, related, set; + for (fld in form.fields) { + if (data[fld]) { + if (fld === 'is_superuser') { + scope[fld] = (data[fld] === 'true' || data[fld] === true) ? 'true' : 'false'; + } else { + scope[fld] = data[fld]; + } + master[fld] = scope[fld]; + } + } + related = data.related; + for (set in form.related) { + if (related[set]) { + relatedSets[set] = { + url: related[set], + iterator: form.related[set].iterator + }; + } + } - data.is_superuser = (data.is_superuser == null || data.is_superuser == undefined || data.is_superuser == '') ? false : - data.is_superuser; - - Wait('start'); - Rest.put(data) - .success( function(data, status, headers, config) { - Wait('stop'); - var base = $location.path().replace(/^\//,'').split('/')[0]; - (base == 'users') ? ReturnToCaller() : ReturnToCaller(1); - }) - .error( function(data, status, headers, config) { - Wait('stop'); - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to update users: ' + $routeParams.id + '. PUT status: ' + status }); - }); - }; + scope.ldap_user = (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') ? true : false; + scope.not_ldap_user = !scope.ldap_user; + master.ldap_user = scope.ldap_user; - scope.showActivity = function() { Stream({ scope: scope }); } + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: scope, + relatedSets: relatedSets + }); + scope.$emit('userLoaded'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve user: ' + + $routeParams.id + '. GET status: ' + status }); + }); - // Cancel - scope.formReset = function() { - $rootScope.flashMessage = null; - generator.reset(); - for (var fld in master) { - scope[fld] = master[fld]; - } - scope['password_confirm'] = scope['password']; - }; + // Save changes to the parent + scope.formSave = function () { + var data = {}, fld; + generator.clearApiErrors(); + $rootScope.flashMessage = null; + Rest.setUrl(defaultUrl + id + '/'); + for (fld in form.fields) { + if (form.fields[fld].realName) { + data[form.fields[fld].realName] = scope[fld]; + } else { + data[fld] = scope[fld]; + } + } - // Password change - scope.clearPWConfirm = function(fld) { - // If password value changes, make sure password_confirm must be re-entered - scope[fld] = ''; - scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); - $rootScope.flashMessage = null; - } + data.is_superuser = data.is_superuser || false; + + Wait('start'); + Rest.put(data) + .success(function () { + Wait('stop'); + var base = $location.path().replace(/^\//, '').split('/')[0]; + if (base === 'users') { + ReturnToCaller(); + } + ReturnToCaller(1); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to update users: ' + $routeParams.id + + '. PUT status: ' + status }); + }); + }; + + scope.showActivity = function () { + Stream({ + scope: scope + }); + }; + + // Cancel + scope.formReset = function () { + $rootScope.flashMessage = null; + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + scope.password_confirm = scope.password; + }; + + // Password change + scope.clearPWConfirm = function (fld) { + // If password value changes, make sure password_confirm must be re-entered + scope[fld] = ''; + scope[form.name + '_form'][fld].$setValidity('awpassmatch', false); + $rootScope.flashMessage = null; + }; - // Related set: Add button - scope.add = function(set) { - $rootScope.flashMessage = null; - if (set == 'permissions') { - if (scope.PermissionAddAllowed) { - $location.path('/' + base + '/' + $routeParams.user_id + '/' + set + '/add'); - } - else { - Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); - } - } - else { - $location.path('/' + base + '/' + $routeParams.user_id + '/' + set); - } - }; + // Related set: Add button + scope.add = function (set) { + $rootScope.flashMessage = null; + if (set === 'permissions') { + if (scope.PermissionAddAllowed) { + $location.path('/' + base + '/' + $routeParams.user_id + '/' + set + '/add'); + } else { + Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); + } + } else { + $location.path('/' + base + '/' + $routeParams.user_id + '/' + set); + } + }; - // Related set: Edit button - scope.edit = function(set, id, name) { - $rootScope.flashMessage = null; - if (set == 'permissions') { - $location.path('/users/' + $routeParams.user_id + '/permissions/' + id); - } - else { - $location.path('/' + set + '/' + id); - } - }; + // Related set: Edit button + scope.edit = function (set, id) { + $rootScope.flashMessage = null; + if (set === 'permissions') { + $location.path('/users/' + $routeParams.user_id + '/permissions/' + id); + } else { + $location.path('/' + set + '/' + id); + } + }; - // Related set: Delete button - scope['delete'] = function(set, itm_id, name, title) { - $rootScope.flashMessage = null; - - var action = function() { - var url; - if (set == 'permissions') { - if (scope.PermissionAddAllowed) { - url = GetBasePath('base') + 'permissions/' + itm_id + '/'; + // Related set: Delete button + scope['delete'] = function (set, itm_id, name, title) { + $rootScope.flashMessage = null; + + var action = function () { + var url; + if (set === 'permissions') { + if (scope.PermissionAddAllowed) { + url = GetBasePath('base') + 'permissions/' + itm_id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success(function () { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error(function (data, status) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + } else { + Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); + } + } else { + url = defaultUrl + $routeParams.user_id + '/' + set + '/'; Rest.setUrl(url); - Rest.destroy() - .success( function(data, status, headers, config) { + Rest.post({ + id: itm_id, + disassociate: 1 + }) + .success(function () { $('#prompt-modal').modal('hide'); scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { + }) + .error(function (data, status) { $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - } - else { - Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.'); - } - } - else { - url = defaultUrl + $routeParams.user_id + '/' + set + '/'; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - } - } + }); + } + }; - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.username + ' ' + title + '?', - action: action - }); - } - - }); // $scope.$on - - // Put form back to its original state - ResetForm(); - - - if ($scope.removeModifyForm) { - $scope.removeModifyForm(); - } - $scope.removeModifyForm = $scope.$on('modifyForm', function() { - // Modify form based on LDAP settings - Rest.setUrl(GetBasePath('config')); - Rest.get() - .success( function(data, status, headers, config) { - if (data['user_ldap_fields']) { - var fld; - for (var i=0; i < data['user_ldap_fields'].length; i++) { - fld = data['user_ldap_fields'][i]; - if (form.fields[fld]) { - form.fields[fld]['readonly'] = true; - form.fields[fld]['editRequired'] = false; - if (form.fields[fld].awRequiredWhen) { - delete form.fields[fld].awRequiredWhen; - } - } - } - } - $scope.$emit('formReady'); - }) - .error( function(data, status, headers, config) { - ProcessErrors($scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to retrieve application config. GET status: ' + status }); - }); - }); - - Wait('start'); - Rest.setUrl(defaultUrl + id + '/'); - Rest.get() - .success( function(data, status, headers, config) { - if (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') { - //this is an LDAP user - $scope.$emit('modifyForm'); - } - else { - $scope.$emit('formReady'); - } - }) - .error( function(data, status, headers, config) { - ProcessErrors($scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to retrieve user: ' + id + '. GET status: ' + status }); + Prompt({ + hdr: 'Delete', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.username + ' ' + title + '?', + action: action }); + }; + }); // $scope.$on + + // Put form back to its original state + ResetForm(); + + + if ($scope.removeModifyForm) { + $scope.removeModifyForm(); + } + $scope.removeModifyForm = $scope.$on('modifyForm', function () { + // Modify form based on LDAP settings + Rest.setUrl(GetBasePath('config')); + Rest.get() + .success(function (data) { + var i, fld; + if (data.user_ldap_fields) { + for (i = 0; i < data.user_ldap_fields.length; i++) { + fld = data.user_ldap_fields[i]; + if (form.fields[fld]) { + form.fields[fld].readonly = true; + form.fields[fld].editRequired = false; + if (form.fields[fld].awRequiredWhen) { + delete form.fields[fld].awRequiredWhen; + } + } + } + } + $scope.$emit('formReady'); + }) + .error(function (data, status) { + ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve application config. GET status: ' + status }); + }); + }); + + Wait('start'); + Rest.setUrl(defaultUrl + id + '/'); + Rest.get() + .success(function (data) { + if (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') { + //this is an LDAP user + $scope.$emit('modifyForm'); + } else { + $scope.$emit('formReady'); + } + }) + .error(function (data, status) { + ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve user: ' + id + '. GET status: ' + status }); + }); } -UsersEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'Prompt', 'CheckAccess', - 'ResetForm', 'Wait', 'Stream']; - +UsersEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm', + 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', + 'GetBasePath', 'Prompt', 'CheckAccess', 'ResetForm', 'Wait', 'Stream' +]; \ No newline at end of file From d25e712e2197115c17e3e9316d1231ed2224e1dc Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 11 Feb 2014 04:52:15 +0000 Subject: [PATCH 02/27] Finixhed applying jsHint linting to js files. Created initial Gruntfile.js build script and package.json script for keeping track of required node modules. --- .gitignore | 1 + Gruntfile.js | 32 + awx/ui/static/js/app.js | 515 +-- awx/ui/static/js/config.js | 32 +- awx/ui/static/js/controllers/Credentials.js | 21 +- awx/ui/static/js/controllers/JobEvents.js | 15 +- awx/ui/static/js/forms/ActivityDetail.js | 15 +- awx/ui/static/js/forms/Credentials.js | 174 +- awx/ui/static/js/forms/Groups.js | 170 +- awx/ui/static/js/forms/HostGroups.js | 39 +- awx/ui/static/js/forms/Hosts.js | 66 +- awx/ui/static/js/forms/Inventories.js | 53 +- awx/ui/static/js/forms/InventoryGroups.js | 27 - awx/ui/static/js/forms/InventoryHosts.js | 147 - awx/ui/static/js/forms/InventoryStatus.js | 57 - awx/ui/static/js/forms/JobEventData.js | 7 +- awx/ui/static/js/forms/JobEvents.js | 144 + awx/ui/static/js/forms/JobSummary.js | 12 +- awx/ui/static/js/forms/JobTemplates.js | 141 +- awx/ui/static/js/forms/Jobs.js | 155 +- awx/ui/static/js/forms/LicenseForm.js | 84 + awx/ui/static/js/forms/Organizations.js | 133 +- awx/ui/static/js/forms/Permissions.js | 138 +- awx/ui/static/js/forms/ProjectStatus.js | 11 +- awx/ui/static/js/forms/Projects.js | 246 +- awx/ui/static/js/forms/Teams.js | 197 +- awx/ui/static/js/forms/Users.js | 192 +- awx/ui/static/js/help/InventoryGroups.js | 95 +- awx/ui/static/js/help/InventoryHosts.js | 24 - awx/ui/static/js/helpers/Access.js | 187 +- awx/ui/static/js/helpers/Children.js | 118 +- awx/ui/static/js/helpers/Credentials.js | 325 +- awx/ui/static/js/helpers/Events.js | 473 +-- awx/ui/static/js/helpers/Groups.js | 2075 ++++++------ awx/ui/static/js/helpers/Hosts.js | 2 + awx/ui/static/js/helpers/JobSubmission.js | 882 +++-- awx/ui/static/js/helpers/Jobs.js | 229 +- awx/ui/static/js/helpers/Lookup.js | 268 +- awx/ui/static/js/helpers/PaginationHelpers.js | 290 +- awx/ui/static/js/helpers/Parse.js | 100 +- awx/ui/static/js/helpers/Permissions.js | 75 +- awx/ui/static/js/helpers/ProjectPath.js | 130 +- awx/ui/static/js/helpers/Projects.js | 216 +- awx/ui/static/js/helpers/Selection.js | 291 +- awx/ui/static/js/helpers/Users.js | 55 +- awx/ui/static/js/helpers/api-defaults.js | 162 +- awx/ui/static/js/helpers/inventory.js | 442 +-- awx/ui/static/js/helpers/md5.js | 54 +- awx/ui/static/js/helpers/refresh-related.js | 64 +- awx/ui/static/js/helpers/refresh.js | 78 +- awx/ui/static/js/helpers/related-search.js | 412 ++- awx/ui/static/js/helpers/search.js | 898 +++--- awx/ui/static/js/helpers/teams.js | 202 +- awx/ui/static/js/lists/Admins.js | 38 +- awx/ui/static/js/lists/CloudCredentials.js | 40 +- awx/ui/static/js/lists/Credentials.js | 63 +- awx/ui/static/js/lists/Groups.js | 38 +- awx/ui/static/js/lists/HomeGroups.js | 76 +- awx/ui/static/js/lists/HomeHosts.js | 44 +- awx/ui/static/js/lists/Hosts.js | 36 +- awx/ui/static/js/lists/Inventories.js | 65 +- awx/ui/static/js/lists/InventoryHosts.js | 49 +- awx/ui/static/js/lists/JobEvents.js | 26 +- awx/ui/static/js/lists/JobHosts.js | 25 +- awx/ui/static/js/lists/JobTemplates.js | 51 +- awx/ui/static/js/lists/Jobs.js | 3 + awx/ui/static/js/lists/Organizations.js | 38 +- awx/ui/static/js/lists/Permissions.js | 49 +- awx/ui/static/js/lists/Projects.js | 70 +- awx/ui/static/js/lists/Streams.js | 88 +- awx/ui/static/js/lists/Teams.js | 44 +- awx/ui/static/js/lists/Users.js | 47 +- .../static/js/widgets/InventorySyncStatus.js | 172 +- awx/ui/static/js/widgets/JobStatus.js | 165 +- awx/ui/static/js/widgets/ObjectCount.js | 112 +- awx/ui/static/js/widgets/SCMSyncStatus.js | 171 +- awx/ui/static/js/widgets/Stream.js | 847 ++--- awx/ui/static/lib/ansible/AuthService.js | 241 +- awx/ui/static/lib/ansible/InventoryTree.js | 511 +-- awx/ui/static/lib/ansible/RestServices.js | 334 +- awx/ui/static/lib/ansible/Timer.js | 83 +- awx/ui/static/lib/ansible/TreeSelector.js | 693 ---- awx/ui/static/lib/ansible/Utilities.js | 702 ++-- awx/ui/static/lib/ansible/api-loader.js | 54 +- awx/ui/static/lib/ansible/directives.js | 1 + awx/ui/static/lib/ansible/filters.js | 31 +- awx/ui/static/lib/ansible/form-generator.js | 2825 ++++++++--------- .../static/lib/ansible/generator-helpers.js | 1218 ++++--- awx/ui/static/lib/ansible/license.js | 305 +- awx/ui/static/lib/ansible/list-generator.js | 805 ++--- awx/ui/static/lib/ansible/prompt-dialog.js | 49 +- awx/ui/static/lib/ansible/pwdmeter.js | 455 +-- awx/ui/templates/ui/index.html | 4 +- package.json | 9 + 94 files changed, 10589 insertions(+), 11059 deletions(-) create mode 100644 Gruntfile.js delete mode 100644 awx/ui/static/js/forms/InventoryGroups.js delete mode 100644 awx/ui/static/js/forms/InventoryHosts.js delete mode 100644 awx/ui/static/js/forms/InventoryStatus.js create mode 100644 awx/ui/static/js/forms/JobEvents.js create mode 100644 awx/ui/static/js/forms/LicenseForm.js delete mode 100644 awx/ui/static/js/help/InventoryHosts.js delete mode 100644 awx/ui/static/lib/ansible/TreeSelector.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore index e8fd62b1cc..5538679ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ awx/public/static awx/ui/static/js/awx-min.js awx/ui/static/css/awx.min.css env/* +node_modules/** build deb-build dist diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000000..2765d65d13 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,32 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + + pkg: grunt.file.readJSON('./package.json'), + + jshint: { + options: { + jshintrc: '.jshintrc' + }, + uses_defaults: ['awx/ui/static/js/*','awx/ui/static/lib/ansible/*', '!awx/ui/static/js/awx-min.js'] + }, + + uglify: { + options: { + banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd") %> */' + }, + my_target: { + files: { + 'awx/ui/static/js/awx-min.js': ['awx/ui/static/js/**/*.js', 'awx/ui/static/lib/ansible/*.js', + '!awx/ui/static/js/awx-min.js'] + } + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + + grunt.registerTask('default', ['jshint', 'uglify']); +} diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index a95a888464..fa88f9140f 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -4,23 +4,22 @@ * Our main application mdoule. Declare application routes and perform initialization chores. * */ - var urlPrefix = $basePath; angular.module('ansible', [ 'RestServices', 'AuthService', 'Utilities', - 'OrganizationFormDefinition', + 'OrganizationFormDefinition', 'UserFormDefinition', 'FormGenerator', 'OrganizationListDefinition', - 'UserListDefinition', + 'UserListDefinition', 'UserHelper', - 'ListGenerator', + 'ListGenerator', 'PromptDialog', - 'ApiLoader', - 'RelatedSearchHelper', + 'ApiLoader', + 'RelatedSearchHelper', 'SearchHelper', 'PaginationHelpers', 'RefreshHelper', @@ -58,6 +57,7 @@ angular.module('ansible', [ 'JobFormDefinition', 'JobEventsListDefinition', 'JobEventDataDefinition', + 'JobEventsFormDefinition', 'JobHostDefinition', 'JobSummaryDefinition', 'ParseHelper', @@ -75,9 +75,7 @@ angular.module('ansible', [ 'ObjectCountWidget', 'StreamWidget', 'JobsHelper', - 'InventoryStatusDefinition', 'InventoryGroupsHelpDefinition', - 'InventoryHostsHelpDefinition', 'InventoryTree', 'CredentialsHelper', 'TimerService', @@ -85,253 +83,368 @@ angular.module('ansible', [ 'HomeGroupListDefinition', 'HomeHostListDefinition', 'ActivityDetailDefinition' - ]) - .config(['$routeProvider', function($routeProvider) { - $routeProvider. - when('/jobs', - { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobsListCtrl }). +]) + .config(['$routeProvider', + function ($routeProvider) { + $routeProvider. + when('/jobs', { + templateUrl: urlPrefix + 'partials/jobs.html', + controller: 'JobsListCtrl' + }). - when('/jobs/:id', - { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobsEdit }). + when('/jobs/:id', { + templateUrl: urlPrefix + 'partials/jobs.html', + controller: 'JobsEdit' + }). - when('/jobs/:id/job_events', - { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobEventsList }). + when('/jobs/:id/job_events', { + templateUrl: urlPrefix + 'partials/jobs.html', + controller: 'JobEventsList' + }). - when('/jobs/:id/job_host_summaries', - { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobHostSummaryList }). - - when('/jobs/:job_id/job_events/:event_id', - { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobEventsEdit }). + when('/jobs/:id/job_host_summaries', { + templateUrl: urlPrefix + 'partials/jobs.html', + controller: 'JobHostSummaryList' + }). - when('/job_templates', - { templateUrl: urlPrefix + 'partials/job_templates.html', controller: JobTemplatesList }). - - when('/job_templates/add', - { templateUrl: urlPrefix + 'partials/job_templates.html', controller: JobTemplatesAdd }). + when('/jobs/:job_id/job_events/:event_id', { + templateUrl: urlPrefix + 'partials/jobs.html', + controller: 'JobEventsEdit' + }). - when('/job_templates/:id', - { templateUrl: urlPrefix + 'partials/job_templates.html', controller: JobTemplatesEdit }). + when('/job_templates', { + templateUrl: urlPrefix + 'partials/job_templates.html', + controller: 'JobTemplatesList' + }). - when('/projects', - { templateUrl: urlPrefix + 'partials/projects.html', controller: ProjectsList }). + when('/job_templates/add', { + templateUrl: urlPrefix + 'partials/job_templates.html', + controller: 'JobTemplatesAdd' + }). - when('/projects/add', - { templateUrl: urlPrefix + 'partials/projects.html', controller: ProjectsAdd }). + when('/job_templates/:id', { + templateUrl: urlPrefix + 'partials/job_templates.html', + controller: 'JobTemplatesEdit' + }). - when('/projects/:id', - { templateUrl: urlPrefix + 'partials/projects.html', controller: ProjectsEdit }). + when('/projects', { + templateUrl: urlPrefix + 'partials/projects.html', + controller: 'ProjectsList' + }). - when('/projects/:project_id/organizations', - { templateUrl: urlPrefix + 'partials/projects.html', controller: OrganizationsList }). + when('/projects/add', { + templateUrl: urlPrefix + 'partials/projects.html', + controller: 'ProjectsAdd' + }). - when('/projects/:project_id/organizations/add', - { templateUrl: urlPrefix + 'partials/projects.html', controller: OrganizationsAdd }). + when('/projects/:id', { + templateUrl: urlPrefix + 'partials/projects.html', + controller: 'ProjectsEdit' + }). - when('/hosts/:id/job_host_summaries', - { templateUrl: urlPrefix + 'partials/jobs.html', controller: JobHostSummaryList }). + when('/projects/:project_id/organizations', { + templateUrl: urlPrefix + 'partials/projects.html', + controller: 'OrganizationsList' + }). - when('/inventories', - { templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesList }). + when('/projects/:project_id/organizations/add', { + templateUrl: urlPrefix + 'partials/projects.html', + controller: 'OrganizationsAdd' + }). - when('/inventories/add', - { templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesAdd }). + when('/hosts/:id/job_host_summaries', { + templateUrl: urlPrefix + 'partials/jobs.html', + controller: 'JobHostSummaryList' + }). - when('/inventories/:inventory_id', - { templateUrl: urlPrefix + 'partials/inventory-edit.html', controller: InventoriesEdit }). + when('/inventories', { + templateUrl: urlPrefix + 'partials/inventories.html', + controller: 'InventoriesList' + }). - when('/organizations', { templateUrl: urlPrefix + 'partials/organizations.html', - controller: OrganizationsList }). + when('/inventories/add', { + templateUrl: urlPrefix + 'partials/inventories.html', + controller: 'InventoriesAdd' + }). - when('/organizations/add', { templateUrl: urlPrefix + 'partials/organizations.html', - controller: OrganizationsAdd }). + when('/inventories/:inventory_id', { + templateUrl: urlPrefix + 'partials/inventory-edit.html', + controller: 'InventoriesEdit' + }). - when('/organizations/:organization_id', { templateUrl: urlPrefix + 'partials/organizations.html', - controller: OrganizationsEdit }). + when('/organizations', { + templateUrl: urlPrefix + 'partials/organizations.html', + controller: 'OrganizationsList' + }). - when('/organizations/:organization_id/admins', { templateUrl: urlPrefix + 'partials/organizations.html', - controller: AdminsList }). + when('/organizations/add', { + templateUrl: urlPrefix + 'partials/organizations.html', + controller: 'OrganizationsAdd' + }). - when('/organizations/:organization_id/users', { templateUrl: urlPrefix + 'partials/users.html', - controller: UsersList }). + when('/organizations/:organization_id', { + templateUrl: urlPrefix + 'partials/organizations.html', + controller: 'OrganizationsEdit' + }). - when('/organizations/:organization_id/users/add', { templateUrl: urlPrefix + 'partials/users.html', - controller: UsersAdd }). + when('/organizations/:organization_id/admins', { + templateUrl: urlPrefix + 'partials/organizations.html', + controller: 'AdminsList' + }). - when('/organizations/:organization_id/users/:user_id', { templateUrl: urlPrefix + 'partials/users.html', - controller: UsersEdit }). + when('/organizations/:organization_id/users', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'UsersList' + }). - when('/teams', { templateUrl: urlPrefix + 'partials/teams.html', - controller: TeamsList }). + when('/organizations/:organization_id/users/add', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'UsersAdd' + }). - when('/teams/add', { templateUrl: urlPrefix + 'partials/teams.html', - controller: TeamsAdd }). + when('/organizations/:organization_id/users/:user_id', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'UsersEdit' + }). - when('/teams/:team_id', { templateUrl: urlPrefix + 'partials/teams.html', - controller: TeamsEdit }). - - when('/teams/:team_id/permissions/add', { templateUrl: urlPrefix + 'partials/teams.html', - controller: PermissionsAdd }). + when('/teams', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'TeamsList' + }). - when('/teams/:team_id/permissions', { templateUrl: urlPrefix + 'partials/teams.html', - controller: PermissionsList }). + when('/teams/add', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'TeamsAdd' + }). - when('/teams/:team_id/permissions/:permission_id', { templateUrl: urlPrefix + 'partials/teams.html', - controller: PermissionsEdit }). + when('/teams/:team_id', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'TeamsEdit' + }). - when('/teams/:team_id/users', { templateUrl: urlPrefix + 'partials/teams.html', - controller: UsersList }). + when('/teams/:team_id/permissions/add', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'PermissionsAdd' + }). - when('/teams/:team_id/users/:user_id', { templateUrl: urlPrefix + 'partials/teams.html', - controller: UsersEdit }). + when('/teams/:team_id/permissions', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'PermissionsList' + }). - when('/teams/:team_id/projects', { templateUrl: urlPrefix + 'partials/teams.html', - controller: ProjectsList }). + when('/teams/:team_id/permissions/:permission_id', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'PermissionsEdit' + }). - when('/teams/:team_id/projects/add', { templateUrl: urlPrefix + 'partials/teams.html', - controller: ProjectsAdd }). + when('/teams/:team_id/users', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'UsersList' + }). - when('/teams/:team_id/projects/:project_id', { templateUrl: urlPrefix + 'partials/teams.html', - controller: ProjectsEdit }). - - when('/teams/:team_id/credentials', { templateUrl: urlPrefix + 'partials/teams.html', - controller: CredentialsList }). + when('/teams/:team_id/users/:user_id', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'UsersEdit' + }). - when('/teams/:team_id/credentials/add', { templateUrl: urlPrefix + 'partials/teams.html', - controller: CredentialsAdd }). + when('/teams/:team_id/projects', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'ProjectsList' + }). - when('/teams/:team_id/credentials/:credential_id', { templateUrl: urlPrefix + 'partials/teams.html', - controller: CredentialsEdit }). + when('/teams/:team_id/projects/add', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'ProjectsAdd' + }). - when('/credentials', { templateUrl: urlPrefix + 'partials/credentials.html', - controller: CredentialsList }). + when('/teams/:team_id/projects/:project_id', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'ProjectsEdit' + }). - when('/credentials/add', { templateUrl: urlPrefix + 'partials/credentials.html', - controller: CredentialsAdd }). + when('/teams/:team_id/credentials', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'CredentialsList' + }). - when('/credentials/:credential_id', { templateUrl: urlPrefix + 'partials/credentials.html', - controller: CredentialsEdit }). - - when('/users', { templateUrl: urlPrefix + 'partials/users.html', - controller: UsersList }). + when('/teams/:team_id/credentials/add', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'CredentialsAdd' + }). - when('/users/add', { templateUrl: urlPrefix + 'partials/users.html', - controller: UsersAdd }). + when('/teams/:team_id/credentials/:credential_id', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'CredentialsEdit' + }). - when('/users/:user_id', { templateUrl: urlPrefix + 'partials/users.html', - controller: UsersEdit }). + when('/credentials', { + templateUrl: urlPrefix + 'partials/credentials.html', + controller: 'CredentialsList' + }). - when('/users/:user_id/credentials', { templateUrl: urlPrefix + 'partials/users.html', - controller: CredentialsList }). + when('/credentials/add', { + templateUrl: urlPrefix + 'partials/credentials.html', + controller: 'CredentialsAdd' + }). - when('/users/:user_id/permissions/add', { templateUrl: urlPrefix + 'partials/users.html', - controller: PermissionsAdd }). + when('/credentials/:credential_id', { + templateUrl: urlPrefix + 'partials/credentials.html', + controller: 'CredentialsEdit' + }). - when('/users/:user_id/permissions', { templateUrl: urlPrefix + 'partials/users.html', - controller: PermissionsList }). + when('/users', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'UsersList' + }). - when('/users/:user_id/permissions/:permission_id', { templateUrl: urlPrefix + 'partials/users.html', - controller: PermissionsEdit }). + when('/users/add', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'UsersAdd' + }). - when('/users/:user_id/credentials/add', { templateUrl: urlPrefix + 'partials/teams.html', - controller: CredentialsAdd }). + when('/users/:user_id', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'UsersEdit' + }). - when('/teams/:user_id/credentials/:credential_id', { templateUrl: urlPrefix + 'partials/teams.html', - controller: CredentialsEdit }). + when('/users/:user_id/credentials', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'CredentialsList' + }). - when('/login', { templateUrl: urlPrefix + 'partials/home.html', controller: Authenticate }). + when('/users/:user_id/permissions/add', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'PermissionsAdd' + }). - when('/logout', { templateUrl: urlPrefix + 'partials/home.html', controller: Authenticate }). + when('/users/:user_id/permissions', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'PermissionsList' + }). - when('/home', { templateUrl: urlPrefix + 'partials/home.html', controller: Home }). + when('/users/:user_id/permissions/:permission_id', { + templateUrl: urlPrefix + 'partials/users.html', + controller: 'PermissionsEdit' + }). - when('/home/groups', { templateUrl: urlPrefix + 'partials/subhome.html', controller: HomeGroups }). + when('/users/:user_id/credentials/add', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'CredentialsAdd' + }). - when('/home/hosts', { templateUrl: urlPrefix + 'partials/subhome.html', controller: HomeHosts }). - - otherwise({redirectTo: '/home'}); - }]) - .run(['$cookieStore', '$rootScope', 'CheckLicense', '$location', 'Authorization','LoadBasePaths', 'ViewLicense', - 'Timer', 'ClearScope', 'HideStream', - function($cookieStore, $rootScope, CheckLicense, $location, Authorization, LoadBasePaths, ViewLicense, - Timer, ClearScope, HideStream) { - - LoadBasePaths(); - - $rootScope.breadcrumbs = new Array(); - $rootScope.crumbCache = new Array(); - $rootScope.sessionTimer = Timer.init(); + when('/teams/:user_id/credentials/:credential_id', { + templateUrl: urlPrefix + 'partials/teams.html', + controller: 'CredentialsEdit' + }). - $rootScope.$on("$routeChangeStart", function(event, next, current) { + when('/login', { + templateUrl: urlPrefix + 'partials/home.html', + controller: 'Authenticate' + }). - // Before navigating away from current tab, make sure the primary view is visible - if ($('#stream-container').is(':visible')) { - HideStream(); - } + when('/logout', { + templateUrl: urlPrefix + 'partials/home.html', + controller: 'Authenticate' + }). - // On each navigation request, check that the user is logged in - if ( !/^\/(login|logout)/.test($location.path()) ) { - // capture most recent URL, excluding login/logout - $rootScope.lastPath = $location.path(); - $cookieStore.put('lastPath', $location.path()); - } + when('/home', { + templateUrl: urlPrefix + 'partials/home.html', + controller: 'Home' + }). - if (Authorization.isUserLoggedIn() == false) { - if ( next.templateUrl != (urlPrefix + 'partials/login.html') ) { - $location.path('/login'); - } - } - else if ($rootScope.sessionTimer.isExpired()) { - if ( next.templateUrl != (urlPrefix + 'partials/login.html') ) { - $rootScope.sessionTimer.expireSession(); - $location.path('/login'); - } - } - else { - if ($rootScope.current_user == undefined || $rootScope.current_user == null) { - Authorization.restoreUserInfo(); //user must have hit browser refresh - } - CheckLicense(); - } - - // Make the correct tab active - var base = $location.path().replace(/^\//,'').split('/')[0]; - if (base == '') { - base = 'home'; - } - else { - base.replace(/\_/g,' '); - } - $('.nav-tabs a[href="#' + base + '"]').tab('show'); + when('/home/groups', { + templateUrl: urlPrefix + 'partials/subhome.html', + controller: 'HomeGroups' + }). + + when('/home/hosts', { + templateUrl: urlPrefix + 'partials/subhome.html', + controller: 'HomeHosts' + }). + + otherwise({ + redirectTo: '/home' + }); + } + ]) + .run(['$cookieStore', '$rootScope', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'ViewLicense', + 'Timer', 'ClearScope', 'HideStream', + function ($cookieStore, $rootScope, CheckLicense, $location, Authorization, LoadBasePaths, ViewLicense, + Timer, ClearScope, HideStream) { + + LoadBasePaths(); + + $rootScope.breadcrumbs = []; + $rootScope.crumbCache = []; + $rootScope.sessionTimer = Timer.init(); + + $rootScope.$on("$routeChangeStart", function (event, next) { + + // Before navigating away from current tab, make sure the primary view is visible + if ($('#stream-container').is(':visible')) { + HideStream(); + } + + // On each navigation request, check that the user is logged in + if (!/^\/(login|logout)/.test($location.path())) { + // capture most recent URL, excluding login/logout + $rootScope.lastPath = $location.path(); + $cookieStore.put('lastPath', $location.path()); + } + + if (Authorization.isUserLoggedIn() === false) { + if (next.templateUrl !== (urlPrefix + 'partials/login.html')) { + $location.path('/login'); + } + } else if ($rootScope.sessionTimer.isExpired()) { + if (next.templateUrl !== (urlPrefix + 'partials/login.html')) { + $rootScope.sessionTimer.expireSession(); + $location.path('/login'); + } + } else { + if ($rootScope.current_user === undefined || $rootScope.current_user === null) { + Authorization.restoreUserInfo(); //user must have hit browser refresh + } + CheckLicense(); + } + + // Make the correct tab active + var base = $location.path().replace(/^\//, '').split('/')[0]; + if (base === '') { + base = 'home'; + } else { + base.replace(/\_/g, ' '); + } + $('.nav-tabs a[href="#' + base + '"]').tab('show'); }); - if (!Authorization.getToken()) { - // When the app first loads, redirect to login page - $rootScope.sessionExpired = false; - $cookieStore.put('sessionExpired', false); - $location.path('/login'); - } - else { - // If browser refresh, set the user_is_superuser value - $rootScope['user_is_superuser'] = Authorization.getUserInfo('is_superuser'); - } - - // If browser refresh, activate the correct tab - var base = ($location.path().replace(/^\//,'').split('/')[0]); - if (base == '') { - base = 'home'; - $location.path('/home'); - } - else { - base.replace(/\_/g,' '); - } - $('.nav-tabs a[href="#' + base + '"]').tab('show'); - - $rootScope.viewCurrentUser = function() { - $location.path('/users/' + $rootScope.current_user.id); + if (!Authorization.getToken()) { + // When the app first loads, redirect to login page + $rootScope.sessionExpired = false; + $cookieStore.put('sessionExpired', false); + $location.path('/login'); + } else { + // If browser refresh, set the user_is_superuser value + $rootScope.user_is_superuser = Authorization.getUserInfo('is_superuser'); } - $rootScope.viewLicense = function() { - //$location.path('/license'); - ViewLicense(); - } - }]); + // If browser refresh, activate the correct tab + var base = ($location.path().replace(/^\//, '').split('/')[0]); + if (base === '') { + base = 'home'; + $location.path('/home'); + } else { + base.replace(/\_/g, ' '); + } + $('.nav-tabs a[href="#' + base + '"]').tab('show'); + + $rootScope.viewCurrentUser = function () { + $location.path('/users/' + $rootScope.current_user.id); + }; + + $rootScope.viewLicense = function () { + //$location.path('/license'); + ViewLicense(); + }; + } + ]); \ No newline at end of file diff --git a/awx/ui/static/js/config.js b/awx/ui/static/js/config.js index c7f6b47587..5fac0d9a38 100644 --- a/awx/ui/static/js/config.js +++ b/awx/ui/static/js/config.js @@ -1,4 +1,4 @@ -/************************************ +/********************************************************************** * * Copyright (c) 2014 AnsibleWorks, Inc. * @@ -8,19 +8,21 @@ * */ -var $AnsibleConfig = -{ - tooltip_delay: {show: 500, hide: 100}, // Default number of milliseconds to delay displaying/hiding tooltips +/*jshint unused:false */ - debug_mode: true, // Enable console logging messages - - password_strength: 45, // User password strength. Integer between 0 and 100, 100 being impossibly strong. - // This value controls progress bar colors: - // 0 to password_strength - 15 = red; - // password_strength - 15 to password_strength = yellow - // > password_strength = green - // It also controls password validation. Passwords are rejected if the score is not > password_strength. +var $AnsibleConfig = { - session_timeout: 1800 // Number of seconds before an inactive session is automatically timed out and forced to log in again. - // Separate from time out value set in API. - } + tooltip_delay: {show: 500, hide: 100}, // Default number of milliseconds to delay displaying/hiding tooltips + + debug_mode: true, // Enable console logging messages + + password_strength: 45, // User password strength. Integer between 0 and 100, 100 being impossibly strong. + // This value controls progress bar colors: + // 0 to password_strength - 15 = red; + // password_strength - 15 to password_strength = yellow + // > password_strength = green + // It also controls password validation. Passwords are rejected if the score is not > password_strength. + + session_timeout: 1800 // Number of seconds before an inactive session is automatically timed out and forced to log in again. + // Separate from time out value set in API. +}; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Credentials.js b/awx/ui/static/js/controllers/Credentials.js index ef4a636035..7ba65e003c 100644 --- a/awx/ui/static/js/controllers/Credentials.js +++ b/awx/ui/static/js/controllers/Credentials.js @@ -1,12 +1,12 @@ -/************************************ +/************************************************* * Copyright (c) 2014 AnsibleWorks, Inc. * - * * Credentials.js * * Controller functions for the Credential model. * */ + 'use strict'; function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList, @@ -114,10 +114,10 @@ function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest var url = defaultUrl + id + '/'; Rest.setUrl(url); Rest.destroy() - .success(function (data, status, headers, config) { + .success(function () { scope.search(list.iterator); }) - .error(function (data, status, headers, config) { + .error(function (data, status) { Wait('stop'); ProcessErrors(scope, data, status, null, { hdr: 'Error!', @@ -143,7 +143,7 @@ CredentialsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeP function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateList, SearchInit, PaginateInit, LookUpInit, UserList, TeamList, GetBasePath, - GetChoices, Empty, KindChange, OwnerChange, FormSave, DebugForm) { + GetChoices, Empty, KindChange, OwnerChange, FormSave) { ClearScope('tree-form'); ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -152,7 +152,6 @@ function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routePar var form = CredentialForm, generator = GenerateForm, scope = generator.inject(form, { mode: 'add', related: false }), - base = $location.path().replace(/^\//, '').split('/')[0], defaultUrl = GetBasePath('credentials'), url; @@ -193,10 +192,10 @@ function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routePar url = GetBasePath('users') + $routeParams.user_id + '/'; Rest.setUrl(url); Rest.get() - .success(function (data, status, headers, config) { + .success(function (data) { scope.user_username = data.username; }) - .error(function (data, status, headers, config) { + .error(function (data, status) { ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve user. GET status: ' + status }); }); @@ -210,10 +209,10 @@ function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routePar url = GetBasePath('teams') + $routeParams.team_id + '/'; Rest.setUrl(url); Rest.get() - .success(function (data, status, headers, config) { + .success(function (data) { scope.team_name = data.name; }) - .error(function (data, status, headers, config) { + .error(function (data, status) { ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve team. GET status: ' + status }); }); @@ -289,7 +288,7 @@ function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routePar CredentialsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'CredentialForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList', 'SearchInit', 'PaginateInit', 'LookUpInit', 'UserList', 'TeamList', 'GetBasePath', 'GetChoices', 'Empty', - 'KindChange', 'OwnerChange', 'FormSave', 'DebugForm' + 'KindChange', 'OwnerChange', 'FormSave' ]; diff --git a/awx/ui/static/js/controllers/JobEvents.js b/awx/ui/static/js/controllers/JobEvents.js index 7c9406dd0d..f62f0ff73f 100644 --- a/awx/ui/static/js/controllers/JobEvents.js +++ b/awx/ui/static/js/controllers/JobEvents.js @@ -249,13 +249,12 @@ JobEventsList.$inject = ['$filter', '$scope', '$rootScope', '$location', '$log', 'ProcessErrors', 'GetBasePath', 'LookUpInit', 'ToggleChildren', 'FormatDate', 'EventView', 'Refresh', 'Wait' ]; -function JobEventsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventForm, GenerateForm, - Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, FormatDate, EventView, - Wait) { - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. - // Inject dynamic view - var form = JobEventForm, +function JobEventsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventsForm, GenerateForm, + Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, FormatDate, EventView, Wait) { + + ClearScope('htmlTemplate'); + + var form = JobEventsForm, generator = GenerateForm, scope = GenerateForm.inject(form, { mode: 'edit', related: true }), defaultUrl = GetBasePath('base') + 'job_events/' + $routeParams.event_id + '/'; @@ -348,7 +347,7 @@ function JobEventsEdit($scope, $rootScope, $compile, $location, $log, $routePara } -JobEventsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobEventForm', +JobEventsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobEventsForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', 'FormatDate', 'EventView', 'Wait' ]; \ No newline at end of file diff --git a/awx/ui/static/js/forms/ActivityDetail.js b/awx/ui/static/js/forms/ActivityDetail.js index 557e586219..e5b63ae77a 100644 --- a/awx/ui/static/js/forms/ActivityDetail.js +++ b/awx/ui/static/js/forms/ActivityDetail.js @@ -6,11 +6,10 @@ * */ angular.module('ActivityDetailDefinition', []) - .value( - 'ActivityDetailForm', { - + .value('ActivityDetailForm', { + name: 'activity', - editTitle: 'Activity Detail', + editTitle: 'Activity Detail', well: false, 'class': 'horizontal-narrow', formFieldSize: 'col-lg-10', @@ -21,18 +20,18 @@ angular.module('ActivityDetailDefinition', []) label: "Initiated by", type: 'text', readonly: true - }, + }, operation: { label: 'Action', type: 'text', readonly: true - }, + }, changes: { label: 'Changes', type: 'textarea', ngHide: "!changes || changes =='' || changes == 'null'", readonly: true - } - } + } + } }); //Form diff --git a/awx/ui/static/js/forms/Credentials.js b/awx/ui/static/js/forms/Credentials.js index eef3a5be53..31ec9dec2b 100644 --- a/awx/ui/static/js/forms/Credentials.js +++ b/awx/ui/static/js/forms/Credentials.js @@ -6,23 +6,22 @@ * */ angular.module('CredentialFormDefinition', []) - .value( - 'CredentialForm', { - - addTitle: 'Create Credential', //Legend in add mode - editTitle: '{{ name }}', //Legend in edit mode + .value('CredentialForm', { + + addTitle: 'Create Credential', //Legend in add mode + editTitle: '{{ name }}', //Legend in edit mode name: 'credential', well: true, forceListeners: true, - + actions: { stream: { ngClick: "showActivity()", awToolTip: "View Activity Stream", mode: 'edit' - } - }, - + } + }, + fields: { name: { label: 'Name', @@ -30,27 +29,31 @@ angular.module('CredentialFormDefinition', []) addRequired: true, editRequired: true, autocomplete: false - }, - description: { + }, + description: { label: 'Description', type: 'text', addRequired: false, editRequired: false - }, + }, owner: { label: "Does this credential belong to a team or user?", type: 'radio_group', ngChange: "ownerChange()", - options: [ - { label: 'User', value: 'user', selected: true }, - { label: 'Team', value: 'team' } - ], - awPopOver: "

A credential must be associated with either a user or a team. Choosing a user allows only the selected user access " + + options: [{ + label: 'User', + value: 'user', + selected: true + }, { + label: 'Team', + value: 'team' + }], + awPopOver: "

A credential must be associated with either a user or a team. Choosing a user allows only the selected user access " + "to the credential. Choosing a team shares the credential with all team members.

", dataTitle: 'Owner', dataPlacement: 'right', dataContainer: "body" - }, + }, user: { label: 'User that owns this credential', type: 'lookup', @@ -58,8 +61,11 @@ angular.module('CredentialFormDefinition', []) sourceField: 'username', ngClick: 'lookUpUser()', ngShow: "owner == 'user'", - awRequiredWhen: { variable: "user_required", init: "false" } - }, + awRequiredWhen: { + variable: "user_required", + init: "false" + } + }, team: { label: 'Team that owns this credential', type: 'lookup', @@ -67,69 +73,84 @@ angular.module('CredentialFormDefinition', []) sourceField: 'name', ngClick: 'lookUpTeam()', ngShow: "owner == 'team'", - awRequiredWhen: { variable: "team_required", init: "false" } - }, + awRequiredWhen: { + variable: "team_required", + init: "false" + } + }, kind: { label: 'Type', excludeModal: true, type: 'select', ngOptions: 'kind.label for kind in credential_kind_options', ngChange: 'kindChange()', - addRequired: true, + addRequired: true, editRequired: true, - helpCollapse: [ - { hdr: 'Select a Credential Type', - content: '
\n' + - '
AWS
\n' + - '
Access keys for Amazon Web Services used for inventory management or deployment.
\n' + - '
Machine
\n' + - '
Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' + - 'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' + - 'remote hosts.
' + - '
Rackspace
\n' + - '
Access information for Rackspace Cloud used for inventory management or deployment.
\n' + - '
SCM
\n' + - '
Used to check out and synchronize playbook repositories with a remote source control ' + - 'management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are ' + - 'used on the Projects tab.
\n' + - '
\n' - }] - }, + helpCollapse: [{ + hdr: 'Select a Credential Type', + content: '
\n' + + '
AWS
\n' + + '
Access keys for Amazon Web Services used for inventory management or deployment.
\n' + + '
Machine
\n' + + '
Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' + + 'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' + + 'remote hosts.
' + + '
Rackspace
\n' + + '
Access information for Rackspace Cloud used for inventory management or deployment.
\n' + + '
SCM
\n' + + '
Used to check out and synchronize playbook repositories with a remote source control ' + + 'management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are ' + + 'used on the Projects tab.
\n' + + '
\n' + }] + }, access_key: { label: 'Access Key', type: 'text', ngShow: "kind.value == 'aws'", - awRequiredWhen: { variable: "aws_required", init: false }, + awRequiredWhen: { + variable: "aws_required", + init: false + }, autocomplete: false, apiField: 'username' - }, + }, secret_key: { label: 'Secret Key', type: 'password', ngShow: "kind.value == 'aws'", - awRequiredWhen: { variable: "aws_required", init: false }, + awRequiredWhen: { + variable: "aws_required", + init: false + }, autocomplete: false, ask: false, clear: false, apiField: 'passwowrd' - }, + }, "username": { labelBind: 'usernameLabel', type: 'text', ngShow: "kind.value && kind.value !== 'aws'", - awRequiredWhen: {variable: 'rackspace_required', init: false }, - autocomplete: false + awRequiredWhen: { + variable: 'rackspace_required', + init: false }, + autocomplete: false + }, "api_key": { label: 'API Key', type: 'password', ngShow: "kind.value == 'rax'", - awRequiredWhen: { variable: "rackspace_required", init: false }, + awRequiredWhen: { + variable: "rackspace_required", + init: false + }, autocomplete: false, ask: false, clear: false, apiField: 'passwowrd' - }, + }, "password": { label: 'Password', type: 'password', @@ -141,7 +162,7 @@ angular.module('CredentialFormDefinition', []) clear: false, associated: 'password_confirm', autocomplete: false - }, + }, "password_confirm": { label: 'Confirm Password', type: 'password', @@ -151,7 +172,7 @@ angular.module('CredentialFormDefinition', []) awPassMatch: true, associated: 'password', autocomplete: false - }, + }, "ssh_password": { label: 'SSH Password', type: 'password', @@ -163,7 +184,7 @@ angular.module('CredentialFormDefinition', []) clear: true, associated: 'ssh_password_confirm', autocomplete: false - }, + }, "ssh_password_confirm": { label: 'Confirm SSH Password', type: 'password', @@ -173,7 +194,7 @@ angular.module('CredentialFormDefinition', []) awPassMatch: true, associated: 'ssh_password', autocomplete: false - }, + }, "ssh_key_data": { labelBind: 'sshKeyDataLabel', type: 'textarea', @@ -182,7 +203,7 @@ angular.module('CredentialFormDefinition', []) editRequired: false, 'class': 'ssh-key-field', rows: 10 - }, + }, "ssh_key_unlock": { label: 'Key Password', type: 'password', @@ -192,9 +213,9 @@ angular.module('CredentialFormDefinition', []) ngChange: "clearPWConfirm('ssh_key_unlock_confirm')", associated: 'ssh_key_unlock_confirm', ask: true, - askShow: "kind.value == 'ssh'", //Only allow ask for machine credentials + askShow: "kind.value == 'ssh'", //Only allow ask for machine credentials clear: true - }, + }, "ssh_key_unlock_confirm": { label: 'Confirm Key Password', type: 'password', @@ -203,7 +224,7 @@ angular.module('CredentialFormDefinition', []) editRequired: false, awPassMatch: true, associated: 'ssh_key_unlock' - }, + }, "sudo_username": { label: 'Sudo Username', type: 'text', @@ -211,7 +232,7 @@ angular.module('CredentialFormDefinition', []) addRequired: false, editRequired: false, autocomplete: false - }, + }, "sudo_password": { label: 'Sudo Password', type: 'password', @@ -223,7 +244,7 @@ angular.module('CredentialFormDefinition', []) clear: true, associated: 'sudo_password_confirm', autocomplete: false - }, + }, "sudo_password_confirm": { label: 'Confirm Sudo Password', type: 'password', @@ -233,24 +254,21 @@ angular.module('CredentialFormDefinition', []) awPassMatch: true, associated: 'sudo_password', autocomplete: false - } - }, - - buttons: { //for now always generates \n"; - - if (target.id == 1 || inbound.parent == 0) { - // We're moving the group to the top level, or we're moving a top level group down - html += "

Move Group

\n"; - } - else { - html += "

Copy or Move?

\n"; + + if (target.id === 1 || inbound.parent === 0) { + // We're moving the group to the top level, or we're moving a top level group down + html += "

Move Group

\n"; + } else { + html += "

Copy or Move?

\n"; } html += "\n"; html += "
\n"; - - if (target.id == 1) { + + if (target.id === 1) { html += "

Are you sure you want to move group " + inbound.name + " to the top level?

"; - } - else if (inbound.parent == 0) { + } else if (inbound.parent === 0) { html += "

Are you sure you want to move group " + inbound.name + " from the top level and make it a child of " + target.name + "?

"; - } - else { + } else { html += "
\n"; html += "

Would you like to copy or move group " + inbound.name + " to group " + target.name + "?

\n"; html += "
\n"; @@ -300,12 +321,12 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P html += "
\n"; html += "
\n"; } - + html += "
\n"; html += "
\n"; html += "Cancel\n"; - if (target.id == 1 || inbound.parent == 0) { + if (target.id === 1 || inbound.parent === 0) { // We're moving the group to the top level, or we're moving a top level group down html += "Yes\n"; } @@ -314,134 +335,135 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P html += "
\n"; html += "\n"; html += "\n"; - + // Inject our custom dialog - var e = angular.element(document.getElementById('inventory-modal-container')); + e= angular.element(document.getElementById('inventory-modal-container')); e.empty().append(html); $compile(e)(scope); - + // Display it $('#copy-prompt-modal').modal({ backdrop: 'static', keyboard: true, show: true - }); - + }); + // Respond to move - scope.moveGroup = function() { - + scope.moveGroup = function () { + var url, group, parent; $('#copy-prompt-modal').modal('hide'); Wait('start'); - + // disassociate the group from the original parent if (scope.removeGroupRemove) { - scope.removeGroupRemove(); + scope.removeGroupRemove(); } - scope.removeGroupRemove = scope.$on('removeGroup', function() { + scope.removeGroupRemove = scope.$on('removeGroup', function () { if (inbound.parent > 0) { // Only remove a group from a parent when the parent is a group and not the inventory root - var parent = Find({ list: scope.groups, key: 'id', val: inbound.parent }) - var url = GetBasePath('base') + 'groups/' + parent.group_id + '/children/'; + parent = Find({ list: scope.groups, key: 'id', val: inbound.parent }); + url = GetBasePath('base') + 'groups/' + parent.group_id + '/children/'; Rest.setUrl(url); Rest.post({ id: inbound.group_id, disassociate: 1 }) - .success( function(data, status, headers, config) { + .success(function () { //Triggers refresh of group list in inventory controller - scope.$emit('GroupDeleteCompleted'); - }) - .error( function(data, status, headers, config) { + scope.$emit('GroupDeleteCompleted'); + }) + .error(function (data, status) { Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to remove ' + inbound.name + - ' from ' + parent.name + '. POST returned status: ' + status }); + ProcessErrors(scope, data, status, null, { + hdr: 'Error!', + msg: 'Failed to remove ' + inbound.name + + ' from ' + parent.name + '. POST returned status: ' + status }); - } - else { + }); + } else { //Triggers refresh of group list in inventory controller - scope.$emit('GroupDeleteCompleted'); + scope.$emit('GroupDeleteCompleted'); } - }); + }); // add the new group to the target parent - var url = (!Empty(target.group_id)) ? - GetBasePath('base') + 'groups/' + target.group_id + '/children/' : - GetBasePath('inventory') + scope.inventory_id + '/groups/'; - var group = { + url = (!Empty(target.group_id)) ? + GetBasePath('base') + 'groups/' + target.group_id + '/children/' : + GetBasePath('inventory') + scope.inventory_id + '/groups/'; + group = { id: inbound.group_id, name: inbound.name, description: inbound.description, inventory: scope.inventory_id - } + }; Rest.setUrl(url); Rest.post(group) - .success( function(data, status, headers, config) { + .success(function () { scope.$emit('removeGroup'); - }) - .error( function(data, status, headers, config) { + }) + .error(function (data, status) { var target_name = (Empty(target.group_id)) ? 'inventory' : target.name; Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to add ' + node.attr('name') + ' to ' + - target_name + '. POST returned status: ' + status }); - }); - } - + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to add ' + inbound.name + ' to ' + target_name + '. POST returned status: ' + status }); + }); + }; - scope.copyGroup = function() { + + scope.copyGroup = function () { $('#copy-prompt-modal').modal('hide'); Wait('start'); // add the new group to the target parent - var url = (!Empty(target.group_id)) ? - GetBasePath('base') + 'groups/' + target.group_id + '/children/' : - GetBasePath('inventory') + scope.inventory_id + '/groups/'; - var group = { - id: inbound.group_id, - name: inbound.name, - description: inbound.description, - inventory: scope.inventory_id - } + var url = (!Empty(target.group_id)) ? + GetBasePath('base') + 'groups/' + target.group_id + '/children/' : + GetBasePath('inventory') + scope.inventory_id + '/groups/', + group = { + id: inbound.group_id, + name: inbound.name, + description: inbound.description, + inventory: scope.inventory_id + }; + Rest.setUrl(url); Rest.post(group) - .success( function(data, status, headers, config) { - //Triggers refresh of group list in inventory controller - scope.$emit('GroupDeleteCompleted'); - }) - .error( function(data, status, headers, config) { - var target_name = (Empty(target.group_id)) ? 'inventory' : target.name; - Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to add ' + inbound.name + ' to ' + - target_name + '. POST returned status: ' + status }); - }); - } + .success(function () { + //Triggers refresh of group list in inventory controller + scope.$emit('GroupDeleteCompleted'); + }) + .error(function (data, status) { + var target_name = (Empty(target.group_id)) ? 'inventory' : target.name; + Wait('stop'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to add ' + inbound.name + ' to ' + target_name + '. POST returned status: ' + status + }); + }); + }; - } - }]) - - // Copy a host after drag-n-drop - .factory('CopyMoveHost', ['$compile', 'Alert', 'ProcessErrors', 'Find', 'Wait', 'Rest', 'Empty', 'GetBasePath', - function($compile, Alert, ProcessErrors, Find, Wait, Rest, Empty, GetBasePath) { - return function(params) { + }; + } +]) + +// Copy a host after drag-n-drop +.factory('CopyMoveHost', ['$compile', 'Alert', 'ProcessErrors', 'Find', 'Wait', 'Rest', 'Empty', 'GetBasePath', + function ($compile, Alert, ProcessErrors, Find, Wait, Rest, Empty, GetBasePath) { + return function (params) { var scope = params.scope, target = Find({ list: scope.groups, key: 'id', val: params.target_tree_id }), host = Find({ list: scope.hosts, key: 'id', val: params.host_id }), - found = false, i; - + found = false, e, i, html = ''; + if (host.summary_fields.all_groups) { - for (i=0; i< host.summary_fields.all_groups.length; i++) { - if (host.summary_fields.all_groups[i].id == target.group_id) { - found = true; - break; + for (i = 0; i < host.summary_fields.all_groups.length; i++) { + if (host.summary_fields.all_groups[i].id === target.group_id) { + found = true; + break; } } } if (found) { - var html = ''; html += "
\n"; html += "
\n"; html += "
\n"; html += "
\n"; - html += "\n"; html += "

Already in Group

\n"; html += "
\n"; @@ -456,31 +478,30 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P html += "
\n"; // Inject our custom dialog - var e = angular.element(document.getElementById('inventory-modal-container')); + e = angular.element(document.getElementById('inventory-modal-container')); e.empty().append(html); $compile(e)(scope); - + // Display it $('#copy-alert-modal').modal({ backdrop: 'static', keyboard: true, show: true - }); - - } - else { + }); + + } else { // Build the html for our prompt dialog - var html = ''; + html = ''; html += "
\n"; html += "
\n"; html += "
\n"; html += "
\n"; - html += "\n"; html += "

Copy Host

\n"; html += "
\n"; html += "
\n"; - html += "

Are you sure you want to copy host " + host.name + ' to group ' + target.name + '?

'; + html += "

Are you sure you want to copy host " + host.name + ' to group ' + target.name + '?

'; html += "
\n"; html += "
\n"; html += "No\n"; @@ -489,35 +510,35 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P html += "
\n"; html += "
\n"; html += "
\n"; - + // Inject our custom dialog - var e = angular.element(document.getElementById('inventory-modal-container')); + e = angular.element(document.getElementById('inventory-modal-container')); e.empty().append(html); $compile(e)(scope); - + // Display it $('#copy-prompt-modal').modal({ backdrop: 'static', keyboard: true, show: true - }); + }); - scope.copyHost = function() { + scope.copyHost = function () { $('#copy-prompt-modal').modal('hide'); Wait('start'); Rest.setUrl(GetBasePath('groups') + target.group_id + '/hosts/'); Rest.post(host) - .success(function(data, status, headers, config) { + .success(function () { // Signal the controller to refresh the hosts view scope.$emit('GroupTreeRefreshed'); - }) - .error(function(data, status, headers, config) { + }) + .error(function (data, status) { Wait('stop'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to add ' + host.name + ' to ' + - target.name + '. POST returned status: ' + status }); - }); - } + ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to add ' + host.name + ' to ' + + target.name + '. POST returned status: ' + status }); + }); + }; } - } - }]); + }; + } +]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/RestServices.js b/awx/ui/static/lib/ansible/RestServices.js index cf9588793f..efcd546aa4 100644 --- a/awx/ui/static/lib/ansible/RestServices.js +++ b/awx/ui/static/lib/ansible/RestServices.js @@ -4,154 +4,194 @@ * Generic accessor for Ansible Commander services * */ - - 'use strict'; +'use strict'; -angular.module('RestServices',['ngCookies','AuthService']) -.factory('Rest', ['$http','$rootScope','$cookieStore', '$q', 'Authorization', -function($http, $rootScope, $cookieStore, $q, Authorization) { - return { - - headers: {}, +angular.module('RestServices', ['ngCookies', 'AuthService']) + .factory('Rest', ['$http', '$rootScope', '$cookieStore', '$q', 'Authorization', + function ($http, $rootScope, $cookieStore, $q, Authorization) { + return { - setUrl: function (url) { - this.url = url; - }, - checkExpired: function() { - return $rootScope.sessionTimer.isExpired(); - }, - pReplace: function() { - //in our url, replace :xx params with a value, assuming - //we can find it in user supplied params. - var key,rgx; - for (key in this.params) { - rgx = new RegExp("\\:" + key,'gm'); - if (rgx.test(this.url)) { - this.url = this.url.replace(rgx,this.params[key]); - delete this.params[key]; - } - } - }, - createResponse: function(data, status) { - // Simulate an http response when a token error occurs - // http://stackoverflow.com/questions/18243286/angularjs-promises-simulate-http-promises - - var promise = $q.reject({ data: data, status: status }); - promise.success = function(fn){ - promise.then(function(response){ fn(response.data, response.status) }, null); - return promise + headers: {}, + + setUrl: function (url) { + this.url = url; + }, + checkExpired: function () { + return $rootScope.sessionTimer.isExpired(); + }, + pReplace: function () { + //in our url, replace :xx params with a value, assuming + //we can find it in user supplied params. + var key, rgx; + for (key in this.params) { + rgx = new RegExp("\\:" + key, 'gm'); + if (rgx.test(this.url)) { + this.url = this.url.replace(rgx, this.params[key]); + delete this.params[key]; + } + } + }, + createResponse: function (data, status) { + // Simulate an http response when a token error occurs + // http://stackoverflow.com/questions/18243286/angularjs-promises-simulate-http-promises + + var promise = $q.reject({ + data: data, + status: status + }); + promise.success = function (fn) { + promise.then(function (response) { + fn(response.data, response.status); + }, null); + return promise; + }; + promise.error = function (fn) { + promise.then(null, function (response) { + fn(response.data, response.status); + }); + return promise; + }; + return promise; + }, + + setHeader: function (hdr) { + // Pass in { key: value } pairs to be added to the header + for (var h in hdr) { + this.headers[h] = hdr[h]; + } + }, + get: function (args) { + args = (args) ? args : {}; + this.params = (args.params) ? args.params : null; + this.pReplace(); + var expired = this.checkExpired(), + token = Authorization.getToken(); + if (expired) { + return this.createResponse({ + detail: 'Token is expired' + }, 401); + } else if (token) { + this.setHeader({ + Authorization: 'Token ' + token + }); + this.setHeader({ + "X-Auth-Token": 'Token ' + token + }); + return $http({ + method: 'GET', + url: this.url, + headers: this.headers, + params: this.params + }); + } else { + return this.createResponse({ + detail: 'Invalid token' + }, 401); + } + }, + post: function (data) { + var token = Authorization.getToken(), + expired = this.checkExpired(); + if (expired) { + return this.createResponse({ + detail: 'Token is expired' + }, 401); + } else if (token) { + this.setHeader({ + Authorization: 'Token ' + token + }); + this.setHeader({ + "X-Auth-Token": 'Token ' + token + }); + return $http({ + method: 'POST', + url: this.url, + headers: this.headers, + data: data + }); + } else { + return this.createResponse({ + detail: 'Invalid token' + }, 401); + } + }, + put: function (data) { + var token = Authorization.getToken(), + expired = this.checkExpired(); + if (expired) { + return this.createResponse({ + detail: 'Token is expired' + }, 401); + } else if (token) { + this.setHeader({ + Authorization: 'Token ' + token + }); + this.setHeader({ + "X-Auth-Token": 'Token ' + token + }); + return $http({ + method: 'PUT', + url: this.url, + headers: this.headers, + data: data + }); + } else { + return this.createResponse({ + detail: 'Invalid token' + }, 401); + } + }, + destroy: function (data) { + var token = Authorization.getToken(), + expired = this.checkExpired(); + if (expired) { + return this.createResponse({ + detail: 'Token is expired' + }, 401); + } else if (token) { + this.setHeader({ + Authorization: 'Token ' + token + }); + this.setHeader({ + "X-Auth-Token": 'Token ' + token + }); + return $http({ + method: 'DELETE', + url: this.url, + headers: this.headers, + data: data + }); + } else { + return this.createResponse({ + detail: 'Invalid token' + }, 401); + } + }, + options: function () { + var token = Authorization.getToken(), + expired = this.checkExpired(); + if (expired) { + return this.createResponse({ + detail: 'Token is expired' + }, 401); + } else if (token) { + this.setHeader({ + Authorization: 'Token ' + token + }); + this.setHeader({ + "X-Auth-Token": 'Token ' + token + }); + return $http({ + method: 'OPTIONS', + url: this.url, + headers: this.headers + }); + } else { + return this.createResponse({ + detail: 'Invalid token' + }, 401); + } + } }; - promise.error = function(fn){ - promise.then(null, function(response){ fn(response.data, response.status) }); - return promise; - }; - return promise; - }, - - setHeader: function(hdr) { - // Pass in { key: value } pairs to be added to the header - for (var h in hdr) { - this.headers[h] = hdr[h]; } - }, - get: function(args) { - args = (args) ? args : {}; - this.params = (args.params) ? args.params : null; - this.pReplace(); - var expired = this.checkExpired(); - var token = Authorization.getToken(); - if (expired) { - return this.createResponse({ detail: 'Token is expired' }, 401); - } - else if (token) { - this.setHeader({ Authorization: 'Token ' + token }); - this.setHeader({ "X-Auth-Token": 'Token ' + token }); - return $http({method: 'GET', - url: this.url, - headers: this.headers, - params: this.params - }); - } - else { - return this.createResponse({ detail: 'Invalid token' }, 401); - } - }, - post: function(data) { - var token = Authorization.getToken(); - var expired = this.checkExpired(); - if (expired) { - return this.createResponse({ detail: 'Token is expired' }, 401); - } - else if (token) { - this.setHeader({ Authorization: 'Token ' + token }); - this.setHeader({ "X-Auth-Token": 'Token ' + token }); - return $http({ - method: 'POST', - url: this.url, - headers: this.headers, - data: data }); - } - else { - return this.createResponse({ detail: 'Invalid token' }, 401); - } - }, - put: function(data) { - var token = Authorization.getToken(); - var expired = this.checkExpired(); - if (expired) { - return this.createResponse({ detail: 'Token is expired' }, 401); - } - else if (token) { - this.setHeader({ Authorization: 'Token ' + token }); - this.setHeader({ "X-Auth-Token": 'Token ' + token }); - return $http({ - method: 'PUT', - url: this.url, - headers: this.headers, - data: data }); - } - else { - return this.createResponse({ detail: 'Invalid token' }, 401); - } - }, - destroy: function(data) { - var token = Authorization.getToken(); - var expired = this.checkExpired(); - if (expired) { - return this.createResponse({ detail: 'Token is expired' }, 401); - } - else if (token) { - this.setHeader({ Authorization: 'Token ' + token }); - this.setHeader({ "X-Auth-Token": 'Token ' + token }); - return $http({ - method: 'DELETE', - url: this.url, - headers: this.headers, - data: data }); - } - else { - return this.createResponse({ detail: 'Invalid token' }, 401); - } - }, - options: function() { - var token = Authorization.getToken(); - var expired = this.checkExpired(); - if (expired) { - return this.createResponse({ detail: 'Token is expired' }, 401); - } - else if (token) { - this.setHeader({ Authorization: 'Token ' + token }); - this.setHeader({ "X-Auth-Token": 'Token ' + token }); - return $http({ - method: 'OPTIONS', - url: this.url, - headers: this.headers - }); - } - else { - return this.createResponse({ detail: 'Invalid token' }, 401); - } - } - } -}]); - + ]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/Timer.js b/awx/ui/static/lib/ansible/Timer.js index cfc2d4ecdd..36912da5fc 100644 --- a/awx/ui/static/lib/ansible/Timer.js +++ b/awx/ui/static/lib/ansible/Timer.js @@ -7,52 +7,51 @@ * duration set in config.js * */ - 'use strict'; angular.module('TimerService', ['ngCookies', 'Utilities']) - .factory('Timer', ['$rootScope', '$cookieStore', '$location', 'GetBasePath', 'Empty', - function($rootScope, $cookieStore, $location, GetBasePath, Empty) { - return { + .factory('Timer', ['$rootScope', '$cookieStore', '$location', 'GetBasePath', 'Empty', + function ($rootScope, $cookieStore) { + return { - sessionTime: null, - timeout: null, - - getSessionTime: function() { - return (this.sessionTime) ? this.sessionTime : $cookieStore.get('sessionTime'); - }, + sessionTime: null, + timeout: null, - isExpired: function() { - var stime = this.getSessionTime(); - var now = new Date().getTime(); - if ((stime - now) <= 0) { - //expired - return true; - } - else { - // not expired. move timer forward. - this.moveForward(); - return false; - } - }, - - expireSession: function() { - this.sessionTime = 0; - $rootScope.sessionExpired = true; - $cookieStore.put('sessionExpired', true); - }, + getSessionTime: function () { + return (this.sessionTime) ? this.sessionTime : $cookieStore.get('sessionTime'); + }, - moveForward: function() { - var t = new Date().getTime() + ($AnsibleConfig.session_timeout * 1000); - this.sessionTime = t; - $cookieStore.put('sessionTime', t); - $rootScope.sessionExpired = false; - $cookieStore.put('sessionExpired', false); - }, + isExpired: function () { + var stime = this.getSessionTime(), + now = new Date().getTime(); + if ((stime - now) <= 0) { + //expired + return true; + } else { + // not expired. move timer forward. + this.moveForward(); + return false; + } + }, - init: function() { - this.moveForward(); - return this; - } - } - }]); \ No newline at end of file + expireSession: function () { + this.sessionTime = 0; + $rootScope.sessionExpired = true; + $cookieStore.put('sessionExpired', true); + }, + + moveForward: function () { + var t = new Date().getTime() + ($AnsibleConfig.session_timeout * 1000); + this.sessionTime = t; + $cookieStore.put('sessionTime', t); + $rootScope.sessionExpired = false; + $cookieStore.put('sessionExpired', false); + }, + + init: function () { + this.moveForward(); + return this; + } + }; + } + ]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/TreeSelector.js b/awx/ui/static/lib/ansible/TreeSelector.js deleted file mode 100644 index 2b9c723464..0000000000 --- a/awx/ui/static/lib/ansible/TreeSelector.js +++ /dev/null @@ -1,693 +0,0 @@ - -/************************************ - * - * Copyright (c) 2014 AnsibleWorks, Inc. - * - * TreeSelector.js - * - */ - -angular.module('TreeSelector', ['Utilities', 'RestServices', 'TreeSelector', 'GroupsHelper']) - - .factory('SortNodes', [ function() { - return function(data) { - //Sort nodes by name - var names = []; - var newData = []; - for (var i=0; i < data.length; i++) { - names.push(data[i].name); - } - names.sort(); - for (var j=0; j < names.length; j++) { - for (i=0; i < data.length; i++) { - if (data[i].name == names[j]) { - newData.push(data[i]); - } - } - } - return newData; - } - }]) - - // Figure out the group level tool tip - .factory('GetToolTip', [ 'FormatDate', function(FormatDate) { - return function(params) { - - var node = params.node; - - var tip = ''; - var link = ''; - var html_class = ''; - var active_failures = node.hosts_with_active_failures; - var total_hosts = node.total_hosts; - var source = node.summary_fields.inventory_source.source; - var status = node.summary_fields.inventory_source.status; - - // Return values for the status indicator - var status_date = node.summary_fields.inventory_source.last_updated - var last_update = ( status_date == "" || status_date == null ) ? null : FormatDate(new Date(status_date)); - - switch (status) { - case 'never updated': - html_class = 'na'; - tip = '

Inventory update has not been performed.

'; - link = ''; - break; - case 'failed': - tip = '

Inventory update failed! Click to view process output.

'; - link = '/#/inventories/' + node.inventory + '/groups?name=' + node.name; - html_class = true; - break; - case 'successful': - tip = '

Inventory update completed on ' + last_update + '.

'; - html_class = false; - link = ''; - break; - case 'updating': - tip = '

Inventory update process running now. Click to view status.

'; - link = '/#/inventories/' + node.inventory + '/groups?name=' + node.name; - html_class = false; - break; - } - - if (status !== 'failed' && status !== 'updating') { - // update status will not override job status - if (active_failures > 0) { - tip += "

Contains " + active_failures + - [ (active_failures == 1) ? ' host' : ' hosts' ] + ' with failed jobs. Click to view the offending ' + - [ (active_failures == 1) ? ' host' : ' hosts' ] + '.

'; - link = '/#/inventories/' + node.inventory + '/hosts?has_active_failures=true'; - html_class = 'true'; - } - else { - if (total_hosts == 0) { - // no hosts - tip += "

There are no hosts in this group. It's a sad empty shell.

"; - html_class = (html_class == '') ? 'na' : html_class; - } - else if (total_hosts == 1) { - // on host with 0 failures - tip += "

The 1 host in this group is happy! It does not have a job failure.

"; - html_class = 'false'; - } - else { - // many hosts with 0 failures - tip += "

All " + total_hosts + " hosts in this group are happy! None of them have " + - " job failures.

"; - html_class = 'false'; - } - } - } - - return { tooltip: tip, url: link, 'class': html_class }; - - } - }]) - - .factory('GetInventoryToolTip', [ 'FormatDate', function(FormatDate) { - return function(params) { - - var node = params.node; - - var tip = ''; - var link = ''; - var html_class = ''; - var active_failures = node.hosts_with_active_failures; - var total_hosts = node.total_hosts; - var group_failures = node.groups_with_active_failures; - var total_groups = node.total_groups; - var inventory_sources = node.total_inventory_sources; - - if (group_failures > 0) { - tip += "Has " + group_failures + - [ (group_failures == 1) ? ' group' : ' groups' ] + ' with failed inventory updates. ' + - 'Click to view the offending ' + - [ (group_failures == 1) ? ' group.' : ' groups.' ]; - link = '/#/inventories/' + node.id + '/groups?status=failed'; - html_class = 'true'; - } - else if (inventory_sources == 1) { - // on host with 0 failures - tip += "

1 group with an inventory source is happy! No updates have failed.

"; - link = ''; - html_class = 'false'; - } - else if (inventory_sources > 0) { - tip += "

" + inventory_sources + " groups with an inventory source are happy! No updates have failed.

"; - link = 0; - html_class = 'false'; - } - - if (html_class !== 'true') { - // Add job status - if (active_failures > 0) { - tip += "

Contains " + scope.inventories[i].hosts_with_active_failures + - [ (active_failures == 1) ? ' host' : ' hosts' ] + ' with job failures. Click to view the offending ' + - [ (active_failures == 1) ? ' host' : ' hosts' ] + '.

'; - link = '/#/inventories/' + node.id + '/hosts?has_active_failures=true'; - html_class = 'true'; - } - else if (total_hosts == 0) { - tip += "

There are no hosts in this inventory. It's a sad empty shell.

"; - link = ""; - html_class = (html_class == '') ? 'na' : html_class; - } - else if (total_hosts == 1) { - tip += "

The 1 host found in this inventory is happy! There are no job failures.

"; - link = ""; - html_class = "false"; - } - else if (total_hosts > 0) { - tip += "

All " + total_hosts + " hosts are happy! There are no job failures."; - link = ""; - html_class = "false"; - } - } - - return { tooltip: tip, url: link, 'class': html_class }; - - } - }]) - - .factory('BuildTree', ['Rest', 'GetBasePath', 'ProcessErrors', '$compile', '$rootScope', 'Wait', 'SortNodes', 'GetToolTip', - 'GetInventoryToolTip', - function(Rest, GetBasePath, ProcessErrors, $compile, $rootScope, Wait, SortNodes, GetToolTip, GetInventoryToolTip) { - return function(params) { - var scope = params.scope; - var inventory_id = params.inventory_id; - var emit_on_select = params.emit_on_select; - var target_id = params.target_id; - var refresh_tree = (params.refresh == undefined || params.refresh == false) ? false : true; - var moveable = (params.moveable == undefined || params.moveable == false) ? false : true; - var group_id = params.group_id; - var id = params.id; - - var html = ''; - var toolTip = 'Hosts have failed jobs?'; - var idx = 0; - - function refresh(parent) { - var group, title; - var id = parent.attr('id'); - if (parent.attr('data-group-id')) { - group = parent.attr('data-group-id'); - title = parent.attr('data-name'); - } - else { - group = null; - title = 'All Hosts' - } - // The following will trigger the host list to load. See Inventory.js controller. - scope.$emit(emit_on_select, id, group, title); - } - - function activate(e) { - /* Set the clicked node as active */ - var elm = angular.element(e.target); // - var parent = angular.element(e.target.parentNode.parentNode); //

  • - $('.search-tree .active').removeClass('active'); - elm.parent().addClass('active'); // add active class to
    - refresh(parent); - } - - function toggle(e) { - var id, parent, elm, icon; - - if (e.target.tagName == 'I') { - id = e.target.parentNode.parentNode.parentNode.attributes.id.value; - parent = angular.element(e.target.parentNode.parentNode.parentNode); //
  • - elm = angular.element(e.target.parentNode); // - } - else { - id = e.target.parentNode.parentNode.attributes.id.value; - parent = angular.element(e.target.parentNode.parentNode); - elm = angular.element(e.target); - } - - var sibling = angular.element(parent.children()[2]); // - var state = parent.attr('data-state'); - var icon = angular.element(elm.children()[0]); - - if (state == 'closed') { - // expand the elment - var childlists = parent.find('ul'); - if (childlists && childlists.length > 0) { - // has childen - for (var i=0; i < childlists.length; i++) { - var listChild = angular.element(childlists[i]); - var listParent = angular.element(listChild.parent()); - if (listParent.attr('id') == id) { - angular.element(childlists[i]).removeClass('hidden'); - } - } - } - parent.attr('data-state','open'); - icon.removeClass('icon-caret-right').addClass('icon-caret-down'); - } - else { - // close the element - parent.attr('data-state','closed'); - icon.removeClass('icon-caret-down').addClass('icon-caret-right'); - var childlists = parent.find('ul'); - var sublist, subicon; - if (childlists && childlists.length > 0) { - // has childen - childlists.each(function(idx) { - $(this).addClass('hidden'); - subicon = $(this).find('li').first().find('.expand-container i'); - subicon.removeClass('icon-caret-down').addClass('icon-caret-right'); - }); - } - /* When the active node's parent is closed, activate the parent */ - if ($(parent).find('.active').length > 0) { - $(parent).find('.active').removeClass('active'); - sibling.addClass('active'); - refresh(parent); - } - } - } - - if (scope.moveNodeRemove) { - scope.moveNodeRemove(); - } - scope.moveNodeRemove = scope.$on('MoveNode', function(e, node, parent, target) { - var inv_id = scope['inventory_id']; - var variables; - - function cleanUp(state) { - /* - if (state !== 'fail') { - // Visually move the element. Elment will be appended to the - // end of target element list - var elm = $('#' + node.attr('id')).detach(); - if (target.find('ul').length > 0) { - // parent has children - target.find('ul').first().append(elm); - } - else { - target.append('
      '); - target.find('ul').first().append(elm); - } - - // Remove any styling that might be left on the target - // and put the expander icon back the way it should be - target.find('div').each(function(idx) { - if (idx > 0 && idx < 3) { - $(this).css({ 'border-bottom': '2px solid #f5f5f5' }); - } - }); - - // Make sure the parent and target have the correct expander class/icon. - function setExpander(n) { - var c = n.find('.expand-container'); - var icon; - c.first().empty(); - if (n.attr('id') == 'inventory-root-node') { - c.first().html(''); - } - else if (c.length > 1) { - // not root and has children, put expander icon back - icon = (n.attr('data-state') == 'opened') ? 'icon-caret-down' : 'icon-caret-right'; - c.first().html('
      '); - c.first().find('a').first().bind('click', toggle); - } - } - setExpander(target); - setExpander(parent); - } - Wait('stop'); - */ - // Reload the tree - html = ''; - idx = 0; - loadTreeData(); - } - - // disassociate the group from the original parent - if (scope.removeGroupRemove) { - scope.removeGroupRemove(); - } - scope.removeGroupRemove = scope.$on('removeGroup', function() { - if (parent.attr('data-group-id')) { - // Only remove a group from a parent when the parent is a group and not the inventory root - var url = GetBasePath('base') + 'groups/' + parent.attr('data-group-id') + '/children/'; - Rest.setUrl(url); - Rest.post({ id: node.attr('data-group-id'), disassociate: 1 }) - .success( function(data, status, headers, config) { - cleanUp('success'); - }) - .error( function(data, status, headers, config) { - cleanUp('fail'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to remove ' + node.attr('name') + ' from ' + - parent.attr('name') + '. POST returned status: ' + status }); - }); - } - else { - cleanUp('success'); - } - }); - - if (scope['addToTargetRemove']) { - scope.addToTargetRemove(); - } - scope.addToTargetRemove = scope.$on('addToTarget', function() { - // add the new group to the target parent - var url = (target.attr('data-group-id')) ? GetBasePath('base') + 'groups/' + target.attr('data-group-id') + '/children/' : - GetBasePath('inventory') + inv_id + '/groups/'; - var group = { - id: node.attr('data-group-id'), - name: node.attr('data-name'), - description: node.attr('data-description'), - inventory: inv_id - } - Rest.setUrl(url); - Rest.post(group) - .success( function(data, status, headers, config) { - scope.$emit('removeGroup'); - }) - .error( function(data, status, headers, config) { - cleanUp('fail'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to add ' + node.attr('name') + ' to ' + - target.attr('name') + '. POST returned status: ' + status }); - }); - }); - - Wait('start'); - // Lookup the inventory. We already have what we need except for variables. - var url = GetBasePath('base') + 'groups/' + node.attr('data-group-id') + '/'; - Rest.setUrl(url); - Rest.get() - .success( function(data, status, headers, config) { - variables = (data.variables) ? JSON.parse(data.variables) : ""; - scope.$emit('addToTarget'); - }) - .error( function(data, status, headers, config) { - cleanUp('fail'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to lookup group ' + node.attr('name') + - '. GET returned status: ' + status }); - }); - }); - - // The HTML is ready. Insert it into the view. - if (scope.searchTreeReadyRemove) { - scope.searchTreeReadyRemove(); - } - scope.searchTreeReadyRemove = scope.$on('searchTreeReady', function(e, html) { - - var container = angular.element(document.getElementById(target_id)); - container.empty(); - var compiled = $compile(html)(scope); - container.append(compiled); - - function setTitleWidth(elm) { - // Fix for overflowing title text - var container = $('#search-tree-target'); - var container_offset = container.offset(); - var parent = elm.parent(); //
    • - var parent_offset = parent.offset(); - var expander = parent.find('.expand-container').first(); - var badge = parent.find('.badge-container').first(); - var width = container.width() - parent_offset.left + container_offset.left - - badge.width() - expander.width() - 10; - elm.css('width', width + 'px'); - } - - // Fix overflowing title text now - $('#' + target_id).find('.title-container').each(function(idx) { - setTitleWidth($(this)); - }); - - // Fix overflowing title text on screen resize - var timeout; - $(window).resize(function() { - clearTimeout(timeout); //remove prior timer so we don't resize a million times - timeout = setTimeout(function() { - $('#' + target_id).find('.title-container').each(function(idx) { - setTitleWidth($(this)); - }); - }, 500); - }); - - var links = container.find('a'); - for (var i=0; i < links.length; i++) { - var link = angular.element(links[i]); - if (link.hasClass('expand')) { - link.unbind('click', toggle); - link.bind('click', toggle); - } - if (link.hasClass('activate')) { - link.unbind('click', activate); - link.bind('click', activate); - } - } - - if (refresh_tree && group_id !== undefined) { - // pick a node by group_id - $('li[data-group-id="' + group_id + '"] .activate').first().click(); - } - else if (refresh_tree && id !== undefined) { - // pick a node by id - $('#' + id + ' .activate').first().click(); - } - else if (!refresh_tree) { - // default to the root node - $('#inventory-root-node .activate').first().click(); - } - - // Make the tree drag-n-droppable - if (moveable) { - $('#selector-tree .activate').draggable({ - cursor: "pointer", - cursorAt: { top: -16, left: -10 }, - revert: 'invalid', - helper: 'clone', - start: function (e, ui) { - var txt = '[ ' + ui.helper.text() + ' ]'; - ui.helper.css({ 'display': 'inline-block', 'font-weight': 'normal', 'color': '#171717', - 'background-color': '#f5f5f5', 'overflow': 'visible', 'white-space': 'normal', - 'z-index': 5000 }).text(txt); - } - }) - .droppable({ - //hoverClass: 'droppable-hover', - tolerance: 'pointer', - over: function (e, ui) { - var p = $(this).parent().parent(); - p.find('div').each(function(idx) { - if (idx > 0 && idx < 3) { - $(this).css({ 'border-bottom': '2px solid #171717' }); - } - }); - var c = p.find('.expand-container').first(); - c.empty().html(''); - }, - out: function (e, ui) { - var p = $(this).parent().parent(); - p.find('div').each(function(idx) { - if (idx > 0 && idx < 3) { - $(this).css({ 'border-bottom': '2px solid #f5f5f5' }); - } - }); - var c = p.find('.expand-container'); - var icon; - c.first().empty(); - if (c.length > 1) { - // has children, put expander icon back - icon = (p.attr('data-state') == 'opened') ? 'icon-caret-down' : 'icon-caret-right'; - c.first().html(''); - c.first().find('a').first().bind('click', toggle); - } - }, - drop: function (e,ui) { - var variables; - var node = ui.draggable.parent().parent(); // node being moved - var parent = node.parent().parent(); // node from - var target = $(this).parent().parent(); // node to - scope.$emit('MoveNode', node, parent, target); - - // Make sure angular picks up changes and jQuery doesn't - // leave us in limbo... - if (!scope.$$phase) { - scope.$digest(); - } - e.preventDefault(); - } - }); - } // if moveable - - Wait('stop'); - }); - - function buildHTML(tree_data) { - var sorted = SortNodes(tree_data); - var toolTip; - - html += (sorted.length > 0) ? "
        \n" : ""; - for(var i=0; i < sorted.length; i++) { - html += "
      • "; - - if (sorted[i].children.length > 0) { - html += ""; - } - else { - html += " "; - } - html += "
        "; - - toolTip = GetToolTip({ node: sorted[i] }); - - html += "
        "; - html += ""; - html += ""; - html += "
        "; - - html += ""; - - idx++; - if (sorted[i].children.length > 0) { - buildHTML(sorted[i].children); - } - else { - //html += "
          \n"; - html += "
        • \n"; - } - } - html += "
        \n"; - } - - // Build the HTML for our tree - if (scope.buildAllGroupsRemove) { - scope.buildAllGroupsRemove(); - } - scope.buildAllGroupsRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree) { - Rest.setUrl(inventory_tree); - Rest.get() - .success( function(data, status, headers, config) { - buildHTML(data); - scope.$emit('searchTreeReady', html + "
      • \n\n
        \n"); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get inventory tree for: ' + inventory_id + '. GET returned: ' + status }); - }); - }); - - // Builds scope.inventory_groups, used by the group picker on Hosts view to build the list of potential groups - // that can be added to a host. <<<< Should probably be moved to /helpers/Hosts.js - if (scope.buildGroupListRemove) { - scope.buildGroupListRemove(); - } - scope.buildGroupListRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree, groups_url) { - scope.inventory_groups = []; - Rest.setUrl(groups_url); - Rest.get() - .success( function(data, status, headers, config) { - var groups = []; - for (var i=0; i < data.results.length; i++) { - groups.push({ - id: data.results[i].id, - description: data.results[i].description, - name: data.results[i].name }); - } - scope.inventory_groups = SortNodes(groups); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get groups for inventory: ' + inventory_id + '. GET returned: ' + status }); - }); - }); - - - function loadTreeData() { - // Load the inventory root node - Wait('start'); - Rest.setUrl (GetBasePath('inventory') + inventory_id + '/'); - Rest.get() - .success( function(data, status, headers, config) { - - var tip = GetInventoryToolTip({ node: data }); - - html += "
        Group Selector:
        \n" + - "
        \n" + - "
          \n" + - "
        • " + - "
          " + - "
          \n"; - - html += ""; - html += "
          \n"; - - html += ""; - - scope.$emit('buildAllGroups', data.name, data.related.tree, data.related.groups); - - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get inventory: ' + inventory_id + '. GET returned: ' + status }); - }); - } - - loadTreeData(); - - } - }]) - - // Set node name and description after an update to Group properties. - .factory('SetNodeName', [ function() { - return function(params) { - var scope = params.scope; - var name = params.name; - var descr = params.description; - var group_id = (params.group_id !== undefined) ? params.group_id : null; - var inventory_id = (params.inventory_id != undefined) ? params.inventory_id : null; - - if (group_id !== null) { - $('#inventory-tree').find('li [data-group-id="' + group_id + '"]').each(function(idx) { - $(this).attr('data-name',name); - $(this).attr('data-description',descr); - $(this).find('.activate').first().text(name); - }); - } - - if (inventory_id !== null) { - $('#inventory-root-node').attr('data-name', name).attr('data-description', descr).find('.activate').first().text(name); - } - } - }]) - - .factory('ClickNode', [ function() { - return function(params) { - var selector = params.selector; //jquery selector string to find the correct
        • - $(selector + ' .activate').first().click(); - } - }]) - - .factory('DeleteNode', [ function() { - return function(params) { - var selector = params.selector; //jquery selector string to find the correct
        • - $(selector).first().detach(); - } - }]); diff --git a/awx/ui/static/lib/ansible/Utilities.js b/awx/ui/static/lib/ansible/Utilities.js index 046adb3b73..fd3531bb81 100644 --- a/awx/ui/static/lib/ansible/Utilities.js +++ b/awx/ui/static/lib/ansible/Utilities.js @@ -10,68 +10,72 @@ 'use strict'; -angular.module('Utilities',['RestServices', 'Utilities']) - - .factory('ClearScope', [ function() { - return function(id) { - - var element = document.getElementById(id), scope; +angular.module('Utilities', ['RestServices', 'Utilities']) + +.factory('ClearScope', [ + function () { + return function (id) { + + var element = document.getElementById(id), + scope; if (element) { scope = angular.element(element).scope(); scope.$destroy(); } - $('.tooltip').each( function() { + $('.tooltip').each(function () { // Remove any lingering tooltip and popover
          elements $(this).remove(); }); - $('.popover').each(function() { + $('.popover').each(function () { // remove lingering popover
          . Seems to be a bug in TB3 RC1 $(this).remove(); }); try { $('#help-modal').dialog('close'); - } - catch(e) { + } catch (e) { // ignore } $(window).unbind('resize'); }; - }]) + } +]) - - /* Empty() - * - * Test if a value is 'empty'. Returns true if val is null | '' | undefined. - * Only works on non-Ojbect types. - * - */ - .factory('Empty', [ function() { - return function(val) { + +/* Empty() + * + * Test if a value is 'empty'. Returns true if val is null | '' | undefined. + * Only works on non-Ojbect types. + * + */ +.factory('Empty', [ + function () { + return function (val) { return (val === null || val === undefined || val === '') ? true : false; }; - }]) - - - .factory('ToggleClass', function() { - return function(selector, cssClass) { - // Toggles the existance of a css class on a given element - if ( $(selector) && $(selector).hasClass(cssClass) ) { - $(selector).removeClass(cssClass); - } - else if ($(selector)) { - $(selector).addClass(cssClass); - } - }; - }) + } +]) - .factory('Alert', ['$rootScope', function($rootScope) { - return function(hdr, msg, cls, action, secondAlert, disableButtons) { +.factory('ToggleClass', function () { + return function (selector, cssClass) { + // Toggles the existance of a css class on a given element + if ($(selector) && $(selector).hasClass(cssClass)) { + $(selector).removeClass(cssClass); + } else if ($(selector)) { + $(selector).addClass(cssClass); + } + }; +}) + + +.factory('Alert', ['$rootScope', + function ($rootScope) { + return function (hdr, msg, cls, action, secondAlert, disableButtons) { // Pass in the header and message you want displayed on TB modal dialog found in index.html. // Assumes an #id of 'alert-modal'. Pass in an optional TB alert class (i.e. alert-danger, alert-success, // alert-info...). Pass an optional function(){}, if you want a specific action to occur when user @@ -79,15 +83,19 @@ angular.module('Utilities',['RestServices', 'Utilities']) if (secondAlert) { $rootScope.alertHeader2 = hdr; $rootScope.alertBody2 = msg; - $rootScope.alertClass2 = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger - $('#alert-modal2').modal({ show: true, keyboard: true , backdrop: 'static' }); + $rootScope.alertClass2 = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger + $('#alert-modal2').modal({ + show: true, + keyboard: true, + backdrop: 'static' + }); $rootScope.disableButtons2 = (disableButtons) ? true : false; if (action) { - $('#alert-modal2').on('hidden', function() { + $('#alert-modal2').on('hidden', function () { action(); }); } - $(document).bind('keydown', function(e) { + $(document).bind('keydown', function (e) { if (e.keyCode === 27) { $('#alert-modal2').modal('hide'); if (action) { @@ -95,14 +103,17 @@ angular.module('Utilities',['RestServices', 'Utilities']) } } }); - } - else { + } else { $rootScope.alertHeader = hdr; $rootScope.alertBody = msg; - $rootScope.alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger - $('#alert-modal').modal({ show: true, keyboard: true , backdrop: 'static' }); - - $(document).bind('keydown', function(e) { + $rootScope.alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger + $('#alert-modal').modal({ + show: true, + keyboard: true, + backdrop: 'static' + }); + + $(document).bind('keydown', function (e) { if (e.keyCode === 27) { $('#alert-modal').modal('hide'); if (action) { @@ -113,168 +124,171 @@ angular.module('Utilities',['RestServices', 'Utilities']) $rootScope.disableButtons = (disableButtons) ? true : false; if (action) { - $('#alert-modal').on('hidden', function() { + $('#alert-modal').on('hidden', function () { action(); }); } } }; - }]) + } +]) - .factory('ProcessErrors', ['$rootScope', '$cookieStore', '$log', '$location', 'Alert', 'Wait', - function($rootScope, $cookieStore, $log, $location, Alert, Wait) { - return function(scope, data, status, form, defaultMsg) { - var field, fieldErrors, msg; - Wait('stop'); - if ($AnsibleConfig.debug_mode && console) { - console.log('Debug status: ' + status); - console.log('Debug data: '); - console.log(data); +.factory('ProcessErrors', ['$rootScope', '$cookieStore', '$log', '$location', 'Alert', 'Wait', + function ($rootScope, $cookieStore, $log, $location, Alert, Wait) { + return function (scope, data, status, form, defaultMsg) { + var field, fieldErrors, msg; + Wait('stop'); + if ($AnsibleConfig.debug_mode && console) { + console.log('Debug status: ' + status); + console.log('Debug data: '); + console.log(data); + } + if (status === 403) { + msg = 'The API responded with a 403 Access Denied error. '; + if (data.detail) { + msg += 'Detail: ' + data.detail; + } else { + msg += 'Please contact your system administrator.'; } - if (status === 403) { - msg = 'The API responded with a 403 Access Denied error. '; - if (data.detail) { - msg += 'Detail: ' + data.detail; + Alert(defaultMsg.hdr, msg); + } else if ((status === 401 && data.detail && data.detail === 'Token is expired') || + (status === 401 && data.detail && data.detail === 'Invalid token')) { + $rootScope.sessionTimer.expireSession(); + $location.url('/login'); + } else if (data.non_field_errors) { + Alert('Error!', data.non_field_errors); + } else if (data.detail) { + Alert(defaultMsg.hdr, defaultMsg.msg + ' ' + data.detail); + } else if (data.__all__) { + Alert('Error!', data.__all__); + } else if (form) { + fieldErrors = false; + for (field in form.fields) { + if (data[field] && form.fields[field].tab) { + // If the form is part of a tab group, activate the tab + $('#' + form.name + "_tabs a[href=\"#" + form.fields[field].tab + '"]').tab('show'); } - else { - msg += 'Please contact your system administrator.'; - } - Alert(defaultMsg.hdr, msg); - } - else if ( (status === 401 && data.detail && data.detail === 'Token is expired') || - (status === 401 && data.detail && data.detail === 'Invalid token') ) { - $rootScope.sessionTimer.expireSession(); - $location.url('/login'); - } - else if (data.non_field_errors) { - Alert('Error!', data.non_field_errors); - } - else if (data.detail) { - Alert(defaultMsg.hdr, defaultMsg.msg + ' ' + data.detail); - } - else if (data.__all__) { - Alert('Error!', data.__all__); - } - else if (form) { - fieldErrors = false; - for (field in form.fields ) { - if (data[field] && form.fields[field].tab) { - // If the form is part of a tab group, activate the tab - $('#' + form.name + "_tabs a[href=\"#" + form.fields[field].tab + '"]').tab('show'); - } - if (form.fields[field].realName) { - if (data[form.fields[field].realName]) { - scope[field + '_api_error'] = data[form.fields[field]][0]; - //scope[form.name + '_form'][form.fields[field].realName].$setValidity('apiError', false); - $('[name="' + form.fields[field].realName + '"]').addClass('ng-invalid'); - fieldErrors = true; - } - } - if (form.fields[field].sourceModel) { - if (data[field]) { - scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '_api_error'] = - data[field][0]; - //scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField].$setValidity('apiError', false); - $('[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').addClass('ng-invalid'); - fieldErrors = true; - } - } - else { - if (data[field]) { - scope[field + '_api_error'] = data[field][0]; - //scope[form.name + '_form'][field].$setValidity('apiError', false); - $('[name="' + field + '"]').addClass('ng-invalid'); - fieldErrors = true; - } + if (form.fields[field].realName) { + if (data[form.fields[field].realName]) { + scope[field + '_api_error'] = data[form.fields[field]][0]; + //scope[form.name + '_form'][form.fields[field].realName].$setValidity('apiError', false); + $('[name="' + form.fields[field].realName + '"]').addClass('ng-invalid'); + fieldErrors = true; } } - if ((!fieldErrors) && defaultMsg) { - Alert(defaultMsg.hdr, defaultMsg.msg); + if (form.fields[field].sourceModel) { + if (data[field]) { + scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '_api_error'] = + data[field][0]; + //scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField].$setValidity('apiError', false); + $('[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').addClass('ng-invalid'); + fieldErrors = true; + } + } else { + if (data[field]) { + scope[field + '_api_error'] = data[field][0]; + //scope[form.name + '_form'][field].$setValidity('apiError', false); + $('[name="' + field + '"]').addClass('ng-invalid'); + fieldErrors = true; + } } } - else { + if ((!fieldErrors) && defaultMsg) { Alert(defaultMsg.hdr, defaultMsg.msg); } - }; - }]) + } else { + Alert(defaultMsg.hdr, defaultMsg.msg); + } + }; + } +]) - - .factory('LoadBreadCrumbs', ['$rootScope', '$routeParams', '$location', 'Empty', - function($rootScope, $routeParams, $location, Empty) { - return function(crumb) { - - var title, found, j, i, paths, ppath, parent, child; - - function toUppercase(a) { - return a.toUpperCase(); - } - function singular(a) { - return (a === 'ies') ? 'y' : ''; - } - - //Keep a list of path/title mappings. When we see /organizations/XX in the path, for example, - //we'll know the actual organization name it maps to. - if (!Empty(crumb)) { - found = false; - //crumb.title = crumb.title.charAt(0).toUpperCase() + crumb.title.slice(1); - for (i=0; i < $rootScope.crumbCache.length; i++) { - if ($rootScope.crumbCache[i].path === crumb.path) { - found = true; - $rootScope.crumbCache[i] = crumb; - break; - } - } - if (!found) { - $rootScope.crumbCache.push(crumb); +.factory('LoadBreadCrumbs', ['$rootScope', '$routeParams', '$location', 'Empty', + function ($rootScope, $routeParams, $location, Empty) { + return function (crumb) { + + var title, found, j, i, paths, ppath, parent, child; + + function toUppercase(a) { + return a.toUpperCase(); + } + + function singular(a) { + return (a === 'ies') ? 'y' : ''; + } + + //Keep a list of path/title mappings. When we see /organizations/XX in the path, for example, + //we'll know the actual organization name it maps to. + if (!Empty(crumb)) { + found = false; + //crumb.title = crumb.title.charAt(0).toUpperCase() + crumb.title.slice(1); + for (i = 0; i < $rootScope.crumbCache.length; i++) { + if ($rootScope.crumbCache[i].path === crumb.path) { + found = true; + $rootScope.crumbCache[i] = crumb; + break; } } - - paths = $location.path().replace(/^\//,'').split('/'); - ppath = ''; - $rootScope.breadcrumbs = []; - if (paths.length > 1) { - for (i=0; i < paths.length - 1; i++) { - if (i > 0 && paths[i].match(/\d+/)) { - parent = paths[i-1]; - child = parent.replace(/(ies$|s$)/, singular); - child = child.charAt(0).toUpperCase() + child.slice(1); - // find the correct title - found = false; - for (j=0; j < $rootScope.crumbCache.length; j++) { - if ($rootScope.crumbCache[j].path === '/' + parent + '/' + paths[i]) { - child = $rootScope.crumbCache[j].title; - found = true; - break; - } - } - - if (found && $rootScope.crumbCache[j].altPath !== undefined) { - // Use altPath to override default path construction - $rootScope.breadcrumbs.push({ title: child, path: $rootScope.crumbCache[j].altPath }); - } - else { - $rootScope.breadcrumbs.push({ title: child, path: ppath + '/' + paths[i] }); - } - } - else { - if (/_/.test(paths[i])) { - // replace '_' with space and uppercase each word - paths[i] = paths[i].replace(/(?:^|_)\S/g, toUppercase) - .replace(/_/g,' '); - } - title = paths[i].charAt(0).toUpperCase() + paths[i].slice(1); - $rootScope.breadcrumbs.push({ title: title, path: ppath + '/' + paths[i] }); - } - ppath += '/' + paths[i]; - } + if (!found) { + $rootScope.crumbCache.push(crumb); } - }; - }]) - - .factory('HelpDialog', ['$rootScope', '$location', 'Store', function($rootScope, $location, Store) { - return function(params) { + } + + paths = $location.path().replace(/^\//, '').split('/'); + ppath = ''; + $rootScope.breadcrumbs = []; + if (paths.length > 1) { + for (i = 0; i < paths.length - 1; i++) { + if (i > 0 && paths[i].match(/\d+/)) { + parent = paths[i - 1]; + child = parent.replace(/(ies$|s$)/, singular); + child = child.charAt(0).toUpperCase() + child.slice(1); + // find the correct title + found = false; + for (j = 0; j < $rootScope.crumbCache.length; j++) { + if ($rootScope.crumbCache[j].path === '/' + parent + '/' + paths[i]) { + child = $rootScope.crumbCache[j].title; + found = true; + break; + } + } + + if (found && $rootScope.crumbCache[j].altPath !== undefined) { + // Use altPath to override default path construction + $rootScope.breadcrumbs.push({ + title: child, + path: $rootScope.crumbCache[j].altPath + }); + } else { + $rootScope.breadcrumbs.push({ + title: child, + path: ppath + '/' + paths[i] + }); + } + } else { + if (/_/.test(paths[i])) { + // replace '_' with space and uppercase each word + paths[i] = paths[i].replace(/(?:^|_)\S/g, toUppercase) + .replace(/_/g, ' '); + } + title = paths[i].charAt(0).toUpperCase() + paths[i].slice(1); + $rootScope.breadcrumbs.push({ + title: title, + path: ppath + '/' + paths[i] + }); + } + ppath += '/' + paths[i]; + } + } + }; + } +]) + +.factory('HelpDialog', ['$rootScope', '$location', 'Store', + function ($rootScope, $location, Store) { + return function (params) { // Display a help dialog // // HelpDialog({ defn: }) @@ -285,10 +299,10 @@ angular.module('Utilities',['RestServices', 'Utilities']) autoShow = params.autoShow || false; function showHelp(step) { - - var btns, ww, width, height, isOpen=false; + + var btns, ww, width, height, isOpen = false; current_step = step; - + function buildHtml(step) { var html = ''; //html += (step.intro) ? "
          " + step.intro + "
          " : ""; @@ -301,7 +315,7 @@ angular.module('Utilities',['RestServices', 'Utilities']) "name=\"auto-off-checkbox\" id=\"auto-off-checkbox\"> Do not show this message in the future
          \n" : ""; return html; } - + width = (defn.story.width) ? defn.story.width : 510; height = (defn.story.height) ? defn.story.height : 600; @@ -311,21 +325,19 @@ angular.module('Utilities',['RestServices', 'Utilities']) try { isOpen = $('#help-modal').dialog('isOpen'); - } - catch(e) { + } catch (e) { // ignore } if (isOpen) { $('#help-modal').html(buildHtml(defn.story.steps[current_step])); - } - else { + } else { // Define buttons based on story length btns = []; if (defn.story.steps.length > 1) { btns.push({ text: "Prev", - click: function(e) { + click: function (e) { if (current_step - 1 === 0) { $(e.target).button('disable'); } @@ -338,7 +350,7 @@ angular.module('Utilities',['RestServices', 'Utilities']) }); btns.push({ text: "Next", - click: function(e) { + click: function (e) { if (current_step + 1 > 0) { $(e.target).prev().button('enable'); } @@ -349,12 +361,19 @@ angular.module('Utilities',['RestServices', 'Utilities']) } }); } - btns.push({ text: "Close", - click: function() { $('#help-modal').dialog('close'); } + btns.push({ + text: "Close", + click: function () { + $('#help-modal').dialog('close'); + } }); // Show the dialog $('#help-modal').html(buildHtml(defn.story.steps[current_step])).dialog({ - position: { my: "center top", at: "center top+150", of: 'body' }, + position: { + my: "center top", + at: "center top+150", + of: 'body' + }, title: defn.story.hdr, width: width, height: height, @@ -363,75 +382,91 @@ angular.module('Utilities',['RestServices', 'Utilities']) show: 500, hide: 500, resizable: false, - close: function() { $('#help-modal').empty(); } + close: function () { + $('#help-modal').empty(); + } }); - + // Make the buttons look like TB and add FA icons - $('.ui-dialog-buttonset button').each( function() { + $('.ui-dialog-buttonset button').each(function () { var c, h, l; l = $(this).text(); if (l === 'Close') { h = "fa-times"; c = "btn btn-default"; - $(this).attr({ 'class': c }).html(" Close"); - } - else if (l === 'Prev') { + $(this).attr({ + 'class': c + }).html(" Close"); + } else if (l === 'Prev') { h = "fa-chevron-left"; c = "btn btn-primary"; - $(this).attr({ 'class': c }).html(" Prev"); - } - else { + $(this).attr({ + 'class': c + }).html(" Prev"); + } else { h = "fa-chevron-right"; c = "btn btn-primary"; - $(this).attr({ 'class': c }).html("Next ").css({ 'margin-right': '20px'}); + $(this).attr({ + 'class': c + }).html("Next ").css({ + 'margin-right': '20px' + }); } }); $('.ui-dialog[aria-describedby="help-modal"]').find('.ui-dialog-titlebar button') - .empty().attr({ 'class': 'close' }).text('x'); - + .empty().attr({ + 'class': 'close' + }).text('x'); + // If user clicks the checkbox, update local storage - $('#auto-off-checkbox').click(function() { + $('#auto-off-checkbox').click(function () { if ($('input[name="auto-off-checkbox"]:checked').length) { - Store('inventoryAutoHelp','off'); - } - else { - Store('inventoryAutoHelp','on'); + Store('inventoryAutoHelp', 'off'); + } else { + Store('inventoryAutoHelp', 'on'); } }); } } - + showHelp(0); }; - }]) + } +]) - .factory('ReturnToCaller', ['$location', 'Empty', function($location, Empty) { - return function(idx) { +.factory('ReturnToCaller', ['$location', 'Empty', + function ($location, Empty) { + return function (idx) { // Split the current path by '/' and use the array elements from 0 up to and // including idx as the new path. If no idx value supplied, use 0 to length - 1. - var paths = $location.path().replace(/^\//,'').split('/'), - newpath = '', i; + var paths = $location.path().replace(/^\//, '').split('/'), + newpath = '', + i; idx = (Empty(idx)) ? paths.length - 1 : idx + 1; - for (i=0; i < idx; i++) { + for (i = 0; i < idx; i++) { newpath += '/' + paths[i]; } $location.path(newpath); }; - }]) + } +]) - .factory('FormatDate', ['$filter', function($filter) { - return function(dt) { +.factory('FormatDate', ['$filter', + function ($filter) { + return function (dt) { // Wrapper for data filter- an attempt to insure all dates display in // the same format. Pass in date object. return $filter('date')(dt, 'MM/dd/yy HH:mm:ss'); }; - }]) + } +]) - .factory('Wait', [ '$rootScope', function($rootScope) { - return function(directive) { +.factory('Wait', ['$rootScope', + function ($rootScope) { + return function (directive) { // Display a spinning icon in the center of the screen to freeze the // UI while waiting on async things to complete (i.e. API calls). // Wait('start' | 'stop'); @@ -448,16 +483,22 @@ angular.module('Utilities',['RestServices', 'Utilities']) width: $(document).width(), height: $(document).height() }).fadeIn(); - $('.spinny').css({ top: y, left: x }).fadeIn(400); - } - else if (directive === 'stop' && $rootScope.waiting){ - $('.spinny, .overlay').fadeOut(400, function(){ $rootScope.waiting = false; }); + $('.spinny').css({ + top: y, + left: x + }).fadeIn(400); + } else if (directive === 'stop' && $rootScope.waiting) { + $('.spinny, .overlay').fadeOut(400, function () { + $rootScope.waiting = false; + }); } }; - }]) - - .factory('HideElement', [ function() { - return function(selector, action) { + } +]) + +.factory('HideElement', [ + function () { + return function (selector, action) { // Fade-in a cloack or vail or a specific element var target = $(selector), width = target.css('width'), @@ -468,7 +509,7 @@ angular.module('Utilities',['RestServices', 'Utilities']) backgroundColor = target.css('background-color'), margin = target.css('margin'), padding = target.css('padding'); - + parent.append("
          "); $('#curtain-div').show(0, action); }; - }]) + } +]) - .factory('ShowElement', [ function() { - return function() { +.factory('ShowElement', [ + function () { + return function () { // And Fade-out the cloack revealing the element - $('#curtain-div').fadeOut(500, function() { $(this).remove(); }); + $('#curtain-div').fadeOut(500, function () { + $(this).remove(); + }); }; - }]) + } +]) - .factory('GetChoices', [ 'Rest', 'ProcessErrors', function(Rest, ProcessErrors) { - return function(params) { +.factory('GetChoices', ['Rest', 'ProcessErrors', + function (Rest, ProcessErrors) { + return function (params) { // Get dropdown options var scope = params.scope, url = params.url, field = params.field, variable = params.variable, - callback = params.callback, // Optional. Provide if you want scop.$emit on completion. - choice_name = params.choice_name; // Optional. Used when data is in something other than 'choices' + callback = params.callback, // Optional. Provide if you want scop.$emit on completion. + choice_name = params.choice_name; // Optional. Used when data is in something other than 'choices' if (scope[variable]) { scope[variable].length = 0; - } - else { + } else { scope[variable] = []; } Rest.setUrl(url); Rest.options() - .success( function(data) { + .success(function (data) { var choices, i; choices = (choice_name) ? data.actions.GET[field][choice_name] : data.actions.GET[field].choices; // including 'name' property so list can be used by search - for (i=0; i < choices.length; i++) { - scope[variable].push({ label: choices[i][1], value: choices[i][0], name: choices[i][1]}); + for (i = 0; i < choices.length; i++) { + scope[variable].push({ + label: choices[i][1], + value: choices[i][0], + name: choices[i][1] + }); } if (callback) { scope.$emit(callback); } }) - .error( function(data, status) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status }); + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to get ' + url + '. GET status: ' + status }); }); }; - }]) - - /* - * Search an array of objects, returning the matchting object or null - * - * Find({ list: [], key: "key", val: }); - */ - .factory('Find', [ function(){ - return function(params) { + } +]) + +/* + * Search an array of objects, returning the matchting object or null + * + * Find({ list: [], key: "key", val: }); + */ +.factory('Find', [ + function () { + return function (params) { var list = params.list, key = params.key, val = params.val, - found = false, i; + found = false, + i; if (typeof list === 'object' && Array.isArray(list)) { - for (i=0; i < params.list.length; i++) { + for (i = 0; i < params.list.length; i++) { if (list[i][key] === val) { found = true; break; @@ -554,19 +607,22 @@ angular.module('Utilities',['RestServices', 'Utilities']) } return null; }; - }]) + } +]) - /* - * DeugForm({ form: , scope: }); - * - * Use to log the $pristine and $valid properties of each form element. Helpful when form - * buttons fail to enable/disable properly. - * - */ - .factory('DebugForm', [ function() { - return function(params) { +/* + * DeugForm({ form: , scope: }); + * + * Use to log the $pristine and $valid properties of each form element. Helpful when form + * buttons fail to enable/disable properly. + * + */ +.factory('DebugForm', [ + function () { + return function (params) { var form = params.form, - scope = params.scope, fld; + scope = params.scope, + fld; for (fld in form.fields) { if (scope[form.name + '_form'][fld]) { console.log(fld + ' valid: ' + scope[form.name + '_form'][fld].$valid); @@ -574,49 +630,52 @@ angular.module('Utilities',['RestServices', 'Utilities']) if (form.fields[fld].sourceModel) { if (scope[form.name + '_form'][form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField]) { console.log(form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField + ' valid: ' + - scope[form.name + '_form'][form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField].$valid); + scope[form.name + '_form'][form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField].$valid); } } } console.log('form pristine: ' + scope[form.name + '_form'].$pristine); console.log('form valid: ' + scope[form.name + '_form'].$valid); }; - }]) + } +]) - - /* Store - * - * Wrapper for local storage. All local storage requests flow through here so that we can - * stringify/unstringify objects and respond to future issues in one place. For example, - * we may at some point want to only use session storage rather than local storage. We might - * want to add a test for whether or not local/session storage exists for the browser, etc. - * - * store(key,value) will store the value using the key - * - * store(key) retrieves the value of the key - * - */ - .factory('Store', ['Empty', function(Empty) { - return function(key, value) { + +/* Store + * + * Wrapper for local storage. All local storage requests flow through here so that we can + * stringify/unstringify objects and respond to future issues in one place. For example, + * we may at some point want to only use session storage rather than local storage. We might + * want to add a test for whether or not local/session storage exists for the browser, etc. + * + * store(key,value) will store the value using the key + * + * store(key) retrieves the value of the key + * + */ +.factory('Store', ['Empty', + function (Empty) { + return function (key, value) { if (!Empty(value)) { // Store the value localStorage[key] = JSON.stringify(value); - } - else if (!Empty(key)) { + } else if (!Empty(key)) { // Return the value var val = localStorage[key]; return (!Empty(val)) ? JSON.parse(val) : null; } }; - }]) + } +]) - /* - * - * ApplyEllipsis() - * - */ - .factory('ApplyEllipsis', [ function() { - return function(selector) { +/* + * + * ApplyEllipsis() + * + */ +.factory('ApplyEllipsis', [ + function () { + return function (selector) { // Add a hidden element to the DOM. We'll use this to calc the px length of // our target text. var tmp = $('#string-test'); @@ -625,26 +684,26 @@ angular.module('Utilities',['RestServices', 'Utilities']) tmp = $('#string-test'); } // Find and process the text. - $(selector).each(function() { - var setTitle = true, txt, w, pw, cw, df; + $(selector).each(function () { + var setTitle = true, + txt, w, pw, cw, df; if ($(this).attr('title')) { txt = $(this).attr('title'); setTitle = false; - } - else { + } else { txt = $(this).text(); } tmp.text(txt); - w = tmp.width(); //text width - pw = $(this).parent().width(); //parent width + w = tmp.width(); //text width + pw = $(this).parent().width(); //parent width if (w > pw) { // text is wider than parent width if (setTitle) { // Save the original text in the title - $(this).attr('title',txt); + $(this).attr('title', txt); } cw = w / txt.length; // px width per character - df = w - pw; // difference in px + df = w - pw; // difference in px txt = txt.substr(0, txt.length - (Math.ceil(df / cw) + 3)); $(this).text(txt + '...'); } @@ -654,16 +713,7 @@ angular.module('Utilities',['RestServices', 'Utilities']) $(this).text(txt); } }); - + }; - }]); - - - - - - - - - - + } +]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/api-loader.js b/awx/ui/static/lib/ansible/api-loader.js index bf999cd5c5..5c4c46f0bf 100644 --- a/awx/ui/static/lib/ansible/api-loader.js +++ b/awx/ui/static/lib/ansible/api-loader.js @@ -1,45 +1,53 @@ /********************************************* * Copyright (c) 2014 AnsibleWorks, Inc. * - * + * * Read /api and /api/X to discover all the base paths needed * to access the primary model objects. * */ - 'use strict'; angular.module('ApiLoader', ['Utilities']) - .factory('LoadBasePaths', ['$http', '$rootScope', 'Store', 'ProcessErrors', - function($http, $rootScope, Store, ProcessErrors) { - return function() { +.factory('LoadBasePaths', ['$http', '$rootScope', 'Store', 'ProcessErrors', + function ($http, $rootScope, Store, ProcessErrors) { + return function () { $http.get('/api/') - .success( function(data) { + .success(function (data) { var base = data.current_version; $http.get(base) - .success( function(data) { + .success(function (data) { data.base = base; $rootScope.defaultUrls = data; Store('api', data); }) - .error ( function(data, status) { - $rootScope.defaultUrls = { status: 'error' }; - ProcessErrors(null, data, status, null, - { hdr: 'Error', msg: 'Failed to read ' + base + '. GET status: ' + status }); + .error(function (data, status) { + $rootScope.defaultUrls = { + status: 'error' + }; + ProcessErrors(null, data, status, null, { + hdr: 'Error', + msg: 'Failed to read ' + base + '. GET status: ' + status + }); }); }) - .error( function(data, status) { - $rootScope.defaultUrls = { status: 'error' }; - ProcessErrors(null, data, status, null, - { hdr: 'Error', msg: 'Failed to read /api. GET status: ' + status }); + .error(function (data, status) { + $rootScope.defaultUrls = { + status: 'error' + }; + ProcessErrors(null, data, status, null, { + hdr: 'Error', + msg: 'Failed to read /api. GET status: ' + status + }); }); }; - }]) + } +]) - .factory('GetBasePath', ['$rootScope', 'Store', 'LoadBasePaths', 'Empty', - function($rootScope, Store, LoadBasePaths, Empty) { - return function(set) { +.factory('GetBasePath', ['$rootScope', 'Store', 'LoadBasePaths', 'Empty', + function ($rootScope, Store, LoadBasePaths, Empty) { + return function (set) { // use /api/v1/ results to construct API URLs. if (Empty($rootScope.defaultUrls)) { // browser refresh must have occurred. load from local storage @@ -47,11 +55,9 @@ angular.module('ApiLoader', ['Utilities']) $rootScope.defaultUrls = Store('api'); return $rootScope.defaultUrls[set]; } - return ''; //we should never get here + return ''; //we should never get here } return $rootScope.defaultUrls[set]; }; - }]); - - - + } +]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/directives.js b/awx/ui/static/lib/ansible/directives.js index e92251dddf..6b35580257 100644 --- a/awx/ui/static/lib/ansible/directives.js +++ b/awx/ui/static/lib/ansible/directives.js @@ -10,6 +10,7 @@ /* global chkPass:false */ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'JobsHelper']) + // awpassmatch: Add to password_confirm field. Will test if value // matches that of 'input[name="password"]' .directive('awpassmatch', function() { diff --git a/awx/ui/static/lib/ansible/filters.js b/awx/ui/static/lib/ansible/filters.js index 7c393a469a..f8eb69af6a 100644 --- a/awx/ui/static/lib/ansible/filters.js +++ b/awx/ui/static/lib/ansible/filters.js @@ -1,26 +1,29 @@ /********************************************* - * Copyright (c) 2014 AnsibleWorks, Inc. + * Copyright (c) 2014 AnsibleWorks, Inc. * - * Custom filters + * Custom filters * */ 'use strict'; angular.module('AWFilters', []) + // // capitalize -capitalize the first letter of each word // - .filter('capitalize', [ function() { - return function(input) { - var values, result, i; - if (input) { - values = input.replace(/\_/g,' ').split(" "); - result = ""; - for (i = 0; i < values.length; i++){ - result += values[i].charAt(0).toUpperCase() + values[i].substr(1) + ' '; + .filter('capitalize', [ + function () { + return function (input) { + var values, result, i; + if (input) { + values = input.replace(/\_/g, ' ').split(" "); + result = ""; + for (i = 0; i < values.length; i++) { + result += values[i].charAt(0).toUpperCase() + values[i].substr(1) + ' '; + } + return result.trim(); } - return result.trim(); - } - }; - }]); \ No newline at end of file + }; + } + ]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/form-generator.js b/awx/ui/static/lib/ansible/form-generator.js index d7ce0277c2..dd916ab7f7 100644 --- a/awx/ui/static/lib/ansible/form-generator.js +++ b/awx/ui/static/lib/ansible/form-generator.js @@ -1,1530 +1,1483 @@ /********************************************* * Copyright (c) 2014 AnsibleWorks, Inc. * - * FormGenerator + * FormGenerator * Pass in a form definition from FormDefinitions and out pops an html template. * See js/form-definitions.js for form example. For now produces a Twitter Bootstrap - * horizontal form. - * + * horizontal form. + * */ 'use strict'; angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities']) - + .factory('GenerateForm', ['$rootScope', '$location', '$cookieStore', '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column', 'NavigationLink', 'HelpCollapse', 'Button', 'DropDown', 'Empty', 'SelectIcon', -function($rootScope, $location, $cookieStore, $compile, SearchWidget, PaginateWidget, Attr, Icon, Column, NavigationLink, - HelpCollapse, Button, DropDown, Empty, SelectIcon) { - return { - - setForm: function(form) { - this.form = form; - }, - - attr: Attr, + function ($rootScope, $location, $cookieStore, $compile, SearchWidget, PaginateWidget, Attr, Icon, Column, NavigationLink, + HelpCollapse, Button, DropDown, Empty, SelectIcon) { + return { - icon: Icon, + setForm: function (form) { + this.form = form; + }, - accordion_count: 0, + attr: Attr, - scope: null, + icon: Icon, - has: function(key) { - return (this.form[key] && this.form[key] !== null && this.form[key] !== undefined) ? true : false; - }, + accordion_count: 0, - inject: function(form, options) { - // - // Use to inject the form as html into the view. View MUST have an ng-bind for 'htmlTemplate'.t - // Returns scope of form. - // - - var element, fld, set, show; + scope: null, - if (options.modal) { - if (options.modal_body_id) { - element = angular.element(document.getElementById(options.modal_body_id)); - } - else { - // use default dialog - element = angular.element(document.getElementById('form-modal-body')); - } - } - else { - if (options.id) { - element = angular.element(document.getElementById(options.id)); - } - else { - element = angular.element(document.getElementById('htmlTemplate')); - } - } + has: function (key) { + return (this.form[key] && this.form[key] !== null && this.form[key] !== undefined) ? true : false; + }, - this.mode = options.mode; - this.modal = (options.modal) ? true : false; - this.setForm(form); + inject: function (form, options) { + // + // Use to inject the form as html into the view. View MUST have an ng-bind for 'htmlTemplate'.t + // Returns scope of form. + // - if (options.html) { - element.html(options.html); - } - else { - element.html(this.build(options)); - } - - if (options.scope) { - this.scope = options.scope; - } - else { - this.scope = element.scope(); - } + var element, fld, set, show; - $compile(element)(this.scope); - - if (!options.html) { - // Reset the scope to prevent displaying old data from our last visit to this form - for (fld in form.fields) { - this.scope[fld] = null; - } - for (set in form.related) { - this.scope[set] = null; - } - if ( ((!options.modal) && options.related) || this.form.forceListeners ) { - this.addListeners(); - } - if (options.mode === 'add') { - this.applyDefaults(); - } - } - - // Remove any lingering tooltip and popover
          elements - $('.tooltip').each( function() { - $(this).remove(); - }); - - $('.popover').each(function() { - // remove lingering popover
          . Seems to be a bug in TB3 RC1 - $(this).remove(); - }); - - $(window).unbind('resize'); - - // Prepend an asterisk to required field label - $('.form-control[required], input[type="radio"][required]').each(function() { - var label, span; - if ( Empty($(this).attr('aw-required-when')) ) { - label = $(this).parent().parent().find('label').first(); - if ($(this).attr('type') === 'radio') { - label = $(this).parent().parent().parent().find('label').first(); + if (options.modal) { + if (options.modal_body_id) { + element = angular.element(document.getElementById(options.modal_body_id)); + } else { + // use default dialog + element = angular.element(document.getElementById('form-modal-body')); } - if (label.length > 0) { - span = label.children('span'); - if (span.length > 0 && !span.first().hasClass('prepend-asterisk')) { - span.first().addClass('prepend-asterisk'); - } - else if (span.length <= 0 && !label.first().hasClass('prepend-asterisk')) { - label.first().addClass('prepend-asterisk'); - } + } else { + if (options.id) { + element = angular.element(document.getElementById(options.id)); + } else { + element = angular.element(document.getElementById('htmlTemplate')); } } - }); - try { - $('#help-modal').empty().dialog('destroy'); - } - catch(e) { - //ignore any errors should the dialog not be initialized - } + this.mode = options.mode; + this.modal = (options.modal) ? true : false; + this.setForm(form); - if (options.modal) { - this.scope.formModalActionDisabled = false; - this.scope.formModalInfo = false; //Disable info button for default modal - if (form) { - if (options.modal_title_id) { - this.scope[options.modal_title_id] = (options.mode === 'add') ? form.addTitle : form.editTitle; + if (options.html) { + element.html(options.html); + } else { + element.html(this.build(options)); + } + + if (options.scope) { + this.scope = options.scope; + } else { + this.scope = element.scope(); + } + + $compile(element)(this.scope); + + if (!options.html) { + // Reset the scope to prevent displaying old data from our last visit to this form + for (fld in form.fields) { + this.scope[fld] = null; } - else { - this.scope.formModalHeader = (options.mode === 'add') ? form.addTitle : form.editTitle; //Default title for default modal + for (set in form.related) { + this.scope[set] = null; + } + if (((!options.modal) && options.related) || this.form.forceListeners) { + this.addListeners(); + } + if (options.mode === 'add') { + this.applyDefaults(); } } - if (options.modal_selector) { - $(options.modal_selector).modal({ show: true, backdrop: 'static', keyboard: true }); - $(options.modal_selector).on('shown.bs.modal', function() { - $(options.modal_select + ' input:first').focus(); - }); - $(options.modal_selector).on('hidden.bs.modal', function() { - $('.tooltip').each( function() { - // Remove any lingering tooltip and popover
          elements - $(this).remove(); - }); - $('.popover').each(function(index) { - // remove lingering popover
          . Seems to be a bug in TB3 RC1 - $(this).remove(); - }); - }); - } - else { - show = (options.show_modal === false) ? false : true; - $('#form-modal').modal({ show: show, backdrop: 'static', keyboard: true }); - $('#form-modal').on('shown.bs.modal', function() { - $('#form-modal input:first').focus(); - }); - $('#form-modal').on('hidden.bs.modal', function() { - $('.tooltip').each( function(index) { - // Remove any lingering tooltip and popover
          elements - $(this).remove(); - }); - - $('.popover').each(function(index) { - // remove lingering popover
          . Seems to be a bug in TB3 RC1 - $(this).remove(); - }); - }); - } - $(document).bind('keydown', function(e) { - if (e.keyCode === 27) { - if (options.modal_selector) { - $(options.modal_selector).modal('hide'); - } - $('#prompt-modal').modal('hide'); - $('#form-modal').modal('hide'); - } + // Remove any lingering tooltip and popover
          elements + $('.tooltip').each(function () { + $(this).remove(); }); - } - if (!this.scope.$$phase) { - this.scope.$digest(); - } - - return this.scope; - }, - - applyDefaults: function() { - for (var fld in this.form.fields) { - if (this.form.fields[fld]['default'] || this.form.fields[fld]['default'] === 0) { - if (this.form.fields[fld].type === 'select' && this.scope[fld + '_options']) { - this.scope[fld] = this.scope[fld + '_options'][this.form.fields[fld]['default']]; - } - else { - this.scope[fld] = this.form.fields[fld]['default']; - } - } - } - }, - - reset: function() { - // The form field values cannot be reset with jQuery. Each field is tied to a model, so to clear the field - // value, you have to clear the model. - - var fld, scope = this.scope, form = this.form; - - if (scope[form.name + '_form']) { - scope[form.name + '_form'].$setPristine(); - } - - function resetField(f, fld) { - // f is the field object, fld is the key - - if (f.type === 'checkbox_group') { - for (var i=0; i < f.fields.length; i++) { - scope[f.fields[i].name] = ''; - scope[f.fields[i].name + '_api_error'] = ''; - scope[form.name + '_form'][f.fields[i].name].$setValidity('apiError', true); - } - } - else { - scope[fld] = ''; - scope[fld + '_api_error'] = ''; - } - if (f.sourceModel) { - scope[f.sourceModel + '_' + f.sourceField] = ''; - scope[f.sourceModel + '_' + f.sourceField + '_api_error'] = ''; - if (scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField]) { - scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setValidity('apiError', true); - } - } - if (f.type === 'lookup' && scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField]) { - scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setPristine(); - scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setValidity('apiError', true); - } - if (scope[form.name + '_form'][fld]) { - scope[form.name + '_form'][fld].$setPristine(); - scope[form.name + '_form'][fld].$setValidity('apiError', true); - } - if (f.chkPass && scope[form.name + '_form'][fld]) { - scope[form.name + '_form'][fld].$setValidity('complexity', true); - $('#progbar').css({ width: 0 }); - } - if (f.awPassMatch && scope[form.name + '_form'][fld]) { - scope[form.name + '_form'][fld].$setValidity('awpassmatch', true); - } - if (f.ask) { - scope[fld + '_ask'] = false; - } - } - - for (fld in form.fields) { - resetField(form.fields[fld], fld); - } - if (form.statusFields) { - for (fld in form.statusFields) { - resetField(form.statusFields[fld], fld); - } - } - if (this.mode === 'add') { - this.applyDefaults(); - } - }, - - addListeners: function() { - - if (this.modal) { - $('.jqui-accordion-modal').accordion({ - collapsible: false, - heightStyle: 'content', - active: 0 + $('.popover').each(function () { + // remove lingering popover
          . Seems to be a bug in TB3 RC1 + $(this).remove(); }); - } - else { - this.scope.accordionToggle = function(selector) { - $(selector).collapse('toggle'); - if ( $(selector + '-icon').hasClass('fa-minus') ) { - $(selector + '-icon').removeClass('fa-minus').addClass('fa-plus'); - } - else { - $(selector + '-icon').removeClass('fa-plus').addClass('fa-minus'); - } - }; - $('.jqui-accordion').each( function(index) { - - var active = false, - list = $cookieStore.get('accordions'), - found = false, - id, base, i; + $(window).unbind('resize'); - if (list) { - id = $(this).attr('id'); - base = ($location.path().replace(/^\//,'').split('/')[0]); - for (i=0; i < list.length && found === false; i++) { - if (list[i].base === base && list[i].id === id) { - found = true; - active = list[i].active; + // Prepend an asterisk to required field label + $('.form-control[required], input[type="radio"][required]').each(function () { + var label, span; + if (Empty($(this).attr('aw-required-when'))) { + label = $(this).parent().parent().find('label').first(); + if ($(this).attr('type') === 'radio') { + label = $(this).parent().parent().parent().find('label').first(); + } + if (label.length > 0) { + span = label.children('span'); + if (span.length > 0 && !span.first().hasClass('prepend-asterisk')) { + span.first().addClass('prepend-asterisk'); + } else if (span.length <= 0 && !label.first().hasClass('prepend-asterisk')) { + label.first().addClass('prepend-asterisk'); } } } + }); - if (found === false && $(this).attr('data-open') === 'true') { - active = 0; + try { + $('#help-modal').empty().dialog('destroy'); + } catch (e) { + //ignore any errors should the dialog not be initialized + } + + if (options.modal) { + this.scope.formModalActionDisabled = false; + this.scope.formModalInfo = false; //Disable info button for default modal + if (form) { + if (options.modal_title_id) { + this.scope[options.modal_title_id] = (options.mode === 'add') ? form.addTitle : form.editTitle; + } else { + this.scope.formModalHeader = (options.mode === 'add') ? form.addTitle : form.editTitle; //Default title for default modal + } } - - $(this).accordion({ - collapsible: true, - heightStyle: 'content', - active: active, - activate: function( event, ui ) { - $('.jqui-accordion').each( function(index) { - var active = $(this).accordion('option', 'active'), - id = $(this).attr('id'), - base = ($location.path().replace(/^\//,'').split('/')[0]), - list = $cookieStore.get('accordions'), - i, found; - if (list === null || list === undefined) { - list = []; - } - found = false; - for (i=0; i < list.length && found === false; i++) { - if ( list[i].base === base && list[i].id === id) { - found = true; - list[i].active = active; - } - } - if (found === false) { - list.push({ base: base, id: id, active: active }); - } - $cookieStore.put('accordions',list); + if (options.modal_selector) { + $(options.modal_selector).modal({ + show: true, + backdrop: 'static', + keyboard: true + }); + $(options.modal_selector).on('shown.bs.modal', function () { + $(options.modal_select + ' input:first').focus(); + }); + $(options.modal_selector).on('hidden.bs.modal', function () { + $('.tooltip').each(function () { + // Remove any lingering tooltip and popover
          elements + $(this).remove(); }); + + $('.popover').each(function () { + // remove lingering popover
          . Seems to be a bug in TB3 RC1 + $(this).remove(); + }); + }); + } else { + show = (options.show_modal === false) ? false : true; + $('#form-modal').modal({ + show: show, + backdrop: 'static', + keyboard: true + }); + $('#form-modal').on('shown.bs.modal', function () { + $('#form-modal input:first').focus(); + }); + $('#form-modal').on('hidden.bs.modal', function () { + $('.tooltip').each(function () { + // Remove any lingering tooltip and popover
          elements + $(this).remove(); + }); + + $('.popover').each(function () { + // remove lingering popover
          . Seems to be a bug in TB3 RC1 + $(this).remove(); + }); + }); + } + $(document).bind('keydown', function (e) { + if (e.keyCode === 27) { + if (options.modal_selector) { + $(options.modal_selector).modal('hide'); + } + $('#prompt-modal').modal('hide'); + $('#form-modal').modal('hide'); } }); - }); - } - }, - - genID: function() { - var id = new Date(); - return id.getTime(); - }, - - headerField: function(fld, field, options) { - var html = ''; - if (field.label) { - html += "\n"; - } - html += ""; - } - - html += "'; - html += (field.icon) ? Icon(field.icon) : ""; - html += "" + field.label + ""; - html += (field.awPopOver && !field.awPopOverRight) ? Attr(field, 'awPopOver', fld) : ""; - html += "\n"; + } + }, + + reset: function () { + // The form field values cannot be reset with jQuery. Each field is tied to a model, so to clear the field + // value, you have to clear the model. + + var fld, scope = this.scope, + form = this.form; + + if (scope[form.name + '_form']) { + scope[form.name + '_form'].$setPristine(); + } + + function resetField(f, fld) { + // f is the field object, fld is the key + + if (f.type === 'checkbox_group') { + for (var i = 0; i < f.fields.length; i++) { + scope[f.fields[i].name] = ''; + scope[f.fields[i].name + '_api_error'] = ''; + scope[form.name + '_form'][f.fields[i].name].$setValidity('apiError', true); + } + } else { + scope[fld] = ''; + scope[fld + '_api_error'] = ''; + } + if (f.sourceModel) { + scope[f.sourceModel + '_' + f.sourceField] = ''; + scope[f.sourceModel + '_' + f.sourceField + '_api_error'] = ''; + if (scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField]) { + scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setValidity('apiError', true); + } + } + if (f.type === 'lookup' && scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField]) { + scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setPristine(); + scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setValidity('apiError', true); + } + if (scope[form.name + '_form'][fld]) { + scope[form.name + '_form'][fld].$setPristine(); + scope[form.name + '_form'][fld].$setValidity('apiError', true); + } + if (f.chkPass && scope[form.name + '_form'][fld]) { + scope[form.name + '_form'][fld].$setValidity('complexity', true); + $('#progbar').css({ + width: 0 + }); + } + if (f.awPassMatch && scope[form.name + '_form'][fld]) { + scope[form.name + '_form'][fld].$setValidity('awpassmatch', true); + } + if (f.ask) { + scope[fld + '_ask'] = false; + } + } + + for (fld in form.fields) { + resetField(form.fields[fld], fld); + } + if (form.statusFields) { + for (fld in form.statusFields) { + resetField(form.statusFields[fld], fld); + } + } + if (this.mode === 'add') { + this.applyDefaults(); + } + }, + + addListeners: function () { + + if (this.modal) { + $('.jqui-accordion-modal').accordion({ + collapsible: false, + heightStyle: 'content', + active: 0 + }); + } else { + this.scope.accordionToggle = function (selector) { + $(selector).collapse('toggle'); + if ($(selector + '-icon').hasClass('fa-minus')) { + $(selector + '-icon').removeClass('fa-minus').addClass('fa-plus'); + } else { + $(selector + '-icon').removeClass('fa-plus').addClass('fa-minus'); + } + }; + + $('.jqui-accordion').each(function () { + + var active = false, + list = $cookieStore.get('accordions'), + found = false, + id, base, i; + + if (list) { + id = $(this).attr('id'); + base = ($location.path().replace(/^\//, '').split('/')[0]); + for (i = 0; i < list.length && found === false; i++) { + if (list[i].base === base && list[i].id === id) { + found = true; + active = list[i].active; + } + } + } + + if (found === false && $(this).attr('data-open') === 'true') { + active = 0; + } + + $(this).accordion({ + collapsible: true, + heightStyle: 'content', + active: active, + activate: function () { + $('.jqui-accordion').each(function () { + var active = $(this).accordion('option', 'active'), + id = $(this).attr('id'), + base = ($location.path().replace(/^\//, '').split('/')[0]), + list = $cookieStore.get('accordions'), + i, found; + if (list === null || list === undefined) { + list = []; + } + found = false; + for (i = 0; i < list.length && found === false; i++) { + if (list[i].base === base && list[i].id === id) { + found = true; + list[i].active = active; + } + } + if (found === false) { + list.push({ + base: base, + id: id, + active: active + }); + } + $cookieStore.put('accordions', list); + }); + } + }); + }); + } + }, + + genID: function () { + var id = new Date(); + return id.getTime(); + }, + + headerField: function (fld, field) { + var html = ''; + if (field.label) { + html += "\n"; + } + html += "\n"; - html += "
          \n"; - html += "
          ×\n" : ""; - html += field.alertTxt; - html += "
          \n"; - html += "
          \n"; - html += "
          \n"; - } + }, - if (field.type === 'hidden') { - if ( (options.mode === 'edit' && field.includeOnEdit) || - (options.mode === 'add' && field.includeOnAdd) ) { - html += ""; + + buildField: function (fld, field, options, form) { + + var i, fldWidth, offset, html = '', + horizontal = (this.form.horizontal) ? true : false; + + function getFieldWidth() { + var x; + if (form.formFieldSize) { + x = form.formFieldSize; + } else if (field.xtraWide) { + x = "col-lg-10"; + } else if (field.column) { + x = "col-lg-8"; + } else if (!form.formFieldSize && options.modal) { + x = "col-lg-10"; + } else { + x = "col-lg-6"; + } + return x; } - } - - if ( (! field.readonly) || (field.readonly && options.mode === 'edit') ) { - html += "
          "; + } + + html += "'; + html += (field.icon) ? Icon(field.icon) : ""; + html += "" + field.label + ""; + html += (field.awPopOver && !field.awPopOverRight) ? Attr(field, 'awPopOver', fld) : ""; + html += "\n"; + } + return html; + } + + + if (field.type === 'alertblock') { + html += "
          \n"; + html += "
          \n"; + html += "
          ×\n" : ""; + html += field.alertTxt; + html += "
          \n"; + html += "
          \n"; + html += "
          \n"; + } + + if (field.type === 'hidden') { + if ((options.mode === 'edit' && field.includeOnEdit) || + (options.mode === 'add' && field.includeOnAdd)) { + html += ""; + } + } + + if ((!field.readonly) || (field.readonly && options.mode === 'edit')) { + html += "
          \n" : ""; + //text fields + if (field.type === 'text' || field.type === 'password' || field.type === 'email') { + html += label(); + html += "
          \n" : ""; + + if (field.control === null || field.control === undefined || field.control) { + html += "\n"; + html += "\n
          \n"; + if (field.ask) { + html += "
          \n"; + } + + // Add error messages + if ((options.mode === 'add' && field.addRequired) || (options.mode === 'edit' && field.editRequired) || + field.awRequiredWhen) { + html += "
          A value is required!
          \n"; + } + if (field.type === "email") { + html += "
          A valid email address is required!
          \n"; + } + if (field.awPassMatch) { + html += "
          Must match Password value
          \n"; + } + if (field.awValidUrl) { + html += "
          URL must begin with ssh, http or https and may not contain '@'
          \n"; + } + + html += "
          \n"; + + if (field.chkPass) { + // complexity error + html += "
          Password must be stronger
          \n"; + + // progress bar + html += "
          \n"; + html += "
          \n"; + html += "
          \n"; + html += "
          \n"; + + // help panel + html += HelpCollapse({ + hdr: 'Password Complexity', + content: "

          A password with reasonable strength is required. As you type the password " + + "a progress bar will measure the strength. Sufficient strength is reached when the bar turns green.

          " + + "

          Password strength is judged using the following:

          " + + "
            " + + "
          • Minimum 8 characters in length
          • \n" + + "
          • Contains a sufficient combination of the following items:\n" + + "
              \n" + + "
            • UPPERCASE letters
            • \n" + + "
            • Numbers
            • \n" + + "
            • Symbols _!@#$%^&*()
            • \n" + + "
            \n" + + "
          • \n" + + "
          \n", + idx: this.accordion_count++, + show: null + }); + html += "
          \n"; + } + + // Add help panel(s) + html += (field.helpCollapse) ? this.buildHelpCollapse(field.helpCollapse) : ''; + + html += "
          \n"; + } + + //textarea fields + if (field.type === 'textarea') { + + html += label(); + + html += "
          Parse as: " + + " YAML\n"; + html += " JSON\n"; + html += "
          \n"; + } + + html += "\n"; - - // Add error messages - if ( (options.mode == 'add' && field.addRequired) || (options.mode == 'edit' && field.editRequired) ) { - html += "
          A value is required!
          \n"; - } - html += "
          \n"; - html += "
          \n"; - } - - //select field - if (field.type == 'select') { - - html += label(); - - html += "
          "; - html += (field.defaultOption) ? field.defaultOption : "Choose a " + field.label.toLowerCase(); - html += "\n"; - html += "\n"; - // Add error messages - if ( (options.mode == 'add' && field.addRequired) || (options.mode == 'edit' && field.editRequired) || - field.awRequiredWhen ) { - html += "
          A value is required!
          \n"; - } - html += "
          \n"; - - // Add help panel(s) - html += (field.helpCollapse) ? this.buildHelpCollapse(field.helpCollapse) : ''; - - html += "
          \n"; - } - - //number field - if (field.type == 'number') { - - html += label(); - - html += "
          A value is required!
          \n"; - } - if (field.integer) { - html += "
          Must be an integer value
          \n"; - } - if (field.min !== undefined || field.max !== undefined) { - html += "
          Must be an integer between " + field.min + " and "; - html += (field.max !== undefined) ? field.max : 'unlimited'; - html += "
          \n"; - } - html += "
          \n"; - html += "
          \n"; - } - - //checkbox group - if (field.type == 'checkbox_group') { - - html += label(); - - html += "
          A value is required!
          \n"; - } - if (field.integer) { - html += "
          Must be an integer value
          \n"; - } - if (field.min || field.max) { - html += "
          Must be in range " + field.min + " to " + - field.max + "
          \n"; - } - html += "
          \n"; - html += "
          \n"; - html += "
          \n"; - } - - //checkbox - if (field.type == 'checkbox') { - - if (horizontal) { - var fldWidth = getFieldWidth(); - var offset = 12 - parsetInt(fldWidth.replace(/[A-Z,a-z,-]/g,'')); - html += "
          \n"; - } - - html += "
          \n"; - html += "\n"; - html += "
          \n"; - html += "
          \n" - - if (horizontal) { - html += "
          \n"; - } - } - - //radio group - if (field.type == 'radio_group') { - - html += label(); - - html += "
          A value is required!
          \n"; - } - html += "
          \n"; - - // Add help panel(s) - html += (field.helpCollapse) ? this.buildHelpCollapse(field.helpCollapse) : ''; - - html += "
          \n"; - } - - // radio button - if (field.type == 'radio') { - - if (horizontal) { - var fldWidth = getFieldWidth(); - var offset = 12 - parsetInt(fldWidth.replace(/[A-Z,a-z,-]/g,'')); - html += "
          \n"; - } - - html += "
          \n"; - html += "
          \n"; - html += "
          \n" - - if (horizontal) { - html += "
          \n"; - } - } - - //lookup type fields - if (field.type == 'lookup' && (field.excludeMode == undefined || field.excludeMode != options.mode)) { - - html += label(); - - html += "
          \n"; - html += "\n"; - html += "\n"; - html += "\n"; - html += "A value is required!
          \n"; - } - html += "
          Value not found
          \n"; - html += "
          \n"; - html += "
          \n"; - } - - //custom fields - if (field.type == 'custom') { - /*html += "
          '; - html += (field.icon) ? this.icon(field.icon) : ""; - html += (field.label) ? field.label : ''; - html += '' + "\n"; - html += "
          \n"; - */ - - html += label(); - - html += "
          \n"; - for (var action in this.form.actions) { - if (this.form.actions[action].mode == 'all' || this.form.actions[action].mode == options.mode) { - html += this.button({ btn: this.form.actions[action], action: action, toolbar: true }); - } - } - html += "
          \n"; - return html; - }, - - - breadCrumbs: function(options, navigation) { - - var html = ''; - html += "
          \n"; - html += "
            \n"; - html += "
          • {{ crumb.title }}
          • \n"; - - if (navigation) { - - var paths = $location.path().replace(/^\//,'').split('/'); - - if (paths.length == 2) { - html += "
          • "; - if (options.mode == 'edit') { - html += this.form.editTitle; - } - else { - html += this.form.addTitle; - } - html += "
          • \n"; - } - - html += "
          • \n"; - html += "
          \n"; - html += "
          \n"; - for (var itm in navigation) { - if (navigation[itm].active) { - html += ""; - break; - } - } - - html += "\n"; - html += "
          \n"; - html += "
          \n"; - } - else { - html += "
        • "; - if (options.mode == 'edit') { - html += this.form.editTitle; - } - else { - html += this.form.addTitle; - } - html += "
        • \n
        \n
        \n"; - } - return html; - }, - - build: function(options) { - // - // Generate HTML. Do NOT call this function directly. Called by inject(). Returns an HTML - // string to be injected into the current view. - // - var html = ''; - - if (!this.modal && (options.breadCrumbs == undefined || options.breadCrumbs == true)) { - if (this.form.navigationLinks) { - html += this.breadCrumbs(options, this.form.navigationLinks); - } - else { - html += this.breadCrumbs(options); - } - } - - if ((!this.modal && this.form.statusFields)) { - // Add status fields section (used in Jobs form) - html += "
        \n"; - if (this.form.statusActions) { - html += "
        \n"; - var act; - for (var action in this.form.statusActions) { - act = this.form.statusActions[action]; - html += this.button({ btn: act, action: action, toolbar: true }); - } - html += "
        \n"; - //html += "
        \n"; - } - html += "
        \n"; - for (var fld in this.form.statusFields) { - field = this.form.statusFields[fld]; - html += this.buildField(fld, field, options, this.form); - } - html += "
        \n"; - html += "
        \n"; - } - - if (this.form.fieldsAsHeader) { - html += "
        \n"; - html += "\n"; - for (var fld in this.form.fields) { - field = this.form.fields[fld]; - html += this.headerField(fld, field, options); - } - html += "\n"; - html += "
        \n"; - } - else { - - if ( this.form.collapse && this.form.collapseMode == options.mode) { - html += "
        \n"; - html += "

        " + this.form.collapseTitle + "

        \n"; - html += "
        \n"; - } - - // Start the well - if ( !this.modal && this.has('well') ) { - html += "
        \n"; - } - - if (!this.modal && this.form.actions) { - html += this.getActions(options); - } - - // Add a title and optionally a close button (used on Inventory->Groups) - if ( (!options.modal) && this.form.showTitle ) { - html += "
        "; - html += (options.mode == 'edit') ? this.form.editTitle : this.form.addTitle; - if (this.has('titleActions')) { - html += "
        \n"; - for (var btn in this.form.titleActions) { - html += this.button({ btn: this.form.titleActions[btn], action: btn, toolbar: true }); - } - html += "
        \n"; - } - html += "
        \n"; - html += "
        \n"; - } - - html += "
        \n"; - html += "
        {{ flashMessage }}
        \n"; - - var field; - if (this.form.twoColumns) { - html += "
        \n"; - html += "
        \n"; - for (var fld in this.form.fields) { - field = this.form.fields[fld]; - if (field.column == 1) { - html += this.buildField(fld, field, options, this.form); - } - } - html += "
        \n"; - html += "
        \n"; - for (var fld in this.form.fields) { - field = this.form.fields[fld]; - if (field.column == 2) { - html += this.buildField(fld, field, options, this.form); - } - } - html += "
        \n"; - html += "
        \n"; - } - else if (this.form.tabs) { - html += "
          \n"; - for (var i=0; i < this.form.tabs.length; i++) { - var tab = this.form.tabs[i]; - html += "" + tab.label + "\n"; - } - html += "
        \n"; - html += "
        \n"; - for (var i=0; i < this.form.tabs.length; i++) { - var tab = this.form.tabs[i]; - html += "
        \n"; - for (var fld in this.form.fields) { - if (this.form.fields[fld].tab == tab.name) { - html += this.buildField(fld, this.form.fields[fld], options, this.form); - } - } - html += "
        \n" - } - html += "
        \n"; - } - else { - // original, single-column form - var section = ''; - var group = ''; - for (var fld in this.form.fields) { - var field = this.form.fields[fld]; - if (!(options.modal && field.excludeModal)) { - if (field.group && field.group != group) { - if (group !== '') { - html += "
        \n"; + if (field.integer) { + html += "
        Must be an integer value
        \n"; } - html += "
        \n"; - html += "
        " + field.group + "
        \n"; - group = field.group; - } - if (field.section && field.section != section) { - if (section !== '') { - html += "
        \n"; - } - else { + if (field.min !== undefined || field.max !== undefined) { + html += "
        Must be an integer between " + field.min + " and "; + html += (field.max !== undefined) ? field.max : 'unlimited'; html += "
        \n"; - html += "
        \n"; } - var sectionShow = (this.form[field.section + 'Show']) ? " ng-show=\"" + this.form[field.section + 'Show'] + "\"" : ""; - html += "" + field.section + "\n"; - html += "\n"; - section = field.section; - } - html += this.buildField(fld, field, options, this.form); - } - } - if (section !== '') { - html += "
        \n
        \n"; - } - if (group !== '') { - html += "
        \n"; - } - } - - //buttons - if (!this.modal) { - if (this.has('buttons')) { - - if (this.form.twoColumns) { - html += "
        \n"; - html += "
        \n"; - html += "
        \n"; - } - - html += "
        \n"; + html += "
        \n"; } - var width = 12 - offset; - html += "
        \n"; - } - //html += "\n"; - - //html += "
        \n"; - - for (var btn in this.form.buttons) { - if (typeof this.form.buttons[btn] == 'object') { - var button = this.form.buttons[btn]; + //checkbox group + if (field.type === 'checkbox_group') { - // Set default color and label for Save and Reset - if (btn == 'save') { - button.label = 'Save'; - button['class'] = 'btn-success'; - } - if (btn == 'reset') { - button.label = 'Reset'; - button['class'] = 'btn-default'; - } - - // Build button HTML - html += "
        \n"; + html += "
        \n"; } - } - html += "
        \n"; - if (this.form.horizontal) { + //checkbox + if (field.type === 'checkbox') { + + if (horizontal) { + fldWidth = getFieldWidth(); + offset = 12 - parseInt(fldWidth.replace(/[A-Z,a-z,-]/g, ''),10); + html += "
        \n"; + } + + html += "
        \n"; + html += "\n"; + html += "
        \n"; + html += "
        \n"; + + if (horizontal) { + html += "
        \n"; + } + } + + //radio group + if (field.type === 'radio_group') { + + html += label(); + + html += "
        A value is required!
        \n"; + } + html += "
        \n"; + + // Add help panel(s) + html += (field.helpCollapse) ? this.buildHelpCollapse(field.helpCollapse) : ''; + + html += "
        \n"; + } + + // radio button + if (field.type === 'radio') { + + if (horizontal) { + fldWidth = getFieldWidth(); + offset = 12 - parseInt(fldWidth.replace(/[A-Z,a-z,-]/g, ''),10); + html += "
        \n"; + } + + html += "
        \n"; + html += "
        \n"; + html += "
        \n"; + + if (horizontal) { + html += "
        \n"; + } + } + + //lookup type fields + if (field.type === 'lookup' && (field.excludeMode === undefined || field.excludeMode !== options.mode)) { + + html += label(); + + html += "
        \n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "A value is required!
        \n"; + } + html += "
        Value not found
        \n"; + html += "
        \n"; + html += "\n"; + } + + //custom fields + if (field.type === 'custom') { + html += label(); + html += "
        \n", action; + for (action in this.form.actions) { + if (this.form.actions[action].mode === 'all' || this.form.actions[action].mode === options.mode) { + html += this.button({ btn: this.form.actions[action], action: action, toolbar: true }); + } } - } - } - html += "\n"; - - if ( !this.modal && this.has('well') ) { - html += "
        \n"; - } + html += "\n"; + return html; + }, - if ( this.form.collapse && this.form.collapseMode == options.mode ) { - html += "\n"; - html += "\n"; - } - } - if ((!this.modal && this.form.items)) { - for (var itm in this.form.items) { - html += "
        \n"; - html += SearchWidget({ iterator: this.form.items[itm].iterator, template: this.form.items[itm], mini: false, label: 'Filter Events'}); - html += "
        Viewing" + " \{\{ " + this.form.items[itm].iterator + "Page + 1 \}\} of " + - "\{\{ " + this.form.items[itm].iterator + "Count \}\}
        \n"; - html += "
        \n"; - html += "\n"; - html += "
        ' + "\n"; - for (var fld in this.form.items[itm].fields) { - var field = this.form.items[itm].fields[fld]; - html += this.buildField(fld, field, options, this.form); - } - html += "
        \n"; - html += "\n"; - html += "
        \n"; - } - } - - if ((!this.modal) && options.related && this.form.related) { - html += this.buildCollections(options); - } + breadCrumbs: function (options, navigation) { - return html; - - }, + var itm, paths, html = ''; + html += "
        \n"; + html += "
          \n"; + html += "
        • {{ crumb.title }}
        • \n"; - buildCollections: function(options) { - // - // Create TB accordians with imbedded lists for related collections - // Should not be called directly. Called internally by build(). - // - var idx = 1; - var form = this.form; - var html = "
          \n"; - for (var itm in form.related) { - if (form.related[itm].type == 'collection') { - html += "

          " + form.related[itm].title + "

          \n"; - html += "
          \n"; - - if (form.related[itm].instructions) { - html += "
          \n"; - html += "\n"; - html += "Hint: " + form.related[itm].instructions + "\n"; - html += "
          \n" - } - - html += "
          \n"; - html += "
          \n"; - - html += SearchWidget({ iterator: form.related[itm].iterator, template: form.related[itm], mini: true }); - - html += "
          \n"; - html += "
          \n"; - - for (var act in form.related[itm].actions) { - var action = form.related[itm].actions[act]; - html += this.button({ btn: action, action: act, toolbar: true }); - } - - html += "
          \n"; - html += "
          \n"; - html += "
          \n" - - // Start the list - html += "
          \n"; - html += "\n"; - html += "\n"; - html += "\n"; - html += (form.related[itm].index == undefined || form.related[itm].index !== false) ? "\n" : ""; - for (var fld in form.related[itm].fields) { - html += "\n"; - } - html += "\n"; - html += "\n"; - html += ""; - html += "\n"; - html += "\n"; - if (form.related[itm].index == undefined || form.related[itm].index !== false) { - html += "\n"; - } - var cnt = 1; - var rfield; - var base = (form.related[itm].base) ? form.related[itm].base : itm; - base = base.replace(/^\//,''); - for (var fld in form.related[itm].fields) { - cnt++; - html += Column({ list: form.related[itm], fld: fld, options: options, base: base }); - } + html += "\n"; + html += "\n"; + html += "\n"; + } else { + html += "
        • "; + if (options.mode === 'edit') { + html += this.form.editTitle; + } else { + html += this.form.addTitle; + } + html += "
        • \n\n\n"; + } + return html; + }, - // Row level actions - html += "\n"; - html += "\n"; + if (!this.modal && (options.breadCrumbs === undefined || options.breadCrumbs === true)) { + if (this.form.navigationLinks) { + html += this.breadCrumbs(options, this.form.navigationLinks); + } else { + html += this.breadCrumbs(options); + } + } - // Message for loading - html += "\n"; - html += "\n"; - html += "\n"; + if ((!this.modal && this.form.statusFields)) { + // Add status fields section (used in Jobs form) + html += "
          \n"; + if (this.form.statusActions) { + html += "
          \n"; + for (action in this.form.statusActions) { + act = this.form.statusActions[action]; + html += this.button({ + btn: act, + action: action, + toolbar: true + }); + } + html += "
          \n"; + //html += "
          \n"; + } + html += "
          \n"; + for (fld in this.form.statusFields) { + field = this.form.statusFields[fld]; + html += this.buildField(fld, field, options, this.form); + } + html += "
          \n"; + html += "
          \n"; + } - // End List - html += "\n"; - html += "
          #" + - form.related[itm]['fields'][fld].label; - html += " "; + if (options.mode === 'edit') { + html += this.form.editTitle; + } else { + html += this.form.addTitle; + } + html += "\n"; } - else { - html += "icon-sort-up"; + + html += "
        • \n"; + html += "\n"; + html += "
          \n"; + for (itm in navigation) { + if (navigation[itm].active) { + html += ""; + break; + } } - } - else { - html += "icon-sort"; - } - html += "\">
          {{ $index + ((" + form.related[itm].iterator + "_page - 1) * " + - form.related[itm].iterator + "_page_size) + 1 }}."; - for (var act in form.related[itm].fieldActions) { - var fAction = form.related[itm].fieldActions[act]; - html += "\n"; - html += "
          No records matched your search.
          Loading...
          \n"; - html += "
          \n"; // close well - html += "
          \n"; // close list div + if (this.form.fieldsAsHeader) { + html += "
          \n"; + html += "
          \n"; + for (fld in this.form.fields) { + field = this.form.fields[fld]; + html += this.headerField(fld, field, options); + } + html += "
          \n"; + html += "
          \n"; + } else { - html += PaginateWidget({ set: itm, iterator: form.related[itm].iterator, mini: true }); + if (this.form.collapse && this.form.collapseMode === options.mode) { + html += "
          \n"; + html += "

          " + this.form.collapseTitle + "

          \n"; + html += "
          \n"; + } - // End Accordion - html += "
          \n"; // accordion inner + // Start the well + if (!this.modal && this.has('well')) { + html += "
          \n"; + } - idx++; + if (!this.modal && this.form.actions) { + html += this.getActions(options); + } + + // Add a title and optionally a close button (used on Inventory->Groups) + if ((!options.modal) && this.form.showTitle) { + html += "
          "; + html += (options.mode === 'edit') ? this.form.editTitle : this.form.addTitle; + if (this.has('titleActions')) { + html += "
          \n"; + for (btn in this.form.titleActions) { + html += this.button({ + btn: this.form.titleActions[btn], + action: btn, + toolbar: true + }); + } + html += "
          \n"; + } + html += "
          \n"; + html += "
          \n"; + } + + html += "
          \n"; + html += "
          {{ flashMessage }}
          \n"; + + if (this.form.twoColumns) { + html += "
          \n"; + html += "
          \n"; + for (fld in this.form.fields) { + field = this.form.fields[fld]; + if (field.column === 1) { + html += this.buildField(fld, field, options, this.form); + } + } + html += "
          \n"; + html += "
          \n"; + for (fld in this.form.fields) { + field = this.form.fields[fld]; + if (field.column === 2) { + html += this.buildField(fld, field, options, this.form); + } + } + html += "
          \n"; + html += "
          \n"; + } else if (this.form.tabs) { + html += "
            \n"; + for (i = 0; i < this.form.tabs.length; i++) { + tab = this.form.tabs[i]; + html += "" + tab.label + "\n"; + } + html += "
          \n"; + html += "
          \n"; + for (i = 0; i < this.form.tabs.length; i++) { + tab = this.form.tabs[i]; + html += "
          \n"; + for (fld in this.form.fields) { + if (this.form.fields[fld].tab === tab.name) { + html += this.buildField(fld, this.form.fields[fld], options, this.form); + } + } + html += "
          \n"; + } + html += "
          \n"; + } else { + // original, single-column form + section = ''; + group = ''; + for (fld in this.form.fields) { + field = this.form.fields[fld]; + if (!(options.modal && field.excludeModal)) { + if (field.group && field.group !== group) { + if (group !== '') { + html += "
          \n"; + } + html += "
          \n"; + html += "
          " + field.group + "
          \n"; + group = field.group; + } + if (field.section && field.section !== section) { + if (section !== '') { + html += "
          \n"; + } else { + html += "
          \n"; + html += "
          \n"; + } + sectionShow = (this.form[field.section + 'Show']) ? " ng-show=\"" + this.form[field.section + 'Show'] + "\"" : ""; + html += "" + field.section + "

          \n"; + html += "\n"; + section = field.section; + } + html += this.buildField(fld, field, options, this.form); + } + } + if (section !== '') { + html += "
          \n
        \n"; + } + if (group !== '') { + html += "\n"; + } + } + + //buttons + if (!this.modal) { + if (this.has('buttons')) { + + if (this.form.twoColumns) { + html += "
        \n"; + html += "
        \n"; + html += "
        \n"; + } + + html += "
        \n"; + } + + for (btn in this.form.buttons) { + if (typeof this.form.buttons[btn] === 'object') { + button = this.form.buttons[btn]; + + // Set default color and label for Save and Reset + if (btn === 'save') { + button.label = 'Save'; + button['class'] = 'btn-success'; + } + if (btn === 'reset') { + button.label = 'Reset'; + button['class'] = 'btn-default'; + } + + // Build button HTML + html += "
        \n"; + + if (this.form.horizontal) { + html += "
        \n"; + } + + if (this.form.twoColumns) { + html += "
        \n"; + html += "\n"; + } + } + } + html += "\n"; + + if (!this.modal && this.has('well')) { + html += "\n"; + } + + if (this.form.collapse && this.form.collapseMode === options.mode) { + html += "\n"; + html += "\n"; + } + } + + if ((!this.modal) && options.related && this.form.related) { + html += this.buildCollections(options); + } + + return html; + + }, + + buildCollections: function (options) { + // + // Create TB accordians with imbedded lists for related collections + // Should not be called directly. Called internally by build(). + // + var idx = 1, + form = this.form, + html = "
        \n", + act, fAction, fld, itm, action, cnt, base; + + for (itm in form.related) { + if (form.related[itm].type === 'collection') { + html += "

        " + form.related[itm].title + "

        \n"; + html += "
        \n"; + + if (form.related[itm].instructions) { + html += "
        \n"; + html += "\n"; + html += "Hint: " + form.related[itm].instructions + "\n"; + html += "
        \n"; + } + + html += "
        \n"; + html += "
        \n"; + + html += SearchWidget({ + iterator: form.related[itm].iterator, + template: form.related[itm], + mini: true + }); + + html += "
        \n"; + html += "
        \n"; + + for (act in form.related[itm].actions) { + action = form.related[itm].actions[act]; + html += this.button({ + btn: action, + action: act, + toolbar: true + }); + } + + html += "
        \n"; + html += "
        \n"; + html += "
        \n"; + + // Start the list + html += "
        \n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += (form.related[itm].index === undefined || form.related[itm].index !== false) ? "\n" : ""; + for (fld in form.related[itm].fields) { + html += "\n"; + } + html += "\n"; + html += "\n"; + html += ""; + html += "\n"; + + html += "\n"; + if (form.related[itm].index === undefined || form.related[itm].index !== false) { + html += "\n"; + } + cnt = 1; + base = (form.related[itm].base) ? form.related[itm].base : itm; + base = base.replace(/^\//, ''); + for (fld in form.related[itm].fields) { + cnt++; + html += Column({ + list: form.related[itm], + fld: fld, + options: options, + base: base + }); + } + + // Row level actions + html += "\n"; + html += "\n"; + + // Message for loading + html += "\n"; + html += "\n"; + html += "\n"; + + // End List + html += "\n"; + html += "
        #" + + form.related[itm].fields[fld].label; + html += "
        {{ $index + ((" + form.related[itm].iterator + "_page - 1) * " + + form.related[itm].iterator + "_page_size) + 1 }}."; + for (act in form.related[itm].fieldActions) { + fAction = form.related[itm].fieldActions[act]; + html += "\n"; + html += "
        No records matched your search.
        Loading...
        \n"; + html += "
        \n"; // close well + html += "
        \n"; // close list div + + html += PaginateWidget({ + set: itm, + iterator: form.related[itm].iterator, + mini: true + }); + + // End Accordion + html += "
        \n"; // accordion inner + + idx++; + } + } + html += "

        \n"; // accordion body + html += "\n"; + + return html; } - } - html += "\n"; // accordion body - html += "\n"; - - return html; - } - -}}]); \ No newline at end of file + }; + } +]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/generator-helpers.js b/awx/ui/static/lib/ansible/generator-helpers.js index 05398cab0c..8fb3835e99 100644 --- a/awx/ui/static/lib/ansible/generator-helpers.js +++ b/awx/ui/static/lib/ansible/generator-helpers.js @@ -3,593 +3,589 @@ * * GeneratorHelpers * - * Functions shared between FormGenerator and ListGenerator - * + * Functions shared between FormGenerator and ListGenerator + * */ 'use strict'; angular.module('GeneratorHelpers', ['GeneratorHelpers']) - - .factory('Attr', function() { - return function(obj, key, fld) { - var result; - var value = (typeof obj[key] === "string") ? obj[key].replace(/[\'\"]/g, '"') : obj[key]; + +.factory('Attr', function () { + return function (obj, key, fld) { + var i, s, result, + value = (typeof obj[key] === "string") ? obj[key].replace(/[\'\"]/g, '"') : obj[key]; if (/^ng/.test(key)) { - result = 'ng-' + key.replace(/^ng/,'').toLowerCase() + "=\"" + value + "\" "; - } - else if (/^data|^aw/.test(key) && key != 'awPopOver') { - var s = ''; - for (var i=0; i < key.length; i++) { + result = 'ng-' + key.replace(/^ng/, '').toLowerCase() + "=\"" + value + "\" "; + } else if (/^data|^aw/.test(key) && key !== 'awPopOver') { + s = ''; + for (i = 0; i < key.length; i++) { if (/[A-Z]/.test(key.charAt(i))) { s += '-' + key.charAt(i).toLowerCase(); - } - else { + } else { s += key.charAt(i); } } result = s + "=\"" + value + "\" "; - } - else { - switch(key) { - case 'trueValue': - result = "ng-true-value=\"" + value + "\" "; - break; - case 'falseValue': - result = "ng-false-value=\"" + value + "\" "; - break; - case 'awPopOver': - // construct the entire help link - result = " "; - break; - case 'columnShow': - result = "ng-show=\"" + value + "\" "; - break; - case 'icon': - // new method of constructing icon tag. Replces Icon method. - result = ""; - break; - case 'autocomplete': - result = "autocomplete=\""; - result += (value) ? 'true' : 'false'; - result += "\" "; - break; - default: - result = key + "=\"" + value + "\" "; + } else { + switch (key) { + case 'trueValue': + result = "ng-true-value=\"" + value + "\" "; + break; + case 'falseValue': + result = "ng-false-value=\"" + value + "\" "; + break; + case 'awPopOver': + // construct the entire help link + result = " "; + break; + case 'columnShow': + result = "ng-show=\"" + value + "\" "; + break; + case 'icon': + // new method of constructing icon tag. Replces Icon method. + result = ""; + break; + case 'autocomplete': + result = "autocomplete=\""; + result += (value) ? 'true' : 'false'; + result += "\" "; + break; + default: + result = key + "=\"" + value + "\" "; } } - return result; - - } - }) + return result; - .factory('Icon', function() { - return function(icon) { + }; +}) + +.factory('Icon', function () { + return function (icon) { return " "; - } - }) + }; +}) - .factory('SelectIcon', ['Icon', function(Icon) { - return function(params) { - // Common point for matching any type of action to the appropriate - // icon. The intention is to maintain consistent meaning and presentation - // for every icon used in the application. - var icon; - var action = params.action; - var size = params.size; - switch(action) { - case 'help': - icon = "fa-question-circle"; +.factory('SelectIcon', ['Icon', + function (Icon) { + return function (params) { + // Common point for matching any type of action to the appropriate + // icon. The intention is to maintain consistent meaning and presentation + // for every icon used in the application. + var icon, + action = params.action, + size = params.size; + switch (action) { + case 'help': + icon = "fa-question-circle"; break; case 'add': - case 'create': - icon= "fa-plus"; + case 'create': + icon = "fa-plus"; break; case 'edit': icon = "fa-pencil"; - break; + break; case 'delete': - icon = "fa-trash-o"; - break; + icon = "fa-trash-o"; + break; case 'group_update': icon = 'fa-exchange'; break; - case 'scm_update': + case 'scm_update': icon = 'fa-cloud-download'; break; case 'cancel': icon = 'fa-minus-circle'; break; case 'run': - case 'rerun': + case 'rerun': case 'submit': icon = 'fa-rocket'; break; - case 'stream': + case 'stream': icon = 'fa-clock-o'; break; case 'refresh': icon = 'fa-refresh'; - break; - case 'close': - icon='fa-arrow-left'; break; - case 'save': - icon='fa-check-square-o'; + case 'close': + icon = 'fa-arrow-left'; + break; + case 'save': + icon = 'fa-check-square-o'; break; case 'properties': - icon="fa-wrench"; + icon = "fa-wrench"; break; - case 'reset': - icon="fa-undo"; + case 'reset': + icon = "fa-undo"; break; case 'view': - icon="fa-search-plus"; + icon = "fa-search-plus"; break; case 'sync_status': - icon="fa-cloud"; - break; + icon = "fa-cloud"; + break; } - icon += (size) ? " " + size : ""; - return Icon(icon); - } - }]) + icon += (size) ? " " + size : ""; + return Icon(icon); + }; + } +]) - .factory('Button', ['Attr', 'SelectIcon', function(Attr, SelectIcon) { - return function(params) { - - // pass in button object, get back html +.factory('Button', ['Attr', 'SelectIcon', + function (Attr, SelectIcon) { + return function (params) { - var btn = params.btn; - var action = params.action; // label used to select the icon - var toolbar = params.toolbar; - - if (toolbar) { - //if this is a toolbar button, set some defaults - btn['class'] = 'btn-xs btn-primary'; - btn['iconSize'] = 'fa-lg'; - delete btn['label']; - } - - var html = ''; - - html += " "; - - return html; - } - }]) - - - .factory('NavigationLink', ['Attr', 'Icon', function(Attr, Icon) { - return function(link) { - var html = "\n"; - } - else { - html = ''; - } - - html += "
        \n"; - html += "\n"; - html += "\n"; - html += "
        \n"; - html += (params.td == undefined || params.td !== false) ? "\n" : ""; - - return html; - - } - }]) - - .factory('BadgeCount', [ function() { - return function(params) { - - // Adds a badge count with optional tooltip - - var list = params['list']; - var fld = params['fld']; - var field = list.fields[fld]; - var options = params['options']; - var base = params['base']; - var html = "\n"; - html += ""; - html += "\{\{ " + list.iterator + '.' + fld + " \}\}"; - html += ""; - html += (field.badgeLabel) ? " " + field.badgeLabel : ""; - html += "\n"; - html += "\n"; - return html; - } - }]) - - .factory('Badge', [ function() { - return function(field) { - - // Adds an icon(s) with optional tooltip - - var html = ''; - - if (field.badges) { - for (var i=0; i < field.badges.length; i++) { - if (field.badges[i].toolTip) { - html += "
        "; - if (field.badges[i].toolTip) { - html += ""; - } - html += "\n"; - } - } - else { - if (field.badgeToolTip) { - html += ""; - if (field.badgeToolTip) { - html += ""; - } - html += "\n"; - } - - return html; - - } - }]) - - .factory('Breadcrumbs', ['Attr', function(Attr) { - return function(params) { - - // Generate breadcrumbs using the list-generator.js method. - - var list = params.list; - var mode = params.mode; - var html = ''; - - html += "
        \n"; - html += "
          \n"; - html += "
        • {{ crumb.title }}
        • \n"; - - if (list.navigationLinks) { - var navigation = list.navigationLinks; - if (navigation['ngHide']) { - html += "
        • "; - html += list.editTitle; - html += "
        • \n"; - html += "
        • \n"; + if (toolbar) { + //if this is a toolbar button, set some defaults + btn.class = 'btn-xs btn-primary'; + btn.iconSize = 'fa-lg'; + delete btn.label; } - else { - html += "
        • \n"; - html += "
        \n"; + + html += " "; + + return html; + }; + } +]) + + +.factory('NavigationLink', ['Attr', 'Icon', + function (Attr, Icon) { + return function (link) { + var html = "\n"; + } else { + html = ''; + } + + html += "
        \n"; + html += "\n"; + html += "\n"; - html += "
        \n"; - html += "
        \n"; - } - else { - html += "
      • "; - if (mode == 'select') { - html += list.selectTitle; + html += "\n"; + html += (params.td === undefined || params.td !== false) ? "\n" : ""; + + return html; + + }; + } +]) + +.factory('BadgeCount', [ + function () { + return function (params) { + + // Adds a badge count with optional tooltip + + var list = params.list, + fld = params.fld, + field = list.fields[fld], + html; + + html = "\n"; + html += ""; + html += "{{ " + list.iterator + '.' + fld + " }}"; + html += ""; + html += (field.badgeLabel) ? " " + field.badgeLabel : ""; + html += "\n"; + html += "\n"; + return html; + }; + } +]) + +.factory('Badge', [ + function () { + return function (field) { + + // Adds an icon(s) with optional tooltip + + var i, html = ''; + + if (field.badges) { + for (i = 0; i < field.badges.length; i++) { + if (field.badges[i].toolTip) { + html += ""; + if (field.badges[i].toolTip) { + html += ""; + } + html += "\n"; + } + } else { + if (field.badgeToolTip) { + html += ""; + if (field.badgeToolTip) { + html += ""; + } + html += "\n"; } - else { - html += list.editTitle; + return html; + }; + } +]) + +.factory('Breadcrumbs', ['Attr', + function (Attr) { + return function (params) { + + // Generate breadcrumbs using the list-generator.js method. + + var list = params.list, + mode = params.mode, + html = '', itm, navigation; + + html += "
        \n"; + html += "
          \n"; + html += "
        • {{ crumb.title }}
        • \n"; + + if (list.navigationLinks) { + navigation = list.navigationLinks; + if (navigation.ngHide) { + html += "
        • "; + html += list.editTitle; + html += "
        • \n"; + html += "
        • \n"; + } else { + html += "
        • \n"; + html += "
        \n"; + } + html += "
        "; + break; + } + } + html += "\n"; + html += "
        \n"; + html += "
        \n"; + } else { + html += "
      • "; + if (mode === 'select') { + html += list.selectTitle; + } else { + html += list.editTitle; + } + html += "
      • \n\n\n"; } - html += "\n\n\n"; - } + + return html; + + }; + } +]) + +.factory('Column', ['Attr', 'Icon', 'DropDown', 'Badge', 'BadgeCount', + function (Attr, Icon, DropDown, Badge, BadgeCount) { + return function (params) { + var list = params.list, + fld = params.fld, + options = params.options, + base = params.base, + field = list.fields[fld], + html = '', cap; + + if (field.type !== undefined && field.type === 'DropDown') { + html = DropDown(params); + } else if (field.type === 'badgeCount') { + html = BadgeCount(params); + } else { + html += "" : ""; + + // Badge + if (options.mode !== 'lookup' && (field.badges || (field.badgeIcon && field.badgePlacement && field.badgePlacement === 'left'))) { + html += Badge(field); + } + + // Add collapse/expand icon --used on job_events page + if (list.hasChildren && field.hasChildren) { + html += ""; + //ng-show=\"'\{\{ " + list.iterator + ".related.children \}\}' !== ''\" + } + + if (list.name === 'groups') { + html += "
        "; + } + if (list.name === 'hosts') { + html += ""; + } + + // close ngShow + html += (field.ngShow) ? "" : ""; + + // Specific to Job Events page -showing event detail/results + html += (field.appendHTML) ? "
        \n" : ""; + + // Badge + if (options.mode !== 'lookup' && field.badgeIcon && field.badgePlacement && field.badgePlacement !== 'left') { + html += Badge(field); + } + } + return html += "\n"; + }; + } +]) + +.factory('HelpCollapse', function () { + return function (params) { - return html; - - } - }]) - - .factory('Column', ['Attr', 'Icon', 'DropDown', 'Badge', 'BadgeCount', function(Attr, Icon, DropDown, Badge, BadgeCount) { - return function(params) { - var list = params['list']; - var fld = params['fld']; - var options = params['options']; - var base = params['base']; - - var field = list['fields'][fld]; - var html = ''; + var hdr = params.hdr, + content = params.content, + show = params.show, + idx = params.idx, + bind = params.bind, + html = ''; - if (field.type !== undefined && field.type == 'DropDown') { - html = DropDown(params); - } - else if (field.type == 'badgeCount') { - html = BadgeCount(params); - } - else { - html += "" : ""; - - // Badge - if ( options.mode !== 'lookup' && (field.badges || (field.badgeIcon && field.badgePlacement && field.badgePlacement == 'left')) ) { - html += Badge(field); - } - - // Add collapse/expand icon --used on job_events page - if (list['hasChildren'] && field.hasChildren) { - html += ""; - //ng-show=\"'\{\{ " + list.iterator + ".related.children \}\}' !== ''\" - } - - if (list.name == 'groups') { - html += "
        "; - } - if (list.name == 'hosts') { - html += ""; - } - - // close ngShow - html += (field.ngShow) ? "" : ""; - - // Specific to Job Events page -showing event detail/results - html += (field.appendHTML) ? "
        \n" : ""; - - // Badge - if (options.mode !== 'lookup' && field.badgeIcon && field.badgePlacement && field.badgePlacement !== 'left') { - html += Badge(field); - } - } - - return html += "\n"; - - } - }]) - - .factory('HelpCollapse', function() { - return function(params) { - var hdr = params.hdr; - var content = params.content; - var show = params.show; - var idx = params.idx; - var bind = params.bind; //Pass in scope variable containing html - var html = ''; html += "
        \n"; - html += "
        \n"; - + html += "
        \n"; - html += "
        \n"; + html += "
        \n"; html += "\n"; html += "
          \n"; - for ( var fld in form.fields) { - if ( (form.fields[fld].searchable == undefined || form.fields[fld].searchable == true) - && (((form.fields[fld].searchWidget == undefined || form.fields[fld].searchWidget == 1) && i == 1 ) || - (form.fields[fld].searchWidget == i)) ) { - html += "
        • " + - form.fields[fld].searchLabel + "
        • \n"; - } - else { - html += form.fields[fld].label.replace(/\/g,' ') + "', " + i + ")\">" + - form.fields[fld].label.replace(/\/g,' ') + "\n"; - } + for (fld in form.fields) { + if ((form.fields[fld].searchable === undefined || form.fields[fld].searchable === true) && + (((form.fields[fld].searchWidget === undefined || form.fields[fld].searchWidget === 1) && i === 1) || + (form.fields[fld].searchWidget === i))) { + html += "
        • " + + form.fields[fld].searchLabel + "
        • \n"; + } else { + html += form.fields[fld].label.replace(/
          /g, ' ') + "', " + i + ")\">" + + form.fields[fld].label.replace(/
          /g, ' ') + "\n"; + } } } html += "
        \n"; html += "
        \n"; - - html += "\n"; - - html += "\n"; - + // Reset button for drop-down html += "
        \n"; html += "
        \n"; + html += "\n"; + + html += "
        \n"; } return html; - - } - }) - - .factory('PaginateWidget', [ function() { - return function(params) { - var iterator = params.iterator; - var set = params.set; - var html = ''; - html += "\n"; - html += "
        \n"; - html += "
        \n"; - html += "
          \n"; - html += "
        • " + - "
        • \n"; - html += "
        • " + - "
        • \n"; - html += "
        • " + - "{{ page }}
        • \n"; - html += "
        • " + iterator + "_num_pages\">
        • \n"; - html += "
        • = " + iterator + "_num_pages\">
        • \n"; - html += "
        \n"; - html += "
        \n"; - html += "
        \n"; - html += "
        \n"; - html += "Page {{ " + iterator + "_page }} of {{ " + iterator + "_num_pages }} for {{ " + iterator + "_total_rows | number:0 }} " + set + '.'; - html += "
        \n"; - html += "
        \n"; - html += "
        \n"; - return html; - } - }]); - + }; +}) +.factory('PaginateWidget', [ + function () { + return function (params) { + var iterator = params.iterator, + set = params.set, + html = ''; + html += "\n"; + html += "
        \n"; + html += "
        \n"; + html += "
          \n"; + html += "
        • " + + "
        • \n"; + html += "
        • " + + "
        • \n"; + html += "
        • " + + "{{ page }}
        • \n"; + html += "
        • " + iterator + "_num_pages\">
        • \n"; + html += "
        • = " + iterator + "_num_pages\">
        • \n"; + html += "
        \n"; + html += "
        \n"; + html += "
        \n"; + html += "
        \n"; + html += "Page {{ " + iterator + "_page }} of {{ " + iterator + "_num_pages }} for {{ " + iterator + "_total_rows | number:0 }} " + set + '.'; + html += "
        \n"; + html += "
        \n"; + html += "
        \n"; + + return html; + }; + } +]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/license.js b/awx/ui/static/lib/ansible/license.js index ebf08eec95..42b20a3c7c 100644 --- a/awx/ui/static/lib/ansible/license.js +++ b/awx/ui/static/lib/ansible/license.js @@ -9,200 +9,129 @@ 'use strict'; -angular.module('License', ['RestServices', 'Utilities', 'FormGenerator', 'PromptDialog']) - .factory('ViewLicense', ['$location', '$rootScope', 'GenerateForm', 'Rest', 'Alert', 'GetBasePath', 'ProcessErrors', - 'FormatDate', 'Prompt', 'Empty', - function($location, $rootScope, GenerateForm, Rest, Alert, GetBasePath, ProcessErrors, FormatDate, Prompt, Empty) { - return function() { - - var defaultUrl=GetBasePath('config'); - var generator = GenerateForm; - - var form = { - name: 'license', - well: false, - forceListeners: true, - fields: { - license_status: { - type: 'custom', - control: '
        \{\{ license_status \}\}
        ', - readonly: true, - section: 'License' - }, - license_key: { - label: 'Key', - type: 'textarea', - 'class': 'modal-input-xlarge', - readonly: true, - section: 'License' - }, - license_date: { - label: 'Expires On', - type: 'text', - readonly: true, - section: 'License' - }, - time_remaining: { - label: 'Time Left', - type: 'text', - readonly: true, - section: 'License' - }, - available_instances: { - label: 'Available', - type: 'text', - readonly: true, - section: 'Managed Hosts' - }, - current_instances: { - label: 'Used', - type: 'text', - readonly: true, - section: 'Managed Hosts' - }, - free_instances: { - label: 'Remaining', - type: 'text', - readonly: true, - section: 'Managed Hosts', - controlNGClass: 'free_instances_class', - labelNGClass: 'free_instances_class' - }, - company_name: { - label: 'Company', - type: 'text', - readonly: true, - section: 'Contact Info' - }, - contact_name: { - label: 'Contact', - type: 'text', - readonly: true, - section: 'Contact Info' - }, - contact_email: { - label: 'Contact Email', - type: 'text', - readonly: true, - section: 'Contact Info' - } - } - }; +angular.module('License', ['RestServices', 'Utilities', 'FormGenerator', 'PromptDialog', 'LicenseFormDefinition']) + .factory('ViewLicense', ['$location', '$rootScope', 'GenerateForm', 'Rest', 'Alert', 'GetBasePath', 'ProcessErrors', + 'FormatDate', 'Prompt', 'Empty', 'LicenseForm', + function ($location, $rootScope, GenerateForm, Rest, Alert, GetBasePath, ProcessErrors, FormatDate, Prompt, Empty, + LicenseForm) { + return function () { - var base = $location.path().replace(/^\//,'').split('/')[0]; - - - // Retrieve detail record and prepopulate the form - Rest.setUrl(defaultUrl); - Rest.get() - .success( function(data, status, headers, config) { - - for (var fld in form.fields) { - if (fld != 'time_remaining' && fld != 'license_status') { - if (Empty(data['license_info'][fld])) { - delete form.fields[fld]; - } - } - } + var defaultUrl = GetBasePath('config'), + generator = GenerateForm, + form = angular.copy(LicenseForm), + scope; - if (data['license_info']['is_aws'] || Empty(data['license_info']['license_date'])) { - delete form.fields['license_date']; - delete form.fields['time_remaining']; - } + // Retrieve detail record and prepopulate the form + Rest.setUrl(defaultUrl); + Rest.get() + .success(function (data) { - var scope = generator.inject(form, { mode: 'edit', modal: true, related: false}); - generator.reset(); - - scope.formModalAction = function() { - $('#form-modal').modal("hide"); - } - - scope.formModalActionLabel = 'OK'; - scope.formModalCancelShow = false; - scope.formModalInfo = 'Purchase/Extend License'; - scope.formModalHeader = 'Tower License'; + var fld, dt, days, remainder, hours, minutes, seconds, license; + + for (fld in form.fields) { + if (fld !== 'time_remaining' && fld !== 'license_status') { + if (Empty(data.license_info[fld])) { + delete form.fields[fld]; + } + } + } - //$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none'); - //$('#form-modal').addClass('skinny-modal'); - - - // Respond to license button - scope.formModalInfoAction = function() { - Prompt({ - hdr: 'Tower Licensing', - body: "

        Ansible Tower licenses can be purchased or extended by visiting " + - "the Ansible online store. Would you like to purchase or extend your license now?

        ", - 'class': 'btn-primary', - action: function() { - var href = $('#license-link').attr('href'); - window.open(href, 'storeWindow'); - } - }); - } + if (data.license_info.is_aws || Empty(data.license_info.license_date)) { + delete form.fields.license_date; + delete form.fields.time_remaining; + } - for (var fld in form.fields) { - if (!Empty(data['license_info'][fld])) { - scope[fld] = data['license_info'][fld]; - } - } - - if (scope['license_date']) { - var dt = new Date(parseInt(scope['license_date'])); - if (dt.getFullYear() == '1970') { - // date was passed in seconds rather than milliseconds - dt = new Date(parseInt(scope['license_date']) * 1000); - scope['time_remaining'] = scope['time_remaining'] + '000'; - } - scope['license_date'] = FormatDate(dt); + scope = generator.inject(form, { mode: 'edit', modal: true, related: false }); + generator.reset(); - var days = parseInt(scope['time_remaining'] / 86400000); - var remainder = scope['time_remaining'] - (days * 86400000); - var hours = parseInt(remainder / 3600000); - remainder = remainder - (hours * 3600000); - var minutes = parseInt(remainder / 60000); - remainder = remainder - (minutes * 60000); - var seconds = parseInt(remainder / 1000); - scope['time_remaining'] = days + ' days ' + ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2); - } + scope.formModalAction = function () { + $('#form-modal').modal("hide"); + }; - if (parseInt(scope['free_instances']) <= 0) { - scope['free_instances_class'] = 'field-failure'; - } - else { - scope['free_instances_class'] = 'field-success'; - } + scope.formModalActionLabel = 'OK'; + scope.formModalCancelShow = false; + scope.formModalInfo = 'Purchase/Extend License'; + scope.formModalHeader = 'Tower License'; - var license = data['license_info']; - if (license['valid_key'] !== undefined && license['valid_key'] == false) { - scope['license_status'] = 'Invalid'; - scope['status_color'] = 'license-invalid'; - } - else if (license['demo'] !== undefined && license['demo'] == true) { - scope['license_status'] = 'Demo'; - scope['status_color'] = 'license-demo'; - } - else if (license['date_expired'] !== undefined && license['date_expired'] == true) { - scope['license_status'] = 'Expired'; - scope['status_color'] = 'license-expired'; - } - else if (license['date_warning'] !== undefined && license['date_warning'] == true) { - scope['license_status'] = 'Expiration Warning'; - scope['status_color'] = 'license-warning'; - } - else if (license['free_instances'] !== undefined && parseInt(license['free_instances']) <= 0) { - scope['license_status'] = 'No available managed hosts'; - scope['status_color'] = 'license-invalid'; - } - else { - scope['license_status'] = 'Valid'; - scope['status_color'] = 'license-valid'; - } + //$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none'); + //$('#form-modal').addClass('skinny-modal'); - }) - .error( function(data, status, headers, config) { - ProcessErrors($rootScope, data, status, form, - { hdr: 'Error!', msg: 'Failed to retrieve license. GET status: ' + status }); - }); - } - }]); + + // Respond to license button + scope.formModalInfoAction = function () { + Prompt({ + hdr: 'Tower Licensing', + body: "

        Ansible Tower licenses can be purchased or extended by visiting " + + "the Ansible online store. Would you like to purchase or extend your license now?

        ", + 'class': 'btn-primary', + action: function () { + var href = $('#license-link').attr('href'); + window.open(href, 'storeWindow'); + } + }); + }; + + for (fld in form.fields) { + if (!Empty(data.license_info[fld])) { + scope[fld] = data.license_info[fld]; + } + } + + if (scope.license_date) { + dt = new Date(parseInt(scope.license_date)); + if (dt.getFullYear() === '1970') { + // date was passed in seconds rather than milliseconds + dt = new Date(parseInt(scope.license_date,10) * 1000); + scope.time_remaining = scope.time_remaining + '000'; + } + scope.license_date = FormatDate(dt); + + days = parseInt(scope.time_remaining / 86400000, 10); + remainder = scope.time_remaining - (days * 86400000); + hours = parseInt(remainder / 3600000, 10); + remainder = remainder - (hours * 3600000); + minutes = parseInt(remainder / 60000, 10); + remainder = remainder - (minutes * 60000); + seconds = parseInt(remainder / 1000, 10); + scope.time_remaining = days + ' days ' + ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + + ('0' + seconds).slice(-2); + } + + if (parseInt(scope.free_instances) <= 0) { + scope.free_instances_class = 'field-failure'; + } else { + scope.free_instances_class = 'field-success'; + } + + license = data.license_info; + if (license.valid_key !== undefined && !license.valid_key) { + scope.license_status = 'Invalid'; + scope.status_color = 'license-invalid'; + } else if (license.demo !== undefined && license.demo) { + scope.license_status = 'Demo'; + scope.status_color = 'license-demo'; + } else if (license.date_expired !== undefined && license.date_expired) { + scope.license_status = 'Expired'; + scope.status_color = 'license-expired'; + } else if (license.date_warning !== undefined && license.date_warning) { + scope.license_status = 'Expiration Warning'; + scope.status_color = 'license-warning'; + } else if (license.free_instances !== undefined && parseInt(license.free_instances) <= 0) { + scope.license_status = 'No available managed hosts'; + scope.status_color = 'license-invalid'; + } else { + scope.license_status = 'Valid'; + scope.status_color = 'license-valid'; + } + + }) + .error(function (data, status) { + ProcessErrors($rootScope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to retrieve license. GET status: ' + status + }); + }); + }; + } + ]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/list-generator.js b/awx/ui/static/lib/ansible/list-generator.js index da7d625966..4ba4d9fa7a 100644 --- a/awx/ui/static/lib/ansible/list-generator.js +++ b/awx/ui/static/lib/ansible/list-generator.js @@ -1,7 +1,7 @@ /********************************************* * Copyright (c) 2014 AnsibleWorks, Inc. * - * ListGenerator + * ListGenerator * Pass in a list definition from ListDefinitions and out pops an html template. * Use inject method to generate the html and inject into the current view. * @@ -10,412 +10,439 @@ 'use strict'; angular.module('ListGenerator', ['GeneratorHelpers']) - .factory('GenerateList', [ '$location', '$compile', '$rootScope', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', + .factory('GenerateList', ['$location', '$compile', '$rootScope', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column', 'DropDown', 'NavigationLink', 'Button', 'SelectIcon', 'Breadcrumbs', -function($location, $compile, $rootScope, SearchWidget, PaginateWidget, Attr, Icon, Column, DropDown, NavigationLink, Button, SelectIcon, - Breadcrumbs) { - return { - - setList: function(list) { - this.list = list; - }, - - attr: Attr, + function ($location, $compile, $rootScope, SearchWidget, PaginateWidget, Attr, Icon, Column, DropDown, NavigationLink, Button, SelectIcon, + Breadcrumbs) { + return { - icon: Icon, + setList: function (list) { + this.list = list; + }, - has: function(key) { - return (this.form[key] && this.form[key] !== null && this.form[key] !== undefined) ? true : false; - }, + attr: Attr, - hide: function() { - $('#lookup-modal').modal('hide'); - }, + icon: Icon, - button: Button, + has: function (key) { + return (this.form[key] && this.form[key] !== null && this.form[key] !== undefined) ? true : false; + }, - inject: function(list, options) { - // options.mode = one of edit, select or lookup - // - // Modes edit and select will inject the list as html into element #htmlTemplate. - // 'lookup' mode injects the list html into #lookup-modal-body. - // - // For options.mode == 'lookup', include the following: - // - // hdr: - // - // Inject into a custom element using options.id: <'.selector'> - // Control breadcrumb creation with options.breadCrumbs: - // - var element; + hide: function () { + $('#lookup-modal').modal('hide'); + }, - if (options.mode === 'lookup') { - element = angular.element(document.getElementById('lookup-modal-body')); - } - else if (options.id) { - element = angular.element(document.getElementById(options.id)); - } - else { - element = angular.element(document.getElementById('htmlTemplate')); - } - this.setList(list); - element.html(this.build(options)); // Inject the html - if (options.prepend) { // Add any extra HTML passed in options - element.prepend(options.prepend); - } - if (options.append) { - element.append(options.prepend); - } - - if (options.scope) { - this.scope = options.scope; - } - else { - this.scope = element.scope(); // Set scope specific to the element we're compiling, avoids circular reference - } // From here use 'scope' to manipulate the form, as the form is not in '$scope' - - $compile(element)(this.scope); + button: Button, - // Reset the scope to prevent displaying old data from our last visit to this list - this.scope[list.name] = null; - this.scope[list.iterator] = null; + inject: function (list, options) { + // options.mode = one of edit, select or lookup + // + // Modes edit and select will inject the list as html into element #htmlTemplate. + // 'lookup' mode injects the list html into #lookup-modal-body. + // + // For options.mode == 'lookup', include the following: + // + // hdr: + // + // Inject into a custom element using options.id: <'.selector'> + // Control breadcrumb creation with options.breadCrumbs: + // + var element; - // Remove any lingering tooltip and popover
        elements - $('.tooltip').each( function(index) { - $(this).remove(); - }); - - $('.popover').each(function(index) { - // remove lingering popover
        . Seems to be a bug in TB3 RC1 - $(this).remove(); - }); - $(window).unbind('resize'); - - try { - $('#help-modal').empty().dialog('destroy'); - } - catch(e) { - //ignore any errors should the dialog not be initialized - } - - if (options.mode === 'lookup') { - // options should include {hdr: , action: } - this.scope.formModalActionDisabled = false; - this.scope.lookupHeader = options.hdr; - $('#lookup-modal').modal({ backdrop: 'static', keyboard: true }); - $('#lookup-modal').unbind('hidden.bs.modal'); - $(document).bind('keydown', function(e) { - if (e.keyCode === 27) { - $('#lookup-modal').modal('hide'); + if (options.mode === 'lookup') { + element = angular.element(document.getElementById('lookup-modal-body')); + } else if (options.id) { + element = angular.element(document.getElementById(options.id)); + } else { + element = angular.element(document.getElementById('htmlTemplate')); + } + this.setList(list); + element.html(this.build(options)); // Inject the html + if (options.prepend) { // Add any extra HTML passed in options + element.prepend(options.prepend); + } + if (options.append) { + element.append(options.prepend); } - }); - } - - return this.scope; - }, - build: function(options) { - // - // Generate HTML. Do NOT call this function directly. Called by inject(). Returns an HTML - // string to be injected into the current view. - // - var html = ''; - var list = this.list; + if (options.scope) { + this.scope = options.scope; + } else { + this.scope = element.scope(); // Set scope specific to the element we're compiling, avoids circular reference + } // From here use 'scope' to manipulate the form, as the form is not in '$scope' - if (options.activityStream) { - // Breadcrumbs for activity stream widget - // Make the links clickable using ng-click function so we can first remove the stream widget - // before navigation - html += "
        \n"; - html += "
          \n"; - html += "
        • {{ crumb.title }}
        • \n"; - html += "
        • "; - html += list.editTitle; - html += "
        • \n
        \n
        \n"; - } - else if (options.mode != 'lookup' && (options.breadCrumbs == undefined || options.breadCrumbs == true)) { - //Breadcrumbs - html += Breadcrumbs({ list: list, mode: options.mode }); - } - - if (options.mode == 'edit' && list.editInstructions) { - html += "
        \n"; - html += "\n"; - html += "Hint: " + list.editInstructions + "\n"; - html += "
        \n"; - } - - if (options.mode != 'lookup' && (list.well == undefined || list.well == true)) { - html += "
        \n"; - } - - if (options.activityStream) { - // Add a title row - html += "
        \n"; - html += "
        \n"; - html += "
        {{ streamTitle }}
        \n"; - html += "
        \n"; - html += "
        \n"; - } + $compile(element)(this.scope); - html += "
        \n"; - - if (list.name != 'groups') { - if (options.searchSize) { - html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: options.searchSize, - searchWidgets: list.searchWidgets }); - } - else if (options.mode == 'summary') { - html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-6' }); - } - else if (options.mode == 'lookup' || options.id != undefined) { - html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' }); - } - else { - html += SearchWidget({ iterator: list.iterator, template: list, mini: true }); - } - } + // Reset the scope to prevent displaying old data from our last visit to this list + this.scope[list.name] = null; + this.scope[list.iterator] = null; - if (options.mode != 'lookup') { - //actions - var base = $location.path().replace(/^\//,'').split('/')[0]; - html += "
        \n"; - - html += "
        \n"; - - // Add toolbar buttons or 'actions' - for (var action in list.actions) { - if (list.actions[action].mode == 'all' || list.actions[action].mode == options.mode) { - if ( (list.actions[action].basePaths == undefined) || - (list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1) ) { - html += this.button({ btn: list.actions[action], action: action, toolbar: true }); - } - } - } + // Remove any lingering tooltip and popover
        elements + $('.tooltip').each(function() { + $(this).remove(); + }); - //select instructions - if (options.mode == 'select' && list.selectInstructions) { - var btn = { - awPopOver: list.selectInstructions, - dataPlacement: 'top', - dataContainer: 'body', - 'class': 'btn-xs btn-help', - awToolTip: 'Click for help', - dataTitle: 'Help', - iconSize: 'fa-lg' - }; - //html += this.button(btn, 'select'); - html += this.button({ btn: btn, action: 'help', toolbar: true }); - } + $('.popover').each(function() { + // remove lingering popover
        . Seems to be a bug in TB3 RC1 + $(this).remove(); + }); + $(window).unbind('resize'); - html += "
        \n"; - html += "
        \n"; - } - else { - //lookup - html += "
        \n"; - } + try { + $('#help-modal').empty().dialog('destroy'); + } catch (e) { + //ignore any errors should the dialog not be initialized + } - html += "
        \n"; - - // Add a title and optionally a close button (used on Inventory->Groups) - if (options.mode !== 'lookup' && list.showTitle) { - html += "
        "; - html += (options.mode == 'edit' || options.mode == 'summary') ? list.editTitle : list.addTitle; - html += "
        \n"; - } + if (options.mode === 'lookup') { + // options should include {hdr: , action: } + this.scope.formModalActionDisabled = false; + this.scope.lookupHeader = options.hdr; + $('#lookup-modal').modal({ + backdrop: 'static', + keyboard: true + }); + $('#lookup-modal').unbind('hidden.bs.modal'); + $(document).bind('keydown', function (e) { + if (e.keyCode === 27) { + $('#lookup-modal').modal('hide'); + } + }); + } - // table header row - html += "#\n"; - } - for (var fld in list.fields) { - if ( (list.fields[fld].searchOnly == undefined || list.fields[fld].searchOnly == false) && - !(options.mode == 'lookup' && list.fields[fld].excludeModal !== undefined && list.fields[fld].excludeModal == true) ) { - html += "\n"; - } - } - if (options.mode == 'select' || options.mode == 'lookup') { - html += ""; - } - else if (options.mode == 'edit' && list.fieldActions) { - html += "\n"; - } - html += "\n"; - html += "\n"; - - // table body - html += "\n"; - html += "{{ $index + ((" + list.iterator + "_page - 1) * " + list.iterator + "_page_size) + 1 }}.\n"; - } - var cnt = 2; - var base = (list.base) ? list.base : list.name; - base = base.replace(/^\//,''); - for (fld in list.fields) { - cnt++; - if ( (list.fields[fld].searchOnly == undefined || list.fields[fld].searchOnly == false) && - !(options.mode == 'lookup' && list.fields[fld].excludeModal !== undefined && list.fields[fld].excludeModal == true) ) { - html += Column({ list: list, fld: fld, options: options, base: base }); - } - } - - if (options.mode == 'select' || options.mode == 'lookup') { - html += ""; - } - else if ((options.mode == 'edit' || options.mode == 'summary') && list.fieldActions) { - - // Row level actions - - html += ""; - } - html += "\n"; - - // Message for when a collection is empty - html += "\n"; - html += "\n"; - html += "\n"; - - // Message for loading - html += "\n"; - html += "\n"; - html += "\n"; - - // End List - html += "\n"; - html += "
        \n"; + html += "
          \n"; + html += "
        • {{ crumb.title }}
        • \n"; + html += "
        • "; + html += list.editTitle; + html += "
        • \n
        \n\n"; + } else if (options.mode !== 'lookup' && (options.breadCrumbs === undefined || options.breadCrumbs)) { + //Breadcrumbs + html += Breadcrumbs({ + list: list, + mode: options.mode + }); + } + + if (options.mode === 'edit' && list.editInstructions) { + html += "
        \n"; + html += "\n"; + html += "Hint: " + list.editInstructions + "\n"; + html += "
        \n"; + } + + if (options.mode !== 'lookup' && (list.well === undefined || list.well)) { + html += "
        \n"; + } + + if (options.activityStream) { + // Add a title row + html += "
        \n"; + html += "
        \n"; + html += "
        {{ streamTitle }}
        \n"; + html += "
        \n"; + html += "
        \n"; + } + + html += "
        \n"; + + if (list.name !== 'groups') { + if (options.searchSize) { + html += SearchWidget({ + iterator: list.iterator, + template: list, + mini: true, + size: options.searchSize, + searchWidgets: list.searchWidgets + }); + } else if (options.mode === 'summary') { + html += SearchWidget({ + iterator: list.iterator, + template: list, + mini: true, + size: 'col-lg-6' + }); + } else if (options.mode === 'lookup' || options.id !== undefined) { + html += SearchWidget({ + iterator: list.iterator, + template: list, + mini: true, + size: 'col-lg-8' + }); + } else { + html += SearchWidget({ + iterator: list.iterator, + template: list, + mini: true + }); } } - else { - html += "fa-sort"; - } - html += "\">"; + + if (options.mode !== 'lookup') { + //actions + base = $location.path().replace(/^\//, '').split('/')[0]; + html += "
        \n"; + + html += "
        \n"; + + // Add toolbar buttons or 'actions' + for (action in list.actions) { + if (list.actions[action].mode === 'all' || list.actions[action].mode === options.mode) { + if ((list.actions[action].basePaths === undefined) || + (list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1)) { + html += this.button({ + btn: list.actions[action], + action: action, + toolbar: true + }); + } + } + } + + //select instructions + if (options.mode === 'select' && list.selectInstructions) { + btn = { + awPopOver: list.selectInstructions, + dataPlacement: 'top', + dataContainer: 'body', + 'class': 'btn-xs btn-help', + awToolTip: 'Click for help', + dataTitle: 'Help', + iconSize: 'fa-lg' + }; + //html += this.button(btn, 'select'); + html += this.button({ + btn: btn, + action: 'help', + toolbar: true + }); + } + + html += "
        \n"; + html += "
        \n"; + } else { + //lookup + html += "
        \n"; + } + + html += "
        \n"; + + // Add a title and optionally a close button (used on Inventory->Groups) + if (options.mode !== 'lookup' && list.showTitle) { + html += "
        "; + html += (options.mode === 'edit' || options.mode === 'summary') ? list.editTitle : list.addTitle; + html += "
        \n"; + } + + // table header row + html += "#\n"; + } + for (fld in list.fields) { + if ((list.fields[fld].searchOnly === undefined || list.fields[fld].searchOnly === false) && + !(options.mode === 'lookup' && list.fields[fld].excludeModal !== undefined && list.fields[fld].excludeModal === true)) { + html += "\n"; + } + } + if (options.mode === 'select' || options.mode === 'lookup') { + html += ""; + } else if (options.mode === 'edit' && list.fieldActions) { + html += "\n"; + } + html += "\n"; + html += "\n"; + + // table body + html += "\n"; + html += "{{ $index + ((" + list.iterator + "_page - 1) * " + list.iterator + "_page_size) + 1 }}.\n"; + } + cnt = 2; + base = (list.base) ? list.base : list.name; + base = base.replace(/^\//, ''); + for (fld in list.fields) { + cnt++; + if ((list.fields[fld].searchOnly === undefined || list.fields[fld].searchOnly === false) && + !(options.mode === 'lookup' && list.fields[fld].excludeModal !== undefined && + list.fields[fld].excludeModal === true)) { + html += Column({ + list: list, + fld: fld, + options: options, + base: base + }); + } + } + + if (options.mode === 'select' || options.mode === 'lookup') { + html += ""; + } else if ((options.mode === 'edit' || options.mode === 'summary') && list.fieldActions) { + + // Row level actions + + html += ""; + } + html += "\n"; + + // Message for when a collection is empty + html += "\n"; + html += "\n"; + html += "\n"; + + // Message for loading + html += "\n"; + html += "\n"; + html += "\n"; + + // End List + html += "\n"; + html += "
        "; + } + html += "SelectActions
        "; + + for (field_action in list.fieldActions) { + if (field_action !== 'columnClass') { + if (list.fieldActions[field_action].type && list.fieldActions[field_action].type === 'DropDown') { + html += DropDown({ + list: list, + fld: field_action, + options: options, + base: base, + type: 'fieldActions', + td: false + }); + } else { + fAction = list.fieldActions[field_action]; + html += ""; + } else { + html += SelectIcon({ + action: field_action + }); + } + html += (fAction.label) ? " " + list.fieldActions[field_action].label : ""; + html += ""; + } + } + } + html += "
        No records matched your search.
        Loading...
        \n"; + + if (options.mode === 'select' && (options.selectButton === undefined || options.selectButton)) { + html += "
        \n"; + html += " \n"; + html += "
        \n"; + } + + if (options.mode !== 'lookup' && (list.well === undefined || list.well === true)) { + html += "
        \n"; //well + } + + if (list.name !== 'groups') { + if (options.mode === 'lookup' || (options.id && options.id === "form-modal-body")) { + html += PaginateWidget({ + set: list.name, + iterator: list.iterator + }); + } else { + html += PaginateWidget({ + set: list.name, + iterator: list.iterator + }); + } + } + + return html; } - html += "
        SelectActions
        "; - - var field_action, fAction, itm; - - for (field_action in list.fieldActions) { - if (field_action !== 'columnClass') { - if (list.fieldActions[field_action].type && list.fieldActions[field_action].type == 'DropDown') { - html += DropDown({ - list: list, - fld: field_action, - options: options, - base: base, - type: 'fieldActions', - td: false - }); - } - else { - fAction = list.fieldActions[field_action]; - html += ""; - } - else { - html += SelectIcon({ action: field_action }); - } - html += (fAction.label) ? " " + list.fieldActions[field_action]['label'] : ""; - html += ""; - } - } - } - html += "
        No records matched your search.
        Loading...
        \n"; - - if (options.mode == 'select' && (options.selectButton == undefined || options.selectButton == true)) { - html += "
        \n"; - html += " \n"; - html += "
        \n"; - } - - if (options.mode != 'lookup' && (list.well == undefined || list.well == true)) { - html += "
        \n"; //well - } - - if (list.name !== 'groups') { - if ( options.mode == 'lookup' || (options.id && options.id == "form-modal-body") ) { - html += PaginateWidget({ set: list.name, iterator: list.iterator }); - } - else { - html += PaginateWidget({ set: list.name, iterator: list.iterator }); - } - } - - return html; - - } - -}}]); \ No newline at end of file + }; + } + ]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/prompt-dialog.js b/awx/ui/static/lib/ansible/prompt-dialog.js index f5891796c0..c4a11559d5 100644 --- a/awx/ui/static/lib/ansible/prompt-dialog.js +++ b/awx/ui/static/lib/ansible/prompt-dialog.js @@ -2,12 +2,12 @@ * Copyright (c) 2014 AnsibleWorks, Inc. * * PromptDialog - * Prompt the user with a Yes/No dialog to confirm an action such + * Prompt the user with a Yes/No dialog to confirm an action such * as Delete. Assumes a hidden dialog already exists in $scope. - * See example at bottom. If user responds with Yes, execute action + * See example at bottom. If user responds with Yes, execute action * parameter. * - * params: { hdr: 'header msg', + * params: { hdr: 'header msg', * body: 'body text/html', * class: 'btn-class for Yes button', --defaults to btn-danger * action: function() {} --action to take, if use clicks Yes @@ -17,25 +17,26 @@ 'use strict'; angular.module('PromptDialog', ['Utilities']) - .factory('Prompt', ['$rootScope', '$compile', 'Alert', function($rootScope, $compile, Alert) { - return function(params) { - - var dialog = angular.element(document.getElementById('prompt-modal')); - var scope = dialog.scope(); - - scope.promptHeader = params.hdr; - scope.promptBody = params.body; - scope.promptAction = params.action; - - var cls = (params['class'] == null || params['class'] == undefined) ? 'btn-danger' : params['class']; - - $('#prompt_action_btn').removeClass(cls).addClass(cls); - - $(dialog).modal({ - backdrop: 'static', - keyboard: true, - show: true - }); + .factory('Prompt', [ + function () { + return function (params) { + + var dialog = angular.element(document.getElementById('prompt-modal')), + scope = dialog.scope(), cls; + + scope.promptHeader = params.hdr; + scope.promptBody = params.body; + scope.promptAction = params.action; + + cls = (params['class'] === null || params['class'] === undefined) ? 'btn-danger' : params['class']; + + $('#prompt_action_btn').removeClass(cls).addClass(cls); + + $(dialog).modal({ + backdrop: 'static', + keyboard: true, + show: true + }); + }; } - }]); - \ No newline at end of file + ]); \ No newline at end of file diff --git a/awx/ui/static/lib/ansible/pwdmeter.js b/awx/ui/static/lib/ansible/pwdmeter.js index 535b53d587..b87818f176 100644 --- a/awx/ui/static/lib/ansible/pwdmeter.js +++ b/awx/ui/static/lib/ansible/pwdmeter.js @@ -22,205 +22,294 @@ ** 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** -** CLH 9/5/13 - Set required strength in config.js +** CLH 09/05/13 - Set required strength in config.js +** 02/10/14 - Applied jsHint */ -String.prototype.strReverse = function() { - var newstring = ""; - for (var s=0; s < this.length; s++) { - newstring = this.charAt(s) + newstring; - } - return newstring; +/*jshint eqeqeq:false, unused:false */ + +String.prototype.strReverse = function () { + var newstring = "", s; + for (s = 0; s < this.length; s++) { + newstring = this.charAt(s) + newstring; + } + return newstring; }; var nScore = 0; + function chkPass(pwd) { - // Simultaneous variable declaration and value assignment aren't supported in IE apparently - // so I'm forced to assign the same value individually per var to support a crappy browser *sigh* - var nLength=0, nAlphaUC=0, nAlphaLC=0, nNumber=0, nSymbol=0, nMidChar=0, nRequirements=0, - nAlphasOnly=0, nNumbersOnly=0, nUnqChar=0, nRepChar=0, nRepInc=0, nConsecAlphaUC=0, nConsecAlphaLC=0, - nConsecNumber=0, nConsecSymbol=0, nConsecCharType=0, nSeqAlpha=0, nSeqNumber=0, nSeqSymbol=0, - nSeqChar=0, nReqChar=0, nMultConsecCharType=0; - var nMultRepChar=1, nMultConsecSymbol=1; - var nMultMidChar=2, nMultRequirements=2, nMultConsecAlphaUC=2, nMultConsecAlphaLC=2, nMultConsecNumber=2; - var nReqCharType=3, nMultAlphaUC=3, nMultAlphaLC=3, nMultSeqAlpha=3, nMultSeqNumber=3, nMultSeqSymbol=3; - var nMultLength=4, nMultNumber=4; - var nMultSymbol=6; - var nTmpAlphaUC="", nTmpAlphaLC="", nTmpNumber="", nTmpSymbol=""; - var sAlphaUC="0", sAlphaLC="0", sNumber="0", sSymbol="0", sMidChar="0", sRequirements="0", - sAlphasOnly="0", sNumbersOnly="0", sRepChar="0", sConsecAlphaUC="0", sConsecAlphaLC="0", - sConsecNumber="0", sSeqAlpha="0", sSeqNumber="0", sSeqSymbol="0"; - var sAlphas = "abcdefghijklmnopqrstuvwxyz"; - var sNumerics = "01234567890"; - var sSymbols = ")_!@#$%^&*()"; - var sComplexity = "Too Short"; - var sStandards = "Below"; - var nMinPwdLen = 8; - if (document.all) { var nd = 0; } else { var nd = 1; } - if (pwd) { - nScore = parseInt(pwd.length * nMultLength); - nLength = pwd.length; - var arrPwd = pwd.replace(/\s+/g,"").split(/\s*/); - var arrPwdLen = arrPwd.length; - - /* Loop through password to check for Symbol, Numeric, Lowercase and Uppercase pattern matches */ - for (var a=0; a < arrPwdLen; a++) { - if (arrPwd[a].match(/[A-Z]/g)) { - if (nTmpAlphaUC !== "") { if ((nTmpAlphaUC + 1) == a) { nConsecAlphaUC++; nConsecCharType++; } } - nTmpAlphaUC = a; - nAlphaUC++; - } - else if (arrPwd[a].match(/[a-z]/g)) { - if (nTmpAlphaLC !== "") { if ((nTmpAlphaLC + 1) == a) { nConsecAlphaLC++; nConsecCharType++; } } - nTmpAlphaLC = a; - nAlphaLC++; - } - else if (arrPwd[a].match(/[0-9]/g)) { - if (a > 0 && a < (arrPwdLen - 1)) { nMidChar++; } - if (nTmpNumber !== "") { if ((nTmpNumber + 1) == a) { nConsecNumber++; nConsecCharType++; } } - nTmpNumber = a; - nNumber++; - } - else if (arrPwd[a].match(/[^a-zA-Z0-9_]/g)) { - if (a > 0 && a < (arrPwdLen - 1)) { nMidChar++; } - if (nTmpSymbol !== "") { if ((nTmpSymbol + 1) == a) { nConsecSymbol++; nConsecCharType++; } } - nTmpSymbol = a; - nSymbol++; - } - /* Internal loop through password to check for repeat characters */ - var bCharExists = false; - for (var b=0; b < arrPwdLen; b++) { - if (arrPwd[a] == arrPwd[b] && a != b) { /* repeat character exists */ - bCharExists = true; - /* + // Simultaneous variable declaration and value assignment aren't supported in IE apparently + // so I'm forced to assign the same value individually per var to support a crappy browser *sigh* + var nLength = 0, + nAlphaUC = 0, + nAlphaLC = 0, + nNumber = 0, + nSymbol = 0, + nMidChar = 0, + nRequirements = 0, + nAlphasOnly = 0, + nNumbersOnly = 0, + nUnqChar = 0, + nRepChar = 0, + nRepInc = 0, + nConsecAlphaUC = 0, + nConsecAlphaLC = 0, + nConsecNumber = 0, + nConsecSymbol = 0, + nConsecCharType = 0, + nSeqAlpha = 0, + nSeqNumber = 0, + nSeqSymbol = 0, + nSeqChar = 0, + nReqChar = 0, + nMultConsecCharType = 0, + nMultRepChar = 1, + nMultConsecSymbol = 1, + nMultMidChar = 2, + nMultRequirements = 2, + nMultConsecAlphaUC = 2, + nMultConsecAlphaLC = 2, + nMultConsecNumber = 2, + nReqCharType = 3, + nMultAlphaUC = 3, + nMultAlphaLC = 3, + nMultSeqAlpha = 3, + nMultSeqNumber = 3, + nMultSeqSymbol = 3, + nMultLength = 4, + nMultNumber = 4, + nMultSymbol = 6, + nTmpAlphaUC = "", + nTmpAlphaLC = "", + nTmpNumber = "", + nTmpSymbol = "", + sAlphaUC = "0", + sAlphaLC = "0", + sNumber = "0", + sSymbol = "0", + sMidChar = "0", + sRequirements = "0", + sAlphasOnly = "0", + sNumbersOnly = "0", + sRepChar = "0", + sConsecAlphaUC = "0", + sConsecAlphaLC = "0", + sConsecNumber = "0", + sSeqAlpha = "0", + sSeqNumber = "0", + sSeqSymbol = "0", + sAlphas = "abcdefghijklmnopqrstuvwxyz", + sNumerics = "01234567890", + sSymbols = ")_!@#$%^&*()", + sComplexity = "Too Short", + sStandards = "Below", + nMinPwdLen = 8, + a, nd, arrPwd, arrPwdLen,bCharExists,b,s,sFwd,sRev,progbar,required_strength,warning_level; + + if (document.all) { + nd = 0; + } else { + nd = 1; + } + if (pwd) { + nScore = parseInt(pwd.length * nMultLength); + nLength = pwd.length; + arrPwd = pwd.replace(/\s+/g, "").split(/\s*/); + arrPwdLen = arrPwd.length; + + /* Loop through password to check for Symbol, Numeric, Lowercase and Uppercase pattern matches */ + for (a = 0; a < arrPwdLen; a++) { + if (arrPwd[a].match(/[A-Z]/g)) { + if (nTmpAlphaUC !== "") { + if ((nTmpAlphaUC + 1) == a) { + nConsecAlphaUC++; + nConsecCharType++; + } + } + nTmpAlphaUC = a; + nAlphaUC++; + } else if (arrPwd[a].match(/[a-z]/g)) { + if (nTmpAlphaLC !== "") { + if ((nTmpAlphaLC + 1) == a) { + nConsecAlphaLC++; + nConsecCharType++; + } + } + nTmpAlphaLC = a; + nAlphaLC++; + } else if (arrPwd[a].match(/[0-9]/g)) { + if (a > 0 && a < (arrPwdLen - 1)) { + nMidChar++; + } + if (nTmpNumber !== "") { + if ((nTmpNumber + 1) == a) { + nConsecNumber++; + nConsecCharType++; + } + } + nTmpNumber = a; + nNumber++; + } else if (arrPwd[a].match(/[^a-zA-Z0-9_]/g)) { + if (a > 0 && a < (arrPwdLen - 1)) { + nMidChar++; + } + if (nTmpSymbol !== "") { + if ((nTmpSymbol + 1) == a) { + nConsecSymbol++; + nConsecCharType++; + } + } + nTmpSymbol = a; + nSymbol++; + } + + /* Internal loop through password to check for repeat characters */ + bCharExists = false; + for (b = 0; b < arrPwdLen; b++) { + if (arrPwd[a] == arrPwd[b] && a != b) { /* repeat character exists */ + bCharExists = true; + /* Calculate icrement deduction based on proximity to identical characters Deduction is incremented each time a new match is discovered Deduction amount is based on total password length divided by the difference of distance between currently selected match */ - nRepInc += Math.abs(arrPwdLen/(b-a)); + nRepInc += Math.abs(arrPwdLen / (b - a)); + } } - } - if (bCharExists) { - nRepChar++; - nUnqChar = arrPwdLen-nRepChar; - nRepInc = (nUnqChar) ? Math.ceil(nRepInc/nUnqChar) : Math.ceil(nRepInc); - } - } - - /* Check for sequential alpha string patterns (forward and reverse) */ - for (var s=0; s < 23; s++) { - var sFwd = sAlphas.substring(s,parseInt(s+3)); - var sRev = sFwd.strReverse(); - if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { nSeqAlpha++; nSeqChar++;} - } - - /* Check for sequential numeric string patterns (forward and reverse) */ - for (var s=0; s < 8; s++) { - var sFwd = sNumerics.substring(s,parseInt(s+3)); - var sRev = sFwd.strReverse(); - if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { nSeqNumber++; nSeqChar++;} - } - - /* Check for sequential symbol string patterns (forward and reverse) */ - for (var s=0; s < 8; s++) { - var sFwd = sSymbols.substring(s,parseInt(s+3)); - var sRev = sFwd.strReverse(); - if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { nSeqSymbol++; nSeqChar++;} - } - - /* Modify overall score value based on usage vs requirements */ + if (bCharExists) { + nRepChar++; + nUnqChar = arrPwdLen - nRepChar; + nRepInc = (nUnqChar) ? Math.ceil(nRepInc / nUnqChar) : Math.ceil(nRepInc); + } + } - /* General point assignment */ - if (nAlphaUC > 0 && nAlphaUC < nLength) { - nScore = parseInt(nScore + ((nLength - nAlphaUC) * 2)); - sAlphaUC = "+ " + parseInt((nLength - nAlphaUC) * 2); - } - if (nAlphaLC > 0 && nAlphaLC < nLength) { - nScore = parseInt(nScore + ((nLength - nAlphaLC) * 2)); - sAlphaLC = "+ " + parseInt((nLength - nAlphaLC) * 2); - } - if (nNumber > 0 && nNumber < nLength) { - nScore = parseInt(nScore + (nNumber * nMultNumber)); - sNumber = "+ " + parseInt(nNumber * nMultNumber); - } - if (nSymbol > 0) { - nScore = parseInt(nScore + (nSymbol * nMultSymbol)); - sSymbol = "+ " + parseInt(nSymbol * nMultSymbol); - } - if (nMidChar > 0) { - nScore = parseInt(nScore + (nMidChar * nMultMidChar)); - sMidChar = "+ " + parseInt(nMidChar * nMultMidChar); - } + /* Check for sequential alpha string patterns (forward and reverse) */ + for (s = 0; s < 23; s++) { + sFwd = sAlphas.substring(s, parseInt(s + 3)); + sRev = sFwd.strReverse(); + if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { + nSeqAlpha++; + nSeqChar++; + } + } - /* Point deductions for poor practices */ - if ((nAlphaLC > 0 || nAlphaUC > 0) && nSymbol === 0 && nNumber === 0) { // Only Letters - nScore = parseInt(nScore - nLength); - nAlphasOnly = nLength; - sAlphasOnly = "- " + nLength; - } - if (nAlphaLC === 0 && nAlphaUC === 0 && nSymbol === 0 && nNumber > 0) { // Only Numbers - nScore = parseInt(nScore - nLength); - nNumbersOnly = nLength; - sNumbersOnly = "- " + nLength; - } - if (nRepChar > 0) { // Same character exists more than once - nScore = parseInt(nScore - nRepInc); - sRepChar = "- " + nRepInc; - } - if (nConsecAlphaUC > 0) { // Consecutive Uppercase Letters exist - nScore = parseInt(nScore - (nConsecAlphaUC * nMultConsecAlphaUC)); - sConsecAlphaUC = "- " + parseInt(nConsecAlphaUC * nMultConsecAlphaUC); - } - if (nConsecAlphaLC > 0) { // Consecutive Lowercase Letters exist - nScore = parseInt(nScore - (nConsecAlphaLC * nMultConsecAlphaLC)); - sConsecAlphaLC = "- " + parseInt(nConsecAlphaLC * nMultConsecAlphaLC); - } - if (nConsecNumber > 0) { // Consecutive Numbers exist - nScore = parseInt(nScore - (nConsecNumber * nMultConsecNumber)); - sConsecNumber = "- " + parseInt(nConsecNumber * nMultConsecNumber); - } - if (nSeqAlpha > 0) { // Sequential alpha strings exist (3 characters or more) - nScore = parseInt(nScore - (nSeqAlpha * nMultSeqAlpha)); - sSeqAlpha = "- " + parseInt(nSeqAlpha * nMultSeqAlpha); - } - if (nSeqNumber > 0) { // Sequential numeric strings exist (3 characters or more) - nScore = parseInt(nScore - (nSeqNumber * nMultSeqNumber)); - sSeqNumber = "- " + parseInt(nSeqNumber * nMultSeqNumber); - } - if (nSeqSymbol > 0) { // Sequential symbol strings exist (3 characters or more) - nScore = parseInt(nScore - (nSeqSymbol * nMultSeqSymbol)); - sSeqSymbol = "- " + parseInt(nSeqSymbol * nMultSeqSymbol); - } + /* Check for sequential numeric string patterns (forward and reverse) */ + for (s = 0; s < 8; s++) { + sFwd = sNumerics.substring(s, parseInt(s + 3)); + sRev = sFwd.strReverse(); + if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { + nSeqNumber++; + nSeqChar++; + } + } - /* Determine complexity based on overall score */ - if (nScore > 100) { nScore = 100; } else if (nScore < 0) { nScore = 0; } + /* Check for sequential symbol string patterns (forward and reverse) */ + for (s = 0; s < 8; s++) { + sFwd = sSymbols.substring(s, parseInt(s + 3)); + sRev = sFwd.strReverse(); + if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) { + nSeqSymbol++; + nSeqChar++; + } + } - var progbar = $("#progbar"); - var required_strength = $AnsibleConfig.password_strength; - var warning_level = ($AnsibleConfig.password_strength - 15 < 0) ? 0 : $AnsibleConfig.password_strength - 15; + /* Modify overall score value based on usage vs requirements */ - progbar.css("width", nScore + '%'); + /* General point assignment */ + if (nAlphaUC > 0 && nAlphaUC < nLength) { + nScore = parseInt(nScore + ((nLength - nAlphaUC) * 2)); + sAlphaUC = "+ " + parseInt((nLength - nAlphaUC) * 2); + } + if (nAlphaLC > 0 && nAlphaLC < nLength) { + nScore = parseInt(nScore + ((nLength - nAlphaLC) * 2)); + sAlphaLC = "+ " + parseInt((nLength - nAlphaLC) * 2); + } + if (nNumber > 0 && nNumber < nLength) { + nScore = parseInt(nScore + (nNumber * nMultNumber)); + sNumber = "+ " + parseInt(nNumber * nMultNumber); + } + if (nSymbol > 0) { + nScore = parseInt(nScore + (nSymbol * nMultSymbol)); + sSymbol = "+ " + parseInt(nSymbol * nMultSymbol); + } + if (nMidChar > 0) { + nScore = parseInt(nScore + (nMidChar * nMultMidChar)); + sMidChar = "+ " + parseInt(nMidChar * nMultMidChar); + } - if (nScore >= 0 && nScore <= warning_level) { - sComplexity = 'Weak'; - progbar.addClass('progress-bar-danger') - progbar.removeClass('progress-bar-success progress-bar-warning') - } else if (nScore > warning_level && nScore <= required_strength) { - sComplexity = 'Good'; - progbar.addClass('progress-bar-warning') - progbar.removeClass('progress-bar-success progress-bar-danger') - } else if (nScore > required_strength) { - sComplexity = "Strong"; - progbar.addClass('progress-bar-success') - progbar.removeClass('progress-bar-warning progress-bar-danger') - } - } - else { - /* no password, so reset the displays */ - var progbar = $("#progbar"); - progbar.css("width", '0%'); - progbar.removeClass('progress-bar-success progress-bar-warning') - } - return nScore; + /* Point deductions for poor practices */ + if ((nAlphaLC > 0 || nAlphaUC > 0) && nSymbol === 0 && nNumber === 0) { // Only Letters + nScore = parseInt(nScore - nLength); + nAlphasOnly = nLength; + sAlphasOnly = "- " + nLength; + } + if (nAlphaLC === 0 && nAlphaUC === 0 && nSymbol === 0 && nNumber > 0) { // Only Numbers + nScore = parseInt(nScore - nLength); + nNumbersOnly = nLength; + sNumbersOnly = "- " + nLength; + } + if (nRepChar > 0) { // Same character exists more than once + nScore = parseInt(nScore - nRepInc); + sRepChar = "- " + nRepInc; + } + if (nConsecAlphaUC > 0) { // Consecutive Uppercase Letters exist + nScore = parseInt(nScore - (nConsecAlphaUC * nMultConsecAlphaUC)); + sConsecAlphaUC = "- " + parseInt(nConsecAlphaUC * nMultConsecAlphaUC); + } + if (nConsecAlphaLC > 0) { // Consecutive Lowercase Letters exist + nScore = parseInt(nScore - (nConsecAlphaLC * nMultConsecAlphaLC)); + sConsecAlphaLC = "- " + parseInt(nConsecAlphaLC * nMultConsecAlphaLC); + } + if (nConsecNumber > 0) { // Consecutive Numbers exist + nScore = parseInt(nScore - (nConsecNumber * nMultConsecNumber)); + sConsecNumber = "- " + parseInt(nConsecNumber * nMultConsecNumber); + } + if (nSeqAlpha > 0) { // Sequential alpha strings exist (3 characters or more) + nScore = parseInt(nScore - (nSeqAlpha * nMultSeqAlpha)); + sSeqAlpha = "- " + parseInt(nSeqAlpha * nMultSeqAlpha); + } + if (nSeqNumber > 0) { // Sequential numeric strings exist (3 characters or more) + nScore = parseInt(nScore - (nSeqNumber * nMultSeqNumber)); + sSeqNumber = "- " + parseInt(nSeqNumber * nMultSeqNumber); + } + if (nSeqSymbol > 0) { // Sequential symbol strings exist (3 characters or more) + nScore = parseInt(nScore - (nSeqSymbol * nMultSeqSymbol)); + sSeqSymbol = "- " + parseInt(nSeqSymbol * nMultSeqSymbol); + } + + /* Determine complexity based on overall score */ + if (nScore > 100) { + nScore = 100; + } else if (nScore < 0) { + nScore = 0; + } + + progbar = $("#progbar"); + required_strength = $AnsibleConfig.password_strength; + warning_level = ($AnsibleConfig.password_strength - 15 < 0) ? 0 : $AnsibleConfig.password_strength - 15; + + progbar.css("width", nScore + '%'); + + if (nScore >= 0 && nScore <= warning_level) { + sComplexity = 'Weak'; + progbar.addClass('progress-bar-danger'); + progbar.removeClass('progress-bar-success progress-bar-warning'); + } else if (nScore > warning_level && nScore <= required_strength) { + sComplexity = 'Good'; + progbar.addClass('progress-bar-warning'); + progbar.removeClass('progress-bar-success progress-bar-danger'); + } else if (nScore > required_strength) { + sComplexity = "Strong"; + progbar.addClass('progress-bar-success'); + progbar.removeClass('progress-bar-warning progress-bar-danger'); + } + } else { + /* no password, so reset the displays */ + progbar = $("#progbar"); + progbar.css("width", '0%'); + progbar.removeClass('progress-bar-success progress-bar-warning'); + } + return nScore; } \ No newline at end of file diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html index 92f62a7fa0..85ae82c714 100644 --- a/awx/ui/templates/ui/index.html +++ b/awx/ui/templates/ui/index.html @@ -71,10 +71,11 @@ + - + @@ -123,7 +124,6 @@ - {% endif %} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..119076c330 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "name": "ansible-commander", + "version": "1.4.5", + "devDependencies": { + "grunt": "latest", + "grunt-contrib-jshint": "~0.8.0", + "grunt-contrib-uglify": "~0.3.1" + } +} From 3a5e2f4f1ef8b96cf5a5df061a52921228e8565e Mon Sep 17 00:00:00 2001 From: Chris Church Date: Tue, 11 Feb 2014 15:19:51 -0500 Subject: [PATCH 03/27] AC-996 Don't try to use admin template since admin is disabled. --- awx/main/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/awx/main/views.py b/awx/main/views.py index 331e56071a..3ab721ca13 100644 --- a/awx/main/views.py +++ b/awx/main/views.py @@ -2,6 +2,7 @@ # All Rights Reserved. # Django +from django.conf import settings from django.shortcuts import render from django.template import RequestContext from django.utils.safestring import mark_safe @@ -10,7 +11,7 @@ def handle_error(request, status=404, **kwargs): # FIXME: Should attempt to check HTTP Accept request header and return # plain JSON response instead of HTML (maybe only for /api/*). context = kwargs - if request.path.startswith('/admin/'): + if 'django.contrib.admin' in settings.INSTALLED_APPS and request.path.startswith('/admin/'): template_name = 'admin/error.html' else: # Return enough context to popuplate the base API template. From e81d02885f57ab4ed16d87d51181570c3e5c968f Mon Sep 17 00:00:00 2001 From: Chris Houseknecht Date: Wed, 12 Feb 2014 18:24:30 +0000 Subject: [PATCH 04/27] AC-1006 upgraded all js libraries to latest release. Fixed obvious broken things. Installed bower to make package installation/upgrade easier. Added less to Grunt build. --- .bowerrc | 3 + .gitignore | 2 +- Gruntfile.js | 22 +- awx/ui/static/css/bootstrap-theme.css | 384 - awx/ui/static/css/bootstrap-theme.min.css | 1 - awx/ui/static/css/bootstrap.css | 6805 ----- awx/ui/static/css/bootstrap.min.css | 9 - awx/ui/static/css/select2-bootstrap.css | 87 - awx/ui/static/css/select2-spinner.gif | Bin 1849 -> 0 bytes awx/ui/static/css/select2.css | 615 - awx/ui/static/css/select2.png | Bin 613 -> 0 bytes awx/ui/static/css/select2x2.png | Bin 845 -> 0 bytes awx/ui/static/js/app.js | 3 + awx/ui/static/js/awx-min.js | 50 + awx/ui/static/js/controllers/Admins.js | 32 +- awx/ui/static/js/controllers/Credentials.js | 389 +- awx/ui/static/js/controllers/Inventories.js | 278 +- awx/ui/static/js/controllers/JobEvents.js | 157 +- awx/ui/static/js/controllers/JobHosts.js | 78 +- awx/ui/static/js/controllers/JobTemplates.js | 333 +- awx/ui/static/js/controllers/Jobs.js | 268 +- awx/ui/static/js/controllers/Organizations.js | 177 +- awx/ui/static/js/controllers/Permissions.js | 146 +- awx/ui/static/js/controllers/Projects.js | 399 +- awx/ui/static/js/controllers/Teams.js | 143 +- awx/ui/static/js/controllers/Users.js | 218 +- awx/ui/static/js/forms/Organizations.js | 4 + awx/ui/static/js/forms/Projects.js | 12 +- awx/ui/static/js/forms/Teams.js | 4 +- awx/ui/static/js/forms/Users.js | 4 + awx/ui/static/js/helpers/Selection.js | 4 +- awx/ui/static/js/helpers/related-search.js | 30 +- awx/ui/static/js/lists/Credentials.js | 2 +- awx/ui/static/js/lists/Inventories.js | 2 +- awx/ui/static/js/lists/JobTemplates.js | 2 +- awx/ui/static/js/lists/Organizations.js | 4 +- awx/ui/static/js/lists/Permissions.js | 2 +- awx/ui/static/js/lists/Projects.js | 2 +- awx/ui/static/js/lists/Teams.js | 2 +- awx/ui/static/js/lists/Users.js | 2 +- awx/ui/static/js/widgets/Stream.js | 3 +- awx/ui/static/less/ansible-ui.less | 38 +- .../angular-1.2.9/angular-resource.min.js.map | 8 - .../lib/angular-1.2.9/angular-route.min.js | 14 - awx/ui/static/lib/angular-1.2.9/angular.js | 20560 ---------------- .../static/lib/angular-1.2.9/angular.min.js | 202 - .../lib/angular-1.2.9/angular.min.js.gzip | Bin 36880 -> 0 bytes .../lib/angular-1.2.9/angular.min.js.map | 8 - awx/ui/static/lib/angular-cookies/.bower.json | 19 + awx/ui/static/lib/angular-cookies/README.md | 54 + .../angular-cookies.js | 2 +- .../angular-cookies.min.js | 2 +- .../angular-cookies.min.js.map | 0 awx/ui/static/lib/angular-cookies/bower.json | 8 + awx/ui/static/lib/angular-md5/.bower.json | 45 + awx/ui/static/lib/angular-md5/Gruntfile.js | 129 + awx/ui/static/lib/angular-md5/README.md | 36 + awx/ui/static/lib/angular-md5/angular-md5.js | 200 + .../static/lib/angular-md5/angular-md5.min.js | 7 + .../lib/angular-md5/angular-md5.min.js.map | 1 + awx/ui/static/lib/angular-md5/bower.json | 34 + .../static/lib/angular-md5/example/index.html | 30 + .../lib/angular-md5/lib/filters/gravatar.js | 13 + .../static/lib/angular-md5/lib/filters/md5.js | 8 + awx/ui/static/lib/angular-md5/lib/index.js | 8 + .../lib/angular-md5/lib/services/md5.js | 215 + awx/ui/static/lib/angular-md5/package.json | 45 + .../static/lib/angular-resource/.bower.json | 19 + awx/ui/static/lib/angular-resource/README.md | 54 + .../angular-resource.js | 8 +- .../angular-resource.min.js | 8 +- .../angular-resource.min.js.map | 8 + awx/ui/static/lib/angular-resource/bower.json | 8 + awx/ui/static/lib/angular-route/.bower.json | 19 + awx/ui/static/lib/angular-route/README.md | 54 + .../angular-route.js | 29 +- .../lib/angular-route/angular-route.min.js | 14 + .../angular-route.min.js.map | 2 +- awx/ui/static/lib/angular-route/bower.json | 8 + .../static/lib/angular-sanitize/.bower.json | 19 + awx/ui/static/lib/angular-sanitize/README.md | 54 + .../angular-sanitize.js | 65 +- .../angular-sanitize.min.js | 2 +- .../angular-sanitize.min.js.map | 2 +- awx/ui/static/lib/angular-sanitize/bower.json | 8 + awx/ui/static/lib/angular/.bower.json | 17 + awx/ui/static/lib/angular/README.md | 48 + .../angular-csp.css | 0 awx/ui/static/lib/angular/angular.js | 15220 ++++++++---- awx/ui/static/lib/angular/angular.min.js | 369 +- awx/ui/static/lib/angular/angular.min.js.gzip | Bin 0 -> 37081 bytes awx/ui/static/lib/angular/angular.min.js.map | 8 + awx/ui/static/lib/angular/bower.json | 7 + awx/ui/static/lib/ansible/Utilities.js | 71 +- awx/ui/static/lib/ansible/form-generator.js | 53 +- .../static/lib/ansible/generator-helpers.js | 4 +- awx/ui/static/lib/ansible/list-generator.js | 41 +- .../lib/components-font-awesome/.bower.json | 21 + .../lib/components-font-awesome/.gitignore | 4 + .../lib/components-font-awesome/Makefile | 15 + .../lib/components-font-awesome/README.md | 24 + .../lib/components-font-awesome/bower.json | 10 + .../components-font-awesome/component.json | 20 + .../lib/components-font-awesome/composer.json | 26 + .../css/font-awesome.css | 0 .../css/font-awesome.min.css | 0 .../fonts/FontAwesome.otf | Bin .../fonts/fontawesome-webfont.eot | Bin .../fonts/fontawesome-webfont.svg | 0 .../fonts/fontawesome-webfont.ttf | Bin .../fonts/fontawesome-webfont.woff | Bin .../less/bootstrap.less | 84 + .../less/bordered-pulled.less | 16 + .../components-font-awesome/less/core.less | 12 + .../components-font-awesome/less/extras.less | 2 + .../less/fixed-width.less | 6 + .../less/font-awesome.less | 17 + .../components-font-awesome/less/icons.less | 412 + .../components-font-awesome/less/larger.less | 13 + .../components-font-awesome/less/list.less | 19 + .../components-font-awesome/less/mixins.less | 20 + .../components-font-awesome/less/path.less | 14 + .../less/rotated-flipped.less | 9 + .../less/spinning.less | 30 + .../components-font-awesome/less/stacked.less | 20 + .../less/variables.less | 381 + .../scss/_bootstrap.scss | 84 + .../scss/_bordered-pulled.scss | 16 + .../components-font-awesome/scss/_core.scss | 12 + .../components-font-awesome/scss/_extras.scss | 44 + .../scss/_fixed-width.scss | 6 + .../components-font-awesome/scss/_icons.scss | 412 + .../components-font-awesome/scss/_larger.scss | 13 + .../components-font-awesome/scss/_list.scss | 19 + .../components-font-awesome/scss/_mixins.scss | 20 + .../components-font-awesome/scss/_path.scss | 14 + .../scss/_rotated-flipped.scss | 9 + .../scss/_spinning.scss | 30 + .../scss/_stacked.scss | 20 + .../scss/_variables.scss | 381 + .../scss/font-awesome.scss | 17 + awx/ui/static/lib/jquery/.bower.json | 22 + awx/ui/static/lib/jquery/.gitignore | 1 + awx/ui/static/lib/jquery/README.md | 11 + awx/ui/static/lib/jquery/bower.json | 11 + awx/ui/static/lib/jquery/component.json | 15 + awx/ui/static/lib/jquery/composer.json | 36 + awx/ui/static/lib/jquery/jquery-migrate.js | 521 + .../static/lib/jquery/jquery-migrate.min.js | 2 + awx/ui/static/lib/jquery/jquery.js | 9111 +++++++ awx/ui/static/lib/jquery/jquery.min.js | 4 + awx/ui/static/lib/jquery/jquery.min.map | 1 + awx/ui/static/lib/jquery/package.json | 7 + awx/ui/static/lib/jqueryui/.bower.json | 21 + awx/ui/static/lib/jqueryui/.gitignore | 3 + awx/ui/static/lib/jqueryui/AUTHORS.txt | 233 + awx/ui/static/lib/jqueryui/MANIFEST | 452 + awx/ui/static/lib/jqueryui/MIT-LICENSE.txt | 26 + awx/ui/static/lib/jqueryui/README.md | 11 + awx/ui/static/lib/jqueryui/bower.json | 10 + awx/ui/static/lib/jqueryui/composer.json | 63 + awx/ui/static/lib/jqueryui/package.json | 66 + .../themes/base/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../base/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../base/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../base/images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../base/images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../base/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../lib/jqueryui/themes/base/jquery-ui.css | 1188 + .../themes/base/jquery.ui.accordion.css | 38 + .../jqueryui/themes/base/jquery.ui.all.css | 12 + .../themes/base/jquery.ui.autocomplete.css | 16 + .../jqueryui/themes/base/jquery.ui.base.css | 25 + .../jqueryui/themes/base/jquery.ui.button.css | 114 + .../jqueryui/themes/base/jquery.ui.core.css | 93 + .../themes/base/jquery.ui.datepicker.css | 178 + .../jqueryui/themes/base/jquery.ui.dialog.css | 69 + .../jqueryui/themes/base/jquery.ui.menu.css | 79 + .../themes/base/jquery.ui.progressbar.css | 28 + .../themes/base/jquery.ui.resizable.css | 78 + .../themes/base/jquery.ui.selectable.css | 15 + .../jqueryui/themes/base/jquery.ui.slider.css | 73 + .../themes/base/jquery.ui.spinner.css | 65 + .../jqueryui/themes/base/jquery.ui.tabs.css | 52 + .../jqueryui/themes/base/jquery.ui.theme.css | 406 + .../themes/base/jquery.ui.tooltip.css | 19 + .../base/minified/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../themes/base/minified/jquery-ui.min.css | 4 + .../base/minified/jquery.ui.accordion.min.css | 5 + .../minified/jquery.ui.autocomplete.min.css | 5 + .../base/minified/jquery.ui.button.min.css | 5 + .../base/minified/jquery.ui.core.min.css | 5 + .../minified/jquery.ui.datepicker.min.css | 5 + .../base/minified/jquery.ui.dialog.min.css | 5 + .../base/minified/jquery.ui.menu.min.css | 5 + .../minified/jquery.ui.progressbar.min.css | 5 + .../base/minified/jquery.ui.resizable.min.css | 5 + .../minified/jquery.ui.selectable.min.css | 5 + .../base/minified/jquery.ui.slider.min.css | 5 + .../base/minified/jquery.ui.spinner.min.css | 5 + .../base/minified/jquery.ui.tabs.min.css | 5 + .../base/minified/jquery.ui.theme.min.css | 5 + .../base/minified/jquery.ui.tooltip.min.css | 5 + .../black-tie/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-thick_8_333333_40x40.png | Bin 0 -> 312 bytes .../images/ui-bg_flat_65_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_glass_40_111111_1x400.png | Bin 0 -> 260 bytes .../images/ui-bg_glass_55_1c1c1c_1x400.png | Bin 0 -> 260 bytes .../ui-bg_highlight-hard_100_f9f9f9_1x100.png | Bin 0 -> 252 bytes .../ui-bg_highlight-hard_40_aaaaaa_1x100.png | Bin 0 -> 252 bytes .../ui-bg_highlight-soft_50_aaaaaa_1x100.png | Bin 0 -> 280 bytes .../ui-bg_inset-hard_45_cd0a0a_1x100.png | Bin 0 -> 324 bytes .../ui-bg_inset-hard_55_ffeb80_1x100.png | Bin 0 -> 309 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_4ca300_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_bbbbbb_256x240.png | Bin 0 -> 6991 bytes .../images/ui-icons_ededed_256x240.png | Bin 0 -> 6916 bytes .../images/ui-icons_ffcf29_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/black-tie/jquery-ui.css | 1177 + .../themes/black-tie/jquery-ui.min.css | 5 + .../themes/black-tie/jquery.ui.theme.css | 406 + .../blitzer/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-thick_75_f3d8d8_40x40.png | Bin 0 -> 413 bytes .../images/ui-bg_dots-small_65_a6a6a6_2x2.png | Bin 0 -> 207 bytes .../images/ui-bg_flat_0_333333_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_65_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_glass_55_fbf8ee_1x400.png | Bin 0 -> 340 bytes .../ui-bg_highlight-hard_100_eeeeee_1x100.png | Bin 0 -> 252 bytes .../ui-bg_highlight-hard_100_f6f6f6_1x100.png | Bin 0 -> 251 bytes .../ui-bg_highlight-soft_15_cc0000_1x100.png | Bin 0 -> 322 bytes .../images/ui-icons_004276_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cc0000_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../lib/jqueryui/themes/blitzer/jquery-ui.css | 1177 + .../jqueryui/themes/blitzer/jquery-ui.min.css | 5 + .../themes/blitzer/jquery.ui.theme.css | 406 + .../cupertino/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-thick_90_eeeeee_40x40.png | Bin 0 -> 312 bytes .../images/ui-bg_flat_15_cd0a0a_40x100.png | Bin 0 -> 206 bytes .../images/ui-bg_glass_100_e4f1fb_1x400.png | Bin 0 -> 350 bytes .../images/ui-bg_glass_50_3baae3_1x400.png | Bin 0 -> 336 bytes .../images/ui-bg_glass_80_d7ebf9_1x400.png | Bin 0 -> 346 bytes .../ui-bg_highlight-hard_100_f2f5f7_1x100.png | Bin 0 -> 332 bytes .../ui-bg_highlight-hard_70_000000_1x100.png | Bin 0 -> 249 bytes .../ui-bg_highlight-soft_100_deedf7_1x100.png | Bin 0 -> 387 bytes .../ui-bg_highlight-soft_25_ffef8f_1x100.png | Bin 0 -> 309 bytes .../images/ui-icons_2694e8_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_3d80b3_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_72a7cf_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/cupertino/jquery-ui.css | 1177 + .../themes/cupertino/jquery-ui.min.css | 5 + .../themes/cupertino/jquery.ui.theme.css | 406 + .../dark-hive/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_30_cccccc_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_50_5c5c5c_40x100.png | Bin 0 -> 230 bytes .../images/ui-bg_glass_40_ffc73d_1x400.png | Bin 0 -> 316 bytes .../ui-bg_highlight-hard_20_0972a5_1x100.png | Bin 0 -> 323 bytes .../ui-bg_highlight-soft_33_003147_1x100.png | Bin 0 -> 352 bytes .../ui-bg_highlight-soft_35_222222_1x100.png | Bin 0 -> 277 bytes .../ui-bg_highlight-soft_44_444444_1x100.png | Bin 0 -> 277 bytes .../ui-bg_highlight-soft_80_eeeeee_1x100.png | Bin 0 -> 276 bytes .../images/ui-bg_loop_25_000000_21x21.png | Bin 0 -> 285 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_4b8e0b_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_a83300_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cccccc_256x240.png | Bin 0 -> 6975 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/dark-hive/jquery-ui.css | 1177 + .../themes/dark-hive/jquery-ui.min.css | 5 + .../themes/dark-hive/jquery.ui.theme.css | 406 + .../dot-luv/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-thick_15_0b3e6f_40x40.png | Bin 0 -> 424 bytes .../ui-bg_dots-medium_30_0b58a2_4x4.png | Bin 0 -> 237 bytes .../images/ui-bg_dots-small_20_333333_2x2.png | Bin 0 -> 206 bytes .../images/ui-bg_dots-small_30_a32d00_2x2.png | Bin 0 -> 218 bytes .../images/ui-bg_dots-small_40_00498f_2x2.png | Bin 0 -> 224 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_40_292929_40x100.png | Bin 0 -> 230 bytes .../ui-bg_gloss-wave_20_111111_500x100.png | Bin 0 -> 3769 bytes .../images/ui-icons_00498f_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_98d2fb_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_9ccdfc_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../lib/jqueryui/themes/dot-luv/jquery-ui.css | 1177 + .../jqueryui/themes/dot-luv/jquery-ui.min.css | 5 + .../themes/dot-luv/jquery.ui.theme.css | 406 + .../eggplant/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_0_eeeeee_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_55_994d53_40x100.png | Bin 0 -> 206 bytes .../images/ui-bg_flat_55_fafafa_40x100.png | Bin 0 -> 230 bytes .../ui-bg_gloss-wave_30_3d3644_500x100.png | Bin 0 -> 5941 bytes .../ui-bg_highlight-soft_100_dcd9de_1x100.png | Bin 0 -> 342 bytes .../ui-bg_highlight-soft_100_eae6ea_1x100.png | Bin 0 -> 373 bytes .../ui-bg_highlight-soft_25_30273a_1x100.png | Bin 0 -> 369 bytes .../ui-bg_highlight-soft_45_5f5964_1x100.png | Bin 0 -> 361 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_734d99_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_8d78a5_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_a8a3ae_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ebccce_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/eggplant/jquery-ui.css | 1177 + .../themes/eggplant/jquery-ui.min.css | 5 + .../themes/eggplant/jquery.ui.theme.css | 406 + .../excite-bike/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-small_25_c5ddfc_40x40.png | Bin 0 -> 342 bytes .../ui-bg_diagonals-thick_20_e69700_40x40.png | Bin 0 -> 417 bytes .../ui-bg_diagonals-thick_22_1484e6_40x40.png | Bin 0 -> 409 bytes .../ui-bg_diagonals-thick_26_2293f7_40x40.png | Bin 0 -> 406 bytes .../images/ui-bg_flat_0_e69700_40x100.png | Bin 0 -> 206 bytes .../images/ui-bg_flat_0_e6b900_40x100.png | Bin 0 -> 206 bytes .../ui-bg_highlight-soft_100_f9f9f9_1x100.png | Bin 0 -> 277 bytes .../ui-bg_inset-hard_100_eeeeee_1x100.png | Bin 0 -> 253 bytes .../images/ui-icons_0a82eb_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_0b54d5_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_5fa5e3_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_fcdd4a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/excite-bike/jquery-ui.css | 1177 + .../themes/excite-bike/jquery-ui.min.css | 5 + .../themes/excite-bike/jquery.ui.theme.css | 406 + .../themes/flick/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_0_eeeeee_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_55_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 207 bytes .../ui-bg_highlight-soft_100_f6f6f6_1x100.png | Bin 0 -> 277 bytes .../ui-bg_highlight-soft_25_0073ea_1x100.png | Bin 0 -> 338 bytes .../ui-bg_highlight-soft_50_dddddd_1x100.png | Bin 0 -> 280 bytes .../flick/images/ui-icons_0073ea_256x240.png | Bin 0 -> 4549 bytes .../flick/images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../flick/images/ui-icons_666666_256x240.png | Bin 0 -> 6988 bytes .../flick/images/ui-icons_ff0084_256x240.png | Bin 0 -> 4549 bytes .../flick/images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../lib/jqueryui/themes/flick/jquery-ui.css | 1177 + .../jqueryui/themes/flick/jquery-ui.min.css | 5 + .../jqueryui/themes/flick/jquery.ui.theme.css | 406 + .../hot-sneaks/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-small_40_db4865_40x40.png | Bin 0 -> 332 bytes .../ui-bg_diagonals-small_50_93c3cd_40x40.png | Bin 0 -> 333 bytes .../ui-bg_diagonals-small_50_ff3853_40x40.png | Bin 0 -> 330 bytes .../ui-bg_diagonals-small_75_ccd232_40x40.png | Bin 0 -> 333 bytes .../ui-bg_dots-medium_80_ffff38_4x4.png | Bin 0 -> 225 bytes .../images/ui-bg_dots-small_35_35414f_2x2.png | Bin 0 -> 223 bytes .../images/ui-bg_flat_75_ba9217_40x100.png | Bin 0 -> 206 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 208 bytes .../ui-bg_white-lines_85_f7f7ba_40x100.png | Bin 0 -> 364 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_88a206_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_c02669_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_e1e463_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffeb33_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/hot-sneaks/jquery-ui.css | 1177 + .../themes/hot-sneaks/jquery-ui.min.css | 5 + .../themes/hot-sneaks/jquery.ui.theme.css | 406 + .../humanity/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_75_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_glass_100_f5f0e5_1x400.png | Bin 0 -> 354 bytes .../images/ui-bg_glass_25_cb842e_1x400.png | Bin 0 -> 335 bytes .../images/ui-bg_glass_70_ede4d4_1x400.png | Bin 0 -> 351 bytes .../ui-bg_highlight-hard_100_f4f0ec_1x100.png | Bin 0 -> 327 bytes .../ui-bg_highlight-hard_65_fee4bd_1x100.png | Bin 0 -> 314 bytes .../ui-bg_highlight-hard_75_f5f5b5_1x100.png | Bin 0 -> 323 bytes .../ui-bg_inset-soft_100_f4f0ec_1x100.png | Bin 0 -> 403 bytes .../images/ui-icons_c47a23_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cb672b_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_f08000_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_f35f07_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ff7519_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/humanity/jquery-ui.css | 1177 + .../themes/humanity/jquery-ui.min.css | 5 + .../themes/humanity/jquery.ui.theme.css | 406 + .../le-frog/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-small_0_aaaaaa_40x40.png | Bin 0 -> 207 bytes .../ui-bg_diagonals-thick_15_444444_40x40.png | Bin 0 -> 313 bytes .../ui-bg_diagonals-thick_95_ffdc2e_40x40.png | Bin 0 -> 411 bytes .../images/ui-bg_glass_55_fbf5d0_1x400.png | Bin 0 -> 336 bytes .../ui-bg_highlight-hard_30_285c00_1x100.png | Bin 0 -> 331 bytes .../ui-bg_highlight-soft_33_3a8104_1x100.png | Bin 0 -> 345 bytes .../ui-bg_highlight-soft_50_4eb305_1x100.png | Bin 0 -> 351 bytes .../ui-bg_highlight-soft_60_4ca20b_1x100.png | Bin 0 -> 364 bytes .../ui-bg_inset-soft_10_285c00_1x100.png | Bin 0 -> 388 bytes .../images/ui-icons_4eb305_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_72b42d_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../lib/jqueryui/themes/le-frog/jquery-ui.css | 1177 + .../jqueryui/themes/le-frog/jquery-ui.min.css | 5 + .../themes/le-frog/jquery.ui.theme.css | 406 + .../mint-choc/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_glass_15_5f391b_1x400.png | Bin 0 -> 341 bytes .../ui-bg_gloss-wave_20_1c160d_500x100.png | Bin 0 -> 5793 bytes .../ui-bg_gloss-wave_25_453326_500x100.png | Bin 0 -> 5852 bytes .../ui-bg_gloss-wave_30_44372c_500x100.png | Bin 0 -> 5914 bytes .../ui-bg_highlight-soft_20_201913_1x100.png | Bin 0 -> 386 bytes .../ui-bg_highlight-soft_20_619226_1x100.png | Bin 0 -> 346 bytes .../ui-bg_inset-soft_10_201913_1x100.png | Bin 0 -> 396 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_9bcc60_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_add978_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_e3ddc9_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_f1fd86_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/mint-choc/jquery-ui.css | 1177 + .../themes/mint-choc/jquery-ui.min.css | 5 + .../themes/mint-choc/jquery.ui.theme.css | 406 + .../overcast/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_0_eeeeee_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_55_c0402a_40x100.png | Bin 0 -> 206 bytes .../images/ui-bg_flat_55_eeeeee_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_glass_100_f8f8f8_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_35_dddddd_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_60_eeeeee_1x400.png | Bin 0 -> 262 bytes .../ui-bg_inset-hard_75_999999_1x100.png | Bin 0 -> 253 bytes .../ui-bg_inset-soft_50_c9c9c9_1x100.png | Bin 0 -> 281 bytes .../images/ui-icons_3383bb_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_70b2e1_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_999999_256x240.png | Bin 0 -> 6986 bytes .../images/ui-icons_fbc856_256x240.png | Bin 0 -> 4549 bytes .../jqueryui/themes/overcast/jquery-ui.css | 1177 + .../themes/overcast/jquery-ui.min.css | 5 + .../themes/overcast/jquery.ui.theme.css | 406 + .../images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonal-maze_20_6e4f1c_10x10.png | Bin 0 -> 296 bytes .../ui-bg_diagonal-maze_40_000000_10x10.png | Bin 0 -> 239 bytes .../ui-bg_fine-grain_10_eceadf_60x60.png | Bin 0 -> 10759 bytes .../ui-bg_fine-grain_10_f8f7f6_60x60.png | Bin 0 -> 9904 bytes .../ui-bg_fine-grain_15_eceadf_60x60.png | Bin 0 -> 10529 bytes .../ui-bg_fine-grain_15_f7f3de_60x60.png | Bin 0 -> 10891 bytes .../ui-bg_fine-grain_15_ffffff_60x60.png | Bin 0 -> 3397 bytes .../ui-bg_fine-grain_65_654b24_60x60.png | Bin 0 -> 14444 bytes .../ui-bg_fine-grain_68_b83400_60x60.png | Bin 0 -> 11877 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_3572ac_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_8c291d_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_b83400_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_fbdb93_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../themes/pepper-grinder/jquery-ui.css | 1177 + .../themes/pepper-grinder/jquery-ui.min.css | 5 + .../themes/pepper-grinder/jquery.ui.theme.css | 406 + .../redmond/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_55_fbec88_40x100.png | Bin 0 -> 206 bytes .../images/ui-bg_glass_75_d0e5f5_1x400.png | Bin 0 -> 336 bytes .../images/ui-bg_glass_85_dfeffc_1x400.png | Bin 0 -> 341 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_gloss-wave_55_5c9ccc_500x100.png | Bin 0 -> 5824 bytes .../ui-bg_inset-hard_100_f5f8f9_1x100.png | Bin 0 -> 333 bytes .../ui-bg_inset-hard_100_fcfdfd_1x100.png | Bin 0 -> 292 bytes .../images/ui-icons_217bc0_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_469bdd_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_6da8d5_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_d8e7f3_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_f9bd01_256x240.png | Bin 0 -> 4549 bytes .../lib/jqueryui/themes/redmond/jquery-ui.css | 1177 + .../jqueryui/themes/redmond/jquery-ui.min.css | 5 + .../themes/redmond/jquery.ui.theme.css | 406 + .../smoothness/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 208 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 335 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 207 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 280 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 6999 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../jqueryui/themes/smoothness/jquery-ui.css | 1177 + .../themes/smoothness/jquery-ui.min.css | 5 + .../themes/smoothness/jquery.ui.theme.css | 406 + .../south-street/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_glass_55_fcf0ba_1x400.png | Bin 0 -> 333 bytes .../ui-bg_gloss-wave_100_ece8da_500x100.png | Bin 0 -> 5759 bytes .../ui-bg_highlight-hard_100_f5f3e5_1x100.png | Bin 0 -> 336 bytes .../ui-bg_highlight-hard_100_fafaf4_1x100.png | Bin 0 -> 321 bytes .../ui-bg_highlight-hard_15_459e00_1x100.png | Bin 0 -> 328 bytes .../ui-bg_highlight-hard_95_cccccc_1x100.png | Bin 0 -> 252 bytes .../ui-bg_highlight-soft_25_67b021_1x100.png | Bin 0 -> 353 bytes .../ui-bg_highlight-soft_95_ffedad_1x100.png | Bin 0 -> 351 bytes .../ui-bg_inset-soft_15_2b2922_1x100.png | Bin 0 -> 349 bytes .../images/ui-icons_808080_256x240.png | Bin 0 -> 7005 bytes .../images/ui-icons_847e71_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_8DC262_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_eeeeee_256x240.png | Bin 0 -> 6916 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../themes/south-street/jquery-ui.css | 1177 + .../themes/south-street/jquery-ui.min.css | 5 + .../themes/south-street/jquery.ui.theme.css | 406 + .../themes/start/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_55_999999_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_75_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_glass_45_0078ae_1x400.png | Bin 0 -> 346 bytes .../images/ui-bg_glass_55_f8da4e_1x400.png | Bin 0 -> 345 bytes .../images/ui-bg_glass_75_79c9ec_1x400.png | Bin 0 -> 348 bytes .../ui-bg_gloss-wave_45_e14f1c_500x100.png | Bin 0 -> 5864 bytes .../ui-bg_gloss-wave_50_6eac2c_500x100.png | Bin 0 -> 5906 bytes .../ui-bg_gloss-wave_75_2191c0_500x100.png | Bin 0 -> 5977 bytes .../ui-bg_inset-hard_100_fcfdfd_1x100.png | Bin 0 -> 292 bytes .../start/images/ui-icons_0078ae_256x240.png | Bin 0 -> 4549 bytes .../start/images/ui-icons_056b93_256x240.png | Bin 0 -> 4549 bytes .../start/images/ui-icons_d8e7f3_256x240.png | Bin 0 -> 4549 bytes .../start/images/ui-icons_e0fdff_256x240.png | Bin 0 -> 4549 bytes .../start/images/ui-icons_f5e175_256x240.png | Bin 0 -> 4549 bytes .../start/images/ui-icons_f7a50d_256x240.png | Bin 0 -> 4549 bytes .../start/images/ui-icons_fcd113_256x240.png | Bin 0 -> 4549 bytes .../lib/jqueryui/themes/start/jquery-ui.css | 1177 + .../jqueryui/themes/start/jquery-ui.min.css | 5 + .../jqueryui/themes/start/jquery.ui.theme.css | 406 + .../themes/sunny/images/animated-overlay.gif | Bin 0 -> 1738 bytes ...ui-bg_diagonals-medium_20_d34d17_40x40.png | Bin 0 -> 382 bytes .../images/ui-bg_flat_30_cccccc_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_50_5c5c5c_40x100.png | Bin 0 -> 230 bytes .../ui-bg_gloss-wave_45_817865_500x100.png | Bin 0 -> 5891 bytes .../ui-bg_gloss-wave_60_fece2f_500x100.png | Bin 0 -> 5849 bytes .../ui-bg_gloss-wave_70_ffdd57_500x100.png | Bin 0 -> 5543 bytes .../ui-bg_gloss-wave_90_fff9e5_500x100.png | Bin 0 -> 5389 bytes .../ui-bg_highlight-soft_100_feeebd_1x100.png | Bin 0 -> 343 bytes .../ui-bg_inset-soft_30_ffffff_1x100.png | Bin 0 -> 203 bytes .../sunny/images/ui-icons_3d3d3d_256x240.png | Bin 0 -> 6992 bytes .../sunny/images/ui-icons_bd7b00_256x240.png | Bin 0 -> 4549 bytes .../sunny/images/ui-icons_d19405_256x240.png | Bin 0 -> 4549 bytes .../sunny/images/ui-icons_eb990f_256x240.png | Bin 0 -> 4549 bytes .../sunny/images/ui-icons_ed9f26_256x240.png | Bin 0 -> 4549 bytes .../sunny/images/ui-icons_fadc7a_256x240.png | Bin 0 -> 4549 bytes .../sunny/images/ui-icons_ffe180_256x240.png | Bin 0 -> 4549 bytes .../lib/jqueryui/themes/sunny/jquery-ui.css | 1177 + .../jqueryui/themes/sunny/jquery-ui.min.css | 5 + .../jqueryui/themes/sunny/jquery.ui.theme.css | 406 + .../swanky-purse/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_diamond_10_4f4221_10x8.png | Bin 0 -> 307 bytes .../images/ui-bg_diamond_20_372806_10x8.png | Bin 0 -> 310 bytes .../images/ui-bg_diamond_25_675423_10x8.png | Bin 0 -> 312 bytes .../images/ui-bg_diamond_25_d5ac5d_10x8.png | Bin 0 -> 313 bytes .../images/ui-bg_diamond_8_261803_10x8.png | Bin 0 -> 310 bytes .../images/ui-bg_diamond_8_443113_10x8.png | Bin 0 -> 310 bytes .../images/ui-bg_flat_75_ddd4b0_40x100.png | Bin 0 -> 206 bytes .../ui-bg_highlight-hard_65_fee4bd_1x100.png | Bin 0 -> 314 bytes .../images/ui-icons_070603_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_e8e2b5_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_e9cd86_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_efec9f_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_f2ec64_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_f9f2bd_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ff7519_256x240.png | Bin 0 -> 4549 bytes .../themes/swanky-purse/jquery-ui.css | 1177 + .../themes/swanky-purse/jquery-ui.min.css | 5 + .../themes/swanky-purse/jquery.ui.theme.css | 406 + .../trontastic/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-small_50_262626_40x40.png | Bin 0 -> 250 bytes .../images/ui-bg_flat_0_303030_40x100.png | Bin 0 -> 230 bytes .../images/ui-bg_flat_0_4c4c4c_40x100.png | Bin 0 -> 230 bytes .../images/ui-bg_glass_40_0a0a0a_1x400.png | Bin 0 -> 260 bytes .../images/ui-bg_glass_55_f1fbe5_1x400.png | Bin 0 -> 348 bytes .../images/ui-bg_glass_60_000000_1x400.png | Bin 0 -> 258 bytes .../ui-bg_gloss-wave_55_000000_500x100.png | Bin 0 -> 3867 bytes .../ui-bg_gloss-wave_85_9fda58_500x100.png | Bin 0 -> 5940 bytes .../ui-bg_gloss-wave_95_f6ecd5_500x100.png | Bin 0 -> 5794 bytes .../images/ui-icons_000000_256x240.png | Bin 0 -> 5331 bytes .../images/ui-icons_1f1f1f_256x240.png | Bin 0 -> 6927 bytes .../images/ui-icons_9fda58_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_b8ec79_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/trontastic/jquery-ui.css | 1177 + .../themes/trontastic/jquery-ui.min.css | 5 + .../themes/trontastic/jquery.ui.theme.css | 406 + .../ui-darkness/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_30_cccccc_40x100.png | Bin 0 -> 220 bytes .../images/ui-bg_flat_50_5c5c5c_40x100.png | Bin 0 -> 230 bytes .../images/ui-bg_glass_20_555555_1x400.png | Bin 0 -> 260 bytes .../images/ui-bg_glass_40_0078a3_1x400.png | Bin 0 -> 342 bytes .../images/ui-bg_glass_40_ffc73d_1x400.png | Bin 0 -> 316 bytes .../ui-bg_gloss-wave_25_333333_500x100.png | Bin 0 -> 3816 bytes .../ui-bg_highlight-soft_80_eeeeee_1x100.png | Bin 0 -> 276 bytes .../ui-bg_inset-soft_25_000000_1x100.png | Bin 0 -> 275 bytes .../ui-bg_inset-soft_30_f58400_1x100.png | Bin 0 -> 340 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_4b8e0b_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_a83300_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_cccccc_256x240.png | Bin 0 -> 6975 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../jqueryui/themes/ui-darkness/jquery-ui.css | 1177 + .../themes/ui-darkness/jquery-ui.min.css | 5 + .../themes/ui-darkness/jquery.ui.theme.css | 406 + .../ui-lightness/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 418 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 312 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 205 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin 0 -> 348 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 207 bytes .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin 0 -> 5815 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 278 bytes .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin 0 -> 328 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_228ef1_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ef8c08_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../themes/ui-lightness/jquery-ui.css | 1177 + .../themes/ui-lightness/jquery-ui.min.css | 5 + .../themes/ui-lightness/jquery.ui.theme.css | 406 + .../themes/vader/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 212 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_gloss-wave_16_121212_500x100.png | Bin 0 -> 3848 bytes .../ui-bg_highlight-hard_15_888888_1x100.png | Bin 0 -> 251 bytes .../ui-bg_highlight-hard_55_555555_1x100.png | Bin 0 -> 250 bytes .../ui-bg_highlight-soft_35_adadad_1x100.png | Bin 0 -> 280 bytes .../ui-bg_highlight-soft_60_dddddd_1x100.png | Bin 0 -> 279 bytes .../ui-bg_inset-soft_15_121212_1x100.png | Bin 0 -> 277 bytes .../vader/images/ui-icons_666666_256x240.png | Bin 0 -> 6988 bytes .../vader/images/ui-icons_aaaaaa_256x240.png | Bin 0 -> 6987 bytes .../vader/images/ui-icons_bbbbbb_256x240.png | Bin 0 -> 6991 bytes .../vader/images/ui-icons_c98000_256x240.png | Bin 0 -> 4549 bytes .../vader/images/ui-icons_cccccc_256x240.png | Bin 0 -> 6975 bytes .../vader/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../vader/images/ui-icons_f29a00_256x240.png | Bin 0 -> 4549 bytes .../lib/jqueryui/themes/vader/jquery-ui.css | 1177 + .../jqueryui/themes/vader/jquery-ui.min.css | 5 + .../jqueryui/themes/vader/jquery.ui.theme.css | 406 + awx/ui/static/lib/jqueryui/ui/.jshintrc | 22 + .../lib/jqueryui/ui/i18n/jquery-ui-i18n.js | 1793 ++ .../ui/i18n/jquery.ui.datepicker-af.js | 23 + .../ui/i18n/jquery.ui.datepicker-ar-DZ.js | 23 + .../ui/i18n/jquery.ui.datepicker-ar.js | 23 + .../ui/i18n/jquery.ui.datepicker-az.js | 23 + .../ui/i18n/jquery.ui.datepicker-be.js | 23 + .../ui/i18n/jquery.ui.datepicker-bg.js | 24 + .../ui/i18n/jquery.ui.datepicker-bs.js | 23 + .../ui/i18n/jquery.ui.datepicker-ca.js | 23 + .../ui/i18n/jquery.ui.datepicker-cs.js | 23 + .../ui/i18n/jquery.ui.datepicker-cy-GB.js | 23 + .../ui/i18n/jquery.ui.datepicker-da.js | 23 + .../ui/i18n/jquery.ui.datepicker-de.js | 23 + .../ui/i18n/jquery.ui.datepicker-el.js | 23 + .../ui/i18n/jquery.ui.datepicker-en-AU.js | 23 + .../ui/i18n/jquery.ui.datepicker-en-GB.js | 23 + .../ui/i18n/jquery.ui.datepicker-en-NZ.js | 23 + .../ui/i18n/jquery.ui.datepicker-eo.js | 23 + .../ui/i18n/jquery.ui.datepicker-es.js | 23 + .../ui/i18n/jquery.ui.datepicker-et.js | 23 + .../ui/i18n/jquery.ui.datepicker-eu.js | 23 + .../ui/i18n/jquery.ui.datepicker-fa.js | 59 + .../ui/i18n/jquery.ui.datepicker-fi.js | 23 + .../ui/i18n/jquery.ui.datepicker-fo.js | 23 + .../ui/i18n/jquery.ui.datepicker-fr-CA.js | 23 + .../ui/i18n/jquery.ui.datepicker-fr-CH.js | 23 + .../ui/i18n/jquery.ui.datepicker-fr.js | 25 + .../ui/i18n/jquery.ui.datepicker-gl.js | 23 + .../ui/i18n/jquery.ui.datepicker-he.js | 23 + .../ui/i18n/jquery.ui.datepicker-hi.js | 23 + .../ui/i18n/jquery.ui.datepicker-hr.js | 23 + .../ui/i18n/jquery.ui.datepicker-hu.js | 23 + .../ui/i18n/jquery.ui.datepicker-hy.js | 23 + .../ui/i18n/jquery.ui.datepicker-id.js | 23 + .../ui/i18n/jquery.ui.datepicker-is.js | 23 + .../ui/i18n/jquery.ui.datepicker-it.js | 23 + .../ui/i18n/jquery.ui.datepicker-ja.js | 23 + .../ui/i18n/jquery.ui.datepicker-ka.js | 21 + .../ui/i18n/jquery.ui.datepicker-kk.js | 23 + .../ui/i18n/jquery.ui.datepicker-km.js | 23 + .../ui/i18n/jquery.ui.datepicker-ko.js | 23 + .../ui/i18n/jquery.ui.datepicker-ky.js | 24 + .../ui/i18n/jquery.ui.datepicker-lb.js | 23 + .../ui/i18n/jquery.ui.datepicker-lt.js | 23 + .../ui/i18n/jquery.ui.datepicker-lv.js | 23 + .../ui/i18n/jquery.ui.datepicker-mk.js | 23 + .../ui/i18n/jquery.ui.datepicker-ml.js | 23 + .../ui/i18n/jquery.ui.datepicker-ms.js | 23 + .../ui/i18n/jquery.ui.datepicker-nb.js | 22 + .../ui/i18n/jquery.ui.datepicker-nl-BE.js | 23 + .../ui/i18n/jquery.ui.datepicker-nl.js | 23 + .../ui/i18n/jquery.ui.datepicker-nn.js | 22 + .../ui/i18n/jquery.ui.datepicker-no.js | 23 + .../ui/i18n/jquery.ui.datepicker-pl.js | 23 + .../ui/i18n/jquery.ui.datepicker-pt-BR.js | 23 + .../ui/i18n/jquery.ui.datepicker-pt.js | 22 + .../ui/i18n/jquery.ui.datepicker-rm.js | 21 + .../ui/i18n/jquery.ui.datepicker-ro.js | 26 + .../ui/i18n/jquery.ui.datepicker-ru.js | 23 + .../ui/i18n/jquery.ui.datepicker-sk.js | 23 + .../ui/i18n/jquery.ui.datepicker-sl.js | 24 + .../ui/i18n/jquery.ui.datepicker-sq.js | 23 + .../ui/i18n/jquery.ui.datepicker-sr-SR.js | 23 + .../ui/i18n/jquery.ui.datepicker-sr.js | 23 + .../ui/i18n/jquery.ui.datepicker-sv.js | 23 + .../ui/i18n/jquery.ui.datepicker-ta.js | 23 + .../ui/i18n/jquery.ui.datepicker-th.js | 23 + .../ui/i18n/jquery.ui.datepicker-tj.js | 23 + .../ui/i18n/jquery.ui.datepicker-tr.js | 23 + .../ui/i18n/jquery.ui.datepicker-uk.js | 24 + .../ui/i18n/jquery.ui.datepicker-vi.js | 23 + .../ui/i18n/jquery.ui.datepicker-zh-CN.js | 23 + .../ui/i18n/jquery.ui.datepicker-zh-HK.js | 23 + .../ui/i18n/jquery.ui.datepicker-zh-TW.js | 23 + awx/ui/static/lib/jqueryui/ui/jquery-ui.js | 15003 +++++++++++ .../lib/jqueryui/ui/jquery.ui.accordion.js | 572 + .../lib/jqueryui/ui/jquery.ui.autocomplete.js | 610 + .../lib/jqueryui/ui/jquery.ui.button.js | 419 + .../static/lib/jqueryui/ui/jquery.ui.core.js | 320 + .../lib/jqueryui/ui/jquery.ui.datepicker.js | 2038 ++ .../lib/jqueryui/ui/jquery.ui.dialog.js | 808 + .../lib/jqueryui/ui/jquery.ui.draggable.js | 958 + .../lib/jqueryui/ui/jquery.ui.droppable.js | 372 + .../lib/jqueryui/ui/jquery.ui.effect-blind.js | 82 + .../jqueryui/ui/jquery.ui.effect-bounce.js | 113 + .../lib/jqueryui/ui/jquery.ui.effect-clip.js | 67 + .../lib/jqueryui/ui/jquery.ui.effect-drop.js | 65 + .../jqueryui/ui/jquery.ui.effect-explode.js | 97 + .../lib/jqueryui/ui/jquery.ui.effect-fade.js | 30 + .../lib/jqueryui/ui/jquery.ui.effect-fold.js | 76 + .../jqueryui/ui/jquery.ui.effect-highlight.js | 50 + .../jqueryui/ui/jquery.ui.effect-pulsate.js | 63 + .../lib/jqueryui/ui/jquery.ui.effect-scale.js | 318 + .../lib/jqueryui/ui/jquery.ui.effect-shake.js | 74 + .../lib/jqueryui/ui/jquery.ui.effect-slide.js | 64 + .../jqueryui/ui/jquery.ui.effect-transfer.js | 47 + .../lib/jqueryui/ui/jquery.ui.effect.js | 1289 + .../static/lib/jqueryui/ui/jquery.ui.menu.js | 621 + .../static/lib/jqueryui/ui/jquery.ui.mouse.js | 169 + .../lib/jqueryui/ui/jquery.ui.position.js | 497 + .../lib/jqueryui/ui/jquery.ui.progressbar.js | 145 + .../lib/jqueryui/ui/jquery.ui.resizable.js | 968 + .../lib/jqueryui/ui/jquery.ui.selectable.js | 277 + .../lib/jqueryui/ui/jquery.ui.slider.js | 672 + .../lib/jqueryui/ui/jquery.ui.sortable.js | 1285 + .../lib/jqueryui/ui/jquery.ui.spinner.js | 493 + .../static/lib/jqueryui/ui/jquery.ui.tabs.js | 846 + .../lib/jqueryui/ui/jquery.ui.tooltip.js | 402 + .../lib/jqueryui/ui/jquery.ui.widget.js | 521 + .../ui/minified/i18n/jquery-ui-i18n.min.js | 6 + .../i18n/jquery.ui.datepicker-af.min.js | 4 + .../i18n/jquery.ui.datepicker-ar-DZ.min.js | 4 + .../i18n/jquery.ui.datepicker-ar.min.js | 4 + .../i18n/jquery.ui.datepicker-az.min.js | 4 + .../i18n/jquery.ui.datepicker-be.min.js | 4 + .../i18n/jquery.ui.datepicker-bg.min.js | 4 + .../i18n/jquery.ui.datepicker-bs.min.js | 4 + .../i18n/jquery.ui.datepicker-ca.min.js | 4 + .../i18n/jquery.ui.datepicker-cs.min.js | 4 + .../i18n/jquery.ui.datepicker-cy-GB.min.js | 4 + .../i18n/jquery.ui.datepicker-da.min.js | 4 + .../i18n/jquery.ui.datepicker-de.min.js | 4 + .../i18n/jquery.ui.datepicker-el.min.js | 4 + .../i18n/jquery.ui.datepicker-en-AU.min.js | 4 + .../i18n/jquery.ui.datepicker-en-GB.min.js | 4 + .../i18n/jquery.ui.datepicker-en-NZ.min.js | 4 + .../i18n/jquery.ui.datepicker-eo.min.js | 4 + .../i18n/jquery.ui.datepicker-es.min.js | 4 + .../i18n/jquery.ui.datepicker-et.min.js | 4 + .../i18n/jquery.ui.datepicker-eu.min.js | 4 + .../i18n/jquery.ui.datepicker-fa.min.js | 4 + .../i18n/jquery.ui.datepicker-fi.min.js | 4 + .../i18n/jquery.ui.datepicker-fo.min.js | 4 + .../i18n/jquery.ui.datepicker-fr-CA.min.js | 4 + .../i18n/jquery.ui.datepicker-fr-CH.min.js | 4 + .../i18n/jquery.ui.datepicker-fr.min.js | 4 + .../i18n/jquery.ui.datepicker-gl.min.js | 4 + .../i18n/jquery.ui.datepicker-he.min.js | 4 + .../i18n/jquery.ui.datepicker-hi.min.js | 4 + .../i18n/jquery.ui.datepicker-hr.min.js | 4 + .../i18n/jquery.ui.datepicker-hu.min.js | 4 + .../i18n/jquery.ui.datepicker-hy.min.js | 4 + .../i18n/jquery.ui.datepicker-id.min.js | 4 + .../i18n/jquery.ui.datepicker-is.min.js | 4 + .../i18n/jquery.ui.datepicker-it.min.js | 4 + .../i18n/jquery.ui.datepicker-ja.min.js | 4 + .../i18n/jquery.ui.datepicker-ka.min.js | 4 + .../i18n/jquery.ui.datepicker-kk.min.js | 4 + .../i18n/jquery.ui.datepicker-km.min.js | 4 + .../i18n/jquery.ui.datepicker-ko.min.js | 4 + .../i18n/jquery.ui.datepicker-ky.min.js | 4 + .../i18n/jquery.ui.datepicker-lb.min.js | 4 + .../i18n/jquery.ui.datepicker-lt.min.js | 4 + .../i18n/jquery.ui.datepicker-lv.min.js | 4 + .../i18n/jquery.ui.datepicker-mk.min.js | 4 + .../i18n/jquery.ui.datepicker-ml.min.js | 4 + .../i18n/jquery.ui.datepicker-ms.min.js | 4 + .../i18n/jquery.ui.datepicker-nb.min.js | 4 + .../i18n/jquery.ui.datepicker-nl-BE.min.js | 4 + .../i18n/jquery.ui.datepicker-nl.min.js | 4 + .../i18n/jquery.ui.datepicker-nn.min.js | 4 + .../i18n/jquery.ui.datepicker-no.min.js | 4 + .../i18n/jquery.ui.datepicker-pl.min.js | 4 + .../i18n/jquery.ui.datepicker-pt-BR.min.js | 4 + .../i18n/jquery.ui.datepicker-pt.min.js | 4 + .../i18n/jquery.ui.datepicker-rm.min.js | 4 + .../i18n/jquery.ui.datepicker-ro.min.js | 4 + .../i18n/jquery.ui.datepicker-ru.min.js | 4 + .../i18n/jquery.ui.datepicker-sk.min.js | 4 + .../i18n/jquery.ui.datepicker-sl.min.js | 4 + .../i18n/jquery.ui.datepicker-sq.min.js | 4 + .../i18n/jquery.ui.datepicker-sr-SR.min.js | 4 + .../i18n/jquery.ui.datepicker-sr.min.js | 4 + .../i18n/jquery.ui.datepicker-sv.min.js | 4 + .../i18n/jquery.ui.datepicker-ta.min.js | 4 + .../i18n/jquery.ui.datepicker-th.min.js | 4 + .../i18n/jquery.ui.datepicker-tj.min.js | 4 + .../i18n/jquery.ui.datepicker-tr.min.js | 4 + .../i18n/jquery.ui.datepicker-uk.min.js | 4 + .../i18n/jquery.ui.datepicker-vi.min.js | 4 + .../i18n/jquery.ui.datepicker-zh-CN.min.js | 4 + .../i18n/jquery.ui.datepicker-zh-HK.min.js | 4 + .../i18n/jquery.ui.datepicker-zh-TW.min.js | 4 + .../lib/jqueryui/ui/minified/jquery-ui.min.js | 12 + .../ui/minified/jquery.ui.accordion.min.js | 4 + .../ui/minified/jquery.ui.autocomplete.min.js | 4 + .../ui/minified/jquery.ui.button.min.js | 4 + .../ui/minified/jquery.ui.core.min.js | 4 + .../ui/minified/jquery.ui.datepicker.min.js | 5 + .../ui/minified/jquery.ui.dialog.min.js | 4 + .../ui/minified/jquery.ui.draggable.min.js | 4 + .../ui/minified/jquery.ui.droppable.min.js | 4 + .../ui/minified/jquery.ui.effect-blind.min.js | 4 + .../minified/jquery.ui.effect-bounce.min.js | 4 + .../ui/minified/jquery.ui.effect-clip.min.js | 4 + .../ui/minified/jquery.ui.effect-drop.min.js | 4 + .../minified/jquery.ui.effect-explode.min.js | 4 + .../ui/minified/jquery.ui.effect-fade.min.js | 4 + .../ui/minified/jquery.ui.effect-fold.min.js | 4 + .../jquery.ui.effect-highlight.min.js | 4 + .../minified/jquery.ui.effect-pulsate.min.js | 4 + .../ui/minified/jquery.ui.effect-scale.min.js | 4 + .../ui/minified/jquery.ui.effect-shake.min.js | 4 + .../ui/minified/jquery.ui.effect-slide.min.js | 4 + .../minified/jquery.ui.effect-transfer.min.js | 4 + .../ui/minified/jquery.ui.effect.min.js | 4 + .../ui/minified/jquery.ui.menu.min.js | 4 + .../ui/minified/jquery.ui.mouse.min.js | 4 + .../ui/minified/jquery.ui.position.min.js | 4 + .../ui/minified/jquery.ui.progressbar.min.js | 4 + .../ui/minified/jquery.ui.resizable.min.js | 4 + .../ui/minified/jquery.ui.selectable.min.js | 4 + .../ui/minified/jquery.ui.slider.min.js | 4 + .../ui/minified/jquery.ui.sortable.min.js | 4 + .../ui/minified/jquery.ui.spinner.min.js | 4 + .../ui/minified/jquery.ui.tabs.min.js | 4 + .../ui/minified/jquery.ui.tooltip.min.js | 4 + .../ui/minified/jquery.ui.widget.min.js | 4 + awx/ui/static/lib/less.js/.bower.json | 29 + awx/ui/static/lib/less.js/build.gradle | 347 + .../less.js/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 50514 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + awx/ui/static/lib/less.js/gradlew | 164 + awx/ui/static/lib/less.js/gradlew.bat | 90 + awx/ui/static/lib/less/less-1.4.1.min.js | 11 - awx/ui/static/lib/select2/.bower.json | 25 + awx/ui/static/lib/twitter/.bower.json | 35 + awx/ui/static/lib/twitter/Gruntfile.js | 418 + awx/ui/static/lib/twitter/LICENSE | 21 + awx/ui/static/lib/twitter/README.md | 173 + awx/ui/static/lib/twitter/bower.json | 24 + awx/ui/static/lib/twitter/browserstack.json | 44 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20290 bytes .../fonts/glyphicons-halflings-regular.svg | 229 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41236 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23292 bytes awx/ui/static/lib/twitter/js/affix.js | 137 + awx/ui/static/lib/twitter/js/alert.js | 88 + awx/ui/static/lib/twitter/js/button.js | 107 + awx/ui/static/lib/twitter/js/carousel.js | 205 + awx/ui/static/lib/twitter/js/collapse.js | 170 + awx/ui/static/lib/twitter/js/dropdown.js | 147 + awx/ui/static/lib/twitter/js/modal.js | 243 + awx/ui/static/lib/twitter/js/popover.js | 110 + awx/ui/static/lib/twitter/js/scrollspy.js | 153 + awx/ui/static/lib/twitter/js/tab.js | 125 + awx/ui/static/lib/twitter/js/tooltip.js | 399 + awx/ui/static/lib/twitter/js/transition.js | 48 + awx/ui/static/lib/twitter/less/alerts.less | 67 + awx/ui/static/lib/twitter/less/badges.less | 55 + awx/ui/static/lib/twitter/less/bootstrap.less | 49 + .../static/lib/twitter/less/breadcrumbs.less | 26 + .../lib/twitter/less/button-groups.less | 226 + awx/ui/static/lib/twitter/less/buttons.less | 155 + awx/ui/static/lib/twitter/less/carousel.less | 232 + awx/ui/static/lib/twitter/less/close.less | 33 + awx/ui/static/lib/twitter/less/code.less | 63 + .../twitter/less/component-animations.less | 29 + awx/ui/static/lib/twitter/less/dropdowns.less | 213 + awx/ui/static/lib/twitter/less/forms.less | 419 + .../static/lib/twitter/less/glyphicons.less | 233 + awx/ui/static/lib/twitter/less/grid.less | 100 + .../static/lib/twitter/less/input-groups.less | 157 + awx/ui/static/lib/twitter/less/jumbotron.less | 44 + awx/ui/static/lib/twitter/less/labels.less | 64 + .../static/lib/twitter/less/list-group.less | 110 + awx/ui/static/lib/twitter/less/media.less | 56 + awx/ui/static/lib/twitter/less/mixins.less | 926 + awx/ui/static/lib/twitter/less/modals.less | 138 + awx/ui/static/lib/twitter/less/navbar.less | 616 + awx/ui/static/lib/twitter/less/navs.less | 242 + awx/ui/static/lib/twitter/less/normalize.less | 423 + awx/ui/static/lib/twitter/less/pager.less | 55 + .../static/lib/twitter/less/pagination.less | 88 + awx/ui/static/lib/twitter/less/panels.less | 230 + awx/ui/static/lib/twitter/less/popovers.less | 133 + awx/ui/static/lib/twitter/less/print.less | 101 + .../lib/twitter/less/progress-bars.less | 80 + .../twitter/less/responsive-utilities.less | 93 + .../static/lib/twitter/less/scaffolding.less | 134 + awx/ui/static/lib/twitter/less/tables.less | 233 + awx/ui/static/lib/twitter/less/theme.less | 247 + .../static/lib/twitter/less/thumbnails.less | 36 + awx/ui/static/lib/twitter/less/tooltip.less | 95 + awx/ui/static/lib/twitter/less/type.less | 296 + awx/ui/static/lib/twitter/less/utilities.less | 56 + awx/ui/static/lib/twitter/less/variables.less | 827 + awx/ui/static/lib/twitter/less/wells.less | 29 + awx/ui/static/lib/twitter/package.json | 71 + .../static/lib/twitter/test-infra/README.md | 100 + .../test-infra/npm-shrinkwrap.canonical.json | 1 + .../lib/twitter/test-infra/requirements.txt | 1 + .../static/lib/twitter/test-infra/s3_cache.py | 107 + .../lib/twitter/test-infra/sauce_browsers.yml | 83 + .../lib/twitter/test-infra/shrinkwrap.js | 24 + .../test-infra/uncached-npm-install.sh | 4 + awx/ui/templates/ui/index.html | 38 +- package.json | 3 +- 960 files changed, 112155 insertions(+), 35865 deletions(-) create mode 100644 .bowerrc delete mode 100644 awx/ui/static/css/bootstrap-theme.css delete mode 100644 awx/ui/static/css/bootstrap-theme.min.css delete mode 100644 awx/ui/static/css/bootstrap.css delete mode 100644 awx/ui/static/css/bootstrap.min.css delete mode 100644 awx/ui/static/css/select2-bootstrap.css delete mode 100644 awx/ui/static/css/select2-spinner.gif delete mode 100644 awx/ui/static/css/select2.css delete mode 100644 awx/ui/static/css/select2.png delete mode 100644 awx/ui/static/css/select2x2.png create mode 100644 awx/ui/static/js/awx-min.js delete mode 100644 awx/ui/static/lib/angular-1.2.9/angular-resource.min.js.map delete mode 100644 awx/ui/static/lib/angular-1.2.9/angular-route.min.js delete mode 100644 awx/ui/static/lib/angular-1.2.9/angular.js delete mode 100644 awx/ui/static/lib/angular-1.2.9/angular.min.js delete mode 100644 awx/ui/static/lib/angular-1.2.9/angular.min.js.gzip delete mode 100644 awx/ui/static/lib/angular-1.2.9/angular.min.js.map create mode 100644 awx/ui/static/lib/angular-cookies/.bower.json create mode 100644 awx/ui/static/lib/angular-cookies/README.md rename awx/ui/static/lib/{angular-1.2.9 => angular-cookies}/angular-cookies.js (99%) rename awx/ui/static/lib/{angular-1.2.9 => angular-cookies}/angular-cookies.min.js (97%) rename awx/ui/static/lib/{angular-1.2.9 => angular-cookies}/angular-cookies.min.js.map (100%) create mode 100644 awx/ui/static/lib/angular-cookies/bower.json create mode 100644 awx/ui/static/lib/angular-md5/.bower.json create mode 100644 awx/ui/static/lib/angular-md5/Gruntfile.js create mode 100644 awx/ui/static/lib/angular-md5/README.md create mode 100644 awx/ui/static/lib/angular-md5/angular-md5.js create mode 100644 awx/ui/static/lib/angular-md5/angular-md5.min.js create mode 100644 awx/ui/static/lib/angular-md5/angular-md5.min.js.map create mode 100644 awx/ui/static/lib/angular-md5/bower.json create mode 100644 awx/ui/static/lib/angular-md5/example/index.html create mode 100644 awx/ui/static/lib/angular-md5/lib/filters/gravatar.js create mode 100644 awx/ui/static/lib/angular-md5/lib/filters/md5.js create mode 100644 awx/ui/static/lib/angular-md5/lib/index.js create mode 100644 awx/ui/static/lib/angular-md5/lib/services/md5.js create mode 100644 awx/ui/static/lib/angular-md5/package.json create mode 100644 awx/ui/static/lib/angular-resource/.bower.json create mode 100644 awx/ui/static/lib/angular-resource/README.md rename awx/ui/static/lib/{angular-1.2.9 => angular-resource}/angular-resource.js (99%) rename awx/ui/static/lib/{angular-1.2.9 => angular-resource}/angular-resource.min.js (75%) create mode 100644 awx/ui/static/lib/angular-resource/angular-resource.min.js.map create mode 100644 awx/ui/static/lib/angular-resource/bower.json create mode 100644 awx/ui/static/lib/angular-route/.bower.json create mode 100644 awx/ui/static/lib/angular-route/README.md rename awx/ui/static/lib/{angular-1.2.9 => angular-route}/angular-route.js (97%) create mode 100644 awx/ui/static/lib/angular-route/angular-route.min.js rename awx/ui/static/lib/{angular-1.2.9 => angular-route}/angular-route.min.js.map (90%) create mode 100644 awx/ui/static/lib/angular-route/bower.json create mode 100644 awx/ui/static/lib/angular-sanitize/.bower.json create mode 100644 awx/ui/static/lib/angular-sanitize/README.md rename awx/ui/static/lib/{angular-1.2.9 => angular-sanitize}/angular-sanitize.js (89%) rename awx/ui/static/lib/{angular-1.2.9 => angular-sanitize}/angular-sanitize.min.js (99%) rename awx/ui/static/lib/{angular-1.2.9 => angular-sanitize}/angular-sanitize.min.js.map (94%) create mode 100644 awx/ui/static/lib/angular-sanitize/bower.json create mode 100644 awx/ui/static/lib/angular/.bower.json create mode 100644 awx/ui/static/lib/angular/README.md rename awx/ui/static/lib/{angular-1.2.9 => angular}/angular-csp.css (100%) mode change 100755 => 100644 awx/ui/static/lib/angular/angular.js create mode 100644 awx/ui/static/lib/angular/angular.min.js.gzip create mode 100644 awx/ui/static/lib/angular/angular.min.js.map create mode 100644 awx/ui/static/lib/angular/bower.json create mode 100644 awx/ui/static/lib/components-font-awesome/.bower.json create mode 100644 awx/ui/static/lib/components-font-awesome/.gitignore create mode 100644 awx/ui/static/lib/components-font-awesome/Makefile create mode 100644 awx/ui/static/lib/components-font-awesome/README.md create mode 100644 awx/ui/static/lib/components-font-awesome/bower.json create mode 100644 awx/ui/static/lib/components-font-awesome/component.json create mode 100644 awx/ui/static/lib/components-font-awesome/composer.json rename awx/ui/static/{ => lib/components-font-awesome}/css/font-awesome.css (100%) mode change 100755 => 100644 rename awx/ui/static/{ => lib/components-font-awesome}/css/font-awesome.min.css (100%) mode change 100755 => 100644 rename awx/ui/static/{ => lib/components-font-awesome}/fonts/FontAwesome.otf (100%) mode change 100755 => 100644 rename awx/ui/static/{ => lib/components-font-awesome}/fonts/fontawesome-webfont.eot (100%) rename awx/ui/static/{ => lib/components-font-awesome}/fonts/fontawesome-webfont.svg (100%) rename awx/ui/static/{ => lib/components-font-awesome}/fonts/fontawesome-webfont.ttf (100%) rename awx/ui/static/{ => lib/components-font-awesome}/fonts/fontawesome-webfont.woff (100%) create mode 100644 awx/ui/static/lib/components-font-awesome/less/bootstrap.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/bordered-pulled.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/core.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/extras.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/fixed-width.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/font-awesome.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/icons.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/larger.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/list.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/mixins.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/path.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/rotated-flipped.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/spinning.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/stacked.less create mode 100644 awx/ui/static/lib/components-font-awesome/less/variables.less create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_bootstrap.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_bordered-pulled.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_core.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_extras.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_fixed-width.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_icons.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_larger.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_list.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_mixins.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_path.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_rotated-flipped.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_spinning.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_stacked.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/_variables.scss create mode 100644 awx/ui/static/lib/components-font-awesome/scss/font-awesome.scss create mode 100644 awx/ui/static/lib/jquery/.bower.json create mode 100644 awx/ui/static/lib/jquery/.gitignore create mode 100644 awx/ui/static/lib/jquery/README.md create mode 100644 awx/ui/static/lib/jquery/bower.json create mode 100644 awx/ui/static/lib/jquery/component.json create mode 100644 awx/ui/static/lib/jquery/composer.json create mode 100644 awx/ui/static/lib/jquery/jquery-migrate.js create mode 100644 awx/ui/static/lib/jquery/jquery-migrate.min.js create mode 100644 awx/ui/static/lib/jquery/jquery.js create mode 100644 awx/ui/static/lib/jquery/jquery.min.js create mode 100644 awx/ui/static/lib/jquery/jquery.min.map create mode 100644 awx/ui/static/lib/jquery/package.json create mode 100644 awx/ui/static/lib/jqueryui/.bower.json create mode 100644 awx/ui/static/lib/jqueryui/.gitignore create mode 100644 awx/ui/static/lib/jqueryui/AUTHORS.txt create mode 100644 awx/ui/static/lib/jqueryui/MANIFEST create mode 100644 awx/ui/static/lib/jqueryui/MIT-LICENSE.txt create mode 100644 awx/ui/static/lib/jqueryui/README.md create mode 100644 awx/ui/static/lib/jqueryui/bower.json create mode 100644 awx/ui/static/lib/jqueryui/composer.json create mode 100644 awx/ui/static/lib/jqueryui/package.json create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-icons_2e83ff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-icons_888888_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.accordion.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.all.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.autocomplete.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.base.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.button.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.core.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.datepicker.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.dialog.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.menu.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.progressbar.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.resizable.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.selectable.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.slider.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.spinner.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.tabs.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/jquery.ui.tooltip.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-icons_2e83ff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-icons_888888_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.accordion.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.autocomplete.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.button.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.core.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.datepicker.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.dialog.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.menu.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.progressbar.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.resizable.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.selectable.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.slider.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.spinner.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.tabs.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.theme.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/base/minified/jquery.ui.tooltip.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_diagonals-thick_8_333333_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_flat_65_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_glass_40_111111_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_glass_55_1c1c1c_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_highlight-hard_40_aaaaaa_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_highlight-soft_50_aaaaaa_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_inset-hard_45_cd0a0a_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-bg_inset-hard_55_ffeb80_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-icons_4ca300_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-icons_bbbbbb_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-icons_ededed_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-icons_ffcf29_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/black-tie/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_dots-small_65_a6a6a6_2x2.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_flat_0_333333_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_flat_65_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_glass_55_fbf8ee_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_highlight-hard_100_eeeeee_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-bg_highlight-soft_15_cc0000_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-icons_004276_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-icons_cc0000_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/blitzer/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_flat_15_cd0a0a_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_glass_100_e4f1fb_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_glass_50_3baae3_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_glass_80_d7ebf9_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_highlight-hard_70_000000_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_highlight-soft_100_deedf7_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-bg_highlight-soft_25_ffef8f_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-icons_2694e8_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-icons_2e83ff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-icons_3d80b3_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-icons_72a7cf_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/cupertino/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_flat_30_cccccc_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_flat_50_5c5c5c_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_glass_40_ffc73d_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_highlight-hard_20_0972a5_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_highlight-soft_33_003147_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_highlight-soft_35_222222_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_highlight-soft_44_444444_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_highlight-soft_80_eeeeee_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-bg_loop_25_000000_21x21.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-icons_4b8e0b_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-icons_a83300_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-icons_cccccc_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/dark-hive/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_diagonals-thick_15_0b3e6f_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_dots-medium_30_0b58a2_4x4.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_dots-small_20_333333_2x2.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_dots-small_30_a32d00_2x2.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_dots-small_40_00498f_2x2.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_flat_40_292929_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-bg_gloss-wave_20_111111_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-icons_00498f_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-icons_98d2fb_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-icons_9ccdfc_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/dot-luv/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_flat_0_eeeeee_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_flat_55_994d53_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_flat_55_fafafa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_gloss-wave_30_3d3644_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_highlight-soft_100_dcd9de_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_highlight-soft_100_eae6ea_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_highlight-soft_25_30273a_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-bg_highlight-soft_45_5f5964_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-icons_734d99_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-icons_8d78a5_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-icons_a8a3ae_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-icons_ebccce_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/eggplant/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_diagonals-small_25_c5ddfc_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_diagonals-thick_20_e69700_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_diagonals-thick_22_1484e6_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_diagonals-thick_26_2293f7_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_flat_0_e69700_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_flat_0_e6b900_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_highlight-soft_100_f9f9f9_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-bg_inset-hard_100_eeeeee_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-icons_0a82eb_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-icons_0b54d5_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-icons_5fa5e3_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-icons_fcdd4a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/excite-bike/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_flat_0_eeeeee_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_flat_55_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-icons_0073ea_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-icons_666666_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-icons_ff0084_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/flick/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_diagonals-small_40_db4865_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_diagonals-small_50_93c3cd_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_diagonals-small_50_ff3853_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_diagonals-small_75_ccd232_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_dots-medium_80_ffff38_4x4.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_dots-small_35_35414f_2x2.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_flat_75_ba9217_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-bg_white-lines_85_f7f7ba_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-icons_88a206_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-icons_c02669_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-icons_e1e463_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-icons_ffeb33_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/hot-sneaks/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_flat_75_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_glass_100_f5f0e5_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_glass_25_cb842e_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_glass_70_ede4d4_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_highlight-hard_100_f4f0ec_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_highlight-hard_65_fee4bd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_highlight-hard_75_f5f5b5_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-bg_inset-soft_100_f4f0ec_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-icons_c47a23_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-icons_cb672b_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-icons_f08000_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-icons_f35f07_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-icons_ff7519_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/humanity/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_diagonals-thick_15_444444_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_diagonals-thick_95_ffdc2e_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_glass_55_fbf5d0_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_highlight-hard_30_285c00_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_highlight-soft_33_3a8104_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_highlight-soft_50_4eb305_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_highlight-soft_60_4ca20b_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-bg_inset-soft_10_285c00_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-icons_4eb305_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-icons_72b42d_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/le-frog/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_glass_15_5f391b_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_gloss-wave_20_1c160d_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_gloss-wave_25_453326_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_gloss-wave_30_44372c_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_highlight-soft_20_201913_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_highlight-soft_20_619226_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-bg_inset-soft_10_201913_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-icons_9bcc60_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-icons_add978_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-icons_e3ddc9_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-icons_f1fd86_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/mint-choc/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_flat_0_eeeeee_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_flat_55_c0402a_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_flat_55_eeeeee_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_glass_35_dddddd_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_glass_60_eeeeee_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_inset-hard_75_999999_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-icons_3383bb_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-icons_70b2e1_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-icons_999999_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/images/ui-icons_fbc856_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/overcast/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_diagonal-maze_40_000000_10x10.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_10_eceadf_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_10_f8f7f6_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_15_eceadf_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_15_f7f3de_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_15_ffffff_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_65_654b24_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-bg_fine-grain_68_b83400_60x60.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-icons_3572ac_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-icons_8c291d_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-icons_b83400_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-icons_fbdb93_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/pepper-grinder/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/redmond/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-icons_2e83ff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-icons_454545_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-icons_888888_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/smoothness/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_glass_55_fcf0ba_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_gloss-wave_100_ece8da_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_highlight-hard_100_fafaf4_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_highlight-hard_15_459e00_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_highlight-hard_95_cccccc_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_highlight-soft_25_67b021_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_highlight-soft_95_ffedad_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-bg_inset-soft_15_2b2922_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-icons_808080_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-icons_847e71_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-icons_8DC262_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-icons_eeeeee_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/south-street/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_flat_55_999999_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_flat_75_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_glass_45_0078ae_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_glass_55_f8da4e_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_glass_75_79c9ec_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_0078ae_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_056b93_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_d8e7f3_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_e0fdff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_f5e175_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_f7a50d_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/images/ui-icons_fcd113_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/start/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/start/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/start/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_diagonals-medium_20_d34d17_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_flat_30_cccccc_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_flat_50_5c5c5c_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_gloss-wave_45_817865_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_gloss-wave_60_fece2f_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_gloss-wave_70_ffdd57_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_gloss-wave_90_fff9e5_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_highlight-soft_100_feeebd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-bg_inset-soft_30_ffffff_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_3d3d3d_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_bd7b00_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_d19405_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_eb990f_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_ed9f26_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_fadc7a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/images/ui-icons_ffe180_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/sunny/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_diamond_10_4f4221_10x8.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_diamond_20_372806_10x8.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_diamond_25_675423_10x8.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_diamond_25_d5ac5d_10x8.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_diamond_8_261803_10x8.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_diamond_8_443113_10x8.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_flat_75_ddd4b0_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-bg_highlight-hard_65_fee4bd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_070603_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_e8e2b5_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_e9cd86_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_efec9f_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_f2ec64_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_f9f2bd_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/images/ui-icons_ff7519_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/swanky-purse/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_diagonals-small_50_262626_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_flat_0_303030_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_flat_0_4c4c4c_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_glass_40_0a0a0a_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_glass_55_f1fbe5_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_glass_60_000000_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_gloss-wave_55_000000_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_gloss-wave_85_9fda58_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-bg_gloss-wave_95_f6ecd5_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-icons_000000_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-icons_1f1f1f_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-icons_9fda58_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-icons_b8ec79_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/trontastic/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_glass_20_555555_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-icons_4b8e0b_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-icons_a83300_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-icons_cccccc_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-darkness/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_flat_10_000000_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-icons_222222_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-icons_228ef1_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-icons_ef8c08_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-icons_ffd27a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/images/ui-icons_ffffff_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/ui-lightness/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/animated-overlay.gif create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_gloss-wave_16_121212_500x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_highlight-hard_15_888888_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_highlight-hard_55_555555_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_highlight-soft_35_adadad_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_highlight-soft_60_dddddd_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-bg_inset-soft_15_121212_1x100.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_666666_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_aaaaaa_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_bbbbbb_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_c98000_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_cccccc_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_cd0a0a_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/images/ui-icons_f29a00_256x240.png create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/jquery-ui.css create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/jquery-ui.min.css create mode 100644 awx/ui/static/lib/jqueryui/themes/vader/jquery.ui.theme.css create mode 100644 awx/ui/static/lib/jqueryui/ui/.jshintrc create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery-ui-i18n.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-af.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ar-DZ.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ar.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-az.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-be.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-bg.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-bs.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ca.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-cs.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-cy-GB.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-da.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-de.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-el.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-en-AU.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-en-GB.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-en-NZ.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-eo.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-es.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-et.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-eu.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-fa.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-fi.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-fo.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-fr-CA.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-fr-CH.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-fr.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-gl.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-he.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-hi.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-hr.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-hu.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-hy.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-id.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-is.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-it.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ja.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ka.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-kk.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-km.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ko.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ky.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-lb.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-lt.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-lv.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-mk.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ml.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ms.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-nb.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-nl-BE.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-nl.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-nn.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-no.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-pl.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-pt-BR.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-pt.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-rm.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ro.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ru.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-sk.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-sl.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-sq.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-sr-SR.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-sr.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-sv.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-ta.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-th.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-tj.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-tr.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-uk.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-vi.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-zh-CN.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-zh-HK.js create mode 100644 awx/ui/static/lib/jqueryui/ui/i18n/jquery.ui.datepicker-zh-TW.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery-ui.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.accordion.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.autocomplete.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.button.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.core.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.datepicker.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.dialog.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.draggable.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.droppable.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-blind.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-bounce.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-clip.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-drop.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-explode.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-fade.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-fold.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-highlight.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-pulsate.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-scale.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-shake.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-slide.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect-transfer.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.effect.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.menu.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.mouse.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.position.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.progressbar.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.resizable.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.selectable.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.slider.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.sortable.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.spinner.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.tabs.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.tooltip.js create mode 100644 awx/ui/static/lib/jqueryui/ui/jquery.ui.widget.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery-ui-i18n.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-af.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ar-DZ.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ar.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-az.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-be.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-bg.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-bs.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ca.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-cs.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-cy-GB.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-da.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-de.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-el.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-en-AU.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-en-GB.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-en-NZ.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-eo.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-es.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-et.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-eu.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-fa.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-fi.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-fo.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-fr-CA.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-fr-CH.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-fr.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-gl.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-he.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-hi.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-hr.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-hu.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-hy.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-id.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-is.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-it.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ja.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ka.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-kk.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-km.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ko.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ky.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-lb.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-lt.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-lv.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-mk.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ml.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ms.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-nb.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-nl-BE.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-nl.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-nn.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-no.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-pl.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-pt-BR.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-pt.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-rm.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ro.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ru.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-sk.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-sl.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-sq.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-sr-SR.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-sr.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-sv.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-ta.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-th.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-tj.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-tr.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-uk.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-vi.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-zh-CN.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-zh-HK.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/i18n/jquery.ui.datepicker-zh-TW.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery-ui.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.accordion.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.autocomplete.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.button.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.core.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.datepicker.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.dialog.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.draggable.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.droppable.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-blind.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-bounce.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-clip.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-drop.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-explode.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-fade.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-fold.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-highlight.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-pulsate.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-scale.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-shake.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-slide.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect-transfer.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.effect.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.menu.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.mouse.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.position.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.progressbar.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.resizable.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.selectable.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.slider.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.sortable.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.spinner.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.tabs.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.tooltip.min.js create mode 100644 awx/ui/static/lib/jqueryui/ui/minified/jquery.ui.widget.min.js create mode 100644 awx/ui/static/lib/less.js/.bower.json create mode 100644 awx/ui/static/lib/less.js/build.gradle create mode 100644 awx/ui/static/lib/less.js/gradle/wrapper/gradle-wrapper.jar create mode 100644 awx/ui/static/lib/less.js/gradle/wrapper/gradle-wrapper.properties create mode 100755 awx/ui/static/lib/less.js/gradlew create mode 100644 awx/ui/static/lib/less.js/gradlew.bat delete mode 100644 awx/ui/static/lib/less/less-1.4.1.min.js create mode 100644 awx/ui/static/lib/select2/.bower.json create mode 100644 awx/ui/static/lib/twitter/.bower.json create mode 100644 awx/ui/static/lib/twitter/Gruntfile.js create mode 100644 awx/ui/static/lib/twitter/LICENSE create mode 100644 awx/ui/static/lib/twitter/README.md create mode 100644 awx/ui/static/lib/twitter/bower.json create mode 100644 awx/ui/static/lib/twitter/browserstack.json create mode 100644 awx/ui/static/lib/twitter/fonts/glyphicons-halflings-regular.eot create mode 100644 awx/ui/static/lib/twitter/fonts/glyphicons-halflings-regular.svg create mode 100644 awx/ui/static/lib/twitter/fonts/glyphicons-halflings-regular.ttf create mode 100644 awx/ui/static/lib/twitter/fonts/glyphicons-halflings-regular.woff create mode 100644 awx/ui/static/lib/twitter/js/affix.js create mode 100644 awx/ui/static/lib/twitter/js/alert.js create mode 100644 awx/ui/static/lib/twitter/js/button.js create mode 100644 awx/ui/static/lib/twitter/js/carousel.js create mode 100644 awx/ui/static/lib/twitter/js/collapse.js create mode 100644 awx/ui/static/lib/twitter/js/dropdown.js create mode 100644 awx/ui/static/lib/twitter/js/modal.js create mode 100644 awx/ui/static/lib/twitter/js/popover.js create mode 100644 awx/ui/static/lib/twitter/js/scrollspy.js create mode 100644 awx/ui/static/lib/twitter/js/tab.js create mode 100644 awx/ui/static/lib/twitter/js/tooltip.js create mode 100644 awx/ui/static/lib/twitter/js/transition.js create mode 100644 awx/ui/static/lib/twitter/less/alerts.less create mode 100644 awx/ui/static/lib/twitter/less/badges.less create mode 100644 awx/ui/static/lib/twitter/less/bootstrap.less create mode 100644 awx/ui/static/lib/twitter/less/breadcrumbs.less create mode 100644 awx/ui/static/lib/twitter/less/button-groups.less create mode 100644 awx/ui/static/lib/twitter/less/buttons.less create mode 100644 awx/ui/static/lib/twitter/less/carousel.less create mode 100644 awx/ui/static/lib/twitter/less/close.less create mode 100644 awx/ui/static/lib/twitter/less/code.less create mode 100644 awx/ui/static/lib/twitter/less/component-animations.less create mode 100644 awx/ui/static/lib/twitter/less/dropdowns.less create mode 100644 awx/ui/static/lib/twitter/less/forms.less create mode 100644 awx/ui/static/lib/twitter/less/glyphicons.less create mode 100644 awx/ui/static/lib/twitter/less/grid.less create mode 100644 awx/ui/static/lib/twitter/less/input-groups.less create mode 100644 awx/ui/static/lib/twitter/less/jumbotron.less create mode 100644 awx/ui/static/lib/twitter/less/labels.less create mode 100644 awx/ui/static/lib/twitter/less/list-group.less create mode 100644 awx/ui/static/lib/twitter/less/media.less create mode 100644 awx/ui/static/lib/twitter/less/mixins.less create mode 100644 awx/ui/static/lib/twitter/less/modals.less create mode 100644 awx/ui/static/lib/twitter/less/navbar.less create mode 100644 awx/ui/static/lib/twitter/less/navs.less create mode 100644 awx/ui/static/lib/twitter/less/normalize.less create mode 100644 awx/ui/static/lib/twitter/less/pager.less create mode 100644 awx/ui/static/lib/twitter/less/pagination.less create mode 100644 awx/ui/static/lib/twitter/less/panels.less create mode 100644 awx/ui/static/lib/twitter/less/popovers.less create mode 100644 awx/ui/static/lib/twitter/less/print.less create mode 100644 awx/ui/static/lib/twitter/less/progress-bars.less create mode 100644 awx/ui/static/lib/twitter/less/responsive-utilities.less create mode 100644 awx/ui/static/lib/twitter/less/scaffolding.less create mode 100644 awx/ui/static/lib/twitter/less/tables.less create mode 100644 awx/ui/static/lib/twitter/less/theme.less create mode 100644 awx/ui/static/lib/twitter/less/thumbnails.less create mode 100644 awx/ui/static/lib/twitter/less/tooltip.less create mode 100644 awx/ui/static/lib/twitter/less/type.less create mode 100644 awx/ui/static/lib/twitter/less/utilities.less create mode 100644 awx/ui/static/lib/twitter/less/variables.less create mode 100644 awx/ui/static/lib/twitter/less/wells.less create mode 100644 awx/ui/static/lib/twitter/package.json create mode 100644 awx/ui/static/lib/twitter/test-infra/README.md create mode 100644 awx/ui/static/lib/twitter/test-infra/npm-shrinkwrap.canonical.json create mode 100644 awx/ui/static/lib/twitter/test-infra/requirements.txt create mode 100755 awx/ui/static/lib/twitter/test-infra/s3_cache.py create mode 100644 awx/ui/static/lib/twitter/test-infra/sauce_browsers.yml create mode 100644 awx/ui/static/lib/twitter/test-infra/shrinkwrap.js create mode 100755 awx/ui/static/lib/twitter/test-infra/uncached-npm-install.sh diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000000..7a5b920bcc --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "awx/ui/static/lib" +} diff --git a/.gitignore b/.gitignore index 5538679ba9..1eb3946561 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ awx/projects awx/job_status awx/public/media awx/public/static -awx/ui/static/js/awx-min.js +awx/ui/static/js/awx.min.js awx/ui/static/css/awx.min.css env/* node_modules/** diff --git a/Gruntfile.js b/Gruntfile.js index 2765d65d13..3d2aa16892 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -11,15 +11,26 @@ module.exports = function(grunt) { uses_defaults: ['awx/ui/static/js/*','awx/ui/static/lib/ansible/*', '!awx/ui/static/js/awx-min.js'] }, - uglify: { + uglify: { options: { banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %> */' - }, + }, my_target: { files: { - 'awx/ui/static/js/awx-min.js': ['awx/ui/static/js/**/*.js', 'awx/ui/static/lib/ansible/*.js', - '!awx/ui/static/js/awx-min.js'] + 'awx/ui/static/js/awx-min.js': ['awx/ui/static/js/**/*.js', 'awx/ui/static/lib/ansible/*.js', + '!awx/ui/static/js/awx.min.js'] + } + } + }, + + less: { + production: { + options: { + cleancss: true + }, + files: { + "awx/ui/static/css/awx.min.css": "awx/ui/static/less/ansible-ui.less" } } } @@ -27,6 +38,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-less'); - grunt.registerTask('default', ['jshint', 'uglify']); + grunt.registerTask('default', ['jshint', 'uglify', 'less']); } diff --git a/awx/ui/static/css/bootstrap-theme.css b/awx/ui/static/css/bootstrap-theme.css deleted file mode 100644 index ad11735693..0000000000 --- a/awx/ui/static/css/bootstrap-theme.css +++ /dev/null @@ -1,384 +0,0 @@ -.btn-default, -.btn-primary, -.btn-success, -.btn-info, -.btn-warning, -.btn-danger { - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.btn-default:active, -.btn-primary:active, -.btn-success:active, -.btn-info:active, -.btn-warning:active, -.btn-danger:active, -.btn-default.active, -.btn-primary.active, -.btn-success.active, -.btn-info.active, -.btn-warning.active, -.btn-danger.active { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn:active, -.btn.active { - background-image: none; -} - -.btn-default { - text-shadow: 0 1px 0 #fff; - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, 0%, #e6e6e6, 100%); - background-image: -moz-linear-gradient(top, #ffffff 0%, #e6e6e6 100%); - background-image: linear-gradient(to bottom, #ffffff 0%, #e6e6e6 100%); - background-repeat: repeat-x; - border-color: #e0e0e0; - border-color: #ccc; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); -} - -.btn-default:active, -.btn-default.active { - background-color: #e6e6e6; - border-color: #e0e0e0; -} - -.btn-primary { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); - background-repeat: repeat-x; - border-color: #2d6ca2; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); -} - -.btn-primary:active, -.btn-primary.active { - background-color: #3071a9; - border-color: #2d6ca2; -} - -.btn-success { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44)); - background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%); - background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%); - background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); - background-repeat: repeat-x; - border-color: #419641; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); -} - -.btn-success:active, -.btn-success.active { - background-color: #449d44; - border-color: #419641; -} - -.btn-warning { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f)); - background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%); - background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); - background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); - background-repeat: repeat-x; - border-color: #eb9316; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); -} - -.btn-warning:active, -.btn-warning.active { - background-color: #ec971f; - border-color: #eb9316; -} - -.btn-danger { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c)); - background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%); - background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%); - background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); - background-repeat: repeat-x; - border-color: #c12e2a; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); -} - -.btn-danger:active, -.btn-danger.active { - background-color: #c9302c; - border-color: #c12e2a; -} - -.btn-info { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5)); - background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%); - background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); - background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); - background-repeat: repeat-x; - border-color: #2aabd2; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); -} - -.btn-info:active, -.btn-info.active { - background-color: #31b0d5; - border-color: #2aabd2; -} - -.thumbnail, -.img-thumbnail { - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - background-color: #357ebd; - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); -} - -.navbar { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#f8f8f8)); - background-image: -webkit-linear-gradient(top, #ffffff, 0%, #f8f8f8, 100%); - background-image: -moz-linear-gradient(top, #ffffff 0%, #f8f8f8 100%); - background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%); - background-repeat: repeat-x; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); -} - -.navbar .navbar-nav > .active > a { - background-color: #f8f8f8; -} - -.navbar-brand, -.navbar-nav > li > a { - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); -} - -.navbar-inverse { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#3c3c3c), to(#222222)); - background-image: -webkit-linear-gradient(top, #3c3c3c, 0%, #222222, 100%); - background-image: -moz-linear-gradient(top, #3c3c3c 0%, #222222 100%); - background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); -} - -.navbar-inverse .navbar-nav > .active > a { - background-color: #222222; -} - -.navbar-inverse .navbar-brand, -.navbar-inverse .navbar-nav > li > a { - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} - -.navbar-static-top, -.navbar-fixed-top, -.navbar-fixed-bottom { - border-radius: 0; -} - -.alert { - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.alert-success { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#c8e5bc)); - background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #c8e5bc, 100%); - background-image: -moz-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); - background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); - background-repeat: repeat-x; - border-color: #b2dba1; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); -} - -.alert-info { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#b9def0)); - background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #b9def0, 100%); - background-image: -moz-linear-gradient(top, #d9edf7 0%, #b9def0 100%); - background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); - background-repeat: repeat-x; - border-color: #9acfea; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); -} - -.alert-warning { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#f8efc0)); - background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #f8efc0, 100%); - background-image: -moz-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); - background-repeat: repeat-x; - border-color: #f5e79e; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); -} - -.alert-danger { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#e7c3c3)); - background-image: -webkit-linear-gradient(top, #f2dede, 0%, #e7c3c3, 100%); - background-image: -moz-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); - background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); - background-repeat: repeat-x; - border-color: #dca7a7; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); -} - -.progress { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ebebeb), to(#f5f5f5)); - background-image: -webkit-linear-gradient(top, #ebebeb, 0%, #f5f5f5, 100%); - background-image: -moz-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); - background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); -} - -.progress-bar { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); -} - -.progress-bar-success { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44)); - background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%); - background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%); - background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); -} - -.progress-bar-info { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5)); - background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%); - background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); - background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); -} - -.progress-bar-warning { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f)); - background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%); - background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); - background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); -} - -.progress-bar-danger { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c)); - background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%); - background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%); - background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); -} - -.list-group { - border-radius: 4px; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); -} - -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - text-shadow: 0 -1px 0 #3071a9; - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3278b3)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #3278b3, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #3278b3 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); - background-repeat: repeat-x; - border-color: #3278b3; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); -} - -.panel { - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.panel-default > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f5f5f5), to(#e8e8e8)); - background-image: -webkit-linear-gradient(top, #f5f5f5, 0%, #e8e8e8, 100%); - background-image: -moz-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); - background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); -} - -.panel-primary > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); -} - -.panel-success > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#d0e9c6)); - background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #d0e9c6, 100%); - background-image: -moz-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); - background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); -} - -.panel-info > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#c4e3f3)); - background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #c4e3f3, 100%); - background-image: -moz-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); - background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); -} - -.panel-warning > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#faf2cc)); - background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #faf2cc, 100%); - background-image: -moz-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); -} - -.panel-danger > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#ebcccc)); - background-image: -webkit-linear-gradient(top, #f2dede, 0%, #ebcccc, 100%); - background-image: -moz-linear-gradient(top, #f2dede 0%, #ebcccc 100%); - background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); -} - -.well { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#e8e8e8), to(#f5f5f5)); - background-image: -webkit-linear-gradient(top, #e8e8e8, 0%, #f5f5f5, 100%); - background-image: -moz-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); - background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); - background-repeat: repeat-x; - border-color: #dcdcdc; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); - -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); -} \ No newline at end of file diff --git a/awx/ui/static/css/bootstrap-theme.min.css b/awx/ui/static/css/bootstrap-theme.min.css deleted file mode 100644 index cad36b4e60..0000000000 --- a/awx/ui/static/css/bootstrap-theme.min.css +++ /dev/null @@ -1 +0,0 @@ -.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,0%,#e6e6e6,100%);background-image:-moz-linear-gradient(top,#fff 0,#e6e6e6 100%);background-image:linear-gradient(to bottom,#fff 0,#e6e6e6 100%);background-repeat:repeat-x;border-color:#e0e0e0;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0)}.btn-default:active,.btn-default.active{background-color:#e6e6e6;border-color:#e0e0e0}.btn-primary{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;border-color:#2d6ca2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.btn-primary:active,.btn-primary.active{background-color:#3071a9;border-color:#2d6ca2}.btn-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;border-color:#419641;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.btn-success:active,.btn-success.active{background-color:#449d44;border-color:#419641}.btn-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;border-color:#eb9316;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.btn-warning:active,.btn-warning.active{background-color:#ec971f;border-color:#eb9316}.btn-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;border-color:#c12e2a;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.btn-danger:active,.btn-danger.active{background-color:#c9302c;border-color:#c12e2a}.btn-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;border-color:#2aabd2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.btn-info:active,.btn-info.active{background-color:#31b0d5;border-color:#2aabd2}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.navbar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#f8f8f8));background-image:-webkit-linear-gradient(top,#fff,0%,#f8f8f8,100%);background-image:-moz-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff8f8f8',GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar .navbar-nav>.active>a{background-color:#f8f8f8}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-gradient(linear,left 0,left 100%,from(#3c3c3c),to(#222));background-image:-webkit-linear-gradient(top,#3c3c3c,0%,#222,100%);background-image:-moz-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c',endColorstr='#ff222222',GradientType=0)}.navbar-inverse .navbar-nav>.active>a{background-color:#222}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#c8e5bc));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#c8e5bc,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;border-color:#b2dba1;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffc8e5bc',GradientType=0)}.alert-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#b9def0));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#b9def0,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffb9def0',GradientType=0)}.alert-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#f8efc0));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#f8efc0,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;border-color:#f5e79e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fff8efc0',GradientType=0)}.alert-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#e7c3c3));background-image:-webkit-linear-gradient(top,#f2dede,0%,#e7c3c3,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;border-color:#dca7a7;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffe7c3c3',GradientType=0)}.progress{background-image:-webkit-gradient(linear,left 0,left 100%,from(#ebebeb),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#ebebeb,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff5f5f5',GradientType=0)}.progress-bar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.progress-bar-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.progress-bar-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.progress-bar-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.progress-bar-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3278b3));background-image:-webkit-linear-gradient(top,#428bca,0%,#3278b3,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3278b3',GradientType=0)}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f5f5f5),to(#e8e8e8));background-image:-webkit-linear-gradient(top,#f5f5f5,0%,#e8e8e8,100%);background-image:-moz-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#d0e9c6));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#d0e9c6,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffd0e9c6',GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#c4e3f3));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#c4e3f3,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffc4e3f3',GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#faf2cc));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#faf2cc,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fffaf2cc',GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#ebcccc));background-image:-webkit-linear-gradient(top,#f2dede,0%,#ebcccc,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffebcccc',GradientType=0)}.well{background-image:-webkit-gradient(linear,left 0,left 100%,from(#e8e8e8),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#e8e8e8,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} \ No newline at end of file diff --git a/awx/ui/static/css/bootstrap.css b/awx/ui/static/css/bootstrap.css deleted file mode 100644 index e34f1e1710..0000000000 --- a/awx/ui/static/css/bootstrap.css +++ /dev/null @@ -1,6805 +0,0 @@ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - */ - -/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ - -article, -aside,.table -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -audio, -canvas, -video { - display: inline-block; -} - -audio:not([controls]) { - display: none; - height: 0; -} - -[hidden] { - display: none; -} - -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -body { - margin: 0; -} - -a:focus { - outline: thin dotted; -} - -a:active, -a:hover { - outline: 0; -} - -h1 { - margin: 0.67em 0; - font-size: 2em; -} - -abbr[title] { - border-bottom: 1px dotted; -} - -b, -strong { - font-weight: bold; -} - -dfn { - font-style: italic; -} - -hr { - height: 0; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -mark { - color: #000; - background: #ff0; -} - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -pre { - white-space: pre-wrap; -} - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -small { - font-size: 80%; -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - border: 0; -} - -svg:not(:root) { - overflow: hidden; -} - -figure { - margin: 0; -} - -fieldset { - padding: 0.35em 0.625em 0.75em; - margin: 0 2px; - border: 1px solid #c0c0c0; -} - -legend { - padding: 0; - border: 0; -} - -button, -input, -select, -textarea { - margin: 0; - font-family: inherit; - font-size: 100%; -} - -button, -input { - line-height: normal; -} - -button, -select { - text-transform: none; -} - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -button[disabled], -html input[disabled] { - cursor: default; -} - -input[type="checkbox"], -input[type="radio"] { - padding: 0; - box-sizing: border-box; -} - -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -@media print { - * { - color: #000 !important; - text-shadow: none !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 2cm .5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - .navbar { - display: none; - } - .table td, - .table th { - background-color: #fff !important; - } - .btn > .caret, - .dropup > .btn > .caret { - border-top-color: #000 !important; - } - .label { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } -} - -*, -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - font-size: 62.5%; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.428571429; - color: #333333; - background-color: #ffffff; -} - -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -button, -input, -select[multiple], -textarea { - background-image: none; -} - -a { - color: #428bca; - text-decoration: none; -} - -a:hover, -a:focus { - color: #2a6496; - text-decoration: underline; -} - -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -img { - vertical-align: middle; -} - -.img-responsive { - display: block; - height: auto; - max-width: 100%; -} - -.img-rounded { - border-radius: 6px; -} - -.img-thumbnail { - display: inline-block; - height: auto; - max-width: 100%; - padding: 4px; - line-height: 1.428571429; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -.img-circle { - border-radius: 50%; -} - -hr { - margin-top: 20px; - margin-bottom: 20px; - border: 0; - border-top: 1px solid #eeeeee; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0 0 0 0); - border: 0; -} - -p { - margin: 0 0 10px; -} - -.lead { - margin-bottom: 20px; - font-size: 16.099999999999998px; - font-weight: 200; - line-height: 1.4; -} - -@media (min-width: 768px) { - .lead { - font-size: 21px; - } -} - -small { - font-size: 85%; -} - -cite { - font-style: normal; -} - -.text-muted { - color: #999999; -} - -.text-primary { - color: #428bca; -} - -.text-warning { - color: #c09853; -} - -.text-danger { - color: #b94a48; -} - -.text-success { - color: #468847; -} - -.text-info { - color: #3a87ad; -} - -.text-left { - text-align: left; -} - -.text-right { - text-align: right; -} - -.text-center { - text-align: center; -} - -h1, -h2, -h3, -h4, -h5, -h6, -.h1, -.h2, -.h3, -.h4, -.h5, -.h6 { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-weight: 500; - line-height: 1.1; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small, -.h1 small, -.h2 small, -.h3 small, -.h4 small, -.h5 small, -.h6 small { - font-weight: normal; - line-height: 1; - color: #999999; -} - -h1, -h2, -h3 { - margin-top: 20px; - margin-bottom: 10px; -} - -h4, -h5, -h6 { - margin-top: 10px; - margin-bottom: 10px; -} - -h1, -.h1 { - font-size: 36px; -} - -h2, -.h2 { - font-size: 30px; -} - -h3, -.h3 { - font-size: 24px; -} - -h4, -.h4 { - font-size: 18px; -} - -h5, -.h5 { - font-size: 14px; -} - -h6, -.h6 { - font-size: 12px; -} - -h1 small, -.h1 small { - font-size: 24px; -} - -h2 small, -.h2 small { - font-size: 18px; -} - -h3 small, -.h3 small, -h4 small, -.h4 small { - font-size: 14px; -} - -.page-header { - padding-bottom: 9px; - margin: 40px 0 20px; - border-bottom: 1px solid #eeeeee; -} - -ul, -ol { - margin-top: 0; - margin-bottom: 10px; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -.list-unstyled { - padding-left: 0; - list-style: none; -} - -.list-inline { - padding-left: 0; - list-style: none; -} - -.list-inline > li { - display: inline-block; - padding-right: 5px; - padding-left: 5px; -} - -dl { - margin-bottom: 20px; -} - -dt, -dd { - line-height: 1.428571429; -} - -dt { - font-weight: bold; -} - -dd { - margin-left: 0; -} - -@media (min-width: 768px) { - .dl-horizontal dt { - float: left; - width: 160px; - overflow: hidden; - clear: left; - text-align: right; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } - .dl-horizontal dd:before, - .dl-horizontal dd:after { - display: table; - content: " "; - } - .dl-horizontal dd:after { - clear: both; - } - .dl-horizontal dd:before, - .dl-horizontal dd:after { - display: table; - content: " "; - } - .dl-horizontal dd:after { - clear: both; - } -} - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; -} - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -blockquote { - padding: 10px 20px; - margin: 0 0 20px; - border-left: 5px solid #eeeeee; -} - -blockquote p { - font-size: 17.5px; - font-weight: 300; - line-height: 1.25; -} - -blockquote p:last-child { - margin-bottom: 0; -} - -blockquote small { - display: block; - line-height: 1.428571429; - color: #999999; -} - -blockquote small:before { - content: '\2014 \00A0'; -} - -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; -} - -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} - -blockquote.pull-right small:before { - content: ''; -} - -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 1.428571429; -} - -code, -pre { - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; -} - -code { - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - white-space: nowrap; - background-color: #f9f2f4; - border-radius: 4px; -} - -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 1.428571429; - color: #333333; - word-break: break-all; - word-wrap: break-word; - background-color: #f5f5f5; - border: 1px solid #cccccc; - border-radius: 4px; -} - -pre.prettyprint { - margin-bottom: 20px; -} - -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} - -.container { - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto; -} - -.container:before, -.container:after { - display: table; - content: " "; -} - -.container:after { - clear: both; -} - -.container:before, -.container:after { - display: table; - content: " "; -} - -.container:after { - clear: both; -} - -.row { - margin-right: -15px; - margin-left: -15px; -} - -.row:before, -.row:after { - display: table; - content: " "; -} - -.row:after { - clear: both; -} - -.row:before, -.row:after { - display: table; - content: " "; -} - -.row:after { - clear: both; -} - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11, -.col-xs-12, -.col-sm-1, -.col-sm-2, -.col-sm-3, -.col-sm-4, -.col-sm-5, -.col-sm-6, -.col-sm-7, -.col-sm-8, -.col-sm-9, -.col-sm-10, -.col-sm-11, -.col-sm-12, -.col-md-1, -.col-md-2, -.col-md-3, -.col-md-4, -.col-md-5, -.col-md-6, -.col-md-7, -.col-md-8, -.col-md-9, -.col-md-10, -.col-md-11, -.col-md-12, -.col-lg-1, -.col-lg-2, -.col-lg-3, -.col-lg-4, -.col-lg-5, -.col-lg-6, -.col-lg-7, -.col-lg-8, -.col-lg-9, -.col-lg-10, -.col-lg-11, -.col-lg-12 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px; -} - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11 { - float: left; -} - -.col-xs-1 { - width: 8.333333333333332%; -} - -.col-xs-2 { - width: 16.666666666666664%; -} - -.col-xs-3 { - width: 25%; -} - -.col-xs-4 { - width: 33.33333333333333%; -} - -.col-xs-5 { - width: 41.66666666666667%; -} - -.col-xs-6 { - width: 50%; -} - -.col-xs-7 { - width: 58.333333333333336%; -} - -.col-xs-8 { - width: 66.66666666666666%; -} - -.col-xs-9 { - width: 75%; -} - -.col-xs-10 { - width: 83.33333333333334%; -} - -.col-xs-11 { - width: 91.66666666666666%; -} - -.col-xs-12 { - width: 100%; -} - -@media (min-width: 768px) { - .container { - max-width: 750px; - } - .col-sm-1, - .col-sm-2, - .col-sm-3, - .col-sm-4, - .col-sm-5, - .col-sm-6, - .col-sm-7, - .col-sm-8, - .col-sm-9, - .col-sm-10, - .col-sm-11 { - float: left; - } - .col-sm-1 { - width: 8.333333333333332%; - } - .col-sm-2 { - width: 16.666666666666664%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-4 { - width: 33.33333333333333%; - } - .col-sm-5 { - width: 41.66666666666667%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-7 { - width: 58.333333333333336%; - } - .col-sm-8 { - width: 66.66666666666666%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-10 { - width: 83.33333333333334%; - } - .col-sm-11 { - width: 91.66666666666666%; - } - .col-sm-12 { - width: 100%; - } - .col-sm-push-1 { - left: 8.333333333333332%; - } - .col-sm-push-2 { - left: 16.666666666666664%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-4 { - left: 33.33333333333333%; - } - .col-sm-push-5 { - left: 41.66666666666667%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-7 { - left: 58.333333333333336%; - } - .col-sm-push-8 { - left: 66.66666666666666%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-10 { - left: 83.33333333333334%; - } - .col-sm-push-11 { - left: 91.66666666666666%; - } - .col-sm-pull-1 { - right: 8.333333333333332%; - } - .col-sm-pull-2 { - right: 16.666666666666664%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-4 { - right: 33.33333333333333%; - } - .col-sm-pull-5 { - right: 41.66666666666667%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-7 { - right: 58.333333333333336%; - } - .col-sm-pull-8 { - right: 66.66666666666666%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-10 { - right: 83.33333333333334%; - } - .col-sm-pull-11 { - right: 91.66666666666666%; - } - .col-sm-offset-1 { - margin-left: 8.333333333333332%; - } - .col-sm-offset-2 { - margin-left: 16.666666666666664%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-4 { - margin-left: 33.33333333333333%; - } - .col-sm-offset-5 { - margin-left: 41.66666666666667%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-7 { - margin-left: 58.333333333333336%; - } - .col-sm-offset-8 { - margin-left: 66.66666666666666%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-10 { - margin-left: 83.33333333333334%; - } - .col-sm-offset-11 { - margin-left: 91.66666666666666%; - } -} - -@media (min-width: 992px) { - .container { - max-width: 970px; - } - .col-md-1, - .col-md-2, - .col-md-3, - .col-md-4, - .col-md-5, - .col-md-6, - .col-md-7, - .col-md-8, - .col-md-9, - .col-md-10, - .col-md-11 { - float: left; - } - .col-md-1 { - width: 8.333333333333332%; - } - .col-md-2 { - width: 16.666666666666664%; - } - .col-md-3 { - width: 25%; - } - .col-md-4 { - width: 33.33333333333333%; - } - .col-md-5 { - width: 41.66666666666667%; - } - .col-md-6 { - width: 50%; - } - .col-md-7 { - width: 58.333333333333336%; - } - .col-md-8 { - width: 66.66666666666666%; - } - .col-md-9 { - width: 75%; - } - .col-md-10 { - width: 83.33333333333334%; - } - .col-md-11 { - width: 91.66666666666666%; - } - .col-md-12 { - width: 100%; - } - .col-md-push-0 { - left: auto; - } - .col-md-push-1 { - left: 8.333333333333332%; - } - .col-md-push-2 { - left: 16.666666666666664%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-4 { - left: 33.33333333333333%; - } - .col-md-push-5 { - left: 41.66666666666667%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-7 { - left: 58.333333333333336%; - } - .col-md-push-8 { - left: 66.66666666666666%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-10 { - left: 83.33333333333334%; - } - .col-md-push-11 { - left: 91.66666666666666%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-pull-1 { - right: 8.333333333333332%; - } - .col-md-pull-2 { - right: 16.666666666666664%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-4 { - right: 33.33333333333333%; - } - .col-md-pull-5 { - right: 41.66666666666667%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-7 { - right: 58.333333333333336%; - } - .col-md-pull-8 { - right: 66.66666666666666%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-10 { - right: 83.33333333333334%; - } - .col-md-pull-11 { - right: 91.66666666666666%; - } - .col-md-offset-0 { - margin-left: 0; - } - .col-md-offset-1 { - margin-left: 8.333333333333332%; - } - .col-md-offset-2 { - margin-left: 16.666666666666664%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-4 { - margin-left: 33.33333333333333%; - } - .col-md-offset-5 { - margin-left: 41.66666666666667%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-7 { - margin-left: 58.333333333333336%; - } - .col-md-offset-8 { - margin-left: 66.66666666666666%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-10 { - margin-left: 83.33333333333334%; - } - .col-md-offset-11 { - margin-left: 91.66666666666666%; - } -} - -@media (min-width: 1200px) { - .container { - max-width: 1170px; - } - .col-lg-1, - .col-lg-2, - .col-lg-3, - .col-lg-4, - .col-lg-5, - .col-lg-6, - .col-lg-7, - .col-lg-8, - .col-lg-9, - .col-lg-10, - .col-lg-11 { - float: left; - } - .col-lg-1 { - width: 8.333333333333332%; - } - .col-lg-2 { - width: 16.666666666666664%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-4 { - width: 33.33333333333333%; - } - .col-lg-5 { - width: 41.66666666666667%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-7 { - width: 58.333333333333336%; - } - .col-lg-8 { - width: 66.66666666666666%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-10 { - width: 83.33333333333334%; - } - .col-lg-11 { - width: 91.66666666666666%; - } - .col-lg-12 { - width: 100%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-push-1 { - left: 8.333333333333332%; - } - .col-lg-push-2 { - left: 16.666666666666664%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-4 { - left: 33.33333333333333%; - } - .col-lg-push-5 { - left: 41.66666666666667%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-7 { - left: 58.333333333333336%; - } - .col-lg-push-8 { - left: 66.66666666666666%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-10 { - left: 83.33333333333334%; - } - .col-lg-push-11 { - left: 91.66666666666666%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-pull-1 { - right: 8.333333333333332%; - } - .col-lg-pull-2 { - right: 16.666666666666664%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-4 { - right: 33.33333333333333%; - } - .col-lg-pull-5 { - right: 41.66666666666667%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-7 { - right: 58.333333333333336%; - } - .col-lg-pull-8 { - right: 66.66666666666666%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-10 { - right: 83.33333333333334%; - } - .col-lg-pull-11 { - right: 91.66666666666666%; - } - .col-lg-offset-0 { - margin-left: 0; - } - .col-lg-offset-1 { - margin-left: 8.333333333333332%; - } - .col-lg-offset-2 { - margin-left: 16.666666666666664%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-4 { - margin-left: 33.33333333333333%; - } - .col-lg-offset-5 { - margin-left: 41.66666666666667%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-7 { - margin-left: 58.333333333333336%; - } - .col-lg-offset-8 { - margin-left: 66.66666666666666%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-10 { - margin-left: 83.33333333333334%; - } - .col-lg-offset-11 { - margin-left: 91.66666666666666%; - } -} - -table { - max-width: 100%; - background-color: transparent; -} - -th { - text-align: left; -} - -.table { - width: 100%; - margin-bottom: 20px; -} - -.table thead > tr > th, -.table tbody > tr > th, -.table tfoot > tr > th, -.table thead > tr > td, -.table tbody > tr > td, -.table tfoot > tr > td { - padding: 8px; - line-height: 1.428571429; - vertical-align: top; - border-top: 1px solid #dddddd; -} - -.table thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #dddddd; -} - -.table caption + thead tr:first-child th, -.table colgroup + thead tr:first-child th, -.table thead:first-child tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child td { - border-top: 0; -} - -.table tbody + tbody { - border-top: 2px solid #dddddd; -} - -.table .table { - background-color: #ffffff; -} - -.table-condensed thead > tr > th, -.table-condensed tbody > tr > th, -.table-condensed tfoot > tr > th, -.table-condensed thead > tr > td, -.table-condensed tbody > tr > td, -.table-condensed tfoot > tr > td { - padding: 5px; -} - -.table-bordered { - border: 1px solid #dddddd; -} - -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #dddddd; -} - -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - border-bottom-width: 2px; -} - -.table-striped > tbody > tr:nth-child(odd) > td, -.table-striped > tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} - -.table-hover > tbody > tr:hover > td, -.table-hover > tbody > tr:hover > th { - background-color: #f5f5f5; -} - -table col[class*="col-"] { - display: table-column; - float: none; -} - -table td[class*="col-"], -table th[class*="col-"] { - display: table-cell; - float: none; -} - -.table > thead > tr > td.active, -.table > tbody > tr > td.active, -.table > tfoot > tr > td.active, -.table > thead > tr > th.active, -.table > tbody > tr > th.active, -.table > tfoot > tr > th.active, -.table > thead > tr.active > td, -.table > tbody > tr.active > td, -.table > tfoot > tr.active > td, -.table > thead > tr.active > th, -.table > tbody > tr.active > th, -.table > tfoot > tr.active > th { - background-color: #f5f5f5; -} - -.table > thead > tr > td.success, -.table > tbody > tr > td.success, -.table > tfoot > tr > td.success, -.table > thead > tr > th.success, -.table > tbody > tr > th.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > tbody > tr.success > td, -.table > tfoot > tr.success > td, -.table > thead > tr.success > th, -.table > tbody > tr.success > th, -.table > tfoot > tr.success > th { - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.table-hover > tbody > tr > td.success:hover, -.table-hover > tbody > tr > th.success:hover, -.table-hover > tbody > tr.success:hover > td { - background-color: #d0e9c6; - border-color: #c9e2b3; -} - -.table > thead > tr > td.danger, -.table > tbody > tr > td.danger, -.table > tfoot > tr > td.danger, -.table > thead > tr > th.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > tbody > tr.danger > td, -.table > tfoot > tr.danger > td, -.table > thead > tr.danger > th, -.table > tbody > tr.danger > th, -.table > tfoot > tr.danger > th { - background-color: #f2dede; - border-color: #eed3d7; -} - -.table-hover > tbody > tr > td.danger:hover, -.table-hover > tbody > tr > th.danger:hover, -.table-hover > tbody > tr.danger:hover > td { - background-color: #ebcccc; - border-color: #e6c1c7; -} - -.table > thead > tr > td.warning, -.table > tbody > tr > td.warning, -.table > tfoot > tr > td.warning, -.table > thead > tr > th.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > tbody > tr.warning > td, -.table > tfoot > tr.warning > td, -.table > thead > tr.warning > th, -.table > tbody > tr.warning > th, -.table > tfoot > tr.warning > th { - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.table-hover > tbody > tr > td.warning:hover, -.table-hover > tbody > tr > th.warning:hover, -.table-hover > tbody > tr.warning:hover > td { - background-color: #faf2cc; - border-color: #f8e5be; -} - -@media (max-width: 768px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-x: scroll; - overflow-y: hidden; - border: 1px solid #dddddd; - } - .table-responsive > .table { - margin-bottom: 0; - background-color: #fff; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > thead > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > thead > tr:last-child > td, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: inherit; - color: #333333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} - -label { - display: inline-block; - margin-bottom: 5px; - font-weight: bold; -} - -input[type="search"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - /* IE8-9 */ - - line-height: normal; -} - -input[type="file"] { - display: block; -} - -select[multiple], -select[size] { - height: auto; -} - -select optgroup { - font-family: inherit; - font-size: inherit; - font-style: inherit; -} - -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -input[type="number"]::-webkit-outer-spin-button, -input[type="number"]::-webkit-inner-spin-button { - height: auto; -} - -.form-control:-moz-placeholder { - color: #999999; -} - -.form-control::-moz-placeholder { - color: #999999; -} - -.form-control:-ms-input-placeholder { - color: #999999; -} - -.form-control::-webkit-input-placeholder { - color: #999999; -} - -.form-control { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.428571429; - color: #555555; - vertical-align: middle; - background-color: #ffffff; - border: 1px solid #cccccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; - transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; -} - -.form-control:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); -} - -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - cursor: not-allowed; - background-color: #eeeeee; -} - -textarea.form-control { - height: auto; -} - -.form-group { - margin-bottom: 15px; -} - -.radio, -.checkbox { - display: block; - min-height: 20px; - padding-left: 20px; - margin-top: 10px; - margin-bottom: 10px; - vertical-align: middle; -} - -.radio label, -.checkbox label { - display: inline; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; -} - -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - float: left; - margin-left: -20px; -} - -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; -} - -.radio-inline, -.checkbox-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - vertical-align: middle; - cursor: pointer; -} - -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; -} - -input[type="radio"][disabled], -input[type="checkbox"][disabled], -.radio[disabled], -.radio-inline[disabled], -.checkbox[disabled], -.checkbox-inline[disabled], -fieldset[disabled] input[type="radio"], -fieldset[disabled] input[type="checkbox"], -fieldset[disabled] .radio, -fieldset[disabled] .radio-inline, -fieldset[disabled] .checkbox, -fieldset[disabled] .checkbox-inline { - cursor: not-allowed; -} - -.input-sm { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -select.input-sm { - height: 30px; - line-height: 30px; -} - -textarea.input-sm { - height: auto; -} - -.input-lg { - height: 45px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -select.input-lg { - height: 45px; - line-height: 45px; -} - -textarea.input-lg { - height: auto; -} - -.has-warning .help-block, -.has-warning .control-label { - color: #c09853; -} - -.has-warning .form-control { - border-color: #c09853; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-warning .form-control:focus { - border-color: #a47e3c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; -} - -.has-warning .input-group-addon { - color: #c09853; - background-color: #fcf8e3; - border-color: #c09853; -} - -.has-error .help-block, -.has-error .control-label { - color: #b94a48; -} - -.has-error .form-control { - border-color: #b94a48; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-error .form-control:focus { - border-color: #953b39; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; -} - -.has-error .input-group-addon { - color: #b94a48; - background-color: #f2dede; - border-color: #b94a48; -} - -.has-success .help-block, -.has-success .control-label { - color: #468847; -} - -.has-success .form-control { - border-color: #468847; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-success .form-control:focus { - border-color: #356635; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; -} - -.has-success .input-group-addon { - color: #468847; - background-color: #dff0d8; - border-color: #468847; -} - -.form-control-static { - padding-top: 7px; - margin-bottom: 0; -} - -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #737373; -} - -@media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - padding-left: 0; - margin-top: 0; - margin-bottom: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } -} - -.form-horizontal .control-label, -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - padding-top: 7px; - margin-top: 0; - margin-bottom: 0; -} - -.form-horizontal .form-group { - margin-right: -15px; - margin-left: -15px; -} - -.form-horizontal .form-group:before, -.form-horizontal .form-group:after { - display: table; - content: " "; -} - -.form-horizontal .form-group:after { - clear: both; -} - -.form-horizontal .form-group:before, -.form-horizontal .form-group:after { - display: table; - content: " "; -} - -.form-horizontal .form-group:after { - clear: both; -} - -@media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - } -} - -.btn { - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: normal; - line-height: 1.428571429; - text-align: center; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - border: 1px solid transparent; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn:hover, -.btn:focus { - color: #333333; - text-decoration: none; -} - -.btn:active, -.btn.active { - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - pointer-events: none; - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} - -.btn-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; -} - -.btn-default:hover, -.btn-default:focus, -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - color: #333333; - background-color: #ebebeb; - border-color: #adadad; -} - -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - background-image: none; -} - -.btn-default.disabled, -.btn-default[disabled], -fieldset[disabled] .btn-default, -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled:active, -.btn-default[disabled]:active, -fieldset[disabled] .btn-default:active, -.btn-default.disabled.active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default.active { - background-color: #ffffff; - border-color: #cccccc; -} - -.btn-primary { - color: #ffffff; - background-color: #428bca; - border-color: #357ebd; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #3276b1; - border-color: #285e8e; -} - -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-image: none; -} - -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { - background-color: #428bca; - border-color: #357ebd; -} - -.btn-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: #eea236; -} - -.btn-warning:hover, -.btn-warning:focus, -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ed9c28; - border-color: #d58512; -} - -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - background-image: none; -} - -.btn-warning.disabled, -.btn-warning[disabled], -fieldset[disabled] .btn-warning, -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled:active, -.btn-warning[disabled]:active, -fieldset[disabled] .btn-warning:active, -.btn-warning.disabled.active, -.btn-warning[disabled].active, -fieldset[disabled] .btn-warning.active { - background-color: #f0ad4e; - border-color: #eea236; -} - -.btn-danger { - color: #ffffff; - background-color: #d9534f; - border-color: #d43f3a; -} - -.btn-danger:hover, -.btn-danger:focus, -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #d2322d; - border-color: #ac2925; -} - -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - background-image: none; -} - -.btn-danger.disabled, -.btn-danger[disabled], -fieldset[disabled] .btn-danger, -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled:active, -.btn-danger[disabled]:active, -fieldset[disabled] .btn-danger:active, -.btn-danger.disabled.active, -.btn-danger[disabled].active, -fieldset[disabled] .btn-danger.active { - background-color: #d9534f; - border-color: #d43f3a; -} - -.btn-success { - color: #ffffff; - background-color: #5cb85c; - border-color: #4cae4c; -} - -.btn-success:hover, -.btn-success:focus, -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #47a447; - border-color: #398439; -} - -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - background-image: none; -} - -.btn-success.disabled, -.btn-success[disabled], -fieldset[disabled] .btn-success, -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled:active, -.btn-success[disabled]:active, -fieldset[disabled] .btn-success:active, -.btn-success.disabled.active, -.btn-success[disabled].active, -fieldset[disabled] .btn-success.active { - background-color: #5cb85c; - border-color: #4cae4c; -} - -.btn-info { - color: #ffffff; - background-color: #5bc0de; - border-color: #46b8da; -} - -.btn-info:hover, -.btn-info:focus, -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #39b3d7; - border-color: #269abc; -} - -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - background-image: none; -} - -.btn-info.disabled, -.btn-info[disabled], -fieldset[disabled] .btn-info, -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled:active, -.btn-info[disabled]:active, -fieldset[disabled] .btn-info:active, -.btn-info.disabled.active, -.btn-info[disabled].active, -fieldset[disabled] .btn-info.active { - background-color: #5bc0de; - border-color: #46b8da; -} - -.btn-link { - font-weight: normal; - color: #428bca; - cursor: pointer; - border-radius: 0; -} - -.btn-link, -.btn-link:active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} - -.btn-link, -.btn-link:hover, -.btn-link:focus, -.btn-link:active { - border-color: transparent; -} - -.btn-link:hover, -.btn-link:focus { - color: #2a6496; - text-decoration: underline; - background-color: transparent; -} - -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:hover, -.btn-link[disabled]:focus, -fieldset[disabled] .btn-link:focus { - color: #999999; - text-decoration: none; -} - -.btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -.btn-sm, -.btn-xs { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-xs { - padding: 1px 5px; -} - -.btn-block { - display: block; - width: 100%; - padding-right: 0; - padding-left: 0; -} - -.btn-block + .btn-block { - margin-top: 5px; -} - -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} - -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} - -.fade.in { - opacity: 1; -} - -.collapse { - display: none; -} - -.collapse.in { - display: block; -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height 0.35s ease; - transition: height 0.35s ease; -} - -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('../fonts/glyphicons-halflings-regular.eot'); - src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); -} - -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; -} - -.glyphicon-asterisk:before { - content: "\2a"; -} - -.glyphicon-plus:before { - content: "\2b"; -} - -.glyphicon-euro:before { - content: "\20ac"; -} - -.glyphicon-minus:before { - content: "\2212"; -} - -.glyphicon-cloud:before { - content: "\2601"; -} - -.glyphicon-envelope:before { - content: "\2709"; -} - -.glyphicon-pencil:before { - content: "\270f"; -} - -.glyphicon-glass:before { - content: "\e001"; -} - -.glyphicon-music:before { - content: "\e002"; -} - -.glyphicon-search:before { - content: "\e003"; -} - -.glyphicon-heart:before { - content: "\e005"; -} - -.glyphicon-star:before { - content: "\e006"; -} - -.glyphicon-star-empty:before { - content: "\e007"; -} - -.glyphicon-user:before { - content: "\e008"; -} - -.glyphicon-film:before { - content: "\e009"; -} - -.glyphicon-th-large:before { - content: "\e010"; -} - -.glyphicon-th:before { - content: "\e011"; -} - -.glyphicon-th-list:before { - content: "\e012"; -} - -.glyphicon-ok:before { - content: "\e013"; -} - -.glyphicon-remove:before { - content: "\e014"; -} - -.glyphicon-zoom-in:before { - content: "\e015"; -} - -.glyphicon-zoom-out:before { - content: "\e016"; -} - -.glyphicon-off:before { - content: "\e017"; -} - -.glyphicon-signal:before { - content: "\e018"; -} - -.glyphicon-cog:before { - content: "\e019"; -} - -.glyphicon-trash:before { - content: "\e020"; -} - -.glyphicon-home:before { - content: "\e021"; -} - -.glyphicon-file:before { - content: "\e022"; -} - -.glyphicon-time:before { - content: "\e023"; -} - -.glyphicon-road:before { - content: "\e024"; -} - -.glyphicon-download-alt:before { - content: "\e025"; -} - -.glyphicon-download:before { - content: "\e026"; -} - -.glyphicon-upload:before { - content: "\e027"; -} - -.glyphicon-inbox:before { - content: "\e028"; -} - -.glyphicon-play-circle:before { - content: "\e029"; -} - -.glyphicon-repeat:before { - content: "\e030"; -} - -.glyphicon-refresh:before { - content: "\e031"; -} - -.glyphicon-list-alt:before { - content: "\e032"; -} - -.glyphicon-flag:before { - content: "\e034"; -} - -.glyphicon-headphones:before { - content: "\e035"; -} - -.glyphicon-volume-off:before { - content: "\e036"; -} - -.glyphicon-volume-down:before { - content: "\e037"; -} - -.glyphicon-volume-up:before { - content: "\e038"; -} - -.glyphicon-qrcode:before { - content: "\e039"; -} - -.glyphicon-barcode:before { - content: "\e040"; -} - -.glyphicon-tag:before { - content: "\e041"; -} - -.glyphicon-tags:before { - content: "\e042"; -} - -.glyphicon-book:before { - content: "\e043"; -} - -.glyphicon-print:before { - content: "\e045"; -} - -.glyphicon-font:before { - content: "\e047"; -} - -.glyphicon-bold:before { - content: "\e048"; -} - -.glyphicon-italic:before { - content: "\e049"; -} - -.glyphicon-text-height:before { - content: "\e050"; -} - -.glyphicon-text-width:before { - content: "\e051"; -} - -.glyphicon-align-left:before { - content: "\e052"; -} - -.glyphicon-align-center:before { - content: "\e053"; -} - -.glyphicon-align-right:before { - content: "\e054"; -} - -.glyphicon-align-justify:before { - content: "\e055"; -} - -.glyphicon-list:before { - content: "\e056"; -} - -.glyphicon-indent-left:before { - content: "\e057"; -} - -.glyphicon-indent-right:before { - content: "\e058"; -} - -.glyphicon-facetime-video:before { - content: "\e059"; -} - -.glyphicon-picture:before { - content: "\e060"; -} - -.glyphicon-map-marker:before { - content: "\e062"; -} - -.glyphicon-adjust:before { - content: "\e063"; -} - -.glyphicon-tint:before { - content: "\e064"; -} - -.glyphicon-edit:before { - content: "\e065"; -} - -.glyphicon-share:before { - content: "\e066"; -} - -.glyphicon-check:before { - content: "\e067"; -} - -.glyphicon-move:before { - content: "\e068"; -} - -.glyphicon-step-backward:before { - content: "\e069"; -} - -.glyphicon-fast-backward:before { - content: "\e070"; -} - -.glyphicon-backward:before { - content: "\e071"; -} - -.glyphicon-play:before { - content: "\e072"; -} - -.glyphicon-pause:before { - content: "\e073"; -} - -.glyphicon-stop:before { - content: "\e074"; -} - -.glyphicon-forward:before { - content: "\e075"; -} - -.glyphicon-fast-forward:before { - content: "\e076"; -} - -.glyphicon-step-forward:before { - content: "\e077"; -} - -.glyphicon-eject:before { - content: "\e078"; -} - -.glyphicon-chevron-left:before { - content: "\e079"; -} - -.glyphicon-chevron-right:before { - content: "\e080"; -} - -.glyphicon-plus-sign:before { - content: "\e081"; -} - -.glyphicon-minus-sign:before { - content: "\e082"; -} - -.glyphicon-remove-sign:before { - content: "\e083"; -} - -.glyphicon-ok-sign:before { - content: "\e084"; -} - -.glyphicon-question-sign:before { - content: "\e085"; -} - -.glyphicon-info-sign:before { - content: "\e086"; -} - -.glyphicon-screenshot:before { - content: "\e087"; -} - -.glyphicon-remove-circle:before { - content: "\e088"; -} - -.glyphicon-ok-circle:before { - content: "\e089"; -} - -.glyphicon-ban-circle:before { - content: "\e090"; -} - -.glyphicon-arrow-left:before { - content: "\e091"; -} - -.glyphicon-arrow-right:before { - content: "\e092"; -} - -.glyphicon-arrow-up:before { - content: "\e093"; -} - -.glyphicon-arrow-down:before { - content: "\e094"; -} - -.glyphicon-share-alt:before { - content: "\e095"; -} - -.glyphicon-resize-full:before { - content: "\e096"; -} - -.glyphicon-resize-small:before { - content: "\e097"; -} - -.glyphicon-exclamation-sign:before { - content: "\e101"; -} - -.glyphicon-gift:before { - content: "\e102"; -} - -.glyphicon-leaf:before { - content: "\e103"; -} - -.glyphicon-eye-open:before { - content: "\e105"; -} - -.glyphicon-eye-close:before { - content: "\e106"; -} - -.glyphicon-warning-sign:before { - content: "\e107"; -} - -.glyphicon-plane:before { - content: "\e108"; -} - -.glyphicon-random:before { - content: "\e110"; -} - -.glyphicon-comment:before { - content: "\e111"; -} - -.glyphicon-magnet:before { - content: "\e112"; -} - -.glyphicon-chevron-up:before { - content: "\e113"; -} - -.glyphicon-chevron-down:before { - content: "\e114"; -} - -.glyphicon-retweet:before { - content: "\e115"; -} - -.glyphicon-shopping-cart:before { - content: "\e116"; -} - -.glyphicon-folder-close:before { - content: "\e117"; -} - -.glyphicon-folder-open:before { - content: "\e118"; -} - -.glyphicon-resize-vertical:before { - content: "\e119"; -} - -.glyphicon-resize-horizontal:before { - content: "\e120"; -} - -.glyphicon-hdd:before { - content: "\e121"; -} - -.glyphicon-bullhorn:before { - content: "\e122"; -} - -.glyphicon-certificate:before { - content: "\e124"; -} - -.glyphicon-thumbs-up:before { - content: "\e125"; -} - -.glyphicon-thumbs-down:before { - content: "\e126"; -} - -.glyphicon-hand-right:before { - content: "\e127"; -} - -.glyphicon-hand-left:before { - content: "\e128"; -} - -.glyphicon-hand-up:before { - content: "\e129"; -} - -.glyphicon-hand-down:before { - content: "\e130"; -} - -.glyphicon-circle-arrow-right:before { - content: "\e131"; -} - -.glyphicon-circle-arrow-left:before { - content: "\e132"; -} - -.glyphicon-circle-arrow-up:before { - content: "\e133"; -} - -.glyphicon-circle-arrow-down:before { - content: "\e134"; -} - -.glyphicon-globe:before { - content: "\e135"; -} - -.glyphicon-tasks:before { - content: "\e137"; -} - -.glyphicon-filter:before { - content: "\e138"; -} - -.glyphicon-fullscreen:before { - content: "\e140"; -} - -.glyphicon-dashboard:before { - content: "\e141"; -} - -.glyphicon-heart-empty:before { - content: "\e143"; -} - -.glyphicon-link:before { - content: "\e144"; -} - -.glyphicon-phone:before { - content: "\e145"; -} - -.glyphicon-usd:before { - content: "\e148"; -} - -.glyphicon-gbp:before { - content: "\e149"; -} - -.glyphicon-sort:before { - content: "\e150"; -} - -.glyphicon-sort-by-alphabet:before { - content: "\e151"; -} - -.glyphicon-sort-by-alphabet-alt:before { - content: "\e152"; -} - -.glyphicon-sort-by-order:before { - content: "\e153"; -} - -.glyphicon-sort-by-order-alt:before { - content: "\e154"; -} - -.glyphicon-sort-by-attributes:before { - content: "\e155"; -} - -.glyphicon-sort-by-attributes-alt:before { - content: "\e156"; -} - -.glyphicon-unchecked:before { - content: "\e157"; -} - -.glyphicon-expand:before { - content: "\e158"; -} - -.glyphicon-collapse-down:before { - content: "\e159"; -} - -.glyphicon-collapse-up:before { - content: "\e160"; -} - -.glyphicon-log-in:before { - content: "\e161"; -} - -.glyphicon-flash:before { - content: "\e162"; -} - -.glyphicon-log-out:before { - content: "\e163"; -} - -.glyphicon-new-window:before { - content: "\e164"; -} - -.glyphicon-record:before { - content: "\e165"; -} - -.glyphicon-save:before { - content: "\e166"; -} - -.glyphicon-open:before { - content: "\e167"; -} - -.glyphicon-saved:before { - content: "\e168"; -} - -.glyphicon-import:before { - content: "\e169"; -} - -.glyphicon-export:before { - content: "\e170"; -} - -.glyphicon-send:before { - content: "\e171"; -} - -.glyphicon-floppy-disk:before { - content: "\e172"; -} - -.glyphicon-floppy-saved:before { - content: "\e173"; -} - -.glyphicon-floppy-remove:before { - content: "\e174"; -} - -.glyphicon-floppy-save:before { - content: "\e175"; -} - -.glyphicon-floppy-open:before { - content: "\e176"; -} - -.glyphicon-credit-card:before { - content: "\e177"; -} - -.glyphicon-transfer:before { - content: "\e178"; -} - -.glyphicon-cutlery:before { - content: "\e179"; -} - -.glyphicon-header:before { - content: "\e180"; -} - -.glyphicon-compressed:before { - content: "\e181"; -} - -.glyphicon-earphone:before { - content: "\e182"; -} - -.glyphicon-phone-alt:before { - content: "\e183"; -} - -.glyphicon-tower:before { - content: "\e184"; -} - -.glyphicon-stats:before { - content: "\e185"; -} - -.glyphicon-sd-video:before { - content: "\e186"; -} - -.glyphicon-hd-video:before { - content: "\e187"; -} - -.glyphicon-subtitles:before { - content: "\e188"; -} - -.glyphicon-sound-stereo:before { - content: "\e189"; -} - -.glyphicon-sound-dolby:before { - content: "\e190"; -} - -.glyphicon-sound-5-1:before { - content: "\e191"; -} - -.glyphicon-sound-6-1:before { - content: "\e192"; -} - -.glyphicon-sound-7-1:before { - content: "\e193"; -} - -.glyphicon-copyright-mark:before { - content: "\e194"; -} - -.glyphicon-registration-mark:before { - content: "\e195"; -} - -.glyphicon-cloud-download:before { - content: "\e197"; -} - -.glyphicon-cloud-upload:before { - content: "\e198"; -} - -.glyphicon-tree-conifer:before { - content: "\e199"; -} - -.glyphicon-tree-deciduous:before { - content: "\e200"; -} - -.glyphicon-briefcase:before { - content: "\1f4bc"; -} - -.glyphicon-calendar:before { - content: "\1f4c5"; -} - -.glyphicon-pushpin:before { - content: "\1f4cc"; -} - -.glyphicon-paperclip:before { - content: "\1f4ce"; -} - -.glyphicon-camera:before { - content: "\1f4f7"; -} - -.glyphicon-lock:before { - content: "\1f512"; -} - -.glyphicon-bell:before { - content: "\1f514"; -} - -.glyphicon-bookmark:before { - content: "\1f516"; -} - -.glyphicon-fire:before { - content: "\1f525"; -} - -.glyphicon-wrench:before { - content: "\1f527"; -} - -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px solid #000000; - border-right: 4px solid transparent; - border-bottom: 0 dotted; - border-left: 4px solid transparent; - content: ""; -} - -.dropdown { - position: relative; -} - -.dropdown-toggle:focus { - outline: 0; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - list-style: none; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; -} - -.dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.428571429; - color: #333333; - white-space: nowrap; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #428bca; -} - -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #428bca; - outline: 0; -} - -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999999; -} - -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.open > .dropdown-menu { - display: block; -} - -.open > a { - outline: 0; -} - -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.428571429; - color: #999999; -} - -.dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990; -} - -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0 dotted; - border-bottom: 4px solid #000000; - content: ""; -} - -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} - -@media (min-width: 768px) { - .navbar-right .dropdown-menu { - right: 0; - left: auto; - } -} - -.btn-default .caret { - border-top-color: #333333; -} - -.btn-primary .caret, -.btn-success .caret, -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret { - border-top-color: #fff; -} - -.dropup .btn-default .caret { - border-bottom-color: #333333; -} - -.dropup .btn-primary .caret, -.dropup .btn-success .caret, -.dropup .btn-warning .caret, -.dropup .btn-danger .caret, -.dropup .btn-info .caret { - border-bottom-color: #fff; -} - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; -} - -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - float: left; -} - -.btn-group > .btn:hover, -.btn-group-vertical > .btn:hover, -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus, -.btn-group > .btn:active, -.btn-group-vertical > .btn:active, -.btn-group > .btn.active, -.btn-group-vertical > .btn.active { - z-index: 2; -} - -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus { - outline: none; -} - -.btn-group .btn + .btn, -.btn-group .btn + .btn-group, -.btn-group .btn-group + .btn, -.btn-group .btn-group + .btn-group { - margin-left: -1px; -} - -.btn-toolbar:before, -.btn-toolbar:after { - display: table; - content: " "; -} - -.btn-toolbar:after { - clear: both; -} - -.btn-toolbar:before, -.btn-toolbar:after { - display: table; - content: " "; -} - -.btn-toolbar:after { - clear: both; -} - -.btn-toolbar .btn-group { - float: left; -} - -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group, -.btn-toolbar > .btn-group + .btn-group { - margin-left: 5px; -} - -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} - -.btn-group > .btn:first-child { - margin-left: 0; -} - -.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.btn-group > .btn-group { - float: left; -} - -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} - -.btn-group > .btn-group:first-child > .btn:last-child, -.btn-group > .btn-group:first-child > .dropdown-toggle { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.btn-group > .btn-group:last-child > .btn:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - -.btn-group-xs > .btn { - padding: 5px 10px; - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-group-sm > .btn { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-group-lg > .btn { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -.btn-group > .btn + .dropdown-toggle { - padding-right: 8px; - padding-left: 8px; -} - -.btn-group > .btn-lg + .dropdown-toggle { - padding-right: 12px; - padding-left: 12px; -} - -.btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn .caret { - margin-left: 0; -} - -.btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0; -} - -.dropup .btn-lg .caret { - border-width: 0 5px 5px; -} - -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group { - display: block; - float: none; - width: 100%; - max-width: 100%; -} - -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after { - display: table; - content: " "; -} - -.btn-group-vertical > .btn-group:after { - clear: both; -} - -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after { - display: table; - content: " "; -} - -.btn-group-vertical > .btn-group:after { - clear: both; -} - -.btn-group-vertical > .btn-group > .btn { - float: none; -} - -.btn-group-vertical > .btn + .btn, -.btn-group-vertical > .btn + .btn-group, -.btn-group-vertical > .btn-group + .btn, -.btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; -} - -.btn-group-vertical > .btn:not(:first-child):not(:last-child) { - border-radius: 0; -} - -.btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.btn-group-vertical > .btn:last-child:not(:first-child) { - border-top-right-radius: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 0; -} - -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} - -.btn-group-vertical > .btn-group:first-child > .btn:last-child, -.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.btn-group-vertical > .btn-group:last-child > .btn:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.btn-group-justified { - display: table; - width: 100%; - border-collapse: separate; - table-layout: fixed; -} - -.btn-group-justified .btn { - display: table-cell; - float: none; - width: 1%; -} - -[data-toggle="buttons"] > .btn > input[type="radio"], -[data-toggle="buttons"] > .btn > input[type="checkbox"] { - display: none; -} - -.input-group { - position: relative; - display: table; - border-collapse: separate; -} - -.input-group.col { - float: none; - padding-right: 0; - padding-left: 0; -} - -.input-group .form-control { - width: 100%; - margin-bottom: 0; -} - -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon, -.input-group-lg > .input-group-btn > .btn { - height: 45px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -select.input-group-lg > .form-control, -select.input-group-lg > .input-group-addon, -select.input-group-lg > .input-group-btn > .btn { - height: 45px; - line-height: 45px; -} - -textarea.input-group-lg > .form-control, -textarea.input-group-lg > .input-group-addon, -textarea.input-group-lg > .input-group-btn > .btn { - height: auto; -} - -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon, -.input-group-sm > .input-group-btn > .btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -select.input-group-sm > .form-control, -select.input-group-sm > .input-group-addon, -select.input-group-sm > .input-group-btn > .btn { - height: 30px; - line-height: 30px; -} - -textarea.input-group-sm > .form-control, -textarea.input-group-sm > .input-group-addon, -textarea.input-group-sm > .input-group-btn > .btn { - height: auto; -} - -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; -} - -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} - -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; -} - -.input-group-addon { - padding: 6px 12px; - font-size: 14px; - font-weight: normal; - line-height: 1; - text-align: center; - background-color: #eeeeee; - border: 1px solid #cccccc; - border-radius: 4px; -} - -.input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 3px; -} - -.input-group-addon.input-lg { - padding: 10px 16px; - font-size: 18px; - border-radius: 6px; -} - -.input-group-addon input[type="radio"], -.input-group-addon input[type="checkbox"] { - margin-top: 0; -} - -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .dropdown-toggle, -.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.input-group-addon:first-child { - border-right: 0; -} - -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .dropdown-toggle, -.input-group-btn:first-child > .btn:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.input-group-addon:last-child { - border-left: 0; -} - -.input-group-btn { - position: relative; - white-space: nowrap; -} - -.input-group-btn > .btn { - position: relative; -} - -.input-group-btn > .btn + .btn { - margin-left: -4px; -} - -.input-group-btn > .btn:hover, -.input-group-btn > .btn:active { - z-index: 2; -} - -.nav { - padding-left: 0; - margin-bottom: 0; - list-style: none; -} - -.nav:before, -.nav:after { - display: table; - content: " "; -} - -.nav:after { - clear: both; -} - -.nav:before, -.nav:after { - display: table; - content: " "; -} - -.nav:after { - clear: both; -} - -.nav > li { - position: relative; - display: block; -} - -.nav > li > a { - position: relative; - display: block; - padding: 10px 15px; -} - -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.nav > li.disabled > a { - color: #999999; -} - -.nav > li.disabled > a:hover, -.nav > li.disabled > a:focus { - color: #999999; - text-decoration: none; - cursor: not-allowed; - background-color: transparent; -} - -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background-color: #eeeeee; - border-color: #428bca; -} - -.nav .nav-divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.nav > li > a > img { - max-width: none; -} - -.nav-tabs { - border-bottom: 1px solid #dddddd; -} - -.nav-tabs > li { - float: left; - margin-bottom: -1px; -} - -.nav-tabs > li > a { - margin-right: 2px; - line-height: 1.428571429; - border: 1px solid transparent; - border-radius: 4px 4px 0 0; -} - -.nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #dddddd; -} - -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - color: #555555; - cursor: default; - background-color: #ffffff; - border: 1px solid #dddddd; - border-bottom-color: transparent; -} - -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; -} - -.nav-tabs.nav-justified > li { - float: none; -} - -.nav-tabs.nav-justified > li > a { - text-align: center; -} - -@media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } -} - -.nav-tabs.nav-justified > li > a { - margin-right: 0; - border-bottom: 1px solid #dddddd; -} - -.nav-tabs.nav-justified > .active > a { - border-bottom-color: #ffffff; -} - -.nav-pills > li { - float: left; -} - -.nav-pills > li > a { - border-radius: 5px; -} - -.nav-pills > li + li { - margin-left: 2px; -} - -.nav-pills > li.active > a, -.nav-pills > li.active > a:hover, -.nav-pills > li.active > a:focus { - color: #ffffff; - background-color: #428bca; -} - -.nav-stacked > li { - float: none; -} - -.nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; -} - -.nav-justified { - width: 100%; -} - -.nav-justified > li { - float: none; -} - -.nav-justified > li > a { - text-align: center; -} - -@media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } -} - -.nav-tabs-justified { - border-bottom: 0; -} - -.nav-tabs-justified > li > a { - margin-right: 0; - border-bottom: 1px solid #dddddd; -} - -.nav-tabs-justified > .active > a { - border-bottom-color: #ffffff; -} - -.tabbable:before, -.tabbable:after { - display: table; - content: " "; -} - -.tabbable:after { - clear: both; -} - -.tabbable:before, -.tabbable:after { - display: table; - content: " "; -} - -.tabbable:after { - clear: both; -} - -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} - -.tab-content > .active, -.pill-content > .active { - display: block; -} - -.nav .caret { - border-top-color: #428bca; - border-bottom-color: #428bca; -} - -.nav a:hover .caret { - border-top-color: #2a6496; - border-bottom-color: #2a6496; -} - -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.navbar { - position: relative; - z-index: 1000; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent; -} - -.navbar:before, -.navbar:after { - display: table; - content: " "; -} - -.navbar:after { - clear: both; -} - -.navbar:before, -.navbar:after { - display: table; - content: " "; -} - -.navbar:after { - clear: both; -} - -@media (min-width: 768px) { - .navbar { - border-radius: 4px; - } -} - -.navbar-header:before, -.navbar-header:after { - display: table; - content: " "; -} - -.navbar-header:after { - clear: both; -} - -.navbar-header:before, -.navbar-header:after { - display: table; - content: " "; -} - -.navbar-header:after { - clear: both; -} - -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} - -.navbar-collapse { - max-height: 340px; - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} - -.navbar-collapse:before, -.navbar-collapse:after { - display: table; - content: " "; -} - -.navbar-collapse:after { - clear: both; -} - -.navbar-collapse:before, -.navbar-collapse:after { - display: table; - content: " "; -} - -.navbar-collapse:after { - clear: both; -} - -.navbar-collapse.in { - overflow-y: auto; -} - -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-collapse .navbar-nav.navbar-left:first-child { - margin-left: -15px; - } - .navbar-collapse .navbar-nav.navbar-right:last-child { - margin-right: -15px; - } - .navbar-collapse .navbar-text:last-child { - margin-right: 0; - } -} - -.container > .navbar-header, -.container > .navbar-collapse { - margin-right: -15px; - margin-left: -15px; -} - -@media (min-width: 768px) { - .container > .navbar-header, - .container > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } -} - -.navbar-static-top { - border-width: 0 0 1px; -} - -@media (min-width: 768px) { - .navbar-static-top { - border-radius: 0; - } -} - -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - border-width: 0 0 1px; -} - -@media (min-width: 768px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } -} - -.navbar-fixed-top { - top: 0; - z-index: 1030; -} - -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; -} - -.navbar-brand { - float: left; - padding: 15px 15px; - font-size: 18px; - line-height: 20px; -} - -.navbar-brand:hover, -.navbar-brand:focus { - text-decoration: none; -} - -@media (min-width: 768px) { - .navbar > .container .navbar-brand { - margin-left: -15px; - } -} - -.navbar-toggle { - position: relative; - float: right; - padding: 9px 10px; - margin-top: 8px; - margin-right: 15px; - margin-bottom: 8px; - background-color: transparent; - border: 1px solid transparent; - border-radius: 4px; -} - -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} - -.navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} - -@media (min-width: 768px) { - .navbar-toggle { - display: none; - } -} - -.navbar-nav { - margin: 7.5px -15px; -} - -.navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; -} - -@media (max-width: 767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 20px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } -} - -@media (min-width: 768px) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 15px; - padding-bottom: 15px; - } -} - -@media (min-width: 768px) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - } -} - -.navbar-form { - padding: 10px 15px; - margin-top: 8px; - margin-right: -15px; - margin-bottom: 8px; - margin-left: -15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); -} - -@media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - padding-left: 0; - margin-top: 0; - margin-bottom: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } -} - -@media (max-width: 767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } -} - -@media (min-width: 768px) { - .navbar-form { - width: auto; - padding-top: 0; - padding-bottom: 0; - margin-right: 0; - margin-left: 0; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} - -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.navbar-nav.pull-right > li > .dropdown-menu, -.navbar-nav > li > .dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.navbar-btn { - margin-top: 8px; - margin-bottom: 8px; -} - -.navbar-text { - float: left; - margin-top: 15px; - margin-bottom: 15px; -} - -@media (min-width: 768px) { - .navbar-text { - margin-right: 15px; - margin-left: 15px; - } -} - -.navbar-default { - background-color: #f8f8f8; - border-color: #e7e7e7; -} - -.navbar-default .navbar-brand { - color: #777777; -} - -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus { - color: #5e5e5e; - background-color: transparent; -} - -.navbar-default .navbar-text { - color: #777777; -} - -.navbar-default .navbar-nav > li > a { - color: #777777; -} - -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #333333; - background-color: transparent; -} - -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #555555; - background-color: #e7e7e7; -} - -.navbar-default .navbar-nav > .disabled > a, -.navbar-default .navbar-nav > .disabled > a:hover, -.navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; - background-color: transparent; -} - -.navbar-default .navbar-toggle { - border-color: #dddddd; -} - -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: #dddddd; -} - -.navbar-default .navbar-toggle .icon-bar { - background-color: #cccccc; -} - -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: #e6e6e6; -} - -.navbar-default .navbar-nav > .dropdown > a:hover .caret, -.navbar-default .navbar-nav > .dropdown > a:focus .caret { - border-top-color: #333333; - border-bottom-color: #333333; -} - -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .open > a:hover, -.navbar-default .navbar-nav > .open > a:focus { - color: #555555; - background-color: #e7e7e7; -} - -.navbar-default .navbar-nav > .open > a .caret, -.navbar-default .navbar-nav > .open > a:hover .caret, -.navbar-default .navbar-nav > .open > a:focus .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.navbar-default .navbar-nav > .dropdown > a .caret { - border-top-color: #777777; - border-bottom-color: #777777; -} - -@media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #777777; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #333333; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #555555; - background-color: #e7e7e7; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; - background-color: transparent; - } -} - -.navbar-default .navbar-link { - color: #777777; -} - -.navbar-default .navbar-link:hover { - color: #333333; -} - -.navbar-inverse { - background-color: #222222; - border-color: #080808; -} - -.navbar-inverse .navbar-brand { - color: #999999; -} - -.navbar-inverse .navbar-brand:hover, -.navbar-inverse .navbar-brand:focus { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .navbar-text { - color: #999999; -} - -.navbar-inverse .navbar-nav > li > a { - color: #999999; -} - -.navbar-inverse .navbar-nav > li > a:hover, -.navbar-inverse .navbar-nav > li > a:focus { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:hover, -.navbar-inverse .navbar-nav > .active > a:focus { - color: #ffffff; - background-color: #080808; -} - -.navbar-inverse .navbar-nav > .disabled > a, -.navbar-inverse .navbar-nav > .disabled > a:hover, -.navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; - background-color: transparent; -} - -.navbar-inverse .navbar-toggle { - border-color: #333333; -} - -.navbar-inverse .navbar-toggle:hover, -.navbar-inverse .navbar-toggle:focus { - background-color: #333333; -} - -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #ffffff; -} - -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #101010; -} - -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .open > a:hover, -.navbar-inverse .navbar-nav > .open > a:focus { - color: #ffffff; - background-color: #080808; -} - -.navbar-inverse .navbar-nav > .dropdown > a:hover .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .navbar-nav > .dropdown > a .caret { - border-top-color: #999999; - border-bottom-color: #999999; -} - -.navbar-inverse .navbar-nav > .open > a .caret, -.navbar-inverse .navbar-nav > .open > a:hover .caret, -.navbar-inverse .navbar-nav > .open > a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -@media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #999999; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ffffff; - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ffffff; - background-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; - background-color: transparent; - } -} - -.navbar-inverse .navbar-link { - color: #999999; -} - -.navbar-inverse .navbar-link:hover { - color: #ffffff; -} - -.breadcrumb { - padding: 8px 15px; - margin-bottom: 20px; - list-style: none; - background-color: #f5f5f5; - border-radius: 4px; -} - -.breadcrumb > li { - display: inline-block; -} - -.breadcrumb > li + li:before { - padding: 0 5px; - color: #cccccc; - content: "/\00a0"; -} - -.breadcrumb > .active { - color: #999999; -} - -.pagination { - display: inline-block; - padding-left: 0; - margin: 20px 0; - border-radius: 4px; -} - -.pagination > li { - display: inline; -} - -.pagination > li > a, -.pagination > li > span { - position: relative; - float: left; - padding: 6px 12px; - margin-left: -1px; - line-height: 1.428571429; - text-decoration: none; - background-color: #ffffff; - border: 1px solid #dddddd; -} - -.pagination > li:first-child > a, -.pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} - -.pagination > li:last-child > a, -.pagination > li:last-child > span { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - background-color: #eeeeee; -} - -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - z-index: 2; - color: #ffffff; - cursor: default; - background-color: #428bca; - border-color: #428bca; -} - -.pagination > .disabled > span, -.pagination > .disabled > a, -.pagination > .disabled > a:hover, -.pagination > .disabled > a:focus { - color: #999999; - cursor: not-allowed; - background-color: #ffffff; - border-color: #dddddd; -} - -.pagination-lg > li > a, -.pagination-lg > li > span { - padding: 10px 16px; - font-size: 18px; -} - -.pagination-lg > li:first-child > a, -.pagination-lg > li:first-child > span { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; -} - -.pagination-lg > li:last-child > a, -.pagination-lg > li:last-child > span { - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; -} - -.pagination-sm > li > a, -.pagination-sm > li > span { - padding: 5px 10px; - font-size: 12px; -} - -.pagination-sm > li:first-child > a, -.pagination-sm > li:first-child > span { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; -} - -.pagination-sm > li:last-child > a, -.pagination-sm > li:last-child > span { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -.pager { - padding-left: 0; - margin: 20px 0; - text-align: center; - list-style: none; -} - -.pager:before, -.pager:after { - display: table; - content: " "; -} - -.pager:after { - clear: both; -} - -.pager:before, -.pager:after { - display: table; - content: " "; -} - -.pager:after { - clear: both; -} - -.pager li { - display: inline; -} - -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 15px; -} - -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.pager .next > a, -.pager .next > span { - float: right; -} - -.pager .previous > a, -.pager .previous > span { - float: left; -} - -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999999; - cursor: not-allowed; - background-color: #ffffff; -} - -.label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; -} - -.label[href]:hover, -.label[href]:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.label:empty { - display: none; -} - -.label-default { - background-color: #999999; -} - -.label-default[href]:hover, -.label-default[href]:focus { - background-color: #808080; -} - -.label-primary { - background-color: #428bca; -} - -.label-primary[href]:hover, -.label-primary[href]:focus { - background-color: #3071a9; -} - -.label-success { - background-color: #5cb85c; -} - -.label-success[href]:hover, -.label-success[href]:focus { - background-color: #449d44; -} - -.label-info { - background-color: #5bc0de; -} - -.label-info[href]:hover, -.label-info[href]:focus { - background-color: #31b0d5; -} - -.label-warning { - background-color: #f0ad4e; -} - -.label-warning[href]:hover, -.label-warning[href]:focus { - background-color: #ec971f; -} - -.label-danger { - background-color: #d9534f; -} - -.label-danger[href]:hover, -.label-danger[href]:focus { - background-color: #c9302c; -} - -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - background-color: #999999; - border-radius: 10px; -} - -.badge:empty { - display: none; -} - -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.btn .badge { - position: relative; - top: -1px; -} - -a.list-group-item.active > .badge, -.nav-pills > .active > a > .badge { - color: #428bca; - background-color: #ffffff; -} - -.nav-pills > li > a > .badge { - margin-left: 3px; -} - -.jumbotron { - padding: 30px; - margin-bottom: 30px; - font-size: 21px; - font-weight: 200; - line-height: 2.1428571435; - color: inherit; - background-color: #eeeeee; -} - -.jumbotron h1 { - line-height: 1; - color: inherit; -} - -.jumbotron p { - line-height: 1.4; -} - -.container .jumbotron { - border-radius: 6px; -} - -@media screen and (min-width: 768px) { - .jumbotron { - padding-top: 48px; - padding-bottom: 48px; - } - .container .jumbotron { - padding-right: 60px; - padding-left: 60px; - } - .jumbotron h1 { - font-size: 63px; - } -} - -.thumbnail { - display: inline-block; - display: block; - height: auto; - max-width: 100%; - padding: 4px; - line-height: 1.428571429; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -.thumbnail > img { - display: block; - height: auto; - max-width: 100%; -} - -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #428bca; -} - -.thumbnail > img { - margin-right: auto; - margin-left: auto; -} - -.thumbnail .caption { - padding: 9px; - color: #333333; -} - -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px; -} - -.alert h4 { - margin-top: 0; - color: inherit; -} - -.alert .alert-link { - font-weight: bold; -} - -.alert > p, -.alert > ul { - margin-bottom: 0; -} - -.alert > p + p { - margin-top: 5px; -} - -.alert-dismissable { - padding-right: 35px; -} - -.alert-dismissable .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; -} - -.alert-success { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-success hr { - border-top-color: #c9e2b3; -} - -.alert-success .alert-link { - color: #356635; -} - -.alert-info { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-info hr { - border-top-color: #a6e1ec; -} - -.alert-info .alert-link { - color: #2d6987; -} - -.alert-warning { - color: #c09853; - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.alert-warning hr { - border-top-color: #f8e5be; -} - -.alert-warning .alert-link { - color: #a47e3c; -} - -.alert-danger { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-danger hr { - border-top-color: #e6c1c7; -} - -.alert-danger .alert-link { - color: #953b39; -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -.progress { - height: 20px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f5f5f5; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.progress-bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - color: #ffffff; - text-align: center; - background-color: #428bca; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - transition: width 0.6s ease; -} - -.progress-striped .progress-bar { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 40px 40px; -} - -.progress.active .progress-bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - -.progress-bar-success { - background-color: #5cb85c; -} - -.progress-striped .progress-bar-success { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-info { - background-color: #5bc0de; -} - -.progress-striped .progress-bar-info { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-warning { - background-color: #f0ad4e; -} - -.progress-striped .progress-bar-warning { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-danger { - background-color: #d9534f; -} - -.progress-striped .progress-bar-danger { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.media, -.media-body { - overflow: hidden; - zoom: 1; -} - -.media, -.media .media { - margin-top: 15px; -} - -.media:first-child { - margin-top: 0; -} - -.media-object { - display: block; -} - -.media-heading { - margin: 0 0 5px; -} - -.media > .pull-left { - margin-right: 10px; -} - -.media > .pull-right { - margin-left: 10px; -} - -.media-list { - padding-left: 0; - list-style: none; -} - -.list-group { - padding-left: 0; - margin-bottom: 20px; -} - -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #ffffff; - border: 1px solid #dddddd; -} - -.list-group-item:first-child { - border-top-right-radius: 4px; - border-top-left-radius: 4px; -} - -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} - -.list-group-item > .badge { - float: right; -} - -.list-group-item > .badge + .badge { - margin-right: 5px; -} - -a.list-group-item { - color: #555555; -} - -a.list-group-item .list-group-item-heading { - color: #333333; -} - -a.list-group-item:hover, -a.list-group-item:focus { - text-decoration: none; - background-color: #f5f5f5; -} - -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - z-index: 2; - color: #ffffff; - background-color: #428bca; - border-color: #428bca; -} - -.list-group-item.active .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading { - color: inherit; -} - -.list-group-item.active .list-group-item-text, -.list-group-item.active:hover .list-group-item-text, -.list-group-item.active:focus .list-group-item-text { - color: #e1edf7; -} - -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; -} - -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3; -} - -.panel { - margin-bottom: 20px; - background-color: #ffffff; - border: 1px solid transparent; - border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.panel-body { - padding: 15px; -} - -.panel-body:before, -.panel-body:after { - display: table; - content: " "; -} - -.panel-body:after { - clear: both; -} - -.panel-body:before, -.panel-body:after { - display: table; - content: " "; -} - -.panel-body:after { - clear: both; -} - -.panel > .list-group { - margin-bottom: 0; -} - -.panel > .list-group .list-group-item { - border-width: 1px 0; -} - -.panel > .list-group .list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.panel > .list-group .list-group-item:last-child { - border-bottom: 0; -} - -.panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; -} - -.panel > .table { - margin-bottom: 0; -} - -.panel > .panel-body + .table { - border-top: 1px solid #dddddd; -} - -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} - -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 16px; -} - -.panel-title > a { - color: inherit; -} - -.panel-footer { - padding: 10px 15px; - background-color: #f5f5f5; - border-top: 1px solid #dddddd; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} - -.panel-group .panel { - margin-bottom: 0; - overflow: hidden; - border-radius: 4px; -} - -.panel-group .panel + .panel { - margin-top: 5px; -} - -.panel-group .panel-heading { - border-bottom: 0; -} - -.panel-group .panel-heading + .panel-collapse .panel-body { - border-top: 1px solid #dddddd; -} - -.panel-group .panel-footer { - border-top: 0; -} - -.panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #dddddd; -} - -.panel-default { - border-color: #dddddd; -} - -.panel-default > .panel-heading { - color: #333333; - background-color: #f5f5f5; - border-color: #dddddd; -} - -.panel-default > .panel-heading + .panel-collapse .panel-body { - border-top-color: #dddddd; -} - -.panel-default > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #dddddd; -} - -.panel-primary { - border-color: #428bca; -} - -.panel-primary > .panel-heading { - color: #ffffff; - background-color: #428bca; - border-color: #428bca; -} - -.panel-primary > .panel-heading + .panel-collapse .panel-body { - border-top-color: #428bca; -} - -.panel-primary > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #428bca; -} - -.panel-success { - border-color: #d6e9c6; -} - -.panel-success > .panel-heading { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.panel-success > .panel-heading + .panel-collapse .panel-body { - border-top-color: #d6e9c6; -} - -.panel-success > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #d6e9c6; -} - -.panel-warning { - border-color: #fbeed5; -} - -.panel-warning > .panel-heading { - color: #c09853; - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.panel-warning > .panel-heading + .panel-collapse .panel-body { - border-top-color: #fbeed5; -} - -.panel-warning > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #fbeed5; -} - -.panel-danger { - border-color: #eed3d7; -} - -.panel-danger > .panel-heading { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.panel-danger > .panel-heading + .panel-collapse .panel-body { - border-top-color: #eed3d7; -} - -.panel-danger > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #eed3d7; -} - -.panel-info { - border-color: #bce8f1; -} - -.panel-info > .panel-heading { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.panel-info > .panel-heading + .panel-collapse .panel-body { - border-top-color: #bce8f1; -} - -.panel-info > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #bce8f1; -} - -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.well-lg { - padding: 24px; - border-radius: 6px; -} - -.well-sm { - padding: 9px; - border-radius: 3px; -} - -.close { - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} - -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} - -.modal-open { - overflow: hidden; -} - -body.modal-open, -.modal-open .navbar-fixed-top, -.modal-open .navbar-fixed-bottom { - margin-right: 15px; -} - -.modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - display: none; - overflow: auto; - overflow-y: scroll; -} - -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -moz-transition: -moz-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} - -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - transform: translate(0, 0); -} - -.modal-dialog { - z-index: 1050; - width: auto; - padding: 10px; - margin-right: auto; - margin-left: auto; -} - -.modal-content { - position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - outline: none; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - background-clip: padding-box; -} - -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1030; - background-color: #000000; -} - -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} - -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} - -.modal-header { - min-height: 16.428571429px; - padding: 15px; - border-bottom: 1px solid #e5e5e5; -} - -.modal-header .close { - margin-top: -2px; -} - -.modal-title { - margin: 0; - line-height: 1.428571429; -} - -.modal-body { - position: relative; - padding: 20px; -} - -.modal-footer { - padding: 19px 20px 20px; - margin-top: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - content: " "; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - content: " "; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer .btn + .btn { - margin-bottom: 0; - margin-left: 5px; -} - -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} - -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} - -@media screen and (min-width: 768px) { - .modal-dialog { - right: auto; - left: 50%; - width: 600px; - padding-top: 30px; - padding-bottom: 30px; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } -} - -.tooltip { - position: absolute; - z-index: 1030; - display: block; - font-size: 12px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; -} - -.tooltip.in { - opacity: 0.9; - filter: alpha(opacity=90); -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px; -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px; -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px; -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - border-radius: 4px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.top-left .tooltip-arrow { - bottom: 0; - left: 5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.top-right .tooltip-arrow { - right: 5px; - bottom: 0; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-right-color: #000000; - border-width: 5px 5px 5px 0; -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-left-color: #000000; - border-width: 5px 0 5px 5px; -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.tooltip.bottom-left .tooltip-arrow { - top: 0; - left: 5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.tooltip.bottom-right .tooltip-arrow { - top: 0; - right: 5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - white-space: normal; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - background-clip: padding-box; -} - -.popover.top { - margin-top: -10px; -} - -.popover.right { - margin-left: 10px; -} - -.popover.bottom { - margin-top: 10px; -} - -.popover.left { - margin-left: -10px; -} - -.popover-title { - padding: 8px 14px; - margin: 0; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 5px 5px 0 0; -} - -.popover-content { - padding: 9px 14px; -} - -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.popover .arrow { - border-width: 11px; -} - -.popover .arrow:after { - border-width: 10px; - content: ""; -} - -.popover.top .arrow { - bottom: -11px; - left: 50%; - margin-left: -11px; - border-top-color: #999999; - border-top-color: rgba(0, 0, 0, 0.25); - border-bottom-width: 0; -} - -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-top-color: #ffffff; - border-bottom-width: 0; - content: " "; -} - -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-right-color: #999999; - border-right-color: rgba(0, 0, 0, 0.25); - border-left-width: 0; -} - -.popover.right .arrow:after { - bottom: -10px; - left: 1px; - border-right-color: #ffffff; - border-left-width: 0; - content: " "; -} - -.popover.bottom .arrow { - top: -11px; - left: 50%; - margin-left: -11px; - border-bottom-color: #999999; - border-bottom-color: rgba(0, 0, 0, 0.25); - border-top-width: 0; -} - -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-bottom-color: #ffffff; - border-top-width: 0; - content: " "; -} - -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-left-color: #999999; - border-left-color: rgba(0, 0, 0, 0.25); - border-right-width: 0; -} - -.popover.left .arrow:after { - right: 1px; - bottom: -10px; - border-left-color: #ffffff; - border-right-width: 0; - content: " "; -} - -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} - -.carousel-inner > .item { - position: relative; - display: none; - -webkit-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - height: auto; - max-width: 100%; - line-height: 1; -} - -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} - -.carousel-inner > .active { - left: 0; -} - -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.carousel-inner > .next { - left: 100%; -} - -.carousel-inner > .prev { - left: -100%; -} - -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} - -.carousel-inner > .active.left { - left: -100%; -} - -.carousel-inner > .active.right { - left: 100%; -} - -.carousel-control { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 15%; - font-size: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); - opacity: 0.5; - filter: alpha(opacity=50); -} - -.carousel-control.left { - background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); - background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); - background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); -} - -.carousel-control.right { - right: 0; - left: auto; - background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); - background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); - background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); -} - -.carousel-control:hover, -.carousel-control:focus { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-control .icon-prev, -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-left, -.carousel-control .glyphicon-chevron-right { - position: absolute; - top: 50%; - left: 50%; - z-index: 5; - display: inline-block; -} - -.carousel-control .icon-prev, -.carousel-control .icon-next { - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - font-family: serif; -} - -.carousel-control .icon-prev:before { - content: '\2039'; -} - -.carousel-control .icon-next:before { - content: '\203a'; -} - -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - padding-left: 0; - margin-left: -30%; - text-align: center; - list-style: none; -} - -.carousel-indicators li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - cursor: pointer; - border: 1px solid #ffffff; - border-radius: 10px; -} - -.carousel-indicators .active { - width: 12px; - height: 12px; - margin: 0; - background-color: #ffffff; -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 20px; - left: 15%; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} - -.carousel-caption .btn { - text-shadow: none; -} - -@media screen and (min-width: 768px) { - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - margin-left: -15px; - font-size: 30px; - } - .carousel-caption { - right: 20%; - left: 20%; - padding-bottom: 30px; - } - .carousel-indicators { - bottom: 20px; - } -} - -.clearfix:before, -.clearfix:after { - display: table; - content: " "; -} - -.clearfix:after { - clear: both; -} - -.pull-right { - float: right !important; -} - -.pull-left { - float: left !important; -} - -.hide { - display: none !important; -} - -.show { - display: block !important; -} - -.invisible { - visibility: hidden; -} - -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.affix { - position: fixed; -} - -@-ms-viewport { - width: device-width; -} - -@media screen and (max-width: 400px) { - @-ms-viewport { - width: 320px; - } -} - -.hidden { - display: none !important; - visibility: hidden !important; -} - -.visible-xs { - display: none !important; -} - -tr.visible-xs { - display: none !important; -} - -th.visible-xs, -td.visible-xs { - display: none !important; -} - -@media (max-width: 767px) { - .visible-xs { - display: block !important; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-xs.visible-sm { - display: block !important; - } - tr.visible-xs.visible-sm { - display: table-row !important; - } - th.visible-xs.visible-sm, - td.visible-xs.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-xs.visible-md { - display: block !important; - } - tr.visible-xs.visible-md { - display: table-row !important; - } - th.visible-xs.visible-md, - td.visible-xs.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-xs.visible-lg { - display: block !important; - } - tr.visible-xs.visible-lg { - display: table-row !important; - } - th.visible-xs.visible-lg, - td.visible-xs.visible-lg { - display: table-cell !important; - } -} - -.visible-sm { - display: none !important; -} - -tr.visible-sm { - display: none !important; -} - -th.visible-sm, -td.visible-sm { - display: none !important; -} - -@media (max-width: 767px) { - .visible-sm.visible-xs { - display: block !important; - } - tr.visible-sm.visible-xs { - display: table-row !important; - } - th.visible-sm.visible-xs, - td.visible-sm.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-sm.visible-md { - display: block !important; - } - tr.visible-sm.visible-md { - display: table-row !important; - } - th.visible-sm.visible-md, - td.visible-sm.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-sm.visible-lg { - display: block !important; - } - tr.visible-sm.visible-lg { - display: table-row !important; - } - th.visible-sm.visible-lg, - td.visible-sm.visible-lg { - display: table-cell !important; - } -} - -.visible-md { - display: none !important; -} - -tr.visible-md { - display: none !important; -} - -th.visible-md, -td.visible-md { - display: none !important; -} - -@media (max-width: 767px) { - .visible-md.visible-xs { - display: block !important; - } - tr.visible-md.visible-xs { - display: table-row !important; - } - th.visible-md.visible-xs, - td.visible-md.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-md.visible-sm { - display: block !important; - } - tr.visible-md.visible-sm { - display: table-row !important; - } - th.visible-md.visible-sm, - td.visible-md.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-md.visible-lg { - display: block !important; - } - tr.visible-md.visible-lg { - display: table-row !important; - } - th.visible-md.visible-lg, - td.visible-md.visible-lg { - display: table-cell !important; - } -} - -.visible-lg { - display: none !important; -} - -tr.visible-lg { - display: none !important; -} - -th.visible-lg, -td.visible-lg { - display: none !important; -} - -@media (max-width: 767px) { - .visible-lg.visible-xs { - display: block !important; - } - tr.visible-lg.visible-xs { - display: table-row !important; - } - th.visible-lg.visible-xs, - td.visible-lg.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-lg.visible-sm { - display: block !important; - } - tr.visible-lg.visible-sm { - display: table-row !important; - } - th.visible-lg.visible-sm, - td.visible-lg.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-lg.visible-md { - display: block !important; - } - tr.visible-lg.visible-md { - display: table-row !important; - } - th.visible-lg.visible-md, - td.visible-lg.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } -} - -.hidden-xs { - display: block !important; -} - -tr.hidden-xs { - display: table-row !important; -} - -th.hidden-xs, -td.hidden-xs { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-xs { - display: none !important; - } - tr.hidden-xs { - display: none !important; - } - th.hidden-xs, - td.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-xs.hidden-sm { - display: none !important; - } - tr.hidden-xs.hidden-sm { - display: none !important; - } - th.hidden-xs.hidden-sm, - td.hidden-xs.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-xs.hidden-md { - display: none !important; - } - tr.hidden-xs.hidden-md { - display: none !important; - } - th.hidden-xs.hidden-md, - td.hidden-xs.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-xs.hidden-lg { - display: none !important; - } - tr.hidden-xs.hidden-lg { - display: none !important; - } - th.hidden-xs.hidden-lg, - td.hidden-xs.hidden-lg { - display: none !important; - } -} - -.hidden-sm { - display: block !important; -} - -tr.hidden-sm { - display: table-row !important; -} - -th.hidden-sm, -td.hidden-sm { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-sm.hidden-xs { - display: none !important; - } - tr.hidden-sm.hidden-xs { - display: none !important; - } - th.hidden-sm.hidden-xs, - td.hidden-sm.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } - tr.hidden-sm { - display: none !important; - } - th.hidden-sm, - td.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-sm.hidden-md { - display: none !important; - } - tr.hidden-sm.hidden-md { - display: none !important; - } - th.hidden-sm.hidden-md, - td.hidden-sm.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-sm.hidden-lg { - display: none !important; - } - tr.hidden-sm.hidden-lg { - display: none !important; - } - th.hidden-sm.hidden-lg, - td.hidden-sm.hidden-lg { - display: none !important; - } -} - -.hidden-md { - display: block !important; -} - -tr.hidden-md { - display: table-row !important; -} - -th.hidden-md, -td.hidden-md { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-md.hidden-xs { - display: none !important; - } - tr.hidden-md.hidden-xs { - display: none !important; - } - th.hidden-md.hidden-xs, - td.hidden-md.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-md.hidden-sm { - display: none !important; - } - tr.hidden-md.hidden-sm { - display: none !important; - } - th.hidden-md.hidden-sm, - td.hidden-md.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } - tr.hidden-md { - display: none !important; - } - th.hidden-md, - td.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-md.hidden-lg { - display: none !important; - } - tr.hidden-md.hidden-lg { - display: none !important; - } - th.hidden-md.hidden-lg, - td.hidden-md.hidden-lg { - display: none !important; - } -} - -.hidden-lg { - display: block !important; -} - -tr.hidden-lg { - display: table-row !important; -} - -th.hidden-lg, -td.hidden-lg { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-lg.hidden-xs { - display: none !important; - } - tr.hidden-lg.hidden-xs { - display: none !important; - } - th.hidden-lg.hidden-xs, - td.hidden-lg.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-lg.hidden-sm { - display: none !important; - } - tr.hidden-lg.hidden-sm { - display: none !important; - } - th.hidden-lg.hidden-sm, - td.hidden-lg.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-lg.hidden-md { - display: none !important; - } - tr.hidden-lg.hidden-md { - display: none !important; - } - th.hidden-lg.hidden-md, - td.hidden-lg.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } - tr.hidden-lg { - display: none !important; - } - th.hidden-lg, - td.hidden-lg { - display: none !important; - } -} - -.visible-print { - display: none !important; -} - -tr.visible-print { - display: none !important; -} - -th.visible-print, -td.visible-print { - display: none !important; -} - -@media print { - .visible-print { - display: block !important; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } - .hidden-print { - display: none !important; - } - tr.hidden-print { - display: none !important; - } - th.hidden-print, - td.hidden-print { - display: none !important; - } -} \ No newline at end of file diff --git a/awx/ui/static/css/bootstrap.min.css b/awx/ui/static/css/bootstrap.min.css deleted file mode 100644 index a553c4f5e0..0000000000 --- a/awx/ui/static/css/bootstrap.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - *//*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}button,input,select[multiple],textarea{background-image:none}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16.099999999999998px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:21px}}small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#428bca}.text-warning{color:#c09853}.text-danger{color:#b94a48}.text-success{color:#468847}.text-info{color:#3a87ad}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:20px;margin-bottom:10px}h4,h5,h6{margin-top:10px;margin-bottom:10px}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}h1 small,.h1 small{font-size:24px}h2 small,.h2 small{font-size:18px}h3 small,.h3 small,h4 small,.h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{display:block;line-height:1.428571429;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:1.428571429}code,pre{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11{float:left}.col-xs-1{width:8.333333333333332%}.col-xs-2{width:16.666666666666664%}.col-xs-3{width:25%}.col-xs-4{width:33.33333333333333%}.col-xs-5{width:41.66666666666667%}.col-xs-6{width:50%}.col-xs-7{width:58.333333333333336%}.col-xs-8{width:66.66666666666666%}.col-xs-9{width:75%}.col-xs-10{width:83.33333333333334%}.col-xs-11{width:91.66666666666666%}.col-xs-12{width:100%}@media(min-width:768px){.container{max-width:750px}.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11{float:left}.col-sm-1{width:8.333333333333332%}.col-sm-2{width:16.666666666666664%}.col-sm-3{width:25%}.col-sm-4{width:33.33333333333333%}.col-sm-5{width:41.66666666666667%}.col-sm-6{width:50%}.col-sm-7{width:58.333333333333336%}.col-sm-8{width:66.66666666666666%}.col-sm-9{width:75%}.col-sm-10{width:83.33333333333334%}.col-sm-11{width:91.66666666666666%}.col-sm-12{width:100%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-11{left:91.66666666666666%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-11{margin-left:91.66666666666666%}}@media(min-width:992px){.container{max-width:970px}.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11{float:left}.col-md-1{width:8.333333333333332%}.col-md-2{width:16.666666666666664%}.col-md-3{width:25%}.col-md-4{width:33.33333333333333%}.col-md-5{width:41.66666666666667%}.col-md-6{width:50%}.col-md-7{width:58.333333333333336%}.col-md-8{width:66.66666666666666%}.col-md-9{width:75%}.col-md-10{width:83.33333333333334%}.col-md-11{width:91.66666666666666%}.col-md-12{width:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.333333333333332%}.col-md-push-2{left:16.666666666666664%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333333333333%}.col-md-push-5{left:41.66666666666667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.333333333333336%}.col-md-push-8{left:66.66666666666666%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333333333334%}.col-md-push-11{left:91.66666666666666%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-11{right:91.66666666666666%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-11{margin-left:91.66666666666666%}}@media(min-width:1200px){.container{max-width:1170px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11{float:left}.col-lg-1{width:8.333333333333332%}.col-lg-2{width:16.666666666666664%}.col-lg-3{width:25%}.col-lg-4{width:33.33333333333333%}.col-lg-5{width:41.66666666666667%}.col-lg-6{width:50%}.col-lg-7{width:58.333333333333336%}.col-lg-8{width:66.66666666666666%}.col-lg-9{width:75%}.col-lg-10{width:83.33333333333334%}.col-lg-11{width:91.66666666666666%}.col-lg-12{width:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-11{left:91.66666666666666%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-11{margin-left:91.66666666666666%}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table thead>tr>th,.table tbody>tr>th,.table tfoot>tr>th,.table thead>tr>td,.table tbody>tr>td,.table tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table caption+thead tr:first-child th,.table colgroup+thead tr:first-child th,.table thead:first-child tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed thead>tr>th,.table-condensed tbody>tr>th,.table-condensed tfoot>tr>th,.table-condensed thead>tr>td,.table-condensed tbody>tr>td,.table-condensed tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8;border-color:#d6e9c6}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td{background-color:#d0e9c6;border-color:#c9e2b3}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede;border-color:#eed3d7}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td{background-color:#ebcccc;border-color:#e6c1c7}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3;border-color:#fbeed5}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td{background-color:#faf2cc;border-color:#f8e5be}@media(max-width:768px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0;background-color:#fff}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>thead>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>thead>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:45px;line-height:45px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label{color:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.has-error .help-block,.has-error .control-label{color:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.has-success .help-block,.has-success .control-label{color:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;background-color:#dff0d8;border-color:#468847}.form-control-static{padding-top:7px;margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-link{font-weight:normal;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-print:before{content:"\e045"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-briefcase:before{content:"\1f4bc"}.glyphicon-calendar:before{content:"\1f4c5"}.glyphicon-pushpin:before{content:"\1f4cc"}.glyphicon-paperclip:before{content:"\1f4ce"}.glyphicon-camera:before{content:"\1f4f7"}.glyphicon-lock:before{content:"\1f512"}.glyphicon-bell:before{content:"\1f514"}.glyphicon-bookmark:before{content:"\1f516"}.glyphicon-fire:before{content:"\1f525"}.glyphicon-wrench:before{content:"\1f527"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0 dotted;border-left:4px solid transparent;content:""}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#fff;text-decoration:none;background-color:#428bca}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0 dotted;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-default .caret{border-top-color:#333}.btn-primary .caret,.btn-success .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret{border-top-color:#fff}.dropup .btn-default .caret{border-bottom-color:#333}.dropup .btn-primary .caret,.dropup .btn-success .caret,.dropup .btn-warning .caret,.dropup .btn-danger .caret,.dropup .btn-info .caret{border-bottom-color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:5px 10px;padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified .btn{display:table-cell;float:none;width:1%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group.col{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}}.nav-tabs.nav-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs.nav-justified>.active>a{border-bottom-color:#fff}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:5px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs-justified>.active>a{border-bottom-color:#fff}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.nav .caret{border-top-color:#428bca;border-bottom-color:#428bca}.nav a:hover .caret{border-top-color:#2a6496;border-bottom-color:#2a6496}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;z-index:1000;min-height:50px;margin-bottom:20px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-collapse .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-collapse .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-collapse .navbar-text:last-child{margin-right:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;border-width:0 0 1px}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;z-index:1030}.navbar-fixed-bottom{bottom:0;margin-bottom:0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-text{float:left;margin-top:15px;margin-bottom:15px}@media(min-width:768px){.navbar-text{margin-right:15px;margin-left:15px}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e6e6e6}.navbar-default .navbar-nav>.dropdown>a:hover .caret,.navbar-default .navbar-nav>.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.open>a .caret,.navbar-default .navbar-nav>.open>a:hover .caret,.navbar-default .navbar-nav>.open>a:focus .caret{border-top-color:#555;border-bottom-color:#555}.navbar-default .navbar-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .navbar-nav>.open>a .caret,.navbar-inverse .navbar-nav>.open>a:hover .caret,.navbar-inverse .navbar-nav>.open>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.badge:empty{display:none}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.btn .badge{position:relative;top:-1px}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.jumbotron h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.thumbnail{display:inline-block;display:block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img{display:block;height:auto;max-width:100%}a.thumbnail:hover,a.thumbnail:focus{border-color:#428bca}.thumbnail>img{margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table{margin-bottom:0}.panel>.panel-body+.table{border-top:1px solid #ddd}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-title{margin-top:0;margin-bottom:0;font-size:16px}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#fbeed5}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#eed3d7}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#eed3d7}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}body.modal-open,.modal-open .navbar-fixed-top,.modal-open .navbar-fixed-bottom{margin-right:15px}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{z-index:1050;width:auto;padding:10px;margin-right:auto;margin-left:auto}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{right:auto;left:50%;width:600px;padding-top:30px;padding-bottom:30px}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.5)),to(rgba(0,0,0,0.0001)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.0001)),to(rgba(0,0,0,0.5)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;left:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.affix{position:fixed}@-ms-viewport{width:device-width}@media screen and (max-width:400px){@-ms-viewport{width:320px}}.hidden{display:none!important;visibility:hidden!important}.visible-xs{display:none!important}tr.visible-xs{display:none!important}th.visible-xs,td.visible-xs{display:none!important}@media(max-width:767px){.visible-xs{display:block!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm{display:none!important}tr.visible-sm{display:none!important}th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md{display:none!important}tr.visible-md{display:none!important}th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-md.visible-lg{display:block!important}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg{display:none!important}tr.visible-lg{display:none!important}th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-lg{display:block!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}.hidden-xs{display:block!important}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs{display:none!important}tr.hidden-xs{display:none!important}th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm{display:none!important}tr.hidden-xs.hidden-sm{display:none!important}th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md{display:none!important}tr.hidden-xs.hidden-md{display:none!important}th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg{display:none!important}tr.hidden-xs.hidden-lg{display:none!important}th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs{display:none!important}tr.hidden-sm.hidden-xs{display:none!important}th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}tr.hidden-sm{display:none!important}th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md{display:none!important}tr.hidden-sm.hidden-md{display:none!important}th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg{display:none!important}tr.hidden-sm.hidden-lg{display:none!important}th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs{display:none!important}tr.hidden-md.hidden-xs{display:none!important}th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm{display:none!important}tr.hidden-md.hidden-sm{display:none!important}th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}tr.hidden-md{display:none!important}th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg{display:none!important}tr.hidden-md.hidden-lg{display:none!important}th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs{display:none!important}tr.hidden-lg.hidden-xs{display:none!important}th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm{display:none!important}tr.hidden-lg.hidden-sm{display:none!important}th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md{display:none!important}tr.hidden-lg.hidden-md{display:none!important}th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg{display:none!important}tr.hidden-lg{display:none!important}th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print{display:none!important}tr.visible-print{display:none!important}th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}.hidden-print{display:none!important}tr.hidden-print{display:none!important}th.hidden-print,td.hidden-print{display:none!important}} \ No newline at end of file diff --git a/awx/ui/static/css/select2-bootstrap.css b/awx/ui/static/css/select2-bootstrap.css deleted file mode 100644 index 909971074c..0000000000 --- a/awx/ui/static/css/select2-bootstrap.css +++ /dev/null @@ -1,87 +0,0 @@ -.form-control .select2-choice { - border: 0; - border-radius: 2px; -} - -.form-control .select2-choice .select2-arrow { - border-radius: 0 2px 2px 0; -} - -.form-control.select2-container { - height: auto !important; - padding: 0px; -} - -.form-control.select2-container.select2-dropdown-open { - border-color: #5897FB; - border-radius: 3px 3px 0 0; -} - -.form-control .select2-container.select2-dropdown-open .select2-choices { - border-radius: 3px 3px 0 0; -} - -.form-control.select2-container .select2-choices { - border: 0 !important; - border-radius: 3px; -} - -.control-group.warning .select2-container .select2-choice, -.control-group.warning .select2-container .select2-choices, -.control-group.warning .select2-container-active .select2-choice, -.control-group.warning .select2-container-active .select2-choices, -.control-group.warning .select2-dropdown-open.select2-drop-above .select2-choice, -.control-group.warning .select2-dropdown-open.select2-drop-above .select2-choices, -.control-group.warning .select2-container-multi.select2-container-active .select2-choices { - border: 1px solid #C09853 !important; -} - -.control-group.warning .select2-container .select2-choice div { - border-left: 1px solid #C09853 !important; - background: #FCF8E3 !important; -} - -.control-group.error .select2-container .select2-choice, -.control-group.error .select2-container .select2-choices, -.control-group.error .select2-container-active .select2-choice, -.control-group.error .select2-container-active .select2-choices, -.control-group.error .select2-dropdown-open.select2-drop-above .select2-choice, -.control-group.error .select2-dropdown-open.select2-drop-above .select2-choices, -.control-group.error .select2-container-multi.select2-container-active .select2-choices { - border: 1px solid #B94A48 !important; -} - -.control-group.error .select2-container .select2-choice div { - border-left: 1px solid #B94A48 !important; - background: #F2DEDE !important; -} - -.control-group.info .select2-container .select2-choice, -.control-group.info .select2-container .select2-choices, -.control-group.info .select2-container-active .select2-choice, -.control-group.info .select2-container-active .select2-choices, -.control-group.info .select2-dropdown-open.select2-drop-above .select2-choice, -.control-group.info .select2-dropdown-open.select2-drop-above .select2-choices, -.control-group.info .select2-container-multi.select2-container-active .select2-choices { - border: 1px solid #3A87AD !important; -} - -.control-group.info .select2-container .select2-choice div { - border-left: 1px solid #3A87AD !important; - background: #D9EDF7 !important; -} - -.control-group.success .select2-container .select2-choice, -.control-group.success .select2-container .select2-choices, -.control-group.success .select2-container-active .select2-choice, -.control-group.success .select2-container-active .select2-choices, -.control-group.success .select2-dropdown-open.select2-drop-above .select2-choice, -.control-group.success .select2-dropdown-open.select2-drop-above .select2-choices, -.control-group.success .select2-container-multi.select2-container-active .select2-choices { - border: 1px solid #468847 !important; -} - -.control-group.success .select2-container .select2-choice div { - border-left: 1px solid #468847 !important; - background: #DFF0D8 !important; -} diff --git a/awx/ui/static/css/select2-spinner.gif b/awx/ui/static/css/select2-spinner.gif deleted file mode 100644 index 5b33f7e54f4e55b6b8774d86d96895db9af044b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1849 zcma*odr(tX9tZI2z31lM+(&YVk%mZ}5P~KlG2s=WSbGzm0!x7^P##Mnh7t-jP!X0Q zk_SQ}Po-L1tlDK;6l?(>v)e5ZBQx4|Y-Q?nr@Px3?9h(3ZWr3^tj=`TP57gKr87N$ zp2wWee1GRRCwo_xahnw)5cxNPJbCg2L6DV|6`#+yw6v6!mDS$f9-JvFD^n;GQ&UrZ zzh5jCkByB101O60U0q#p_1BM>Cv-vP?&s4@g_((4_1L=L$(a91)0=J91Gas#R{McE znYG^9*0A5YZ>#;~+Wkn(W5B0^yELIYLP!K}mB~<)AM@1&nqekynuaEGqPrzoH|KodRXJy)%+w_fu3nE5>@Bd_b zqC$EQ;{c`T&?EsNO|igL9gC7Ygxv?aQUEXMq?~>wg{EyW;VcJ37CUF#HjrT=KQO_* zS>M9yydXk18D(+QDJ1>r);Lav_uYKp$T?4vr{Q$lTo&pKv^?(>L-)G2*lwH!Ah7k? z7oH<8h-(KTKt5V6$8gF)C7Io&P5=SjTh)=zV=E2EUhQZP##L8S{d%UK>>+y82>+FV+#^BzW7u3F)Bb>=lYQ%%j`F>ASe zo*cw@V#u6T`A2He;70mR(V&iV&-7{qP~=SRf&jm9-T{*ZeZ}$rd0#6c&fLG^xJcf5 z+p<`wJYgW+_s*V{uI$nMB;%8`S_3>PfGOj3Rq}@Cx^+j?rk92fANSFDBYnOqQ>Vdj z)(|$AhP4t&Lb=Gvo2#3Gl%9<=Gv`Mz?Po@P4iLF!x}GUWJICDlFk-hS^Whyh7x~VH z@0vD1>HYD4&e+~yzS*-sFR{9`{QEEZO1zg7>R&7cHts-6j!xHVdA8eI+ZlVzd%`es zJT@$#GX(gvCJ1oJN%yLBK}{V=V;seo;!w|Yte!W1%5qLNFWqvZW>h&IiH+oPT=b@E zPhGzv5=(Un*X>v`>%8h_nj^NdYcE6NHS_ifkCV$*D)Tqrbu`s;<=t<4 zAHNqNV?6(g<1PY-w@#I-WYFViz?9TrkMr)u0g`O`u|>T;k|2sV*YF^punvT;$SuTy{j3Gv)yqD!R_CF>yR)MzmmYS5v+~R zXAdD%ng9?df;wd8GxR#%3O+gz};Vo;)sK%Bj-q>Oq%R7JU-KD?vYu>#2UjaDo z&8$>5xW~?KPD_#XFToU1hIb*VOMidUr6iYiO0N|i-7s`T8!cFT`rN!^1Pt78J93i6 z5HI1wIM$94m{3SLDvISDe6$ZG1;eq_D9RTaaC>=cO{@Bs>$IlPCPJJ$h$)-3vzNUQ6OsN#_zWxey!_9%hxwH2_dEJi=yY|1c7nDm2_Lm!Cof8-R_+9UkS zcBE(o47yE)oMR(Q=dp1a2wTX5KvvGyLqlWTa7V&!A*|w|)ax~1_~aJ0=_Lilg*0iQk7#ZD EAHN$8j{pDw diff --git a/awx/ui/static/css/select2.css b/awx/ui/static/css/select2.css deleted file mode 100644 index 2b32ed6f28..0000000000 --- a/awx/ui/static/css/select2.css +++ /dev/null @@ -1,615 +0,0 @@ -/* -Version: 3.4.5 Timestamp: Mon Nov 4 08:22:42 PST 2013 -*/ -.select2-container { - margin: 0; - position: relative; - display: inline-block; - /* inline-block for ie7 */ - zoom: 1; - *display: inline; - vertical-align: middle; -} - -.select2-container, -.select2-drop, -.select2-search, -.select2-search input { - /* - Force border-box so that % widths fit the parent - container without overlap because of margin/padding. - - More Info : http://www.quirksmode.org/css/box.html - */ - -webkit-box-sizing: border-box; /* webkit */ - -moz-box-sizing: border-box; /* firefox */ - box-sizing: border-box; /* css3 */ -} - -.select2-container .select2-choice { - display: block; - height: 26px; - padding: 0 0 0 8px; - overflow: hidden; - position: relative; - - border: 1px solid #aaa; - white-space: nowrap; - line-height: 26px; - color: #444; - text-decoration: none; - - border-radius: 4px; - - background-clip: padding-box; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - background-color: #fff; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff)); - background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%); - background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0); - background-image: linear-gradient(top, #fff 0%, #eee 50%); -} - -.select2-container.select2-drop-above .select2-choice { - border-bottom-color: #aaa; - - border-radius: 0 0 4px 4px; - - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff)); - background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%); - background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0); - background-image: linear-gradient(top, #eee 0%, #fff 90%); -} - -.select2-container.select2-allowclear .select2-choice .select2-chosen { - margin-right: 42px; -} - -.select2-container .select2-choice > .select2-chosen { - margin-right: 26px; - display: block; - overflow: hidden; - - white-space: nowrap; - - text-overflow: ellipsis; -} - -.select2-container .select2-choice abbr { - display: none; - width: 12px; - height: 12px; - position: absolute; - right: 24px; - top: 8px; - - font-size: 1px; - text-decoration: none; - - border: 0; - background: url('select2.png') right top no-repeat; - cursor: pointer; - outline: 0; -} - -.select2-container.select2-allowclear .select2-choice abbr { - display: inline-block; -} - -.select2-container .select2-choice abbr:hover { - background-position: right -11px; - cursor: pointer; -} - -.select2-drop-mask { - border: 0; - margin: 0; - padding: 0; - position: fixed; - left: 0; - top: 0; - min-height: 100%; - min-width: 100%; - height: auto; - width: auto; - opacity: 0; - z-index: 9998; - /* styles required for IE to work */ - background-color: #fff; - filter: alpha(opacity=0); -} - -.select2-drop { - width: 100%; - margin-top: -1px; - position: absolute; - z-index: 9999; - top: 100%; - - background: #fff; - color: #000; - border: 1px solid #aaa; - border-top: 0; - - border-radius: 0 0 4px 4px; - - -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); - box-shadow: 0 4px 5px rgba(0, 0, 0, .15); -} - -.select2-drop-auto-width { - border-top: 1px solid #aaa; - width: auto; -} - -.select2-drop-auto-width .select2-search { - padding-top: 4px; -} - -.select2-drop.select2-drop-above { - margin-top: 1px; - border-top: 1px solid #aaa; - border-bottom: 0; - - border-radius: 4px 4px 0 0; - - -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); - box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); -} - -.select2-drop-active { - border: 1px solid #5897fb; - border-top: none; -} - -.select2-drop.select2-drop-above.select2-drop-active { - border-top: 1px solid #5897fb; -} - -.select2-container .select2-choice .select2-arrow { - display: inline-block; - width: 18px; - height: 100%; - position: absolute; - right: 0; - top: 0; - - border-left: 1px solid #aaa; - border-radius: 0 4px 4px 0; - - background-clip: padding-box; - - background: #ccc; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); - background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%); - background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0); - background-image: linear-gradient(top, #ccc 0%, #eee 60%); -} - -.select2-container .select2-choice .select2-arrow b { - display: block; - width: 100%; - height: 100%; - background: url('select2.png') no-repeat 0 1px; -} - -.select2-search { - display: inline-block; - width: 100%; - min-height: 26px; - margin: 0; - padding-left: 4px; - padding-right: 4px; - - position: relative; - z-index: 10000; - - white-space: nowrap; -} - -.select2-search input { - width: 100%; - height: auto !important; - min-height: 26px; - padding: 4px 20px 4px 5px; - margin: 0; - - outline: 0; - font-family: sans-serif; - font-size: 1em; - - border: 1px solid #aaa; - border-radius: 0; - - -webkit-box-shadow: none; - box-shadow: none; - - background: #fff url('select2.png') no-repeat 100% -22px; - background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); - background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #fff 85%, #eee 99%); -} - -.select2-drop.select2-drop-above .select2-search input { - margin-top: 4px; -} - -.select2-search input.select2-active { - background: #fff url('select2-spinner.gif') no-repeat 100%; - background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); - background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #fff 85%, #eee 99%); -} - -.select2-container-active .select2-choice, -.select2-container-active .select2-choices { - border: 1px solid #5897fb; - outline: none; - - -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3); - box-shadow: 0 0 5px rgba(0, 0, 0, .3); -} - -.select2-dropdown-open .select2-choice { - border-bottom-color: transparent; - -webkit-box-shadow: 0 1px 0 #fff inset; - box-shadow: 0 1px 0 #fff inset; - - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - - background-color: #eee; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee)); - background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%); - background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0); - background-image: linear-gradient(top, #fff 0%, #eee 50%); -} - -.select2-dropdown-open.select2-drop-above .select2-choice, -.select2-dropdown-open.select2-drop-above .select2-choices { - border: 1px solid #5897fb; - border-top-color: transparent; - - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee)); - background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%); - background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0); - background-image: linear-gradient(bottom, #fff 0%, #eee 50%); -} - -.select2-dropdown-open .select2-choice .select2-arrow { - background: transparent; - border-left: none; - filter: none; -} -.select2-dropdown-open .select2-choice .select2-arrow b { - background-position: -18px 1px; -} - -/* results */ -.select2-results { - max-height: 200px; - padding: 0 0 0 4px; - margin: 4px 4px 4px 0; - position: relative; - overflow-x: hidden; - overflow-y: auto; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -.select2-results ul.select2-result-sub { - margin: 0; - padding-left: 0; -} - -.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px } -.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px } -.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px } -.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px } -.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px } -.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px } -.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px } - -.select2-results li { - list-style: none; - display: list-item; - background-image: none; -} - -.select2-results li.select2-result-with-children > .select2-result-label { - font-weight: bold; -} - -.select2-results .select2-result-label { - padding: 3px 7px 4px; - margin: 0; - cursor: pointer; - - min-height: 1em; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.select2-results .select2-highlighted { - background: #3875d7; - color: #fff; -} - -.select2-results li em { - background: #feffde; - font-style: normal; -} - -.select2-results .select2-highlighted em { - background: transparent; -} - -.select2-results .select2-highlighted ul { - background: #fff; - color: #000; -} - - -.select2-results .select2-no-results, -.select2-results .select2-searching, -.select2-results .select2-selection-limit { - background: #f4f4f4; - display: list-item; -} - -/* -disabled look for disabled choices in the results dropdown -*/ -.select2-results .select2-disabled.select2-highlighted { - color: #666; - background: #f4f4f4; - display: list-item; - cursor: default; -} -.select2-results .select2-disabled { - background: #f4f4f4; - display: list-item; - cursor: default; -} - -.select2-results .select2-selected { - display: none; -} - -.select2-more-results.select2-active { - background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%; -} - -.select2-more-results { - background: #f4f4f4; - display: list-item; -} - -/* disabled styles */ - -.select2-container.select2-container-disabled .select2-choice { - background-color: #f4f4f4; - background-image: none; - border: 1px solid #ddd; - cursor: default; -} - -.select2-container.select2-container-disabled .select2-choice .select2-arrow { - background-color: #f4f4f4; - background-image: none; - border-left: 0; -} - -.select2-container.select2-container-disabled .select2-choice abbr { - display: none; -} - - -/* multiselect */ - -.select2-container-multi .select2-choices { - height: auto !important; - height: 1%; - margin: 0; - padding: 0; - position: relative; - - border: 1px solid #aaa; - cursor: text; - overflow: hidden; - - background-color: #fff; - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff)); - background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%); - background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%); - background-image: linear-gradient(top, #eee 1%, #fff 15%); -} - -.select2-locked { - padding: 3px 5px 3px 5px !important; -} - -.select2-container-multi .select2-choices { - min-height: 26px; -} - -.select2-container-multi.select2-container-active .select2-choices { - border: 1px solid #5897fb; - outline: none; - - -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3); - box-shadow: 0 0 5px rgba(0, 0, 0, .3); -} -.select2-container-multi .select2-choices li { - float: left; - list-style: none; -} -.select2-container-multi .select2-choices .select2-search-field { - margin: 0; - padding: 0; - white-space: nowrap; -} - -.select2-container-multi .select2-choices .select2-search-field input { - padding: 5px; - margin: 1px 0; - - font-family: sans-serif; - font-size: 100%; - color: #666; - outline: 0; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - background: transparent !important; -} - -.select2-container-multi .select2-choices .select2-search-field input.select2-active { - background: #fff url('select2-spinner.gif') no-repeat 100% !important; -} - -.select2-default { - color: #999 !important; -} - -.select2-container-multi .select2-choices .select2-search-choice { - padding: 3px 5px 3px 18px; - margin: 3px 0 3px 5px; - position: relative; - - line-height: 13px; - color: #333; - cursor: default; - border: 1px solid #aaaaaa; - - border-radius: 3px; - - -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05); - box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05); - - background-clip: padding-box; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - background-color: #e4e4e4; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0); - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee)); - background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); - background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); - background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); -} -.select2-container-multi .select2-choices .select2-search-choice .select2-chosen { - cursor: default; -} -.select2-container-multi .select2-choices .select2-search-choice-focus { - background: #d4d4d4; -} - -.select2-search-choice-close { - display: block; - width: 12px; - height: 13px; - position: absolute; - right: 3px; - top: 4px; - - font-size: 1px; - outline: none; - background: url('select2.png') right top no-repeat; -} - -.select2-container-multi .select2-search-choice-close { - left: 3px; -} - -.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover { - background-position: right -11px; -} -.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close { - background-position: right -11px; -} - -/* disabled styles */ -.select2-container-multi.select2-container-disabled .select2-choices { - background-color: #f4f4f4; - background-image: none; - border: 1px solid #ddd; - cursor: default; -} - -.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice { - padding: 3px 5px 3px 5px; - border: 1px solid #ddd; - background-image: none; - background-color: #f4f4f4; -} - -.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none; - background: none; -} -/* end multiselect */ - - -.select2-result-selectable .select2-match, -.select2-result-unselectable .select2-match { - text-decoration: underline; -} - -.select2-offscreen, .select2-offscreen:focus { - clip: rect(0 0 0 0) !important; - width: 1px !important; - height: 1px !important; - border: 0 !important; - margin: 0 !important; - padding: 0 !important; - overflow: hidden !important; - position: absolute !important; - outline: 0 !important; - left: 0px !important; - top: 0px !important; -} - -.select2-display-none { - display: none; -} - -.select2-measure-scrollbar { - position: absolute; - top: -10000px; - left: -10000px; - width: 100px; - height: 100px; - overflow: scroll; -} -/* Retina-ize icons */ - -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) { - .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b { - background-image: url('select2x2.png') !important; - background-repeat: no-repeat !important; - background-size: 60px 40px !important; - } - .select2-search input { - background-position: 100% -21px !important; - } -} diff --git a/awx/ui/static/css/select2.png b/awx/ui/static/css/select2.png deleted file mode 100644 index 1d804ffb99699b9e030f1010314de0970b5a000d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 613 zcmV-r0-F7aP)#WY!I$JQV$)A5aAS1BM||2XVJl=+L1^1S1H% zM-&lx?NZpUrHhn>fk<>POqf2sh40}xxGZfc+t+#Eb(qHy9_3*1(U%t9t)QDnI#YAL(|ACV(>)>6WD-t!8tutHkdb^#3`HzoJG3A2@T`% zA|K@o*b!`R#(7)PWrMFn2))Ca3MR4(zaT`Zr61*kZK5NPnZwQszxh$fyv3?&4c>$q z2m=+yc0dRXRAsPDxF6sD;@rK4JGdR_``1S~o6Xi@2&aR6hcSrEp9HVRzEqVDqBn<1%hR=D4e1f^ra^A|34Cjc=Gny{F(o#MrvPYgZuTJOz(n)-F<| zj()qR;C={)N<0RRvDZ^@6ND+W*}gh-Lip(MDt!(zMSO)!j2j+*hxgzC-e3$@(O2p* zu;+gddm(cZwXTCLx*Ky4THOa*^b^F`woveIeCK^0aR|TJ00000NkvXXu0mjfA#WC6 diff --git a/awx/ui/static/css/select2x2.png b/awx/ui/static/css/select2x2.png deleted file mode 100644 index 4bdd5c961d452c49dfa0789c2c7ffb82c238fc24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 845 zcmV-T1G4;yP)upQ6WKflyv?C|ADVW!U!t`EpA+x zB)5#EjWk-_X77YJZtQo`E0SF)^1bZr%)B7Cd`*OK*r z5WG-7e-R9G9^69ksDt29&oyHqxPSt|-S>xi3%PTd+GjY+BGF|nWC(7D-sd(kxqd9~ zS@2YF5vB+>dP8+$l^{oO3-lEWiGA*QIU)Wds#9M6RZ9N zcQ4y4)xqQOxD=vwu%7cz1nY#$lT&y8HCmkWgpwQP#3dhnYj9|2aS_R}IUF_^6s#$= zTm%~>A#oM?KIg$kh=<`gJkeoHa2LrulVy$Yx+N_0R3$4I!R*0677f(FKqm`2_o4~W z0h}fQZ`lC^1A+m;fM7uI(R1`S0KtG@KrkQ}5DW+&@cTnDVIow56KciMk7a899t0bC zC1KI{TsMe5NAR%GD_5`B-@ad4k~K3SO%H z_M31|`HV?E6)u$E3c&*<*n20+V@mRCop>R5;DWuZCmjSo7p@R&OYl^@G0?(c="Error",d=a.non_field_errors[0]):(c="Error",d="The login attempt failed with a status of: "+b),o.reset(),h(c,d,"alert-danger",l)}))}}function CredentialsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){o("htmlTemplate"),t("start");var v,w=h,x=q("credentials"),y=i,z=c.path().replace(/^\//,"").split("/")[0],A="credentials"===z?"edit":"select",B=y.inject(w,{mode:A});B.selected=[],B.credentialLoading=!0,v=q(z)+("users"===z?e.user_id+"/credentials/":e.team_id+"/credentials/"),r({scope:B,list:w,url:v,returnToCaller:1}),B.removePostRefresh&&B.removePostRefresh(),B.removePostRefresh=B.$on("PostRefresh",function(){var a,b;for(t("stop"),$("#prompt-modal").off(),w.fields.kind.searchOptions=B.credential_kind_options,a=0;a/g," ");for(x in z.fields.status.searchOptions)if(z.fields.status.searchOptions[x].value===b.status){B[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[x];break}}if(b.source){B[z.iterator+"SearchField"]="source",B[z.iterator+"SelectShow"]=!0,B[z.iterator+"SearchSelectOpts"]=z.fields.source.searchOptions,B[z.iterator+"SearchFieldLabel"]=z.fields.source.label.replace(//g," ");for(x in z.fields.source.searchOptions)if(z.fields.source.searchOptions[x].value===b.source){B[z.iterator+"SearchSelectValue"]=z.fields.source.searchOptions[x];break}b.status&&(B[z.iterator+"ExtraParms"]="&inventory_source__status__icontains="+b.status)}b.has_external_source&&(B[z.iterator+"SearchField"]="has_external_source",B[z.iterator+"SearchValue"]=z.fields.has_external_source.searchValue,B[z.iterator+"InputDisable"]=!0,B[z.iterator+"SearchType"]="in",B[z.iterator+"SearchFieldLabel"]=z.fields.has_external_source.label),B.search(z.iterator),f(),B.showActivity=function(){p({scope:B})},B.editGroup=function(a,b){q({scope:B,group_id:a,inventory_id:b,groups_reload:!1})},B.viewUpdateStatus=function(a){B.groups=B.home_groups,o({scope:B,tree_id:a})},B.updateGroup=function(a){var b=w({list:B.home_groups,key:"id",val:a});b&&(u(b.source)||("updating"===b.status?s("Update in Progress","The inventory update process is currently running for group "+b.name+". Use the Refresh button to monitor the status.","alert-info"):(r("start"),t.setUrl(b.related.inventory_source),t.get().success(function(a){v({scope:B,url:a.related.update,group_name:a.summary_fields.group.name,group_source:a.source,tree_id:b.id,group_id:b.id})}).error(function(a,c){e(B,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+b.related.inventory_source+" POST returned status: "+c})}))))},B.refresh=function(){B.search(z.iterator,null,!1,!0)}}function HomeHosts(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){h("htmlTemplate");var s=d,t=c,u=i("hosts"),v=s.inject(t,{mode:"edit"});v.removePostRefresh&&v.removePostRefresh(),v.removePostRefresh=v.$on("PostRefresh",function(){for(var a=0;a0?(z.inventories[a].failed_hosts_tip=z.inventories[a].hosts_with_active_failures+(1===z.inventories[a].hosts_with_active_failures?" host":" hosts")+" with job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="true"):0===z.inventories[a].total_hosts?(z.inventories[a].failed_hosts_tip="No hosts defined. Click to add.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="na"):(z.inventories[a].failed_hosts_tip=z.inventories[a].total_hosts+(z.inventories[a].total_hosts>1?" hosts":" host")+" with no job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="false"),z.inventories[a].status=z.inventories[a].inventory_sources_with_failures+" / "+z.inventories[a].total_inventory_sources,z.inventories[a].inventory_sources_with_failures>0?(z.inventories[a].status_tip=z.inventories[a].inventory_sources_with_failures+" cloud "+(1===z.inventories[a].inventory_sources_with_failures?"source":"sources")+" with failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="failed"):0===z.inventories[a].total_inventory_sources?(z.inventories[a].status_tip="Not synced with a cloud source. Click to edit.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="na"):(z.inventories[a].status_tip=z.inventories[a].total_inventory_sources+" cloud "+(z.inventories[a].total_inventory_sources>1?"sources":"source")+" with no failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="successful")}),z.removeRefreshInventories&&z.removeRefreshInventories(),z.removeRefreshInventories=z.$on("RefreshInventories",function(){z.search(u.iterator)}),z.showActivity=function(){s({scope:z})},z.editInventoryProperties=function(a){t({scope:z,inventory_id:a})},z.addInventory=function(){c.path(c.path()+"/add")},z.editInventory=function(a){c.path(c.path()+"/"+a)},z.deleteInventory=function(a,b){var c=function(){var b=v+a+"/";$("#prompt-modal").on("hidden.bs.modal",function(){r("start")}),$("#prompt-modal").modal("hide"),f.setUrl(b),f.destroy().success(function(){z.search(u.iterator)}).error(function(a,c){r("stop"),p(z,a,c,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+c})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},z.lookupOrganization=function(a){f.setUrl(q("organizations")+a+"/"),f.get().success(function(a){return a.name})},z.viewJobs=function(a){c.url("/jobs/?inventory__int="+a)},z.viewFailedJobs=function(a){c.url("/jobs/?inventory__int="+a+"&status=failed")}}function InventoriesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){n("htmlTemplate");var w,x=t("inventory"),y=g,z=h;y.well=!0,y.formLabelSize=null,y.formFieldSize=null,w=z.inject(y,{mode:"add",related:!1}),w.inventoryParseType="yaml",z.reset(),l(),u(w,"inventory_variables","inventoryParseType"),s({scope:w,form:y,current_item:f.organization_id?f.organization_id:null,list:p,field:"organization"}),w.formSave=function(){z.clearApiErrors(),v("start");try{var a,b,c;if(b="json"===w.inventoryParseType?JSON.parse(w.inventory_variables):jsyaml.load(w.inventory_variables),"object"!=typeof b)throw"failed to return an object!";c={};for(a in y.fields)"inventory_variables"!==a&&(y.fields[a].realName?c[y.fields[a].realName]=w[a]:c[a]=w[a]);i.setUrl(x),i.post(c).success(function(a){var c=a.id;w.inventory_variables?(i.setUrl(a.related.variable_data),i.put(b).success(function(){v("stop"),d.path("/inventories/"+c+"/")}).error(function(a,b){v("stop"),k(w,a,b,null,{hdr:"Error!",msg:"Failed to add inventory varaibles. PUT returned status: "+b})})):(v("stop"),d.path("/inventories/"+c+"/"))}).error(function(a,b){v("stop"),k(w,a,b,y,{hdr:"Error!",msg:"Failed to add new inventory. Post returned status: "+b})})}catch(e){v("stop"),j("Error","Error parsing inventory variables. Parser returned: "+e)}},w.formReset=function(){z.reset()}}function InventoriesEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P){f("htmlTemplate");var Q=e,R=g;a.inventory_id=c.inventory_id,r({path:b.path(),title:"{{ inventory_name }}"}),a.removeGroupTreeLoaded&&a.removeGroupTreeLoaded(),a.removeGroupTreeLoaded=a.$on("GroupTreeLoaded",function(b,c,e){var f,g;f=angular.element(document.getElementById("breadcrumbs")),f.html(q({list:R,mode:"edit"})),d(f)(a),Q.inject(R,{mode:"edit",id:"groups-container",breadCrumbs:!1,searchSize:"col-lg-5 col-md-5 col-sm-5"}),a.groups=e,a.inventory_name=c,a.groups.length>0?(a.selected_tree_id=a.groups[0].id,a.selected_group_id=a.groups[0].group_id,a.groups[0].selected_class="selected",a.groups[0].active_class="active-row",a.selected_group_name=a.groups[0].name):(a.selected_tree_id=null,a.selected_group_id=null),a.show_failures=!1,l({scope:a,inventory_id:a.inventory_id,tree_id:a.selected_tree_id,group_id:a.selected_group_id}),setTimeout(function(){$("#groups_table .name-column").each(function(){var a,b,c,d,e;a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%",$(this).find(".group-name").css({width:e})}),L("#groups_table .group-name a"),L("#hosts_table .host-name a")},2500),M(),g=P("inventoryAutoHelp"),"off"!==g&&a.autoShowGroupHelp&&a.showGroupHelp({autoShow:!0})}),a.removeGroupTreeRefreshed&&a.removeGroupTreeRefreshed(),a.removeGroupTreeRefreshed=a.$on("GroupTreeRefreshed",function(){setTimeout(function(){L("#groups_table .group-name a")},2500),a.showHosts(a.selected_tree_id,a.selected_group_id,!1)}),a.removeGroupDeleteCompleted&&a.removeGroupDeleteCompleted(),a.removeGroupDeleteCompleted=a.$on("GroupDeleteCompleted",function(){a.selected_tree_id=1,a.selected_group_id=null,i({scope:a,inventory_id:a.inventory_id,refresh:!0})}),a.removeCopMoveGroup&&a.removeCopyMoveGroup(),a.removeCopyMoveGroup=a.$on("CopyMoveGroup",function(b,c,d){G({scope:a,target_tree_id:d,inbound_tree_id:c})}),a.removeCopMoveHost&&a.removeCopyMoveHost(),a.removeCopyMoveHost=a.$on("CopyMoveHost",function(b,c,d){H({scope:a,target_tree_id:c,host_id:d})}),a.showHosts=function(b,c,d){if(null!==b){j("start"),a.selected_tree_id=b,a.selected_group_id=c,a.hosts=[],a.show_failures=d;for(var e=0;e"+c.name+". Use the Refresh button to monitor the status.","alert-info"):(j("start"),t.setUrl(c.related.inventory_source),t.get().success(function(b){v({scope:a,url:b.related.update,group_name:b.summary_fields.group.name,group_source:b.source,tree_id:c.id,group_id:c.group_id})}).error(function(b,d){j("stop"),u(a,b,d,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+c.related.inventory_source+" POST returned status: "+d})}))))},a.cancelUpdate=function(b){z({scope:a,tree_id:b})},a.toggle=function(b){x({scope:a,list:R,id:b})},a.refreshGroups=function(b,c){b&&(a.selected_tree_id=b,a.selected_group_id=c),i({scope:a,inventory_id:a.inventory_id,refresh:!0})},a.viewUpdateStatus=function(b,c){y({scope:a,tree_id:b,group_id:c})},a.deleteGroup=function(b,c){p({scope:a,tree_id:b,group_id:c,inventory_id:a.inventory_id})},a.createHost=function(){B({scope:a})},a.editInventoryProperties=function(){C({scope:a,inventory_id:a.inventory_id})},a.editHost=function(b){D({scope:a,host_id:b,inventory_id:a.inventory_id})},a.deleteHost=function(b,c){E({scope:a,host_id:b,host_name:c})},a.toggleHostEnabled=function(b,c){F({scope:a,host_id:b,external_source:c})},a.showGroupActivity=function(){var b,c,d;a.selected_group_id?(d=A({list:a.groups,key:"id",val:a.selected_tree_id}),b=J("activity_stream")+"?group__id="+a.selected_group_id,c="Showing all activities for group "+d.name):(c="Showing all activities for all "+a.inventory_name+" groups",b=J("activity_stream")+"?group__inventory__id="+a.inventory_id),I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showHostActivity=function(){var b,c;c="Showing all activities for all "+a.inventory_name+" hosts",b=J("activity_stream")+"?host__inventory__id="+a.inventory_id,I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showJobSummary=function(a){K({job_id:a})},a.showGroupHelp=function(a){var b={defn:O};a&&(b.autoShow=a.autoShow||!1),N(b)},i({scope:a,inventory_id:a.inventory_id,refresh:!1})}function JobEventsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){function y(a){var b,c,d,e,f,g="",h=!1;if(a.res){if("string"==typeof a.res)c=a.res.match(/\n/g),d=c?c.length:1,d=d>10?10:d,h=!0,g+='
        \n',g+="\n",g+='\n",g+="
        \n";else for(e in a.res){if(("msg"===e||"stdout"===e||"stderr"===e)&&null!==a.res[e]&&""!==a.res[e]){switch(g+='
        \n',g+="\n",c=a.res[e].match(/\n/g),d=c?c.length:1,d=d>10?10:d,g+='\n",g+="
        \n",h=!0}if("results"===e&&Array.isArray(a.res[e])&&a.res[e].length>0){for(f="",b=0;b10?10:d,""!==f&&(g+='
        \n',g+="\n",g+='\n",g+="
        \n",h=!0)}"rc"===e&&""!==a.res[e]&&(g+='
        \n',g+="\n",g+='\n',g+="
        \n",h=!0)}g=h?'
        \n'+g+"
        \n":""}return g=a.hosts?''+a.host+"\n"+g:""===g?null:g}p("htmlTemplate");var z,A=i,B=r("jobs")+f.id+"/job_events/",C=j,D=C.inject(A,{mode:"edit"});A.base=d.path(),D.job_id=f.id,c.flashMessage=null,D.selected=[],D.expand=!0,D.parentNode="parent-event",D.childNode="child-event",D.removeSetHostLinks&&D.removeSetHostLinks(),D.removeSetHostLinks=D.$on("SetHostLinks",function(a,b){for(var c=0;c15?5:e,$('textarea[name="'+c+'"]').attr("rows",e)));break;case"module_name":case"module_args":a.event_data.res&&a.event_data.res.invocation&&(t[c]=a.event_data.res.invocation.fld) +}q("stop")}).error(function(a){k(t,a,status,null,{hdr:"Error!",msg:"Failed to retrieve host: "+f.event_id+". GET status: "+status})}),t.navigateBack=function(){var a="/jobs/"+f.job_id+"/job_events";f.page&&(a+="?page="+f.page),d.url(a)},t.rawView=function(){p({event_id:t.id})}}function JobHostSummaryList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){o("htmlTemplate");var u=h,v=c.path().replace(/^\//,"").split("/")[0],w=q(v)+e.id+"/job_host_summaries/",x=i,y=x.inject(u,{mode:"edit"});u.index="hosts"===v?!1:!0,y.selected=[],"hosts"===v?(y.job_id=null,y.host_id=e.id):(y.job_id=e.id,y.host_id=null),y.RemoveSetHostLink&&y.RemoveSetHostLink(),y.RemoveSetHostLink=y.$on("setHostLink",function(a,b){for(var c=0;c0?y.jobhosts[0].summary_fields.host.name:"Host"}),e.inventory&&y.$emit("setHostLink",e.inventory))}),l({scope:y,set:"jobhosts",list:u,url:w}),m({scope:y,list:u,url:w}),e.host_name&&(y[u.iterator+"SearchField"]="host",y[u.iterator+"SearchValue"]=e.host_name,y[u.iterator+"SearchFieldLabel"]=u.fields.host.label),y.search(u.iterator),y.showEvents=function(a,b){f.setUrl(b),f.get().success(function(b){j({path:"/jobs/"+b.id,title:b.name}),c.url("/jobs/"+b.id+"/job_events/?host="+encodeURI(a))}).error(function(a,c){p(y,a,c,null,{hdr:"Error!",msg:"Failed to lookup last job: "+b+". GET status: "+c})})},y.showJob=function(a){c.path("/jobs/"+a)},y.refresh=function(){null===y.host_id&&(y.jobSearchSpin=!0,y.jobLoading=!0,t("start"),r({scope:y,set:"jobhosts",iterator:"jobhost",url:y.current_url}))}}function JobTemplatesList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){o("htmlTemplate");var y=h,z=q("job_templates"),A=i,B=c.path().replace(/^\//,"").split("/")[0],C="job_templates"===B?"edit":"select",D=A.inject(y,{mode:C});b.flashMessage=null,D.removePostRefresh&&D.removePostRefresh(),D.removePostRefresh=D.$on("PostRefresh",function(){w("stop"),$("#prompt-modal").off()}),l({scope:D,set:"job_templates",list:y,url:z}),m({scope:D,list:y,url:z}),e.name&&(D[y.iterator+"SearchField"]="name",D[y.iterator+"SearchValue"]=e.name,D[y.iterator+"SearchFieldLabel"]=y.fields.name.label),D.search(y.iterator),j(),D.showActivity=function(){x({scope:D})},D.addJobTemplate=function(){c.path(c.path()+"/add")},D.editJobTemplate=function(a){c.path(c.path()+"/"+a)},D.deleteJobTemplate=function(a,b){var c=function(){$("#prompt-modal").on("hidden.bs.modal",function(){w("start")}),$("#prompt-modal").modal("hide");var b=z+a+"/";f.setUrl(b),f.destroy().success(function(){D.search(y.iterator)}).error(function(a){w("stop"),p(D,a,status,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+status})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},D.submitJob=function(a){v({scope:D,id:a})}}function JobTemplatesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){n("htmlTemplate");var x,y,z=o("job_templates"),A=g,B=h,C=B.inject(A,{mode:"add",related:!1}),D={},E={};C.parseType="yaml",u(C),C.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],C.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],C.playbook_options=[],C.allow_callbacks="false",B.reset(),l(),t({scope:C,master:D,check_field:"allow_callbacks",default_val:!1}),s({scope:C,form:A,current_item:null,list:p,field:"inventory"}),jQuery.extend(!0,E,q),E.name="cloudcredentials",E.iterator="cloudcredential",s({url:o("credentials")+"?cloud=true",scope:C,form:A,current_item:null,list:E,field:"cloud_credential",hdr:"Select Cloud Credential"}),s({url:o("credentials")+"?kind=ssh",scope:C,form:A,current_item:null,list:q,field:"credential",hdr:"Select Machine Credential"}),x=function(a,b){var c;a!==b&&C.project&&(v("start"),c=o("projects")+C.project+"/playbooks/",i.setUrl(c),i.get().success(function(a){var b,c=[];for(b=0;b=2)for(var a in O)J.search(O[a].iterator)}),J.removeRelatedJobs&&J.removeRelatedJobs(),J.removeRelatedJobs=J.$on("relatedjobs",function(){var a,b;if(J.jobs&&J.jobs.length)for(a=0;a0)for(c=0;c/g," ");for(y in z.fields.status.searchOptions)if(z.fields.status.searchOptions[y].value===e.status){C[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[y];break}}C.search(z.iterator),j(),C.refresh=function(){x("start"),C.jobLoading=!1,u({scope:C,set:"jobs",iterator:"job",url:C.current_url})},C.refreshJob=C.refresh,C.editJob=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a)},C.viewEvents=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_events")},C.viewSummary=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_host_summaries")},C.deleteJob=function(a){f.setUrl(A+a+"/"),f.get().success(function(b){var c,d,e,g;"pending"===b.status||"running"===b.status||"waiting"===b.status?(d=b.related.cancel,e="cancel",g="Cancel Job"):(d=A+a+"/",e="delete",g="Delete Job"),c=function(){f.setUrl(d),"cancel"===e?f.post().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. POST returned status: "+b})}):f.destroy().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. DELETE returned status: "+b})})},k({hdr:g,body:"Are you sure you want to "+e+" job "+a+"?",action:c})}).error(function(a,b){p(C,a,b,null,{hdr:"Error!",msg:"Failed to get job details. GET returned status: "+b})})},C.submitJob=function(a,b){s({scope:C,id:a,template:b})}}function JobsEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z){function A(a){if(null!==a&&""!==a&&void 0!==a){var b=v("projects")+a+"/playbooks/";i.setUrl(b),i.get().success(function(a){F.playbook_options=[];for(var b=0;b15?15:c}p("htmlTemplate");var C=v("jobs"),D=h,E=g,F=D.inject(E,{mode:"edit",related:!0}),G={},H=f.id,I={},J=0;D.reset(),F.job_id=H,F.parseType="yaml",F.statusSearchSpin=!1,F.jobLoadedRemove&&F.jobLoadedRemove(),F.jobLoadedRemove=F.$on("jobLoaded",function(a,b){A(F.project),F[E.name+"ReadOnly"]="new"===F.status?!1:!0,$("#forks-slider").slider("option","value",F.forks),$("#forks-slider").slider("disable"),$('input[type="checkbox"]').attr("disabled","disabled"),$('input[type="radio"]').attr("disabled","disabled"),$("#host_config_key-gen-btn").attr("disabled","disabled"),$("textarea").attr("readonly","readonly"),i.setUrl(F.template_url),i.get().success(function(a){var b=a.host_config_key?"true":"false";F.host_config_key=a.host_config_key,w({scope:F,master:G,check_field:"allow_callbacks",default_val:b}),F.callback_url=a.related?a.related.callback:"<< Job template not found >>",F.$emit("jobTemplateLoadFinished")}).error(function(){z("stop"),F.callback_url="<< Job template not found >>"}),b?(i.setUrl(b),i.get().success(function(a){F.cloud_credential_name=a.name,F.$emit("jobTemplateLoadFinished")}).error(function(a,b){k(F,a,b,null,{hdr:"Error!",msg:"Failed to related cloud credential. GET returned status: "+b})})):F.$emit("jobTemplateLoadFinished")}),F.removeJobTemplateLoadFinished&&F.removeJobTemplateLoadFinished(),F.removeJobTemplateLoadFinished=F.$on("jobTemplateLoadFinished",function(){J++,J>=3&&z("stop")}),F.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],F.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],F.playbook_options=null,F.playbook=null,z("start"),i.setUrl(C+":id/"),i.get({params:{id:H}}).success(function(a){var b,c,d,e,f,g;l();for(d in E.fields){if("variables"!==d&&null!==a[d]&&void 0!==a[d]){if("select"===E.fields[d].type)if(F[d+"_options"]&&F[d+"_options"].length>0)for(b=0;b/g," ");for(a in A.fields.scm_type.searchOptions)if(A.fields.scm_type.searchOptions[a].value===e.scm_type){F[A.iterator+"SearchSelectValue"]=A.fields.scm_type.searchOptions[a];break}}else if(e.status){F[A.iterator+"SearchValue"]=e.status,F[A.iterator+"SearchField"]="status",F[A.iterator+"SelectShow"]=!0,F[A.iterator+"SearchFieldLabel"]=A.fields.status.label,F[A.iterator+"SearchSelectOpts"]=A.fields.status.searchOptions;for(a in A.fields.status.searchOptions)if(A.fields.status.searchOptions[a].value===e.status){F[A.iterator+"SearchSelectValue"]=A.fields.status.searchOptions[a];break}}F.search(A.iterator)}),F.removeChoicesReady&&F.removeChoicesReady(),F.removeChoicesReady=F.$on("choicesReadyProject",function(){H++,2===H&&F.$emit("choicesCompleteProject")}),y({scope:F,url:B,field:"status",variable:"project_status_options",callback:"choicesReadyProject"}),y({scope:F,url:B,field:"scm_type",variable:"project_scm_type_options",callback:"choicesReadyProject"}),j(),F.showActivity=function(){x({scope:F})},F.addProject=function(){c.path(c.path()+"/add")},F.editProject=function(a){c.path(c.path()+"/"+a)},F.showSCMStatus=function(a){var b,c=F.$on("PostRefresh",function(){var d; +for(b=0;bRefresh
        button to view the latest status.","alert-info")}).error(function(a,b){p(F,a,b,null,{hdr:"Error!",msg:"Call to "+c+" failed. GET status: "+b})})}),F.cancelUpdate=function(a,b){var c,d,e=!1;for(c=0;cRefresh button to view the latet status.","alert-info")},F.refresh=function(){w("start"),F.projectLoading=!1,v({scope:F,set:"projects",iterator:"project",url:F.current_url})},F.SCMUpdate=function(a){var b;for(b=0;bb;b++){for(d[b].match(/[A-Z]/g)?(""!==R&&R+1==b&&(y++,C++),R=b,o++):d[b].match(/[a-z]/g)?(""!==S&&S+1==b&&(z++,C++),S=b,p++):d[b].match(/[0-9]/g)?(b>0&&e-1>b&&s++,""!==T&&T+1==b&&(A++,C++),T=b,q++):d[b].match(/[^a-zA-Z0-9_]/g)&&(b>0&&e-1>b&&s++,""!==U&&U+1==b&&(B++,C++),U=b,r++),f=!1,g=0;e>g;g++)d[b]==d[g]&&b!=g&&(f=!0,x+=Math.abs(e/(g-b)));f&&(w++,v=e-w,x=Math.ceil(v?x/v:x))}for(h=0;23>h;h++)i=ib.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(D++,G++);for(h=0;8>h;h++)i=jb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(E++,G++);for(h=0;8>h;h++)i=kb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(F++,G++);o>0&&n>o&&(nScore=parseInt(nScore+2*(n-o)),V="+ "+parseInt(2*(n-o))),p>0&&n>p&&(nScore=parseInt(nScore+2*(n-p)),W="+ "+parseInt(2*(n-p))),q>0&&n>q&&(nScore=parseInt(nScore+q*P),X="+ "+parseInt(q*P)),r>0&&(nScore=parseInt(nScore+r*Q),Y="+ "+parseInt(r*Q)),s>0&&(nScore=parseInt(nScore+s*H),Z="+ "+parseInt(s*H)),(p>0||o>0)&&0===r&&0===q&&(nScore=parseInt(nScore-n),t=n,_="- "+n),0===p&&0===o&&0===r&&q>0&&(nScore=parseInt(nScore-n),u=n,ab="- "+n),w>0&&(nScore=parseInt(nScore-x),bb="- "+x),y>0&&(nScore=parseInt(nScore-y*I),cb="- "+parseInt(y*I)),z>0&&(nScore=parseInt(nScore-z*J),db="- "+parseInt(z*J)),A>0&&(nScore=parseInt(nScore-A*K),eb="- "+parseInt(A*K)),D>0&&(nScore=parseInt(nScore-D*L),fb="- "+parseInt(D*L)),E>0&&(nScore=parseInt(nScore-E*M),gb="- "+parseInt(E*M)),F>0&&(nScore=parseInt(nScore-F*N),hb="- "+parseInt(F*N)),nScore>100?nScore=100:0>nScore&&(nScore=0),k=$("#progbar"),l=$AnsibleConfig.password_strength,m=$AnsibleConfig.password_strength-15<0?0:$AnsibleConfig.password_strength-15,k.css("width",nScore+"%"),nScore>=0&&m>=nScore?(lb="Weak",k.addClass("progress-bar-danger"),k.removeClass("progress-bar-success progress-bar-warning")):nScore>m&&l>=nScore?(lb="Good",k.addClass("progress-bar-warning"),k.removeClass("progress-bar-success progress-bar-danger")):nScore>l&&(lb="Strong",k.addClass("progress-bar-success"),k.removeClass("progress-bar-warning progress-bar-danger"))}else k=$("#progbar"),k.css("width","0%"),k.removeClass("progress-bar-success progress-bar-warning");return nScore}function AdminsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=h,r=o("organizations")+e.organization_id+"/users/",s=i,t="select",u=s.inject(h,{mode:t}),v=o("organizations")+e.organization_id+"/admins/";p({scope:u,list:q,url:v,returnToCaller:1}),l({scope:u,set:"admins",list:q,url:r}),m({scope:u,list:q,url:r}),u.search(q.iterator),j()}function Authenticate(a,b,c,d,e,f,g,h,i,j,k){var l,m,n,o;l=function(){$("#login-username").focus()},n=k(d.sessionExpired)?a.get("sessionExpired"):d.sessionExpired,m=function(){return k(d.lastPath)?a.get("lastPath"):d.lastPath},$AnsibleConfig.debug_mode&&console&&(console.log("User session expired: "+n),console.log("Last URL: "+m())),$(".modal[aria-hidden=false]").each(function(){"login-modal"!==$(this).attr("id")&&$(this).modal("hide")}),i("stop"),$("#login-modal").modal({show:!0,keyboard:!1,backdrop:"static"}),$("#login-modal").on("shown.bs.modal",function(){l()}),o=angular.element(document.getElementById("login-modal")).scope(),o.login_username=null,o.login_password=null,o.loginForm.login_username.$setPristine(),o.loginForm.login_password.$setPristine(),"/logout"===e.path()&&f.logout(),d.userLoggedIn=!1,a.put("userLoggedIn",!1),$("#login-password").bind("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13===b&&$("#login-button").click()}),o.reset=function(){$("#login-form input").each(function(){$(this).val("")})},o.systemLogin=function(a,b){$(".api-error").empty();var c;k(a)||k(b)?h("Error!","Please provide a username and password before attempting to login.","alert-danger",l):(i("start"),f.retrieveToken(a,b).success(function(a,b){$("#login-modal").modal("hide"),c=a.token,f.setToken(a.token,a.expires),d.sessionTimer=j.init(),f.getUser().success(function(a){f.setUserInfo(a),d.user_is_superuser=a.results[0].is_superuser,f.getLicense().success(function(a){f.setLicense(a.license_info),m()?e.path(m()):e.url("/home?login=true")}).error(function(){i("stop"),h("Error","Failed to access user information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){i("stop"),h("Error","Failed to access license information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){var c,d,e;if(i("stop"),a.non_field_errors&&0===a.non_field_errors.length)for(e in a)o[e+"Error"]=a[e][0];else a.non_field_errors&&a.non_field_errors.length>0?(c="Error",d=a.non_field_errors[0]):(c="Error",d="The login attempt failed with a status of: "+b),o.reset(),h(c,d,"alert-danger",l)}))}}function CredentialsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){o("htmlTemplate"),t("start");var v,w=h,x=q("credentials"),y=i,z=c.path().replace(/^\//,"").split("/")[0],A="credentials"===z?"edit":"select",B=y.inject(w,{mode:A});B.selected=[],B.credentialLoading=!0,v=q(z)+("users"===z?e.user_id+"/credentials/":e.team_id+"/credentials/"),r({scope:B,list:w,url:v,returnToCaller:1}),B.removePostRefresh&&B.removePostRefresh(),B.removePostRefresh=B.$on("PostRefresh",function(){var a,b;for(t("stop"),$("#prompt-modal").off(),w.fields.kind.searchOptions=B.credential_kind_options,a=0;a/g," ");for(x in z.fields.status.searchOptions)if(z.fields.status.searchOptions[x].value===b.status){B[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[x];break}}if(b.source){B[z.iterator+"SearchField"]="source",B[z.iterator+"SelectShow"]=!0,B[z.iterator+"SearchSelectOpts"]=z.fields.source.searchOptions,B[z.iterator+"SearchFieldLabel"]=z.fields.source.label.replace(//g," ");for(x in z.fields.source.searchOptions)if(z.fields.source.searchOptions[x].value===b.source){B[z.iterator+"SearchSelectValue"]=z.fields.source.searchOptions[x];break}b.status&&(B[z.iterator+"ExtraParms"]="&inventory_source__status__icontains="+b.status)}b.has_external_source&&(B[z.iterator+"SearchField"]="has_external_source",B[z.iterator+"SearchValue"]=z.fields.has_external_source.searchValue,B[z.iterator+"InputDisable"]=!0,B[z.iterator+"SearchType"]="in",B[z.iterator+"SearchFieldLabel"]=z.fields.has_external_source.label),B.search(z.iterator),f(),B.showActivity=function(){p({scope:B})},B.editGroup=function(a,b){q({scope:B,group_id:a,inventory_id:b,groups_reload:!1})},B.viewUpdateStatus=function(a){B.groups=B.home_groups,o({scope:B,tree_id:a})},B.updateGroup=function(a){var b=w({list:B.home_groups,key:"id",val:a});b&&(u(b.source)||("updating"===b.status?s("Update in Progress","The inventory update process is currently running for group "+b.name+". Use the Refresh button to monitor the status.","alert-info"):(r("start"),t.setUrl(b.related.inventory_source),t.get().success(function(a){v({scope:B,url:a.related.update,group_name:a.summary_fields.group.name,group_source:a.source,tree_id:b.id,group_id:b.id})}).error(function(a,c){e(B,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+b.related.inventory_source+" POST returned status: "+c})}))))},B.refresh=function(){B.search(z.iterator,null,!1,!0)}}function HomeHosts(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){h("htmlTemplate");var s=d,t=c,u=i("hosts"),v=s.inject(t,{mode:"edit"});v.removePostRefresh&&v.removePostRefresh(),v.removePostRefresh=v.$on("PostRefresh",function(){for(var a=0;a0?(z.inventories[a].failed_hosts_tip=z.inventories[a].hosts_with_active_failures+(1===z.inventories[a].hosts_with_active_failures?" host":" hosts")+" with job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="true"):0===z.inventories[a].total_hosts?(z.inventories[a].failed_hosts_tip="No hosts defined. Click to add.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="na"):(z.inventories[a].failed_hosts_tip=z.inventories[a].total_hosts+(z.inventories[a].total_hosts>1?" hosts":" host")+" with no job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="false"),z.inventories[a].status=z.inventories[a].inventory_sources_with_failures+" / "+z.inventories[a].total_inventory_sources,z.inventories[a].inventory_sources_with_failures>0?(z.inventories[a].status_tip=z.inventories[a].inventory_sources_with_failures+" cloud "+(1===z.inventories[a].inventory_sources_with_failures?"source":"sources")+" with failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="failed"):0===z.inventories[a].total_inventory_sources?(z.inventories[a].status_tip="Not synced with a cloud source. Click to edit.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="na"):(z.inventories[a].status_tip=z.inventories[a].total_inventory_sources+" cloud "+(z.inventories[a].total_inventory_sources>1?"sources":"source")+" with no failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="successful")}),z.removeRefreshInventories&&z.removeRefreshInventories(),z.removeRefreshInventories=z.$on("RefreshInventories",function(){z.search(u.iterator)}),z.showActivity=function(){s({scope:z})},z.editInventoryProperties=function(a){t({scope:z,inventory_id:a})},z.addInventory=function(){c.path(c.path()+"/add")},z.editInventory=function(a){c.path(c.path()+"/"+a)},z.deleteInventory=function(a,b){var c=function(){var b=v+a+"/";$("#prompt-modal").on("hidden.bs.modal",function(){r("start")}),$("#prompt-modal").modal("hide"),f.setUrl(b),f.destroy().success(function(){z.search(u.iterator)}).error(function(a,c){r("stop"),p(z,a,c,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+c})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},z.lookupOrganization=function(a){f.setUrl(q("organizations")+a+"/"),f.get().success(function(a){return a.name})},z.viewJobs=function(a){c.url("/jobs/?inventory__int="+a)},z.viewFailedJobs=function(a){c.url("/jobs/?inventory__int="+a+"&status=failed")}}function InventoriesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){n("htmlTemplate");var w,x=t("inventory"),y=g,z=h;y.well=!0,y.formLabelSize=null,y.formFieldSize=null,w=z.inject(y,{mode:"add",related:!1}),w.inventoryParseType="yaml",z.reset(),l(),u(w,"inventory_variables","inventoryParseType"),s({scope:w,form:y,current_item:f.organization_id?f.organization_id:null,list:p,field:"organization"}),w.formSave=function(){z.clearApiErrors(),v("start");try{var a,b,c;if(b="json"===w.inventoryParseType?JSON.parse(w.inventory_variables):jsyaml.load(w.inventory_variables),"object"!=typeof b)throw"failed to return an object!";c={};for(a in y.fields)"inventory_variables"!==a&&(y.fields[a].realName?c[y.fields[a].realName]=w[a]:c[a]=w[a]);i.setUrl(x),i.post(c).success(function(a){var c=a.id;w.inventory_variables?(i.setUrl(a.related.variable_data),i.put(b).success(function(){v("stop"),d.path("/inventories/"+c+"/")}).error(function(a,b){v("stop"),k(w,a,b,null,{hdr:"Error!",msg:"Failed to add inventory varaibles. PUT returned status: "+b})})):(v("stop"),d.path("/inventories/"+c+"/"))}).error(function(a,b){v("stop"),k(w,a,b,y,{hdr:"Error!",msg:"Failed to add new inventory. Post returned status: "+b})})}catch(e){v("stop"),j("Error","Error parsing inventory variables. Parser returned: "+e)}},w.formReset=function(){z.reset()}}function InventoriesEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P){f("htmlTemplate");var Q=e,R=g;a.inventory_id=c.inventory_id,r({path:b.path(),title:"{{ inventory_name }}"}),a.removeGroupTreeLoaded&&a.removeGroupTreeLoaded(),a.removeGroupTreeLoaded=a.$on("GroupTreeLoaded",function(b,c,e){var f,g;f=angular.element(document.getElementById("breadcrumbs")),f.html(q({list:R,mode:"edit"})),d(f)(a),Q.inject(R,{mode:"edit",id:"groups-container",breadCrumbs:!1,searchSize:"col-lg-5 col-md-5 col-sm-5"}),a.groups=e,a.inventory_name=c,a.groups.length>0?(a.selected_tree_id=a.groups[0].id,a.selected_group_id=a.groups[0].group_id,a.groups[0].selected_class="selected",a.groups[0].active_class="active-row",a.selected_group_name=a.groups[0].name):(a.selected_tree_id=null,a.selected_group_id=null),a.show_failures=!1,l({scope:a,inventory_id:a.inventory_id,tree_id:a.selected_tree_id,group_id:a.selected_group_id}),setTimeout(function(){$("#groups_table .name-column").each(function(){var a,b,c,d,e;a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%",$(this).find(".group-name").css({width:e})}),L("#groups_table .group-name a"),L("#hosts_table .host-name a")},2500),M(),g=P("inventoryAutoHelp"),"off"!==g&&a.autoShowGroupHelp&&a.showGroupHelp({autoShow:!0})}),a.removeGroupTreeRefreshed&&a.removeGroupTreeRefreshed(),a.removeGroupTreeRefreshed=a.$on("GroupTreeRefreshed",function(){setTimeout(function(){L("#groups_table .group-name a")},2500),a.showHosts(a.selected_tree_id,a.selected_group_id,!1)}),a.removeGroupDeleteCompleted&&a.removeGroupDeleteCompleted(),a.removeGroupDeleteCompleted=a.$on("GroupDeleteCompleted",function(){a.selected_tree_id=1,a.selected_group_id=null,i({scope:a,inventory_id:a.inventory_id,refresh:!0})}),a.removeCopMoveGroup&&a.removeCopyMoveGroup(),a.removeCopyMoveGroup=a.$on("CopyMoveGroup",function(b,c,d){G({scope:a,target_tree_id:d,inbound_tree_id:c})}),a.removeCopMoveHost&&a.removeCopyMoveHost(),a.removeCopyMoveHost=a.$on("CopyMoveHost",function(b,c,d){H({scope:a,target_tree_id:c,host_id:d})}),a.showHosts=function(b,c,d){if(null!==b){j("start"),a.selected_tree_id=b,a.selected_group_id=c,a.hosts=[],a.show_failures=d;for(var e=0;e"+c.name+". Use the Refresh button to monitor the status.","alert-info"):(j("start"),t.setUrl(c.related.inventory_source),t.get().success(function(b){v({scope:a,url:b.related.update,group_name:b.summary_fields.group.name,group_source:b.source,tree_id:c.id,group_id:c.group_id})}).error(function(b,d){j("stop"),u(a,b,d,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+c.related.inventory_source+" POST returned status: "+d})}))))},a.cancelUpdate=function(b){z({scope:a,tree_id:b})},a.toggle=function(b){x({scope:a,list:R,id:b})},a.refreshGroups=function(b,c){b&&(a.selected_tree_id=b,a.selected_group_id=c),i({scope:a,inventory_id:a.inventory_id,refresh:!0})},a.viewUpdateStatus=function(b,c){y({scope:a,tree_id:b,group_id:c})},a.deleteGroup=function(b,c){p({scope:a,tree_id:b,group_id:c,inventory_id:a.inventory_id})},a.createHost=function(){B({scope:a})},a.editInventoryProperties=function(){C({scope:a,inventory_id:a.inventory_id})},a.editHost=function(b){D({scope:a,host_id:b,inventory_id:a.inventory_id})},a.deleteHost=function(b,c){E({scope:a,host_id:b,host_name:c})},a.toggleHostEnabled=function(b,c){F({scope:a,host_id:b,external_source:c})},a.showGroupActivity=function(){var b,c,d;a.selected_group_id?(d=A({list:a.groups,key:"id",val:a.selected_tree_id}),b=J("activity_stream")+"?group__id="+a.selected_group_id,c="Showing all activities for group "+d.name):(c="Showing all activities for all "+a.inventory_name+" groups",b=J("activity_stream")+"?group__inventory__id="+a.inventory_id),I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showHostActivity=function(){var b,c;c="Showing all activities for all "+a.inventory_name+" hosts",b=J("activity_stream")+"?host__inventory__id="+a.inventory_id,I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showJobSummary=function(a){K({job_id:a})},a.showGroupHelp=function(a){var b={defn:O};a&&(b.autoShow=a.autoShow||!1),N(b)},i({scope:a,inventory_id:a.inventory_id,refresh:!1})}function JobEventsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){function y(a){var b,c,d,e,f,g="",h=!1;if(a.res){if("string"==typeof a.res)c=a.res.match(/\n/g),d=c?c.length:1,d=d>10?10:d,h=!0,g+='
        \n',g+="\n",g+='\n",g+="
        \n";else for(e in a.res){if(("msg"===e||"stdout"===e||"stderr"===e)&&null!==a.res[e]&&""!==a.res[e]){switch(g+='
        \n',g+="\n",c=a.res[e].match(/\n/g),d=c?c.length:1,d=d>10?10:d,g+='\n",g+="
        \n",h=!0}if("results"===e&&Array.isArray(a.res[e])&&a.res[e].length>0){for(f="",b=0;b10?10:d,""!==f&&(g+='
        \n',g+="\n",g+='\n",g+="
        \n",h=!0)}"rc"===e&&""!==a.res[e]&&(g+='
        \n',g+="\n",g+='\n',g+="
        \n",h=!0)}g=h?'
        \n'+g+"
        \n":""}return g=a.hosts?''+a.host+"\n"+g:""===g?null:g}p("htmlTemplate");var z,A=i,B=r("jobs")+f.id+"/job_events/",C=j,D=C.inject(A,{mode:"edit"});A.base=d.path(),D.job_id=f.id,c.flashMessage=null,D.selected=[],D.expand=!0,D.parentNode="parent-event",D.childNode="child-event",D.removeSetHostLinks&&D.removeSetHostLinks(),D.removeSetHostLinks=D.$on("SetHostLinks",function(a,b){for(var c=0;c15?5:e,$('textarea[name="'+c+'"]').attr("rows",e)));break;case"module_name":case"module_args":a.event_data.res&&a.event_data.res.invocation&&(t[c]=a.event_data.res.invocation.fld)}q("stop")}).error(function(a){k(t,a,status,null,{hdr:"Error!",msg:"Failed to retrieve host: "+f.event_id+". GET status: "+status})}),t.navigateBack=function(){var a="/jobs/"+f.job_id+"/job_events";f.page&&(a+="?page="+f.page),d.url(a)},t.rawView=function(){p({event_id:t.id})}}function JobHostSummaryList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){o("htmlTemplate");var u=h,v=c.path().replace(/^\//,"").split("/")[0],w=q(v)+e.id+"/job_host_summaries/",x=i,y=x.inject(u,{mode:"edit"});u.index="hosts"===v?!1:!0,y.selected=[],"hosts"===v?(y.job_id=null,y.host_id=e.id):(y.job_id=e.id,y.host_id=null),y.RemoveSetHostLink&&y.RemoveSetHostLink(),y.RemoveSetHostLink=y.$on("setHostLink",function(a,b){for(var c=0;c0?y.jobhosts[0].summary_fields.host.name:"Host"}),e.inventory&&y.$emit("setHostLink",e.inventory))}),l({scope:y,set:"jobhosts",list:u,url:w}),m({scope:y,list:u,url:w}),e.host_name&&(y[u.iterator+"SearchField"]="host",y[u.iterator+"SearchValue"]=e.host_name,y[u.iterator+"SearchFieldLabel"]=u.fields.host.label),y.search(u.iterator),y.showEvents=function(a,b){f.setUrl(b),f.get().success(function(b){j({path:"/jobs/"+b.id,title:b.name}),c.url("/jobs/"+b.id+"/job_events/?host="+encodeURI(a))}).error(function(a,c){p(y,a,c,null,{hdr:"Error!",msg:"Failed to lookup last job: "+b+". GET status: "+c})})},y.showJob=function(a){c.path("/jobs/"+a)},y.refresh=function(){null===y.host_id&&(y.jobSearchSpin=!0,y.jobLoading=!0,t("start"),r({scope:y,set:"jobhosts",iterator:"jobhost",url:y.current_url}))}}function JobTemplatesList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){o("htmlTemplate");var y=h,z=q("job_templates"),A=i,B=c.path().replace(/^\//,"").split("/")[0],C="job_templates"===B?"edit":"select",D=A.inject(y,{mode:C});b.flashMessage=null,D.removePostRefresh&&D.removePostRefresh(),D.removePostRefresh=D.$on("PostRefresh",function(){w("stop"),$("#prompt-modal").off()}),l({scope:D,set:"job_templates",list:y,url:z}),m({scope:D,list:y,url:z}),e.name&&(D[y.iterator+"SearchField"]="name",D[y.iterator+"SearchValue"]=e.name,D[y.iterator+"SearchFieldLabel"]=y.fields.name.label),D.search(y.iterator),j(),D.showActivity=function(){x({scope:D})},D.addJobTemplate=function(){c.path(c.path()+"/add")},D.editJobTemplate=function(a){c.path(c.path()+"/"+a)},D.deleteJobTemplate=function(a,b){var c=function(){$("#prompt-modal").on("hidden.bs.modal",function(){w("start")}),$("#prompt-modal").modal("hide");var b=z+a+"/";f.setUrl(b),f.destroy().success(function(){D.search(y.iterator)}).error(function(a){w("stop"),p(D,a,status,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+status})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},D.submitJob=function(a){v({scope:D,id:a})}}function JobTemplatesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){n("htmlTemplate");var x,y,z=o("job_templates"),A=g,B=h,C=B.inject(A,{mode:"add",related:!1}),D={},E={};C.parseType="yaml",u(C),C.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],C.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],C.playbook_options=[],C.allow_callbacks="false",B.reset(),l(),t({scope:C,master:D,check_field:"allow_callbacks",default_val:!1}),s({scope:C,form:A,current_item:null,list:p,field:"inventory"}),jQuery.extend(!0,E,q),E.name="cloudcredentials",E.iterator="cloudcredential",s({url:o("credentials")+"?cloud=true",scope:C,form:A,current_item:null,list:E,field:"cloud_credential",hdr:"Select Cloud Credential"}),s({url:o("credentials")+"?kind=ssh",scope:C,form:A,current_item:null,list:q,field:"credential",hdr:"Select Machine Credential"}),x=function(a,b){var c;a!==b&&C.project&&(v("start"),c=o("projects")+C.project+"/playbooks/",i.setUrl(c),i.get().success(function(a){var b,c=[];for(b=0;b=2)for(var a in O)J.search(O[a].iterator)}),J.removeRelatedJobs&&J.removeRelatedJobs(),J.removeRelatedJobs=J.$on("relatedjobs",function(){var a,b; +if(J.jobs&&J.jobs.length)for(a=0;a0)for(c=0;c/g," ");for(y in z.fields.status.searchOptions)if(z.fields.status.searchOptions[y].value===e.status){C[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[y];break}}C.search(z.iterator),j(),C.refresh=function(){x("start"),C.jobLoading=!1,u({scope:C,set:"jobs",iterator:"job",url:C.current_url})},C.refreshJob=C.refresh,C.editJob=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a)},C.viewEvents=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_events")},C.viewSummary=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_host_summaries")},C.deleteJob=function(a){f.setUrl(A+a+"/"),f.get().success(function(b){var c,d,e,g;"pending"===b.status||"running"===b.status||"waiting"===b.status?(d=b.related.cancel,e="cancel",g="Cancel Job"):(d=A+a+"/",e="delete",g="Delete Job"),c=function(){f.setUrl(d),"cancel"===e?f.post().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. POST returned status: "+b})}):f.destroy().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. DELETE returned status: "+b})})},k({hdr:g,body:"Are you sure you want to "+e+" job "+a+"?",action:c})}).error(function(a,b){p(C,a,b,null,{hdr:"Error!",msg:"Failed to get job details. GET returned status: "+b})})},C.submitJob=function(a,b){s({scope:C,id:a,template:b})}}function JobsEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z){function A(a){if(null!==a&&""!==a&&void 0!==a){var b=v("projects")+a+"/playbooks/";i.setUrl(b),i.get().success(function(a){F.playbook_options=[];for(var b=0;b15?15:c}p("htmlTemplate");var C=v("jobs"),D=h,E=g,F=D.inject(E,{mode:"edit",related:!0}),G={},H=f.id,I={},J=0;D.reset(),F.job_id=H,F.parseType="yaml",F.statusSearchSpin=!1,F.jobLoadedRemove&&F.jobLoadedRemove(),F.jobLoadedRemove=F.$on("jobLoaded",function(a,b){A(F.project),F[E.name+"ReadOnly"]="new"===F.status?!1:!0,$("#forks-slider").slider("option","value",F.forks),$("#forks-slider").slider("disable"),$('input[type="checkbox"]').attr("disabled","disabled"),$('input[type="radio"]').attr("disabled","disabled"),$("#host_config_key-gen-btn").attr("disabled","disabled"),$("textarea").attr("readonly","readonly"),i.setUrl(F.template_url),i.get().success(function(a){var b=a.host_config_key?"true":"false";F.host_config_key=a.host_config_key,w({scope:F,master:G,check_field:"allow_callbacks",default_val:b}),F.callback_url=a.related?a.related.callback:"<< Job template not found >>",F.$emit("jobTemplateLoadFinished")}).error(function(){z("stop"),F.callback_url="<< Job template not found >>"}),b?(i.setUrl(b),i.get().success(function(a){F.cloud_credential_name=a.name,F.$emit("jobTemplateLoadFinished")}).error(function(a,b){k(F,a,b,null,{hdr:"Error!",msg:"Failed to related cloud credential. GET returned status: "+b})})):F.$emit("jobTemplateLoadFinished")}),F.removeJobTemplateLoadFinished&&F.removeJobTemplateLoadFinished(),F.removeJobTemplateLoadFinished=F.$on("jobTemplateLoadFinished",function(){J++,J>=3&&z("stop")}),F.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],F.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],F.playbook_options=null,F.playbook=null,z("start"),i.setUrl(C+":id/"),i.get({params:{id:H}}).success(function(a){var b,c,d,e,f,g;l();for(d in E.fields){if("variables"!==d&&null!==a[d]&&void 0!==a[d]){if("select"===E.fields[d].type)if(F[d+"_options"]&&F[d+"_options"].length>0)for(b=0;b/g," ");for(a in A.fields.scm_type.searchOptions)if(A.fields.scm_type.searchOptions[a].value===e.scm_type){F[A.iterator+"SearchSelectValue"]=A.fields.scm_type.searchOptions[a];break}}else if(e.status){F[A.iterator+"SearchValue"]=e.status,F[A.iterator+"SearchField"]="status",F[A.iterator+"SelectShow"]=!0,F[A.iterator+"SearchFieldLabel"]=A.fields.status.label,F[A.iterator+"SearchSelectOpts"]=A.fields.status.searchOptions;for(a in A.fields.status.searchOptions)if(A.fields.status.searchOptions[a].value===e.status){F[A.iterator+"SearchSelectValue"]=A.fields.status.searchOptions[a];break}}F.search(A.iterator)}),F.removeChoicesReady&&F.removeChoicesReady(),F.removeChoicesReady=F.$on("choicesReadyProject",function(){H++,2===H&&F.$emit("choicesCompleteProject")}),y({scope:F,url:B,field:"status",variable:"project_status_options",callback:"choicesReadyProject"}),y({scope:F,url:B,field:"scm_type",variable:"project_scm_type_options",callback:"choicesReadyProject"}),j(),F.showActivity=function(){x({scope:F})},F.addProject=function(){c.path(c.path()+"/add")},F.editProject=function(a){c.path(c.path()+"/"+a)},F.showSCMStatus=function(a){var b,c=F.$on("PostRefresh",function(){var d;for(b=0;bRefresh button to view the latest status.","alert-info")}).error(function(a,b){p(F,a,b,null,{hdr:"Error!",msg:"Call to "+c+" failed. GET status: "+b})})}),F.cancelUpdate=function(a,b){var c,d,e=!1;for(c=0;cRefresh button to view the latet status.","alert-info")},F.refresh=function(){w("start"),F.projectLoading=!1,v({scope:F,set:"projects",iterator:"project",url:F.current_url})},F.SCMUpdate=function(a){var b;for(b=0;bb;b++){for(d[b].match(/[A-Z]/g)?(""!==R&&R+1==b&&(y++,C++),R=b,o++):d[b].match(/[a-z]/g)?(""!==S&&S+1==b&&(z++,C++),S=b,p++):d[b].match(/[0-9]/g)?(b>0&&e-1>b&&s++,""!==T&&T+1==b&&(A++,C++),T=b,q++):d[b].match(/[^a-zA-Z0-9_]/g)&&(b>0&&e-1>b&&s++,""!==U&&U+1==b&&(B++,C++),U=b,r++),f=!1,g=0;e>g;g++)d[b]==d[g]&&b!=g&&(f=!0,x+=Math.abs(e/(g-b)));f&&(w++,v=e-w,x=Math.ceil(v?x/v:x))}for(h=0;23>h;h++)i=ib.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(D++,G++);for(h=0;8>h;h++)i=jb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(E++,G++);for(h=0;8>h;h++)i=kb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(F++,G++);o>0&&n>o&&(nScore=parseInt(nScore+2*(n-o)),V="+ "+parseInt(2*(n-o))),p>0&&n>p&&(nScore=parseInt(nScore+2*(n-p)),W="+ "+parseInt(2*(n-p))),q>0&&n>q&&(nScore=parseInt(nScore+q*P),X="+ "+parseInt(q*P)),r>0&&(nScore=parseInt(nScore+r*Q),Y="+ "+parseInt(r*Q)),s>0&&(nScore=parseInt(nScore+s*H),Z="+ "+parseInt(s*H)),(p>0||o>0)&&0===r&&0===q&&(nScore=parseInt(nScore-n),t=n,_="- "+n),0===p&&0===o&&0===r&&q>0&&(nScore=parseInt(nScore-n),u=n,ab="- "+n),w>0&&(nScore=parseInt(nScore-x),bb="- "+x),y>0&&(nScore=parseInt(nScore-y*I),cb="- "+parseInt(y*I)),z>0&&(nScore=parseInt(nScore-z*J),db="- "+parseInt(z*J)),A>0&&(nScore=parseInt(nScore-A*K),eb="- "+parseInt(A*K)),D>0&&(nScore=parseInt(nScore-D*L),fb="- "+parseInt(D*L)),E>0&&(nScore=parseInt(nScore-E*M),gb="- "+parseInt(E*M)),F>0&&(nScore=parseInt(nScore-F*N),hb="- "+parseInt(F*N)),nScore>100?nScore=100:0>nScore&&(nScore=0),k=$("#progbar"),l=$AnsibleConfig.password_strength,m=$AnsibleConfig.password_strength-15<0?0:$AnsibleConfig.password_strength-15,k.css("width",nScore+"%"),nScore>=0&&m>=nScore?(lb="Weak",k.addClass("progress-bar-danger"),k.removeClass("progress-bar-success progress-bar-warning")):nScore>m&&l>=nScore?(lb="Good",k.addClass("progress-bar-warning"),k.removeClass("progress-bar-success progress-bar-danger")):nScore>l&&(lb="Strong",k.addClass("progress-bar-success"),k.removeClass("progress-bar-warning progress-bar-danger"))}else k=$("#progbar"),k.css("width","0%"),k.removeClass("progress-bar-success progress-bar-warning");return nScore}function AdminsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=h,r=o("organizations")+e.organization_id+"/users/",s=i,t="select",u=s.inject(h,{mode:t}),v=o("organizations")+e.organization_id+"/admins/";p({scope:u,list:q,url:v,returnToCaller:1}),l({scope:u,set:"admins",list:q,url:r}),m({scope:u,list:q,url:r}),u.search(q.iterator),j()}function Authenticate(a,b,c,d,e,f,g,h,i,j,k){var l,m,n,o;l=function(){$("#login-username").focus()},n=k(d.sessionExpired)?a.get("sessionExpired"):d.sessionExpired,m=function(){return k(d.lastPath)?a.get("lastPath"):d.lastPath},$AnsibleConfig.debug_mode&&console&&(console.log("User session expired: "+n),console.log("Last URL: "+m())),$(".modal[aria-hidden=false]").each(function(){"login-modal"!==$(this).attr("id")&&$(this).modal("hide")}),i("stop"),$("#login-modal").modal({show:!0,keyboard:!1,backdrop:"static"}),$("#login-modal").on("shown.bs.modal",function(){l()}),o=angular.element(document.getElementById("login-modal")).scope(),o.login_username=null,o.login_password=null,o.loginForm.login_username.$setPristine(),o.loginForm.login_password.$setPristine(),"/logout"===e.path()&&f.logout(),d.userLoggedIn=!1,a.put("userLoggedIn",!1),$("#login-password").bind("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13===b&&$("#login-button").click()}),o.reset=function(){$("#login-form input").each(function(){$(this).val("")})},o.systemLogin=function(a,b){$(".api-error").empty();var c;k(a)||k(b)?h("Error!","Please provide a username and password before attempting to login.","alert-danger",l):(i("start"),f.retrieveToken(a,b).success(function(a,b){$("#login-modal").modal("hide"),c=a.token,f.setToken(a.token,a.expires),d.sessionTimer=j.init(),f.getUser().success(function(a){f.setUserInfo(a),d.user_is_superuser=a.results[0].is_superuser,f.getLicense().success(function(a){f.setLicense(a.license_info),m()?e.path(m()):e.url("/home?login=true")}).error(function(){i("stop"),h("Error","Failed to access user information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){i("stop"),h("Error","Failed to access license information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){var c,d,e;if(i("stop"),a.non_field_errors&&0===a.non_field_errors.length)for(e in a)o[e+"Error"]=a[e][0];else a.non_field_errors&&a.non_field_errors.length>0?(c="Error",d=a.non_field_errors[0]):(c="Error",d="The login attempt failed with a status of: "+b),o.reset(),h(c,d,"alert-danger",l)}))}}function CredentialsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){o("htmlTemplate"),t("start");var v,w=h,x=q("credentials"),y=i,z=c.path().replace(/^\//,"").split("/")[0],A="credentials"===z?"edit":"select",B=y.inject(w,{mode:A});B.selected=[],B.credentialLoading=!0,v=q(z)+("users"===z?e.user_id+"/credentials/":e.team_id+"/credentials/"),r({scope:B,list:w,url:v,returnToCaller:1}),B.removePostRefresh&&B.removePostRefresh(),B.removePostRefresh=B.$on("PostRefresh",function(){var a,b;for(t("stop"),$("#prompt-modal").off(),w.fields.kind.searchOptions=B.credential_kind_options,a=0;a/g," ");for(x in z.fields.status.searchOptions)if(z.fields.status.searchOptions[x].value===b.status){B[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[x];break}}if(b.source){B[z.iterator+"SearchField"]="source",B[z.iterator+"SelectShow"]=!0,B[z.iterator+"SearchSelectOpts"]=z.fields.source.searchOptions,B[z.iterator+"SearchFieldLabel"]=z.fields.source.label.replace(//g," ");for(x in z.fields.source.searchOptions)if(z.fields.source.searchOptions[x].value===b.source){B[z.iterator+"SearchSelectValue"]=z.fields.source.searchOptions[x];break}b.status&&(B[z.iterator+"ExtraParms"]="&inventory_source__status__icontains="+b.status)}b.has_external_source&&(B[z.iterator+"SearchField"]="has_external_source",B[z.iterator+"SearchValue"]=z.fields.has_external_source.searchValue,B[z.iterator+"InputDisable"]=!0,B[z.iterator+"SearchType"]="in",B[z.iterator+"SearchFieldLabel"]=z.fields.has_external_source.label),B.search(z.iterator),f(),B.showActivity=function(){p({scope:B})},B.editGroup=function(a,b){q({scope:B,group_id:a,inventory_id:b,groups_reload:!1})},B.viewUpdateStatus=function(a){B.groups=B.home_groups,o({scope:B,tree_id:a})},B.updateGroup=function(a){var b=w({list:B.home_groups,key:"id",val:a});b&&(u(b.source)||("updating"===b.status?s("Update in Progress","The inventory update process is currently running for group "+b.name+". Use the Refresh button to monitor the status.","alert-info"):(r("start"),t.setUrl(b.related.inventory_source),t.get().success(function(a){v({scope:B,url:a.related.update,group_name:a.summary_fields.group.name,group_source:a.source,tree_id:b.id,group_id:b.id})}).error(function(a,c){e(B,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+b.related.inventory_source+" POST returned status: "+c})}))))},B.refresh=function(){B.search(z.iterator,null,!1,!0)}}function HomeHosts(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){h("htmlTemplate");var s=d,t=c,u=i("hosts"),v=s.inject(t,{mode:"edit"});v.removePostRefresh&&v.removePostRefresh(),v.removePostRefresh=v.$on("PostRefresh",function(){for(var a=0;a0?(z.inventories[a].failed_hosts_tip=z.inventories[a].hosts_with_active_failures+(1===z.inventories[a].hosts_with_active_failures?" host":" hosts")+" with job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="true"):0===z.inventories[a].total_hosts?(z.inventories[a].failed_hosts_tip="No hosts defined. Click to add.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="na"):(z.inventories[a].failed_hosts_tip=z.inventories[a].total_hosts+(z.inventories[a].total_hosts>1?" hosts":" host")+" with no job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="false"),z.inventories[a].status=z.inventories[a].inventory_sources_with_failures+" / "+z.inventories[a].total_inventory_sources,z.inventories[a].inventory_sources_with_failures>0?(z.inventories[a].status_tip=z.inventories[a].inventory_sources_with_failures+" cloud "+(1===z.inventories[a].inventory_sources_with_failures?"source":"sources")+" with failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="failed"):0===z.inventories[a].total_inventory_sources?(z.inventories[a].status_tip="Not synced with a cloud source. Click to edit.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="na"):(z.inventories[a].status_tip=z.inventories[a].total_inventory_sources+" cloud "+(z.inventories[a].total_inventory_sources>1?"sources":"source")+" with no failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="successful") +}),z.removeRefreshInventories&&z.removeRefreshInventories(),z.removeRefreshInventories=z.$on("RefreshInventories",function(){z.search(u.iterator)}),z.showActivity=function(){s({scope:z})},z.editInventoryProperties=function(a){t({scope:z,inventory_id:a})},z.addInventory=function(){c.path(c.path()+"/add")},z.editInventory=function(a){c.path(c.path()+"/"+a)},z.deleteInventory=function(a,b){var c=function(){var b=v+a+"/";$("#prompt-modal").on("hidden.bs.modal",function(){r("start")}),$("#prompt-modal").modal("hide"),f.setUrl(b),f.destroy().success(function(){z.search(u.iterator)}).error(function(a,c){r("stop"),p(z,a,c,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+c})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},z.lookupOrganization=function(a){f.setUrl(q("organizations")+a+"/"),f.get().success(function(a){return a.name})},z.viewJobs=function(a){c.url("/jobs/?inventory__int="+a)},z.viewFailedJobs=function(a){c.url("/jobs/?inventory__int="+a+"&status=failed")}}function InventoriesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){n("htmlTemplate");var w,x=t("inventory"),y=g,z=h;y.well=!0,y.formLabelSize=null,y.formFieldSize=null,w=z.inject(y,{mode:"add",related:!1}),w.inventoryParseType="yaml",z.reset(),l(),u(w,"inventory_variables","inventoryParseType"),s({scope:w,form:y,current_item:f.organization_id?f.organization_id:null,list:p,field:"organization"}),w.formSave=function(){z.clearApiErrors(),v("start");try{var a,b,c;if(b="json"===w.inventoryParseType?JSON.parse(w.inventory_variables):jsyaml.load(w.inventory_variables),"object"!=typeof b)throw"failed to return an object!";c={};for(a in y.fields)"inventory_variables"!==a&&(y.fields[a].realName?c[y.fields[a].realName]=w[a]:c[a]=w[a]);i.setUrl(x),i.post(c).success(function(a){var c=a.id;w.inventory_variables?(i.setUrl(a.related.variable_data),i.put(b).success(function(){v("stop"),d.path("/inventories/"+c+"/")}).error(function(a,b){v("stop"),k(w,a,b,null,{hdr:"Error!",msg:"Failed to add inventory varaibles. PUT returned status: "+b})})):(v("stop"),d.path("/inventories/"+c+"/"))}).error(function(a,b){v("stop"),k(w,a,b,y,{hdr:"Error!",msg:"Failed to add new inventory. Post returned status: "+b})})}catch(e){v("stop"),j("Error","Error parsing inventory variables. Parser returned: "+e)}},w.formReset=function(){z.reset()}}function InventoriesEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P){f("htmlTemplate");var Q=e,R=g;a.inventory_id=c.inventory_id,r({path:b.path(),title:"{{ inventory_name }}"}),a.removeGroupTreeLoaded&&a.removeGroupTreeLoaded(),a.removeGroupTreeLoaded=a.$on("GroupTreeLoaded",function(b,c,e){var f,g;f=angular.element(document.getElementById("breadcrumbs")),f.html(q({list:R,mode:"edit"})),d(f)(a),Q.inject(R,{mode:"edit",id:"groups-container",breadCrumbs:!1,searchSize:"col-lg-5 col-md-5 col-sm-5"}),a.groups=e,a.inventory_name=c,a.groups.length>0?(a.selected_tree_id=a.groups[0].id,a.selected_group_id=a.groups[0].group_id,a.groups[0].selected_class="selected",a.groups[0].active_class="active-row",a.selected_group_name=a.groups[0].name):(a.selected_tree_id=null,a.selected_group_id=null),a.show_failures=!1,l({scope:a,inventory_id:a.inventory_id,tree_id:a.selected_tree_id,group_id:a.selected_group_id}),setTimeout(function(){$("#groups_table .name-column").each(function(){var a,b,c,d,e;a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%",$(this).find(".group-name").css({width:e})}),L("#groups_table .group-name a"),L("#hosts_table .host-name a")},2500),M(),g=P("inventoryAutoHelp"),"off"!==g&&a.autoShowGroupHelp&&a.showGroupHelp({autoShow:!0})}),a.removeGroupTreeRefreshed&&a.removeGroupTreeRefreshed(),a.removeGroupTreeRefreshed=a.$on("GroupTreeRefreshed",function(){setTimeout(function(){L("#groups_table .group-name a")},2500),a.showHosts(a.selected_tree_id,a.selected_group_id,!1)}),a.removeGroupDeleteCompleted&&a.removeGroupDeleteCompleted(),a.removeGroupDeleteCompleted=a.$on("GroupDeleteCompleted",function(){a.selected_tree_id=1,a.selected_group_id=null,i({scope:a,inventory_id:a.inventory_id,refresh:!0})}),a.removeCopMoveGroup&&a.removeCopyMoveGroup(),a.removeCopyMoveGroup=a.$on("CopyMoveGroup",function(b,c,d){G({scope:a,target_tree_id:d,inbound_tree_id:c})}),a.removeCopMoveHost&&a.removeCopyMoveHost(),a.removeCopyMoveHost=a.$on("CopyMoveHost",function(b,c,d){H({scope:a,target_tree_id:c,host_id:d})}),a.showHosts=function(b,c,d){if(null!==b){j("start"),a.selected_tree_id=b,a.selected_group_id=c,a.hosts=[],a.show_failures=d;for(var e=0;e"+c.name+". Use the Refresh button to monitor the status.","alert-info"):(j("start"),t.setUrl(c.related.inventory_source),t.get().success(function(b){v({scope:a,url:b.related.update,group_name:b.summary_fields.group.name,group_source:b.source,tree_id:c.id,group_id:c.group_id})}).error(function(b,d){j("stop"),u(a,b,d,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+c.related.inventory_source+" POST returned status: "+d})}))))},a.cancelUpdate=function(b){z({scope:a,tree_id:b})},a.toggle=function(b){x({scope:a,list:R,id:b})},a.refreshGroups=function(b,c){b&&(a.selected_tree_id=b,a.selected_group_id=c),i({scope:a,inventory_id:a.inventory_id,refresh:!0})},a.viewUpdateStatus=function(b,c){y({scope:a,tree_id:b,group_id:c})},a.deleteGroup=function(b,c){p({scope:a,tree_id:b,group_id:c,inventory_id:a.inventory_id})},a.createHost=function(){B({scope:a})},a.editInventoryProperties=function(){C({scope:a,inventory_id:a.inventory_id})},a.editHost=function(b){D({scope:a,host_id:b,inventory_id:a.inventory_id})},a.deleteHost=function(b,c){E({scope:a,host_id:b,host_name:c})},a.toggleHostEnabled=function(b,c){F({scope:a,host_id:b,external_source:c})},a.showGroupActivity=function(){var b,c,d;a.selected_group_id?(d=A({list:a.groups,key:"id",val:a.selected_tree_id}),b=J("activity_stream")+"?group__id="+a.selected_group_id,c="Showing all activities for group "+d.name):(c="Showing all activities for all "+a.inventory_name+" groups",b=J("activity_stream")+"?group__inventory__id="+a.inventory_id),I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showHostActivity=function(){var b,c;c="Showing all activities for all "+a.inventory_name+" hosts",b=J("activity_stream")+"?host__inventory__id="+a.inventory_id,I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showJobSummary=function(a){K({job_id:a})},a.showGroupHelp=function(a){var b={defn:O};a&&(b.autoShow=a.autoShow||!1),N(b)},i({scope:a,inventory_id:a.inventory_id,refresh:!1})}function JobEventsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){function y(a){var b,c,d,e,f,g="",h=!1;if(a.res){if("string"==typeof a.res)c=a.res.match(/\n/g),d=c?c.length:1,d=d>10?10:d,h=!0,g+='
        \n',g+="\n",g+='\n",g+="
        \n";else for(e in a.res){if(("msg"===e||"stdout"===e||"stderr"===e)&&null!==a.res[e]&&""!==a.res[e]){switch(g+='
        \n',g+="\n",c=a.res[e].match(/\n/g),d=c?c.length:1,d=d>10?10:d,g+='\n",g+="
        \n",h=!0}if("results"===e&&Array.isArray(a.res[e])&&a.res[e].length>0){for(f="",b=0;b10?10:d,""!==f&&(g+='
        \n',g+="\n",g+='\n",g+="
        \n",h=!0)}"rc"===e&&""!==a.res[e]&&(g+='
        \n',g+="\n",g+='\n',g+="
        \n",h=!0)}g=h?'
        \n'+g+"
        \n":""}return g=a.hosts?''+a.host+"\n"+g:""===g?null:g}p("htmlTemplate");var z,A=i,B=r("jobs")+f.id+"/job_events/",C=j,D=C.inject(A,{mode:"edit"});A.base=d.path(),D.job_id=f.id,c.flashMessage=null,D.selected=[],D.expand=!0,D.parentNode="parent-event",D.childNode="child-event",D.removeSetHostLinks&&D.removeSetHostLinks(),D.removeSetHostLinks=D.$on("SetHostLinks",function(a,b){for(var c=0;c15?5:e,$('textarea[name="'+c+'"]').attr("rows",e)));break;case"module_name":case"module_args":a.event_data.res&&a.event_data.res.invocation&&(t[c]=a.event_data.res.invocation.fld)}q("stop")}).error(function(a){k(t,a,status,null,{hdr:"Error!",msg:"Failed to retrieve host: "+f.event_id+". GET status: "+status})}),t.navigateBack=function(){var a="/jobs/"+f.job_id+"/job_events";f.page&&(a+="?page="+f.page),d.url(a)},t.rawView=function(){p({event_id:t.id})}}function JobHostSummaryList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){o("htmlTemplate");var u=h,v=c.path().replace(/^\//,"").split("/")[0],w=q(v)+e.id+"/job_host_summaries/",x=i,y=x.inject(u,{mode:"edit"});u.index="hosts"===v?!1:!0,y.selected=[],"hosts"===v?(y.job_id=null,y.host_id=e.id):(y.job_id=e.id,y.host_id=null),y.RemoveSetHostLink&&y.RemoveSetHostLink(),y.RemoveSetHostLink=y.$on("setHostLink",function(a,b){for(var c=0;c0?y.jobhosts[0].summary_fields.host.name:"Host"}),e.inventory&&y.$emit("setHostLink",e.inventory))}),l({scope:y,set:"jobhosts",list:u,url:w}),m({scope:y,list:u,url:w}),e.host_name&&(y[u.iterator+"SearchField"]="host",y[u.iterator+"SearchValue"]=e.host_name,y[u.iterator+"SearchFieldLabel"]=u.fields.host.label),y.search(u.iterator),y.showEvents=function(a,b){f.setUrl(b),f.get().success(function(b){j({path:"/jobs/"+b.id,title:b.name}),c.url("/jobs/"+b.id+"/job_events/?host="+encodeURI(a))}).error(function(a,c){p(y,a,c,null,{hdr:"Error!",msg:"Failed to lookup last job: "+b+". GET status: "+c})})},y.showJob=function(a){c.path("/jobs/"+a)},y.refresh=function(){null===y.host_id&&(y.jobSearchSpin=!0,y.jobLoading=!0,t("start"),r({scope:y,set:"jobhosts",iterator:"jobhost",url:y.current_url}))}}function JobTemplatesList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){o("htmlTemplate");var y=h,z=q("job_templates"),A=i,B=c.path().replace(/^\//,"").split("/")[0],C="job_templates"===B?"edit":"select",D=A.inject(y,{mode:C});b.flashMessage=null,D.removePostRefresh&&D.removePostRefresh(),D.removePostRefresh=D.$on("PostRefresh",function(){w("stop"),$("#prompt-modal").off()}),l({scope:D,set:"job_templates",list:y,url:z}),m({scope:D,list:y,url:z}),e.name&&(D[y.iterator+"SearchField"]="name",D[y.iterator+"SearchValue"]=e.name,D[y.iterator+"SearchFieldLabel"]=y.fields.name.label),D.search(y.iterator),j(),D.showActivity=function(){x({scope:D})},D.addJobTemplate=function(){c.path(c.path()+"/add")},D.editJobTemplate=function(a){c.path(c.path()+"/"+a)},D.deleteJobTemplate=function(a,b){var c=function(){$("#prompt-modal").on("hidden.bs.modal",function(){w("start")}),$("#prompt-modal").modal("hide");var b=z+a+"/";f.setUrl(b),f.destroy().success(function(){D.search(y.iterator)}).error(function(a){w("stop"),p(D,a,status,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+status})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},D.submitJob=function(a){v({scope:D,id:a})}}function JobTemplatesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){n("htmlTemplate");var x,y,z=o("job_templates"),A=g,B=h,C=B.inject(A,{mode:"add",related:!1}),D={},E={};C.parseType="yaml",u(C),C.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],C.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],C.playbook_options=[],C.allow_callbacks="false",B.reset(),l(),t({scope:C,master:D,check_field:"allow_callbacks",default_val:!1}),s({scope:C,form:A,current_item:null,list:p,field:"inventory"}),jQuery.extend(!0,E,q),E.name="cloudcredentials",E.iterator="cloudcredential",s({url:o("credentials")+"?cloud=true",scope:C,form:A,current_item:null,list:E,field:"cloud_credential",hdr:"Select Cloud Credential"}),s({url:o("credentials")+"?kind=ssh",scope:C,form:A,current_item:null,list:q,field:"credential",hdr:"Select Machine Credential"}),x=function(a,b){var c;a!==b&&C.project&&(v("start"),c=o("projects")+C.project+"/playbooks/",i.setUrl(c),i.get().success(function(a){var b,c=[];for(b=0;b=2)for(var a in O)J.search(O[a].iterator)}),J.removeRelatedJobs&&J.removeRelatedJobs(),J.removeRelatedJobs=J.$on("relatedjobs",function(){var a,b;if(J.jobs&&J.jobs.length)for(a=0;a0)for(c=0;c/g," ");for(y in z.fields.status.searchOptions)if(z.fields.status.searchOptions[y].value===e.status){C[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[y];break}}C.search(z.iterator),j(),C.refresh=function(){x("start"),C.jobLoading=!1,u({scope:C,set:"jobs",iterator:"job",url:C.current_url})},C.refreshJob=C.refresh,C.editJob=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a)},C.viewEvents=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_events")},C.viewSummary=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_host_summaries")},C.deleteJob=function(a){f.setUrl(A+a+"/"),f.get().success(function(b){var c,d,e,g;"pending"===b.status||"running"===b.status||"waiting"===b.status?(d=b.related.cancel,e="cancel",g="Cancel Job"):(d=A+a+"/",e="delete",g="Delete Job"),c=function(){f.setUrl(d),"cancel"===e?f.post().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. POST returned status: "+b})}):f.destroy().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. DELETE returned status: "+b})})},k({hdr:g,body:"Are you sure you want to "+e+" job "+a+"?",action:c})}).error(function(a,b){p(C,a,b,null,{hdr:"Error!",msg:"Failed to get job details. GET returned status: "+b})})},C.submitJob=function(a,b){s({scope:C,id:a,template:b})}}function JobsEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z){function A(a){if(null!==a&&""!==a&&void 0!==a){var b=v("projects")+a+"/playbooks/";i.setUrl(b),i.get().success(function(a){F.playbook_options=[];for(var b=0;b15?15:c}p("htmlTemplate");var C=v("jobs"),D=h,E=g,F=D.inject(E,{mode:"edit",related:!0}),G={},H=f.id,I={},J=0;D.reset(),F.job_id=H,F.parseType="yaml",F.statusSearchSpin=!1,F.jobLoadedRemove&&F.jobLoadedRemove(),F.jobLoadedRemove=F.$on("jobLoaded",function(a,b){A(F.project),F[E.name+"ReadOnly"]="new"===F.status?!1:!0,$("#forks-slider").slider("option","value",F.forks),$("#forks-slider").slider("disable"),$('input[type="checkbox"]').attr("disabled","disabled"),$('input[type="radio"]').attr("disabled","disabled"),$("#host_config_key-gen-btn").attr("disabled","disabled"),$("textarea").attr("readonly","readonly"),i.setUrl(F.template_url),i.get().success(function(a){var b=a.host_config_key?"true":"false";F.host_config_key=a.host_config_key,w({scope:F,master:G,check_field:"allow_callbacks",default_val:b}),F.callback_url=a.related?a.related.callback:"<< Job template not found >>",F.$emit("jobTemplateLoadFinished")}).error(function(){z("stop"),F.callback_url="<< Job template not found >>"}),b?(i.setUrl(b),i.get().success(function(a){F.cloud_credential_name=a.name,F.$emit("jobTemplateLoadFinished")}).error(function(a,b){k(F,a,b,null,{hdr:"Error!",msg:"Failed to related cloud credential. GET returned status: "+b})})):F.$emit("jobTemplateLoadFinished")}),F.removeJobTemplateLoadFinished&&F.removeJobTemplateLoadFinished(),F.removeJobTemplateLoadFinished=F.$on("jobTemplateLoadFinished",function(){J++,J>=3&&z("stop")}),F.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],F.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],F.playbook_options=null,F.playbook=null,z("start"),i.setUrl(C+":id/"),i.get({params:{id:H}}).success(function(a){var b,c,d,e,f,g;l();for(d in E.fields){if("variables"!==d&&null!==a[d]&&void 0!==a[d]){if("select"===E.fields[d].type)if(F[d+"_options"]&&F[d+"_options"].length>0)for(b=0;b/g," ");for(a in A.fields.scm_type.searchOptions)if(A.fields.scm_type.searchOptions[a].value===e.scm_type){F[A.iterator+"SearchSelectValue"]=A.fields.scm_type.searchOptions[a];break}}else if(e.status){F[A.iterator+"SearchValue"]=e.status,F[A.iterator+"SearchField"]="status",F[A.iterator+"SelectShow"]=!0,F[A.iterator+"SearchFieldLabel"]=A.fields.status.label,F[A.iterator+"SearchSelectOpts"]=A.fields.status.searchOptions;for(a in A.fields.status.searchOptions)if(A.fields.status.searchOptions[a].value===e.status){F[A.iterator+"SearchSelectValue"]=A.fields.status.searchOptions[a];break}}F.search(A.iterator)}),F.removeChoicesReady&&F.removeChoicesReady(),F.removeChoicesReady=F.$on("choicesReadyProject",function(){H++,2===H&&F.$emit("choicesCompleteProject")}),y({scope:F,url:B,field:"status",variable:"project_status_options",callback:"choicesReadyProject"}),y({scope:F,url:B,field:"scm_type",variable:"project_scm_type_options",callback:"choicesReadyProject"}),j(),F.showActivity=function(){x({scope:F})},F.addProject=function(){c.path(c.path()+"/add")},F.editProject=function(a){c.path(c.path()+"/"+a)},F.showSCMStatus=function(a){var b,c=F.$on("PostRefresh",function(){var d;for(b=0;bRefresh button to view the latest status.","alert-info")}).error(function(a,b){p(F,a,b,null,{hdr:"Error!",msg:"Call to "+c+" failed. GET status: "+b})})}),F.cancelUpdate=function(a,b){var c,d,e=!1;for(c=0;cRefresh button to view the latet status.","alert-info")},F.refresh=function(){w("start"),F.projectLoading=!1,v({scope:F,set:"projects",iterator:"project",url:F.current_url})},F.SCMUpdate=function(a){var b;for(b=0;bb;b++){for(d[b].match(/[A-Z]/g)?(""!==R&&R+1==b&&(y++,C++),R=b,o++):d[b].match(/[a-z]/g)?(""!==S&&S+1==b&&(z++,C++),S=b,p++):d[b].match(/[0-9]/g)?(b>0&&e-1>b&&s++,""!==T&&T+1==b&&(A++,C++),T=b,q++):d[b].match(/[^a-zA-Z0-9_]/g)&&(b>0&&e-1>b&&s++,""!==U&&U+1==b&&(B++,C++),U=b,r++),f=!1,g=0;e>g;g++)d[b]==d[g]&&b!=g&&(f=!0,x+=Math.abs(e/(g-b)));f&&(w++,v=e-w,x=Math.ceil(v?x/v:x))}for(h=0;23>h;h++)i=ib.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(D++,G++);for(h=0;8>h;h++)i=jb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(E++,G++);for(h=0;8>h;h++)i=kb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(F++,G++);o>0&&n>o&&(nScore=parseInt(nScore+2*(n-o)),V="+ "+parseInt(2*(n-o))),p>0&&n>p&&(nScore=parseInt(nScore+2*(n-p)),W="+ "+parseInt(2*(n-p))),q>0&&n>q&&(nScore=parseInt(nScore+q*P),X="+ "+parseInt(q*P)),r>0&&(nScore=parseInt(nScore+r*Q),Y="+ "+parseInt(r*Q)),s>0&&(nScore=parseInt(nScore+s*H),Z="+ "+parseInt(s*H)),(p>0||o>0)&&0===r&&0===q&&(nScore=parseInt(nScore-n),t=n,_="- "+n),0===p&&0===o&&0===r&&q>0&&(nScore=parseInt(nScore-n),u=n,ab="- "+n),w>0&&(nScore=parseInt(nScore-x),bb="- "+x),y>0&&(nScore=parseInt(nScore-y*I),cb="- "+parseInt(y*I)),z>0&&(nScore=parseInt(nScore-z*J),db="- "+parseInt(z*J)),A>0&&(nScore=parseInt(nScore-A*K),eb="- "+parseInt(A*K)),D>0&&(nScore=parseInt(nScore-D*L),fb="- "+parseInt(D*L)),E>0&&(nScore=parseInt(nScore-E*M),gb="- "+parseInt(E*M)),F>0&&(nScore=parseInt(nScore-F*N),hb="- "+parseInt(F*N)),nScore>100?nScore=100:0>nScore&&(nScore=0),k=$("#progbar"),l=$AnsibleConfig.password_strength,m=$AnsibleConfig.password_strength-15<0?0:$AnsibleConfig.password_strength-15,k.css("width",nScore+"%"),nScore>=0&&m>=nScore?(lb="Weak",k.addClass("progress-bar-danger"),k.removeClass("progress-bar-success progress-bar-warning")):nScore>m&&l>=nScore?(lb="Good",k.addClass("progress-bar-warning"),k.removeClass("progress-bar-success progress-bar-danger")):nScore>l&&(lb="Strong",k.addClass("progress-bar-success"),k.removeClass("progress-bar-warning progress-bar-danger"))}else k=$("#progbar"),k.css("width","0%"),k.removeClass("progress-bar-success progress-bar-warning");return nScore}function AdminsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=h,r=o("organizations")+e.organization_id+"/users/",s=i,t="select",u=s.inject(h,{mode:t}),v=o("organizations")+e.organization_id+"/admins/";p({scope:u,list:q,url:v,returnToCaller:1}),l({scope:u,set:"admins",list:q,url:r}),m({scope:u,list:q,url:r}),u.search(q.iterator),j()}function Authenticate(a,b,c,d,e,f,g,h,i,j,k){var l,m,n,o;l=function(){$("#login-username").focus()},n=k(d.sessionExpired)?a.get("sessionExpired"):d.sessionExpired,m=function(){return k(d.lastPath)?a.get("lastPath"):d.lastPath},$AnsibleConfig.debug_mode&&console&&(console.log("User session expired: "+n),console.log("Last URL: "+m())),$(".modal[aria-hidden=false]").each(function(){"login-modal"!==$(this).attr("id")&&$(this).modal("hide")}),i("stop"),$("#login-modal").modal({show:!0,keyboard:!1,backdrop:"static"}),$("#login-modal").on("shown.bs.modal",function(){l()}),o=angular.element(document.getElementById("login-modal")).scope(),o.login_username=null,o.login_password=null,o.loginForm.login_username.$setPristine(),o.loginForm.login_password.$setPristine(),"/logout"===e.path()&&f.logout(),d.userLoggedIn=!1,a.put("userLoggedIn",!1),$("#login-password").bind("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13===b&&$("#login-button").click()}),o.reset=function(){$("#login-form input").each(function(){$(this).val("")})},o.systemLogin=function(a,b){$(".api-error").empty();var c;k(a)||k(b)?h("Error!","Please provide a username and password before attempting to login.","alert-danger",l):(i("start"),f.retrieveToken(a,b).success(function(a,b){$("#login-modal").modal("hide"),c=a.token,f.setToken(a.token,a.expires),d.sessionTimer=j.init(),f.getUser().success(function(a){f.setUserInfo(a),d.user_is_superuser=a.results[0].is_superuser,f.getLicense().success(function(a){f.setLicense(a.license_info),m()?e.path(m()):e.url("/home?login=true")}).error(function(){i("stop"),h("Error","Failed to access user information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){i("stop"),h("Error","Failed to access license information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){var c,d,e;if(i("stop"),a.non_field_errors&&0===a.non_field_errors.length)for(e in a)o[e+"Error"]=a[e][0];else a.non_field_errors&&a.non_field_errors.length>0?(c="Error",d=a.non_field_errors[0]):(c="Error",d="The login attempt failed with a status of: "+b),o.reset(),h(c,d,"alert-danger",l)}))}}function CredentialsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){o("htmlTemplate"),t("start");var v,w=h,x=q("credentials"),y=i,z=c.path().replace(/^\//,"").split("/")[0],A="credentials"===z?"edit":"select",B=y.inject(w,{mode:A});B.selected=[],B.credentialLoading=!0,v=q(z)+("users"===z?e.user_id+"/credentials/":e.team_id+"/credentials/"),r({scope:B,list:w,url:v,returnToCaller:1}),B.removePostRefresh&&B.removePostRefresh(),B.removePostRefresh=B.$on("PostRefresh",function(){var a,b;for(t("stop"),$("#prompt-modal").off(),w.fields.kind.searchOptions=B.credential_kind_options,a=0;a/g," ");for(x in z.fields.status.searchOptions)if(z.fields.status.searchOptions[x].value===b.status){B[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[x];break}}if(b.source){B[z.iterator+"SearchField"]="source",B[z.iterator+"SelectShow"]=!0,B[z.iterator+"SearchSelectOpts"]=z.fields.source.searchOptions,B[z.iterator+"SearchFieldLabel"]=z.fields.source.label.replace(//g," ");for(x in z.fields.source.searchOptions)if(z.fields.source.searchOptions[x].value===b.source){B[z.iterator+"SearchSelectValue"]=z.fields.source.searchOptions[x];break}b.status&&(B[z.iterator+"ExtraParms"]="&inventory_source__status__icontains="+b.status)}b.has_external_source&&(B[z.iterator+"SearchField"]="has_external_source",B[z.iterator+"SearchValue"]=z.fields.has_external_source.searchValue,B[z.iterator+"InputDisable"]=!0,B[z.iterator+"SearchType"]="in",B[z.iterator+"SearchFieldLabel"]=z.fields.has_external_source.label),B.search(z.iterator),f(),B.showActivity=function(){p({scope:B})},B.editGroup=function(a,b){q({scope:B,group_id:a,inventory_id:b,groups_reload:!1})},B.viewUpdateStatus=function(a){B.groups=B.home_groups,o({scope:B,tree_id:a})},B.updateGroup=function(a){var b=w({list:B.home_groups,key:"id",val:a});b&&(u(b.source)||("updating"===b.status?s("Update in Progress","The inventory update process is currently running for group "+b.name+". Use the Refresh button to monitor the status.","alert-info"):(r("start"),t.setUrl(b.related.inventory_source),t.get().success(function(a){v({scope:B,url:a.related.update,group_name:a.summary_fields.group.name,group_source:a.source,tree_id:b.id,group_id:b.id})}).error(function(a,c){e(B,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+b.related.inventory_source+" POST returned status: "+c})}))))},B.refresh=function(){B.search(z.iterator,null,!1,!0)}}function HomeHosts(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){h("htmlTemplate");var s=d,t=c,u=i("hosts"),v=s.inject(t,{mode:"edit"});v.removePostRefresh&&v.removePostRefresh(),v.removePostRefresh=v.$on("PostRefresh",function(){for(var a=0;a0?(z.inventories[a].failed_hosts_tip=z.inventories[a].hosts_with_active_failures+(1===z.inventories[a].hosts_with_active_failures?" host":" hosts")+" with job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="true"):0===z.inventories[a].total_hosts?(z.inventories[a].failed_hosts_tip="No hosts defined. Click to add.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="na"):(z.inventories[a].failed_hosts_tip=z.inventories[a].total_hosts+(z.inventories[a].total_hosts>1?" hosts":" host")+" with no job failures. Click to view details.",z.inventories[a].failed_hosts_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].failed_hosts_class="false"),z.inventories[a].status=z.inventories[a].inventory_sources_with_failures+" / "+z.inventories[a].total_inventory_sources,z.inventories[a].inventory_sources_with_failures>0?(z.inventories[a].status_tip=z.inventories[a].inventory_sources_with_failures+" cloud "+(1===z.inventories[a].inventory_sources_with_failures?"source":"sources")+" with failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="failed"):0===z.inventories[a].total_inventory_sources?(z.inventories[a].status_tip="Not synced with a cloud source. Click to edit.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="na"):(z.inventories[a].status_tip=z.inventories[a].total_inventory_sources+" cloud "+(z.inventories[a].total_inventory_sources>1?"sources":"source")+" with no failures. Click to view details.",z.inventories[a].status_link="/#/inventories/"+z.inventories[a].id+"/",z.inventories[a].status_class="successful")}),z.removeRefreshInventories&&z.removeRefreshInventories(),z.removeRefreshInventories=z.$on("RefreshInventories",function(){z.search(u.iterator)}),z.showActivity=function(){s({scope:z})},z.editInventoryProperties=function(a){t({scope:z,inventory_id:a})},z.addInventory=function(){c.path(c.path()+"/add")},z.editInventory=function(a){c.path(c.path()+"/"+a)},z.deleteInventory=function(a,b){var c=function(){var b=v+a+"/";$("#prompt-modal").on("hidden.bs.modal",function(){r("start")}),$("#prompt-modal").modal("hide"),f.setUrl(b),f.destroy().success(function(){z.search(u.iterator)}).error(function(a,c){r("stop"),p(z,a,c,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+c})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},z.lookupOrganization=function(a){f.setUrl(q("organizations")+a+"/"),f.get().success(function(a){return a.name})},z.viewJobs=function(a){c.url("/jobs/?inventory__int="+a)},z.viewFailedJobs=function(a){c.url("/jobs/?inventory__int="+a+"&status=failed")}}function InventoriesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){n("htmlTemplate");var w,x=t("inventory"),y=g,z=h;y.well=!0,y.formLabelSize=null,y.formFieldSize=null,w=z.inject(y,{mode:"add",related:!1}),w.inventoryParseType="yaml",z.reset(),l(),u(w,"inventory_variables","inventoryParseType"),s({scope:w,form:y,current_item:f.organization_id?f.organization_id:null,list:p,field:"organization"}),w.formSave=function(){z.clearApiErrors(),v("start");try{var a,b,c;if(b="json"===w.inventoryParseType?JSON.parse(w.inventory_variables):jsyaml.load(w.inventory_variables),"object"!=typeof b)throw"failed to return an object!";c={};for(a in y.fields)"inventory_variables"!==a&&(y.fields[a].realName?c[y.fields[a].realName]=w[a]:c[a]=w[a]);i.setUrl(x),i.post(c).success(function(a){var c=a.id;w.inventory_variables?(i.setUrl(a.related.variable_data),i.put(b).success(function(){v("stop"),d.path("/inventories/"+c+"/")}).error(function(a,b){v("stop"),k(w,a,b,null,{hdr:"Error!",msg:"Failed to add inventory varaibles. PUT returned status: "+b})})):(v("stop"),d.path("/inventories/"+c+"/"))}).error(function(a,b){v("stop"),k(w,a,b,y,{hdr:"Error!",msg:"Failed to add new inventory. Post returned status: "+b})})}catch(e){v("stop"),j("Error","Error parsing inventory variables. Parser returned: "+e)}},w.formReset=function(){z.reset()}}function InventoriesEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P){f("htmlTemplate");var Q=e,R=g;a.inventory_id=c.inventory_id,r({path:b.path(),title:"{{ inventory_name }}"}),a.removeGroupTreeLoaded&&a.removeGroupTreeLoaded(),a.removeGroupTreeLoaded=a.$on("GroupTreeLoaded",function(b,c,e){var f,g;f=angular.element(document.getElementById("breadcrumbs")),f.html(q({list:R,mode:"edit"})),d(f)(a),Q.inject(R,{mode:"edit",id:"groups-container",breadCrumbs:!1,searchSize:"col-lg-5 col-md-5 col-sm-5"}),a.groups=e,a.inventory_name=c,a.groups.length>0?(a.selected_tree_id=a.groups[0].id,a.selected_group_id=a.groups[0].group_id,a.groups[0].selected_class="selected",a.groups[0].active_class="active-row",a.selected_group_name=a.groups[0].name):(a.selected_tree_id=null,a.selected_group_id=null),a.show_failures=!1,l({scope:a,inventory_id:a.inventory_id,tree_id:a.selected_tree_id,group_id:a.selected_group_id}),setTimeout(function(){$("#groups_table .name-column").each(function(){var a,b,c,d,e;a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%",$(this).find(".group-name").css({width:e})}),L("#groups_table .group-name a"),L("#hosts_table .host-name a")},2500),M(),g=P("inventoryAutoHelp"),"off"!==g&&a.autoShowGroupHelp&&a.showGroupHelp({autoShow:!0})}),a.removeGroupTreeRefreshed&&a.removeGroupTreeRefreshed(),a.removeGroupTreeRefreshed=a.$on("GroupTreeRefreshed",function(){setTimeout(function(){L("#groups_table .group-name a")},2500),a.showHosts(a.selected_tree_id,a.selected_group_id,!1)}),a.removeGroupDeleteCompleted&&a.removeGroupDeleteCompleted(),a.removeGroupDeleteCompleted=a.$on("GroupDeleteCompleted",function(){a.selected_tree_id=1,a.selected_group_id=null,i({scope:a,inventory_id:a.inventory_id,refresh:!0})}),a.removeCopMoveGroup&&a.removeCopyMoveGroup(),a.removeCopyMoveGroup=a.$on("CopyMoveGroup",function(b,c,d){G({scope:a,target_tree_id:d,inbound_tree_id:c})}),a.removeCopMoveHost&&a.removeCopyMoveHost(),a.removeCopyMoveHost=a.$on("CopyMoveHost",function(b,c,d){H({scope:a,target_tree_id:c,host_id:d})}),a.showHosts=function(b,c,d){if(null!==b){j("start"),a.selected_tree_id=b,a.selected_group_id=c,a.hosts=[],a.show_failures=d;for(var e=0;e"+c.name+". Use the Refresh button to monitor the status.","alert-info"):(j("start"),t.setUrl(c.related.inventory_source),t.get().success(function(b){v({scope:a,url:b.related.update,group_name:b.summary_fields.group.name,group_source:b.source,tree_id:c.id,group_id:c.group_id})}).error(function(b,d){j("stop"),u(a,b,d,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+c.related.inventory_source+" POST returned status: "+d})}))))},a.cancelUpdate=function(b){z({scope:a,tree_id:b})},a.toggle=function(b){x({scope:a,list:R,id:b})},a.refreshGroups=function(b,c){b&&(a.selected_tree_id=b,a.selected_group_id=c),i({scope:a,inventory_id:a.inventory_id,refresh:!0})},a.viewUpdateStatus=function(b,c){y({scope:a,tree_id:b,group_id:c})},a.deleteGroup=function(b,c){p({scope:a,tree_id:b,group_id:c,inventory_id:a.inventory_id})},a.createHost=function(){B({scope:a})},a.editInventoryProperties=function(){C({scope:a,inventory_id:a.inventory_id})},a.editHost=function(b){D({scope:a,host_id:b,inventory_id:a.inventory_id})},a.deleteHost=function(b,c){E({scope:a,host_id:b,host_name:c})},a.toggleHostEnabled=function(b,c){F({scope:a,host_id:b,external_source:c})},a.showGroupActivity=function(){var b,c,d;a.selected_group_id?(d=A({list:a.groups,key:"id",val:a.selected_tree_id}),b=J("activity_stream")+"?group__id="+a.selected_group_id,c="Showing all activities for group "+d.name):(c="Showing all activities for all "+a.inventory_name+" groups",b=J("activity_stream")+"?group__inventory__id="+a.inventory_id),I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showHostActivity=function(){var b,c;c="Showing all activities for all "+a.inventory_name+" hosts",b=J("activity_stream")+"?host__inventory__id="+a.inventory_id,I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showJobSummary=function(a){K({job_id:a})},a.showGroupHelp=function(a){var b={defn:O};a&&(b.autoShow=a.autoShow||!1),N(b)},i({scope:a,inventory_id:a.inventory_id,refresh:!1})}function JobEventsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){function y(a){var b,c,d,e,f,g="",h=!1;if(a.res){if("string"==typeof a.res)c=a.res.match(/\n/g),d=c?c.length:1,d=d>10?10:d,h=!0,g+='
        \n',g+="\n",g+='\n",g+="
        \n";else for(e in a.res){if(("msg"===e||"stdout"===e||"stderr"===e)&&null!==a.res[e]&&""!==a.res[e]){switch(g+='
        \n',g+="\n",c=a.res[e].match(/\n/g),d=c?c.length:1,d=d>10?10:d,g+='\n",g+="
        \n",h=!0}if("results"===e&&Array.isArray(a.res[e])&&a.res[e].length>0){for(f="",b=0;b10?10:d,""!==f&&(g+='
        \n',g+="\n",g+='\n",g+="
        \n",h=!0)}"rc"===e&&""!==a.res[e]&&(g+='
        \n',g+="\n",g+='\n',g+="
        \n",h=!0)}g=h?'
        \n'+g+"
        \n":""}return g=a.hosts?''+a.host+"\n"+g:""===g?null:g}p("htmlTemplate");var z,A=i,B=r("jobs")+f.id+"/job_events/",C=j,D=C.inject(A,{mode:"edit"});A.base=d.path(),D.job_id=f.id,c.flashMessage=null,D.selected=[],D.expand=!0,D.parentNode="parent-event",D.childNode="child-event",D.removeSetHostLinks&&D.removeSetHostLinks(),D.removeSetHostLinks=D.$on("SetHostLinks",function(a,b){for(var c=0;c15?5:e,$('textarea[name="'+c+'"]').attr("rows",e)));break;case"module_name":case"module_args":a.event_data.res&&a.event_data.res.invocation&&(t[c]=a.event_data.res.invocation.fld)}q("stop")}).error(function(a){k(t,a,status,null,{hdr:"Error!",msg:"Failed to retrieve host: "+f.event_id+". GET status: "+status})}),t.navigateBack=function(){var a="/jobs/"+f.job_id+"/job_events";f.page&&(a+="?page="+f.page),d.url(a)},t.rawView=function(){p({event_id:t.id})}}function JobHostSummaryList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){o("htmlTemplate");var u=h,v=c.path().replace(/^\//,"").split("/")[0],w=q(v)+e.id+"/job_host_summaries/",x=i,y=x.inject(u,{mode:"edit"});u.index="hosts"===v?!1:!0,y.selected=[],"hosts"===v?(y.job_id=null,y.host_id=e.id):(y.job_id=e.id,y.host_id=null),y.RemoveSetHostLink&&y.RemoveSetHostLink(),y.RemoveSetHostLink=y.$on("setHostLink",function(a,b){for(var c=0;c0?y.jobhosts[0].summary_fields.host.name:"Host"}),e.inventory&&y.$emit("setHostLink",e.inventory))}),l({scope:y,set:"jobhosts",list:u,url:w}),m({scope:y,list:u,url:w}),e.host_name&&(y[u.iterator+"SearchField"]="host",y[u.iterator+"SearchValue"]=e.host_name,y[u.iterator+"SearchFieldLabel"]=u.fields.host.label),y.search(u.iterator),y.showEvents=function(a,b){f.setUrl(b),f.get().success(function(b){j({path:"/jobs/"+b.id,title:b.name}),c.url("/jobs/"+b.id+"/job_events/?host="+encodeURI(a))}).error(function(a,c){p(y,a,c,null,{hdr:"Error!",msg:"Failed to lookup last job: "+b+". GET status: "+c})})},y.showJob=function(a){c.path("/jobs/"+a)},y.refresh=function(){null===y.host_id&&(y.jobSearchSpin=!0,y.jobLoading=!0,t("start"),r({scope:y,set:"jobhosts",iterator:"jobhost",url:y.current_url}))}}function JobTemplatesList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){o("htmlTemplate");var y=h,z=q("job_templates"),A=i,B=c.path().replace(/^\//,"").split("/")[0],C="job_templates"===B?"edit":"select",D=A.inject(y,{mode:C});b.flashMessage=null,D.removePostRefresh&&D.removePostRefresh(),D.removePostRefresh=D.$on("PostRefresh",function(){w("stop"),$("#prompt-modal").off()}),l({scope:D,set:"job_templates",list:y,url:z}),m({scope:D,list:y,url:z}),e.name&&(D[y.iterator+"SearchField"]="name",D[y.iterator+"SearchValue"]=e.name,D[y.iterator+"SearchFieldLabel"]=y.fields.name.label),D.search(y.iterator),j(),D.showActivity=function(){x({scope:D})},D.addJobTemplate=function(){c.path(c.path()+"/add")},D.editJobTemplate=function(a){c.path(c.path()+"/"+a)},D.deleteJobTemplate=function(a,b){var c=function(){$("#prompt-modal").on("hidden.bs.modal",function(){w("start")}),$("#prompt-modal").modal("hide");var b=z+a+"/";f.setUrl(b),f.destroy().success(function(){D.search(y.iterator)}).error(function(a){w("stop"),p(D,a,status,null,{hdr:"Error!",msg:"Call to "+b+" failed. DELETE returned status: "+status})})};k({hdr:"Delete",body:"Are you sure you want to delete "+b+"?",action:c})},D.submitJob=function(a){v({scope:D,id:a})}}function JobTemplatesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){n("htmlTemplate");var x,y,z=o("job_templates"),A=g,B=h,C=B.inject(A,{mode:"add",related:!1}),D={},E={};C.parseType="yaml",u(C),C.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],C.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],C.playbook_options=[],C.allow_callbacks="false",B.reset(),l(),t({scope:C,master:D,check_field:"allow_callbacks",default_val:!1}),s({scope:C,form:A,current_item:null,list:p,field:"inventory"}),jQuery.extend(!0,E,q),E.name="cloudcredentials",E.iterator="cloudcredential",s({url:o("credentials")+"?cloud=true",scope:C,form:A,current_item:null,list:E,field:"cloud_credential",hdr:"Select Cloud Credential"}),s({url:o("credentials")+"?kind=ssh",scope:C,form:A,current_item:null,list:q,field:"credential",hdr:"Select Machine Credential"}),x=function(a,b){var c;a!==b&&C.project&&(v("start"),c=o("projects")+C.project+"/playbooks/",i.setUrl(c),i.get().success(function(a){var b,c=[];for(b=0;b=2)for(var a in O)J.search(O[a].iterator)}),J.removeRelatedJobs&&J.removeRelatedJobs(),J.removeRelatedJobs=J.$on("relatedjobs",function(){var a,b;if(J.jobs&&J.jobs.length)for(a=0;a0)for(c=0;c/g," ");for(y in z.fields.status.searchOptions)if(z.fields.status.searchOptions[y].value===e.status){C[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[y];break}}C.search(z.iterator),j(),C.refresh=function(){x("start"),C.jobLoading=!1,u({scope:C,set:"jobs",iterator:"job",url:C.current_url})},C.refreshJob=C.refresh,C.editJob=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a)},C.viewEvents=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_events")},C.viewSummary=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_host_summaries")},C.deleteJob=function(a){f.setUrl(A+a+"/"),f.get().success(function(b){var c,d,e,g;"pending"===b.status||"running"===b.status||"waiting"===b.status?(d=b.related.cancel,e="cancel",g="Cancel Job"):(d=A+a+"/",e="delete",g="Delete Job"),c=function(){f.setUrl(d),"cancel"===e?f.post().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. POST returned status: "+b})}):f.destroy().success(function(){$("#prompt-modal").modal("hide"),C.search(z.iterator)}).error(function(a,b){$("#prompt-modal").modal("hide"),p(C,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. DELETE returned status: "+b})})},k({hdr:g,body:"Are you sure you want to "+e+" job "+a+"?",action:c})}).error(function(a,b){p(C,a,b,null,{hdr:"Error!",msg:"Failed to get job details. GET returned status: "+b})})},C.submitJob=function(a,b){s({scope:C,id:a,template:b})}}function JobsEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z){function A(a){if(null!==a&&""!==a&&void 0!==a){var b=v("projects")+a+"/playbooks/";i.setUrl(b),i.get().success(function(a){F.playbook_options=[];for(var b=0;b15?15:c}p("htmlTemplate");var C=v("jobs"),D=h,E=g,F=D.inject(E,{mode:"edit",related:!0}),G={},H=f.id,I={},J=0;D.reset(),F.job_id=H,F.parseType="yaml",F.statusSearchSpin=!1,F.jobLoadedRemove&&F.jobLoadedRemove(),F.jobLoadedRemove=F.$on("jobLoaded",function(a,b){A(F.project),F[E.name+"ReadOnly"]="new"===F.status?!1:!0,$("#forks-slider").slider("option","value",F.forks),$("#forks-slider").slider("disable"),$('input[type="checkbox"]').attr("disabled","disabled"),$('input[type="radio"]').attr("disabled","disabled"),$("#host_config_key-gen-btn").attr("disabled","disabled"),$("textarea").attr("readonly","readonly"),i.setUrl(F.template_url),i.get().success(function(a){var b=a.host_config_key?"true":"false";F.host_config_key=a.host_config_key,w({scope:F,master:G,check_field:"allow_callbacks",default_val:b}),F.callback_url=a.related?a.related.callback:"<< Job template not found >>",F.$emit("jobTemplateLoadFinished")}).error(function(){z("stop"),F.callback_url="<< Job template not found >>"}),b?(i.setUrl(b),i.get().success(function(a){F.cloud_credential_name=a.name,F.$emit("jobTemplateLoadFinished")}).error(function(a,b){k(F,a,b,null,{hdr:"Error!",msg:"Failed to related cloud credential. GET returned status: "+b})})):F.$emit("jobTemplateLoadFinished")}),F.removeJobTemplateLoadFinished&&F.removeJobTemplateLoadFinished(),F.removeJobTemplateLoadFinished=F.$on("jobTemplateLoadFinished",function(){J++,J>=3&&z("stop")}),F.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],F.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],F.playbook_options=null,F.playbook=null,z("start"),i.setUrl(C+":id/"),i.get({params:{id:H}}).success(function(a){var b,c,d,e,f,g;l();for(d in E.fields){if("variables"!==d&&null!==a[d]&&void 0!==a[d]){if("select"===E.fields[d].type)if(F[d+"_options"]&&F[d+"_options"].length>0)for(b=0;b/g," ");for(a in A.fields.scm_type.searchOptions)if(A.fields.scm_type.searchOptions[a].value===e.scm_type){F[A.iterator+"SearchSelectValue"]=A.fields.scm_type.searchOptions[a];break}}else if(e.status){F[A.iterator+"SearchValue"]=e.status,F[A.iterator+"SearchField"]="status",F[A.iterator+"SelectShow"]=!0,F[A.iterator+"SearchFieldLabel"]=A.fields.status.label,F[A.iterator+"SearchSelectOpts"]=A.fields.status.searchOptions;for(a in A.fields.status.searchOptions)if(A.fields.status.searchOptions[a].value===e.status){F[A.iterator+"SearchSelectValue"]=A.fields.status.searchOptions[a];break}}F.search(A.iterator)}),F.removeChoicesReady&&F.removeChoicesReady(),F.removeChoicesReady=F.$on("choicesReadyProject",function(){H++,2===H&&F.$emit("choicesCompleteProject")}),y({scope:F,url:B,field:"status",variable:"project_status_options",callback:"choicesReadyProject"}),y({scope:F,url:B,field:"scm_type",variable:"project_scm_type_options",callback:"choicesReadyProject"}),j(),F.showActivity=function(){x({scope:F})},F.addProject=function(){c.path(c.path()+"/add")},F.editProject=function(a){c.path(c.path()+"/"+a)},F.showSCMStatus=function(a){var b,c=F.$on("PostRefresh",function(){var d;for(b=0;bRefresh button to view the latest status.","alert-info")}).error(function(a,b){p(F,a,b,null,{hdr:"Error!",msg:"Call to "+c+" failed. GET status: "+b})})}),F.cancelUpdate=function(a,b){var c,d,e=!1;for(c=0;cRefresh button to view the latet status.","alert-info")},F.refresh=function(){w("start"),F.projectLoading=!1,v({scope:F,set:"projects",iterator:"project",url:F.current_url})},F.SCMUpdate=function(a){var b;for(b=0;bb;b++){for(d[b].match(/[A-Z]/g)?(""!==R&&R+1==b&&(y++,C++),R=b,o++):d[b].match(/[a-z]/g)?(""!==S&&S+1==b&&(z++,C++),S=b,p++):d[b].match(/[0-9]/g)?(b>0&&e-1>b&&s++,""!==T&&T+1==b&&(A++,C++),T=b,q++):d[b].match(/[^a-zA-Z0-9_]/g)&&(b>0&&e-1>b&&s++,""!==U&&U+1==b&&(B++,C++),U=b,r++),f=!1,g=0;e>g;g++)d[b]==d[g]&&b!=g&&(f=!0,x+=Math.abs(e/(g-b)));f&&(w++,v=e-w,x=Math.ceil(v?x/v:x))}for(h=0;23>h;h++)i=ib.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(D++,G++);for(h=0;8>h;h++)i=jb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(E++,G++);for(h=0;8>h;h++)i=kb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(F++,G++);o>0&&n>o&&(nScore=parseInt(nScore+2*(n-o)),V="+ "+parseInt(2*(n-o))),p>0&&n>p&&(nScore=parseInt(nScore+2*(n-p)),W="+ "+parseInt(2*(n-p))),q>0&&n>q&&(nScore=parseInt(nScore+q*P),X="+ "+parseInt(q*P)),r>0&&(nScore=parseInt(nScore+r*Q),Y="+ "+parseInt(r*Q)),s>0&&(nScore=parseInt(nScore+s*H),Z="+ "+parseInt(s*H)),(p>0||o>0)&&0===r&&0===q&&(nScore=parseInt(nScore-n),t=n,_="- "+n),0===p&&0===o&&0===r&&q>0&&(nScore=parseInt(nScore-n),u=n,ab="- "+n),w>0&&(nScore=parseInt(nScore-x),bb="- "+x),y>0&&(nScore=parseInt(nScore-y*I),cb="- "+parseInt(y*I)),z>0&&(nScore=parseInt(nScore-z*J),db="- "+parseInt(z*J)),A>0&&(nScore=parseInt(nScore-A*K),eb="- "+parseInt(A*K)),D>0&&(nScore=parseInt(nScore-D*L),fb="- "+parseInt(D*L)),E>0&&(nScore=parseInt(nScore-E*M),gb="- "+parseInt(E*M)),F>0&&(nScore=parseInt(nScore-F*N),hb="- "+parseInt(F*N)),nScore>100?nScore=100:0>nScore&&(nScore=0),k=$("#progbar"),l=$AnsibleConfig.password_strength,m=$AnsibleConfig.password_strength-15<0?0:$AnsibleConfig.password_strength-15,k.css("width",nScore+"%"),nScore>=0&&m>=nScore?(lb="Weak",k.addClass("progress-bar-danger"),k.removeClass("progress-bar-success progress-bar-warning")):nScore>m&&l>=nScore?(lb="Good",k.addClass("progress-bar-warning"),k.removeClass("progress-bar-success progress-bar-danger")):nScore>l&&(lb="Strong",k.addClass("progress-bar-success"),k.removeClass("progress-bar-warning progress-bar-danger"))}else k=$("#progbar"),k.css("width","0%"),k.removeClass("progress-bar-success progress-bar-warning");return nScore}function AdminsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=h,r=o("organizations")+e.organization_id+"/users/",s=i,t="select",u=o("organizations")+e.organization_id+"/admins/";s.inject(h,{mode:t,scope:a}),p({scope:a,list:q,url:u,returnToCaller:1}),l({scope:a,set:"admins",list:q,url:r}),m({scope:a,list:q,url:r}),a.search(q.iterator),j()}function Authenticate(a,b,c,d,e,f,g,h,i,j,k){var l,m,n,o;l=function(){$("#login-username").focus()},n=k(d.sessionExpired)?a.get("sessionExpired"):d.sessionExpired,m=function(){return k(d.lastPath)?a.get("lastPath"):d.lastPath},$AnsibleConfig.debug_mode&&console&&(console.log("User session expired: "+n),console.log("Last URL: "+m())),$(".modal[aria-hidden=false]").each(function(){"login-modal"!==$(this).attr("id")&&$(this).modal("hide")}),i("stop"),$("#login-modal").modal({show:!0,keyboard:!1,backdrop:"static"}),$("#login-modal").on("shown.bs.modal",function(){l()}),o=angular.element(document.getElementById("login-modal")).scope(),o.login_username=null,o.login_password=null,o.loginForm.login_username.$setPristine(),o.loginForm.login_password.$setPristine(),"/logout"===e.path()&&f.logout(),d.userLoggedIn=!1,a.put("userLoggedIn",!1),$("#login-password").bind("keypress",function(a){var b=a.keyCode?a.keyCode:a.which;13===b&&$("#login-button").click()}),o.reset=function(){$("#login-form input").each(function(){$(this).val("")})},o.systemLogin=function(a,b){$(".api-error").empty();var c;k(a)||k(b)?h("Error!","Please provide a username and password before attempting to login.","alert-danger",l):(i("start"),f.retrieveToken(a,b).success(function(a,b){$("#login-modal").modal("hide"),c=a.token,f.setToken(a.token,a.expires),d.sessionTimer=j.init(),f.getUser().success(function(a){f.setUserInfo(a),d.user_is_superuser=a.results[0].is_superuser,f.getLicense().success(function(a){f.setLicense(a.license_info),m()?e.path(m()):e.url("/home?login=true")}).error(function(){i("stop"),h("Error","Failed to access user information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){i("stop"),h("Error","Failed to access license information. GET returned status: "+b,"alert-danger",l)})}).error(function(a,b){var c,d,e;if(i("stop"),a.non_field_errors&&0===a.non_field_errors.length)for(e in a)o[e+"Error"]=a[e][0];else a.non_field_errors&&a.non_field_errors.length>0?(c="Error",d=a.non_field_errors[0]):(c="Error",d="The login attempt failed with a status of: "+b),o.reset(),h(c,d,"alert-danger",l)}))}}function CredentialsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){o(),t("start");var v,w=h,x=q("credentials"),y=i,z=c.path().replace(/^\//,"").split("/")[0],A="credentials"===z?"edit":"select";y.inject(w,{mode:A,scope:a}),a.selected=[],a.credentialLoading=!0,v=q(z)+("users"===z?e.user_id+"/credentials/":e.team_id+"/credentials/"),"select"===A&&r({scope:a,list:w,url:v,returnToCaller:1}),a.removePostRefresh&&a.removePostRefresh(),a.removePostRefresh=a.$on("PostRefresh",function(){var b,c;for(t("stop"),$("#prompt-modal").off(),w.fields.kind.searchOptions=a.credential_kind_options,b=0;b/g," ");for(x in z.fields.status.searchOptions)if(z.fields.status.searchOptions[x].value===b.status){B[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[x];break}}if(b.source){B[z.iterator+"SearchField"]="source",B[z.iterator+"SelectShow"]=!0,B[z.iterator+"SearchSelectOpts"]=z.fields.source.searchOptions,B[z.iterator+"SearchFieldLabel"]=z.fields.source.label.replace(//g," ");for(x in z.fields.source.searchOptions)if(z.fields.source.searchOptions[x].value===b.source){B[z.iterator+"SearchSelectValue"]=z.fields.source.searchOptions[x];break}b.status&&(B[z.iterator+"ExtraParms"]="&inventory_source__status__icontains="+b.status)}b.has_external_source&&(B[z.iterator+"SearchField"]="has_external_source",B[z.iterator+"SearchValue"]=z.fields.has_external_source.searchValue,B[z.iterator+"InputDisable"]=!0,B[z.iterator+"SearchType"]="in",B[z.iterator+"SearchFieldLabel"]=z.fields.has_external_source.label),B.search(z.iterator),f(),B.showActivity=function(){p({scope:B})},B.editGroup=function(a,b){q({scope:B,group_id:a,inventory_id:b,groups_reload:!1})},B.viewUpdateStatus=function(a){B.groups=B.home_groups,o({scope:B,tree_id:a})},B.updateGroup=function(a){var b=w({list:B.home_groups,key:"id",val:a});b&&(u(b.source)||("updating"===b.status?s("Update in Progress","The inventory update process is currently running for group "+b.name+". Use the Refresh button to monitor the status.","alert-info"):(r("start"),t.setUrl(b.related.inventory_source),t.get().success(function(a){v({scope:B,url:a.related.update,group_name:a.summary_fields.group.name,group_source:a.source,tree_id:b.id,group_id:b.id})}).error(function(a,c){e(B,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+b.related.inventory_source+" POST returned status: "+c})}))))},B.refresh=function(){B.search(z.iterator,null,!1,!0)}}function HomeHosts(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){h("htmlTemplate");var s=d,t=c,u=i("hosts"),v=s.inject(t,{mode:"edit"});v.removePostRefresh&&v.removePostRefresh(),v.removePostRefresh=v.$on("PostRefresh",function(){for(var a=0;a0?(a.inventories[b].failed_hosts_tip=a.inventories[b].hosts_with_active_failures+(1===a.inventories[b].hosts_with_active_failures?" host":" hosts")+" with job failures. Click to view details.",a.inventories[b].failed_hosts_link="/#/inventories/"+a.inventories[b].id+"/",a.inventories[b].failed_hosts_class="true"):0===a.inventories[b].total_hosts?(a.inventories[b].failed_hosts_tip="No hosts defined. Click to add.",a.inventories[b].failed_hosts_link="/#/inventories/"+a.inventories[b].id+"/",a.inventories[b].failed_hosts_class="na"):(a.inventories[b].failed_hosts_tip=a.inventories[b].total_hosts+(a.inventories[b].total_hosts>1?" hosts":" host")+" with no job failures. Click to view details.",a.inventories[b].failed_hosts_link="/#/inventories/"+a.inventories[b].id+"/",a.inventories[b].failed_hosts_class="false"),a.inventories[b].status=a.inventories[b].inventory_sources_with_failures+" / "+a.inventories[b].total_inventory_sources,a.inventories[b].inventory_sources_with_failures>0?(a.inventories[b].status_tip=a.inventories[b].inventory_sources_with_failures+" cloud "+(1===a.inventories[b].inventory_sources_with_failures?"source":"sources")+" with failures. Click to view details.",a.inventories[b].status_link="/#/inventories/"+a.inventories[b].id+"/",a.inventories[b].status_class="failed"):0===a.inventories[b].total_inventory_sources?(a.inventories[b].status_tip="Not synced with a cloud source. Click to edit.",a.inventories[b].status_link="/#/inventories/"+a.inventories[b].id+"/",a.inventories[b].status_class="na"):(a.inventories[b].status_tip=a.inventories[b].total_inventory_sources+" cloud "+(a.inventories[b].total_inventory_sources>1?"sources":"source")+" with no failures. Click to view details.",a.inventories[b].status_link="/#/inventories/"+a.inventories[b].id+"/",a.inventories[b].status_class="successful")}),a.removeRefreshInventories&&a.removeRefreshInventories(),a.removeRefreshInventories=a.$on("RefreshInventories",function(){a.search(u.iterator)}),a.showActivity=function(){s({scope:a})},a.editInventoryProperties=function(b){t({scope:a,inventory_id:b})},a.addInventory=function(){c.path(c.path()+"/add")},a.editInventory=function(a){c.path(c.path()+"/"+a)},a.deleteInventory=function(b,c){var d=function(){var c=v+b+"/";$("#prompt-modal").on("hidden.bs.modal",function(){r("start")}),$("#prompt-modal").modal("hide"),f.setUrl(c),f.destroy().success(function(){a.search(u.iterator)}).error(function(b,d){r("stop"),p(a,b,d,null,{hdr:"Error!",msg:"Call to "+c+" failed. DELETE returned status: "+d})})};k({hdr:"Delete",body:"Are you sure you want to delete "+c+"?",action:d})},a.lookupOrganization=function(a){f.setUrl(q("organizations")+a+"/"),f.get().success(function(a){return a.name})},a.viewJobs=function(a){c.url("/jobs/?inventory__int="+a)},a.viewFailedJobs=function(a){c.url("/jobs/?inventory__int="+a+"&status=failed")}}function InventoriesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){n();var w=t("inventory"),x=g,y=h;x.well=!0,x.formLabelSize=null,x.formFieldSize=null,y.inject(x,{mode:"add",related:!1,scope:a}),a.inventoryParseType="yaml",y.reset(),l(),u(a,"inventory_variables","inventoryParseType"),s({scope:a,form:x,current_item:f.organization_id?f.organization_id:null,list:p,field:"organization"}),a.formSave=function(){y.clearApiErrors(),v("start");try{var b,c,e;if(c="json"===a.inventoryParseType?JSON.parse(a.inventory_variables):jsyaml.load(a.inventory_variables),"object"!=typeof c)throw"failed to return an object!";e={};for(b in x.fields)"inventory_variables"!==b&&(x.fields[b].realName?e[x.fields[b].realName]=a[b]:e[b]=a[b]);i.setUrl(w),i.post(e).success(function(b){var e=b.id;a.inventory_variables?(i.setUrl(b.related.variable_data),i.put(c).success(function(){v("stop"),d.path("/inventories/"+e+"/")}).error(function(b,c){k(a,b,c,null,{hdr:"Error!",msg:"Failed to add inventory varaibles. PUT returned status: "+c})})):(v("stop"),d.path("/inventories/"+e+"/"))}).error(function(b,c){k(a,b,c,x,{hdr:"Error!",msg:"Failed to add new inventory. Post returned status: "+c})})}catch(f){v("stop"),j("Error","Error parsing inventory variables. Parser returned: "+f)}},a.formReset=function(){y.reset()}}function InventoriesEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P){f();var Q=e,R=g;a.inventory_id=c.inventory_id,r({path:b.path(),title:"{{ inventory_name }}"}),a.removeGroupTreeLoaded&&a.removeGroupTreeLoaded(),a.removeGroupTreeLoaded=a.$on("GroupTreeLoaded",function(b,c,e){var f,g;f=angular.element(document.getElementById("breadcrumbs")),f.html(q({list:R,mode:"edit"})),d(f)(a),Q.inject(R,{mode:"edit",id:"groups-container",breadCrumbs:!1,searchSize:"col-lg-5 col-md-5 col-sm-5"}),a.groups=e,a.inventory_name=c,a.groups.length>0?(a.selected_tree_id=a.groups[0].id,a.selected_group_id=a.groups[0].group_id,a.groups[0].selected_class="selected",a.groups[0].active_class="active-row",a.selected_group_name=a.groups[0].name):(a.selected_tree_id=null,a.selected_group_id=null),a.show_failures=!1,l({scope:a,inventory_id:a.inventory_id,tree_id:a.selected_tree_id,group_id:a.selected_group_id}),setTimeout(function(){$("#groups_table .name-column").each(function(){var a,b,c,d,e;a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%",$(this).find(".group-name").css({width:e})}),L("#groups_table .group-name a"),L("#hosts_table .host-name a")},2500),M(),g=P("inventoryAutoHelp"),"off"!==g&&a.autoShowGroupHelp&&a.showGroupHelp({autoShow:!0})}),a.removeGroupTreeRefreshed&&a.removeGroupTreeRefreshed(),a.removeGroupTreeRefreshed=a.$on("GroupTreeRefreshed",function(){setTimeout(function(){L("#groups_table .group-name a")},2500),a.showHosts(a.selected_tree_id,a.selected_group_id,!1)}),a.removeGroupDeleteCompleted&&a.removeGroupDeleteCompleted(),a.removeGroupDeleteCompleted=a.$on("GroupDeleteCompleted",function(){a.selected_tree_id=1,a.selected_group_id=null,i({scope:a,inventory_id:a.inventory_id,refresh:!0})}),a.removeCopMoveGroup&&a.removeCopyMoveGroup(),a.removeCopyMoveGroup=a.$on("CopyMoveGroup",function(b,c,d){G({scope:a,target_tree_id:d,inbound_tree_id:c})}),a.removeCopMoveHost&&a.removeCopyMoveHost(),a.removeCopyMoveHost=a.$on("CopyMoveHost",function(b,c,d){H({scope:a,target_tree_id:c,host_id:d})}),a.showHosts=function(b,c,d){if(null!==b){j("start"),a.selected_tree_id=b,a.selected_group_id=c,a.hosts=[],a.show_failures=d;for(var e=0;e"+c.name+". Use the Refresh button to monitor the status.","alert-info"):(j("start"),t.setUrl(c.related.inventory_source),t.get().success(function(b){v({scope:a,url:b.related.update,group_name:b.summary_fields.group.name,group_source:b.source,tree_id:c.id,group_id:c.group_id})}).error(function(b,d){j("stop"),u(a,b,d,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+c.related.inventory_source+" POST returned status: "+d})}))))},a.cancelUpdate=function(b){z({scope:a,tree_id:b})},a.toggle=function(b){x({scope:a,list:R,id:b})},a.refreshGroups=function(b,c){b&&(a.selected_tree_id=b,a.selected_group_id=c),i({scope:a,inventory_id:a.inventory_id,refresh:!0})},a.viewUpdateStatus=function(b,c){y({scope:a,tree_id:b,group_id:c})},a.deleteGroup=function(b,c){p({scope:a,tree_id:b,group_id:c,inventory_id:a.inventory_id})},a.createHost=function(){B({scope:a})},a.editInventoryProperties=function(){C({scope:a,inventory_id:a.inventory_id})},a.editHost=function(b){D({scope:a,host_id:b,inventory_id:a.inventory_id})},a.deleteHost=function(b,c){E({scope:a,host_id:b,host_name:c})},a.toggleHostEnabled=function(b,c){F({scope:a,host_id:b,external_source:c})},a.showGroupActivity=function(){var b,c,d;a.selected_group_id?(d=A({list:a.groups,key:"id",val:a.selected_tree_id}),b=J("activity_stream")+"?group__id="+a.selected_group_id,c="Showing all activities for group "+d.name):(c="Showing all activities for all "+a.inventory_name+" groups",b=J("activity_stream")+"?group__inventory__id="+a.inventory_id),I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showHostActivity=function(){var b,c;c="Showing all activities for all "+a.inventory_name+" hosts",b=J("activity_stream")+"?host__inventory__id="+a.inventory_id,I({scope:a,inventory_name:a.inventory_name,url:b,title:c})},a.showJobSummary=function(a){K({job_id:a})},a.showGroupHelp=function(a){var b={defn:O};a&&(b.autoShow=a.autoShow||!1),N(b)},i({scope:a,inventory_id:a.inventory_id,refresh:!1})}function JobEventsList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){function y(a){var b,c,d,e,f,g="",h=!1;if(a.res){if("string"==typeof a.res)c=a.res.match(/\n/g),d=c?c.length:1,d=d>10?10:d,h=!0,g+='
        \n',g+="\n",g+='\n",g+="
        \n";else for(e in a.res){if(("msg"===e||"stdout"===e||"stderr"===e)&&null!==a.res[e]&&""!==a.res[e]){switch(g+='
        \n',g+="\n",c=a.res[e].match(/\n/g),d=c?c.length:1,d=d>10?10:d,g+='\n",g+="
        \n",h=!0}if("results"===e&&Array.isArray(a.res[e])&&a.res[e].length>0){for(f="",b=0;b10?10:d,""!==f&&(g+='
        \n',g+="\n",g+='\n",g+="
        \n",h=!0)}"rc"===e&&""!==a.res[e]&&(g+='
        \n',g+="\n",g+='\n',g+="
        \n",h=!0)}g=h?'
        \n'+g+"
        \n":""}return g=a.hosts?''+a.host+"\n"+g:""===g?null:g}p();var z,A=i,B=r("jobs")+f.id+"/job_events/",C=j;C.inject(A,{mode:"edit",scope:b}),A.base=d.path(),b.job_id=f.id,c.flashMessage=null,b.selected=[],b.expand=!0,b.parentNode="parent-event",b.childNode="child-event",b.removeSetHostLinks&&b.removeSetHostLinks(),b.removeSetHostLinks=b.$on("SetHostLinks",function(a,c){for(var d=0;d15?5:g,$('textarea[name="'+d+'"]').attr("rows",g)));break;case"module_name":case"module_args":b.event_data.res&&b.event_data.res.invocation&&(a[d]=b.event_data.res.invocation.fld)}q("stop")}).error(function(b){k(a,b,status,null,{hdr:"Error!",msg:"Failed to retrieve host: "+f.event_id+". GET status: "+status})}),a.navigateBack=function(){var a="/jobs/"+f.job_id+"/job_events";f.page&&(a+="?page="+f.page),d.url(a)},a.rawView=function(){p({event_id:a.id})}}function JobHostSummaryList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){o();var u=h,v=c.path().replace(/^\//,"").split("/")[0],w=q(v)+e.id+"/job_host_summaries/",x=i,y=x.inject(u,{mode:"edit"});u.index="hosts"===v?!1:!0,a.selected=[],"hosts"===v?(a.job_id=null,a.host_id=e.id):(a.job_id=e.id,a.host_id=null),a.RemoveSetHostLink&&a.RemoveSetHostLink(),a.RemoveSetHostLink=a.$on("setHostLink",function(b,c){for(var d=0;d0?a.jobhosts[0].summary_fields.host.name:"Host"}),e.inventory&&a.$emit("setHostLink",e.inventory))}),l({scope:y,set:"jobhosts",list:u,url:w}),m({scope:y,list:u,url:w}),e.host_name&&(y[u.iterator+"SearchField"]="host",y[u.iterator+"SearchValue"]=e.host_name,y[u.iterator+"SearchFieldLabel"]=u.fields.host.label),a.search(u.iterator),a.showEvents=function(a,b){f.setUrl(b),f.get().success(function(b){j({path:"/jobs/"+b.id,title:b.name}),c.url("/jobs/"+b.id+"/job_events/?host="+encodeURI(a))}).error(function(a,c){p(y,a,c,null,{hdr:"Error!",msg:"Failed to lookup last job: "+b+". GET status: "+c})})},a.showJob=function(a){c.path("/jobs/"+a)},a.refresh=function(){null===a.host_id&&(a.jobSearchSpin=!0,a.jobLoading=!0,t("start"),r({scope:y,set:"jobhosts",iterator:"jobhost",url:a.current_url}))}}function JobTemplatesList(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){o();var y=h,z=q("job_templates"),A=i,B=c.path().replace(/^\//,"").split("/")[0],C="job_templates"===B?"edit":"select";A.inject(y,{mode:C,scope:a}),b.flashMessage=null,a.removePostRefresh&&a.removePostRefresh(),a.removePostRefresh=a.$on("PostRefresh",function(){w("stop"),$("#prompt-modal").off()}),l({scope:a,set:"job_templates",list:y,url:z}),m({scope:a,list:y,url:z}),e.name&&(a[y.iterator+"SearchField"]="name",a[y.iterator+"SearchValue"]=e.name,a[y.iterator+"SearchFieldLabel"]=y.fields.name.label),a.search(y.iterator),j(),a.showActivity=function(){x({scope:a})},a.addJobTemplate=function(){c.path(c.path()+"/add")},a.editJobTemplate=function(a){c.path(c.path()+"/"+a)},a.deleteJobTemplate=function(b,c){var d=function(){$("#prompt-modal").on("hidden.bs.modal",function(){w("start")}),$("#prompt-modal").modal("hide");var c=z+b+"/";f.setUrl(c),f.destroy().success(function(){a.search(y.iterator)}).error(function(b){w("stop"),p(a,b,status,null,{hdr:"Error!",msg:"Call to "+c+" failed. DELETE returned status: "+status})})};k({hdr:"Delete",body:"Are you sure you want to delete "+c+"?",action:d})},a.submitJob=function(b){v({scope:a,id:b})}}function JobTemplatesAdd(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){n();var x,y,z=o("job_templates"),A=g,B=h,C={},D={};B.inject(A,{mode:"add",related:!1,scope:a}),a.parseType="yaml",u(a),a.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],a.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],a.playbook_options=[],a.allow_callbacks="false",B.reset(),l(),t({scope:a,master:C,check_field:"allow_callbacks",default_val:!1}),s({scope:a,form:A,current_item:null,list:p,field:"inventory"}),jQuery.extend(!0,D,q),D.name="cloudcredentials",D.iterator="cloudcredential",s({url:o("credentials")+"?cloud=true",scope:a,form:A,current_item:null,list:D,field:"cloud_credential",hdr:"Select Cloud Credential"}),s({url:o("credentials")+"?kind=ssh",scope:a,form:A,current_item:null,list:q,field:"credential",hdr:"Select Machine Credential"}),x=function(b,c){var d;b!==c&&a.project&&(v("start"),d=o("projects")+a.project+"/playbooks/",i.setUrl(d),i.get().success(function(b){var c,d=[];for(c=0;c=2)for(var b in N)a.search(N[b].iterator)}),a.removeRelatedJobs&&a.removeRelatedJobs(),a.removeRelatedJobs=a.$on("relatedjobs",function(){var b,c;if(a.jobs&&a.jobs.length)for(b=0;b0)for(d=0;d/g," ");for(y in z.fields.status.searchOptions)if(z.fields.status.searchOptions[y].value===e.status){a[z.iterator+"SearchSelectValue"]=z.fields.status.searchOptions[y];break}}a.search(z.iterator),j(),a.refresh=function(){x("start"),a.jobLoading=!1,u({scope:a,set:"jobs",iterator:"job",url:a.current_url})},a.refreshJob=a.refresh,a.editJob=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a)},a.viewEvents=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_events")},a.viewSummary=function(a,b){j({path:"/jobs/"+a,title:a+" - "+b}),c.path(c.path()+"/"+a+"/job_host_summaries")},a.deleteJob=function(b){f.setUrl(A+b+"/"),f.get().success(function(c){var d,e,g,h;"pending"===c.status||"running"===c.status||"waiting"===c.status?(e=c.related.cancel,g="cancel",h="Cancel Job"):(e=A+b+"/",g="delete",h="Delete Job"),d=function(){f.setUrl(e),"cancel"===g?f.post().success(function(){$("#prompt-modal").modal("hide"),a.search(z.iterator)}).error(function(b,c){$("#prompt-modal").modal("hide"),p(a,b,c,null,{hdr:"Error!",msg:"Call to "+e+" failed. POST returned status: "+c})}):f.destroy().success(function(){$("#prompt-modal").modal("hide"),a.search(z.iterator)}).error(function(b,c){$("#prompt-modal").modal("hide"),p(a,b,c,null,{hdr:"Error!",msg:"Call to "+e+" failed. DELETE returned status: "+c})})},k({hdr:h,body:"Are you sure you want to "+g+" job "+b+"?",action:d})}).error(function(b,c){p(a,b,c,null,{hdr:"Error!",msg:"Failed to get job details. GET returned status: "+c})})},a.submitJob=function(b,c){s({scope:a,id:b,template:c})}}function JobsEdit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z){function A(b){if(null!==b&&""!==b&&void 0!==b){var c=v("projects")+b+"/playbooks/";i.setUrl(c),i.get().success(function(b){a.playbook_options=[];for(var c=0;c15?15:c}p();var C=v("jobs"),D=h,E=g,F={},G=f.id,H={},I=0;D.inject(E,{mode:"edit",related:!0,scope:a}),D.reset(),a.job_id=G,a.parseType="yaml",a.statusSearchSpin=!1,a.jobLoadedRemove&&a.jobLoadedRemove(),a.jobLoadedRemove=a.$on("jobLoaded",function(b,c){A(a.project),a[E.name+"ReadOnly"]="new"===a.status?!1:!0,$("#forks-slider").slider("option","value",a.forks),$("#forks-slider").slider("disable"),$('input[type="checkbox"]').attr("disabled","disabled"),$('input[type="radio"]').attr("disabled","disabled"),$("#host_config_key-gen-btn").attr("disabled","disabled"),$("textarea").attr("readonly","readonly"),i.setUrl(a.template_url),i.get().success(function(b){var c=b.host_config_key?"true":"false";a.host_config_key=b.host_config_key,w({scope:a,master:F,check_field:"allow_callbacks",default_val:c}),a.callback_url=b.related?b.related.callback:"<< Job template not found >>",a.$emit("jobTemplateLoadFinished")}).error(function(){z("stop"),a.callback_url="<< Job template not found >>"}),c?(i.setUrl(c),i.get().success(function(b){a.cloud_credential_name=b.name,a.$emit("jobTemplateLoadFinished")}).error(function(b,c){k(a,b,c,null,{hdr:"Error!",msg:"Failed to related cloud credential. GET returned status: "+c})})):a.$emit("jobTemplateLoadFinished")}),a.removeJobTemplateLoadFinished&&a.removeJobTemplateLoadFinished(),a.removeJobTemplateLoadFinished=a.$on("jobTemplateLoadFinished",function(){I++,I>=3&&z("stop")}),a.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}],a.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}],a.playbook_options=null,a.playbook=null,z("start"),i.setUrl(C+":id/"),i.get({params:{id:G}}).success(function(b){var c,d,e,f,g,h;l();for(e in E.fields){if("variables"!==e&&null!==b[e]&&void 0!==b[e]){if("select"===E.fields[e].type)if(a[e+"_options"]&&a[e+"_options"].length>0)for(c=0;c/g," ");for(b in A.fields.scm_type.searchOptions)if(A.fields.scm_type.searchOptions[b].value===e.scm_type){a[A.iterator+"SearchSelectValue"]=A.fields.scm_type.searchOptions[b];break}}else if(e.status){a[A.iterator+"SearchValue"]=e.status,a[A.iterator+"SearchField"]="status",a[A.iterator+"SelectShow"]=!0,a[A.iterator+"SearchFieldLabel"]=A.fields.status.label,a[A.iterator+"SearchSelectOpts"]=A.fields.status.searchOptions;for(b in A.fields.status.searchOptions)if(A.fields.status.searchOptions[b].value===e.status){a[A.iterator+"SearchSelectValue"]=A.fields.status.searchOptions[b];break}}a.search(A.iterator)}),a.removeChoicesReady&&a.removeChoicesReady(),a.removeChoicesReady=a.$on("choicesReadyProject",function(){G++,2===G&&a.$emit("choicesCompleteProject")}),y({scope:a,url:B,field:"status",variable:"project_status_options",callback:"choicesReadyProject"}),y({scope:a,url:B,field:"scm_type",variable:"project_scm_type_options",callback:"choicesReadyProject"}),j(),a.showActivity=function(){x({scope:a})},a.addProject=function(){c.path(c.path()+"/add")},a.editProject=function(a){c.path(c.path()+"/"+a)},a.showSCMStatus=function(b){var c,d=a.$on("PostRefresh",function(){var e;for(c=0;cRefresh button to view the latest status.","alert-info")}).error(function(b,c){p(a,b,c,null,{hdr:"Error!",msg:"Call to "+d+" failed. GET status: "+c})})}),a.cancelUpdate=function(b,c){var d,e,h=!1;for(d=0;dRefresh button to view the latet status.","alert-info")},a.refresh=function(){w("start"),a.projectLoading=!1,v({scope:a,set:"projects",iterator:"project",url:a.current_url})},a.SCMUpdate=function(b){var c;for(c=0;cb;b++){for(d[b].match(/[A-Z]/g)?(""!==R&&R+1==b&&(y++,C++),R=b,o++):d[b].match(/[a-z]/g)?(""!==S&&S+1==b&&(z++,C++),S=b,p++):d[b].match(/[0-9]/g)?(b>0&&e-1>b&&s++,""!==T&&T+1==b&&(A++,C++),T=b,q++):d[b].match(/[^a-zA-Z0-9_]/g)&&(b>0&&e-1>b&&s++,""!==U&&U+1==b&&(B++,C++),U=b,r++),f=!1,g=0;e>g;g++)d[b]==d[g]&&b!=g&&(f=!0,x+=Math.abs(e/(g-b)));f&&(w++,v=e-w,x=Math.ceil(v?x/v:x))}for(h=0;23>h;h++)i=ib.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(D++,G++);for(h=0;8>h;h++)i=jb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(E++,G++);for(h=0;8>h;h++)i=kb.substring(h,parseInt(h+3)),j=i.strReverse(),(-1!=a.toLowerCase().indexOf(i)||-1!=a.toLowerCase().indexOf(j))&&(F++,G++);o>0&&n>o&&(nScore=parseInt(nScore+2*(n-o)),V="+ "+parseInt(2*(n-o))),p>0&&n>p&&(nScore=parseInt(nScore+2*(n-p)),W="+ "+parseInt(2*(n-p))),q>0&&n>q&&(nScore=parseInt(nScore+q*P),X="+ "+parseInt(q*P)),r>0&&(nScore=parseInt(nScore+r*Q),Y="+ "+parseInt(r*Q)),s>0&&(nScore=parseInt(nScore+s*H),Z="+ "+parseInt(s*H)),(p>0||o>0)&&0===r&&0===q&&(nScore=parseInt(nScore-n),t=n,_="- "+n),0===p&&0===o&&0===r&&q>0&&(nScore=parseInt(nScore-n),u=n,ab="- "+n),w>0&&(nScore=parseInt(nScore-x),bb="- "+x),y>0&&(nScore=parseInt(nScore-y*I),cb="- "+parseInt(y*I)),z>0&&(nScore=parseInt(nScore-z*J),db="- "+parseInt(z*J)),A>0&&(nScore=parseInt(nScore-A*K),eb="- "+parseInt(A*K)),D>0&&(nScore=parseInt(nScore-D*L),fb="- "+parseInt(D*L)),E>0&&(nScore=parseInt(nScore-E*M),gb="- "+parseInt(E*M)),F>0&&(nScore=parseInt(nScore-F*N),hb="- "+parseInt(F*N)),nScore>100?nScore=100:0>nScore&&(nScore=0),k=$("#progbar"),l=$AnsibleConfig.password_strength,m=$AnsibleConfig.password_strength-15<0?0:$AnsibleConfig.password_strength-15,k.css("width",nScore+"%"),nScore>=0&&m>=nScore?(lb="Weak",k.addClass("progress-bar-danger"),k.removeClass("progress-bar-success progress-bar-warning")):nScore>m&&l>=nScore?(lb="Good",k.addClass("progress-bar-warning"),k.removeClass("progress-bar-success progress-bar-danger")):nScore>l&&(lb="Strong",k.addClass("progress-bar-success"),k.removeClass("progress-bar-warning progress-bar-danger"))}else k=$("#progbar"),k.css("width","0%"),k.removeClass("progress-bar-success progress-bar-warning");return nScore}var urlPrefix=$basePath;angular.module("ansible",["ngRoute","ngSanitize","ngCookies","RestServices","AuthService","Utilities","OrganizationFormDefinition","UserFormDefinition","FormGenerator","OrganizationListDefinition","UserListDefinition","UserHelper","ListGenerator","PromptDialog","ApiLoader","RelatedSearchHelper","SearchHelper","PaginationHelpers","RefreshHelper","AdminListDefinition","AWDirectives","InventoriesListDefinition","InventoryFormDefinition","InventoryHelper","InventoryGroupsDefinition","InventoryHostsDefinition","HostsHelper","AWFilters","HostFormDefinition","HostListDefinition","GroupFormDefinition","GroupListDefinition","GroupsHelper","TeamsListDefinition","TeamFormDefinition","TeamHelper","CredentialsListDefinition","CredentialFormDefinition","LookUpHelper","JobTemplatesListDefinition","JobTemplateFormDefinition","JobSubmissionHelper","ProjectsListDefinition","ProjectFormDefinition","ProjectStatusDefinition","ProjectsHelper","PermissionFormDefinition","PermissionListDefinition","PermissionsHelper","JobsListDefinition","JobFormDefinition","JobEventsListDefinition","JobEventDataDefinition","JobEventsFormDefinition","JobHostDefinition","JobSummaryDefinition","ParseHelper","ChildrenHelper","EventsHelper","ProjectPathHelper","md5Helper","AccessHelper","SelectionHelper","License","HostGroupsFormDefinition","JobStatusWidget","InventorySyncStatusWidget","SCMSyncStatusWidget","ObjectCountWidget","StreamWidget","JobsHelper","InventoryGroupsHelpDefinition","InventoryTree","CredentialsHelper","TimerService","StreamListDefinition","HomeGroupListDefinition","HomeHostListDefinition","ActivityDetailDefinition"]).config(["$routeProvider",function(a){a.when("/jobs",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsListCtrl"}).when("/jobs/:id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsEdit"}).when("/jobs/:id/job_events",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsList"}).when("/jobs/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/jobs/:job_id/job_events/:event_id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsEdit"}).when("/job_templates",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesList"}).when("/job_templates/add",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesAdd"}).when("/job_templates/:id",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesEdit"}).when("/projects",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsList"}).when("/projects/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsAdd"}).when("/projects/:id",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsEdit"}).when("/projects/:project_id/organizations",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsList"}).when("/projects/:project_id/organizations/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsAdd"}).when("/hosts/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/inventories",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesList"}).when("/inventories/add",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesAdd"}).when("/inventories/:inventory_id",{templateUrl:urlPrefix+"partials/inventory-edit.html",controller:"InventoriesEdit"}).when("/organizations",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsList"}).when("/organizations/add",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsAdd"}).when("/organizations/:organization_id",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsEdit"}).when("/organizations/:organization_id/admins",{templateUrl:urlPrefix+"partials/organizations.html",controller:"AdminsList"}).when("/organizations/:organization_id/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/organizations/:organization_id/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/organizations/:organization_id/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/teams",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsList"}).when("/teams/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsAdd"}).when("/teams/:team_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsEdit"}).when("/teams/:team_id/permissions/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsAdd"}).when("/teams/:team_id/permissions",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsList"}).when("/teams/:team_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsEdit"}).when("/teams/:team_id/users",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersList"}).when("/teams/:team_id/users/:user_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersEdit"}).when("/teams/:team_id/projects",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsList"}).when("/teams/:team_id/projects/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsAdd"}).when("/teams/:team_id/projects/:project_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsEdit"}).when("/teams/:team_id/credentials",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsList"}).when("/teams/:team_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:team_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/credentials",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsList"}).when("/credentials/add",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsAdd"}).when("/credentials/:credential_id",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsEdit"}).when("/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/users/:user_id/credentials",{templateUrl:urlPrefix+"partials/users.html",controller:"CredentialsList"}).when("/users/:user_id/permissions/add",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsAdd"}).when("/users/:user_id/permissions",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsList"}).when("/users/:user_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsEdit"}).when("/users/:user_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:user_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/login",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/logout",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/home",{templateUrl:urlPrefix+"partials/home.html",controller:"Home"}).when("/home/groups",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeGroups"}).when("/home/hosts",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeHosts"}).otherwise({redirectTo:"/home"})}]).run(["$cookieStore","$rootScope","CheckLicense","$location","Authorization","LoadBasePaths","ViewLicense","Timer","ClearScope","HideStream",function(a,b,c,d,e,f,g,h,i,j){f(),b.breadcrumbs=[],b.crumbCache=[],b.sessionTimer=h.init(),b.$on("$routeChangeStart",function(f,g){$("#stream-container").is(":visible")&&j(),/^\/(login|logout)/.test(d.path())||(b.lastPath=d.path(),a.put("lastPath",d.path())),e.isUserLoggedIn()===!1?g.templateUrl!==urlPrefix+"partials/login.html"&&d.path("/login"):b.sessionTimer.isExpired()?g.templateUrl!==urlPrefix+"partials/login.html"&&(b.sessionTimer.expireSession(),d.path("/login")):((void 0===b.current_user||null===b.current_user)&&e.restoreUserInfo(),c());var h=d.path().replace(/^\//,"").split("/")[0];""===h?h="home":h.replace(/\_/g," "),$('.nav-tabs a[href="#'+h+'"]').tab("show")}),e.getToken()?b.user_is_superuser=e.getUserInfo("is_superuser"):(b.sessionExpired=!1,a.put("sessionExpired",!1),d.path("/login"));var k=d.path().replace(/^\//,"").split("/")[0];""===k?(k="home",d.path("/home")):k.replace(/\_/g," "),$('.nav-tabs a[href="#'+k+'"]').tab("show"),b.viewCurrentUser=function(){d.path("/users/"+b.current_user.id)},b.viewLicense=function(){g()}}]);var urlPrefix=$basePath;angular.module("ansible",["RestServices","AuthService","Utilities","OrganizationFormDefinition","UserFormDefinition","FormGenerator","OrganizationListDefinition","UserListDefinition","UserHelper","ListGenerator","PromptDialog","ApiLoader","RelatedSearchHelper","SearchHelper","PaginationHelpers","RefreshHelper","AdminListDefinition","AWDirectives","InventoriesListDefinition","InventoryFormDefinition","InventoryHelper","InventoryGroupsDefinition","InventoryHostsDefinition","HostsHelper","AWFilters","HostFormDefinition","HostListDefinition","GroupFormDefinition","GroupListDefinition","GroupsHelper","TeamsListDefinition","TeamFormDefinition","TeamHelper","CredentialsListDefinition","CredentialFormDefinition","LookUpHelper","JobTemplatesListDefinition","JobTemplateFormDefinition","JobSubmissionHelper","ProjectsListDefinition","ProjectFormDefinition","ProjectStatusDefinition","ProjectsHelper","PermissionFormDefinition","PermissionListDefinition","PermissionsHelper","JobsListDefinition","JobFormDefinition","JobEventsListDefinition","JobEventDataDefinition","JobEventsFormDefinition","JobHostDefinition","JobSummaryDefinition","ParseHelper","ChildrenHelper","EventsHelper","ProjectPathHelper","md5Helper","AccessHelper","SelectionHelper","License","HostGroupsFormDefinition","JobStatusWidget","InventorySyncStatusWidget","SCMSyncStatusWidget","ObjectCountWidget","StreamWidget","JobsHelper","InventoryGroupsHelpDefinition","InventoryTree","CredentialsHelper","TimerService","StreamListDefinition","HomeGroupListDefinition","HomeHostListDefinition","ActivityDetailDefinition"]).config(["$routeProvider",function(a){a.when("/jobs",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsListCtrl"}).when("/jobs/:id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsEdit"}).when("/jobs/:id/job_events",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsList"}).when("/jobs/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/jobs/:job_id/job_events/:event_id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsEdit"}).when("/job_templates",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesList"}).when("/job_templates/add",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesAdd"}).when("/job_templates/:id",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesEdit"}).when("/projects",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsList"}).when("/projects/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsAdd"}).when("/projects/:id",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsEdit"}).when("/projects/:project_id/organizations",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsList"}).when("/projects/:project_id/organizations/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsAdd"}).when("/hosts/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/inventories",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesList"}).when("/inventories/add",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesAdd"}).when("/inventories/:inventory_id",{templateUrl:urlPrefix+"partials/inventory-edit.html",controller:"InventoriesEdit"}).when("/organizations",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsList"}).when("/organizations/add",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsAdd"}).when("/organizations/:organization_id",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsEdit"}).when("/organizations/:organization_id/admins",{templateUrl:urlPrefix+"partials/organizations.html",controller:"AdminsList"}).when("/organizations/:organization_id/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/organizations/:organization_id/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/organizations/:organization_id/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/teams",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsList"}).when("/teams/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsAdd"}).when("/teams/:team_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsEdit"}).when("/teams/:team_id/permissions/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsAdd"}).when("/teams/:team_id/permissions",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsList"}).when("/teams/:team_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsEdit"}).when("/teams/:team_id/users",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersList"}).when("/teams/:team_id/users/:user_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersEdit"}).when("/teams/:team_id/projects",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsList"}).when("/teams/:team_id/projects/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsAdd"}).when("/teams/:team_id/projects/:project_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsEdit"}).when("/teams/:team_id/credentials",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsList"}).when("/teams/:team_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:team_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/credentials",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsList"}).when("/credentials/add",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsAdd"}).when("/credentials/:credential_id",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsEdit"}).when("/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/users/:user_id/credentials",{templateUrl:urlPrefix+"partials/users.html",controller:"CredentialsList"}).when("/users/:user_id/permissions/add",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsAdd"}).when("/users/:user_id/permissions",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsList"}).when("/users/:user_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsEdit"}).when("/users/:user_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:user_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/login",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/logout",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/home",{templateUrl:urlPrefix+"partials/home.html",controller:"Home"}).when("/home/groups",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeGroups"}).when("/home/hosts",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeHosts"}).otherwise({redirectTo:"/home"})}]).run(["$cookieStore","$rootScope","CheckLicense","$location","Authorization","LoadBasePaths","ViewLicense","Timer","ClearScope","HideStream",function(a,b,c,d,e,f,g,h,i,j){f(),b.breadcrumbs=[],b.crumbCache=[],b.sessionTimer=h.init(),b.$on("$routeChangeStart",function(f,g){$("#stream-container").is(":visible")&&j(),/^\/(login|logout)/.test(d.path())||(b.lastPath=d.path(),a.put("lastPath",d.path())),e.isUserLoggedIn()===!1?g.templateUrl!==urlPrefix+"partials/login.html"&&d.path("/login"):b.sessionTimer.isExpired()?g.templateUrl!==urlPrefix+"partials/login.html"&&(b.sessionTimer.expireSession(),d.path("/login")):((void 0===b.current_user||null===b.current_user)&&e.restoreUserInfo(),c());var h=d.path().replace(/^\//,"").split("/")[0];""===h?h="home":h.replace(/\_/g," "),$('.nav-tabs a[href="#'+h+'"]').tab("show")}),e.getToken()?b.user_is_superuser=e.getUserInfo("is_superuser"):(b.sessionExpired=!1,a.put("sessionExpired",!1),d.path("/login")); +var k=d.path().replace(/^\//,"").split("/")[0];""===k?(k="home",d.path("/home")):k.replace(/\_/g," "),$('.nav-tabs a[href="#'+k+'"]').tab("show"),b.viewCurrentUser=function(){d.path("/users/"+b.current_user.id)},b.viewLicense=function(){g()}}]);var urlPrefix=$basePath;angular.module("ansible",["RestServices","AuthService","Utilities","OrganizationFormDefinition","UserFormDefinition","FormGenerator","OrganizationListDefinition","UserListDefinition","UserHelper","ListGenerator","PromptDialog","ApiLoader","RelatedSearchHelper","SearchHelper","PaginationHelpers","RefreshHelper","AdminListDefinition","AWDirectives","InventoriesListDefinition","InventoryFormDefinition","InventoryHelper","InventoryGroupsDefinition","InventoryHostsDefinition","HostsHelper","AWFilters","HostFormDefinition","HostListDefinition","GroupFormDefinition","GroupListDefinition","GroupsHelper","TeamsListDefinition","TeamFormDefinition","TeamHelper","CredentialsListDefinition","CredentialFormDefinition","LookUpHelper","JobTemplatesListDefinition","JobTemplateFormDefinition","JobSubmissionHelper","ProjectsListDefinition","ProjectFormDefinition","ProjectStatusDefinition","ProjectsHelper","PermissionFormDefinition","PermissionListDefinition","PermissionsHelper","JobsListDefinition","JobFormDefinition","JobEventsListDefinition","JobEventDataDefinition","JobEventsFormDefinition","JobHostDefinition","JobSummaryDefinition","ParseHelper","ChildrenHelper","EventsHelper","ProjectPathHelper","md5Helper","AccessHelper","SelectionHelper","License","HostGroupsFormDefinition","JobStatusWidget","InventorySyncStatusWidget","SCMSyncStatusWidget","ObjectCountWidget","StreamWidget","JobsHelper","InventoryGroupsHelpDefinition","InventoryTree","CredentialsHelper","TimerService","StreamListDefinition","HomeGroupListDefinition","HomeHostListDefinition","ActivityDetailDefinition"]).config(["$routeProvider",function(a){a.when("/jobs",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsListCtrl"}).when("/jobs/:id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsEdit"}).when("/jobs/:id/job_events",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsList"}).when("/jobs/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/jobs/:job_id/job_events/:event_id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsEdit"}).when("/job_templates",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesList"}).when("/job_templates/add",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesAdd"}).when("/job_templates/:id",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesEdit"}).when("/projects",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsList"}).when("/projects/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsAdd"}).when("/projects/:id",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsEdit"}).when("/projects/:project_id/organizations",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsList"}).when("/projects/:project_id/organizations/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsAdd"}).when("/hosts/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/inventories",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesList"}).when("/inventories/add",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesAdd"}).when("/inventories/:inventory_id",{templateUrl:urlPrefix+"partials/inventory-edit.html",controller:"InventoriesEdit"}).when("/organizations",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsList"}).when("/organizations/add",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsAdd"}).when("/organizations/:organization_id",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsEdit"}).when("/organizations/:organization_id/admins",{templateUrl:urlPrefix+"partials/organizations.html",controller:"AdminsList"}).when("/organizations/:organization_id/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/organizations/:organization_id/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/organizations/:organization_id/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/teams",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsList"}).when("/teams/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsAdd"}).when("/teams/:team_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsEdit"}).when("/teams/:team_id/permissions/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsAdd"}).when("/teams/:team_id/permissions",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsList"}).when("/teams/:team_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsEdit"}).when("/teams/:team_id/users",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersList"}).when("/teams/:team_id/users/:user_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersEdit"}).when("/teams/:team_id/projects",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsList"}).when("/teams/:team_id/projects/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsAdd"}).when("/teams/:team_id/projects/:project_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsEdit"}).when("/teams/:team_id/credentials",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsList"}).when("/teams/:team_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:team_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/credentials",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsList"}).when("/credentials/add",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsAdd"}).when("/credentials/:credential_id",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsEdit"}).when("/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/users/:user_id/credentials",{templateUrl:urlPrefix+"partials/users.html",controller:"CredentialsList"}).when("/users/:user_id/permissions/add",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsAdd"}).when("/users/:user_id/permissions",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsList"}).when("/users/:user_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsEdit"}).when("/users/:user_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:user_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/login",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/logout",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/home",{templateUrl:urlPrefix+"partials/home.html",controller:"Home"}).when("/home/groups",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeGroups"}).when("/home/hosts",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeHosts"}).otherwise({redirectTo:"/home"})}]).run(["$cookieStore","$rootScope","CheckLicense","$location","Authorization","LoadBasePaths","ViewLicense","Timer","ClearScope","HideStream",function(a,b,c,d,e,f,g,h,i,j){f(),b.breadcrumbs=[],b.crumbCache=[],b.sessionTimer=h.init(),b.$on("$routeChangeStart",function(f,g){$("#stream-container").is(":visible")&&j(),/^\/(login|logout)/.test(d.path())||(b.lastPath=d.path(),a.put("lastPath",d.path())),e.isUserLoggedIn()===!1?g.templateUrl!==urlPrefix+"partials/login.html"&&d.path("/login"):b.sessionTimer.isExpired()?g.templateUrl!==urlPrefix+"partials/login.html"&&(b.sessionTimer.expireSession(),d.path("/login")):((void 0===b.current_user||null===b.current_user)&&e.restoreUserInfo(),c());var h=d.path().replace(/^\//,"").split("/")[0];""===h?h="home":h.replace(/\_/g," "),$('.nav-tabs a[href="#'+h+'"]').tab("show")}),e.getToken()?b.user_is_superuser=e.getUserInfo("is_superuser"):(b.sessionExpired=!1,a.put("sessionExpired",!1),d.path("/login"));var k=d.path().replace(/^\//,"").split("/")[0];""===k?(k="home",d.path("/home")):k.replace(/\_/g," "),$('.nav-tabs a[href="#'+k+'"]').tab("show"),b.viewCurrentUser=function(){d.path("/users/"+b.current_user.id)},b.viewLicense=function(){g()}}]);var urlPrefix=$basePath;angular.module("ansible",["RestServices","AuthService","Utilities","OrganizationFormDefinition","UserFormDefinition","FormGenerator","OrganizationListDefinition","UserListDefinition","UserHelper","ListGenerator","PromptDialog","ApiLoader","RelatedSearchHelper","SearchHelper","PaginationHelpers","RefreshHelper","AdminListDefinition","AWDirectives","InventoriesListDefinition","InventoryFormDefinition","InventoryHelper","InventoryGroupsDefinition","InventoryHostsDefinition","HostsHelper","AWFilters","HostFormDefinition","HostListDefinition","GroupFormDefinition","GroupListDefinition","GroupsHelper","TeamsListDefinition","TeamFormDefinition","TeamHelper","CredentialsListDefinition","CredentialFormDefinition","LookUpHelper","JobTemplatesListDefinition","JobTemplateFormDefinition","JobSubmissionHelper","ProjectsListDefinition","ProjectFormDefinition","ProjectStatusDefinition","ProjectsHelper","PermissionFormDefinition","PermissionListDefinition","PermissionsHelper","JobsListDefinition","JobFormDefinition","JobEventsListDefinition","JobEventDataDefinition","JobEventsFormDefinition","JobHostDefinition","JobSummaryDefinition","ParseHelper","ChildrenHelper","EventsHelper","ProjectPathHelper","md5Helper","AccessHelper","SelectionHelper","License","HostGroupsFormDefinition","JobStatusWidget","InventorySyncStatusWidget","SCMSyncStatusWidget","ObjectCountWidget","StreamWidget","JobsHelper","InventoryGroupsHelpDefinition","InventoryTree","CredentialsHelper","TimerService","StreamListDefinition","HomeGroupListDefinition","HomeHostListDefinition","ActivityDetailDefinition"]).config(["$routeProvider",function(a){a.when("/jobs",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsListCtrl"}).when("/jobs/:id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsEdit"}).when("/jobs/:id/job_events",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsList"}).when("/jobs/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/jobs/:job_id/job_events/:event_id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsEdit"}).when("/job_templates",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesList"}).when("/job_templates/add",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesAdd"}).when("/job_templates/:id",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesEdit"}).when("/projects",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsList"}).when("/projects/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsAdd"}).when("/projects/:id",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsEdit"}).when("/projects/:project_id/organizations",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsList"}).when("/projects/:project_id/organizations/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsAdd"}).when("/hosts/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/inventories",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesList"}).when("/inventories/add",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesAdd"}).when("/inventories/:inventory_id",{templateUrl:urlPrefix+"partials/inventory-edit.html",controller:"InventoriesEdit"}).when("/organizations",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsList"}).when("/organizations/add",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsAdd"}).when("/organizations/:organization_id",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsEdit"}).when("/organizations/:organization_id/admins",{templateUrl:urlPrefix+"partials/organizations.html",controller:"AdminsList"}).when("/organizations/:organization_id/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/organizations/:organization_id/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/organizations/:organization_id/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/teams",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsList"}).when("/teams/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsAdd"}).when("/teams/:team_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsEdit"}).when("/teams/:team_id/permissions/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsAdd"}).when("/teams/:team_id/permissions",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsList"}).when("/teams/:team_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsEdit"}).when("/teams/:team_id/users",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersList"}).when("/teams/:team_id/users/:user_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersEdit"}).when("/teams/:team_id/projects",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsList"}).when("/teams/:team_id/projects/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsAdd"}).when("/teams/:team_id/projects/:project_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsEdit"}).when("/teams/:team_id/credentials",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsList"}).when("/teams/:team_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:team_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/credentials",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsList"}).when("/credentials/add",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsAdd"}).when("/credentials/:credential_id",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsEdit"}).when("/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/users/:user_id/credentials",{templateUrl:urlPrefix+"partials/users.html",controller:"CredentialsList"}).when("/users/:user_id/permissions/add",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsAdd"}).when("/users/:user_id/permissions",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsList"}).when("/users/:user_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsEdit"}).when("/users/:user_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:user_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/login",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/logout",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/home",{templateUrl:urlPrefix+"partials/home.html",controller:"Home"}).when("/home/groups",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeGroups"}).when("/home/hosts",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeHosts"}).otherwise({redirectTo:"/home"})}]).run(["$cookieStore","$rootScope","CheckLicense","$location","Authorization","LoadBasePaths","ViewLicense","Timer","ClearScope","HideStream",function(a,b,c,d,e,f,g,h,i,j){f(),b.breadcrumbs=[],b.crumbCache=[],b.sessionTimer=h.init(),b.$on("$routeChangeStart",function(f,g){$("#stream-container").is(":visible")&&j(),/^\/(login|logout)/.test(d.path())||(b.lastPath=d.path(),a.put("lastPath",d.path())),e.isUserLoggedIn()===!1?g.templateUrl!==urlPrefix+"partials/login.html"&&d.path("/login"):b.sessionTimer.isExpired()?g.templateUrl!==urlPrefix+"partials/login.html"&&(b.sessionTimer.expireSession(),d.path("/login")):((void 0===b.current_user||null===b.current_user)&&e.restoreUserInfo(),c());var h=d.path().replace(/^\//,"").split("/")[0];""===h?h="home":h.replace(/\_/g," "),$('.nav-tabs a[href="#'+h+'"]').tab("show")}),e.getToken()?b.user_is_superuser=e.getUserInfo("is_superuser"):(b.sessionExpired=!1,a.put("sessionExpired",!1),d.path("/login"));var k=d.path().replace(/^\//,"").split("/")[0];""===k?(k="home",d.path("/home")):k.replace(/\_/g," "),$('.nav-tabs a[href="#'+k+'"]').tab("show"),b.viewCurrentUser=function(){d.path("/users/"+b.current_user.id)},b.viewLicense=function(){g()}}]);var urlPrefix=$basePath;angular.module("ansible",["RestServices","AuthService","Utilities","OrganizationFormDefinition","UserFormDefinition","FormGenerator","OrganizationListDefinition","UserListDefinition","UserHelper","ListGenerator","PromptDialog","ApiLoader","RelatedSearchHelper","SearchHelper","PaginationHelpers","RefreshHelper","AdminListDefinition","AWDirectives","InventoriesListDefinition","InventoryFormDefinition","InventoryHelper","InventoryGroupsDefinition","InventoryHostsDefinition","HostsHelper","AWFilters","HostFormDefinition","HostListDefinition","GroupFormDefinition","GroupListDefinition","GroupsHelper","TeamsListDefinition","TeamFormDefinition","TeamHelper","CredentialsListDefinition","CredentialFormDefinition","LookUpHelper","JobTemplatesListDefinition","JobTemplateFormDefinition","JobSubmissionHelper","ProjectsListDefinition","ProjectFormDefinition","ProjectStatusDefinition","ProjectsHelper","PermissionFormDefinition","PermissionListDefinition","PermissionsHelper","JobsListDefinition","JobFormDefinition","JobEventsListDefinition","JobEventDataDefinition","JobEventsFormDefinition","JobHostDefinition","JobSummaryDefinition","ParseHelper","ChildrenHelper","EventsHelper","ProjectPathHelper","md5Helper","AccessHelper","SelectionHelper","License","HostGroupsFormDefinition","JobStatusWidget","InventorySyncStatusWidget","SCMSyncStatusWidget","ObjectCountWidget","StreamWidget","JobsHelper","InventoryGroupsHelpDefinition","InventoryTree","CredentialsHelper","TimerService","StreamListDefinition","HomeGroupListDefinition","HomeHostListDefinition","ActivityDetailDefinition"]).config(["$routeProvider",function(a){a.when("/jobs",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsListCtrl"}).when("/jobs/:id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobsEdit"}).when("/jobs/:id/job_events",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsList"}).when("/jobs/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/jobs/:job_id/job_events/:event_id",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobEventsEdit"}).when("/job_templates",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesList"}).when("/job_templates/add",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesAdd"}).when("/job_templates/:id",{templateUrl:urlPrefix+"partials/job_templates.html",controller:"JobTemplatesEdit"}).when("/projects",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsList"}).when("/projects/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsAdd"}).when("/projects/:id",{templateUrl:urlPrefix+"partials/projects.html",controller:"ProjectsEdit"}).when("/projects/:project_id/organizations",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsList"}).when("/projects/:project_id/organizations/add",{templateUrl:urlPrefix+"partials/projects.html",controller:"OrganizationsAdd"}).when("/hosts/:id/job_host_summaries",{templateUrl:urlPrefix+"partials/jobs.html",controller:"JobHostSummaryList"}).when("/inventories",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesList"}).when("/inventories/add",{templateUrl:urlPrefix+"partials/inventories.html",controller:"InventoriesAdd"}).when("/inventories/:inventory_id",{templateUrl:urlPrefix+"partials/inventory-edit.html",controller:"InventoriesEdit"}).when("/organizations",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsList"}).when("/organizations/add",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsAdd"}).when("/organizations/:organization_id",{templateUrl:urlPrefix+"partials/organizations.html",controller:"OrganizationsEdit"}).when("/organizations/:organization_id/admins",{templateUrl:urlPrefix+"partials/organizations.html",controller:"AdminsList"}).when("/organizations/:organization_id/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/organizations/:organization_id/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/organizations/:organization_id/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/teams",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsList"}).when("/teams/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsAdd"}).when("/teams/:team_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"TeamsEdit"}).when("/teams/:team_id/permissions/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsAdd"}).when("/teams/:team_id/permissions",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsList"}).when("/teams/:team_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"PermissionsEdit"}).when("/teams/:team_id/users",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersList"}).when("/teams/:team_id/users/:user_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"UsersEdit"}).when("/teams/:team_id/projects",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsList"}).when("/teams/:team_id/projects/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsAdd"}).when("/teams/:team_id/projects/:project_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"ProjectsEdit"}).when("/teams/:team_id/credentials",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsList"}).when("/teams/:team_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:team_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/credentials",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsList"}).when("/credentials/add",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsAdd"}).when("/credentials/:credential_id",{templateUrl:urlPrefix+"partials/credentials.html",controller:"CredentialsEdit"}).when("/users",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersList"}).when("/users/add",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersAdd"}).when("/users/:user_id",{templateUrl:urlPrefix+"partials/users.html",controller:"UsersEdit"}).when("/users/:user_id/credentials",{templateUrl:urlPrefix+"partials/users.html",controller:"CredentialsList"}).when("/users/:user_id/permissions/add",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsAdd"}).when("/users/:user_id/permissions",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsList"}).when("/users/:user_id/permissions/:permission_id",{templateUrl:urlPrefix+"partials/users.html",controller:"PermissionsEdit"}).when("/users/:user_id/credentials/add",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsAdd"}).when("/teams/:user_id/credentials/:credential_id",{templateUrl:urlPrefix+"partials/teams.html",controller:"CredentialsEdit"}).when("/login",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/logout",{templateUrl:urlPrefix+"partials/home.html",controller:"Authenticate"}).when("/home",{templateUrl:urlPrefix+"partials/home.html",controller:"Home"}).when("/home/groups",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeGroups"}).when("/home/hosts",{templateUrl:urlPrefix+"partials/subhome.html",controller:"HomeHosts"}).otherwise({redirectTo:"/home"})}]).run(["$cookieStore","$rootScope","CheckLicense","$location","Authorization","LoadBasePaths","ViewLicense","Timer","ClearScope","HideStream",function(a,b,c,d,e,f,g,h,i,j){f(),b.breadcrumbs=[],b.crumbCache=[],b.sessionTimer=h.init(),b.$on("$routeChangeStart",function(f,g){$("#stream-container").is(":visible")&&j(),/^\/(login|logout)/.test(d.path())||(b.lastPath=d.path(),a.put("lastPath",d.path())),e.isUserLoggedIn()===!1?g.templateUrl!==urlPrefix+"partials/login.html"&&d.path("/login"):b.sessionTimer.isExpired()?g.templateUrl!==urlPrefix+"partials/login.html"&&(b.sessionTimer.expireSession(),d.path("/login")):((void 0===b.current_user||null===b.current_user)&&e.restoreUserInfo(),c());var h=d.path().replace(/^\//,"").split("/")[0];""===h?h="home":h.replace(/\_/g," "),$('.nav-tabs a[href="#'+h+'"]').tab("show")}),e.getToken()?b.user_is_superuser=e.getUserInfo("is_superuser"):(b.sessionExpired=!1,a.put("sessionExpired",!1),d.path("/login"));var k=d.path().replace(/^\//,"").split("/")[0];""===k?(k="home",d.path("/home")):k.replace(/\_/g," "),$('.nav-tabs a[href="#'+k+'"]').tab("show"),b.viewCurrentUser=function(){d.path("/users/"+b.current_user.id)},b.viewLicense=function(){g()}}]);var $AnsibleConfig={tooltip_delay:{show:500,hide:100},debug_mode:!0,password_strength:45,session_timeout:1800};AdminsList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","AdminList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","GetBasePath","SelectionInit"],Authenticate.$inject=["$cookieStore","$window","$scope","$rootScope","$location","Authorization","ToggleClass","Alert","Wait","Timer","Empty"],CredentialsList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","CredentialList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","SelectionInit","GetChoices","Wait","Stream"],CredentialsAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","CredentialForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GenerateList","SearchInit","PaginateInit","LookUpInit","UserList","TeamList","GetBasePath","GetChoices","Empty","KindChange","OwnerChange","FormSave"],CredentialsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","CredentialForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","ReturnToCaller","ClearScope","Prompt","GetBasePath","GetChoices","KindChange","UserList","TeamList","LookUpInit","Empty","OwnerChange","FormSave","Stream","Wait"],Home.$inject=["$scope","$compile","$routeParams","$rootScope","$location","Wait","ObjectCount","JobStatus","InventorySyncStatus","SCMSyncStatus","ClearScope","Stream","Rest","GetBasePath","ProcessErrors","Button"],HomeGroups.$inject=["$location","$routeParams","HomeGroupList","GenerateList","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GetBasePath","SearchInit","PaginateInit","FormatDate","GetHostsStatusMsg","GetSyncStatusMsg","ViewUpdateStatus","Stream","GroupsEdit","Wait","Alert","Rest","Empty","InventoryUpdate","Find"],HomeHosts.$inject=["$location","$routeParams","HomeHostList","GenerateList","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GetBasePath","SearchInit","PaginateInit","FormatDate","SetStatus","ToggleHostEnabled","HostsEdit","Stream","Find","ShowJobSummary"],InventoriesList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","InventoryList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","Wait","Stream","EditInventoryProperties"],InventoriesAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","InventoryForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GenerateList","OrganizationList","SearchInit","PaginateInit","LookUpInit","GetBasePath","ParseTypeChange","Wait"],InventoriesEdit.$inject=["$scope","$location","$routeParams","$compile","GenerateList","ClearScope","InventoryGroups","InventoryHosts","BuildTree","Wait","GetSyncStatusMsg","InjectHosts","HostsReload","GroupsAdd","GroupsEdit","GroupsDelete","Breadcrumbs","LoadBreadCrumbs","Empty","Rest","ProcessErrors","InventoryUpdate","Alert","ToggleChildren","ViewUpdateStatus","GroupsCancelUpdate","Find","HostsCreate","EditInventoryProperties","HostsEdit","HostsDelete","ToggleHostEnabled","CopyMoveGroup","CopyMoveHost","Stream","GetBasePath","ShowJobSummary","ApplyEllipsis","WatchInventoryWindowResize","HelpDialog","InventoryGroupsHelp","Store"],JobEventsList.$inject=["$filter","$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","JobEventList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","LookUpInit","ToggleChildren","FormatDate","EventView","Refresh","Wait"],JobEventsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","JobEventsForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ClearScope","GetBasePath","FormatDate","EventView","Wait"],JobHostSummaryList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","JobHostList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","Refresh","JobStatusToolTip","Wait"],JobTemplatesList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","JobTemplateList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","PromptPasswords","JobTemplateForm","CredentialList","LookUpInit","SubmitJob","Wait","Stream"],JobTemplatesAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","JobTemplateForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GetBasePath","InventoryList","CredentialList","ProjectList","LookUpInit","md5Setup","ParseTypeChange","Wait","Empty"],JobTemplatesEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","JobTemplateForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","ReturnToCaller","ClearScope","InventoryList","CredentialList","ProjectList","LookUpInit","PromptPasswords","GetBasePath","md5Setup","ParseTypeChange","JobStatusToolTip","FormatDate","Wait","Stream","Empty","Prompt"],JobsListCtrl.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","JobList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","LookUpInit","SubmitJob","FormatDate","Refresh","JobStatusToolTip","Empty","Wait"],JobsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","JobForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","ReturnToCaller","ClearScope","InventoryList","CredentialList","ProjectList","LookUpInit","PromptPasswords","GetBasePath","md5Setup","FormatDate","JobStatusToolTip","Wait"],OrganizationsList.$inject=["$routeParams","$scope","$rootScope","$location","$log","Rest","Alert","LoadBreadCrumbs","Prompt","GenerateList","OrganizationList","SearchInit","PaginateInit","ClearScope","ProcessErrors","GetBasePath","SelectionInit","Wait","Stream"],OrganizationsAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","OrganizationForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ClearScope","GetBasePath","ReturnToCaller","Wait"],OrganizationsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","OrganizationForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","Prompt","ClearScope","GetBasePath","Wait","Stream"],PermissionsList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","PermissionList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","CheckAccess","Wait"],PermissionsAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","PermissionsForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ClearScope","GetBasePath","ReturnToCaller","InventoryList","ProjectList","LookUpInit","CheckAccess","Wait","PermissionCategoryChange"],PermissionsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","PermissionsForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","Prompt","GetBasePath","InventoryList","ProjectList","LookUpInit","CheckAccess","Wait","PermissionCategoryChange"],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","GetChoices","Empty"],ProjectsAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","ProjectsForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ClearScope","GetBasePath","ReturnToCaller","GetProjectPath","LookUpInit","OrganizationList","CredentialList","GetChoices","DebugForm","Wait"],ProjectsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","ProjectsForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","Prompt","ClearScope","GetBasePath","ReturnToCaller","GetProjectPath","Authorization","CredentialList","LookUpInit","GetChoices","Empty","DebugForm","Wait","Stream"],TeamsList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","TeamList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","SetTeamListeners","GetBasePath","SelectionInit","Wait","Stream"],TeamsAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","TeamForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GenerateList","OrganizationList","SearchInit","PaginateInit","GetBasePath","LookUpInit","Wait"],TeamsEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","TeamForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","ReturnToCaller","ClearScope","LookUpInit","Prompt","GetBasePath","CheckAccess","OrganizationList","Wait","Stream"],UsersList.$inject=["$scope","$rootScope","$location","$log","$routeParams","Rest","Alert","UserList","GenerateList","LoadBreadCrumbs","Prompt","SearchInit","PaginateInit","ReturnToCaller","ClearScope","ProcessErrors","GetBasePath","SelectionInit","Wait","Stream"],UsersAdd.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","UserForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","ReturnToCaller","ClearScope","GetBasePath","LookUpInit","OrganizationList","ResetForm","Wait"],UsersEdit.$inject=["$scope","$rootScope","$compile","$location","$log","$routeParams","UserForm","GenerateForm","Rest","Alert","ProcessErrors","LoadBreadCrumbs","RelatedSearchInit","RelatedPaginateInit","ReturnToCaller","ClearScope","GetBasePath","Prompt","CheckAccess","ResetForm","Wait","Stream"],angular.module("ActivityDetailDefinition",[]).value("ActivityDetailForm",{name:"activity",editTitle:"Activity Detail",well:!1,"class":"horizontal-narrow",formFieldSize:"col-lg-10",formLabelSize:"col-lg-2",fields:{user:{label:"Initiated by",type:"text",readonly:!0},operation:{label:"Action",type:"text",readonly:!0},changes:{label:"Changes",type:"textarea",ngHide:"!changes || changes =='' || changes == 'null'",readonly:!0}}}),angular.module("CredentialFormDefinition",[]).value("CredentialForm",{addTitle:"Create Credential",editTitle:"{{ name }}",name:"credential",well:!0,forceListeners:!0,actions:{stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"edit"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,autocomplete:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},owner:{label:"Does this credential belong to a team or user?",type:"radio_group",ngChange:"ownerChange()",options:[{label:"User",value:"user",selected:!0},{label:"Team",value:"team"}],awPopOver:"

        A credential must be associated with either a user or a team. Choosing a user allows only the selected user access to the credential. Choosing a team shares the credential with all team members.

        ",dataTitle:"Owner",dataPlacement:"right",dataContainer:"body"},user:{label:"User that owns this credential",type:"lookup",sourceModel:"user",sourceField:"username",ngClick:"lookUpUser()",ngShow:"owner == 'user'",awRequiredWhen:{variable:"user_required",init:"false"}},team:{label:"Team that owns this credential",type:"lookup",sourceModel:"team",sourceField:"name",ngClick:"lookUpTeam()",ngShow:"owner == 'team'",awRequiredWhen:{variable:"team_required",init:"false"}},kind:{label:"Type",excludeModal:!0,type:"select",ngOptions:"kind.label for kind in credential_kind_options",ngChange:"kindChange()",addRequired:!0,editRequired:!0,helpCollapse:[{hdr:"Select a Credential Type",content:"
        \n
        AWS
        \n
        Access keys for Amazon Web Services used for inventory management or deployment.
        \n
        Machine
        \n
        Authentication for remote machine access. This can include SSH keys, usernames, passwords, and sudo information. Machine credentials are used when submitting jobs to run playbooks against remote hosts.
        Rackspace
        \n
        Access information for Rackspace Cloud used for inventory management or deployment.
        \n
        SCM
        \n
        Used to check out and synchronize playbook repositories with a remote source control management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are used on the Projects tab.
        \n
        \n"}]},access_key:{label:"Access Key",type:"text",ngShow:"kind.value == 'aws'",awRequiredWhen:{variable:"aws_required",init:!1},autocomplete:!1,apiField:"username"},secret_key:{label:"Secret Key",type:"password",ngShow:"kind.value == 'aws'",awRequiredWhen:{variable:"aws_required",init:!1},autocomplete:!1,ask:!1,clear:!1,apiField:"passwowrd"},username:{labelBind:"usernameLabel",type:"text",ngShow:"kind.value && kind.value !== 'aws'",awRequiredWhen:{variable:"rackspace_required",init:!1},autocomplete:!1},api_key:{label:"API Key",type:"password",ngShow:"kind.value == 'rax'",awRequiredWhen:{variable:"rackspace_required",init:!1},autocomplete:!1,ask:!1,clear:!1,apiField:"passwowrd"},password:{label:"Password",type:"password",ngShow:"kind.value == 'scm'",addRequired:!1,editRequired:!1,ngChange:"clearPWConfirm('password_confirm')",ask:!1,clear:!1,associated:"password_confirm",autocomplete:!1},password_confirm:{label:"Confirm Password",type:"password",ngShow:"kind.value == 'scm'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"password",autocomplete:!1},ssh_password:{label:"SSH Password",type:"password",ngShow:"kind.value == 'ssh'",ngChange:"clearPWConfirm('ssh_password_confirm')",addRequired:!1,editRequired:!1,ask:!0,clear:!0,associated:"ssh_password_confirm",autocomplete:!1},ssh_password_confirm:{label:"Confirm SSH Password",type:"password",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"ssh_password",autocomplete:!1},ssh_key_data:{labelBind:"sshKeyDataLabel",type:"textarea",ngShow:"kind.value == 'ssh' || kind.value == 'scm'",addRequired:!1,editRequired:!1,"class":"ssh-key-field",rows:10},ssh_key_unlock:{label:"Key Password",type:"password",ngShow:"kind.value == 'ssh' || kind.value == 'scm'",addRequired:!1,editRequired:!1,ngChange:"clearPWConfirm('ssh_key_unlock_confirm')",associated:"ssh_key_unlock_confirm",ask:!0,askShow:"kind.value == 'ssh'",clear:!0},ssh_key_unlock_confirm:{label:"Confirm Key Password",type:"password",ngShow:"kind.value == 'ssh' || kind.value == 'scm'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"ssh_key_unlock"},sudo_username:{label:"Sudo Username",type:"text",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,autocomplete:!1},sudo_password:{label:"Sudo Password",type:"password",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,ngChange:"clearPWConfirm('sudo_password_confirm')",ask:!0,clear:!0,associated:"sudo_password_confirm",autocomplete:!1},sudo_password_confirm:{label:"Confirm Sudo Password",type:"password",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"sudo_password",autocomplete:!1}},buttons:{save:{label:"Save",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("GroupFormDefinition",[]).value("GroupForm",{addTitle:"Create Group",editTitle:"Edit Group",showTitle:!0,cancelButton:!1,name:"group",well:!0,formLabelSize:"col-lg-3",formFieldSize:"col-lg-9",tabs:[{name:"properties",label:"Properties"},{name:"source",label:"Source"}],fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,tab:"properties"},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,tab:"properties"},variables:{label:"Variables",type:"textarea",addRequired:!1,editRequird:!1,rows:6,"default":"---",dataTitle:"Group Variables",dataPlacement:"right",awPopOver:'

        Variables defined here apply to all child groups and hosts.

        Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataContainer:"body",tab:"properties"},source:{label:"Source",type:"select",ngOptions:"source.label for source in source_type_options",ngChange:"sourceChange()",addRequired:!1,editRequired:!1,tab:"source"},source_path:{label:"Script Path",ngShow:"source && source.value == 'file'",type:"text",awRequiredWhen:{variable:"sourcePathRequired",init:"false"},tab:"source"},credential:{label:"Cloud Credential",type:"lookup",ngShow:"source && source.value !== ''",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,tab:"source"},source_regions:{label:"Regions",type:"text",ngShow:"source && (source.value == 'rax' || source.value == 'ec2')",addRequired:!1,editRequired:!1,awMultiselect:"source_region_choices",dataTitle:"Source Regions",dataPlacement:"right",awPopOver:"

        Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, or choose All to include all regions. Tower will only be updated with Hosts associated with the selected regions.

        ",dataContainer:"body",tab:"source"},source_vars:{label:"Source Variables",ngShow:"source && (source.value == 'file' || source.value == 'ec2')",type:"textarea",addRequired:!1,editRequird:!1,rows:6,"default":"---",parseTypeName:"envParseType",dataTitle:"Source Variables",dataPlacement:"right",awPopOver:'

        Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables view ec2.ini in the Ansible github repo.

        Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataContainer:"body",tab:"source"},checkbox_group:{label:"Update Options",type:"checkbox_group",ngShow:"source && (source.value !== '' && source.value !== null)",tab:"source",fields:[{name:"overwrite",label:"Overwrite",type:"checkbox",ngShow:"source.value !== '' && source.value !== null",addRequired:!1,editRequired:!1,awPopOver:"

        When checked all child groups and hosts not found on the remote source will be deleted from the local inventory.

        Unchecked any local child hosts and groups not found on the external source will remain untouched by the inventory update process.

        ",dataTitle:"Overwrite",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"overwrite_vars",label:"Overwrite Variables",type:"checkbox",ngShow:"source.value !== '' && source.value !== null",addRequired:!1,editRequired:!1,awPopOver:"

        If checked, all variables for child groups and hosts will be removed and replaced by those found on the external source.

        When not checked a merge will be performed, combining local variables with those found on the external source.

        ",dataTitle:"Overwrite Variables",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"update_on_launch",label:"Update on Launch",type:"checkbox",ngShow:"source.value !== '' && source.value !== null",addRequired:!1,editRequired:!1,awPopOver:"

        Each time a job runs using this inventory, refresh the inventory from the selected source before executing job tasks.

        ",dataTitle:"Update on Launch",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"}]}},buttons:{labelClass:"col-lg-3",controlClass:"col-lg-5",save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("HostGroupsFormDefinition",[]).value("HostGroupsForm",{editTitle:"Host Groups",name:"host",well:!1,formLabelSize:"col-lg-3",formFieldSize:"col-lg-9",fields:{groups:{label:"Groups",type:"select",multiple:!0,ngOptions:"group.name for group in inventory_groups",addRequired:!0,editRequired:!0,awPopOver:"

        Provide a host name, ip address, or ip address:port. Examples include:

        myserver.domain.com
        127.0.0.1
        10.1.0.140:25
        server.example.com:25
        ",dataTitle:"Host Name",dataPlacement:"right",dataContainer:"#form-modal .modal-content"}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("HostFormDefinition",[]).value("HostForm",{addTitle:"Create Host",editTitle:"{{ name }}",name:"host",well:!1,formLabelSize:"col-lg-3",formFieldSize:"col-lg-9",fields:{name:{label:"Host Name",type:"text",addRequired:!0,editRequired:!0,awPopOver:"

        Provide a host name, ip address, or ip address:port. Examples include:

        myserver.domain.com
        127.0.0.1
        10.1.0.140:25
        server.example.com:25
        ",dataTitle:"Host Name",dataPlacement:"right",dataContainer:"#form-modal .modal-content"},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},enabled:{label:"Enabled?",type:"checkbox",addRequired:!1,editRequired:!1,"default":!0,awPopOver:"

        Indicates if a host is available and should be included in running jobs.

        For hosts that are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.

        ",dataTitle:"Host Enabled",dataPlacement:"right",dataContainer:"#form-modal .modal-content",ngDisabled:"has_inventory_sources == true"},variables:{label:"Variables",type:"textarea",addRequired:!1,editRequird:!1,rows:6,"class":"modal-input-xlarge","default":"---",awPopOver:'

        Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataTitle:"Host Variables",dataPlacement:"right",dataContainer:"#form-modal .modal-content"},inventory:{type:"hidden",includeOnEdit:!0,includeOnAdd:!0}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("InventoryFormDefinition",[]).value("InventoryForm",{addTitle:"Create Inventory",editTitle:"{{ inventory_name | capitalize }}",name:"inventory",well:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{inventory_name:{realName:"name",label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},inventory_description:{realName:"description",label:"Description",type:"text",addRequired:!1,editRequired:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",ngClick:"lookUpOrganization()",awRequiredWhen:{variable:"organizationrequired",init:"true"}},inventory_variables:{realName:"variables",label:"Variables",type:"textarea","class":"span12",addRequired:!1,editRequird:!1,parseTypeName:"inventoryParseType",rows:6,"default":"---",awPopOver:'

        Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataTitle:"Inventory Variables",dataPlacement:"right",dataContainer:"body"}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("JobEventDataDefinition",[]).value("JobEventDataForm",{editTitle:"{{ id }} - {{ event_display }}",name:"job_events",well:!1,"class":"horizontal-narrow",fields:{event_data:{label:!1,type:"textarea",readonly:!0,rows:18,"class":"modal-input-xxlarge"}}}),angular.module("JobEventsFormDefinition",[]).value("JobEventsForm",{name:"job_events",well:!1,forceListeners:!0,fields:{status:{labelClass:"job-{{ status }}",type:"custom",section:"Event",control:'
        {{ status }}
        '},id:{label:"ID",type:"text",readonly:!0,section:"Event","class":"span1"},created:{label:"Created On",type:"text",section:"Event",readonly:!0},host:{label:"Host",type:"text",readonly:!0,section:"Event",ngShow:"host !== ''"},play:{label:"Play",type:"text",readonly:!0,section:"Event",ngShow:"play !== ''"},task:{label:"Task",type:"text",readonly:!0,section:"Event",ngShow:"task !== ''"},rc:{label:"Return Code",type:"text",readonly:!0,section:"Results","class":"span1",ngShow:"rc !== ''"},msg:{label:"Msg",type:"textarea",readonly:!0,section:"Results","class":"nowrap",ngShow:"msg !== ''",rows:10},stdout:{label:"Std Out",type:"textarea",readonly:!0,section:"Results","class":"nowrap",ngShow:"stdout !== ''",rows:10},stderr:{label:"Std Err",type:"textarea",readonly:!0,section:"Results","class":"nowrap",ngShow:"stderr !== ''",rows:10},results:{label:"Results",type:"textarea",section:"Results",readonly:!0,"class":"nowrap",ngShow:"results !== ''",rows:10},start:{label:"Start",type:"text",readonly:!0,section:"Timing",ngShow:"start !== ''"},traceback:{label:!1,type:"textarea",readonly:!0,section:"Traceback","class":"nowrap",ngShow:"traceback !== ''",rows:10},end:{label:"End",type:"text",readonly:!0,section:"Timing",ngShow:"end !== ''"},delta:{label:"Elapsed",type:"text",readonly:!0,section:"Timing",ngShow:"delta !== ''"},module_name:{label:"Name",type:"text",readonly:!0,section:"Module",ngShow:"module_name !== ''"},module_args:{label:"Args",type:"text",readonly:!0,section:"Module",ngShow:"module_args !== ''"}}}),angular.module("JobSummaryDefinition",[]).value("JobSummary",{editTitle:"{{ id }} - {{ name }}",name:"jobs",well:!1,fields:{status:{type:"custom",control:'
        Status {{ status }}
        ',readonly:!0},created:{label:"Created On",type:"text",readonly:!0},result_stdout:{label:"Standard Out",type:"textarea",readonly:!0,xtraWide:!0,rows:"{{ stdout_rows }}","class":"nowrap mono-space resizable",ngShow:'result_stdout != ""'},result_traceback:{label:"Traceback",type:"textarea",xtraWide:!0,readonly:!0,rows:"{{ traceback_rows }}","class":"nowrap mono-space resizable",ngShow:'result_traceback != ""'}}}),angular.module("JobTemplateFormDefinition",[]).value("JobTemplateForm",{addTitle:"Create Job Templates",editTitle:"{{ name }}",name:"job_templates",twoColumns:!0,well:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,column:1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,column:1},job_type:{label:"Job Type",type:"select",ngOptions:"type.label for type in job_type_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"

        When this template is submitted as a job, setting the type to run will execute the playbook, running tasks on the selected hosts.

        Setting the type to check will not execute the playbook. Instead, ansible will check playbook syntax, test environment setup and report problems.

        ",dataTitle:"Job Type",dataPlacement:"right",dataContainer:"body"},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",ngClick:"lookUpInventory()",awRequiredWhen:{variable:"inventoryrequired",init:"true"},column:1,awPopOver:"

        Select the inventory containing the hosts you want this job to manage.

        ",dataTitle:"Inventory",dataPlacement:"right",dataContainer:"body"},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",ngClick:"lookUpProject()",awRequiredWhen:{variable:"projectrequired",init:"true"},column:1,awPopOver:"

        Select the project containing the playbook you want this job to execute.

        ",dataTitle:"Project",dataPlacement:"right",dataContainer:"body"},playbook:{label:"Playbook",type:"select",ngOptions:"book for book in playbook_options",id:"playbook-select",awRequiredWhen:{variable:"playbookrequired",init:"true"},column:1,awPopOver:"

        Select the playbook to be executed by this job.

        ",dataTitle:"Playbook",dataPlacement:"right",dataContainer:"body"},credential:{label:"Machine Credential",type:"lookup",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing the username and SSH key or password that Ansbile will need to log into the remote hosts.

        ",dataTitle:"Credential",dataPlacement:"right",dataContainer:"body"},cloud_credential:{label:"Cloud Credential",type:"lookup",sourceModel:"cloud_credential",sourceField:"name",ngClick:"lookUpCloudcredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Selecting an optional cloud credential in the job template will pass along the access credentials to the running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.

        ",dataTitle:"Cloud Credential",dataPlacement:"right",dataContainer:"body"},forks:{label:"Forks",id:"forks-number",type:"number",integer:!0,min:0,spinner:!0,"default":"0",addRequired:!1,editRequired:!1,"class":"input-small",column:1,awPopOver:'

        The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies the default value from the ansible configuration file.

        ',dataTitle:"Forks",dataPlacement:"right",dataContainer:"body"},limit:{label:"Limit",type:"text",addRequired:!1,editRequired:!1,column:1,awPopOver:'

        Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. Multiple patterns can be separated by ; : or ,

        For more information and examples see the Patters top at docs.ansible.com.

        ',dataTitle:"Limit",dataPlacement:"right",dataContainer:"body"},verbosity:{label:"Verbosity",type:"select",ngOptions:"v.label for v in verbosity_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"

        Control the level of output ansible will produce as the playbook executes.

        ",dataTitle:"Verbosity",dataPlacement:"right",dataContainer:"body"},variables:{label:"Extra Variables",type:"textarea",rows:6,"class":"span12",addRequired:!1,editRequired:!1,"default":"---",column:2,awPopOver:'

        Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n',dataTitle:"Extra Variables",dataPlacement:"right",dataContainer:"body"},job_tags:{label:"Job Tags",type:"textarea",rows:1,addRequired:!1,editRequired:!1,"class":"span12",column:2,awPopOver:"

        Provide a comma separated list of tags.

        \n

        Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.

        For example, you might have a task consisiting of a long list of actions. Tag values can be assigned to each action. Suppose the actions have been assigned tag values of "configuration", "packages" and "install".

        If you just want to run the "configuration" and "packages" actions, you would enter the following here in the Job Tags field:

        \n
        configuration,packages
        \n",dataTitle:"Job Tags",dataPlacement:"right",dataContainer:"body"},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')",column:2,awPopOver:'

        Create a callback URL a host can use to contact Tower and request a configuration update using the job template. The URL will look like the following:

        \n

        http://your.server.com:999/api/v1/job_templates/1/callback/

        The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataTitle:"Callback URL",dataContainer:"body"},callback_url:{label:"Callback URL",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:2,required:!1,"class":"span12",awPopOver:'

        Using this URL a host can contact Tower and request a configuration update using the job template. The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataTitle:"Callback URL",dataContainer:"body"},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2,awPopOver:'

        When contacting the Tower server using the callback URL, the calling host must authenticate by including this key in the POST data of the request. Here\'s an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n',dataPlacement:"right",dataContainer:"body"}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{jobs:{type:"collection",title:"Jobs",iterator:"job",index:!1,open:!1,actions:{reset:{dataPlacement:"top",icon:"icon-undo",mode:"all","class":"btn-xs btn-primary",awToolTip:"Reset the search filter",ngClick:"resetSearch('job')",iconSize:"large"}},fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},created:{label:"Date",link:!1,searchable:!1},status:{label:"Status","class":"job-{{ job.status }}",searchType:"select",linkTo:"{{}} job.statusLinkTo }}",searchOptions:[{name:"new",value:"new"},{name:"waiting",value:"waiting"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",value:"failed"},{name:"canceled",value:"canceled"}],badgeIcon:"fa icon-job-{{ job.status }}",badgePlacement:"left",badgeToolTip:"{{ job.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgHref:"{{ job.statusLinkTo }}",awToolTip:"{{ job.statusBadgeToolTip }}",dataPlacement:"top"}},fieldActions:{edit:{label:"View",ngClick:"edit('jobs', job.id, job.name)",icon:"icon-zoom-in"}}}}}),angular.module("JobFormDefinition",[]).value("JobForm",{addTitle:"Create Job",editTitle:"{{ id }} - {{ name }}",name:"jobs",well:!0,collapse:!0,collapseMode:"edit",collapseTitle:"Job Template",twoColumns:!0,navigationLinks:{details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",active:!0,ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",icon:"icon-laptop"}},fields:{name:{label:"Job Template",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,column:1},job_type:{label:"Job Type",type:"select",ngOptions:"type.label for type in job_type_options","default":"run",addRequired:!0,editRequired:!0,awPopOver:"

        When this template is submitted as a job, setting the type to run will execute the playbook, running tasks on the selected hosts.

        Setting the type to check will not execute the playbook. Instead, ansible will check playbook syntax, test environment setup and report problems.

        ",dataTitle:"Job Type",dataPlacement:"right",dataContainer:"body",column:1},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",addRequired:!0,editRequired:!0,ngClick:"lookUpInventory()",column:1,awPopOver:"

        Select the inventory containing the hosts you want this job to manage.

        ",dataTitle:"Inventory",dataPlacement:"right",dataContainer:"body"},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",addRequired:!0,editRequired:!0,ngClick:"lookUpProject()",column:1,awPopOver:"

        Select the project containing the playbook you want this job to execute.

        ",dataTitle:"Project",dataPlacement:"right",dataContainer:"body"},playbook:{label:"Playbook",type:"select",ngOptions:"book for book in playbook_options",id:"playbook-select",addRequired:!0,editRequired:!0,column:1,awPopOver:"

        Select the playbook to be executed by this job.

        ",dataTitle:"Playbook",dataPlacement:"right",dataContainer:"body"},credential:{label:"Credential",type:"lookup",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing the username and SSH key or password that Ansbile will need to log into the remote hosts.

        ",dataTitle:"Credential",dataPlacement:"right",dataContainer:"body"},cloud_credential:{label:"Cloud Credential",type:"lookup",sourceModel:"cloud_credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Selecting an optional cloud credential in the job template will pass along the access credentials to the running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.

        ",dataTitle:"Cloud Credential",dataPlacement:"right",dataContainer:"body"},forks:{label:"Forks",id:"forks-number",type:"number",integer:!0,min:0,spinner:!0,"class":"input-small","default":"0",addRequired:!1,editRequired:!1,column:1,disabled:!0,awPopOver:"

        The number of parallel or simultaneous processes to use while executing the playbook.

        ",dataContainer:"body",dataTitle:"Forks",dataPlacement:"right"},limit:{label:"Limit",type:"text",addRequired:!1,editRequired:!1,column:1,awPopOver:'

        Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. Multiple patterns can be separated by ; : or ,

        For more information and examples see the Selecting Targets section under Inventory and Patterns in the Ansible documentation.

        ',dataContainer:"body",dataTitle:"Limit",dataPlacement:"right"},verbosity:{label:"Verbosity",type:"select",ngOptions:"v.label for v in verbosity_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"

        Control the level of output ansible will produce as the playbook executes.

        ",dataTitle:"Verbosity",dataPlacement:"right",dataContainer:"body"},variables:{label:"Extra Variables",type:"textarea",rows:6,"class":"span12",addRequired:!1,editRequired:!1,column:2,awPopOver:'

        Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n',dataTitle:"Extra Variables",dataContainer:"body",dataPlacement:"right"},job_tags:{label:"Job Tags",type:"textarea",rows:1,addRequired:!1,editRequired:!1,"class":"span12",column:2,awPopOver:"

        Provide a comma separated list of tags.

        \n

        Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.

        For example, you might have a task consisiting of a long list of actions. Tag values can be assigned to each action. Suppose the actions have been assigned tag values of "configuration", "packages" and "install".

        If you just want to run the "configuration" and "packages" actions, you would enter the following here in the Job Tags field:

        \n
        configuration,packages
        \n",dataTitle:"Job Tags",dataContainer:"body",dataPlacement:"right"},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')","class":"span12",column:2,awPopOver:'

        Create a callback URL a host can use to contact Tower and request a configuration update using the job template. The URL will look like the following:

        \n

        http://your.server.com:999/api/v1/job_templates/1/callback/

        The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataContainer:"body",dataTitle:"Callback URL"},callback_url:{label:"Callback URL",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:2,required:!1,"class":"span12",awPopOver:'

        Using this URL a host can contact Tower and request a configuration update using the job template. The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataContainer:"body",dataTitle:"Callback URL"},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2,awPopOver:'

        When contacting Tower using the callback URL, the calling host must authenticate by including this key in the POST data of the request. Here\'s an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n',dataPlacement:"right",dataContainer:"body"}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-undo","class":"btn btn-default",ngDisabled:!0}},statusFields:{status:{type:"custom",control:'
        Status {{ status }}
        ',readonly:!0},created:{label:"Created On",type:"text",readonly:!0},result_stdout:{label:"Standard Out",type:"textarea",readonly:!0,xtraWide:!0,rows:"{{ stdout_rows }}","class":"nowrap mono-space",ngShow:"result_stdout != ''"},result_traceback:{label:"Traceback",type:"textarea",xtraWide:!0,readonly:!0,rows:"{{ traceback_rows }}","class":"nowrap mono-space",ngShow:"result_traceback != ''"}},statusActions:{refresh:{dataPlacement:"top",icon:"icon-refresh",iconSize:"large",mode:"all","class":"btn-xs btn-primary",awToolTip:"Refresh the page",ngClick:"refresh()"}}}),angular.module("LicenseFormDefinition",[]).value("LicenseForm",{name:"license",well:!1,forceListeners:!0,fields:{license_status:{type:"custom",control:'
        {{ license_status }}
        ',readonly:!0,section:"License"},license_key:{label:"Key",type:"textarea","class":"modal-input-xlarge",readonly:!0,section:"License"},license_date:{label:"Expires On",type:"text",readonly:!0,section:"License"},time_remaining:{label:"Time Left",type:"text",readonly:!0,section:"License"},available_instances:{label:"Available",type:"text",readonly:!0,section:"Managed Hosts"},current_instances:{label:"Used",type:"text",readonly:!0,section:"Managed Hosts"},free_instances:{label:"Remaining",type:"text",readonly:!0,section:"Managed Hosts",controlNGClass:"free_instances_class",labelNGClass:"free_instances_class"},company_name:{label:"Company",type:"text",readonly:!0,section:"Contact Info"},contact_name:{label:"Contact",type:"text",readonly:!0,section:"Contact Info"},contact_email:{label:"Contact Email",type:"text",readonly:!0,section:"Contact Info"}}}),angular.module("OrganizationFormDefinition",[]).value("OrganizationForm",{addTitle:"Create Organization",editTitle:"{{ name }}",name:"organization",well:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{users:{type:"collection",title:"Users",iterator:"user",open:!1,actions:{add:{ngClick:"add('users')",label:"Add",icon:"icon-plus",awToolTip:"Add a new user"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', user.id, user.username)",icon:"icon-edit","class":"btn-default",awToolTip:"Edit user"},"delete":{label:"Delete",ngClick:"delete('users', user.id, user.username, 'users')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove user"}}},admins:{type:"collection",title:"Administrators",iterator:"admin",open:!1,base:"/users",actions:{add:{ngClick:"add('admins')",icon:"icon-plus",label:"Add",awToolTip:"Add new administrator"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', admin.id, admin.username)",icon:"icon-edit",awToolTip:"Edit administrator","class":"btn-default"},"delete":{label:"Delete",ngClick:"delete('admins', admin.id, admin.username, 'administrators')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove administrator"}}}}}),angular.module("PermissionFormDefinition",[]).value("PermissionsForm",{addTitle:"Add Permission",editTitle:"{{ name }}",name:"permission",well:!0,forceListeners:!0,stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"},fields:{category:{label:"Permission Type",labelClass:"prepend-asterisk",type:"radio_group",options:[{label:"Inventory",value:"Inventory",selected:!0},{label:"Deployment",value:"Deploy"}],ngChange:"selectCategory()"},name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},user:{label:"User",type:"hidden"},team:{label:"Team",type:"hidden"},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",ngShow:"category == 'Deploy'",ngClick:"lookUpProject()",awRequiredWhen:{variable:"projectrequired",init:"false"}},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",ngClick:"lookUpInventory()",awRequiredWhen:{variable:"inventoryrequired",init:"true"}},permission_type:{label:"Permission",labelClass:"prepend-asterisk",type:"radio_group",options:[{label:"Read",value:"read",ngShow:"category == 'Inventory'"},{label:"Write",value:"write",ngShow:"category == 'Inventory'"},{label:"Admin",value:"admin",ngShow:"category == 'Inventory'"},{label:"Run",value:"run",ngShow:"category == 'Deploy'"},{label:"Check",value:"check",ngShow:"category == 'Deploy'"}],helpCollapse:[{hdr:"Permission",ngBind:"permissionTypeHelp"}]}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("ProjectStatusDefinition",[]).value("ProjectStatusForm",{name:"project_update",editTitle:"SCM Status",well:!1,"class":"horizontal-narrow",fields:{created:{label:"Created",type:"text",readonly:!0},status:{label:"Status",type:"text",readonly:!0},result_stdout:{label:"Std Out",type:"textarea",ngShow:"result_stdout","class":"mono-space",readonly:!0,rows:15},result_traceback:{label:"Traceback",type:"textarea",ngShow:"result_traceback","class":"mono-space",readonly:!0,rows:15}}}),angular.module("ProjectFormDefinition",[]).value("ProjectsForm",{addTitle:"Create Project",editTitle:"{{ name }}",name:"project",well:!0,forceListeners:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",addRequired:!0,editRequired:!1,excludeMode:"edit",ngClick:"lookUpOrganization()",awRequiredWhen:{variable:"organizationrequired",init:"true"},awPopOver:"

        A project must have at least one organization. Pick one organization now to create the project, and then after the project is created you can add additional organizations.

        Only super users and organization administrators are allowed to make changes to projects. Associating one or more organizations to a project determins which organizations admins have access to modify the project.",dataTitle:"Organization",dataContainer:"body",dataPlacement:"right"},scm_type:{label:"SCM Type",type:"select",ngOptions:"type.label for type in scm_type_options",ngChange:"scmChange()",addRequired:!0,editRequired:!0},missing_path_alert:{type:"alertblock","class":"alert-info",ngShow:"showMissingPlaybooksAlert && scm_type.value == ''",alertTxt:'

        WARNING: There are no unassigned playbook directories in the base project path {{ base_dir }}. Either the projects directory is empty, or all of the contents are already assigned to other projects. New projects can be checked out from source control by changing the SCM type option rather than specifying checkout paths manually. To continue with manual setup, log into the Tower host and ensure content is present in a subdirectory under {{ base_dir }}. Run "chown -R awx" on the content directory to ensure Tower can read the playbooks.

        ',closeable:!1},base_dir:{label:"Project Base Path",type:"textarea",showonly:!0,ngShow:"scm_type.value == ''",awPopOver:"

        Base path used for locating playbooks. Directories found inside this path will be listed in the playbook directory drop-down. Together the base path and selected playbook directory provide the full path used to locate playbooks.

        Use PROJECTS_ROOT in your environment settings file to determine the base path value.

        ",dataTitle:"Project Base Path",dataContainer:"body",dataPlacement:"right"},local_path:{label:"Playbook Directory",type:"select",id:"local-path-select",ngOptions:"path.label for path in project_local_paths",awRequiredWhen:{variable:"pathRequired",init:!1},ngShow:"scm_type.value == '' && !showMissingPlaybooksAlert",awPopOver:"

        Select from the list of directories found in the base path.Together the base path and the playbook directory provide the full path used to locate playbooks.

        Use PROJECTS_ROOT in your environment settings file to determine the base path value.

        ",dataTitle:"Project Path",dataContainer:"body",dataPlacement:"right"},scm_url:{label:"SCM URL",type:"text",ngShow:"scm_type && scm_type.value !== ''",awRequiredWhen:{variable:"scmRequired",init:!1},helpCollapse:[{hdr:"GIT URLs",content:'

        Example URLs for GIT SCM include:

        • https://github.com/ansible/ansible.git
        • git@github.com:ansible/ansible.git
        • git://servername.example.com/ansible.git

        Note: If using SSH protocol for GitHub or Bitbucket, enter in the SSH key only, do not enter a username (other than git). Additionally, GitHub and Bitbucket do not support password authentication when using SSH protocol. GIT read only protocol (git://) does not use username or password information.',show:"scm_type.value == 'git'"},{hdr:"SVN URLs",content:'

        Example URLs for Subversion SCM include:

        • https://github.com/ansible/ansible
        • svn://servername.example.com/path
        • svn+ssh://servername.example.com/path
        ',show:"scm_type.value == 'svn'"},{hdr:"Mercurial URLs",content:'

        Example URLs for Mercurial SCM include:

        • https://bitbucket.org/username/project
        • ssh://hg@bitbucket.org/username/project
        • ssh://server.example.com/path

        Note: Mercurial does not support password authentication for SSH. If applicable, add the username, password and key below. Do not put the username and key in the URL. If using Bitbucket and SSH, do not supply your Bitbucket username.',show:"scm_type.value == 'hg'"}]},scm_branch:{labelBind:"scmBranchLabel",type:"text",ngShow:"scm_type && scm_type.value !== ''",addRequired:!1,editRequired:!1},credential:{label:"SCM Credential",type:"lookup",ngShow:"scm_type && scm_type.value !== ''",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1},checkbox_group:{label:"SCM Update Options",type:"checkbox_group",ngShow:"scm_type && scm_type.value !== ''",fields:[{name:"scm_clean",label:"Clean",type:"checkbox",addRequired:!1,editRequired:!1,awPopOver:"

        Remove any local modifications prior to performing an update.

        ",dataTitle:"SCM Clean",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"scm_delete_on_update",label:"Delete on Update",type:"checkbox",addRequired:!1,editRequired:!1,awPopOver:"

        Delete the local repository in its entirety prior to performing an update.

        Depending on the size of the repository this may significantly increase the amount of time required to complete an update.

        ",dataTitle:"SCM Delete",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"scm_update_on_launch",label:"Update on Launch",type:"checkbox",addRequired:!1,editRequired:!1,awPopOver:"

        Each time a job runs using this project, perform an update to the local repository prior to starting the job.

        ",dataTitle:"SCM Update",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"}]}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{organizations:{type:"collection",title:"Organizations",iterator:"organization",open:!1,actions:{add:{ngClick:"add('organizations')",icon:"icon-plus",label:"Add",awToolTip:"Add an organization"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('organizations', organization.id, organization.name)",icon:"icon-edit",awToolTip:"Edit the organization","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('organizations', organization.id, organization.name, 'organizations')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the organization"}}}}}),angular.module("TeamFormDefinition",[]).value("TeamForm",{addTitle:"Create Team",editTitle:"{{ name }}",name:"team",well:!0,collapse:!0,collapseTitle:"Team Settings",collapseMode:"edit",collapseOpen:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",ngClick:"lookUpOrganization()",awRequiredWhen:{variable:"teamrequired",init:"true"}}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{credentials:{type:"collection",title:"Credentials",iterator:"credential",open:!1,actions:{add:{ngClick:"add('credentials')",icon:"icon-plus",label:"Add",add:"Add a new credential"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('credentials', credential.id, credential.name)",icon:"icon-edit",awToolTip:"Modify the credential","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('credentials', credential.id, credential.name, 'credentials')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove the credential"}}},permissions:{type:"collection",title:"Permissions",iterator:"permission",open:!1,actions:{add:{ngClick:"add('permissions')",icon:"icon-plus",label:"Add",awToolTip:"Add a permission for this user",ngShow:"PermissionAddAllowed"}},fields:{name:{key:!0,label:"Name",ngClick:"edit('permissions', permission.id, permission.name)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('permissions', permission.id, permission.name)",icon:"icon-edit",awToolTip:"Edit the permission","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('permissions', permission.id, permission.name, 'permissions')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the permission",ngShow:"PermissionAddAllowed"}}},projects:{type:"collection",title:"Projects",iterator:"project",open:!1,actions:{add:{ngClick:"add('projects')",icon:"icon-plus",label:"Add"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('projects', project.id, project.name)",icon:"icon-edit",awToolTip:"Modify the project","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('projects', project.id, project.name, 'projects')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove the project"}}},users:{type:"collection",title:"Users",iterator:"user",open:!1,actions:{add:{ngClick:"add('users')",icon:"icon-plus",label:"Add",awToolTip:"Add a user"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', user.id, user.username)",icon:"icon-edit",awToolTip:"Edit user","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('users', user.id, user.username, 'users')",icon:"icon-terash","class":"btn-danger",awToolTip:"Remove user"}}}}}),angular.module("UserFormDefinition",[]).value("UserForm",{addTitle:"Create User",editTitle:"{{ username }}",name:"user",well:!0,forceListeners:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{first_name:{label:"First Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},last_name:{label:"Last Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},email:{label:"Email",type:"email",addRequired:!0,editRequired:!0,autocomplete:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",ngClick:"lookUpOrganization()",excludeMode:"edit",awRequiredWhen:{variable:"orgrequired",init:!0}},username:{label:"Username",type:"text",awRequiredWhen:{variable:"not_ldap_user",init:!0},autocomplete:!1},password:{label:"Password",type:"password",ngShow:"ldap_user == false",addRequired:!0,editRequired:!1,ngChange:"clearPWConfirm('password_confirm')",autocomplete:!1,chkPass:!0},password_confirm:{label:"Confirm Password",type:"password",ngShow:"ldap_user == false",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"password",autocomplete:!1},is_superuser:{label:"Superuser (User has full system administration privileges.)",type:"checkbox",trueValue:"true",falseValue:"false","default":"false",ngShow:"current_user['is_superuser'] == true"},ldap_user:{label:"Created by LDAP",type:"checkbox",readonly:!0}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{credentials:{type:"collection",title:"Credentials",iterator:"credential",open:!1,actions:{add:{ngClick:"add('credentials')",icon:"icon-plus",label:"Add",awToolTip:"Add a credential for this user"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('credentials', credential.id, credential.name)",icon:"icon-edit",awToolTip:"Edit the credential","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('credentials', credential.id, credential.name, 'credentials')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the credential"}}},permissions:{type:"collection",title:"Permissions",iterator:"permission",open:!1,actions:{add:{ngClick:"add('permissions')",icon:"icon-plus",label:"Add",awToolTip:"Add a permission for this user",ngShow:"PermissionAddAllowed"}},fields:{name:{key:!0,label:"Name",ngClick:"edit('permissions', permission.id, permission.name)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('permissions', permission.id, permission.name)",icon:"icon-edit",awToolTip:"Edit the permission","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('permissions', permission.id, permission.name, 'permissions')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the permission",ngShow:"PermissionAddAllowed"}}},admin_of_organizations:{type:"collection",title:"Admin of Organizations",iterator:"adminof",open:!1,base:"/organizations",actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}},organizations:{type:"collection",title:"Organizations",iterator:"organization",open:!1,actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}},teams:{type:"collection",title:"Teams",iterator:"team",open:!1,actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}},projects:{type:"collection",title:"Projects",iterator:"project",open:!1,actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}}}}),angular.module("InventoryGroupsHelpDefinition",[]).value("InventoryGroupsHelp",{story:{hdr:"Building your inventory",width:510,height:560,steps:[{intro:"Start by creating a group:",img:{src:"groups001.png",maxWidth:338,maxHeight:222},box:'Click on the groups list (the left side of the page) to add a new group.',autoOffNotice:!0},{intro:"Enter group properties:",img:{src:"groups002.png",maxWidth:443,maxHeight:251},box:'Enter the group name, a description and any inventory variables. Variables can be entered using either JSON or YAML syntax. For more on inventory variables, see docs.ansible.com/intro_inventory.html'},{intro:"Cloud inventory: select cloud source",img:{src:"groups003.png",maxWidth:412,maxHeight:215},box:'For a cloud inventory, choose the cloud provider from the list and select your credentials. If you have not already setup credentials for the provider, you will need to do that first on the Credentials tab.'},{intro:"Cloud inventory: synchronize Tower with the cloud",img:{src:"groups004.png",maxWidth:261,maxHeight:221},box:'To pull the cloud inventory into Tower, initiate an inventory sync by clicking .'},{intro:"Groups can have subgroups:",img:{src:"groups005.png",maxWidth:430,maxHeight:206},box:'
        First, select a group. Then click to create a new group. The new group will be added to the selected group.
        '},{intro:"Copy or move groups:",img:{src:"groups006.png",maxWidth:263,maxHeight:211},box:'
        Copy or move a group by dragging and dropping its name onto another group name. A dialog will appear asking if the group should be coppied or moved.
        '},{intro:"Adding hosts:",img:{src:"groups007.png",maxWidth:466,maxHeight:178},box:'

        First, select a Group. Then click on the hosts list (the right side of the page) to create a host. The new host will be part of the selected group.

        Note hosts cannot be added to the All Hosts group.

        '}]}}),angular.module("AccessHelper",["RestServices","Utilities","ngCookies"]).factory("CheckAccess",["$rootScope","Alert","Rest","GetBasePath","ProcessErrors",function(a,b,c,d,e){return function(b){var d=a.current_user,f=b.scope; +d.is_superuser?f.PermissionAddAllowed=!0:d.related.admin_of_organizations&&(c.setUrl(d.related.admin_of_organizations),c.get().success(function(a){f.PermissionAddAllowed=a.results.length>0?!0:!1}).error(function(a,b){e(f,a,b,null,{hdr:"Error!",msg:"Call to "+d.related.admin_of_organizations+" failed. DELETE returned status: "+b})}))}}]).factory("CheckLicense",["$rootScope","$cookieStore","Alert","$location","Authorization",function(a,b,c,d,e){return function(){var d,f,g="success",h=b.get("license"),i='

        To purchase a license or extend an existing license visit the Ansible online store, or visit support.ansible.com for assistance.

        ';h&&!e.licenseTested()&&(h.tested=!0,b.remove("license"),b.put("license",h),a.license_tested=!0,void 0!==h.valid_key&&h.valid_key===!1?(g="alert-danger",d="License Error",f="

        There is a problem with the /etc/awx/license file on your Tower server. Check to make sure Tower can access the file.

        "+i,c(d,f,g,null,!1,!0)):void 0!==h.demo&&h.demo===!0&&(g="alert-info",d="Tower Demo",f="

        Thank you for trying Ansible Tower. You can use this edition to manage up to 10 hosts free.

        "+i,c(d,f,g)),void 0!==h.date_expired&&h.date_expired===!0?(g="alert-info",d="License Expired",f="

        Your Ansible Tower License has expired and is no longer compliant. You can continue, but you will be unable to add any additional hosts.

        "+i,c(d,f,g)):void 0!==h.date_warning&&h.date_warning===!0&&(g="alert-info",d="License Warning",f="

        Your Ansible Tower license is about to expire!

        "+i,c(d,f,g)),void 0!==h.free_instances&&parseInt(h.free_instances)<=0&&(g="alert-info",d="License Warning",f="

        Your Ansible Tower license has reached capacity for the number of managed hosts allowed. You will not be able to add any additional hosts.

        "+i,c(d,f,g,null,!0)))}}]),angular.module("ChildrenHelper",["RestServices","Utilities"]).factory("ToggleChildren",[function(){return function(a){function b(a){var b;for(i[a].ngicon="fa fa-minus-square-o node-toggle",b=a+1;b10?10:i,i=3>i?3:i,f.fields[h].rows=i);break;case"results":if(a.event_data&&a.event_data.res&&void 0===a.event_data.res[h])delete f.fields[h];else if(Array.isArray(a.event_data.res[h])&&0!==a.event_data.res[h].length){for(j="",c=0;c10?10:i,i=3>i?3:i,f.fields[h].rows=i)}else delete f.fields[h];break;case"module_name":case"module_args":a.event_data&&a.event_data.res&&(void 0===a.event_data.res.invocation||void 0===a.event_data.res.invocation[h])&&delete f.fields[h]}b=d.inject(f,{mode:"edit",modal:!0,related:!1}),d.reset(),b.formModalAction=function(){$("#form-modal").modal("hide")},b.formModalActionLabel="OK",b.formModalCancelShow=!1,b.formModalInfo="View JSON",$("#form-modal .btn-success").removeClass("btn-success").addClass("btn-none"),$("#form-modal").addClass("skinny-modal"),b.formModalHeader=a.event_display.replace(/^\u00a0*/g,""),b.formModalInfoAction=function(){var b=g,c=b.inject(l,{mode:"edit",modal:!0,related:!1,modal_selector:"#form-modal2",modal_body_id:"form-modal2-body",modal_title_id:"formModal2Header"});b.reset(),c.formModal2Header=a.event_display.replace(/^\u00a0*/g,""),c.event_data=JSON.stringify(a.event_data,null," "),c.formModal2ActionLabel="OK",c.formModal2CancelShow=!1,c.formModal2Info=!1,c.formModalInfo="View JSON",c.formModal2Action=function(){$("#form-modal2").modal("hide")},$("#form-modal2 .btn-success").removeClass("btn-success").addClass("btn-none")},"string"==typeof a.event_data.res&&(b.traceback=a.event_data.res);for(h in f.fields)switch(h){case"status":b.status=a.failed?"error":a.changed?"changed":"success";break;case"created":n=new Date(a.created),b.created=k(n);break;case"host":a.summary_fields&&a.summary_fields.host&&(b.host=a.summary_fields.host.name);break;case"id":case"task":case"play":b[h]=a[h];break;case"start":case"end":a.event_data&&a.event_data.res&&!m(a.event_data.res[h])&&(b[h]=a.event_data.res[h]);break;case"results":if(Array.isArray(a.event_data.res[h])&&a.event_data.res[h].length>0){for(j="",c=0;c button.',"alert-info"):(f("start"),a.setUrl(l.related.inventory_source),a.get().success(function(a){var b=a.related.current_update?a.related.current_update:a.related.last_update;d({group_name:a.summary_fields.group.name,last_update:b,license_error:a.summary_fields.last_update&&a.summary_fields.last_update.license_error?!0:!1,tree_id:j,group_id:k,parent_scope:i})}).error(function(a,c){f("stop"),b(i,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+l.related.inventory_source+" POST returned status: "+c})})))}}]).factory("GetHostsStatusMsg",[function(){return function(a){var b,c,d,e=a.active_failures,f=a.total_hosts;return e>0?(b=f+(1===f?" host":" hosts")+". "+e+" with failed jobs.",d="true",c=!0):(c=!1,0===f?(b="Group contains 0 hosts.",d="na"):(b=f+(1===f?" host":" hosts")+". No job failures",d="false")),{tooltip:b,failures:c,"class":d}}}]).factory("GetSyncStatusMsg",[function(){return function(a){var b,c,d,e=a.status,f="",g="Start sync process";switch(b=e,c="icon-cloud-"+b,e){case"never updated":b="never",c="icon-cloud-na disabled",d='Sync not performed. Click to start it now.';break;case"none":case"":f="btn-disabled",b="n/a",c="icon-cloud-na disabled",d='Cloud source not configured. Click to update.',g=d;break;case"failed":d="Sync failed. Click to view log.";break;case"successful":d="Sync completed. Click to view log.";break;case"updating":d="Sync running"}return{"class":c,tooltip:d,status:b,launch_class:f,launch_tip:g}}}]).factory("SourceChange",["GetBasePath","CredentialList","LookUpInit","Empty",function(a,b,c,d){return function(e){var f,g,h=e.scope,i=e.form;d(h.source)||("file"===h.source.value?h.sourcePathRequired=!0:(h.sourcePathRequired=!1,h.source_path="",h[i.name+"_form"].source_path.$setValidity("required",!0)),"rax"===h.source.value?(h.source_region_choices=h.rax_regions,$("#s2id_group_source_regions").select2("data",[{id:"all",text:"All"}])):"ec2"===h.source.value&&(h.source_region_choices=h.ec2_regions,$("#s2id_group_source_regions").select2("data",[{id:"all",text:"All"}])),("rax"===h.source.value||"ec2"===h.source.value)&&(f="rax"===h.source.value?"rax":"aws",g=a("credentials")+"?cloud=true&kind="+f,c({url:g,scope:h,form:i,list:b,field:"credential"})))}}]).factory("GroupsCancelUpdate",["Rest","ProcessErrors","Alert","Wait","Find",function(a,b,c,d,e){return function(f){var g,h=f.scope,i=f.tree_id;h.removeCancelUpdate&&h.removeCancelUpdate(),h.removeCancelUpdate=h.$on("CancelUpdate",function(e,f){a.setUrl(f),a.post().success(function(){d("stop"),c("Inventory Sync Cancelled",'Your request to cancel the sync process was submitted to the task manger. Click the button to monitor the status.',"alert-info")}).error(function(a,c){d("stop"),b(h,a,c,null,{hdr:"Error!",msg:"Call to "+f+" failed. POST status: "+c})})}),h.removeCheckCancel&&h.removeCheckCancel(),h.removeCheckCancel=h.$on("CheckCancel",function(e,f,g){var i=g?g:f;i+="cancel/",a.setUrl(i),a.get().success(function(a){a.can_cancel?h.$emit("CancelUpdate",i):(d("stop"),c("Cancel Inventory Sync",'Either you do not have access or the sync process completed.
        Click the button to view the latest status.',"alert-info"))}).error(function(a,c){d("stop"),b(h,a,c,null,{hdr:"Error!",msg:"Call to "+i+" failed. GET status: "+c})})}),g=e({list:h.groups,key:"id",val:i}),h.selected_tree_id=g.id,h.selected_group_id=g.group_id,!g||"updating"!==g.status&&"pending"!==g.status?c("Cancel Inventory Sync",'The sync process completed. Click the to view the latest status.',"alert-info"):(d("start"),a.setUrl(g.related.inventory_source),a.get().success(function(a){h.$emit("CheckCancel",a.related.last_update,a.related.current_update)}).error(function(a,c){d("stop"),b(h,a,c,null,{hdr:"Error!",msg:"Call to "+g.related.inventory_source+" failed. GET status: "+c})}))}}]).factory("GroupsAdd",["$rootScope","$location","$log","$routeParams","Rest","Alert","GroupForm","GenerateForm","Prompt","ProcessErrors","GetBasePath","ParseTypeChange","GroupsEdit","Wait","GetChoices","GetSourceTypeOptions","LookUpInit","BuildTree","SourceChange","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){return function(b){var c,d=b.inventory_id,i=void 0!==b.group_id?b.group_id:null,m=b.scope,q=null!==i?k("groups")+i+"/children/":k("inventory")+d+"/groups/",u=g,v=h,w=v.inject(u,{mode:"add",modal:!0,related:!1,show_modal:!1});$("#form-modal .btn-none").removeClass("btn-none").addClass("btn-success"),w.formModalActionLabel="Save",w.formModalCancelShow=!0,w.parseType="yaml",w.source=null,l(w),v.reset(),w.removeAddTreeRefreshed&&w.removeAddTreeRefreshed(),w.removeAddTreeRefreshed=w.$on("GroupTreeRefreshed",function(){a.formModalHeader=null,a.formModalCancleShow=null,a.formModalActionLabel=null,n("stop"),$("#form-modal").modal("hide"),w.removeAddTreeRefreshed()}),w.removeSaveComplete&&w.removeSaveComplete(),w.removeSaveComplete=w.$on("SaveComplete",function(a,b,c){c||(w.searchCleanup&&w.searchCleanup(),w.formModalActionDisabled=!1,r({scope:m,inventory_id:d,refresh:!0,new_group_id:b}),t())}),w.removeFormSaveSuccess&&w.removeFormSaveSuccess(),w.removeFormSaveSuccess=w.$on("formSaveSuccess",function(a,b,c){var d,g,h,i,k=!1,l={};if(null!==w.source.value&&""!==w.source.value){for(l.group=b,l.source=w.source.value,l.source_path=w.source_path,l.credential=w.credential,l.overwrite=w.overwrite,l.overwrite_vars=w.overwrite_vars,l.update_on_launch=w.update_on_launch,d=$("#s2id_group_source_regions").select2("data"),g=[],h=0;h"+A.summary_fields.group.name+". Use the Refresh button to monitor the status.","alert-info"):o({scope:A,group_id:d,url:A.group_update_url,group_name:A.name,group_source:A.source.value})},A.sourceChange=function(){v({scope:A,form:g})}}}]).factory("GroupsDelete",["$rootScope","$location","$log","$routeParams","Rest","Alert","GroupForm","GenerateForm","Prompt","ProcessErrors","GetBasePath","Wait","BuildTree","Find",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return function(a){var b,c=a.scope,d=a.tree_id,f=a.inventory_id,g=n({list:c.groups,key:"id",val:d}),h=k("inventory")+f+"/groups/";b=function(){$("#prompt-modal").on("hidden.bs.modal",function(){l("start")}),$("#prompt-modal").modal("hide"),e.setUrl(h),e.post({id:g.group_id,disassociate:1}).success(function(){$("#prompt-modal").off(),c.$emit("GroupDeleteCompleted")}).error(function(a,b){l("stop"),j(c,a,b,null,{hdr:"Error!",msg:"Call to "+h+" failed. POST returned status: "+b})})},i({hdr:"Delete Group",body:"

        Are you sure you want to delete group "+g.name+"?

        ",action:b,"class":"btn-danger"})}}]).factory("ShowUpdateStatus",["$rootScope","$location","$log","$routeParams","Rest","Alert","GenerateForm","Prompt","ProcessErrors","GetBasePath","FormatDate","InventoryStatusForm","Wait","Empty","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(a){function b(a){var b,d;return b=a.match(/\n/g),d=b?b.length:1,d>c?c:d}var c,d,h,j,n,p,q,r=a.group_name,s=a.last_update,t=g,u=l,v=a.license_error;void 0===s||null===s||""===s?(m("stop"),f("Missing Configuration","The selected group is not configured for inventory sync. Edit the group and provide Source information.","alert-info")):(d='
        \n
        \n',$("#inventory-modal-container").empty().append(d),h=t.inject(u,{mode:"edit",id:"form-container",breadCrumbs:!1,related:!1}),j=$(document).width(),n=$("body").height(),j>1199?(p=675,q=750>n?n-20:750,c=18):1199>=j&&j>=768?(p=550,q=620>n?n-15:620,c=12):(p=j-20,q=500>n?n:500,c=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:p,height:q,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#inventory-modal-container").empty(),o()},open:function(){m("stop")}}),e.setUrl(s),e.get().success(function(a){for(var c in u.fields)a[c]&&(h[c]="created"===c?k(new Date(a[c])):a[c]);h.license_error=v,h.status_rows=b(a.status),h.stdout_rows=b(a.result_stdout),h.traceback_rows=b(a.result_traceback),$("#status-modal-dialog").dialog("open")}).error(function(a,b){$("#form-modal").modal("hide"),i(h,a,b,null,{hdr:"Error!",msg:"Failed to retrieve last update: "+s+". GET status: "+b})}))}}]),angular.module("HostsHelper",["RestServices","Utilities","ListGenerator","HostListDefinition","SearchHelper","PaginationHelpers","ListGenerator","AuthService","HostsHelper","InventoryHelper","RelatedSearchHelper","InventoryFormDefinition","SelectionHelper","HostGroupsFormDefinition"]).factory("SetEnabledMsg",[function(){return function(a){a.enabledToolTip=a.has_inventory_sources?a.enabled?"Host is available":"Host is not available":a.enabled?"Host is available. Click to toggle.":"Host is not available. Click to toggle."}}]).factory("SetHostStatus",["SetEnabledMsg",function(a){return function(b){b.activeFailuresLink="/#/hosts/"+b.id+"/job_host_summaries/?inventory="+b.inventory+"&host_name="+encodeURI(b.name),b.has_active_failures===!0?(b.badgeToolTip="Most recent job failed. Click to view jobs.",b.active_failures="failed"):b.has_active_failures===!1&&null===b.last_job?(b.has_active_failures="none",b.badgeToolTip="No job data available.",b.active_failures="n/a"):b.has_active_failures===!1&&null!==b.last_job&&(b.badgeToolTip="Most recent job successful. Click to view jobs.",b.active_failures="success"),b.enabled_flag=b.enabled,a(b)}}]).factory("SetStatus",["SetEnabledMsg","Empty",function(a,b){return function(c){function d(a){return a.length>25?a.substr(0,25)+"...":a}function e(a){var b,c,e;if(a.has_active_failures===!0||a.has_active_failures===!1&&null!==a.last_job)if(a.has_active_failures===!0?(a.badgeToolTip="Most recent job failed. Click to view jobs.",a.active_failures="failed"):(a.badgeToolTip="Most recent job successful. Click to view jobs.",a.active_failures="success"),a.summary_fields.recent_jobs.length>0){for(e=a.summary_fields.recent_jobs.sort(function(a,b){return-1*(a-b)}),h="Recent Jobs",g='\n',g+="\n",g+="\n",g+="\n",g+="\n",g+="\n",g+="\n",b=0;b\n",g+='\n",g+='\n',g+='\n',g+='\n",g+="\n";g+="\n",g+="
        ID\n",g+='Status\n',g+="ViewName\n",g+="
        '+c.id+"Events Hosts'+d(c.name)+"
        \n"}else h="No job data",g="

        No recent job data available for this host.

        ";else a.has_active_failures===!1&&null===a.last_job&&(a.has_active_failures="none",a.badgeToolTip="No job data available.",a.active_failures="n/a");a.job_status_html=g,a.job_status_title=h}var f,g,h,i=c.scope,j=c.host;if(b(j))for(f=0;fAre you sure you want to delete host "+j+" from group "+n.name+"?

        ":"

        Are you sure you want to delete host "+j+"?

        ",g({hdr:"Delete Host",body:c,action:b,"class":"btn-danger"})}}]).factory("EditHostGroups",["$rootScope","$location","$log","$routeParams","Rest","Alert","GenerateForm","Prompt","ProcessErrors","GetBasePath","HostsReload","ParseTypeChange","Wait",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(a){var b,c,d,f,h,l=a.host_id,n=a.inventory_id,o=g,p=[];for(c='
        \n',c+='
        \n',c+="\n",c+='\n',c+="
        \n",c+='
        \n',c+="\n",c+='\n',c+="
        \n",c+="
        \n",c+='
        \n',c+='
        \n',c+='\n',c+='\n',c+="

        (move selected groups)

        \n",c+="
        \n",c+="
        \n",d=j("hosts")+l+"/",f=o.inject(null,{mode:"edit",modal:!0,related:!1,html:c}),b=0;bGroups',f.formModalCancelShow=!0,f.formModalActionDisabled=!0,$("#form-modal .btn-none").removeClass("btn-none").addClass("btn-success"),f.hostGroupChangeRemove&&f.hostGroupChangeRemove(),f.hostGroupChangeRemove=f.$on("hostGroupChange",function(){p.pop(),0===p.length&&(h=function(){setTimeout(function(){m("stop")},500)},k({scope:f,inventory_id:n,group_id:f.group_id,action:h}))}),f.formModalAction=function(){var a,b,c;for($("#form-modal").modal("hide"),m("start"),a=0;a0?(f.assignedGroups=null,f.leftButtonDisabled=!0,f.rightButtonDisabled=!1):f.rightButtonDisabled=!0},f.rightChange=function(){null!==f.assignedGroups&&f.assignedGroups.length>0?(f.selectedGroups=null,f.leftButtonDisabled=!1,f.rightButtonDisabled=!0):f.leftButtonDisabled=!0},f.moveLeft=function(){var a,b,c,d;for(a=0;af.available_groups[b].name.toLowerCase()&&f.assignedGroups[a].name.toLowerCase()f.host_groups[b].name.toLowerCase()&&f.selectedGroups[a].name.toLowerCase()0){for(j("stop"),u+='
        \n',u+=w?w:"",o=0;o\n',u+='\n",u+='
        \n',u+='A value is required!\n',u+='\n',u+="
        \n",u+="
        \n",n=l.associated,l=p.fields[l.associated],q[n]="",u+='
        \n',u+='\n",u+='
        \n',u+='A value is required!\n',l.awPassMatch&&(u+='Must match Password value\n'),u+='\n',u+="
        \n",u+="
        \n";u+="\n",m=angular.element(document.getElementById("password-body")),m.html(u),c(m.contents())(q),$("#password-modal").modal(),$("#password-modal").on("shown.bs.modal",function(){$("#password-body").find('input[type="password"]:first').focus()})}else q.startJob()}}]).factory("SubmitJob",["PromptPasswords","$compile","Rest","$location","GetBasePath","CredentialList","LookUpInit","CredentialForm","ProcessErrors","JobTemplateForm","Wait",function(a,b,c,d,e,f,g,h,i,j,k){return function(b){function l(b){var e,f,g;m.credentialWatchRemove&&m.credentialWatchRemove(),e=(new Date).toISOString(),f=b.related.jobs?b.related.jobs:b.related.job_template+"jobs/",g=o?o:b.name,k("start"),c.setUrl(f),c.post({name:g+" "+e,description:b.description,job_template:b.id,inventory:b.inventory,project:b.project,playbook:b.playbook,credential:b.credential,forks:b.forks,limit:b.limit,verbosity:b.verbosity,extra_vars:b.extra_vars}).success(function(b){m.job_id=b.id,b.passwords_needed_to_start.length>0?a({scope:m,passwords:b.passwords_needed_to_start,start_url:b.related.start,form:h}):(c.setUrl(b.related.start),c.post().success(function(){k("stop");var a=d.path().replace(/^\//,"").split("/")[0];"jobs"===a?m.refresh():d.path("/jobs")}).error(function(a,b){i(m,a,b,null,{hdr:"Error!",msg:"Failed to start job. POST returned status: "+b})}))}).error(function(a,b){k("stop"),i(m,a,b,null,{hdr:"Error!",msg:"Failed to create job. POST returned status: "+b})})}var m=b.scope,n=b.id,o=b.template?b.template:null,p=d.path().replace(/^\//,"").split("/")[0],q=e(p)+n+"/";k("start"),c.setUrl(q),c.get().success(function(a){m.credential="",""===a.credential||null===a.credential?(k("stop"),m.credentialWatchRemove&&m.credentialWatchRemove(),m.credentialWatchRemove=m.$watch("credential",function(b,c){b!==c&&""!==m.credential&&null!==m.credential&&void 0!==m.credential&&(a.credential=m.credential,l(a))}),g({scope:m,form:j,current_item:null,list:f,field:"credential",hdr:"Credential Required"}),m.lookUpCredential()):l(a)}).error(function(a,b){i(m,a,b,null,{hdr:"Error!",msg:"Failed to get job template details. GET returned status: "+b})})}}]).factory("ProjectUpdate",["PromptPasswords","$compile","Rest","$location","GetBasePath","ProcessErrors","Alert","ProjectsForm","Wait",function(a,b,c,d,e,f,g,h,i){return function(b){var d=b.scope,j=b.project_id,k=e("projects")+j+"/update/";d.removeUpdateSubmitted&&d.removeUpdateSubmitted(),d.removeUpdateSubmitted=d.$on("UpdateSubmitted",function(){i("stop"),g("Update Started","The request to start the SCM update process was submitted. To monitor the update status, refresh the page by clicking the Refresh button.","alert-info"),d.refresh()}),d.removeSCMSubmit&&d.removeSCMSubmit(),d.removeSCMSubmit=d.$on("SCMSubmit",function(b,c,e){a({scope:d,passwords:c,start_url:k,form:h,extra_html:e})}),i("start"),c.setUrl(k),c.get().success(function(a){var b,c;if(i("stop"),a.can_update){for(c="",b=0;b\n',c+='\n',c+='
        \n',c+=' button.',"alert-info"),d.removeHostReloadComplete&&d.removeHostReloadComplete()}),d.removeUpdateSubmitted&&d.removeUpdateSubmitted(),d.removeUpdateSubmitted=d.$on("UpdateSubmitted",function(a,b){"started"===b&&(d.refreshGroups?(d.selected_tree_id=k,d.selected_group_id=i,d.refreshGroups()):d.refresh&&d.refresh(),d.$emit("HostReloadComplete"))}),d.removeInventorySubmit&&d.removeInventorySubmit(),d.removeInventorySubmit=d.$on("InventorySubmit",function(b,c,f){a({scope:d,passwords:c,start_url:e,form:h,extra_html:f})}),j("start"),c.setUrl(e),c.get().success(function(a){a.can_update?d.$emit("InventorySubmit",a.passwords_needed_to_update):(j("stop"),g("Permission Denied","You do not have access to run the update. Please contact your system administrator.","alert-danger"))}).error(function(a,b){j("stop"),f(d,a,b,null,{hdr:"Error!",msg:"Failed to get inventory_source details. "+e+"GET status: "+b})})}}]),angular.module("JobsHelper",["Utilities","FormGenerator","JobSummaryDefinition","InventoryHelper"]).factory("JobStatusToolTip",[function(){return function(a){var b;switch(a){case"successful":case"success":b="There were no failed tasks.";break;case"failed":b="Some tasks encountered errors.";break;case"canceled":b="Stopped by user request.";break;case"new":b="In queue, waiting on task manager.";break;case"waiting":b="SCM Update or Inventory Update is executing.";break;case"pending":b="Not in queue, waiting on task manager.";break;case"running":b="Playbook tasks executing."}return b}}]).factory("ShowJobSummary",["Rest","Wait","GetBasePath","FormatDate","ProcessErrors","GenerateForm","JobSummary","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h){return function(i){function j(a){var b=a.match(/\n/g),c=b?b.length:1;return c>p?20:c}var k,l,m,n,o,p,q,r,s=i.job_id,t=f,u=g;r='
        \n',$("#inventory-modal-container").empty().append(r),k=t.inject(u,{mode:"edit",id:"form-container",breadCrumbs:!1,related:!1}),l=$(document).width(),m=$("body").height(),l>1199?(n=675,o=750>m?m-20:750,p=20):1199>=l&&l>=768?(n=550,o=620>m?m-15:620,p=15):(n=l-20,o=500>m?m:500,p=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:n,height:o,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#inventory-modal-container").empty(),h()},open:function(){b("stop")}}),b("start"),q=c("jobs")+s+"/",a.setUrl(q),a.get().success(function(a){var b;k.id=a.id,k.name=a.name,k.status=a.status,k.result_stdout=a.result_stdout,k.result_traceback=a.result_traceback,k.stdout_rows=j(k.result_stdout),k.traceback_rows=j(k.result_traceback),b=new Date(a.created),k.created=d(b),$("#status-modal-dialog").dialog("open")}).error(function(a,b){e(k,a,b,null,{hdr:"Error!",msg:"Attempt to load job failed. GET returned status: "+b})})}}]),angular.module("LookUpHelper",["RestServices","Utilities","SearchHelper","PaginationHelpers","ListGenerator","ApiLoader"]).factory("LookUpInit",["Alert","Rest","GenerateList","SearchInit","PaginateInit","GetBasePath","FormatDate","Empty",function(a,b,c,d,e,f,g,h){return function(b){var i,j,k,l,m=b.scope,n=b.form,o=b.list,p=b.field,q=b.postAction;i=b.url?b.url:f("inventories"===o.name?"inventory":o.name),j=o.iterator.charAt(0).toUpperCase()+o.iterator.substring(1),k=b.hdr?b.hdr:"Select "+j,l=/\/$/.test(i)?i+"?":i+"&",l+=n.fields[p].sourceField+"__iexact=:value",$('input[name="'+n.fields[p].sourceModel+"_"+n.fields[p].sourceField+'"]').attr("data-url",l),$('input[name="'+n.fields[p].sourceModel+"_"+n.fields[p].sourceField+'"]').attr("data-source",p),m["lookUp"+j]=function(){var b=c,f=b.inject(o,{mode:"lookup",hdr:k});$("#lookup-modal").on("hidden.bs.modal",function(){f.searchCleanup&&f.searchCleanup(),(""===m[p]||null===m[p])&&(m[n.fields[p].sourceModel+"_"+n.fields[p].sourceField]="",m.$$phase||m.$digest())}),f.selectAction=function(){var c,d=!1;for(c=0;c5?f[j+"_page"]-5:1,e=f[j+"_page"]<6?10<=f[j+"_num_pages"]?10:f[j+"_num_pages"]:f[j+"_page"]+4=c;c++)f[j+"_page_range"].push(c)}}]).factory("RelatedPaginateInit",["RefreshRelated","$cookieStore","Wait",function(a,b,c){return function(d){var e,f=d.scope,g=d.relatedSets,h=d.pageSize?d.pageSize:10;for(e in g)f[g[e].iterator+"_url"]=g[e].url,f[g[e].iterator+"_page"]=0,f[g[e].iterator+"_page_size"]=h;f.getPage=function(b,d,e){var g=f[e+"_url"].replace(/.page\=\d+/,""),h=/\/$/.test(g)?"?":"&";g+=h+"page="+b,g+=f[e+"SearchParams"]?"&"+f[e+"SearchParams"]+"&page_size="+f[e+"_page_size"]:"page_size="+f[e+"PageSize"],c("start"),a({scope:f,set:d,iterator:e,url:g})},f.pageIsActive=function(a,b){return a===f[b+"_page"]?"active":""},f.changePageSize=function(c,d){f[d+"_page"]=1;var e=f[d+"_url"];b.put(d+"_page_size",f[d+"_page_size"]),e=e.replace(/\/\?.*$/,"/"),e+=f[d+"SearchParams"]?"?"+f[d+"SearchParams"]+"&page_size="+f[d+"_page_size"]:"?page_size="+f[d+"_page_size"],a({scope:f,set:c,iterator:d,url:e})}}}]).factory("PaginateInit",["Refresh","$cookieStore","Wait",function(a,b,c){return function(b){var d=b.scope,e=b.list,f=b.iterator?b.iterator:e.iterator,g=b.mode?b.mode:null;d[f+"_page"]=b.page?b.page:1,d[f+"_url"]=b.url,d[f+"_mode"]=g,d[f+"_page_size"]=b.pageSize?b.pageSize:"lookup"===g?5:20,d.getPage=function(b,e,f){var g=d[f+"_url"].replace(/.page\=\d+/,""),h=/\/$/.test(g)?"?":"&";g+=h+"page="+b,g+=d[f+"SearchParams"]?"&"+d[f+"SearchParams"]+"&page_size="+d[f+"_page_size"]:"page_size="+d[f+"PageSize"],c("start"),a({scope:d,set:e,iterator:f,url:g})},d.pageIsActive=function(a,b){return a===d[b+"_page"]?"active":""},d.changePageSize=function(b,e){d[e+"_page"]=0;var f=d[e+"_url"].replace(/\?page_size\=\d+/,""),g=/\/$/.test(f)?"?":"&";f+=d[e+"SearchParams"]?g+d[e+"SearchParams"]+"&page_size="+d[e+"_page_size"]:g+"page_size="+d[e+"_page_size"],c("start"),a({scope:d,set:b,iterator:e,url:f})}}}]),angular.module("ParseHelper",[]).factory("ParseTypeChange",[function(){return function(a,b,c){var d=b?b:"variables",e=c?c:"parseType";a.blockParseTypeWatch=!1,a.blockVariableDataWatch=!1,a["remove"+d+"Watch"]&&a["remove"+d+"Watch"](),a["remove"+d+"Watch"]=a.$watch(e,function(b,c){var e;if(b!==c)if("json"===b)if(a[d]&&!/^---$/.test(a[d]))try{e=jsyaml.load(a[d]),a[d]=JSON.stringify(e,null," ")}catch(f){}else a[d]="{}";else if(a[d]&&!/^\{\}$/.test(a[d]))try{e=JSON.parse(a[d]),a[d]=jsyaml.safeDump(e)}catch(f){}else a[d]="---"})}}]),angular.module("PermissionsHelper",[]).factory("PermissionCategoryChange",[function(){return function(a){var b=a.scope,c=a.reset;"Inventory"===b.category?(b.projectrequired=!1,b.permissionTypeHelp="
        \n
        Read
        \n
        Only allow the user or team to view the inventory.
        \n
        Write
        \n
        Allow the user or team to modify hosts and groups contained in the inventory, add new hosts and groups, and perform inventory sync operations.\n
        Admin
        \n
        Allow the user or team full access to the inventory. This includes reading, writing, deletion of the inventory and inventory sync operations.
        \n
        \n"):(b.projectrequired=!0,b.permissionTypeHelp="
        \n
        Run
        \n
        Allow the user or team to perform a live deployment of the project against the inventory. In Run mode modules will be executed, and changes to the inventory will occur.
        \n
        Check
        \n
        Only allow the user or team to deploy the project against the inventory as a dry-run operation. In Check mode, module operations will only be simulated. No changes will occur.
        \n
        \n"),c&&(b.permission_type="Inventory"===b.category?"read":"run")}}]),angular.module("ProjectPathHelper",["RestServices","Utilities"]).factory("GetProjectPath",["Alert","Rest","GetBasePath","ProcessErrors",function(a,b,c,d){return function(a){function e(a){var b,c,d=[],e=[];for(b=0;b
        \n',$("#projects-modal-container").empty().append(b),c=q.inject(r,{mode:"edit",id:"form-container",related:!1,breadCrumbs:!1}),q.reset(),d=$(document).width(),f=$("body").height(),d>1199?(h=675,j=750>f?f-20:750,n=20):1199>=d&&d>=768?(h=550,j=620>f?f-15:620,n=15):(h=d-20,j=500>f?f:500,n=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:h,height:j,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#projects-modal-container").empty()},open:function(){m("stop")}}),e.setUrl(p),e.get().success(function(a){var b,d=a;for(b in r.fields)d[b]?c[b]="created"===b?k(new Date(d[b])):d[b]:d.summary_fields.project[b]&&(c[b]=d.summary_fields.project[b]);$("#status-modal-dialog").dialog({title:d.summary_fields.project.name+" Status"}).dialog("open")}).error(function(a,b){$("#form-modal").modal("hide"),i(c,a,b,r,{hdr:"Error!",msg:"Failed to retrieve status of project: "+o+". GET status: "+b})})}}]),angular.module("SelectionHelper",["Utilities","RestServices"]).factory("SelectionInit",["Rest","Alert","ProcessErrors","ReturnToCaller","Wait",function(a,b,c,d,e){return function(b){var f,g=b.scope,h=b.list,i=b.url,j=b.returnToCaller;f=void 0!==b.selected?b.selected:[],g.formModalActionDisabled=!0,g.disableSelectBtn=!0,g["toggle_"+h.iterator]=function(a,b){var c,d,e;for(c=0;c0?(g.formModalActionDisabled=!1,g.disableSelectBtn=!1):(g.formModalActionDisabled=!0,g.disableSelectBtn=!0)},g.finishSelection=function(){function b(){f=[],void 0!==j?d(j):($("#form-modal").modal("hide"),g.$emit("modalClosed"))}function k(b){a.post(b).success(function(a,b){m.push({result:"success",data:a,status:b}),g.$emit("callFinished")}).error(function(a,b,c){m.push({result:"error",data:a,status:b,headers:c}),g.$emit("callFinished")})}a.setUrl(i);var l,m=[];if(g.formModalActionDisabled=!0,g.disableSelectBtn=!0,e("start"),g.callFinishedRemove&&g.callFinishedRemove(),g.callFinishedRemove=g.$on("callFinished",function(){var a,d=0;if(m.length===f.length){for(e("stop"),a=0;a0)for(l=0;lh)h++,setTimeout(1e3,e());else if("success"===g.status)return d(a)}var f,g={},h=0;return null===c.apiDefaults||void 0===c.apiDefaults?(f="/api/v1/",b.setUrl(f),b.get().success(function(a){var b,d=a;for(b in d)switch(b){case"organizations":d[b].iterator="organization";break;case"jobs":d[b].iterator="job";break;case"users":d[b].iterator="user";break;case"teams":d[b].iterator="team";break;case"hosts":d[b].iterator="host";break;case"groups":d[b].iterator="group";break;case"projects":d[b].iterator="project";break;case"inventories":d[b].iterator="inventory"}c.apiDefaults=d,g={status:"success"}}).error(function(a,b){g={status:"error",msg:"Call to "+f+" failed. GET returned status: "+b}}),e()):d(a)}}]),angular.module("InventoryHelper",["RestServices","Utilities","OrganizationListDefinition","ListGenerator","AuthService","InventoryHelper","InventoryFormDefinition","ParseHelper","SearchHelper"]).factory("WatchInventoryWindowResize",["ApplyEllipsis",function(a){return function(){var b;$(window).resize(function(){clearTimeout(b),b=setTimeout(function(){$("#groups_table .name-column").each(function(){var a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%";$(this).find(".group-name").css({width:e})}),a("#groups_table .group-name a"),a("#hosts_table .host-name a")},100)})}}]).factory("SaveInventory",["InventoryForm","Rest","Alert","ProcessErrors","LookUpInit","OrganizationList","GetBasePath","ParseTypeChange","Wait",function(a,b,c,d,e,f,g,h,i){return function(e){var f,h,j,k=e.scope,l=a,m=g("inventory");i("start");try{if(h="json"===k.inventoryParseType?JSON.parse(k.inventory_variables):jsyaml.load(k.inventory_variables),"object"!=typeof h)throw"failed to return an object!";j={};for(f in l.fields)"inventory_variables"!==f&&(l.fields[f].realName?j[l.fields[f].realName]=k[f]:j[f]=k[f]);b.setUrl(m+k.inventory_id+"/"),b.put(j).success(function(a){k.inventory_variables?(b.setUrl(a.related.variable_data),b.put(h).success(function(){i("stop"),k.$emit("InventorySaved")}).error(function(a,b){d(k,a,b,l,{hdr:"Error!",msg:"Failed to update inventory varaibles. PUT returned status: "+b})})):k.$emit("InventorySaved")}).error(function(a,b){d(k,a,b,l,{hdr:"Error!",msg:"Failed to update inventory. POST returned status: "+b})})}catch(n){i("stop"),c("Error","Error parsing inventory variables. Parser returned: "+n)}}}]).factory("EditInventoryProperties",["InventoryForm","GenerateForm","Rest","Alert","ProcessErrors","LookUpInit","OrganizationList","GetBasePath","ParseTypeChange","SaveInventory","Wait","Store","SearchInit",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(n){var o,p=n.scope,q=n.inventory_id,r=b,s=a,t={},u=l("CurrentSearchParams");s.well=!1,o=r.inject(s,{mode:"edit",modal:!0,related:!1,modal_show:!1}),s.well=!0,i(o,"inventory_variables","inventoryParseType"),o.inventoryParseType="yaml",o.formModalActionLabel="Save",o.formModalCancelShow=!0,o.formModalInfo=!1,o.formModalHeader="Inventory Properties",k("start"),c.setUrl(h("inventory")+q+"/"),c.get().success(function(a){var b,c;for(b in s.fields){if("inventory_variables"===b){if($.isEmptyObject(a.variables)||"{}"===a.variables||"null"===a.variables||""===a.variables)o.inventory_variables="---";else try{c=JSON.parse(a.variables),o.inventory_variables=jsyaml.safeDump(c)}catch(e){d("Variable Parse Error","Attempted to parse variables for inventory: "+q+". Parse returned: "+e),console&&(console.log(e),console.log("data:"),console.log(a.variables)),o.inventory_variables="---"}t.inventory_variables=o.variables}else"inventory_name"===b?(o[b]=a.name,t[b]=o[b]):"inventory_description"===b?(o[b]=a.description,t[b]=o[b]):a[b]&&(o[b]=a[b],t[b]=o[b]);s.fields[b].sourceModel&&a.summary_fields&&a.summary_fields[s.fields[b].sourceModel]&&(o[s.fields[b].sourceModel+"_"+s.fields[b].sourceField]=a.summary_fields[s.fields[b].sourceModel][s.fields[b].sourceField],t[s.fields[b].sourceModel+"_"+s.fields[b].sourceField]=a.summary_fields[s.fields[b].sourceModel][s.fields[b].sourceField])}f({scope:o,form:s,current_item:o.organization,list:g,field:"organization"}),k("stop"),$("#form-modal").modal("show")}).error(function(a,b){e(o,a,b,null,{hdr:"Error!",msg:"Failed to get inventory: "+q+". GET returned: "+b})}),o.removeInventorySaved&&o.removeInventorySaved(),o.removeInventorySaved=o.$on("InventorySaved",function(){$("#form-modal").modal("hide"),o.searchCleanp&&o.searchCleanup(),m({scope:p,set:u.set,list:u.list,url:u.defaultUrl,iterator:u.iterator,sort_order:u.sort_order,setWidgets:!1}),p.$emit("RefreshInventories")}),o.cancelModal=function(){o.searchCleanp&&o.searchCleanup(),m({scope:p,set:u.set,list:u.list,url:u.defaultUrl,iterator:u.iterator,sort_order:u.sort_order,setWidgets:!1})},o.formModalAction=function(){p.inventory_id=q,p.inventory_name=o.inventory_name,j({scope:o})}}}]),angular.module("md5Helper",["RestServices","Utilities"]).factory("md5Setup",[function(){return function(a){var b=a.scope,c=a.master,d=a.check_field,e=a.default_val;b[d]=e,c[d]=e,b.genMD5=function(a){var c=new Date;b[a]=$.md5("AnsibleWorks"+c.getTime())},b.toggleCallback=function(a){"false"===b.allow_callbacks&&(b[a]="")},b.selectAll=function(a){$('input[name="'+a+'"]').focus().select()}}}]),angular.module("RefreshRelatedHelper",["RestServices","Utilities","PaginationHelpers"]).factory("RefreshRelated",["ProcessErrors","Rest","Wait","PageRangeSetup",function(a,b,c,d){return function(e){var f=e.scope,g=e.set,h=e.iterator,i=e.url;b.setUrl(i),b.get().success(function(a){d({scope:f,count:a.count,next:a.next,previous:a.previous,iterator:h}),f[g]=a.results,f[h+"Loading"]=!1,f[h+"HoldInput"]=!1,c("stop"),f.$emit("related"+g)}).error(function(b,c){a(f,b,c,null,{hdr:"Error!",msg:"Failed to retrieve "+g+". GET returned status: "+c})})}}]),angular.module("RefreshHelper",["RestServices","Utilities","PaginationHelpers"]).factory("Refresh",["ProcessErrors","Rest","Wait","Empty","PageRangeSetup",function(a,b,c,d,e){return function(d){var f=d.scope,g=d.set,h=d.iterator,i=d.url;f.current_url=i,b.setUrl(i),b.get().success(function(a){var b,d;for(e({scope:f,count:a.count,next:a.next,previous:a.previous,iterator:h}),f[h+"Loading"]=!1,b=1;3>=b;b++)d=1===b?"":b,f[h+"HoldInput"+d]=!1;f[g]=a.results,window.scrollTo(0,0),c("stop"),f.$emit("PostRefresh")}).error(function(b,c){f[h+"HoldInput"]=!1,a(f,b,c,null,{hdr:"Error!",msg:"Failed to retrieve "+g+". GET returned status: "+c})})}}]),angular.module("RelatedSearchHelper",["RestServices","Utilities","RefreshRelatedHelper"]).factory("RelatedSearchInit",["$timeout","Alert","Rest","RefreshRelated","Wait",function(a,b,c,d,e){return function(a){function b(a){var b,c,d,e;for(e in h.related)if("tree"!==h.related[e].type&&(void 0===a||a===h.related[e].iterator)){b=h.related[e].iterator;for(d in h.related[e].fields)if(h.related[e].fields[d].key){f[b+"SearchField"]=d,f[b+"SearchFieldLabel"]=h.related[e].fields[d].label;break}f[b+"SortOrder"]=null,f[b+"SearchType"]="icontains",f[b+"SearchTypeLabel"]="Contains",f[b+"SearchValue"]=null,f[b+"SelectShow"]=!1,f[b+"ShowStartBtn"]=!0,f[b+"HideAllStartBtn"]=!1,c=f[b+"SearchField"],!h.related[e].fields[c].searchType||"boolean"!==h.related[e].fields[c].searchType&&"select"!==h.related[e].fields[c].searchType||(f[b+"SelectShow"]=!0,f[b+"SearchSelectOpts"]=h.fields[c].searchOptions),h.related[e].fields[c].searchType&&"gtzero"===h.related[e].fields[c].searchType&&(f[b+"InputHide"]=!0)}}var c,f=a.scope,g=a.relatedSets,h=a.form;b(),f.resetSearch=function(a){b(a),f.search(a)},f.setSearchField=function(a,b,c){var d,e;for(e in h.related)h.related[e].iterator===a&&(d=h.related[e].fields[b]);f[a+"SearchFieldLabel"]=c,f[a+"SearchField"]=b,f[a+"SearchValue"]="",f[a+"SelectShow"]=!1,f[a+"InputHide"]=!1,f[a+"ShowStartBtn"]=!0,void 0!==d.searchType&&"gtzero"===d.searchType&&(f[a+"InputHide"]=!0,f[a+"ShowStartBtn"]=!1),void 0===d.searchType||"boolean"!==d.searchType&&"select"!==d.searchType||(f[a+"SelectShow"]=!0,f[a+"SearchSelectOpts"]=d.searchOptions),void 0!==d.searchType&&"int"===d.searchType&&(f[a+"SearchType"]="int"),f.search(a)},f.setSearchType=function(a,b,c){f[a+"SearchTypeLabel"]=c,f[a+"SearchType"]=b,f.search(a)},f.startSearch=function(a,b){13===a.keyCode&&f.search(b)},f.search=function(a){e("start"),f[a+"Loading"]=!0,f[a+"HoldInput"]=!0,f[a+"SearchValue"]&&(f[a+"ShowStartBtn"]=!1),"host"===a&&"has_active_failures"===f.hostSearchField&&(f.hostFailureFilter=f.hostSearchSelectValue&&1===f.hostSearchSelectValue.value?!0:!1);var b,i,j,k,l;for(i in g)if(g[i].iterator===a){j=i,k=g[i].url;for(b in h.related[i].fields)h.related[i].fields[b].key&&(l=h.related[i].fields[b].desc?"-"+b:b);break}l=null===f[a+"SortOrder"]?l:f[a+"SortOrder"],c=h.related[j].fields[f[a+"SearchField"]],f[a+"SelectShow"]===!1&&""!==f[a+"SearchValue"]&&void 0!==f[a+"SearchValue"]||f[a+"SelectShow"]&&f[a+"SearchSelectValue"]||c.searchType&&"gtzero"===c.searchType?(f[a+"SearchParams"]=c.sourceModel?c.sourceModel+"__"+c.sourceField+"__":c.searchField?c.searchField+"__":f[a+"SearchField"]+"__",f[a+"SearchParams"]+=!c.searchType||"int"!==c.searchType&&"boolean"!==c.searchType?c.searchType&&"gtzero"===c.searchType?"gt=0":f[a+"SearchType"]+"=":"int=",!c.searchType||"boolean"!==c.searchType&&"select"!==c.searchType?(void 0===c.searchType||"gtzero"===c.searchType)&&(f[a+"SearchParams"]+=encodeURI(f[a+"SearchValue"])):f[a+"SearchParams"]+=f[a+"SearchSelectValue"].value,f[a+"SearchParams"]+=l?"&order_by="+encodeURI(l):""):f[a+"SearchParams"]=l?"order_by="+encodeURI(l):"",f[a+"Page"]=0,k+=k.match(/\/$/)?"?":"&",k+=f[a+"SearchParams"],k+=f[a+"PageSize"]?"&page_size="+f[a+"PageSize"]:"",d({scope:f,set:j,iterator:a,url:k})},f.sort=function(a,b){var c,d,e,g;$("."+a+" .list-header").each(function(){if($(this).attr("id")!==a+"-"+b+"-header"){var c=$(this).find("i");c.attr("class","icon-sort")}}),d=$("#"+a+"-"+b+"-header i"),e="",d.hasClass("icon-sort")?(d.removeClass("icon-sort"),d.addClass("icon-sort-up")):d.hasClass("icon-sort-up")?(d.removeClass("icon-sort-up"),d.addClass("icon-sort-down"),e="-"):d.hasClass("icon-sort-down")&&(d.removeClass("icon-sort-down"),d.addClass("icon-sort-up"));for(g in h.related)h.related[g].iterator===a&&(c=h.related[g].fields[b].sourceModel?e+h.related[g].fields[b].sourceModel+"__"+h.related[g].fields[b].sourceField:e+b);f[a+"SortOrder"]=c,f.search(a)}}}]),angular.module("SearchHelper",["RestServices","Utilities","RefreshHelper"]).factory("SearchInit",["Alert","Rest","Refresh","$location","GetBasePath","Empty","$timeout","Wait","Store",function(a,b,c,d,e,f,g,h,i){return function(a){function b(a){var b,c,d,e;e=void 0===a||1===a?"":a,l[p+"SearchField"+e]="",l[p+"SearchFieldLabel"+e]="";for(c in o.fields)if((void 0===o.fields[c].searchWidget&&1===a||o.fields[c].searchWidget===a)&&o.fields[c].key){o.fields[c].sourceModel?(d=o.fields[c].sourceModel+"__"+o.fields[c].sourceField,r=o.fields[c].desc?"-"+d:d):r=o.fields[c].desc?"-"+c:c,(void 0===o.fields[c].searchable||o.fields[c].searchable===!0)&&(l[p+"SearchField"+e]=c,l[p+"SearchFieldLabel"+e]=o.fields[c].label);break}if(f(l[p+"SearchField"+e]))for(c in o.fields)if((void 0===o.fields[c].searchWidget&&1===a||o.fields[c].searchWidget===a)&&(void 0===o.fields[c].searchable||o.fields[c].searchable===!0)){l[p+"SearchField"+e]=c,l[p+"SearchFieldLabel"+e]=o.fields[c].label;break}l[p+"SearchType"+e]="icontains",l[p+"SearchTypeLabel"+e]="Contains",l[p+"SearchParams"+e]="",l[p+"SearchValue"+e]="",l[p+"SelectShow"+e]=!1,l[p+"HideSearchType"+e]=!1,l[p+"InputDisable"+e]=!1,l[p+"ExtraParms"+e]="",l[p+"ShowStartBtn"+e]=!0,l[p+"HideAllStartBtn"+e]=!1,l[p+"SearchPlaceholder"+e]=o.fields[l[p+"SearchField"+e]]&&o.fields[l[p+"SearchField"+e]].searchPlaceholder?l[o.fields[l[p+"SearchField"+e]].searchPlaceholder]?l[o.fields[l[p+"SearchField"+e]].searchPlaceholder]:o.fields[l[p+"SearchField"+e]].searchPlaceholder:"Search",l[p+"InputDisable"+e]=o.fields[l[p+"SearchField"+e]]&&"all"===o.fields[l[p+"SearchField"+e]].searchObject?!0:!1,b=l[p+"SearchField"+e],o.fields[b]&&(!o.fields[b].searchType||"boolean"!==o.fields[b].searchType&&"select"!==o.fields[b].searchType||(l[p+"SelectShow"+e]=!0,l[p+"SearchSelectOpts"+e]=o.fields[b].searchOptions),o.fields[b].searchType&&"int"===o.fields[b].searchType&&(l[p+"HideSearchType"+e]=!0),o.fields[b].searchType&&"gtzero"===o.fields[b].searchType&&(l[p+"InputHide"+e]=!0))}var e,g,j,k,l=a.scope,m=a.set,n=a.url,o=a.list,p=a.iterator?a.iterator:o.iterator,q=a.setWidgets===!1?!1:!0,r=a.sort_order||"";if(q)for(e=o.searchWidgets?o.searchWidgets:1,g=1;e>=g;g++)j=1===g?"":g,$("#search-widget-container"+j)&&b(g);k={set:m,defaultUrl:n,list:o,iterator:p,sort_order:r},i("CurrentSearchParams",k),l.setSearchField=function(a,b,c,d){var e=void 0===d||1===d?"":d;l[a+"SearchFieldLabel"+e]=c,l[a+"SearchField"+e]=b,l[a+"SearchValue"+e]="",l[a+"SelectShow"+e]=!1,l[a+"HideSearchType"+e]=!1,l[a+"InputHide"+e]=!1,l[a+"SearchType"+e]="icontains",l[a+"InputDisable"+e]="all"===o.fields[b].searchObject?!0:!1,l[a+"ShowStartBtn"+e]=!0,l[a+"SearchPlaceholder"+e]=o.fields[l[a+"SearchField"+e]]&&o.fields[l[a+"SearchField"+e]].searchPlaceholder?l[o.fields[l[a+"SearchField"+e]].searchPlaceholder]?l[o.fields[l[a+"SearchField"+e]].searchPlaceholder]:o.fields[l[a+"SearchField"+e]].searchPlaceholder:"Search",o.fields[b].searchType&&"gtzero"===o.fields[b].searchType?(l[a+"InputDisable"+e]=!0,l[a+"ShowStartBtn"+e]=!1,l.search(a)):o.fields[b].searchSingleValue?(l[a+"InputDisable"+e]=!0,l[a+"SearchValue"+e]=o.fields[b].searchValue,l[a+"SearchSelectValue"+e]="boolean"===o.fields[b].searchType&&"true"===o.fields[b].searchValue?{value:1}:"boolean"===o.fields[b].searchType&&"false"===o.fields[b].searchValue?{value:0}:{value:o.fields[b].searchValue},l[a+"ShowStartBtn"+e]=!1):"in"===o.fields[b].searchType?(l[a+"SearchType"+e]="in",l[a+"SearchValue"+e]=o.fields[b].searchValue,l[a+"InputDisable"+e]=!0,l[a+"ShowStartBtn"+e]=!1):!o.fields[b].searchType||"boolean"!==o.fields[b].searchType&&"select"!==o.fields[b].searchType&&"select_or"!==o.fields[b].searchType?o.fields[b].searchType&&"int"===o.fields[b].searchType?l[a+"SearchType"+e]="int":o.fields[b].searchType&&"isnull"===o.fields[b].searchType&&(l[a+"SearchType"+e]="isnull",l[a+"InputDisable"+e]=!0,l[a+"SearchValue"+e]="true",l[a+"ShowStartBtn"+e]=!1):(l[a+"SelectShow"+e]=!0,l[a+"SearchSelectOpts"+e]=o.fields[b].searchOptions),l.search(a)},l.resetSearch=function(a){var c,e=o.searchWidgets?o.searchWidgets:1;for(c=1;e>=c;c++)b(c);window.location="/#"+d.path(),l.search(a)},l.removeDoSearch&&l.removeDoSearch(),l.removeDoSearch=l.$on("doSearch",function(a,b,d,e){l[b+"Loading"]=void 0===e||e===!0?!0:!1;var f,g=n;l[b+"Page"]=d?parseInt(d)-1:0,l[b+"SearchParams"]&&(g+=/\/$/.test(g)?"?"+l[b+"SearchParams"]:"&"+l[b+"SearchParams"]),f=/\/$/.test(g)?"?":"&",g+=l[b+"_page_size"]?f+"page_size="+l[b+"_page_size"]:"",d&&(f=/\/$/.test(g)?"?":"&",g+=f+"page="+d),l[b+"ExtraParms"]&&(f=/\/$/.test(g)?"?":"&",g+=f+l[b+"ExtraParms"]),g=g.replace(/\&\&/,"&"),c({scope:l,set:m,iterator:b,url:g})}),l.removePrepareSearch&&l.removePrepareSearch(),l.removePrepareSearch=l.$on("prepareSearch",function(a,b,c,d,e){h("start"),l[b+"SearchParams"]="";var f,g,i=o.searchWidgets?o.searchWidgets:1;for(f=1;i>=f;f++)g=1===f?"":f,$("#search-widget-container"+g)&&o.fields[l[b+"SearchField"+g]]&&o.fields[l[b+"SearchField"+g]].searchObject&&("all"!==o.fields[l[b+"SearchField"+g]].searchObject?(l[b+"HideAllStartBtn"+g]=!1,l[b+"SearchValue"+g]?(l[b+"ShowStartBtn"+g]=!1,l[b+"SearchParams"]+=o.fields[l[b+"SearchField"+g]].searchOnID?"&"+o.fields[l[b+"SearchField"+g]].searchObject+"__id="+l[b+"SearchValue"+g]:"&"+o.fields[l[b+"SearchField"+g]].searchObject+"__name__icontains="+l[b+"SearchValue"+g]):(l[b+"ShowStartBtn"+g]=!0,l[b+"SearchParams"]+="&"+o.fields[l[b+"SearchField"+g]].searchField+"="+o.fields[l[b+"SearchField"+g]].searchObject)):l[b+"HideAllStartBtn"+g]=!0);l.$emit("prepareSearch2",b,c,d,e)}),l.removePrepareSearch2&&l.removePrepareSearch2(),l.removePrepareSearch2=l.$on("prepareSearch2",function(a,b,c,d,e){var g,h,i=o.searchWidgets?o.searchWidgets:1;for(g=1;i>=g;g++)h=1===g?"":g,l[b+"HoldInput"+h]=!0,$("#search-widget-container"+h)&&o.fields[l[b+"SearchField"+h]]&&!o.fields[l[b+"SearchField"+h]].searchObject&&(l[b+"ShowStartBtn"+h]=l[b+"SearchValue"+h]?!1:!0,(!l[b+"SelectShow"+h]&&!f(l[b+"SearchValue"+h])||l[b+"SelectShow"+h]&&l[b+"SearchSelectValue"+h]||o.fields[l[b+"SearchField"+h]]&&"gtzero"===o.fields[l[b+"SearchField"+h]].searchType)&&(l[b+"SearchParams"]+=o.fields[l[b+"SearchField"+h]].searchField?"&"+o.fields[l[b+"SearchField"+h]].searchField+"__":o.fields[l[b+"SearchField"+h]].sourceModel?"&"+o.fields[l[b+"SearchField"+h]].sourceModel+"__"+o.fields[l[b+"SearchField"+h]].sourceField+"__":"select"!==o.fields[l[b+"SearchField"+h]].searchType||""!==l[b+"SearchSelectValue"+h].value&&null!==l[b+"SearchSelectValue"+h].value?"&"+l[b+"SearchField"+h]+"__":"&"+l[b+"SearchField"+h]+"__",l[b+"SearchParams"]+=!o.fields[l[b+"SearchField"+h]].searchType||"int"!==o.fields[l[b+"SearchField"+h]].searchType&&"boolean"!==o.fields[l[b+"SearchField"+h]].searchType?o.fields[l[b+"SearchField"+h]].searchType&&"gtzero"===o.fields[l[b+"SearchField"+h]].searchType?"gt=0":"select"!==o.fields[l[b+"SearchField"+h]].searchType||""!==l[b+"SearchSelectValue"+h].value&&null!==l[b+"SearchSelectValue"+h].value?l[b+"SearchType"+h]+"=":"iexact=":"int=",!o.fields[l[b+"SearchField"+h]].searchType||"boolean"!==o.fields[l[b+"SearchField"+h]].searchType&&"select"!==o.fields[l[b+"SearchField"+h]].searchType?(!o.fields[l[b+"SearchField"+h]].searchType||o.fields[l[b+"SearchField"+h]].searchType&&"or"!==o.fields[l[b+"SearchField"+h]].searchType&&"gtzero"!==o.fields[l[b+"SearchField"+h]].searchType)&&(l[b+"SearchParams"]+=encodeURI(l[b+"SearchValue"+h])):l[b+"SearchParams"]+=l[b+"SearchSelectValue"+h].value));("inventory"===b&&l.inventoryFailureFilter||"host"===b&&l.hostFailureFilter)&&(l[b+"SearchParams"]+="&has_active_failures=true"),r&&(l[b+"SearchParams"]+=l[b+"SearchParams"]?"&":"",l[b+"SearchParams"]+="order_by="+encodeURI(r)),l.$emit("doSearch",b,c,d,e)}),l.startSearch=function(a,b){13===a.keyCode&&l.search(b)},l.search=function(a,b,c){c=void 0===c?!0:!1,c&&(l[m]=[]),l.$emit("prepareSearch",a,b,c)},l.sort=function(a){$(".list-header").each(function(){if($(this).attr("id")!==a+"-header"){var b=$(this).find("i");b.attr("class","fa fa-sort")}});var b=$("#"+a+"-header i"),c="";b.hasClass("fa-sort")?(b.removeClass("fa-sort"),b.addClass("fa-sort-up")):b.hasClass("fa-sort-up")?(b.removeClass("fa-sort-up"),b.addClass("fa-sort-down"),c="-"):b.hasClass("fa-sort-down")&&(b.removeClass("fa-sort-down"),b.addClass("fa-sort-up")),r=o.fields[a].searchField?c+o.fields[a].searchField:o.fields[a].sortField?c+o.fields[a].sortField:o.fields[a].sourceModel?c+o.fields[a].sourceModel+"__"+o.fields[a].sourceField:c+a,l.search(o.iterator)},l.searchCleanup=function(){l.removeDoSearch(),l.removePrepareSearch(),l.removePrepareSearch2()}}}]),angular.module("TeamHelper",["RestServices","Utilities","OrganizationListDefinition","SearchHelper","PaginationHelpers","ListGenerator"]).factory("SetTeamListeners",["Alert","Rest",function(a,b){return function(a){var c=a.scope,d=a.set,e=a.iterator;c.$on("TeamResultFound",function(a,b,f){var g,h,i,j;if(f.length===b.length){for(i="organization",j="organization_name",g=0;gSelect existing users by clicking each user or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        ",base:"users",index:!0,hover:!0,fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},actions:{},fieldActions:{}}),angular.module("CloudCredentialsListDefinition",[]).value("CloudCredentialList",{name:"cloudcredentials",iterator:"cloudcredential",selectTitle:"Add Cloud Credentials",editTitle:"Cloud Credentials",selectInstructions:"

        Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        Create a brand new credential by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",excludeModal:!1},team:{label:"Team",ngBind:"credential.team_name",sourceModel:"team",sourceField:"name",excludeModal:!0},user:{label:"User",ngBind:"credential.user_username",sourceModel:"user",sourceField:"username",excludeModal:!0}},actions:{add:{mode:"all",ngClick:"addCredential()","class":"btn-sm",awToolTip:"Create a new credential"}},fieldActions:{edit:{ngClick:"editCredential(credential.id)",icon:"fa-edit",label:"Edit","class":"btn-sm",awToolTip:"Edit credential",dataPlacement:"top"},"delete":{ngClick:"deleteCredential(credential.id, credential.name)",icon:"fa-trash-o",label:"Delete","class":"btn-sm",awToolTip:"Delete credential",dataPlacement:"top"}}}),angular.module("CredentialsListDefinition",[]).value("CredentialList",{name:"credentials",iterator:"credential",selectTitle:"Add Credentials",editTitle:"Credentials",selectInstructions:"

        Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        Create a brand new credential by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",excludeModal:!1},kind:{label:"Type",searchType:"select",searchOptions:[],excludeModal:!0,nosort:!0}},actions:{add:{mode:"all",ngClick:"addCredential()",awToolTip:"Create a new credential"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{ngClick:"editCredential(credential.id)",icon:"fa-edit",label:"Edit","class":"btn-sm",awToolTip:"Edit credential",dataPlacement:"top"},"delete":{ngClick:"deleteCredential(credential.id, credential.name)",icon:"fa-trash",label:"Delete","class":"btn-sm",awToolTip:"Delete credential",dataPlacement:"top"}}}),angular.module("GroupListDefinition",[]).value("GroupList",{name:"groups",iterator:"group",selectTitle:"Copy Groups",editTitle:"Groups",index:!0,well:!1,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{help:{awPopOver:"Choose groups by clicking on each group you wish to add. Click the Select button to add the groups to the selected inventory group.",dataContainer:"#form-modal .modal-content",mode:"all",awToolTip:"Click for help",dataTitle:"Adding Groups"}},fieldActions:{edit:{label:"Edit",ngClick:"editGroup(group.id)",icon:"icon-edit","class":"btn-xs",awToolTip:"Edit group",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteGroup(group.id, group.name)",icon:"icon-trash","class":"btn-xs",awToolTip:"Delete group",dataPlacement:"top"}}}),angular.module("HomeGroupListDefinition",[]).value("HomeGroupList",{name:"home_groups",iterator:"group",editTitle:"Groups",index:!0,hover:!0,well:!0,fields:{name:{key:!0,label:"Group",ngClick:"editGroup(group.id, group.inventory)",columnClass:"col-lg-4 col-md3 col-sm-3 col-xs-6 ellipsis"},inventory_name:{label:"Inventory",sourceModel:"inventory",sourceField:"name",columnClass:"col-lg-3 col-md2 col-sm-2 hidden-xs elllipsis",linkTo:"{{ /#/inventories/' + group.inventory + '/' }}"},source:{label:"Source",searchType:"select",searchOptions:[{name:"ec2",value:"ec2"},{name:"none",value:""},{name:"rax",value:"rax"}],sourceModel:"inventory_source",sourceField:"source",searchOnly:!0},has_external_source:{label:"Has external source?",searchType:"in",searchValue:"ec2,rax",searchOnly:!0,sourceModel:"inventory_source",sourceField:"source"},has_active_failures:{label:"Has failed hosts?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},last_update_failed:{label:"Update failed?",searchType:"select",searchSingleValue:!0,searchValue:"failed",searchOnly:!0,sourceModel:"inventory_source",sourceField:"status"},id:{label:"ID",searchOnly:!0}},fieldActions:{sync_status:{mode:"all",ngClick:"viewUpdateStatus(group.id, group.group_id)",awToolTip:"{{ group.status_tooltip }}",ngClass:"group.status_class",dataPlacement:"top"},failed_hosts:{mode:"all",awToolTip:"{{ group.hosts_status_tip }}",dataPlacement:"top",ngHref:"/#/inventories/{{ group.inventory }}/",iconClass:"{{ 'fa icon-failures-' + group.hosts_status_class }}"},group_update:{mode:"all",ngClick:"updateGroup(group.id)",awToolTip:"{{ group.launch_tooltip }}",ngShow:"(group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",ngClass:"group.launch_class",dataPlacement:"top"},cancel:{mode:"all",ngClick:"cancelUpdate(group.id)",awToolTip:"Cancel sync process","class":"red-txt",ngShow:"(group.status == 'running' || group.status == 'pending' || group.status == 'updating')",dataPlacement:"top"},edit:{label:"Edit",mode:"all",ngClick:"editGroup(group.id)",awToolTip:"Edit group",dataPlacement:"top"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("HomeHostListDefinition",[]).value("HomeHostList",{name:"hosts",iterator:"host",selectTitle:"Add Existing Hosts",editTitle:"Hosts",index:!0,hover:!0,well:!0,fields:{name:{key:!0,label:"Name",columnClass:"col-lg-4 col-md3 col-sm-3 col-xs-7 ellipsis",ngClick:"editHost(host.id, host.name)"},inventory_name:{label:"Inventory",sourceModel:"inventory",sourceField:"name",columnClass:"col-lg-3 col-md2 col-sm-2 hidden-xs elllipsis",linkTo:"{{ '/#/inventories/' + host.inventory }}"},enabled:{label:"Disabled?",searchSingleValue:!0,searchType:"boolean",searchValue:"false",searchOnly:!0},has_active_failures:{label:"Has failed jobs?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},has_inventory_sources:{label:"Has external source?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},id:{label:"ID",searchOnly:!0}},fieldActions:{enabled_flag:{iconClass:"{{ 'fa icon-enabled-' + host.enabled }}",dataPlacement:"top",awToolTip:"{{ host.enabledToolTip }}",dataTipWatch:"host.enabledToolTip",ngClick:"toggleHostEnabled(host.id, host.has_inventory_sources)"},active_failures:{awPopOver:"{{ host.job_status_html }}",dataTitle:"{{ host.job_status_title }}",awToolTip:"{{ host.badgeToolTip }}",awTipPlacement:"top",dataPlacement:"left",iconClass:"{{ 'fa icon-failures-' + host.has_active_failures }}"},edit:{label:"Edit",ngClick:"editHost(host.id)",icon:"icon-edit",awToolTip:"Edit host",dataPlacement:"top"}},actions:{stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("HostListDefinition",[]).value("HostList",{name:"hosts",iterator:"host",selectTitle:"Add Existing Hosts",editTitle:"Hosts",index:!0,well:!1,fields:{name:{key:!0,label:"Host Name",linkTo:"/inventories/{{ inventory_id }}/hosts/{{ host.id }}"},description:{label:"Description"}},actions:{help:{awPopOver:"Select hosts by clicking on each host you wish to add. Add the selected hosts to the group by clicking the Select button.",dataContainer:"#form-modal .modal-content",mode:"all",awToolTip:"Click for help",dataTitle:"Selecting Hosts"}},fieldActions:{edit:{label:"Edit",ngClick:"editHost({{ host.id }})",icon:"icon-edit","class":"btn-xs",awToolTip:"Edit host",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteHost(host.id, host.name)",icon:"icon-trash","class":"btn-xs",awToolTip:"Delete host",dataPlacement:"top"}}}),angular.module("InventoriesListDefinition",[]).value("InventoryList",{name:"inventories",iterator:"inventory",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},organization:{label:"Organization",ngBind:"inventory.summary_fields.organization.name",linkTo:"/#/organizations/{{ inventory.organization }}",sourceModel:"organization",sourceField:"name",excludeModal:!0},has_inventory_sources:{label:"Cloud sourced?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},has_active_failures:{label:"Failed hosts?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},inventory_sources_with_failures:{label:"Sync failures?",searchType:"gtzero",searchValue:"true",searchOnly:!0}},actions:{add:{mode:"all",ngClick:"addInventory()",awToolTip:"Create a new inventory"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",icon:"icon-comments-alt",mode:"all"}},fieldActions:{status:{ngHref:"inventory.status_link",iconClass:"{{ 'fa fa-cloud icon-cloud-' + inventory.status_class }}",awToolTip:"{{ inventory.status_tip }}",dataPlacement:"top"},failed_hosts:{ngHref:"inventory.failed_hosts_link",iconClass:"{{ 'fa icon-failures-' + inventory.failed_hosts_class }}",awToolTip:"{{ inventory.failed_hosts_tip }}",dataPlacement:"top"},edit:{label:"Edit",ngClick:"editInventoryProperties(inventory.id)",awToolTip:"Edit inventory",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteInventory(inventory.id, inventory.names')",awToolTip:"Delete inventory",dataPlacement:"top"}}}),angular.module("InventoryGroupsDefinition",[]).value("InventoryGroups",{name:"groups",iterator:"group",editTitle:"{{ inventory_name }}",showTitle:!1,well:!0,index:!1,hover:!1,hasChildren:!0,filterBy:"{ show: true }","class":"table-condensed table-no-border",fields:{name:{label:"Groups",key:!0,ngClick:"showHosts(group.id,group.group_id, false)",ngClass:"group.selected_class",hasChildren:!0,columnClass:"col-lg-9 col-md-9 col-sm-7 col-xs-7",nosort:!0,awDroppable:"{{ group.isDroppable }}",awDraggable:"{{ group.isDraggable }}",dataContainment:"#groups_table",dataTreeId:"{{ group.id }}",dataGroupId:"{{ group.group_id }}",dataType:"group"}},actions:{columnClass:"col-lg-3 col-md-3 col-sm-5 col-xs-5",create:{mode:"all",ngClick:"createGroup()",awToolTip:"Create a new group"},properties:{mode:"all",awToolTip:"Edit inventory properties",ngClick:"editInventoryProperties()"},refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refreshGroups()"},stream:{ngClick:"showGroupActivity()",awToolTip:"View Activity Stream",mode:"all"},help:{mode:"all",awToolTip:"Get help building your inventory",ngClick:"showGroupHelp()",id:"inventory-summary-help"}},fieldActions:{sync_status:{mode:"all",ngClick:"viewUpdateStatus(group.id, group.group_id)",ngShow:"group.id > 1",awToolTip:"{{ group.status_tooltip }}",dataTipWatch:"group.launch_tooltip",ngClass:"group.status_class",dataPlacement:"top"},failed_hosts:{mode:"all",awToolTip:"{{ group.hosts_status_tip }}",ngShow:"group.id > 1",dataPlacement:"top",ngClick:"showHosts(group.id, group.group_id, group.show_failures)",iconClass:"{{ 'fa icon-failures-' + group.hosts_status_class }}"},group_update:{mode:"all",ngClick:"updateGroup(group.id)",awToolTip:"{{ group.launch_tooltip }}",dataTipWatch:"group.launch_tooltip",ngShow:"group.id > 1 && (group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",ngClass:"group.launch_class",dataPlacement:"top"},cancel:{mode:"all",ngClick:"cancelUpdate({{ group.id }})",awToolTip:"Cancel sync process","class":"red-txt",ngShow:"group.id > 1 && (group.status == 'running' || group.status == 'pending' || group.status == 'updating')",dataPlacement:"top"},edit:{mode:"all",ngClick:"editGroup({{ group.group_id + ',' + group.id }})",awToolTip:"Edit group",ngShow:"group.id > 1",dataPlacement:"top"},"delete":{mode:"all",ngClick:"deleteGroup({{ group.id + ',' + group.group_id }})",awToolTip:"Delete group",ngShow:"group.id != 1",dataPlacement:"top"}}}),angular.module("InventoryHostsDefinition",[]).value("InventoryHosts",{name:"hosts",iterator:"host",editTitle:"{{ selected_group }}",showTitle:!1,well:!0,index:!1,hover:!1,hasChildren:!0,"class":"table-condensed table-no-border",fields:{name:{key:!0,label:"Hosts",ngClick:"editHost(host.id)",searchPlaceholder:"search_place_holder",columnClass:"col-lg-9 col-md-9 col-sm-7 col-xs-7",dataHostId:"{{ host.id }}",dataType:"host",awDraggable:"true"},enabled:{label:"Disabled?",searchSingleValue:!0,searchType:"boolean",searchValue:"false",searchOnly:!0},has_active_failures:{label:"Failed jobs?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0}},fieldActions:{enabled_flag:{iconClass:"{{ 'fa icon-enabled-' + host.enabled }}",dataPlacement:"top",awToolTip:"{{ host.enabledToolTip }}",dataTipWatch:"host.enabledToolTip",ngClick:"toggleHostEnabled(host.id, host.has_inventory_sources)"},active_failures:{awPopOver:"{{ host.job_status_html }}",dataTitle:"{{ host.job_status_title }}",awToolTip:"{{ host.badgeToolTip }}",awTipPlacement:"top",dataPlacement:"left",iconClass:"{{ 'fa icon-failures-' + host.has_active_failures }}"},edit:{ngClick:"editHost(host.id)",icon:"icon-edit",awToolTip:"Edit host",dataPlacement:"top"},"delete":{ngClick:"deleteHost(host.id, host.name)",icon:"icon-trash",awToolTip:"Delete host",dataPlacement:"top"}},actions:{columnClass:"col-lg-3 col-md-3 col-sm-5 col-xs-5",create:{mode:"all",ngClick:"createHost()",ngHide:"selected_tree_id == 1",awToolTip:"Create a new host"},stream:{ngClick:"showHostActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("JobEventsListDefinition",[]).value("JobEventList",{name:"jobevents",iterator:"jobevent",editTitle:"Job Events",index:!1,hover:!0,hasChildren:!0,filterBy:"{ show: true }",navigationLinks:{details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",active:!0,icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",icon:"icon-laptop"}},fields:{created:{label:"Created On",columnClass:"col-lg-1 col-md-1 hidden-sm hidden-xs",key:!0,nosort:!0,searchable:!1,link:!1},status:{label:"Status",showValue:!1,columnClass:"col-sm-1 col-xs-2 text-center",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}],nosort:!0,searchable:!1,ngClick:"viewJobEvent({{ jobevent.id }})",awToolTip:"{{ jobevent.statusBadgeToolTip }}",dataPlacement:"top",badgeIcon:"fa icon-job-{{ jobevent.status }}",badgePlacement:"left",badgeToolTip:"{{ jobevent.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgClick:"viewJobEvent({{ jobevent.id }})"},event_display:{label:"Event",hasChildren:!0,ngClick:"toggleChildren(jobevent.id, jobevent.related.children)",nosort:!0,searchable:!1,ngClass:"{{ jobevent.class }}",appendHTML:"jobevent.event_detail"},host:{label:"Host",ngBind:"jobevent.summary_fields.host.name",ngHref:"{{ jobevent.hostLink }}",searchField:"hosts__name",nosort:!0,searchOnly:!1,id:"job-event-host-header","class":"break",columnClass:"col-lg-2 hidden-sm hidden-xs"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"}},fieldActions:{columnClass:"col-sm-1 col-xs-2",view:{label:"View",ngClick:"viewJobEvent(jobevent.id)",awToolTip:"View event details",dataPlacement:"top"}}}),angular.module("JobHostDefinition",[]).value("JobHostList",{name:"jobhosts",iterator:"jobhost",editTitle:"All summaries",index:!0,hover:!0,navigationLinks:{ngHide:"host_id !== null",details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",active:!0,icon:"icon-laptop"}},fields:{job:{label:"Job ID",ngClick:"showJob(jobhost.job)",columnShow:"host_id !== null",key:!0,desc:!0},host:{label:"Host",key:!0,sourceModel:"host",sourceField:"name",ngBind:"jobhost.host_name",ngHref:"jobhost.hostLinkTo"},status:{label:"Status",badgeNgHref:"{{ jobhost.statusLinkTo }}",badgeIcon:"fa icon-job-{{ jobhost.status }}",badgePlacement:"left",badgeToolTip:"{{ jobhost.statusBadgeToolTip }}",badgeTipPlacement:"top",ngHref:"{{ jobhost.statusLinkTo }}",awToolTip:"{{ jobhost.statusBadgeToolTip }}",dataPlacement:"top",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}]},failed:{label:"Job failed?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0,nosort:!0},ok:{label:"Success",searchable:!1},changed:{label:"Changed",searchable:!1},failures:{label:"Failure",searchable:!0,searchLabel:"Contains failed events?",searchType:"gtzero"},dark:{label:"Unreachable",searchable:!0,searchType:"gtzero",searchLabel:"Contains unreachable hosts?"},skipped:{label:"Skipped",searchable:!1}},actions:{help:{awPopOver:"
        \n
        Success
        Tasks successfully executed on the host.
        \n
        Changed
        Actions taken on the host.
        \n
        Failure
        Tasks that failed on the host.
        \n
        Unreachable
        Times the ansible server could not reach the host.
        \n
        Skipped
        Tasks bypassed and not performed on the host due to prior task failure or the host being unreachable.
        \n
        \n",dataPlacement:"left",dataContainer:"body",mode:"all","class":"btn-xs btn-help",awToolTip:"Click for help",dataTitle:"Job Host Summary",id:"jobhost-help-button"},refresh:{mode:"all","class":"btn-xs",awToolTip:"Refresh the page",ngClick:"refresh()",ngShow:"host_id == null"}},fieldActions:{}}),angular.module("JobTemplatesListDefinition",[]).value("JobTemplateList",{name:"job_templates",iterator:"job_template",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{mode:"all",ngClick:"addJobTemplate()",basePaths:["job_templates"],awToolTip:"Create a new template"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",icon:"icon-comments-alt",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editJobTemplate(job_template.id)",icon:"icon-edit",awToolTip:"Edit template","class":"btn-default btn-xs",dataPlacement:"top"},submit:{label:"Launch",icon:"icon-rocket",mode:"all","class":"btn-xs btn-success",ngClick:"submitJob(job_template.id)",awToolTip:"Start a job using this template",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteJobTemplate(job_template.id, job_template.name)",icon:"icon-trash","class":"btn-danger btn-xs",awToolTip:"Delete template",dataPlacement:"top"}}}),angular.module("JobsListDefinition",[]).value("JobList",{name:"jobs",iterator:"job",editTitle:"Jobs",index:!1,hover:!0,"class":"jobs-table",fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},inventory:{label:"Inventory ID",searchType:"int",searchOnly:!0},created:{label:"Create On",link:!1,searchable:!1},job_template:{label:"Job Template",ngBind:"job.summary_fields.job_template.name",ngHref:"{{ '/#/job_templates/' + job.job_template }}",sourceModel:"job_template",sourceField:"name"},failed:{label:"Job failed?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0,nosort:!0},status:{label:"Status","class":"job-{{ job.status }}",searchType:"select",linkTo:"{{ job.statusLinkTo }}",searchOptions:[{name:"new",value:"new"},{name:"waiting",value:"waiting"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",value:"failed"},{name:"canceled",value:"canceled"}],badgeIcon:"fa icon-job-{{ job.status }}",badgePlacement:"left",badgeToolTip:"{{ job.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgHref:"{{ job.statusLinkTo }}",awToolTip:"{{ job.statusBadgeToolTip }}",dataPlacement:"top"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"}},fieldActions:{submit:{label:"Relaunch",icon:"icon-rocket",mode:"all",ngClick:"submitJob(job.id, job.summary_fields.job_template.name)",awToolTip:"Start the job",dataPlacement:"top"},cancel:{label:"Stop",mode:"all",ngClick:"deleteJob(job.id)",awToolTip:"Cancel a running or pending job",ngShow:"job.status == 'pending' || job.status == 'running' || job.status == 'waiting'",dataPlacement:"top"},"delete":{label:"Delete",mode:"all",ngClick:"deleteJob(job.id)",awToolTip:"Delete the job",ngShow:"job.status != 'pending' && job.status != 'running' && job.status != 'waiting'",dataPlacement:"top"},dropdown:{type:"DropDown",label:"View",icon:"fa-search-plus","class":"btn-default btn-xs",options:[{ngClick:"editJob(job.id, job.summary_fields.job_template.name)",label:"Status"},{ngClick:"viewEvents(job.id, job.summary_fields.job_template.name)",label:"Events",ngHide:"job.status == 'new'"},{ngClick:"viewSummary(job.id, job.summary_fields.job_template.name)",label:"Host Summary",ngHide:"job.status == 'new'"}]}}}),angular.module("OrganizationListDefinition",[]).value("OrganizationList",{name:"organizations",iterator:"organization",selectTitle:"Add Organizations",editTitle:"Organizations",hover:!0,index:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{mode:"all",ngClick:"addOrganization()",awToolTip:"Create a new organization"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editOrganization(organization.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit organization",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteOrganization(organization.id, organization.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete organization",dataPlacement:"top"}}}),angular.module("PermissionListDefinition",[]).value("PermissionList",{name:"permissions",iterator:"permission",selectTitle:"Add Permission",selectInstructions:'Click on a row to select it, and click Finished when done. Use the green button to create a new row.',editTitle:"Permissions",index:!0,well:!0,fields:{name:{key:!0,label:"Name",ngClick:"editPermission(permission.id)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},actions:{add:{mode:"all",ngClick:"addPermission()",awToolTip:"Add a new permission",ngShow:"PermissionAddAllowed"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editPermission(permission.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit permission",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deletePermission(permission.id, permission.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete permission",ngShow:"PermissionAddAllowed",dataPlacement:"top"}}}),angular.module("ProjectsListDefinition",[]).value("ProjectList",{name:"projects",iterator:"project",selectTitle:"Add Project",editTitle:"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 brand new project by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",columnClass:"hidden-sm hidden-xs",excludeModal:!0},scm_type:{label:"Type",searchType:"select",searchOptions:[],excludeModal:!0,nosort:!0},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:[],excludeModal:!0},last_updated:{label:"Last Updated",type:"date",excludeModal:!0,searchable:!1}},actions:{add:{mode:"all",ngClick:"addProject()",awToolTip:"Create a new project"},help:{awPopOver:"
        \n
        Updating
        A source control update is in progress.
        \n
        Never Updated
        This project has not yet been updated from source control.
        \n
        Failed
        An error occurred during the most recent source control update, click the status text for more information.
        \n
        Successful
        TThe latest source control update completed successfully.
        \n
        Missing
        The previously configured local project directory is missing.
        \n
        N/A
        The project is not linked to source control, so updates are not applicable.
        \n
        \n",dataPlacement:"left",dataContainer:"body",mode:"all",awToolTip:"Click for help",awTipPlacement:"top"},refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editProject(project.id)",awToolTip:"Edit project properties",dataPlacement:"top"},scm_update:{label:"Update",ngClick:"SCMUpdate(project.id)",awToolTip:"{{ project.scm_update_tooltip }}",ngClass:"project.scm_type_class",dataPlacement:"top"},cancel:{label:"Stop",ngClick:"cancelUpdate(project.id, project.name)",awToolTip:"Cancel a running SCM update process",ngShow:"project.status == 'updating'",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteProject(project.id, project.name)",awToolTip:"Permanently remove project from the database",ngShow:"project.status !== 'updating'",dataPlacement:"top"}}}),angular.module("StreamListDefinition",[]).value("StreamList",{name:"activities",iterator:"activity",editTitle:"Activity Stream",selectInstructions:"",index:!1,hover:!0,"class":"table-condensed",searchWidgets:3,fields:{timestamp:{label:"Event Time",key:!0,desc:!0,noLink:!0,searchable:!1},user:{label:"Initiated by",ngBindHtml:"activity.user",sourceModel:"actor",sourceField:"username",searchPlaceholder:"Username",searchWidget:1},description:{label:"Action",ngBindHtml:"activity.description",nosort:!0,searchable:!1,columnClass:"col-lg-7"},system_event:{label:"System event",searchOnly:!0,searchType:"isnull",sourceModel:"actor",sourceField:"username",searchWidget:1},all_objects:{label:"All",searchOnly:!0,searchObject:"all",searchPlaceholder:"All resources",searchWidget:2},credential_search:{label:"Credential",searchOnly:!0,searchObject:"credential",searchPlaceholder:"Credential name",searchWidget:2,searchField:"object1"},group_search:{label:"Group",searchOnly:!0,searchObject:"group",searchPlaceholder:"Group name",searchWidget:2,searchField:"object1"},host_search:{label:"Host",searchOnly:!0,searchObject:"host",searchPlaceholder:"Host name",searchWidget:2,searchField:"object1"},inventory_search:{label:"Inventory",searchOnly:!0,searchObject:"inventory",searchPlaceholder:"Inventory name",searchWidget:2,searchField:"object1"},job_template_search:{label:"Job Template",searchOnly:!0,searchObject:"job_template",searchPlaceholder:"Job template name",searchWidget:2,searchField:"object1"},job_search:{label:"Job",searchOnly:!0,searchObject:"job",searchPlaceholder:"Job id",searchOnID:!0,searchWidget:2,searchField:"object1"},organization_search:{label:"Organization",searchOnly:!0,searchObject:"organization",searchPlaceholder:"Organization name",searchWidget:2,searchField:"object1"},project_search:{label:"Project",searchOnly:!0,searchObject:"project",searchPlaceholder:"Project name",searchWidget:2,searchField:"object1"},user_search:{label:"User",searchOnly:!0,searchObject:"user",searchPlaceholder:"Primary username",searchWidget:2,searchField:"object1"},all_objects3:{label:"All",searchOnly:!0,searchObject:"all",searchPlaceholder:"All related resources",searchWidget:3,searchField:"object2"},credential_search3:{label:"Credential",searchOnly:!0,searchObject:"credential",searchPlaceholder:"Related credential name",searchWidget:3,searchField:"object2"},group_search3:{label:"Group",searchOnly:!0,searchObject:"group",searchPlaceholder:"Related group name",searchWidget:3,searchField:"object2"},host_search3:{label:"Host",searchOnly:!0,searchObject:"host",searchPlaceholder:"Related host name",searchWidget:3,searchField:"object2"},inventory_search3:{label:"Inventory",searchOnly:!0,searchObject:"inventory",searchPlaceholder:"Related inventory name",searchWidget:3,searchField:"object2"},job_search3:{label:"Job",searchOnly:!0,searchObject:"job",searchPlaceholder:"Job id",searchOnID:!0,searchWidget:3,searchField:"object2"},job_template_search3:{label:"Job Template",searchOnly:!0,searchObject:"job_template",searchPlaceholder:"Related job template name",searchWidget:3,searchField:"object2"},organization_search3:{label:"Organization",searchOnly:!0,searchObject:"organization",searchPlaceholder:"Related organization name",searchWidget:3,searchField:"object2"},project_search3:{label:"Project",searchOnly:!0,searchObject:"project",searchPlaceholder:"Related project name",searchWidget:3,searchField:"object2"},user_search3:{label:"User",searchOnly:!0,searchObject:"user",searchPlaceholder:"Related username",searchWidget:3,searchField:"object2"}},actions:{refresh:{mode:"all","class":"btn-xs",awToolTip:"Refresh the page",ngClick:"refreshStream()"},close:{mode:"all",awToolTip:"Close Activity Stream view",ngClick:"closeStream()"}},fieldActions:{view:{label:"View",ngClick:"showDetail(activity.id)",icon:"fa-zoom-in","class":"btn-default btn-xs",awToolTip:"View event details",dataPlacement:"top"}}}),angular.module("TeamsListDefinition",[]).value("TeamList",{name:"teams",iterator:"team",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"},organization:{label:"Organization",ngBind:"team.organization_name",sourceModel:"organization",sourceField:"name"}},actions:{add:{mode:"all",ngClick:"addTeam()",awToolTip:"Create a new team"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editTeam(team.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit team",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteTeam(team.id, team.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete team",dataPlacement:"top"}}}),angular.module("UserListDefinition",[]).value("UserList",{name:"users",iterator:"user",selectTitle:"Add Users",editTitle:"Users",selectInstructions:"

        Select existing users by clicking each user or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        When available, a brand new user can be created by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},actions:{add:{label:"Create New",mode:"all",ngClick:"addUser()",basePaths:["organizations","users"],"class":"btn-xs",awToolTip:"Create a new user"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editUser(user.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit user",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteUser(user.id, user.username)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete user",dataPlacement:"top"}}}),angular.module("InventorySyncStatusWidget",["RestServices","Utilities"]).factory("InventorySyncStatus",["$rootScope","$compile",function(a,b){return function(a){function c(a){var b=a.label,c=a.count,d=a.fail,e=a.link,f=a.fail_link,g="\n"; +return g+='\n",g+=''+d+"",g+="\n",g+='',g+=''+c+"",g+="\n"}var d,e,f,g,h,i=a.scope,j=a.target,k=a.dashboard;if(d='
        \n',d+='
        Inventory Sync Status
        \n',d+='
        \n',d+='\n',d+="\n",d+="\n",d+='\n',d+='\n',d+='\n',d+="\n",d+="\n",d+="\n",d+=c({label:"Inventories",count:k.inventories&&k.inventories.total_with_inventory_source?k.inventories.total_with_inventory_source:0,fail:k.inventories&&k.inventories.inventory_failed?k.inventories.inventory_failed:0,link:"/#/inventories/?has_inventory_sources=true",fail_link:"/#/inventories/?inventory_sources_with_failures=true"}),e=0,f=0,k.inventory_sources)for(h in k.inventory_sources)e+=k.inventory_sources[h].total?k.inventory_sources[h].total:0,f+=k.inventory_sources[h].failed?k.inventory_sources[h].failed:0;d+=c({label:"Groups",count:e,fail:f,link:"/#/home/groups/?has_external_source=true",fail_link:"/#/home/groups/?status=failed"});for(h in k.inventory_sources)k.inventory_sources[h].total&&(d+=c({label:k.inventory_sources[h].label,count:k.inventory_sources[h].total?k.inventory_sources[h].total:0,fail:k.inventory_sources[h].failed?k.inventory_sources[h].failed:0,link:"/#/home/groups/?source="+h,fail_link:"/#/home/groups/?status=failed&source="+h}));d+="\n",d+="
        FailedTotal
        \n",d+="
        \n",d+="
        \n",d+="
        \n",g=angular.element(document.getElementById(j)),g.html(d),b(g)(i),i.$emit("WidgetLoaded")}}]),angular.module("JobStatusWidget",["RestServices","Utilities"]).factory("JobStatus",["$rootScope","$compile","Rest","GetBasePath","ProcessErrors","Wait",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.fail_link,f=a.count,g=a.fail;return b+="\n",b+='\n",b+=''+g+"",b+="\n",b+='',b+=''+f+"",b+="\n"}var d,e=a.scope,f=a.target,g=a.dashboard,h="";h='
        \n',h+='
        Job Status
        \n',h+='
        \n',h+='\n',h+="\n",h+="\n",h+='\n',h+='\n',h+='\n',h+="\n",h+="\n",h+="\n",h+=c({label:"Jobs",link:"/#/jobs",count:g.jobs&&g.jobs.total?g.jobs.total:0,fail:g.jobs&&g.jobs.failed?g.jobs.failed:0,fail_link:"/#/jobs/?status=failed"}),h+=c({label:"Inventories",link:"/#/inventories",count:g.inventories&&g.inventories.total?g.inventories.total:0,fail:g.inventories&&g.inventories.job_failed?g.inventories.job_failed:0,fail_link:"/#/inventories/?has_active_failures=true"}),h+=c({label:"Groups",link:"/#/home/groups",count:g.groups&&g.groups.total?g.groups.total:0,fail:g.groups&&g.groups.job_failed?g.groups.job_failed:0,fail_link:"/#/home/groups/?has_active_failures=true"}),h+=c({label:"Hosts",link:"/#/home/hosts",count:g.hosts&&g.hosts.total?g.hosts.total:0,fail:g.hosts&&g.hosts.failed?g.hosts.failed:0,fail_link:"/#/home/hosts/?has_active_failures=true"}),h+="\n",h+="
        FailedTotal
        \n",h+="
        \n",h+="
        \n",h+="
        \n",d=angular.element(document.getElementById(f)),d.html(h),b(d)(e),e.$emit("WidgetLoaded")}}]),angular.module("ObjectCountWidget",["RestServices","Utilities"]).factory("ObjectCount",["$rootScope","$compile","Rest","GetBasePath","ProcessErrors","Wait",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.count;return b+="\n",b+='\n",b+='',b+=''+e+"",b+="\n"}var d,e,f,g=a.scope,h=a.target,i=a.dashboard,j=["organizations","users","teams","credentials","projects","inventories","groups","hosts","job_templates","jobs"];for(e='
        \n',e+='
        System Summary
        \n',e+='
        \n',e+='\n',e+="\n",e+="\n",e+='\n',e+='\n',e+="\n",e+="\n",e+="\n",d=0;d\n",e+="
        Total
        \n",e+="
        \n",e+="
        \n",f=angular.element(document.getElementById(h)),f.html(e),b(f)(g),g.$emit("WidgetLoaded")}}]),angular.module("SCMSyncStatusWidget",["RestServices","Utilities"]).factory("SCMSyncStatus",["$rootScope","$compile",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.fail_link,f=a.count,g=a.fail;return b+="\n",b+=''+c+"\n",b+=''+g+"",b+="\n",b+='',b+=''+f+"",b+="\n"}var d,e,f,g,h,i,j=a.scope,k=a.target,l=a.dashboard;if(e='
        \n',e+='
        Project SCM Status
        \n',e+='
        \n',e+='\n',e+="\n",e+="\n",e+='\n',e+='\n',e+='\n',e+="\n",e+="\n",e+="\n",f=0,l.scm_types)for(h in l.scm_types)f+=l.scm_types[h].total?l.scm_types[h].total:0;e+=c({label:"Projects",link:"/#/projects",count:f,fail:l.projects&&l.projects.failed?l.projects.failed:0,fail_link:"/#/projects/?status=failed"}),i=[];for(h in l.scm_types)i.push(h);for(i.sort(),d=0;d\n",e+="
        FailedTotal
        \n",e+="
        \n",e+="
        \n",e+="
        \n",g=angular.element(document.getElementById(k)),g.html(e),b(g)(j),j.$emit("WidgetLoaded")}}]),angular.module("StreamWidget",["RestServices","Utilities","StreamListDefinition","SearchHelper","PaginationHelpers","RefreshHelper","ListGenerator","StreamWidget","AuthService"]).factory("setStreamHeight",[function(){return function(){var a=$("#stream-content").height(),b=parseInt($("#tab-content-container").css("min-height").replace(/px/,"")),c=a>b?a:b;$("#tab-content-container").css({"min-height":c})}}]).factory("ShowStream",["setStreamHeight","Authorization",function(a){return function(){var b=$("#stream-container");b.css({position:"absolute",top:0,left:0,width:"100%","min-height":"100%","background-color":"#FFF"}),a(),b.show("slide",{direction:"left"},{duration:500,queue:!1})}}]).factory("HideStream",["LoadBreadCrumbs",function(a){return function(){var b=$("#stream-container");b.hide("slide",{direction:"left"},{duration:500,queue:!1}),setTimeout(function(){b.detach(),b.empty(),b.unbind(),$("#tab-content-container").css({"min-height":0})},500),a()}}]).factory("StreamBreadCrumbs",["$rootScope","$location",function(a,b){return function(){a.breadcrumbs=[];var c,d,e,f,g=b.path().split("/");for(g.splice(0,1),e=0;e=f;f++)c+="/"+g[f];for(f=0;f0)for(f=0;e>=f;f++)c+="/"+g[f];else c="/"+g[e];d=g[e],d=d.charAt(0).toUpperCase()+d.slice(1)}a.breadcrumbs.push({path:c,title:d,ngClick:"closeStream('"+c+"')"})}}}]).factory("FixUrl",[function(){return function(a){return a.replace(/\/api\/v1\//,"/#/")}}]).factory("BuildUrl",[function(){return function(a){var b="/#/";switch(a.base){case"group":case"host":b+="home/"+a.base+"s/?id="+a.id;break;case"inventory":b+="inventories/"+a.id+"/";break;default:b+=a.base+"s/"+a.id+"/"}return b}}]).factory("BuildDescription",["FixUrl","BuildUrl",function(a,b){return function(a){function c(a){return a.replace(/^_deleted_\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d+:\d+_/,"")}var d,e,f,g,h,i,j,k;d=a.operation,d+=/e$/.test(a.operation)?"d ":"ed ",e=d,f=a.object1,g=a.object2,h=a.summary_fields[f]?a.summary_fields[f][0]:null,i=f===g?a.summary_fields[f][1]:a.summary_fields[g]?a.summary_fields[g][0]:null,("user"===f||"user"===g)&&(a.summary_fields.user[0].name=a.summary_fields.user[0].username),i&&i.name&&!/^_delete/.test(i.name)?(i.base=g,d+=g+' '+i.name+""+("disassociate"===a.operation?" from ":" to "),e+=g+" "+i.name+("disassociate"===a.operation?" from ":" to ")):g&&(j="",i&&i.name&&(j=" "+c(i.name)),d+=g+j+("disassociate"===a.operation?" from ":" to "),e+=g+j+("disassociate"===a.operation?" from ":" to ")),h&&h.name&&!/^\_delete/.test(h.name)?(h.base=f,d+=f+' '+h.name+"",e+=f+" "+h.name):f&&(j="",k="",!h||!h.name||h&&h.name&&/^_delete/.test(h.name)?a.changes&&a.changes.name?"string"==typeof a.changes.name?(j=" "+a.changes.name,k=j):"object"==typeof a.changes.name&&Array.isArray(a.changes.name)&&(j=" "+a.changes.name[0],k=j):"job"===f&&h&&a.changes&&a.changes.job_template?"delete"!==a.operation?(h.base=f,j=' '+h.id+" "+a.changes.job_template+"",k=" "+h.id+" "+a.changes.job_template):(j=" "+h.id+" "+a.changes.job_template,k=j):"job"===f&&h&&("delete"!==a.operation?(h.base=f,j=' '+h.id+"",k=" "+h.id):(j=" "+h.id,k=j)):h&&h.name&&(j=" "+c(h.name),k=j),d+=f+j,e+=f+k),a.description=d,a.description_nolink=e}}]).factory("ShowDetail",["$rootScope","Rest","Alert","GenerateForm","ProcessErrors","GetBasePath","FormatDate","ActivityDetailForm","Empty","Find",function(a,b,c,d,e,f,g,h,i,j){return function(a){var b,c,e,f=a.activity_id,i=a.scope,k=d,l=h,m=j({list:i.activities,key:"id",val:f});m&&(m.changes_stringified=JSON.stringify(m.changes,null," "),b=m.changes_stringified.match(/\n/g),c=b?b.length:1,c=1>c?3:10,l.fields.changes.rows=10,e=k.inject(l,{mode:"edit",modal:!0,related:!1}),e.changes=m.changes_stringified,e.user=(m.summary_fields.actor?m.summary_fields.actor.username:"system")+" on "+g(new Date(m.timestamps)),e.operation=m.description_nolink,e.formModalAction=function(){$("#form-modal").modal("hide")},$("#form-modal").on("show.bs.modal",function(){$("#form-modal-body").css({width:"auto",height:"auto","max-height":"100%"})}),e.formModalActionLabel="OK",e.formModalCancelShow=!1,e.formModalInfo=!1,e.formModalHeader="Event "+m.id,e.$$phase||e.$digest())}}]).factory("Stream",["$rootScope","$location","Rest","GetBasePath","ProcessErrors","Wait","StreamList","SearchInit","PaginateInit","GenerateList","FormatDate","ShowStream","HideStream","BuildDescription","FixUrl","BuildUrl","ShowDetail","StreamBreadCrumbs","setStreamHeight","Find","Store",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){return function(c){var e,f,o,v,w=g,x=d("activity_stream"),y=j,z=b.path().replace(/^\//,"").split("/")[0],A=c.scope,B=u("CurrentSearchParams"),C=c&&c.inventory_name?c.inventory_name:null,D=c&&c.url?c.url:null;a.flashMessage=null,D?x=D:"/home"!==b.path()&&(e="inventories"===z?"inventory":z.replace(/s$/,""),f=b.path().split("/"),f.splice(0,1),f.length>1&&/^\d+/.test(f[f.length-1])?(e=f[f.length-2],e="inventories"===e?"inventory":e.replace(/s$/,""),x+="?"+e+"__id="+f[f.length-1]):f.length>1?(e=f[f.length-1],e="inventories"===e?"inventory":e.replace(/s$/,""),x+="?or__object1="+e+"&or__object2="+e):x+="?or__object1="+e+"&or__object2="+e),$("#tab-content-container").append('
        '),r(),C&&(o=t({list:a.breadcrumbs,key:"title",val:"{{ inventory_name }}"}),o&&(o.title=C)),l(),v=y.inject(w,{mode:"edit",id:"stream-content",searchSize:"col-lg-3",secondWidget:!0,activityStream:!0}),v.streamTitle=c&&c.title?c.title:null,v.closeStream=function(a){m(),v.searchCleanup&&v.searchCleanup(),B&&h({scope:A,set:B.set,list:B.list,url:B.defaultUrl,iterator:B.iterator,sort_order:B.sort_order,setWidgets:!1}),a&&b.path(a)},v.refreshStream=function(){v.search(w.iterator)},v.showDetail=function(a){q({scope:v,activity_id:a})},v.removeStreamPostRefresh&&v.removeStreamPostRefresh(),v.removeStreamPostRefresh=v.$on("PostRefresh",function(){var a,b,c,d,e,f;for(a=0;a'+v.activities[a].summary_fields.actor.username+"":"system",d=/^\_delete/,e=v.activities[a].object1,f=v.activities[a].object2,e&&v.activities[a].summary_fields[e]&&v.activities[a].summary_fields[e].name?d.test(v.activities[a].summary_fields[e].name)?v.activities[a].objects=v.activities[a].summary_fields[e].name:(c=p(v.activities[a].summary_fields.object1),v.activities[a].objects=''+v.activities[a].summary_fields[e].name+""):v.activities[a].object1&&(v.activities[a].objects=v.activities[a].object1),f&&v.activities[a].summary_fields[f]&&v.activities[a].summary_fields[f].name?d.test(v.activities[a].summary_fields.object2.name)?v.activities[a].objects+=","+v.activities[a].summary_fields[f].name:(c=p(v.activities[a].summary_fields.object2),v.activities[a].objects+=', '+v.activities[a].summary_fields[f].name+""):v.activities[a].object2&&(v.activities[a].objects+=", "+v.activities[a].object2),n(v.activities[a]);setTimeout(function(){s()},500)}),h({scope:v,set:w.name,list:w,url:x}),i({scope:v,list:w,url:x}),v.search(w.iterator)}}]),angular.module("AuthService",["ngCookies","Utilities"]).factory("Authorization",["$http","$rootScope","$location","$cookieStore","GetBasePath",function(a,b,c,d,e){return{setToken:function(a,c){d.remove("token"),d.remove("token_expires"),d.remove("userLoggedIn"),d.put("token",a),d.put("token_expires",c),d.put("userLoggedIn",!0),d.put("sessionExpired",!1),b.token=a,b.userLoggedIn=!0,b.token_expires=c,b.sessionExpired=!1},isUserLoggedIn:function(){return void 0===b.userLoggedIn&&(b.userLoggedIn=d.get("userLoggedIn"),b.sessionExpired=d.get("sessionExpired")),b.userLoggedIn},getToken:function(){return b.token?b.token:d.get("token")},retrieveToken:function(b,c){return a({method:"POST",url:e("authtoken"),data:{username:b,password:c}})},logout:function(){var a=angular.element(document.getElementById("main-view")).scope();a.$destroy(),b.$destroy(),d.remove("accordions"),d.remove("token"),d.remove("token_expires"),d.remove("current_user"),d.remove("lastPath"),d.put("userLoggedIn",!1),d.put("sessionExpired",!1),d.remove("lastPath","/home"),b.current_user={},b.license_tested=void 0,b.userLoggedIn=!1,b.sessionExpired=!1,b.token=null,b.token_expires=null,b.lastPath="/home"},getLicense:function(){return a({method:"GET",url:e("config"),headers:{Authorization:"Token "+this.getToken()}})},setLicense:function(a){a.tested=!1,d.put("license",a)},licenseTested:function(){var a,c;return void 0!==b.license_tested?c=b.license_tested:(a=d.get("license"),c=a&&void 0!==a.tested?a.tested:!1),c},getUser:function(){return a({method:"GET",url:"/api/v1/me/",headers:{Authorization:"Token "+this.getToken()}})},setUserInfo:function(a){b.current_user=a.results[0],d.put("current_user",a.results[0])},restoreUserInfo:function(){b.current_user=d.get("current_user")},getUserInfo:function(a){var c;return b.current_user?b.current_user[a]:(this.restoreUserInfo(),c=d.get("current_user"),c[a])}}}]),angular.module("InventoryTree",["Utilities","RestServices","GroupsHelper","PromptDialog"]).factory("SortNodes",[function(){return function(a){var b,c,d=[],e=[];for(b=0;b0?!0:!1,has_inventory_sources:s[e].has_inventory_sources,id:r,source:s[e].summary_fields.inventory_source.source,group_id:s[e].id,event_level:c,children:i,ngicon:s[e].children.length>0?"fa fa-minus-square-o node-toggle":"fa fa-square-o node-no-toggle",ngclick:"toggle("+r+")",related:{children:s[e].children.length>0?s[e].related.children:"",inventory_source:s[e].related.inventory_source},status:s[e].summary_fields.inventory_source.status,status_class:k["class"],status_tooltip:k.tooltip,launch_tooltip:k.launch_tip,launch_class:k.launch_class,hosts_status_tip:n.tooltip,show_failures:n.failures,hosts_status_class:n["class"],selected_class:"",show:!0,isDraggable:!0,isDroppable:!0},q.push(o),p&&o.group_id===p&&(m.selected_tree_id=r,m.selected_group_id=o.group_id),s[e].children.length>0&&j(s[e].children,r,c+1)}}function k(){e("start"),a.setUrl(b("inventory")+l+"/"),a.get().success(function(a){m.$emit("buildAllGroups",a.name,a.related.tree,a.related.groups)}).error(function(a,b){e("stop"),c(m,a,b,null,{hdr:"Error!",msg:"Failed to get inventory: "+l+". GET returned: "+b})})}var l=h.inventory_id,m=h.scope,n=h.refresh,o=h.emit,p=h.new_group_id,q=[],r=1;m.buildAllGroupsRemove&&m.buildAllGroupsRemove(),m.buildAllGroupsRemove=m.$on("buildAllGroups",function(b,d,f){a.setUrl(f),a.get().success(function(a){i(a),j(a,0,0),m.autoShowGroupHelp=0===a.length?!0:!1,n?(m.groups=q,m.$emit("GroupTreeRefreshed",d,q,o)):m.$emit("GroupTreeLoaded",d,q,o)}).error(function(a,b){e("stop"),c(m,a,b,null,{hdr:"Error!",msg:"Failed to get inventory tree for: "+l+". GET returned: "+b})})}),k()}}]).factory("UpdateGroup",["ApplyEllipsis","GetSyncStatusMsg","Empty",function(a,b,c){return function(d){var e,f,g,h,i,j=d.scope,k=d.group_id,l=d.properties;for(e=0;e\n',m+='\n",m+="
        \n",i=angular.element(document.getElementById("inventory-modal-container")),i.empty().append(m),a(i)(j),$("#copy-prompt-modal").modal({backdrop:"static",keyboard:!0,show:!0}),j.moveGroup=function(){var a,b,i;$("#copy-prompt-modal").modal("hide"),e("start"),j.removeGroupRemove&&j.removeGroupRemove(),j.removeGroupRemove=j.$on("removeGroup",function(){l.parent>0?(i=d({list:j.groups,key:"id",val:l.parent}),a=h("base")+"groups/"+i.group_id+"/children/",f.setUrl(a),f.post({id:l.group_id,disassociate:1}).success(function(){j.$emit("GroupDeleteCompleted")}).error(function(a,b){e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to remove "+l.name+" from "+i.name+". POST returned status: "+b})})):j.$emit("GroupDeleteCompleted")}),a=g(k.group_id)?h("inventory")+j.inventory_id+"/groups/":h("base")+"groups/"+k.group_id+"/children/",b={id:l.group_id,name:l.name,description:l.description,inventory:j.inventory_id},f.setUrl(a),f.post(b).success(function(){j.$emit("removeGroup")}).error(function(a,b){var d=g(k.group_id)?"inventory":k.name;e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+d+". POST returned status: "+b})})},j.copyGroup=function(){$("#copy-prompt-modal").modal("hide"),e("start");var a=g(k.group_id)?h("inventory")+j.inventory_id+"/groups/":h("base")+"groups/"+k.group_id+"/children/",b={id:l.group_id,name:l.name,description:l.description,inventory:j.inventory_id};f.setUrl(a),f.post(b).success(function(){j.$emit("GroupDeleteCompleted")}).error(function(a,b){var d=g(k.group_id)?"inventory":k.name;e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+d+". POST returned status: "+b})})}}}]).factory("CopyMoveHost",["$compile","Alert","ProcessErrors","Find","Wait","Rest","Empty","GetBasePath",function(a,b,c,d,e,f,g,h){return function(b){var g,i,j=b.scope,k=d({list:j.groups,key:"id",val:b.target_tree_id}),l=d({list:j.hosts,key:"id",val:b.host_id}),m=!1,n="";if(l.summary_fields.all_groups)for(i=0;i\n',n+='\n",n+="
        \n",n+="
        \n",g=angular.element(document.getElementById("inventory-modal-container")),g.empty().append(n),a(g)(j),$("#copy-alert-modal").modal({backdrop:"static",keyboard:!0,show:!0})):(n="",n+='\n",g=angular.element(document.getElementById("inventory-modal-container")),g.empty().append(n),a(g)(j),$("#copy-prompt-modal").modal({backdrop:"static",keyboard:!0,show:!0}),j.copyHost=function(){$("#copy-prompt-modal").modal("hide"),e("start"),f.setUrl(h("groups")+k.group_id+"/hosts/"),f.post(l).success(function(){j.$emit("GroupTreeRefreshed")}).error(function(a,b){e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+k.name+". POST returned status: "+b})})})}}]),angular.module("RestServices",["ngCookies","AuthService"]).factory("Rest",["$http","$rootScope","$cookieStore","$q","Authorization",function(a,b,c,d,e){return{headers:{},setUrl:function(a){this.url=a},checkExpired:function(){return b.sessionTimer.isExpired()},pReplace:function(){var a,b;for(a in this.params)b=new RegExp("\\:"+a,"gm"),b.test(this.url)&&(this.url=this.url.replace(b,this.params[a]),delete this.params[a])},createResponse:function(a,b){var c=d.reject({data:a,status:b});return c.success=function(a){return c.then(function(b){a(b.data,b.status)},null),c},c.error=function(a){return c.then(null,function(b){a(b.data,b.status)}),c},c},setHeader:function(a){for(var b in a)this.headers[b]=a[b]},get:function(b){b=b?b:{},this.params=b.params?b.params:null,this.pReplace();var c=this.checkExpired(),d=e.getToken();return c?this.createResponse({detail:"Token is expired"},401):d?(this.setHeader({Authorization:"Token "+d}),this.setHeader({"X-Auth-Token":"Token "+d}),a({method:"GET",url:this.url,headers:this.headers,params:this.params})):this.createResponse({detail:"Invalid token"},401)},post:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"POST",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},put:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"PUT",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},destroy:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"DELETE",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},options:function(){var b=e.getToken(),c=this.checkExpired();return c?this.createResponse({detail:"Token is expired"},401):b?(this.setHeader({Authorization:"Token "+b}),this.setHeader({"X-Auth-Token":"Token "+b}),a({method:"OPTIONS",url:this.url,headers:this.headers})):this.createResponse({detail:"Invalid token"},401)}}}]),angular.module("TimerService",["ngCookies","Utilities"]).factory("Timer",["$rootScope","$cookieStore","$location","GetBasePath","Empty",function(a,b){return{sessionTime:null,timeout:null,getSessionTime:function(){return this.sessionTime?this.sessionTime:b.get("sessionTime")},isExpired:function(){var a=this.getSessionTime(),b=(new Date).getTime();return 0>=a-b?!0:(this.moveForward(),!1)},expireSession:function(){this.sessionTime=0,a.sessionExpired=!0,b.put("sessionExpired",!0)},moveForward:function(){var c=(new Date).getTime()+1e3*$AnsibleConfig.session_timeout;this.sessionTime=c,b.put("sessionTime",c),a.sessionExpired=!1,b.put("sessionExpired",!1)},init:function(){return this.moveForward(),this}}}]),angular.module("Utilities",["RestServices","Utilities"]).factory("ClearScope",[function(){return function(a){var b,c=document.getElementById(a);c&&(b=angular.element(c).scope(),b.$destroy()),$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()});try{$("#help-modal").dialog("close")}catch(d){}$(window).unbind("resize")}}]).factory("Empty",[function(){return function(a){return null===a||void 0===a||""===a?!0:!1}}]).factory("ToggleClass",function(){return function(a,b){$(a)&&$(a).hasClass(b)?$(a).removeClass(b):$(a)&&$(a).addClass(b)}}).factory("Alert",["$rootScope",function(a){return function(b,c,d,e,f,g){f?(a.alertHeader2=b,a.alertBody2=c,a.alertClass2=d?d:"alert-danger",$("#alert-modal2").modal({show:!0,keyboard:!0,backdrop:"static"}),a.disableButtons2=g?!0:!1,e&&$("#alert-modal2").on("hidden",function(){e()}),$(document).bind("keydown",function(a){27===a.keyCode&&($("#alert-modal2").modal("hide"),e&&e())})):(a.alertHeader=b,a.alertBody=c,a.alertClass=d?d:"alert-danger",$("#alert-modal").modal({show:!0,keyboard:!0,backdrop:"static"}),$(document).bind("keydown",function(a){27===a.keyCode&&($("#alert-modal").modal("hide"),e&&e())}),a.disableButtons=g?!0:!1,e&&$("#alert-modal").on("hidden",function(){e()}))}}]).factory("ProcessErrors",["$rootScope","$cookieStore","$log","$location","Alert","Wait",function(a,b,c,d,e,f){return function(b,c,g,h,i){var j,k,l;if(f("stop"),$AnsibleConfig.debug_mode&&console&&(console.log("Debug status: "+g),console.log("Debug data: "),console.log(c)),403===g)l="The API responded with a 403 Access Denied error. ",l+=c.detail?"Detail: "+c.detail:"Please contact your system administrator.",e(i.hdr,l);else if(401===g&&c.detail&&"Token is expired"===c.detail||401===g&&c.detail&&"Invalid token"===c.detail)a.sessionTimer.expireSession(),d.url("/login");else if(c.non_field_errors)e("Error!",c.non_field_errors);else if(c.detail)e(i.hdr,i.msg+" "+c.detail);else if(c.__all__)e("Error!",c.__all__);else if(h){k=!1;for(j in h.fields)c[j]&&h.fields[j].tab&&$("#"+h.name+'_tabs a[href="#'+h.fields[j].tab+'"]').tab("show"),h.fields[j].realName&&c[h.fields[j].realName]&&(b[j+"_api_error"]=c[h.fields[j]][0],$('[name="'+h.fields[j].realName+'"]').addClass("ng-invalid"),k=!0),h.fields[j].sourceModel?c[j]&&(b[h.fields[j].sourceModel+"_"+h.fields[j].sourceField+"_api_error"]=c[j][0],$('[name="'+h.fields[j].sourceModel+"_"+h.fields[j].sourceField+'"]').addClass("ng-invalid"),k=!0):c[j]&&(b[j+"_api_error"]=c[j][0],$('[name="'+j+'"]').addClass("ng-invalid"),k=!0); +!k&&i&&e(i.hdr,i.msg)}else e(i.hdr,i.msg)}}]).factory("LoadBreadCrumbs",["$rootScope","$routeParams","$location","Empty",function(a,b,c,d){return function(b){function e(a){return a.toUpperCase()}function f(a){return"ies"===a?"y":""}var g,h,i,j,k,l,m,n;if(!d(b)){for(h=!1,j=0;j1)for(j=0;j0&&k[j].match(/\d+/)){for(m=k[j-1],n=m.replace(/(ies$|s$)/,f),n=n.charAt(0).toUpperCase()+n.slice(1),h=!1,i=0;i\n",b+='
        \n',b+='',b+="
        \n",b+='
        '+a.box+"
        ",b+=f&&a.autoOffNotice?'
        \n':""}var h,i,j,k,l=!1;e=a,j=d.story.width?d.story.width:510,k=d.story.height?d.story.height:600,i=$(document).width(),j=j>i?i:j;try{l=$("#help-modal").dialog("isOpen")}catch(m){}l?$("#help-modal").html(g(d.story.steps[e])):(h=[],d.story.steps.length>1&&(h.push({text:"Prev",click:function(a){e-1===0&&$(a.target).button("disable"),e-10&&$(a.target).prev().button("enable"),e+1===d.story.steps.length-1&&$(a.target).button("disable"),b(e+1)}})),h.push({text:"Close",click:function(){$("#help-modal").dialog("close")}}),$("#help-modal").html(g(d.story.steps[e])).dialog({position:{my:"center top",at:"center top+150",of:"body"},title:d.story.hdr,width:j,height:k,buttons:h,closeOnEscape:!0,show:500,hide:500,resizable:!1,close:function(){$("#help-modal").empty()}}),$(".ui-dialog-buttonset button").each(function(){var a,b,c;c=$(this).text(),"Close"===c?(b="fa-times",a="btn btn-default",$(this).attr({"class":a}).html(' Close')):"Prev"===c?(b="fa-chevron-left",a="btn btn-primary",$(this).attr({"class":a}).html(' Prev')):(b="fa-chevron-right",a="btn btn-primary",$(this).attr({"class":a}).html('Next ').css({"margin-right":"20px"}))}),$('.ui-dialog[aria-describedby="help-modal"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$("#auto-off-checkbox").click(function(){$('input[name="auto-off-checkbox"]:checked').length?c("inventoryAutoHelp","off"):c("inventoryAutoHelp","on")}))}var d=a.defn,e=a.step,f=a.autoShow||!1;b(0)}}]).factory("ReturnToCaller",["$location","Empty",function(a,b){return function(c){var d,e=a.path().replace(/^\//,"").split("/"),f="";for(c=b(c)?e.length-1:c+1,d=0;c>d;d++)f+="/"+e[d];a.path(f)}}]).factory("FormatDate",["$filter",function(a){return function(b){return a("date")(b,"MM/dd/yy HH:mm:ss")}}]).factory("Wait",["$rootScope",function(a){return function(b){var c,d,e,f,g,h;"start"!==b||a.waiting?"stop"===b&&a.waiting&&$(".spinny, .overlay").fadeOut(400,function(){a.waiting=!1}):(a.waiting=!0,c=$(window).width(),d=$(window).height(),e=$(".spinny").width(),f=$(".spinny").height(),g=(c-e)/2,h=(d-f)/2,$(".overlay").css({width:$(document).width(),height:$(document).height()}).fadeIn(),$(".spinny").css({top:h,left:g}).fadeIn(400))}}]).factory("HideElement",[function(){return function(a,b){var c=$(a),d=c.css("width"),e=c.css("height"),f=c.position(),g=c.parent(),h=c.css("border-radius"),i=c.css("background-color"),j=c.css("margin"),k=c.css("padding");g.append('
        '),$("#curtain-div").show(0,b)}}]).factory("ShowElement",[function(){return function(){$("#curtain-div").fadeOut(500,function(){$(this).remove()})}}]).factory("GetChoices",["Rest","ProcessErrors",function(a,b){return function(c){var d=c.scope,e=c.url,f=c.field,g=c.variable,h=c.callback,i=c.choice_name;d[g]?d[g].length=0:d[g]=[],a.setUrl(e),a.options().success(function(a){var b,c;for(b=i?a.actions.GET[f][i]:a.actions.GET[f].choices,c=0;c
        '),b=$("#string-test")),$(a).each(function(){var a,c,d,e,f,g=!0;$(this).attr("title")?(a=$(this).attr("title"),g=!1):a=$(this).text(),b.text(a),c=b.width(),d=$(this).parent().width(),c>d&&(g&&$(this).attr("title",a),e=c/a.length,f=c-d,a=a.substr(0,a.length-(Math.ceil(f/e)+3)),$(this).text(a+"...")),d>c&&!g&&(a=$(this).attr("title"),$(this).text(a))})}}]),angular.module("ApiLoader",["Utilities"]).factory("LoadBasePaths",["$http","$rootScope","Store","ProcessErrors",function(a,b,c,d){return function(){a.get("/api/").success(function(e){var f=e.current_version;a.get(f).success(function(a){a.base=f,b.defaultUrls=a,c("api",a)}).error(function(a,c){b.defaultUrls={status:"error"},d(null,a,c,null,{hdr:"Error",msg:"Failed to read "+f+". GET status: "+c})})}).error(function(a,c){b.defaultUrls={status:"error"},d(null,a,c,null,{hdr:"Error",msg:"Failed to read /api. GET status: "+c})})}}]).factory("GetBasePath",["$rootScope","Store","LoadBasePaths","Empty",function(a,b,c,d){return function(c){return d(a.defaultUrls)?b("api")?(a.defaultUrls=b("api"),a.defaultUrls[c]):"":a.defaultUrls[c]}}]),angular.module("AWDirectives",["RestServices","Utilities","AuthService","JobsHelper"]).directive("awpassmatch",function(){return{require:"ngModel",link:function(a,b,c,d){d.$parsers.unshift(function(a){var b=c.awpassmatch,e=$('input[name="'+b+'"]').val();return a===e?(d.$setValidity("awpassmatch",!0),a):void d.$setValidity("awpassmatch",!1)})}}}).directive("capitalize",function(){return{require:"ngModel",link:function(a,b,c,d){d.$parsers.unshift(function(a){var b,c=a.split(" "),e="";for(b=0;bparseInt(b.attr("max"),10)?void d.$setValidity("max",!1):a):void d.$setValidity("integer",!1)})}}}).directive("awRequiredWhen",function(){return{require:"ngModel",link:function(a,b,c,d){function e(){var e,f=b.val(),g=!0;!a[c.awRequiredWhen]||null!==b.attr("required")&&void 0!==b.attr("required")?a[c.awRequiredWhen]||(b.removeAttr("required"),$(b).hasClass("lookup")?(e=$(b).parent().parent().parent().find("label").first(),e.removeClass("prepend-asterisk")):$(b).parent().parent().find("label").first().removeClass("prepend-asterisk")):($(b).attr("required","required"),$(b).hasClass("lookup")?$(b).parent().parent().parent().find("label").first().addClass("prepend-asterisk"):$(b).parent().parent().find("label").first().addClass("prepend-asterisk")),!a[c.awRequiredWhen]||void 0!==f&&null!==f&&""!==f||(g=!1),d.$setValidity("required",g)}void 0!==c.awrequiredInit&&null!==c.awrequiredInit&&(a[c.awRequiredWhen]=c.awrequiredInit,e()),a.$watch(c.awRequiredWhen,function(){e()}),a.$watch($(b).attr("name"),function(){e()})}}}).directive("awPlaceholder",[function(){return{require:"ngModel",link:function(a,b,c){$(b).attr("placeholder",a[c.awPlaceholder]),a.$watch(c.awPlaceholder,function(a){$(b).attr("placeholder",a)})}}}]).directive("awlookup",["Rest",function(a){return{require:"ngModel",link:function(b,c,d,e){e.$parsers.unshift(function(d){if(""!==d&&null!==d){var f=c.attr("data-url");f=f.replace(/\:value/,encodeURI(d)),b[c.attr("data-source")]=null,a.setUrl(f),a.get().then(function(a){var f=a.data.results;return f.length>0?(b[c.attr("data-source")]=f[0].id,b[c.attr("name")]=f[0].name,e.$setValidity("required",!0),e.$setValidity("awlookup",!0),d):(e.$setValidity("required",!0),void e.$setValidity("awlookup",!1))})}else e.$setValidity("awlookup",!0),b[c.attr("data-source")]=null})}}}]).directive("awValidUrl",[function(){return{require:"ngModel",link:function(a,b,c,d){d.$parsers.unshift(function(a){var b,c,e=!0;""!==a&&(d.$setValidity("required",!0),b=/^(https|http|ssh)\:\/\//,c=/\@/g,(!b.test(a)||c.test(a))&&(e=!1)),d.$setValidity("awvalidurl",e)})}}}]).directive("awToolTip",function(){return function(a,b,c){var d,e=void 0!==c.delay&&null!==c.delay?c.delay:$AnsibleConfig.tooltip_delay;d=c.awTipPlacement?c.awTipPlacement:void 0!==c.placement&&null!==c.placement?c.placement:"left",$(b).on("hidden.bs.tooltip",function(){$(".tooltip").each(function(){$(this).remove()})}),$(b).tooltip({placement:d,delay:e,html:!0,title:c.awToolTip,container:"body"}),c.tipWatch&&a.$watch(c.tipWatch,function(a,c){a!==c&&$(b).tooltip("hide").attr("data-original-title",a).tooltip("fixTitle")})}}).directive("awPopOver",["$compile",function(a){return function(b,c,d){var e=void 0!==d.placement&&null!==d.placement?d.placement:"left",f=void 0!==d.title&&null!==d.title?d.title:"Help",g=void 0!==d.container?d.container:!1;$(c).popover({placement:e,delay:0,title:f,content:d.awPopOver,trigger:"manual",html:!0,container:g}),$(c).click(function(){var c=$(this).attr("id");$(".help-link, .help-link-white").each(function(){c!==$(this).attr("id")&&$(this).popover("hide")}),$(".popover").each(function(){$(this).remove()}),$(".tooltip").each(function(){$(this).hide()}),$(this).popover("toggle"),$(".popover").each(function(){a($(this))(b)})}),$(document).bind("keydown",function(a){27===a.keyCode&&($(c).popover("hide"),$(".popover").each(function(){$(this).remove()}))})}}]).directive("ngSlider",[function(){return{require:"ngModel",link:function(a,b,c,d){var e=b.attr("name");$("#"+e+"-slider").slider({value:0,step:1,min:b.attr("min"),max:b.attr("max"),slide:function(b,c){d.$setViewValue(c.value),d.$setValidity("required",!0),d.$setValidity("min",!0),d.$setValidity("max",!0),d.$dirty=!0,d.$render(),a.$$phase||a.$digest()}}),$("#"+e+"-number").change(function(){$("#"+e+"-slider").slider("value",parseInt($(this).val(),10))})}}}]).directive("awMultiSelect",[function(){return{require:"ngModel",link:function(a,b){$(b).multiselect({buttonClass:"btn-default, btn-mini",buttonWidth:"auto",buttonContainer:'
        ',maxHeight:!1,buttonText:function(a){if(0===a.length)return'None selected ';if(a.length>3)return a.length+' selected ';var b="";return a.each(function(){b+=$(this).text()+", "}),b.substr(0,b.length-2)+' '}})}}}]).directive("ngSpinner",[function(){return{require:"ngModel",link:function(a,b,c,d){var e,f;e=b.attr("data-disabled"),f={value:0,step:1,min:b.attr("min"),max:b.attr("max"),numberFormat:"d",spin:function(b,c){d.$setViewValue(c.value),d.$setValidity("required",!0),d.$setValidity("min",!0),d.$setValidity("max",!0),d.$dirty=!0,d.$render(),a.job_templates_form.$dirty=!0,a.$$phase||a.$digest()}},e&&(f.disabled=!0),$(b).spinner(f)}}}]).directive("chkPass",[function(){return{require:"ngModel",link:function(a,b,c,d){$(b).keyup(function(){var c=!0,e=chkPass(b.val());b.val()&&(c=e>$AnsibleConfig.password_strength?!0:!1),d.$setValidity("complexity",c),a.$$phase||a.$digest()})}}}]).directive("awRefresh",["$rootScope",function(a){return{link:function(b){function c(){for(var a=""+b.refreshCnt;a.length<2;)a="0"+a;return"Refresh in "+a+" sec."}b.refreshCnt=$AnsibleConfig.refresh_rate,b.refreshMsg=c(),a.timer&&clearInterval(a.timer),a.timer=setInterval(function(){b.refreshCnt--,b.refreshCnt<=0&&(b.refresh(),b.refreshCnt=$AnsibleConfig.refresh_rate),b.refreshMsg=c(),b.$$phase||b.$digest()},1e3)}}}]).directive("awMultiselect",[function(){return{require:"^form",link:function(a,b,c,d){$(b).select2({multiple:!0,data:function(){if(a[c.awMultiselect]){var b,d=a[c.awMultiselect],e=[];for(b=0;b1?!0:!1):!1},over:function(){$(this).addClass("droppable-hover")},out:function(){$(this).removeClass("droppable-hover")},drop:function(a,c){$(this).removeClass("droppable-hover"),"group"===c.draggable.attr("data-type")?b.$emit("CopyMoveGroup",parseInt(c.draggable.attr("data-tree-id"),10),parseInt($(this).attr("data-tree-id"),10)):"host"===c.draggable.attr("data-type")&&b.$emit("CopyMoveHost",parseInt($(this).attr("data-tree-id"),10),parseInt(c.draggable.attr("data-host-id"),10))},tolerance:"pointer"})}}]),angular.module("AWFilters",[]).filter("capitalize",[function(){return function(a){var b,c,d;if(a){for(b=a.replace(/\_/g," ").split(" "),c="",d=0;d0&&(b=a.children("span"),b.length>0&&!b.first().hasClass("prepend-asterisk")?b.first().addClass("prepend-asterisk"):b.length<=0&&!a.first().hasClass("prepend-asterisk")&&a.first().addClass("prepend-asterisk")))});try{$("#help-modal").empty().dialog("destroy")}catch(h){}return b.modal&&(this.scope.formModalActionDisabled=!1,this.scope.formModalInfo=!1,a&&(b.modal_title_id?this.scope[b.modal_title_id]="add"===b.mode?a.addTitle:a.editTitle:this.scope.formModalHeader="add"===b.mode?a.addTitle:a.editTitle),b.modal_selector?($(b.modal_selector).modal({show:!0,backdrop:"static",keyboard:!0}),$(b.modal_selector).on("shown.bs.modal",function(){$(b.modal_select+" input:first").focus()}),$(b.modal_selector).on("hidden.bs.modal",function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()})})):(g=b.show_modal===!1?!1:!0,$("#form-modal").modal({show:g,backdrop:"static",keyboard:!0}),$("#form-modal").on("shown.bs.modal",function(){$("#form-modal input:first").focus()}),$("#form-modal").on("hidden.bs.modal",function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()})})),$(document).bind("keydown",function(a){27===a.keyCode&&(b.modal_selector&&$(b.modal_selector).modal("hide"),$("#prompt-modal").modal("hide"),$("#form-modal").modal("hide"))})),this.scope.$$phase||this.scope.$digest(),this.scope},applyDefaults:function(){for(var a in this.form.fields)(this.form.fields[a]["default"]||0===this.form.fields[a]["default"])&&(this.scope[a]="select"===this.form.fields[a].type&&this.scope[a+"_options"]?this.scope[a+"_options"][this.form.fields[a]["default"]]:this.form.fields[a]["default"])},reset:function(){function a(a,b){if("checkbox_group"===a.type)for(var e=0;e\n"),c+='\n"},clearApiErrors:function(){for(var a in this.form.fields)this.form.fields[a].sourceModel?(this.scope[this.form.fields[a].sourceModel+"_"+this.form.fields[a].sourceField+"_api_error"]="",$('[name="'+this.form.fields[a].sourceModel+"_"+this.form.fields[a].sourceField+'"]').removeClass("ng-invalid")):this.form.fields[a].realName?(this.scope[this.form.fields[a].realName+"_api_error"]="",$('[name="'+this.form.fields[a].realName+'"]').removeClass("ng-invalid")):(this.scope[a+"_api_error"]="",$('[name="'+a+'"]').removeClass("ng-invalid"));this.scope.$$phase||this.scope.$digest()},button:l,navigationLink:j,buildHelpCollapse:function(a){var b,c="",d={};for(b=0;b\n"),f}function l(){var c="";return(b.label||b.labelBind)&&(c+="\n"),c}var m,n,o,p="",q=this.form.horizontal?!0:!1;if("alertblock"===b.type&&(p+='
        \n',p+='
        \n",p+=void 0===b.closeable||b.closeable===!0?'\n':"",p+=b.alertTxt,p+="
        \n",p+="
        \n",p+="
        \n"),"hidden"===b.type&&("edit"===c.mode&&b.includeOnEdit||"add"===c.mode&&b.includeOnAdd)&&(p+=''),!b.readonly||b.readonly&&"edit"===c.mode){if(p+='
        \n",("text"===b.type||"password"===b.type||"email"===b.type)&&(p+=l(),p+="
        \n",p+=b.clear||b.genMD5?'
        \n':"",(null===b.control||void 0===b.control||b.control)&&(p+="\n
        \n'),("add"===c.mode&&b.addRequired||"edit"===c.mode&&b.editRequired||b.awRequiredWhen)&&(p+='
        A value is required!
        \n'),"email"===b.type&&(p+='
        A valid email address is required!
        \n'),b.awPassMatch&&(p+='
        Must match Password value
        \n'),b.awValidUrl&&(p+='
        URL must begin with ssh, http or https and may not contain '@'
        \n"),p+='
        \n',b.chkPass&&(p+='
        Password must be stronger
        \n',p+='
        \n',p+='
        \n',p+='
        \n',p+="
        \n",p+=k({hdr:"Password Complexity",content:'

        A password with reasonable strength is required. As you type the password a progress bar will measure the strength. Sufficient strength is reached when the bar turns green.

        Password strength is judged using the following:

        • Minimum 8 characters in length
        • \n
        • Contains a sufficient combination of the following items:\n
            \n
          • UPPERCASE letters
          • \n
          • Numbers
          • \n
          • Symbols _!@#$%^&*()
          • \n
          \n
        • \n
        \n',idx:this.accordion_count++,show:null}),p+="
        \n"),p+=b.helpCollapse?this.buildHelpCollapse(b.helpCollapse):"",p+="
        \n"),"textarea"===b.type&&(p+=l(),p+="
        \n",("variables"===a||"extra_vars"===a||"inventory_variables"===a||"source_vars"===a)&&(p+='
        Parse as: JSON\n',p+="
        \n"),p+="\n",("add"===c.mode&&b.addRequired||"edit"===c.mode&&b.editRequired)&&(p+='
        A value is required!
        \n'),p+='
        \n',p+="
        \n"),"select"===b.type&&(p+=l(),p+="
        \n",p+="A value is required!
        \n'),b.integer&&(p+='
        Must be an integer value
        \n'),(void 0!==b.min||void 0!==b.max)&&(p+='
        Must be an integer between '+b.min+" and ",p+=void 0!==b.max?b.max:"unlimited",p+="
        \n"),p+='
        \n',p+="
        \n"),"checkbox_group"===b.type){for(p+=l(),p+="
        \n",p+='
        A value is required!
        \n'),b.integer&&(p+='
        Must be an integer value
        \n'),(b.min||b.max)&&(p+='
        Must be in range '+b.min+" to "+b.max+"
        \n"),p+='
        \n',p+="
        \n",p+="
        \n"}if("checkbox"===b.type&&(q&&(n=e(),o=12-parseInt(n.replace(/[A-Z,a-z,-]/g,""),10),p+='
        \n'),p+='
        \n',p+="\n",p+='
        \n',p+="
        \n",q&&(p+="
        \n")),"radio_group"===b.type){for(p+=l(),p+="
        \n",m=0;m",p+=' "+b.options[m].label+"\n",p+="\n";("add"===c.mode&&b.addRequired||"edit"===c.mode&&b.editRequired)&&(p+='
        A value is required!
        \n'),p+='
        \n',p+=b.helpCollapse?this.buildHelpCollapse(b.helpCollapse):"",p+="
        \n"}"radio"===b.type&&(q&&(n=e(),o=12-parseInt(n.replace(/[A-Z,a-z,-]/g,""),10),p+='
        \n'),p+='
        \n',p+="\n",p+='
        \n',p+="
        \n",q&&(p+="
        \n")),"lookup"!==b.type||void 0!==b.excludeMode&&b.excludeMode===c.mode||(p+=l(),p+="
        \n",p+='
        \n',p+='\n',p+='\n',p+="\n",p+='A value is required!
        \n'),p+='
        Value not found
        \n',p+='
        \n',p+="
        \n"),"custom"===b.type&&(p+=l(),p+="
        \n",p+="
        \n",p+="
        \n"),p+="
        \n"}return p},getActions:function(a){var b,c='
        \n';for(b in this.form.actions)("all"===this.form.actions[b].mode||this.form.actions[b].mode===a.mode)&&(c+=this.button({btn:this.form.actions[b],action:b,toolbar:!0}));return c+="
        \n"},breadCrumbs:function(a,c){var d,e,f="";if(f+='\n"}else f+='
      • ',f+="edit"===a.mode?this.form.editTitle:this.form.addTitle,f+="
      • \n\n\n";return f},build:function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,p="";if(this.modal||void 0!==a.breadCrumbs&&a.breadCrumbs!==!0||(p+=this.form.navigationLinks?this.breadCrumbs(a,this.form.navigationLinks):this.breadCrumbs(a)),!this.modal&&this.form.statusFields){if(p+='
        \n',this.form.statusActions){p+='
        \n';for(c in this.form.statusActions)b=this.form.statusActions[c],p+=this.button({btn:b,action:c,toolbar:!0});p+="
        \n"}p+='
        \n';for(f in this.form.statusFields)g=this.form.statusFields[f],p+=this.buildField(f,g,a,this.form);p+="
        \n",p+="
        \n"}if(this.form.fieldsAsHeader){p+='
        \n',p+='
        \n';for(f in this.form.fields)g=this.form.fields[f],p+=this.headerField(f,g,a);p+="
        \n",p+="
        \n"}else{if(this.form.collapse&&this.form.collapseMode===a.mode&&(p+='
        \n",p+="
        \n"),!this.modal&&this.has("well")&&(p+='
        \n'),!this.modal&&this.form.actions&&(p+=this.getActions(a)),!a.modal&&this.form.showTitle){if(p+='
        ',p+="edit"===a.mode?this.form.editTitle:this.form.addTitle,this.has("titleActions")){p+='
        \n';for(d in this.form.titleActions)p+=this.button({btn:this.form.titleActions[d],action:d,toolbar:!0});p+="
        \n"}p+="
        \n",p+='
        \n'}if(p+='
        \n',p+='
        {{ flashMessage }}
        \n',this.form.twoColumns){p+='
        \n',p+='
        \n';for(f in this.form.fields)g=this.form.fields[f],1===g.column&&(p+=this.buildField(f,g,a,this.form));p+="
        \n",p+='
        \n';for(f in this.form.fields)g=this.form.fields[f],2===g.column&&(p+=this.buildField(f,g,a,this.form));p+="
        \n",p+="
        \n"}else if(this.form.tabs){for(p+='\n",p+='
        \n',h=0;h\n';for(f in this.form.fields)this.form.fields[f].tab===k.name&&(p+=this.buildField(f,this.form.fields[f],a,this.form));p+="
        \n"}p+="
        \n"}else{i="",j="";for(f in this.form.fields)g=this.form.fields[f],a.modal&&g.excludeModal||(g.group&&g.group!==j&&(""!==j&&(p+="
        \n"),p+='
        \n',p+="
        "+g.group+"
        \n",j=g.group),g.section&&g.section!==i&&(""!==i?p+="
        \n":(p+="
        \n",p+='
        \n'),l=this.form[g.section+"Show"]?' ng-show="'+this.form[g.section+"Show"]+'"':"",p+=""+g.section+"\n",p+="\n",i=g.section),p+=this.buildField(f,g,a,this.form));""!==i&&(p+="
        \n\n"),""!==j&&(p+="\n")}if(!this.modal&&this.has("buttons")){this.form.twoColumns&&(p+='
        \n',p+='
        \n',p+="
        \n"),p+='
        \n");for(d in this.form.buttons)"object"==typeof this.form.buttons[d]&&(e=this.form.buttons[d],"save"===d&&(e.label="Save",e["class"]="btn-success"),"reset"===d&&(e.label="Reset",e["class"]="btn-default"),p+='
        \n",this.form.horizontal&&(p+="
        \n"),this.form.twoColumns&&(p+="
        \n",p+="\n")}p+="\n",!this.modal&&this.has("well")&&(p+="\n"),this.form.collapse&&this.form.collapseMode===a.mode&&(p+="\n",p+="\n")}return!this.modal&&a.related&&this.form.related&&(p+=this.buildCollections(a)),p},buildCollections:function(a){var b,c,d,g,h,j,k,l=1,m=this.form,n='
        \n';for(g in m.related)if("collection"===m.related[g].type){n+='

        '+m.related[g].title+"

        \n",n+="
        \n",m.related[g].instructions&&(n+='
        \n',n+='\n',n+="Hint: "+m.related[g].instructions+"\n",n+="
        \n"),n+='
        \n',n+='
        \n',n+=e({iterator:m.related[g].iterator,template:m.related[g],mini:!0}),n+='
        \n',n+='
        \n';for(b in m.related[g].actions)h=m.related[g].actions[b],n+=this.button({btn:h,action:b,toolbar:!0});n+="
        \n",n+="
        \n",n+="
        \n",n+='
        \n',n+='\n',n+="\n",n+="\n",n+=void 0===m.related[g].index||m.related[g].index!==!1?"\n":"";for(d in m.related[g].fields)n+='\n"),j=1,k=m.related[g].base?m.related[g].base:g,k=k.replace(/^\//,"");for(d in m.related[g].fields)j++,n+=i({list:m.related[g],fld:d,options:a,base:k});n+='",n+="\n",n+='\n',n+='\n',n+="\n",n+='\n',n+='\n',n+="\n",n+="\n",n+="
        #"+m.related[g].fields[d].label,n+=' \n',(void 0===m.related[g].index||m.related[g].index!==!1)&&(n+="{{ $index + (("+m.related[g].iterator+"_page - 1) * "+m.related[g].iterator+"_page_size) + 1 }}.';for(b in m.related[g].fieldActions)c=m.related[g].fieldActions[b],n+="",n+=o({action:b}),n+=c.label?" "+c.label:"",n+="";n+="
        No records matched your search.
        Loading...
        \n",n+="
        \n",n+="
        \n",n+=f({set:g,iterator:m.related[g].iterator,mini:!0}),n+="
        \n",l++}return n+="

        \n",n+="\n"}}}]),angular.module("GeneratorHelpers",["GeneratorHelpers"]).factory("Attr",function(){return function(a,b,c){var d,e,f,g="string"==typeof a[b]?a[b].replace(/[\'\"]/g,"""):a[b];if(/^ng/.test(b))f="ng-"+b.replace(/^ng/,"").toLowerCase()+'="'+g+'" ';else if(/^data|^aw/.test(b)&&"awPopOver"!==b){for(e="",d=0;d '}}).factory("SelectIcon",["Icon",function(a){return function(b){var c,d=b.action,e=b.size;switch(d){case"help":c="fa-question-circle";break;case"add":case"create":c="fa-plus";break;case"edit":c="fa-pencil";break;case"delete":c="fa-trash-o";break;case"group_update":c="fa-exchange";break;case"scm_update":c="fa-cloud-download";break;case"cancel":c="fa-minus-circle";break;case"run":case"rerun":case"submit":c="fa-rocket";break;case"stream":c="fa-clock-o";break;case"refresh":c="fa-refresh";break;case"close":c="fa-arrow-left";break;case"save":c="fa-check-square-o";break;case"properties":c="fa-wrench";break;case"reset":c="fa-undo";break;case"view":c="fa-search-plus";break;case"sync_status":c="fa-cloud"}return c+=e?" "+e:"",a(c)}}]).factory("Button",["Attr","SelectIcon",function(a,b){return function(c){var d=c.btn,e=c.action,f=c.toolbar,g="";return f&&(d.class="btn-xs btn-primary",d.iconSize="fa-lg",delete d.label),g+=' "}}]).factory("NavigationLink",["Attr","Icon",function(a,b){return function(c){var d="",d+=c.icon?b(c.icon):"",d+=c.label?c.label:"",d+="\n"}}]).factory("DropDown",["Attr","Icon",function(a,b){return function(a){var c,d,e,f,g=a.list,h=a.fld;for(e=a.field?a.field:a.type?g[a.type][h]:g.fields[h],f=e.label.replace(/ /g,"_"),d=void 0===a.td||a.td!==!1?'\n':"",d+='\n",d+=void 0===a.td||a.td!==!1?"\n":""}}]).factory("BadgeCount",[function(){return function(a){var b,c=a.list,d=a.fld,e=c.fields[d];return b='\n',g+='\n"),g+='\n",g+="\n"}else g+='
      • ',g+="select"===f?e.selectTitle:e.editTitle,g+="
      • \n\n\n";return g}}]).factory("Column",["Attr","Icon","DropDown","Badge","BadgeCount",function(a,b,c,d,e){return function(f){var g,h=f.list,i=f.fld,j=f.options,k=f.base,l=h.fields[i],m="";return void 0!==l.type&&"DropDown"===l.type?m=c(f):"badgeCount"===l.type?m=e(f):(m+='":"","lookup"!==j.mode&&(l.badges||l.badgeIcon&&l.badgePlacement&&"left"===l.badgePlacement)&&(m+=d(l)),h.hasChildren&&l.hasChildren&&(m+=''),"groups"===h.name&&(m+='
        '),"hosts"===h.name&&(m+='"),m+=l.ngShow?"":"",m+=l.appendHTML?'
        \n':"","lookup"!==j.mode&&l.badgeIcon&&l.badgePlacement&&"left"!==l.badgePlacement&&(m+=d(l))),m+="\n"}}]).factory("HelpCollapse",function(){return function(a){var b=a.hdr,c=a.content,d=a.show,e=a.idx,f=a.bind,g="";return g+='
        \n",g+='
        \n',g+='
        \n",g+='

        \n',g+=b,g+='',g+="

        \n",g+="
        \n",g+='
        \n',g+='
        \n",g+="
        \n",g+="
        \n",g+="
        \n"}}).factory("SearchWidget",function(){return function(a){var b,c,d,e=a.iterator,f=a.template,g=a.mini,h="",i=a.searchWidgets?a.searchWidgets:1;for(c=1;i>=c;c++){d=1===c?"":c,h+='
        \n',h+='
        \n',h+='\n',h+="\n",h+='\n",h+="
        \n",h+='\n',h+='\n",h+='
        \n',h+='\n',h+="
        \n",h+="
        \n",h+='\n',h+='\n',h+="
        \n"}return h}}).factory("PaginateWidget",[function(){return function(a){var b=a.iterator,c=a.set,d="";return d+="\n",d+='
        \n',d+='
        \n',d+='
          \n',d+='
        • \n',d+='
        • \n',d+='
        • {{ page }}
        • \n",d+='
        • "+b+'_num_pages">
        • \n',d+='
        • = "+b+'_num_pages">
        • \n',d+="
        \n",d+="
        \n",d+='
        \n",d+='
        \n',d+="Page {{ "+b+"_page }} of {{ "+b+"_num_pages }} for {{ "+b+"_total_rows | number:0 }} "+c+".",d+="
        \n",d+="
        \n",d+="
        \n"}}]),angular.module("License",["RestServices","Utilities","FormGenerator","PromptDialog","LicenseFormDefinition"]).factory("ViewLicense",["$location","$rootScope","GenerateForm","Rest","Alert","GetBasePath","ProcessErrors","FormatDate","Prompt","Empty","LicenseForm",function(a,b,c,d,e,f,g,h,i,j,k){return function(){var a,e=f("config"),l=c,m=angular.copy(k);d.setUrl(e),d.get().success(function(b){var c,d,e,f,g,k,n,o;for(c in m.fields)"time_remaining"!==c&&"license_status"!==c&&j(b.license_info[c])&&delete m.fields[c];(b.license_info.is_aws||j(b.license_info.license_date))&&(delete m.fields.license_date,delete m.fields.time_remaining),a=l.inject(m,{mode:"edit",modal:!0,related:!1}),l.reset(),a.formModalAction=function(){$("#form-modal").modal("hide")},a.formModalActionLabel="OK",a.formModalCancelShow=!1,a.formModalInfo="Purchase/Extend License",a.formModalHeader="Tower License",a.formModalInfoAction=function(){i({hdr:"Tower Licensing",body:'

        Ansible Tower licenses can be purchased or extended by visiting the Ansible online store. Would you like to purchase or extend your license now?

        ',"class":"btn-primary",action:function(){var a=$("#license-link").attr("href");window.open(a,"storeWindow")}})};for(c in m.fields)j(b.license_info[c])||(a[c]=b.license_info[c]);a.license_date&&(d=new Date(parseInt(a.license_date)),"1970"===d.getFullYear()&&(d=new Date(1e3*parseInt(a.license_date,10)),a.time_remaining=a.time_remaining+"000"),a.license_date=h(d),e=parseInt(a.time_remaining/864e5,10),f=a.time_remaining-864e5*e,g=parseInt(f/36e5,10),f-=36e5*g,k=parseInt(f/6e4,10),f-=6e4*k,n=parseInt(f/1e3,10),a.time_remaining=e+" days "+("0"+g).slice(-2)+":"+("0"+k).slice(-2)+":"+("0"+n).slice(-2)),a.free_instances_class=parseInt(a.free_instances)<=0?"field-failure":"field-success",o=b.license_info,void 0===o.valid_key||o.valid_key?void 0!==o.demo&&o.demo?(a.license_status="Demo",a.status_color="license-demo"):void 0!==o.date_expired&&o.date_expired?(a.license_status="Expired",a.status_color="license-expired"):void 0!==o.date_warning&&o.date_warning?(a.license_status="Expiration Warning",a.status_color="license-warning"):void 0!==o.free_instances&&parseInt(o.free_instances)<=0?(a.license_status="No available managed hosts",a.status_color="license-invalid"):(a.license_status="Valid",a.status_color="license-valid"):(a.license_status="Invalid",a.status_color="license-invalid")}).error(function(a,c){g(b,a,c,m,{hdr:"Error!",msg:"Failed to retrieve license. GET status: "+c})})}}]),angular.module("ListGenerator",["GeneratorHelpers"]).factory("GenerateList",["$location","$compile","$rootScope","SearchWidget","PaginateWidget","Attr","Icon","Column","DropDown","NavigationLink","Button","SelectIcon","Breadcrumbs",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return{setList:function(a){this.list=a},attr:f,icon:g,has:function(a){return this.form[a]&&null!==this.form[a]&&void 0!==this.form[a]?!0:!1},hide:function(){$("#lookup-modal").modal("hide")},button:k,inject:function(a,c){var d;d=angular.element(document.getElementById("lookup"===c.mode?"lookup-modal-body":c.id?c.id:"htmlTemplate")),this.setList(a),d.html(this.build(c)),c.prepend&&d.prepend(c.prepend),c.append&&d.append(c.prepend),this.scope=c.scope?c.scope:d.scope(),b(d)(this.scope),this.scope[a.name]=null,this.scope[a.iterator]=null,$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$(window).unbind("resize");try{$("#help-modal").empty().dialog("destroy")}catch(e){}return"lookup"===c.mode&&(this.scope.formModalActionDisabled=!1,this.scope.lookupHeader=c.hdr,$("#lookup-modal").modal({backdrop:"static",keyboard:!0}),$("#lookup-modal").unbind("hidden.bs.modal"),$(document).bind("keydown",function(a){27===a.keyCode&&$("#lookup-modal").modal("hide")})),this.scope},build:function(b){var c,g,j,k,n,o,p,q,r,s="",t=this.list;if(b.activityStream?(s+='\n"):"lookup"===b.mode||void 0!==b.breadCrumbs&&!b.breadCrumbs||(s+=m({list:t,mode:b.mode})),"edit"===b.mode&&t.editInstructions&&(s+='
        \n',s+='\n',s+="Hint: "+t.editInstructions+"\n",s+="
        \n"),"lookup"===b.mode||void 0!==t.well&&!t.well||(s+='
        \n'),b.activityStream&&(s+='
        \n',s+='
        \n',s+="
        {{ streamTitle }}
        \n",s+="
        \n",s+="
        \n"),s+='
        \n',"groups"!==t.name&&(s+=d(b.searchSize?{iterator:t.iterator,template:t,mini:!0,size:b.searchSize,searchWidgets:t.searchWidgets}:"summary"===b.mode?{iterator:t.iterator,template:t,mini:!0,size:"col-lg-6"}:"lookup"===b.mode||void 0!==b.id?{iterator:t.iterator,template:t,mini:!0,size:"col-lg-8"}:{iterator:t.iterator,template:t,mini:!0})),"lookup"!==b.mode){c=a.path().replace(/^\//,"").split("/")[0],s+='
        -1)&&(s+=this.button({btn:t.actions[j],action:j,toolbar:!0}));"select"===b.mode&&t.selectInstructions&&(k={awPopOver:t.selectInstructions,dataPlacement:"top",dataContainer:"body","class":"btn-xs btn-help",awToolTip:"Click for help",dataTitle:"Help",iconSize:"fa-lg"},s+=this.button({btn:k,action:"help",toolbar:!0})),s+="
        \n",s+="
        \n"}else s+='
        \n';s+="
        \n","lookup"!==b.mode&&t.showTitle&&(s+='
        ',s+="edit"===b.mode||"summary"===b.mode?t.editTitle:t.addTitle,s+="
        \n"),s+='",s+=t.fields[n].label,(void 0===t.fields[n].nosort||t.fields[n].nosort!==!0)&&(s+=' Select":"edit"===b.mode&&t.fieldActions&&(s+='';else if(("edit"===b.mode||"summary"===b.mode)&&t.fieldActions){s+='"}return s+="\n",s+='\n',s+='\n',s+="\n",s+='\n',s+='\n',s+="\n",s+="\n",s+="
        \n"),o=2,c=t.base?t.base:t.name,c=c.replace(/^\//,"");for(n in t.fields)o++,void 0!==t.fields[n].searchOnly&&t.fields[n].searchOnly!==!1||"lookup"===b.mode&&void 0!==t.fields[n].excludeModal&&t.fields[n].excludeModal===!0||(s+=h({list:t,fld:n,options:b,base:c}));if("select"===b.mode||"lookup"===b.mode)s+='';for(p in t.fieldActions)if("columnClass"!==p)if(t.fieldActions[p].type&&"DropDown"===t.fieldActions[p].type)s+=i({list:t,fld:p,options:b,base:c,type:"fieldActions",td:!1});else{q=t.fieldActions[p],s+="",s+=q.iconClass?'':l({action:p}),s+=q.label?" "+t.fieldActions[p].label:"",s+=""}s+="
        No records matched your search.
        Loading...
        \n","select"!==b.mode||void 0!==b.selectButton&&!b.selectButton||(s+='\n"),"lookup"===b.mode||void 0!==t.well&&t.well!==!0||(s+="
        \n"),"groups"!==t.name&&(s+=e("lookup"===b.mode||b.id&&"form-modal-body"===b.id?{set:t.name,iterator:t.iterator}:{set:t.name,iterator:t.iterator})),s}}}]),angular.module("PromptDialog",["Utilities"]).factory("Prompt",[function(){return function(a){var b,c=angular.element(document.getElementById("prompt-modal")),d=c.scope();d.promptHeader=a.hdr,d.promptBody=a.body,d.promptAction=a.action,b=null===a["class"]||void 0===a["class"]?"btn-danger":a["class"],$("#prompt_action_btn").removeClass(b).addClass(b),$(c).modal({backdrop:"static",keyboard:!0,show:!0})}}]),String.prototype.strReverse=function(){var a,b="";for(a=0;aA credential must be associated with either a user or a team. Choosing a user allows only the selected user access to the credential. Choosing a team shares the credential with all team members.

        ",dataTitle:"Owner",dataPlacement:"right",dataContainer:"body"},user:{label:"User that owns this credential",type:"lookup",sourceModel:"user",sourceField:"username",ngClick:"lookUpUser()",ngShow:"owner == 'user'",awRequiredWhen:{variable:"user_required",init:"false"}},team:{label:"Team that owns this credential",type:"lookup",sourceModel:"team",sourceField:"name",ngClick:"lookUpTeam()",ngShow:"owner == 'team'",awRequiredWhen:{variable:"team_required",init:"false"}},kind:{label:"Type",excludeModal:!0,type:"select",ngOptions:"kind.label for kind in credential_kind_options",ngChange:"kindChange()",addRequired:!0,editRequired:!0,helpCollapse:[{hdr:"Select a Credential Type",content:"
        \n
        AWS
        \n
        Access keys for Amazon Web Services used for inventory management or deployment.
        \n
        Machine
        \n
        Authentication for remote machine access. This can include SSH keys, usernames, passwords, and sudo information. Machine credentials are used when submitting jobs to run playbooks against remote hosts.
        Rackspace
        \n
        Access information for Rackspace Cloud used for inventory management or deployment.
        \n
        SCM
        \n
        Used to check out and synchronize playbook repositories with a remote source control management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are used on the Projects tab.
        \n
        \n"}]},access_key:{label:"Access Key",type:"text",ngShow:"kind.value == 'aws'",awRequiredWhen:{variable:"aws_required",init:!1},autocomplete:!1,apiField:"username"},secret_key:{label:"Secret Key",type:"password",ngShow:"kind.value == 'aws'",awRequiredWhen:{variable:"aws_required",init:!1},autocomplete:!1,ask:!1,clear:!1,apiField:"passwowrd"},username:{labelBind:"usernameLabel",type:"text",ngShow:"kind.value && kind.value !== 'aws'",awRequiredWhen:{variable:"rackspace_required",init:!1},autocomplete:!1},api_key:{label:"API Key",type:"password",ngShow:"kind.value == 'rax'",awRequiredWhen:{variable:"rackspace_required",init:!1},autocomplete:!1,ask:!1,clear:!1,apiField:"passwowrd"},password:{label:"Password",type:"password",ngShow:"kind.value == 'scm'",addRequired:!1,editRequired:!1,ngChange:"clearPWConfirm('password_confirm')",ask:!1,clear:!1,associated:"password_confirm",autocomplete:!1},password_confirm:{label:"Confirm Password",type:"password",ngShow:"kind.value == 'scm'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"password",autocomplete:!1},ssh_password:{label:"SSH Password",type:"password",ngShow:"kind.value == 'ssh'",ngChange:"clearPWConfirm('ssh_password_confirm')",addRequired:!1,editRequired:!1,ask:!0,clear:!0,associated:"ssh_password_confirm",autocomplete:!1},ssh_password_confirm:{label:"Confirm SSH Password",type:"password",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"ssh_password",autocomplete:!1},ssh_key_data:{labelBind:"sshKeyDataLabel",type:"textarea",ngShow:"kind.value == 'ssh' || kind.value == 'scm'",addRequired:!1,editRequired:!1,"class":"ssh-key-field",rows:10},ssh_key_unlock:{label:"Key Password",type:"password",ngShow:"kind.value == 'ssh' || kind.value == 'scm'",addRequired:!1,editRequired:!1,ngChange:"clearPWConfirm('ssh_key_unlock_confirm')",associated:"ssh_key_unlock_confirm",ask:!0,askShow:"kind.value == 'ssh'",clear:!0},ssh_key_unlock_confirm:{label:"Confirm Key Password",type:"password",ngShow:"kind.value == 'ssh' || kind.value == 'scm'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"ssh_key_unlock"},sudo_username:{label:"Sudo Username",type:"text",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,autocomplete:!1},sudo_password:{label:"Sudo Password",type:"password",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,ngChange:"clearPWConfirm('sudo_password_confirm')",ask:!0,clear:!0,associated:"sudo_password_confirm",autocomplete:!1},sudo_password_confirm:{label:"Confirm Sudo Password",type:"password",ngShow:"kind.value == 'ssh'",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"sudo_password",autocomplete:!1}},buttons:{save:{label:"Save",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("GroupFormDefinition",[]).value("GroupForm",{addTitle:"Create Group",editTitle:"Edit Group",showTitle:!0,cancelButton:!1,name:"group",well:!0,formLabelSize:"col-lg-3",formFieldSize:"col-lg-9",tabs:[{name:"properties",label:"Properties"},{name:"source",label:"Source"}],fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,tab:"properties"},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,tab:"properties"},variables:{label:"Variables",type:"textarea",addRequired:!1,editRequird:!1,rows:6,"default":"---",dataTitle:"Group Variables",dataPlacement:"right",awPopOver:'

        Variables defined here apply to all child groups and hosts.

        Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataContainer:"body",tab:"properties"},source:{label:"Source",type:"select",ngOptions:"source.label for source in source_type_options",ngChange:"sourceChange()",addRequired:!1,editRequired:!1,tab:"source"},source_path:{label:"Script Path",ngShow:"source && source.value == 'file'",type:"text",awRequiredWhen:{variable:"sourcePathRequired",init:"false"},tab:"source"},credential:{label:"Cloud Credential",type:"lookup",ngShow:"source && source.value !== ''",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,tab:"source"},source_regions:{label:"Regions",type:"text",ngShow:"source && (source.value == 'rax' || source.value == 'ec2')",addRequired:!1,editRequired:!1,awMultiselect:"source_region_choices",dataTitle:"Source Regions",dataPlacement:"right",awPopOver:"

        Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, or choose All to include all regions. Tower will only be updated with Hosts associated with the selected regions.

        ",dataContainer:"body",tab:"source"},source_vars:{label:"Source Variables",ngShow:"source && (source.value == 'file' || source.value == 'ec2')",type:"textarea",addRequired:!1,editRequird:!1,rows:6,"default":"---",parseTypeName:"envParseType",dataTitle:"Source Variables",dataPlacement:"right",awPopOver:'

        Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables view ec2.ini in the Ansible github repo.

        Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataContainer:"body",tab:"source"},checkbox_group:{label:"Update Options",type:"checkbox_group",ngShow:"source && (source.value !== '' && source.value !== null)",tab:"source",fields:[{name:"overwrite",label:"Overwrite",type:"checkbox",ngShow:"source.value !== '' && source.value !== null",addRequired:!1,editRequired:!1,awPopOver:"

        When checked all child groups and hosts not found on the remote source will be deleted from the local inventory.

        Unchecked any local child hosts and groups not found on the external source will remain untouched by the inventory update process.

        ",dataTitle:"Overwrite",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"overwrite_vars",label:"Overwrite Variables",type:"checkbox",ngShow:"source.value !== '' && source.value !== null",addRequired:!1,editRequired:!1,awPopOver:"

        If checked, all variables for child groups and hosts will be removed and replaced by those found on the external source.

        When not checked a merge will be performed, combining local variables with those found on the external source.

        ",dataTitle:"Overwrite Variables",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"update_on_launch",label:"Update on Launch",type:"checkbox",ngShow:"source.value !== '' && source.value !== null",addRequired:!1,editRequired:!1,awPopOver:"

        Each time a job runs using this inventory, refresh the inventory from the selected source before executing job tasks.

        ",dataTitle:"Update on Launch",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"}]}},buttons:{labelClass:"col-lg-3",controlClass:"col-lg-5",save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("HostGroupsFormDefinition",[]).value("HostGroupsForm",{editTitle:"Host Groups",name:"host",well:!1,formLabelSize:"col-lg-3",formFieldSize:"col-lg-9",fields:{groups:{label:"Groups",type:"select",multiple:!0,ngOptions:"group.name for group in inventory_groups",addRequired:!0,editRequired:!0,awPopOver:"

        Provide a host name, ip address, or ip address:port. Examples include:

        myserver.domain.com
        127.0.0.1
        10.1.0.140:25
        server.example.com:25
        ",dataTitle:"Host Name",dataPlacement:"right",dataContainer:"#form-modal .modal-content"}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("HostFormDefinition",[]).value("HostForm",{addTitle:"Create Host",editTitle:"{{ name }}",name:"host",well:!1,formLabelSize:"col-lg-3",formFieldSize:"col-lg-9",fields:{name:{label:"Host Name",type:"text",addRequired:!0,editRequired:!0,awPopOver:"

        Provide a host name, ip address, or ip address:port. Examples include:

        myserver.domain.com
        127.0.0.1
        10.1.0.140:25
        server.example.com:25
        ",dataTitle:"Host Name",dataPlacement:"right",dataContainer:"#form-modal .modal-content"},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},enabled:{label:"Enabled?",type:"checkbox",addRequired:!1,editRequired:!1,"default":!0,awPopOver:"

        Indicates if a host is available and should be included in running jobs.

        For hosts that are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.

        ",dataTitle:"Host Enabled",dataPlacement:"right",dataContainer:"#form-modal .modal-content",ngDisabled:"has_inventory_sources == true"},variables:{label:"Variables",type:"textarea",addRequired:!1,editRequird:!1,rows:6,"class":"modal-input-xlarge","default":"---",awPopOver:'

        Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataTitle:"Host Variables",dataPlacement:"right",dataContainer:"#form-modal .modal-content"},inventory:{type:"hidden",includeOnEdit:!0,includeOnAdd:!0}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("InventoryFormDefinition",[]).value("InventoryForm",{addTitle:"Create Inventory",editTitle:"{{ inventory_name | capitalize }}",name:"inventory",well:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{inventory_name:{realName:"name",label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},inventory_description:{realName:"description",label:"Description",type:"text",addRequired:!1,editRequired:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",ngClick:"lookUpOrganization()",awRequiredWhen:{variable:"organizationrequired",init:"true"}},inventory_variables:{realName:"variables",label:"Variables",type:"textarea","class":"span12",addRequired:!1,editRequird:!1,parseTypeName:"inventoryParseType",rows:6,"default":"---",awPopOver:'

        Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n

        View JSON examples at www.json.org

        View YAML examples at docs.ansible.com

        ',dataTitle:"Inventory Variables",dataPlacement:"right",dataContainer:"body"}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("JobEventDataDefinition",[]).value("JobEventDataForm",{editTitle:"{{ id }} - {{ event_display }}",name:"job_events",well:!1,"class":"horizontal-narrow",fields:{event_data:{label:!1,type:"textarea",readonly:!0,rows:18,"class":"modal-input-xxlarge"}}}),angular.module("JobEventsFormDefinition",[]).value("JobEventsForm",{name:"job_events",well:!1,forceListeners:!0,fields:{status:{labelClass:"job-{{ status }}",type:"custom",section:"Event",control:'
        {{ status }}
        '},id:{label:"ID",type:"text",readonly:!0,section:"Event","class":"span1"},created:{label:"Created On",type:"text",section:"Event",readonly:!0},host:{label:"Host",type:"text",readonly:!0,section:"Event",ngShow:"host !== ''"},play:{label:"Play",type:"text",readonly:!0,section:"Event",ngShow:"play !== ''"},task:{label:"Task",type:"text",readonly:!0,section:"Event",ngShow:"task !== ''"},rc:{label:"Return Code",type:"text",readonly:!0,section:"Results","class":"span1",ngShow:"rc !== ''"},msg:{label:"Msg",type:"textarea",readonly:!0,section:"Results","class":"nowrap",ngShow:"msg !== ''",rows:10},stdout:{label:"Std Out",type:"textarea",readonly:!0,section:"Results","class":"nowrap",ngShow:"stdout !== ''",rows:10},stderr:{label:"Std Err",type:"textarea",readonly:!0,section:"Results","class":"nowrap",ngShow:"stderr !== ''",rows:10},results:{label:"Results",type:"textarea",section:"Results",readonly:!0,"class":"nowrap",ngShow:"results !== ''",rows:10},start:{label:"Start",type:"text",readonly:!0,section:"Timing",ngShow:"start !== ''"},traceback:{label:!1,type:"textarea",readonly:!0,section:"Traceback","class":"nowrap",ngShow:"traceback !== ''",rows:10},end:{label:"End",type:"text",readonly:!0,section:"Timing",ngShow:"end !== ''"},delta:{label:"Elapsed",type:"text",readonly:!0,section:"Timing",ngShow:"delta !== ''"},module_name:{label:"Name",type:"text",readonly:!0,section:"Module",ngShow:"module_name !== ''"},module_args:{label:"Args",type:"text",readonly:!0,section:"Module",ngShow:"module_args !== ''"}}}),angular.module("JobSummaryDefinition",[]).value("JobSummary",{editTitle:"{{ id }} - {{ name }}",name:"jobs",well:!1,fields:{status:{type:"custom",control:'
        Status {{ status }}
        ',readonly:!0},created:{label:"Created On",type:"text",readonly:!0},result_stdout:{label:"Standard Out",type:"textarea",readonly:!0,xtraWide:!0,rows:"{{ stdout_rows }}","class":"nowrap mono-space resizable",ngShow:'result_stdout != ""'},result_traceback:{label:"Traceback",type:"textarea",xtraWide:!0,readonly:!0,rows:"{{ traceback_rows }}","class":"nowrap mono-space resizable",ngShow:'result_traceback != ""'}}}),angular.module("JobTemplateFormDefinition",[]).value("JobTemplateForm",{addTitle:"Create Job Templates",editTitle:"{{ name }}",name:"job_templates",twoColumns:!0,well:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,column:1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,column:1},job_type:{label:"Job Type",type:"select",ngOptions:"type.label for type in job_type_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"

        When this template is submitted as a job, setting the type to run will execute the playbook, running tasks on the selected hosts.

        Setting the type to check will not execute the playbook. Instead, ansible will check playbook syntax, test environment setup and report problems.

        ",dataTitle:"Job Type",dataPlacement:"right",dataContainer:"body"},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",ngClick:"lookUpInventory()",awRequiredWhen:{variable:"inventoryrequired",init:"true"},column:1,awPopOver:"

        Select the inventory containing the hosts you want this job to manage.

        ",dataTitle:"Inventory",dataPlacement:"right",dataContainer:"body"},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",ngClick:"lookUpProject()",awRequiredWhen:{variable:"projectrequired",init:"true"},column:1,awPopOver:"

        Select the project containing the playbook you want this job to execute.

        ",dataTitle:"Project",dataPlacement:"right",dataContainer:"body"},playbook:{label:"Playbook",type:"select",ngOptions:"book for book in playbook_options",id:"playbook-select",awRequiredWhen:{variable:"playbookrequired",init:"true"},column:1,awPopOver:"

        Select the playbook to be executed by this job.

        ",dataTitle:"Playbook",dataPlacement:"right",dataContainer:"body"},credential:{label:"Machine Credential",type:"lookup",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing the username and SSH key or password that Ansbile will need to log into the remote hosts.

        ",dataTitle:"Credential",dataPlacement:"right",dataContainer:"body"},cloud_credential:{label:"Cloud Credential",type:"lookup",sourceModel:"cloud_credential",sourceField:"name",ngClick:"lookUpCloudcredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Selecting an optional cloud credential in the job template will pass along the access credentials to the running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.

        ",dataTitle:"Cloud Credential",dataPlacement:"right",dataContainer:"body"},forks:{label:"Forks",id:"forks-number",type:"number",integer:!0,min:0,spinner:!0,"default":"0",addRequired:!1,editRequired:!1,"class":"input-small",column:1,awPopOver:'

        The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies the default value from the ansible configuration file.

        ',dataTitle:"Forks",dataPlacement:"right",dataContainer:"body"},limit:{label:"Limit",type:"text",addRequired:!1,editRequired:!1,column:1,awPopOver:'

        Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. Multiple patterns can be separated by ; : or ,

        For more information and examples see the Patters top at docs.ansible.com.

        ',dataTitle:"Limit",dataPlacement:"right",dataContainer:"body"},verbosity:{label:"Verbosity",type:"select",ngOptions:"v.label for v in verbosity_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"

        Control the level of output ansible will produce as the playbook executes.

        ",dataTitle:"Verbosity",dataPlacement:"right",dataContainer:"body"},variables:{label:"Extra Variables",type:"textarea",rows:6,"class":"span12",addRequired:!1,editRequired:!1,"default":"---",column:2,awPopOver:'

        Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n',dataTitle:"Extra Variables",dataPlacement:"right",dataContainer:"body"},job_tags:{label:"Job Tags",type:"textarea",rows:1,addRequired:!1,editRequired:!1,"class":"span12",column:2,awPopOver:"

        Provide a comma separated list of tags.

        \n

        Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.

        For example, you might have a task consisiting of a long list of actions. Tag values can be assigned to each action. Suppose the actions have been assigned tag values of "configuration", "packages" and "install".

        If you just want to run the "configuration" and "packages" actions, you would enter the following here in the Job Tags field:

        \n
        configuration,packages
        \n",dataTitle:"Job Tags",dataPlacement:"right",dataContainer:"body"},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')",column:2,awPopOver:'

        Create a callback URL a host can use to contact Tower and request a configuration update using the job template. The URL will look like the following:

        \n

        http://your.server.com:999/api/v1/job_templates/1/callback/

        The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataTitle:"Callback URL",dataContainer:"body"},callback_url:{label:"Callback URL",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:2,required:!1,"class":"span12",awPopOver:'

        Using this URL a host can contact Tower and request a configuration update using the job template. The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataTitle:"Callback URL",dataContainer:"body"},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2,awPopOver:'

        When contacting the Tower server using the callback URL, the calling host must authenticate by including this key in the POST data of the request. Here\'s an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n',dataPlacement:"right",dataContainer:"body"}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{jobs:{type:"collection",title:"Jobs",iterator:"job",index:!1,open:!1,actions:{reset:{dataPlacement:"top",icon:"icon-undo",mode:"all","class":"btn-xs btn-primary",awToolTip:"Reset the search filter",ngClick:"resetSearch('job')",iconSize:"large"}},fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},created:{label:"Date",link:!1,searchable:!1},status:{label:"Status","class":"job-{{ job.status }}",searchType:"select",linkTo:"{{}} job.statusLinkTo }}",searchOptions:[{name:"new",value:"new"},{name:"waiting",value:"waiting"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",value:"failed"},{name:"canceled",value:"canceled"}],badgeIcon:"fa icon-job-{{ job.status }}",badgePlacement:"left",badgeToolTip:"{{ job.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgHref:"{{ job.statusLinkTo }}",awToolTip:"{{ job.statusBadgeToolTip }}",dataPlacement:"top"}},fieldActions:{edit:{label:"View",ngClick:"edit('jobs', job.id, job.name)",icon:"icon-zoom-in"}}}}}),angular.module("JobFormDefinition",[]).value("JobForm",{addTitle:"Create Job",editTitle:"{{ id }} - {{ name }}",name:"jobs",well:!0,collapse:!0,collapseMode:"edit",collapseTitle:"Job Template",twoColumns:!0,navigationLinks:{details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",active:!0,ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",icon:"icon-laptop"}},fields:{name:{label:"Job Template",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,column:1},job_type:{label:"Job Type",type:"select",ngOptions:"type.label for type in job_type_options","default":"run",addRequired:!0,editRequired:!0,awPopOver:"

        When this template is submitted as a job, setting the type to run will execute the playbook, running tasks on the selected hosts.

        Setting the type to check will not execute the playbook. Instead, ansible will check playbook syntax, test environment setup and report problems.

        ",dataTitle:"Job Type",dataPlacement:"right",dataContainer:"body",column:1},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",addRequired:!0,editRequired:!0,ngClick:"lookUpInventory()",column:1,awPopOver:"

        Select the inventory containing the hosts you want this job to manage.

        ",dataTitle:"Inventory",dataPlacement:"right",dataContainer:"body"},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",addRequired:!0,editRequired:!0,ngClick:"lookUpProject()",column:1,awPopOver:"

        Select the project containing the playbook you want this job to execute.

        ",dataTitle:"Project",dataPlacement:"right",dataContainer:"body"},playbook:{label:"Playbook",type:"select",ngOptions:"book for book in playbook_options",id:"playbook-select",addRequired:!0,editRequired:!0,column:1,awPopOver:"

        Select the playbook to be executed by this job.

        ",dataTitle:"Playbook",dataPlacement:"right",dataContainer:"body"},credential:{label:"Credential",type:"lookup",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing the username and SSH key or password that Ansbile will need to log into the remote hosts.

        ",dataTitle:"Credential",dataPlacement:"right",dataContainer:"body"},cloud_credential:{label:"Cloud Credential",type:"lookup",sourceModel:"cloud_credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1,awPopOver:"

        Selecting an optional cloud credential in the job template will pass along the access credentials to the running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.

        ",dataTitle:"Cloud Credential",dataPlacement:"right",dataContainer:"body"},forks:{label:"Forks",id:"forks-number",type:"number",integer:!0,min:0,spinner:!0,"class":"input-small","default":"0",addRequired:!1,editRequired:!1,column:1,disabled:!0,awPopOver:"

        The number of parallel or simultaneous processes to use while executing the playbook.

        ",dataContainer:"body",dataTitle:"Forks",dataPlacement:"right"},limit:{label:"Limit",type:"text",addRequired:!1,editRequired:!1,column:1,awPopOver:'

        Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. Multiple patterns can be separated by ; : or ,

        For more information and examples see the Selecting Targets section under Inventory and Patterns in the Ansible documentation.

        ',dataContainer:"body",dataTitle:"Limit",dataPlacement:"right"},verbosity:{label:"Verbosity",type:"select",ngOptions:"v.label for v in verbosity_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"

        Control the level of output ansible will produce as the playbook executes.

        ",dataTitle:"Verbosity",dataPlacement:"right",dataContainer:"body"},variables:{label:"Extra Variables",type:"textarea",rows:6,"class":"span12",addRequired:!1,editRequired:!1,column:2,awPopOver:'

        Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.

        JSON:
        \n
        {
        "somevar": "somevalue",
        "password": "magic"
        }
        \nYAML:
        \n
        ---
        somevar: somevalue
        password: magic
        \n',dataTitle:"Extra Variables",dataContainer:"body",dataPlacement:"right"},job_tags:{label:"Job Tags",type:"textarea",rows:1,addRequired:!1,editRequired:!1,"class":"span12",column:2,awPopOver:"

        Provide a comma separated list of tags.

        \n

        Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.

        For example, you might have a task consisiting of a long list of actions. Tag values can be assigned to each action. Suppose the actions have been assigned tag values of "configuration", "packages" and "install".

        If you just want to run the "configuration" and "packages" actions, you would enter the following here in the Job Tags field:

        \n
        configuration,packages
        \n",dataTitle:"Job Tags",dataContainer:"body",dataPlacement:"right"},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')","class":"span12",column:2,awPopOver:'

        Create a callback URL a host can use to contact Tower and request a configuration update using the job template. The URL will look like the following:

        \n

        http://your.server.com:999/api/v1/job_templates/1/callback/

        The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataContainer:"body",dataTitle:"Callback URL"},callback_url:{label:"Callback URL",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:2,required:!1,"class":"span12",awPopOver:'

        Using this URL a host can contact Tower and request a configuration update using the job template. The request from the host must be a POST. Here is an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n

        Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.

        Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.

        ',dataPlacement:"right",dataContainer:"body",dataTitle:"Callback URL"},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2,awPopOver:'

        When contacting Tower using the callback URL, the calling host must authenticate by including this key in the POST data of the request. Here\'s an example using curl:

        \n

        curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/

        \n',dataPlacement:"right",dataContainer:"body"}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-undo","class":"btn btn-default",ngDisabled:!0}},statusFields:{status:{type:"custom",control:'
        Status {{ status }}
        ',readonly:!0},created:{label:"Created On",type:"text",readonly:!0},result_stdout:{label:"Standard Out",type:"textarea",readonly:!0,xtraWide:!0,rows:"{{ stdout_rows }}","class":"nowrap mono-space",ngShow:"result_stdout != ''"},result_traceback:{label:"Traceback",type:"textarea",xtraWide:!0,readonly:!0,rows:"{{ traceback_rows }}","class":"nowrap mono-space",ngShow:"result_traceback != ''"}},statusActions:{refresh:{dataPlacement:"top",icon:"icon-refresh",iconSize:"large",mode:"all","class":"btn-xs btn-primary",awToolTip:"Refresh the page",ngClick:"refresh()"}}}),angular.module("LicenseFormDefinition",[]).value("LicenseForm",{name:"license",well:!1,forceListeners:!0,fields:{license_status:{type:"custom",control:'
        {{ license_status }}
        ',readonly:!0,section:"License"},license_key:{label:"Key",type:"textarea","class":"modal-input-xlarge",readonly:!0,section:"License"},license_date:{label:"Expires On",type:"text",readonly:!0,section:"License"},time_remaining:{label:"Time Left",type:"text",readonly:!0,section:"License"},available_instances:{label:"Available",type:"text",readonly:!0,section:"Managed Hosts"},current_instances:{label:"Used",type:"text",readonly:!0,section:"Managed Hosts"},free_instances:{label:"Remaining",type:"text",readonly:!0,section:"Managed Hosts",controlNGClass:"free_instances_class",labelNGClass:"free_instances_class"},company_name:{label:"Company",type:"text",readonly:!0,section:"Contact Info"},contact_name:{label:"Contact",type:"text",readonly:!0,section:"Contact Info"},contact_email:{label:"Contact Email",type:"text",readonly:!0,section:"Contact Info"}}}),angular.module("OrganizationFormDefinition",[]).value("OrganizationForm",{addTitle:"Create Organization",editTitle:"{{ name }}",name:"organization",well:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{users:{type:"collection",title:"Users",iterator:"user",open:!1,actions:{add:{ngClick:"add('users')",label:"Add",icon:"icon-plus",awToolTip:"Add a new user"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', user.id, user.username)",icon:"icon-edit","class":"btn-default",awToolTip:"Edit user"},"delete":{label:"Delete",ngClick:"delete('users', user.id, user.username, 'users')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove user"}}},admins:{type:"collection",title:"Administrators",iterator:"admin",open:!1,base:"/users",actions:{add:{ngClick:"add('admins')",icon:"icon-plus",label:"Add",awToolTip:"Add new administrator"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', admin.id, admin.username)",icon:"icon-edit",awToolTip:"Edit administrator","class":"btn-default"},"delete":{label:"Delete",ngClick:"delete('admins', admin.id, admin.username, 'administrators')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove administrator"}}}}}),angular.module("PermissionFormDefinition",[]).value("PermissionsForm",{addTitle:"Add Permission",editTitle:"{{ name }}",name:"permission",well:!0,forceListeners:!0,stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"},fields:{category:{label:"Permission Type",labelClass:"prepend-asterisk",type:"radio_group",options:[{label:"Inventory",value:"Inventory",selected:!0},{label:"Deployment",value:"Deploy"}],ngChange:"selectCategory()"},name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},user:{label:"User",type:"hidden"},team:{label:"Team",type:"hidden"},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",ngShow:"category == 'Deploy'",ngClick:"lookUpProject()",awRequiredWhen:{variable:"projectrequired",init:"false"}},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",ngClick:"lookUpInventory()",awRequiredWhen:{variable:"inventoryrequired",init:"true"}},permission_type:{label:"Permission",labelClass:"prepend-asterisk",type:"radio_group",options:[{label:"Read",value:"read",ngShow:"category == 'Inventory'"},{label:"Write",value:"write",ngShow:"category == 'Inventory'"},{label:"Admin",value:"admin",ngShow:"category == 'Inventory'"},{label:"Run",value:"run",ngShow:"category == 'Deploy'"},{label:"Check",value:"check",ngShow:"category == 'Deploy'"}],helpCollapse:[{hdr:"Permission",ngBind:"permissionTypeHelp"}]}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{}}),angular.module("ProjectStatusDefinition",[]).value("ProjectStatusForm",{name:"project_update",editTitle:"SCM Status",well:!1,"class":"horizontal-narrow",fields:{created:{label:"Created",type:"text",readonly:!0},status:{label:"Status",type:"text",readonly:!0},result_stdout:{label:"Std Out",type:"textarea",ngShow:"result_stdout","class":"mono-space",readonly:!0,rows:15},result_traceback:{label:"Traceback",type:"textarea",ngShow:"result_traceback","class":"mono-space",readonly:!0,rows:15}}}),angular.module("ProjectFormDefinition",[]).value("ProjectsForm",{addTitle:"Create Project",editTitle:"{{ name }}",name:"project",well:!0,forceListeners:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",addRequired:!0,editRequired:!1,excludeMode:"edit",ngClick:"lookUpOrganization()",awRequiredWhen:{variable:"organizationrequired",init:"true"},awPopOver:"

        A project must have at least one organization. Pick one organization now to create the project, and then after the project is created you can add additional organizations.

        Only super users and organization administrators are allowed to make changes to projects. Associating one or more organizations to a project determins which organizations admins have access to modify the project.",dataTitle:"Organization",dataContainer:"body",dataPlacement:"right"},scm_type:{label:"SCM Type",type:"select",ngOptions:"type.label for type in scm_type_options",ngChange:"scmChange()",addRequired:!0,editRequired:!0},missing_path_alert:{type:"alertblock","class":"alert-info",ngShow:"showMissingPlaybooksAlert && scm_type.value == ''",alertTxt:'

        WARNING: There are no unassigned playbook directories in the base project path {{ base_dir }}. Either the projects directory is empty, or all of the contents are already assigned to other projects. New projects can be checked out from source control by changing the SCM type option rather than specifying checkout paths manually. To continue with manual setup, log into the Tower host and ensure content is present in a subdirectory under {{ base_dir }}. Run "chown -R awx" on the content directory to ensure Tower can read the playbooks.

        ',closeable:!1},base_dir:{label:"Project Base Path",type:"textarea",showonly:!0,ngShow:"scm_type.value == ''",awPopOver:"

        Base path used for locating playbooks. Directories found inside this path will be listed in the playbook directory drop-down. Together the base path and selected playbook directory provide the full path used to locate playbooks.

        Use PROJECTS_ROOT in your environment settings file to determine the base path value.

        ",dataTitle:"Project Base Path",dataContainer:"body",dataPlacement:"right"},local_path:{label:"Playbook Directory",type:"select",id:"local-path-select",ngOptions:"path.label for path in project_local_paths",awRequiredWhen:{variable:"pathRequired",init:!1},ngShow:"scm_type.value == '' && !showMissingPlaybooksAlert",awPopOver:"

        Select from the list of directories found in the base path.Together the base path and the playbook directory provide the full path used to locate playbooks.

        Use PROJECTS_ROOT in your environment settings file to determine the base path value.

        ",dataTitle:"Project Path",dataContainer:"body",dataPlacement:"right"},scm_url:{label:"SCM URL",type:"text",ngShow:"scm_type && scm_type.value !== ''",awRequiredWhen:{variable:"scmRequired",init:!1},helpCollapse:[{hdr:"GIT URLs",content:'

        Example URLs for GIT SCM include:

        • https://github.com/ansible/ansible.git
        • git@github.com:ansible/ansible.git
        • git://servername.example.com/ansible.git

        Note: If using SSH protocol for GitHub or Bitbucket, enter in the SSH key only, do not enter a username (other than git). Additionally, GitHub and Bitbucket do not support password authentication when using SSH protocol. GIT read only protocol (git://) does not use username or password information.',show:"scm_type.value == 'git'"},{hdr:"SVN URLs",content:'

        Example URLs for Subversion SCM include:

        • https://github.com/ansible/ansible
        • svn://servername.example.com/path
        • svn+ssh://servername.example.com/path
        ',show:"scm_type.value == 'svn'"},{hdr:"Mercurial URLs",content:'

        Example URLs for Mercurial SCM include:

        • https://bitbucket.org/username/project
        • ssh://hg@bitbucket.org/username/project
        • ssh://server.example.com/path

        Note: Mercurial does not support password authentication for SSH. If applicable, add the username, password and key below. Do not put the username and key in the URL. If using Bitbucket and SSH, do not supply your Bitbucket username.',show:"scm_type.value == 'hg'"}]},scm_branch:{labelBind:"scmBranchLabel",type:"text",ngShow:"scm_type && scm_type.value !== ''",addRequired:!1,editRequired:!1},credential:{label:"SCM Credential",type:"lookup",ngShow:"scm_type && scm_type.value !== ''",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1},checkbox_group:{label:"SCM Update Options",type:"checkbox_group",ngShow:"scm_type && scm_type.value !== ''",fields:[{name:"scm_clean",label:"Clean",type:"checkbox",addRequired:!1,editRequired:!1,awPopOver:"

        Remove any local modifications prior to performing an update.

        ",dataTitle:"SCM Clean",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"scm_delete_on_update",label:"Delete on Update",type:"checkbox",addRequired:!1,editRequired:!1,awPopOver:"

        Delete the local repository in its entirety prior to performing an update.

        Depending on the size of the repository this may significantly increase the amount of time required to complete an update.

        ",dataTitle:"SCM Delete",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"},{name:"scm_update_on_launch",label:"Update on Launch",type:"checkbox",addRequired:!1,editRequired:!1,awPopOver:"

        Each time a job runs using this project, perform an update to the local repository prior to starting the job.

        ",dataTitle:"SCM Update",dataContainer:"body",dataPlacement:"right",labelClass:"checkbox-options"}]}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{organizations:{type:"collection",title:"Organizations",iterator:"organization",open:!1,actions:{add:{ngClick:"add('organizations')",icon:"icon-plus",label:"Add",awToolTip:"Add an organization"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('organizations', organization.id, organization.name)",icon:"icon-edit",awToolTip:"Edit the organization","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('organizations', organization.id, organization.name, 'organizations')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the organization"}}}}}),angular.module("TeamFormDefinition",[]).value("TeamForm",{addTitle:"Create Team",editTitle:"{{ name }}",name:"team",well:!0,collapse:!0,collapseTitle:"Team Settings",collapseMode:"edit",collapseOpen:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",ngClick:"lookUpOrganization()",awRequiredWhen:{variable:"teamrequired",init:"true"}}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{credentials:{type:"collection",title:"Credentials",iterator:"credential",open:!1,actions:{add:{ngClick:"add('credentials')",icon:"icon-plus",label:"Add",add:"Add a new credential"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('credentials', credential.id, credential.name)",icon:"icon-edit",awToolTip:"Modify the credential","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('credentials', credential.id, credential.name, 'credentials')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove the credential"}}},permissions:{type:"collection",title:"Permissions",iterator:"permission",open:!1,actions:{add:{ngClick:"add('permissions')",icon:"icon-plus",label:"Add",awToolTip:"Add a permission for this user",ngShow:"PermissionAddAllowed"}},fields:{name:{key:!0,label:"Name",ngClick:"edit('permissions', permission.id, permission.name)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('permissions', permission.id, permission.name)",icon:"icon-edit",awToolTip:"Edit the permission","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('permissions', permission.id, permission.name, 'permissions')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the permission",ngShow:"PermissionAddAllowed"}}},projects:{type:"collection",title:"Projects",iterator:"project",open:!1,actions:{add:{ngClick:"add('projects')",icon:"icon-plus",label:"Add"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('projects', project.id, project.name)",icon:"icon-edit",awToolTip:"Modify the project","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('projects', project.id, project.name, 'projects')",icon:"icon-trash","class":"btn-danger",awToolTip:"Remove the project"}}},users:{type:"collection",title:"Users",iterator:"user",open:!1,actions:{add:{ngClick:"add('users')",icon:"icon-plus",label:"Add",awToolTip:"Add a user"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', user.id, user.username)",icon:"icon-edit",awToolTip:"Edit user","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('users', user.id, user.username, 'users')",icon:"icon-terash","class":"btn-danger",awToolTip:"Remove user"}}}}}),angular.module("UserFormDefinition",[]).value("UserForm",{addTitle:"Create User",editTitle:"{{ username }}",name:"user",well:!0,forceListeners:!0,actions:{stream:{"class":"btn-primary btn-xs activity-btn",ngClick:"showActivity()",awToolTip:"View Activity Stream",dataPlacement:"top",icon:"icon-comments-alt",mode:"edit",iconSize:"large"}},fields:{first_name:{label:"First Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},last_name:{label:"Last Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},email:{label:"Email",type:"email",addRequired:!0,editRequired:!0,autocomplete:!1},organization:{label:"Organization",type:"lookup",sourceModel:"organization",sourceField:"name",ngClick:"lookUpOrganization()",excludeMode:"edit",awRequiredWhen:{variable:"orgrequired",init:!0}},username:{label:"Username",type:"text",awRequiredWhen:{variable:"not_ldap_user",init:!0},autocomplete:!1},password:{label:"Password",type:"password",ngShow:"ldap_user == false",addRequired:!0,editRequired:!1,ngChange:"clearPWConfirm('password_confirm')",autocomplete:!1,chkPass:!0},password_confirm:{label:"Confirm Password",type:"password",ngShow:"ldap_user == false",addRequired:!1,editRequired:!1,awPassMatch:!0,associated:"password",autocomplete:!1},is_superuser:{label:"Superuser (User has full system administration privileges.)",type:"checkbox",trueValue:"true",falseValue:"false","default":"false",ngShow:"current_user['is_superuser'] == true"},ldap_user:{label:"Created by LDAP",type:"checkbox",readonly:!0}},buttons:{save:{ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",ngDisabled:!0}},related:{credentials:{type:"collection",title:"Credentials",iterator:"credential",open:!1,actions:{add:{ngClick:"add('credentials')",icon:"icon-plus",label:"Add",awToolTip:"Add a credential for this user"}},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('credentials', credential.id, credential.name)",icon:"icon-edit",awToolTip:"Edit the credential","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('credentials', credential.id, credential.name, 'credentials')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the credential"}}},permissions:{type:"collection",title:"Permissions",iterator:"permission",open:!1,actions:{add:{ngClick:"add('permissions')",icon:"icon-plus",label:"Add",awToolTip:"Add a permission for this user",ngShow:"PermissionAddAllowed"}},fields:{name:{key:!0,label:"Name",ngClick:"edit('permissions', permission.id, permission.name)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('permissions', permission.id, permission.name)",icon:"icon-edit",awToolTip:"Edit the permission","class":"btn btn-default"},"delete":{label:"Delete",ngClick:"delete('permissions', permission.id, permission.name, 'permissions')",icon:"icon-trash","class":"btn-danger",awToolTip:"Delete the permission",ngShow:"PermissionAddAllowed"}}},admin_of_organizations:{type:"collection",title:"Admin of Organizations",iterator:"adminof",open:!1,base:"/organizations",actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}},organizations:{type:"collection",title:"Organizations",iterator:"organization",open:!1,actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}},teams:{type:"collection",title:"Teams",iterator:"team",open:!1,actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}},projects:{type:"collection",title:"Projects",iterator:"project",open:!1,actions:{},fields:{name:{key:!0,label:"Name"},description:{label:"Description"}}}}}),angular.module("InventoryGroupsHelpDefinition",[]).value("InventoryGroupsHelp",{story:{hdr:"Building your inventory",width:510,height:560,steps:[{intro:"Start by creating a group:",img:{src:"groups001.png",maxWidth:338,maxHeight:222},box:'Click on the groups list (the left side of the page) to add a new group.',autoOffNotice:!0},{intro:"Enter group properties:",img:{src:"groups002.png",maxWidth:443,maxHeight:251},box:'Enter the group name, a description and any inventory variables. Variables can be entered using either JSON or YAML syntax. For more on inventory variables, see docs.ansible.com/intro_inventory.html'},{intro:"Cloud inventory: select cloud source",img:{src:"groups003.png",maxWidth:412,maxHeight:215},box:'For a cloud inventory, choose the cloud provider from the list and select your credentials. If you have not already setup credentials for the provider, you will need to do that first on the Credentials tab.'},{intro:"Cloud inventory: synchronize Tower with the cloud",img:{src:"groups004.png",maxWidth:261,maxHeight:221},box:'To pull the cloud inventory into Tower, initiate an inventory sync by clicking .'},{intro:"Groups can have subgroups:",img:{src:"groups005.png",maxWidth:430,maxHeight:206},box:'
        First, select a group. Then click to create a new group. The new group will be added to the selected group.
        '},{intro:"Copy or move groups:",img:{src:"groups006.png",maxWidth:263,maxHeight:211},box:'
        Copy or move a group by dragging and dropping its name onto another group name. A dialog will appear asking if the group should be coppied or moved.
        '},{intro:"Adding hosts:",img:{src:"groups007.png",maxWidth:466,maxHeight:178},box:'

        First, select a Group. Then click on the hosts list (the right side of the page) to create a host. The new host will be part of the selected group.

        Note hosts cannot be added to the All Hosts group.

        '}]}}),angular.module("AccessHelper",["RestServices","Utilities","ngCookies"]).factory("CheckAccess",["$rootScope","Alert","Rest","GetBasePath","ProcessErrors",function(a,b,c,d,e){return function(b){var d=a.current_user,f=b.scope; +d.is_superuser?f.PermissionAddAllowed=!0:d.related.admin_of_organizations&&(c.setUrl(d.related.admin_of_organizations),c.get().success(function(a){f.PermissionAddAllowed=a.results.length>0?!0:!1}).error(function(a,b){e(f,a,b,null,{hdr:"Error!",msg:"Call to "+d.related.admin_of_organizations+" failed. DELETE returned status: "+b})}))}}]).factory("CheckLicense",["$rootScope","$cookieStore","Alert","$location","Authorization",function(a,b,c,d,e){return function(){var d,f,g="success",h=b.get("license"),i='

        To purchase a license or extend an existing license visit the Ansible online store, or visit support.ansible.com for assistance.

        ';h&&!e.licenseTested()&&(h.tested=!0,b.remove("license"),b.put("license",h),a.license_tested=!0,void 0!==h.valid_key&&h.valid_key===!1?(g="alert-danger",d="License Error",f="

        There is a problem with the /etc/awx/license file on your Tower server. Check to make sure Tower can access the file.

        "+i,c(d,f,g,null,!1,!0)):void 0!==h.demo&&h.demo===!0&&(g="alert-info",d="Tower Demo",f="

        Thank you for trying Ansible Tower. You can use this edition to manage up to 10 hosts free.

        "+i,c(d,f,g)),void 0!==h.date_expired&&h.date_expired===!0?(g="alert-info",d="License Expired",f="

        Your Ansible Tower License has expired and is no longer compliant. You can continue, but you will be unable to add any additional hosts.

        "+i,c(d,f,g)):void 0!==h.date_warning&&h.date_warning===!0&&(g="alert-info",d="License Warning",f="

        Your Ansible Tower license is about to expire!

        "+i,c(d,f,g)),void 0!==h.free_instances&&parseInt(h.free_instances)<=0&&(g="alert-info",d="License Warning",f="

        Your Ansible Tower license has reached capacity for the number of managed hosts allowed. You will not be able to add any additional hosts.

        "+i,c(d,f,g,null,!0)))}}]),angular.module("ChildrenHelper",["RestServices","Utilities"]).factory("ToggleChildren",[function(){return function(a){function b(a){var b;for(i[a].ngicon="fa fa-minus-square-o node-toggle",b=a+1;b10?10:i,i=3>i?3:i,f.fields[h].rows=i);break;case"results":if(a.event_data&&a.event_data.res&&void 0===a.event_data.res[h])delete f.fields[h];else if(Array.isArray(a.event_data.res[h])&&0!==a.event_data.res[h].length){for(j="",c=0;c10?10:i,i=3>i?3:i,f.fields[h].rows=i)}else delete f.fields[h];break;case"module_name":case"module_args":a.event_data&&a.event_data.res&&(void 0===a.event_data.res.invocation||void 0===a.event_data.res.invocation[h])&&delete f.fields[h]}b=d.inject(f,{mode:"edit",modal:!0,related:!1}),d.reset(),b.formModalAction=function(){$("#form-modal").modal("hide")},b.formModalActionLabel="OK",b.formModalCancelShow=!1,b.formModalInfo="View JSON",$("#form-modal .btn-success").removeClass("btn-success").addClass("btn-none"),$("#form-modal").addClass("skinny-modal"),b.formModalHeader=a.event_display.replace(/^\u00a0*/g,""),b.formModalInfoAction=function(){var b=g,c=b.inject(l,{mode:"edit",modal:!0,related:!1,modal_selector:"#form-modal2",modal_body_id:"form-modal2-body",modal_title_id:"formModal2Header"});b.reset(),c.formModal2Header=a.event_display.replace(/^\u00a0*/g,""),c.event_data=JSON.stringify(a.event_data,null," "),c.formModal2ActionLabel="OK",c.formModal2CancelShow=!1,c.formModal2Info=!1,c.formModalInfo="View JSON",c.formModal2Action=function(){$("#form-modal2").modal("hide")},$("#form-modal2 .btn-success").removeClass("btn-success").addClass("btn-none")},"string"==typeof a.event_data.res&&(b.traceback=a.event_data.res);for(h in f.fields)switch(h){case"status":b.status=a.failed?"error":a.changed?"changed":"success";break;case"created":n=new Date(a.created),b.created=k(n);break;case"host":a.summary_fields&&a.summary_fields.host&&(b.host=a.summary_fields.host.name);break;case"id":case"task":case"play":b[h]=a[h];break;case"start":case"end":a.event_data&&a.event_data.res&&!m(a.event_data.res[h])&&(b[h]=a.event_data.res[h]);break;case"results":if(Array.isArray(a.event_data.res[h])&&a.event_data.res[h].length>0){for(j="",c=0;c
        button.',"alert-info"):(f("start"),a.setUrl(l.related.inventory_source),a.get().success(function(a){var b=a.related.current_update?a.related.current_update:a.related.last_update;d({group_name:a.summary_fields.group.name,last_update:b,license_error:a.summary_fields.last_update&&a.summary_fields.last_update.license_error?!0:!1,tree_id:j,group_id:k,parent_scope:i})}).error(function(a,c){f("stop"),b(i,a,c,null,{hdr:"Error!",msg:"Failed to retrieve inventory source: "+l.related.inventory_source+" POST returned status: "+c})})))}}]).factory("GetHostsStatusMsg",[function(){return function(a){var b,c,d,e=a.active_failures,f=a.total_hosts;return e>0?(b=f+(1===f?" host":" hosts")+". "+e+" with failed jobs.",d="true",c=!0):(c=!1,0===f?(b="Group contains 0 hosts.",d="na"):(b=f+(1===f?" host":" hosts")+". No job failures",d="false")),{tooltip:b,failures:c,"class":d}}}]).factory("GetSyncStatusMsg",[function(){return function(a){var b,c,d,e=a.status,f="",g="Start sync process";switch(b=e,c="icon-cloud-"+b,e){case"never updated":b="never",c="icon-cloud-na disabled",d='Sync not performed. Click to start it now.';break;case"none":case"":f="btn-disabled",b="n/a",c="icon-cloud-na disabled",d='Cloud source not configured. Click to update.',g=d;break;case"failed":d="Sync failed. Click to view log.";break;case"successful":d="Sync completed. Click to view log.";break;case"updating":d="Sync running"}return{"class":c,tooltip:d,status:b,launch_class:f,launch_tip:g}}}]).factory("SourceChange",["GetBasePath","CredentialList","LookUpInit","Empty",function(a,b,c,d){return function(e){var f,g,h=e.scope,i=e.form;d(h.source)||("file"===h.source.value?h.sourcePathRequired=!0:(h.sourcePathRequired=!1,h.source_path="",h[i.name+"_form"].source_path.$setValidity("required",!0)),"rax"===h.source.value?(h.source_region_choices=h.rax_regions,$("#s2id_group_source_regions").select2("data",[{id:"all",text:"All"}])):"ec2"===h.source.value&&(h.source_region_choices=h.ec2_regions,$("#s2id_group_source_regions").select2("data",[{id:"all",text:"All"}])),("rax"===h.source.value||"ec2"===h.source.value)&&(f="rax"===h.source.value?"rax":"aws",g=a("credentials")+"?cloud=true&kind="+f,c({url:g,scope:h,form:i,list:b,field:"credential"})))}}]).factory("GroupsCancelUpdate",["Rest","ProcessErrors","Alert","Wait","Find",function(a,b,c,d,e){return function(f){var g,h=f.scope,i=f.tree_id;h.removeCancelUpdate&&h.removeCancelUpdate(),h.removeCancelUpdate=h.$on("CancelUpdate",function(e,f){a.setUrl(f),a.post().success(function(){d("stop"),c("Inventory Sync Cancelled",'Your request to cancel the sync process was submitted to the task manger. Click the button to monitor the status.',"alert-info")}).error(function(a,c){d("stop"),b(h,a,c,null,{hdr:"Error!",msg:"Call to "+f+" failed. POST status: "+c})})}),h.removeCheckCancel&&h.removeCheckCancel(),h.removeCheckCancel=h.$on("CheckCancel",function(e,f,g){var i=g?g:f;i+="cancel/",a.setUrl(i),a.get().success(function(a){a.can_cancel?h.$emit("CancelUpdate",i):(d("stop"),c("Cancel Inventory Sync",'Either you do not have access or the sync process completed.
        Click the button to view the latest status.',"alert-info"))}).error(function(a,c){d("stop"),b(h,a,c,null,{hdr:"Error!",msg:"Call to "+i+" failed. GET status: "+c})})}),g=e({list:h.groups,key:"id",val:i}),h.selected_tree_id=g.id,h.selected_group_id=g.group_id,!g||"updating"!==g.status&&"pending"!==g.status?c("Cancel Inventory Sync",'The sync process completed. Click the to view the latest status.',"alert-info"):(d("start"),a.setUrl(g.related.inventory_source),a.get().success(function(a){h.$emit("CheckCancel",a.related.last_update,a.related.current_update)}).error(function(a,c){d("stop"),b(h,a,c,null,{hdr:"Error!",msg:"Call to "+g.related.inventory_source+" failed. GET status: "+c})}))}}]).factory("GroupsAdd",["$rootScope","$location","$log","$routeParams","Rest","Alert","GroupForm","GenerateForm","Prompt","ProcessErrors","GetBasePath","ParseTypeChange","GroupsEdit","Wait","GetChoices","GetSourceTypeOptions","LookUpInit","BuildTree","SourceChange","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){return function(b){var c,d=b.inventory_id,i=void 0!==b.group_id?b.group_id:null,m=b.scope,q=null!==i?k("groups")+i+"/children/":k("inventory")+d+"/groups/",u=g,v=h,w=v.inject(u,{mode:"add",modal:!0,related:!1,show_modal:!1});$("#form-modal .btn-none").removeClass("btn-none").addClass("btn-success"),w.formModalActionLabel="Save",w.formModalCancelShow=!0,w.parseType="yaml",w.source=null,l(w),v.reset(),w.removeAddTreeRefreshed&&w.removeAddTreeRefreshed(),w.removeAddTreeRefreshed=w.$on("GroupTreeRefreshed",function(){a.formModalHeader=null,a.formModalCancleShow=null,a.formModalActionLabel=null,n("stop"),$("#form-modal").modal("hide"),w.removeAddTreeRefreshed()}),w.removeSaveComplete&&w.removeSaveComplete(),w.removeSaveComplete=w.$on("SaveComplete",function(a,b,c){c||(w.searchCleanup&&w.searchCleanup(),w.formModalActionDisabled=!1,r({scope:m,inventory_id:d,refresh:!0,new_group_id:b}),t())}),w.removeFormSaveSuccess&&w.removeFormSaveSuccess(),w.removeFormSaveSuccess=w.$on("formSaveSuccess",function(a,b,c){var d,g,h,i,k=!1,l={};if(null!==w.source.value&&""!==w.source.value){for(l.group=b,l.source=w.source.value,l.source_path=w.source_path,l.credential=w.credential,l.overwrite=w.overwrite,l.overwrite_vars=w.overwrite_vars,l.update_on_launch=w.update_on_launch,d=$("#s2id_group_source_regions").select2("data"),g=[],h=0;h"+A.summary_fields.group.name+"
        . Use the Refresh button to monitor the status.","alert-info"):o({scope:A,group_id:d,url:A.group_update_url,group_name:A.name,group_source:A.source.value})},A.sourceChange=function(){v({scope:A,form:g})}}}]).factory("GroupsDelete",["$rootScope","$location","$log","$routeParams","Rest","Alert","GroupForm","GenerateForm","Prompt","ProcessErrors","GetBasePath","Wait","BuildTree","Find",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return function(a){var b,c=a.scope,d=a.tree_id,f=a.inventory_id,g=n({list:c.groups,key:"id",val:d}),h=k("inventory")+f+"/groups/";b=function(){$("#prompt-modal").on("hidden.bs.modal",function(){l("start")}),$("#prompt-modal").modal("hide"),e.setUrl(h),e.post({id:g.group_id,disassociate:1}).success(function(){$("#prompt-modal").off(),c.$emit("GroupDeleteCompleted")}).error(function(a,b){l("stop"),j(c,a,b,null,{hdr:"Error!",msg:"Call to "+h+" failed. POST returned status: "+b})})},i({hdr:"Delete Group",body:"

        Are you sure you want to delete group "+g.name+"?

        ",action:b,"class":"btn-danger"})}}]).factory("ShowUpdateStatus",["$rootScope","$location","$log","$routeParams","Rest","Alert","GenerateForm","Prompt","ProcessErrors","GetBasePath","FormatDate","InventoryStatusForm","Wait","Empty","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(a){function b(a){var b,d;return b=a.match(/\n/g),d=b?b.length:1,d>c?c:d}var c,d,h,j,n,p,q,r=a.group_name,s=a.last_update,t=g,u=l,v=a.license_error;void 0===s||null===s||""===s?(m("stop"),f("Missing Configuration","The selected group is not configured for inventory sync. Edit the group and provide Source information.","alert-info")):(d='
        \n
        \n',$("#inventory-modal-container").empty().append(d),h=t.inject(u,{mode:"edit",id:"form-container",breadCrumbs:!1,related:!1}),j=$(document).width(),n=$("body").height(),j>1199?(p=675,q=750>n?n-20:750,c=18):1199>=j&&j>=768?(p=550,q=620>n?n-15:620,c=12):(p=j-20,q=500>n?n:500,c=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:p,height:q,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#inventory-modal-container").empty(),o()},open:function(){m("stop")}}),e.setUrl(s),e.get().success(function(a){for(var c in u.fields)a[c]&&(h[c]="created"===c?k(new Date(a[c])):a[c]);h.license_error=v,h.status_rows=b(a.status),h.stdout_rows=b(a.result_stdout),h.traceback_rows=b(a.result_traceback),$("#status-modal-dialog").dialog("open")}).error(function(a,b){$("#form-modal").modal("hide"),i(h,a,b,null,{hdr:"Error!",msg:"Failed to retrieve last update: "+s+". GET status: "+b})}))}}]),angular.module("HostsHelper",["RestServices","Utilities","ListGenerator","HostListDefinition","SearchHelper","PaginationHelpers","ListGenerator","AuthService","HostsHelper","InventoryHelper","RelatedSearchHelper","InventoryFormDefinition","SelectionHelper","HostGroupsFormDefinition"]).factory("SetEnabledMsg",[function(){return function(a){a.enabledToolTip=a.has_inventory_sources?a.enabled?"Host is available":"Host is not available":a.enabled?"Host is available. Click to toggle.":"Host is not available. Click to toggle."}}]).factory("SetHostStatus",["SetEnabledMsg",function(a){return function(b){b.activeFailuresLink="/#/hosts/"+b.id+"/job_host_summaries/?inventory="+b.inventory+"&host_name="+encodeURI(b.name),b.has_active_failures===!0?(b.badgeToolTip="Most recent job failed. Click to view jobs.",b.active_failures="failed"):b.has_active_failures===!1&&null===b.last_job?(b.has_active_failures="none",b.badgeToolTip="No job data available.",b.active_failures="n/a"):b.has_active_failures===!1&&null!==b.last_job&&(b.badgeToolTip="Most recent job successful. Click to view jobs.",b.active_failures="success"),b.enabled_flag=b.enabled,a(b)}}]).factory("SetStatus",["SetEnabledMsg","Empty",function(a,b){return function(c){function d(a){return a.length>25?a.substr(0,25)+"...":a}function e(a){var b,c,e;if(a.has_active_failures===!0||a.has_active_failures===!1&&null!==a.last_job)if(a.has_active_failures===!0?(a.badgeToolTip="Most recent job failed. Click to view jobs.",a.active_failures="failed"):(a.badgeToolTip="Most recent job successful. Click to view jobs.",a.active_failures="success"),a.summary_fields.recent_jobs.length>0){for(e=a.summary_fields.recent_jobs.sort(function(a,b){return-1*(a-b)}),h="Recent Jobs",g='\n',g+="\n",g+="\n",g+="\n",g+="\n",g+="\n",g+="\n",b=0;b\n",g+='\n",g+='\n',g+='\n',g+='\n",g+="\n";g+="\n",g+="
        ID\n",g+='Status\n',g+="ViewName\n",g+="
        '+c.id+"Events Hosts'+d(c.name)+"
        \n"}else h="No job data",g="

        No recent job data available for this host.

        ";else a.has_active_failures===!1&&null===a.last_job&&(a.has_active_failures="none",a.badgeToolTip="No job data available.",a.active_failures="n/a");a.job_status_html=g,a.job_status_title=h}var f,g,h,i=c.scope,j=c.host;if(b(j))for(f=0;fAre you sure you want to delete host "+j+" from group "+n.name+"?

        ":"

        Are you sure you want to delete host "+j+"?

        ",g({hdr:"Delete Host",body:c,action:b,"class":"btn-danger"})}}]).factory("EditHostGroups",["$rootScope","$location","$log","$routeParams","Rest","Alert","GenerateForm","Prompt","ProcessErrors","GetBasePath","HostsReload","ParseTypeChange","Wait",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(a){var b,c,d,f,h,l=a.host_id,n=a.inventory_id,o=g,p=[];for(c='
        \n',c+='
        \n',c+="\n",c+='\n',c+="
        \n",c+='
        \n',c+="\n",c+='\n',c+="
        \n",c+="
        \n",c+='
        \n',c+='
        \n',c+='\n',c+='\n',c+="

        (move selected groups)

        \n",c+="
        \n",c+="
        \n",d=j("hosts")+l+"/",f=o.inject(null,{mode:"edit",modal:!0,related:!1,html:c}),b=0;bGroups',f.formModalCancelShow=!0,f.formModalActionDisabled=!0,$("#form-modal .btn-none").removeClass("btn-none").addClass("btn-success"),f.hostGroupChangeRemove&&f.hostGroupChangeRemove(),f.hostGroupChangeRemove=f.$on("hostGroupChange",function(){p.pop(),0===p.length&&(h=function(){setTimeout(function(){m("stop")},500)},k({scope:f,inventory_id:n,group_id:f.group_id,action:h}))}),f.formModalAction=function(){var a,b,c;for($("#form-modal").modal("hide"),m("start"),a=0;a0?(f.assignedGroups=null,f.leftButtonDisabled=!0,f.rightButtonDisabled=!1):f.rightButtonDisabled=!0},f.rightChange=function(){null!==f.assignedGroups&&f.assignedGroups.length>0?(f.selectedGroups=null,f.leftButtonDisabled=!1,f.rightButtonDisabled=!0):f.leftButtonDisabled=!0},f.moveLeft=function(){var a,b,c,d;for(a=0;af.available_groups[b].name.toLowerCase()&&f.assignedGroups[a].name.toLowerCase()f.host_groups[b].name.toLowerCase()&&f.selectedGroups[a].name.toLowerCase()0){for(j("stop"),u+='
        \n',u+=w?w:"",o=0;o\n',u+='\n",u+='
        \n',u+='A value is required!\n',u+='\n',u+="
        \n",u+="\n",n=l.associated,l=p.fields[l.associated],q[n]="",u+='
        \n',u+='\n",u+='
        \n',u+='A value is required!\n',l.awPassMatch&&(u+='Must match Password value\n'),u+='\n',u+="
        \n",u+="
        \n";u+="\n",m=angular.element(document.getElementById("password-body")),m.html(u),c(m.contents())(q),$("#password-modal").modal(),$("#password-modal").on("shown.bs.modal",function(){$("#password-body").find('input[type="password"]:first').focus()})}else q.startJob()}}]).factory("SubmitJob",["PromptPasswords","$compile","Rest","$location","GetBasePath","CredentialList","LookUpInit","CredentialForm","ProcessErrors","JobTemplateForm","Wait",function(a,b,c,d,e,f,g,h,i,j,k){return function(b){function l(b){var e,f,g;m.credentialWatchRemove&&m.credentialWatchRemove(),e=(new Date).toISOString(),f=b.related.jobs?b.related.jobs:b.related.job_template+"jobs/",g=o?o:b.name,k("start"),c.setUrl(f),c.post({name:g+" "+e,description:b.description,job_template:b.id,inventory:b.inventory,project:b.project,playbook:b.playbook,credential:b.credential,forks:b.forks,limit:b.limit,verbosity:b.verbosity,extra_vars:b.extra_vars}).success(function(b){m.job_id=b.id,b.passwords_needed_to_start.length>0?a({scope:m,passwords:b.passwords_needed_to_start,start_url:b.related.start,form:h}):(c.setUrl(b.related.start),c.post().success(function(){k("stop");var a=d.path().replace(/^\//,"").split("/")[0];"jobs"===a?m.refresh():d.path("/jobs")}).error(function(a,b){i(m,a,b,null,{hdr:"Error!",msg:"Failed to start job. POST returned status: "+b})}))}).error(function(a,b){k("stop"),i(m,a,b,null,{hdr:"Error!",msg:"Failed to create job. POST returned status: "+b})})}var m=b.scope,n=b.id,o=b.template?b.template:null,p=d.path().replace(/^\//,"").split("/")[0],q=e(p)+n+"/";k("start"),c.setUrl(q),c.get().success(function(a){m.credential="",""===a.credential||null===a.credential?(k("stop"),m.credentialWatchRemove&&m.credentialWatchRemove(),m.credentialWatchRemove=m.$watch("credential",function(b,c){b!==c&&""!==m.credential&&null!==m.credential&&void 0!==m.credential&&(a.credential=m.credential,l(a))}),g({scope:m,form:j,current_item:null,list:f,field:"credential",hdr:"Credential Required"}),m.lookUpCredential()):l(a)}).error(function(a,b){i(m,a,b,null,{hdr:"Error!",msg:"Failed to get job template details. GET returned status: "+b})})}}]).factory("ProjectUpdate",["PromptPasswords","$compile","Rest","$location","GetBasePath","ProcessErrors","Alert","ProjectsForm","Wait",function(a,b,c,d,e,f,g,h,i){return function(b){var d=b.scope,j=b.project_id,k=e("projects")+j+"/update/";d.removeUpdateSubmitted&&d.removeUpdateSubmitted(),d.removeUpdateSubmitted=d.$on("UpdateSubmitted",function(){i("stop"),g("Update Started","The request to start the SCM update process was submitted. To monitor the update status, refresh the page by clicking the Refresh button.","alert-info"),d.refresh()}),d.removeSCMSubmit&&d.removeSCMSubmit(),d.removeSCMSubmit=d.$on("SCMSubmit",function(b,c,e){a({scope:d,passwords:c,start_url:k,form:h,extra_html:e})}),i("start"),c.setUrl(k),c.get().success(function(a){var b,c;if(i("stop"),a.can_update){for(c="",b=0;b\n',c+='\n',c+='
        \n',c+=' button.',"alert-info"),d.removeHostReloadComplete&&d.removeHostReloadComplete()}),d.removeUpdateSubmitted&&d.removeUpdateSubmitted(),d.removeUpdateSubmitted=d.$on("UpdateSubmitted",function(a,b){"started"===b&&(d.refreshGroups?(d.selected_tree_id=k,d.selected_group_id=i,d.refreshGroups()):d.refresh&&d.refresh(),d.$emit("HostReloadComplete"))}),d.removeInventorySubmit&&d.removeInventorySubmit(),d.removeInventorySubmit=d.$on("InventorySubmit",function(b,c,f){a({scope:d,passwords:c,start_url:e,form:h,extra_html:f})}),j("start"),c.setUrl(e),c.get().success(function(a){a.can_update?d.$emit("InventorySubmit",a.passwords_needed_to_update):(j("stop"),g("Permission Denied","You do not have access to run the update. Please contact your system administrator.","alert-danger"))}).error(function(a,b){j("stop"),f(d,a,b,null,{hdr:"Error!",msg:"Failed to get inventory_source details. "+e+"GET status: "+b})})}}]),angular.module("JobsHelper",["Utilities","FormGenerator","JobSummaryDefinition","InventoryHelper"]).factory("JobStatusToolTip",[function(){return function(a){var b;switch(a){case"successful":case"success":b="There were no failed tasks.";break;case"failed":b="Some tasks encountered errors.";break;case"canceled":b="Stopped by user request.";break;case"new":b="In queue, waiting on task manager.";break;case"waiting":b="SCM Update or Inventory Update is executing.";break;case"pending":b="Not in queue, waiting on task manager.";break;case"running":b="Playbook tasks executing."}return b}}]).factory("ShowJobSummary",["Rest","Wait","GetBasePath","FormatDate","ProcessErrors","GenerateForm","JobSummary","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h){return function(i){function j(a){var b=a.match(/\n/g),c=b?b.length:1;return c>p?20:c}var k,l,m,n,o,p,q,r,s=i.job_id,t=f,u=g;r='
        \n',$("#inventory-modal-container").empty().append(r),k=t.inject(u,{mode:"edit",id:"form-container",breadCrumbs:!1,related:!1}),l=$(document).width(),m=$("body").height(),l>1199?(n=675,o=750>m?m-20:750,p=20):1199>=l&&l>=768?(n=550,o=620>m?m-15:620,p=15):(n=l-20,o=500>m?m:500,p=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:n,height:o,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#inventory-modal-container").empty(),h()},open:function(){b("stop")}}),b("start"),q=c("jobs")+s+"/",a.setUrl(q),a.get().success(function(a){var b;k.id=a.id,k.name=a.name,k.status=a.status,k.result_stdout=a.result_stdout,k.result_traceback=a.result_traceback,k.stdout_rows=j(k.result_stdout),k.traceback_rows=j(k.result_traceback),b=new Date(a.created),k.created=d(b),$("#status-modal-dialog").dialog("open")}).error(function(a,b){e(k,a,b,null,{hdr:"Error!",msg:"Attempt to load job failed. GET returned status: "+b})})}}]),angular.module("LookUpHelper",["RestServices","Utilities","SearchHelper","PaginationHelpers","ListGenerator","ApiLoader"]).factory("LookUpInit",["Alert","Rest","GenerateList","SearchInit","PaginateInit","GetBasePath","FormatDate","Empty",function(a,b,c,d,e,f,g,h){return function(b){var i,j,k,l,m=b.scope,n=b.form,o=b.list,p=b.field,q=b.postAction;i=b.url?b.url:f("inventories"===o.name?"inventory":o.name),j=o.iterator.charAt(0).toUpperCase()+o.iterator.substring(1),k=b.hdr?b.hdr:"Select "+j,l=/\/$/.test(i)?i+"?":i+"&",l+=n.fields[p].sourceField+"__iexact=:value",$('input[name="'+n.fields[p].sourceModel+"_"+n.fields[p].sourceField+'"]').attr("data-url",l),$('input[name="'+n.fields[p].sourceModel+"_"+n.fields[p].sourceField+'"]').attr("data-source",p),m["lookUp"+j]=function(){var b=c,f=b.inject(o,{mode:"lookup",hdr:k});$("#lookup-modal").on("hidden.bs.modal",function(){f.searchCleanup&&f.searchCleanup(),(""===m[p]||null===m[p])&&(m[n.fields[p].sourceModel+"_"+n.fields[p].sourceField]="",m.$$phase||m.$digest())}),f.selectAction=function(){var c,d=!1;for(c=0;c5?f[j+"_page"]-5:1,e=f[j+"_page"]<6?10<=f[j+"_num_pages"]?10:f[j+"_num_pages"]:f[j+"_page"]+4=c;c++)f[j+"_page_range"].push(c)}}]).factory("RelatedPaginateInit",["RefreshRelated","$cookieStore","Wait",function(a,b,c){return function(d){var e,f=d.scope,g=d.relatedSets,h=d.pageSize?d.pageSize:10;for(e in g)f[g[e].iterator+"_url"]=g[e].url,f[g[e].iterator+"_page"]=0,f[g[e].iterator+"_page_size"]=h;f.getPage=function(b,d,e){var g=f[e+"_url"].replace(/.page\=\d+/,""),h=/\/$/.test(g)?"?":"&";g+=h+"page="+b,g+=f[e+"SearchParams"]?"&"+f[e+"SearchParams"]+"&page_size="+f[e+"_page_size"]:"page_size="+f[e+"PageSize"],c("start"),a({scope:f,set:d,iterator:e,url:g})},f.pageIsActive=function(a,b){return a===f[b+"_page"]?"active":""},f.changePageSize=function(c,d){f[d+"_page"]=1;var e=f[d+"_url"];b.put(d+"_page_size",f[d+"_page_size"]),e=e.replace(/\/\?.*$/,"/"),e+=f[d+"SearchParams"]?"?"+f[d+"SearchParams"]+"&page_size="+f[d+"_page_size"]:"?page_size="+f[d+"_page_size"],a({scope:f,set:c,iterator:d,url:e})}}}]).factory("PaginateInit",["Refresh","$cookieStore","Wait",function(a,b,c){return function(b){var d=b.scope,e=b.list,f=b.iterator?b.iterator:e.iterator,g=b.mode?b.mode:null;d[f+"_page"]=b.page?b.page:1,d[f+"_url"]=b.url,d[f+"_mode"]=g,d[f+"_page_size"]=b.pageSize?b.pageSize:"lookup"===g?5:20,d.getPage=function(b,e,f){var g=d[f+"_url"].replace(/.page\=\d+/,""),h=/\/$/.test(g)?"?":"&";g+=h+"page="+b,g+=d[f+"SearchParams"]?"&"+d[f+"SearchParams"]+"&page_size="+d[f+"_page_size"]:"page_size="+d[f+"PageSize"],c("start"),a({scope:d,set:e,iterator:f,url:g})},d.pageIsActive=function(a,b){return a===d[b+"_page"]?"active":""},d.changePageSize=function(b,e){d[e+"_page"]=0;var f=d[e+"_url"].replace(/\?page_size\=\d+/,""),g=/\/$/.test(f)?"?":"&";f+=d[e+"SearchParams"]?g+d[e+"SearchParams"]+"&page_size="+d[e+"_page_size"]:g+"page_size="+d[e+"_page_size"],c("start"),a({scope:d,set:b,iterator:e,url:f})}}}]),angular.module("ParseHelper",[]).factory("ParseTypeChange",[function(){return function(a,b,c){var d=b?b:"variables",e=c?c:"parseType";a.blockParseTypeWatch=!1,a.blockVariableDataWatch=!1,a["remove"+d+"Watch"]&&a["remove"+d+"Watch"](),a["remove"+d+"Watch"]=a.$watch(e,function(b,c){var e;if(b!==c)if("json"===b)if(a[d]&&!/^---$/.test(a[d]))try{e=jsyaml.load(a[d]),a[d]=JSON.stringify(e,null," ")}catch(f){}else a[d]="{}";else if(a[d]&&!/^\{\}$/.test(a[d]))try{e=JSON.parse(a[d]),a[d]=jsyaml.safeDump(e)}catch(f){}else a[d]="---"})}}]),angular.module("PermissionsHelper",[]).factory("PermissionCategoryChange",[function(){return function(a){var b=a.scope,c=a.reset;"Inventory"===b.category?(b.projectrequired=!1,b.permissionTypeHelp="
        \n
        Read
        \n
        Only allow the user or team to view the inventory.
        \n
        Write
        \n
        Allow the user or team to modify hosts and groups contained in the inventory, add new hosts and groups, and perform inventory sync operations.\n
        Admin
        \n
        Allow the user or team full access to the inventory. This includes reading, writing, deletion of the inventory and inventory sync operations.
        \n
        \n"):(b.projectrequired=!0,b.permissionTypeHelp="
        \n
        Run
        \n
        Allow the user or team to perform a live deployment of the project against the inventory. In Run mode modules will be executed, and changes to the inventory will occur.
        \n
        Check
        \n
        Only allow the user or team to deploy the project against the inventory as a dry-run operation. In Check mode, module operations will only be simulated. No changes will occur.
        \n
        \n"),c&&(b.permission_type="Inventory"===b.category?"read":"run")}}]),angular.module("ProjectPathHelper",["RestServices","Utilities"]).factory("GetProjectPath",["Alert","Rest","GetBasePath","ProcessErrors",function(a,b,c,d){return function(a){function e(a){var b,c,d=[],e=[];for(b=0;b
        \n',$("#projects-modal-container").empty().append(b),c=q.inject(r,{mode:"edit",id:"form-container",related:!1,breadCrumbs:!1}),q.reset(),d=$(document).width(),f=$("body").height(),d>1199?(h=675,j=750>f?f-20:750,n=20):1199>=d&&d>=768?(h=550,j=620>f?f-15:620,n=15):(h=d-20,j=500>f?f:500,n=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:h,height:j,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#projects-modal-container").empty()},open:function(){m("stop")}}),e.setUrl(p),e.get().success(function(a){var b,d=a;for(b in r.fields)d[b]?c[b]="created"===b?k(new Date(d[b])):d[b]:d.summary_fields.project[b]&&(c[b]=d.summary_fields.project[b]);$("#status-modal-dialog").dialog({title:d.summary_fields.project.name+" Status"}).dialog("open")}).error(function(a,b){$("#form-modal").modal("hide"),i(c,a,b,r,{hdr:"Error!",msg:"Failed to retrieve status of project: "+o+". GET status: "+b})})}}]),angular.module("SelectionHelper",["Utilities","RestServices"]).factory("SelectionInit",["Rest","Alert","ProcessErrors","ReturnToCaller","Wait",function(a,b,c,d,e){return function(b){var f,g=b.scope,h=b.list,i=b.url,j=b.returnToCaller;f=void 0!==b.selected?b.selected:[],g.formModalActionDisabled=!0,g.disableSelectBtn=!0,g["toggle_"+h.iterator]=function(a,b){var c,d,e;for(c=0;c0?(g.formModalActionDisabled=!1,g.disableSelectBtn=!1):(g.formModalActionDisabled=!0,g.disableSelectBtn=!0)},g.finishSelection=function(){function b(){f=[],void 0!==j?d(j):($("#form-modal").modal("hide"),g.$emit("modalClosed"))}function k(b){a.post(b).success(function(a,b){m.push({result:"success",data:a,status:b}),g.$emit("callFinished")}).error(function(a,b,c){m.push({result:"error",data:a,status:b,headers:c}),g.$emit("callFinished")})}a.setUrl(i);var l,m=[];if(g.formModalActionDisabled=!0,g.disableSelectBtn=!0,e("start"),g.callFinishedRemove&&g.callFinishedRemove(),g.callFinishedRemove=g.$on("callFinished",function(){var a,d=0;if(m.length===f.length){for(e("stop"),a=0;a0)for(l=0;lh)h++,setTimeout(1e3,e());else if("success"===g.status)return d(a)}var f,g={},h=0;return null===c.apiDefaults||void 0===c.apiDefaults?(f="/api/v1/",b.setUrl(f),b.get().success(function(a){var b,d=a;for(b in d)switch(b){case"organizations":d[b].iterator="organization";break;case"jobs":d[b].iterator="job";break;case"users":d[b].iterator="user";break;case"teams":d[b].iterator="team";break;case"hosts":d[b].iterator="host";break;case"groups":d[b].iterator="group";break;case"projects":d[b].iterator="project";break;case"inventories":d[b].iterator="inventory"}c.apiDefaults=d,g={status:"success"}}).error(function(a,b){g={status:"error",msg:"Call to "+f+" failed. GET returned status: "+b}}),e()):d(a)}}]),angular.module("InventoryHelper",["RestServices","Utilities","OrganizationListDefinition","ListGenerator","AuthService","InventoryHelper","InventoryFormDefinition","ParseHelper","SearchHelper"]).factory("WatchInventoryWindowResize",["ApplyEllipsis",function(a){return function(){var b;$(window).resize(function(){clearTimeout(b),b=setTimeout(function(){$("#groups_table .name-column").each(function(){var a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%";$(this).find(".group-name").css({width:e})}),a("#groups_table .group-name a"),a("#hosts_table .host-name a")},100)})}}]).factory("SaveInventory",["InventoryForm","Rest","Alert","ProcessErrors","LookUpInit","OrganizationList","GetBasePath","ParseTypeChange","Wait",function(a,b,c,d,e,f,g,h,i){return function(e){var f,h,j,k=e.scope,l=a,m=g("inventory");i("start");try{if(h="json"===k.inventoryParseType?JSON.parse(k.inventory_variables):jsyaml.load(k.inventory_variables),"object"!=typeof h)throw"failed to return an object!";j={};for(f in l.fields)"inventory_variables"!==f&&(l.fields[f].realName?j[l.fields[f].realName]=k[f]:j[f]=k[f]);b.setUrl(m+k.inventory_id+"/"),b.put(j).success(function(a){k.inventory_variables?(b.setUrl(a.related.variable_data),b.put(h).success(function(){i("stop"),k.$emit("InventorySaved")}).error(function(a,b){d(k,a,b,l,{hdr:"Error!",msg:"Failed to update inventory varaibles. PUT returned status: "+b})})):k.$emit("InventorySaved")}).error(function(a,b){d(k,a,b,l,{hdr:"Error!",msg:"Failed to update inventory. POST returned status: "+b})})}catch(n){i("stop"),c("Error","Error parsing inventory variables. Parser returned: "+n)}}}]).factory("EditInventoryProperties",["InventoryForm","GenerateForm","Rest","Alert","ProcessErrors","LookUpInit","OrganizationList","GetBasePath","ParseTypeChange","SaveInventory","Wait","Store","SearchInit",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(n){var o,p=n.scope,q=n.inventory_id,r=b,s=a,t={},u=l("CurrentSearchParams");s.well=!1,o=r.inject(s,{mode:"edit",modal:!0,related:!1,modal_show:!1}),s.well=!0,i(o,"inventory_variables","inventoryParseType"),o.inventoryParseType="yaml",o.formModalActionLabel="Save",o.formModalCancelShow=!0,o.formModalInfo=!1,o.formModalHeader="Inventory Properties",k("start"),c.setUrl(h("inventory")+q+"/"),c.get().success(function(a){var b,c;for(b in s.fields){if("inventory_variables"===b){if($.isEmptyObject(a.variables)||"{}"===a.variables||"null"===a.variables||""===a.variables)o.inventory_variables="---";else try{c=JSON.parse(a.variables),o.inventory_variables=jsyaml.safeDump(c)}catch(e){d("Variable Parse Error","Attempted to parse variables for inventory: "+q+". Parse returned: "+e),console&&(console.log(e),console.log("data:"),console.log(a.variables)),o.inventory_variables="---"}t.inventory_variables=o.variables}else"inventory_name"===b?(o[b]=a.name,t[b]=o[b]):"inventory_description"===b?(o[b]=a.description,t[b]=o[b]):a[b]&&(o[b]=a[b],t[b]=o[b]);s.fields[b].sourceModel&&a.summary_fields&&a.summary_fields[s.fields[b].sourceModel]&&(o[s.fields[b].sourceModel+"_"+s.fields[b].sourceField]=a.summary_fields[s.fields[b].sourceModel][s.fields[b].sourceField],t[s.fields[b].sourceModel+"_"+s.fields[b].sourceField]=a.summary_fields[s.fields[b].sourceModel][s.fields[b].sourceField])}f({scope:o,form:s,current_item:o.organization,list:g,field:"organization"}),k("stop"),$("#form-modal").modal("show")}).error(function(a,b){e(o,a,b,null,{hdr:"Error!",msg:"Failed to get inventory: "+q+". GET returned: "+b})}),o.removeInventorySaved&&o.removeInventorySaved(),o.removeInventorySaved=o.$on("InventorySaved",function(){$("#form-modal").modal("hide"),o.searchCleanp&&o.searchCleanup(),m({scope:p,set:u.set,list:u.list,url:u.defaultUrl,iterator:u.iterator,sort_order:u.sort_order,setWidgets:!1}),p.$emit("RefreshInventories")}),o.cancelModal=function(){o.searchCleanp&&o.searchCleanup(),m({scope:p,set:u.set,list:u.list,url:u.defaultUrl,iterator:u.iterator,sort_order:u.sort_order,setWidgets:!1})},o.formModalAction=function(){p.inventory_id=q,p.inventory_name=o.inventory_name,j({scope:o})}}}]),angular.module("md5Helper",["RestServices","Utilities"]).factory("md5Setup",[function(){return function(a){var b=a.scope,c=a.master,d=a.check_field,e=a.default_val;b[d]=e,c[d]=e,b.genMD5=function(a){var c=new Date;b[a]=$.md5("AnsibleWorks"+c.getTime())},b.toggleCallback=function(a){"false"===b.allow_callbacks&&(b[a]="")},b.selectAll=function(a){$('input[name="'+a+'"]').focus().select()}}}]),angular.module("RefreshRelatedHelper",["RestServices","Utilities","PaginationHelpers"]).factory("RefreshRelated",["ProcessErrors","Rest","Wait","PageRangeSetup",function(a,b,c,d){return function(e){var f=e.scope,g=e.set,h=e.iterator,i=e.url;b.setUrl(i),b.get().success(function(a){d({scope:f,count:a.count,next:a.next,previous:a.previous,iterator:h}),f[g]=a.results,f[h+"Loading"]=!1,f[h+"HoldInput"]=!1,c("stop"),f.$emit("related"+g)}).error(function(b,c){a(f,b,c,null,{hdr:"Error!",msg:"Failed to retrieve "+g+". GET returned status: "+c})})}}]),angular.module("RefreshHelper",["RestServices","Utilities","PaginationHelpers"]).factory("Refresh",["ProcessErrors","Rest","Wait","Empty","PageRangeSetup",function(a,b,c,d,e){return function(d){var f=d.scope,g=d.set,h=d.iterator,i=d.url;f.current_url=i,b.setUrl(i),b.get().success(function(a){var b,d;for(e({scope:f,count:a.count,next:a.next,previous:a.previous,iterator:h}),f[h+"Loading"]=!1,b=1;3>=b;b++)d=1===b?"":b,f[h+"HoldInput"+d]=!1;f[g]=a.results,window.scrollTo(0,0),c("stop"),f.$emit("PostRefresh")}).error(function(b,c){f[h+"HoldInput"]=!1,a(f,b,c,null,{hdr:"Error!",msg:"Failed to retrieve "+g+". GET returned status: "+c})})}}]),angular.module("RelatedSearchHelper",["RestServices","Utilities","RefreshRelatedHelper"]).factory("RelatedSearchInit",["$timeout","Alert","Rest","RefreshRelated","Wait",function(a,b,c,d,e){return function(a){function b(a){var b,c,d,e;for(e in h.related)if("tree"!==h.related[e].type&&(void 0===a||a===h.related[e].iterator)){b=h.related[e].iterator;for(d in h.related[e].fields)if(h.related[e].fields[d].key){f[b+"SearchField"]=d,f[b+"SearchFieldLabel"]=h.related[e].fields[d].label;break}f[b+"SortOrder"]=null,f[b+"SearchType"]="icontains",f[b+"SearchTypeLabel"]="Contains",f[b+"SearchValue"]=null,f[b+"SelectShow"]=!1,f[b+"ShowStartBtn"]=!0,f[b+"HideAllStartBtn"]=!1,c=f[b+"SearchField"],!h.related[e].fields[c].searchType||"boolean"!==h.related[e].fields[c].searchType&&"select"!==h.related[e].fields[c].searchType||(f[b+"SelectShow"]=!0,f[b+"SearchSelectOpts"]=h.fields[c].searchOptions),h.related[e].fields[c].searchType&&"gtzero"===h.related[e].fields[c].searchType&&(f[b+"InputHide"]=!0)}}var c,f=a.scope,g=a.relatedSets,h=a.form;b(),f.resetSearch=function(a){b(a),f.search(a)},f.setSearchField=function(a,b,c){var d,e;for(e in h.related)h.related[e].iterator===a&&(d=h.related[e].fields[b]);f[a+"SearchFieldLabel"]=c,f[a+"SearchField"]=b,f[a+"SearchValue"]="",f[a+"SelectShow"]=!1,f[a+"InputHide"]=!1,f[a+"ShowStartBtn"]=!0,void 0!==d.searchType&&"gtzero"===d.searchType&&(f[a+"InputHide"]=!0,f[a+"ShowStartBtn"]=!1),void 0===d.searchType||"boolean"!==d.searchType&&"select"!==d.searchType||(f[a+"SelectShow"]=!0,f[a+"SearchSelectOpts"]=d.searchOptions),void 0!==d.searchType&&"int"===d.searchType&&(f[a+"SearchType"]="int"),f.search(a)},f.setSearchType=function(a,b,c){f[a+"SearchTypeLabel"]=c,f[a+"SearchType"]=b,f.search(a)},f.startSearch=function(a,b){13===a.keyCode&&f.search(b)},f.search=function(a){e("start"),f[a+"Loading"]=!0,f[a+"HoldInput"]=!0,f[a+"SearchValue"]&&(f[a+"ShowStartBtn"]=!1),"host"===a&&"has_active_failures"===f.hostSearchField&&(f.hostFailureFilter=f.hostSearchSelectValue&&1===f.hostSearchSelectValue.value?!0:!1);var b,i,j,k,l;for(i in g)if(g[i].iterator===a){j=i,k=g[i].url;for(b in h.related[i].fields)h.related[i].fields[b].key&&(l=h.related[i].fields[b].desc?"-"+b:b);break}l=null===f[a+"SortOrder"]?l:f[a+"SortOrder"],c=h.related[j].fields[f[a+"SearchField"]],f[a+"SelectShow"]===!1&&""!==f[a+"SearchValue"]&&void 0!==f[a+"SearchValue"]||f[a+"SelectShow"]&&f[a+"SearchSelectValue"]||c.searchType&&"gtzero"===c.searchType?(f[a+"SearchParams"]=c.sourceModel?c.sourceModel+"__"+c.sourceField+"__":c.searchField?c.searchField+"__":f[a+"SearchField"]+"__",f[a+"SearchParams"]+=!c.searchType||"int"!==c.searchType&&"boolean"!==c.searchType?c.searchType&&"gtzero"===c.searchType?"gt=0":f[a+"SearchType"]+"=":"int=",!c.searchType||"boolean"!==c.searchType&&"select"!==c.searchType?(void 0===c.searchType||"gtzero"===c.searchType)&&(f[a+"SearchParams"]+=encodeURI(f[a+"SearchValue"])):f[a+"SearchParams"]+=f[a+"SearchSelectValue"].value,f[a+"SearchParams"]+=l?"&order_by="+encodeURI(l):""):f[a+"SearchParams"]=l?"order_by="+encodeURI(l):"",f[a+"Page"]=0,k+=k.match(/\/$/)?"?":"&",k+=f[a+"SearchParams"],k+=f[a+"PageSize"]?"&page_size="+f[a+"PageSize"]:"",d({scope:f,set:j,iterator:a,url:k})},f.sort=function(a,b){var c,d,e,g;$("."+a+" .list-header").each(function(){if($(this).attr("id")!==a+"-"+b+"-header"){var c=$(this).find("i");c.attr("class","icon-sort")}}),d=$("#"+a+"-"+b+"-header i"),e="",d.hasClass("icon-sort")?(d.removeClass("icon-sort"),d.addClass("icon-sort-up")):d.hasClass("icon-sort-up")?(d.removeClass("icon-sort-up"),d.addClass("icon-sort-down"),e="-"):d.hasClass("icon-sort-down")&&(d.removeClass("icon-sort-down"),d.addClass("icon-sort-up"));for(g in h.related)h.related[g].iterator===a&&(c=h.related[g].fields[b].sourceModel?e+h.related[g].fields[b].sourceModel+"__"+h.related[g].fields[b].sourceField:e+b);f[a+"SortOrder"]=c,f.search(a)}}}]),angular.module("SearchHelper",["RestServices","Utilities","RefreshHelper"]).factory("SearchInit",["Alert","Rest","Refresh","$location","GetBasePath","Empty","$timeout","Wait","Store",function(a,b,c,d,e,f,g,h,i){return function(a){function b(a){var b,c,d,e;e=void 0===a||1===a?"":a,l[p+"SearchField"+e]="",l[p+"SearchFieldLabel"+e]="";for(c in o.fields)if((void 0===o.fields[c].searchWidget&&1===a||o.fields[c].searchWidget===a)&&o.fields[c].key){o.fields[c].sourceModel?(d=o.fields[c].sourceModel+"__"+o.fields[c].sourceField,r=o.fields[c].desc?"-"+d:d):r=o.fields[c].desc?"-"+c:c,(void 0===o.fields[c].searchable||o.fields[c].searchable===!0)&&(l[p+"SearchField"+e]=c,l[p+"SearchFieldLabel"+e]=o.fields[c].label);break}if(f(l[p+"SearchField"+e]))for(c in o.fields)if((void 0===o.fields[c].searchWidget&&1===a||o.fields[c].searchWidget===a)&&(void 0===o.fields[c].searchable||o.fields[c].searchable===!0)){l[p+"SearchField"+e]=c,l[p+"SearchFieldLabel"+e]=o.fields[c].label;break}l[p+"SearchType"+e]="icontains",l[p+"SearchTypeLabel"+e]="Contains",l[p+"SearchParams"+e]="",l[p+"SearchValue"+e]="",l[p+"SelectShow"+e]=!1,l[p+"HideSearchType"+e]=!1,l[p+"InputDisable"+e]=!1,l[p+"ExtraParms"+e]="",l[p+"ShowStartBtn"+e]=!0,l[p+"HideAllStartBtn"+e]=!1,l[p+"SearchPlaceholder"+e]=o.fields[l[p+"SearchField"+e]]&&o.fields[l[p+"SearchField"+e]].searchPlaceholder?l[o.fields[l[p+"SearchField"+e]].searchPlaceholder]?l[o.fields[l[p+"SearchField"+e]].searchPlaceholder]:o.fields[l[p+"SearchField"+e]].searchPlaceholder:"Search",l[p+"InputDisable"+e]=o.fields[l[p+"SearchField"+e]]&&"all"===o.fields[l[p+"SearchField"+e]].searchObject?!0:!1,b=l[p+"SearchField"+e],o.fields[b]&&(!o.fields[b].searchType||"boolean"!==o.fields[b].searchType&&"select"!==o.fields[b].searchType||(l[p+"SelectShow"+e]=!0,l[p+"SearchSelectOpts"+e]=o.fields[b].searchOptions),o.fields[b].searchType&&"int"===o.fields[b].searchType&&(l[p+"HideSearchType"+e]=!0),o.fields[b].searchType&&"gtzero"===o.fields[b].searchType&&(l[p+"InputHide"+e]=!0))}var e,g,j,k,l=a.scope,m=a.set,n=a.url,o=a.list,p=a.iterator?a.iterator:o.iterator,q=a.setWidgets===!1?!1:!0,r=a.sort_order||"";if(q)for(e=o.searchWidgets?o.searchWidgets:1,g=1;e>=g;g++)j=1===g?"":g,$("#search-widget-container"+j)&&b(g);k={set:m,defaultUrl:n,list:o,iterator:p,sort_order:r},i("CurrentSearchParams",k),l.setSearchField=function(a,b,c,d){var e=void 0===d||1===d?"":d;l[a+"SearchFieldLabel"+e]=c,l[a+"SearchField"+e]=b,l[a+"SearchValue"+e]="",l[a+"SelectShow"+e]=!1,l[a+"HideSearchType"+e]=!1,l[a+"InputHide"+e]=!1,l[a+"SearchType"+e]="icontains",l[a+"InputDisable"+e]="all"===o.fields[b].searchObject?!0:!1,l[a+"ShowStartBtn"+e]=!0,l[a+"SearchPlaceholder"+e]=o.fields[l[a+"SearchField"+e]]&&o.fields[l[a+"SearchField"+e]].searchPlaceholder?l[o.fields[l[a+"SearchField"+e]].searchPlaceholder]?l[o.fields[l[a+"SearchField"+e]].searchPlaceholder]:o.fields[l[a+"SearchField"+e]].searchPlaceholder:"Search",o.fields[b].searchType&&"gtzero"===o.fields[b].searchType?(l[a+"InputDisable"+e]=!0,l[a+"ShowStartBtn"+e]=!1,l.search(a)):o.fields[b].searchSingleValue?(l[a+"InputDisable"+e]=!0,l[a+"SearchValue"+e]=o.fields[b].searchValue,l[a+"SearchSelectValue"+e]="boolean"===o.fields[b].searchType&&"true"===o.fields[b].searchValue?{value:1}:"boolean"===o.fields[b].searchType&&"false"===o.fields[b].searchValue?{value:0}:{value:o.fields[b].searchValue},l[a+"ShowStartBtn"+e]=!1):"in"===o.fields[b].searchType?(l[a+"SearchType"+e]="in",l[a+"SearchValue"+e]=o.fields[b].searchValue,l[a+"InputDisable"+e]=!0,l[a+"ShowStartBtn"+e]=!1):!o.fields[b].searchType||"boolean"!==o.fields[b].searchType&&"select"!==o.fields[b].searchType&&"select_or"!==o.fields[b].searchType?o.fields[b].searchType&&"int"===o.fields[b].searchType?l[a+"SearchType"+e]="int":o.fields[b].searchType&&"isnull"===o.fields[b].searchType&&(l[a+"SearchType"+e]="isnull",l[a+"InputDisable"+e]=!0,l[a+"SearchValue"+e]="true",l[a+"ShowStartBtn"+e]=!1):(l[a+"SelectShow"+e]=!0,l[a+"SearchSelectOpts"+e]=o.fields[b].searchOptions),l.search(a)},l.resetSearch=function(a){var c,e=o.searchWidgets?o.searchWidgets:1;for(c=1;e>=c;c++)b(c);window.location="/#"+d.path(),l.search(a)},l.removeDoSearch&&l.removeDoSearch(),l.removeDoSearch=l.$on("doSearch",function(a,b,d,e){l[b+"Loading"]=void 0===e||e===!0?!0:!1;var f,g=n;l[b+"Page"]=d?parseInt(d)-1:0,l[b+"SearchParams"]&&(g+=/\/$/.test(g)?"?"+l[b+"SearchParams"]:"&"+l[b+"SearchParams"]),f=/\/$/.test(g)?"?":"&",g+=l[b+"_page_size"]?f+"page_size="+l[b+"_page_size"]:"",d&&(f=/\/$/.test(g)?"?":"&",g+=f+"page="+d),l[b+"ExtraParms"]&&(f=/\/$/.test(g)?"?":"&",g+=f+l[b+"ExtraParms"]),g=g.replace(/\&\&/,"&"),c({scope:l,set:m,iterator:b,url:g})}),l.removePrepareSearch&&l.removePrepareSearch(),l.removePrepareSearch=l.$on("prepareSearch",function(a,b,c,d,e){h("start"),l[b+"SearchParams"]="";var f,g,i=o.searchWidgets?o.searchWidgets:1;for(f=1;i>=f;f++)g=1===f?"":f,$("#search-widget-container"+g)&&o.fields[l[b+"SearchField"+g]]&&o.fields[l[b+"SearchField"+g]].searchObject&&("all"!==o.fields[l[b+"SearchField"+g]].searchObject?(l[b+"HideAllStartBtn"+g]=!1,l[b+"SearchValue"+g]?(l[b+"ShowStartBtn"+g]=!1,l[b+"SearchParams"]+=o.fields[l[b+"SearchField"+g]].searchOnID?"&"+o.fields[l[b+"SearchField"+g]].searchObject+"__id="+l[b+"SearchValue"+g]:"&"+o.fields[l[b+"SearchField"+g]].searchObject+"__name__icontains="+l[b+"SearchValue"+g]):(l[b+"ShowStartBtn"+g]=!0,l[b+"SearchParams"]+="&"+o.fields[l[b+"SearchField"+g]].searchField+"="+o.fields[l[b+"SearchField"+g]].searchObject)):l[b+"HideAllStartBtn"+g]=!0);l.$emit("prepareSearch2",b,c,d,e)}),l.removePrepareSearch2&&l.removePrepareSearch2(),l.removePrepareSearch2=l.$on("prepareSearch2",function(a,b,c,d,e){var g,h,i=o.searchWidgets?o.searchWidgets:1;for(g=1;i>=g;g++)h=1===g?"":g,l[b+"HoldInput"+h]=!0,$("#search-widget-container"+h)&&o.fields[l[b+"SearchField"+h]]&&!o.fields[l[b+"SearchField"+h]].searchObject&&(l[b+"ShowStartBtn"+h]=l[b+"SearchValue"+h]?!1:!0,(!l[b+"SelectShow"+h]&&!f(l[b+"SearchValue"+h])||l[b+"SelectShow"+h]&&l[b+"SearchSelectValue"+h]||o.fields[l[b+"SearchField"+h]]&&"gtzero"===o.fields[l[b+"SearchField"+h]].searchType)&&(l[b+"SearchParams"]+=o.fields[l[b+"SearchField"+h]].searchField?"&"+o.fields[l[b+"SearchField"+h]].searchField+"__":o.fields[l[b+"SearchField"+h]].sourceModel?"&"+o.fields[l[b+"SearchField"+h]].sourceModel+"__"+o.fields[l[b+"SearchField"+h]].sourceField+"__":"select"!==o.fields[l[b+"SearchField"+h]].searchType||""!==l[b+"SearchSelectValue"+h].value&&null!==l[b+"SearchSelectValue"+h].value?"&"+l[b+"SearchField"+h]+"__":"&"+l[b+"SearchField"+h]+"__",l[b+"SearchParams"]+=!o.fields[l[b+"SearchField"+h]].searchType||"int"!==o.fields[l[b+"SearchField"+h]].searchType&&"boolean"!==o.fields[l[b+"SearchField"+h]].searchType?o.fields[l[b+"SearchField"+h]].searchType&&"gtzero"===o.fields[l[b+"SearchField"+h]].searchType?"gt=0":"select"!==o.fields[l[b+"SearchField"+h]].searchType||""!==l[b+"SearchSelectValue"+h].value&&null!==l[b+"SearchSelectValue"+h].value?l[b+"SearchType"+h]+"=":"iexact=":"int=",!o.fields[l[b+"SearchField"+h]].searchType||"boolean"!==o.fields[l[b+"SearchField"+h]].searchType&&"select"!==o.fields[l[b+"SearchField"+h]].searchType?(!o.fields[l[b+"SearchField"+h]].searchType||o.fields[l[b+"SearchField"+h]].searchType&&"or"!==o.fields[l[b+"SearchField"+h]].searchType&&"gtzero"!==o.fields[l[b+"SearchField"+h]].searchType)&&(l[b+"SearchParams"]+=encodeURI(l[b+"SearchValue"+h])):l[b+"SearchParams"]+=l[b+"SearchSelectValue"+h].value));("inventory"===b&&l.inventoryFailureFilter||"host"===b&&l.hostFailureFilter)&&(l[b+"SearchParams"]+="&has_active_failures=true"),r&&(l[b+"SearchParams"]+=l[b+"SearchParams"]?"&":"",l[b+"SearchParams"]+="order_by="+encodeURI(r)),l.$emit("doSearch",b,c,d,e)}),l.startSearch=function(a,b){13===a.keyCode&&l.search(b)},l.search=function(a,b,c){c=void 0===c?!0:!1,c&&(l[m]=[]),l.$emit("prepareSearch",a,b,c)},l.sort=function(a){$(".list-header").each(function(){if($(this).attr("id")!==a+"-header"){var b=$(this).find("i");b.attr("class","fa fa-sort")}});var b=$("#"+a+"-header i"),c="";b.hasClass("fa-sort")?(b.removeClass("fa-sort"),b.addClass("fa-sort-up")):b.hasClass("fa-sort-up")?(b.removeClass("fa-sort-up"),b.addClass("fa-sort-down"),c="-"):b.hasClass("fa-sort-down")&&(b.removeClass("fa-sort-down"),b.addClass("fa-sort-up")),r=o.fields[a].searchField?c+o.fields[a].searchField:o.fields[a].sortField?c+o.fields[a].sortField:o.fields[a].sourceModel?c+o.fields[a].sourceModel+"__"+o.fields[a].sourceField:c+a,l.search(o.iterator)},l.searchCleanup=function(){l.removeDoSearch(),l.removePrepareSearch(),l.removePrepareSearch2()}}}]),angular.module("TeamHelper",["RestServices","Utilities","OrganizationListDefinition","SearchHelper","PaginationHelpers","ListGenerator"]).factory("SetTeamListeners",["Alert","Rest",function(a,b){return function(a){var c=a.scope,d=a.set,e=a.iterator;c.$on("TeamResultFound",function(a,b,f){var g,h,i,j;if(f.length===b.length){for(i="organization",j="organization_name",g=0;gSelect existing users by clicking each user or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        ",base:"users",index:!0,hover:!0,fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},actions:{},fieldActions:{}}),angular.module("CloudCredentialsListDefinition",[]).value("CloudCredentialList",{name:"cloudcredentials",iterator:"cloudcredential",selectTitle:"Add Cloud Credentials",editTitle:"Cloud Credentials",selectInstructions:"

        Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        Create a brand new credential by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",excludeModal:!1},team:{label:"Team",ngBind:"credential.team_name",sourceModel:"team",sourceField:"name",excludeModal:!0},user:{label:"User",ngBind:"credential.user_username",sourceModel:"user",sourceField:"username",excludeModal:!0}},actions:{add:{mode:"all",ngClick:"addCredential()","class":"btn-sm",awToolTip:"Create a new credential"}},fieldActions:{edit:{ngClick:"editCredential(credential.id)",icon:"fa-edit",label:"Edit","class":"btn-sm",awToolTip:"Edit credential",dataPlacement:"top"},"delete":{ngClick:"deleteCredential(credential.id, credential.name)",icon:"fa-trash-o",label:"Delete","class":"btn-sm",awToolTip:"Delete credential",dataPlacement:"top"}}}),angular.module("CredentialsListDefinition",[]).value("CredentialList",{name:"credentials",iterator:"credential",selectTitle:"Add Credentials",editTitle:"Credentials",selectInstructions:"

        Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        Create a brand new credential by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",excludeModal:!1},kind:{label:"Type",searchType:"select",searchOptions:[],excludeModal:!0,nosort:!0}},actions:{add:{mode:"all",ngClick:"addCredential()",awToolTip:"Create a new credential"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{ngClick:"editCredential(credential.id)",icon:"fa-edit",label:"Edit","class":"btn-sm",awToolTip:"Edit credential",dataPlacement:"top"},"delete":{ngClick:"deleteCredential(credential.id, credential.name)",icon:"fa-trash",label:"Delete","class":"btn-sm",awToolTip:"Delete credential",dataPlacement:"top"}}}),angular.module("GroupListDefinition",[]).value("GroupList",{name:"groups",iterator:"group",selectTitle:"Copy Groups",editTitle:"Groups",index:!0,well:!1,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{help:{awPopOver:"Choose groups by clicking on each group you wish to add. Click the Select button to add the groups to the selected inventory group.",dataContainer:"#form-modal .modal-content",mode:"all",awToolTip:"Click for help",dataTitle:"Adding Groups"}},fieldActions:{edit:{label:"Edit",ngClick:"editGroup(group.id)",icon:"icon-edit","class":"btn-xs",awToolTip:"Edit group",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteGroup(group.id, group.name)",icon:"icon-trash","class":"btn-xs",awToolTip:"Delete group",dataPlacement:"top"}}}),angular.module("HomeGroupListDefinition",[]).value("HomeGroupList",{name:"home_groups",iterator:"group",editTitle:"Groups",index:!0,hover:!0,well:!0,fields:{name:{key:!0,label:"Group",ngClick:"editGroup(group.id, group.inventory)",columnClass:"col-lg-4 col-md3 col-sm-3 col-xs-6 ellipsis"},inventory_name:{label:"Inventory",sourceModel:"inventory",sourceField:"name",columnClass:"col-lg-3 col-md2 col-sm-2 hidden-xs elllipsis",linkTo:"{{ /#/inventories/' + group.inventory + '/' }}"},source:{label:"Source",searchType:"select",searchOptions:[{name:"ec2",value:"ec2"},{name:"none",value:""},{name:"rax",value:"rax"}],sourceModel:"inventory_source",sourceField:"source",searchOnly:!0},has_external_source:{label:"Has external source?",searchType:"in",searchValue:"ec2,rax",searchOnly:!0,sourceModel:"inventory_source",sourceField:"source"},has_active_failures:{label:"Has failed hosts?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},last_update_failed:{label:"Update failed?",searchType:"select",searchSingleValue:!0,searchValue:"failed",searchOnly:!0,sourceModel:"inventory_source",sourceField:"status"},id:{label:"ID",searchOnly:!0}},fieldActions:{sync_status:{mode:"all",ngClick:"viewUpdateStatus(group.id, group.group_id)",awToolTip:"{{ group.status_tooltip }}",ngClass:"group.status_class",dataPlacement:"top"},failed_hosts:{mode:"all",awToolTip:"{{ group.hosts_status_tip }}",dataPlacement:"top",ngHref:"/#/inventories/{{ group.inventory }}/",iconClass:"{{ 'fa icon-failures-' + group.hosts_status_class }}"},group_update:{mode:"all",ngClick:"updateGroup(group.id)",awToolTip:"{{ group.launch_tooltip }}",ngShow:"(group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",ngClass:"group.launch_class",dataPlacement:"top"},cancel:{mode:"all",ngClick:"cancelUpdate(group.id)",awToolTip:"Cancel sync process","class":"red-txt",ngShow:"(group.status == 'running' || group.status == 'pending' || group.status == 'updating')",dataPlacement:"top"},edit:{label:"Edit",mode:"all",ngClick:"editGroup(group.id)",awToolTip:"Edit group",dataPlacement:"top"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("HomeHostListDefinition",[]).value("HomeHostList",{name:"hosts",iterator:"host",selectTitle:"Add Existing Hosts",editTitle:"Hosts",index:!0,hover:!0,well:!0,fields:{name:{key:!0,label:"Name",columnClass:"col-lg-4 col-md3 col-sm-3 col-xs-7 ellipsis",ngClick:"editHost(host.id, host.name)"},inventory_name:{label:"Inventory",sourceModel:"inventory",sourceField:"name",columnClass:"col-lg-3 col-md2 col-sm-2 hidden-xs elllipsis",linkTo:"{{ '/#/inventories/' + host.inventory }}"},enabled:{label:"Disabled?",searchSingleValue:!0,searchType:"boolean",searchValue:"false",searchOnly:!0},has_active_failures:{label:"Has failed jobs?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},has_inventory_sources:{label:"Has external source?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},id:{label:"ID",searchOnly:!0}},fieldActions:{enabled_flag:{iconClass:"{{ 'fa icon-enabled-' + host.enabled }}",dataPlacement:"top",awToolTip:"{{ host.enabledToolTip }}",dataTipWatch:"host.enabledToolTip",ngClick:"toggleHostEnabled(host.id, host.has_inventory_sources)"},active_failures:{awPopOver:"{{ host.job_status_html }}",dataTitle:"{{ host.job_status_title }}",awToolTip:"{{ host.badgeToolTip }}",awTipPlacement:"top",dataPlacement:"left",iconClass:"{{ 'fa icon-failures-' + host.has_active_failures }}"},edit:{label:"Edit",ngClick:"editHost(host.id)",icon:"icon-edit",awToolTip:"Edit host",dataPlacement:"top"}},actions:{stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("HostListDefinition",[]).value("HostList",{name:"hosts",iterator:"host",selectTitle:"Add Existing Hosts",editTitle:"Hosts",index:!0,well:!1,fields:{name:{key:!0,label:"Host Name",linkTo:"/inventories/{{ inventory_id }}/hosts/{{ host.id }}"},description:{label:"Description"}},actions:{help:{awPopOver:"Select hosts by clicking on each host you wish to add. Add the selected hosts to the group by clicking the Select button.",dataContainer:"#form-modal .modal-content",mode:"all",awToolTip:"Click for help",dataTitle:"Selecting Hosts"}},fieldActions:{edit:{label:"Edit",ngClick:"editHost({{ host.id }})",icon:"icon-edit","class":"btn-xs",awToolTip:"Edit host",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteHost(host.id, host.name)",icon:"icon-trash","class":"btn-xs",awToolTip:"Delete host",dataPlacement:"top"}}}),angular.module("InventoriesListDefinition",[]).value("InventoryList",{name:"inventories",iterator:"inventory",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},organization:{label:"Organization",ngBind:"inventory.summary_fields.organization.name",linkTo:"/#/organizations/{{ inventory.organization }}",sourceModel:"organization",sourceField:"name",excludeModal:!0},has_inventory_sources:{label:"Cloud sourced?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},has_active_failures:{label:"Failed hosts?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},inventory_sources_with_failures:{label:"Sync failures?",searchType:"gtzero",searchValue:"true",searchOnly:!0}},actions:{add:{mode:"all",ngClick:"addInventory()",awToolTip:"Create a new inventory"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",icon:"icon-comments-alt",mode:"all"}},fieldActions:{status:{ngHref:"inventory.status_link",iconClass:"{{ 'fa fa-cloud icon-cloud-' + inventory.status_class }}",awToolTip:"{{ inventory.status_tip }}",dataPlacement:"top"},failed_hosts:{ngHref:"inventory.failed_hosts_link",iconClass:"{{ 'fa icon-failures-' + inventory.failed_hosts_class }}",awToolTip:"{{ inventory.failed_hosts_tip }}",dataPlacement:"top"},edit:{label:"Edit",ngClick:"editInventoryProperties(inventory.id)",awToolTip:"Edit inventory",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteInventory(inventory.id, inventory.names')",awToolTip:"Delete inventory",dataPlacement:"top"}}}),angular.module("InventoryGroupsDefinition",[]).value("InventoryGroups",{name:"groups",iterator:"group",editTitle:"{{ inventory_name }}",showTitle:!1,well:!0,index:!1,hover:!1,hasChildren:!0,filterBy:"{ show: true }","class":"table-condensed table-no-border",fields:{name:{label:"Groups",key:!0,ngClick:"showHosts(group.id,group.group_id, false)",ngClass:"group.selected_class",hasChildren:!0,columnClass:"col-lg-9 col-md-9 col-sm-7 col-xs-7",nosort:!0,awDroppable:"{{ group.isDroppable }}",awDraggable:"{{ group.isDraggable }}",dataContainment:"#groups_table",dataTreeId:"{{ group.id }}",dataGroupId:"{{ group.group_id }}",dataType:"group"}},actions:{columnClass:"col-lg-3 col-md-3 col-sm-5 col-xs-5",create:{mode:"all",ngClick:"createGroup()",awToolTip:"Create a new group"},properties:{mode:"all",awToolTip:"Edit inventory properties",ngClick:"editInventoryProperties()"},refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refreshGroups()"},stream:{ngClick:"showGroupActivity()",awToolTip:"View Activity Stream",mode:"all"},help:{mode:"all",awToolTip:"Get help building your inventory",ngClick:"showGroupHelp()",id:"inventory-summary-help"}},fieldActions:{sync_status:{mode:"all",ngClick:"viewUpdateStatus(group.id, group.group_id)",ngShow:"group.id > 1",awToolTip:"{{ group.status_tooltip }}",dataTipWatch:"group.launch_tooltip",ngClass:"group.status_class",dataPlacement:"top"},failed_hosts:{mode:"all",awToolTip:"{{ group.hosts_status_tip }}",ngShow:"group.id > 1",dataPlacement:"top",ngClick:"showHosts(group.id, group.group_id, group.show_failures)",iconClass:"{{ 'fa icon-failures-' + group.hosts_status_class }}"},group_update:{mode:"all",ngClick:"updateGroup(group.id)",awToolTip:"{{ group.launch_tooltip }}",dataTipWatch:"group.launch_tooltip",ngShow:"group.id > 1 && (group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",ngClass:"group.launch_class",dataPlacement:"top"},cancel:{mode:"all",ngClick:"cancelUpdate({{ group.id }})",awToolTip:"Cancel sync process","class":"red-txt",ngShow:"group.id > 1 && (group.status == 'running' || group.status == 'pending' || group.status == 'updating')",dataPlacement:"top"},edit:{mode:"all",ngClick:"editGroup({{ group.group_id + ',' + group.id }})",awToolTip:"Edit group",ngShow:"group.id > 1",dataPlacement:"top"},"delete":{mode:"all",ngClick:"deleteGroup({{ group.id + ',' + group.group_id }})",awToolTip:"Delete group",ngShow:"group.id != 1",dataPlacement:"top"}}}),angular.module("InventoryHostsDefinition",[]).value("InventoryHosts",{name:"hosts",iterator:"host",editTitle:"{{ selected_group }}",showTitle:!1,well:!0,index:!1,hover:!1,hasChildren:!0,"class":"table-condensed table-no-border",fields:{name:{key:!0,label:"Hosts",ngClick:"editHost(host.id)",searchPlaceholder:"search_place_holder",columnClass:"col-lg-9 col-md-9 col-sm-7 col-xs-7",dataHostId:"{{ host.id }}",dataType:"host",awDraggable:"true"},enabled:{label:"Disabled?",searchSingleValue:!0,searchType:"boolean",searchValue:"false",searchOnly:!0},has_active_failures:{label:"Failed jobs?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0}},fieldActions:{enabled_flag:{iconClass:"{{ 'fa icon-enabled-' + host.enabled }}",dataPlacement:"top",awToolTip:"{{ host.enabledToolTip }}",dataTipWatch:"host.enabledToolTip",ngClick:"toggleHostEnabled(host.id, host.has_inventory_sources)"},active_failures:{awPopOver:"{{ host.job_status_html }}",dataTitle:"{{ host.job_status_title }}",awToolTip:"{{ host.badgeToolTip }}",awTipPlacement:"top",dataPlacement:"left",iconClass:"{{ 'fa icon-failures-' + host.has_active_failures }}"},edit:{ngClick:"editHost(host.id)",icon:"icon-edit",awToolTip:"Edit host",dataPlacement:"top"},"delete":{ngClick:"deleteHost(host.id, host.name)",icon:"icon-trash",awToolTip:"Delete host",dataPlacement:"top"}},actions:{columnClass:"col-lg-3 col-md-3 col-sm-5 col-xs-5",create:{mode:"all",ngClick:"createHost()",ngHide:"selected_tree_id == 1",awToolTip:"Create a new host"},stream:{ngClick:"showHostActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("JobEventsListDefinition",[]).value("JobEventList",{name:"jobevents",iterator:"jobevent",editTitle:"Job Events",index:!1,hover:!0,hasChildren:!0,filterBy:"{ show: true }",navigationLinks:{details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",active:!0,icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",icon:"icon-laptop"}},fields:{created:{label:"Created On",columnClass:"col-lg-1 col-md-1 hidden-sm hidden-xs",key:!0,nosort:!0,searchable:!1,link:!1},status:{label:"Status",showValue:!1,columnClass:"col-sm-1 col-xs-2 text-center",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}],nosort:!0,searchable:!1,ngClick:"viewJobEvent({{ jobevent.id }})",awToolTip:"{{ jobevent.statusBadgeToolTip }}",dataPlacement:"top",badgeIcon:"fa icon-job-{{ jobevent.status }}",badgePlacement:"left",badgeToolTip:"{{ jobevent.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgClick:"viewJobEvent({{ jobevent.id }})"},event_display:{label:"Event",hasChildren:!0,ngClick:"toggleChildren(jobevent.id, jobevent.related.children)",nosort:!0,searchable:!1,ngClass:"{{ jobevent.class }}",appendHTML:"jobevent.event_detail"},host:{label:"Host",ngBind:"jobevent.summary_fields.host.name",ngHref:"{{ jobevent.hostLink }}",searchField:"hosts__name",nosort:!0,searchOnly:!1,id:"job-event-host-header","class":"break",columnClass:"col-lg-2 hidden-sm hidden-xs"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"}},fieldActions:{columnClass:"col-sm-1 col-xs-2",view:{label:"View",ngClick:"viewJobEvent(jobevent.id)",awToolTip:"View event details",dataPlacement:"top"}}}),angular.module("JobHostDefinition",[]).value("JobHostList",{name:"jobhosts",iterator:"jobhost",editTitle:"All summaries",index:!0,hover:!0,navigationLinks:{ngHide:"host_id !== null",details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",active:!0,icon:"icon-laptop"}},fields:{job:{label:"Job ID",ngClick:"showJob(jobhost.job)",columnShow:"host_id !== null",key:!0,desc:!0},host:{label:"Host",key:!0,sourceModel:"host",sourceField:"name",ngBind:"jobhost.host_name",ngHref:"jobhost.hostLinkTo"},status:{label:"Status",badgeNgHref:"{{ jobhost.statusLinkTo }}",badgeIcon:"fa icon-job-{{ jobhost.status }}",badgePlacement:"left",badgeToolTip:"{{ jobhost.statusBadgeToolTip }}",badgeTipPlacement:"top",ngHref:"{{ jobhost.statusLinkTo }}",awToolTip:"{{ jobhost.statusBadgeToolTip }}",dataPlacement:"top",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}]},failed:{label:"Job failed?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0,nosort:!0},ok:{label:"Success",searchable:!1},changed:{label:"Changed",searchable:!1},failures:{label:"Failure",searchable:!0,searchLabel:"Contains failed events?",searchType:"gtzero"},dark:{label:"Unreachable",searchable:!0,searchType:"gtzero",searchLabel:"Contains unreachable hosts?"},skipped:{label:"Skipped",searchable:!1}},actions:{help:{awPopOver:"
        \n
        Success
        Tasks successfully executed on the host.
        \n
        Changed
        Actions taken on the host.
        \n
        Failure
        Tasks that failed on the host.
        \n
        Unreachable
        Times the ansible server could not reach the host.
        \n
        Skipped
        Tasks bypassed and not performed on the host due to prior task failure or the host being unreachable.
        \n
        \n",dataPlacement:"left",dataContainer:"body",mode:"all","class":"btn-xs btn-help",awToolTip:"Click for help",dataTitle:"Job Host Summary",id:"jobhost-help-button"},refresh:{mode:"all","class":"btn-xs",awToolTip:"Refresh the page",ngClick:"refresh()",ngShow:"host_id == null"}},fieldActions:{}}),angular.module("JobTemplatesListDefinition",[]).value("JobTemplateList",{name:"job_templates",iterator:"job_template",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{mode:"all",ngClick:"addJobTemplate()",basePaths:["job_templates"],awToolTip:"Create a new template"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",icon:"icon-comments-alt",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editJobTemplate(job_template.id)",icon:"icon-edit",awToolTip:"Edit template","class":"btn-default btn-xs",dataPlacement:"top"},submit:{label:"Launch",icon:"icon-rocket",mode:"all","class":"btn-xs btn-success",ngClick:"submitJob(job_template.id)",awToolTip:"Start a job using this template",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteJobTemplate(job_template.id, job_template.name)",icon:"icon-trash","class":"btn-danger btn-xs",awToolTip:"Delete template",dataPlacement:"top"}}}),angular.module("JobsListDefinition",[]).value("JobList",{name:"jobs",iterator:"job",editTitle:"Jobs",index:!1,hover:!0,"class":"jobs-table",fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},inventory:{label:"Inventory ID",searchType:"int",searchOnly:!0},created:{label:"Create On",link:!1,searchable:!1},job_template:{label:"Job Template",ngBind:"job.summary_fields.job_template.name",ngHref:"{{ '/#/job_templates/' + job.job_template }}",sourceModel:"job_template",sourceField:"name"},failed:{label:"Job failed?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0,nosort:!0},status:{label:"Status","class":"job-{{ job.status }}",searchType:"select",linkTo:"{{ job.statusLinkTo }}",searchOptions:[{name:"new",value:"new"},{name:"waiting",value:"waiting"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",value:"failed"},{name:"canceled",value:"canceled"}],badgeIcon:"fa icon-job-{{ job.status }}",badgePlacement:"left",badgeToolTip:"{{ job.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgHref:"{{ job.statusLinkTo }}",awToolTip:"{{ job.statusBadgeToolTip }}",dataPlacement:"top"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"}},fieldActions:{submit:{label:"Relaunch",icon:"icon-rocket",mode:"all",ngClick:"submitJob(job.id, job.summary_fields.job_template.name)",awToolTip:"Start the job",dataPlacement:"top"},cancel:{label:"Stop",mode:"all",ngClick:"deleteJob(job.id)",awToolTip:"Cancel a running or pending job",ngShow:"job.status == 'pending' || job.status == 'running' || job.status == 'waiting'",dataPlacement:"top"},"delete":{label:"Delete",mode:"all",ngClick:"deleteJob(job.id)",awToolTip:"Delete the job",ngShow:"job.status != 'pending' && job.status != 'running' && job.status != 'waiting'",dataPlacement:"top"},dropdown:{type:"DropDown",label:"View",icon:"fa-search-plus","class":"btn-default btn-xs",options:[{ngClick:"editJob(job.id, job.summary_fields.job_template.name)",label:"Status"},{ngClick:"viewEvents(job.id, job.summary_fields.job_template.name)",label:"Events",ngHide:"job.status == 'new'"},{ngClick:"viewSummary(job.id, job.summary_fields.job_template.name)",label:"Host Summary",ngHide:"job.status == 'new'"}]}}}),angular.module("OrganizationListDefinition",[]).value("OrganizationList",{name:"organizations",iterator:"organization",selectTitle:"Add Organizations",editTitle:"Organizations",hover:!0,index:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{mode:"all",ngClick:"addOrganization()",awToolTip:"Create a new organization"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editOrganization(organization.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit organization",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteOrganization(organization.id, organization.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete organization",dataPlacement:"top"}}}),angular.module("PermissionListDefinition",[]).value("PermissionList",{name:"permissions",iterator:"permission",selectTitle:"Add Permission",selectInstructions:'Click on a row to select it, and click Finished when done. Use the green button to create a new row.',editTitle:"Permissions",index:!0,well:!0,fields:{name:{key:!0,label:"Name",ngClick:"editPermission(permission.id)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},actions:{add:{mode:"all",ngClick:"addPermission()",awToolTip:"Add a new permission",ngShow:"PermissionAddAllowed"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editPermission(permission.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit permission",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deletePermission(permission.id, permission.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete permission",ngShow:"PermissionAddAllowed",dataPlacement:"top"}}}),angular.module("ProjectsListDefinition",[]).value("ProjectList",{name:"projects",iterator:"project",selectTitle:"Add Project",editTitle:"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 brand new project by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",columnClass:"hidden-sm hidden-xs",excludeModal:!0},scm_type:{label:"Type",searchType:"select",searchOptions:[],excludeModal:!0,nosort:!0},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:[],excludeModal:!0},last_updated:{label:"Last Updated",type:"date",excludeModal:!0,searchable:!1}},actions:{add:{mode:"all",ngClick:"addProject()",awToolTip:"Create a new project"},help:{awPopOver:"
        \n
        Updating
        A source control update is in progress.
        \n
        Never Updated
        This project has not yet been updated from source control.
        \n
        Failed
        An error occurred during the most recent source control update, click the status text for more information.
        \n
        Successful
        TThe latest source control update completed successfully.
        \n
        Missing
        The previously configured local project directory is missing.
        \n
        N/A
        The project is not linked to source control, so updates are not applicable.
        \n
        \n",dataPlacement:"left",dataContainer:"body",mode:"all",awToolTip:"Click for help",awTipPlacement:"top"},refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editProject(project.id)",awToolTip:"Edit project properties",dataPlacement:"top"},scm_update:{label:"Update",ngClick:"SCMUpdate(project.id)",awToolTip:"{{ project.scm_update_tooltip }}",ngClass:"project.scm_type_class",dataPlacement:"top"},cancel:{label:"Stop",ngClick:"cancelUpdate(project.id, project.name)",awToolTip:"Cancel a running SCM update process",ngShow:"project.status == 'updating'",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteProject(project.id, project.name)",awToolTip:"Permanently remove project from the database",ngShow:"project.status !== 'updating'",dataPlacement:"top"}}}),angular.module("StreamListDefinition",[]).value("StreamList",{name:"activities",iterator:"activity",editTitle:"Activity Stream",selectInstructions:"",index:!1,hover:!0,"class":"table-condensed",searchWidgets:3,fields:{timestamp:{label:"Event Time",key:!0,desc:!0,noLink:!0,searchable:!1},user:{label:"Initiated by",ngBindHtml:"activity.user",sourceModel:"actor",sourceField:"username",searchPlaceholder:"Username",searchWidget:1},description:{label:"Action",ngBindHtml:"activity.description",nosort:!0,searchable:!1,columnClass:"col-lg-7"},system_event:{label:"System event",searchOnly:!0,searchType:"isnull",sourceModel:"actor",sourceField:"username",searchWidget:1},all_objects:{label:"All",searchOnly:!0,searchObject:"all",searchPlaceholder:"All resources",searchWidget:2},credential_search:{label:"Credential",searchOnly:!0,searchObject:"credential",searchPlaceholder:"Credential name",searchWidget:2,searchField:"object1"},group_search:{label:"Group",searchOnly:!0,searchObject:"group",searchPlaceholder:"Group name",searchWidget:2,searchField:"object1"},host_search:{label:"Host",searchOnly:!0,searchObject:"host",searchPlaceholder:"Host name",searchWidget:2,searchField:"object1"},inventory_search:{label:"Inventory",searchOnly:!0,searchObject:"inventory",searchPlaceholder:"Inventory name",searchWidget:2,searchField:"object1"},job_template_search:{label:"Job Template",searchOnly:!0,searchObject:"job_template",searchPlaceholder:"Job template name",searchWidget:2,searchField:"object1"},job_search:{label:"Job",searchOnly:!0,searchObject:"job",searchPlaceholder:"Job id",searchOnID:!0,searchWidget:2,searchField:"object1"},organization_search:{label:"Organization",searchOnly:!0,searchObject:"organization",searchPlaceholder:"Organization name",searchWidget:2,searchField:"object1"},project_search:{label:"Project",searchOnly:!0,searchObject:"project",searchPlaceholder:"Project name",searchWidget:2,searchField:"object1"},user_search:{label:"User",searchOnly:!0,searchObject:"user",searchPlaceholder:"Primary username",searchWidget:2,searchField:"object1"},all_objects3:{label:"All",searchOnly:!0,searchObject:"all",searchPlaceholder:"All related resources",searchWidget:3,searchField:"object2"},credential_search3:{label:"Credential",searchOnly:!0,searchObject:"credential",searchPlaceholder:"Related credential name",searchWidget:3,searchField:"object2"},group_search3:{label:"Group",searchOnly:!0,searchObject:"group",searchPlaceholder:"Related group name",searchWidget:3,searchField:"object2"},host_search3:{label:"Host",searchOnly:!0,searchObject:"host",searchPlaceholder:"Related host name",searchWidget:3,searchField:"object2"},inventory_search3:{label:"Inventory",searchOnly:!0,searchObject:"inventory",searchPlaceholder:"Related inventory name",searchWidget:3,searchField:"object2"},job_search3:{label:"Job",searchOnly:!0,searchObject:"job",searchPlaceholder:"Job id",searchOnID:!0,searchWidget:3,searchField:"object2"},job_template_search3:{label:"Job Template",searchOnly:!0,searchObject:"job_template",searchPlaceholder:"Related job template name",searchWidget:3,searchField:"object2"},organization_search3:{label:"Organization",searchOnly:!0,searchObject:"organization",searchPlaceholder:"Related organization name",searchWidget:3,searchField:"object2"},project_search3:{label:"Project",searchOnly:!0,searchObject:"project",searchPlaceholder:"Related project name",searchWidget:3,searchField:"object2"},user_search3:{label:"User",searchOnly:!0,searchObject:"user",searchPlaceholder:"Related username",searchWidget:3,searchField:"object2"}},actions:{refresh:{mode:"all","class":"btn-xs",awToolTip:"Refresh the page",ngClick:"refreshStream()"},close:{mode:"all",awToolTip:"Close Activity Stream view",ngClick:"closeStream()"}},fieldActions:{view:{label:"View",ngClick:"showDetail(activity.id)",icon:"fa-zoom-in","class":"btn-default btn-xs",awToolTip:"View event details",dataPlacement:"top"}}}),angular.module("TeamsListDefinition",[]).value("TeamList",{name:"teams",iterator:"team",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"},organization:{label:"Organization",ngBind:"team.organization_name",sourceModel:"organization",sourceField:"name"}},actions:{add:{mode:"all",ngClick:"addTeam()",awToolTip:"Create a new team"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editTeam(team.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit team",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteTeam(team.id, team.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete team",dataPlacement:"top"}}}),angular.module("UserListDefinition",[]).value("UserList",{name:"users",iterator:"user",selectTitle:"Add Users",editTitle:"Users",selectInstructions:"

        Select existing users by clicking each user or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        When available, a brand new user can be created by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},actions:{add:{label:"Create New",mode:"all",ngClick:"addUser()",basePaths:["organizations","users"],"class":"btn-xs",awToolTip:"Create a new user"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editUser(user.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit user",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteUser(user.id, user.username)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete user",dataPlacement:"top"}}}),angular.module("InventorySyncStatusWidget",["RestServices","Utilities"]).factory("InventorySyncStatus",["$rootScope","$compile",function(a,b){return function(a){function c(a){var b=a.label,c=a.count,d=a.fail,e=a.link,f=a.fail_link,g="\n"; +return g+='\n",g+=''+d+"",g+="\n",g+='',g+=''+c+"",g+="\n"}var d,e,f,g,h,i=a.scope,j=a.target,k=a.dashboard;if(d='
        \n',d+='
        Inventory Sync Status
        \n',d+='
        \n',d+='\n',d+="\n",d+="\n",d+='\n',d+='\n',d+='\n',d+="\n",d+="\n",d+="\n",d+=c({label:"Inventories",count:k.inventories&&k.inventories.total_with_inventory_source?k.inventories.total_with_inventory_source:0,fail:k.inventories&&k.inventories.inventory_failed?k.inventories.inventory_failed:0,link:"/#/inventories/?has_inventory_sources=true",fail_link:"/#/inventories/?inventory_sources_with_failures=true"}),e=0,f=0,k.inventory_sources)for(h in k.inventory_sources)e+=k.inventory_sources[h].total?k.inventory_sources[h].total:0,f+=k.inventory_sources[h].failed?k.inventory_sources[h].failed:0;d+=c({label:"Groups",count:e,fail:f,link:"/#/home/groups/?has_external_source=true",fail_link:"/#/home/groups/?status=failed"});for(h in k.inventory_sources)k.inventory_sources[h].total&&(d+=c({label:k.inventory_sources[h].label,count:k.inventory_sources[h].total?k.inventory_sources[h].total:0,fail:k.inventory_sources[h].failed?k.inventory_sources[h].failed:0,link:"/#/home/groups/?source="+h,fail_link:"/#/home/groups/?status=failed&source="+h}));d+="\n",d+="
        FailedTotal
        \n",d+="
        \n",d+="
        \n",d+="\n",g=angular.element(document.getElementById(j)),g.html(d),b(g)(i),i.$emit("WidgetLoaded")}}]),angular.module("JobStatusWidget",["RestServices","Utilities"]).factory("JobStatus",["$rootScope","$compile","Rest","GetBasePath","ProcessErrors","Wait",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.fail_link,f=a.count,g=a.fail;return b+="\n",b+='\n",b+=''+g+"",b+="\n",b+='',b+=''+f+"",b+="\n"}var d,e=a.scope,f=a.target,g=a.dashboard,h="";h='
        \n',h+='
        Job Status
        \n',h+='
        \n',h+='\n',h+="\n",h+="\n",h+='\n',h+='\n',h+='\n',h+="\n",h+="\n",h+="\n",h+=c({label:"Jobs",link:"/#/jobs",count:g.jobs&&g.jobs.total?g.jobs.total:0,fail:g.jobs&&g.jobs.failed?g.jobs.failed:0,fail_link:"/#/jobs/?status=failed"}),h+=c({label:"Inventories",link:"/#/inventories",count:g.inventories&&g.inventories.total?g.inventories.total:0,fail:g.inventories&&g.inventories.job_failed?g.inventories.job_failed:0,fail_link:"/#/inventories/?has_active_failures=true"}),h+=c({label:"Groups",link:"/#/home/groups",count:g.groups&&g.groups.total?g.groups.total:0,fail:g.groups&&g.groups.job_failed?g.groups.job_failed:0,fail_link:"/#/home/groups/?has_active_failures=true"}),h+=c({label:"Hosts",link:"/#/home/hosts",count:g.hosts&&g.hosts.total?g.hosts.total:0,fail:g.hosts&&g.hosts.failed?g.hosts.failed:0,fail_link:"/#/home/hosts/?has_active_failures=true"}),h+="\n",h+="
        FailedTotal
        \n",h+="
        \n",h+="
        \n",h+="\n",d=angular.element(document.getElementById(f)),d.html(h),b(d)(e),e.$emit("WidgetLoaded")}}]),angular.module("ObjectCountWidget",["RestServices","Utilities"]).factory("ObjectCount",["$rootScope","$compile","Rest","GetBasePath","ProcessErrors","Wait",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.count;return b+="\n",b+='\n",b+='',b+=''+e+"",b+="\n"}var d,e,f,g=a.scope,h=a.target,i=a.dashboard,j=["organizations","users","teams","credentials","projects","inventories","groups","hosts","job_templates","jobs"];for(e='
        \n',e+='
        System Summary
        \n',e+='
        \n',e+='\n',e+="\n",e+="\n",e+='\n',e+='\n',e+="\n",e+="\n",e+="\n",d=0;d\n",e+="
        Total
        \n",e+="
        \n",e+="
        \n",f=angular.element(document.getElementById(h)),f.html(e),b(f)(g),g.$emit("WidgetLoaded")}}]),angular.module("SCMSyncStatusWidget",["RestServices","Utilities"]).factory("SCMSyncStatus",["$rootScope","$compile",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.fail_link,f=a.count,g=a.fail;return b+="\n",b+=''+c+"\n",b+=''+g+"",b+="\n",b+='',b+=''+f+"",b+="\n"}var d,e,f,g,h,i,j=a.scope,k=a.target,l=a.dashboard;if(e='
        \n',e+='
        Project SCM Status
        \n',e+='
        \n',e+='\n',e+="\n",e+="\n",e+='\n',e+='\n',e+='\n',e+="\n",e+="\n",e+="\n",f=0,l.scm_types)for(h in l.scm_types)f+=l.scm_types[h].total?l.scm_types[h].total:0;e+=c({label:"Projects",link:"/#/projects",count:f,fail:l.projects&&l.projects.failed?l.projects.failed:0,fail_link:"/#/projects/?status=failed"}),i=[];for(h in l.scm_types)i.push(h);for(i.sort(),d=0;d\n",e+="
        FailedTotal
        \n",e+="
        \n",e+="
        \n",e+="\n",g=angular.element(document.getElementById(k)),g.html(e),b(g)(j),j.$emit("WidgetLoaded")}}]),angular.module("StreamWidget",["RestServices","Utilities","StreamListDefinition","SearchHelper","PaginationHelpers","RefreshHelper","ListGenerator","StreamWidget","AuthService"]).factory("setStreamHeight",[function(){return function(){var a=$("#stream-content").height(),b=parseInt($("#tab-content-container").css("min-height").replace(/px/,"")),c=a>b?a:b;$("#tab-content-container").css({"min-height":c})}}]).factory("ShowStream",["setStreamHeight","Authorization",function(a){return function(){var b=$("#stream-container");b.css({position:"absolute",top:0,left:0,width:"100%","min-height":"100%","background-color":"#FFF"}),a(),b.show("slide",{direction:"left"},{duration:500,queue:!1})}}]).factory("HideStream",["LoadBreadCrumbs",function(a){return function(){var b=$("#stream-container");b.hide("slide",{direction:"left"},{duration:500,queue:!1}),setTimeout(function(){b.detach(),b.empty(),b.unbind(),$("#tab-content-container").css({"min-height":0})},500),a()}}]).factory("StreamBreadCrumbs",["$rootScope","$location",function(a,b){return function(){a.breadcrumbs=[];var c,d,e,f,g=b.path().split("/");for(g.splice(0,1),e=0;e=f;f++)c+="/"+g[f];for(f=0;f0)for(f=0;e>=f;f++)c+="/"+g[f];else c="/"+g[e];d=g[e],d=d.charAt(0).toUpperCase()+d.slice(1)}a.breadcrumbs.push({path:c,title:d,ngClick:"closeStream('"+c+"')"})}}}]).factory("FixUrl",[function(){return function(a){return a.replace(/\/api\/v1\//,"/#/")}}]).factory("BuildUrl",[function(){return function(a){var b="/#/";switch(a.base){case"group":case"host":b+="home/"+a.base+"s/?id="+a.id;break;case"inventory":b+="inventories/"+a.id+"/";break;default:b+=a.base+"s/"+a.id+"/"}return b}}]).factory("BuildDescription",["FixUrl","BuildUrl",function(a,b){return function(a){function c(a){return a.replace(/^_deleted_\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d+:\d+_/,"")}var d,e,f,g,h,i,j,k;d=a.operation,d+=/e$/.test(a.operation)?"d ":"ed ",e=d,f=a.object1,g=a.object2,h=a.summary_fields[f]?a.summary_fields[f][0]:null,i=f===g?a.summary_fields[f][1]:a.summary_fields[g]?a.summary_fields[g][0]:null,("user"===f||"user"===g)&&(a.summary_fields.user[0].name=a.summary_fields.user[0].username),i&&i.name&&!/^_delete/.test(i.name)?(i.base=g,d+=g+' '+i.name+""+("disassociate"===a.operation?" from ":" to "),e+=g+" "+i.name+("disassociate"===a.operation?" from ":" to ")):g&&(j="",i&&i.name&&(j=" "+c(i.name)),d+=g+j+("disassociate"===a.operation?" from ":" to "),e+=g+j+("disassociate"===a.operation?" from ":" to ")),h&&h.name&&!/^\_delete/.test(h.name)?(h.base=f,d+=f+' '+h.name+"",e+=f+" "+h.name):f&&(j="",k="",!h||!h.name||h&&h.name&&/^_delete/.test(h.name)?a.changes&&a.changes.name?"string"==typeof a.changes.name?(j=" "+a.changes.name,k=j):"object"==typeof a.changes.name&&Array.isArray(a.changes.name)&&(j=" "+a.changes.name[0],k=j):"job"===f&&h&&a.changes&&a.changes.job_template?"delete"!==a.operation?(h.base=f,j=' '+h.id+" "+a.changes.job_template+"",k=" "+h.id+" "+a.changes.job_template):(j=" "+h.id+" "+a.changes.job_template,k=j):"job"===f&&h&&("delete"!==a.operation?(h.base=f,j=' '+h.id+"",k=" "+h.id):(j=" "+h.id,k=j)):h&&h.name&&(j=" "+c(h.name),k=j),d+=f+j,e+=f+k),a.description=d,a.description_nolink=e}}]).factory("ShowDetail",["$rootScope","Rest","Alert","GenerateForm","ProcessErrors","GetBasePath","FormatDate","ActivityDetailForm","Empty","Find",function(a,b,c,d,e,f,g,h,i,j){return function(a){var b,c,e,f=a.activity_id,i=a.scope,k=d,l=h,m=j({list:i.activities,key:"id",val:f});m&&(m.changes_stringified=JSON.stringify(m.changes,null," "),b=m.changes_stringified.match(/\n/g),c=b?b.length:1,c=1>c?3:10,l.fields.changes.rows=10,e=k.inject(l,{mode:"edit",modal:!0,related:!1}),e.changes=m.changes_stringified,e.user=(m.summary_fields.actor?m.summary_fields.actor.username:"system")+" on "+g(new Date(m.timestamps)),e.operation=m.description_nolink,e.formModalAction=function(){$("#form-modal").modal("hide")},$("#form-modal").on("show.bs.modal",function(){$("#form-modal-body").css({width:"auto",height:"auto","max-height":"100%"})}),e.formModalActionLabel="OK",e.formModalCancelShow=!1,e.formModalInfo=!1,e.formModalHeader="Event "+m.id,e.$$phase||e.$digest())}}]).factory("Stream",["$rootScope","$location","Rest","GetBasePath","ProcessErrors","Wait","StreamList","SearchInit","PaginateInit","GenerateList","FormatDate","ShowStream","HideStream","BuildDescription","FixUrl","BuildUrl","ShowDetail","StreamBreadCrumbs","setStreamHeight","Find","Store",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){return function(c){var e,f,o,v,w=g,x=d("activity_stream"),y=j,z=b.path().replace(/^\//,"").split("/")[0],A=c.scope,B=u("CurrentSearchParams"),C=c&&c.inventory_name?c.inventory_name:null,D=c&&c.url?c.url:null;a.flashMessage=null,D?x=D:"/home"!==b.path()&&(e="inventories"===z?"inventory":z.replace(/s$/,""),f=b.path().split("/"),f.splice(0,1),f.length>1&&/^\d+/.test(f[f.length-1])?(e=f[f.length-2],e="inventories"===e?"inventory":e.replace(/s$/,""),x+="?"+e+"__id="+f[f.length-1]):f.length>1?(e=f[f.length-1],e="inventories"===e?"inventory":e.replace(/s$/,""),x+="?or__object1="+e+"&or__object2="+e):x+="?or__object1="+e+"&or__object2="+e),$("#tab-content-container").append('
        '),r(),C&&(o=t({list:a.breadcrumbs,key:"title",val:"{{ inventory_name }}"}),o&&(o.title=C)),l(),v=y.inject(w,{mode:"edit",id:"stream-content",searchSize:"col-lg-3",secondWidget:!0,activityStream:!0}),v.streamTitle=c&&c.title?c.title:null,v.closeStream=function(a){m(),v.searchCleanup&&v.searchCleanup(),B&&h({scope:A,set:B.set,list:B.list,url:B.defaultUrl,iterator:B.iterator,sort_order:B.sort_order,setWidgets:!1}),a&&b.path(a)},v.refreshStream=function(){v.search(w.iterator)},v.showDetail=function(a){q({scope:v,activity_id:a})},v.removeStreamPostRefresh&&v.removeStreamPostRefresh(),v.removeStreamPostRefresh=v.$on("PostRefresh",function(){var a,b,c,d,e,f;for(a=0;a'+v.activities[a].summary_fields.actor.username+"":"system",d=/^\_delete/,e=v.activities[a].object1,f=v.activities[a].object2,e&&v.activities[a].summary_fields[e]&&v.activities[a].summary_fields[e].name?d.test(v.activities[a].summary_fields[e].name)?v.activities[a].objects=v.activities[a].summary_fields[e].name:(c=p(v.activities[a].summary_fields.object1),v.activities[a].objects=''+v.activities[a].summary_fields[e].name+""):v.activities[a].object1&&(v.activities[a].objects=v.activities[a].object1),f&&v.activities[a].summary_fields[f]&&v.activities[a].summary_fields[f].name?d.test(v.activities[a].summary_fields.object2.name)?v.activities[a].objects+=","+v.activities[a].summary_fields[f].name:(c=p(v.activities[a].summary_fields.object2),v.activities[a].objects+=', '+v.activities[a].summary_fields[f].name+""):v.activities[a].object2&&(v.activities[a].objects+=", "+v.activities[a].object2),n(v.activities[a]);setTimeout(function(){s()},500)}),h({scope:v,set:w.name,list:w,url:x}),i({scope:v,list:w,url:x}),v.search(w.iterator)}}]),angular.module("AuthService",["ngCookies","Utilities"]).factory("Authorization",["$http","$rootScope","$location","$cookieStore","GetBasePath",function(a,b,c,d,e){return{setToken:function(a,c){d.remove("token"),d.remove("token_expires"),d.remove("userLoggedIn"),d.put("token",a),d.put("token_expires",c),d.put("userLoggedIn",!0),d.put("sessionExpired",!1),b.token=a,b.userLoggedIn=!0,b.token_expires=c,b.sessionExpired=!1},isUserLoggedIn:function(){return void 0===b.userLoggedIn&&(b.userLoggedIn=d.get("userLoggedIn"),b.sessionExpired=d.get("sessionExpired")),b.userLoggedIn},getToken:function(){return b.token?b.token:d.get("token")},retrieveToken:function(b,c){return a({method:"POST",url:e("authtoken"),data:{username:b,password:c}})},logout:function(){var a=angular.element(document.getElementById("main-view")).scope();a.$destroy(),b.$destroy(),d.remove("accordions"),d.remove("token"),d.remove("token_expires"),d.remove("current_user"),d.remove("lastPath"),d.put("userLoggedIn",!1),d.put("sessionExpired",!1),d.remove("lastPath","/home"),b.current_user={},b.license_tested=void 0,b.userLoggedIn=!1,b.sessionExpired=!1,b.token=null,b.token_expires=null,b.lastPath="/home"},getLicense:function(){return a({method:"GET",url:e("config"),headers:{Authorization:"Token "+this.getToken()}})},setLicense:function(a){a.tested=!1,d.put("license",a)},licenseTested:function(){var a,c;return void 0!==b.license_tested?c=b.license_tested:(a=d.get("license"),c=a&&void 0!==a.tested?a.tested:!1),c},getUser:function(){return a({method:"GET",url:"/api/v1/me/",headers:{Authorization:"Token "+this.getToken()}})},setUserInfo:function(a){b.current_user=a.results[0],d.put("current_user",a.results[0])},restoreUserInfo:function(){b.current_user=d.get("current_user")},getUserInfo:function(a){var c;return b.current_user?b.current_user[a]:(this.restoreUserInfo(),c=d.get("current_user"),c[a])}}}]),angular.module("InventoryTree",["Utilities","RestServices","GroupsHelper","PromptDialog"]).factory("SortNodes",[function(){return function(a){var b,c,d=[],e=[];for(b=0;b0?!0:!1,has_inventory_sources:s[e].has_inventory_sources,id:r,source:s[e].summary_fields.inventory_source.source,group_id:s[e].id,event_level:c,children:i,ngicon:s[e].children.length>0?"fa fa-minus-square-o node-toggle":"fa fa-square-o node-no-toggle",ngclick:"toggle("+r+")",related:{children:s[e].children.length>0?s[e].related.children:"",inventory_source:s[e].related.inventory_source},status:s[e].summary_fields.inventory_source.status,status_class:k["class"],status_tooltip:k.tooltip,launch_tooltip:k.launch_tip,launch_class:k.launch_class,hosts_status_tip:n.tooltip,show_failures:n.failures,hosts_status_class:n["class"],selected_class:"",show:!0,isDraggable:!0,isDroppable:!0},q.push(o),p&&o.group_id===p&&(m.selected_tree_id=r,m.selected_group_id=o.group_id),s[e].children.length>0&&j(s[e].children,r,c+1)}}function k(){e("start"),a.setUrl(b("inventory")+l+"/"),a.get().success(function(a){m.$emit("buildAllGroups",a.name,a.related.tree,a.related.groups)}).error(function(a,b){e("stop"),c(m,a,b,null,{hdr:"Error!",msg:"Failed to get inventory: "+l+". GET returned: "+b})})}var l=h.inventory_id,m=h.scope,n=h.refresh,o=h.emit,p=h.new_group_id,q=[],r=1;m.buildAllGroupsRemove&&m.buildAllGroupsRemove(),m.buildAllGroupsRemove=m.$on("buildAllGroups",function(b,d,f){a.setUrl(f),a.get().success(function(a){i(a),j(a,0,0),m.autoShowGroupHelp=0===a.length?!0:!1,n?(m.groups=q,m.$emit("GroupTreeRefreshed",d,q,o)):m.$emit("GroupTreeLoaded",d,q,o)}).error(function(a,b){e("stop"),c(m,a,b,null,{hdr:"Error!",msg:"Failed to get inventory tree for: "+l+". GET returned: "+b})})}),k()}}]).factory("UpdateGroup",["ApplyEllipsis","GetSyncStatusMsg","Empty",function(a,b,c){return function(d){var e,f,g,h,i,j=d.scope,k=d.group_id,l=d.properties;for(e=0;e\n',m+='\n",m+="\n",i=angular.element(document.getElementById("inventory-modal-container")),i.empty().append(m),a(i)(j),$("#copy-prompt-modal").modal({backdrop:"static",keyboard:!0,show:!0}),j.moveGroup=function(){var a,b,i;$("#copy-prompt-modal").modal("hide"),e("start"),j.removeGroupRemove&&j.removeGroupRemove(),j.removeGroupRemove=j.$on("removeGroup",function(){l.parent>0?(i=d({list:j.groups,key:"id",val:l.parent}),a=h("base")+"groups/"+i.group_id+"/children/",f.setUrl(a),f.post({id:l.group_id,disassociate:1}).success(function(){j.$emit("GroupDeleteCompleted")}).error(function(a,b){e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to remove "+l.name+" from "+i.name+". POST returned status: "+b})})):j.$emit("GroupDeleteCompleted")}),a=g(k.group_id)?h("inventory")+j.inventory_id+"/groups/":h("base")+"groups/"+k.group_id+"/children/",b={id:l.group_id,name:l.name,description:l.description,inventory:j.inventory_id},f.setUrl(a),f.post(b).success(function(){j.$emit("removeGroup")}).error(function(a,b){var d=g(k.group_id)?"inventory":k.name;e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+d+". POST returned status: "+b})})},j.copyGroup=function(){$("#copy-prompt-modal").modal("hide"),e("start");var a=g(k.group_id)?h("inventory")+j.inventory_id+"/groups/":h("base")+"groups/"+k.group_id+"/children/",b={id:l.group_id,name:l.name,description:l.description,inventory:j.inventory_id};f.setUrl(a),f.post(b).success(function(){j.$emit("GroupDeleteCompleted")}).error(function(a,b){var d=g(k.group_id)?"inventory":k.name;e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+d+". POST returned status: "+b})})}}}]).factory("CopyMoveHost",["$compile","Alert","ProcessErrors","Find","Wait","Rest","Empty","GetBasePath",function(a,b,c,d,e,f,g,h){return function(b){var g,i,j=b.scope,k=d({list:j.groups,key:"id",val:b.target_tree_id}),l=d({list:j.hosts,key:"id",val:b.host_id}),m=!1,n="";if(l.summary_fields.all_groups)for(i=0;i\n',n+='\n",n+="\n",n+="\n",g=angular.element(document.getElementById("inventory-modal-container")),g.empty().append(n),a(g)(j),$("#copy-alert-modal").modal({backdrop:"static",keyboard:!0,show:!0})):(n="",n+='\n",g=angular.element(document.getElementById("inventory-modal-container")),g.empty().append(n),a(g)(j),$("#copy-prompt-modal").modal({backdrop:"static",keyboard:!0,show:!0}),j.copyHost=function(){$("#copy-prompt-modal").modal("hide"),e("start"),f.setUrl(h("groups")+k.group_id+"/hosts/"),f.post(l).success(function(){j.$emit("GroupTreeRefreshed")}).error(function(a,b){e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+k.name+". POST returned status: "+b})})})}}]),angular.module("RestServices",["ngCookies","AuthService"]).factory("Rest",["$http","$rootScope","$cookieStore","$q","Authorization",function(a,b,c,d,e){return{headers:{},setUrl:function(a){this.url=a},checkExpired:function(){return b.sessionTimer.isExpired()},pReplace:function(){var a,b;for(a in this.params)b=new RegExp("\\:"+a,"gm"),b.test(this.url)&&(this.url=this.url.replace(b,this.params[a]),delete this.params[a])},createResponse:function(a,b){var c=d.reject({data:a,status:b});return c.success=function(a){return c.then(function(b){a(b.data,b.status)},null),c},c.error=function(a){return c.then(null,function(b){a(b.data,b.status)}),c},c},setHeader:function(a){for(var b in a)this.headers[b]=a[b]},get:function(b){b=b?b:{},this.params=b.params?b.params:null,this.pReplace();var c=this.checkExpired(),d=e.getToken();return c?this.createResponse({detail:"Token is expired"},401):d?(this.setHeader({Authorization:"Token "+d}),this.setHeader({"X-Auth-Token":"Token "+d}),a({method:"GET",url:this.url,headers:this.headers,params:this.params})):this.createResponse({detail:"Invalid token"},401)},post:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"POST",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},put:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"PUT",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},destroy:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"DELETE",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},options:function(){var b=e.getToken(),c=this.checkExpired();return c?this.createResponse({detail:"Token is expired"},401):b?(this.setHeader({Authorization:"Token "+b}),this.setHeader({"X-Auth-Token":"Token "+b}),a({method:"OPTIONS",url:this.url,headers:this.headers})):this.createResponse({detail:"Invalid token"},401)}}}]),angular.module("TimerService",["ngCookies","Utilities"]).factory("Timer",["$rootScope","$cookieStore","$location","GetBasePath","Empty",function(a,b){return{sessionTime:null,timeout:null,getSessionTime:function(){return this.sessionTime?this.sessionTime:b.get("sessionTime")},isExpired:function(){var a=this.getSessionTime(),b=(new Date).getTime();return 0>=a-b?!0:(this.moveForward(),!1)},expireSession:function(){this.sessionTime=0,a.sessionExpired=!0,b.put("sessionExpired",!0)},moveForward:function(){var c=(new Date).getTime()+1e3*$AnsibleConfig.session_timeout;this.sessionTime=c,b.put("sessionTime",c),a.sessionExpired=!1,b.put("sessionExpired",!1)},init:function(){return this.moveForward(),this}}}]),angular.module("Utilities",["RestServices","Utilities"]).factory("ClearScope",[function(){return function(a){var b,c=document.getElementById(a);c&&(b=angular.element(c).scope(),b.$destroy()),$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()});try{$("#help-modal").dialog("close")}catch(d){}$(window).unbind("resize")}}]).factory("Empty",[function(){return function(a){return null===a||void 0===a||""===a?!0:!1}}]).factory("ToggleClass",function(){return function(a,b){$(a)&&$(a).hasClass(b)?$(a).removeClass(b):$(a)&&$(a).addClass(b)}}).factory("Alert",["$rootScope",function(a){return function(b,c,d,e,f,g){f?(a.alertHeader2=b,a.alertBody2=c,a.alertClass2=d?d:"alert-danger",$("#alert-modal2").modal({show:!0,keyboard:!0,backdrop:"static"}),a.disableButtons2=g?!0:!1,e&&$("#alert-modal2").on("hidden",function(){e()}),$(document).bind("keydown",function(a){27===a.keyCode&&($("#alert-modal2").modal("hide"),e&&e())})):(a.alertHeader=b,a.alertBody=c,a.alertClass=d?d:"alert-danger",$("#alert-modal").modal({show:!0,keyboard:!0,backdrop:"static"}),$(document).bind("keydown",function(a){27===a.keyCode&&($("#alert-modal").modal("hide"),e&&e())}),a.disableButtons=g?!0:!1,e&&$("#alert-modal").on("hidden",function(){e()}))}}]).factory("ProcessErrors",["$rootScope","$cookieStore","$log","$location","Alert","Wait",function(a,b,c,d,e,f){return function(b,c,g,h,i){var j,k,l;if(f("stop"),$AnsibleConfig.debug_mode&&console&&(console.log("Debug status: "+g),console.log("Debug data: "),console.log(c)),403===g)l="The API responded with a 403 Access Denied error. ",l+=c.detail?"Detail: "+c.detail:"Please contact your system administrator.",e(i.hdr,l);else if(401===g&&c.detail&&"Token is expired"===c.detail||401===g&&c.detail&&"Invalid token"===c.detail)a.sessionTimer.expireSession(),d.url("/login");else if(c.non_field_errors)e("Error!",c.non_field_errors);else if(c.detail)e(i.hdr,i.msg+" "+c.detail);else if(c.__all__)e("Error!",c.__all__);else if(h){k=!1;for(j in h.fields)c[j]&&h.fields[j].tab&&$("#"+h.name+'_tabs a[href="#'+h.fields[j].tab+'"]').tab("show"),h.fields[j].realName&&c[h.fields[j].realName]&&(b[j+"_api_error"]=c[h.fields[j]][0],$('[name="'+h.fields[j].realName+'"]').addClass("ng-invalid"),k=!0),h.fields[j].sourceModel?c[j]&&(b[h.fields[j].sourceModel+"_"+h.fields[j].sourceField+"_api_error"]=c[j][0],$('[name="'+h.fields[j].sourceModel+"_"+h.fields[j].sourceField+'"]').addClass("ng-invalid"),k=!0):c[j]&&(b[j+"_api_error"]=c[j][0],$('[name="'+j+'"]').addClass("ng-invalid"),k=!0); +!k&&i&&e(i.hdr,i.msg)}else e(i.hdr,i.msg)}}]).factory("LoadBreadCrumbs",["$rootScope","$routeParams","$location","Empty",function(a,b,c,d){return function(b){function e(a){return a.toUpperCase()}function f(a){return"ies"===a?"y":""}var g,h,i,j,k,l,m,n;if(!d(b)){for(h=!1,j=0;j1)for(j=0;j0&&k[j].match(/\d+/)){for(m=k[j-1],n=m.replace(/(ies$|s$)/,f),n=n.charAt(0).toUpperCase()+n.slice(1),h=!1,i=0;i\n",b+='
        \n',b+='',b+="
        \n",b+='
        '+a.box+"
        ",b+=f&&a.autoOffNotice?'
        \n':""}var h,i,j,k,l=!1;e=a,j=d.story.width?d.story.width:510,k=d.story.height?d.story.height:600,i=$(document).width(),j=j>i?i:j;try{l=$("#help-modal").dialog("isOpen")}catch(m){}l?$("#help-modal").html(g(d.story.steps[e])):(h=[],d.story.steps.length>1&&(h.push({text:"Prev",click:function(a){e-1===0&&$(a.target).button("disable"),e-10&&$(a.target).prev().button("enable"),e+1===d.story.steps.length-1&&$(a.target).button("disable"),b(e+1)}})),h.push({text:"Close",click:function(){$("#help-modal").dialog("close")}}),$("#help-modal").html(g(d.story.steps[e])).dialog({position:{my:"center top",at:"center top+150",of:"body"},title:d.story.hdr,width:j,height:k,buttons:h,closeOnEscape:!0,show:500,hide:500,resizable:!1,close:function(){$("#help-modal").empty()}}),$(".ui-dialog-buttonset button").each(function(){var a,b,c;c=$(this).text(),"Close"===c?(b="fa-times",a="btn btn-default",$(this).attr({"class":a}).html(' Close')):"Prev"===c?(b="fa-chevron-left",a="btn btn-primary",$(this).attr({"class":a}).html(' Prev')):(b="fa-chevron-right",a="btn btn-primary",$(this).attr({"class":a}).html('Next ').css({"margin-right":"20px"}))}),$('.ui-dialog[aria-describedby="help-modal"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$("#auto-off-checkbox").click(function(){$('input[name="auto-off-checkbox"]:checked').length?c("inventoryAutoHelp","off"):c("inventoryAutoHelp","on")}))}var d=a.defn,e=a.step,f=a.autoShow||!1;b(0)}}]).factory("ReturnToCaller",["$location","Empty",function(a,b){return function(c){var d,e=a.path().replace(/^\//,"").split("/"),f="";for(c=b(c)?e.length-1:c+1,d=0;c>d;d++)f+="/"+e[d];a.path(f)}}]).factory("FormatDate",["$filter",function(a){return function(b){return a("date")(b,"MM/dd/yy HH:mm:ss")}}]).factory("Wait",["$rootScope",function(a){return function(b){var c,d,e,f,g,h;"start"!==b||a.waiting?"stop"===b&&a.waiting&&$(".spinny, .overlay").fadeOut(400,function(){a.waiting=!1}):(a.waiting=!0,c=$(window).width(),d=$(window).height(),e=$(".spinny").width(),f=$(".spinny").height(),g=(c-e)/2,h=(d-f)/2,$(".overlay").css({width:$(document).width(),height:$(document).height()}).fadeIn(),$(".spinny").css({top:h,left:g}).fadeIn(400))}}]).factory("HideElement",[function(){return function(a,b){var c=$(a),d=c.css("width"),e=c.css("height"),f=c.position(),g=c.parent(),h=c.css("border-radius"),i=c.css("background-color"),j=c.css("margin"),k=c.css("padding");g.append('
        '),$("#curtain-div").show(0,b)}}]).factory("ShowElement",[function(){return function(){$("#curtain-div").fadeOut(500,function(){$(this).remove()})}}]).factory("GetChoices",["Rest","ProcessErrors",function(a,b){return function(c){var d=c.scope,e=c.url,f=c.field,g=c.variable,h=c.callback,i=c.choice_name;d[g]?d[g].length=0:d[g]=[],a.setUrl(e),a.options().success(function(a){var b,c;for(b=i?a.actions.GET[f][i]:a.actions.GET[f].choices,c=0;c
        . Use the Refresh button to monitor the status.","alert-info"):o({scope:A,group_id:d,url:A.group_update_url,group_name:A.name,group_source:A.source.value})},A.sourceChange=function(){v({scope:A,form:g})}}}]).factory("GroupsDelete",["$rootScope","$location","$log","$routeParams","Rest","Alert","GroupForm","GenerateForm","Prompt","ProcessErrors","GetBasePath","Wait","BuildTree","Find",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){return function(a){var b,c=a.scope,d=a.tree_id,f=a.inventory_id,g=n({list:c.groups,key:"id",val:d}),h=k("inventory")+f+"/groups/";b=function(){$("#prompt-modal").on("hidden.bs.modal",function(){l("start")}),$("#prompt-modal").modal("hide"),e.setUrl(h),e.post({id:g.group_id,disassociate:1}).success(function(){$("#prompt-modal").off(),c.$emit("GroupDeleteCompleted")}).error(function(a,b){l("stop"),j(c,a,b,null,{hdr:"Error!",msg:"Call to "+h+" failed. POST returned status: "+b})})},i({hdr:"Delete Group",body:"

        Are you sure you want to delete group "+g.name+"?

        ",action:b,"class":"btn-danger"})}}]).factory("ShowUpdateStatus",["$rootScope","$location","$log","$routeParams","Rest","Alert","GenerateForm","Prompt","ProcessErrors","GetBasePath","FormatDate","InventoryStatusForm","Wait","Empty","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(a){function b(a){var b,d;return b=a.match(/\n/g),d=b?b.length:1,d>c?c:d}var c,d,h,j,n,p,q,r=a.group_name,s=a.last_update,t=g,u=l,v=a.license_error;void 0===s||null===s||""===s?(m("stop"),f("Missing Configuration","The selected group is not configured for inventory sync. Edit the group and provide Source information.","alert-info")):(d='
        \n
        \n',$("#inventory-modal-container").empty().append(d),h=t.inject(u,{mode:"edit",id:"form-container",breadCrumbs:!1,related:!1}),j=$(document).width(),n=$("body").height(),j>1199?(p=675,q=750>n?n-20:750,c=18):1199>=j&&j>=768?(p=550,q=620>n?n-15:620,c=12):(p=j-20,q=500>n?n:500,c=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:p,height:q,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#inventory-modal-container").empty(),o()},open:function(){m("stop")}}),e.setUrl(s),e.get().success(function(a){for(var c in u.fields)a[c]&&(h[c]="created"===c?k(new Date(a[c])):a[c]);h.license_error=v,h.status_rows=b(a.status),h.stdout_rows=b(a.result_stdout),h.traceback_rows=b(a.result_traceback),$("#status-modal-dialog").dialog("open")}).error(function(a,b){$("#form-modal").modal("hide"),i(h,a,b,null,{hdr:"Error!",msg:"Failed to retrieve last update: "+s+". GET status: "+b})}))}}]),angular.module("HostsHelper",["RestServices","Utilities","ListGenerator","HostListDefinition","SearchHelper","PaginationHelpers","ListGenerator","AuthService","HostsHelper","InventoryHelper","RelatedSearchHelper","InventoryFormDefinition","SelectionHelper","HostGroupsFormDefinition"]).factory("SetEnabledMsg",[function(){return function(a){a.enabledToolTip=a.has_inventory_sources?a.enabled?"Host is available":"Host is not available":a.enabled?"Host is available. Click to toggle.":"Host is not available. Click to toggle."}}]).factory("SetHostStatus",["SetEnabledMsg",function(a){return function(b){b.activeFailuresLink="/#/hosts/"+b.id+"/job_host_summaries/?inventory="+b.inventory+"&host_name="+encodeURI(b.name),b.has_active_failures===!0?(b.badgeToolTip="Most recent job failed. Click to view jobs.",b.active_failures="failed"):b.has_active_failures===!1&&null===b.last_job?(b.has_active_failures="none",b.badgeToolTip="No job data available.",b.active_failures="n/a"):b.has_active_failures===!1&&null!==b.last_job&&(b.badgeToolTip="Most recent job successful. Click to view jobs.",b.active_failures="success"),b.enabled_flag=b.enabled,a(b)}}]).factory("SetStatus",["SetEnabledMsg","Empty",function(a,b){return function(c){function d(a){return a.length>25?a.substr(0,25)+"...":a}function e(a){var b,c,e;if(a.has_active_failures===!0||a.has_active_failures===!1&&null!==a.last_job)if(a.has_active_failures===!0?(a.badgeToolTip="Most recent job failed. Click to view jobs.",a.active_failures="failed"):(a.badgeToolTip="Most recent job successful. Click to view jobs.",a.active_failures="success"),a.summary_fields.recent_jobs.length>0){for(e=a.summary_fields.recent_jobs.sort(function(a,b){return-1*(a-b)}),h="Recent Jobs",g='\n',g+="\n",g+="\n",g+="\n",g+="\n",g+="\n",g+="\n",b=0;b\n",g+='\n",g+='\n',g+='\n',g+='\n",g+="\n";g+="\n",g+="
        ID\n",g+='Status\n',g+="ViewName\n",g+="
        '+c.id+"Events Hosts'+d(c.name)+"
        \n"}else h="No job data",g="

        No recent job data available for this host.

        ";else a.has_active_failures===!1&&null===a.last_job&&(a.has_active_failures="none",a.badgeToolTip="No job data available.",a.active_failures="n/a");a.job_status_html=g,a.job_status_title=h}var f,g,h,i=c.scope,j=c.host;if(b(j))for(f=0;fAre you sure you want to delete host "+j+" from group "+n.name+"?

        ":"

        Are you sure you want to delete host "+j+"?

        ",g({hdr:"Delete Host",body:c,action:b,"class":"btn-danger"})}}]).factory("EditHostGroups",["$rootScope","$location","$log","$routeParams","Rest","Alert","GenerateForm","Prompt","ProcessErrors","GetBasePath","HostsReload","ParseTypeChange","Wait",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(a){var b,c,d,f,h,l=a.host_id,n=a.inventory_id,o=g,p=[];for(c='
        \n',c+='
        \n',c+="\n",c+='\n',c+="
        \n",c+='
        \n',c+="\n",c+='\n',c+="
        \n",c+="
        \n",c+='
        \n',c+='
        \n',c+='\n',c+='\n',c+="

        (move selected groups)

        \n",c+="
        \n",c+="
        \n",d=j("hosts")+l+"/",f=o.inject(null,{mode:"edit",modal:!0,related:!1,html:c}),b=0;bGroups',f.formModalCancelShow=!0,f.formModalActionDisabled=!0,$("#form-modal .btn-none").removeClass("btn-none").addClass("btn-success"),f.hostGroupChangeRemove&&f.hostGroupChangeRemove(),f.hostGroupChangeRemove=f.$on("hostGroupChange",function(){p.pop(),0===p.length&&(h=function(){setTimeout(function(){m("stop")},500)},k({scope:f,inventory_id:n,group_id:f.group_id,action:h}))}),f.formModalAction=function(){var a,b,c;for($("#form-modal").modal("hide"),m("start"),a=0;a0?(f.assignedGroups=null,f.leftButtonDisabled=!0,f.rightButtonDisabled=!1):f.rightButtonDisabled=!0},f.rightChange=function(){null!==f.assignedGroups&&f.assignedGroups.length>0?(f.selectedGroups=null,f.leftButtonDisabled=!1,f.rightButtonDisabled=!0):f.leftButtonDisabled=!0},f.moveLeft=function(){var a,b,c,d;for(a=0;af.available_groups[b].name.toLowerCase()&&f.assignedGroups[a].name.toLowerCase()f.host_groups[b].name.toLowerCase()&&f.selectedGroups[a].name.toLowerCase()0){for(j("stop"),u+='
        \n',u+=w?w:"",o=0;o\n',u+='\n",u+='
        \n',u+='A value is required!\n',u+='\n',u+="
        \n",u+="\n",n=l.associated,l=p.fields[l.associated],q[n]="",u+='
        \n',u+='\n",u+='
        \n',u+='A value is required!\n',l.awPassMatch&&(u+='Must match Password value\n'),u+='\n',u+="
        \n",u+="
        \n";u+="\n",m=angular.element(document.getElementById("password-body")),m.html(u),c(m.contents())(q),$("#password-modal").modal(),$("#password-modal").on("shown.bs.modal",function(){$("#password-body").find('input[type="password"]:first').focus()})}else q.startJob()}}]).factory("SubmitJob",["PromptPasswords","$compile","Rest","$location","GetBasePath","CredentialList","LookUpInit","CredentialForm","ProcessErrors","JobTemplateForm","Wait",function(a,b,c,d,e,f,g,h,i,j,k){return function(b){function l(b){var e,f,g;m.credentialWatchRemove&&m.credentialWatchRemove(),e=(new Date).toISOString(),f=b.related.jobs?b.related.jobs:b.related.job_template+"jobs/",g=o?o:b.name,k("start"),c.setUrl(f),c.post({name:g+" "+e,description:b.description,job_template:b.id,inventory:b.inventory,project:b.project,playbook:b.playbook,credential:b.credential,forks:b.forks,limit:b.limit,verbosity:b.verbosity,extra_vars:b.extra_vars}).success(function(b){m.job_id=b.id,b.passwords_needed_to_start.length>0?a({scope:m,passwords:b.passwords_needed_to_start,start_url:b.related.start,form:h}):(c.setUrl(b.related.start),c.post().success(function(){k("stop");var a=d.path().replace(/^\//,"").split("/")[0];"jobs"===a?m.refresh():d.path("/jobs")}).error(function(a,b){i(m,a,b,null,{hdr:"Error!",msg:"Failed to start job. POST returned status: "+b})}))}).error(function(a,b){k("stop"),i(m,a,b,null,{hdr:"Error!",msg:"Failed to create job. POST returned status: "+b})})}var m=b.scope,n=b.id,o=b.template?b.template:null,p=d.path().replace(/^\//,"").split("/")[0],q=e(p)+n+"/";k("start"),c.setUrl(q),c.get().success(function(a){m.credential="",""===a.credential||null===a.credential?(k("stop"),m.credentialWatchRemove&&m.credentialWatchRemove(),m.credentialWatchRemove=m.$watch("credential",function(b,c){b!==c&&""!==m.credential&&null!==m.credential&&void 0!==m.credential&&(a.credential=m.credential,l(a))}),g({scope:m,form:j,current_item:null,list:f,field:"credential",hdr:"Credential Required"}),m.lookUpCredential()):l(a)}).error(function(a,b){i(m,a,b,null,{hdr:"Error!",msg:"Failed to get job template details. GET returned status: "+b})})}}]).factory("ProjectUpdate",["PromptPasswords","$compile","Rest","$location","GetBasePath","ProcessErrors","Alert","ProjectsForm","Wait",function(a,b,c,d,e,f,g,h,i){return function(b){var d=b.scope,j=b.project_id,k=e("projects")+j+"/update/";d.removeUpdateSubmitted&&d.removeUpdateSubmitted(),d.removeUpdateSubmitted=d.$on("UpdateSubmitted",function(){i("stop"),g("Update Started","The request to start the SCM update process was submitted. To monitor the update status, refresh the page by clicking the Refresh button.","alert-info"),d.refresh()}),d.removeSCMSubmit&&d.removeSCMSubmit(),d.removeSCMSubmit=d.$on("SCMSubmit",function(b,c,e){a({scope:d,passwords:c,start_url:k,form:h,extra_html:e})}),i("start"),c.setUrl(k),c.get().success(function(a){var b,c;if(i("stop"),a.can_update){for(c="",b=0;b\n',c+='\n',c+='
        \n',c+=' button.',"alert-info"),d.removeHostReloadComplete&&d.removeHostReloadComplete()}),d.removeUpdateSubmitted&&d.removeUpdateSubmitted(),d.removeUpdateSubmitted=d.$on("UpdateSubmitted",function(a,b){"started"===b&&(d.refreshGroups?(d.selected_tree_id=k,d.selected_group_id=i,d.refreshGroups()):d.refresh&&d.refresh(),d.$emit("HostReloadComplete"))}),d.removeInventorySubmit&&d.removeInventorySubmit(),d.removeInventorySubmit=d.$on("InventorySubmit",function(b,c,f){a({scope:d,passwords:c,start_url:e,form:h,extra_html:f})}),j("start"),c.setUrl(e),c.get().success(function(a){a.can_update?d.$emit("InventorySubmit",a.passwords_needed_to_update):(j("stop"),g("Permission Denied","You do not have access to run the update. Please contact your system administrator.","alert-danger"))}).error(function(a,b){j("stop"),f(d,a,b,null,{hdr:"Error!",msg:"Failed to get inventory_source details. "+e+"GET status: "+b})})}}]),angular.module("JobsHelper",["Utilities","FormGenerator","JobSummaryDefinition","InventoryHelper"]).factory("JobStatusToolTip",[function(){return function(a){var b;switch(a){case"successful":case"success":b="There were no failed tasks.";break;case"failed":b="Some tasks encountered errors.";break;case"canceled":b="Stopped by user request.";break;case"new":b="In queue, waiting on task manager.";break;case"waiting":b="SCM Update or Inventory Update is executing.";break;case"pending":b="Not in queue, waiting on task manager.";break;case"running":b="Playbook tasks executing."}return b}}]).factory("ShowJobSummary",["Rest","Wait","GetBasePath","FormatDate","ProcessErrors","GenerateForm","JobSummary","WatchInventoryWindowResize",function(a,b,c,d,e,f,g,h){return function(i){function j(a){var b=a.match(/\n/g),c=b?b.length:1;return c>p?20:c}var k,l,m,n,o,p,q,r,s=i.job_id,t=f,u=g;r='
        \n',$("#inventory-modal-container").empty().append(r),k=t.inject(u,{mode:"edit",id:"form-container",breadCrumbs:!1,related:!1}),l=$(document).width(),m=$("body").height(),l>1199?(n=675,o=750>m?m-20:750,p=20):1199>=l&&l>=768?(n=550,o=620>m?m-15:620,p=15):(n=l-20,o=500>m?m:500,p=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:n,height:o,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#inventory-modal-container").empty(),h()},open:function(){b("stop")}}),b("start"),q=c("jobs")+s+"/",a.setUrl(q),a.get().success(function(a){var b;k.id=a.id,k.name=a.name,k.status=a.status,k.result_stdout=a.result_stdout,k.result_traceback=a.result_traceback,k.stdout_rows=j(k.result_stdout),k.traceback_rows=j(k.result_traceback),b=new Date(a.created),k.created=d(b),$("#status-modal-dialog").dialog("open")}).error(function(a,b){e(k,a,b,null,{hdr:"Error!",msg:"Attempt to load job failed. GET returned status: "+b})})}}]),angular.module("LookUpHelper",["RestServices","Utilities","SearchHelper","PaginationHelpers","ListGenerator","ApiLoader"]).factory("LookUpInit",["Alert","Rest","GenerateList","SearchInit","PaginateInit","GetBasePath","FormatDate","Empty",function(a,b,c,d,e,f,g,h){return function(b){var i,j,k,l,m=b.scope,n=b.form,o=b.list,p=b.field,q=b.postAction;i=b.url?b.url:f("inventories"===o.name?"inventory":o.name),j=o.iterator.charAt(0).toUpperCase()+o.iterator.substring(1),k=b.hdr?b.hdr:"Select "+j,l=/\/$/.test(i)?i+"?":i+"&",l+=n.fields[p].sourceField+"__iexact=:value",$('input[name="'+n.fields[p].sourceModel+"_"+n.fields[p].sourceField+'"]').attr("data-url",l),$('input[name="'+n.fields[p].sourceModel+"_"+n.fields[p].sourceField+'"]').attr("data-source",p),m["lookUp"+j]=function(){var b=c,f=b.inject(o,{mode:"lookup",hdr:k});$("#lookup-modal").on("hidden.bs.modal",function(){f.searchCleanup&&f.searchCleanup(),(""===m[p]||null===m[p])&&(m[n.fields[p].sourceModel+"_"+n.fields[p].sourceField]="",m.$$phase||m.$digest())}),f.selectAction=function(){var c,d=!1;for(c=0;c5?f[j+"_page"]-5:1,e=f[j+"_page"]<6?10<=f[j+"_num_pages"]?10:f[j+"_num_pages"]:f[j+"_page"]+4=c;c++)f[j+"_page_range"].push(c)}}]).factory("RelatedPaginateInit",["RefreshRelated","$cookieStore","Wait",function(a,b,c){return function(d){var e,f=d.scope,g=d.relatedSets,h=d.pageSize?d.pageSize:10;for(e in g)f[g[e].iterator+"_url"]=g[e].url,f[g[e].iterator+"_page"]=0,f[g[e].iterator+"_page_size"]=h;f.getPage=function(b,d,e){var g=f[e+"_url"].replace(/.page\=\d+/,""),h=/\/$/.test(g)?"?":"&";g+=h+"page="+b,g+=f[e+"SearchParams"]?"&"+f[e+"SearchParams"]+"&page_size="+f[e+"_page_size"]:"page_size="+f[e+"PageSize"],c("start"),a({scope:f,set:d,iterator:e,url:g})},f.pageIsActive=function(a,b){return a===f[b+"_page"]?"active":""},f.changePageSize=function(c,d){f[d+"_page"]=1;var e=f[d+"_url"];b.put(d+"_page_size",f[d+"_page_size"]),e=e.replace(/\/\?.*$/,"/"),e+=f[d+"SearchParams"]?"?"+f[d+"SearchParams"]+"&page_size="+f[d+"_page_size"]:"?page_size="+f[d+"_page_size"],a({scope:f,set:c,iterator:d,url:e})}}}]).factory("PaginateInit",["Refresh","$cookieStore","Wait",function(a,b,c){return function(b){var d=b.scope,e=b.list,f=b.iterator?b.iterator:e.iterator,g=b.mode?b.mode:null;d[f+"_page"]=b.page?b.page:1,d[f+"_url"]=b.url,d[f+"_mode"]=g,d[f+"_page_size"]=b.pageSize?b.pageSize:"lookup"===g?5:20,d.getPage=function(b,e,f){var g=d[f+"_url"].replace(/.page\=\d+/,""),h=/\/$/.test(g)?"?":"&";g+=h+"page="+b,g+=d[f+"SearchParams"]?"&"+d[f+"SearchParams"]+"&page_size="+d[f+"_page_size"]:"page_size="+d[f+"PageSize"],c("start"),a({scope:d,set:e,iterator:f,url:g})},d.pageIsActive=function(a,b){return a===d[b+"_page"]?"active":""},d.changePageSize=function(b,e){d[e+"_page"]=0;var f=d[e+"_url"].replace(/\?page_size\=\d+/,""),g=/\/$/.test(f)?"?":"&";f+=d[e+"SearchParams"]?g+d[e+"SearchParams"]+"&page_size="+d[e+"_page_size"]:g+"page_size="+d[e+"_page_size"],c("start"),a({scope:d,set:b,iterator:e,url:f})}}}]),angular.module("ParseHelper",[]).factory("ParseTypeChange",[function(){return function(a,b,c){var d=b?b:"variables",e=c?c:"parseType";a.blockParseTypeWatch=!1,a.blockVariableDataWatch=!1,a["remove"+d+"Watch"]&&a["remove"+d+"Watch"](),a["remove"+d+"Watch"]=a.$watch(e,function(b,c){var e;if(b!==c)if("json"===b)if(a[d]&&!/^---$/.test(a[d]))try{e=jsyaml.load(a[d]),a[d]=JSON.stringify(e,null," ")}catch(f){}else a[d]="{}";else if(a[d]&&!/^\{\}$/.test(a[d]))try{e=JSON.parse(a[d]),a[d]=jsyaml.safeDump(e)}catch(f){}else a[d]="---"})}}]),angular.module("PermissionsHelper",[]).factory("PermissionCategoryChange",[function(){return function(a){var b=a.scope,c=a.reset;"Inventory"===b.category?(b.projectrequired=!1,b.permissionTypeHelp="
        \n
        Read
        \n
        Only allow the user or team to view the inventory.
        \n
        Write
        \n
        Allow the user or team to modify hosts and groups contained in the inventory, add new hosts and groups, and perform inventory sync operations.\n
        Admin
        \n
        Allow the user or team full access to the inventory. This includes reading, writing, deletion of the inventory and inventory sync operations.
        \n
        \n"):(b.projectrequired=!0,b.permissionTypeHelp="
        \n
        Run
        \n
        Allow the user or team to perform a live deployment of the project against the inventory. In Run mode modules will be executed, and changes to the inventory will occur.
        \n
        Check
        \n
        Only allow the user or team to deploy the project against the inventory as a dry-run operation. In Check mode, module operations will only be simulated. No changes will occur.
        \n
        \n"),c&&(b.permission_type="Inventory"===b.category?"read":"run")}}]),angular.module("ProjectPathHelper",["RestServices","Utilities"]).factory("GetProjectPath",["Alert","Rest","GetBasePath","ProcessErrors",function(a,b,c,d){return function(a){function e(a){var b,c,d=[],e=[];for(b=0;b
        \n',$("#projects-modal-container").empty().append(b),c=q.inject(r,{mode:"edit",id:"form-container",related:!1,breadCrumbs:!1}),q.reset(),d=$(document).width(),f=$("body").height(),d>1199?(h=675,j=750>f?f-20:750,n=20):1199>=d&&d>=768?(h=550,j=620>f?f-15:620,n=15):(h=d-20,j=500>f?f:500,n=10),$("#status-modal-dialog").dialog({buttons:{OK:function(){$(this).dialog("close")}},modal:!0,width:h,height:j,autoOpen:!1,create:function(){$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$('.ui-dialog[aria-describedby="status-modal-dialog"]').find(".ui-dialog-buttonset button:first").attr({"class":"btn btn-primary"})},resizeStop:function(){var a=$('.ui-dialog[aria-describedby="status-modal-dialog"]'),b=a.find("#status-modal-dialog");b.width(a.width()-28)},close:function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()}),$("#status-modal-dialog").dialog("destroy"),$("#projects-modal-container").empty()},open:function(){m("stop")}}),e.setUrl(p),e.get().success(function(a){var b,d=a;for(b in r.fields)d[b]?c[b]="created"===b?k(new Date(d[b])):d[b]:d.summary_fields.project[b]&&(c[b]=d.summary_fields.project[b]);$("#status-modal-dialog").dialog({title:d.summary_fields.project.name+" Status"}).dialog("open")}).error(function(a,b){$("#form-modal").modal("hide"),i(c,a,b,r,{hdr:"Error!",msg:"Failed to retrieve status of project: "+o+". GET status: "+b})})}}]),angular.module("SelectionHelper",["Utilities","RestServices"]).factory("SelectionInit",["Rest","Alert","ProcessErrors","ReturnToCaller","Wait",function(a,b,c,d,e){return function(b){var f,g=b.scope,h=b.list,i=b.url,j=b.returnToCaller;f=void 0!==b.selected?b.selected:[],g.formModalActionDisabled=!0,g.disableSelectBtn=!0,g["toggle_"+h.iterator]=function(a,b){var c,d,e;for(c=0;c0?(g.formModalActionDisabled=!1,g.disableSelectBtn=!1):(g.formModalActionDisabled=!0,g.disableSelectBtn=!0)},g.finishSelection=function(){function b(){f=[],void 0!==j?d(j):($("#form-modal").modal("hide"),g.$emit("modalClosed"))}function k(b){a.post(b).success(function(a,b){m.push({result:"success",data:a,status:b}),g.$emit("callFinished")}).error(function(a,b,c){m.push({result:"error",data:a,status:b,headers:c}),g.$emit("callFinished")})}a.setUrl(i);var l,m=[];if(g.formModalActionDisabled=!0,g.disableSelectBtn=!0,e("start"),g.callFinishedRemove&&g.callFinishedRemove(),g.callFinishedRemove=g.$on("callFinished",function(){var a,d=0;if(m.length===f.length){for(e("stop"),a=0;a0)for(l=0;lh)h++,setTimeout(1e3,e());else if("success"===g.status)return d(a)}var f,g={},h=0;return null===c.apiDefaults||void 0===c.apiDefaults?(f="/api/v1/",b.setUrl(f),b.get().success(function(a){var b,d=a;for(b in d)switch(b){case"organizations":d[b].iterator="organization";break;case"jobs":d[b].iterator="job";break;case"users":d[b].iterator="user";break;case"teams":d[b].iterator="team";break;case"hosts":d[b].iterator="host";break;case"groups":d[b].iterator="group";break;case"projects":d[b].iterator="project";break;case"inventories":d[b].iterator="inventory"}c.apiDefaults=d,g={status:"success"}}).error(function(a,b){g={status:"error",msg:"Call to "+f+" failed. GET returned status: "+b}}),e()):d(a)}}]),angular.module("InventoryHelper",["RestServices","Utilities","OrganizationListDefinition","ListGenerator","AuthService","InventoryHelper","InventoryFormDefinition","ParseHelper","SearchHelper"]).factory("WatchInventoryWindowResize",["ApplyEllipsis",function(a){return function(){var b;$(window).resize(function(){clearTimeout(b),b=setTimeout(function(){$("#groups_table .name-column").each(function(){var a=$(this).width(),b=$(this).find(".level").width(),c=parseInt($(this).find(".level").css("padding-left").replace(/px/,"")),d=b+c,e=100-Math.ceil(d/a*100)+"%";$(this).find(".group-name").css({width:e})}),a("#groups_table .group-name a"),a("#hosts_table .host-name a")},100)})}}]).factory("SaveInventory",["InventoryForm","Rest","Alert","ProcessErrors","LookUpInit","OrganizationList","GetBasePath","ParseTypeChange","Wait",function(a,b,c,d,e,f,g,h,i){return function(e){var f,h,j,k=e.scope,l=a,m=g("inventory");i("start");try{if(h="json"===k.inventoryParseType?JSON.parse(k.inventory_variables):jsyaml.load(k.inventory_variables),"object"!=typeof h)throw"failed to return an object!";j={};for(f in l.fields)"inventory_variables"!==f&&(l.fields[f].realName?j[l.fields[f].realName]=k[f]:j[f]=k[f]);b.setUrl(m+k.inventory_id+"/"),b.put(j).success(function(a){k.inventory_variables?(b.setUrl(a.related.variable_data),b.put(h).success(function(){i("stop"),k.$emit("InventorySaved")}).error(function(a,b){d(k,a,b,l,{hdr:"Error!",msg:"Failed to update inventory varaibles. PUT returned status: "+b})})):k.$emit("InventorySaved")}).error(function(a,b){d(k,a,b,l,{hdr:"Error!",msg:"Failed to update inventory. POST returned status: "+b})})}catch(n){i("stop"),c("Error","Error parsing inventory variables. Parser returned: "+n)}}}]).factory("EditInventoryProperties",["InventoryForm","GenerateForm","Rest","Alert","ProcessErrors","LookUpInit","OrganizationList","GetBasePath","ParseTypeChange","SaveInventory","Wait","Store","SearchInit",function(a,b,c,d,e,f,g,h,i,j,k,l,m){return function(n){var o,p=n.scope,q=n.inventory_id,r=b,s=a,t={},u=l("CurrentSearchParams");s.well=!1,o=r.inject(s,{mode:"edit",modal:!0,related:!1,modal_show:!1}),s.well=!0,i(o,"inventory_variables","inventoryParseType"),o.inventoryParseType="yaml",o.formModalActionLabel="Save",o.formModalCancelShow=!0,o.formModalInfo=!1,o.formModalHeader="Inventory Properties",k("start"),c.setUrl(h("inventory")+q+"/"),c.get().success(function(a){var b,c;for(b in s.fields){if("inventory_variables"===b){if($.isEmptyObject(a.variables)||"{}"===a.variables||"null"===a.variables||""===a.variables)o.inventory_variables="---";else try{c=JSON.parse(a.variables),o.inventory_variables=jsyaml.safeDump(c)}catch(e){d("Variable Parse Error","Attempted to parse variables for inventory: "+q+". Parse returned: "+e),console&&(console.log(e),console.log("data:"),console.log(a.variables)),o.inventory_variables="---"}t.inventory_variables=o.variables}else"inventory_name"===b?(o[b]=a.name,t[b]=o[b]):"inventory_description"===b?(o[b]=a.description,t[b]=o[b]):a[b]&&(o[b]=a[b],t[b]=o[b]);s.fields[b].sourceModel&&a.summary_fields&&a.summary_fields[s.fields[b].sourceModel]&&(o[s.fields[b].sourceModel+"_"+s.fields[b].sourceField]=a.summary_fields[s.fields[b].sourceModel][s.fields[b].sourceField],t[s.fields[b].sourceModel+"_"+s.fields[b].sourceField]=a.summary_fields[s.fields[b].sourceModel][s.fields[b].sourceField])}f({scope:o,form:s,current_item:o.organization,list:g,field:"organization"}),k("stop"),$("#form-modal").modal("show")}).error(function(a,b){e(o,a,b,null,{hdr:"Error!",msg:"Failed to get inventory: "+q+". GET returned: "+b})}),o.removeInventorySaved&&o.removeInventorySaved(),o.removeInventorySaved=o.$on("InventorySaved",function(){$("#form-modal").modal("hide"),o.searchCleanp&&o.searchCleanup(),m({scope:p,set:u.set,list:u.list,url:u.defaultUrl,iterator:u.iterator,sort_order:u.sort_order,setWidgets:!1}),p.$emit("RefreshInventories")}),o.cancelModal=function(){o.searchCleanp&&o.searchCleanup(),m({scope:p,set:u.set,list:u.list,url:u.defaultUrl,iterator:u.iterator,sort_order:u.sort_order,setWidgets:!1})},o.formModalAction=function(){p.inventory_id=q,p.inventory_name=o.inventory_name,j({scope:o})}}}]),angular.module("md5Helper",["RestServices","Utilities"]).factory("md5Setup",[function(){return function(a){var b=a.scope,c=a.master,d=a.check_field,e=a.default_val;b[d]=e,c[d]=e,b.genMD5=function(a){var c=new Date;b[a]=$.md5("AnsibleWorks"+c.getTime())},b.toggleCallback=function(a){"false"===b.allow_callbacks&&(b[a]="")},b.selectAll=function(a){$('input[name="'+a+'"]').focus().select()}}}]),angular.module("RefreshRelatedHelper",["RestServices","Utilities","PaginationHelpers"]).factory("RefreshRelated",["ProcessErrors","Rest","Wait","PageRangeSetup",function(a,b,c,d){return function(e){var f=e.scope,g=e.set,h=e.iterator,i=e.url;b.setUrl(i),b.get().success(function(a){d({scope:f,count:a.count,next:a.next,previous:a.previous,iterator:h}),f[g]=a.results,f[h+"Loading"]=!1,f[h+"HoldInput"]=!1,c("stop"),f.$emit("related"+g)}).error(function(b,c){a(f,b,c,null,{hdr:"Error!",msg:"Failed to retrieve "+g+". GET returned status: "+c})})}}]),angular.module("RefreshHelper",["RestServices","Utilities","PaginationHelpers"]).factory("Refresh",["ProcessErrors","Rest","Wait","Empty","PageRangeSetup",function(a,b,c,d,e){return function(d){var f=d.scope,g=d.set,h=d.iterator,i=d.url;f.current_url=i,b.setUrl(i),b.get().success(function(a){var b,d;for(e({scope:f,count:a.count,next:a.next,previous:a.previous,iterator:h}),f[h+"Loading"]=!1,b=1;3>=b;b++)d=1===b?"":b,f[h+"HoldInput"+d]=!1;f[g]=a.results,window.scrollTo(0,0),c("stop"),f.$emit("PostRefresh")}).error(function(b,c){f[h+"HoldInput"]=!1,a(f,b,c,null,{hdr:"Error!",msg:"Failed to retrieve "+g+". GET returned status: "+c})})}}]),angular.module("RelatedSearchHelper",["RestServices","Utilities","RefreshRelatedHelper"]).factory("RelatedSearchInit",["$timeout","Alert","Rest","RefreshRelated","Wait",function(a,b,c,d,e){return function(a){function b(a){var b,c,d,e;for(e in h.related)if("tree"!==h.related[e].type&&(void 0===a||a===h.related[e].iterator)){b=h.related[e].iterator;for(d in h.related[e].fields)if(h.related[e].fields[d].key){f[b+"SearchField"]=d,f[b+"SearchFieldLabel"]=h.related[e].fields[d].label;break}f[b+"SortOrder"]=null,f[b+"SearchType"]="icontains",f[b+"SearchTypeLabel"]="Contains",f[b+"SearchValue"]=null,f[b+"SelectShow"]=!1,f[b+"ShowStartBtn"]=!0,f[b+"HideAllStartBtn"]=!1,c=f[b+"SearchField"],!h.related[e].fields[c].searchType||"boolean"!==h.related[e].fields[c].searchType&&"select"!==h.related[e].fields[c].searchType||(f[b+"SelectShow"]=!0,f[b+"SearchSelectOpts"]=h.fields[c].searchOptions),h.related[e].fields[c].searchType&&"gtzero"===h.related[e].fields[c].searchType&&(f[b+"InputHide"]=!0)}}var c,f=a.scope,g=a.relatedSets,h=a.form;b(),f.resetSearch=function(a){b(a),f.search(a)},f.setSearchField=function(a,b,c){var d,e;for(e in h.related)h.related[e].iterator===a&&(d=h.related[e].fields[b]);f[a+"SearchFieldLabel"]=c,f[a+"SearchField"]=b,f[a+"SearchValue"]="",f[a+"SelectShow"]=!1,f[a+"InputHide"]=!1,f[a+"ShowStartBtn"]=!0,void 0!==d.searchType&&"gtzero"===d.searchType&&(f[a+"InputHide"]=!0,f[a+"ShowStartBtn"]=!1),void 0===d.searchType||"boolean"!==d.searchType&&"select"!==d.searchType||(f[a+"SelectShow"]=!0,f[a+"SearchSelectOpts"]=d.searchOptions),void 0!==d.searchType&&"int"===d.searchType&&(f[a+"SearchType"]="int"),f.search(a)},f.setSearchType=function(a,b,c){f[a+"SearchTypeLabel"]=c,f[a+"SearchType"]=b,f.search(a)},f.startSearch=function(a,b){13===a.keyCode&&f.search(b)},f.search=function(a){e("start"),f[a+"Loading"]=!0,f[a+"HoldInput"]=!0,f[a+"SearchValue"]&&(f[a+"ShowStartBtn"]=!1),"host"===a&&"has_active_failures"===f.hostSearchField&&(f.hostFailureFilter=f.hostSearchSelectValue&&1===f.hostSearchSelectValue.value?!0:!1);var b,i,j,k,l;for(i in g)if(g[i].iterator===a){j=i,k=g[i].url;for(b in h.related[i].fields)h.related[i].fields[b].key&&(l=h.related[i].fields[b].desc?"-"+b:b);break}l=null===f[a+"SortOrder"]?l:f[a+"SortOrder"],c=h.related[j].fields[f[a+"SearchField"]],f[a+"SelectShow"]===!1&&""!==f[a+"SearchValue"]&&void 0!==f[a+"SearchValue"]||f[a+"SelectShow"]&&f[a+"SearchSelectValue"]||c.searchType&&"gtzero"===c.searchType?(f[a+"SearchParams"]=c.sourceModel?c.sourceModel+"__"+c.sourceField+"__":c.searchField?c.searchField+"__":f[a+"SearchField"]+"__",f[a+"SearchParams"]+=!c.searchType||"int"!==c.searchType&&"boolean"!==c.searchType?c.searchType&&"gtzero"===c.searchType?"gt=0":f[a+"SearchType"]+"=":"int=",!c.searchType||"boolean"!==c.searchType&&"select"!==c.searchType?(void 0===c.searchType||"gtzero"===c.searchType)&&(f[a+"SearchParams"]+=encodeURI(f[a+"SearchValue"])):f[a+"SearchParams"]+=f[a+"SearchSelectValue"].value,f[a+"SearchParams"]+=l?"&order_by="+encodeURI(l):""):f[a+"SearchParams"]=l?"order_by="+encodeURI(l):"",f[a+"Page"]=0,k+=k.match(/\/$/)?"?":"&",k+=f[a+"SearchParams"],k+=f[a+"PageSize"]?"&page_size="+f[a+"PageSize"]:"",d({scope:f,set:j,iterator:a,url:k})},f.sort=function(a,b){var c,d,e,g;$("."+a+" .list-header").each(function(){if($(this).attr("id")!==a+"-"+b+"-header"){var c=$(this).find("i");c.attr("class","icon-sort")}}),d=$("#"+a+"-"+b+"-header i"),e="",d.hasClass("icon-sort")?(d.removeClass("icon-sort"),d.addClass("icon-sort-up")):d.hasClass("icon-sort-up")?(d.removeClass("icon-sort-up"),d.addClass("icon-sort-down"),e="-"):d.hasClass("icon-sort-down")&&(d.removeClass("icon-sort-down"),d.addClass("icon-sort-up"));for(g in h.related)h.related[g].iterator===a&&(c=h.related[g].fields[b].sourceModel?e+h.related[g].fields[b].sourceModel+"__"+h.related[g].fields[b].sourceField:e+b);f[a+"SortOrder"]=c,f.search(a)}}}]),angular.module("SearchHelper",["RestServices","Utilities","RefreshHelper"]).factory("SearchInit",["Alert","Rest","Refresh","$location","GetBasePath","Empty","$timeout","Wait","Store",function(a,b,c,d,e,f,g,h,i){return function(a){function b(a){var b,c,d,e;e=void 0===a||1===a?"":a,l[p+"SearchField"+e]="",l[p+"SearchFieldLabel"+e]="";for(c in o.fields)if((void 0===o.fields[c].searchWidget&&1===a||o.fields[c].searchWidget===a)&&o.fields[c].key){o.fields[c].sourceModel?(d=o.fields[c].sourceModel+"__"+o.fields[c].sourceField,r=o.fields[c].desc?"-"+d:d):r=o.fields[c].desc?"-"+c:c,(void 0===o.fields[c].searchable||o.fields[c].searchable===!0)&&(l[p+"SearchField"+e]=c,l[p+"SearchFieldLabel"+e]=o.fields[c].label);break}if(f(l[p+"SearchField"+e]))for(c in o.fields)if((void 0===o.fields[c].searchWidget&&1===a||o.fields[c].searchWidget===a)&&(void 0===o.fields[c].searchable||o.fields[c].searchable===!0)){l[p+"SearchField"+e]=c,l[p+"SearchFieldLabel"+e]=o.fields[c].label;break}l[p+"SearchType"+e]="icontains",l[p+"SearchTypeLabel"+e]="Contains",l[p+"SearchParams"+e]="",l[p+"SearchValue"+e]="",l[p+"SelectShow"+e]=!1,l[p+"HideSearchType"+e]=!1,l[p+"InputDisable"+e]=!1,l[p+"ExtraParms"+e]="",l[p+"ShowStartBtn"+e]=!0,l[p+"HideAllStartBtn"+e]=!1,l[p+"SearchPlaceholder"+e]=o.fields[l[p+"SearchField"+e]]&&o.fields[l[p+"SearchField"+e]].searchPlaceholder?l[o.fields[l[p+"SearchField"+e]].searchPlaceholder]?l[o.fields[l[p+"SearchField"+e]].searchPlaceholder]:o.fields[l[p+"SearchField"+e]].searchPlaceholder:"Search",l[p+"InputDisable"+e]=o.fields[l[p+"SearchField"+e]]&&"all"===o.fields[l[p+"SearchField"+e]].searchObject?!0:!1,b=l[p+"SearchField"+e],o.fields[b]&&(!o.fields[b].searchType||"boolean"!==o.fields[b].searchType&&"select"!==o.fields[b].searchType||(l[p+"SelectShow"+e]=!0,l[p+"SearchSelectOpts"+e]=o.fields[b].searchOptions),o.fields[b].searchType&&"int"===o.fields[b].searchType&&(l[p+"HideSearchType"+e]=!0),o.fields[b].searchType&&"gtzero"===o.fields[b].searchType&&(l[p+"InputHide"+e]=!0))}var e,g,j,k,l=a.scope,m=a.set,n=a.url,o=a.list,p=a.iterator?a.iterator:o.iterator,q=a.setWidgets===!1?!1:!0,r=a.sort_order||"";if(q)for(e=o.searchWidgets?o.searchWidgets:1,g=1;e>=g;g++)j=1===g?"":g,$("#search-widget-container"+j)&&b(g);k={set:m,defaultUrl:n,list:o,iterator:p,sort_order:r},i("CurrentSearchParams",k),l.setSearchField=function(a,b,c,d){var e=void 0===d||1===d?"":d;l[a+"SearchFieldLabel"+e]=c,l[a+"SearchField"+e]=b,l[a+"SearchValue"+e]="",l[a+"SelectShow"+e]=!1,l[a+"HideSearchType"+e]=!1,l[a+"InputHide"+e]=!1,l[a+"SearchType"+e]="icontains",l[a+"InputDisable"+e]="all"===o.fields[b].searchObject?!0:!1,l[a+"ShowStartBtn"+e]=!0,l[a+"SearchPlaceholder"+e]=o.fields[l[a+"SearchField"+e]]&&o.fields[l[a+"SearchField"+e]].searchPlaceholder?l[o.fields[l[a+"SearchField"+e]].searchPlaceholder]?l[o.fields[l[a+"SearchField"+e]].searchPlaceholder]:o.fields[l[a+"SearchField"+e]].searchPlaceholder:"Search",o.fields[b].searchType&&"gtzero"===o.fields[b].searchType?(l[a+"InputDisable"+e]=!0,l[a+"ShowStartBtn"+e]=!1,l.search(a)):o.fields[b].searchSingleValue?(l[a+"InputDisable"+e]=!0,l[a+"SearchValue"+e]=o.fields[b].searchValue,l[a+"SearchSelectValue"+e]="boolean"===o.fields[b].searchType&&"true"===o.fields[b].searchValue?{value:1}:"boolean"===o.fields[b].searchType&&"false"===o.fields[b].searchValue?{value:0}:{value:o.fields[b].searchValue},l[a+"ShowStartBtn"+e]=!1):"in"===o.fields[b].searchType?(l[a+"SearchType"+e]="in",l[a+"SearchValue"+e]=o.fields[b].searchValue,l[a+"InputDisable"+e]=!0,l[a+"ShowStartBtn"+e]=!1):!o.fields[b].searchType||"boolean"!==o.fields[b].searchType&&"select"!==o.fields[b].searchType&&"select_or"!==o.fields[b].searchType?o.fields[b].searchType&&"int"===o.fields[b].searchType?l[a+"SearchType"+e]="int":o.fields[b].searchType&&"isnull"===o.fields[b].searchType&&(l[a+"SearchType"+e]="isnull",l[a+"InputDisable"+e]=!0,l[a+"SearchValue"+e]="true",l[a+"ShowStartBtn"+e]=!1):(l[a+"SelectShow"+e]=!0,l[a+"SearchSelectOpts"+e]=o.fields[b].searchOptions),l.search(a)},l.resetSearch=function(a){var c,e=o.searchWidgets?o.searchWidgets:1;for(c=1;e>=c;c++)b(c);window.location="/#"+d.path(),l.search(a)},l.removeDoSearch&&l.removeDoSearch(),l.removeDoSearch=l.$on("doSearch",function(a,b,d,e){l[b+"Loading"]=void 0===e||e===!0?!0:!1;var f,g=n;l[b+"Page"]=d?parseInt(d)-1:0,l[b+"SearchParams"]&&(g+=/\/$/.test(g)?"?"+l[b+"SearchParams"]:"&"+l[b+"SearchParams"]),f=/\/$/.test(g)?"?":"&",g+=l[b+"_page_size"]?f+"page_size="+l[b+"_page_size"]:"",d&&(f=/\/$/.test(g)?"?":"&",g+=f+"page="+d),l[b+"ExtraParms"]&&(f=/\/$/.test(g)?"?":"&",g+=f+l[b+"ExtraParms"]),g=g.replace(/\&\&/,"&"),c({scope:l,set:m,iterator:b,url:g})}),l.removePrepareSearch&&l.removePrepareSearch(),l.removePrepareSearch=l.$on("prepareSearch",function(a,b,c,d,e){h("start"),l[b+"SearchParams"]="";var f,g,i=o.searchWidgets?o.searchWidgets:1;for(f=1;i>=f;f++)g=1===f?"":f,$("#search-widget-container"+g)&&o.fields[l[b+"SearchField"+g]]&&o.fields[l[b+"SearchField"+g]].searchObject&&("all"!==o.fields[l[b+"SearchField"+g]].searchObject?(l[b+"HideAllStartBtn"+g]=!1,l[b+"SearchValue"+g]?(l[b+"ShowStartBtn"+g]=!1,l[b+"SearchParams"]+=o.fields[l[b+"SearchField"+g]].searchOnID?"&"+o.fields[l[b+"SearchField"+g]].searchObject+"__id="+l[b+"SearchValue"+g]:"&"+o.fields[l[b+"SearchField"+g]].searchObject+"__name__icontains="+l[b+"SearchValue"+g]):(l[b+"ShowStartBtn"+g]=!0,l[b+"SearchParams"]+="&"+o.fields[l[b+"SearchField"+g]].searchField+"="+o.fields[l[b+"SearchField"+g]].searchObject)):l[b+"HideAllStartBtn"+g]=!0);l.$emit("prepareSearch2",b,c,d,e)}),l.removePrepareSearch2&&l.removePrepareSearch2(),l.removePrepareSearch2=l.$on("prepareSearch2",function(a,b,c,d,e){var g,h,i=o.searchWidgets?o.searchWidgets:1;for(g=1;i>=g;g++)h=1===g?"":g,l[b+"HoldInput"+h]=!0,$("#search-widget-container"+h)&&o.fields[l[b+"SearchField"+h]]&&!o.fields[l[b+"SearchField"+h]].searchObject&&(l[b+"ShowStartBtn"+h]=l[b+"SearchValue"+h]?!1:!0,(!l[b+"SelectShow"+h]&&!f(l[b+"SearchValue"+h])||l[b+"SelectShow"+h]&&l[b+"SearchSelectValue"+h]||o.fields[l[b+"SearchField"+h]]&&"gtzero"===o.fields[l[b+"SearchField"+h]].searchType)&&(l[b+"SearchParams"]+=o.fields[l[b+"SearchField"+h]].searchField?"&"+o.fields[l[b+"SearchField"+h]].searchField+"__":o.fields[l[b+"SearchField"+h]].sourceModel?"&"+o.fields[l[b+"SearchField"+h]].sourceModel+"__"+o.fields[l[b+"SearchField"+h]].sourceField+"__":"select"!==o.fields[l[b+"SearchField"+h]].searchType||""!==l[b+"SearchSelectValue"+h].value&&null!==l[b+"SearchSelectValue"+h].value?"&"+l[b+"SearchField"+h]+"__":"&"+l[b+"SearchField"+h]+"__",l[b+"SearchParams"]+=!o.fields[l[b+"SearchField"+h]].searchType||"int"!==o.fields[l[b+"SearchField"+h]].searchType&&"boolean"!==o.fields[l[b+"SearchField"+h]].searchType?o.fields[l[b+"SearchField"+h]].searchType&&"gtzero"===o.fields[l[b+"SearchField"+h]].searchType?"gt=0":"select"!==o.fields[l[b+"SearchField"+h]].searchType||""!==l[b+"SearchSelectValue"+h].value&&null!==l[b+"SearchSelectValue"+h].value?l[b+"SearchType"+h]+"=":"iexact=":"int=",!o.fields[l[b+"SearchField"+h]].searchType||"boolean"!==o.fields[l[b+"SearchField"+h]].searchType&&"select"!==o.fields[l[b+"SearchField"+h]].searchType?(!o.fields[l[b+"SearchField"+h]].searchType||o.fields[l[b+"SearchField"+h]].searchType&&"or"!==o.fields[l[b+"SearchField"+h]].searchType&&"gtzero"!==o.fields[l[b+"SearchField"+h]].searchType)&&(l[b+"SearchParams"]+=encodeURI(l[b+"SearchValue"+h])):l[b+"SearchParams"]+=l[b+"SearchSelectValue"+h].value));("inventory"===b&&l.inventoryFailureFilter||"host"===b&&l.hostFailureFilter)&&(l[b+"SearchParams"]+="&has_active_failures=true"),r&&(l[b+"SearchParams"]+=l[b+"SearchParams"]?"&":"",l[b+"SearchParams"]+="order_by="+encodeURI(r)),l.$emit("doSearch",b,c,d,e)}),l.startSearch=function(a,b){13===a.keyCode&&l.search(b)},l.search=function(a,b,c){c=void 0===c?!0:!1,c&&(l[m]=[]),l.$emit("prepareSearch",a,b,c)},l.sort=function(a){$(".list-header").each(function(){if($(this).attr("id")!==a+"-header"){var b=$(this).find("i");b.attr("class","fa fa-sort")}});var b=$("#"+a+"-header i"),c="";b.hasClass("fa-sort")?(b.removeClass("fa-sort"),b.addClass("fa-sort-up")):b.hasClass("fa-sort-up")?(b.removeClass("fa-sort-up"),b.addClass("fa-sort-down"),c="-"):b.hasClass("fa-sort-down")&&(b.removeClass("fa-sort-down"),b.addClass("fa-sort-up")),r=o.fields[a].searchField?c+o.fields[a].searchField:o.fields[a].sortField?c+o.fields[a].sortField:o.fields[a].sourceModel?c+o.fields[a].sourceModel+"__"+o.fields[a].sourceField:c+a,l.search(o.iterator)},l.searchCleanup=function(){l.removeDoSearch(),l.removePrepareSearch(),l.removePrepareSearch2()}}}]),angular.module("TeamHelper",["RestServices","Utilities","OrganizationListDefinition","SearchHelper","PaginationHelpers","ListGenerator"]).factory("SetTeamListeners",["Alert","Rest",function(a,b){return function(a){var c=a.scope,d=a.set,e=a.iterator;c.$on("TeamResultFound",function(a,b,f){var g,h,i,j;if(f.length===b.length){for(i="organization",j="organization_name",g=0;gSelect existing users by clicking each user or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        ",base:"users",index:!0,hover:!0,fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},actions:{},fieldActions:{}}),angular.module("CloudCredentialsListDefinition",[]).value("CloudCredentialList",{name:"cloudcredentials",iterator:"cloudcredential",selectTitle:"Add Cloud Credentials",editTitle:"Cloud Credentials",selectInstructions:"

        Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        Create a brand new credential by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",excludeModal:!1},team:{label:"Team",ngBind:"credential.team_name",sourceModel:"team",sourceField:"name",excludeModal:!0},user:{label:"User",ngBind:"credential.user_username",sourceModel:"user",sourceField:"username",excludeModal:!0}},actions:{add:{mode:"all",ngClick:"addCredential()","class":"btn-sm",awToolTip:"Create a new credential"}},fieldActions:{edit:{ngClick:"editCredential(credential.id)",icon:"fa-edit",label:"Edit","class":"btn-sm",awToolTip:"Edit credential",dataPlacement:"top"},"delete":{ngClick:"deleteCredential(credential.id, credential.name)",icon:"fa-trash-o",label:"Delete","class":"btn-sm",awToolTip:"Delete credential",dataPlacement:"top"}}}),angular.module("CredentialsListDefinition",[]).value("CredentialList",{name:"credentials",iterator:"credential",selectTitle:"Add Credentials",editTitle:"Credentials",selectInstructions:"

        Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        Create a brand new credential by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",excludeModal:!1},kind:{label:"Type",searchType:"select",searchOptions:[],excludeModal:!0,nosort:!0}},actions:{add:{mode:"all",ngClick:"addCredential()",awToolTip:"Create a new credential"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{ngClick:"editCredential(credential.id)",icon:"fa-edit",label:"Edit","class":"btn-sm",awToolTip:"Edit credential",dataPlacement:"top"},"delete":{ngClick:"deleteCredential(credential.id, credential.name)",icon:"fa-trash",label:"Delete","class":"btn-sm",awToolTip:"Delete credential",dataPlacement:"top"}}}),angular.module("GroupListDefinition",[]).value("GroupList",{name:"groups",iterator:"group",selectTitle:"Copy Groups",editTitle:"Groups",index:!0,well:!1,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{help:{awPopOver:"Choose groups by clicking on each group you wish to add. Click the Select button to add the groups to the selected inventory group.",dataContainer:"#form-modal .modal-content",mode:"all",awToolTip:"Click for help",dataTitle:"Adding Groups"}},fieldActions:{edit:{label:"Edit",ngClick:"editGroup(group.id)",icon:"icon-edit","class":"btn-xs",awToolTip:"Edit group",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteGroup(group.id, group.name)",icon:"icon-trash","class":"btn-xs",awToolTip:"Delete group",dataPlacement:"top"}}}),angular.module("HomeGroupListDefinition",[]).value("HomeGroupList",{name:"home_groups",iterator:"group",editTitle:"Groups",index:!0,hover:!0,well:!0,fields:{name:{key:!0,label:"Group",ngClick:"editGroup(group.id, group.inventory)",columnClass:"col-lg-4 col-md3 col-sm-3 col-xs-6 ellipsis"},inventory_name:{label:"Inventory",sourceModel:"inventory",sourceField:"name",columnClass:"col-lg-3 col-md2 col-sm-2 hidden-xs elllipsis",linkTo:"{{ /#/inventories/' + group.inventory + '/' }}"},source:{label:"Source",searchType:"select",searchOptions:[{name:"ec2",value:"ec2"},{name:"none",value:""},{name:"rax",value:"rax"}],sourceModel:"inventory_source",sourceField:"source",searchOnly:!0},has_external_source:{label:"Has external source?",searchType:"in",searchValue:"ec2,rax",searchOnly:!0,sourceModel:"inventory_source",sourceField:"source"},has_active_failures:{label:"Has failed hosts?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},last_update_failed:{label:"Update failed?",searchType:"select",searchSingleValue:!0,searchValue:"failed",searchOnly:!0,sourceModel:"inventory_source",sourceField:"status"},id:{label:"ID",searchOnly:!0}},fieldActions:{sync_status:{mode:"all",ngClick:"viewUpdateStatus(group.id, group.group_id)",awToolTip:"{{ group.status_tooltip }}",ngClass:"group.status_class",dataPlacement:"top"},failed_hosts:{mode:"all",awToolTip:"{{ group.hosts_status_tip }}",dataPlacement:"top",ngHref:"/#/inventories/{{ group.inventory }}/",iconClass:"{{ 'fa icon-failures-' + group.hosts_status_class }}"},group_update:{mode:"all",ngClick:"updateGroup(group.id)",awToolTip:"{{ group.launch_tooltip }}",ngShow:"(group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",ngClass:"group.launch_class",dataPlacement:"top"},cancel:{mode:"all",ngClick:"cancelUpdate(group.id)",awToolTip:"Cancel sync process","class":"red-txt",ngShow:"(group.status == 'running' || group.status == 'pending' || group.status == 'updating')",dataPlacement:"top"},edit:{label:"Edit",mode:"all",ngClick:"editGroup(group.id)",awToolTip:"Edit group",dataPlacement:"top"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("HomeHostListDefinition",[]).value("HomeHostList",{name:"hosts",iterator:"host",selectTitle:"Add Existing Hosts",editTitle:"Hosts",index:!0,hover:!0,well:!0,fields:{name:{key:!0,label:"Name",columnClass:"col-lg-4 col-md3 col-sm-3 col-xs-7 ellipsis",ngClick:"editHost(host.id, host.name)"},inventory_name:{label:"Inventory",sourceModel:"inventory",sourceField:"name",columnClass:"col-lg-3 col-md2 col-sm-2 hidden-xs elllipsis",linkTo:"{{ '/#/inventories/' + host.inventory }}"},enabled:{label:"Disabled?",searchSingleValue:!0,searchType:"boolean",searchValue:"false",searchOnly:!0},has_active_failures:{label:"Has failed jobs?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},has_inventory_sources:{label:"Has external source?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},id:{label:"ID",searchOnly:!0}},fieldActions:{enabled_flag:{iconClass:"{{ 'fa icon-enabled-' + host.enabled }}",dataPlacement:"top",awToolTip:"{{ host.enabledToolTip }}",dataTipWatch:"host.enabledToolTip",ngClick:"toggleHostEnabled(host.id, host.has_inventory_sources)"},active_failures:{awPopOver:"{{ host.job_status_html }}",dataTitle:"{{ host.job_status_title }}",awToolTip:"{{ host.badgeToolTip }}",awTipPlacement:"top",dataPlacement:"left",iconClass:"{{ 'fa icon-failures-' + host.has_active_failures }}"},edit:{label:"Edit",ngClick:"editHost(host.id)",icon:"icon-edit",awToolTip:"Edit host",dataPlacement:"top"}},actions:{stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("HostListDefinition",[]).value("HostList",{name:"hosts",iterator:"host",selectTitle:"Add Existing Hosts",editTitle:"Hosts",index:!0,well:!1,fields:{name:{key:!0,label:"Host Name",linkTo:"/inventories/{{ inventory_id }}/hosts/{{ host.id }}"},description:{label:"Description"}},actions:{help:{awPopOver:"Select hosts by clicking on each host you wish to add. Add the selected hosts to the group by clicking the Select button.",dataContainer:"#form-modal .modal-content",mode:"all",awToolTip:"Click for help",dataTitle:"Selecting Hosts"}},fieldActions:{edit:{label:"Edit",ngClick:"editHost({{ host.id }})",icon:"icon-edit","class":"btn-xs",awToolTip:"Edit host",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteHost(host.id, host.name)",icon:"icon-trash","class":"btn-xs",awToolTip:"Delete host",dataPlacement:"top"}}}),angular.module("InventoriesListDefinition",[]).value("InventoryList",{name:"inventories",iterator:"inventory",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},organization:{label:"Organization",ngBind:"inventory.summary_fields.organization.name",linkTo:"/#/organizations/{{ inventory.organization }}",sourceModel:"organization",sourceField:"name",excludeModal:!0},has_inventory_sources:{label:"Cloud sourced?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},has_active_failures:{label:"Failed hosts?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0},inventory_sources_with_failures:{label:"Sync failures?",searchType:"gtzero",searchValue:"true",searchOnly:!0}},actions:{add:{mode:"all",ngClick:"addInventory()",awToolTip:"Create a new inventory"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",icon:"icon-comments-alt",mode:"all"}},fieldActions:{status:{ngHref:"inventory.status_link",iconClass:"{{ 'fa fa-cloud icon-cloud-' + inventory.status_class }}",awToolTip:"{{ inventory.status_tip }}",dataPlacement:"top"},failed_hosts:{ngHref:"inventory.failed_hosts_link",iconClass:"{{ 'fa icon-failures-' + inventory.failed_hosts_class }}",awToolTip:"{{ inventory.failed_hosts_tip }}",dataPlacement:"top"},edit:{label:"Edit",ngClick:"editInventoryProperties(inventory.id)",awToolTip:"Edit inventory",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteInventory(inventory.id, inventory.names')",awToolTip:"Delete inventory",dataPlacement:"top"}}}),angular.module("InventoryGroupsDefinition",[]).value("InventoryGroups",{name:"groups",iterator:"group",editTitle:"{{ inventory_name }}",showTitle:!1,well:!0,index:!1,hover:!1,hasChildren:!0,filterBy:"{ show: true }","class":"table-condensed table-no-border",fields:{name:{label:"Groups",key:!0,ngClick:"showHosts(group.id,group.group_id, false)",ngClass:"group.selected_class",hasChildren:!0,columnClass:"col-lg-9 col-md-9 col-sm-7 col-xs-7",nosort:!0,awDroppable:"{{ group.isDroppable }}",awDraggable:"{{ group.isDraggable }}",dataContainment:"#groups_table",dataTreeId:"{{ group.id }}",dataGroupId:"{{ group.group_id }}",dataType:"group"}},actions:{columnClass:"col-lg-3 col-md-3 col-sm-5 col-xs-5",create:{mode:"all",ngClick:"createGroup()",awToolTip:"Create a new group"},properties:{mode:"all",awToolTip:"Edit inventory properties",ngClick:"editInventoryProperties()"},refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refreshGroups()"},stream:{ngClick:"showGroupActivity()",awToolTip:"View Activity Stream",mode:"all"},help:{mode:"all",awToolTip:"Get help building your inventory",ngClick:"showGroupHelp()",id:"inventory-summary-help"}},fieldActions:{sync_status:{mode:"all",ngClick:"viewUpdateStatus(group.id, group.group_id)",ngShow:"group.id > 1",awToolTip:"{{ group.status_tooltip }}",dataTipWatch:"group.launch_tooltip",ngClass:"group.status_class",dataPlacement:"top"},failed_hosts:{mode:"all",awToolTip:"{{ group.hosts_status_tip }}",ngShow:"group.id > 1",dataPlacement:"top",ngClick:"showHosts(group.id, group.group_id, group.show_failures)",iconClass:"{{ 'fa icon-failures-' + group.hosts_status_class }}"},group_update:{mode:"all",ngClick:"updateGroup(group.id)",awToolTip:"{{ group.launch_tooltip }}",dataTipWatch:"group.launch_tooltip",ngShow:"group.id > 1 && (group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",ngClass:"group.launch_class",dataPlacement:"top"},cancel:{mode:"all",ngClick:"cancelUpdate({{ group.id }})",awToolTip:"Cancel sync process","class":"red-txt",ngShow:"group.id > 1 && (group.status == 'running' || group.status == 'pending' || group.status == 'updating')",dataPlacement:"top"},edit:{mode:"all",ngClick:"editGroup({{ group.group_id + ',' + group.id }})",awToolTip:"Edit group",ngShow:"group.id > 1",dataPlacement:"top"},"delete":{mode:"all",ngClick:"deleteGroup({{ group.id + ',' + group.group_id }})",awToolTip:"Delete group",ngShow:"group.id != 1",dataPlacement:"top"}}}),angular.module("InventoryHostsDefinition",[]).value("InventoryHosts",{name:"hosts",iterator:"host",editTitle:"{{ selected_group }}",showTitle:!1,well:!0,index:!1,hover:!1,hasChildren:!0,"class":"table-condensed table-no-border",fields:{name:{key:!0,label:"Hosts",ngClick:"editHost(host.id)",searchPlaceholder:"search_place_holder",columnClass:"col-lg-9 col-md-9 col-sm-7 col-xs-7",dataHostId:"{{ host.id }}",dataType:"host",awDraggable:"true"},enabled:{label:"Disabled?",searchSingleValue:!0,searchType:"boolean",searchValue:"false",searchOnly:!0},has_active_failures:{label:"Failed jobs?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0}},fieldActions:{enabled_flag:{iconClass:"{{ 'fa icon-enabled-' + host.enabled }}",dataPlacement:"top",awToolTip:"{{ host.enabledToolTip }}",dataTipWatch:"host.enabledToolTip",ngClick:"toggleHostEnabled(host.id, host.has_inventory_sources)"},active_failures:{awPopOver:"{{ host.job_status_html }}",dataTitle:"{{ host.job_status_title }}",awToolTip:"{{ host.badgeToolTip }}",awTipPlacement:"top",dataPlacement:"left",iconClass:"{{ 'fa icon-failures-' + host.has_active_failures }}"},edit:{ngClick:"editHost(host.id)",icon:"icon-edit",awToolTip:"Edit host",dataPlacement:"top"},"delete":{ngClick:"deleteHost(host.id, host.name)",icon:"icon-trash",awToolTip:"Delete host",dataPlacement:"top"}},actions:{columnClass:"col-lg-3 col-md-3 col-sm-5 col-xs-5",create:{mode:"all",ngClick:"createHost()",ngHide:"selected_tree_id == 1",awToolTip:"Create a new host"},stream:{ngClick:"showHostActivity()",awToolTip:"View Activity Stream",mode:"all"}}}),angular.module("JobEventsListDefinition",[]).value("JobEventList",{name:"jobevents",iterator:"jobevent",editTitle:"Job Events",index:!1,hover:!0,hasChildren:!0,filterBy:"{ show: true }",navigationLinks:{details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",active:!0,icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",icon:"icon-laptop"}},fields:{created:{label:"Created On",columnClass:"col-lg-1 col-md-1 hidden-sm hidden-xs",key:!0,nosort:!0,searchable:!1,link:!1},status:{label:"Status",showValue:!1,columnClass:"col-sm-1 col-xs-2 text-center",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}],nosort:!0,searchable:!1,ngClick:"viewJobEvent({{ jobevent.id }})",awToolTip:"{{ jobevent.statusBadgeToolTip }}",dataPlacement:"top",badgeIcon:"fa icon-job-{{ jobevent.status }}",badgePlacement:"left",badgeToolTip:"{{ jobevent.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgClick:"viewJobEvent({{ jobevent.id }})"},event_display:{label:"Event",hasChildren:!0,ngClick:"toggleChildren(jobevent.id, jobevent.related.children)",nosort:!0,searchable:!1,ngClass:"{{ jobevent.class }}",appendHTML:"jobevent.event_detail"},host:{label:"Host",ngBind:"jobevent.summary_fields.host.name",ngHref:"{{ jobevent.hostLink }}",searchField:"hosts__name",nosort:!0,searchOnly:!1,id:"job-event-host-header","class":"break",columnClass:"col-lg-2 hidden-sm hidden-xs"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"}},fieldActions:{columnClass:"col-sm-1 col-xs-2",view:{label:"View",ngClick:"viewJobEvent(jobevent.id)",awToolTip:"View event details",dataPlacement:"top"}}}),angular.module("JobHostDefinition",[]).value("JobHostList",{name:"jobhosts",iterator:"jobhost",editTitle:"All summaries",index:!0,hover:!0,navigationLinks:{ngHide:"host_id !== null",details:{href:"/#/jobs/{{ job_id }}",label:"Status",icon:"icon-zoom-in",ngShow:"job_id !== null"},events:{href:"/#/jobs/{{ job_id }}/job_events",label:"Events",icon:"icon-list-ul"},hosts:{href:"/#/jobs/{{ job_id }}/job_host_summaries",label:"Host Summary",active:!0,icon:"icon-laptop"}},fields:{job:{label:"Job ID",ngClick:"showJob(jobhost.job)",columnShow:"host_id !== null",key:!0,desc:!0},host:{label:"Host",key:!0,sourceModel:"host",sourceField:"name",ngBind:"jobhost.host_name",ngHref:"jobhost.hostLinkTo"},status:{label:"Status",badgeNgHref:"{{ jobhost.statusLinkTo }}",badgeIcon:"fa icon-job-{{ jobhost.status }}",badgePlacement:"left",badgeToolTip:"{{ jobhost.statusBadgeToolTip }}",badgeTipPlacement:"top",ngHref:"{{ jobhost.statusLinkTo }}",awToolTip:"{{ jobhost.statusBadgeToolTip }}",dataPlacement:"top",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}]},failed:{label:"Job failed?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0,nosort:!0},ok:{label:"Success",searchable:!1},changed:{label:"Changed",searchable:!1},failures:{label:"Failure",searchable:!0,searchLabel:"Contains failed events?",searchType:"gtzero"},dark:{label:"Unreachable",searchable:!0,searchType:"gtzero",searchLabel:"Contains unreachable hosts?"},skipped:{label:"Skipped",searchable:!1}},actions:{help:{awPopOver:"
        \n
        Success
        Tasks successfully executed on the host.
        \n
        Changed
        Actions taken on the host.
        \n
        Failure
        Tasks that failed on the host.
        \n
        Unreachable
        Times the ansible server could not reach the host.
        \n
        Skipped
        Tasks bypassed and not performed on the host due to prior task failure or the host being unreachable.
        \n
        \n",dataPlacement:"left",dataContainer:"body",mode:"all","class":"btn-xs btn-help",awToolTip:"Click for help",dataTitle:"Job Host Summary",id:"jobhost-help-button"},refresh:{mode:"all","class":"btn-xs",awToolTip:"Refresh the page",ngClick:"refresh()",ngShow:"host_id == null"}},fieldActions:{}}),angular.module("JobTemplatesListDefinition",[]).value("JobTemplateList",{name:"job_templates",iterator:"job_template",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{mode:"all",ngClick:"addJobTemplate()",basePaths:["job_templates"],awToolTip:"Create a new template"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",icon:"icon-comments-alt",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editJobTemplate(job_template.id)",icon:"icon-edit",awToolTip:"Edit template","class":"btn-default btn-xs",dataPlacement:"top"},submit:{label:"Launch",icon:"icon-rocket",mode:"all","class":"btn-xs btn-success",ngClick:"submitJob(job_template.id)",awToolTip:"Start a job using this template",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteJobTemplate(job_template.id, job_template.name)",icon:"icon-trash","class":"btn-danger btn-xs",awToolTip:"Delete template",dataPlacement:"top"}}}),angular.module("JobsListDefinition",[]).value("JobList",{name:"jobs",iterator:"job",editTitle:"Jobs",index:!1,hover:!0,"class":"jobs-table",fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},inventory:{label:"Inventory ID",searchType:"int",searchOnly:!0},created:{label:"Create On",link:!1,searchable:!1},job_template:{label:"Job Template",ngBind:"job.summary_fields.job_template.name",ngHref:"{{ '/#/job_templates/' + job.job_template }}",sourceModel:"job_template",sourceField:"name"},failed:{label:"Job failed?",searchSingleValue:!0,searchType:"boolean",searchValue:"true",searchOnly:!0,nosort:!0},status:{label:"Status","class":"job-{{ job.status }}",searchType:"select",linkTo:"{{ job.statusLinkTo }}",searchOptions:[{name:"new",value:"new"},{name:"waiting",value:"waiting"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",value:"failed"},{name:"canceled",value:"canceled"}],badgeIcon:"fa icon-job-{{ job.status }}",badgePlacement:"left",badgeToolTip:"{{ job.statusBadgeToolTip }}",badgeTipPlacement:"top",badgeNgHref:"{{ job.statusLinkTo }}",awToolTip:"{{ job.statusBadgeToolTip }}",dataPlacement:"top"}},actions:{refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"}},fieldActions:{submit:{label:"Relaunch",icon:"icon-rocket",mode:"all",ngClick:"submitJob(job.id, job.summary_fields.job_template.name)",awToolTip:"Start the job",dataPlacement:"top"},cancel:{label:"Stop",mode:"all",ngClick:"deleteJob(job.id)",awToolTip:"Cancel a running or pending job",ngShow:"job.status == 'pending' || job.status == 'running' || job.status == 'waiting'",dataPlacement:"top"},"delete":{label:"Delete",mode:"all",ngClick:"deleteJob(job.id)",awToolTip:"Delete the job",ngShow:"job.status != 'pending' && job.status != 'running' && job.status != 'waiting'",dataPlacement:"top"},dropdown:{type:"DropDown",label:"View",icon:"fa-search-plus","class":"btn-default btn-xs",options:[{ngClick:"editJob(job.id, job.summary_fields.job_template.name)",label:"Status"},{ngClick:"viewEvents(job.id, job.summary_fields.job_template.name)",label:"Events",ngHide:"job.status == 'new'"},{ngClick:"viewSummary(job.id, job.summary_fields.job_template.name)",label:"Host Summary",ngHide:"job.status == 'new'"}]}}}),angular.module("OrganizationListDefinition",[]).value("OrganizationList",{name:"organizations",iterator:"organization",selectTitle:"Add Organizations",editTitle:"Organizations",hover:!0,index:!1,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{mode:"all",ngClick:"addOrganization()",awToolTip:"Create a new organization"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{}}),angular.module("PermissionListDefinition",[]).value("PermissionList",{name:"permissions",iterator:"permission",selectTitle:"Add Permission",selectInstructions:'Click on a row to select it, and click Finished when done. Use the green button to create a new row.',editTitle:"Permissions",index:!0,well:!0,fields:{name:{key:!0,label:"Name",ngClick:"editPermission(permission.id)"},inventory:{label:"Inventory",sourceModel:"inventory",sourceField:"name",ngBind:"permission.summary_fields.inventory.name"},project:{label:"Project",sourceModel:"project",sourceField:"name",ngBind:"permission.summary_fields.project.name"},permission_type:{label:"Permission"}},actions:{add:{mode:"all",ngClick:"addPermission()",awToolTip:"Add a new permission",ngShow:"PermissionAddAllowed"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editPermission(permission.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit permission",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deletePermission(permission.id, permission.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete permission",ngShow:"PermissionAddAllowed",dataPlacement:"top"}}}),angular.module("ProjectsListDefinition",[]).value("ProjectList",{name:"projects",iterator:"project",selectTitle:"Add Project",editTitle:"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 brand new project by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description",columnClass:"hidden-sm hidden-xs",excludeModal:!0},scm_type:{label:"Type",searchType:"select",searchOptions:[],excludeModal:!0,nosort:!0},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:[],excludeModal:!0},last_updated:{label:"Last Updated",type:"date",excludeModal:!0,searchable:!1}},actions:{add:{mode:"all",ngClick:"addProject()",awToolTip:"Create a new project"},help:{awPopOver:"
        \n
        Updating
        A source control update is in progress.
        \n
        Never Updated
        This project has not yet been updated from source control.
        \n
        Failed
        An error occurred during the most recent source control update, click the status text for more information.
        \n
        Successful
        TThe latest source control update completed successfully.
        \n
        Missing
        The previously configured local project directory is missing.
        \n
        N/A
        The project is not linked to source control, so updates are not applicable.
        \n
        \n",dataPlacement:"left",dataContainer:"body",mode:"all",awToolTip:"Click for help",awTipPlacement:"top"},refresh:{mode:"all",awToolTip:"Refresh the page",ngClick:"refresh()"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editProject(project.id)",awToolTip:"Edit project properties",dataPlacement:"top"},scm_update:{label:"Update",ngClick:"SCMUpdate(project.id)",awToolTip:"{{ project.scm_update_tooltip }}",ngClass:"project.scm_type_class",dataPlacement:"top"},cancel:{label:"Stop",ngClick:"cancelUpdate(project.id, project.name)",awToolTip:"Cancel a running SCM update process",ngShow:"project.status == 'updating'",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteProject(project.id, project.name)",awToolTip:"Permanently remove project from the database",ngShow:"project.status !== 'updating'",dataPlacement:"top"}}}),angular.module("StreamListDefinition",[]).value("StreamList",{name:"activities",iterator:"activity",editTitle:"Activity Stream",selectInstructions:"",index:!1,hover:!0,"class":"table-condensed",searchWidgets:3,fields:{timestamp:{label:"Event Time",key:!0,desc:!0,noLink:!0,searchable:!1},user:{label:"Initiated by",ngBindHtml:"activity.user",sourceModel:"actor",sourceField:"username",searchPlaceholder:"Username",searchWidget:1},description:{label:"Action",ngBindHtml:"activity.description",nosort:!0,searchable:!1,columnClass:"col-lg-7"},system_event:{label:"System event",searchOnly:!0,searchType:"isnull",sourceModel:"actor",sourceField:"username",searchWidget:1},all_objects:{label:"All",searchOnly:!0,searchObject:"all",searchPlaceholder:"All resources",searchWidget:2},credential_search:{label:"Credential",searchOnly:!0,searchObject:"credential",searchPlaceholder:"Credential name",searchWidget:2,searchField:"object1"},group_search:{label:"Group",searchOnly:!0,searchObject:"group",searchPlaceholder:"Group name",searchWidget:2,searchField:"object1"},host_search:{label:"Host",searchOnly:!0,searchObject:"host",searchPlaceholder:"Host name",searchWidget:2,searchField:"object1"},inventory_search:{label:"Inventory",searchOnly:!0,searchObject:"inventory",searchPlaceholder:"Inventory name",searchWidget:2,searchField:"object1"},job_template_search:{label:"Job Template",searchOnly:!0,searchObject:"job_template",searchPlaceholder:"Job template name",searchWidget:2,searchField:"object1"},job_search:{label:"Job",searchOnly:!0,searchObject:"job",searchPlaceholder:"Job id",searchOnID:!0,searchWidget:2,searchField:"object1"},organization_search:{label:"Organization",searchOnly:!0,searchObject:"organization",searchPlaceholder:"Organization name",searchWidget:2,searchField:"object1"},project_search:{label:"Project",searchOnly:!0,searchObject:"project",searchPlaceholder:"Project name",searchWidget:2,searchField:"object1"},user_search:{label:"User",searchOnly:!0,searchObject:"user",searchPlaceholder:"Primary username",searchWidget:2,searchField:"object1"},all_objects3:{label:"All",searchOnly:!0,searchObject:"all",searchPlaceholder:"All related resources",searchWidget:3,searchField:"object2"},credential_search3:{label:"Credential",searchOnly:!0,searchObject:"credential",searchPlaceholder:"Related credential name",searchWidget:3,searchField:"object2"},group_search3:{label:"Group",searchOnly:!0,searchObject:"group",searchPlaceholder:"Related group name",searchWidget:3,searchField:"object2"},host_search3:{label:"Host",searchOnly:!0,searchObject:"host",searchPlaceholder:"Related host name",searchWidget:3,searchField:"object2"},inventory_search3:{label:"Inventory",searchOnly:!0,searchObject:"inventory",searchPlaceholder:"Related inventory name",searchWidget:3,searchField:"object2"},job_search3:{label:"Job",searchOnly:!0,searchObject:"job",searchPlaceholder:"Job id",searchOnID:!0,searchWidget:3,searchField:"object2"},job_template_search3:{label:"Job Template",searchOnly:!0,searchObject:"job_template",searchPlaceholder:"Related job template name",searchWidget:3,searchField:"object2"},organization_search3:{label:"Organization",searchOnly:!0,searchObject:"organization",searchPlaceholder:"Related organization name",searchWidget:3,searchField:"object2"},project_search3:{label:"Project",searchOnly:!0,searchObject:"project",searchPlaceholder:"Related project name",searchWidget:3,searchField:"object2"},user_search3:{label:"User",searchOnly:!0,searchObject:"user",searchPlaceholder:"Related username",searchWidget:3,searchField:"object2"}},actions:{refresh:{mode:"all","class":"btn-xs",awToolTip:"Refresh the page",ngClick:"refreshStream()"},close:{mode:"all",awToolTip:"Close Activity Stream view",ngClick:"closeStream()"}},fieldActions:{view:{label:"View",ngClick:"showDetail(activity.id)",icon:"fa-zoom-in","class":"btn-default btn-xs",awToolTip:"View event details",dataPlacement:"top"}}}),angular.module("TeamsListDefinition",[]).value("TeamList",{name:"teams",iterator:"team",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:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"},organization:{label:"Organization",ngBind:"team.organization_name",sourceModel:"organization",sourceField:"name"}},actions:{add:{mode:"all",ngClick:"addTeam()",awToolTip:"Create a new team"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editTeam(team.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit team",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteTeam(team.id, team.name)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete team",dataPlacement:"top"}}}),angular.module("UserListDefinition",[]).value("UserList",{name:"users",iterator:"user",selectTitle:"Add Users",editTitle:"Users",selectInstructions:"

        Select existing users by clicking each user or checking the related checkbox. When finished, click the blue Select button, located bottom right.

        When available, a brand new user can be created by clicking the green Create New button.

        ",index:!0,hover:!0,fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},actions:{add:{label:"Create New",mode:"all",ngClick:"addUser()",basePaths:["organizations","users"],"class":"btn-xs",awToolTip:"Create a new user"},stream:{ngClick:"showActivity()",awToolTip:"View Activity Stream",mode:"all"}},fieldActions:{edit:{label:"Edit",ngClick:"editUser(user.id)",icon:"icon-edit","class":"btn-xs btn-default",awToolTip:"Edit user",dataPlacement:"top"},"delete":{label:"Delete",ngClick:"deleteUser(user.id, user.username)",icon:"icon-trash","class":"btn-xs btn-danger",awToolTip:"Delete user",dataPlacement:"top"}}}),angular.module("InventorySyncStatusWidget",["RestServices","Utilities"]).factory("InventorySyncStatus",["$rootScope","$compile",function(a,b){return function(a){function c(a){var b=a.label,c=a.count,d=a.fail,e=a.link,f=a.fail_link,g="\n"; +return g+='\n",g+=''+d+"",g+="\n",g+='',g+=''+c+"",g+="\n"}var d,e,f,g,h,i=a.scope,j=a.target,k=a.dashboard;if(d='
        \n',d+='
        Inventory Sync Status
        \n',d+='
        \n',d+='\n',d+="\n",d+="\n",d+='\n',d+='\n',d+='\n',d+="\n",d+="\n",d+="\n",d+=c({label:"Inventories",count:k.inventories&&k.inventories.total_with_inventory_source?k.inventories.total_with_inventory_source:0,fail:k.inventories&&k.inventories.inventory_failed?k.inventories.inventory_failed:0,link:"/#/inventories/?has_inventory_sources=true",fail_link:"/#/inventories/?inventory_sources_with_failures=true"}),e=0,f=0,k.inventory_sources)for(h in k.inventory_sources)e+=k.inventory_sources[h].total?k.inventory_sources[h].total:0,f+=k.inventory_sources[h].failed?k.inventory_sources[h].failed:0;d+=c({label:"Groups",count:e,fail:f,link:"/#/home/groups/?has_external_source=true",fail_link:"/#/home/groups/?status=failed"});for(h in k.inventory_sources)k.inventory_sources[h].total&&(d+=c({label:k.inventory_sources[h].label,count:k.inventory_sources[h].total?k.inventory_sources[h].total:0,fail:k.inventory_sources[h].failed?k.inventory_sources[h].failed:0,link:"/#/home/groups/?source="+h,fail_link:"/#/home/groups/?status=failed&source="+h}));d+="\n",d+="
        FailedTotal
        \n",d+="
        \n",d+="
        \n",d+="\n",g=angular.element(document.getElementById(j)),g.html(d),b(g)(i),i.$emit("WidgetLoaded")}}]),angular.module("JobStatusWidget",["RestServices","Utilities"]).factory("JobStatus",["$rootScope","$compile","Rest","GetBasePath","ProcessErrors","Wait",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.fail_link,f=a.count,g=a.fail;return b+="\n",b+='\n",b+=''+g+"",b+="\n",b+='',b+=''+f+"",b+="\n"}var d,e=a.scope,f=a.target,g=a.dashboard,h="";h='
        \n',h+='
        Job Status
        \n',h+='
        \n',h+='\n',h+="\n",h+="\n",h+='\n',h+='\n',h+='\n',h+="\n",h+="\n",h+="\n",h+=c({label:"Jobs",link:"/#/jobs",count:g.jobs&&g.jobs.total?g.jobs.total:0,fail:g.jobs&&g.jobs.failed?g.jobs.failed:0,fail_link:"/#/jobs/?status=failed"}),h+=c({label:"Inventories",link:"/#/inventories",count:g.inventories&&g.inventories.total?g.inventories.total:0,fail:g.inventories&&g.inventories.job_failed?g.inventories.job_failed:0,fail_link:"/#/inventories/?has_active_failures=true"}),h+=c({label:"Groups",link:"/#/home/groups",count:g.groups&&g.groups.total?g.groups.total:0,fail:g.groups&&g.groups.job_failed?g.groups.job_failed:0,fail_link:"/#/home/groups/?has_active_failures=true"}),h+=c({label:"Hosts",link:"/#/home/hosts",count:g.hosts&&g.hosts.total?g.hosts.total:0,fail:g.hosts&&g.hosts.failed?g.hosts.failed:0,fail_link:"/#/home/hosts/?has_active_failures=true"}),h+="\n",h+="
        FailedTotal
        \n",h+="
        \n",h+="
        \n",h+="\n",d=angular.element(document.getElementById(f)),d.html(h),b(d)(e),e.$emit("WidgetLoaded")}}]),angular.module("ObjectCountWidget",["RestServices","Utilities"]).factory("ObjectCount",["$rootScope","$compile","Rest","GetBasePath","ProcessErrors","Wait",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.count;return b+="\n",b+='\n",b+='',b+=''+e+"",b+="\n"}var d,e,f,g=a.scope,h=a.target,i=a.dashboard,j=["organizations","users","teams","credentials","projects","inventories","groups","hosts","job_templates","jobs"];for(e='
        \n',e+='
        System Summary
        \n',e+='
        \n',e+='\n',e+="\n",e+="\n",e+='\n',e+='\n',e+="\n",e+="\n",e+="\n",d=0;d\n",e+="
        Total
        \n",e+="
        \n",e+="
        \n",f=angular.element(document.getElementById(h)),f.html(e),b(f)(g),g.$emit("WidgetLoaded")}}]),angular.module("SCMSyncStatusWidget",["RestServices","Utilities"]).factory("SCMSyncStatus",["$rootScope","$compile",function(a,b){return function(a){function c(a){var b="",c=a.label,d=a.link,e=a.fail_link,f=a.count,g=a.fail;return b+="\n",b+=''+c+"\n",b+=''+g+"",b+="\n",b+='',b+=''+f+"",b+="\n"}var d,e,f,g,h,i,j=a.scope,k=a.target,l=a.dashboard;if(e='
        \n',e+='
        Project SCM Status
        \n',e+='
        \n',e+='\n',e+="\n",e+="\n",e+='\n',e+='\n',e+='\n',e+="\n",e+="\n",e+="\n",f=0,l.scm_types)for(h in l.scm_types)f+=l.scm_types[h].total?l.scm_types[h].total:0;e+=c({label:"Projects",link:"/#/projects",count:f,fail:l.projects&&l.projects.failed?l.projects.failed:0,fail_link:"/#/projects/?status=failed"}),i=[];for(h in l.scm_types)i.push(h);for(i.sort(),d=0;d\n",e+="
        FailedTotal
        \n",e+="
        \n",e+="
        \n",e+="\n",g=angular.element(document.getElementById(k)),g.html(e),b(g)(j),j.$emit("WidgetLoaded")}}]),angular.module("StreamWidget",["RestServices","Utilities","StreamListDefinition","SearchHelper","PaginationHelpers","RefreshHelper","ListGenerator","StreamWidget","AuthService"]).factory("setStreamHeight",[function(){return function(){var a=$("#stream-content").height(),b=parseInt($("#tab-content-container").css("min-height").replace(/px/,"")),c=a>b?a:b;$("#tab-content-container").css({"min-height":c})}}]).factory("ShowStream",["setStreamHeight","Authorization",function(a){return function(){var b=$("#stream-container");b.css({position:"absolute",top:0,left:0,width:"100%","min-height":"100%","background-color":"#FFF"}),a(),b.show("slide",{direction:"left"},{duration:500,queue:!1})}}]).factory("HideStream",["LoadBreadCrumbs",function(a){return function(){var b=$("#stream-container");b.hide("slide",{direction:"left"},{duration:500,queue:!1}),setTimeout(function(){b.detach(),b.empty(),b.unbind(),$("#tab-content-container").css({"min-height":0})},500),a()}}]).factory("StreamBreadCrumbs",["$rootScope","$location",function(a,b){return function(){a.breadcrumbs=[];var c,d,e,f,g=b.path().split("/");for(g.splice(0,1),e=0;e=f;f++)c+="/"+g[f];for(f=0;f0)for(f=0;e>=f;f++)c+="/"+g[f];else c="/"+g[e];d=g[e],d=d.charAt(0).toUpperCase()+d.slice(1)}a.breadcrumbs.push({path:c,title:d})}}}]).factory("FixUrl",[function(){return function(a){return a.replace(/\/api\/v1\//,"/#/")}}]).factory("BuildUrl",[function(){return function(a){var b="/#/";switch(a.base){case"group":case"host":b+="home/"+a.base+"s/?id="+a.id;break;case"inventory":b+="inventories/"+a.id+"/";break;default:b+=a.base+"s/"+a.id+"/"}return b}}]).factory("BuildDescription",["FixUrl","BuildUrl",function(a,b){return function(a){function c(a){return a.replace(/^_deleted_\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d+:\d+_/,"")}var d,e,f,g,h,i,j,k;d=a.operation,d+=/e$/.test(a.operation)?"d ":"ed ",e=d,f=a.object1,g=a.object2,h=a.summary_fields[f]?a.summary_fields[f][0]:null,i=f===g?a.summary_fields[f][1]:a.summary_fields[g]?a.summary_fields[g][0]:null,("user"===f||"user"===g)&&(a.summary_fields.user[0].name=a.summary_fields.user[0].username),i&&i.name&&!/^_delete/.test(i.name)?(i.base=g,d+=g+' '+i.name+""+("disassociate"===a.operation?" from ":" to "),e+=g+" "+i.name+("disassociate"===a.operation?" from ":" to ")):g&&(j="",i&&i.name&&(j=" "+c(i.name)),d+=g+j+("disassociate"===a.operation?" from ":" to "),e+=g+j+("disassociate"===a.operation?" from ":" to ")),h&&h.name&&!/^\_delete/.test(h.name)?(h.base=f,d+=f+' '+h.name+"",e+=f+" "+h.name):f&&(j="",k="",!h||!h.name||h&&h.name&&/^_delete/.test(h.name)?a.changes&&a.changes.name?"string"==typeof a.changes.name?(j=" "+a.changes.name,k=j):"object"==typeof a.changes.name&&Array.isArray(a.changes.name)&&(j=" "+a.changes.name[0],k=j):"job"===f&&h&&a.changes&&a.changes.job_template?"delete"!==a.operation?(h.base=f,j=' '+h.id+" "+a.changes.job_template+"",k=" "+h.id+" "+a.changes.job_template):(j=" "+h.id+" "+a.changes.job_template,k=j):"job"===f&&h&&("delete"!==a.operation?(h.base=f,j=' '+h.id+"",k=" "+h.id):(j=" "+h.id,k=j)):h&&h.name&&(j=" "+c(h.name),k=j),d+=f+j,e+=f+k),a.description=d,a.description_nolink=e}}]).factory("ShowDetail",["$rootScope","Rest","Alert","GenerateForm","ProcessErrors","GetBasePath","FormatDate","ActivityDetailForm","Empty","Find",function(a,b,c,d,e,f,g,h,i,j){return function(a){var b,c,e,f=a.activity_id,i=a.scope,k=d,l=h,m=j({list:i.activities,key:"id",val:f});m&&(m.changes_stringified=JSON.stringify(m.changes,null," "),b=m.changes_stringified.match(/\n/g),c=b?b.length:1,c=1>c?3:10,l.fields.changes.rows=10,e=k.inject(l,{mode:"edit",modal:!0,related:!1}),e.changes=m.changes_stringified,e.user=(m.summary_fields.actor?m.summary_fields.actor.username:"system")+" on "+g(new Date(m.timestamps)),e.operation=m.description_nolink,e.formModalAction=function(){$("#form-modal").modal("hide")},$("#form-modal").on("show.bs.modal",function(){$("#form-modal-body").css({width:"auto",height:"auto","max-height":"100%"})}),e.formModalActionLabel="OK",e.formModalCancelShow=!1,e.formModalInfo=!1,e.formModalHeader="Event "+m.id,e.$$phase||e.$digest())}}]).factory("Stream",["$rootScope","$location","Rest","GetBasePath","ProcessErrors","Wait","StreamList","SearchInit","PaginateInit","GenerateList","FormatDate","ShowStream","HideStream","BuildDescription","FixUrl","BuildUrl","ShowDetail","StreamBreadCrumbs","setStreamHeight","Find","Store",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){return function(c){var e,f,o,v,w=g,x=d("activity_stream"),y=j,z=b.path().replace(/^\//,"").split("/")[0],A=c.scope,B=u("CurrentSearchParams"),C=c&&c.inventory_name?c.inventory_name:null,D=c&&c.url?c.url:null;a.flashMessage=null,D?x=D:"/home"!==b.path()&&(e="inventories"===z?"inventory":z.replace(/s$/,""),f=b.path().split("/"),f.splice(0,1),f.length>1&&/^\d+/.test(f[f.length-1])?(e=f[f.length-2],e="inventories"===e?"inventory":e.replace(/s$/,""),x+="?"+e+"__id="+f[f.length-1]):f.length>1?(e=f[f.length-1],e="inventories"===e?"inventory":e.replace(/s$/,""),x+="?or__object1="+e+"&or__object2="+e):x+="?or__object1="+e+"&or__object2="+e),$("#tab-content-container").append('
        '),r(),C&&(o=t({list:a.breadcrumbs,key:"title",val:"{{ inventory_name }}"}),o&&(o.title=C)),l(),v=y.inject(w,{mode:"edit",id:"stream-content",searchSize:"col-lg-3",secondWidget:!0,activityStream:!0}),v.streamTitle=c&&c.title?c.title:null,v.closeStream=function(a){m(),v.searchCleanup&&v.searchCleanup(),B&&h({scope:A,set:B.set,list:B.list,url:B.defaultUrl,iterator:B.iterator,sort_order:B.sort_order,setWidgets:!1}),a&&b.path(a)},v.refreshStream=function(){v.search(w.iterator)},v.showDetail=function(a){q({scope:v,activity_id:a})},v.removeStreamPostRefresh&&v.removeStreamPostRefresh(),v.removeStreamPostRefresh=v.$on("PostRefresh",function(){var a,b,c,d,e,f;for(a=0;a'+v.activities[a].summary_fields.actor.username+"":"system",d=/^\_delete/,e=v.activities[a].object1,f=v.activities[a].object2,e&&v.activities[a].summary_fields[e]&&v.activities[a].summary_fields[e].name?d.test(v.activities[a].summary_fields[e].name)?v.activities[a].objects=v.activities[a].summary_fields[e].name:(c=p(v.activities[a].summary_fields.object1),v.activities[a].objects=''+v.activities[a].summary_fields[e].name+""):v.activities[a].object1&&(v.activities[a].objects=v.activities[a].object1),f&&v.activities[a].summary_fields[f]&&v.activities[a].summary_fields[f].name?d.test(v.activities[a].summary_fields.object2.name)?v.activities[a].objects+=","+v.activities[a].summary_fields[f].name:(c=p(v.activities[a].summary_fields.object2),v.activities[a].objects+=', '+v.activities[a].summary_fields[f].name+""):v.activities[a].object2&&(v.activities[a].objects+=", "+v.activities[a].object2),n(v.activities[a]);setTimeout(function(){s()},500)}),h({scope:v,set:w.name,list:w,url:x}),i({scope:v,list:w,url:x}),v.search(w.iterator)}}]),angular.module("AuthService",["ngCookies","Utilities"]).factory("Authorization",["$http","$rootScope","$location","$cookieStore","GetBasePath",function(a,b,c,d,e){return{setToken:function(a,c){d.remove("token"),d.remove("token_expires"),d.remove("userLoggedIn"),d.put("token",a),d.put("token_expires",c),d.put("userLoggedIn",!0),d.put("sessionExpired",!1),b.token=a,b.userLoggedIn=!0,b.token_expires=c,b.sessionExpired=!1},isUserLoggedIn:function(){return void 0===b.userLoggedIn&&(b.userLoggedIn=d.get("userLoggedIn"),b.sessionExpired=d.get("sessionExpired")),b.userLoggedIn},getToken:function(){return b.token?b.token:d.get("token")},retrieveToken:function(b,c){return a({method:"POST",url:e("authtoken"),data:{username:b,password:c}})},logout:function(){var a=angular.element(document.getElementById("main-view")).scope();a.$destroy(),b.$destroy(),d.remove("accordions"),d.remove("token"),d.remove("token_expires"),d.remove("current_user"),d.remove("lastPath"),d.put("userLoggedIn",!1),d.put("sessionExpired",!1),d.remove("lastPath","/home"),b.current_user={},b.license_tested=void 0,b.userLoggedIn=!1,b.sessionExpired=!1,b.token=null,b.token_expires=null,b.lastPath="/home"},getLicense:function(){return a({method:"GET",url:e("config"),headers:{Authorization:"Token "+this.getToken()}})},setLicense:function(a){a.tested=!1,d.put("license",a)},licenseTested:function(){var a,c;return void 0!==b.license_tested?c=b.license_tested:(a=d.get("license"),c=a&&void 0!==a.tested?a.tested:!1),c},getUser:function(){return a({method:"GET",url:"/api/v1/me/",headers:{Authorization:"Token "+this.getToken()}})},setUserInfo:function(a){b.current_user=a.results[0],d.put("current_user",a.results[0])},restoreUserInfo:function(){b.current_user=d.get("current_user")},getUserInfo:function(a){var c;return b.current_user?b.current_user[a]:(this.restoreUserInfo(),c=d.get("current_user"),c[a])}}}]),angular.module("InventoryTree",["Utilities","RestServices","GroupsHelper","PromptDialog"]).factory("SortNodes",[function(){return function(a){var b,c,d=[],e=[];for(b=0;b0?!0:!1,has_inventory_sources:s[e].has_inventory_sources,id:r,source:s[e].summary_fields.inventory_source.source,group_id:s[e].id,event_level:c,children:i,ngicon:s[e].children.length>0?"fa fa-minus-square-o node-toggle":"fa fa-square-o node-no-toggle",ngclick:"toggle("+r+")",related:{children:s[e].children.length>0?s[e].related.children:"",inventory_source:s[e].related.inventory_source},status:s[e].summary_fields.inventory_source.status,status_class:k["class"],status_tooltip:k.tooltip,launch_tooltip:k.launch_tip,launch_class:k.launch_class,hosts_status_tip:n.tooltip,show_failures:n.failures,hosts_status_class:n["class"],selected_class:"",show:!0,isDraggable:!0,isDroppable:!0},q.push(o),p&&o.group_id===p&&(m.selected_tree_id=r,m.selected_group_id=o.group_id),s[e].children.length>0&&j(s[e].children,r,c+1)}}function k(){e("start"),a.setUrl(b("inventory")+l+"/"),a.get().success(function(a){m.$emit("buildAllGroups",a.name,a.related.tree,a.related.groups)}).error(function(a,b){e("stop"),c(m,a,b,null,{hdr:"Error!",msg:"Failed to get inventory: "+l+". GET returned: "+b})})}var l=h.inventory_id,m=h.scope,n=h.refresh,o=h.emit,p=h.new_group_id,q=[],r=1;m.buildAllGroupsRemove&&m.buildAllGroupsRemove(),m.buildAllGroupsRemove=m.$on("buildAllGroups",function(b,d,f){a.setUrl(f),a.get().success(function(a){i(a),j(a,0,0),m.autoShowGroupHelp=0===a.length?!0:!1,n?(m.groups=q,m.$emit("GroupTreeRefreshed",d,q,o)):m.$emit("GroupTreeLoaded",d,q,o)}).error(function(a,b){e("stop"),c(m,a,b,null,{hdr:"Error!",msg:"Failed to get inventory tree for: "+l+". GET returned: "+b})})}),k()}}]).factory("UpdateGroup",["ApplyEllipsis","GetSyncStatusMsg","Empty",function(a,b,c){return function(d){var e,f,g,h,i,j=d.scope,k=d.group_id,l=d.properties;for(e=0;e\n',m+='\n",m+="\n",i=angular.element(document.getElementById("inventory-modal-container")),i.empty().append(m),a(i)(j),$("#copy-prompt-modal").modal({backdrop:"static",keyboard:!0,show:!0}),j.moveGroup=function(){var a,b,i;$("#copy-prompt-modal").modal("hide"),e("start"),j.removeGroupRemove&&j.removeGroupRemove(),j.removeGroupRemove=j.$on("removeGroup",function(){l.parent>0?(i=d({list:j.groups,key:"id",val:l.parent}),a=h("base")+"groups/"+i.group_id+"/children/",f.setUrl(a),f.post({id:l.group_id,disassociate:1}).success(function(){j.$emit("GroupDeleteCompleted")}).error(function(a,b){e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to remove "+l.name+" from "+i.name+". POST returned status: "+b})})):j.$emit("GroupDeleteCompleted")}),a=g(k.group_id)?h("inventory")+j.inventory_id+"/groups/":h("base")+"groups/"+k.group_id+"/children/",b={id:l.group_id,name:l.name,description:l.description,inventory:j.inventory_id},f.setUrl(a),f.post(b).success(function(){j.$emit("removeGroup")}).error(function(a,b){var d=g(k.group_id)?"inventory":k.name;e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+d+". POST returned status: "+b})})},j.copyGroup=function(){$("#copy-prompt-modal").modal("hide"),e("start");var a=g(k.group_id)?h("inventory")+j.inventory_id+"/groups/":h("base")+"groups/"+k.group_id+"/children/",b={id:l.group_id,name:l.name,description:l.description,inventory:j.inventory_id};f.setUrl(a),f.post(b).success(function(){j.$emit("GroupDeleteCompleted")}).error(function(a,b){var d=g(k.group_id)?"inventory":k.name;e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+d+". POST returned status: "+b})})}}}]).factory("CopyMoveHost",["$compile","Alert","ProcessErrors","Find","Wait","Rest","Empty","GetBasePath",function(a,b,c,d,e,f,g,h){return function(b){var g,i,j=b.scope,k=d({list:j.groups,key:"id",val:b.target_tree_id}),l=d({list:j.hosts,key:"id",val:b.host_id}),m=!1,n="";if(l.summary_fields.all_groups)for(i=0;i\n',n+='\n",n+="\n",n+="\n",g=angular.element(document.getElementById("inventory-modal-container")),g.empty().append(n),a(g)(j),$("#copy-alert-modal").modal({backdrop:"static",keyboard:!0,show:!0})):(n="",n+='\n",g=angular.element(document.getElementById("inventory-modal-container")),g.empty().append(n),a(g)(j),$("#copy-prompt-modal").modal({backdrop:"static",keyboard:!0,show:!0}),j.copyHost=function(){$("#copy-prompt-modal").modal("hide"),e("start"),f.setUrl(h("groups")+k.group_id+"/hosts/"),f.post(l).success(function(){j.$emit("GroupTreeRefreshed")}).error(function(a,b){e("stop"),c(j,a,b,null,{hdr:"Error!",msg:"Failed to add "+l.name+" to "+k.name+". POST returned status: "+b})})})}}]),angular.module("RestServices",["ngCookies","AuthService"]).factory("Rest",["$http","$rootScope","$cookieStore","$q","Authorization",function(a,b,c,d,e){return{headers:{},setUrl:function(a){this.url=a},checkExpired:function(){return b.sessionTimer.isExpired()},pReplace:function(){var a,b;for(a in this.params)b=new RegExp("\\:"+a,"gm"),b.test(this.url)&&(this.url=this.url.replace(b,this.params[a]),delete this.params[a])},createResponse:function(a,b){var c=d.reject({data:a,status:b});return c.success=function(a){return c.then(function(b){a(b.data,b.status)},null),c},c.error=function(a){return c.then(null,function(b){a(b.data,b.status)}),c},c},setHeader:function(a){for(var b in a)this.headers[b]=a[b]},get:function(b){b=b?b:{},this.params=b.params?b.params:null,this.pReplace();var c=this.checkExpired(),d=e.getToken();return c?this.createResponse({detail:"Token is expired"},401):d?(this.setHeader({Authorization:"Token "+d}),this.setHeader({"X-Auth-Token":"Token "+d}),a({method:"GET",url:this.url,headers:this.headers,params:this.params})):this.createResponse({detail:"Invalid token"},401)},post:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"POST",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},put:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"PUT",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},destroy:function(b){var c=e.getToken(),d=this.checkExpired();return d?this.createResponse({detail:"Token is expired"},401):c?(this.setHeader({Authorization:"Token "+c}),this.setHeader({"X-Auth-Token":"Token "+c}),a({method:"DELETE",url:this.url,headers:this.headers,data:b})):this.createResponse({detail:"Invalid token"},401)},options:function(){var b=e.getToken(),c=this.checkExpired();return c?this.createResponse({detail:"Token is expired"},401):b?(this.setHeader({Authorization:"Token "+b}),this.setHeader({"X-Auth-Token":"Token "+b}),a({method:"OPTIONS",url:this.url,headers:this.headers})):this.createResponse({detail:"Invalid token"},401)}}}]),angular.module("TimerService",["ngCookies","Utilities"]).factory("Timer",["$rootScope","$cookieStore","$location","GetBasePath","Empty",function(a,b){return{sessionTime:null,timeout:null,getSessionTime:function(){return this.sessionTime?this.sessionTime:b.get("sessionTime")},isExpired:function(){var a=this.getSessionTime(),b=(new Date).getTime();return 0>=a-b?!0:(this.moveForward(),!1)},expireSession:function(){this.sessionTime=0,a.sessionExpired=!0,b.put("sessionExpired",!0)},moveForward:function(){var c=(new Date).getTime()+1e3*$AnsibleConfig.session_timeout;this.sessionTime=c,b.put("sessionTime",c),a.sessionExpired=!1,b.put("sessionExpired",!1)},init:function(){return this.moveForward(),this}}}]),angular.module("Utilities",["RestServices","Utilities"]).factory("ClearScope",[function(){return function(){$(".tooltip").each(function(){$(this).remove()}),$(".popover").each(function(){$(this).remove()});try{$("#help-modal").dialog("close")}catch(a){}$(window).unbind("resize")}}]).factory("Empty",[function(){return function(a){return null===a||void 0===a||""===a?!0:!1}}]).factory("ToggleClass",function(){return function(a,b){$(a)&&$(a).hasClass(b)?$(a).removeClass(b):$(a)&&$(a).addClass(b)}}).factory("Alert",["$rootScope",function(a){return function(b,c,d,e,f,g){f?(a.alertHeader2=b,a.alertBody2=c,a.alertClass2=d?d:"alert-danger",$("#alert-modal2").modal({show:!0,keyboard:!0,backdrop:"static"}),a.disableButtons2=g?!0:!1,e&&$("#alert-modal2").on("hidden",function(){e()}),$(document).bind("keydown",function(a){27===a.keyCode&&($("#alert-modal2").modal("hide"),e&&e())})):(a.alertHeader=b,a.alertBody=c,a.alertClass=d?d:"alert-danger",$("#alert-modal").modal({show:!0,keyboard:!0,backdrop:"static"}),$(document).bind("keydown",function(a){27===a.keyCode&&($("#alert-modal").modal("hide"),e&&e())}),a.disableButtons=g?!0:!1,e&&$("#alert-modal").on("hidden",function(){e()}))}}]).factory("ProcessErrors",["$rootScope","$cookieStore","$log","$location","Alert","Wait",function(a,b,c,d,e,f){return function(b,c,g,h,i){var j,k,l;if(f("stop"),$AnsibleConfig.debug_mode&&console&&(console.log("Debug status: "+g),console.log("Debug data: "),console.log(c)),403===g)l="The API responded with a 403 Access Denied error. ",l+=c.detail?"Detail: "+c.detail:"Please contact your system administrator.",e(i.hdr,l);else if(401===g&&c.detail&&"Token is expired"===c.detail||401===g&&c.detail&&"Invalid token"===c.detail)a.sessionTimer.expireSession(),d.url("/login");else if(c.non_field_errors)e("Error!",c.non_field_errors);else if(c.detail)e(i.hdr,i.msg+" "+c.detail);else if(c.__all__)e("Error!",c.__all__);else if(h){k=!1;for(j in h.fields)c[j]&&h.fields[j].tab&&$("#"+h.name+'_tabs a[href="#'+h.fields[j].tab+'"]').tab("show"),h.fields[j].realName&&c[h.fields[j].realName]&&(b[j+"_api_error"]=c[h.fields[j]][0],$('[name="'+h.fields[j].realName+'"]').addClass("ng-invalid"),k=!0),h.fields[j].sourceModel?c[j]&&(b[h.fields[j].sourceModel+"_"+h.fields[j].sourceField+"_api_error"]=c[j][0],$('[name="'+h.fields[j].sourceModel+"_"+h.fields[j].sourceField+'"]').addClass("ng-invalid"),k=!0):c[j]&&(b[j+"_api_error"]=c[j][0],$('[name="'+j+'"]').addClass("ng-invalid"),k=!0); +!k&&i&&e(i.hdr,i.msg)}else e(i.hdr,i.msg)}}]).factory("LoadBreadCrumbs",["$rootScope","$routeParams","$location","Empty",function(a,b,c,d){return function(b){function e(a){return a.toUpperCase()}function f(a){return"ies"===a?"y":""}var g,h,i,j,k,l,m,n;if(!d(b)){for(h=!1,j=0;j1)for(j=0;j0&&k[j].match(/\d+/)){for(m=k[j-1],n=m.replace(/(ies$|s$)/,f),n=n.charAt(0).toUpperCase()+n.slice(1),h=!1,i=0;i\n",b+='
        \n',b+='',b+="
        \n",b+='
        '+a.box+"
        ",b+=f&&a.autoOffNotice?'
        \n':""}var h,i,j,k,l=!1;e=a,j=d.story.width?d.story.width:510,k=d.story.height?d.story.height:600,i=$(document).width(),j=j>i?i:j;try{l=$("#help-modal").dialog("isOpen")}catch(m){}l?$("#help-modal").html(g(d.story.steps[e])):(h=[],d.story.steps.length>1&&(h.push({text:"Prev",click:function(a){e-1===0&&$(a.target).button("disable"),e-10&&$(a.target).prev().button("enable"),e+1===d.story.steps.length-1&&$(a.target).button("disable"),b(e+1)}})),h.push({text:"Close",click:function(){$("#help-modal").dialog("close")}}),$("#help-modal").html(g(d.story.steps[e])).dialog({position:{my:"center top",at:"center top+150",of:"body"},title:d.story.hdr,width:j,height:k,buttons:h,closeOnEscape:!0,show:500,hide:500,resizable:!1,close:function(){$("#help-modal").empty()}}),$(".ui-dialog-buttonset button").each(function(){var a,b,c;c=$(this).text(),"Close"===c?(b="fa-times",a="btn btn-default",$(this).attr({"class":a}).html(' Close')):"Prev"===c?(b="fa-chevron-left",a="btn btn-primary",$(this).attr({"class":a}).html(' Prev')):(b="fa-chevron-right",a="btn btn-primary",$(this).attr({"class":a}).html('Next ').css({"margin-right":"20px"}))}),$('.ui-dialog[aria-describedby="help-modal"]').find(".ui-dialog-titlebar button").empty().attr({"class":"close"}).text("x"),$("#auto-off-checkbox").click(function(){$('input[name="auto-off-checkbox"]:checked').length?c("inventoryAutoHelp","off"):c("inventoryAutoHelp","on")}))}var d=a.defn,e=a.step,f=a.autoShow||!1;b(0)}}]).factory("ReturnToCaller",["$location","Empty",function(a,b){return function(c){var d,e=a.path().replace(/^\//,"").split("/"),f="";for(c=b(c)?e.length-1:c+1,d=0;c>d;d++)f+="/"+e[d];a.path(f)}}]).factory("FormatDate",["$filter",function(a){return function(b){return a("date")(b,"MM/dd/yy HH:mm:ss")}}]).factory("Wait",["$rootScope",function(a){return function(b){var c,d,e,f,g,h;"start"!==b||a.waiting?"stop"===b&&a.waiting&&$(".spinny, .overlay").fadeOut(400,function(){a.waiting=!1}):(a.waiting=!0,c=$(window).width(),d=$(window).height(),e=$(".spinny").width(),f=$(".spinny").height(),g=(c-e)/2,h=(d-f)/2,$(".overlay").css({width:$(document).width(),height:$(document).height()}).fadeIn(),$(".spinny").css({top:h,left:g}).fadeIn(400))}}]).factory("HideElement",[function(){return function(a,b){var c=$(a),d=c.css("width"),e=c.css("height"),f=c.position(),g=c.parent(),h=c.css("border-radius"),i=c.css("background-color"),j=c.css("margin"),k=c.css("padding");g.append('
        '),$("#curtain-div").show(0,b)}}]).factory("ShowElement",[function(){return function(){$("#curtain-div").fadeOut(500,function(){$(this).remove()})}}]).factory("GetChoices",["Rest","ProcessErrors",function(a,b){return function(c){var d=c.scope,e=c.url,f=c.field,g=c.variable,h=c.callback,i=c.choice_name;d[g]?d[g].length=0:d[g]=[],a.setUrl(e),a.options().success(function(a){var b,c;for(b=i?a.actions.GET[f][i]:a.actions.GET[f].choices,c=0;c