From eae92f8751b9c125841061cb0c51dc1d834ee1fd Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 18 Feb 2016 13:02:02 -0500 Subject: [PATCH 01/18] delete management-jobs/schedule, create management-jobs/scheduler, add ui-router states, update references to state names #696 prep for isFactCleanup test in the view - change the way Schedule.js AddSchedule factory recognizes a management job #696 --- awx/ui/client/src/helpers/Schedules.js | 15 +- .../management-jobs/card/card.controller.js | 8 +- .../management-jobs/card/card.partial.html | 2 +- awx/ui/client/src/management-jobs/main.js | 4 +- .../src/management-jobs/schedule/main.js | 15 - .../schedule/schedule.controller.js | 89 --- .../schedule/schedule.partial.html | 6 - .../schedule/schedule.route.js | 51 -- .../src/management-jobs/scheduler/main.js | 52 ++ .../scheduler/schedulerForm.partial.html | 652 ++++++++++++++++++ .../src/scheduler/scheduler.controller.js | 10 +- .../src/scheduler/schedulerAdd.controller.js | 4 +- .../src/scheduler/schedulerEdit.controller.js | 4 +- 13 files changed, 733 insertions(+), 179 deletions(-) delete mode 100644 awx/ui/client/src/management-jobs/schedule/main.js delete mode 100644 awx/ui/client/src/management-jobs/schedule/schedule.controller.js delete mode 100644 awx/ui/client/src/management-jobs/schedule/schedule.partial.html delete mode 100644 awx/ui/client/src/management-jobs/schedule/schedule.route.js create mode 100644 awx/ui/client/src/management-jobs/scheduler/main.js create mode 100644 awx/ui/client/src/management-jobs/scheduler/schedulerForm.partial.html diff --git a/awx/ui/client/src/helpers/Schedules.js b/awx/ui/client/src/helpers/Schedules.js index 0924170311..14e62cdd4f 100644 --- a/awx/ui/client/src/helpers/Schedules.js +++ b/awx/ui/client/src/helpers/Schedules.js @@ -214,19 +214,20 @@ export default return function(params) { var scope = params.scope, callback= params.callback, - base = $location.path().replace(/^\//, '').split('/')[0], + base = params.base || $location.path().replace(/^\//, '').split('/')[0], url = GetBasePath(base), scheduler; - + console.log('AddSchedule $stateParams: ', $stateParams) if (!Empty($stateParams.template_id)) { url += $stateParams.template_id + '/schedules/'; } - else if (!Empty($stateParams.id)) { + else if (!Empty($stateParams.id) && base != 'system_job_templates') { url += $stateParams.id + '/schedules/'; } - else if (!Empty($stateParams.management_job)) { - url += $stateParams.management_job + '/schedules/'; - if(scope.management_job.id === 4){ + else if (base == 'system_job_templates') { + console.log('at least we know its a mgmt job!') + url += $stateParams.id + '/schedules/'; + if(scope.id === 4){ scope.isFactCleanup = true; scope.keep_unit_choices = [{ "label" : "Days", @@ -538,7 +539,7 @@ export default var scope = params.scope, parent_scope = params.parent_scope, iterator = (params.iterator) ? params.iterator : scope.iterator, - base = $location.path().replace(/^\//, '').split('/')[0]; + base = params.base || $location.path().replace(/^\//, '').split('/')[0]; scope.toggleSchedule = function(event, id) { try { diff --git a/awx/ui/client/src/management-jobs/card/card.controller.js b/awx/ui/client/src/management-jobs/card/card.controller.js index e9d5c4409c..5d32ae3e32 100644 --- a/awx/ui/client/src/management-jobs/card/card.controller.js +++ b/awx/ui/client/src/management-jobs/card/card.controller.js @@ -24,6 +24,7 @@ export default Rest.setUrl(defaultUrl); Rest.get() .success(function(data){ + console.log(data) $scope.mgmtCards = data.results; Wait('stop'); }) @@ -238,10 +239,9 @@ export default } }; - $scope.configureSchedule = function() { - $state.transitionTo('managementJobsSchedule', { - management_job: this.job_type, - management_job_id: this.card.id + $scope.configureSchedule = function(id) { + $state.transitionTo('managementJobSchedules', { + id: id }); }; diff --git a/awx/ui/client/src/management-jobs/card/card.partial.html b/awx/ui/client/src/management-jobs/card/card.partial.html index 3b4cfec9ba..17332be2bc 100644 --- a/awx/ui/client/src/management-jobs/card/card.partial.html +++ b/awx/ui/client/src/management-jobs/card/card.partial.html @@ -11,7 +11,7 @@ diff --git a/awx/ui/client/src/management-jobs/main.js b/awx/ui/client/src/management-jobs/main.js index b374b84857..35e6c10c76 100644 --- a/awx/ui/client/src/management-jobs/main.js +++ b/awx/ui/client/src/management-jobs/main.js @@ -5,12 +5,12 @@ *************************************************/ 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/scheduler/scheduler.controller.js b/awx/ui/client/src/scheduler/scheduler.controller.js index d53ea19e28..af7a606168 100644 --- a/awx/ui/client/src/scheduler/scheduler.controller.js +++ b/awx/ui/client/src/scheduler/scheduler.controller.js @@ -19,11 +19,16 @@ export default [ GetBasePath, Wait, Find, LoadDialogPartial, LoadSchedulesScope, GetChoices) { ClearScope(); + console.log($stateParams) 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(); } @@ -87,4 +92,5 @@ export default [ variable: 'type_choices', callback: 'choicesReady' }); + console.log($scope) }]; diff --git a/awx/ui/client/src/scheduler/schedulerAdd.controller.js b/awx/ui/client/src/scheduler/schedulerAdd.controller.js index 26be29c03a..6e3ec321e9 100644 --- a/awx/ui/client/src/scheduler/schedulerAdd.controller.js +++ b/awx/ui/client/src/scheduler/schedulerAdd.controller.js @@ -6,6 +6,7 @@ export default ['$compile', '$state', '$stateParams', 'AddSchedule', 'Wait', '$s $scope.$on("formUpdated", function() { $rootScope.$broadcast("loadSchedulerDetailPane"); }); + console.log('schedulerAdd.controller $scope: ', $scope) $scope.$watchGroup(["schedulerName", "schedulerStartDt", @@ -47,7 +48,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..d5754c4acb 100644 --- a/awx/ui/client/src/scheduler/schedulerEdit.controller.js +++ b/awx/ui/client/src/scheduler/schedulerEdit.controller.js @@ -6,6 +6,7 @@ export default ['$compile', '$state', '$stateParams', 'EditSchedule', 'Wait', '$ $scope.$on("formUpdated", function() { $rootScope.$broadcast("loadSchedulerDetailPane"); }); + console.log($scope) $scope.$watchGroup(["schedulerName", "schedulerStartDt", @@ -51,7 +52,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() { From 247c78c44d217b9cc5877da96dc733f1acbe343e Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Fri, 19 Feb 2016 10:59:58 -0500 Subject: [PATCH 02/18] #696 clean up logging --- awx/ui/client/src/helpers/Schedules.js | 4 +--- awx/ui/client/src/scheduler/scheduler.controller.js | 2 -- awx/ui/client/src/scheduler/schedulerAdd.controller.js | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/awx/ui/client/src/helpers/Schedules.js b/awx/ui/client/src/helpers/Schedules.js index 14e62cdd4f..9b7566e678 100644 --- a/awx/ui/client/src/helpers/Schedules.js +++ b/awx/ui/client/src/helpers/Schedules.js @@ -217,7 +217,6 @@ export default base = params.base || $location.path().replace(/^\//, '').split('/')[0], url = GetBasePath(base), scheduler; - console.log('AddSchedule $stateParams: ', $stateParams) if (!Empty($stateParams.template_id)) { url += $stateParams.template_id + '/schedules/'; } @@ -225,9 +224,8 @@ export default url += $stateParams.id + '/schedules/'; } else if (base == 'system_job_templates') { - console.log('at least we know its a mgmt job!') url += $stateParams.id + '/schedules/'; - if(scope.id === 4){ + if($stateParams.id == 4){ scope.isFactCleanup = true; scope.keep_unit_choices = [{ "label" : "Days", diff --git a/awx/ui/client/src/scheduler/scheduler.controller.js b/awx/ui/client/src/scheduler/scheduler.controller.js index af7a606168..d1209b91da 100644 --- a/awx/ui/client/src/scheduler/scheduler.controller.js +++ b/awx/ui/client/src/scheduler/scheduler.controller.js @@ -19,7 +19,6 @@ export default [ GetBasePath, Wait, Find, LoadDialogPartial, LoadSchedulesScope, GetChoices) { ClearScope(); - console.log($stateParams) var base, e, id, url, parentObject; base = $location.path().replace(/^\//, '').split('/')[0]; @@ -92,5 +91,4 @@ export default [ variable: 'type_choices', callback: 'choicesReady' }); - console.log($scope) }]; diff --git a/awx/ui/client/src/scheduler/schedulerAdd.controller.js b/awx/ui/client/src/scheduler/schedulerAdd.controller.js index 6e3ec321e9..a278af8a28 100644 --- a/awx/ui/client/src/scheduler/schedulerAdd.controller.js +++ b/awx/ui/client/src/scheduler/schedulerAdd.controller.js @@ -6,7 +6,6 @@ export default ['$compile', '$state', '$stateParams', 'AddSchedule', 'Wait', '$s $scope.$on("formUpdated", function() { $rootScope.$broadcast("loadSchedulerDetailPane"); }); - console.log('schedulerAdd.controller $scope: ', $scope) $scope.$watchGroup(["schedulerName", "schedulerStartDt", From 5f75fa9b467575cb49186d3552aae6a8058f7a1d Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Fri, 19 Feb 2016 12:04:09 -0500 Subject: [PATCH 03/18] #696 remove logging pt. 2 --- awx/ui/client/src/management-jobs/card/card.controller.js | 1 - awx/ui/client/src/scheduler/schedulerEdit.controller.js | 1 - 2 files changed, 2 deletions(-) diff --git a/awx/ui/client/src/management-jobs/card/card.controller.js b/awx/ui/client/src/management-jobs/card/card.controller.js index 5d32ae3e32..b74926f652 100644 --- a/awx/ui/client/src/management-jobs/card/card.controller.js +++ b/awx/ui/client/src/management-jobs/card/card.controller.js @@ -24,7 +24,6 @@ export default Rest.setUrl(defaultUrl); Rest.get() .success(function(data){ - console.log(data) $scope.mgmtCards = data.results; Wait('stop'); }) diff --git a/awx/ui/client/src/scheduler/schedulerEdit.controller.js b/awx/ui/client/src/scheduler/schedulerEdit.controller.js index d5754c4acb..05e9d7eef3 100644 --- a/awx/ui/client/src/scheduler/schedulerEdit.controller.js +++ b/awx/ui/client/src/scheduler/schedulerEdit.controller.js @@ -6,7 +6,6 @@ export default ['$compile', '$state', '$stateParams', 'EditSchedule', 'Wait', '$ $scope.$on("formUpdated", function() { $rootScope.$broadcast("loadSchedulerDetailPane"); }); - console.log($scope) $scope.$watchGroup(["schedulerName", "schedulerStartDt", From 5c049d37a65c9d60b9db56dd34449b9471b1a8ae Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Mon, 22 Feb 2016 10:00:50 -0500 Subject: [PATCH 04/18] Lookup modal styling to match given design --- awx/ui/client/legacy-styles/ansible-ui.less | 5 - .../legacy-styles/jquery-ui-overrides.less | 62 ++++++++++++- awx/ui/client/legacy-styles/lists.less | 42 +++++++++ awx/ui/client/src/helpers/Lookup.js | 23 +++-- awx/ui/client/src/shared/Modal.js | 2 +- .../src/shared/branding/colors.default.less | 1 + awx/ui/client/src/shared/branding/colors.less | 1 + .../list-generator/list-generator.factory.js | 92 +++++++++++-------- 8 files changed, 169 insertions(+), 59 deletions(-) diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index ec58ca474f..028529fffa 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -697,11 +697,6 @@ legend { margin-bottom: 7px; } - .pagination > li > a { - padding: 3px 6px; - font-size: 10px; - } - .modal-body { .pagination { margin-top: 15px; 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..9db2792d2b 100644 --- a/awx/ui/client/legacy-styles/lists.less +++ b/awx/ui/client/legacy-styles/lists.less @@ -101,6 +101,8 @@ table, tbody { margin-left: 15px; } + +/* -- Pagination -- */ .List-pagination { margin-top: 20px; font-size: 12px; @@ -108,6 +110,23 @@ table, tbody { text-transform: uppercase; height: 22px; display: flex; + + .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; + } + } } .List-paginationPagerHolder { @@ -244,6 +263,7 @@ table, tbody { padding-left: 15px!important; height: 34px!important; padding-right: 45px!important; + font-family: 'Open Sans', sans-serif; } .List-searchInput:placeholder-shown { @@ -348,3 +368,25 @@ table, tbody { display: block; font-size: 13px; } + +#lookup-modal-dialog { + + .List-searchWidget { + width: 66.6666% + } + + .List-tableHeaderRow { + .List-tableHeader:first-of-type { + width: 3%; + } + } + + .List-tableHeader, + .List-tableHeader:last-of-type { + text-align:left; + } + + .List-tableCell { + color: @default-interface-txt; + } +} diff --git a/awx/ui/client/src/helpers/Lookup.js b/awx/ui/client/src/helpers/Lookup.js index 0b92d43d75..d23614de3c 100644 --- a/awx/ui/client/src/helpers/Lookup.js +++ b/awx/ui/client/src/helpers/Lookup.js @@ -132,7 +132,6 @@ export default master[field] = scope[field]; master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]; - GenerateList.inject(list, { mode: 'lookup', id: 'lookup-modal-dialog', @@ -145,22 +144,22 @@ export default hdr = (params.hdr) ? params.hdr : 'Select ' + name; // Show pop-up - buttons = [{ + buttons = [ + { + label: "Save", + onClick: function() { + scope.selectAction(); + }, + //icon: "fa-check", + "class": "btn btn-primary", + "id": "lookup-save-button" + },{ label: "Cancel", - icon: "fa-times", "class": "btn btn-default", "id": "lookup-cancel-button", onClick: function() { $('#lookup-modal-dialog').dialog('close'); } - },{ - label: "Select", - onClick: function() { - scope.selectAction(); - }, - icon: "fa-check", - "class": "btn btn-primary", - "id": "lookup-save-button" }]; if (scope.removeModalReady) { @@ -175,7 +174,7 @@ export default scope: scope, buttons: buttons, width: 600, - height: (instructions) ? 625 : 500, + height: (instructions) ? 625 : 450, minWidth: 500, title: hdr, id: 'lookup-modal-dialog', 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/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 += ""; From 6fa10deb8ac99a4dc7aa553433c12011459ee207 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Mon, 22 Feb 2016 11:29:20 -0500 Subject: [PATCH 05/18] #999 move adhoc form to inventoryManage state, #951 fix styling & undefined fields of adhoc form --- awx/ui/client/legacy-styles/forms.less | 9 +++++++++ awx/ui/client/legacy-styles/main-layout.less | 4 ++++ awx/ui/client/src/adhoc/adhoc.controller.js | 8 ++++++-- awx/ui/client/src/adhoc/adhoc.form.js | 11 +++++++---- awx/ui/client/src/adhoc/adhoc.partial.html | 2 +- awx/ui/client/src/adhoc/adhoc.route.js | 4 ++-- awx/ui/client/src/controllers/Inventories.js | 3 ++- awx/ui/client/src/partials/inventory-manage.html | 1 + 8 files changed, 32 insertions(+), 10 deletions(-) diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 0556f7e1cd..5f1ae9f449 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -363,6 +363,15 @@ input[type='radio']:checked:before { display: flex; justify-content: flex-end; } +.Form-button{ + margin-left: 4px; +} + +.Form-buttonDefault { + background-color: #FFFFFF; + color: #848992; + border-color: #E8E8E8; +} .Form-saveButton{ background-color: @submit-button-bg; 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..17ca17783a 100644 --- a/awx/ui/client/src/adhoc/adhoc.controller.js +++ b/awx/ui/client/src/adhoc/adhoc.controller.js @@ -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/controllers/Inventories.js b/awx/ui/client/src/controllers/Inventories.js index a506d78ead..9b2774bd98 100644 --- a/awx/ui/client/src/controllers/Inventories.js +++ b/awx/ui/client/src/controllers/Inventories.js @@ -859,7 +859,8 @@ export function InventoriesManage ($log, $scope, $rootScope, $location, } } $rootScope.hostPatterns = host_patterns; - $location.path('/inventories/' + $scope.inventory.id + '/adhoc'); + $state.go('inventoryManage.adhoc'); + //$location.path('/inventories/' + $scope.inventory.id + '/adhoc'); }; $scope.refreshHostsOnGroupRefresh = false; 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 @@
+
From 90d1a3d0208bbaad20f46e4c1f11c668bbed3874 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Tue, 23 Feb 2016 14:04:30 -0500 Subject: [PATCH 06/18] Remove write-only fields from GET response for job template launch, update raw data form to show any fields/passwords needed to launch the job. --- awx/api/serializers.py | 19 ++++++------------- awx/api/views.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index cb22723098..f79fb2ebe3 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1955,7 +1955,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 @@ -1963,18 +1963,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 28697ee58a..1a6e306419 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1876,6 +1876,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): From 382368f8db5f2ab04a3b700838338a0085563d4e Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Wed, 24 Feb 2016 08:20:22 -0500 Subject: [PATCH 07/18] Made standard out details responsive. Removed the /stdout on the end of some of the standard out routes. --- .../adhoc/standard-out-adhoc.partial.html | 2 +- .../adhoc/standard-out-adhoc.route.js | 2 +- .../standard-out-inventory-sync.partial.html | 10 +++++----- .../standard-out-inventory-sync.route.js | 2 +- .../standard-out-management-jobs.partial.html | 4 ++-- .../standard-out-management-jobs.route.js | 2 +- .../standard-out-scm-update.partial.html | 4 ++-- .../scm-update/standard-out-scm-update.route.js | 2 +- .../src/standard-out/standard-out.block.less | 15 +++++++++++++++ .../src/standard-out/standard-out.controller.js | 2 -- 10 files changed, 29 insertions(+), 16 deletions(-) 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..cba201786e 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 @@ -21,13 +21,13 @@
STATUS
- {{ job.status }} + {{ job.status }}
LICENSE ERROR
-
+
{{ job.license_error }}
@@ -55,7 +55,7 @@
LAUNCH TYPE
-
+
{{ job.launch_type }}
@@ -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) { From 1de32b987fedbdf1611d85f532716a7803743894 Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Wed, 24 Feb 2016 13:23:04 -0500 Subject: [PATCH 08/18] Added missing query parameters to /home/hosts and /home/groups --- awx/ui/client/src/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 43ad6627fb..7dd67c1f4e 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -234,7 +234,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 +249,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: { From e8b890ac458482b7004ac01d9788f1ecfe234fd6 Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Wed, 24 Feb 2016 13:28:46 -0500 Subject: [PATCH 09/18] Fixed this /home/groups route. Having the extra slash before the query params was resulting in a redirect to the dashboard. --- .../inventory-sync/standard-out-inventory-sync.partial.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..bcabcbc40a 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
From c65d795b3bd135f11907e407ba1b1c296982adb6 Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Wed, 24 Feb 2016 13:37:27 -0500 Subject: [PATCH 10/18] Fixed this other /home/groups href by removing the extra slash --- .../inventory-sync/standard-out-inventory-sync.partial.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bcabcbc40a..236a07edb1 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 @@ -72,7 +72,7 @@
GROUP
From a2595dcf124a3435cba2b32f76a2bf924604e6f7 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Wed, 24 Feb 2016 18:38:04 -0500 Subject: [PATCH 11/18] API fixes for 500 errors. --- awx/api/serializers.py | 4 ++++ awx/api/views.py | 8 ++++---- awx/main/views.py | 5 ++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 83719f1dba..223803bcbf 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -478,6 +478,10 @@ class BaseSerializer(serializers.ModelSerializer): return attrs +class EmptySerializer(serializers.Serializer): + pass + + class BaseFactSerializer(DocumentSerializer): __metaclass__ = BaseSerializerMetaclass diff --git a/awx/api/views.py b/awx/api/views.py index 1a6e306419..8dc0aff15b 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1940,7 +1940,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() @@ -2019,8 +2019,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 @@ -2202,7 +2202,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({}) @@ -2273,7 +2273,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) From 3d858b68cd68c699c4e8b1e5c28a0129781e6146 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Wed, 24 Feb 2016 10:41:40 -0500 Subject: [PATCH 12/18] Moved LESS code around per comments. Modularized. Removed old lookup helper and references. Modularized Lookup, put in own folder, removed old Lookup.js --- awx/ui/client/legacy-styles/ansible-ui.less | 17 ++ awx/ui/client/legacy-styles/lists.less | 40 --- awx/ui/client/src/app.js | 1 + awx/ui/client/src/helpers.js | 2 - awx/ui/client/src/helpers/Lookup.js | 306 -------------------- awx/ui/client/src/lookup/lookup.block.less | 22 ++ awx/ui/client/src/lookup/lookup.factory.js | 305 +++++++++++++++++++ awx/ui/client/src/lookup/main.js | 12 + awx/ui/client/src/partials/portal.html | 2 +- 9 files changed, 358 insertions(+), 349 deletions(-) delete mode 100644 awx/ui/client/src/helpers/Lookup.js create mode 100644 awx/ui/client/src/lookup/lookup.block.less create mode 100644 awx/ui/client/src/lookup/lookup.factory.js create mode 100644 awx/ui/client/src/lookup/main.js diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index 028529fffa..06d924b141 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -697,6 +697,23 @@ legend { margin-bottom: 7px; } + .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/lists.less b/awx/ui/client/legacy-styles/lists.less index 9db2792d2b..2dcac015c8 100644 --- a/awx/ui/client/legacy-styles/lists.less +++ b/awx/ui/client/legacy-styles/lists.less @@ -101,7 +101,6 @@ table, tbody { margin-left: 15px; } - /* -- Pagination -- */ .List-pagination { margin-top: 20px; @@ -110,23 +109,6 @@ table, tbody { text-transform: uppercase; height: 22px; display: flex; - - .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; - } - } } .List-paginationPagerHolder { @@ -368,25 +350,3 @@ table, tbody { display: block; font-size: 13px; } - -#lookup-modal-dialog { - - .List-searchWidget { - width: 66.6666% - } - - .List-tableHeaderRow { - .List-tableHeader:first-of-type { - width: 3%; - } - } - - .List-tableHeader, - .List-tableHeader:last-of-type { - text-align:left; - } - - .List-tableCell { - color: @default-interface-txt; - } -} diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 43ad6627fb..2c27bf8c20 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'; diff --git a/awx/ui/client/src/helpers.js b/awx/ui/client/src/helpers.js index 4a277970da..4b9c4ab548 100644 --- a/awx/ui/client/src/helpers.js +++ b/awx/ui/client/src/helpers.js @@ -22,7 +22,6 @@ import Jobs from "./helpers/Jobs"; import License from "./helpers/License"; import LoadConfig from "./helpers/LoadConfig"; import LogViewer from "./helpers/LogViewer"; -import Lookup from "./helpers/Lookup"; import PaginationHelpers from "./helpers/PaginationHelpers"; import Parse from "./helpers/Parse"; import ProjectPath from "./helpers/ProjectPath"; @@ -60,7 +59,6 @@ export License, LoadConfig, LogViewer, - Lookup, PaginationHelpers, Parse, ProjectPath, diff --git a/awx/ui/client/src/helpers/Lookup.js b/awx/ui/client/src/helpers/Lookup.js deleted file mode 100644 index d23614de3c..0000000000 --- a/awx/ui/client/src/helpers/Lookup.js +++ /dev/null @@ -1,306 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - - /** - * @ngdoc function - * @name helpers.function:Lookup - * @description - * LookUpInit( { - * scope: , - * form:
, - * current_item: , - * list: , - * field: , - * hdr: - * postAction: optional function to run after selection made, - * callback: optional label to $emit() on parent scope - * input_type: optional string that specifies whether lookup should have checkboxes or radio buttons. defaults to 'checkbox' --- added by JT 8/21/14 - * }) - */ - -import listGenerator from '../shared/list-generator/main'; - -export default - angular.module('LookUpHelper', ['RestServices', 'Utilities', 'SearchHelper', 'PaginationHelpers', listGenerator.name, 'ApiLoader', 'ModalDialog']) - - .factory('LookUpInit', ['Alert', 'Rest', 'ProcessErrors', 'generateList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'FormatDate', 'Empty', 'CreateDialog', - function (Alert, Rest, ProcessErrors, GenerateList, SearchInit, PaginateInit, GetBasePath, FormatDate, Empty, CreateDialog) { - return function (params) { - - var parent_scope = params.scope, - form = params.form, - list = params.list, - field = params.field, - instructions = params.instructions, - postAction = params.postAction, - callback = params.callback, - autopopulateLookup, - input_type = (params.input_type) ? params.input_type: "checkbox", - defaultUrl, name, watchUrl; - - if (params.autopopulateLookup !== undefined) { - autopopulateLookup = params.autopopulateLookup; - } else { - autopopulateLookup = true; - } - - if (params.url) { - // pass in a url value to override the default - defaultUrl = params.url; - } else { - defaultUrl = (list.name === 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name); - } - - if ($('#htmlTemplate #lookup-modal-dialog').length > 0) { - $('#htmlTemplate #lookup-modal-dialog').empty(); - } - else { - $('#htmlTemplate').append("
"); - } - - name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1); - - watchUrl = (/\/$/.test(defaultUrl)) ? defaultUrl + '?' : defaultUrl + '&'; - watchUrl += form.fields[field].sourceField + '__' + 'iexact=:value'; - - $('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-url', watchUrl); - $('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-source', field); - - var sourceModel = form.fields[field].sourceModel, - sourceField = form.fields[field].sourceField; - - // this logic makes sure that the form is being added, and that the lookup to be autopopulated is required - // we also look to see if the lookupinit autopopulateLookup parameter passed in by the controller is false - function fieldIsAutopopulatable() { - if (autopopulateLookup === false) { - return false; - } if (parent_scope.mode === "add") { - if (parent_scope[sourceModel + "_field"].awRequiredWhen && - parent_scope[sourceModel + "_field"].awRequiredWhen.variable && - parent_scope[parent_scope[sourceModel + "_field"].awRequiredWhen.variable]) { - return true; - } else if (parent_scope[sourceModel + "_field"].addRequired === true) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - if (fieldIsAutopopulatable()) { - // Auto populate the field if there is only one result - Rest.setUrl(defaultUrl); - Rest.get() - .success(function (data) { - if (data.count === 1) { - parent_scope[field] = data.results[0].id; - if (parent_scope[form.name + '_form'] && form.fields[field] && sourceModel) { - parent_scope[sourceModel + '_' + sourceField] = - data.results[0][sourceField]; - if (parent_scope[form.name + '_form'][sourceModel + '_' + sourceField]) { - parent_scope[form.name + '_form'][sourceModel + '_' + sourceField] - .$setValidity('awlookup', true); - } - } - if (parent_scope[form.name + '_form']) { - parent_scope[form.name + '_form'].$setDirty(); - } - } - }) - .error(function (data, status) { - ProcessErrors(parent_scope, data, status, form, { hdr: 'Error!', - msg: 'Failed to launch adhoc command. POST returned status: ' + - status }); - }); - } - - - parent_scope['lookUp' + name] = function () { - - var master = {}, - scope = parent_scope.$new(), - name, hdr, buttons; - - // Generating the search list potentially kills the values held in scope for the field. - // We'll keep a copy in master{} that we can revert back to on cancel; - master[field] = scope[field]; - master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = - scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]; - GenerateList.inject(list, { - mode: 'lookup', - id: 'lookup-modal-dialog', - scope: scope, - instructions: instructions, - input_type: input_type - }); - - name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1); - hdr = (params.hdr) ? params.hdr : 'Select ' + name; - - // Show pop-up - buttons = [ - { - label: "Save", - onClick: function() { - scope.selectAction(); - }, - //icon: "fa-check", - "class": "btn btn-primary", - "id": "lookup-save-button" - },{ - label: "Cancel", - "class": "btn btn-default", - "id": "lookup-cancel-button", - onClick: function() { - $('#lookup-modal-dialog').dialog('close'); - } - }]; - - if (scope.removeModalReady) { - scope.removeModalReady(); - } - scope.removeModalReady = scope.$on('ModalReady', function() { - $('#lookup-save-button').attr('disabled','disabled'); - $('#lookup-modal-dialog').dialog('open'); - }); - - CreateDialog({ - scope: scope, - buttons: buttons, - width: 600, - height: (instructions) ? 625 : 450, - minWidth: 500, - title: hdr, - id: 'lookup-modal-dialog', - onClose: function() { - setTimeout( function() { - scope.$apply( function() { - if (Empty(scope[field])) { - scope[field] = master[field]; - scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = - master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]; - } - }); - }, 300); - }, - callback: 'ModalReady' - }); - - SearchInit({ - scope: scope, - set: list.name, - list: list, - url: defaultUrl - }); - - PaginateInit({ - scope: scope, - list: list, - url: defaultUrl, - mode: 'lookup' - }); - - if (scope.lookupPostRefreshRemove) { - scope.lookupPostRefreshRemove(); - } - scope.lookupPostRefreshRemove = scope.$on('PostRefresh', function () { - var fld, i; - for (fld in list.fields) { - if (list.fields[fld].type && list.fields[fld].type === 'date') { - //convert dates to our standard format - for (i = 0; i < scope[list.name].length; i++) { - scope[list.name][i][fld] = FormatDate(new Date(scope[list.name][i][fld])); - } - } - } - - // List generator creates the list, resetting it and losing the previously selected value. - // If the selected value is in the current set, find it and mark selected. - if (!Empty(parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField])) { - scope[list.name].forEach(function(elem) { - if (elem[form.fields[field].sourceField] === - parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) { - scope[field] = elem.id; - } - }); - - } - - if (!Empty(scope[field])) { - scope['toggle_' + list.iterator](scope[field]); - } - - }); - - scope.search(list.iterator); - - scope.selectAction = function () { - var i, found = false; - for (i = 0; i < scope[list.name].length; i++) { - if (scope[list.name][i].checked === '1' || scope[list.name][i].checked===1 || scope[list.name][i].checked === true) { - found = true; - parent_scope[field] = scope[list.name][i].id; - if (parent_scope[form.name + '_form'] && form.fields[field] && form.fields[field].sourceModel) { - parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = - scope[list.name][i][form.fields[field].sourceField]; - if (parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) { - parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField] - .$setValidity('awlookup', true); - } - } - if (parent_scope[form.name + '_form']) { - parent_scope[form.name + '_form'].$setDirty(); - } - } - } - if (found) { - // Selection made - $('#lookup-modal-dialog').dialog('close'); - if (postAction) { - postAction(); - } - if (callback) { - parent_scope.$emit(callback); - } - } - }; - - - scope['toggle_' + list.iterator] = function (id) { - var count = 0; - scope[list.name].forEach( function(row, i) { - if (row.id === id) { - if (row.checked) { - scope[list.name][i].success_class = 'success'; - } - else { - row.checked = true; - scope[list.name][i].success_class = ''; - } - } else { - scope[list.name][i].checked = 0; - scope[list.name][i].success_class = ''; - } - }); - // Check if any rows are checked - scope[list.name].forEach(function(row) { - if (row.checked) { - count++; - } - }); - if (count === 0) { - $('#lookup-save-button').attr('disabled','disabled'); - } - else { - $('#lookup-save-button').removeAttr('disabled'); - } - }; - }; - }; - }]); diff --git a/awx/ui/client/src/lookup/lookup.block.less b/awx/ui/client/src/lookup/lookup.block.less new file mode 100644 index 0000000000..9f2dea25a9 --- /dev/null +++ b/awx/ui/client/src/lookup/lookup.block.less @@ -0,0 +1,22 @@ +@import "../shared/branding/colors.default.less"; + +#LookupModal-dialog { + .List-searchWidget { + width: 66.6666% + } + + .List-tableHeaderRow { + .List-tableHeader:first-of-type { + width: 3%; + } + } + + .List-tableHeader, + .List-tableHeader:last-of-type { + text-align:left; + } + + .List-tableCell { + color: @default-interface-txt; + } +} diff --git a/awx/ui/client/src/lookup/lookup.factory.js b/awx/ui/client/src/lookup/lookup.factory.js new file mode 100644 index 0000000000..468acbc4e6 --- /dev/null +++ b/awx/ui/client/src/lookup/lookup.factory.js @@ -0,0 +1,305 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + /** +* @ngdoc function +* @name helpers.function:Lookup +* @description +* LookUpInit( { +* scope: , +* form: , +* current_item: , +* list: , +* field: , +* hdr: +* postAction: optional function to run after selection made, +* callback: optional label to $emit() on parent scope +* input_type: optional string that specifies whether lookup should have checkboxes or radio buttons. defaults to 'checkbox' --- added by JT 8/21/14 +* }) +*/ + +export default ['Alert', 'Rest', 'ProcessErrors', 'generateList', + 'SearchInit', 'PaginateInit', 'GetBasePath', 'FormatDate', + 'Empty', 'CreateDialog', + function(Alert, Rest, ProcessErrors, GenerateList, + SearchInit, PaginateInit, GetBasePath, FormatDate, + Empty, CreateDialog) { + return function(params) { + + var parent_scope = params.scope, + form = params.form, + list = params.list, + field = params.field, + instructions = params.instructions, + postAction = params.postAction, + callback = params.callback, + autopopulateLookup, + input_type = (params.input_type) ? params.input_type : "checkbox", + defaultUrl, name, watchUrl; + + if (params.autopopulateLookup !== undefined) { + autopopulateLookup = params.autopopulateLookup; + } else { + autopopulateLookup = true; + } + + if (params.url) { + // pass in a url value to override the default + defaultUrl = params.url; + } else { + defaultUrl = (list.name === 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name); + } + + if ($('#htmlTemplate #LookupModal-dialog').length > 0) { + $('#htmlTemplate #LookupModal-dialog').empty(); + } else { + $('#htmlTemplate').append("
"); + } + + name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1); + + watchUrl = (/\/$/.test(defaultUrl)) ? defaultUrl + '?' : defaultUrl + '&'; + watchUrl += form.fields[field].sourceField + '__' + 'iexact=:value'; + + $('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-url', watchUrl); + $('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-source', field); + + var sourceModel = form.fields[field].sourceModel, + sourceField = form.fields[field].sourceField; + + // this logic makes sure that the form is being added, and that the lookup to be autopopulated is required + // we also look to see if the lookupinit autopopulateLookup parameter passed in by the controller is false + function fieldIsAutopopulatable() { + if (autopopulateLookup === false) { + return false; + } + if (parent_scope.mode === "add") { + if (parent_scope[sourceModel + "_field"].awRequiredWhen && + parent_scope[sourceModel + "_field"].awRequiredWhen.variable && + parent_scope[parent_scope[sourceModel + "_field"].awRequiredWhen.variable]) { + return true; + } else if (parent_scope[sourceModel + "_field"].addRequired === true) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + if (fieldIsAutopopulatable()) { + // Auto populate the field if there is only one result + Rest.setUrl(defaultUrl); + Rest.get() + .success(function(data) { + if (data.count === 1) { + parent_scope[field] = data.results[0].id; + if (parent_scope[form.name + '_form'] && form.fields[field] && sourceModel) { + parent_scope[sourceModel + '_' + sourceField] = + data.results[0][sourceField]; + if (parent_scope[form.name + '_form'][sourceModel + '_' + sourceField]) { + parent_scope[form.name + '_form'][sourceModel + '_' + sourceField] + .$setValidity('awlookup', true); + } + } + if (parent_scope[form.name + '_form']) { + parent_scope[form.name + '_form'].$setDirty(); + } + } + }) + .error(function(data, status) { + ProcessErrors(parent_scope, data, status, form, { + hdr: 'Error!', + msg: 'Failed to launch adhoc command. POST returned status: ' + + status + }); + }); + } + + + parent_scope['lookUp' + name] = function() { + + var master = {}, + scope = parent_scope.$new(), + name, hdr, buttons; + + // Generating the search list potentially kills the values held in scope for the field. + // We'll keep a copy in master{} that we can revert back to on cancel; + master[field] = scope[field]; + master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = + scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]; + GenerateList.inject(list, { + mode: 'lookup', + id: 'LookupModal-dialog', + scope: scope, + instructions: instructions, + input_type: input_type + }); + + name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1); + hdr = (params.hdr) ? params.hdr : 'Select ' + name; + + // Show pop-up + buttons = [{ + label: "Save", + onClick: function() { + scope.selectAction(); + }, + //icon: "fa-check", + "class": "btn btn-primary", + "id": "lookup-save-button" + }, { + label: "Cancel", + "class": "btn btn-default", + "id": "lookup-cancel-button", + onClick: function() { + $('#LookupModal-dialog').dialog('close'); + } + }]; + + if (scope.removeModalReady) { + scope.removeModalReady(); + } + scope.removeModalReady = scope.$on('ModalReady', function() { + $('#lookup-save-button').attr('disabled', 'disabled'); + $('#LookupModal-dialog').dialog('open'); + }); + + CreateDialog({ + scope: scope, + buttons: buttons, + width: 600, + height: (instructions) ? 625 : 450, + minWidth: 500, + title: hdr, + id: 'LookupModal-dialog', + onClose: function() { + setTimeout(function() { + scope.$apply(function() { + if (Empty(scope[field])) { + scope[field] = master[field]; + scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = + master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]; + } + }); + }, 300); + }, + callback: 'ModalReady' + }); + + SearchInit({ + scope: scope, + set: list.name, + list: list, + url: defaultUrl + }); + + PaginateInit({ + scope: scope, + list: list, + url: defaultUrl, + mode: 'lookup' + }); + + if (scope.lookupPostRefreshRemove) { + scope.lookupPostRefreshRemove(); + } + scope.lookupPostRefreshRemove = scope.$on('PostRefresh', function() { + var fld, i; + for (fld in list.fields) { + if (list.fields[fld].type && list.fields[fld].type === 'date') { + //convert dates to our standard format + for (i = 0; i < scope[list.name].length; i++) { + scope[list.name][i][fld] = FormatDate(new Date(scope[list.name][i][fld])); + } + } + } + + // List generator creates the list, resetting it and losing the previously selected value. + // If the selected value is in the current set, find it and mark selected. + if (!Empty(parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField])) { + scope[list.name].forEach(function(elem) { + if (elem[form.fields[field].sourceField] === + parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) { + scope[field] = elem.id; + } + }); + + } + + if (!Empty(scope[field])) { + scope['toggle_' + list.iterator](scope[field]); + } + + }); + + scope.search(list.iterator); + + scope.selectAction = function() { + var i, found = false; + for (i = 0; i < scope[list.name].length; i++) { + if (scope[list.name][i].checked === '1' || scope[list.name][i].checked === 1 || scope[list.name][i].checked === true) { + found = true; + parent_scope[field] = scope[list.name][i].id; + if (parent_scope[form.name + '_form'] && form.fields[field] && form.fields[field].sourceModel) { + parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = + scope[list.name][i][form.fields[field].sourceField]; + if (parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) { + parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField] + .$setValidity('awlookup', true); + } + } + if (parent_scope[form.name + '_form']) { + parent_scope[form.name + '_form'].$setDirty(); + } + } + } + if (found) { + // Selection made + $('#LookupModal-dialog').dialog('close'); + if (postAction) { + postAction(); + } + if (callback) { + parent_scope.$emit(callback); + } + } + }; + + + scope['toggle_' + list.iterator] = function(id) { + var count = 0; + scope[list.name].forEach(function(row, i) { + if (row.id === id) { + if (row.checked) { + scope[list.name][i].success_class = 'success'; + } else { + row.checked = true; + scope[list.name][i].success_class = ''; + } + } else { + scope[list.name][i].checked = 0; + scope[list.name][i].success_class = ''; + } + }); + // Check if any rows are checked + scope[list.name].forEach(function(row) { + if (row.checked) { + count++; + } + }); + if (count === 0) { + $('#lookup-save-button').attr('disabled', 'disabled'); + } else { + $('#lookup-save-button').removeAttr('disabled'); + } + }; + }; + }; + + } +]; diff --git a/awx/ui/client/src/lookup/main.js b/awx/ui/client/src/lookup/main.js new file mode 100644 index 0000000000..f5ead33d5b --- /dev/null +++ b/awx/ui/client/src/lookup/main.js @@ -0,0 +1,12 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ +import LookUpInit from './lookup.factory'; +import listGenerator from '../shared/list-generator/main'; + +export default + angular.module('LookUpHelper', ['RestServices', 'Utilities', 'SearchHelper', + 'PaginationHelpers', listGenerator.name, 'ApiLoader', 'ModalDialog']) + .factory('LookUpInit', LookUpInit); 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 @@
- + From c69534de145856e89bde30ef272f7b5bcd807010 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Wed, 24 Feb 2016 10:11:09 -0500 Subject: [PATCH 13/18] Attached sub form work to source control form in projects.js, added title plus some styling Added some breathing room at the bottom of the sub form --- awx/ui/client/legacy-styles/forms.less | 22 +++++++++ awx/ui/client/src/forms/Credentials.js | 54 +++++++++++++++------- awx/ui/client/src/forms/Projects.js | 17 +++++-- awx/ui/client/src/shared/form-generator.js | 27 +++++++++++ 4 files changed, 99 insertions(+), 21 deletions(-) diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 0556f7e1cd..f26f0c03d1 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%; } 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:

  • https://github.com/ansible/ansible.git
  • ' + @@ -135,14 +141,15 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) '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 !== 'manual'", addRequired: false, - editRequired: false + editRequired: false, + subForm: 'sourceSubForm' }, credential: { label: 'SCM Credential', @@ -152,12 +159,14 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) sourceField: 'name', ngClick: 'lookUpCredential()', addRequired: false, - editRequired: false + editRequired: false, + subForm: 'sourceSubForm' }, checkbox_group: { label: 'SCM Update Options', type: 'checkbox_group', ngShow: "scm_type && scm_type.value !== 'manual'", + subForm: 'sourceSubForm', fields: [{ name: 'scm_clean', label: 'Clean', 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"; } From 28f693b7bdbbf44f06d86e9b7bb9f649ef412898 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 25 Feb 2016 09:43:20 -0500 Subject: [PATCH 14/18] #951 #999 add missing dependency injection to unit test, fix misc styles --- awx/ui/client/legacy-styles/forms.less | 3 ++- awx/ui/client/src/adhoc/adhoc.controller.js | 2 +- awx/ui/client/src/controllers/Inventories.js | 1 - awx/ui/client/tests/adhoc/adhoc.controller-test.js | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 5f1ae9f449..86f10ec1c2 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -363,8 +363,9 @@ input[type='radio']:checked:before { display: flex; justify-content: flex-end; } + .Form-button{ - margin-left: 4px; + margin-left: 4px; } .Form-buttonDefault { diff --git a/awx/ui/client/src/adhoc/adhoc.controller.js b/awx/ui/client/src/adhoc/adhoc.controller.js index 17ca17783a..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 *************************************************/ diff --git a/awx/ui/client/src/controllers/Inventories.js b/awx/ui/client/src/controllers/Inventories.js index 9b2774bd98..916b812976 100644 --- a/awx/ui/client/src/controllers/Inventories.js +++ b/awx/ui/client/src/controllers/Inventories.js @@ -860,7 +860,6 @@ export function InventoriesManage ($log, $scope, $rootScope, $location, } $rootScope.hostPatterns = host_patterns; $state.go('inventoryManage.adhoc'); - //$location.path('/inventories/' + $scope.inventory.id + '/adhoc'); }; $scope.refreshHostsOnGroupRefresh = false; 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) { From 908bc92f943f4150fe6765b5fd257219f740a0f5 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 25 Feb 2016 09:58:35 -0500 Subject: [PATCH 15/18] more misc styles #951 #999 --- awx/ui/client/legacy-styles/forms.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 86f10ec1c2..df21f8534c 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -369,9 +369,9 @@ input[type='radio']:checked:before { } .Form-buttonDefault { - background-color: #FFFFFF; - color: #848992; - border-color: #E8E8E8; + background-color: @default-bg; + color: @default-interface-txt; + border-color: @default-border; } .Form-saveButton{ From a99e21521b227892646116492a90f77e4965fbf9 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 25 Feb 2016 10:16:15 -0500 Subject: [PATCH 16/18] force jenkins rebuild --- awx/ui/client/src/management-jobs/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/ui/client/src/management-jobs/main.js b/awx/ui/client/src/management-jobs/main.js index 35e6c10c76..e881baa0fb 100644 --- a/awx/ui/client/src/management-jobs/main.js +++ b/awx/ui/client/src/management-jobs/main.js @@ -1,5 +1,5 @@ /************************************************* - * Copyright (c) 2015 Ansible, Inc. + * Copyright (c) 2016 Ansible, Inc. * * All Rights Reserved *************************************************/ From f8fe6d9ae40346a2ecb2120a29ad467e15ba7151 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Thu, 25 Feb 2016 12:12:28 -0500 Subject: [PATCH 17/18] Removed Alert dependency. --- awx/ui/client/src/lookup/lookup.factory.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/src/lookup/lookup.factory.js b/awx/ui/client/src/lookup/lookup.factory.js index 468acbc4e6..e52dfb4876 100644 --- a/awx/ui/client/src/lookup/lookup.factory.js +++ b/awx/ui/client/src/lookup/lookup.factory.js @@ -21,10 +21,10 @@ * }) */ -export default ['Alert', 'Rest', 'ProcessErrors', 'generateList', +export default ['Rest', 'ProcessErrors', 'generateList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'FormatDate', 'Empty', 'CreateDialog', - function(Alert, Rest, ProcessErrors, GenerateList, + function(Rest, ProcessErrors, GenerateList, SearchInit, PaginateInit, GetBasePath, FormatDate, Empty, CreateDialog) { return function(params) { From 393db691ed07492a1d5652b994cdee522db7292a Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Thu, 25 Feb 2016 12:15:07 -0500 Subject: [PATCH 18/18] Cleaned up indentation. --- awx/ui/client/legacy-styles/forms.less | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index f26f0c03d1..cadb7f14eb 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -142,15 +142,15 @@ } .Form-subForm { - width: 100%; - border-left: 5px solid @default-border; - margin-left: -20px; - padding-left: 15px; - margin-bottom: 15px; + width: 100%; + border-left: 5px solid @default-border; + margin-left: -20px; + padding-left: 15px; + margin-bottom: 15px; - .Form-formGroup { - float: left; - } + .Form-formGroup { + float: left; + } } .Form-subForm--title {