diff --git a/awx/ui/client/src/forms/ActivityDetail.js b/awx/ui/client/src/activity-stream/activity-detail.form.js similarity index 89% rename from awx/ui/client/src/forms/ActivityDetail.js rename to awx/ui/client/src/activity-stream/activity-detail.form.js index 3c80f5b263..50ac02a570 100644 --- a/awx/ui/client/src/forms/ActivityDetail.js +++ b/awx/ui/client/src/activity-stream/activity-detail.form.js @@ -16,9 +16,7 @@ * @description This form is for activity detail modal that can be shown on most pages. */ -export default - angular.module('ActivityDetailDefinition', []) - .factory('ActivityDetailForm', ['i18n', function(i18n) { +export default ['i18n', function(i18n) { return { name: 'activity', @@ -48,4 +46,4 @@ export default } } - };}]); //Form + };}]; diff --git a/awx/ui/client/src/activity-stream/activitystream.controller.js b/awx/ui/client/src/activity-stream/activitystream.controller.js index ada72d572c..b7333b0bab 100644 --- a/awx/ui/client/src/activity-stream/activitystream.controller.js +++ b/awx/ui/client/src/activity-stream/activitystream.controller.js @@ -9,45 +9,47 @@ * @name controllers.function:Activity Stream * @description This controller controls the activity stream. */ -function activityStreamController($scope, $state, subTitle, Stream, GetTargetTitle, list, Dataset) { +export default ['$scope', '$state', 'subTitle', 'Stream', 'GetTargetTitle', + 'StreamList', 'Dataset', + function activityStreamController($scope, $state, subTitle, Stream, + GetTargetTitle, list, Dataset) { - init(); - initOmitSmartTags(); + init(); + initOmitSmartTags(); - function init() { - // search init - $scope.list = list; - $scope[`${list.iterator}_dataset`] = Dataset.data; - $scope[list.name] = $scope[`${list.iterator}_dataset`].results; + function init() { + // search init + $scope.list = list; + $scope[`${list.iterator}_dataset`] = Dataset.data; + $scope[list.name] = $scope[`${list.iterator}_dataset`].results; - // subTitle is passed in via a resolve on the route. If there is no subtitle - // generated in the resolve then we go get the targets generic title. + // subTitle is passed in via a resolve on the route. If there is no subtitle + // generated in the resolve then we go get the targets generic title. - // Get the streams sub-title based on the target. This scope variable is leveraged - // when we define the activity stream list. Specifically it is included in the list - // title. - $scope.streamSubTitle = subTitle ? subTitle : GetTargetTitle($state.params.target); + // Get the streams sub-title based on the target. This scope variable is leveraged + // when we define the activity stream list. Specifically it is included in the list + // title. + $scope.streamSubTitle = subTitle ? subTitle : GetTargetTitle($state.params.target); - // Open the stream - Stream({ - scope: $scope - }); - } + // Open the stream + Stream({ + scope: $scope + }); + } - // Specification of smart-tags omission from the UI is done in the route/state init. - // A limitation is that this specficiation is static and the key for which to be omitted from - // the smart-tags must be known at that time. - // In the case of activity stream, we won't to dynamically ommit the resource for which we are - // displaying the activity stream for. i.e. 'project', 'credential', etc. - function initOmitSmartTags() { - let defaults, route = _.find($state.$current.path, (step) => { - return step.params.hasOwnProperty('activity_search'); - }); - if (route && $state.params.target !== undefined) { - defaults = route.params.activity_search.config.value; - defaults[$state.params.target] = null; + // Specification of smart-tags omission from the UI is done in the route/state init. + // A limitation is that this specficiation is static and the key for which to be omitted from + // the smart-tags must be known at that time. + // In the case of activity stream, we won't to dynamically ommit the resource for which we are + // displaying the activity stream for. i.e. 'project', 'credential', etc. + function initOmitSmartTags() { + let defaults, route = _.find($state.$current.path, (step) => { + return step.params.hasOwnProperty('activity_search'); + }); + if (route && $state.params.target !== undefined) { + defaults = route.params.activity_search.config.value; + defaults[$state.params.target] = null; + } } } -} - -export default ['$scope', '$state', 'subTitle', 'Stream', 'GetTargetTitle', 'StreamList', 'Dataset', activityStreamController]; +]; diff --git a/awx/ui/client/src/activity-stream/activitystream.route.js b/awx/ui/client/src/activity-stream/activitystream.route.js index 5b99ce55bd..22ef581bc6 100644 --- a/awx/ui/client/src/activity-stream/activitystream.route.js +++ b/awx/ui/client/src/activity-stream/activitystream.route.js @@ -60,8 +60,8 @@ export default { return qs.search(path, stateParams); } ], - features: ['FeaturesService', 'ProcessErrors', '$state', '$rootScope', - function(FeaturesService, ProcessErrors, $state, $rootScope) { + features: ['FeaturesService', '$state', '$rootScope', + function(FeaturesService, $state, $rootScope) { var features = FeaturesService.get(); if (features) { if (FeaturesService.featureEnabled('activity_streams')) { @@ -81,12 +81,10 @@ export default { }); } ], - subTitle: ['$stateParams', - 'Rest', - 'ModelToBasePathKey', - 'GetBasePath', + subTitle: ['$stateParams', 'Rest', 'ModelToBasePathKey', 'GetBasePath', 'ProcessErrors', - function($stateParams, rest, ModelToBasePathKey, getBasePath, ProcessErrors) { + function($stateParams, rest, ModelToBasePathKey, getBasePath, + ProcessErrors) { // If we have a target and an ID then we want to go grab the name of the object // that we're examining with the activity stream. This name will be used in the // subtitle. diff --git a/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js b/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js index 80ba348b41..f3ccd0b9b0 100644 --- a/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js +++ b/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js @@ -1,78 +1,77 @@ -export default - function BuildAnchor($log, $filter) { - // Returns a full resource_name HTML string if link can be derived from supplied context - // returns name of resource if activity stream object doesn't contain enough data to build a UI url - // arguments are: a summary_field object, a resource type, an activity stream object - return function (obj, resource, activity) { - var url = '/#/'; - // try/except pattern asserts that: - // if we encounter a case where a UI url can't or shouldn't be generated, just supply the name of the resource - try { - // catch-all case to avoid generating urls if a resource has been deleted - // if a resource still exists, it'll be serialized in the activity's summary_fields - if (!activity.summary_fields[resource]){ - throw {name : 'ResourceDeleted', message: 'The referenced resource no longer exists'}; - } - switch (resource) { - case 'custom_inventory_script': - url += 'inventory_scripts/' + obj.id + '/'; - break; - case 'group': - if (activity.operation === 'create' || activity.operation === 'delete'){ - // the API formats the changes.inventory field as str 'myInventoryName-PrimaryKey' - var inventory_id = _.last(activity.changes.inventory.split('-')); - url += 'inventories/' + inventory_id + '/manage?group=' + activity.changes.id; - } - else { - url += 'inventories/' + activity.summary_fields.inventory[0].id + '/manage?group=' + (activity.changes.id || activity.changes.object1_pk); - } - break; - case 'host': - url += 'home/hosts/' + obj.id; - break; - case 'job': - url += 'jobs/' + obj.id; - break; - case 'inventory': - url += 'inventories/' + obj.id + '/'; - break; - case 'schedule': - // schedule urls depend on the resource they're associated with - if (activity.summary_fields.job_template){ - url += 'job_templates/' + activity.summary_fields.job_template.id + '/schedules/' + obj.id; - } - else if (activity.summary_fields.project){ - url += 'projects/' + activity.summary_fields.project.id + '/schedules/' + obj.id; - } - else if (activity.summary_fields.system_job_template){ - url += 'management_jobs/' + activity.summary_fields.system_job_template.id + '/schedules/edit/' + obj.id; - } - // urls for inventory sync schedules currently depend on having an inventory id and group id - else { - throw {name : 'NotImplementedError', message : 'activity.summary_fields to build this url not implemented yet'}; - } - break; - case 'notification_template': - url += `notification_templates/${obj.id}`; - break; - case 'role': - throw {name : 'NotImplementedError', message : 'role object management is not consolidated to a single UI view'}; - case 'job_template': - url += `templates/job_template/${obj.id}`; - break; - case 'workflow_job_template': - url += `templates/workflow_job_template/${obj.id}`; - break; - default: - url += resource + 's/' + obj.id + '/'; - } - return ' ' + $filter('sanitize')(obj.name || obj.username) + ' '; +export default function BuildAnchor($log, $filter) { + // Returns a full resource_name HTML string if link can be derived from supplied context + // returns name of resource if activity stream object doesn't contain enough data to build a UI url + // arguments are: a summary_field object, a resource type, an activity stream object + return function (obj, resource, activity) { + var url = '/#/'; + // try/except pattern asserts that: + // if we encounter a case where a UI url can't or shouldn't be generated, just supply the name of the resource + try { + // catch-all case to avoid generating urls if a resource has been deleted + // if a resource still exists, it'll be serialized in the activity's summary_fields + if (!activity.summary_fields[resource]){ + throw {name : 'ResourceDeleted', message: 'The referenced resource no longer exists'}; } - catch(err){ - $log.debug(err); - return ' ' + $filter('sanitize')(obj.name || obj.username || '') + ' '; + switch (resource) { + case 'custom_inventory_script': + url += 'inventory_scripts/' + obj.id + '/'; + break; + case 'group': + if (activity.operation === 'create' || activity.operation === 'delete'){ + // the API formats the changes.inventory field as str 'myInventoryName-PrimaryKey' + var inventory_id = _.last(activity.changes.inventory.split('-')); + url += 'inventories/' + inventory_id + '/manage?group=' + activity.changes.id; + } + else { + url += 'inventories/' + activity.summary_fields.inventory[0].id + '/manage?group=' + (activity.changes.id || activity.changes.object1_pk); + } + break; + case 'host': + url += 'home/hosts/' + obj.id; + break; + case 'job': + url += 'jobs/' + obj.id; + break; + case 'inventory': + url += 'inventories/' + obj.id + '/'; + break; + case 'schedule': + // schedule urls depend on the resource they're associated with + if (activity.summary_fields.job_template){ + url += 'job_templates/' + activity.summary_fields.job_template.id + '/schedules/' + obj.id; + } + else if (activity.summary_fields.project){ + url += 'projects/' + activity.summary_fields.project.id + '/schedules/' + obj.id; + } + else if (activity.summary_fields.system_job_template){ + url += 'management_jobs/' + activity.summary_fields.system_job_template.id + '/schedules/edit/' + obj.id; + } + // urls for inventory sync schedules currently depend on having an inventory id and group id + else { + throw {name : 'NotImplementedError', message : 'activity.summary_fields to build this url not implemented yet'}; + } + break; + case 'notification_template': + url += `notification_templates/${obj.id}`; + break; + case 'role': + throw {name : 'NotImplementedError', message : 'role object management is not consolidated to a single UI view'}; + case 'job_template': + url += `templates/job_template/${obj.id}`; + break; + case 'workflow_job_template': + url += `templates/workflow_job_template/${obj.id}`; + break; + default: + url += resource + 's/' + obj.id + '/'; } - }; - } + return ' ' + $filter('sanitize')(obj.name || obj.username) + ' '; + } + catch(err){ + $log.debug(err); + return ' ' + $filter('sanitize')(obj.name || obj.username || '') + ' '; + } + }; +} BuildAnchor.$inject = ['$log', '$filter']; diff --git a/awx/ui/client/src/activity-stream/factories/build-description.factory.js b/awx/ui/client/src/activity-stream/factories/build-description.factory.js index ecd596dda2..967ff8bb5a 100644 --- a/awx/ui/client/src/activity-stream/factories/build-description.factory.js +++ b/awx/ui/client/src/activity-stream/factories/build-description.factory.js @@ -1,126 +1,125 @@ -export default - function BuildDescription(BuildAnchor, $log, i18n) { - return function (activity) { +export default function BuildDescription(BuildAnchor, $log, i18n) { + return function (activity) { - var pastTense = function(operation){ - return (/e$/.test(activity.operation)) ? operation + 'd ' : operation + 'ed '; - }; - // convenience method to see if dis+association operation involves 2 groups - // the group cases are slightly different because groups can be dis+associated into each other - var isGroupRelationship = function(activity){ - return activity.object1 === 'group' && activity.object2 === 'group' && activity.summary_fields.group.length > 1; - }; - - // Activity stream objects will outlive the resources they reference - // in that case, summary_fields will not be available - show generic error text instead - try { - activity.description = pastTense(activity.operation); - switch(activity.object_association){ - // explicit role dis+associations - case 'role': - // object1 field is resource targeted by the dis+association - // object2 field is the resource the role is inherited from - // summary_field.role[0] contains ref info about the role - switch(activity.operation){ - // expected outcome: "disassociated role_name from " - case 'disassociate': - if (isGroupRelationship(activity)){ - activity.description += BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + activity.summary_fields.role[0].role_field + - ' from ' + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); - } - else{ - activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + - ' from ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); - } - break; - // expected outcome: "associated role_name to " - case 'associate': - if (isGroupRelationship(activity)){ - activity.description += BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + activity.summary_fields.role[0].role_field + - ' to ' + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); - } - else{ - activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + - ' to ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); - } - break; - } - break; - // inherited role dis+associations (logic identical to case 'role') - case 'parents': - // object1 field is resource targeted by the dis+association - // object2 field is the resource the role is inherited from - // summary_field.role[0] contains ref info about the role - switch(activity.operation){ - // expected outcome: "disassociated role_name from " - case 'disassociate': - if (isGroupRelationship(activity)){ - activity.description += activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + - 'from ' + activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); - } - else{ - activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + - ' from ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); - } - break; - // expected outcome: "associated role_name to " - case 'associate': - if (isGroupRelationship(activity)){ - activity.description += activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity) + - 'to ' + activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity); - } - else{ - activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + - ' to ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); - } - break; - } - break; - // CRUD operations / resource on resource dis+associations - default: - switch(activity.operation){ - // expected outcome: "disassociated from " - case 'disassociate' : - if (isGroupRelationship(activity)){ - activity.description += activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + - 'from ' + activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); - } - else { - activity.description += activity.object2 + BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + - 'from ' + activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); - } - break; - // expected outcome "associated to " - case 'associate': - // groups are the only resource that can be associated/disassociated into each other - if (isGroupRelationship(activity)){ - activity.description += activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity) + - 'to ' + activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity); - } - else { - activity.description += activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity) + - 'to ' + activity.object2 + BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity); - } - break; - case 'delete': - activity.description += activity.object1 + BuildAnchor(activity.changes, activity.object1, activity); - break; - // expected outcome: "operation " - case 'update': - activity.description += activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); - break; - case 'create': - activity.description += activity.object1 + BuildAnchor(activity.changes, activity.object1, activity); - break; - } - break; - } - } - catch(err){ - $log.debug(err); - activity.description = i18n._('Event summary not available'); - } + var pastTense = function(operation){ + return (/e$/.test(activity.operation)) ? operation + 'd ' : operation + 'ed '; + }; + // convenience method to see if dis+association operation involves 2 groups + // the group cases are slightly different because groups can be dis+associated into each other + var isGroupRelationship = function(activity){ + return activity.object1 === 'group' && activity.object2 === 'group' && activity.summary_fields.group.length > 1; }; - } - BuildDescription.$inject = ['BuildAnchor', '$log', 'i18n']; + // Activity stream objects will outlive the resources they reference + // in that case, summary_fields will not be available - show generic error text instead + try { + activity.description = pastTense(activity.operation); + switch(activity.object_association){ + // explicit role dis+associations + case 'role': + // object1 field is resource targeted by the dis+association + // object2 field is the resource the role is inherited from + // summary_field.role[0] contains ref info about the role + switch(activity.operation){ + // expected outcome: "disassociated role_name from " + case 'disassociate': + if (isGroupRelationship(activity)){ + activity.description += BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + activity.summary_fields.role[0].role_field + + ' from ' + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); + } + else{ + activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + + ' from ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); + } + break; + // expected outcome: "associated role_name to " + case 'associate': + if (isGroupRelationship(activity)){ + activity.description += BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + activity.summary_fields.role[0].role_field + + ' to ' + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); + } + else{ + activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + + ' to ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); + } + break; + } + break; + // inherited role dis+associations (logic identical to case 'role') + case 'parents': + // object1 field is resource targeted by the dis+association + // object2 field is the resource the role is inherited from + // summary_field.role[0] contains ref info about the role + switch(activity.operation){ + // expected outcome: "disassociated role_name from " + case 'disassociate': + if (isGroupRelationship(activity)){ + activity.description += activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + + 'from ' + activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); + } + else{ + activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + + ' from ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); + } + break; + // expected outcome: "associated role_name to " + case 'associate': + if (isGroupRelationship(activity)){ + activity.description += activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity) + + 'to ' + activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity); + } + else{ + activity.description += BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + activity.summary_fields.role[0].role_field + + ' to ' + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); + } + break; + } + break; + // CRUD operations / resource on resource dis+associations + default: + switch(activity.operation){ + // expected outcome: "disassociated from " + case 'disassociate' : + if (isGroupRelationship(activity)){ + activity.description += activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity) + + 'from ' + activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity); + } + else { + activity.description += activity.object2 + BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity) + + 'from ' + activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); + } + break; + // expected outcome "associated to " + case 'associate': + // groups are the only resource that can be associated/disassociated into each other + if (isGroupRelationship(activity)){ + activity.description += activity.object1 + BuildAnchor(activity.summary_fields.group[0], activity.object1, activity) + + 'to ' + activity.object2 + BuildAnchor(activity.summary_fields.group[1], activity.object2, activity); + } + else { + activity.description += activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity) + + 'to ' + activity.object2 + BuildAnchor(activity.summary_fields[activity.object2][0], activity.object2, activity); + } + break; + case 'delete': + activity.description += activity.object1 + BuildAnchor(activity.changes, activity.object1, activity); + break; + // expected outcome: "operation " + case 'update': + activity.description += activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity); + break; + case 'create': + activity.description += activity.object1 + BuildAnchor(activity.changes, activity.object1, activity); + break; + } + break; + } + } + catch(err){ + $log.debug(err); + activity.description = i18n._('Event summary not available'); + } + }; + } + +BuildDescription.$inject = ['BuildAnchor', '$log', 'i18n']; diff --git a/awx/ui/client/src/activity-stream/factories/show-detail.factory.js b/awx/ui/client/src/activity-stream/factories/show-detail.factory.js index fde935e108..f705534db0 100644 --- a/awx/ui/client/src/activity-stream/factories/show-detail.factory.js +++ b/awx/ui/client/src/activity-stream/factories/show-detail.factory.js @@ -1,39 +1,40 @@ -export default - function ShowDetail($filter, $rootScope, Rest, Alert, GenerateForm, ProcessErrors, GetBasePath, FormatDate, ActivityDetailForm, Empty, Find) { - return function (params, scope) { +export default function ShowDetail($filter, $rootScope, Rest, Alert, +GenerateForm, ProcessErrors, GetBasePath, FormatDate, ActivityDetailForm, +Empty, Find) { + return function (params, scope) { - var activity_id = params.activity_id, - activity = Find({ list: params.scope.activities, key: 'id', val: activity_id }), - element; + var activity_id = params.activity_id, + activity = Find({ list: params.scope.activities, key: 'id', val: activity_id }), + element; - if (activity) { + if (activity) { - // Grab our element out of the dom - element = angular.element(document.getElementById('stream-detail-modal')); + // Grab our element out of the dom + element = angular.element(document.getElementById('stream-detail-modal')); - // Grab the modal's scope so that we can set a few variables - scope = element.scope(); + // Grab the modal's scope so that we can set a few variables + scope = element.scope(); - scope.changes = activity.changes; - scope.user = ((activity.summary_fields.actor) ? activity.summary_fields.actor.username : 'system') + - ' on ' + $filter('longDate')(activity.timestamp); - scope.operation = activity.description; - scope.header = "Event " + activity.id; + scope.changes = activity.changes; + scope.user = ((activity.summary_fields.actor) ? activity.summary_fields.actor.username : 'system') + + ' on ' + $filter('longDate')(activity.timestamp); + scope.operation = activity.description; + scope.header = "Event " + activity.id; - // Open the modal - $('#stream-detail-modal').modal({ - show: true, - backdrop: 'static', - keyboard: true - }); + // Open the modal + $('#stream-detail-modal').modal({ + show: true, + backdrop: 'static', + keyboard: true + }); - if (!scope.$$phase) { - scope.$digest(); - } + if (!scope.$$phase) { + scope.$digest(); } + } - }; - } + }; + } ShowDetail.$inject = ['$filter', '$rootScope', 'Rest', 'Alert', 'GenerateForm', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ActivityDetailForm', 'Empty', 'Find']; diff --git a/awx/ui/client/src/activity-stream/factories/stream.factory.js b/awx/ui/client/src/activity-stream/factories/stream.factory.js index b3725fc2aa..bb7f92fb16 100644 --- a/awx/ui/client/src/activity-stream/factories/stream.factory.js +++ b/awx/ui/client/src/activity-stream/factories/stream.factory.js @@ -1,53 +1,52 @@ -export default - function Stream($rootScope, $location, $state, Rest, GetBasePath, ProcessErrors, - Wait, StreamList, GenerateList, FormatDate, - BuildDescription, ShowDetail) { - return function (params) { +export default function Stream($rootScope, $location, $state, Rest, GetBasePath, +ProcessErrors, Wait, StreamList, GenerateList, FormatDate, BuildDescription, +ShowDetail) { + return function (params) { - var scope = params.scope; + var scope = params.scope; - $rootScope.flashMessage = null; + $rootScope.flashMessage = null; - // descriptive title describing what AS is showing - scope.streamTitle = (params && params.title) ? params.title : null; - - scope.refreshStream = function () { - $state.go('.', null, {reload: true}); - }; - - scope.showDetail = function (id) { - ShowDetail({ - scope: scope, - activity_id: id - }); - }; - - if(scope.activities && scope.activities.length > 0) { - buildUserAndDescription(); - } - - scope.$watch('activities', function(){ - // Watch for future update to scope.activities (like page change, column sort, search, etc) - buildUserAndDescription(); - }); - - function buildUserAndDescription(){ - scope.activities.forEach(function(activity, i) { - // build activity.user - if (scope.activities[i].summary_fields.actor) { - scope.activities[i].user = "" + - scope.activities[i].summary_fields.actor.username + ""; - } else { - scope.activities[i].user = 'system'; - } - // build description column / action text - BuildDescription(scope.activities[i]); - - }); - } + // descriptive title describing what AS is showing + scope.streamTitle = (params && params.title) ? params.title : null; + scope.refreshStream = function () { + $state.go('.', null, {reload: true}); }; - } + + scope.showDetail = function (id) { + ShowDetail({ + scope: scope, + activity_id: id + }); + }; + + if(scope.activities && scope.activities.length > 0) { + buildUserAndDescription(); + } + + scope.$watch('activities', function(){ + // Watch for future update to scope.activities (like page change, column sort, search, etc) + buildUserAndDescription(); + }); + + function buildUserAndDescription(){ + scope.activities.forEach(function(activity, i) { + // build activity.user + if (scope.activities[i].summary_fields.actor) { + scope.activities[i].user = "" + + scope.activities[i].summary_fields.actor.username + ""; + } else { + scope.activities[i].user = 'system'; + } + // build description column / action text + BuildDescription(scope.activities[i]); + + }); + } + + }; + } Stream.$inject = ['$rootScope', '$location', '$state', 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', 'StreamList', 'generateList', 'FormatDate', 'BuildDescription', diff --git a/awx/ui/client/src/activity-stream/get-target-title.factory.js b/awx/ui/client/src/activity-stream/get-target-title.factory.js index 85c6c7a80b..543b6acdb3 100644 --- a/awx/ui/client/src/activity-stream/get-target-title.factory.js +++ b/awx/ui/client/src/activity-stream/get-target-title.factory.js @@ -1,51 +1,50 @@ -export default - function GetTargetTitle(i18n) { - return function (target) { +export default function GetTargetTitle(i18n) { + return function (target) { - var rtnTitle = i18n._('ALL ACTIVITY'); + var rtnTitle = i18n._('ALL ACTIVITY'); - switch(target) { - case 'project': - rtnTitle = i18n._('PROJECTS'); - break; - case 'inventory': - rtnTitle = i18n._('INVENTORIES'); - break; - case 'credential': - rtnTitle = i18n._('CREDENTIALS'); - break; - case 'user': - rtnTitle = i18n._('USERS'); - break; - case 'team': - rtnTitle = i18n._('TEAMS'); - break; - case 'notification_template': - rtnTitle = i18n._('NOTIFICATION TEMPLATES'); - break; - case 'organization': - rtnTitle = i18n._('ORGANIZATIONS'); - break; - case 'job': - rtnTitle = i18n._('JOBS'); - break; - case 'custom_inventory_script': - rtnTitle = i18n._('INVENTORY SCRIPTS'); - break; - case 'schedule': - rtnTitle = i18n._('SCHEDULES'); - break; - case 'host': - rtnTitle = i18n._('HOSTS'); - break; - case 'template': - rtnTitle = i18n._('TEMPLATES'); - break; - } + switch(target) { + case 'project': + rtnTitle = i18n._('PROJECTS'); + break; + case 'inventory': + rtnTitle = i18n._('INVENTORIES'); + break; + case 'credential': + rtnTitle = i18n._('CREDENTIALS'); + break; + case 'user': + rtnTitle = i18n._('USERS'); + break; + case 'team': + rtnTitle = i18n._('TEAMS'); + break; + case 'notification_template': + rtnTitle = i18n._('NOTIFICATION TEMPLATES'); + break; + case 'organization': + rtnTitle = i18n._('ORGANIZATIONS'); + break; + case 'job': + rtnTitle = i18n._('JOBS'); + break; + case 'custom_inventory_script': + rtnTitle = i18n._('INVENTORY SCRIPTS'); + break; + case 'schedule': + rtnTitle = i18n._('SCHEDULES'); + break; + case 'host': + rtnTitle = i18n._('HOSTS'); + break; + case 'template': + rtnTitle = i18n._('TEMPLATES'); + break; + } - return rtnTitle; + return rtnTitle; - }; - } + }; +} GetTargetTitle.$inject = ['i18n']; diff --git a/awx/ui/client/src/activity-stream/main.js b/awx/ui/client/src/activity-stream/main.js index 3cb93e3003..b1e625e2d7 100644 --- a/awx/ui/client/src/activity-stream/main.js +++ b/awx/ui/client/src/activity-stream/main.js @@ -14,6 +14,8 @@ import ShowDetail from './factories/show-detail.factory'; import Stream from './factories/stream.factory'; import GetTargetTitle from './get-target-title.factory'; import ModelToBasePathKey from './model-to-base-path-key.factory'; +import ActivityDetailForm from './activity-detail.form'; +import StreamList from './streams.list'; export default angular.module('activityStream', [streamDetailModal.name]) .controller('activityStreamController', activityStreamController) @@ -24,6 +26,8 @@ export default angular.module('activityStream', [streamDetailModal.name]) .factory('Stream', Stream) .factory('GetTargetTitle', GetTargetTitle) .factory('ModelToBasePathKey', ModelToBasePathKey) + .factory('ActivityDetailForm', ActivityDetailForm) + .factory('StreamList', StreamList) .run(['$stateExtender', function($stateExtender) { $stateExtender.addState(activityStreamRoute); }]); diff --git a/awx/ui/client/src/activity-stream/model-to-base-path-key.factory.js b/awx/ui/client/src/activity-stream/model-to-base-path-key.factory.js index bc6cfe74b8..ebad019b02 100644 --- a/awx/ui/client/src/activity-stream/model-to-base-path-key.factory.js +++ b/awx/ui/client/src/activity-stream/model-to-base-path-key.factory.js @@ -10,50 +10,49 @@ * @description Helper functions to convert singular/plural versions of our models to the opposite */ -export default - function ModelToBasePathKey() { - return function(model) { - // This function takes in the singular model string and returns the key needed - // to get the base path from $rootScope/local storage. +export default function ModelToBasePathKey() { + return function(model) { + // This function takes in the singular model string and returns the key needed + // to get the base path from $rootScope/local storage. - var basePathKey; + var basePathKey; - switch(model) { - case 'project': - basePathKey = 'projects'; - break; - case 'inventory': - basePathKey = 'inventory'; - break; - case 'job_template': - basePathKey = 'job_templates'; - break; - case 'credential': - basePathKey = 'credentials'; - break; - case 'user': - basePathKey = 'users'; - break; - case 'team': - basePathKey = 'teams'; - break; - case 'notification_template': - basePathKey = 'notification_templates'; - break; - case 'organization': - basePathKey = 'organizations'; - break; - case 'management_job': - basePathKey = 'management_jobs'; - break; - case 'custom_inventory_script': - basePathKey = 'inventory_scripts'; - break; - case 'workflow_job_template': - basePathKey = 'workflow_job_templates'; - break; - } + switch(model) { + case 'project': + basePathKey = 'projects'; + break; + case 'inventory': + basePathKey = 'inventory'; + break; + case 'job_template': + basePathKey = 'job_templates'; + break; + case 'credential': + basePathKey = 'credentials'; + break; + case 'user': + basePathKey = 'users'; + break; + case 'team': + basePathKey = 'teams'; + break; + case 'notification_template': + basePathKey = 'notification_templates'; + break; + case 'organization': + basePathKey = 'organizations'; + break; + case 'management_job': + basePathKey = 'management_jobs'; + break; + case 'custom_inventory_script': + basePathKey = 'inventory_scripts'; + break; + case 'workflow_job_template': + basePathKey = 'workflow_job_templates'; + break; + } - return basePathKey; - }; - } + return basePathKey; + }; +} diff --git a/awx/ui/client/src/lists/Streams.js b/awx/ui/client/src/activity-stream/streams.list.js similarity index 95% rename from awx/ui/client/src/lists/Streams.js rename to awx/ui/client/src/activity-stream/streams.list.js index 12ae770ee8..e1699741e6 100644 --- a/awx/ui/client/src/lists/Streams.js +++ b/awx/ui/client/src/activity-stream/streams.list.js @@ -5,9 +5,7 @@ *************************************************/ -export default - angular.module('StreamListDefinition', []) - .factory('StreamList', ['i18n', function(i18n) { +export default ['i18n', function(i18n) { return { name: 'activities', @@ -72,4 +70,4 @@ export default } } - };}]); + };}]; diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index a298b634bd..4b3c5e6ed8 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -37,8 +37,6 @@ if ($basePath) { } // Modules -import './forms'; -import './lists'; import portalMode from './portal-mode/main'; import systemTracking from './system-tracking/main'; import inventories from './inventories/main'; @@ -89,6 +87,8 @@ var tower = angular.module('Tower', [ 'I18N', uiRouter, 'ui.router.state.events', + 'pendolytics', + 'lrInfiniteScroll', about.name, access.name, @@ -100,7 +100,6 @@ var tower = angular.module('Tower', [ inventories.name, inventoryScripts.name, organizations.name, - //permissions.name, managementJobs.name, setupMenu.name, mainMenu.name, @@ -121,53 +120,16 @@ var tower = angular.module('Tower', [ teams.name, users.name, projects.name, - //'templates', + scheduler.name, + 'Utilities', - 'OrganizationFormDefinition', - 'UserFormDefinition', - 'OrganizationListDefinition', 'templates', - 'UserListDefinition', 'PromptDialog', 'AWDirectives', - 'InventoriesListDefinition', - 'InventoryFormDefinition', - 'InventoryGroupsDefinition', - 'InventoryHostsDefinition', - 'HostFormDefinition', - 'HostListDefinition', - 'GroupFormDefinition', - 'GroupListDefinition', - 'TeamsListDefinition', - 'TeamFormDefinition', - 'CredentialsListDefinition', - 'CredentialFormDefinition', - 'TemplatesListDefinition', - 'PortalJobTemplatesListDefinition', - 'JobTemplateFormDefinition', - 'CompletedJobsDefinition', - 'AllJobsDefinition', - 'JobSummaryDefinition', - 'HostGroupsFormDefinition', - 'StreamListDefinition', - 'ActivityDetailDefinition', - 'SchedulesListDefinition', - 'ScheduledJobsDefinition', - //'Timezones', - 'JobsListDefinition', - 'LogViewerStatusDefinition', - 'LogViewerOptionsDefinition', - 'lrInfiniteScroll', - 'PortalJobsListDefinition', 'features', - 'pendolytics', - scheduler.name, - 'WorkflowFormDefinition', - 'InventorySourcesListDefinition', - 'WorkflowMakerFormDefinition' ]) -.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/') + .constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/') .constant('AngularScheduler.useTimezone', true) .constant('AngularScheduler.showUTCField', true) .constant('$timezones.definitions.location', urlPrefix + 'lib/angular-tz-extensions/tz/data') diff --git a/awx/ui/client/src/credentials/add/credentials-add.controller.js b/awx/ui/client/src/credentials/add/credentials-add.controller.js index 5671128323..e6daef660f 100644 --- a/awx/ui/client/src/credentials/add/credentials-add.controller.js +++ b/awx/ui/client/src/credentials/add/credentials-add.controller.js @@ -4,14 +4,13 @@ * All Rights Reserved *************************************************/ -export default ['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'CredentialForm', 'GenerateForm', 'Rest', 'Alert', - 'ProcessErrors', 'ClearScope', 'GetBasePath', 'GetChoices', 'Empty', 'KindChange', 'BecomeMethodChange', +export default ['$scope', '$rootScope', '$stateParams', 'CredentialForm', + 'GenerateForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath', + 'GetChoices', 'Empty', 'KindChange', 'BecomeMethodChange', 'OwnerChange', 'CredentialFormSave', '$state', 'CreateSelect2', 'i18n', - function($scope, $rootScope, $compile, $location, $log, - $stateParams, CredentialForm, GenerateForm, Rest, Alert, ProcessErrors, - ClearScope, GetBasePath, GetChoices, Empty, KindChange, BecomeMethodChange, - OwnerChange, CredentialFormSave, $state, CreateSelect2, i18n) { + function($scope, $rootScope, $stateParams, CredentialForm, GenerateForm, + Rest, ProcessErrors, ClearScope, GetBasePath, GetChoices, Empty, KindChange, + BecomeMethodChange, OwnerChange, CredentialFormSave, $state, CreateSelect2, i18n) { ClearScope(); diff --git a/awx/ui/client/src/forms/Credentials.js b/awx/ui/client/src/credentials/credentials.form.js similarity index 99% rename from awx/ui/client/src/forms/Credentials.js rename to awx/ui/client/src/credentials/credentials.form.js index 89af5ea7b9..d2a201fdd1 100644 --- a/awx/ui/client/src/forms/Credentials.js +++ b/awx/ui/client/src/credentials/credentials.form.js @@ -10,9 +10,7 @@ * @description This form is for adding/editing a Credential */ -export default - angular.module('CredentialFormDefinition', []) - .factory('CredentialForm', ['i18n', function(i18n) { +export default ['i18n', function(i18n) { return { addTitle: i18n._('CREATE CREDENTIAL'), //Legend in add mode @@ -474,4 +472,4 @@ export default } } } - };}]); + };}]; diff --git a/awx/ui/client/src/lists/Credentials.js b/awx/ui/client/src/credentials/credentials.list.js similarity index 95% rename from awx/ui/client/src/lists/Credentials.js rename to awx/ui/client/src/credentials/credentials.list.js index 152e182b35..dcbe4db556 100644 --- a/awx/ui/client/src/lists/Credentials.js +++ b/awx/ui/client/src/credentials/credentials.list.js @@ -7,9 +7,7 @@ -export default - angular.module('CredentialsListDefinition', []) - .factory('CredentialList', ['i18n', function(i18n) { +export default ['i18n', function(i18n) { return { name: 'credentials', @@ -95,4 +93,4 @@ export default ngShow: 'credential.summary_fields.user_capabilities.delete' } } - };}]); + };}]; diff --git a/awx/ui/client/src/credentials/edit/credentials-edit.controller.js b/awx/ui/client/src/credentials/edit/credentials-edit.controller.js index 9073b80bdb..2f1d04a0b8 100644 --- a/awx/ui/client/src/credentials/edit/credentials-edit.controller.js +++ b/awx/ui/client/src/credentials/edit/credentials-edit.controller.js @@ -4,15 +4,15 @@ * All Rights Reserved *************************************************/ -export default ['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'CredentialForm', 'Rest', 'Alert', - 'ProcessErrors', 'ClearScope', 'Prompt', 'GetBasePath', 'GetChoices', - 'KindChange', 'BecomeMethodChange', 'Empty', 'OwnerChange', - 'CredentialFormSave', 'Wait', '$state', 'CreateSelect2', 'Authorization', 'i18n', - function($scope, $rootScope, $compile, $location, $log, - $stateParams, CredentialForm, Rest, Alert, ProcessErrors, ClearScope, Prompt, - GetBasePath, GetChoices, KindChange, BecomeMethodChange, Empty, OwnerChange, CredentialFormSave, Wait, - $state, CreateSelect2, Authorization, i18n) { +export default ['$scope', '$rootScope', '$location', '$stateParams', + 'CredentialForm', 'Rest', 'ProcessErrors', 'ClearScope', 'Prompt', + 'GetBasePath', 'GetChoices', 'KindChange', 'BecomeMethodChange', 'Empty', + 'OwnerChange', 'Wait', '$state', 'CreateSelect2', + 'Authorization', 'i18n', 'CredentialFormSave', + function($scope, $rootScope, $location, $stateParams, CredentialForm, Rest, + ProcessErrors, ClearScope, Prompt, GetBasePath, GetChoices, KindChange, + BecomeMethodChange, Empty, OwnerChange, Wait, $state, + CreateSelect2, Authorization, i18n, CredentialFormSave) { ClearScope(); diff --git a/awx/ui/client/src/credentials/list/credentials-list.controller.js b/awx/ui/client/src/credentials/list/credentials-list.controller.js index 6f420f2cd9..b8bc553a2a 100644 --- a/awx/ui/client/src/credentials/list/credentials-list.controller.js +++ b/awx/ui/client/src/credentials/list/credentials-list.controller.js @@ -4,12 +4,11 @@ * All Rights Reserved *************************************************/ -export default ['$scope', '$rootScope', '$location', '$log', - '$stateParams', 'Rest', 'Alert', 'CredentialList', 'Prompt', 'ClearScope', - 'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'i18n', - function($scope, $rootScope, $location, $log, - $stateParams, Rest, Alert, CredentialList, Prompt, ClearScope, - ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset, +export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ClearScope', + 'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter', + 'rbacUiControlService', 'Dataset', 'i18n', + function($scope, Rest, CredentialList, Prompt, ClearScope, ProcessErrors, + GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset, i18n) { ClearScope(); diff --git a/awx/ui/client/src/credentials/main.js b/awx/ui/client/src/credentials/main.js index e4bb2f6f2d..0dfe1d8d5d 100644 --- a/awx/ui/client/src/credentials/main.js +++ b/awx/ui/client/src/credentials/main.js @@ -12,6 +12,8 @@ import BecomeMethodChange from './factories/become-method-change.factory'; import CredentialFormSave from './factories/credential-form-save.factory'; import KindChange from './factories/kind-change.factory'; import OwnerChange from './factories/owner-change.factory'; +import CredentialList from './credentials.list'; +import CredentialForm from './credentials.form'; import { N_ } from '../i18n'; export default @@ -24,6 +26,8 @@ export default .controller('CredentialsList', CredentialsList) .controller('CredentialsAdd', CredentialsAdd) .controller('CredentialsEdit', CredentialsEdit) + .factory('CredentialList', CredentialList) + .factory('CredentialForm', CredentialForm) .config(['$stateProvider', 'stateDefinitionsProvider', function($stateProvider, stateDefinitionsProvider) { let stateDefinitions = stateDefinitionsProvider.$get(); diff --git a/awx/ui/client/src/credentials/ownerList.partial.html b/awx/ui/client/src/credentials/ownerList.partial.html index 5c73ac4d15..a0faea839b 100644 --- a/awx/ui/client/src/credentials/ownerList.partial.html +++ b/awx/ui/client/src/credentials/ownerList.partial.html @@ -1,12 +1,29 @@ -
- diff --git a/awx/ui/client/src/forms.js b/awx/ui/client/src/forms.js deleted file mode 100644 index f51be2d458..0000000000 --- a/awx/ui/client/src/forms.js +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved -*************************************************/ - -import ActivityDetail from "./forms/ActivityDetail"; -import Credentials from "./forms/Credentials"; -import EventsViewer from "./forms/EventsViewer"; -import Groups from "./forms/Groups"; -import HostGroups from "./forms/HostGroups"; -import Hosts from "./forms/Hosts"; -import Inventories from "./forms/Inventories"; -import InventoryStatus from "./forms/InventoryStatus"; -import JobEventData from "./forms/JobEventData"; -import JobSummary from "./forms/JobSummary"; -import JobTemplates from "./forms/JobTemplates"; -import JobVarsPrompt from "./forms/JobVarsPrompt"; -import LogViewerOptions from "./forms/LogViewerOptions"; -import LogViewerStatus from "./forms/LogViewerStatus"; -import Organizations from "./forms/Organizations"; -import Teams from "./forms/Teams"; -import Users from "./forms/Users"; -import WorkflowMaker from "./forms/WorkflowMaker"; -import Workflows from "./forms/Workflows"; - - -export - { ActivityDetail, - Credentials, - EventsViewer, - Groups, - HostGroups, - Hosts, - Inventories, - InventoryStatus, - JobEventData, - JobSummary, - JobTemplates, - JobVarsPrompt, - LogViewerOptions, - LogViewerStatus, - Organizations, - Teams, - Users, - WorkflowMaker, - Workflows - }; diff --git a/awx/ui/client/src/forms/EventsViewer.js b/awx/ui/client/src/forms/EventsViewer.js deleted file mode 100644 index 9b9579f2a1..0000000000 --- a/awx/ui/client/src/forms/EventsViewer.js +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - /** - * @ngdoc function - * @name forms.function:EventsViewer - * @description This form is for events on the job detail page -*/ - -export default - angular.module('EventsViewerFormDefinition', []) - .factory('EventsViewerForm', ['i18n', function(i18n) { - return { - - fields: { - host_name: { - label: i18n._('Host'), - section: i18n._('Event') - }, - status: { - labellabel: i18n._('Status'), - section: i18n._('Event') - }, - id: { - labellabel: i18n._('ID'), - section: i18n._('Event') - }, - created: { - labellabel: i18n._('Created On'), - section: i18n._('Event') - }, - role: { - labellabel: i18n._('Role'), - section: i18n._('Event') - }, - play: { - labellabel: i18n._('Play'), - type: 'text', - section: i18n._('Event') - }, - task: { - labellabel: i18n._('Task'), - section: i18n._('Event') - }, - item: { - labellabel: i18n._('Item'), - section: i18n._('Event') - }, - module_name: { - labellabel: i18n._('Module'), - section: i18n._('Event') - }, - module_args: { - labellabel: i18n._('Arguments'), - section: i18n._('Event') - }, - rc: { - labellabel: i18n._('Return Code'), - section: i18n._('Results') - }, - msg: { - labellabel: i18n._('Message'), - section: i18n._('Results') - }, - results: { - labellabel: i18n._('Results'), - section: i18n._('Results') - }, - start: { - labellabel: i18n._('Start'), - section: i18n._('Timing') - }, - end: { - labellabel: i18n._('End'), - section: i18n._('Timing') - }, - delta: { - labellabel: i18n._('Elapsed'), - section: i18n._('Timing') - } - } - };}]); diff --git a/awx/ui/client/src/forms/Groups.js b/awx/ui/client/src/forms/Groups.js deleted file mode 100644 index 506d66d1b2..0000000000 --- a/awx/ui/client/src/forms/Groups.js +++ /dev/null @@ -1,362 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - /** - * @ngdoc function - * @name forms.function:Groups - * @description This form is for adding/editing a Group on the inventory page -*/ - -export default - angular.module('GroupFormDefinition', []) - .value('GroupFormObject', { - - addTitle: 'CREATE GROUP', - editTitle: '{{ name }}', - showTitle: true, - name: 'group', - basePath: 'groups', - // the parent node this generated state definition tree expects to attach to - stateTree: 'inventoryManage', - // form generator inspects the current state name to determine whether or not to set an active (.is-selected) class on a form tab - // this setting is optional on most forms, except where the form's edit state name is not parentStateName.edit - activeEditState: 'inventoryManage.editGroup', - detailsClick: "$state.go('inventoryManage.editGroup')", - well: false, - fields: { - name: { - label: 'Name', - type: 'text', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - required: true, - tab: 'properties' - }, - description: { - label: 'Description', - type: 'text', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - tab: 'properties' - }, - variables: { - label: 'Variables', - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - dataTitle: 'Group Variables', - dataPlacement: 'right', - parseTypeName: 'parseType', - awPopOver: "

Variables defined here apply to all child groups and hosts.

" + - "

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

" + - "JSON:
\n" + - "
{
  \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body', - tab: 'properties' - }, - source: { - label: 'Source', - type: 'select', - ngOptions: 'source.label for source in source_type_options track by source.value', - ngChange: 'sourceChange(source)', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - ngModel: 'source' - }, - credential: { - // initializes a default value for this search param - // search params with default values set will not generate user-interactable search tags - search: { - kind: null - }, - label: 'Cloud Credential', - type: 'lookup', - list: 'CredentialList', - basePath: 'credentials', - ngShow: "source && source.value !== '' && source.value !== 'custom'", - sourceModel: 'credential', - sourceField: 'name', - ngClick: 'lookupCredential()', - awRequiredWhen: { - reqExpression: "cloudCredentialRequired", - init: "false" - }, - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - watchBasePath: "credentialBasePath" - }, - source_regions: { - label: 'Regions', - type: 'select', - ngOptions: 'source.label for source in source_region_choices track by source.value', - multiSelect: true, - ngShow: "source && (source.value == 'rax' || source.value == 'ec2' || source.value == 'gce' || source.value == 'azure' || source.value == 'azure_rm')", - - - dataTitle: 'Source Regions', - dataPlacement: 'right', - awPopOver: "

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

", - dataContainer: 'body', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - instance_filters: { - label: 'Instance Filters', - type: 'text', - ngShow: "source && source.value == 'ec2'", - dataTitle: 'Instance Filters', - dataPlacement: 'right', - awPopOver: "

Provide a comma-separated list of filter expressions. " + - "Hosts are imported to Tower when ANY of the filters match.

" + - "Limit to hosts having a tag:
\n" + - "
tag-key=TowerManaged
\n" + - "Limit to hosts using either key pair:
\n" + - "
key-name=staging, key-name=production
\n" + - "Limit to hosts where the Name tag begins with test:
\n" + - "
tag:Name=test*
\n" + - "

View the Describe Instances documentation " + - "for a complete list of supported filters.

", - dataContainer: 'body', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - group_by: { - label: 'Only Group By', - type: 'select', - ngShow: "source && source.value == 'ec2'", - ngOptions: 'source.label for source in group_by_choices track by source.value', - multiSelect: true, - dataTitle: 'Only Group By', - dataPlacement: 'right', - awPopOver: "

Select which groups to create automatically. " + - "Tower will create group names similar to the following examples based on the options selected:

    " + - "
  • Availability Zone: zones » us-east-1b
  • " + - "
  • Image ID: images » ami-b007ab1e
  • " + - "
  • Instance ID: instances » i-ca11ab1e
  • " + - "
  • Instance Type: types » type_m1_medium
  • " + - "
  • Key Name: keys » key_testing
  • " + - "
  • Region: regions » us-east-1
  • " + - "
  • Security Group: security_groups » security_group_default
  • " + - "
  • Tags: tags » tag_Name » tag_Name_host1
  • " + - "
  • VPC ID: vpcs » vpc-5ca1ab1e
  • " + - "
  • Tag None: tags » tag_none
  • " + - "

If blank, all groups above are created except Instance ID.

", - dataContainer: 'body', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - inventory_script: { - label : "Custom Inventory Script", - type: 'lookup', - basePath: 'inventory_scripts', - list: 'InventoryScriptsList', - ngShow: "source && source.value === 'custom'", - sourceModel: 'inventory_script', - sourceField: 'name', - awRequiredWhen: { - reqExpression: "source && source.value === 'custom'", - init: "false" - }, - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - }, - custom_variables: { - id: 'custom_variables', - label: 'Environment Variables', //"{{vars_label}}" , - ngShow: "source && source.value=='custom' ", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Environment Variables", - dataPlacement: 'right', - awPopOver: "

Provide environment variables to pass to the custom inventory script.

" + - "

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

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - ec2_variables: { - id: 'ec2_variables', - label: 'Source Variables', //"{{vars_label}}" , - ngShow: "source && source.value == 'ec2'", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Source Variables", - dataPlacement: 'right', - awPopOver: "

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

" + - "

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

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - vmware_variables: { - id: 'vmware_variables', - label: 'Source Variables', //"{{vars_label}}" , - ngShow: "source && source.value == 'vmware'", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Source Variables", - dataPlacement: 'right', - awPopOver: "

Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " + - "" + - "view vmware_inventory.ini in the Ansible github repo.

" + - "

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

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - openstack_variables: { - id: 'openstack_variables', - label: 'Source Variables', //"{{vars_label}}" , - ngShow: "source && source.value == 'openstack'", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Source Variables", - dataPlacement: 'right', - awPopOver: "

Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration " + - "" + - "view openstack.yml in the Ansible github repo.

" + - "

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

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - checkbox_group: { - label: 'Update Options', - type: 'checkbox_group', - ngShow: "source && (source.value !== '' && source.value !== null)", - class: 'Form-checkbox--stacked', - fields: [{ - name: 'overwrite', - label: 'Overwrite', - type: 'checkbox', - ngShow: "source.value !== '' && source.value !== null", - - - awPopOver: '

If checked, all child groups and hosts not found on the external source will be deleted from ' + - 'the local inventory.

When not checked, local child hosts and groups not found on the external source will ' + - 'remain untouched by the inventory update process.

', - dataTitle: 'Overwrite', - dataContainer: 'body', - dataPlacement: 'right', - labelClass: 'checkbox-options', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, { - name: 'overwrite_vars', - label: 'Overwrite Variables', - type: 'checkbox', - ngShow: "source.value !== '' && source.value !== null", - - - awPopOver: '

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

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

', - dataTitle: 'Overwrite Variables', - dataContainer: 'body', - dataPlacement: 'right', - labelClass: 'checkbox-options', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, { - name: 'update_on_launch', - label: 'Update on Launch', - type: 'checkbox', - ngShow: "source.value !== '' && source.value !== null", - awPopOver: '

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

', - dataTitle: 'Update on Launch', - dataContainer: 'body', - dataPlacement: 'right', - labelClass: 'checkbox-options', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }] - }, - update_cache_timeout: { - label: "Cache Timeout (seconds)", - id: 'source-cache-timeout', - type: 'number', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - integer: true, - min: 0, - ngShow: "source && source.value !== '' && update_on_launch", - spinner: true, - "default": 0, - awPopOver: '

Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will ' + - 'evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, ' + - 'and a new inventory sync will be performed.

', - dataTitle: 'Cache Timeout', - dataPlacement: 'right', - dataContainer: "body" - } - }, - - buttons: { - cancel: { - ngClick: 'formCancel()', - ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - close: { - ngClick: 'formCancel()', - ngShow: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - save: { - ngClick: 'formSave()', - ngDisabled: true, - ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)' - } - }, - - related: { - "notifications": { - include: "NotificationsList" - } - } - - }) - .factory('GroupForm', ['GroupFormObject', 'NotificationsList', - function(GroupFormObject, NotificationsList) { - return function() { - var itm; - - for (itm in GroupFormObject.related) { - if (GroupFormObject.related[itm].include === "NotificationsList") { - GroupFormObject.related[itm] = angular.copy(NotificationsList); - GroupFormObject.related[itm].generateList = true; - GroupFormObject.related[itm].disabled = "source === undefined || source.value === ''"; - GroupFormObject.related[itm].ngClick = "$state.go('inventoryManage.editGroup.notifications')"; - } - } - return GroupFormObject; - }; - }]); diff --git a/awx/ui/client/src/forms/HostGroups.js b/awx/ui/client/src/forms/HostGroups.js deleted file mode 100644 index 16479fee2b..0000000000 --- a/awx/ui/client/src/forms/HostGroups.js +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - /** - * @ngdoc function - * @name forms.function:HostGroups - * @description This form is for groups of hosts on the inventory page -*/ - -export default - angular.module('HostGroupsFormDefinition', []) - .value('HostGroupsForm', { - - editTitle: 'HOST GROUPS', - name: 'host', - well: false, - formLabelSize: 'col-lg-3', - formFieldSize: 'col-lg-9', - - fields: { - groups: { - label: 'Groups', - type: 'select', - multiple: true, - ngOptions: 'group.name for group in inventory_groups track by group.value', - required: true, - awPopOver: "

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

" + - "
myserver.domain.com
" + - "127.0.0.1
" + - "10.1.0.140:25
" + - "server.example.com:25" + - "
", - dataTitle: 'Host Name', - dataPlacement: 'right', - dataContainer: '#form-modal .modal-content' - } - }, - - buttons: { //for now always generates