Show More
@@ -34,6 +34,7 from pylons.controllers.util import redi | |||||
34 | from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
35 | from sqlalchemy.exc import IntegrityError |
|
35 | from sqlalchemy.exc import IntegrityError | |
36 |
|
36 | |||
|
37 | import rhodecode | |||
37 | from rhodecode.lib import helpers as h |
|
38 | from rhodecode.lib import helpers as h | |
38 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ |
|
39 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ | |
39 | HasPermissionAnyDecorator, HasRepoPermissionAllDecorator |
|
40 | HasPermissionAnyDecorator, HasRepoPermissionAllDecorator | |
@@ -45,6 +46,7 from rhodecode.model.db import User, Rep | |||||
45 | from rhodecode.model.forms import RepoForm |
|
46 | from rhodecode.model.forms import RepoForm | |
46 | from rhodecode.model.scm import ScmModel |
|
47 | from rhodecode.model.scm import ScmModel | |
47 | from rhodecode.model.repo import RepoModel |
|
48 | from rhodecode.model.repo import RepoModel | |
|
49 | from rhodecode.lib.compat import json | |||
48 |
|
50 | |||
49 | log = logging.getLogger(__name__) |
|
51 | log = logging.getLogger(__name__) | |
50 |
|
52 | |||
@@ -131,9 +133,44 class ReposController(BaseController): | |||||
131 | """GET /repos: All items in the collection""" |
|
133 | """GET /repos: All items in the collection""" | |
132 | # url('repos') |
|
134 | # url('repos') | |
133 |
|
135 | |||
134 |
c.repos_list = |
|
136 | c.repos_list = Repository.query()\ | |
135 |
|
|
137 | .order_by(Repository.repo_name)\ | |
136 | .all(), sort_key='name_sort') |
|
138 | .all() | |
|
139 | ||||
|
140 | repos_data = [] | |||
|
141 | total_records = len(c.repos_list) | |||
|
142 | ||||
|
143 | _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup | |||
|
144 | template = _tmpl_lookup.get_template('data_table/_dt_elements.html') | |||
|
145 | ||||
|
146 | quick_menu = lambda repo_name: (template.get_def("quick_menu") | |||
|
147 | .render(repo_name, _=_, h=h)) | |||
|
148 | repo_lnk = lambda name, rtype, private, fork_of: ( | |||
|
149 | template.get_def("repo_name") | |||
|
150 | .render(name, rtype, private, fork_of, short_name=False, | |||
|
151 | admin=True, _=_, h=h)) | |||
|
152 | ||||
|
153 | repo_actions = lambda repo_name: (template.get_def("repo_actions") | |||
|
154 | .render(repo_name, _=_, h=h)) | |||
|
155 | ||||
|
156 | for repo in c.repos_list: | |||
|
157 | repos_data.append({ | |||
|
158 | "menu": quick_menu(repo.repo_name), | |||
|
159 | "raw_name": repo.repo_name, | |||
|
160 | "name": repo_lnk(repo.repo_name, repo.repo_type, repo.private, repo.fork), | |||
|
161 | "desc": repo.description, | |||
|
162 | "owner": repo.user.username, | |||
|
163 | "action": repo_actions(repo.repo_name), | |||
|
164 | }) | |||
|
165 | ||||
|
166 | c.data = json.dumps({ | |||
|
167 | "totalRecords": total_records, | |||
|
168 | "startIndex": 0, | |||
|
169 | "sort": "name", | |||
|
170 | "dir": "asc", | |||
|
171 | "records": repos_data | |||
|
172 | }) | |||
|
173 | ||||
137 | return render('admin/repos/repos.html') |
|
174 | return render('admin/repos/repos.html') | |
138 |
|
175 | |||
139 | @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') |
|
176 | @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') |
@@ -5,9 +5,8 | |||||
5 | ${_('Repositories administration')} - ${c.rhodecode_name} |
|
5 | ${_('Repositories administration')} - ${c.rhodecode_name} | |
6 | </%def> |
|
6 | </%def> | |
7 |
|
7 | |||
8 |
|
||||
9 | <%def name="breadcrumbs_links()"> |
|
8 | <%def name="breadcrumbs_links()"> | |
10 | ${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Repositories')} |
|
9 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${h.link_to(_('Admin'),h.url('admin_home'))} » <span id="repo_count">0</span> ${_('repositories')} | |
11 | </%def> |
|
10 | </%def> | |
12 | <%def name="page_nav()"> |
|
11 | <%def name="page_nav()"> | |
13 | ${self.menu('admin')} |
|
12 | ${self.menu('admin')} | |
@@ -23,102 +22,114 | |||||
23 | </li> |
|
22 | </li> | |
24 | </ul> |
|
23 | </ul> | |
25 | </div> |
|
24 | </div> | |
26 |
|
25 | <div class="table yui-skin-sam" id="repos_list_wrap"></div> | ||
27 | <div class="table"> |
|
26 | <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div> | |
28 | <div id='repos_list_wrap' class="yui-skin-sam"> |
|
27 | ||
29 | <%cnt=0%> |
|
|||
30 | <%namespace name="dt" file="/data_table/_dt_elements.html"/> |
|
|||
31 |
|
||||
32 | <table id="repos_list"> |
|
|||
33 | <thead> |
|
|||
34 | <tr> |
|
|||
35 | <th class="left"></th> |
|
|||
36 | <th class="left">${_('Name')}</th> |
|
|||
37 | <th class="left">${_('Description')}</th> |
|
|||
38 | <th class="left">${_('Last change')}</th> |
|
|||
39 | <th class="left">${_('Tip')}</th> |
|
|||
40 | <th class="left">${_('Contact')}</th> |
|
|||
41 | <th class="left">${_('Action')}</th> |
|
|||
42 | </tr> |
|
|||
43 | </thead> |
|
|||
44 |
|
28 | |||
45 | %for cnt,repo in enumerate(c.repos_list): |
|
|||
46 | <tr class="parity${(cnt+1)%2}"> |
|
|||
47 | <td class="quick_repo_menu"> |
|
|||
48 | ${dt.quick_menu(repo['name'])} |
|
|||
49 | </td> |
|
|||
50 | <td class="reponame"> |
|
|||
51 | ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],repo['dbrepo_fork'].get('repo_name'), admin=True)} |
|
|||
52 | </td> |
|
|||
53 | ##DESCRIPTION |
|
|||
54 | <td><span class="tooltip" title="${h.tooltip(repo['description'])}"> |
|
|||
55 | ${h.truncate(repo['description'],60)}</span> |
|
|||
56 | </td> |
|
|||
57 | ##LAST CHANGE |
|
|||
58 | <td> |
|
|||
59 | <span class="tooltip" date="${repo['last_change']}" title="${h.tooltip(repo['last_change'])}">${h.age(repo['last_change'])}</span> |
|
|||
60 | </td> |
|
|||
61 | ##LAST REVISION |
|
|||
62 | <td> |
|
|||
63 | ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])} |
|
|||
64 | </td> |
|
|||
65 | <td title="${repo['contact']}">${h.person(repo['contact'])}</td> |
|
|||
66 | <td> |
|
|||
67 | ${h.form(url('repo', repo_name=repo['name']),method='delete')} |
|
|||
68 | ${h.submit('remove_%s' % repo['name'],_('delete'),class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo['name']+"');")} |
|
|||
69 | ${h.end_form()} |
|
|||
70 | </td> |
|
|||
71 | </tr> |
|
|||
72 | %endfor |
|
|||
73 | </table> |
|
|||
74 | </div> |
|
|||
75 | </div> |
|
|||
76 | </div> |
|
29 | </div> | |
77 | <script> |
|
30 | <script> | |
|
31 | var url = "${h.url('formatted_users', format='json')}"; | |||
|
32 | var data = ${c.data|n}; | |||
|
33 | var myDataSource = new YAHOO.util.DataSource(data); | |||
|
34 | myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON; | |||
|
35 | ||||
|
36 | myDataSource.responseSchema = { | |||
|
37 | resultsList: "records", | |||
|
38 | fields: [ | |||
|
39 | {key:"menu"}, | |||
|
40 | {key:"raw_name"}, | |||
|
41 | {key:"name"}, | |||
|
42 | {key:"desc"}, | |||
|
43 | {key:"owner"}, | |||
|
44 | {key:"action"}, | |||
|
45 | ] | |||
|
46 | }; | |||
|
47 | myDataSource.doBeforeCallback = function(req,raw,res,cb) { | |||
|
48 | // This is the filter function | |||
|
49 | var data = res.results || [], | |||
|
50 | filtered = [], | |||
|
51 | i,l; | |||
|
52 | ||||
|
53 | if (req) { | |||
|
54 | req = req.toLowerCase(); | |||
|
55 | for (i = 0; i<data.length; i++) { | |||
|
56 | var pos = data[i].raw_name.toLowerCase().indexOf(req) | |||
|
57 | if (pos != -1) { | |||
|
58 | filtered.push(data[i]); | |||
|
59 | } | |||
|
60 | } | |||
|
61 | res.results = filtered; | |||
|
62 | } | |||
|
63 | YUD.get('repo_count').innerHTML = res.results.length; | |||
|
64 | return res; | |||
|
65 | } | |||
78 |
|
66 | |||
79 | // main table sorting |
|
67 | // main table sorting | |
80 | var myColumnDefs = [ |
|
68 | var myColumnDefs = [ | |
81 | {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"}, |
|
69 | {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"}, | |
82 | {key:"name",label:"${_('Name')}",sortable:true, |
|
70 | {key:"name",label:"${_('Name')}",sortable:true, | |
83 |
|
|
71 | sortOptions: { sortFunction: nameSort }}, | |
84 | {key:"desc",label:"${_('Description')}",sortable:true}, |
|
72 | {key:"desc",label:"${_('Description')}",sortable:true}, | |
85 | {key:"last_change",label:"${_('Last Change')}",sortable:true, |
|
|||
86 | sortOptions: { sortFunction: ageSort }}, |
|
|||
87 | {key:"tip",label:"${_('Tip')}",sortable:true, |
|
|||
88 | sortOptions: { sortFunction: revisionSort }}, |
|
|||
89 | {key:"owner",label:"${_('Owner')}",sortable:true}, |
|
73 | {key:"owner",label:"${_('Owner')}",sortable:true}, | |
90 | {key:"action",label:"${_('Action')}",sortable:false}, |
|
74 | {key:"action",label:"${_('Action')}",sortable:false}, | |
91 | ]; |
|
75 | ]; | |
92 |
|
76 | |||
93 | var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list")); |
|
77 | var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{ | |
94 |
|
78 | sortedBy:{key:"name",dir:"asc"}, | ||
95 | myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE; |
|
79 | paginator: new YAHOO.widget.Paginator({ | |
|
80 | rowsPerPage: 15, | |||
|
81 | alwaysVisible: false, | |||
|
82 | template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}", | |||
|
83 | pageLinks: 5, | |||
|
84 | containerClass: 'pagination-wh', | |||
|
85 | currentPageClass: 'pager_curpage', | |||
|
86 | pageLinkClass: 'pager_link', | |||
|
87 | nextPageLinkLabel: '>', | |||
|
88 | previousPageLinkLabel: '<', | |||
|
89 | firstPageLinkLabel: '<<', | |||
|
90 | lastPageLinkLabel: '>>', | |||
|
91 | containers:['user-paginator'] | |||
|
92 | }), | |||
96 |
|
93 | |||
97 | myDataSource.responseSchema = { |
|
94 | MSG_SORTASC:"${_('Click to sort ascending')}", | |
98 | fields: [ |
|
95 | MSG_SORTDESC:"${_('Click to sort descending')}", | |
99 | {key:"menu"}, |
|
96 | MSG_EMPTY:"${_('No records found.')}", | |
100 | {key:"name"}, |
|
97 | MSG_ERROR:"${_('Data error.')}", | |
101 | {key:"desc"}, |
|
98 | MSG_LOADING:"${_('Loading...')}", | |
102 | {key:"last_change"}, |
|
99 | } | |
103 | {key:"tip"}, |
|
|||
104 | {key:"owner"}, |
|
|||
105 | {key:"action"}, |
|
|||
106 | ] |
|
|||
107 | }; |
|
|||
108 |
|
||||
109 | var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource, |
|
|||
110 | { |
|
|||
111 | sortedBy:{key:"name",dir:"asc"}, |
|
|||
112 | MSG_SORTASC:"${_('Click to sort ascending')}", |
|
|||
113 | MSG_SORTDESC:"${_('Click to sort descending')}", |
|
|||
114 | MSG_EMPTY:"${_('No records found.')}", |
|
|||
115 | MSG_ERROR:"${_('Data error.')}", |
|
|||
116 | MSG_LOADING:"${_('Loading...')}", |
|
|||
117 | } |
|
|||
118 | ); |
|
100 | ); | |
119 | myDataTable.subscribe('postRenderEvent',function(oArgs) { |
|
101 | myDataTable.subscribe('postRenderEvent',function(oArgs) { | |
120 | tooltip_activate(); |
|
102 | tooltip_activate(); | |
121 | quick_repo_menu(); |
|
103 | quick_repo_menu(); | |
122 | }); |
|
104 | }); | |
|
105 | ||||
|
106 | var filterTimeout = null; | |||
|
107 | ||||
|
108 | updateFilter = function () { | |||
|
109 | // Reset timeout | |||
|
110 | filterTimeout = null; | |||
|
111 | ||||
|
112 | // Reset sort | |||
|
113 | var state = myDataTable.getState(); | |||
|
114 | state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC}; | |||
|
115 | ||||
|
116 | // Get filtered data | |||
|
117 | myDataSource.sendRequest(YUD.get('q_filter').value,{ | |||
|
118 | success : myDataTable.onDataReturnInitializeTable, | |||
|
119 | failure : myDataTable.onDataReturnInitializeTable, | |||
|
120 | scope : myDataTable, | |||
|
121 | argument: state | |||
|
122 | }); | |||
|
123 | ||||
|
124 | }; | |||
|
125 | YUE.on('q_filter','click',function(){ | |||
|
126 | YUD.get('q_filter').value = ''; | |||
|
127 | }); | |||
|
128 | ||||
|
129 | YUE.on('q_filter','keyup',function (e) { | |||
|
130 | clearTimeout(filterTimeout); | |||
|
131 | filterTimeout = setTimeout(updateFilter,600); | |||
|
132 | }); | |||
123 | </script> |
|
133 | </script> | |
|
134 | ||||
124 | </%def> |
|
135 | </%def> |
General Comments 0
You need to be logged in to leave comments.
Login now