##// END OF EJS Templates
js: offsetScroll to elements that are found
ergo -
r794:6ce205ff default
parent child Browse files
Show More
@@ -1,393 +1,395 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%inherit file="/base/base.html"/>
3 <%inherit file="/base/base.html"/>
4 <%namespace name="diff_block" file="/changeset/diff_block.html"/>
4 <%namespace name="diff_block" file="/changeset/diff_block.html"/>
5
5
6 <%def name="title()">
6 <%def name="title()">
7 ${_('%s Commit') % c.repo_name} - ${h.show_id(c.commit)}
7 ${_('%s Commit') % c.repo_name} - ${h.show_id(c.commit)}
8 %if c.rhodecode_name:
8 %if c.rhodecode_name:
9 &middot; ${h.branding(c.rhodecode_name)}
9 &middot; ${h.branding(c.rhodecode_name)}
10 %endif
10 %endif
11 </%def>
11 </%def>
12
12
13 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
14 ${self.menu_items(active='repositories')}
14 ${self.menu_items(active='repositories')}
15 </%def>
15 </%def>
16
16
17 <%def name="menu_bar_subnav()">
17 <%def name="menu_bar_subnav()">
18 ${self.repo_menu(active='changelog')}
18 ${self.repo_menu(active='changelog')}
19 </%def>
19 </%def>
20
20
21 <%def name="main()">
21 <%def name="main()">
22 <script>
22 <script>
23 // TODO: marcink switch this to pyroutes
23 // TODO: marcink switch this to pyroutes
24 AJAX_COMMENT_DELETE_URL = "${url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
24 AJAX_COMMENT_DELETE_URL = "${url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
25 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
25 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
26 </script>
26 </script>
27 <div class="box">
27 <div class="box">
28 <div class="title">
28 <div class="title">
29 ${self.repo_page_title(c.rhodecode_db_repo)}
29 ${self.repo_page_title(c.rhodecode_db_repo)}
30 </div>
30 </div>
31
31
32 <div id="changeset_compare_view_content" class="summary changeset">
32 <div id="changeset_compare_view_content" class="summary changeset">
33 <div class="summary-detail">
33 <div class="summary-detail">
34 <div class="summary-detail-header">
34 <div class="summary-detail-header">
35 <span class="breadcrumbs files_location">
35 <span class="breadcrumbs files_location">
36 <h4>${_('Commit')}
36 <h4>${_('Commit')}
37 <code>
37 <code>
38 ${h.show_id(c.commit)}
38 ${h.show_id(c.commit)}
39 </code>
39 </code>
40 </h4>
40 </h4>
41 </span>
41 </span>
42 <span id="parent_link">
42 <span id="parent_link">
43 <a href="#" title="${_('Parent Commit')}">${_('Parent')}</a>
43 <a href="#" title="${_('Parent Commit')}">${_('Parent')}</a>
44 </span>
44 </span>
45 |
45 |
46 <span id="child_link">
46 <span id="child_link">
47 <a href="#" title="${_('Child Commit')}">${_('Child')}</a>
47 <a href="#" title="${_('Child Commit')}">${_('Child')}</a>
48 </span>
48 </span>
49 </div>
49 </div>
50
50
51 <div class="fieldset">
51 <div class="fieldset">
52 <div class="left-label">
52 <div class="left-label">
53 ${_('Description')}:
53 ${_('Description')}:
54 </div>
54 </div>
55 <div class="right-content">
55 <div class="right-content">
56 <div id="trimmed_message_box" class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
56 <div id="trimmed_message_box" class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
57 <div id="message_expand" style="display:none;">
57 <div id="message_expand" style="display:none;">
58 ${_('Expand')}
58 ${_('Expand')}
59 </div>
59 </div>
60 </div>
60 </div>
61 </div>
61 </div>
62
62
63 %if c.statuses:
63 %if c.statuses:
64 <div class="fieldset">
64 <div class="fieldset">
65 <div class="left-label">
65 <div class="left-label">
66 ${_('Commit status')}:
66 ${_('Commit status')}:
67 </div>
67 </div>
68 <div class="right-content">
68 <div class="right-content">
69 <div class="changeset-status-ico">
69 <div class="changeset-status-ico">
70 <div class="${'flag_status %s' % c.statuses[0]} pull-left"></div>
70 <div class="${'flag_status %s' % c.statuses[0]} pull-left"></div>
71 </div>
71 </div>
72 <div title="${_('Commit status')}" class="changeset-status-lbl">[${h.commit_status_lbl(c.statuses[0])}]</div>
72 <div title="${_('Commit status')}" class="changeset-status-lbl">[${h.commit_status_lbl(c.statuses[0])}]</div>
73 </div>
73 </div>
74 </div>
74 </div>
75 %endif
75 %endif
76
76
77 <div class="fieldset">
77 <div class="fieldset">
78 <div class="left-label">
78 <div class="left-label">
79 ${_('References')}:
79 ${_('References')}:
80 </div>
80 </div>
81 <div class="right-content">
81 <div class="right-content">
82 <div class="tags">
82 <div class="tags">
83
83
84 %if c.commit.merge:
84 %if c.commit.merge:
85 <span class="mergetag tag">
85 <span class="mergetag tag">
86 ${_('merge')}
86 ${_('merge')}
87 </span>
87 </span>
88 %endif
88 %endif
89
89
90 %if h.is_hg(c.rhodecode_repo):
90 %if h.is_hg(c.rhodecode_repo):
91 %for book in c.commit.bookmarks:
91 %for book in c.commit.bookmarks:
92 <span class="booktag tag" title="${_('Bookmark %s') % book}">
92 <span class="booktag tag" title="${_('Bookmark %s') % book}">
93 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
93 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
94 </span>
94 </span>
95 %endfor
95 %endfor
96 %endif
96 %endif
97
97
98 %for tag in c.commit.tags:
98 %for tag in c.commit.tags:
99 <span class="tagtag tag" title="${_('Tag %s') % tag}">
99 <span class="tagtag tag" title="${_('Tag %s') % tag}">
100 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-tag"></i>${tag}</a>
100 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-tag"></i>${tag}</a>
101 </span>
101 </span>
102 %endfor
102 %endfor
103
103
104 %if c.commit.branch:
104 %if c.commit.branch:
105 <span class="branchtag tag" title="${_('Branch %s') % c.commit.branch}">
105 <span class="branchtag tag" title="${_('Branch %s') % c.commit.branch}">
106 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-code-fork"></i>${h.shorter(c.commit.branch)}</a>
106 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-code-fork"></i>${h.shorter(c.commit.branch)}</a>
107 </span>
107 </span>
108 %endif
108 %endif
109 </div>
109 </div>
110 </div>
110 </div>
111 </div>
111 </div>
112
112
113 <div class="fieldset">
113 <div class="fieldset">
114 <div class="left-label">
114 <div class="left-label">
115 ${_('Diffs')}:
115 ${_('Diffs')}:
116 </div>
116 </div>
117 <div class="right-content">
117 <div class="right-content">
118 <div class="diff-actions">
118 <div class="diff-actions">
119 <a href="${h.url('changeset_raw_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Raw diff'))}">
119 <a href="${h.url('changeset_raw_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Raw diff'))}">
120 ${_('Raw Diff')}
120 ${_('Raw Diff')}
121 </a>
121 </a>
122 |
122 |
123 <a href="${h.url('changeset_patch_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Patch diff'))}">
123 <a href="${h.url('changeset_patch_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Patch diff'))}">
124 ${_('Patch Diff')}
124 ${_('Patch Diff')}
125 </a>
125 </a>
126 |
126 |
127 <a href="${h.url('changeset_download_home',repo_name=c.repo_name,revision=c.commit.raw_id,diff='download')}" class="tooltip" title="${h.tooltip(_('Download diff'))}">
127 <a href="${h.url('changeset_download_home',repo_name=c.repo_name,revision=c.commit.raw_id,diff='download')}" class="tooltip" title="${h.tooltip(_('Download diff'))}">
128 ${_('Download Diff')}
128 ${_('Download Diff')}
129 </a>
129 </a>
130 |
130 |
131 ${c.ignorews_url(request.GET)}
131 ${c.ignorews_url(request.GET)}
132 |
132 |
133 ${c.context_url(request.GET)}
133 ${c.context_url(request.GET)}
134 </div>
134 </div>
135 </div>
135 </div>
136 </div>
136 </div>
137
137
138 <div class="fieldset">
138 <div class="fieldset">
139 <div class="left-label">
139 <div class="left-label">
140 ${_('Comments')}:
140 ${_('Comments')}:
141 </div>
141 </div>
142 <div class="right-content">
142 <div class="right-content">
143 <div class="comments-number">
143 <div class="comments-number">
144 %if c.comments:
144 %if c.comments:
145 <a href="#comments">${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}</a>,
145 <a href="#comments">${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}</a>,
146 %else:
146 %else:
147 ${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}
147 ${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}
148 %endif
148 %endif
149 %if c.inline_cnt:
149 %if c.inline_cnt:
150 ## this is replaced with a proper link to first comment via JS linkifyComments() func
150 ## this is replaced with a proper link to first comment via JS linkifyComments() func
151 <a href="#inline-comments" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a>
151 <a href="#inline-comments" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a>
152 %else:
152 %else:
153 ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}
153 ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}
154 %endif
154 %endif
155 </div>
155 </div>
156 </div>
156 </div>
157 </div>
157 </div>
158
158
159 </div> <!-- end summary-detail -->
159 </div> <!-- end summary-detail -->
160
160
161 <div id="commit-stats" class="sidebar-right">
161 <div id="commit-stats" class="sidebar-right">
162 <div class="summary-detail-header">
162 <div class="summary-detail-header">
163 <h4 class="item">
163 <h4 class="item">
164 ${_('Author')}
164 ${_('Author')}
165 </h4>
165 </h4>
166 </div>
166 </div>
167 <div class="sidebar-right-content">
167 <div class="sidebar-right-content">
168 ${self.gravatar_with_user(c.commit.author)}
168 ${self.gravatar_with_user(c.commit.author)}
169 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
169 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
170 </div>
170 </div>
171 </div><!-- end sidebar -->
171 </div><!-- end sidebar -->
172 </div> <!-- end summary -->
172 </div> <!-- end summary -->
173 <div class="cs_files_title">
173 <div class="cs_files_title">
174 <span class="cs_files_expand">
174 <span class="cs_files_expand">
175 <span id="files_link"><a href="#" title="${_('Browse files at current commit')}">${_('Browse files')}</a></span> |
175 <span id="files_link"><a href="#" title="${_('Browse files at current commit')}">${_('Browse files')}</a></span> |
176
176
177 <span id="expand_all_files">${_('Expand All')}</span> | <span id="collapse_all_files">${_('Collapse All')}</span>
177 <span id="expand_all_files">${_('Expand All')}</span> | <span id="collapse_all_files">${_('Collapse All')}</span>
178 </span>
178 </span>
179 <h2>
179 <h2>
180 ${diff_block.diff_summary_text(len(c.files), c.lines_added, c.lines_deleted, c.limited_diff)}
180 ${diff_block.diff_summary_text(len(c.files), c.lines_added, c.lines_deleted, c.limited_diff)}
181 </h2>
181 </h2>
182 </div>
182 </div>
183 </div>
183 </div>
184
184
185 <div class="cs_files">
185 <div class="cs_files">
186
186
187 %if not c.files:
187 %if not c.files:
188 <p class="empty_data">${_('No files')}</p>
188 <p class="empty_data">${_('No files')}</p>
189 %endif
189 %endif
190
190
191 <table class="compare_view_files commit_diff">
191 <table class="compare_view_files commit_diff">
192 %for FID, (cs1, cs2, change, path, diff, stats, file) in c.changes[c.commit.raw_id].iteritems():
192 %for FID, (cs1, cs2, change, path, diff, stats, file) in c.changes[c.commit.raw_id].iteritems():
193 <tr class="cs_${change} collapse_file" fid="${FID}">
193 <tr class="cs_${change} collapse_file" fid="${FID}">
194 <td class="cs_icon_td">
194 <td class="cs_icon_td">
195 <span class="collapse_file_icon" fid="${FID}"></span>
195 <span class="collapse_file_icon" fid="${FID}"></span>
196 </td>
196 </td>
197 <td class="cs_icon_td">
197 <td class="cs_icon_td">
198 <div class="flag_status not_reviewed hidden"></div>
198 <div class="flag_status not_reviewed hidden"></div>
199 </td>
199 </td>
200 <td class="cs_${change}" id="a_${FID}">
200 <td class="cs_${change}" id="a_${FID}">
201 <div class="node">
201 <div class="node">
202 <a href="#a_${FID}">
202 <a href="#a_${FID}">
203 <i class="icon-file-${change.lower()}"></i>
203 <i class="icon-file-${change.lower()}"></i>
204 ${h.safe_unicode(path)}
204 ${h.safe_unicode(path)}
205 </a>
205 </a>
206 </div>
206 </div>
207 </td>
207 </td>
208 <td>
208 <td>
209 <div class="changes pull-right">${h.fancy_file_stats(stats)}</div>
209 <div class="changes pull-right">${h.fancy_file_stats(stats)}</div>
210 <div class="comment-bubble pull-right" data-path="${path}">
210 <div class="comment-bubble pull-right" data-path="${path}">
211 <i class="icon-comment"></i>
211 <i class="icon-comment"></i>
212 </div>
212 </div>
213 </td>
213 </td>
214 </tr>
214 </tr>
215 <tr fid="${FID}" id="diff_${FID}" class="diff_links">
215 <tr fid="${FID}" id="diff_${FID}" class="diff_links">
216 <td></td>
216 <td></td>
217 <td></td>
217 <td></td>
218 <td class="cs_${change}">
218 <td class="cs_${change}">
219 ${diff_block.diff_menu(c.repo_name, h.safe_unicode(path), cs1, cs2, change, file)}
219 ${diff_block.diff_menu(c.repo_name, h.safe_unicode(path), cs1, cs2, change, file)}
220 </td>
220 </td>
221 <td class="td-actions rc-form">
221 <td class="td-actions rc-form">
222 ${c.ignorews_url(request.GET, h.FID(cs2,path))} |
222 ${c.ignorews_url(request.GET, h.FID(cs2,path))} |
223 ${c.context_url(request.GET, h.FID(cs2,path))} |
223 ${c.context_url(request.GET, h.FID(cs2,path))} |
224 <div data-comment-id="${h.FID(cs2,path)}" class="btn-link show-inline-comments comments-visible">
224 <div data-comment-id="${h.FID(cs2,path)}" class="btn-link show-inline-comments comments-visible">
225 <span class="comments-show">${_('Show comments')}</span>
225 <span class="comments-show">${_('Show comments')}</span>
226 <span class="comments-hide">${_('Hide comments')}</span>
226 <span class="comments-hide">${_('Hide comments')}</span>
227 </div>
227 </div>
228 </td>
228 </td>
229 </tr>
229 </tr>
230 <tr id="tr_${FID}">
230 <tr id="tr_${FID}">
231 <td></td>
231 <td></td>
232 <td></td>
232 <td></td>
233 <td class="injected_diff" colspan="2">
233 <td class="injected_diff" colspan="2">
234 <div class="diff-container" id="${'diff-container-%s' % (id(change))}">
234 <div class="diff-container" id="${'diff-container-%s' % (id(change))}">
235 <div id="${FID}" class="diffblock margined comm">
235 <div id="${FID}" class="diffblock margined comm">
236 <div class="code-body">
236 <div class="code-body">
237 <div class="full_f_path" path="${h.safe_unicode(path)}"></div>
237 <div class="full_f_path" path="${h.safe_unicode(path)}"></div>
238 ${diff|n}
238 ${diff|n}
239 % if file and file["is_limited_diff"]:
239 % if file and file["is_limited_diff"]:
240 % if file["exceeds_limit"]:
240 % if file["exceeds_limit"]:
241 ${diff_block.file_message()}
241 ${diff_block.file_message()}
242 % else:
242 % else:
243 <h5>${_('Diff was truncated. File content available only in full diff.')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a></h5>
243 <h5>${_('Diff was truncated. File content available only in full diff.')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a></h5>
244 % endif
244 % endif
245 % endif
245 % endif
246 </div>
246 </div>
247 </div>
247 </div>
248 </div>
248 </div>
249 </td>
249 </td>
250 </tr>
250 </tr>
251 %endfor
251 %endfor
252 </table>
252 </table>
253 </div>
253 </div>
254
254
255 % if c.limited_diff:
255 % if c.limited_diff:
256 ${diff_block.changeset_message()}
256 ${diff_block.changeset_message()}
257 % endif
257 % endif
258
258
259 ## template for inline comment form
259 ## template for inline comment form
260 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
260 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
261 ${comment.comment_inline_form()}
261 ${comment.comment_inline_form()}
262
262
263 ## render comments and inlines
263 ## render comments and inlines
264 ${comment.generate_comments()}
264 ${comment.generate_comments()}
265
265
266 ## main comment form and it status
266 ## main comment form and it status
267 ${comment.comments(h.url('changeset_comment', repo_name=c.repo_name, revision=c.commit.raw_id),
267 ${comment.comments(h.url('changeset_comment', repo_name=c.repo_name, revision=c.commit.raw_id),
268 h.commit_status(c.rhodecode_db_repo, c.commit.raw_id))}
268 h.commit_status(c.rhodecode_db_repo, c.commit.raw_id))}
269
269
270 ## FORM FOR MAKING JS ACTION AS CHANGESET COMMENTS
270 ## FORM FOR MAKING JS ACTION AS CHANGESET COMMENTS
271 <script type="text/javascript">
271 <script type="text/javascript">
272
272
273 $(document).ready(function() {
273 $(document).ready(function() {
274
274
275 var boxmax = parseInt($('#trimmed_message_box').css('max-height'), 10);
275 var boxmax = parseInt($('#trimmed_message_box').css('max-height'), 10);
276 if($('#trimmed_message_box').height() === boxmax){
276 if($('#trimmed_message_box').height() === boxmax){
277 $('#message_expand').show();
277 $('#message_expand').show();
278 }
278 }
279
279
280 $('#message_expand').on('click', function(e){
280 $('#message_expand').on('click', function(e){
281 $('#trimmed_message_box').css('max-height', 'none');
281 $('#trimmed_message_box').css('max-height', 'none');
282 $(this).hide();
282 $(this).hide();
283 });
283 });
284
284
285 $('.show-inline-comments').on('click', function(e){
285 $('.show-inline-comments').on('click', function(e){
286 var boxid = $(this).attr('data-comment-id');
286 var boxid = $(this).attr('data-comment-id');
287 var button = $(this);
287 var button = $(this);
288
288
289 if(button.hasClass("comments-visible")) {
289 if(button.hasClass("comments-visible")) {
290 $('#{0} .inline-comments'.format(boxid)).each(function(index){
290 $('#{0} .inline-comments'.format(boxid)).each(function(index){
291 $(this).hide();
291 $(this).hide();
292 })
292 })
293 button.removeClass("comments-visible");
293 button.removeClass("comments-visible");
294 } else {
294 } else {
295 $('#{0} .inline-comments'.format(boxid)).each(function(index){
295 $('#{0} .inline-comments'.format(boxid)).each(function(index){
296 $(this).show();
296 $(this).show();
297 })
297 })
298 button.addClass("comments-visible");
298 button.addClass("comments-visible");
299 }
299 }
300 });
300 });
301
301
302
302
303 // next links
303 // next links
304 $('#child_link').on('click', function(e){
304 $('#child_link').on('click', function(e){
305 // fetch via ajax what is going to be the next link, if we have
305 // fetch via ajax what is going to be the next link, if we have
306 // >1 links show them to user to choose
306 // >1 links show them to user to choose
307 if(!$('#child_link').hasClass('disabled')){
307 if(!$('#child_link').hasClass('disabled')){
308 $.ajax({
308 $.ajax({
309 url: '${h.url('changeset_children',repo_name=c.repo_name, revision=c.commit.raw_id)}',
309 url: '${h.url('changeset_children',repo_name=c.repo_name, revision=c.commit.raw_id)}',
310 success: function(data) {
310 success: function(data) {
311 if(data.results.length === 0){
311 if(data.results.length === 0){
312 $('#child_link').html('${_('No Child Commits')}').addClass('disabled');
312 $('#child_link').html('${_('No Child Commits')}').addClass('disabled');
313 }
313 }
314 if(data.results.length === 1){
314 if(data.results.length === 1){
315 var commit = data.results[0];
315 var commit = data.results[0];
316 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
316 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
317 }
317 }
318 else if(data.results.length === 2){
318 else if(data.results.length === 2){
319 $('#child_link').addClass('disabled');
319 $('#child_link').addClass('disabled');
320 $('#child_link').addClass('double');
320 $('#child_link').addClass('double');
321 var _html = '';
321 var _html = '';
322 _html +='<a title="__title__" href="__url__">__rev__</a> '
322 _html +='<a title="__title__" href="__url__">__rev__</a> '
323 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
323 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
324 .replace('__title__', data.results[0].message)
324 .replace('__title__', data.results[0].message)
325 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
325 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
326 _html +=' | '
326 _html +=' | '
327 _html +='<a title="__title__" href="__url__">__rev__</a> '
327 _html +='<a title="__title__" href="__url__">__rev__</a> '
328 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
328 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
329 .replace('__title__', data.results[1].message)
329 .replace('__title__', data.results[1].message)
330 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
330 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
331 $('#child_link').html(_html);
331 $('#child_link').html(_html);
332 }
332 }
333 }
333 }
334 });
334 });
335 e.preventDefault();
335 e.preventDefault();
336 }
336 }
337 });
337 });
338
338
339 // prev links
339 // prev links
340 $('#parent_link').on('click', function(e){
340 $('#parent_link').on('click', function(e){
341 // fetch via ajax what is going to be the next link, if we have
341 // fetch via ajax what is going to be the next link, if we have
342 // >1 links show them to user to choose
342 // >1 links show them to user to choose
343 if(!$('#parent_link').hasClass('disabled')){
343 if(!$('#parent_link').hasClass('disabled')){
344 $.ajax({
344 $.ajax({
345 url: '${h.url('changeset_parents',repo_name=c.repo_name, revision=c.commit.raw_id)}',
345 url: '${h.url('changeset_parents',repo_name=c.repo_name, revision=c.commit.raw_id)}',
346 success: function(data) {
346 success: function(data) {
347 if(data.results.length === 0){
347 if(data.results.length === 0){
348 $('#parent_link').html('${_('No Parent Commits')}').addClass('disabled');
348 $('#parent_link').html('${_('No Parent Commits')}').addClass('disabled');
349 }
349 }
350 if(data.results.length === 1){
350 if(data.results.length === 1){
351 var commit = data.results[0];
351 var commit = data.results[0];
352 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
352 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
353 }
353 }
354 else if(data.results.length === 2){
354 else if(data.results.length === 2){
355 $('#parent_link').addClass('disabled');
355 $('#parent_link').addClass('disabled');
356 $('#parent_link').addClass('double');
356 $('#parent_link').addClass('double');
357 var _html = '';
357 var _html = '';
358 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
358 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
359 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
359 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
360 .replace('__title__', data.results[0].message)
360 .replace('__title__', data.results[0].message)
361 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
361 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
362 _html +=' | '
362 _html +=' | '
363 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
363 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
364 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
364 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
365 .replace('__title__', data.results[1].message)
365 .replace('__title__', data.results[1].message)
366 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
366 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
367 $('#parent_link').html(_html);
367 $('#parent_link').html(_html);
368 }
368 }
369 }
369 }
370 });
370 });
371 e.preventDefault();
371 e.preventDefault();
372 }
372 }
373 });
373 });
374
374
375 if (location.hash) {
375 if (location.hash) {
376 var result = splitDelimitedHash(location.hash);
376 var result = splitDelimitedHash(location.hash);
377 var line = $('html').find(result.loc);
377 var line = $('html').find(result.loc);
378 if (line.length > 0){
378 offsetScroll(line, 70);
379 offsetScroll(line, 70);
379 }
380 }
381 }
380
382
381 // browse tree @ revision
383 // browse tree @ revision
382 $('#files_link').on('click', function(e){
384 $('#files_link').on('click', function(e){
383 window.location = '${h.url('files_home',repo_name=c.repo_name, revision=c.commit.raw_id, f_path='')}';
385 window.location = '${h.url('files_home',repo_name=c.repo_name, revision=c.commit.raw_id, f_path='')}';
384 e.preventDefault();
386 e.preventDefault();
385 });
387 });
386
388
387 // inject comments into their proper positions
389 // inject comments into their proper positions
388 var file_comments = $('.inline-comment-placeholder');
390 var file_comments = $('.inline-comment-placeholder');
389 renderInlineComments(file_comments, true);
391 renderInlineComments(file_comments, true);
390 })
392 })
391 </script>
393 </script>
392
394
393 </%def>
395 </%def>
@@ -1,322 +1,324 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title(*args)">
3 <%def name="title(*args)">
4 ${_('%s Files') % c.repo_name}
4 ${_('%s Files') % c.repo_name}
5 %if hasattr(c,'file'):
5 %if hasattr(c,'file'):
6 &middot; ${h.safe_unicode(c.file.path) or '\\'}
6 &middot; ${h.safe_unicode(c.file.path) or '\\'}
7 %endif
7 %endif
8
8
9 %if c.rhodecode_name:
9 %if c.rhodecode_name:
10 &middot; ${h.branding(c.rhodecode_name)}
10 &middot; ${h.branding(c.rhodecode_name)}
11 %endif
11 %endif
12 </%def>
12 </%def>
13
13
14 <%def name="breadcrumbs_links()">
14 <%def name="breadcrumbs_links()">
15 ${_('Files')}
15 ${_('Files')}
16 %if c.file:
16 %if c.file:
17 @ ${h.show_id(c.commit)}
17 @ ${h.show_id(c.commit)}
18 %endif
18 %endif
19 </%def>
19 </%def>
20
20
21 <%def name="menu_bar_nav()">
21 <%def name="menu_bar_nav()">
22 ${self.menu_items(active='repositories')}
22 ${self.menu_items(active='repositories')}
23 </%def>
23 </%def>
24
24
25 <%def name="menu_bar_subnav()">
25 <%def name="menu_bar_subnav()">
26 ${self.repo_menu(active='files')}
26 ${self.repo_menu(active='files')}
27 </%def>
27 </%def>
28
28
29 <%def name="main()">
29 <%def name="main()">
30 <div class="title">
30 <div class="title">
31 ${self.repo_page_title(c.rhodecode_db_repo)}
31 ${self.repo_page_title(c.rhodecode_db_repo)}
32 </div>
32 </div>
33
33
34 <div id="pjax-container" class="summary">
34 <div id="pjax-container" class="summary">
35 <div id="files_data">
35 <div id="files_data">
36 <%include file='files_pjax.html'/>
36 <%include file='files_pjax.html'/>
37 </div>
37 </div>
38 </div>
38 </div>
39 <script>
39 <script>
40 var curState = {
40 var curState = {
41 commit_id: "${c.commit.raw_id}"
41 commit_id: "${c.commit.raw_id}"
42 };
42 };
43
43
44 var getState = function(context) {
44 var getState = function(context) {
45 var url = $(location).attr('href');
45 var url = $(location).attr('href');
46 var _base_url = '${h.url("files_home",repo_name=c.repo_name,revision='',f_path='')}';
46 var _base_url = '${h.url("files_home",repo_name=c.repo_name,revision='',f_path='')}';
47 var _annotate_url = '${h.url("files_annotate_home",repo_name=c.repo_name,revision='',f_path='')}';
47 var _annotate_url = '${h.url("files_annotate_home",repo_name=c.repo_name,revision='',f_path='')}';
48 _base_url = _base_url.replace('//', '/');
48 _base_url = _base_url.replace('//', '/');
49 _annotate_url = _annotate_url.replace('//', '/');
49 _annotate_url = _annotate_url.replace('//', '/');
50
50
51 //extract f_path from url.
51 //extract f_path from url.
52 var parts = url.split(_base_url);
52 var parts = url.split(_base_url);
53 if (parts.length != 2) {
53 if (parts.length != 2) {
54 parts = url.split(_annotate_url);
54 parts = url.split(_annotate_url);
55 if (parts.length != 2) {
55 if (parts.length != 2) {
56 var rev = "tip";
56 var rev = "tip";
57 var f_path = "";
57 var f_path = "";
58 } else {
58 } else {
59 var parts2 = parts[1].split('/');
59 var parts2 = parts[1].split('/');
60 var rev = parts2.shift(); // pop the first element which is the revision
60 var rev = parts2.shift(); // pop the first element which is the revision
61 var f_path = parts2.join('/');
61 var f_path = parts2.join('/');
62 }
62 }
63
63
64 } else {
64 } else {
65 var parts2 = parts[1].split('/');
65 var parts2 = parts[1].split('/');
66 var rev = parts2.shift(); // pop the first element which is the revision
66 var rev = parts2.shift(); // pop the first element which is the revision
67 var f_path = parts2.join('/');
67 var f_path = parts2.join('/');
68 }
68 }
69
69
70 var _node_list_url = pyroutes.url('files_nodelist_home',
70 var _node_list_url = pyroutes.url('files_nodelist_home',
71 {repo_name: templateContext.repo_name,
71 {repo_name: templateContext.repo_name,
72 revision: rev, f_path: f_path});
72 revision: rev, f_path: f_path});
73 var _url_base = pyroutes.url('files_home',
73 var _url_base = pyroutes.url('files_home',
74 {repo_name: templateContext.repo_name,
74 {repo_name: templateContext.repo_name,
75 revision: rev, f_path:'__FPATH__'});
75 revision: rev, f_path:'__FPATH__'});
76 return {
76 return {
77 url: url,
77 url: url,
78 f_path: f_path,
78 f_path: f_path,
79 rev: rev,
79 rev: rev,
80 commit_id: curState.commit_id,
80 commit_id: curState.commit_id,
81 node_list_url: _node_list_url,
81 node_list_url: _node_list_url,
82 url_base: _url_base
82 url_base: _url_base
83 };
83 };
84 };
84 };
85
85
86 var metadataRequest = null;
86 var metadataRequest = null;
87 var getFilesMetadata = function() {
87 var getFilesMetadata = function() {
88 if (metadataRequest && metadataRequest.readyState != 4) {
88 if (metadataRequest && metadataRequest.readyState != 4) {
89 metadataRequest.abort();
89 metadataRequest.abort();
90 }
90 }
91 if (source_page) {
91 if (source_page) {
92 return false;
92 return false;
93 }
93 }
94
94
95 if ($('#file-tree-wrapper').hasClass('full-load')) {
95 if ($('#file-tree-wrapper').hasClass('full-load')) {
96 // in case our HTML wrapper has full-load class we don't
96 // in case our HTML wrapper has full-load class we don't
97 // trigger the async load of metadata
97 // trigger the async load of metadata
98 return false;
98 return false;
99 }
99 }
100
100
101 var state = getState('metadata');
101 var state = getState('metadata');
102 var url_data = {
102 var url_data = {
103 'repo_name': templateContext.repo_name,
103 'repo_name': templateContext.repo_name,
104 'commit_id': state.commit_id,
104 'commit_id': state.commit_id,
105 'f_path': state.f_path
105 'f_path': state.f_path
106 };
106 };
107
107
108 var url = pyroutes.url('files_nodetree_full', url_data);
108 var url = pyroutes.url('files_nodetree_full', url_data);
109
109
110 metadataRequest = $.ajax({url: url});
110 metadataRequest = $.ajax({url: url});
111
111
112 metadataRequest.done(function(data) {
112 metadataRequest.done(function(data) {
113 $('#file-tree').html(data);
113 $('#file-tree').html(data);
114 timeagoActivate();
114 timeagoActivate();
115 });
115 });
116 metadataRequest.fail(function (data, textStatus, errorThrown) {
116 metadataRequest.fail(function (data, textStatus, errorThrown) {
117 console.log(data);
117 console.log(data);
118 if (data.status != 0) {
118 if (data.status != 0) {
119 alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText));
119 alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText));
120 }
120 }
121 });
121 });
122 };
122 };
123
123
124 var callbacks = function() {
124 var callbacks = function() {
125 var state = getState('callbacks');
125 var state = getState('callbacks');
126 timeagoActivate();
126 timeagoActivate();
127
127
128 // used for history, and switch to
128 // used for history, and switch to
129 var initialCommitData = {
129 var initialCommitData = {
130 id: null,
130 id: null,
131 text: '${_("Switch To Commit")}',
131 text: '${_("Switch To Commit")}',
132 type: 'sha',
132 type: 'sha',
133 raw_id: null,
133 raw_id: null,
134 files_url: null
134 files_url: null
135 };
135 };
136
136
137 if ($('#trimmed_message_box').height() < 50) {
137 if ($('#trimmed_message_box').height() < 50) {
138 $('#message_expand').hide();
138 $('#message_expand').hide();
139 }
139 }
140
140
141 $('#message_expand').on('click', function(e) {
141 $('#message_expand').on('click', function(e) {
142 $('#trimmed_message_box').css('max-height', 'none');
142 $('#trimmed_message_box').css('max-height', 'none');
143 $(this).hide();
143 $(this).hide();
144 });
144 });
145
145
146
146
147 if (source_page) {
147 if (source_page) {
148 // variants for with source code, not tree view
148 // variants for with source code, not tree view
149
149
150 if (location.href.indexOf('#') != -1) {
150 if (location.href.indexOf('#') != -1) {
151 page_highlights = location.href.substring(location.href.indexOf('#') + 1).split('L');
151 page_highlights = location.href.substring(location.href.indexOf('#') + 1).split('L');
152 if (page_highlights.length == 2) {
152 if (page_highlights.length == 2) {
153 highlight_ranges = page_highlights[1].split(",");
153 highlight_ranges = page_highlights[1].split(",");
154
154
155 var h_lines = [];
155 var h_lines = [];
156 for (pos in highlight_ranges) {
156 for (pos in highlight_ranges) {
157 var _range = highlight_ranges[pos].split('-');
157 var _range = highlight_ranges[pos].split('-');
158 if (_range.length == 2) {
158 if (_range.length == 2) {
159 var start = parseInt(_range[0]);
159 var start = parseInt(_range[0]);
160 var end = parseInt(_range[1]);
160 var end = parseInt(_range[1]);
161 if (start < end) {
161 if (start < end) {
162 for (var i = start; i <= end; i++) {
162 for (var i = start; i <= end; i++) {
163 h_lines.push(i);
163 h_lines.push(i);
164 }
164 }
165 }
165 }
166 }
166 }
167 else {
167 else {
168 h_lines.push(parseInt(highlight_ranges[pos]));
168 h_lines.push(parseInt(highlight_ranges[pos]));
169 }
169 }
170 }
170 }
171
171
172 for (pos in h_lines) {
172 for (pos in h_lines) {
173 // @comment-highlight-color
173 // @comment-highlight-color
174 $('#L' + h_lines[pos]).css('background-color', '#ffd887');
174 $('#L' + h_lines[pos]).css('background-color', '#ffd887');
175 }
175 }
176
176
177 var _first_line = $('#L' + h_lines[0]).get(0);
177 var _first_line = $('#L' + h_lines[0]).get(0);
178 if (_first_line) {
178 if (_first_line) {
179 var line = $('#L' + h_lines[0]);
179 var line = $('#L' + h_lines[0]);
180 if (line.length > 0){
180 offsetScroll(line, 70);
181 offsetScroll(line, 70);
181 }
182 }
182 }
183 }
183 }
184 }
185 }
184
186
185 // select code link event
187 // select code link event
186 $("#hlcode").mouseup(getSelectionLink);
188 $("#hlcode").mouseup(getSelectionLink);
187
189
188 // file history select2
190 // file history select2
189 select2FileHistorySwitcher('#diff1', initialCommitData, state);
191 select2FileHistorySwitcher('#diff1', initialCommitData, state);
190 $('#diff1').on('change', function(e) {
192 $('#diff1').on('change', function(e) {
191 $('#diff').removeClass('disabled').removeAttr("disabled");
193 $('#diff').removeClass('disabled').removeAttr("disabled");
192 $('#show_rev').removeClass('disabled').removeAttr("disabled");
194 $('#show_rev').removeClass('disabled').removeAttr("disabled");
193 });
195 });
194
196
195 // show more authors
197 // show more authors
196 $('#show_authors').on('click', function(e) {
198 $('#show_authors').on('click', function(e) {
197 e.preventDefault();
199 e.preventDefault();
198 var url = pyroutes.url('files_authors_home',
200 var url = pyroutes.url('files_authors_home',
199 {'repo_name': templateContext.repo_name,
201 {'repo_name': templateContext.repo_name,
200 'revision': state.rev, 'f_path': state.f_path});
202 'revision': state.rev, 'f_path': state.f_path});
201
203
202 $.pjax({
204 $.pjax({
203 url: url,
205 url: url,
204 data: 'annotate=${"1" if c.annotate else "0"}',
206 data: 'annotate=${"1" if c.annotate else "0"}',
205 container: '#file_authors',
207 container: '#file_authors',
206 push: false,
208 push: false,
207 timeout: pjaxTimeout
209 timeout: pjaxTimeout
208 }).complete(function(){
210 }).complete(function(){
209 $('#show_authors').hide();
211 $('#show_authors').hide();
210 })
212 })
211 });
213 });
212
214
213 // load file short history
215 // load file short history
214 $('#file_history_overview').on('click', function(e) {
216 $('#file_history_overview').on('click', function(e) {
215 e.preventDefault();
217 e.preventDefault();
216 path = state.f_path;
218 path = state.f_path;
217 if (path.indexOf("#") >= 0) {
219 if (path.indexOf("#") >= 0) {
218 path = path.slice(0, path.indexOf("#"));
220 path = path.slice(0, path.indexOf("#"));
219 }
221 }
220 var url = pyroutes.url('changelog_file_home',
222 var url = pyroutes.url('changelog_file_home',
221 {'repo_name': templateContext.repo_name,
223 {'repo_name': templateContext.repo_name,
222 'revision': state.rev, 'f_path': path, 'limit': 6});
224 'revision': state.rev, 'f_path': path, 'limit': 6});
223 $('#file_history_container').show();
225 $('#file_history_container').show();
224 $('#file_history_container').html('<div class="file-history-inner">{0}</div>'.format(_gettext('Loading ...')));
226 $('#file_history_container').html('<div class="file-history-inner">{0}</div>'.format(_gettext('Loading ...')));
225
227
226 $.pjax({
228 $.pjax({
227 url: url,
229 url: url,
228 container: '#file_history_container',
230 container: '#file_history_container',
229 push: false,
231 push: false,
230 timeout: pjaxTimeout
232 timeout: pjaxTimeout
231 })
233 })
232 });
234 });
233
235
234 }
236 }
235 else {
237 else {
236 getFilesMetadata();
238 getFilesMetadata();
237
239
238 // fuzzy file filter
240 // fuzzy file filter
239 fileBrowserListeners(state.node_list_url, state.url_base);
241 fileBrowserListeners(state.node_list_url, state.url_base);
240
242
241 // switch to widget
243 // switch to widget
242 select2RefSwitcher('#refs_filter', initialCommitData);
244 select2RefSwitcher('#refs_filter', initialCommitData);
243 $('#refs_filter').on('change', function(e) {
245 $('#refs_filter').on('change', function(e) {
244 var data = $('#refs_filter').select2('data');
246 var data = $('#refs_filter').select2('data');
245 curState.commit_id = data.raw_id;
247 curState.commit_id = data.raw_id;
246 $.pjax({url: data.files_url, container: '#pjax-container', timeout: pjaxTimeout});
248 $.pjax({url: data.files_url, container: '#pjax-container', timeout: pjaxTimeout});
247 });
249 });
248
250
249 $("#prev_commit_link").on('click', function(e) {
251 $("#prev_commit_link").on('click', function(e) {
250 var data = $(this).data();
252 var data = $(this).data();
251 curState.commit_id = data.commitId;
253 curState.commit_id = data.commitId;
252 });
254 });
253
255
254 $("#next_commit_link").on('click', function(e) {
256 $("#next_commit_link").on('click', function(e) {
255 var data = $(this).data();
257 var data = $(this).data();
256 curState.commit_id = data.commitId;
258 curState.commit_id = data.commitId;
257 });
259 });
258
260
259 $('#at_rev').on("keypress", function(e) {
261 $('#at_rev').on("keypress", function(e) {
260 /* ENTER PRESSED */
262 /* ENTER PRESSED */
261 if (e.keyCode === 13) {
263 if (e.keyCode === 13) {
262 var rev = $('#at_rev').val();
264 var rev = $('#at_rev').val();
263 // explicit reload page here. with pjax entering bad input
265 // explicit reload page here. with pjax entering bad input
264 // produces not so nice results
266 // produces not so nice results
265 window.location = pyroutes.url('files_home',
267 window.location = pyroutes.url('files_home',
266 {'repo_name': templateContext.repo_name,
268 {'repo_name': templateContext.repo_name,
267 'revision': rev, 'f_path': state.f_path});
269 'revision': rev, 'f_path': state.f_path});
268 }
270 }
269 });
271 });
270 }
272 }
271 };
273 };
272
274
273 var pjaxTimeout = 5000;
275 var pjaxTimeout = 5000;
274
276
275 $(document).pjax(".pjax-link", "#pjax-container", {
277 $(document).pjax(".pjax-link", "#pjax-container", {
276 "fragment": "#pjax-content",
278 "fragment": "#pjax-content",
277 "maxCacheLength": 1000,
279 "maxCacheLength": 1000,
278 "timeout": pjaxTimeout
280 "timeout": pjaxTimeout
279 });
281 });
280
282
281 // define global back/forward states
283 // define global back/forward states
282 var isPjaxPopState = false;
284 var isPjaxPopState = false;
283 $(document).on('pjax:popstate', function() {
285 $(document).on('pjax:popstate', function() {
284 isPjaxPopState = true;
286 isPjaxPopState = true;
285 });
287 });
286
288
287 $(document).on('pjax:end', function(xhr, options) {
289 $(document).on('pjax:end', function(xhr, options) {
288 if (isPjaxPopState) {
290 if (isPjaxPopState) {
289 isPjaxPopState = false;
291 isPjaxPopState = false;
290 callbacks();
292 callbacks();
291 _NODEFILTER.resetFilter();
293 _NODEFILTER.resetFilter();
292 }
294 }
293
295
294 // run callback for tracking if defined for google analytics etc.
296 // run callback for tracking if defined for google analytics etc.
295 // this is used to trigger tracking on pjax
297 // this is used to trigger tracking on pjax
296 if (typeof window.rhodecode_statechange_callback !== 'undefined') {
298 if (typeof window.rhodecode_statechange_callback !== 'undefined') {
297 var state = getState('statechange');
299 var state = getState('statechange');
298 rhodecode_statechange_callback(state.url, null)
300 rhodecode_statechange_callback(state.url, null)
299 }
301 }
300 });
302 });
301
303
302 $(document).on('pjax:success', function(event, xhr, options) {
304 $(document).on('pjax:success', function(event, xhr, options) {
303 if (event.target.id == "file_history_container") {
305 if (event.target.id == "file_history_container") {
304 $('#file_history_overview').hide();
306 $('#file_history_overview').hide();
305 $('#file_history_overview_full').show();
307 $('#file_history_overview_full').show();
306 timeagoActivate();
308 timeagoActivate();
307 } else {
309 } else {
308 callbacks();
310 callbacks();
309 }
311 }
310 });
312 });
311
313
312 $(document).ready(function() {
314 $(document).ready(function() {
313 callbacks();
315 callbacks();
314 var search_GET = "${request.GET.get('search','')}";
316 var search_GET = "${request.GET.get('search','')}";
315 if (search_GET == "1") {
317 if (search_GET == "1") {
316 _NODEFILTER.initFilter();
318 _NODEFILTER.initFilter();
317 }
319 }
318 });
320 });
319
321
320 </script>
322 </script>
321
323
322 </%def>
324 </%def>
@@ -1,589 +1,591 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)}
4 ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)}
5 %if c.rhodecode_name:
5 %if c.rhodecode_name:
6 &middot; ${h.branding(c.rhodecode_name)}
6 &middot; ${h.branding(c.rhodecode_name)}
7 %endif
7 %endif
8 </%def>
8 </%def>
9
9
10 <%def name="breadcrumbs_links()">
10 <%def name="breadcrumbs_links()">
11 <span id="pr-title">
11 <span id="pr-title">
12 ${c.pull_request.title}
12 ${c.pull_request.title}
13 %if c.pull_request.is_closed():
13 %if c.pull_request.is_closed():
14 (${_('Closed')})
14 (${_('Closed')})
15 %endif
15 %endif
16 </span>
16 </span>
17 <div id="pr-title-edit" class="input" style="display: none;">
17 <div id="pr-title-edit" class="input" style="display: none;">
18 ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)}
18 ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)}
19 </div>
19 </div>
20 </%def>
20 </%def>
21
21
22 <%def name="menu_bar_nav()">
22 <%def name="menu_bar_nav()">
23 ${self.menu_items(active='repositories')}
23 ${self.menu_items(active='repositories')}
24 </%def>
24 </%def>
25
25
26 <%def name="menu_bar_subnav()">
26 <%def name="menu_bar_subnav()">
27 ${self.repo_menu(active='showpullrequest')}
27 ${self.repo_menu(active='showpullrequest')}
28 </%def>
28 </%def>
29
29
30 <%def name="main()">
30 <%def name="main()">
31 <script type="text/javascript">
31 <script type="text/javascript">
32 // TODO: marcink switch this to pyroutes
32 // TODO: marcink switch this to pyroutes
33 AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
33 AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
34 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
34 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
35 </script>
35 </script>
36 <div class="box">
36 <div class="box">
37 <div class="title">
37 <div class="title">
38 ${self.repo_page_title(c.rhodecode_db_repo)}
38 ${self.repo_page_title(c.rhodecode_db_repo)}
39 </div>
39 </div>
40
40
41 ${self.breadcrumbs()}
41 ${self.breadcrumbs()}
42
42
43
43
44 <div class="box pr-summary">
44 <div class="box pr-summary">
45 <div class="summary-details block-left">
45 <div class="summary-details block-left">
46 <%summary = lambda n:{False:'summary-short'}.get(n)%>
46 <%summary = lambda n:{False:'summary-short'}.get(n)%>
47 <div class="pr-details-title">
47 <div class="pr-details-title">
48 ${_('Pull request #%s') % c.pull_request.pull_request_id} ${_('From')} ${h.format_date(c.pull_request.created_on)}
48 ${_('Pull request #%s') % c.pull_request.pull_request_id} ${_('From')} ${h.format_date(c.pull_request.created_on)}
49 %if c.allowed_to_update:
49 %if c.allowed_to_update:
50 <span id="open_edit_pullrequest" class="block-right action_button">${_('Edit')}</span>
50 <span id="open_edit_pullrequest" class="block-right action_button">${_('Edit')}</span>
51 <span id="close_edit_pullrequest" class="block-right action_button" style="display: none;">${_('Close')}</span>
51 <span id="close_edit_pullrequest" class="block-right action_button" style="display: none;">${_('Close')}</span>
52 %endif
52 %endif
53 </div>
53 </div>
54
54
55 <div id="summary" class="fields pr-details-content">
55 <div id="summary" class="fields pr-details-content">
56 <div class="field">
56 <div class="field">
57 <div class="label-summary">
57 <div class="label-summary">
58 <label>${_('Origin')}:</label>
58 <label>${_('Origin')}:</label>
59 </div>
59 </div>
60 <div class="input">
60 <div class="input">
61 <div class="pr-origininfo">
61 <div class="pr-origininfo">
62 ## branch link is only valid if it is a branch
62 ## branch link is only valid if it is a branch
63 <span class="tag">
63 <span class="tag">
64 %if c.pull_request.source_ref_parts.type == 'branch':
64 %if c.pull_request.source_ref_parts.type == 'branch':
65 <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
65 <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
66 %else:
66 %else:
67 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
67 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
68 %endif
68 %endif
69 </span>
69 </span>
70 <span class="clone-url">
70 <span class="clone-url">
71 <a href="${h.url('summary_home', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
71 <a href="${h.url('summary_home', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
72 </span>
72 </span>
73 </div>
73 </div>
74 <div class="pr-pullinfo">
74 <div class="pr-pullinfo">
75 %if h.is_hg(c.pull_request.source_repo):
75 %if h.is_hg(c.pull_request.source_repo):
76 <input type="text" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly">
76 <input type="text" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly">
77 %elif h.is_git(c.pull_request.source_repo):
77 %elif h.is_git(c.pull_request.source_repo):
78 <input type="text" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly">
78 <input type="text" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly">
79 %endif
79 %endif
80 </div>
80 </div>
81 </div>
81 </div>
82 </div>
82 </div>
83 <div class="field">
83 <div class="field">
84 <div class="label-summary">
84 <div class="label-summary">
85 <label>${_('Target')}:</label>
85 <label>${_('Target')}:</label>
86 </div>
86 </div>
87 <div class="input">
87 <div class="input">
88 <div class="pr-targetinfo">
88 <div class="pr-targetinfo">
89 ## branch link is only valid if it is a branch
89 ## branch link is only valid if it is a branch
90 <span class="tag">
90 <span class="tag">
91 %if c.pull_request.target_ref_parts.type == 'branch':
91 %if c.pull_request.target_ref_parts.type == 'branch':
92 <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
92 <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
93 %else:
93 %else:
94 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
94 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
95 %endif
95 %endif
96 </span>
96 </span>
97 <span class="clone-url">
97 <span class="clone-url">
98 <a href="${h.url('summary_home', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
98 <a href="${h.url('summary_home', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
99 </span>
99 </span>
100 </div>
100 </div>
101 </div>
101 </div>
102 </div>
102 </div>
103 <div class="field">
103 <div class="field">
104 <div class="label-summary">
104 <div class="label-summary">
105 <label>${_('Review')}:</label>
105 <label>${_('Review')}:</label>
106 </div>
106 </div>
107 <div class="input">
107 <div class="input">
108 %if c.pull_request_review_status:
108 %if c.pull_request_review_status:
109 <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div>
109 <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div>
110 <span class="changeset-status-lbl tooltip">
110 <span class="changeset-status-lbl tooltip">
111 %if c.pull_request.is_closed():
111 %if c.pull_request.is_closed():
112 ${_('Closed')},
112 ${_('Closed')},
113 %endif
113 %endif
114 ${h.commit_status_lbl(c.pull_request_review_status)}
114 ${h.commit_status_lbl(c.pull_request_review_status)}
115 </span>
115 </span>
116 - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)}
116 - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)}
117 %endif
117 %endif
118 </div>
118 </div>
119 </div>
119 </div>
120 <div class="field">
120 <div class="field">
121 <div class="pr-description-label label-summary">
121 <div class="pr-description-label label-summary">
122 <label>${_('Description')}:</label>
122 <label>${_('Description')}:</label>
123 </div>
123 </div>
124 <div id="pr-desc" class="input">
124 <div id="pr-desc" class="input">
125 <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div>
125 <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div>
126 </div>
126 </div>
127 <div id="pr-desc-edit" class="input textarea editor" style="display: none;">
127 <div id="pr-desc-edit" class="input textarea editor" style="display: none;">
128 <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea>
128 <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea>
129 </div>
129 </div>
130 </div>
130 </div>
131 <div class="field">
131 <div class="field">
132 <div class="label-summary">
132 <div class="label-summary">
133 <label>${_('Comments')}:</label>
133 <label>${_('Comments')}:</label>
134 </div>
134 </div>
135 <div class="input">
135 <div class="input">
136 <div>
136 <div>
137 <div class="comments-number">
137 <div class="comments-number">
138 %if c.comments:
138 %if c.comments:
139 <a href="#comments">${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)}</a>,
139 <a href="#comments">${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)}</a>,
140 %else:
140 %else:
141 ${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)}
141 ${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)}
142 %endif
142 %endif
143 %if c.inline_cnt:
143 %if c.inline_cnt:
144 ## this is replaced with a proper link to first comment via JS linkifyComments() func
144 ## this is replaced with a proper link to first comment via JS linkifyComments() func
145 <a href="#inline-comments" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a>
145 <a href="#inline-comments" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a>
146 %else:
146 %else:
147 ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}
147 ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}
148 %endif
148 %endif
149
149
150 % if c.outdated_cnt:
150 % if c.outdated_cnt:
151 ,${ungettext("%d Outdated Comment", "%d Outdated Comments", c.outdated_cnt) % c.outdated_cnt} <span id="show-outdated-comments" class="btn btn-link">${_('(Show)')}</span>
151 ,${ungettext("%d Outdated Comment", "%d Outdated Comments", c.outdated_cnt) % c.outdated_cnt} <span id="show-outdated-comments" class="btn btn-link">${_('(Show)')}</span>
152 % endif
152 % endif
153 </div>
153 </div>
154 </div>
154 </div>
155 </div>
155 </div>
156 </div>
156 </div>
157 <div id="pr-save" class="field" style="display: none;">
157 <div id="pr-save" class="field" style="display: none;">
158 <div class="label-summary"></div>
158 <div class="label-summary"></div>
159 <div class="input">
159 <div class="input">
160 <span id="edit_pull_request" class="btn btn-small">${_('Save Changes')}</span>
160 <span id="edit_pull_request" class="btn btn-small">${_('Save Changes')}</span>
161 </div>
161 </div>
162 </div>
162 </div>
163 </div>
163 </div>
164 </div>
164 </div>
165 <div>
165 <div>
166 ## AUTHOR
166 ## AUTHOR
167 <div class="reviewers-title block-right">
167 <div class="reviewers-title block-right">
168 <div class="pr-details-title">
168 <div class="pr-details-title">
169 ${_('Author')}
169 ${_('Author')}
170 </div>
170 </div>
171 </div>
171 </div>
172 <div class="block-right pr-details-content reviewers">
172 <div class="block-right pr-details-content reviewers">
173 <ul class="group_members">
173 <ul class="group_members">
174 <li>
174 <li>
175 ${self.gravatar_with_user(c.pull_request.author.email, 16)}
175 ${self.gravatar_with_user(c.pull_request.author.email, 16)}
176 </li>
176 </li>
177 </ul>
177 </ul>
178 </div>
178 </div>
179 ## REVIEWERS
179 ## REVIEWERS
180 <div class="reviewers-title block-right">
180 <div class="reviewers-title block-right">
181 <div class="pr-details-title">
181 <div class="pr-details-title">
182 ${_('Pull request reviewers')}
182 ${_('Pull request reviewers')}
183 %if c.allowed_to_update:
183 %if c.allowed_to_update:
184 <span id="open_edit_reviewers" class="block-right action_button">${_('Edit')}</span>
184 <span id="open_edit_reviewers" class="block-right action_button">${_('Edit')}</span>
185 <span id="close_edit_reviewers" class="block-right action_button" style="display: none;">${_('Close')}</span>
185 <span id="close_edit_reviewers" class="block-right action_button" style="display: none;">${_('Close')}</span>
186 %endif
186 %endif
187 </div>
187 </div>
188 </div>
188 </div>
189 <div id="reviewers" class="block-right pr-details-content reviewers">
189 <div id="reviewers" class="block-right pr-details-content reviewers">
190 ## members goes here !
190 ## members goes here !
191 <ul id="review_members" class="group_members">
191 <ul id="review_members" class="group_members">
192 %for member,status in c.pull_request_reviewers:
192 %for member,status in c.pull_request_reviewers:
193 <li id="reviewer_${member.user_id}">
193 <li id="reviewer_${member.user_id}">
194 <div class="reviewers_member">
194 <div class="reviewers_member">
195 <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
195 <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
196 <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div>
196 <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div>
197 </div>
197 </div>
198 <div id="reviewer_${member.user_id}_name" class="reviewer_name">
198 <div id="reviewer_${member.user_id}_name" class="reviewer_name">
199 ${self.gravatar_with_user(member.email, 16)} <div class="reviewer">(${_('owner') if c.pull_request.user_id == member.user_id else _('reviewer')})</div>
199 ${self.gravatar_with_user(member.email, 16)} <div class="reviewer">(${_('owner') if c.pull_request.user_id == member.user_id else _('reviewer')})</div>
200 </div>
200 </div>
201 <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="review_members" />
201 <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="review_members" />
202 %if c.allowed_to_update:
202 %if c.allowed_to_update:
203 <div class="reviewer_member_remove action_button" onclick="removeReviewMember(${member.user_id}, true)" style="visibility: hidden;">
203 <div class="reviewer_member_remove action_button" onclick="removeReviewMember(${member.user_id}, true)" style="visibility: hidden;">
204 <i class="icon-remove-sign" ></i>
204 <i class="icon-remove-sign" ></i>
205 </div>
205 </div>
206 %endif
206 %endif
207 </div>
207 </div>
208 </li>
208 </li>
209 %endfor
209 %endfor
210 </ul>
210 </ul>
211 %if not c.pull_request.is_closed():
211 %if not c.pull_request.is_closed():
212 <div id="add_reviewer_input" class='ac' style="display: none;">
212 <div id="add_reviewer_input" class='ac' style="display: none;">
213 %if c.allowed_to_update:
213 %if c.allowed_to_update:
214 <div class="reviewer_ac">
214 <div class="reviewer_ac">
215 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))}
215 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))}
216 <div id="reviewers_container"></div>
216 <div id="reviewers_container"></div>
217 </div>
217 </div>
218 <div>
218 <div>
219 <span id="update_pull_request" class="btn btn-small">${_('Save Changes')}</span>
219 <span id="update_pull_request" class="btn btn-small">${_('Save Changes')}</span>
220 </div>
220 </div>
221 %endif
221 %endif
222 </div>
222 </div>
223 %endif
223 %endif
224 </div>
224 </div>
225 </div>
225 </div>
226 </div>
226 </div>
227 <div class="box">
227 <div class="box">
228 ##DIFF
228 ##DIFF
229 <div class="table" >
229 <div class="table" >
230 <div id="changeset_compare_view_content">
230 <div id="changeset_compare_view_content">
231 ##CS
231 ##CS
232 % if c.missing_requirements:
232 % if c.missing_requirements:
233 <div class="box">
233 <div class="box">
234 <div class="alert alert-warning">
234 <div class="alert alert-warning">
235 <div>
235 <div>
236 <strong>${_('Missing requirements:')}</strong>
236 <strong>${_('Missing requirements:')}</strong>
237 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
237 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
238 </div>
238 </div>
239 </div>
239 </div>
240 </div>
240 </div>
241 % elif c.missing_commits:
241 % elif c.missing_commits:
242 <div class="box">
242 <div class="box">
243 <div class="alert alert-warning">
243 <div class="alert alert-warning">
244 <div>
244 <div>
245 <strong>${_('Missing commits')}:</strong>
245 <strong>${_('Missing commits')}:</strong>
246 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
246 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
247 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
247 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
248 </div>
248 </div>
249 </div>
249 </div>
250 </div>
250 </div>
251 % endif
251 % endif
252 <div class="compare_view_commits_title">
252 <div class="compare_view_commits_title">
253 % if c.allowed_to_update and not c.pull_request.is_closed():
253 % if c.allowed_to_update and not c.pull_request.is_closed():
254 <button id="update_commits" class="btn btn-small">${_('Update commits')}</button>
254 <button id="update_commits" class="btn btn-small">${_('Update commits')}</button>
255 % endif
255 % endif
256 % if len(c.commit_ranges):
256 % if len(c.commit_ranges):
257 <h2>${ungettext('Compare View: %s commit','Compare View: %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}</h2>
257 <h2>${ungettext('Compare View: %s commit','Compare View: %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}</h2>
258 % endif
258 % endif
259 </div>
259 </div>
260 % if not c.missing_commits:
260 % if not c.missing_commits:
261 <%include file="/compare/compare_commits.html" />
261 <%include file="/compare/compare_commits.html" />
262 ## FILES
262 ## FILES
263 <div class="cs_files_title">
263 <div class="cs_files_title">
264 <span class="cs_files_expand">
264 <span class="cs_files_expand">
265 <span id="expand_all_files">${_('Expand All')}</span> | <span id="collapse_all_files">${_('Collapse All')}</span>
265 <span id="expand_all_files">${_('Expand All')}</span> | <span id="collapse_all_files">${_('Collapse All')}</span>
266 </span>
266 </span>
267 <h2>
267 <h2>
268 ${diff_block.diff_summary_text(len(c.files), c.lines_added, c.lines_deleted, c.limited_diff)}
268 ${diff_block.diff_summary_text(len(c.files), c.lines_added, c.lines_deleted, c.limited_diff)}
269 </h2>
269 </h2>
270 </div>
270 </div>
271 % endif
271 % endif
272 <div class="cs_files">
272 <div class="cs_files">
273 %if not c.files and not c.missing_commits:
273 %if not c.files and not c.missing_commits:
274 <span class="empty_data">${_('No files')}</span>
274 <span class="empty_data">${_('No files')}</span>
275 %endif
275 %endif
276 <table class="compare_view_files">
276 <table class="compare_view_files">
277 <%namespace name="diff_block" file="/changeset/diff_block.html"/>
277 <%namespace name="diff_block" file="/changeset/diff_block.html"/>
278 %for FID, change, path, stats in c.files:
278 %for FID, change, path, stats in c.files:
279 <tr class="cs_${change} collapse_file" fid="${FID}">
279 <tr class="cs_${change} collapse_file" fid="${FID}">
280 <td class="cs_icon_td">
280 <td class="cs_icon_td">
281 <span class="collapse_file_icon" fid="${FID}"></span>
281 <span class="collapse_file_icon" fid="${FID}"></span>
282 </td>
282 </td>
283 <td class="cs_icon_td">
283 <td class="cs_icon_td">
284 <div class="flag_status not_reviewed hidden"></div>
284 <div class="flag_status not_reviewed hidden"></div>
285 </td>
285 </td>
286 <td class="cs_${change}" id="a_${FID}">
286 <td class="cs_${change}" id="a_${FID}">
287 <div class="node">
287 <div class="node">
288 <a href="#a_${FID}">
288 <a href="#a_${FID}">
289 <i class="icon-file-${change.lower()}"></i>
289 <i class="icon-file-${change.lower()}"></i>
290 ${h.safe_unicode(path)}
290 ${h.safe_unicode(path)}
291 </a>
291 </a>
292 </div>
292 </div>
293 </td>
293 </td>
294 <td>
294 <td>
295 <div class="changes pull-right">${h.fancy_file_stats(stats)}</div>
295 <div class="changes pull-right">${h.fancy_file_stats(stats)}</div>
296 <div class="comment-bubble pull-right" data-path="${path}">
296 <div class="comment-bubble pull-right" data-path="${path}">
297 <i class="icon-comment"></i>
297 <i class="icon-comment"></i>
298 </div>
298 </div>
299 </td>
299 </td>
300 </tr>
300 </tr>
301 <tr fid="${FID}" id="diff_${FID}" class="diff_links">
301 <tr fid="${FID}" id="diff_${FID}" class="diff_links">
302 <td></td>
302 <td></td>
303 <td></td>
303 <td></td>
304 <td class="cs_${change}">
304 <td class="cs_${change}">
305 %if c.target_repo.repo_name == c.repo_name:
305 %if c.target_repo.repo_name == c.repo_name:
306 ${diff_block.diff_menu(c.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)}
306 ${diff_block.diff_menu(c.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)}
307 %else:
307 %else:
308 ## this is slightly different case later, since the other repo can have this
308 ## this is slightly different case later, since the other repo can have this
309 ## file in other state than the origin repo
309 ## file in other state than the origin repo
310 ${diff_block.diff_menu(c.target_repo.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)}
310 ${diff_block.diff_menu(c.target_repo.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)}
311 %endif
311 %endif
312 </td>
312 </td>
313 <td class="td-actions rc-form">
313 <td class="td-actions rc-form">
314 <div data-comment-id="${FID}" class="btn-link show-inline-comments comments-visible">
314 <div data-comment-id="${FID}" class="btn-link show-inline-comments comments-visible">
315 <span class="comments-show">${_('Show comments')}</span>
315 <span class="comments-show">${_('Show comments')}</span>
316 <span class="comments-hide">${_('Hide comments')}</span>
316 <span class="comments-hide">${_('Hide comments')}</span>
317 </div>
317 </div>
318 </td>
318 </td>
319 </tr>
319 </tr>
320 <tr id="tr_${FID}">
320 <tr id="tr_${FID}">
321 <td></td>
321 <td></td>
322 <td></td>
322 <td></td>
323 <td class="injected_diff" colspan="2">
323 <td class="injected_diff" colspan="2">
324 ${diff_block.diff_block_simple([c.changes[FID]])}
324 ${diff_block.diff_block_simple([c.changes[FID]])}
325 </td>
325 </td>
326 </tr>
326 </tr>
327
327
328 ## Loop through inline comments
328 ## Loop through inline comments
329 % if c.outdated_comments.get(path,False):
329 % if c.outdated_comments.get(path,False):
330 <tr class="outdated">
330 <tr class="outdated">
331 <td></td>
331 <td></td>
332 <td></td>
332 <td></td>
333 <td colspan="2">
333 <td colspan="2">
334 <p>${_('Outdated Inline Comments')}:</p>
334 <p>${_('Outdated Inline Comments')}:</p>
335 </td>
335 </td>
336 </tr>
336 </tr>
337 <tr class="outdated">
337 <tr class="outdated">
338 <td></td>
338 <td></td>
339 <td></td>
339 <td></td>
340 <td colspan="2" class="outdated_comment_block">
340 <td colspan="2" class="outdated_comment_block">
341 % for line, comments in c.outdated_comments[path].iteritems():
341 % for line, comments in c.outdated_comments[path].iteritems():
342 <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
342 <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
343 % for co in comments:
343 % for co in comments:
344 ${comment.comment_block_outdated(co)}
344 ${comment.comment_block_outdated(co)}
345 % endfor
345 % endfor
346 </div>
346 </div>
347 % endfor
347 % endfor
348 </td>
348 </td>
349 </tr>
349 </tr>
350 % endif
350 % endif
351 %endfor
351 %endfor
352 ## Loop through inline comments for deleted files
352 ## Loop through inline comments for deleted files
353 %for path in c.deleted_files:
353 %for path in c.deleted_files:
354 <tr class="outdated deleted">
354 <tr class="outdated deleted">
355 <td></td>
355 <td></td>
356 <td></td>
356 <td></td>
357 <td>${path}</td>
357 <td>${path}</td>
358 </tr>
358 </tr>
359 <tr class="outdated deleted">
359 <tr class="outdated deleted">
360 <td></td>
360 <td></td>
361 <td></td>
361 <td></td>
362 <td>(${_('Removed')})</td>
362 <td>(${_('Removed')})</td>
363 </tr>
363 </tr>
364 % if path in c.outdated_comments:
364 % if path in c.outdated_comments:
365 <tr class="outdated deleted">
365 <tr class="outdated deleted">
366 <td></td>
366 <td></td>
367 <td></td>
367 <td></td>
368 <td colspan="2">
368 <td colspan="2">
369 <p>${_('Outdated Inline Comments')}:</p>
369 <p>${_('Outdated Inline Comments')}:</p>
370 </td>
370 </td>
371 </tr>
371 </tr>
372 <tr class="outdated">
372 <tr class="outdated">
373 <td></td>
373 <td></td>
374 <td></td>
374 <td></td>
375 <td colspan="2" class="outdated_comment_block">
375 <td colspan="2" class="outdated_comment_block">
376 % for line, comments in c.outdated_comments[path].iteritems():
376 % for line, comments in c.outdated_comments[path].iteritems():
377 <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
377 <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
378 % for co in comments:
378 % for co in comments:
379 ${comment.comment_block_outdated(co)}
379 ${comment.comment_block_outdated(co)}
380 % endfor
380 % endfor
381 </div>
381 </div>
382 % endfor
382 % endfor
383 </td>
383 </td>
384 </tr>
384 </tr>
385 % endif
385 % endif
386 %endfor
386 %endfor
387 </table>
387 </table>
388 </div>
388 </div>
389 % if c.limited_diff:
389 % if c.limited_diff:
390 <h5>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></h5>
390 <h5>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></h5>
391 % endif
391 % endif
392 </div>
392 </div>
393 </div>
393 </div>
394
394
395 % if c.limited_diff:
395 % if c.limited_diff:
396 <p>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></p>
396 <p>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></p>
397 % endif
397 % endif
398
398
399 ## template for inline comment form
399 ## template for inline comment form
400 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
400 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
401 ${comment.comment_inline_form()}
401 ${comment.comment_inline_form()}
402
402
403 ## render comments and inlines
403 ## render comments and inlines
404 ${comment.generate_comments(include_pull_request=True, is_pull_request=True)}
404 ${comment.generate_comments(include_pull_request=True, is_pull_request=True)}
405
405
406 % if not c.pull_request.is_closed():
406 % if not c.pull_request.is_closed():
407 ## main comment form and it status
407 ## main comment form and it status
408 ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name,
408 ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name,
409 pull_request_id=c.pull_request.pull_request_id),
409 pull_request_id=c.pull_request.pull_request_id),
410 c.pull_request_review_status,
410 c.pull_request_review_status,
411 is_pull_request=True, change_status=c.allowed_to_change_status)}
411 is_pull_request=True, change_status=c.allowed_to_change_status)}
412 %endif
412 %endif
413
413
414 <script type="text/javascript">
414 <script type="text/javascript">
415 if (location.hash) {
415 if (location.hash) {
416 var result = splitDelimitedHash(location.hash);
416 var result = splitDelimitedHash(location.hash);
417 var line = $('html').find(result.loc);
417 var line = $('html').find(result.loc);
418 if (line.length > 0){
418 offsetScroll(line, 70);
419 offsetScroll(line, 70);
419 }
420 }
421 }
420 $(function(){
422 $(function(){
421 ReviewerAutoComplete('user');
423 ReviewerAutoComplete('user');
422 // custom code mirror
424 // custom code mirror
423 var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input');
425 var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input');
424
426
425 var PRDetails = {
427 var PRDetails = {
426 editButton: $('#open_edit_pullrequest'),
428 editButton: $('#open_edit_pullrequest'),
427 closeButton: $('#close_edit_pullrequest'),
429 closeButton: $('#close_edit_pullrequest'),
428 viewFields: $('#pr-desc, #pr-title'),
430 viewFields: $('#pr-desc, #pr-title'),
429 editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'),
431 editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'),
430
432
431 init: function() {
433 init: function() {
432 var that = this;
434 var that = this;
433 this.editButton.on('click', function(e) { that.edit(); });
435 this.editButton.on('click', function(e) { that.edit(); });
434 this.closeButton.on('click', function(e) { that.view(); });
436 this.closeButton.on('click', function(e) { that.view(); });
435 },
437 },
436
438
437 edit: function(event) {
439 edit: function(event) {
438 this.viewFields.hide();
440 this.viewFields.hide();
439 this.editButton.hide();
441 this.editButton.hide();
440 this.editFields.show();
442 this.editFields.show();
441 codeMirrorInstance.refresh();
443 codeMirrorInstance.refresh();
442 },
444 },
443
445
444 view: function(event) {
446 view: function(event) {
445 this.editFields.hide();
447 this.editFields.hide();
446 this.closeButton.hide();
448 this.closeButton.hide();
447 this.viewFields.show();
449 this.viewFields.show();
448 }
450 }
449 };
451 };
450
452
451 var ReviewersPanel = {
453 var ReviewersPanel = {
452 editButton: $('#open_edit_reviewers'),
454 editButton: $('#open_edit_reviewers'),
453 closeButton: $('#close_edit_reviewers'),
455 closeButton: $('#close_edit_reviewers'),
454 addButton: $('#add_reviewer_input'),
456 addButton: $('#add_reviewer_input'),
455 removeButtons: $('.reviewer_member_remove'),
457 removeButtons: $('.reviewer_member_remove'),
456
458
457 init: function() {
459 init: function() {
458 var that = this;
460 var that = this;
459 this.editButton.on('click', function(e) { that.edit(); });
461 this.editButton.on('click', function(e) { that.edit(); });
460 this.closeButton.on('click', function(e) { that.close(); });
462 this.closeButton.on('click', function(e) { that.close(); });
461 },
463 },
462
464
463 edit: function(event) {
465 edit: function(event) {
464 this.editButton.hide();
466 this.editButton.hide();
465 this.closeButton.show();
467 this.closeButton.show();
466 this.addButton.show();
468 this.addButton.show();
467 this.removeButtons.css('visibility', 'visible');
469 this.removeButtons.css('visibility', 'visible');
468 },
470 },
469
471
470 close: function(event) {
472 close: function(event) {
471 this.editButton.show();
473 this.editButton.show();
472 this.closeButton.hide();
474 this.closeButton.hide();
473 this.addButton.hide();
475 this.addButton.hide();
474 this.removeButtons.css('visibility', 'hidden');
476 this.removeButtons.css('visibility', 'hidden');
475 }
477 }
476 };
478 };
477
479
478 PRDetails.init();
480 PRDetails.init();
479 ReviewersPanel.init();
481 ReviewersPanel.init();
480
482
481 $('#show-outdated-comments').on('click', function(e){
483 $('#show-outdated-comments').on('click', function(e){
482 var button = $(this);
484 var button = $(this);
483 var outdated = $('.outdated');
485 var outdated = $('.outdated');
484 if (button.html() === "(Show)") {
486 if (button.html() === "(Show)") {
485 button.html("(Hide)");
487 button.html("(Hide)");
486 outdated.show();
488 outdated.show();
487 } else {
489 } else {
488 button.html("(Show)");
490 button.html("(Show)");
489 outdated.hide();
491 outdated.hide();
490 }
492 }
491 });
493 });
492
494
493 $('.show-inline-comments').on('change', function(e){
495 $('.show-inline-comments').on('change', function(e){
494 var show = 'none';
496 var show = 'none';
495 var target = e.currentTarget;
497 var target = e.currentTarget;
496 if(target.checked){
498 if(target.checked){
497 show = ''
499 show = ''
498 }
500 }
499 var boxid = $(target).attr('id_for');
501 var boxid = $(target).attr('id_for');
500 var comments = $('#{0} .inline-comments'.format(boxid));
502 var comments = $('#{0} .inline-comments'.format(boxid));
501 var fn_display = function(idx){
503 var fn_display = function(idx){
502 $(this).css('display', show);
504 $(this).css('display', show);
503 };
505 };
504 $(comments).each(fn_display);
506 $(comments).each(fn_display);
505 var btns = $('#{0} .inline-comments-button'.format(boxid));
507 var btns = $('#{0} .inline-comments-button'.format(boxid));
506 $(btns).each(fn_display);
508 $(btns).each(fn_display);
507 });
509 });
508
510
509 // inject comments into their proper positions
511 // inject comments into their proper positions
510 var file_comments = $('.inline-comment-placeholder');
512 var file_comments = $('.inline-comment-placeholder');
511 %if c.pull_request.is_closed():
513 %if c.pull_request.is_closed():
512 renderInlineComments(file_comments, false);
514 renderInlineComments(file_comments, false);
513 %else:
515 %else:
514 renderInlineComments(file_comments, true);
516 renderInlineComments(file_comments, true);
515 %endif
517 %endif
516 var commentTotals = {};
518 var commentTotals = {};
517 $.each(file_comments, function(i, comment) {
519 $.each(file_comments, function(i, comment) {
518 var path = $(comment).attr('path');
520 var path = $(comment).attr('path');
519 var comms = $(comment).children().length;
521 var comms = $(comment).children().length;
520 if (path in commentTotals) {
522 if (path in commentTotals) {
521 commentTotals[path] += comms;
523 commentTotals[path] += comms;
522 } else {
524 } else {
523 commentTotals[path] = comms;
525 commentTotals[path] = comms;
524 }
526 }
525 });
527 });
526 $.each(commentTotals, function(path, total) {
528 $.each(commentTotals, function(path, total) {
527 var elem = $('.comment-bubble[data-path="'+ path +'"]');
529 var elem = $('.comment-bubble[data-path="'+ path +'"]');
528 elem.css('visibility', 'visible');
530 elem.css('visibility', 'visible');
529 elem.html(elem.html() + ' ' + total );
531 elem.html(elem.html() + ' ' + total );
530 });
532 });
531
533
532 $('#merge_pull_request_form').submit(function() {
534 $('#merge_pull_request_form').submit(function() {
533 if (!$('#merge_pull_request').attr('disabled')) {
535 if (!$('#merge_pull_request').attr('disabled')) {
534 $('#merge_pull_request').attr('disabled', 'disabled');
536 $('#merge_pull_request').attr('disabled', 'disabled');
535 }
537 }
536 return true;
538 return true;
537 });
539 });
538
540
539 $('#edit_pull_request').on('click', function(e){
541 $('#edit_pull_request').on('click', function(e){
540 var title = $('#pr-title-input').val();
542 var title = $('#pr-title-input').val();
541 var description = codeMirrorInstance.getValue();
543 var description = codeMirrorInstance.getValue();
542 editPullRequest(
544 editPullRequest(
543 "${c.repo_name}", "${c.pull_request.pull_request_id}",
545 "${c.repo_name}", "${c.pull_request.pull_request_id}",
544 title, description);
546 title, description);
545 });
547 });
546
548
547 $('#update_pull_request').on('click', function(e){
549 $('#update_pull_request').on('click', function(e){
548 updateReviewers(undefined, "${c.repo_name}", "${c.pull_request.pull_request_id}");
550 updateReviewers(undefined, "${c.repo_name}", "${c.pull_request.pull_request_id}");
549 });
551 });
550
552
551 $('#update_commits').on('click', function(e){
553 $('#update_commits').on('click', function(e){
552 var isDisabled = !$(e.currentTarget).attr('disabled');
554 var isDisabled = !$(e.currentTarget).attr('disabled');
553 $(e.currentTarget).text(_gettext('Updating...'));
555 $(e.currentTarget).text(_gettext('Updating...'));
554 $(e.currentTarget).attr('disabled', 'disabled');
556 $(e.currentTarget).attr('disabled', 'disabled');
555 if(isDisabled){
557 if(isDisabled){
556 updateCommits("${c.repo_name}", "${c.pull_request.pull_request_id}");
558 updateCommits("${c.repo_name}", "${c.pull_request.pull_request_id}");
557 }
559 }
558
560
559 });
561 });
560 // fixing issue with caches on firefox
562 // fixing issue with caches on firefox
561 $('#update_commits').removeAttr("disabled");
563 $('#update_commits').removeAttr("disabled");
562
564
563 $('#close_pull_request').on('click', function(e){
565 $('#close_pull_request').on('click', function(e){
564 closePullRequest("${c.repo_name}", "${c.pull_request.pull_request_id}");
566 closePullRequest("${c.repo_name}", "${c.pull_request.pull_request_id}");
565 });
567 });
566
568
567 $('.show-inline-comments').on('click', function(e){
569 $('.show-inline-comments').on('click', function(e){
568 var boxid = $(this).attr('data-comment-id');
570 var boxid = $(this).attr('data-comment-id');
569 var button = $(this);
571 var button = $(this);
570
572
571 if(button.hasClass("comments-visible")) {
573 if(button.hasClass("comments-visible")) {
572 $('#{0} .inline-comments'.format(boxid)).each(function(index){
574 $('#{0} .inline-comments'.format(boxid)).each(function(index){
573 $(this).hide();
575 $(this).hide();
574 })
576 })
575 button.removeClass("comments-visible");
577 button.removeClass("comments-visible");
576 } else {
578 } else {
577 $('#{0} .inline-comments'.format(boxid)).each(function(index){
579 $('#{0} .inline-comments'.format(boxid)).each(function(index){
578 $(this).show();
580 $(this).show();
579 })
581 })
580 button.addClass("comments-visible");
582 button.addClass("comments-visible");
581 }
583 }
582 });
584 });
583 })
585 })
584 </script>
586 </script>
585
587
586 </div>
588 </div>
587 </div>
589 </div>
588
590
589 </%def>
591 </%def>
General Comments 0
You need to be logged in to leave comments. Login now