Mercurial > public > src > rhodecode
changeset 2766:c525d7e641a6 beta
rewrote admin repos page.
- less info (no VCS data), but much faster.
- having 1000s of repos is not a problem now
- pagination/filtering using YUI datatable
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Thu, 26 Jul 2012 22:03:40 +0200 |
parents | cc8d7d450d15 |
children | 81a17ef4afc0 |
files | rhodecode/controllers/admin/repos.py rhodecode/templates/admin/repos/repos.html |
diffstat | 2 files changed, 131 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/controllers/admin/repos.py Thu Jul 26 22:01:41 2012 +0200 +++ b/rhodecode/controllers/admin/repos.py Thu Jul 26 22:03:40 2012 +0200 @@ -34,6 +34,7 @@ from pylons.i18n.translation import _ from sqlalchemy.exc import IntegrityError +import rhodecode from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ HasPermissionAnyDecorator, HasRepoPermissionAllDecorator @@ -45,6 +46,7 @@ from rhodecode.model.forms import RepoForm from rhodecode.model.scm import ScmModel from rhodecode.model.repo import RepoModel +from rhodecode.lib.compat import json log = logging.getLogger(__name__) @@ -131,9 +133,44 @@ """GET /repos: All items in the collection""" # url('repos') - c.repos_list = ScmModel().get_repos(Repository.query() - .order_by(Repository.repo_name) - .all(), sort_key='name_sort') + c.repos_list = Repository.query()\ + .order_by(Repository.repo_name)\ + .all() + + repos_data = [] + total_records = len(c.repos_list) + + _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup + template = _tmpl_lookup.get_template('data_table/_dt_elements.html') + + quick_menu = lambda repo_name: (template.get_def("quick_menu") + .render(repo_name, _=_, h=h)) + repo_lnk = lambda name, rtype, private, fork_of: ( + template.get_def("repo_name") + .render(name, rtype, private, fork_of, short_name=False, + admin=True, _=_, h=h)) + + repo_actions = lambda repo_name: (template.get_def("repo_actions") + .render(repo_name, _=_, h=h)) + + for repo in c.repos_list: + repos_data.append({ + "menu": quick_menu(repo.repo_name), + "raw_name": repo.repo_name, + "name": repo_lnk(repo.repo_name, repo.repo_type, repo.private, repo.fork), + "desc": repo.description, + "owner": repo.user.username, + "action": repo_actions(repo.repo_name), + }) + + c.data = json.dumps({ + "totalRecords": total_records, + "startIndex": 0, + "sort": "name", + "dir": "asc", + "records": repos_data + }) + return render('admin/repos/repos.html') @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
--- a/rhodecode/templates/admin/repos/repos.html Thu Jul 26 22:01:41 2012 +0200 +++ b/rhodecode/templates/admin/repos/repos.html Thu Jul 26 22:03:40 2012 +0200 @@ -5,9 +5,8 @@ ${_('Repositories administration')} - ${c.rhodecode_name} </%def> - <%def name="breadcrumbs_links()"> - ${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Repositories')} + <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'))} » <span id="repo_count">0</span> ${_('repositories')} </%def> <%def name="page_nav()"> ${self.menu('admin')} @@ -23,102 +22,114 @@ </li> </ul> </div> - - <div class="table"> - <div id='repos_list_wrap' class="yui-skin-sam"> - <%cnt=0%> - <%namespace name="dt" file="/data_table/_dt_elements.html"/> - - <table id="repos_list"> - <thead> - <tr> - <th class="left"></th> - <th class="left">${_('Name')}</th> - <th class="left">${_('Description')}</th> - <th class="left">${_('Last change')}</th> - <th class="left">${_('Tip')}</th> - <th class="left">${_('Contact')}</th> - <th class="left">${_('Action')}</th> - </tr> - </thead> + <div class="table yui-skin-sam" id="repos_list_wrap"></div> + <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div> + - %for cnt,repo in enumerate(c.repos_list): - <tr class="parity${(cnt+1)%2}"> - <td class="quick_repo_menu"> - ${dt.quick_menu(repo['name'])} - </td> - <td class="reponame"> - ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],repo['dbrepo_fork'].get('repo_name'), admin=True)} - </td> - ##DESCRIPTION - <td><span class="tooltip" title="${h.tooltip(repo['description'])}"> - ${h.truncate(repo['description'],60)}</span> - </td> - ##LAST CHANGE - <td> - <span class="tooltip" date="${repo['last_change']}" title="${h.tooltip(repo['last_change'])}">${h.age(repo['last_change'])}</span> - </td> - ##LAST REVISION - <td> - ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])} - </td> - <td title="${repo['contact']}">${h.person(repo['contact'])}</td> - <td> - ${h.form(url('repo', repo_name=repo['name']),method='delete')} - ${h.submit('remove_%s' % repo['name'],_('delete'),class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo['name']+"');")} - ${h.end_form()} - </td> - </tr> - %endfor - </table> - </div> - </div> </div> <script> + var url = "${h.url('formatted_users', format='json')}"; + var data = ${c.data|n}; + var myDataSource = new YAHOO.util.DataSource(data); + myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON; + + myDataSource.responseSchema = { + resultsList: "records", + fields: [ + {key:"menu"}, + {key:"raw_name"}, + {key:"name"}, + {key:"desc"}, + {key:"owner"}, + {key:"action"}, + ] + }; + myDataSource.doBeforeCallback = function(req,raw,res,cb) { + // This is the filter function + var data = res.results || [], + filtered = [], + i,l; + + if (req) { + req = req.toLowerCase(); + for (i = 0; i<data.length; i++) { + var pos = data[i].raw_name.toLowerCase().indexOf(req) + if (pos != -1) { + filtered.push(data[i]); + } + } + res.results = filtered; + } + YUD.get('repo_count').innerHTML = res.results.length; + return res; + } // main table sorting var myColumnDefs = [ {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"}, {key:"name",label:"${_('Name')}",sortable:true, - sortOptions: { sortFunction: nameSort }}, + sortOptions: { sortFunction: nameSort }}, {key:"desc",label:"${_('Description')}",sortable:true}, - {key:"last_change",label:"${_('Last Change')}",sortable:true, - sortOptions: { sortFunction: ageSort }}, - {key:"tip",label:"${_('Tip')}",sortable:true, - sortOptions: { sortFunction: revisionSort }}, {key:"owner",label:"${_('Owner')}",sortable:true}, {key:"action",label:"${_('Action')}",sortable:false}, ]; - var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list")); - - myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE; + var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{ + sortedBy:{key:"name",dir:"asc"}, + paginator: new YAHOO.widget.Paginator({ + rowsPerPage: 15, + alwaysVisible: false, + template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}", + pageLinks: 5, + containerClass: 'pagination-wh', + currentPageClass: 'pager_curpage', + pageLinkClass: 'pager_link', + nextPageLinkLabel: '>', + previousPageLinkLabel: '<', + firstPageLinkLabel: '<<', + lastPageLinkLabel: '>>', + containers:['user-paginator'] + }), - myDataSource.responseSchema = { - fields: [ - {key:"menu"}, - {key:"name"}, - {key:"desc"}, - {key:"last_change"}, - {key:"tip"}, - {key:"owner"}, - {key:"action"}, - ] - }; - - var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource, - { - sortedBy:{key:"name",dir:"asc"}, - MSG_SORTASC:"${_('Click to sort ascending')}", - MSG_SORTDESC:"${_('Click to sort descending')}", - MSG_EMPTY:"${_('No records found.')}", - MSG_ERROR:"${_('Data error.')}", - MSG_LOADING:"${_('Loading...')}", - } + MSG_SORTASC:"${_('Click to sort ascending')}", + MSG_SORTDESC:"${_('Click to sort descending')}", + MSG_EMPTY:"${_('No records found.')}", + MSG_ERROR:"${_('Data error.')}", + MSG_LOADING:"${_('Loading...')}", + } ); myDataTable.subscribe('postRenderEvent',function(oArgs) { tooltip_activate(); quick_repo_menu(); }); + + var filterTimeout = null; + + updateFilter = function () { + // Reset timeout + filterTimeout = null; + + // Reset sort + var state = myDataTable.getState(); + state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC}; + + // Get filtered data + myDataSource.sendRequest(YUD.get('q_filter').value,{ + success : myDataTable.onDataReturnInitializeTable, + failure : myDataTable.onDataReturnInitializeTable, + scope : myDataTable, + argument: state + }); + + }; + YUE.on('q_filter','click',function(){ + YUD.get('q_filter').value = ''; + }); + + YUE.on('q_filter','keyup',function (e) { + clearTimeout(filterTimeout); + filterTimeout = setTimeout(updateFilter,600); + }); </script> + </%def>