1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 15:21:13 +03:00

Replaced TB accordions with JQueryUI accordions. We now keep track of which accordions are open on each page. When the user navigates away and then comes back to a page, the accordions are restored. Accordion state is stored in the session cookie.

This commit is contained in:
chouseknecht 2013-06-27 03:37:42 -04:00
parent 453c13f116
commit 0277a2177c
28 changed files with 1448 additions and 98 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -133,6 +133,15 @@ angular.module('ansible', [
when('/teams/:team_id', { templateUrl: urlPrefix + 'partials/teams.html', when('/teams/:team_id', { templateUrl: urlPrefix + 'partials/teams.html',
controller: TeamsEdit }). controller: TeamsEdit }).
when('/teams/:team_id/permissions/add', { templateUrl: urlPrefix + 'partials/teams.html',
controller: PermissionsAdd }).
when('/teams/:team_id/permissions', { templateUrl: urlPrefix + 'partials/teams.html',
controller: PermissionsList }).
when('/teams/:team_id/permissions/:permission_id', { templateUrl: urlPrefix + 'partials/teams.html',
controller: PermissionsEdit }).
when('/teams/:team_id/users', { templateUrl: urlPrefix + 'partials/teams.html', when('/teams/:team_id/users', { templateUrl: urlPrefix + 'partials/teams.html',
controller: UsersList }). controller: UsersList }).

View File

@ -317,13 +317,23 @@ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
// Related set: Add button // Related set: Add button
scope.add = function(set) { scope.add = function(set) {
$rootScope.flashMessage = null; $rootScope.flashMessage = null;
$location.path('/' + base + '/' + $routeParams.team_id + '/' + set); if (set == 'permissions') {
$location.path('/' + base + '/' + $routeParams.team_id + '/' + set + '/add');
}
else {
$location.path('/' + base + '/' + $routeParams.team_id + '/' + set);
}
}; };
// Related set: Edit button // Related set: Edit button
scope.edit = function(set, id, name) { scope.edit = function(set, id, name) {
$rootScope.flashMessage = null; $rootScope.flashMessage = null;
$location.path('/' + set + '/' + id); if (set == 'permissions') {
$location.path('/' + base + '/' + $routeParams.team_id + '/' + set + '/' + id);
}
else {
$location.path('/' + set + '/' + id);
}
}; };
// Related set: Delete button // Related set: Delete button
@ -331,25 +341,41 @@ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
$rootScope.flashMessage = null; $rootScope.flashMessage = null;
var action = function() { var action = function() {
var url = defaultUrl + $routeParams.team_id + '/' + set + '/'; var url;
Rest.setUrl(url); if (set == 'permissions') {
Rest.post({ id: itm_id, disassociate: 1 }) url = GetBasePath('base') + 'permissions/' + itm_id + '/';
.success( function(data, status, headers, config) { Rest.setUrl(url);
$('#prompt-modal').modal('hide'); Rest.destroy()
scope.search(form.related[set].iterator); .success( function(data, status, headers, config) {
}) $('#prompt-modal').modal('hide');
.error( function(data, status, headers, config) { scope.search(form.related[set].iterator);
$('#prompt-modal').modal('hide'); })
ProcessErrors(scope, data, status, null, .error( function(data, status, headers, config) {
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); $('#prompt-modal').modal('hide');
}); ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
});
}
else {
var url = defaultUrl + $routeParams.team_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', Prompt({ hdr: 'Delete',
body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?',
action: action action: action
}); });
} }
} }

View File

@ -11,9 +11,13 @@ angular.module('TeamFormDefinition', [])
'TeamForm', { 'TeamForm', {
addTitle: 'Create Team', //Legend in add mode addTitle: 'Create Team', //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode editTitle: '{{ name }}', //Legend in edit mode
name: 'team', name: 'team',
well: true, well: true,
collapse: true,
collapseTitle: 'Team Settings',
collapseMode: 'edit',
collapseOpen: true,
fields: { fields: {
name: { name: {
@ -58,52 +62,6 @@ angular.module('TeamFormDefinition', [])
related: { //related colletions (and maybe items?) related: { //related colletions (and maybe items?)
users: {
type: 'collection',
title: 'Users',
iterator: 'user',
open: false,
actions: {
add: {
ngClick: "add('users')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a user'
}
},
fields: {
username: {
key: true,
label: 'Username'
},
first_name: {
label: 'First Name'
},
last_name: {
label: 'Last Name'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('users', \{\{ user.id \}\}, '\{\{ user.username \}\}')",
icon: 'icon-edit',
"class": 'btn-success',
awToolTip: 'Edit user'
},
"delete": {
label: 'Delete',
ngClick: "delete('users', \{\{ user.id \}\}, '\{\{ user.username \}\}', 'users')",
icon: 'icon-remove',
"class": 'btn-danger',
awToolTip: 'Remove user'
}
}
},
credentials: { credentials: {
type: 'collection', type: 'collection',
title: 'Credentials', title: 'Credentials',
@ -147,6 +105,61 @@ angular.module('TeamFormDefinition', [])
} }
}, },
permissions: {
type: 'collection',
title: 'Permissions',
iterator: 'permission',
open: false,
actions: {
add: {
ngClick: "add('permissions')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a permission for this user'
}
},
fields: {
name: {
key: true,
label: 'Name',
ngClick: "edit('permissions', \{\{ permission.id \}\}, '\{\{ permission.name \}\}')"
},
project: {
label: 'Project',
sourceModel: 'project',
sourceField: 'name',
ngBind: 'permission.summary_fields.project.name',
},
inventory: {
label: 'Inventory',
sourceModel: 'inventory',
sourceField: 'name',
ngBind: 'permission.summary_fields.inventory.name',
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('permissions', \{\{ permission.id \}\}, '\{\{ permission.name \}\}')",
icon: 'icon-edit',
"class": 'btn-success',
awToolTip: 'Edit the permission'
},
"delete": {
label: 'Delete',
ngClick: "delete('permissions', \{\{ permission.id \}\}, '\{\{ permission.name \}\}', 'permissions')",
icon: 'icon-remove',
"class": 'btn-danger',
awToolTip: 'Delete the permission'
}
}
},
projects: { projects: {
type: 'collection', type: 'collection',
title: 'Projects', title: 'Projects',
@ -187,6 +200,52 @@ angular.module('TeamFormDefinition', [])
awToolTip: 'Remove the project' awToolTip: 'Remove the project'
} }
} }
},
users: {
type: 'collection',
title: 'Users',
iterator: 'user',
open: false,
actions: {
add: {
ngClick: "add('users')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a user'
}
},
fields: {
username: {
key: true,
label: 'Username'
},
first_name: {
label: 'First Name'
},
last_name: {
label: 'Last Name'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('users', \{\{ user.id \}\}, '\{\{ user.username \}\}')",
icon: 'icon-edit',
"class": 'btn-success',
awToolTip: 'Edit user'
},
"delete": {
label: 'Delete',
ngClick: "delete('users', \{\{ user.id \}\}, '\{\{ user.username \}\}', 'users')",
icon: 'icon-remove',
"class": 'btn-danger',
awToolTip: 'Remove user'
}
}
} }
} }

View File

@ -13,7 +13,11 @@ angular.module('UserFormDefinition', [])
addTitle: 'Create User', //Legend in add mode addTitle: 'Create User', //Legend in add mode
editTitle: '{{ username }}', //Legend in edit mode editTitle: '{{ username }}', //Legend in edit mode
name: 'user', //Form name attribute name: 'user', //Form name attribute
well: true, //Wrap the form with TB well well: true, //Wrap the form with TB well
collapse: true,
collapseTitle: 'User Settings',
collapseMode: 'edit',
collapseOpen: true,
fields: { fields: {
username: { username: {

View File

@ -8,9 +8,9 @@
* *
*/ */
angular.module('FormGenerator', ['GeneratorHelpers']) angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
.factory('GenerateForm', [ '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column', .factory('GenerateForm', [ '$location', '$cookieStore', '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column',
function($compile, SearchWidget, PaginateWidget, Attr, Icon, Column) { function($location, $cookieStore, $compile, SearchWidget, PaginateWidget, Attr, Icon, Column) {
return { return {
setForm: function(form) { setForm: function(form) {
@ -106,18 +106,66 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
}, },
addListeners: function() { addListeners: function() {
// Listen for accordion collapse events and toggle the header icon
$('.collapse') $('.jqui-accordion').each( function(index) {
.on('show', function() {
var element = $(this).parent().find('.accordion-heading i'); var active = false;
element.removeClass('icon-angle-down'); var list = $cookieStore.get('accordions');
element.addClass('icon-angle-up'); var found = false;
}) if (list) {
.on('hide', function() { var id = $(this).attr('id');
var element = $(this).parent().find('.accordion-heading i'); var base = ($location.path().replace(/^\//,'').split('/')[0]);
element.removeClass('icon-angle-up'); for (var i=0; i < list.length && found == false; i++) {
element.addClass('icon-angle-down'); if (list[i].base == base && list[i].id == id) {
}); found = true;
active = list[i].active;
}
}
}
if (found == false && $(this).attr('data-open') == 'true') {
active = 0;
}
$(this).accordion({
collapsible: true,
heightStyle: 'content',
active: active,
activate: function( event, ui ) {
$('.jqui-accordion').each( function(index) {
var active = $(this).accordion('option', 'active');
var id = $(this).attr('id');
var base = ($location.path().replace(/^\//,'').split('/')[0]);
var list = $cookieStore.get('accordions');
if (list == null || list == undefined) {
list = [];
}
var found = false;
for (var i=0; i < list.length && found == false; i++) {
if ( list[i].base == base && list[i].id == id) {
found = true;
list[i].active = active;
}
}
if (found == false) {
list.push({ base: base, id: id, active: active });
}
$cookieStore.put('accordions',list);
});
}
});
});
},
genID: function() {
var id = new Date();
return id.getTime();
}, },
headerField: function(fld, field, options) { headerField: function(fld, field, options) {
@ -556,13 +604,21 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
else { else {
if ( this.form.collapse && this.form.collapseMode == options.mode) { if ( this.form.collapse && this.form.collapseMode == options.mode) {
html += "<div class=\"accordion-group\">\n"; /*html += "<div class=\"accordion-group\">\n";
html += "<div class=\"accordion-heading\">\n"; html += "<div class=\"accordion-heading\">\n";
html += "<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse1\">"; html += "<a id=\"" + this.form.name + "-collapse-0\" class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse0\">";
html += "<i class=\"icon-angle-down icon-white\"></i>" + this.form.collapseTitle + "</a>\n"; html += "<i class=\"icon-angle-down icon-white\"></i>" + this.form.collapseTitle + "</a>\n";
html += "</div>\n"; html += "</div>\n";
html += "<div id=\"collapse1\" class=\"accordion-body collapse\">\n"; html += "<div id=\"collapse0\" class=\"accordion-body collapse";
html += (this.form.collapseOpen) ? " in" : "";
html += "\">\n";
html += "<div class=\"accordion-inner\">\n"; html += "<div class=\"accordion-inner\">\n";
*/
html += "<div id=\"" + this.form.name + "-collapse-0\" ";
html += (this.form.collapseOpen) ? "data-open=\"true\" " : "";
html += "class=\"jqui-accordion\">\n";
html += "<h3>" + this.form.collapseTitle + "<h3>\n";
html += "<div>\n";
} }
// Start the well // Start the well
@ -654,8 +710,7 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
if ( this.form.collapse && this.form.collapseMode == options.mode ) { if ( this.form.collapse && this.form.collapseMode == options.mode ) {
html += "</div>\n"; html += "</div>\n";
html += "</div>\n"; html += "</div>\n";
html += "</div>\n";
} }
} }
@ -708,13 +763,17 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
var idx = 1; var idx = 1;
var form = this.form; var form = this.form;
var html = "<div class=\"accordion-group\">\n"; /* var html = "<div class=\"accordion-group\">\n";
html += "<div class=\"accordion-heading\">\n"; html += "<div class=\"accordion-heading\">\n";
html += "<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse2\">"; html += "<a id=\"" + form.name + "-collapse-2\" class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse2\">";
html += "<i class=\"icon-angle-up icon-white\"></i>Inventory Content</a>\n"; html += "<i class=\"icon-angle-up icon-white\"></i>Inventory Content</a>\n";
html += "</div>\n"; html += "</div>\n";
html += "<div id=\"collapse2\" class=\"accordion-body collapse in\">\n"; html += "<div id=\"collapse2\" class=\"accordion-body collapse in\">\n";
html += "<div class=\"accordion-inner\">\n"; html += "<div class=\"accordion-inner\">\n";
*/
html = "<div id=\"" + this.form.name + "-collapse-2\" data-open=\"true\" class=\"jqui-accordion\">\n";
html += "<h3>Inventory Content<h3>\n";
html += "<div>\n";
for (var itm in form.related) { for (var itm in form.related) {
if (form.related[itm].type == 'tree') { if (form.related[itm].type == 'tree') {
@ -834,7 +893,7 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
html += "</div>\n"; html += "</div>\n";
html += "</div>\n"; html += "</div>\n";
html += "</div>\n"; //html += "</div>\n";
return html; return html;
}, },
@ -846,13 +905,14 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
// //
var idx = 1; var idx = 1;
var form = this.form; var form = this.form;
var html = "<div class=\"accordion\" id=\"accordion\">\n"; html = "<div id=\"" + this.form.name + "-collapse-" + idx + "\" class=\"jqui-accordion\">\n";
for (var itm in form.related) { for (var itm in form.related) {
if (form.related[itm].type == 'collection' || form.related[itm].type == 'tree') { if (form.related[itm].type == 'collection') {
// Start the accordion group // Start the accordion group
html += "<div class=\"accordion-group\">\n"; /* html += "<div class=\"accordion-group\">\n";
html += "<div class=\"accordion-heading\">\n"; html += "<div class=\"accordion-heading\">\n";
html += "<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse" + idx + "\">"; html += "<a id=\"" + form.name + "-collapse-" + idx + "\" class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse" + idx + "\">";
html += "<i class=\"icon-angle-down icon-white\"></i>" + form.related[itm].title + "</a>\n"; html += "<i class=\"icon-angle-down icon-white\"></i>" + form.related[itm].title + "</a>\n";
html += "</div>\n"; html += "</div>\n";
html += "<div id=\"collapse" + idx + "\" class=\"accordion-body collapse"; html += "<div id=\"collapse" + idx + "\" class=\"accordion-body collapse";
@ -861,6 +921,11 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
} }
html += "\">\n"; html += "\">\n";
html += "<div class=\"accordion-inner\">\n"; html += "<div class=\"accordion-inner\">\n";
*/
html += "<h3>" + form.related[itm].title + "<h3>\n";
html += "<div>\n";
if (form.related[itm].instructions) { if (form.related[itm].instructions) {
html += "<div class=\"alert alert-info alert-block\">\n"; html += "<div class=\"alert alert-info alert-block\">\n";
@ -964,14 +1029,13 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
html += PaginateWidget({ set: itm, iterator: form.related[itm].iterator, mini: true }); html += PaginateWidget({ set: itm, iterator: form.related[itm].iterator, mini: true });
// End Accordion Group // End Accordion
html += "</div>\n"; // accordion inner html += "</div>\n"; // accordion inner
html += "</div>\n"; // accordion body
html += "</div>\n"; // accordion group
idx++; idx++;
} }
} }
html += "</div>\n"; // accordion body
html += "</div>\n"; html += "</div>\n";
return html; return html;

View File

@ -4,10 +4,10 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Ansible Commander</title> <title>Ansible Commander</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/custom-theme/jquery-ui-1.10.3.custom.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap.min.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap-responsive.min.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap-responsive.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/font-awesome.min.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/font-awesome.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/redmond/jquery-ui-1.10.3.custom.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/ansible-ui.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/ansible-ui.css" />
<link rel="shortcut icon" href="{{ STATIC_URL }}img/favicon.ico" /> <link rel="shortcut icon" href="{{ STATIC_URL }}img/favicon.ico" />
<script src="{{ STATIC_URL }}js/config.js"></script> <script src="{{ STATIC_URL }}js/config.js"></script>