Mercurial > kallithea
changeset 2936:62e493c7f436 beta
Added lightweight dashboard option. ref #500
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Thu, 18 Oct 2012 20:16:00 +0200 |
parents | 20c0af65ac52 |
children | d439d408b415 |
files | rhodecode/controllers/admin/settings.py rhodecode/controllers/home.py rhodecode/lib/base.py rhodecode/lib/helpers.py rhodecode/model/db.py rhodecode/model/forms.py rhodecode/model/scm.py rhodecode/templates/admin/settings/settings.html rhodecode/templates/data_table/_dt_elements.html rhodecode/templates/index_base.html |
diffstat | 10 files changed, 246 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/controllers/admin/settings.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/controllers/admin/settings.py Thu Oct 18 20:16:00 2012 +0200 @@ -185,18 +185,23 @@ sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon') sett1.app_settings_value = \ form_result['rhodecode_show_public_icon'] + Session().add(sett1) sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon') sett2.app_settings_value = \ form_result['rhodecode_show_private_icon'] + Session().add(sett2) sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags') sett3.app_settings_value = \ form_result['rhodecode_stylify_metatags'] + Session().add(sett3) - Session().add(sett1) - Session().add(sett2) - Session().add(sett3) + sett4 = RhodeCodeSetting.get_by_name_or_create('lightweight_dashboard') + sett4.app_settings_value = \ + form_result['rhodecode_lightweight_dashboard'] + Session().add(sett4) + Session().commit() set_rhodecode_config(config) h.flash(_('Updated visualisation settings'),
--- a/rhodecode/controllers/home.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/controllers/home.py Thu Oct 18 20:16:00 2012 +0200 @@ -26,11 +26,16 @@ import logging from pylons import tmpl_context as c, request +from pylons.i18n.translation import _ from webob.exc import HTTPBadRequest +import rhodecode +from rhodecode.lib import helpers as h +from rhodecode.lib.ext_json import json from rhodecode.lib.auth import LoginRequired from rhodecode.lib.base import BaseController, render from rhodecode.model.db import Repository +from sqlalchemy.sql.expression import func log = logging.getLogger(__name__) @@ -42,9 +47,55 @@ super(HomeController, self).__before__() def index(self): - c.repos_list = self.scm_model.get_repos() c.groups = self.scm_model.get_repos_groups() c.group = None + + if c.visual.lightweight_dashboard is False: + c.repos_list = self.scm_model.get_repos() + ## lightweight version of dashboard + else: + c.repos_list = Repository.query()\ + .filter(Repository.group_id == None)\ + .order_by(func.lower(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, c=c)) + repo_lnk = lambda name, rtype, private, fork_of: ( + template.get_def("repo_name") + .render(name, rtype, private, fork_of, short_name=False, + admin=False, _=_, h=h, c=c)) + rss_lnk = lambda repo_name: (template.get_def("rss") + .render(repo_name, _=_, h=h, c=c)) + atom_lnk = lambda repo_name: (template.get_def("atom") + .render(repo_name, _=_, h=h, c=c)) + + for repo in c.repos_list: + repos_data.append({ + "menu": quick_menu(repo.repo_name), + "raw_name": repo.repo_name.lower(), + "name": repo_lnk(repo.repo_name, repo.repo_type, + repo.private, repo.fork), + "last_change": h.age(repo.last_db_change), + "desc": repo.description, + "owner": h.person(repo.user.username), + "rss": rss_lnk(repo.repo_name), + "atom": atom_lnk(repo.repo_name), + }) + + c.data = json.dumps({ + "totalRecords": total_records, + "startIndex": 0, + "sort": "name", + "dir": "asc", + "records": repos_data + }) + return render('/index.html') def repo_switcher(self):
--- a/rhodecode/lib/base.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/lib/base.py Thu Oct 18 20:16:00 2012 +0200 @@ -245,6 +245,7 @@ c.visual.show_public_icon = str2bool(config.get('rhodecode_show_public_icon')) c.visual.show_private_icon = str2bool(config.get('rhodecode_show_private_icon')) c.visual.stylify_metatags = str2bool(config.get('rhodecode_stylify_metatags')) + c.visual.lightweight_dashboard = str2bool(config.get('rhodecode_lightweight_dashboard')) c.repo_name = get_repo_slug(request) c.backends = BACKENDS.keys()
--- a/rhodecode/lib/helpers.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/lib/helpers.py Thu Oct 18 20:16:00 2012 +0200 @@ -42,7 +42,7 @@ from rhodecode.lib.annotate import annotate_highlight from rhodecode.lib.utils import repo_name_slug from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \ - get_changeset_safe, datetime_to_time, time_to_datetime + get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict from rhodecode.lib.markup_renderer import MarkupRenderer from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError from rhodecode.lib.vcs.backends.base import BaseChangeset
--- a/rhodecode/model/db.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/model/db.py Thu Oct 18 20:16:00 2012 +0200 @@ -856,6 +856,10 @@ Session().add(repo) Session().commit() + @property + def last_db_change(self): + return self.updated_on + #========================================================================== # SCM PROPERTIES #==========================================================================
--- a/rhodecode/model/forms.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/model/forms.py Thu Oct 18 20:16:00 2012 +0200 @@ -254,6 +254,8 @@ rhodecode_show_private_icon = v.StringBoolean(if_missing=False) rhodecode_stylify_metatags = v.StringBoolean(if_missing=False) + rhodecode_lightweight_dashboard = v.StringBoolean(if_missing=False) + return _ApplicationVisualisationForm
--- a/rhodecode/model/scm.py Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/model/scm.py Thu Oct 18 20:16:00 2012 +0200 @@ -115,6 +115,7 @@ tmp_d = {} tmp_d['name'] = dbr.repo_name tmp_d['name_sort'] = tmp_d['name'].lower() + tmp_d['raw_name'] = tmp_d['name'].lower() tmp_d['description'] = dbr.description tmp_d['description_sort'] = tmp_d['description'].lower() tmp_d['last_change'] = last_change @@ -149,6 +150,7 @@ tmp_d = {} tmp_d['name'] = dbr.repo_name tmp_d['name_sort'] = tmp_d['name'].lower() + tmp_d['raw_name'] = tmp_d['name'].lower() tmp_d['description'] = dbr.description tmp_d['description_sort'] = tmp_d['description'].lower() tmp_d['dbrepo'] = dbr.get_dict()
--- a/rhodecode/templates/admin/settings/settings.html Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/templates/admin/settings/settings.html Thu Oct 18 20:16:00 2012 +0200 @@ -122,6 +122,17 @@ <!-- fields --> <div class="fields"> + <div class="field"> + <div class="label label-checkbox"> + <label>${_('General')}:</label> + </div> + <div class="checkboxes"> + <div class="checkbox"> + ${h.checkbox('rhodecode_lightweight_dashboard','True')} + <label for="rhodecode_lightweight_dashboard">${_('Use lightweight dashboard')}</label> + </div> + </div> + </div> <div class="field"> <div class="label label-checkbox">
--- a/rhodecode/templates/data_table/_dt_elements.html Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/templates/data_table/_dt_elements.html Thu Oct 18 20:16:00 2012 +0200 @@ -76,8 +76,8 @@ ${h.link_to(get_name(name),h.url('summary_home',repo_name=name),class_="repo_name")} %endif %if fork_of: - <a href="${h.url('summary_home',repo_name=fork_of)}"> - <img class="icon" alt="${_('fork')}" title="${_('Fork of')} ${fork_of}" src="${h.url('/images/icons/arrow_divide.png')}"/></a> + <a href="${h.url('summary_home',repo_name=fork_of.repo_name)}"> + <img class="icon" alt="${_('fork')}" title="${_('Fork of')} ${fork_of.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/></a> %endif </div> </%def> @@ -94,6 +94,22 @@ </div> </%def> +<%def name="rss(name)"> + %if c.rhodecode_user.username != 'default': + <a title="${_('Subscribe to %s rss feed')% name}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=name,api_key=c.rhodecode_user.api_key)}"></a> + %else: + <a title="${_('Subscribe to %s rss feed')% name}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=name)}"></a> + %endif +</%def> + +<%def name="atom(name)"> + %if c.rhodecode_user.username != 'default': + <a title="${_('Subscribe to %s atom feed')% name}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=name,api_key=c.rhodecode_user.api_key)}"></a> + %else: + <a title="${_('Subscribe to %s atom feed')% name}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=name)}"></a> + %endif +</%def> + <%def name="user_gravatar(email, size=24)"> <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(email, size)}"/> </div> </%def>
--- a/rhodecode/templates/index_base.html Thu Oct 18 02:14:30 2012 +0200 +++ b/rhodecode/templates/index_base.html Thu Oct 18 20:16:00 2012 +0200 @@ -59,10 +59,11 @@ <div id="welcome" style="display:none;text-align:center"> <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1> </div> + <%cnt=0%> + <%namespace name="dt" file="/data_table/_dt_elements.html"/> + % if c.visual.lightweight_dashboard is False: + ## old full detailed version <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> @@ -85,7 +86,7 @@ </td> ##REPO NAME AND ICONS <td class="reponame"> - ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],repo['dbrepo_fork'].get('repo_name'),pageargs.get('short_repo_names'))} + ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']),pageargs.get('short_repo_names'))} </td> ##DESCRIPTION <td><span class="tooltip" title="${h.tooltip(repo['description'])}"> @@ -106,38 +107,33 @@ ## <td title="${repo['contact']}">${h.person(repo['contact'])}</td> <td> - %if c.rhodecode_user.username != 'default': - <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=repo['name'],api_key=c.rhodecode_user.api_key)}"></a> - %else: - <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a> - %endif: + ${dt.rss(repo['name'])} </td> <td> - %if c.rhodecode_user.username != 'default': - <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'],api_key=c.rhodecode_user.api_key)}"></a> - %else: - <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a> - %endif: + ${dt.atom(repo['name'])} </td> </tr> %endfor </tbody> </table> </div> + % else: + ## lightweight version + <div class="yui-skin-sam" id="repos_list_wrap"></div> + <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div> + % endif </div> </div> + % if c.visual.lightweight_dashboard is False: <script> YUD.get('repo_count').innerHTML = ${cnt+1 if cnt else 0}; var func = function(node){ return node.parentNode.parentNode.parentNode.parentNode; } - var sort_by = "name"; - var sort_dir = "asc"; - // groups table sorting var myColumnDefs = [ - {key:"name",label:"${_('Group Name')}",sortable:true, + {key:"name",label:"${_('Group name')}",sortable:true, sortOptions: { sortFunction: groupNameSort }}, {key:"desc",label:"${_('Description')}",sortable:true}, ]; @@ -152,13 +148,25 @@ ] }; - var myDataTable = new YAHOO.widget.DataTable("groups_list_wrap", myColumnDefs, myDataSource, - { - sortedBy:{key:"name",dir:"asc"}, - MSG_SORTASC:"${_('Click to sort ascending')}", - MSG_SORTDESC:"${_('Click to sort descending')}" - } - ); + var myDataTable = new YAHOO.widget.DataTable("groups_list_wrap", myColumnDefs, myDataSource,{ + sortedBy:{key:"name",dir:"asc"}, + paginator: new YAHOO.widget.Paginator({ + rowsPerPage: 5, + 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'] + }), + MSG_SORTASC:"${_('Click to sort ascending')}", + MSG_SORTDESC:"${_('Click to sort descending')}" + }); // main table sorting var myColumnDefs = [ @@ -182,6 +190,7 @@ myDataSource.responseSchema = { fields: [ {key:"menu"}, + //{key:"raw_name"}, {key:"name"}, {key:"desc"}, {key:"last_change"}, @@ -194,7 +203,7 @@ var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource, { - sortedBy:{key:sort_by,dir:sort_dir}, + sortedBy:{key:"name",dir:"asc"}, MSG_SORTASC:"${_('Click to sort ascending')}", MSG_SORTDESC:"${_('Click to sort descending')}", MSG_EMPTY:"${_('No records found.')}", @@ -209,3 +218,115 @@ }); </script> + % else: + <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:"last_change"}, + {key:"owner"}, + {key:"rss"}, + {key:"atom"}, + ] + }; + 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 }}, + {key:"desc",label:"${_('Description')}",sortable:true}, + //{key:"last_change",label:"${_('Last Change')}",sortable:true, + // sortOptions: { sortFunction: ageSort }}, + {key:"owner",label:"${_('Owner')}",sortable:true}, + {key:"rss",label:"",sortable:false}, + {key:"atom",label:"",sortable:false}, + ]; + + 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'] + }), + + 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> + % endif + \ No newline at end of file