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',
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',
controller: UsersList }).

View File

@ -317,13 +317,23 @@ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
// Related set: Add button
scope.add = function(set) {
$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
scope.edit = function(set, id, name) {
$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
@ -331,25 +341,41 @@ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
$rootScope.flashMessage = null;
var action = function() {
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 });
});
var url;
if (set == 'permissions') {
url = GetBasePath('base') + 'permissions/' + itm_id + '/';
Rest.setUrl(url);
Rest.destroy()
.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. 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',
body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?',
action: action
});
Prompt({ hdr: 'Delete',
body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?',
action: action
});
}
}

View File

@ -11,9 +11,13 @@ angular.module('TeamFormDefinition', [])
'TeamForm', {
addTitle: 'Create Team', //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode
editTitle: '{{ name }}', //Legend in edit mode
name: 'team',
well: true,
collapse: true,
collapseTitle: 'Team Settings',
collapseMode: 'edit',
collapseOpen: true,
fields: {
name: {
@ -58,52 +62,6 @@ angular.module('TeamFormDefinition', [])
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: {
type: 'collection',
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: {
type: 'collection',
title: 'Projects',
@ -187,6 +200,52 @@ angular.module('TeamFormDefinition', [])
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
editTitle: '{{ username }}', //Legend in edit mode
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: {
username: {

View File

@ -8,9 +8,9 @@
*
*/
angular.module('FormGenerator', ['GeneratorHelpers'])
.factory('GenerateForm', [ '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column',
function($compile, SearchWidget, PaginateWidget, Attr, Icon, Column) {
angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
.factory('GenerateForm', [ '$location', '$cookieStore', '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column',
function($location, $cookieStore, $compile, SearchWidget, PaginateWidget, Attr, Icon, Column) {
return {
setForm: function(form) {
@ -106,18 +106,66 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
},
addListeners: function() {
// Listen for accordion collapse events and toggle the header icon
$('.collapse')
.on('show', function() {
var element = $(this).parent().find('.accordion-heading i');
element.removeClass('icon-angle-down');
element.addClass('icon-angle-up');
})
.on('hide', function() {
var element = $(this).parent().find('.accordion-heading i');
element.removeClass('icon-angle-up');
element.addClass('icon-angle-down');
});
$('.jqui-accordion').each( function(index) {
var active = false;
var list = $cookieStore.get('accordions');
var found = false;
if (list) {
var id = $(this).attr('id');
var base = ($location.path().replace(/^\//,'').split('/')[0]);
for (var i=0; i < list.length && found == false; i++) {
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) {
@ -556,13 +604,21 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
else {
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 += "<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 += "</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 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
@ -654,8 +710,7 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
if ( this.form.collapse && this.form.collapseMode == options.mode ) {
html += "</div>\n";
html += "</div>\n";
html += "</div>\n";
html += "</div>\n";
}
}
@ -708,13 +763,17 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
var idx = 1;
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 += "<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 += "</div>\n";
html += "<div id=\"collapse2\" class=\"accordion-body collapse in\">\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) {
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";
return html;
},
@ -846,13 +905,14 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
//
var idx = 1;
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) {
if (form.related[itm].type == 'collection' || form.related[itm].type == 'tree') {
if (form.related[itm].type == 'collection') {
// Start the accordion group
html += "<div class=\"accordion-group\">\n";
/* html += "<div class=\"accordion-group\">\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 += "</div>\n";
html += "<div id=\"collapse" + idx + "\" class=\"accordion-body collapse";
@ -861,6 +921,11 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
}
html += "\">\n";
html += "<div class=\"accordion-inner\">\n";
*/
html += "<h3>" + form.related[itm].title + "<h3>\n";
html += "<div>\n";
if (form.related[itm].instructions) {
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 });
// End Accordion Group
// End Accordion
html += "</div>\n"; // accordion inner
html += "</div>\n"; // accordion body
html += "</div>\n"; // accordion group
idx++;
}
}
html += "</div>\n"; // accordion body
html += "</div>\n";
return html;

View File

@ -4,10 +4,10 @@
<meta charset="utf-8">
<title>Ansible Commander</title>
<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-responsive.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="shortcut icon" href="{{ STATIC_URL }}img/favicon.ico" />
<script src="{{ STATIC_URL }}js/config.js"></script>