comparison rhodecode/templates/admin/users/users.html @ 2658:80d837028c40 beta

implemented admin panel Users table with YUI datatable - much better handling of big amount of users - filtering by username - sorting by columns
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 25 Jul 2012 21:54:03 +0200
parents 44f328d6f209
children cc8d7d450d15
comparison
equal deleted inserted replaced
2657:001c7e2ae986 2658:80d837028c40
4 <%def name="title()"> 4 <%def name="title()">
5 ${_('Users administration')} - ${c.rhodecode_name} 5 ${_('Users administration')} - ${c.rhodecode_name}
6 </%def> 6 </%def>
7 7
8 <%def name="breadcrumbs_links()"> 8 <%def name="breadcrumbs_links()">
9 ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Users')} 9 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="user_count">0</span> ${_('users')}
10 </%def> 10 </%def>
11 11
12 <%def name="page_nav()"> 12 <%def name="page_nav()">
13 ${self.menu('admin')} 13 ${self.menu('admin')}
14 </%def> 14 </%def>
15 15
16 <%def name="main()"> 16 <%def name="main()">
17 <div class="box"> 17 <div class="box">
18 <!-- box / title --> 18 <!-- box / title -->
19 <div class="title"> 19 <div class="title">
20 ${self.breadcrumbs()} 20 ${self.breadcrumbs()}
21 <ul class="links"> 21 <ul class="links">
22 <li> 22 <li>
23 <span>${h.link_to(_(u'ADD NEW USER'),h.url('new_user'))}</span> 23 <span>${h.link_to(_(u'ADD NEW USER'),h.url('new_user'))}</span>
24 </li> 24 </li>
25
26 </ul> 25 </ul>
27 </div> 26 </div>
28 <!-- end box / title --> 27 <!-- end box / title -->
29 <div class="table"> 28 <div class="table yui-skin-sam" id="users_list_wrap"></div>
30 <table class="table_disp"> 29 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
31 <tr class="header">
32 <th></th>
33 <th class="left">${_('username')}</th>
34 <th class="left">${_('name')}</th>
35 <th class="left">${_('lastname')}</th>
36 <th class="left">${_('last login')}</th>
37 <th class="left">${_('active')}</th>
38 <th class="left">${_('admin')}</th>
39 <th class="left">${_('ldap')}</th>
40 <th class="left">${_('action')}</th>
41 </tr>
42 %for cnt,user in enumerate(c.users_list):
43 %if user.username !='default':
44 <tr class="parity${cnt%2}">
45 <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"/> </div></td>
46 <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
47 <td>${user.name}</td>
48 <td>${user.lastname}</td>
49 <td>${h.fmt_date(user.last_login)}</td>
50 <td>${h.bool2icon(user.active)}</td>
51 <td>${h.bool2icon(user.admin)}</td>
52 <td>${h.bool2icon(bool(user.ldap_dn))}</td>
53 <td>
54 ${h.form(url('delete_user', id=user.user_id),method='delete')}
55 ${h.submit('remove_',_('delete'),id="remove_user_%s" % user.user_id,
56 class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user: %s') % user.username+"');")}
57 ${h.end_form()}
58 </td>
59 </tr>
60 %endif
61 %endfor
62 </table>
63 </div>
64 </div> 30 </div>
31
32 <script>
33 var url = "${h.url('formatted_users', format='json')}";
34 var data = ${c.data|n};
35 var myDataSource = new YAHOO.util.DataSource(data);
36 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
37
38 myDataSource.responseSchema = {
39 resultsList: "records",
40 fields: [
41 {key: "gravatar"},
42 {key: "raw_username"},
43 {key: "username"},
44 {key: "firstname"},
45 {key: "lastname"},
46 {key: "last_login"},
47 {key: "active"},
48 {key: "admin"},
49 {key: "ldap"},
50 {key: "action"},
51 ]
52 };
53 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
54 // This is the filter function
55 var data = res.results || [],
56 filtered = [],
57 i,l;
58
59 if (req) {
60 req = req.toLowerCase();
61 for (i = 0; i<data.length; i++) {
62 var pos = data[i].raw_username.toLowerCase().indexOf(req)
63 if (pos != -1) {
64 filtered.push(data[i]);
65 }
66 }
67 res.results = filtered;
68 }
69 YUD.get('user_count').innerHTML = res.results.length;
70 return res;
71 }
72
73 // main table sorting
74 var myColumnDefs = [
75 {key:"gravatar",label:"",sortable:false,},
76 {key:"username",label:"${_('username')}",sortable:true,
77 sortOptions: { sortFunction: linkSort }
78 },
79 {key:"firstname",label:"${_('firstname')}",sortable:true,},
80 {key:"lastname",label:"${_('lastname')}",sortable:true,},
81 {key:"last_login",label:"${_('last login')}",sortable:true,},
82 {key:"active",label:"${_('active')}",sortable:true,},
83 {key:"admin",label:"${_('admin')}",sortable:true,},
84 {key:"ldap",label:"${_('ldap')}",sortable:true,},
85 {key:"action",label:"${_('action')}",sortable:false},
86 ];
87
88 var myDataTable = new YAHOO.widget.DataTable("users_list_wrap", myColumnDefs, myDataSource,{
89 sortedBy:{key:"username",dir:"asc"},
90 paginator: new YAHOO.widget.Paginator({
91 rowsPerPage: 15,
92 alwaysVisible: false,
93 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
94 pageLinks: 5,
95 containerClass: 'pagination-wh',
96 currentPageClass: 'pager_curpage',
97 pageLinkClass: 'pager_link',
98 nextPageLinkLabel: '&gt;',
99 previousPageLinkLabel: '&lt;',
100 firstPageLinkLabel: '&lt;&lt;',
101 lastPageLinkLabel: '&gt;&gt;',
102 containers:['user-paginator']
103 }),
104
105 MSG_SORTASC:"${_('Click to sort ascending')}",
106 MSG_SORTDESC:"${_('Click to sort descending')}",
107 MSG_EMPTY:"${_('No records found.')}",
108 MSG_ERROR:"${_('Data error.')}",
109 MSG_LOADING:"${_('Loading...')}",
110 }
111 );
112 myDataTable.subscribe('postRenderEvent',function(oArgs) {
113
114 });
115
116 var filterTimeout = null;
117
118 updateFilter = function () {
119 // Reset timeout
120 filterTimeout = null;
121
122 // Reset sort
123 var state = myDataTable.getState();
124 state.sortedBy = {key:'username', dir:YAHOO.widget.DataTable.CLASS_ASC};
125
126 // Get filtered data
127 myDataSource.sendRequest(YUD.get('q_filter').value,{
128 success : myDataTable.onDataReturnInitializeTable,
129 failure : myDataTable.onDataReturnInitializeTable,
130 scope : myDataTable,
131 argument: state
132 });
133
134 };
135 YUE.on('q_filter','click',function(){
136 YUD.get('q_filter').value = '';
137 });
138
139 YUE.on('q_filter','keyup',function (e) {
140 clearTimeout(filterTimeout);
141 filterTimeout = setTimeout(updateFilter,600);
142 });
143
144
145
146 </script>
147
65 </%def> 148 </%def>