diff --git a/awx/api/serializers.py b/awx/api/serializers.py index b06fef0a97..cd5e80dac6 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -552,6 +552,10 @@ class BaseSerializer(serializers.ModelSerializer): return ret +class EmptySerializer(serializers.Serializer): + pass + + class BaseFactSerializer(DocumentSerializer): __metaclass__ = BaseSerializerMetaclass @@ -2059,7 +2063,7 @@ class JobLaunchSerializer(BaseSerializer): variables_needed_to_start = serializers.ReadOnlyField() credential_needed_to_start = serializers.SerializerMethodField() survey_enabled = serializers.SerializerMethodField() - extra_vars = VerbatimField(required=False) + extra_vars = VerbatimField(required=False, write_only=True) class Meta: model = JobTemplate @@ -2067,18 +2071,11 @@ class JobLaunchSerializer(BaseSerializer): 'ask_variables_on_launch', 'survey_enabled', 'variables_needed_to_start', 'credential', 'credential_needed_to_start',) read_only_fields = ('ask_variables_on_launch',) - write_only_fields = ('credential', 'extra_vars',) - - def to_representation(self, obj): - res = super(JobLaunchSerializer, self).to_representation(obj) - view = self.context.get('view', None) - if obj and hasattr(view, '_raw_data_form_marker'): - if obj.passwords_needed_to_start: - password_keys = dict([(p, u'') for p in obj.passwords_needed_to_start]) - res.update(password_keys) - if self.get_credential_needed_to_start(obj) is True: - res.update(dict(credential='')) - return res + extra_kwargs = { + 'credential': { + 'write_only': True, + }, + } def get_credential_needed_to_start(self, obj): return not (obj and obj.credential and obj.credential.active) diff --git a/awx/api/views.py b/awx/api/views.py index 8263bfca1d..b08bbf7e58 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1896,6 +1896,21 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView): is_job_start = True always_allow_superuser = False + def update_raw_data(self, data): + obj = self.get_object() + extra_vars = data.get('extra_vars') or {} + if obj: + for p in obj.passwords_needed_to_start: + data[p] = u'' + if obj.credential and obj.credential.active: + data.pop('credential', None) + else: + data['credential'] = None + for v in obj.variables_needed_to_start: + extra_vars.setdefault(v, u'') + data['extra_vars'] = extra_vars + return data + def post(self, request, *args, **kwargs): obj = self.get_object() if not request.user.can_access(self.model, 'start', obj): @@ -1945,7 +1960,7 @@ class JobTemplateSurveySpec(GenericAPIView): model = JobTemplate parent_model = JobTemplate - # FIXME: Add serializer class to define fields in OPTIONS request! + serializer_class = EmptySerializer def get(self, request, *args, **kwargs): obj = self.get_object() @@ -2024,8 +2039,8 @@ class JobTemplateActivityStreamList(SubListAPIView): class JobTemplateCallback(GenericAPIView): model = JobTemplate - # FIXME: Add serializer class to define fields in OPTIONS request! permission_classes = (JobTemplateCallbackPermission,) + serializer_class = EmptySerializer @csrf_exempt @transaction.non_atomic_requests @@ -2207,7 +2222,7 @@ class SystemJobTemplateDetail(RetrieveAPIView): class SystemJobTemplateLaunch(GenericAPIView): model = SystemJobTemplate - # FIXME: Add serializer class to define fields in OPTIONS request! + serializer_class = EmptySerializer def get(self, request, *args, **kwargs): return Response({}) @@ -2278,7 +2293,7 @@ class JobActivityStreamList(SubListAPIView): class JobStart(GenericAPIView): model = Job - # FIXME: Add serializer class to define fields in OPTIONS request! + serializer_class = EmptySerializer is_job_start = True def get(self, request, *args, **kwargs): diff --git a/awx/main/views.py b/awx/main/views.py index 5720405093..a1036a96e6 100644 --- a/awx/main/views.py +++ b/awx/main/views.py @@ -34,7 +34,10 @@ def handle_error(request, status=404, **kwargs): status_code = status default_detail = kwargs['content'] api_error_view = ApiErrorView.as_view(view_name=kwargs['name'], exception_class=APIException) - return api_error_view(request) + response = api_error_view(request) + if hasattr(response, 'render'): + response.render() + return response else: kwargs['content'] = format_html('{}', kwargs.get('content', '')) return render(request, 'error.html', kwargs, status=status) diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index ec58ca474f..06d924b141 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -697,11 +697,23 @@ legend { margin-bottom: 7px; } - .pagination > li > a { + .pagination>li>a, + .pagination>li>span { + border: 1px solid @grey-border; padding: 3px 6px; font-size: 10px; } + .pagination li { + a#next-page { + border-radius: 0 4px 4px 0; + } + + a#previous-page { + border-radius: 4px 0 0 4px; + } + } + .modal-body { .pagination { margin-top: 15px; diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 0556f7e1cd..4e78e5c0bd 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -141,6 +141,28 @@ padding-right: 50px; } +.Form-subForm { + width: 100%; + border-left: 5px solid @default-border; + margin-left: -20px; + padding-left: 15px; + margin-bottom: 15px; + + .Form-formGroup { + float: left; + } +} + +.Form-subForm--title { + font-weight: bold; + text-transform: uppercase; + color: @default-interface-txt; + font-size: small; + width: 100%; + float: left; + margin-bottom: 10px; +} + .Form-textAreaLabel{ width:100%; } @@ -364,6 +386,16 @@ input[type='radio']:checked:before { justify-content: flex-end; } +.Form-button{ + margin-left: 4px; +} + +.Form-buttonDefault { + background-color: @default-bg; + color: @default-interface-txt; + border-color: @default-border; +} + .Form-saveButton{ background-color: @submit-button-bg; margin-right: 20px; diff --git a/awx/ui/client/legacy-styles/jquery-ui-overrides.less b/awx/ui/client/legacy-styles/jquery-ui-overrides.less index c21dadb3c6..c40440bf8a 100644 --- a/awx/ui/client/legacy-styles/jquery-ui-overrides.less +++ b/awx/ui/client/legacy-styles/jquery-ui-overrides.less @@ -14,12 +14,13 @@ table.ui-datepicker-calendar { } /* Modal dialog */ - .ui-dialog-title { - font-size: 22px; - color: @blue-link; + font-size: 15px; + color: @default-interface-txt; font-weight: bold; line-height: normal; + font-family: 'Open Sans', helvetica; + text-transform: uppercase; } .ui-dialog { .close { @@ -33,12 +34,14 @@ table.ui-datepicker-calendar { .ui-widget-header { border-radius: 0; border: none; - border-bottom: 1px solid #A9A9A9; - height: 55px; } .ui-dialog-titlebar { padding-bottom: 0; padding-top: 12px; + + button.close i { + font-size: 24px; + } } .ui-dialog-titlebar .ui-state-default { background-image: none; @@ -58,9 +61,58 @@ table.ui-datepicker-calendar { background-position: -80px -224px; color: @black; } + + button.btn.btn-primary, + button.btn.btn-default { + padding: 5px 15px; + font-size: 12px; + line-height: 1.5; + transition: background-color 0.2s; + font-size: 12px; + } + + button.btn.btn-primary { + text-transform: uppercase; + background-color: @default-succ; + border-color: @default-succ; + + &:hover { + background-color: @default-succ-hov; + border-color: @default-succ-hov; + } + + &:disabled { + background-color: @default-succ-disabled; + border-color: @default-succ-disabled; + } + + &:first-of-type { + margin-right: 24px; + } + } + + button.btn.btn-default { + text-transform: uppercase; + border-color: @default-border; + color: @default-interface-txt; + } + + .ui-dialog-buttonpane.ui-widget-content { + border: none; + margin: 0; + padding-top: 0; + padding-right: 8px; + } + + .input-group-btn.dropdown, .List-pagination, .List-tableHeader { + font-family: 'Open Sans', sans-serif; + } + } .ui-dialog-buttonset { + text-transform: uppercase; + button.btn.btn-default.ui-state-hover, button.btn.btn-default.ui-state-active, button.btn.btn-default.ui-state-focus { diff --git a/awx/ui/client/legacy-styles/lists.less b/awx/ui/client/legacy-styles/lists.less index 020d306dfc..2dcac015c8 100644 --- a/awx/ui/client/legacy-styles/lists.less +++ b/awx/ui/client/legacy-styles/lists.less @@ -101,6 +101,7 @@ table, tbody { margin-left: 15px; } +/* -- Pagination -- */ .List-pagination { margin-top: 20px; font-size: 12px; @@ -244,6 +245,7 @@ table, tbody { padding-left: 15px!important; height: 34px!important; padding-right: 45px!important; + font-family: 'Open Sans', sans-serif; } .List-searchInput:placeholder-shown { diff --git a/awx/ui/client/legacy-styles/main-layout.less b/awx/ui/client/legacy-styles/main-layout.less index 803d554eaf..5b7f8f1c01 100644 --- a/awx/ui/client/legacy-styles/main-layout.less +++ b/awx/ui/client/legacy-styles/main-layout.less @@ -91,6 +91,10 @@ body { margin-top: 20px; } +.btn{ + text-transform: uppercase; +} + @media (max-width: 1075px) { #main-menu-container { diff --git a/awx/ui/client/src/adhoc/adhoc.controller.js b/awx/ui/client/src/adhoc/adhoc.controller.js index 24a289ebe9..cb9e0a648e 100644 --- a/awx/ui/client/src/adhoc/adhoc.controller.js +++ b/awx/ui/client/src/adhoc/adhoc.controller.js @@ -1,5 +1,5 @@ /************************************************* - * Copyright (c) 2015 Ansible, Inc. + * Copyright (c) 2016 Ansible, Inc. * * All Rights Reserved *************************************************/ @@ -10,7 +10,7 @@ * @description This controller controls the adhoc form creation, command launching and navigating to standard out after command has been succesfully ran. */ function adhocController($q, $scope, $rootScope, $location, $stateParams, - CheckPasswords, PromptForPasswords, CreateLaunchDialog, adhocForm, + $state, CheckPasswords, PromptForPasswords, CreateLaunchDialog, adhocForm, GenerateForm, Rest, ProcessErrors, ClearScope, GetBasePath, GetChoices, KindChange, LookUpInit, CredentialList, Empty, Wait) { @@ -162,6 +162,10 @@ function adhocController($q, $scope, $rootScope, $location, $stateParams, privateFn.initializeForm(id, urls, hostPattern); + $scope.formCancel = function(){ + $state.go('inventoryManage'); + } + // remove all data input into the form and reset the form back to defaults $scope.formReset = function () { GenerateForm.reset(); @@ -291,7 +295,7 @@ function adhocController($q, $scope, $rootScope, $location, $stateParams, } export default ['$q', '$scope', '$rootScope', '$location', '$stateParams', - 'CheckPasswords', 'PromptForPasswords', 'CreateLaunchDialog', 'adhocForm', + '$state', 'CheckPasswords', 'PromptForPasswords', 'CreateLaunchDialog', 'adhocForm', 'GenerateForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'GetChoices', 'KindChange', 'LookUpInit', 'CredentialList', 'Empty', 'Wait', adhocController]; diff --git a/awx/ui/client/src/adhoc/adhoc.form.js b/awx/ui/client/src/adhoc/adhoc.form.js index d200d37b47..2632a0e7bb 100644 --- a/awx/ui/client/src/adhoc/adhoc.form.js +++ b/awx/ui/client/src/adhoc/adhoc.form.js @@ -12,7 +12,7 @@ export default function() { return { - editTitle: 'Execute Command', + addTitle: 'Execute Command', name: 'adhoc', well: true, forceListeners: true, @@ -125,13 +125,16 @@ export default function() { buttons: { launch: { - label: 'Launch', + label: 'Save', ngClick: 'launchJob()', - ngDisabled: true + ngDisabled: true, + 'class': 'Form-buttonDefault Form-button' }, reset: { ngClick: 'formReset()', - ngDisabled: true + ngDisabled: true, + label: 'Reset', + 'class': 'Form-buttonDefault Form-button' } }, diff --git a/awx/ui/client/src/adhoc/adhoc.partial.html b/awx/ui/client/src/adhoc/adhoc.partial.html index 7420af3ea9..eb25ec5b56 100644 --- a/awx/ui/client/src/adhoc/adhoc.partial.html +++ b/awx/ui/client/src/adhoc/adhoc.partial.html @@ -1,4 +1,4 @@ -
+
diff --git a/awx/ui/client/src/adhoc/adhoc.route.js b/awx/ui/client/src/adhoc/adhoc.route.js index f5fa7e9639..5e7b47a850 100644 --- a/awx/ui/client/src/adhoc/adhoc.route.js +++ b/awx/ui/client/src/adhoc/adhoc.route.js @@ -7,8 +7,8 @@ import {templateUrl} from '../shared/template-url/template-url.factory'; export default { - route: '/inventories/:inventory_id/adhoc', - name: 'inventoryAdhoc', + route: '/adhoc', + name: 'inventoryManage.adhoc', templateUrl: templateUrl('adhoc/adhoc'), controller: 'adhocController', resolve: { diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 43ad6627fb..6d32be86fd 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -45,6 +45,7 @@ import adhoc from './adhoc/main'; import login from './login/main'; import activityStream from './activity-stream/main'; import standardOut from './standard-out/main'; +import lookUpHelper from './lookup/main'; import {JobTemplatesList, JobTemplatesAdd, JobTemplatesEdit} from './controllers/JobTemplates'; import {LicenseController} from './controllers/License'; import {ScheduleEditController} from './controllers/Schedules'; @@ -234,7 +235,7 @@ var tower = angular.module('Tower', [ }). state('dashboardGroups', { - url: '/home/groups', + url: '/home/groups?id&name&has_active_failures&status&source&has_external_source&inventory_source__id', templateUrl: urlPrefix + 'partials/subhome.html', controller: HomeGroups, ncyBreadcrumb: { @@ -249,7 +250,7 @@ var tower = angular.module('Tower', [ }). state('dashboardHosts', { - url: '/home/hosts?has_active_failures', + url: '/home/hosts?has_active_failures&name&id', templateUrl: urlPrefix + 'partials/subhome.html', controller: HomeHosts, data: { diff --git a/awx/ui/client/src/controllers/Inventories.js b/awx/ui/client/src/controllers/Inventories.js index a506d78ead..916b812976 100644 --- a/awx/ui/client/src/controllers/Inventories.js +++ b/awx/ui/client/src/controllers/Inventories.js @@ -859,7 +859,7 @@ export function InventoriesManage ($log, $scope, $rootScope, $location, } } $rootScope.hostPatterns = host_patterns; - $location.path('/inventories/' + $scope.inventory.id + '/adhoc'); + $state.go('inventoryManage.adhoc'); }; $scope.refreshHostsOnGroupRefresh = false; diff --git a/awx/ui/client/src/forms/Credentials.js b/awx/ui/client/src/forms/Credentials.js index 9921b3a27c..221ab12b22 100644 --- a/awx/ui/client/src/forms/Credentials.js +++ b/awx/ui/client/src/forms/Credentials.js @@ -18,6 +18,9 @@ export default editTitle: '{{ name }}', //Legend in edit mode name: 'credential', forceListeners: true, + subFormTitles: { + credentialSubForm: 'Type Details', + }, actions: { @@ -103,7 +106,8 @@ export default '\n', dataTitle: 'Type', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + hasSubForm: true, // helpCollapse: [{ // hdr: 'Select a Credential Type', // content: '
\n' + @@ -131,7 +135,8 @@ export default init: false }, autocomplete: false, - apiField: 'username' + apiField: 'username', + subForm: 'credentialSubForm', }, secret_key: { label: 'Secret Key', @@ -145,7 +150,8 @@ export default ask: false, clear: false, hasShowInputButton: true, - apiField: 'passwowrd' + apiField: 'passwowrd', + subForm: 'credentialSubForm' }, security_token: { label: 'STS Token', @@ -157,7 +163,8 @@ export default hasShowInputButton: true, dataTitle: 'STS Token', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subForm: 'credentialSubForm' }, "host": { labelBind: 'hostLabel', @@ -172,7 +179,8 @@ export default awRequiredWhen: { variable: 'host_required', init: false - } + }, + subForm: 'credentialSubForm' }, "username": { labelBind: 'usernameLabel', @@ -183,7 +191,8 @@ export default variable: 'username_required', init: false }, - autocomplete: false + autocomplete: false, + subForm: "credentialSubForm" }, "email_address": { labelBind: 'usernameLabel', @@ -197,7 +206,8 @@ export default awPopOver: '

The email address assigned to the Google Compute Engine service account.

', dataTitle: 'Email', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subForm: 'credentialSubForm' }, "subscription_id": { labelBind: "usernameLabel", @@ -213,8 +223,8 @@ export default awPopOver: '

Subscription ID is an Azure construct, which is mapped to a username.

', dataTitle: 'Subscription ID', dataPlacement: 'right', - dataContainer: "body" - + dataContainer: "body", + subForm: 'credentialSubForm' }, "api_key": { label: 'API Key', @@ -228,6 +238,7 @@ export default ask: false, hasShowInputButton: true, clear: false, + subForm: 'credentialSubForm' }, "password": { labelBind: 'passwordLabel', @@ -242,7 +253,8 @@ export default awRequiredWhen: { variable: "password_required", init: false - } + }, + subForm: "credentialSubForm" }, "ssh_password": { label: 'Password', // formally 'SSH Password' @@ -252,7 +264,8 @@ export default editRequired: false, ask: true, hasShowInputButton: true, - autocomplete: false + autocomplete: false, + subForm: 'credentialSubForm' }, "ssh_key_data": { labelBind: 'sshKeyDataLabel', @@ -273,7 +286,8 @@ export default awPopOverWatch: "key_description", dataTitle: 'Help', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subForm: "credentialSubForm" }, "ssh_key_unlock": { label: 'Private Key Passphrase', @@ -285,6 +299,7 @@ export default ask: true, hasShowInputButton: true, askShow: "kind.value == 'ssh'", // Only allow ask for machine credentials + subForm: 'credentialSubForm' }, "become_method": { label: "Privilege Escalation", @@ -297,7 +312,8 @@ export default "This is equivalent to specifying the --become-method=BECOME_METHOD parameter, where BECOME_METHOD could be "+ "sudo | su | pbrun | pfexec | runas
(defaults to sudo)

", dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subForm: 'credentialSubForm' }, "become_username": { label: 'Privilege Escalation Username', @@ -305,7 +321,8 @@ export default ngShow: "kind.value == 'ssh' && (become_method && become_method.value)", addRequired: false, editRequired: false, - autocomplete: false + autocomplete: false, + subForm: 'credentialSubForm' }, "become_password": { label: 'Privilege Escalation Password', @@ -315,7 +332,8 @@ export default editRequired: false, ask: true, hasShowInputButton: true, - autocomplete: false + autocomplete: false, + subForm: 'credentialSubForm' }, "project": { labelBind: 'projectLabel', @@ -331,7 +349,8 @@ export default awRequiredWhen: { variable: 'project_required', init: false - } + }, + subForm: 'credentialSubForm' }, "vault_password": { label: "Vault Password", @@ -341,7 +360,8 @@ export default editRequired: false, ask: true, hasShowInputButton: true, - autocomplete: false + autocomplete: false, + subForm: 'credentialSubForm' } }, diff --git a/awx/ui/client/src/forms/Projects.js b/awx/ui/client/src/forms/Projects.js index 3019bc9a69..dbf04c457f 100644 --- a/awx/ui/client/src/forms/Projects.js +++ b/awx/ui/client/src/forms/Projects.js @@ -19,6 +19,10 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) name: 'project', forceListeners: true, tabs: true, + subFormTitles: { + sourceSubForm: 'Source Details', + }, + fields: { name: { @@ -62,7 +66,8 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) ngOptions: 'type.label for type in scm_type_options track by type.value', ngChange: 'scmChange()', addRequired: true, - editRequired: true + editRequired: true, + hasSubForm: true }, missing_path_alert: { type: 'alertblock', @@ -112,6 +117,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) variable: "scmRequired", init: false }, + subForm: 'sourceSubForm', helpCollapse: [{ hdr: 'GIT URLs', content: '

Example URLs for GIT SCM include:

diff --git a/awx/ui/client/src/management-jobs/main.js b/awx/ui/client/src/management-jobs/main.js index b374b84857..e881baa0fb 100644 --- a/awx/ui/client/src/management-jobs/main.js +++ b/awx/ui/client/src/management-jobs/main.js @@ -1,16 +1,16 @@ /************************************************* - * Copyright (c) 2015 Ansible, Inc. + * Copyright (c) 2016 Ansible, Inc. * * All Rights Reserved *************************************************/ import managementJobsCard from './card/main'; -import managementJobsSchedule from './schedule/main'; +import managementJobsScheduler from './scheduler/main'; import list from './management-jobs.list'; export default angular.module('managementJobs', [ managementJobsCard.name, - managementJobsSchedule.name + managementJobsScheduler.name ]) .factory('managementJobsListObject', list); diff --git a/awx/ui/client/src/management-jobs/schedule/main.js b/awx/ui/client/src/management-jobs/schedule/main.js deleted file mode 100644 index e71036c9d6..0000000000 --- a/awx/ui/client/src/management-jobs/schedule/main.js +++ /dev/null @@ -1,15 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import route from './schedule.route'; -import controller from './schedule.controller'; - -export default - angular.module('managementJobsSchedule', []) - .controller('managementJobsScheduleController', controller) - .run(['$stateExtender', function($stateExtender) { - $stateExtender.addState(route); - }]); diff --git a/awx/ui/client/src/management-jobs/schedule/schedule.controller.js b/awx/ui/client/src/management-jobs/schedule/schedule.controller.js deleted file mode 100644 index c83b378674..0000000000 --- a/awx/ui/client/src/management-jobs/schedule/schedule.controller.js +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Schedules - * @description This controller's for schedules -*/ - -export default [ - '$scope', '$location', '$stateParams', 'SchedulesList', 'Rest', - 'ProcessErrors', 'GetBasePath', 'Wait','LoadSchedulesScope', 'GetChoices', - 'management_job', '$rootScope', - function($scope, $location, $stateParams, SchedulesList, Rest, - ProcessErrors, GetBasePath, Wait, LoadSchedulesScope, GetChoices, - management_job, $rootScope) { - var base, id, url, parentObject; - $scope.management_job = management_job; - base = $location.path().replace(/^\//, '').split('/')[0]; - - // GetBasePath('management_job') must map to 'system_job_templates' - // to match the api syntax - $rootScope.defaultUrls.management_jobs = 'api/v1/system_job_templates/'; - - if ($scope.removePostRefresh) { - $scope.removePostRefresh(); - } - $scope.removePostRefresh = $scope.$on('PostRefresh', function() { - var list = $scope.schedules; - list.forEach(function(element, idx) { - list[idx].play_tip = (element.enabled) ? 'Schedule is Active.'+ - ' Click to temporarily stop.' : 'Schedule is temporarily '+ - 'stopped. Click to activate.'; - }); - }); - - if ($scope.removeParentLoaded) { - $scope.removeParentLoaded(); - } - $scope.removeParentLoaded = $scope.$on('ParentLoaded', function() { - url += "schedules/"; - SchedulesList.well = true; - LoadSchedulesScope({ - parent_scope: $scope, - scope: $scope, - list: SchedulesList, - id: 'management_jobs_schedule', - url: url, - pageSize: 20 - }); - }); - - if ($scope.removeChoicesReady) { - $scope.removeChocesReady(); - } - $scope.removeChoicesReady = $scope.$on('choicesReady', function() { - // Load the parent object - id = $stateParams.management_job_id; - url = GetBasePath('system_job_templates') + id + '/'; - Rest.setUrl(url); - Rest.get() - .success(function(data) { - parentObject = data; - $scope.$emit('ParentLoaded'); - }) - .error(function(data, status) { - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. GET returned: ' + status }); - }); - }); - - $scope.refreshJobs = function() { - $scope.search(SchedulesList.iterator); - }; - - Wait('start'); - - GetChoices({ - scope: $scope, - url: GetBasePath('system_jobs'), - field: 'type', - variable: 'type_choices', - callback: 'choicesReady' - }); - } -]; diff --git a/awx/ui/client/src/management-jobs/schedule/schedule.partial.html b/awx/ui/client/src/management-jobs/schedule/schedule.partial.html deleted file mode 100644 index 43b01efc55..0000000000 --- a/awx/ui/client/src/management-jobs/schedule/schedule.partial.html +++ /dev/null @@ -1,6 +0,0 @@ -
-
-
- -
-
diff --git a/awx/ui/client/src/management-jobs/schedule/schedule.route.js b/awx/ui/client/src/management-jobs/schedule/schedule.route.js deleted file mode 100644 index 837d6dfb86..0000000000 --- a/awx/ui/client/src/management-jobs/schedule/schedule.route.js +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import {templateUrl} from '../../shared/template-url/template-url.factory'; - -export default { - name: 'managementJobsSchedule', - route: '/management_jobs/:management_job_id/schedules', - templateUrl: templateUrl('management-jobs/schedule/schedule'), - controller: 'managementJobsScheduleController', - data: { - activityStream: true, - activityStreamTarget: 'schedule' - }, - params: {management_job: null}, - resolve: { - features: ['FeaturesService', function(FeaturesService) { - return FeaturesService.get(); - }], - management_job: - [ '$stateParams', - '$q', - 'Rest', - 'GetBasePath', - 'ProcessErrors', - function($stateParams, $q, rest, getBasePath, ProcessErrors) { - if ($stateParams.management_job) { - return $q.when($stateParams.management_job); - } - - var managementJobId = $stateParams.management_job_id; - - var url = getBasePath('system_job_templates') + managementJobId + '/'; - rest.setUrl(url); - return rest.get() - .then(function(data) { - return data.data; - }).catch(function (response) { - ProcessErrors(null, response.data, response.status, null, { - hdr: 'Error!', - msg: 'Failed to get inventory script info. GET returned status: ' + - response.status - }); - }); - } - ] - } -}; diff --git a/awx/ui/client/src/management-jobs/scheduler/main.js b/awx/ui/client/src/management-jobs/scheduler/main.js new file mode 100644 index 0000000000..49498debbd --- /dev/null +++ b/awx/ui/client/src/management-jobs/scheduler/main.js @@ -0,0 +1,52 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import controller from '../../scheduler/scheduler.controller'; +import addController from '../../scheduler/schedulerAdd.controller'; +import editController from '../../scheduler/schedulerEdit.controller'; + +export default + angular.module('managementJobScheduler', []) + .controller('managementJobController', controller) + .controller('managementJobAddController', addController) + .controller('managementJobEditController', editController) + .run(['$stateExtender', function($stateExtender){ + $stateExtender.addState({ + name: 'managementJobSchedules', + route: '/management_jobs/:id/schedules', + templateUrl: templateUrl('scheduler/scheduler'), + controller: 'managementJobController', + resolve: { + features: ['FeaturesService', function(FeaturesService){ + return FeaturesService.get(); + }] + } + }); + $stateExtender.addState({ + name: 'managementJobSchedules.add', + route: '/add', + templateUrl: templateUrl('management-jobs/scheduler/schedulerForm'), + controller: 'managementJobAddController', + resolve: { + features: ['FeaturesService', function(FeaturesService){ + return FeaturesService.get(); + }] + } + }); + $stateExtender.addState({ + name: 'managementJobSchedules.edit', + route: '/add', + templateUrl: templateUrl('management-jobs/scheduler/schedulerForm'), + controller: 'managementJobEditController', + resolve: { + features: ['FeaturesService', function(FeaturesService){ + return FeaturesService.get(); + }] + } + }); + }]); \ No newline at end of file diff --git a/awx/ui/client/src/management-jobs/scheduler/schedulerForm.partial.html b/awx/ui/client/src/management-jobs/scheduler/schedulerForm.partial.html new file mode 100644 index 0000000000..a838db96a5 --- /dev/null +++ b/awx/ui/client/src/management-jobs/scheduler/schedulerForm.partial.html @@ -0,0 +1,652 @@ +
+
+
{{ schedulerName || "Add Schedule"}}
+
{{ schedulerName || "Edit Schedule"}}
+
+ +
+
+
+ + + +
+ + +
+ A schedule name is required. +
+
+
+ +
+ + + + +
+
+
+
+
+ +
+ + + : + + + + : + + + +
+
+ The time must be in HH24:MM:SS format. +
+
+
+ + +
+
+ + +
+
+
+
+ Frequency Details
+
+
+ + + +
+ Please provide a value between 1 and 999. +
+
+
+
+ +
+ +
+ The day must be between 1 and 31. +
+
+
+
+ +
+
+ + +
+
+
+
+ * + +
+
+ + +
+
+ The day must be between 1 and 31. +
+
+
+
+ +
+
+ + + +
+
+
+ +
+
+ + + + + + + +
+
+
+ Please select one or more days. +
+
+
+ +
+ +
+
+
+ + +
+ Please provide a value between 1 and 999. +
+
+
+ +
+ + + + +
+
+ Please provide a valid date. +
+
+
+
+
+ +
+ Note: For facts collected older than the time period specified, save one fact scan (snapshot) per time window (frequency). For example, facts older than 30 days are purged, while one weekly fact scan is kept. + Caution: Setting both numerical variables to "0" will delete all facts.
+ +
+ + +
A value is required.
+
This is not a valid number.
+
+ +
+
+ +
+
+ +
Please enter the number of days you would like to keep this data.
+
Please enter a valid number.
+
Please enter a non-negative number.
+
Please enter a number smaller than 9999.
+
+
+ +
+
+ +
+
+ +
+
+ +
Please enter the number of days you would like to keep this data.
+
Please enter a valid number.
+
Please enter a non-negative number.
+
Please enter a number smaller than 9999.
+
+
+ +
+
+ + +
+

+ The scheduler options are invalid or incomplete. +

+
+
+ +
+ {{ rrule_nlp_description }} +
+
+ +
+ + + +
+
+
    +
  • + {{ occurrence.utc }} +
  • +
+
    +
  • + {{ occurrence.local }} +
  • +
+
+ +
+ + +
+
+
diff --git a/awx/ui/client/src/partials/inventory-manage.html b/awx/ui/client/src/partials/inventory-manage.html index 452df8bbb8..ecae801c20 100644 --- a/awx/ui/client/src/partials/inventory-manage.html +++ b/awx/ui/client/src/partials/inventory-manage.html @@ -1,4 +1,5 @@
+
diff --git a/awx/ui/client/src/partials/portal.html b/awx/ui/client/src/partials/portal.html index 077eed49e3..fe6039de54 100644 --- a/awx/ui/client/src/partials/portal.html +++ b/awx/ui/client/src/partials/portal.html @@ -32,4 +32,4 @@
- + diff --git a/awx/ui/client/src/scheduler/scheduler.controller.js b/awx/ui/client/src/scheduler/scheduler.controller.js index d53ea19e28..d1209b91da 100644 --- a/awx/ui/client/src/scheduler/scheduler.controller.js +++ b/awx/ui/client/src/scheduler/scheduler.controller.js @@ -21,9 +21,13 @@ export default [ ClearScope(); var base, e, id, url, parentObject; - base = $location.path().replace(/^\//, '').split('/')[0]; - + if (base == 'management_jobs') { + $scope.base = base = 'system_job_templates'; + } + if ($stateParams.job_type){ + $scope.job_type = $stateParams.job_type; + } if ($scope.removePostRefresh) { $scope.removePostRefresh(); } diff --git a/awx/ui/client/src/scheduler/schedulerAdd.controller.js b/awx/ui/client/src/scheduler/schedulerAdd.controller.js index 26be29c03a..a278af8a28 100644 --- a/awx/ui/client/src/scheduler/schedulerAdd.controller.js +++ b/awx/ui/client/src/scheduler/schedulerAdd.controller.js @@ -47,7 +47,8 @@ export default ['$compile', '$state', '$stateParams', 'AddSchedule', 'Wait', '$s AddSchedule({ scope: $scope, - callback: 'SchedulesRefresh' + callback: 'SchedulesRefresh', + base: $scope.base ? $scope.base : null }); var callSelect2 = function() { diff --git a/awx/ui/client/src/scheduler/schedulerEdit.controller.js b/awx/ui/client/src/scheduler/schedulerEdit.controller.js index fb8d8052b5..05e9d7eef3 100644 --- a/awx/ui/client/src/scheduler/schedulerEdit.controller.js +++ b/awx/ui/client/src/scheduler/schedulerEdit.controller.js @@ -51,7 +51,8 @@ export default ['$compile', '$state', '$stateParams', 'EditSchedule', 'Wait', '$ EditSchedule({ scope: $scope, id: parseInt($stateParams.schedule_id), - callback: 'SchedulesRefresh' + callback: 'SchedulesRefresh', + base: $scope.base ? $scope.base: null }); var callSelect2 = function() { diff --git a/awx/ui/client/src/shared/Modal.js b/awx/ui/client/src/shared/Modal.js index 2c17b1e14c..37ae34f97a 100644 --- a/awx/ui/client/src/shared/Modal.js +++ b/awx/ui/client/src/shared/Modal.js @@ -106,7 +106,7 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper']) resizable: resizable, create: function () { // Fix the close button - $('.ui-dialog[aria-describedby="' + id + '"]').find('.ui-dialog-titlebar button').empty().attr({'class': 'close'}).text('x'); + $('.ui-dialog[aria-describedby="' + id + '"]').find('.ui-dialog-titlebar button').empty().attr({'class': 'close'}).html(''); setTimeout(function() { // Make buttons bootstrapy diff --git a/awx/ui/client/src/shared/branding/colors.default.less b/awx/ui/client/src/shared/branding/colors.default.less index fbde1449ac..dd53943e88 100644 --- a/awx/ui/client/src/shared/branding/colors.default.less +++ b/awx/ui/client/src/shared/branding/colors.default.less @@ -12,6 +12,7 @@ @default-err-hov: #FF1105; @default-succ: #3CB878; @default-succ-hov: #60D66F; +@default-succ-disabled: lighten(@default-succ, 30); @default-link: #1678C4; @default-link-hov: #4498DA; @default-button-hov: #F2F2F2; diff --git a/awx/ui/client/src/shared/branding/colors.less b/awx/ui/client/src/shared/branding/colors.less index 4d9d801584..839b79a174 100644 --- a/awx/ui/client/src/shared/branding/colors.less +++ b/awx/ui/client/src/shared/branding/colors.less @@ -5,6 +5,7 @@ @blue-dark: #2a6496; /* link hover */ @grey: #A9A9A9; @grey-txt: #707070; +@grey-border: #DDDDDD; @info: #d9edf7; /* alert info background color */ @info-border: #bce8f1; /* alert info border color */ @info-color: #3a87ad; diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index ed9aa488ae..693a090f68 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -1476,6 +1476,9 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat } html += "\n"; } else { + var inSubForm = false; + var currentSubForm = undefined; + var hasSubFormField; // original, single-column form section = ''; group = ''; @@ -1502,9 +1505,33 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += "\n"; section = field.section; } + + // To hide/show the subform when the value changes on parent + if (field.hasSubForm === true) { + hasSubFormField = fld; + } + + // Add a subform container + if(field.subForm && currentSubForm === undefined) { + currentSubForm = field.subForm; + var subFormTitle = this.form.subFormTitles[field.subForm]; + + html += '
'; + html += ''+ subFormTitle +''; + } + else if (!field.subForm && currentSubForm !== undefined) { + currentSubForm = undefined; + html += '
'; + } + html += this.buildField(fld, field, options, this.form); + } } + if (currentSubForm) { + currentSubForm = undefined; + html += ''; + } if (section !== '') { html += "\n\n"; } diff --git a/awx/ui/client/src/shared/list-generator/list-generator.factory.js b/awx/ui/client/src/shared/list-generator/list-generator.factory.js index 304478ab3c..3d974db190 100644 --- a/awx/ui/client/src/shared/list-generator/list-generator.factory.js +++ b/awx/ui/client/src/shared/list-generator/list-generator.factory.js @@ -299,44 +299,47 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate list = this.list, base, size, action, fld, cnt, field_action, fAction, itm; - if(options.title !== false){ - html += "
"; - html += "
"; + if (options.mode !== 'lookup') { + if(options.title !== false){ + html += "
"; + html += "
"; - if (list.listTitle) { + if (list.listTitle) { - html += "
" + list.listTitle + "
"; - // We want to show the list title badge by default and only hide it when the list config specifically passes a false flag - list.listTitleBadge = (typeof list.listTitleBadge === 'boolean' && list.listTitleBadge == false) ? false : true; - if(list.listTitleBadge) { - html += "{{(" + list.iterator + "_total_rows | number:0)}}"; - } + html += "
" + list.listTitle + "
"; + // We want to show the list title badge by default and only hide it when the list config specifically passes a false flag + list.listTitleBadge = (typeof list.listTitleBadge === 'boolean' && list.listTitleBadge == false) ? false : true; + if(list.listTitleBadge) { + html += "{{(" + list.iterator + "_total_rows | number:0)}}"; + } + } + + html += "
"; + if(list.toolbarAuxAction) { + html += "
"; + html += list.toolbarAuxAction; + html += "
"; + } + html += "
"; + html += "
\n"; + + for (action in list.actions) { + list.actions[action] = _.defaults(list.actions[action], { dataPlacement: "top" }); + } + + html += "
\n"; + html += "
"; + html += "
"; + } } - html += "
"; - if(list.toolbarAuxAction) { - html += "
"; - html += list.toolbarAuxAction; - html += "
"; - } - html += "
"; - html += "
\n"; - - for (action in list.actions) { - list.actions[action] = _.defaults(list.actions[action], { dataPlacement: "top" }); - } - - html += "
\n"; - html += "
"; - html += "
"; - } if (options.mode === 'edit' && list.editInstructions) { html += "
\n"; - html += "\n"; + html += "\n"; html += "Hint: " + list.editInstructions + "\n"; html += "
\n"; } @@ -356,7 +359,6 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate html += "
"; html += (list.emptyListText) ? list.emptyListText : "PLEASE ADD ITEMS TO THIS LIST"; html += "
"; - if (options.showSearch=== undefined || options.showSearch === true) { // Only show the search bar if we are loading results or if we have at least 1 base result html += "
0)\">\n"; @@ -459,6 +461,20 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate innerTable += ''; } + // Change layout if a lookup list, place radio buttons before labels + if (options.mode === 'lookup') { + if(options.input_type==="radio"){ //added by JT so that lookup forms can be either radio inputs or check box inputs + innerTable += ""; + } + else { // its assumed that options.input_type = checkbox + innerTable += ""; + } + } + cnt = 2; base = (list.base) ? list.base : list.name; base = base.replace(/^\//, ''); @@ -475,7 +491,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate } } - if (options.mode === 'select' || options.mode === 'lookup') { + if (options.mode === 'select') { if(options.input_type==="radio"){ //added by JT so that lookup forms can be either radio inputs or check box inputs innerTable += ""; + } for (fld in list.fields) { if ((list.fields[fld].searchOnly === undefined || list.fields[fld].searchOnly === false) && !(options.mode === 'lookup' && list.fields[fld].excludeModal === true)) { @@ -643,9 +662,10 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate html += "\n"; } } - if (options.mode === 'select' || options.mode === 'lookup') { - html += "Select"; - } else if (options.mode === 'edit' && list.fieldActions) { + if (options.mode === 'select') { + html += "Select"; + } + else if (options.mode === 'edit' && list.fieldActions) { html += ""; diff --git a/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.partial.html b/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.partial.html index 9d6d6ad4ac..3b8b51fa97 100644 --- a/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.partial.html +++ b/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.partial.html @@ -17,7 +17,7 @@
STATUS
- {{ job.status }} + {{ job.status }}
diff --git a/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js b/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js index 180baa17fa..d9d121b443 100644 --- a/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js +++ b/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js @@ -8,7 +8,7 @@ import {templateUrl} from '../../shared/template-url/template-url.factory'; export default { name: 'adHocJobStdout', - route: '/ad_hoc_commands/:id/stdout', + route: '/ad_hoc_commands/:id', templateUrl: templateUrl('standard-out/adhoc/standard-out-adhoc'), controller: 'JobStdoutController', ncyBreadcrumb: { diff --git a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html index 63835c3c80..3a1152f0ec 100644 --- a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html +++ b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html @@ -11,7 +11,7 @@
NAME
@@ -21,13 +21,13 @@
STATUS
- {{ job.status }} + {{ job.status }}
LICENSE ERROR
-
+
{{ job.license_error }}
@@ -55,7 +55,7 @@
LAUNCH TYPE
-
+
{{ job.launch_type }}
@@ -72,7 +72,7 @@
GROUP
@@ -94,14 +94,14 @@
OVERWRITE
-
+
{{ job.overwrite }}
OVERWRITE VARS
-
+
{{ job.overwrite_vars }}
diff --git a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js index 85afb5e01f..a357f39afc 100644 --- a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js +++ b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js @@ -10,7 +10,7 @@ import {templateUrl} from '../../shared/template-url/template-url.factory'; export default { name: 'inventorySyncStdout', - route: '/inventory_sync/:id/stdout', + route: '/inventory_sync/:id', templateUrl: templateUrl('standard-out/inventory-sync/standard-out-inventory-sync'), controller: 'JobStdoutController', ncyBreadcrumb: { diff --git a/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.partial.html b/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.partial.html index f268e9569a..36a29fef55 100644 --- a/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.partial.html +++ b/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.partial.html @@ -17,7 +17,7 @@
STATUS
- {{ job.status }} + {{ job.status }}
@@ -44,7 +44,7 @@
LAUNCH TYPE
-
+
{{ job.launch_type }}
diff --git a/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js b/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js index c119ea215b..6eaa1aa184 100644 --- a/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js +++ b/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js @@ -8,7 +8,7 @@ import {templateUrl} from '../../shared/template-url/template-url.factory'; export default { name: 'managementJobStdout', - route: '/management_jobs/:id/stdout', + route: '/management_jobs/:id', templateUrl: templateUrl('standard-out/management-jobs/standard-out-management-jobs'), controller: 'JobStdoutController', ncyBreadcrumb: { diff --git a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html index 883d382c20..ec1378cad7 100644 --- a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html +++ b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html @@ -21,7 +21,7 @@
STATUS
- {{ job.status }} + {{ job.status }}
@@ -48,7 +48,7 @@
LAUNCH TYPE
-
+
{{ job.launch_type }}
diff --git a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js index 5f9a089231..294518cd7b 100644 --- a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js +++ b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js @@ -10,7 +10,7 @@ import {templateUrl} from '../../shared/template-url/template-url.factory'; export default { name: 'scmUpdateStdout', - route: '/scm_update/:id/stdout', + route: '/scm_update/:id', templateUrl: templateUrl('standard-out/scm-update/standard-out-scm-update'), controller: 'JobStdoutController', ncyBreadcrumb: { diff --git a/awx/ui/client/src/standard-out/standard-out.block.less b/awx/ui/client/src/standard-out/standard-out.block.less index 7fcd0aa9b6..654439b6ed 100644 --- a/awx/ui/client/src/standard-out/standard-out.block.less +++ b/awx/ui/client/src/standard-out/standard-out.block.less @@ -58,3 +58,18 @@ .StandardOut-statusText { margin-left: 6px; } + +.StandardOut--capitalize { + text-transform: capitalize; +} + +@standardout-breakpoint: 900px; + +@media screen and (max-width: @standardout-breakpoint) { + .StandardOut { + flex-direction: column; + } + .StandardOut-rightPanel { + margin-left: 0px; + } +} diff --git a/awx/ui/client/src/standard-out/standard-out.controller.js b/awx/ui/client/src/standard-out/standard-out.controller.js index f95eaab1fb..e0ac1362e4 100644 --- a/awx/ui/client/src/standard-out/standard-out.controller.js +++ b/awx/ui/client/src/standard-out/standard-out.controller.js @@ -158,8 +158,6 @@ export function JobStdoutController ($location, $log, $rootScope, $scope, $compi } }; - $(".StandardOut").height($("body").height() - 60); - Rest.setUrl(GetBasePath('base') + jobType + '/' + job_id + '/'); Rest.get() .success(function(data) { diff --git a/awx/ui/client/tests/adhoc/adhoc.controller-test.js b/awx/ui/client/tests/adhoc/adhoc.controller-test.js index c60af03f44..26583b71dd 100644 --- a/awx/ui/client/tests/adhoc/adhoc.controller-test.js +++ b/awx/ui/client/tests/adhoc/adhoc.controller-test.js @@ -55,6 +55,7 @@ describe("adhoc.controller", function() { $provide.value('Wait', waitCallback); $provide.value('$stateExtender', stateExtenderCallback); $provide.value('$stateParams', angular.noop); + $provide.value('$state', angular.noop); }])); beforeEach("put $q in scope", window.inject(['$q', function($q) {