Changeset - 0226b6d6b2b5
[Not reviewed]
beta
1 14 0
Marcin Kuzminski - 13 years ago 2013-01-09 01:59:43
marcin@python-works.com
Use common function for generation of grid data
- admin grid now has dedicated edit button, and uses changeset_cache
- some small improvements to grid
- all other datatables use this
15 files changed with 611 insertions and 483 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/routing.py
Show inline comments
 
@@ -350,26 +350,24 @@ def make_map(config):
 
        m.connect('admin_home', '', action='index')
 
        m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
 
                  action='add_repo')
 

	
 
    #==========================================================================
 
    # API V2
 
    #==========================================================================
 
    with rmap.submapper(path_prefix=ADMIN_PREFIX,
 
                        controller='api/api') as m:
 
        m.connect('api', '/api')
 

	
 
    #USER JOURNAL
 
    rmap.connect('journal_my_repos', '%s/journal_my_repos' % ADMIN_PREFIX,
 
                 controller='journal', action='index_my_repos')
 
    rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
 
                 controller='journal', action='index')
 
    rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
 
                 controller='journal', action='journal_rss')
 
    rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
 
                 controller='journal', action='journal_atom')
 

	
 
    rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
 
                 controller='journal', action="public_journal")
 

	
 
    rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
 
                 controller='journal', action="public_journal_rss")
rhodecode/controllers/admin/repos.py
Show inline comments
 
@@ -126,58 +126,28 @@ class ReposController(BaseController):
 
        defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
 
        return defaults
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def index(self, format='html'):
 
        """GET /repos: All items in the collection"""
 
        # url('repos')
 

	
 
        c.repos_list = Repository.query()\
 
                        .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=True, _=_, h=h, c=c))
 

	
 
        repo_actions = lambda repo_name: (template.get_def("repo_actions")
 
                                       .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),
 
                "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
 
        })
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
 
                                                   admin=True)
 
        #json used to render the grid
 
        c.data = json.dumps(repos_data)
 

	
 
        return render('admin/repos/repos.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def create(self):
 
        """
 
        POST /repos: Create a new item"""
 
        # url('repos')
 

	
 
        self.__load_defaults()
 
        form_result = {}
 
        try:
rhodecode/controllers/admin/repos_groups.py
Show inline comments
 
@@ -286,72 +286,36 @@ class ReposGroupsController(BaseControll
 
        c.group = RepoGroup.get_or_404(id)
 
        c.group_repos = c.group.repositories.all()
 

	
 
        #overwrite our cached list with current filter
 
        gr_filter = c.group_repos
 
        c.repo_cnt = 0
 

	
 
        groups = RepoGroup.query().order_by(RepoGroup.group_name)\
 
            .filter(RepoGroup.group_parent_id == id).all()
 
        c.groups = self.scm_model.get_repos_groups(groups)
 

	
 
        if c.visual.lightweight_dashboard is False:
 
            c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter)
 

	
 
            c.repos_list = c.cached_repo_list
 
            c.repo_list = self.scm_model.get_repos(all_repos=gr_filter)
 
        ## lightweight version of dashboard
 
        else:
 
            c.repos_list = Repository.query()\
 
                            .filter(Repository.group_id == id)\
 
                            .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))
 
            last_change = lambda last_change:  (template.get_def("last_change")
 
                                           .render(last_change, _=_, 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": last_change(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
 
            })
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
 
                                                   admin=False)
 
        #json used to render the grid
 
        c.data = json.dumps(repos_data)
 

	
 
        return render('admin/repos_groups/repos_groups.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def edit(self, id, format='html'):
 
        """GET /repos_groups/id/edit: Form to edit an existing item"""
 
        # url('edit_repos_group', id=ID)
 

	
 
        c.repos_group = ReposGroupModel()._get_repos_group(id)
 
        defaults = self.__load_data(c.repos_group.group_id)
 

	
 
        # we need to exclude this group from the group list for editing
rhodecode/controllers/admin/settings.py
Show inline comments
 
@@ -39,29 +39,30 @@ from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    HasPermissionAnyDecorator, NotAnonymous
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.celerylib import tasks, run_task
 
from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
 
    set_rhodecode_config, repo_name_slug, check_git_version
 
from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
 
    RhodeCodeSetting, PullRequest, PullRequestReviewers
 
from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
 
    ApplicationUiSettingsForm, ApplicationVisualisationForm
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.db import User
 
from rhodecode.model.notification import EmailNotificationModel
 
from rhodecode.model.meta import Session
 
from rhodecode.lib.utils2 import str2bool, safe_unicode
 

	
 
from rhodecode.lib.compat import json
 
log = logging.getLogger(__name__)
 

	
 

	
 
class SettingsController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 
    # To properly map this controller, ensure your config/routing.py
 
    # file has a resource setup:
 
    #     map.resource('setting', 'settings', controller='admin/settings',
 
    #         path_prefix='/admin', name_prefix='admin_')
 

	
 
    @LoginRequired()
 
    def __before__(self):
 
@@ -381,35 +382,40 @@ class SettingsController(BaseController)
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 

	
 
    @NotAnonymous()
 
    def my_account(self):
 
        """
 
        GET /_admin/my_account Displays info about my account
 
        """
 
        # url('admin_settings_my_account')
 

	
 
        c.user = User.get(self.rhodecode_user.user_id)
 
        all_repos = Session().query(Repository)\
 
                     .filter(Repository.user_id == c.user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        c.user_repos = ScmModel().get_repos(all_repos)
 

	
 
        if c.user.username == 'default':
 
            h.flash(_("You can't edit this user since it's"
 
              " crucial for entire application"), category='warning')
 
            return redirect(url('users'))
 

	
 
        repos_list = Session().query(Repository)\
 
                     .filter(Repository.user_id ==
 
                             self.rhodecode_user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
 
                                                   admin=True)
 
        #json used to render the grid
 
        c.data = json.dumps(repos_data)
 

	
 
        defaults = c.user.get_dict()
 

	
 
        c.form = htmlfill.render(
 
            render('admin/users/user_edit_my_account_form.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 
        return render('admin/users/user_edit_my_account.html')
 

	
 
    @NotAnonymous()
 
    def my_account_update(self):
 
@@ -440,41 +446,32 @@ class SettingsController(BaseController)
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
            return render('admin/users/user_edit_my_account.html')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('error occurred during update of user %s') \
 
                    % form_result.get('username'), category='error')
 

	
 
        return redirect(url('my_account'))
 

	
 
    @NotAnonymous()
 
    def my_account_my_repos(self):
 
        all_repos = Session().query(Repository)\
 
            .filter(Repository.user_id == self.rhodecode_user.user_id)\
 
            .order_by(func.lower(Repository.repo_name))\
 
            .all()
 
        c.user_repos = ScmModel().get_repos(all_repos)
 
        return render('admin/users/user_edit_my_account_repos.html')
 

	
 
    @NotAnonymous()
 
    def my_account_my_pullrequests(self):
 
        c.my_pull_requests = PullRequest.query()\
 
                                .filter(PullRequest.user_id==
 
                                .filter(PullRequest.user_id ==
 
                                        self.rhodecode_user.user_id)\
 
                                .all()
 
        c.participate_in_pull_requests = \
 
            [x.pull_request for x in PullRequestReviewers.query()\
 
                                    .filter(PullRequestReviewers.user_id==
 
                                    .filter(PullRequestReviewers.user_id ==
 
                                            self.rhodecode_user.user_id)\
 
                                    .all()]
 
        return render('admin/users/user_edit_my_account_pullrequests.html')
 

	
 
    @NotAnonymous()
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def create_repository(self):
 
        """GET /_admin/create_repository: Form to create a new item"""
 

	
 
        c.repo_groups = RepoGroup.groups_choices(check_perms=True)
 
        c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
 
        choices, c.landing_revs = ScmModel().get_repo_landing_revs()
rhodecode/controllers/home.py
Show inline comments
 
@@ -19,107 +19,61 @@
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 

	
 
from pylons import tmpl_context as c, request
 
from pylons.i18n.translation import _
 
from webob.exc import HTTPBadRequest
 
from sqlalchemy.sql.expression import func
 

	
 
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
 
from rhodecode.model.repo import RepoModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class HomeController(BaseController):
 

	
 
    @LoginRequired()
 
    def __before__(self):
 
        super(HomeController, self).__before__()
 

	
 
    def index(self):
 
        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))
 
            last_change = lambda last_change:  (template.get_def("last_change")
 
                                           .render(last_change, _=_, 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))
 
            tip = lambda repo_name, cs_cache: (template.get_def("revision")
 
                                    .render(repo_name,
 
                                            cs_cache.get('revision'),
 
                                            cs_cache.get('raw_id'),
 
                                            cs_cache.get('author'),
 
                                            cs_cache.get('message'), _=_, h=h,
 
                                            c=c))
 

	
 
            def desc(desc):
 
                if c.visual.stylify_metatags:
 
                    return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
 
                else:
 
                    return h.urlify_text(h.truncate(desc, 60))
 

	
 
            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": last_change(repo.last_db_change),
 
                    "tip": tip(repo.repo_name, repo.changeset_cache),
 
                    "desc": 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
 
            })
 
            repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
 
                                                       admin=False)
 
            #json used to render the grid
 
            c.data = json.dumps(repos_data)
 

	
 
        return render('/index.html')
 

	
 
    def repo_switcher(self):
 
        if request.is_xhr:
 
            all_repos = Repository.query().order_by(Repository.repo_name).all()
 
            c.repos_list = self.scm_model.get_repos(all_repos,
 
                                                    sort_key='name_sort',
 
                                                    simple=True)
 
            return render('/repo_switcher_list.html')
 
        else:
 
            raise HTTPBadRequest()
rhodecode/controllers/journal.py
Show inline comments
 
@@ -18,40 +18,42 @@
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import logging
 
from itertools import groupby
 

	
 
from sqlalchemy import or_
 
from sqlalchemy.orm import joinedload
 
from sqlalchemy.sql.expression import func
 

	
 
from webhelpers.paginate import Page
 
from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
 

	
 
from webob.exc import HTTPBadRequest
 
from pylons import request, tmpl_context as c, response, url
 
from pylons.i18n.translation import _
 

	
 
import rhodecode.lib.helpers as h
 
from rhodecode.lib.auth import LoginRequired, NotAnonymous
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.model.db import UserLog, UserFollowing, Repository, User
 
from rhodecode.model.meta import Session
 
from sqlalchemy.sql.expression import func
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.lib.utils2 import safe_int, AttributeDict
 
from rhodecode.controllers.admin.admin import _journal_filter
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.lib.compat import json
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class JournalController(BaseController):
 

	
 
    def __before__(self):
 
        super(JournalController, self).__before__()
 
        self.language = 'en-us'
 
        self.ttl = "5"
 
        self.feed_nr = 20
 
        c.search_term = request.GET.get('filter')
 
@@ -69,36 +71,91 @@ class JournalController(BaseController):
 

	
 
        journal = self._get_journal_data(c.following)
 

	
 
        def url_generator(**kw):
 
            return url.current(filter=c.search_term, **kw)
 

	
 
        c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
 
        c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
 

	
 
        c.journal_data = render('journal/journal_data.html')
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            return c.journal_data
 
        return render('journal/journal.html')
 

	
 
        repos_list = Session().query(Repository)\
 
                     .filter(Repository.user_id ==
 
                             self.rhodecode_user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
 
                                                   admin=True)
 
        #json used to render the grid
 
        c.data = json.dumps(repos_data)
 

	
 
        watched_repos_data = []
 

	
 
        ## watched repos
 
        _render = RepoModel._render_datatable
 

	
 
        def quick_menu(repo_name):
 
            return _render('quick_menu', repo_name)
 

	
 
        def repo_lnk(name, rtype, private, fork_of):
 
            return _render('repo_name', name, rtype, private, fork_of,
 
                           short_name=False, admin=False)
 

	
 
        def last_rev(repo_name, cs_cache):
 
            return _render('revision', repo_name, cs_cache.get('revision'),
 
                           cs_cache.get('raw_id'), cs_cache.get('author'),
 
                           cs_cache.get('message'))
 

	
 
    @LoginRequired()
 
    @NotAnonymous()
 
    def index_my_repos(self):
 
        c.user = User.get(self.rhodecode_user.user_id)
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            all_repos = self.sa.query(Repository)\
 
                     .filter(Repository.user_id == c.user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 
            c.user_repos = ScmModel().get_repos(all_repos)
 
            return render('journal/journal_page_repos.html')
 
        def desc(desc):
 
            from pylons import tmpl_context as c
 
            if c.visual.stylify_metatags:
 
                return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
 
            else:
 
                return h.urlify_text(h.truncate(desc, 60))
 

	
 
        def repo_actions(repo_name):
 
            return _render('repo_actions', repo_name)
 

	
 
        def owner_actions(user_id, username):
 
            return _render('user_name', user_id, username)
 

	
 
        def toogle_follow(repo_id):
 
            return  _render('toggle_follow', repo_id)
 

	
 
        for entry in c.following:
 
            repo = entry.follows_repository
 
            cs_cache = repo.changeset_cache
 
            row = {
 
                "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_changeset": last_rev(repo.repo_name, cs_cache),
 
                "raw_tip": cs_cache.get('revision'),
 
                "action": toogle_follow(repo.repo_id)
 
            }
 

	
 
            watched_repos_data.append(row)
 

	
 
        c.watched_data = json.dumps({
 
            "totalRecords": len(c.following),
 
            "startIndex": 0,
 
            "sort": "name",
 
            "dir": "asc",
 
            "records": watched_repos_data
 
        })
 
        return render('journal/journal.html')
 

	
 
    @LoginRequired(api_access=True)
 
    @NotAnonymous()
 
    def journal_atom(self):
 
        """
 
        Produce an atom-1.0 feed via feedgenerator module
 
        """
 
        following = self.sa.query(UserFollowing)\
 
            .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
 
            .options(joinedload(UserFollowing.follows_repository))\
 
            .all()
 
        return self._atom_feed(following, public=False)
rhodecode/model/repo.py
Show inline comments
 
@@ -32,24 +32,25 @@ from datetime import datetime
 
from rhodecode.lib.vcs.backends import get_backend
 
from rhodecode.lib.compat import json
 
from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\
 
    remove_prefix
 
from rhodecode.lib.caching_query import FromCache
 
from rhodecode.lib.hooks import log_create_repository, log_delete_repository
 

	
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
 
    Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup,\
 
    RhodeCodeSetting
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import HasRepoPermissionAny
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class RepoModel(BaseModel):
 

	
 
    cls = Repository
 
    URL_SEPARATOR = Repository.url_sep()
 

	
 
    def __get_users_group(self, users_group):
 
        return self._get_instance(UsersGroup, users_group,
 
@@ -104,24 +105,113 @@ class RepoModel(BaseModel):
 
    def get_users_groups_js(self):
 
        users_groups = self.sa.query(UsersGroup)\
 
            .filter(UsersGroup.users_group_active == True).all()
 

	
 
        return json.dumps([
 
            {
 
             'id': gr.users_group_id,
 
             'grname': gr.users_group_name,
 
             'grmembers': len(gr.members),
 
            } for gr in users_groups]
 
        )
 

	
 
    @classmethod
 
    def _render_datatable(cls, tmpl, *args, **kwargs):
 
        import rhodecode
 
        from pylons import tmpl_context as c
 
        from pylons.i18n.translation import _
 

	
 
        _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
 
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
        tmpl = template.get_def(tmpl)
 
        kwargs.update(dict(_=_, h=h, c=c))
 
        return tmpl.render(*args, **kwargs)
 

	
 
    def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True):
 
        _render = self._render_datatable
 

	
 
        def quick_menu(repo_name):
 
            return _render('quick_menu', repo_name)
 

	
 
        def repo_lnk(name, rtype, private, fork_of):
 
            return _render('repo_name', name, rtype, private, fork_of,
 
                           short_name=not admin, admin=False)
 

	
 
        def last_change(last_change):
 
            return _render("last_change", last_change)
 

	
 
        def rss_lnk(repo_name):
 
            return _render("rss", repo_name)
 

	
 
        def atom_lnk(repo_name):
 
            return _render("atom", repo_name)
 

	
 
        def last_rev(repo_name, cs_cache):
 
            return _render('revision', repo_name, cs_cache.get('revision'),
 
                           cs_cache.get('raw_id'), cs_cache.get('author'),
 
                           cs_cache.get('message'))
 

	
 
        def desc(desc):
 
            from pylons import tmpl_context as c
 
            if c.visual.stylify_metatags:
 
                return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
 
            else:
 
                return h.urlify_text(h.truncate(desc, 60))
 

	
 
        def repo_actions(repo_name):
 
            return _render('repo_actions', repo_name)
 

	
 
        def owner_actions(user_id, username):
 
            return _render('user_name', user_id, username)
 

	
 
        repos_data = []
 
        for repo in repos_list:
 
            if perm_check:
 
                # check permission at this level
 
                if not HasRepoPermissionAny(
 
                    'repository.read', 'repository.write', 'repository.admin'
 
                )(repo.repo_name, 'get_repos_as_dict check'):
 
                    continue
 
            cs_cache = repo.changeset_cache
 
            row = {
 
                "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": last_change(repo.last_db_change),
 
                "last_changeset": last_rev(repo.repo_name, cs_cache),
 
                "raw_tip": cs_cache.get('revision'),
 
                "desc": desc(repo.description),
 
                "owner": h.person(repo.user.username),
 
                "rss": rss_lnk(repo.repo_name),
 
                "atom": atom_lnk(repo.repo_name),
 

	
 
            }
 
            if admin:
 
                row.update({
 
                    "action": repo_actions(repo.repo_name),
 
                    "owner": owner_actions(repo.user.user_id,
 
                                           h.person(repo.user.username))
 
                })
 
            repos_data.append(row)
 

	
 
        return {
 
            "totalRecords": len(repos_list),
 
            "startIndex": 0,
 
            "sort": "name",
 
            "dir": "asc",
 
            "records": repos_data
 
        }
 

	
 
    def _get_defaults(self, repo_name):
 
        """
 
        Get's information about repository, and returns a dict for
 
        usage in forms
 

	
 
        :param repo_name:
 
        """
 

	
 
        repo_info = Repository.get_by_repo_name(repo_name)
 

	
 
        if repo_info is None:
 
            return None
rhodecode/public/css/style.css
Show inline comments
 
@@ -3226,25 +3226,25 @@ table.code-browser .submodule-dir {
 
	padding-top: 0px;
 
	text-align: left;
 
}
 
 
.accept_icon {
 
    background: url("../images/icons/accept.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 
 
.edit_icon {
 
	background: url("../images/icons/folder_edit.png") no-repeat scroll 3px;
 
	background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px;
 
	padding-left: 20px;
 
	padding-top: 0px;
 
	text-align: left;
 
}
 
 
.delete_icon {
 
	background: url("../images/icons/delete.png") no-repeat scroll 3px;
 
	padding-left: 20px;
 
	padding-top: 0px;
 
	text-align: left;
 
}
 
rhodecode/templates/admin/repos/repos.html
Show inline comments
 
@@ -31,24 +31,25 @@
 
  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_changeset"},
 
         {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();
 
@@ -61,32 +62,34 @@
 
          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_changeset",label:"${_('Tip')}",sortable:true,
 
          sortOptions: { sortFunction: revisionSort }},      
 
      {key:"owner",label:"${_('Owner')}",sortable:true},
 
      {key:"action",label:"${_('Action')}",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,
 
        rowsPerPage: 25,
 
        alwaysVisible: false,
 
        template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
 
        pageLinks: 5,
 
        containerClass: 'pagination-wh',
 
        currentPageClass: 'pager_curpage',
 
        pageLinkClass: 'pager_link',
 
        nextPageLinkLabel: '&gt;',
 
        previousPageLinkLabel: '&lt;',
 
        firstPageLinkLabel: '&lt;&lt;',
 
        lastPageLinkLabel: '&gt;&gt;',
 
        containers:['user-paginator']
 
    }),
 
@@ -102,34 +105,38 @@
 
      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};
 
      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 = '';
 
	  if(!YUD.hasClass('q_filter', 'loaded')){
 
		  YUD.get('q_filter').value = '';
 
		  //TODO: load here full list later to do search within groups
 
		  YUD.addClass('q_filter', 'loaded');
 
	  }
 
   });
 

	
 
  YUE.on('q_filter','keyup',function (e) {
 
      clearTimeout(filterTimeout);
 
      filterTimeout = setTimeout(updateFilter,600);
 
  });
 
</script>
 

	
 
</%def>
rhodecode/templates/admin/users/user_edit_my_account.html
Show inline comments
 
@@ -39,25 +39,25 @@
 
           </li>
 
           <li>
 
             <span><a id="show_pullrequests" class="link-white" href="#pullrequests">${_('My pull requests')}</a> </span>
 
           </li>
 
           %if h.HasPermissionAny('hg.admin','hg.create.repository')():
 
             <li>
 
               <span>${h.link_to(_('Add repo'),h.url('admin_settings_create_repository'))}</span>
 
             </li>
 
           %endif
 
         </ul>
 
    </div>
 
    <!-- end box / title -->
 
    <div id="perms" class="table">
 
    <div id="perms_container" class="table">
 
           %for section in sorted(c.rhodecode_user.permissions.keys()):
 
            <div class="perms_section_head">${section.replace("_"," ").capitalize()}</div>
 

	
 
            <div id='tbl_list_wrap_${section}' class="yui-skin-sam">
 
            <table id="tbl_list_${section}">
 
              <thead>
 
                  <tr>
 
                  <th class="left">${_('Name')}</th>
 
                  <th class="left">${_('Permission')}</th>
 
              </thead>
 
              <tbody>
 
            %for k in c.rhodecode_user.permissions[section]:
 
@@ -85,164 +85,194 @@
 
                        %else:
 
                        <span class="perm_tag ${_perm}">${section_perm}</span>
 
                        %endif
 
                     </td>
 
                </tr>
 
             %endif
 
            %endfor
 
            </tbody>
 
            </table>
 
            </div>
 
           %endfor
 
    </div>
 
    <div id="my" class="table" style="display:none">
 
    <div id="my_container" style="display:none">
 
        <div class="table yui-skin-sam" id="repos_list_wrap"></div>
 
        <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
 
    </div>
 
    <div id="pullrequests" class="table" style="display:none"></div>
 
    <div id="pullrequests_container" class="table" style="display:none">
 
        ## loaded via AJAX
 
        ${_('Loading...')}    
 
    </div>
 
</div>
 

	
 

	
 

	
 
<script type="text/javascript">
 
var filter_activate = function(){
 
    var nodes = YUQ('#my tr td a.repo_name');
 
    var func = function(node){
 
        return node.parentNode.parentNode.parentNode.parentNode;
 
    }
 
    q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
 
}
 

	
 
var show_perms = function(e){
 
    YUD.addClass('show_perms', 'current');
 
    YUD.removeClass('show_my','current');
 
    YUD.removeClass('show_pullrequests','current');
 

	
 
    YUD.setStyle('my','display','none');
 
    YUD.setStyle('pullrequests','display','none');
 
    YUD.setStyle('perms','display','');
 
    YUD.setStyle('my_container','display','none');
 
    YUD.setStyle('pullrequests_container','display','none');
 
    YUD.setStyle('perms_container','display','');
 
    YUD.setStyle('q_filter','display','none');
 
}
 
YUE.on('show_perms','click',function(e){
 
    show_perms();
 
})
 

	
 
var show_my = function(e){
 
    YUD.addClass('show_my', 'current');
 
    YUD.removeClass('show_perms','current');
 
    YUD.removeClass('show_pullrequests','current');
 

	
 
    YUD.setStyle('perms','display','none');
 
    YUD.setStyle('pullrequests','display','none');
 
    YUD.setStyle('my','display','');
 
    YUD.setStyle('perms_container','display','none');
 
    YUD.setStyle('pullrequests_container','display','none');
 
    YUD.setStyle('my_container','display','');
 
    YUD.setStyle('q_filter','display','');
 

	
 

	
 
    var url = "${h.url('journal_my_repos')}";
 
    ypjax(url, 'my', function(){
 
        table_sort();
 
        filter_activate();
 
    });
 
    if(!YUD.hasClass('show_my', 'loaded')){
 
    	table_renderer(${c.data |n});
 
        YUD.addClass('show_my', 'loaded');
 
    }
 
}
 
YUE.on('show_my','click',function(e){
 
	show_my(e);
 
})
 

	
 
var show_pullrequests = function(e){
 
    YUD.addClass('show_pullrequests', 'current');
 
    YUD.removeClass('show_my','current');
 
    YUD.removeClass('show_perms','current');
 

	
 
    YUD.setStyle('my','display','none');
 
    YUD.setStyle('perms','display','none');
 
    YUD.setStyle('pullrequests','display','');
 
    YUD.setStyle('my_container','display','none');
 
    YUD.setStyle('perms_container','display','none');
 
    YUD.setStyle('pullrequests_container','display','');
 
    YUD.setStyle('q_filter','display','none');
 

	
 
    var url = "${h.url('admin_settings_my_pullrequests')}";
 
    ypjax(url, 'pullrequests');
 
    ypjax(url, 'pullrequests_container');
 
}
 
YUE.on('show_pullrequests','click',function(e){
 
	show_pullrequests(e)
 
})
 

	
 
var tabs = {
 
    'perms': show_perms,
 
    'my': show_my,
 
    'pullrequests': show_pullrequests
 
}
 
var url = location.href.split('#');
 
if (url[1]) {
 
    //We have a hash
 
    var tabHash = url[1];
 
    var func = tabs[tabHash]
 
    if (func){
 
        func();
 
    }
 
}
 

	
 
// 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:"tip",label:"${_('Tip')}",sortable:true,
 
        sortOptions: { sortFunction: revisionSort }},
 
    {key:"action1",label:"",sortable:false},
 
    {key:"action2",label:"",sortable:false},
 
];
 
function table_renderer(data){
 
	  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:"last_changeset"},
 
	         {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;
 
          }
 
          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:"last_changeset",label:"${_('Tip')}",sortable:true,
 
	          sortOptions: { sortFunction: revisionSort }},      
 
	      {key:"action",label:"${_('Action')}",sortable:false},
 
	  ];
 

	
 
function table_sort(){
 
var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
 
myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
 
myDataSource.responseSchema = {
 
    fields: [
 
        {key:"menu"},
 
        {key:"name"},
 
        {key:"tip"},
 
        {key:"action1"},
 
        {key:"action2"},
 
    ]
 
};
 
var trans_defs =  {
 
    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...')}",
 
}
 
var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,trans_defs);
 
myDataTable.subscribe('postRenderEvent',function(oArgs) {
 
    tooltip_activate();
 
    quick_repo_menu();
 
    filter_activate();
 
});
 
	  var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
 
	    sortedBy:{key:"name",dir:"asc"},
 
	    paginator: new YAHOO.widget.Paginator({
 
	        rowsPerPage: 50,
 
	        alwaysVisible: false,
 
	        template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
 
	        pageLinks: 5,
 
	        containerClass: 'pagination-wh',
 
	        currentPageClass: 'pager_curpage',
 
	        pageLinkClass: 'pager_link',
 
	        nextPageLinkLabel: '&gt;',
 
	        previousPageLinkLabel: '&lt;',
 
	        firstPageLinkLabel: '&lt;&lt;',
 
	        lastPageLinkLabel: '&gt;&gt;',
 
	        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;
 

	
 
var permsColumnDefs = [
 
    {key:"name",label:"${_('Name')}",sortable:true, sortOptions: { sortFunction: permNameSort }},
 
    {key:"perm",label:"${_('Permission')}",sortable:false,},
 
];
 
	  updateFilter = function() {
 
	      // Reset timeout
 
	      filterTimeout = null;
 

	
 
// perms repos table
 
var myDataSource2 = new YAHOO.util.DataSource(YUD.get("tbl_list_repositories"));
 
myDataSource2.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
 
myDataSource2.responseSchema = {
 
    fields: [
 
        {key:"name"},
 
        {key:"perm"},
 
    ]
 
};
 
	      // Reset sort
 
	      var state = myDataTable.getState();
 
	      state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
 

	
 
new YAHOO.widget.DataTable("tbl_list_wrap_repositories", permsColumnDefs, myDataSource2, trans_defs);
 
	      // Get filtered data
 
	      myDataSource.sendRequest(YUD.get('q_filter').value,{
 
	          success : myDataTable.onDataReturnInitializeTable,
 
	          failure : myDataTable.onDataReturnInitializeTable,
 
	          scope   : myDataTable,
 
	          argument: state
 
	      });
 

	
 
//perms groups table
 
var myDataSource3 = new YAHOO.util.DataSource(YUD.get("tbl_list_repositories_groups"));
 
myDataSource3.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
 
myDataSource3.responseSchema = {
 
    fields: [
 
        {key:"name"},
 
        {key:"perm"},
 
    ]
 
};
 
	  };
 
	  YUE.on('q_filter','click',function(){
 
	      if(!YUD.hasClass('q_filter', 'loaded')){
 
	          YUD.get('q_filter').value = '';
 
	          //TODO: load here full list later to do search within groups
 
	          YUD.addClass('q_filter', 'loaded');
 
	      }
 
	   });
 

	
 
new YAHOO.widget.DataTable("tbl_list_wrap_repositories_groups", permsColumnDefs, myDataSource3, trans_defs);
 
}
 
	  YUE.on('q_filter','keyup',function (e) {
 
	      clearTimeout(filterTimeout);
 
	      filterTimeout = setTimeout(updateFilter,600);
 
	  });
 
	}
 
</script>
 
</%def>
rhodecode/templates/admin/users/user_edit_my_account_repos.html
Show inline comments
 
<div id='repos_list_wrap' class="yui-skin-sam">
 
  <table id="repos_list">
 
  <thead>
 
      <tr>
 
      <th></th>
 
      <th class="left">${_('Name')}</th>
 
      <th class="left">${_('Revision')}</th>
 
      <th class="left">${_('Action')}</th>
 
      <th class="left">${_('Action')}</th>
 
  </thead>
 
   <tbody>
 
   <%namespace name="dt" file="/data_table/_dt_elements.html"/>
 
   %if c.user_repos:
 
       %for repo in c.user_repos:
 
          <tr>
 
              ##QUICK MENU
 
              <td class="quick_repo_menu">
 
                ${dt.quick_menu(repo['name'])}
 
              </td>
 
              ##REPO NAME AND ICONS
 
              <td class="reponame">
 
                ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']))}
 
              </td>
 
              ##LAST REVISION
 
              <td>
 
                  ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
 
              </td>
 
              <td><a href="${h.url('repo_settings_home',repo_name=repo['name'])}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="${h.url('/images/icons/application_form_edit.png')}"/></a></td>
 
              <td>
 
                ${h.form(url('repo_settings_delete', repo_name=repo['name']),method='delete')}
 
                  ${h.submit('remove_%s' % repo['name'],'',class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo['name']+"');")}
 
                ${h.end_form()}
 
              </td>
 
          </tr>
 
       %endfor
 
   %else:
 
      <div style="padding:5px 0px 10px 0px;">
 
      ${_('No repositories yet')}
 
      %if h.HasPermissionAny('hg.admin','hg.create.repository')():
 
          ${h.link_to(_('create one now'),h.url('admin_settings_create_repository'),class_="ui-btn")}
 
      %endif
 
      </div>
 
   %endif
 
   </tbody>
 
   </table>
 
</div>
 

	
rhodecode/templates/data_table/_dt_elements.html
Show inline comments
 
## DATA TABLE RE USABLE ELEMENTS
 
## usage:
 
## <%namespace name="dt" file="/data_table/_dt_elements.html"/>
 

	
 
<%def name="repo_actions(repo_name)">
 
  ${h.form(h.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()}
 
</%def>
 

	
 
<%def name="quick_menu(repo_name)">
 
  <ul class="menu_items hidden">
 
    <li style="border-top:1px solid #003367;margin-left:18px;padding-left:-99px"></li>
 
    <li>
 
       <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=repo_name)}">
 
       <span class="icon">
 
           <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
 
       </span>
 
       <span>${_('Summary')}</span>
 
       </a>
 
    </li>
 
    <li>
 
@@ -37,25 +31,25 @@
 
    </li>
 
    <li>
 
       <a title="${_('Fork')}" href="${h.url('repo_fork_home',repo_name=repo_name)}">
 
       <span class="icon">
 
           <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Fork')}" />
 
       </span>
 
       <span>${_('Fork')}</span>
 
       </a>
 
    </li>
 
  </ul>
 
</%def>
 

	
 
<%def name="repo_name(name,rtype,private,fork_of,short_name=False, admin=False)">
 
<%def name="repo_name(name,rtype,private,fork_of,short_name=False,admin=False)">
 
    <%
 
    def get_name(name,short_name=short_name):
 
      if short_name:
 
        return name.split('/')[-1]
 
      else:
 
        return name
 
    %>
 
  <div style="white-space: nowrap">
 
   ##TYPE OF REPO
 
   %if h.is_hg(rtype):
 
     <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
 
   %elif h.is_git(rtype):
 
@@ -107,22 +101,44 @@
 
<%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>
 

	
 
<%def name="repo_actions(repo_name)">
 
  <div>
 
    <div style="float:left">
 
    <a href="${h.url('repo_settings_home',repo_name=repo_name)}" title="${_('edit')}">
 
      ${h.submit('edit_%s' % repo_name,_('edit'),class_="edit_icon action_button")}
 
    </a>
 
    </div>
 
    <div style="float:left">
 
    ${h.form(h.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()}
 
    </div>
 
  </div>  
 
</%def>
 

	
 
<%def name="user_actions(user_id, username)">
 
  ${h.form(h.url('delete_user', id=user_id),method='delete')}
 
      ${h.submit('remove_',_('delete'),id="remove_user_%s" % user_id,
 
      class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user: %s') % username+"');")}
 
  ${h.end_form()}
 
</%def>
 

	
 
<%def name="user_name(user_id, username)">
 
    ${h.link_to(username,h.url('edit_user', id=user_id))}
 
</%def>
 

	
 
<%def name="toggle_follow(repo_id)">
 
  <span id="follow_toggle_${repo_id}" class="following" title="${_('Stop following this repository')}"
 
        onclick="javascript:toggleFollowingRepo(this, ${repo_id},'${str(h.get_token())}')">
 
  </span>
 
</%def>
 

	
rhodecode/templates/index_base.html
Show inline comments
 
@@ -118,27 +118,24 @@
 
            </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;
 
      }
 

	
 
      // groups table sorting
 
      var myColumnDefs = [
 
          {key:"name",label:"${_('Group name')}",sortable:true,
 
              sortOptions: { sortFunction: groupNameSort }},
 
          {key:"desc",label:"${_('Description')}",sortable:true},
 
      ];
 

	
 
      var myDataSource = new YAHOO.util.DataSource(YUD.get("groups_list"));
 

	
 
      myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
 
      myDataSource.responseSchema = {
 
@@ -205,44 +202,46 @@
 
              {
 
    	       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...')}",
 
              }
 
      );
 
      myDataTable.subscribe('postRenderEvent',function(oArgs) {
 
          tooltip_activate();
 
          quick_repo_menu();
 
          var func = function(node){
 
              return node.parentNode.parentNode.parentNode.parentNode;
 
          }          
 
          q_filter('q_filter',YUQ('div.table tr td a.repo_name'),func);
 
      });
 

	
 
    </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: "tip"},
 
               {key:"last_changeset"},
 
               {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) {
 
@@ -258,25 +257,25 @@
 
            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:"tip",label:"${_('Tip')}",sortable:true,
 
            {key:"last_changeset",label:"${_('Tip')}",sortable:true,
 
                sortOptions: { sortFunction: revisionSort }},
 
            {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: ${c.visual.lightweight_dashboard_items},
 
              alwaysVisible: false,
 
              template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
 
@@ -302,33 +301,37 @@
 
            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};
 
            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 = '';
 
            if(!YUD.hasClass('q_filter', 'loaded')){
 
                YUD.get('q_filter').value = '';
 
                //TODO: load here full list later to do search within groups
 
                YUD.addClass('q_filter', 'loaded');
 
            }
 
         });
 

	
 
        YUE.on('q_filter','keyup',function (e) {
 
            clearTimeout(filterTimeout);
 
            filterTimeout = setTimeout(updateFilter,600);
 
        });
 
      </script>
 
    % endif
rhodecode/templates/journal/journal.html
Show inline comments
 
@@ -34,138 +34,119 @@
 
           <li>
 
             <span><a href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('RSS feed')}" alt="${_('RSS feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
 
           </li>
 
           <li>
 
             <span><a href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/atom.png')}"/></a></span>
 
           </li>
 
         </ul>
 
	    </div>
 
	    <div id="journal">${c.journal_data}</div>
 
    </div>
 
    <div class="box box-right">
 
        <!-- box / title -->
 
    
 
        <div class="title">
 
            <h5>
 
            <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
 
            <a id="show_watched" class="link-white" href="#watched">${_('Watched')}</a> / <a id="show_my" class="link-white" href="#my">${_('My repos')}</a>
 
            <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}" style="display: none"/>
 
            <input class="q_filter_box" id="q_filter_watched" size="15" type="text" name="filter" value="${_('quick filter...')}" style="display: none"/>
 
            </h5>
 
             %if h.HasPermissionAny('hg.admin','hg.create.repository')():
 
             <ul class="links">
 
             <ul class="links" style="color:#DADADA">
 
               <li>
 
                 <span>${h.link_to(_('ADD'),h.url('admin_settings_create_repository'))}</span>
 
                 <span><a id="show_watched" class="link-white current" href="#watched">${_('Watched')}</a> </span>
 
               </li>
 
               <li>
 
                 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
 
               </li>
 
               %if h.HasPermissionAny('hg.admin','hg.create.repository')():
 
                 <li>
 
                   <span>${h.link_to(_('Add repo'),h.url('admin_settings_create_repository'))}</span>
 
                 </li>
 
               %endif
 
             </ul>
 
             %endif
 
        </div>
 
        </div>        
 
        
 
        <!-- end box / title -->
 
        <div id="my" class="table" style="display:none">
 
        ## loaded via AJAX
 
        ${_('Loading...')}
 
        <div id="my_container" style="display:none">
 
            <div class="table yui-skin-sam" id="repos_list_wrap"></div>
 
            <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
 
        </div>
 

	
 
        <div id="watched" class="table">
 
          %if c.following:
 
            <table>
 
            <thead>
 
                <tr>
 
                <th class="left">${_('Name')}</th>
 
            </thead>
 
             <tbody>
 
                %for entry in c.following:
 
                  <tr>
 
                    <td>
 
                      %if entry.follows_user_id:
 
                        <img title="${_('following user')}" alt="${_('user')}" src="${h.url('/images/icons/user.png')}"/>
 
                        ${entry.follows_user.full_contact}
 
                      %endif
 

	
 
                      %if entry.follows_repo_id:
 
                        <div style="float:right;padding-right:5px">
 
                        <span id="follow_toggle_${entry.follows_repository.repo_id}" class="following" title="${_('Stop following this repository')}"
 
                              onclick="javascript:toggleFollowingRepo(this,${entry.follows_repository.repo_id},'${str(h.get_token())}')">
 
                        </span>
 
                        </div>
 

	
 
                         %if h.is_hg(entry.follows_repository):
 
                           <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
 
                         %elif h.is_git(entry.follows_repository):
 
                           <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
 
                         %endif
 

	
 
                        %if entry.follows_repository.private and c.visual.show_private_icon:
 
                          <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
 
                        %elif not entry.follows_repository.private and c.visual.show_public_icon:
 
                          <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
 
                        %endif
 
                        <span class="watched_repo">
 
                            ${h.link_to(entry.follows_repository.repo_name,h.url('summary_home',repo_name=entry.follows_repository.repo_name))}
 
                        </span>
 
                      %endif
 
                    </td>
 
                  </tr>
 
                %endfor
 
            </tbody>
 
            </table>
 
          %else:
 
              <div style="padding:5px 0px 10px 0px;">
 
              ${_('You are not following any users or repositories')}
 
              </div>
 
          %endif
 
        
 
        <div id="watched_container">
 
            <div class="table yui-skin-sam" id="watched_repos_list_wrap"></div>
 
            <div id="watched-user-paginator" style="padding: 0px 0px 0px 20px"></div>
 
        </div>
 
    </div>
 

	
 
    <script type="text/javascript">
 

	
 
    YUE.on('j_filter','click',function(){
 
        var jfilter = YUD.get('j_filter');
 
        if(YUD.hasClass(jfilter, 'initial')){
 
            jfilter.value = '';
 
        }
 
    });
 
    var fix_j_filter_width = function(len){
 
        YUD.setStyle(YUD.get('j_filter'),'width',Math.max(80, len*6.50)+'px');
 
    }
 
    YUE.on('j_filter','keyup',function(){
 
        fix_j_filter_width(YUD.get('j_filter').value.length);
 
    });
 
    YUE.on('filter_form','submit',function(e){
 
        YUE.preventDefault(e)
 
        var val = YUD.get('j_filter').value;
 
        window.location = "${url.current(filter='__FILTER__')}".replace('__FILTER__',val);
 
    });
 
    fix_j_filter_width(YUD.get('j_filter').value.length);
 

	
 
    var show_my = function(e){
 
        YUD.setStyle('watched','display','none');
 
        YUD.setStyle('my','display','');
 

	
 
        var url = "${h.url('admin_settings_my_repos')}";
 
        ypjax(url, 'my', function(){
 
    YUE.on('refresh','click',function(e){
 
        ypjax("${h.url.current(filter=c.search_term)}","journal",function(){
 
            show_more_event();
 
            tooltip_activate();
 
            quick_repo_menu();
 
            var nodes = YUQ('#my tr td a.repo_name');
 
            var func = function(node){
 
                return node.parentNode.parentNode.parentNode;
 
            }
 
            q_filter('q_filter',nodes,func);
 
        });
 
            show_changeset_tooltip();
 
            });
 
        YUE.preventDefault(e);
 
    });    
 
    
 
    var show_my = function(e){
 
        YUD.setStyle('watched_container','display','none');
 
        YUD.setStyle('my_container','display','');
 
        YUD.setStyle('q_filter','display','');
 
        YUD.setStyle('q_filter_watched','display','none');
 

	
 
        YUD.addClass('show_my', 'current');
 
        YUD.removeClass('show_watched','current');
 
        
 
        if(!YUD.hasClass('show_my', 'loaded')){
 
            table_renderer(${c.data |n});
 
            YUD.addClass('show_my', 'loaded');
 
        }
 
    }
 
    YUE.on('show_my','click',function(e){
 
        show_my(e);
 
    })
 
    var show_watched = function(e){
 
    	YUD.setStyle('my','display','none');
 
        YUD.setStyle('watched','display','');
 
        var nodes = YUQ('#watched .watched_repo a');
 
    	YUD.setStyle('my_container','display','none');
 
        YUD.setStyle('watched_container','display','');
 
        YUD.setStyle('q_filter_watched','display','');
 
        YUD.setStyle('q_filter','display','none');
 

	
 
        YUD.addClass('show_watched', 'current');
 
        YUD.removeClass('show_my','current');
 
        if(!YUD.hasClass('show_watched', 'loaded')){
 
        	watched_renderer(${c.watched_data |n});
 
            YUD.addClass('show_watched', 'loaded');
 
        }        
 
        
 
        return
 
        var nodes = YUQ('#watched_container .watched_repo a');
 
        var target = 'q_filter';
 
        var func = function(node){
 
            return node.parentNode.parentNode;
 
        }
 
        q_filter(target,nodes,func);
 
    }
 
    YUE.on('show_watched','click',function(e){
 
        show_watched(e);
 
    })
 
    //init watched
 
    show_watched();
 

	
 
@@ -173,69 +154,222 @@
 
        'watched': show_watched,
 
        'my': show_my,
 
    }
 
    var url = location.href.split('#');
 
    if (url[1]) {
 
        //We have a hash
 
        var tabHash = url[1];
 
        var func = tabs[tabHash]
 
        if (func){
 
        	func();
 
        }
 
    }
 
    function watched_renderer(data){
 
        var myDataSource = new YAHOO.util.DataSource(data);
 
        myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
 

	
 
    YUE.on('refresh','click',function(e){
 
        ypjax("${h.url.current(filter=c.search_term)}","journal",function(){
 
        	show_more_event();
 
        	tooltip_activate();
 
        	show_changeset_tooltip();
 
        	});
 
        YUE.preventDefault(e);
 
    });
 
        myDataSource.responseSchema = {
 
            resultsList: "records",
 
            fields: [
 
               {key:"menu"},
 
               {key:"raw_name"},
 
               {key:"name"},
 
               {key:"last_changeset"},
 
               {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;
 
            }
 
            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:"last_changeset",label:"${_('Tip')}",sortable:true,
 
                sortOptions: { sortFunction: revisionSort }},      
 
            {key:"action",label:"${_('Action')}",sortable:false},
 
        ];
 

	
 
    // 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:"tip",label:"${_('Tip')}",sortable:true,
 
            sortOptions: { sortFunction: revisionSort }},
 
        {key:"action1",label:"",sortable:false},
 
        {key:"action2",label:"",sortable:false},
 
    ];
 
        var myDataTable = new YAHOO.widget.DataTable("watched_repos_list_wrap", myColumnDefs, myDataSource,{
 
          sortedBy:{key:"name",dir:"asc"},
 
          paginator: new YAHOO.widget.Paginator({
 
              rowsPerPage: 25,
 
              alwaysVisible: false,
 
              template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
 
              pageLinks: 5,
 
              containerClass: 'pagination-wh',
 
              currentPageClass: 'pager_curpage',
 
              pageLinkClass: 'pager_link',
 
              nextPageLinkLabel: '&gt;',
 
              previousPageLinkLabel: '&lt;',
 
              firstPageLinkLabel: '&lt;&lt;',
 
              lastPageLinkLabel: '&gt;&gt;',
 
              containers:['watched-user-paginator']
 
          }),
 

	
 
    var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
 
          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;
 

	
 
    myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
 
            // 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_watched').value,{
 
                success : myDataTable.onDataReturnInitializeTable,
 
                failure : myDataTable.onDataReturnInitializeTable,
 
                scope   : myDataTable,
 
                argument: state
 
            });
 

	
 
        };
 
        YUE.on('q_filter_watched','click',function(){
 
            if(!YUD.hasClass('q_filter_watched', 'loaded')){
 
                YUD.get('q_filter_watched').value = '';
 
                //TODO: load here full list later to do search within groups
 
                YUD.addClass('q_filter_watched', 'loaded');
 
            }
 
         });
 

	
 
    myDataSource.responseSchema = {
 
        fields: [
 
            {key:"menu"},
 
            {key:"name"},
 
            {key:"tip"},
 
            {key:"action1"},
 
            {key:"action2"}
 
        ]
 
    };
 
        YUE.on('q_filter_watched','keyup',function (e) {
 
            clearTimeout(filterTimeout);
 
            filterTimeout = setTimeout(updateFilter,600);
 
        });
 
      }
 
    
 
    function table_renderer(data){
 
        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:"last_changeset"},
 
               {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;
 
            }
 
            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:"last_changeset",label:"${_('Tip')}",sortable:true,
 
                sortOptions: { sortFunction: revisionSort }},      
 
            {key:"action",label:"${_('Action')}",sortable:false},
 
        ];
 

	
 
    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...')}",
 
        var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
 
          sortedBy:{key:"name",dir:"asc"},
 
          paginator: new YAHOO.widget.Paginator({
 
              rowsPerPage: 25,
 
              alwaysVisible: false,
 
              template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
 
              pageLinks: 5,
 
              containerClass: 'pagination-wh',
 
              currentPageClass: 'pager_curpage',
 
              pageLinkClass: 'pager_link',
 
              nextPageLinkLabel: '&gt;',
 
              previousPageLinkLabel: '&lt;',
 
              firstPageLinkLabel: '&lt;&lt;',
 
              lastPageLinkLabel: '&gt;&gt;',
 
              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(){
 
            if(!YUD.hasClass('q_filter', 'loaded')){
 
                YUD.get('q_filter').value = '';
 
                //TODO: load here full list later to do search within groups
 
                YUD.addClass('q_filter', 'loaded');
 
            }
 
    );
 
    myDataTable.subscribe('postRenderEvent',function(oArgs) {
 
        tooltip_activate();
 
        quick_repo_menu();
 
        var func = function(node){
 
            return node.parentNode.parentNode.parentNode.parentNode;
 
        }
 
        q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
 
    });
 
         });
 

	
 
        YUE.on('q_filter','keyup',function (e) {
 
            clearTimeout(filterTimeout);
 
            filterTimeout = setTimeout(updateFilter,600);
 
        });
 
      }    
 
    
 
    </script>
 
</%def>
rhodecode/templates/journal/journal_page_repos.html
Show inline comments
 
deleted file
0 comments (0 inline, 0 general)