Merge pull request #5606 from jlmitch5/cleanupOtherResources

Update Resource Modules
This commit is contained in:
jlmitch5 2017-03-21 11:30:10 -04:00 committed by GitHub
commit 722f09357d
98 changed files with 1453 additions and 2579 deletions

View File

@ -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
};}];

View File

@ -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];
];

View File

@ -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.

View File

@ -1,78 +1,77 @@
export default
function BuildAnchor($log, $filter) {
// Returns a full <a href=''>resource_name</a> 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 ' <a href=\"' + url + '\"> ' + $filter('sanitize')(obj.name || obj.username) + ' </a> ';
export default function BuildAnchor($log, $filter) {
// Returns a full <a href=''>resource_name</a> 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 ' <a href=\"' + url + '\"> ' + $filter('sanitize')(obj.name || obj.username) + ' </a> ';
}
catch(err){
$log.debug(err);
return ' ' + $filter('sanitize')(obj.name || obj.username || '') + ' ';
}
};
}
BuildAnchor.$inject = ['$log', '$filter'];

View File

@ -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 <object2> role_name from <object1>"
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 <object2> role_name to <object1>"
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 <object2> role_name from <object1>"
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 <object2> role_name to <object1>"
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 <object2> from <object1>"
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 <object2> to <object1>"
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 <object1>"
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 <object2> role_name from <object1>"
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 <object2> role_name to <object1>"
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 <object2> role_name from <object1>"
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 <object2> role_name to <object1>"
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 <object2> from <object1>"
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 <object2> to <object1>"
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 <object1>"
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'];

View File

@ -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'];

View File

@ -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 = "<a href=\"/#/users/" + scope.activities[i].summary_fields.actor.id + "\">" +
scope.activities[i].summary_fields.actor.username + "</a>";
} 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 = "<a href=\"/#/users/" + scope.activities[i].summary_fields.actor.id + "\">" +
scope.activities[i].summary_fields.actor.username + "</a>";
} 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',

View File

@ -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'];

View File

@ -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);
}]);

View File

@ -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;
};
}

View File

@ -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
}
}
};}]);
};}];

View File

@ -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')

View File

@ -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();

View File

@ -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
}
}
}
};}]);
};}];

View File

@ -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'
}
}
};}]);
};}];

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -1,12 +1,29 @@
<div class="OwnerList" ng-init="ownersLimit = 5; ownersLimitConst = 5; ">
<div class="OwnerList-Container" ng-repeat="owner in owners_list | limitTo:ownersLimit">
<a ng-if="owner.type === 'organization'" ui-sref="organizations.edit({ organization_id: owner.id })">{{ owner.name }}{{$last ? '' : ', '}}</a>
<a ng-if="owner.type === 'user'" ui-sref="users.edit({ user_id: owner.id })">{{ owner.name }}{{$last ? '' : ', '}}</a>
<a ng-if="owner.type === 'team'" ui-sref="teams.edit({ team_id: owner.id })">{{ owner.name }}{{$last ? '' : ', '}}</a>
<div class="OwnerList" ng-init="ownersLimit = 5; ownersLimitConst = 5;">
<div class="OwnerList-Container"
ng-repeat="owner in owners_list | limitTo:ownersLimit">
<a ng-if="owner.type === 'organization'"
ui-sref="organizations.edit({ organization_id: owner.id })">
{{ owner.name }}{{$last ? '' : ', '}}
</a>
<a ng-if="owner.type === 'user'"
ui-sref="users.edit({ user_id: owner.id })">
{{ owner.name }}{{$last ? '' : ', '}}
</a>
<a ng-if="owner.type === 'team'"
ui-sref="teams.edit({ team_id: owner.id })">
{{ owner.name }}{{$last ? '' : ', '}}
</a>
</div>
<div class="OwnerList-seeMore" ng-show="owners_list.length > ownersLimitConst && ownersLimit == ownersLimitConst"
ng-click="ownersLimit = owners_list.length">View More</div>
<div class="OwnerList-seeLess" ng-show="owners_list.length > ownersLimitConst && ownersLimit != ownersLimitConst"
ng-click="ownersLimit = ownersLimitConst">View Less</div>
</div>
<div class="OwnerList-seeMore"
ng-show="owners_list.length > ownersLimitConst && ownersLimit == ownersLimitConst"
ng-click="ownersLimit = owners_list.length">
View More
</div>
<div class="OwnerList-seeLess"
ng-show="owners_list.length > ownersLimitConst && ownersLimit != ownersLimitConst"
ng-click="ownersLimit = ownersLimitConst">
View Less
</div>
</div>

View File

@ -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
};

View File

@ -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')
}
}
};}]);

View File

@ -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: "<p>Variables defined here apply to all child groups and hosts.</p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the " +
"radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp; \"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
"or choose <em>All</em> to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
"</p>",
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: "<p>Provide a comma-separated list of filter expressions. " +
"Hosts are imported to Tower when <em>ANY</em> of the filters match.</p>" +
"Limit to hosts having a tag:<br />\n" +
"<blockquote>tag-key=TowerManaged</blockquote>\n" +
"Limit to hosts using either key pair:<br />\n" +
"<blockquote>key-name=staging, key-name=production</blockquote>\n" +
"Limit to hosts where the Name tag begins with <em>test</em>:<br />\n" +
"<blockquote>tag:Name=test*</blockquote>\n" +
"<p>View the <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html\" target=\"_blank\">Describe Instances documentation</a> " +
"for a complete list of supported filters.</p>",
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: "<p>Select which groups to create automatically. " +
"Tower will create group names similar to the following examples based on the options selected:</p><ul>" +
"<li>Availability Zone: <strong>zones &raquo; us-east-1b</strong></li>" +
"<li>Image ID: <strong>images &raquo; ami-b007ab1e</strong></li>" +
"<li>Instance ID: <strong>instances &raquo; i-ca11ab1e</strong></li>" +
"<li>Instance Type: <strong>types &raquo; type_m1_medium</strong></li>" +
"<li>Key Name: <strong>keys &raquo; key_testing</strong></li>" +
"<li>Region: <strong>regions &raquo; us-east-1</strong></li>" +
"<li>Security Group: <strong>security_groups &raquo; security_group_default</strong></li>" +
"<li>Tags: <strong>tags &raquo; tag_Name &raquo; tag_Name_host1</strong></li>" +
"<li>VPC ID: <strong>vpcs &raquo; vpc-5ca1ab1e</strong></li>" +
"<li>Tag None: <strong>tags &raquo; tag_none</strong></li>" +
"</ul><p>If blank, all groups above are created except <em>Instance ID</em>.</p>",
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: "<p>Provide environment variables to pass to the custom inventory script.</p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/contrib/inventory/ec2.ini\" target=\"_blank\">" +
"view ec2.ini in the Ansible github repo.</a></p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/contrib/inventory/vmware_inventory.ini\" target=\"_blank\">" +
"view vmware_inventory.ini in the Ansible github repo.</a></p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/contrib/inventory/openstack.yml\" target=\"_blank\">" +
"view openstack.yml in the Ansible github repo.</a></p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: '<p>If checked, all child groups and hosts not found on the external source will be deleted from ' +
'the local inventory.</p><p>When not checked, local child hosts and groups not found on the external source will ' +
'remain untouched by the inventory update process.</p>',
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: '<p>If checked, all variables for child groups and hosts will be removed and replaced by those ' +
'found on the external source.</p><p>When not checked, a merge will be performed, combining local variables with ' +
'those found on the external source.</p>',
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: '<p>Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
'executing job tasks.</p>',
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 <span class=\"small-text\"> (seconds)</span>",
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: '<p>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.</p>',
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;
};
}]);

View File

@ -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: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" +
"10.1.0.140:25<br />" +
"server.example.com:25" +
"</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: '#form-modal .modal-content'
}
},
buttons: { //for now always generates <button> tags
reset: {
ngClick: 'formReset()',
ngDisabled: true
},
save: {
ngClick: 'formSave()',
ngDisabled: true
}
},
related: { }
}); //UserForm

View File

@ -1,60 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:InventoryStatus
* @description This form is for adding/editing an InventoryStatus
*/
export default
angular.module('InventoryStatusDefinition', [])
.value('InventoryStatusForm', {
name: 'inventory_update',
editTitle: 'INVENTORY STATUS',
well: false,
'class': 'horizontal-narrow',
fields: {
license_error: {
type: 'alertblock',
'class': 'alert-info',
alertTxt: 'The invenvtory update process exceeded the available number of licensed hosts. ' +
'<strong><a ng-click=\"viewLicense()\" href=\"\">View your license</a></strong> ' +
'for more information.',
ngShow: 'license_error',
closeable: true
},
created: {
label: 'Created',
type: 'text',
readonly: true
},
status: {
label: 'Status',
type: 'text',
readonly: true,
'class': 'nowrap mono-space resizable',
rows: '{{ status_rows }}'
},
result_stdout: {
label: 'Std Out',
type: 'textarea',
ngShow: 'result_stdout',
'class': 'nowrap mono-space resizable',
readonly: true,
rows: '{{ stdout_rows }}'
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
ngShow: 'result_traceback',
'class': 'nowrap mono-space resizable',
readonly: true,
rows: '{{ traceback_rows }}'
}
}
}); //Form

View File

@ -1,32 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:JobEventData
* @description Not sure if this is used...
*/
export default
angular.module('JobEventDataDefinition', [])
.value('JobEventDataForm', {
editTitle: '{{ id }} - {{ event_display }}',
name: 'job_events',
well: false,
'class': 'horizontal-narrow',
fields: {
event_data: {
label: false,
type: 'textarea',
readonly: true,
rows: 18,
'class': 'modal-input-xxlarge'
}
}
}); //Form

View File

@ -1,53 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:JobSummary
* @description Display job status info in a dialog
*/
export default
angular.module('JobSummaryDefinition', [])
.value('JobSummary', {
editTitle: '{{ id }} - {{ name }}',
name: 'jobs',
well: false,
fields: {
status: {
//label: 'Job Status',
type: 'custom',
control: '<div class=\"job-detail-status\"><span style="padding-right: 15px; font-weight: bold;">Status</span> ' +
'<i class=\"fa icon-job-{{ status }}\"></i> {{ status }}</div>',
readonly: true
},
created: {
label: 'Created On',
type: 'text',
readonly: true
},
result_stdout: {
label: 'Standard Out',
type: 'textarea',
readonly: true,
xtraWide: true,
rows: '{{ stdout_rows }}',
'class': 'nowrap mono-space resizable',
ngShow: 'result_stdout != ""'
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
xtraWide: true,
readonly: true,
rows: '{{ traceback_rows }}',
'class': 'nowrap mono-space resizable',
ngShow: 'result_traceback != ""'
}
}
});

View File

@ -1,40 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:JobVarsPrompt
* @description This form is for job variables prompt modal
*/
export default
angular.module('JobVarsPromptFormDefinition', [])
.value ('JobVarsPromptForm', {
addTitle: '',
editTitle: '',
name: 'job',
well: false,
actions: { },
fields: {
extra_vars: {
label: null,
type: 'textarea',
rows: 6,
"default": "---"
}
},
buttons: { },
related: { }
});

View File

@ -1,102 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:LogViewerOptions
* @description This form is for the page to view logs
*/
export default
angular.module('LogViewerOptionsDefinition', [])
.value('LogViewerOptionsForm', {
name: 'status',
well: false,
fields: {
"job_template": {
label: "Job Template",
type: "text",
readonly: true
},
"inventory": {
label: "Inventory",
type: "text",
readonly: true
},
"project": {
label: "Project",
type: "text",
readonly: true
},
"playbook": {
label: "Playbook",
type: "text",
readonly: true
},
"credential": {
label: "Credential",
type: "text",
readonly: true
},
"cloud credential": {
label: "Cloud Cred.",
type: "text",
readonly: true
},
"forks": {
label: "Forks",
type: "text",
readonly: true
},
"limit": {
label: "Limit",
type: "text",
readonly: true
},
"verbosity": {
label: "Verbosity",
type: "text",
readonly: true
},
"job_tags": {
label: "Job Tags",
type: "text",
readonly: true
},
"inventory_source": {
label: "Group",
type: "text",
readonly: true
},
"source": {
label: "Source",
type: "text",
readonly: true
},
"source_path": {
label: "Source Path",
type: "text",
readonly: true
},
"source_regions":{
label: "Regions",
type: "text",
readonly: true
},
"overwrite": {
label: "Overwrite",
type: "text",
readonly: true
},
"overwrite_vars": {
label: "Overwrite Vars",
type: "text",
readonly: true
}
}
});

View File

@ -1,61 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:LogViewerStatus
* @description Form definition for LogViewer.js helper
*/
export default
angular.module('LogViewerStatusDefinition', [])
.factory('LogViewerStatusForm', ['i18n', function(i18n) {
return {
name: 'status',
well: false,
fields: {
"name": {
label: i18n._("Name"),
type: "text",
readonly: true,
},
"status": {
label: i18n._("Status"),
type: "text",
readonly: true
},
"license_error": {
label: i18n._("License Error"),
type: "text",
readonly: true
},
"started": {
label: i18n._("Started"),
type: "date",
"filter": "longDate",
readonly: true
},
"finished": {
label: i18n._("Finished"),
type: "date",
"filter": "longDate",
readonly: true
},
"elapsed": {
label: i18n._("Elapsed"),
type: "text",
readonly: true
},
"launch_type": {
label: i18n._("Launch Type"),
type: "text",
readonly: true
}
}
};}]);

View File

@ -1,50 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name forms.function:ProjectStatus
* @description This form is for adding/editing project status
*/
export default
angular.module('ProjectStatusDefinition', [])
.value('ProjectStatusForm', {
name: 'project_update',
editTitle: 'SCM STATUS',
well: false,
'class': 'horizontal-narrow',
fields: {
created: {
label: 'Created',
type: 'text',
readonly: true
},
status: {
label: 'Status',
type: 'text',
readonly: true
},
result_stdout: {
label: 'Std Out',
type: 'textarea',
ngShow: "result_stdout",
'class': 'mono-space',
readonly: true,
rows: 15
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
ngShow: "result_traceback",
'class': 'mono-space',
readonly: true,
rows: 15
}
}
}); //Form

View File

@ -10,9 +10,7 @@
* @description This form is for adding/editing an inventory
*/
export default
angular.module('InventoryFormDefinition', [])
.factory('InventoryForm', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
addTitle: i18n._('NEW INVENTORY'),
@ -134,4 +132,4 @@ angular.module('InventoryFormDefinition', [])
}
}
};}]);
};}];

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('InventoriesListDefinition', [])
.factory('InventoryList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'inventories',
@ -96,4 +94,4 @@ export default
ngShow: 'inventory.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -13,6 +13,11 @@ import { copyMoveGroupRoute, copyMoveHostRoute } from './manage/copy-move/copy-m
import adHocRoute from './manage/adhoc/adhoc.route';
import { templateUrl } from '../shared/template-url/template-url.factory';
import { N_ } from '../i18n';
// actual inventory list config object
import InventoryList from './inventory.list';
import InventoryForm from './inventory.form';
export default
angular.module('inventory', [
inventoryAdd.name,
@ -20,6 +25,8 @@ angular.module('inventory', [
inventoryList.name,
inventoryManage.name,
])
.factory('InventoryList', InventoryList)
.factory('InventoryForm', InventoryForm)
.config(['$stateProvider', '$stateExtenderProvider', 'stateDefinitionsProvider',
function($stateProvider, $stateExtenderProvider, stateDefinitionsProvider) {
// When stateDefinition.lazyLoad() resolves, states matching name.** or /url** will be de-registered and replaced with resolved states

View File

@ -0,0 +1,24 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'groups',
iterator: 'copy',
selectTitle: 'Copy Groups',
index: false,
well: false,
emptyListText: 'PLEASE CREATE ADDITIONAL GROUPS / HOSTS TO PERFORM THIS ACTION',
fields: {
name: {
key: true,
label: 'Target Group Name'
}
},
basePath: 'api/v1/inventories/{{$stateParams.inventory_id}}/groups'
};

View File

@ -6,8 +6,10 @@
import CopyMoveGroupsController from './copy-move-groups.controller';
import CopyMoveHostsController from './copy-move-hosts.controller';
import CopyMoveGroupList from './copy-move-groups.list';
export default
angular.module('manageCopyMove', [])
.controller('CopyMoveGroupsController', CopyMoveGroupsController)
.controller('CopyMoveHostsController', CopyMoveHostsController);
.controller('CopyMoveHostsController', CopyMoveHostsController)
.value('CopyMoveGroupList', CopyMoveGroupList);

View File

@ -0,0 +1,360 @@
/*************************************************
* 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 ['NotificationsList',
function(NotificationsList) {
return function() {
var 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: "<p>Variables defined here apply to all child groups and hosts.</p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the " +
"radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp; \"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
"or choose <em>All</em> to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
"</p>",
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: "<p>Provide a comma-separated list of filter expressions. " +
"Hosts are imported to Tower when <em>ANY</em> of the filters match.</p>" +
"Limit to hosts having a tag:<br />\n" +
"<blockquote>tag-key=TowerManaged</blockquote>\n" +
"Limit to hosts using either key pair:<br />\n" +
"<blockquote>key-name=staging, key-name=production</blockquote>\n" +
"Limit to hosts where the Name tag begins with <em>test</em>:<br />\n" +
"<blockquote>tag:Name=test*</blockquote>\n" +
"<p>View the <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html\" target=\"_blank\">Describe Instances documentation</a> " +
"for a complete list of supported filters.</p>",
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: "<p>Select which groups to create automatically. " +
"Tower will create group names similar to the following examples based on the options selected:</p><ul>" +
"<li>Availability Zone: <strong>zones &raquo; us-east-1b</strong></li>" +
"<li>Image ID: <strong>images &raquo; ami-b007ab1e</strong></li>" +
"<li>Instance ID: <strong>instances &raquo; i-ca11ab1e</strong></li>" +
"<li>Instance Type: <strong>types &raquo; type_m1_medium</strong></li>" +
"<li>Key Name: <strong>keys &raquo; key_testing</strong></li>" +
"<li>Region: <strong>regions &raquo; us-east-1</strong></li>" +
"<li>Security Group: <strong>security_groups &raquo; security_group_default</strong></li>" +
"<li>Tags: <strong>tags &raquo; tag_Name &raquo; tag_Name_host1</strong></li>" +
"<li>VPC ID: <strong>vpcs &raquo; vpc-5ca1ab1e</strong></li>" +
"<li>Tag None: <strong>tags &raquo; tag_none</strong></li>" +
"</ul><p>If blank, all groups above are created except <em>Instance ID</em>.</p>",
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: "<p>Provide environment variables to pass to the custom inventory script.</p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/contrib/inventory/ec2.ini\" target=\"_blank\">" +
"view ec2.ini in the Ansible github repo.</a></p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/contrib/inventory/vmware_inventory.ini\" target=\"_blank\">" +
"view vmware_inventory.ini in the Ansible github repo.</a></p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: "<p>Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/contrib/inventory/openstack.yml\" target=\"_blank\">" +
"view openstack.yml in the Ansible github repo.</a></p>" +
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
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: '<p>If checked, all child groups and hosts not found on the external source will be deleted from ' +
'the local inventory.</p><p>When not checked, local child hosts and groups not found on the external source will ' +
'remain untouched by the inventory update process.</p>',
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: '<p>If checked, all variables for child groups and hosts will be removed and replaced by those ' +
'found on the external source.</p><p>When not checked, a merge will be performed, combining local variables with ' +
'those found on the external source.</p>',
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: '<p>Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
'executing job tasks.</p>',
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 <span class=\"small-text\"> (seconds)</span>",
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: '<p>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.</p>',
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"
}
}
};
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;
};
}];

View File

@ -0,0 +1,167 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'groups',
iterator: 'group',
editTitle: '{{ inventory.name }}',
listTitle: 'GROUPS',
searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
showTitle: false,
well: true,
index: false,
hover: true,
'class': 'table-no-border',
multiSelect: true,
trackBy: 'group.id',
fields: {
sync_status: {
label: '',
nosort: true,
mode: 'all',
iconOnly: true,
ngClick: 'viewUpdateStatus(group.id)',
awToolTip: "{{ group.status_tooltip }}",
dataTipWatch: "group.status_tooltip",
icon: "{{ 'fa icon-cloud-' + group.status_class }}",
ngClass: "group.status_class",
dataPlacement: "top",
columnClass: 'status-column List-staticColumn--smallStatus'
},
failed_hosts: {
label: '',
nosort: true,
mode: 'all',
iconOnly: true,
awToolTip: "{{ group.hosts_status_tip }}",
dataPlacement: "top",
ngClick: "showFailedHosts(group)",
icon: "{{ 'fa icon-job-' + group.hosts_status_class }}",
columnClass: 'status-column List-staticColumn--smallStatus'
},
name: {
label: 'Groups',
key: true,
ngClick: "groupSelect(group.id)",
columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6',
class: 'InventoryManage-breakWord',
},
total_groups: {
nosort: true,
label: '',
type: 'badgeCount',
ngHide: 'group.total_groups == 0',
noLink: true,
awToolTip: "{{group.name | sanitize}} contains {{group.total_groups}} {{group.total_groups === 1 ? 'child' : 'children'}}"
}
},
actions: {
refresh: {
mode: 'all',
awToolTip: "Refresh the page",
ngClick: "refreshGroups()",
ngShow: "socketStatus == 'error'",
actionClass: 'btn List-buttonDefault',
buttonContent: 'REFRESH'
},
launch: {
mode: 'all',
// $scope.$parent is governed by InventoryManageController,
ngDisabled: '!$parent.groupsSelected && !$parent.hostsSelected',
ngClick: '$parent.setAdhocPattern()',
awToolTip: "Select an inventory source by clicking the check box beside it. The inventory source can be a single group or host, a selection of multiple hosts, or a selection of multiple groups.",
dataTipWatch: "adhocCommandTooltip",
actionClass: 'btn List-buttonDefault',
buttonContent: 'RUN COMMANDS',
showTipWhenDisabled: true,
tooltipInnerClass: "Tooltip-wide",
ngShow: 'canAdhoc'
// TODO: set up a tip watcher and change text based on when
// things are selected/not selected. This is started and
// commented out in the inventory controller within the watchers.
// awToolTip: "{{ adhocButtonTipContents }}",
// dataTipWatch: "adhocButtonTipContents"
},
create: {
mode: 'all',
ngClick: "createGroup()",
awToolTip: "Create a new group",
actionClass: 'btn List-buttonSubmit',
buttonContent: '&#43; ADD GROUP',
ngShow: 'canAdd',
dataPlacement: "top",
}
},
fieldActions: {
columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6 text-right',
group_update: {
//label: 'Sync',
mode: 'all',
ngClick: 'updateGroup(group)',
awToolTip: "{{ group.launch_tooltip }}",
dataTipWatch: "group.launch_tooltip",
ngShow: "(group.status !== 'running' && group.status " +
"!== 'pending' && group.status !== 'updating') && group.summary_fields.user_capabilities.start",
ngClass: "group.launch_class",
dataPlacement: "top",
},
cancel: {
//label: 'Cancel',
mode: 'all',
ngClick: "cancelUpdate(group.id)",
awToolTip: "Cancel sync process",
'class': 'red-txt',
ngShow: "(group.status == 'running' || group.status == 'pending' " +
"|| group.status == 'updating') && group.summary_fields.user_capabilities.start",
dataPlacement: "top",
iconClass: "fa fa-minus-circle"
},
copy: {
mode: 'all',
ngClick: "copyMoveGroup(group.id)",
awToolTip: 'Copy or move group',
ngShow: "group.id > 0 && group.summary_fields.user_capabilities.copy",
dataPlacement: "top"
},
schedule: {
mode: 'all',
ngClick: "scheduleGroup(group.id)",
awToolTip: "{{ group.group_schedule_tooltip }}",
ngClass: "group.scm_type_class",
dataPlacement: 'top',
ngShow: "!(group.summary_fields.inventory_source.source === '')"
},
edit: {
//label: 'Edit',
mode: 'all',
ngClick: "editGroup(group.id)",
awToolTip: 'Edit group',
dataPlacement: "top",
ngShow: "group.summary_fields.user_capabilities.edit"
},
view: {
//label: 'Edit',
mode: 'all',
ngClick: "editGroup(group.id)",
awToolTip: 'View group',
dataPlacement: "top",
ngShow: "!group.summary_fields.user_capabilities.edit"
},
"delete": {
//label: 'Delete',
mode: 'all',
ngClick: "deleteGroup(group)",
awToolTip: 'Delete group',
dataPlacement: "top",
ngShow: "group.summary_fields.user_capabilities.delete"
}
}
};

View File

@ -11,6 +11,8 @@ import GetSourceTypeOptions from './factories/get-source-type-options.factory';
import GetSyncStatusMsg from './factories/get-sync-status-msg.factory';
import GroupsCancelUpdate from './factories/groups-cancel-update.factory';
import ViewUpdateStatus from './factories/view-update-status.factory';
import InventoryGroups from './inventory-groups.list';
import GroupForm from './groups.form';
export default
angular.module('manageGroups', [])
@ -19,5 +21,7 @@ angular.module('manageGroups', [])
.factory('GetSyncStatusMsg', GetSyncStatusMsg)
.factory('GroupsCancelUpdate', GroupsCancelUpdate)
.factory('ViewUpdateStatus', ViewUpdateStatus)
.factory('GroupForm', GroupForm)
.value('InventoryGroups', InventoryGroups)
.controller('GroupAddController', GroupAddController)
.controller('GroupEditController', GroupEditController);

View File

@ -10,9 +10,7 @@
* @description This form is for adding/editing a host on the inventory page
*/
export default
angular.module('HostFormDefinition', [])
.factory('HostForm', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
addTitle: i18n._('CREATE HOST'),
@ -102,4 +100,4 @@ export default
}
},
};
}]);
}];

View File

@ -0,0 +1,119 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'hosts',
iterator: 'host',
editTitle: '{{ selected_group }}',
listTitle: 'HOSTS',
searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
showTitle: false,
well: true,
index: false,
hover: true,
hasChildren: true,
'class': 'table-no-border',
multiSelect: true,
trackBy: 'host.id',
fields: {
active_failures: {
label: '',
iconOnly: true,
nosort: true,
// do not remove this ng-click directive
// the list generator case to handle fields without ng-click
// cannot handle the aw-* directives
ngClick: 'noop()',
awPopOver: "{{ host.job_status_html }}",
dataTitle: "{{ host.job_status_title }}",
awToolTip: "{{ host.badgeToolTip }}",
dataPlacement: 'top',
icon: "{{ 'fa icon-job-' + host.active_failures }}",
id: 'active-failures-action',
columnClass: 'status-column List-staticColumn--smallStatus'
},
name: {
key: true,
label: 'Hosts',
ngClick: "editHost(host.id)",
ngClass: "{ 'host-disabled-label': !host.enabled }",
columnClass: 'col-lg-6 col-md-8 col-sm-8 col-xs-7',
dataHostId: "{{ host.id }}",
dataType: "host",
class: 'InventoryManage-breakWord'
}
},
fieldActions: {
columnClass: 'col-lg-6 col-md-4 col-sm-4 col-xs-5 text-right',
copy: {
mode: 'all',
ngClick: "copyMoveHost(host.id)",
awToolTip: 'Copy or move host to another group',
dataPlacement: "top",
ngShow: 'host.summary_fields.user_capabilities.edit'
},
edit: {
//label: 'Edit',
ngClick: "editHost(host.id)",
icon: 'icon-edit',
awToolTip: 'Edit host',
dataPlacement: 'top',
ngShow: 'host.summary_fields.user_capabilities.edit'
},
view: {
//label: 'Edit',
ngClick: "editHost(host.id)",
awToolTip: 'View host',
dataPlacement: 'top',
ngShow: '!host.summary_fields.user_capabilities.edit'
},
"delete": {
//label: 'Delete',
ngClick: "deleteHost(host.id, host.name)",
icon: 'icon-trash',
awToolTip: 'Delete host',
dataPlacement: 'top',
ngShow: 'host.summary_fields.user_capabilities.delete'
}
},
actions: {
system_tracking: {
buttonContent: 'System Tracking',
ngClick: 'systemTracking()',
awToolTip: "Select one or two hosts by clicking the checkbox beside the host. System tracking offers the ability to compare the results of two scan runs from different dates on one host or the same date on two hosts.",
dataTipWatch: "systemTrackingTooltip",
dataPlacement: 'top',
awFeature: 'system_tracking',
actionClass: 'btn List-buttonDefault system-tracking',
ngDisabled: 'systemTrackingDisabled || !hostsSelected',
showTipWhenDisabled: true,
tooltipInnerClass: "Tooltip-wide",
ngShow: true
},
refresh: {
mode: 'all',
awToolTip: "Refresh the page",
ngClick: "refreshGroups()",
ngShow: "socketStatus == 'error'",
actionClass: 'btn List-buttonDefault',
buttonContent: 'REFRESH'
},
create: {
mode: 'all',
ngClick: "createHost()",
awToolTip: "Create a new host",
actionClass: 'btn List-buttonSubmit',
buttonContent: '&#43; ADD HOST',
ngShow: 'canAdd',
dataPlacement: "top",
}
}
};

View File

@ -8,10 +8,14 @@ import HostsAddController from './hosts-add.controller';
import HostsEditController from './hosts-edit.controller';
import SetStatus from './factories/set-status.factory';
import SetEnabledMsg from './factories/set-enabled-msg.factory';
import InventoryHosts from './inventory-hosts.list';
import HostForm from './hosts.form';
export default
angular.module('manageHosts', [])
.factory('SetStatus', SetStatus)
.factory('SetEnabledMsg', SetEnabledMsg)
.factory('HostForm', HostForm)
.value('InventoryHosts', InventoryHosts)
.controller('HostsAddController', HostsAddController)
.controller('HostEditController', HostsEditController);

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('AllJobsDefinition', [])
.factory('AllJobsList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'jobs',
@ -118,4 +116,4 @@ export default
}
}
};
}]);
}];

View File

@ -14,6 +14,7 @@ import RelaunchInventory from './factories/relaunch-inventory.factory';
import RelaunchJob from './factories/relaunch-job.factory';
import RelaunchPlaybook from './factories/relaunch-playbook.factory';
import RelaunchSCM from './factories/relaunch-scm.factory';
import AllJobsList from './all-jobs.list';
export default
angular.module('JobsModule', [])
@ -28,4 +29,5 @@ export default
.factory('RelaunchInventory', RelaunchInventory)
.factory('RelaunchJob', RelaunchJob)
.factory('RelaunchPlaybook', RelaunchPlaybook)
.factory('RelaunchSCM', RelaunchSCM);
.factory('RelaunchSCM', RelaunchSCM)
.factory('AllJobsList', AllJobsList);

View File

@ -1,53 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import CloudCredentials from "./lists/CloudCredentials";
import CompletedJobs from "./lists/CompletedJobs";
import AllJobs from "./lists/AllJobs";
import Credentials from "./lists/Credentials";
import Groups from "./lists/Groups";
import Hosts from "./lists/Hosts";
import Inventories from "./lists/Inventories";
import InventoryGroups from "./lists/InventoryGroups";
import InventoryHosts from "./lists/InventoryHosts";
import InventorySources from "./lists/InventorySources";
import JobEvents from "./lists/JobEvents";
import JobHosts from "./lists/JobHosts";
import Jobs from "./lists/Jobs";
import Organizations from "./lists/Organizations";
import PortalJobTemplates from "./lists/PortalJobTemplates";
import PortalJobs from "./lists/PortalJobs";
import ScheduledJobs from "./lists/ScheduledJobs";
import Schedules from "./lists/Schedules";
import Streams from "./lists/Streams";
import Teams from "./lists/Teams";
import Templates from "./lists/Templates";
import Users from "./lists/Users";
export
{ CloudCredentials,
CompletedJobs,
AllJobs,
Credentials,
Groups,
Hosts,
Inventories,
InventoryGroups,
InventoryHosts,
InventorySources,
JobEvents,
JobHosts,
Jobs,
Organizations,
PortalJobTemplates,
PortalJobs,
ScheduledJobs,
Schedules,
Streams,
Teams,
Templates,
Users
};

View File

@ -1,77 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('CloudCredentialsListDefinition', [])
.value('CloudCredentialList', {
name: 'cloudcredentials',
iterator: 'cloudcredential',
selectTitle: 'Add Cloud Credentials',
editTitle: 'CLOUD CREDENTIALS',
selectInstructions: '<p>Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue ' +
'<em>Select</em> button, located bottom right.</p> <p>Create a brand new credential by clicking the <i class=\"fa fa-plus"></i> button.</p>',
index: false,
hover: true,
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description',
excludeModal: false
},
team: {
label: 'Team',
ngBind: 'credential.team_name',
sourceModel: 'team',
sourceField: 'name',
excludeModal: true
},
user: {
label: 'User',
ngBind: 'credential.user_username',
sourceModel: 'user',
sourceField: 'username',
excludeModal: true
}
},
actions: {
add: {
mode: 'all', // One of: edit, select, all
ngClick: 'addCredential()',
awToolTip: 'Create a new credential',
actionClass: 'btn btn-sm List-buttonSubmit',
buttonContent: '&#43; ADD'
}
},
fieldActions: {
edit: {
ngClick: "editCredential(credential.id)",
icon: 'fa-edit',
label: 'Edit',
"class": 'btn-sm',
awToolTip: 'Edit credential',
dataPlacement: 'top'
},
"delete": {
ngClick: "deleteCredential(credential.id, credential.name)",
icon: 'fa-trash-o',
label: 'Delete',
"class": 'btn-sm',
awToolTip: 'Delete credential',
dataPlacement: 'top'
}
}
});

View File

@ -1,27 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('GroupListDefinition', [])
.value('CopyMoveGroupList', {
name: 'groups',
iterator: 'copy',
selectTitle: 'Copy Groups',
index: false,
well: false,
emptyListText: 'PLEASE CREATE ADDITIONAL GROUPS / HOSTS TO PERFORM THIS ACTION',
fields: {
name: {
key: true,
label: 'Target Group Name'
}
},
basePath: 'api/v1/inventories/{{$stateParams.inventory_id}}/groups'
});

View File

@ -1,28 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('HostListDefinition', [])
.value('HostList', {
name: 'copy_hosts',
iterator: 'copy_host',
selectTitle: 'Add Existing Hosts',
editTitle: 'Hosts',
index: false,
well: false,
fields: {
name: {
key: true,
label: 'Host Name'
}
},
actions: { },
fieldActions: { }
});

View File

@ -1,170 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('InventoryGroupsDefinition', [])
.value('InventoryGroups', {
name: 'groups',
iterator: 'group',
editTitle: '{{ inventory.name }}',
listTitle: 'GROUPS',
searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
showTitle: false,
well: true,
index: false,
hover: true,
'class': 'table-no-border',
multiSelect: true,
trackBy: 'group.id',
fields: {
sync_status: {
label: '',
nosort: true,
mode: 'all',
iconOnly: true,
ngClick: 'viewUpdateStatus(group.id)',
awToolTip: "{{ group.status_tooltip }}",
dataTipWatch: "group.status_tooltip",
icon: "{{ 'fa icon-cloud-' + group.status_class }}",
ngClass: "group.status_class",
dataPlacement: "top",
columnClass: 'status-column List-staticColumn--smallStatus'
},
failed_hosts: {
label: '',
nosort: true,
mode: 'all',
iconOnly: true,
awToolTip: "{{ group.hosts_status_tip }}",
dataPlacement: "top",
ngClick: "showFailedHosts(group)",
icon: "{{ 'fa icon-job-' + group.hosts_status_class }}",
columnClass: 'status-column List-staticColumn--smallStatus'
},
name: {
label: 'Groups',
key: true,
ngClick: "groupSelect(group.id)",
columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6',
class: 'InventoryManage-breakWord',
},
total_groups: {
nosort: true,
label: '',
type: 'badgeCount',
ngHide: 'group.total_groups == 0',
noLink: true,
awToolTip: "{{group.name | sanitize}} contains {{group.total_groups}} {{group.total_groups === 1 ? 'child' : 'children'}}"
}
},
actions: {
refresh: {
mode: 'all',
awToolTip: "Refresh the page",
ngClick: "refreshGroups()",
ngShow: "socketStatus == 'error'",
actionClass: 'btn List-buttonDefault',
buttonContent: 'REFRESH'
},
launch: {
mode: 'all',
// $scope.$parent is governed by InventoryManageController,
ngDisabled: '!$parent.groupsSelected && !$parent.hostsSelected',
ngClick: '$parent.setAdhocPattern()',
awToolTip: "Select an inventory source by clicking the check box beside it. The inventory source can be a single group or host, a selection of multiple hosts, or a selection of multiple groups.",
dataTipWatch: "adhocCommandTooltip",
actionClass: 'btn List-buttonDefault',
buttonContent: 'RUN COMMANDS',
showTipWhenDisabled: true,
tooltipInnerClass: "Tooltip-wide",
ngShow: 'canAdhoc'
// TODO: set up a tip watcher and change text based on when
// things are selected/not selected. This is started and
// commented out in the inventory controller within the watchers.
// awToolTip: "{{ adhocButtonTipContents }}",
// dataTipWatch: "adhocButtonTipContents"
},
create: {
mode: 'all',
ngClick: "createGroup()",
awToolTip: "Create a new group",
actionClass: 'btn List-buttonSubmit',
buttonContent: '&#43; ADD GROUP',
ngShow: 'canAdd',
dataPlacement: "top",
}
},
fieldActions: {
columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6 text-right',
group_update: {
//label: 'Sync',
mode: 'all',
ngClick: 'updateGroup(group)',
awToolTip: "{{ group.launch_tooltip }}",
dataTipWatch: "group.launch_tooltip",
ngShow: "(group.status !== 'running' && group.status " +
"!== 'pending' && group.status !== 'updating') && group.summary_fields.user_capabilities.start",
ngClass: "group.launch_class",
dataPlacement: "top",
},
cancel: {
//label: 'Cancel',
mode: 'all',
ngClick: "cancelUpdate(group.id)",
awToolTip: "Cancel sync process",
'class': 'red-txt',
ngShow: "(group.status == 'running' || group.status == 'pending' " +
"|| group.status == 'updating') && group.summary_fields.user_capabilities.start",
dataPlacement: "top",
iconClass: "fa fa-minus-circle"
},
copy: {
mode: 'all',
ngClick: "copyMoveGroup(group.id)",
awToolTip: 'Copy or move group',
ngShow: "group.id > 0 && group.summary_fields.user_capabilities.copy",
dataPlacement: "top"
},
schedule: {
mode: 'all',
ngClick: "scheduleGroup(group.id)",
awToolTip: "{{ group.group_schedule_tooltip }}",
ngClass: "group.scm_type_class",
dataPlacement: 'top',
ngShow: "!(group.summary_fields.inventory_source.source === '')"
},
edit: {
//label: 'Edit',
mode: 'all',
ngClick: "editGroup(group.id)",
awToolTip: 'Edit group',
dataPlacement: "top",
ngShow: "group.summary_fields.user_capabilities.edit"
},
view: {
//label: 'Edit',
mode: 'all',
ngClick: "editGroup(group.id)",
awToolTip: 'View group',
dataPlacement: "top",
ngShow: "!group.summary_fields.user_capabilities.edit"
},
"delete": {
//label: 'Delete',
mode: 'all',
ngClick: "deleteGroup(group)",
awToolTip: 'Delete group',
dataPlacement: "top",
ngShow: "group.summary_fields.user_capabilities.delete"
}
}
});

View File

@ -1,122 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('InventoryHostsDefinition', [])
.value('InventoryHosts', {
name: 'hosts',
iterator: 'host',
editTitle: '{{ selected_group }}',
listTitle: 'HOSTS',
searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
showTitle: false,
well: true,
index: false,
hover: true,
hasChildren: true,
'class': 'table-no-border',
multiSelect: true,
trackBy: 'host.id',
fields: {
active_failures: {
label: '',
iconOnly: true,
nosort: true,
// do not remove this ng-click directive
// the list generator case to handle fields without ng-click
// cannot handle the aw-* directives
ngClick: 'noop()',
awPopOver: "{{ host.job_status_html }}",
dataTitle: "{{ host.job_status_title }}",
awToolTip: "{{ host.badgeToolTip }}",
dataPlacement: 'top',
icon: "{{ 'fa icon-job-' + host.active_failures }}",
id: 'active-failures-action',
columnClass: 'status-column List-staticColumn--smallStatus'
},
name: {
key: true,
label: 'Hosts',
ngClick: "editHost(host.id)",
ngClass: "{ 'host-disabled-label': !host.enabled }",
columnClass: 'col-lg-6 col-md-8 col-sm-8 col-xs-7',
dataHostId: "{{ host.id }}",
dataType: "host",
class: 'InventoryManage-breakWord'
}
},
fieldActions: {
columnClass: 'col-lg-6 col-md-4 col-sm-4 col-xs-5 text-right',
copy: {
mode: 'all',
ngClick: "copyMoveHost(host.id)",
awToolTip: 'Copy or move host to another group',
dataPlacement: "top",
ngShow: 'host.summary_fields.user_capabilities.edit'
},
edit: {
//label: 'Edit',
ngClick: "editHost(host.id)",
icon: 'icon-edit',
awToolTip: 'Edit host',
dataPlacement: 'top',
ngShow: 'host.summary_fields.user_capabilities.edit'
},
view: {
//label: 'Edit',
ngClick: "editHost(host.id)",
awToolTip: 'View host',
dataPlacement: 'top',
ngShow: '!host.summary_fields.user_capabilities.edit'
},
"delete": {
//label: 'Delete',
ngClick: "deleteHost(host.id, host.name)",
icon: 'icon-trash',
awToolTip: 'Delete host',
dataPlacement: 'top',
ngShow: 'host.summary_fields.user_capabilities.delete'
}
},
actions: {
system_tracking: {
buttonContent: 'System Tracking',
ngClick: 'systemTracking()',
awToolTip: "Select one or two hosts by clicking the checkbox beside the host. System tracking offers the ability to compare the results of two scan runs from different dates on one host or the same date on two hosts.",
dataTipWatch: "systemTrackingTooltip",
dataPlacement: 'top',
awFeature: 'system_tracking',
actionClass: 'btn List-buttonDefault system-tracking',
ngDisabled: 'systemTrackingDisabled || !hostsSelected',
showTipWhenDisabled: true,
tooltipInnerClass: "Tooltip-wide",
ngShow: true
},
refresh: {
mode: 'all',
awToolTip: "Refresh the page",
ngClick: "refreshGroups()",
ngShow: "socketStatus == 'error'",
actionClass: 'btn List-buttonDefault',
buttonContent: 'REFRESH'
},
create: {
mode: 'all',
ngClick: "createHost()",
awToolTip: "Create a new host",
actionClass: 'btn List-buttonSubmit',
buttonContent: '&#43; ADD HOST',
ngShow: 'canAdd',
dataPlacement: "top",
}
}
});

View File

@ -1,34 +0,0 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('InventorySourcesListDefinition', [])
.value('InventorySourcesList', {
name: 'workflow_inventory_sources',
iterator: 'inventory_source',
basePath: 'inventory_sources',
listTitle: 'INVENTORY SOURCES',
index: false,
hover: true,
fields: {
name: {
label: 'Name',
ngBind: 'inventory_source.summary_fields.group.name',
columnClass: 'col-md-11',
simpleTip: {
awToolTip: "Inventory: {{inventory_source.summary_fields.inventory.name}}",
dataPlacement: "top"
}
}
},
actions: {},
fieldActions: {}
});

View File

@ -1,104 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('JobEventsListDefinition', [])
.factory('JobEventList', ['i18n', function(i18n) {
return {
name: 'jobevents',
iterator: 'jobevent',
editTitle: i18n._('JOB EVENTS'),
index: false,
hover: true,
"class": "condensed",
hasChildren: true,
filterBy: '{ show: true }',
navigationLinks: {
//details: {
// href: '/#/jobs/{{ job_id }}',
// label: 'Status',
// icon: 'icon-zoom-in',
// ngShow: 'job_id !== null'
//},
events: {
href: '/#/job_events/{{ job_id }}',
label: i18n._('Events'),
active: true,
icon: 'icon-list-ul'
},
hosts: {
href: '/#/job_host_summaries/{{ job_id }}',
label: i18n._('Host Summary'),
icon: 'icon-laptop'
}
},
fields: {
created: {
label: i18n._('Created On'),
columnClass: 'col-lg-1 col-md-1 hidden-sm hidden-xs',
key: true,
nosort: true,
noLink: true
},
status: {
label: i18n._('Status'),
showValue: false,
columnClass: 'col-sm-1 col-xs-2 text-center',
nosort: true,
ngClick: 'viewJobEvent(jobevent.id)',
awToolTip: '{{ jobevent.statusBadgeToolTip }}',
dataPlacement: 'top',
badgeIcon: 'fa icon-job-{{ jobevent.status }}',
badgePlacement: 'left',
badgeToolTip: '{{ jobevent.statusBadgeToolTip }}',
badgeTipPlacement: 'top',
badgeNgClick: 'viewJobEvent(jobevent.id)'
},
event_display: {
label: i18n._('Event'),
hasChildren: true,
ngClick: 'toggleChildren(jobevent.id, jobevent.related.children)',
nosort: true,
ngClass: '{{ jobevent.class }}',
appendHTML: 'jobevent.event_detail'
},
host: {
label: i18n._('Host'),
ngBind: 'jobevent.summary_fields.host.name',
ngHref: '{{ jobevent.hostLink }}',
nosort: true,
id: 'job-event-host-header',
'class': 'break',
columnClass: 'col-lg-2 hidden-sm hidden-xs'
}
},
actions: {
refresh: {
mode: 'all',
awToolTip: 'Refresh the page',
ngClick: 'refresh()',
actionClass: 'btn List-buttonDefault',
buttonContent: i18n._('REFRESH')
}
},
fieldActions: {
columnClass: 'col-sm-1 col-xs-2',
view: {
label: i18n._('View'),
ngClick: 'viewJobEvent(jobevent.id)',
awToolTip: i18n._('View event details'),
dataPlacement: 'top'
}
}
};}]);

View File

@ -1,105 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('JobHostDefinition', [])
.value('JobHostList', {
name: 'jobhosts',
iterator: 'jobhost',
editTitle: 'ALL SUMMARIES',
"class": "table-condensed",
index: false,
hover: true,
navigationLinks: {
ngHide: 'host_id !== null',
//details: {
// href: "/#/jobs/{{ job_id }}",
// label: 'Status',
// icon: 'icon-zoom-in',
// ngShow: "job_id !== null"
//},
events: {
href: "/#/job_events/{{ job_id }}",
label: 'Events',
icon: 'icon-list-ul'
},
hosts: {
href: "/#/job_host_summariess/{{ job_id }}",
label: 'Host Summary',
active: true,
icon: 'icon-laptop'
}
},
fields: {
host: {
label: 'Host',
key: true,
sourceModel: 'host',
sourceField: 'name',
ngBind: 'jobhost.host_name',
ngHref: "{{ jobhost.hostLinkTo }}"
},
status: {
label: 'Status',
badgeNgHref: "{{ jobhost.statusLinkTo }}",
badgeIcon: 'fa icon-job-{{ jobhost.status }}',
badgePlacement: 'left',
badgeToolTip: "{{ jobhost.statusBadgeToolTip }}",
badgeTipPlacement: 'top',
ngHref: "{{ jobhost.statusLinkTo }}",
awToolTip: "{{ jobhost.statusBadgeToolTip }}",
dataPlacement: 'top'
},
ok: {
label: 'Success',
},
changed: {
label: 'Changed',
},
failures: {
label: 'Failure',
},
dark: {
label: 'Unreachable',
},
skipped: {
label: 'Skipped',
}
},
actions: {
help: {
awPopOver: "<dl>\n<dt>Success</dt><dd>Tasks successfully executed on the host.</dd>\n" +
"<dt>Changed</dt><dd>Actions taken on the host.</dd>\n" +
"<dt>Failure</dt><dd>Tasks that failed on the host.</dd>\n" +
"<dt>Unreachable</dt><dd>Times the ansible server could not reach the host.</dd>\n" +
"<dt>Skipped</dt><dd>Tasks bypassed and not performed on the host due to prior task failure or the host being unreachable.</dd>\n" +
"</dl>\n",
dataPlacement: 'left',
dataContainer: "body",
mode: 'all',
actionClass: 'btn-xs btn-help',
awToolTip: 'Click for help',
dataTitle: 'Job Host Summary',
id: 'jobhost-help-button'
},
refresh: {
mode: 'all',
awToolTip: "Refresh the page",
ngClick: "refresh()",
ngShow: "host_id == null", //don't show when viewing from inventory->hosts
actionClass: 'btn List-buttonDefault',
buttonContent: 'REFRESH'
}
}
//fieldActions: {}
});

View File

@ -1,85 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
angular.module('JobsListDefinition', [])
.value( 'JobsList', {
name: 'jobs',
iterator: 'job',
editTitle: 'JOBS',
'class': 'table-condensed',
index: false,
hover: true,
well: false,
fields: {
id: {
label: 'ID',
ngClick:"viewjobResults(job)",
key: true,
desc: true,
columnClass: 'col-lg-1 col-md-1 col-sm-2 col-xs-2',
awToolTip: "{{ job.status_tip }}",
awTipPlacement: "top",
},
status: {
label: '',
columnClass: 'col-lg-1 col-md-2 col-sm-2 col-xs-2',
awToolTip: "{{ job.status_tip }}",
awTipPlacement: "top",
dataTitle: "{{ job.status_popover_title }}",
icon: 'icon-job-{{ job.status }}',
iconOnly: true,
ngClick:"viewjobResults(job)"
},
started: {
label: 'Started',
noLink: true,
filter: "longDate",
columnClass: "col-lg-2 col-md-2 hidden-xs"
},
type: {
label: 'Type',
ngBind: 'job.type_label',
link: false,
columnClass: "col-lg-2 col-md-2 hidden-sm hidden-xs"
},
name: {
label: 'Name',
columnClass: 'col-md-3 col-xs-5',
ngClick: "viewjobResults(job)",
}
},
actions: { },
fieldActions: {
submit: {
mode: 'all',
icon: 'icon-rocket',
ngClick: 'relaunchJob($event, job.id)',
awToolTip: 'Relaunch using the same parameters',
dataPlacement: 'top',
ngHide: "job.type == 'system_job' "
},
cancel: {
mode: 'all',
ngClick: 'deleteJob(job.id)',
awToolTip: 'Cancel the job',
dataPlacement: 'top',
ngShow: "job.status == 'running'"
},
"delete": {
mode: 'all',
ngClick: 'deleteJob(job.id)',
awToolTip: 'Delete the job',
dataPlacement: 'top',
ngShow: "job.status != 'running'"
}
}
});

View File

@ -8,8 +8,8 @@ export default ['$scope', '$rootScope', '$location', '$stateParams',
'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait','$state',
function($scope, $rootScope, $location, $stateParams, OrganizationForm,
GenerateForm, Rest, Alert, ProcessErrors,
ClearScope, GetBasePath, Wait, $state) {
GenerateForm, Rest, Alert, ProcessErrors, ClearScope, GetBasePath, Wait,
$state) {
Rest.setUrl(GetBasePath('organizations'));
Rest.options()

View File

@ -4,12 +4,11 @@
* All Rights Reserved
*************************************************/
export default ['$scope', '$rootScope', '$location', '$log', '$stateParams',
'OrganizationForm', 'Rest', 'Alert', 'ProcessErrors', 'Prompt', 'ClearScope',
'GetBasePath', 'Wait', '$state', 'ToggleNotification',
function($scope, $rootScope, $location, $log, $stateParams,
OrganizationForm, Rest, Alert, ProcessErrors, Prompt, ClearScope,
GetBasePath, Wait, $state, ToggleNotification) {
export default ['$scope', '$location', '$stateParams', 'OrganizationForm',
'Rest', 'ProcessErrors', 'Prompt', 'ClearScope', 'GetBasePath', 'Wait',
'$state', 'ToggleNotification', function($scope, $location, $stateParams,
OrganizationForm, Rest, ProcessErrors, Prompt, ClearScope, GetBasePath,
Wait, $state, ToggleNotification) {
ClearScope();

View File

@ -11,11 +11,13 @@
* Controller for handling permissions adding
*/
export default ['$scope', '$rootScope', 'ProcessErrors', 'GetBasePath', 'generateList',
'templateUrl', '$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'UserList',
function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
templateUrl, $state, Rest, $q, Wait, $window, qs, UserList) {
$scope.$on("linkLists", function() {
export default ['$scope', '$rootScope', 'ProcessErrors', 'GetBasePath',
'generateList', '$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet',
'UserList',
function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
$state, Rest, $q, Wait, $window, qs, UserList) {
$scope.$on("linkLists", function() {
if ($state.current.name.split(".")[1] === "users") {
$scope.addType = "Users";

View File

@ -6,56 +6,56 @@
/* jshint unused: vars */
import addUsers from './addUsers.controller';
export default
['Wait', 'templateUrl', '$state', '$view', '$compile', function(Wait, templateUrl, $state, $view, $compile) {
return {
restrict: 'E',
scope: {
addUsersType: '@'
},
controller: addUsers,
templateUrl: templateUrl('organizations/linkout/addUsers/addUsers'),
link: function(scope, element, attrs, ctrl) {
export default ['Wait', 'templateUrl', '$compile', function(Wait, templateUrl,
$compile) {
return {
restrict: 'E',
scope: {
addUsersType: '@'
},
controller: addUsers,
templateUrl: templateUrl('organizations/linkout/addUsers/addUsers'),
link: function(scope, element, attrs, ctrl) {
$("body").addClass("is-modalOpen");
$("body").addClass("is-modalOpen");
$("body").append(element);
$("body").append(element);
Wait('start');
Wait('start');
scope.$broadcast("linkLists");
scope.$broadcast("linkLists");
setTimeout(function() {
$('#add-users-modal').modal("show");
}, 200);
setTimeout(function() {
$('#add-users-modal').modal("show");
}, 200);
$('.modal[aria-hidden=false]').each(function () {
if ($(this).attr('id') !== 'add-users-modal') {
$(this).modal('hide');
}
});
$('.modal[aria-hidden=false]').each(function () {
if ($(this).attr('id') !== 'add-users-modal') {
$(this).modal('hide');
}
});
scope.closeModal = function() {
$("body").removeClass("is-modalOpen");
$('#add-users-modal').on('hidden.bs.modal',
function () {
$('.AddUsers').remove();
});
$('#add-users-modal').modal('hide');
};
scope.closeModal = function() {
$("body").removeClass("is-modalOpen");
$('#add-users-modal').on('hidden.bs.modal',
function () {
$('.AddUsers').remove();
});
$('#add-users-modal').modal('hide');
};
scope.$on('closeUsersModal', function() {
scope.closeModal();
});
scope.$on('closeUsersModal', function() {
scope.closeModal();
});
scope.compileList = function(html) {
$('#add-users-list').append($compile(html)(scope));
};
scope.compileList = function(html) {
$('#add-users-list').append($compile(html)(scope));
};
Wait('stop');
Wait('stop');
window.scrollTo(0,0);
}
};
}
];
window.scrollTo(0,0);
}
};
}
];

View File

@ -4,13 +4,11 @@
* All Rights Reserved
*************************************************/
export default ['$stateParams', '$scope', 'UserList', 'Rest', '$state',
'generateList', '$compile', 'Wait', 'OrgAdminList',
'OrgAdminsDataset',
'Prompt', 'ProcessErrors', 'GetBasePath', '$filter',
function($stateParams, $scope, UserList, Rest, $state, GenerateList,
$compile, Wait, OrgAdminList, OrgAdminsDataset, Prompt, ProcessErrors,
GetBasePath, $filter) {
export default ['$stateParams', '$scope', 'Rest', '$state', '$compile', 'Wait',
'OrgAdminList', 'OrgAdminsDataset', 'Prompt', 'ProcessErrors',
'GetBasePath', '$filter',
function($stateParams, $scope, Rest, $state, $compile, Wait, OrgAdminList,
OrgAdminsDataset, Prompt, ProcessErrors, GetBasePath, $filter) {
var orgBase = GetBasePath('organizations');

View File

@ -4,15 +4,12 @@
* All Rights Reserved
*************************************************/
export default ['$scope', '$rootScope', '$location', '$log',
'$stateParams', 'Rest', 'Alert', 'Prompt', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
'GetBasePath', 'JobTemplateForm', 'InitiatePlaybookRun', 'Wait', 'TemplateCopyService',
'$compile', '$state', 'OrgJobTemplateList', 'OrgJobTemplateDataset', 'QuerySet',
function($scope, $rootScope, $location, $log,
$stateParams, Rest, Alert, Prompt, ReturnToCaller, ClearScope, ProcessErrors,
GetBasePath, JobTemplateForm, InitiatePlaybookRun, Wait, TemplateCopyService,
$compile, $state, OrgJobTemplateList, Dataset, qs) {
export default ['$scope', '$rootScope', '$stateParams', 'Rest', 'ProcessErrors',
'GetBasePath', 'InitiatePlaybookRun', 'Wait', 'TemplateCopyService',
'$state', 'OrgJobTemplateList', 'OrgJobTemplateDataset', 'QuerySet',
function($scope, $rootScope, $stateParams, Rest, ProcessErrors, GetBasePath,
InitiatePlaybookRun, Wait, TemplateCopyService, $state, OrgJobTemplateList,
Dataset, qs) {
var list = OrgJobTemplateList,
orgBase = GetBasePath('organizations');

View File

@ -4,15 +4,14 @@
* All Rights Reserved
*************************************************/
export default ['$scope', '$rootScope', '$location', '$log',
'$stateParams', 'Rest', 'Alert', 'Prompt',
'ReturnToCaller', 'ClearScope', 'OrgProjectList', 'OrgProjectDataset',
'ProcessErrors', 'GetBasePath', 'ProjectUpdate',
'Wait', 'GetChoices', 'Empty', 'Find', 'GetProjectIcon', 'GetProjectToolTip', '$filter', '$state',
function($scope, $rootScope, $location, $log, $stateParams, Rest, Alert, Prompt,
ReturnToCaller, ClearScope, OrgProjectList, Dataset,
ProcessErrors, GetBasePath, ProjectUpdate,
Wait, GetChoices, Empty, Find, GetProjectIcon, GetProjectToolTip, $filter, $state) {
export default ['$scope', '$rootScope', '$log', '$stateParams', 'Rest', 'Alert',
'OrgProjectList', 'OrgProjectDataset', 'ProcessErrors', 'GetBasePath',
'ProjectUpdate', 'Wait', 'GetChoices', 'Empty', 'Find', 'GetProjectIcon',
'GetProjectToolTip', '$filter', '$state',
function($scope, $rootScope, $log, $stateParams, Rest, Alert,
OrgProjectList, Dataset, ProcessErrors, GetBasePath, ProjectUpdate,
Wait, GetChoices, Empty, Find, GetProjectIcon, GetProjectToolTip, $filter,
$state) {
var list = OrgProjectList,
projUrl,

View File

@ -4,15 +4,10 @@
* All Rights Reserved
*************************************************/
export default ['$scope', '$rootScope', '$location', '$log', '$stateParams', 'OrgTeamList',
'Rest', 'Alert', 'Prompt', 'OrgTeamsDataset', 'ReturnToCaller', 'ClearScope',
'ProcessErrors', 'GetBasePath',
'Wait', '$state',
function($scope, $rootScope, $location, $log, $stateParams, OrgTeamList,
Rest, Alert, Prompt, Dataset, ReturnToCaller, ClearScope,
ProcessErrors, GetBasePath,
Wait, $state) {
export default ['$scope', '$stateParams', 'OrgTeamList', 'Rest',
'OrgTeamsDataset', 'GetBasePath', 'Wait', '$state',
function($scope, $stateParams, OrgTeamList, Rest, Dataset, GetBasePath,
Wait, $state) {
var list = OrgTeamList,
orgBase = GetBasePath('organizations');

View File

@ -5,11 +5,10 @@
*************************************************/
export default ['$stateParams', '$scope', 'OrgUserList','Rest', '$state',
'generateList', '$compile', 'Wait', 'OrgUsersDataset',
'Prompt', 'ProcessErrors', 'GetBasePath', '$filter',
function($stateParams, $scope, OrgUserList, Rest, $state, GenerateList,
$compile, Wait, OrgUsersDataset, Prompt, ProcessErrors,
GetBasePath, $filter) {
'$compile', 'Wait', 'OrgUsersDataset', 'Prompt', 'ProcessErrors',
'GetBasePath', '$filter',
function($stateParams, $scope, OrgUserList, Rest, $state, $compile, Wait,
OrgUsersDataset, Prompt, ProcessErrors, GetBasePath, $filter) {
var orgBase = GetBasePath('organizations');

View File

@ -10,6 +10,8 @@ import OrganizationsAdd from './add/organizations-add.controller';
import OrganizationsEdit from './edit/organizations-edit.controller';
import organizationsLinkout from './linkout/main';
import OrganizationsLinkoutStates from './linkout/organizations-linkout.route';
import OrganizationForm from './organizations.form';
import OrganizationList from './organizations.list';
import { N_ } from '../i18n';
@ -20,6 +22,8 @@ angular.module('Organizations', [
.controller('OrganizationsList', OrganizationsList)
.controller('OrganizationsAdd', OrganizationsAdd)
.controller('OrganizationsEdit', OrganizationsEdit)
.factory('OrganizationForm', OrganizationForm)
.factory('OrganizationList', OrganizationList)
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
let stateExtender = $stateExtenderProvider.$get(),

View File

@ -10,10 +10,10 @@
* @description This form is for adding/editing an organization
*/
export default
angular.module('OrganizationFormDefinition', [])
.factory('OrganizationFormObject', ['i18n', function(i18n) {
return {
export default ['NotificationsList', 'i18n',
function(NotificationsList, i18n) {
return function() {
var OrganizationFormObject = {
addTitle: i18n._('NEW ORGANIZATION'), //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
@ -98,18 +98,15 @@ export default
}
}
};}])
};
.factory('OrganizationForm', ['OrganizationFormObject', 'NotificationsList',
function(OrganizationFormObject, NotificationsList) {
return function() {
var itm;
for (itm in OrganizationFormObject.related) {
if (OrganizationFormObject.related[itm].include === "NotificationsList") {
OrganizationFormObject.related[itm] = NotificationsList;
OrganizationFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
}
return OrganizationFormObject;
};
}]);
var itm;
for (itm in OrganizationFormObject.related) {
if (OrganizationFormObject.related[itm].include === "NotificationsList") {
OrganizationFormObject.related[itm] = NotificationsList;
OrganizationFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
}
return OrganizationFormObject;
};
}];

View File

@ -5,17 +5,15 @@
*************************************************/
export default
angular.module('OrganizationListDefinition', [])
.value('OrganizationList', {
export default [function() {
return {
name: 'organizations',
iterator: 'organization',
selectTitle: 'Add Organizations',
selectInstructions: '<p>Select existing organizations by clicking each organization or checking the related checkbox. When finished, ' +
'click the blue <em>Select</em> button, located bottom right.</p><p>Create a new organization by clicking the ' +
'<i class=\"fa fa-plus\"></i> button.</p>',
editTitle: 'ORGANIZATIONS',
editTitle: 'Organizations',
hover: true,
index: false,
@ -62,4 +60,5 @@ export default
dataPlacement: 'top'
}
}
});
};
}];

View File

@ -5,9 +5,13 @@
*************************************************/
import route from './portal-mode.route';
import PortalJobsList from './portal-jobs.list';
import PortalJobTemplateList from './portal-job-templates.list';
export default
angular.module('portalMode', [])
.factory('PortalJobsList', PortalJobsList)
.factory('PortalJobTemplateList', PortalJobTemplateList)
.run(['$stateExtender', function($stateExtender){
$stateExtender.addState(route);
}]);
}]);

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('PortalJobTemplatesListDefinition', [])
.factory('PortalJobTemplateList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'job_templates',
@ -43,4 +41,4 @@ export default
dataPlacement: 'top'
}
}
};}]);
};}];

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('PortalJobsListDefinition', [])
.factory('PortalJobsList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'jobs',
@ -44,4 +42,4 @@ export default
},
actions: { }
};}]);
};}];

View File

@ -13,7 +13,6 @@
export default ['i18n', 'NotificationsList', function(i18n, NotificationsList) {
return function() {
var projectsFormObj = {
addTitle: i18n._('NEW PROJECT'),
editTitle: '{{ name }}',
name: 'project',

View File

@ -16,6 +16,8 @@ import EditSchedule from './factories/edit-schedule.factory';
import RRuleToAPI from './factories/r-rule-to-api.factory';
import SchedulePost from './factories/schedule-post.factory';
import ToggleSchedule from './factories/toggle-schedule.factory';
import SchedulesList from './schedules.list';
import ScheduledJobsList from './scheduled-jobs.list';
export default
angular.module('scheduler', [])
@ -28,6 +30,8 @@ export default
.factory('RRuleToAPI', RRuleToAPI)
.factory('SchedulePost', SchedulePost)
.factory('ToggleSchedule', ToggleSchedule)
.factory('SchedulesList', SchedulesList)
.factory('ScheduledJobsList', ScheduledJobsList)
.directive('schedulerDatePicker', schedulerDatePicker)
.run(['$stateExtender', function($stateExtender) {
// Inventory sync schedule states registered in: awx/ui/client/src/inventories/manage/groups/main.js

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('ScheduledJobsDefinition', [])
.factory('ScheduledJobsList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'schedules',
@ -85,4 +83,4 @@ export default
ngShow: 'schedule.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('SchedulesListDefinition', [])
.factory('SchedulesList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'schedules',
@ -97,4 +95,4 @@ export default
ngShow: 'schedule.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -745,9 +745,6 @@ function(ConfigurationUtils, i18n, $rootScope) {
.directive('awToolTip', [function() {
return {
link: function(scope, element, attrs) {
// if (attrs.class.indexOf("JobResultsStdOut") > -1) {
// debugger;
// }
var delay = { show: 200, hide: 0 },
placement,
stateChangeWatcher;

View File

@ -4,10 +4,10 @@
* All Rights Reserved
*************************************************/
export default ['$scope', '$rootScope', '$stateParams', 'TeamForm', 'GenerateForm',
'Rest', 'Alert', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', '$state',
function($scope, $rootScope, $stateParams, TeamForm, GenerateForm, Rest, Alert, ProcessErrors,
ClearScope, GetBasePath, Wait, $state) {
export default ['$scope', '$rootScope', 'TeamForm', 'GenerateForm', 'Rest',
'Alert', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', '$state',
function($scope, $rootScope, TeamForm, GenerateForm, Rest, Alert,
ProcessErrors, ClearScope, GetBasePath, Wait, $state) {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//$scope.

View File

@ -6,9 +6,8 @@
export default ['$scope', '$rootScope', '$stateParams', 'TeamForm', 'Rest',
'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', '$state',
function($scope, $rootScope, $stateParams,
TeamForm, Rest, ProcessErrors, ClearScope, GetBasePath, Wait, $state) {
function($scope, $rootScope, $stateParams, TeamForm, Rest, ProcessErrors,
ClearScope, GetBasePath, Wait, $state) {
ClearScope();
var form = TeamForm,

View File

@ -4,11 +4,10 @@
* All Rights Reserved
*************************************************/
export default ['$scope', '$rootScope', '$log',
'$stateParams', 'Rest', 'Alert', 'TeamList', 'Prompt', 'ClearScope',
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset',
function($scope, $rootScope, $log, $stateParams,
Rest, Alert, TeamList, Prompt, ClearScope, ProcessErrors,
export default ['$scope', 'Rest', 'TeamList', 'Prompt', 'ClearScope',
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
'rbacUiControlService', 'Dataset',
function($scope, Rest, TeamList, Prompt, ClearScope, ProcessErrors,
GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset) {
ClearScope();

View File

@ -7,6 +7,8 @@
import TeamsList from './list/teams-list.controller';
import TeamsAdd from './add/teams-add.controller';
import TeamsEdit from './edit/teams-edit.controller';
import TeamList from './teams.list';
import TeamForm from './teams.form';
import { N_ } from '../i18n';
export default
@ -14,6 +16,8 @@ angular.module('Teams', [])
.controller('TeamsList', TeamsList)
.controller('TeamsAdd', TeamsAdd)
.controller('TeamsEdit', TeamsEdit)
.factory('TeamList', TeamList)
.factory('TeamForm', TeamForm)
.config(['$stateProvider', 'stateDefinitionsProvider',
function($stateProvider, stateDefinitionsProvider) {
let stateDefinitions = stateDefinitionsProvider.$get();

View File

@ -10,9 +10,7 @@
* @description This form is for adding/editing teams
*/
export default
angular.module('TeamFormDefinition', [])
.factory('TeamForm', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
addTitle: i18n._('NEW TEAM'), //Legend in add mode
@ -162,4 +160,4 @@ export default
}
}
},
};}]); //InventoryForm
};}];

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('TeamsListDefinition', [])
.factory('TeamList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'teams',
@ -83,4 +81,4 @@ export default
ngShow: 'team.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('CompletedJobsDefinition', [])
.factory('CompletedJobsList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
// These tooltip fields are consumed to build disabled related tabs tooltips in the form > add view
awToolTip: i18n._('Please save and run a job to view'),
@ -84,4 +82,4 @@ export default
ngShow: 'completed_job.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -0,0 +1,31 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'workflow_inventory_sources',
iterator: 'inventory_source',
basePath: 'inventory_sources',
listTitle: 'INVENTORY SOURCES',
index: false,
hover: true,
fields: {
name: {
label: 'Name',
ngBind: 'inventory_source.summary_fields.group.name',
columnClass: 'col-md-11',
simpleTip: {
awToolTip: "Inventory: {{inventory_source.summary_fields.inventory.name}}",
dataPlacement: "top"
}
}
},
actions: {},
fieldActions: {}
};

View File

@ -11,11 +11,10 @@
*/
export default
angular.module('JobTemplateFormDefinition', [ 'CompletedJobsDefinition'])
.factory('JobTemplateFormObject', ['i18n', function(i18n) {
return {
export default ['NotificationsList', 'CompletedJobsList', 'i18n',
function(NotificationsList, CompletedJobsList, i18n) {
return function() {
var JobTemplateFormObject = {
addTitle: i18n._('NEW JOB TEMPLATE'),
editTitle: '{{ name }}',
@ -487,26 +486,22 @@ export default
class: 'Form-primaryButton'
}
}
};}])
};
var itm;
.factory('JobTemplateForm', ['JobTemplateFormObject', 'NotificationsList', 'CompletedJobsList',
function(JobTemplateFormObject, NotificationsList, CompletedJobsList) {
return function() {
var itm;
for (itm in JobTemplateFormObject.related) {
if (JobTemplateFormObject.related[itm].include === "NotificationsList") {
JobTemplateFormObject.related[itm] = _.clone(NotificationsList);
JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.notifications')";
JobTemplateFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
if (JobTemplateFormObject.related[itm].include === "CompletedJobsList") {
JobTemplateFormObject.related[itm] = CompletedJobsList;
JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.completed_jobs')";
JobTemplateFormObject.related[itm].generateList = true;
}
}
for (itm in JobTemplateFormObject.related) {
if (JobTemplateFormObject.related[itm].include === "NotificationsList") {
JobTemplateFormObject.related[itm] = _.clone(NotificationsList);
JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.notifications')";
JobTemplateFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
if (JobTemplateFormObject.related[itm].include === "CompletedJobsList") {
JobTemplateFormObject.related[itm] = CompletedJobsList;
JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.completed_jobs')";
JobTemplateFormObject.related[itm].generateList = true;
}
}
return JobTemplateFormObject;
};
}]);
return JobTemplateFormObject;
};
}];

View File

@ -20,6 +20,11 @@ import workflowService from './workflows/workflow.service';
import templateCopyService from './copy-template/template-copy.service';
import CallbackHelpInit from './job_templates/factories/callback-help-init.factory';
import md5Setup from './job_templates/factories/md-5-setup.factory';
import WorkflowForm from './workflows.form';
import CompletedJobsList from './completed-jobs.list';
import InventorySourcesList from './inventory-sources.list';
import TemplateList from './templates.list';
import JobTemplateForm from './job-template.form';
export default
angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesAdd.name,
@ -31,6 +36,11 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
.service('TemplateCopyService', templateCopyService)
.factory('CallbackHelpInit', CallbackHelpInit)
.factory('md5Setup', md5Setup)
.factory('WorkflowForm', WorkflowForm)
.factory('CompletedJobsList', CompletedJobsList)
.factory('TemplateList', TemplateList)
.factory('JobTemplateForm', JobTemplateForm)
.value('InventorySourcesList', InventorySourcesList)
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('TemplatesListDefinition', [])
.factory('TemplateList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'templates',
@ -129,4 +127,4 @@ export default
ngShow: 'template.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -10,11 +10,9 @@
* @description This form is for adding/editing a Workflow
*/
export default
angular.module('WorkflowFormDefinition', [])
.factory('WorkflowFormObject', ['i18n', function(i18n) {
return {
export default ['NotificationsList', 'i18n', function(NotificationsList, i18n) {
return function() {
var WorkflowFormObject = {
addTitle: i18n._('NEW WORKFLOW JOB TEMPLATE'),
editTitle: '{{ name }}',
@ -190,21 +188,18 @@ export default
class: 'Form-primaryButton'
}
}
};}])
};
.factory('WorkflowForm', ['WorkflowFormObject', 'NotificationsList',
function(WorkflowFormObject, NotificationsList) {
return function() {
var itm;
var itm;
for (itm in WorkflowFormObject.related) {
if (WorkflowFormObject.related[itm].include === "NotificationsList") {
WorkflowFormObject.related[itm] = _.clone(NotificationsList);
WorkflowFormObject.related[itm].ngClick = "$state.go('templates.editWorkflowJobTemplate.notifications')";
WorkflowFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
}
for (itm in WorkflowFormObject.related) {
if (WorkflowFormObject.related[itm].include === "NotificationsList") {
WorkflowFormObject.related[itm] = _.clone(NotificationsList);
WorkflowFormObject.related[itm].ngClick = "$state.go('templates.editWorkflowJobTemplate.notifications')";
WorkflowFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
}
return WorkflowFormObject;
};
}]);
return WorkflowFormObject;
};
}];

View File

@ -4,15 +4,13 @@
* All Rights Reserved
*************************************************/
export default
[ '$scope', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors', 'ClearScope',
'Wait', '$state', 'CreateSelect2', 'TemplatesService', 'ToJSON',
'ParseTypeChange', 'OrganizationList', '$q', 'Rest', 'GetBasePath',
function(
$scope, WorkflowForm, GenerateForm, Alert, ProcessErrors, ClearScope,
Wait, $state, CreateSelect2, TemplatesService, ToJSON,
ParseTypeChange, OrganizationList, $q, Rest, GetBasePath
) {
export default [
'$scope', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors',
'ClearScope', 'Wait', '$state', 'CreateSelect2', 'TemplatesService',
'ToJSON', 'ParseTypeChange', '$q', 'Rest', 'GetBasePath',
function($scope, WorkflowForm, GenerateForm, Alert, ProcessErrors,
ClearScope, Wait, $state, CreateSelect2, TemplatesService, ToJSON,
ParseTypeChange, $q, Rest, GetBasePath) {
Rest.setUrl(GetBasePath('workflow_job_templates'));
Rest.options()

View File

@ -4,18 +4,16 @@
* All Rights Reserved
*************************************************/
export default
[ '$scope', '$stateParams', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors',
'ClearScope', 'GetBasePath', '$q', 'ParseTypeChange', 'Wait', 'Empty',
'ToJSON', 'initSurvey', '$state', 'CreateSelect2', 'ParseVariableString',
'TemplatesService', 'OrganizationList', 'Rest', 'WorkflowService', 'ToggleNotification', 'OrgAdminLookup',
function(
$scope, $stateParams, WorkflowForm, GenerateForm, Alert, ProcessErrors,
ClearScope, GetBasePath, $q, ParseTypeChange, Wait, Empty,
ToJSON, SurveyControllerInit, $state, CreateSelect2, ParseVariableString,
TemplatesService, OrganizationList, Rest, WorkflowService, ToggleNotification, OrgAdminLookup
) {
export default [
'$scope', '$stateParams', 'WorkflowForm', 'GenerateForm', 'Alert',
'ProcessErrors', 'ClearScope', 'GetBasePath', '$q', 'ParseTypeChange',
'Wait', 'Empty', 'ToJSON', 'initSurvey', '$state', 'CreateSelect2',
'ParseVariableString', 'TemplatesService', 'Rest', 'ToggleNotification',
'OrgAdminLookup',
function($scope, $stateParams, WorkflowForm, GenerateForm, Alert,
ProcessErrors, ClearScope, GetBasePath, $q, ParseTypeChange, Wait, Empty,
ToJSON, SurveyControllerInit, $state, CreateSelect2, ParseVariableString,
TemplatesService, Rest, ToggleNotification, OrgAdminLookup) {
ClearScope();
$scope.$watch('workflow_job_template_obj.summary_fields.user_capabilities.edit', function(val) {

View File

@ -4,7 +4,7 @@
* All Rights Reserved
*************************************************/
export default [ '$state','moment', '$timeout', '$window',
export default ['$state','moment', '$timeout', '$window',
function($state, moment, $timeout, $window) {
return {

View File

@ -1,9 +1,11 @@
import workflowMaker from './workflow-maker.directive';
import WorkflowMakerController from './workflow-maker.controller';
import WorkflowMakerForm from './workflow-maker.form';
export default
angular.module('templates.workflowMaker', [])
// In order to test this controller I had to expose it at the module level
// like so. Is this correct? Is there a better pattern for doing this?
.controller('WorkflowMakerController', WorkflowMakerController)
.factory('WorkflowMakerForm', WorkflowMakerForm)
.directive('workflowMaker', workflowMaker);

View File

@ -4,14 +4,10 @@
* All Rights Reserved
*************************************************/
export default ['$scope', 'WorkflowService', 'generateList', 'TemplateList', 'ProjectList',
'GetBasePath', 'Wait', 'TemplatesService', '$state',
'ProcessErrors', 'InventorySourcesList', 'CreateSelect2', 'WorkflowMakerForm',
'GenerateForm', 'InventoryList', 'CredentialList', '$q',
function($scope, WorkflowService, GenerateList, TemplateList, ProjectList,
GetBasePath, Wait, TemplatesService, $state,
ProcessErrors, InventorySourcesList, CreateSelect2, WorkflowMakerForm,
GenerateForm, InventoryList, CredentialList, $q) {
export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
'$state', 'ProcessErrors', 'CreateSelect2', 'WorkflowMakerForm', '$q',
function($scope, WorkflowService, GetBasePath, TemplatesService, $state,
ProcessErrors, CreateSelect2, WorkflowMakerForm, $q) {
let form = WorkflowMakerForm();

View File

@ -10,16 +10,9 @@
* @description This form is for adding/editing a Job Template
*/
// export default
// angular.module('WorkflowMakerFormDefinition', [])
//
// .value ('WorkflowMakerFormObject', {
export default
angular.module('WorkflowMakerFormDefinition', [])
.factory('WorkflowMakerFormObject', ['i18n', function(i18n) {
return {
export default ['NotificationsList', 'i18n', function(NotificationsList, i18n) {
return function() {
var WorkflowMakerFormObject = {
addTitle: '',
editTitle: '',
@ -176,16 +169,15 @@ export default
ngShow: '(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
}
}
};}])
.factory('WorkflowMakerForm', ['WorkflowMakerFormObject', 'NotificationsList', function(WorkflowMakerFormObject, NotificationsList) {
return function() {
var itm;
for (itm in WorkflowMakerFormObject.related) {
if (WorkflowMakerFormObject.related[itm].include === "NotificationsList") {
WorkflowMakerFormObject.related[itm] = NotificationsList;
WorkflowMakerFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
}
return WorkflowMakerFormObject;
};
}]);
};
var itm;
for (itm in WorkflowMakerFormObject.related) {
if (WorkflowMakerFormObject.related[itm].include === "NotificationsList") {
WorkflowMakerFormObject.related[itm] = NotificationsList;
WorkflowMakerFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
}
return WorkflowMakerFormObject;
};
}];

View File

@ -12,13 +12,12 @@ const user_type_options = [
{ type: 'system_administrator', label: N_('System Administrator') },
];
export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'GenerateForm',
'Rest', 'Alert', 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'GetBasePath',
export default ['$scope', '$rootScope', 'UserForm', 'GenerateForm', 'Rest',
'Alert', 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'GetBasePath',
'Wait', 'CreateSelect2', '$state', '$location', 'i18n',
function($scope, $rootScope, $stateParams, UserForm,
GenerateForm, Rest, Alert, ProcessErrors, ReturnToCaller, ClearScope,
GetBasePath, Wait, CreateSelect2, $state, $location, i18n) {
function($scope, $rootScope, UserForm, GenerateForm, Rest, Alert,
ProcessErrors, ReturnToCaller, ClearScope, GetBasePath, Wait, CreateSelect2,
$state, $location, i18n) {
ClearScope();
var defaultUrl = GetBasePath('organizations'),

View File

@ -12,11 +12,10 @@ const user_type_options = [
{ type: 'system_administrator', label: N_('System Administrator') },
];
export default ['$scope', '$rootScope', '$location',
'$stateParams', 'UserForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath',
'Wait', 'CreateSelect2', '$state', 'i18n',
function($scope, $rootScope, $location,
$stateParams, UserForm, Rest, ProcessErrors,
export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'Rest',
'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', 'CreateSelect2',
'$state', 'i18n',
function($scope, $rootScope, $stateParams, UserForm, Rest, ProcessErrors,
ClearScope, GetBasePath, Wait, CreateSelect2, $state, i18n) {
for (var i = 0; i < user_type_options.length; i++) {

View File

@ -12,12 +12,12 @@ const user_type_options = [
{ type: 'system_administrator', label: N_('System Administrator') },
];
export default ['$scope', '$rootScope', '$stateParams',
'Rest', 'Alert', 'UserList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'i18n',
function($scope, $rootScope, $stateParams,
Rest, Alert, UserList, Prompt, ClearScope, ProcessErrors, GetBasePath,
Wait, $state, $filter, rbacUiControlService, Dataset, i18n) {
export default ['$scope', '$rootScope', 'Rest', 'UserList', 'Prompt',
'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
'rbacUiControlService', 'Dataset', 'i18n',
function($scope, $rootScope, Rest, UserList, Prompt, ClearScope,
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService,
Dataset, i18n) {
for (var i = 0; i < user_type_options.length; i++) {
user_type_options[i].label = i18n._(user_type_options[i].label);

View File

@ -7,6 +7,8 @@
import UsersList from './list/users-list.controller';
import UsersAdd from './add/users-add.controller';
import UsersEdit from './edit/users-edit.controller';
import UserForm from './users.form';
import UserList from './users.list';
import { N_ } from '../i18n';
export default
@ -14,6 +16,8 @@ angular.module('Users', [])
.controller('UsersList', UsersList)
.controller('UsersAdd', UsersAdd)
.controller('UsersEdit', UsersEdit)
.factory('UserForm', UserForm)
.factory('UserList', UserList)
.config(['$stateProvider', 'stateDefinitionsProvider',
function($stateProvider, stateDefinitionsProvider) {
let stateDefinitions = stateDefinitionsProvider.$get();

View File

@ -10,9 +10,7 @@
* @description This form is for adding/editing users
*/
export default
angular.module('UserFormDefinition', [])
.factory('UserForm', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
addTitle: i18n._('NEW USER'),
@ -229,4 +227,4 @@ export default
}
}
};}]);
};}];

View File

@ -5,9 +5,7 @@
*************************************************/
export default
angular.module('UserListDefinition', [])
.factory('UserList', ['i18n', function(i18n) {
export default ['i18n', function(i18n) {
return {
name: 'users',
@ -87,4 +85,4 @@ export default
ngShow: 'user.summary_fields.user_capabilities.delete'
}
}
};}]);
};}];

View File

@ -1,30 +1,9 @@
export default ['workflowData',
'workflowResultsService',
'workflowDataOptions',
'jobLabels',
'workflowNodes',
'$scope',
'ParseTypeChange',
'ParseVariableString',
'WorkflowService',
'count',
'$state',
'i18n',
'moment',
function(workflowData,
workflowResultsService,
workflowDataOptions,
jobLabels,
workflowNodes,
$scope,
ParseTypeChange,
ParseVariableString,
WorkflowService,
count,
$state,
i18n,
moment
) {
export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
'jobLabels', 'workflowNodes', '$scope', 'ParseTypeChange',
'ParseVariableString', 'WorkflowService', 'count', '$state', 'i18n',
'moment', function(workflowData, workflowResultsService,
workflowDataOptions, jobLabels, workflowNodes, $scope, ParseTypeChange,
ParseVariableString, WorkflowService, count, $state, i18n, moment) {
var runTimeElapsedTimer = null;
var getTowerLinks = function() {