mirror of
https://github.com/ansible/awx.git
synced 2026-05-19 14:57:39 -02:30
Latest UI changes
This commit is contained in:
@@ -26,17 +26,20 @@
|
|||||||
<script src="js/controllers/Users.js"></script>
|
<script src="js/controllers/Users.js"></script>
|
||||||
<script src="js/controllers/Admins.js"></script>
|
<script src="js/controllers/Admins.js"></script>
|
||||||
<script src="js/controllers/Inventories.js"></script>
|
<script src="js/controllers/Inventories.js"></script>
|
||||||
|
<script src="js/controllers/Teams.js"></script>
|
||||||
<script src="js/controllers/Hosts.js"></script>
|
<script src="js/controllers/Hosts.js"></script>
|
||||||
<script src="js/controllers/Groups.js"></script>
|
<script src="js/controllers/Groups.js"></script>
|
||||||
<script src="js/forms/Users.js"></script>
|
<script src="js/forms/Users.js"></script>
|
||||||
<script src="js/forms/Organizations.js"></script>
|
<script src="js/forms/Organizations.js"></script>
|
||||||
<script src="js/forms/Inventories.js"></script>
|
<script src="js/forms/Inventories.js"></script>
|
||||||
|
<script src="js/forms/Teams.js"></script>
|
||||||
<script src="js/forms/Hosts.js"></script>
|
<script src="js/forms/Hosts.js"></script>
|
||||||
<script src="js/forms/Groups.js"></script>
|
<script src="js/forms/Groups.js"></script>
|
||||||
<script src="js/lists/Users.js"></script>
|
<script src="js/lists/Users.js"></script>
|
||||||
<script src="js/lists/Organizations.js"></script>
|
<script src="js/lists/Organizations.js"></script>
|
||||||
<script src="js/lists/Admins.js"></script>
|
<script src="js/lists/Admins.js"></script>
|
||||||
<script src="js/lists/Inventories.js"></script>
|
<script src="js/lists/Inventories.js"></script>
|
||||||
|
<script src="js/lists/Teams.js"></script>
|
||||||
<script src="js/lists/Hosts.js"></script>
|
<script src="js/lists/Hosts.js"></script>
|
||||||
<script src="js/lists/Groups.js"></script>
|
<script src="js/lists/Groups.js"></script>
|
||||||
<script src="js/helpers/api-defaults.js"></script>
|
<script src="js/helpers/api-defaults.js"></script>
|
||||||
@@ -48,6 +51,7 @@
|
|||||||
<script src="js/helpers/paginate.js"></script>
|
<script src="js/helpers/paginate.js"></script>
|
||||||
<script src="js/helpers/inventory.js"></script>
|
<script src="js/helpers/inventory.js"></script>
|
||||||
<script src="js/helpers/hosts.js"></script>
|
<script src="js/helpers/hosts.js"></script>
|
||||||
|
<script src="js/helpers/teams.js"></script>
|
||||||
<script src="lib/ansible/directives.js"></script>
|
<script src="lib/ansible/directives.js"></script>
|
||||||
<script src="lib/ansible/filters.js"></script>
|
<script src="lib/ansible/filters.js"></script>
|
||||||
<script src="lib/ansible/tooltip.js"></script>
|
<script src="lib/ansible/tooltip.js"></script>
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ angular.module('ansible', [
|
|||||||
'HostHelper',
|
'HostHelper',
|
||||||
'GroupFormDefinition',
|
'GroupFormDefinition',
|
||||||
'GroupListDefinition',
|
'GroupListDefinition',
|
||||||
|
'TeamsListDefinition',
|
||||||
|
'TeamFormDefinition',
|
||||||
|
'TeamHelper'
|
||||||
])
|
])
|
||||||
.config(['$routeProvider', function($routeProvider) {
|
.config(['$routeProvider', function($routeProvider) {
|
||||||
$routeProvider.
|
$routeProvider.
|
||||||
@@ -60,7 +63,7 @@ angular.module('ansible', [
|
|||||||
when('/inventories/:id/groups/add', { templateUrl: 'partials/inventories.html',
|
when('/inventories/:id/groups/add', { templateUrl: 'partials/inventories.html',
|
||||||
controller: GroupsAdd }).
|
controller: GroupsAdd }).
|
||||||
|
|
||||||
when('/inventories/:inventory_id/groups/:id', { templateUrl: 'partials/inventories.html',
|
when('/inventories/:inventory_id/groups/:id', { templateUrl: 'partials/inventories.html',
|
||||||
controller: GroupsEdit }).
|
controller: GroupsEdit }).
|
||||||
|
|
||||||
when('/organizations', { templateUrl: 'partials/organizations.html',
|
when('/organizations', { templateUrl: 'partials/organizations.html',
|
||||||
@@ -83,6 +86,15 @@ angular.module('ansible', [
|
|||||||
|
|
||||||
when('/organizations/:organization_id/users/:id', { templateUrl: 'partials/users.html',
|
when('/organizations/:organization_id/users/:id', { templateUrl: 'partials/users.html',
|
||||||
controller: UsersEdit }).
|
controller: UsersEdit }).
|
||||||
|
|
||||||
|
when('/teams', { templateUrl: 'partials/teams.html',
|
||||||
|
controller: TeamsList }).
|
||||||
|
|
||||||
|
when('/teams/add', { templateUrl: 'partials/teams.html',
|
||||||
|
controller: TeamsAdd }).
|
||||||
|
|
||||||
|
when('/teams/:id', { templateUrl: 'partials/teams.html',
|
||||||
|
controller: TeamsEdit }).
|
||||||
|
|
||||||
when('/users', { templateUrl: 'partials/users.html',
|
when('/users', { templateUrl: 'partials/users.html',
|
||||||
controller: UsersList }).
|
controller: UsersList }).
|
||||||
|
|||||||
@@ -105,17 +105,24 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (scope.selected.length > 0 ) {
|
if (scope.selected.length > 0 ) {
|
||||||
|
var inventory = null;
|
||||||
for (var i=0; i < scope.selected.length; i++) {
|
for (var i=0; i < scope.selected.length; i++) {
|
||||||
var inventory = scope.inventoies[scope.selected[i]].name;
|
for (var j=0; j < scope.inventories.length; j++) {
|
||||||
Rest.post(scope.inventories[scope.selected[i]])
|
if (scope.inventories[j].id == scope.selected[i]) {
|
||||||
.success( function(data, status, headers, config) {
|
inventory = scope.inventories[j];
|
||||||
scope.queue.push({ result: 'success', data: data, status: status });
|
}
|
||||||
scope.$emit('callFinished');
|
}
|
||||||
})
|
if (inventory !== null) {
|
||||||
.error( function(data, status, headers, config) {
|
Rest.post(inventory)
|
||||||
scope.queue.push({ result: 'error', data: data, status: status, headers: headers });
|
.success( function(data, status, headers, config) {
|
||||||
scope.$emit('callFinished');
|
scope.queue.push({ result: 'success', data: data, status: status });
|
||||||
});
|
scope.$emit('callFinished');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
scope.queue.push({ result: 'error', data: data, status: status, headers: headers });
|
||||||
|
scope.$emit('callFinished');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
328
lib/static/web/app/js/controllers/Teams.js
Normal file
328
lib/static/web/app/js/controllers/Teams.js
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
/************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Teams.js
|
||||||
|
*
|
||||||
|
* Controller functions for the Team model.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function TeamsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, TeamList,
|
||||||
|
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
|
||||||
|
ClearScope, ProcessErrors, SetTeamListeners)
|
||||||
|
{
|
||||||
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
|
//scope.
|
||||||
|
var list = TeamList;
|
||||||
|
var defaultUrl = '/api/v1/teams/';
|
||||||
|
var view = GenerateList;
|
||||||
|
var paths = $location.path().replace(/^\//,'').split('/');
|
||||||
|
var mode = (paths[0] == 'teams') ? 'edit' : 'select'; // if base path 'teams', we're here to add/edit teams
|
||||||
|
var scope = view.inject(list, { mode: mode }); // Inject our view
|
||||||
|
scope.selected = [];
|
||||||
|
|
||||||
|
SetTeamListeners({ scope: scope, set: 'teams', iterator: list.iterator });
|
||||||
|
SearchInit({ scope: scope, set: 'teams', list: list, url: defaultUrl });
|
||||||
|
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||||
|
scope.search(list.iterator);
|
||||||
|
|
||||||
|
LoadBreadCrumbs();
|
||||||
|
|
||||||
|
scope.addTeam = function() {
|
||||||
|
$location.path($location.path() + '/add');
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.editTeam = function(id) {
|
||||||
|
$location.path($location.path() + '/' + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.deleteTeam = function(id, name) {
|
||||||
|
|
||||||
|
var action = function() {
|
||||||
|
var url = defaultUrl + id + '/';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.delete()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
scope.search(list.iterator);
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Prompt({ hdr: 'Delete',
|
||||||
|
body: 'Are you sure you want to delete ' + name + '?',
|
||||||
|
action: action
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.lookupOrganization = function(organization_id) {
|
||||||
|
Rest.setUrl('/api/v1/organization/' + organization_id + '/');
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
return data.name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.finishSelection = function() {
|
||||||
|
Rest.setUrl('/api/v1' + $location.path() + '/'); // We're assuming the path matches the api path.
|
||||||
|
// Will this always be true??
|
||||||
|
scope.queue = [];
|
||||||
|
|
||||||
|
scope.$on('callFinished', function() {
|
||||||
|
// We call the API for each selected user. We need to hang out until all the api
|
||||||
|
// calls are finished.
|
||||||
|
if (scope.queue.length == scope.selected.length) {
|
||||||
|
// All the api calls finished
|
||||||
|
$('input[type="checkbox"]').prop("checked",false);
|
||||||
|
scope.selected = [];
|
||||||
|
var errors = 0;
|
||||||
|
for (var i=0; i < scope.queue.length; i++) {
|
||||||
|
if (scope.queue[i].result == 'error') {
|
||||||
|
errors++;
|
||||||
|
// there is no way to know which user raised the error. no data comes
|
||||||
|
// back from the api call.
|
||||||
|
// $('td.username-column').each(function(index) {
|
||||||
|
// if ($(this).text() == scope.queue[i].username) {
|
||||||
|
// $(this).addClass("error");
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errors > 0) {
|
||||||
|
Alert('Error', 'There was an error while adding one or more of the selected teams.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ReturnToCaller(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (scope.selected.length > 0 ) {
|
||||||
|
var team = null;
|
||||||
|
for (var i=0; i < scope.selected.length; i++) {
|
||||||
|
for (var j=0; j < scope.teams.length; j++) {
|
||||||
|
if (scope.teams[j].id == scope.selected[i]) {
|
||||||
|
team = scope.teams[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (team !== null) {
|
||||||
|
Rest.post(team)
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
scope.queue.push({ result: 'success', data: data, status: status });
|
||||||
|
scope.$emit('callFinished');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
scope.queue.push({ result: 'error', data: data, status: status, headers: headers });
|
||||||
|
scope.$emit('callFinished');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ReturnToCaller();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.toggle_team = function(idx) {
|
||||||
|
if (scope.selected.indexOf(idx) > -1) {
|
||||||
|
scope.selected.splice(scope.selected.indexOf(idx),1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope.selected.push(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'TeamList', 'GenerateList',
|
||||||
|
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
|
||||||
|
'SetTeamListeners' ];
|
||||||
|
|
||||||
|
|
||||||
|
function TeamsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm,
|
||||||
|
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
|
||||||
|
GenerateList, OrganizationList, SearchInit, PaginateInit, TeamLookUpOrganizationInit)
|
||||||
|
{
|
||||||
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
|
//scope.
|
||||||
|
|
||||||
|
// Inject dynamic view
|
||||||
|
var defaultUrl = '/api/v1/teams/';
|
||||||
|
var form = TeamForm;
|
||||||
|
var generator = GenerateForm;
|
||||||
|
var scope = generator.inject(form, {mode: 'add', related: false});
|
||||||
|
generator.reset();
|
||||||
|
LoadBreadCrumbs();
|
||||||
|
TeamLookUpOrganizationInit({ scope: scope });
|
||||||
|
|
||||||
|
// Save
|
||||||
|
scope.formSave = function() {
|
||||||
|
Rest.setUrl(defaultUrl);
|
||||||
|
var data = {}
|
||||||
|
for (var fld in form.fields) {
|
||||||
|
data[fld] = scope[fld];
|
||||||
|
}
|
||||||
|
Rest.post(data)
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
ReturnToCaller();
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, form,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to add new inventory. Post returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
scope.formReset = function() {
|
||||||
|
// Defaults
|
||||||
|
generator.reset();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm', 'GenerateForm',
|
||||||
|
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateList',
|
||||||
|
'OrganizationList', 'SearchInit', 'PaginateInit', 'TeamLookUpOrganizationInit' ];
|
||||||
|
|
||||||
|
|
||||||
|
function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm,
|
||||||
|
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit,
|
||||||
|
RelatedPaginateInit, ReturnToCaller, ClearScope, TeamLookUpOrganizationInit, Prompt)
|
||||||
|
{
|
||||||
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
|
//scope.
|
||||||
|
|
||||||
|
var defaultUrl='/api/v1/teams/';
|
||||||
|
var generator = GenerateForm;
|
||||||
|
var form = InventoryForm;
|
||||||
|
var scope = generator.inject(form, {mode: 'edit', related: true});
|
||||||
|
generator.reset();
|
||||||
|
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||||
|
var master = {};
|
||||||
|
var id = $routeParams.id;
|
||||||
|
var relatedSets = {};
|
||||||
|
|
||||||
|
TeamLookUpOrganizationInit({ scope: scope });
|
||||||
|
|
||||||
|
// After inventory is loaded, retrieve each related set and any lookups
|
||||||
|
scope.$on('teamLoaded', function() {
|
||||||
|
Rest.setUrl(scope['organization_url']);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
scope['organization_name'] = data.name;
|
||||||
|
master['organization_name'] = data.name;
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to retrieve: ' + scope.orgnization_url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
for (var set in relatedSets) {
|
||||||
|
scope.search(relatedSets[set].iterator);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Retrieve detail record and prepopulate the form
|
||||||
|
Rest.setUrl(defaultUrl + ':id/');
|
||||||
|
Rest.get({ params: {id: id} })
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
LoadBreadCrumbs({ path: '/teams/' + id, title: data.name });
|
||||||
|
for (var fld in form.fields) {
|
||||||
|
if (data[fld]) {
|
||||||
|
scope[fld] = data[fld];
|
||||||
|
master[fld] = scope[fld];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var related = data.related;
|
||||||
|
for (var set in form.related) {
|
||||||
|
if (related[set]) {
|
||||||
|
relatedSets[set] = { url: related[set], iterator: form.related[set].iterator };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||||
|
RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets });
|
||||||
|
RelatedPaginateInit({ scope: scope, relatedSets: relatedSets });
|
||||||
|
scope['organization_url'] = data.related.organization;
|
||||||
|
scope.$emit('teamLoaded');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, form,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to retrieve team: ' + $routeParams.id + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save changes to the parent
|
||||||
|
scope.formSave = function() {
|
||||||
|
Rest.setUrl(defaultUrl + $routeParams.id);
|
||||||
|
var data = {}
|
||||||
|
for (var fld in form.fields) {
|
||||||
|
data[fld] = scope[fld];
|
||||||
|
}
|
||||||
|
Rest.put(data)
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||||
|
(base == 'inventories') ? ReturnToCaller() : ReturnToCaller(1);
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, form,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to update team: ' + $routeParams.id + '. PUT status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
scope.formReset = function() {
|
||||||
|
generator.reset();
|
||||||
|
for (var fld in master) {
|
||||||
|
scope[fld] = master[fld];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Related set: Add button
|
||||||
|
scope.add = function(set) {
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
$location.path('/' + base + '/' + $routeParams.id + '/' + set + '/add');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Related set: Edit button
|
||||||
|
scope.edit = function(set, id, name) {
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
$location.path('/' + base + '/' + $routeParams.id + '/' + set + '/' + id);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Related set: Delete button
|
||||||
|
scope.delete = function(set, itm_id, name, title) {
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
|
||||||
|
var action = function() {
|
||||||
|
var url = defaultUrl + id + '/' + set + '/';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post({ id: itm_id, disassociate: 1 })
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
scope.search(form.related[set].iterator);
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Prompt({ hdr: 'Delete',
|
||||||
|
body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?',
|
||||||
|
action: action
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm',
|
||||||
|
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
|
||||||
|
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'TeamLookUpOrganizationInit', 'Prompt'
|
||||||
|
];
|
||||||
|
|
||||||
65
lib/static/web/app/js/forms/Teams.js
Normal file
65
lib/static/web/app/js/forms/Teams.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* Teams.js
|
||||||
|
* Form definition for Team model
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
angular.module('TeamFormDefinition', [])
|
||||||
|
.value(
|
||||||
|
'TeamForm', {
|
||||||
|
|
||||||
|
addTitle: 'Create Team', //Legend in add mode
|
||||||
|
editTitle: '{{ name }}', //Legend in edit mode
|
||||||
|
name: 'team',
|
||||||
|
well: true,
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
name: {
|
||||||
|
label: 'Name',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
capitalize: true
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: 'Description',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true
|
||||||
|
},
|
||||||
|
organization: {
|
||||||
|
label: 'Organization',
|
||||||
|
type: 'lookup',
|
||||||
|
sourceModel: 'organization',
|
||||||
|
sourceField: 'name',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
ngClick: 'lookUpOrganization()'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
buttons: { //for now always generates <button> tags
|
||||||
|
save: {
|
||||||
|
label: 'Save',
|
||||||
|
icon: 'icon-ok',
|
||||||
|
class: 'btn btn-success',
|
||||||
|
ngClick: 'formSave()', //$scope.function to call on click, optional
|
||||||
|
ngDisabled: true //Disable when $pristine or $invalid, optional
|
||||||
|
},
|
||||||
|
reset: {
|
||||||
|
ngClick: 'formReset()',
|
||||||
|
label: 'Reset',
|
||||||
|
icon: 'icon-remove',
|
||||||
|
class: 'btn',
|
||||||
|
ngDisabled: true //Disabled when $pristine
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
related: { //related colletions (and maybe items?)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}); //InventoryForm
|
||||||
|
|
||||||
@@ -36,6 +36,10 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities'])
|
|||||||
lookup_results = [];
|
lookup_results = [];
|
||||||
scope.$emit('refreshFinished', data['results']);
|
scope.$emit('refreshFinished', data['results']);
|
||||||
}
|
}
|
||||||
|
else if (set == 'teams') {
|
||||||
|
lookup_results = [];
|
||||||
|
scope.$emit('TeamRefreshFinished', data['results']);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
scope[iterator + 'SearchSpin'] = false;
|
scope[iterator + 'SearchSpin'] = false;
|
||||||
scope[set] = data['results'];
|
scope[set] = data['results'];
|
||||||
|
|||||||
109
lib/static/web/app/js/helpers/teams.js
Normal file
109
lib/static/web/app/js/helpers/teams.js
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* TeamHelper
|
||||||
|
* Routines shared amongst the team controllers
|
||||||
|
*/
|
||||||
|
|
||||||
|
angular.module('TeamHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition',
|
||||||
|
'SearchHelper', 'PaginateHelper', 'ListGenerator' ])
|
||||||
|
.factory('SetTeamListeners', ['Alert', 'Rest', function(Alert, Rest) {
|
||||||
|
return function(params) {
|
||||||
|
|
||||||
|
var scope = params.scope;
|
||||||
|
var set = params.set;
|
||||||
|
var iterator = params.iterator;
|
||||||
|
|
||||||
|
// Listeners to perform lookups after main inventory list loads
|
||||||
|
|
||||||
|
scope.$on('TeamResultFound', function(e, results, lookup_results) {
|
||||||
|
if ( lookup_results.length == results.length ) {
|
||||||
|
key = 'organization';
|
||||||
|
property = 'organization_name';
|
||||||
|
for (var i=0; i < results.length; i++) {
|
||||||
|
for (var j=0; j < lookup_results.length; j++) {
|
||||||
|
if (results[i][key] == lookup_results[j].id) {
|
||||||
|
results[i][property] = lookup_results[j].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope[iterator + 'SearchSpin'] = false;
|
||||||
|
scope[set] = results;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.$on('TeamRefreshFinished', function(e, results) {
|
||||||
|
// Loop through the result set (sent to us by the search helper) and
|
||||||
|
// lookup the id and name of each organization. After each lookup
|
||||||
|
// completes, call resultFound.
|
||||||
|
|
||||||
|
var lookup_results = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < results.length; i++) {
|
||||||
|
Rest.setUrl('/api/v1/organizations/' + results[i].organization + '/');
|
||||||
|
Rest.get()
|
||||||
|
.success( function( data, status, headers, config) {
|
||||||
|
console.log('here!');
|
||||||
|
console.log(data);
|
||||||
|
lookup_results.push({ id: data.id, value: data.name });
|
||||||
|
scope.$emit('TeamResultFound', results, lookup_results);
|
||||||
|
})
|
||||||
|
.error( function( data, status, headers, config) {
|
||||||
|
lookup_results.push({ id: 'error' });
|
||||||
|
scope.$emit('TeamResultFound', results, lookup_results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
.factory('TeamLookUpOrganizationInit', ['Alert', 'Rest', 'OrganizationList', 'GenerateList', 'SearchInit', 'PaginateInit',
|
||||||
|
function(Alert, Rest, OrganizationList, GenerateList, SearchInit, PaginateInit) {
|
||||||
|
return function(params) {
|
||||||
|
|
||||||
|
var scope = params.scope;
|
||||||
|
|
||||||
|
// Show pop-up to select organization
|
||||||
|
scope.lookUpOrganization = function() {
|
||||||
|
var list = OrganizationList;
|
||||||
|
var listGenerator = GenerateList;
|
||||||
|
var listScope = listGenerator.inject(list, { mode: 'lookup', hdr: 'Select Organization' });
|
||||||
|
var defaultUrl = '/api/v1/organizations';
|
||||||
|
|
||||||
|
listScope.selectAction = function() {
|
||||||
|
var found = false;
|
||||||
|
for (var i=0; i < listScope[list.name].length; i++) {
|
||||||
|
if (listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] == "success") {
|
||||||
|
found = true;
|
||||||
|
scope['organization'] = listScope[list.name][i].id;
|
||||||
|
scope['organization_name'] = listScope[list.name][i].name;
|
||||||
|
scope['team_form'].$setDirty();
|
||||||
|
listGenerator.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found == false) {
|
||||||
|
Alert('No Selection', 'Click on a row to select an Organization before clicking the Select button.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listScope.toggle_organization = function(id) {
|
||||||
|
// when user clicks a row, remove 'success' class from all rows except clicked-on row
|
||||||
|
if (listScope[list.name]) {
|
||||||
|
for (var i=0; i < listScope[list.name].length; i++) {
|
||||||
|
listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id != null && id != undefined) {
|
||||||
|
listScope[list.iterator + "_" + id + "_class"] = "success";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchInit({ scope: listScope, set: list.name, list: list, url: defaultUrl });
|
||||||
|
PaginateInit({ scope: listScope, list: list, url: defaultUrl, mode: 'lookup' });
|
||||||
|
scope.search(list.iterator);
|
||||||
|
listScope.toggle_organization(scope.organization);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
|
||||||
59
lib/static/web/app/js/lists/Teams.js
Normal file
59
lib/static/web/app/js/lists/Teams.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* Teams.js
|
||||||
|
* List view object for Team data model.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
angular.module('TeamsListDefinition', [])
|
||||||
|
.value(
|
||||||
|
'TeamList', {
|
||||||
|
|
||||||
|
name: 'teams',
|
||||||
|
iterator: 'team',
|
||||||
|
selectTitle: 'Add Team',
|
||||||
|
editTitle: 'Teams',
|
||||||
|
selectInstructions: 'Check the Select checkbox next to each team to be added, and click Finished when done. Use the green <i class=\"icon-plus\"></i> button to create a new team.',
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
name: {
|
||||||
|
key: true,
|
||||||
|
label: 'Name'
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: 'Descriptions'
|
||||||
|
},
|
||||||
|
organization: {
|
||||||
|
label: 'Organization',
|
||||||
|
ngBind: 'team.organization_name',
|
||||||
|
sourceModel: 'organization',
|
||||||
|
sourceField: 'name'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
add: {
|
||||||
|
icon: 'icon-plus',
|
||||||
|
mode: 'all', // One of: edit, select, all
|
||||||
|
ngClick: 'addTeam()',
|
||||||
|
class: 'btn btn-mini btn-success',
|
||||||
|
awToolTip: 'Create a new team'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fieldActions: {
|
||||||
|
edit: {
|
||||||
|
ngClick: "editTeam(\{\{ team.id \}\})",
|
||||||
|
icon: 'icon-edit',
|
||||||
|
awToolTip: 'Edit team'
|
||||||
|
},
|
||||||
|
|
||||||
|
delete: {
|
||||||
|
ngClick: "deleteTeam(\{\{ team.id \}\},'\{\{ team.name \}\}')",
|
||||||
|
icon: 'icon-remove',
|
||||||
|
class: 'btn-danger',
|
||||||
|
awToolTip: 'Delete team'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
3
lib/static/web/app/partials/teams.html
Normal file
3
lib/static/web/app/partials/teams.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="tab-pane" id="teams">
|
||||||
|
<div id="htmlTemplate"></div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user