##// END OF EJS Templates
comments: use unified aggregation of comments counters....
marcink -
r1332:f4e615fc default
parent child Browse files
Show More
@@ -807,50 +807,44 b' class PullrequestsController(BaseRepoCon'
807 807 c.approval_msg = _('Reviewer approval is pending.')
808 808 c.pr_merge_status = False
809 809
810 # inline comments
811 inline_comments = cc_model.get_inline_comments(
812 c.rhodecode_db_repo.repo_id, pull_request=pull_request_id)
813
814 _inline_cnt, c.inline_versions = cc_model.get_inline_comments_count(
815 inline_comments, version=at_version, include_aggregates=True)
816
817 810 c.versions = pull_request_display_obj.versions()
811 c.at_version = at_version
818 812 c.at_version_num = at_version if at_version and at_version != 'latest' else None
819 813 c.at_version_pos = ChangesetComment.get_index_from_version(
820 814 c.at_version_num, c.versions)
821 815
822 is_outdated = lambda co: \
823 not c.at_version_num \
824 or co.pull_request_version_id <= c.at_version_num
816 # GENERAL COMMENTS with versions #
817 q = cc_model._all_general_comments_of_pull_request(pull_request_latest)
818 general_comments = q.order_by(ChangesetComment.pull_request_version_id.asc())
825 819
826 # inline_comments_until_version
827 if c.at_version_num:
820 # pick comments we want to render at current version
821 c.comment_versions = cc_model.aggregate_comments(
822 general_comments, c.versions, c.at_version_num)
823 c.comments = c.comment_versions[c.at_version_num]['until']
824
825 # INLINE COMMENTS with versions #
826 q = cc_model._all_inline_comments_of_pull_request(pull_request_latest)
827 inline_comments = q.order_by(ChangesetComment.pull_request_version_id.asc())
828 c.inline_versions = cc_model.aggregate_comments(
829 inline_comments, c.versions, c.at_version_num, inline=True)
830
828 831 # if we use version, then do not show later comments
829 832 # than current version
830 833 paths = collections.defaultdict(lambda: collections.defaultdict(list))
831 for fname, per_line_comments in inline_comments.iteritems():
832 for lno, comments in per_line_comments.iteritems():
833 for co in comments:
834 if co.pull_request_version_id and is_outdated(co):
834 for co in inline_comments:
835 if c.at_version_num:
836 # pick comments that are at least UPTO given version, so we
837 # don't render comments for higher version
838 should_render = co.pull_request_version_id and \
839 co.pull_request_version_id <= c.at_version_num
840 else:
841 # showing all, for 'latest'
842 should_render = True
843
844 if should_render:
835 845 paths[co.f_path][co.line_no].append(co)
836 846 inline_comments = paths
837 847
838 # outdated comments
839 c.outdated_cnt = 0
840 if CommentsModel.use_outdated_comments(pull_request_latest):
841 outdated_comments = cc_model.get_outdated_comments(
842 c.rhodecode_db_repo.repo_id,
843 pull_request=pull_request_at_ver)
844
845 # Count outdated comments and check for deleted files
846 is_outdated = lambda co: \
847 not c.at_version_num \
848 or co.pull_request_version_id < c.at_version_num
849 for file_name, lines in outdated_comments.iteritems():
850 for comments in lines.values():
851 comments = [comm for comm in comments if is_outdated(comm)]
852 c.outdated_cnt += len(comments)
853
854 848 # load compare data into template context
855 849 self._load_compare_data(pull_request_at_ver, inline_comments)
856 850
@@ -860,10 +854,6 b' class PullrequestsController(BaseRepoCon'
860 854 # We need to swap that here to generate it properly on the html side
861 855 c.target_repo = c.source_repo
862 856
863 # general comments
864 c.comments = cc_model.get_comments(
865 c.rhodecode_db_repo.repo_id, pull_request=pull_request_id)
866
867 857 if c.allowed_to_update:
868 858 force_close = ('forced_closed', _('Close Pull Request'))
869 859 statuses = ChangesetStatus.STATUSES + [force_close]
@@ -874,7 +864,6 b' class PullrequestsController(BaseRepoCon'
874 864 c.ancestor = None # TODO: add ancestor here
875 865 c.pull_request = pull_request_display_obj
876 866 c.pull_request_latest = pull_request_latest
877 c.at_version = at_version
878 867
879 868 c.changes = None
880 869 c.file_changes = None
@@ -39,7 +39,7 b' from rhodecode.lib.utils import action_l'
39 39 from rhodecode.lib.utils2 import extract_mentioned_users
40 40 from rhodecode.model import BaseModel
41 41 from rhodecode.model.db import (
42 ChangesetComment, User, Notification, PullRequest)
42 ChangesetComment, User, Notification, PullRequest, AttributeDict)
43 43 from rhodecode.model.notification import NotificationModel
44 44 from rhodecode.model.meta import Session
45 45 from rhodecode.model.settings import VcsSettingsModel
@@ -83,6 +83,52 b' class CommentsModel(BaseModel):'
83 83 log.error(traceback.format_exc())
84 84 return global_renderer
85 85
86 def aggregate_comments(self, comments, versions, show_version, inline=False):
87 # group by versions, and count until, and display objects
88
89 comment_groups = collections.defaultdict(list)
90 [comment_groups[
91 _co.pull_request_version_id].append(_co) for _co in comments]
92
93 def yield_comments(pos):
94 for co in comment_groups[pos]:
95 yield co
96
97 comment_versions = collections.defaultdict(
98 lambda: collections.defaultdict(list))
99 prev_prvid = -1
100 # fake last entry with None, to aggregate on "latest" version which
101 # doesn't have an pull_request_version_id
102 for ver in versions + [AttributeDict({'pull_request_version_id': None})]:
103 prvid = ver.pull_request_version_id
104 if prev_prvid == -1:
105 prev_prvid = prvid
106
107 for co in yield_comments(prvid):
108 comment_versions[prvid]['at'].append(co)
109
110 # save until
111 current = comment_versions[prvid]['at']
112 prev_until = comment_versions[prev_prvid]['until']
113 cur_until = prev_until + current
114 comment_versions[prvid]['until'].extend(cur_until)
115
116 # save outdated
117 if inline:
118 outdated = [x for x in cur_until
119 if x.outdated_at_version(show_version)]
120 else:
121 outdated = [x for x in cur_until
122 if x.older_than_version(show_version)]
123 display = [x for x in cur_until if x not in outdated]
124
125 comment_versions[prvid]['outdated'] = outdated
126 comment_versions[prvid]['display'] = display
127
128 prev_prvid = prvid
129
130 return comment_versions
131
86 132 def create(self, text, repo, user, commit_id=None, pull_request=None,
87 133 f_path=None, line_no=None, status_change=None,
88 134 status_change_type=None, comment_type=None,
@@ -376,18 +422,14 b' class CommentsModel(BaseModel):'
376 422 return self._group_comments_by_path_and_line_number(q)
377 423
378 424 def get_inline_comments_count(self, inline_comments, skip_outdated=True,
379 version=None, include_aggregates=False):
380 version_aggregates = collections.defaultdict(list)
425 version=None):
381 426 inline_cnt = 0
382 427 for fname, per_line_comments in inline_comments.iteritems():
383 428 for lno, comments in per_line_comments.iteritems():
384 429 for comm in comments:
385 version_aggregates[comm.pull_request_version_id].append(comm)
386 430 if not comm.outdated_at_version(version) and skip_outdated:
387 431 inline_cnt += 1
388 432
389 if include_aggregates:
390 return inline_cnt, version_aggregates
391 433 return inline_cnt
392 434
393 435 def get_outdated_comments(self, repo_id, pull_request):
@@ -511,6 +553,13 b' class CommentsModel(BaseModel):'
511 553 .filter(ChangesetComment.pull_request == pull_request)
512 554 return comments
513 555
556 def _all_general_comments_of_pull_request(self, pull_request):
557 comments = Session().query(ChangesetComment)\
558 .filter(ChangesetComment.line_no == None)\
559 .filter(ChangesetComment.f_path == None)\
560 .filter(ChangesetComment.pull_request == pull_request)
561 return comments
562
514 563 @staticmethod
515 564 def use_outdated_comments(pull_request):
516 565 settings_model = VcsSettingsModel(repo=pull_request.target_repo)
@@ -2959,6 +2959,15 b' class ChangesetComment(Base, BaseModel):'
2959 2959 """
2960 2960 return self.outdated and self.pull_request_version_id != version
2961 2961
2962 def older_than_version(self, version):
2963 """
2964 Checks if comment is made from previous version than given
2965 """
2966 if version is None:
2967 return self.pull_request_version_id is not None
2968
2969 return self.pull_request_version_id < version
2970
2962 2971 @property
2963 2972 def resolved(self):
2964 2973 return self.resolved_by[0] if self.resolved_by else None
@@ -2973,9 +2982,9 b' class ChangesetComment(Base, BaseModel):'
2973 2982
2974 2983 def __repr__(self):
2975 2984 if self.comment_id:
2976 return '<DB:ChangesetComment #%s>' % self.comment_id
2985 return '<DB:Comment #%s>' % self.comment_id
2977 2986 else:
2978 return '<DB:ChangesetComment at %#x>' % id(self)
2987 return '<DB:Comment at %#x>' % id(self)
2979 2988
2980 2989
2981 2990 class ChangesetStatus(Base, BaseModel):
@@ -51,7 +51,7 b' tr.inline-comments div {'
51 51 float: left;
52 52
53 53 padding: 0.4em 0.4em;
54 margin: 2px 5px 0px -10px;
54 margin: 3px 5px 0px -10px;
55 55 display: inline-block;
56 56 min-height: 0;
57 57
@@ -180,7 +180,7 b''
180 180 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
181 181
182 182 ## render comments
183 ${comment.generate_comments()}
183 ${comment.generate_comments(c.comments)}
184 184
185 185 ## main comment form and it status
186 186 ${comment.comments(h.url('changeset_comment', repo_name=c.repo_name, revision=c.commit.raw_id),
@@ -6,8 +6,13 b''
6 6 <%namespace name="base" file="/base/base.mako"/>
7 7
8 8 <%def name="comment_block(comment, inline=False)">
9 <% outdated_at_ver = comment.outdated_at_version(getattr(c, 'at_version', None)) %>
10 9 <% pr_index_ver = comment.get_index_version(getattr(c, 'versions', [])) %>
10 % if inline:
11 <% outdated_at_ver = comment.outdated_at_version(getattr(c, 'at_version_num', None)) %>
12 % else:
13 <% outdated_at_ver = comment.older_than_version(getattr(c, 'at_version_num', None)) %>
14 % endif
15
11 16
12 17 <div class="comment
13 18 ${'comment-inline' if inline else 'comment-general'}
@@ -83,16 +88,19 b''
83 88 <div class="comment-links-block">
84 89
85 90 % if inline:
86 % if outdated_at_ver:
87 91 <div class="pr-version-inline">
88 92 <a href="${h.url.current(version=comment.pull_request_version_id, anchor='comment-{}'.format(comment.comment_id))}">
89 <code class="pr-version-num">
90 outdated ${'v{}'.format(pr_index_ver)}
93 % if outdated_at_ver:
94 <code class="pr-version-num" title="${_('Outdated comment from pull request version {0}').format(pr_index_ver)}">
95 outdated ${'v{}'.format(pr_index_ver)} |
91 96 </code>
97 % elif pr_index_ver:
98 <code class="pr-version-num" title="${_('Comment from pull request version {0}').format(pr_index_ver)}">
99 ${'v{}'.format(pr_index_ver)} |
100 </code>
101 % endif
92 102 </a>
93 103 </div>
94 |
95 % endif
96 104 % else:
97 105 % if comment.pull_request_version_id and pr_index_ver:
98 106 |
@@ -102,7 +110,7 b''
102 110 ${_('Outdated comment from pull request version {}').format(pr_index_ver)}
103 111 </a>
104 112 % else:
105 <div class="tooltip" title="${_('Comment from pull request version {0}').format(pr_index_ver)}">
113 <div title="${_('Comment from pull request version {0}').format(pr_index_ver)}">
106 114 <a href="${h.url('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id, version=comment.pull_request_version_id)}">
107 115 <code class="pr-version-num">
108 116 ${'v{}'.format(pr_index_ver)}
@@ -143,9 +151,9 b''
143 151 </%def>
144 152
145 153 ## generate main comments
146 <%def name="generate_comments(include_pull_request=False, is_pull_request=False)">
154 <%def name="generate_comments(comments, include_pull_request=False, is_pull_request=False)">
147 155 <div id="comments">
148 %for comment in c.comments:
156 %for comment in comments:
149 157 <div id="comment-tr-${comment.comment_id}">
150 158 ## only render comments that are not from pull request, or from
151 159 ## pull request and a status change
@@ -35,6 +35,7 b''
35 35 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
36 36 </script>
37 37 <div class="box">
38
38 39 <div class="title">
39 40 ${self.repo_page_title(c.rhodecode_db_repo)}
40 41 </div>
@@ -42,6 +43,7 b''
42 43 ${self.breadcrumbs()}
43 44
44 45 <div class="box pr-summary">
46
45 47 <div class="summary-details block-left">
46 48 <% summary = lambda n:{False:'summary-short'}.get(n) %>
47 49 <div class="pr-details-title">
@@ -173,10 +175,13 b''
173 175 ## CURRENTLY SELECT PR VERSION
174 176 <tr class="version-pr" style="display: ${'' if c.at_version_num is None else 'none'}">
175 177 <td>
176 % if c.at_version in [None, 'latest']:
178 % if c.at_version_num is None:
177 179 <i class="icon-ok link"></i>
178 180 % else:
179 <i class="icon-comment"></i> <code>${len(c.inline_versions[None])}</code>
181 <i class="icon-comment"></i>
182 <code>
183 ${len(c.comment_versions[None]['at'])}/${len(c.inline_versions[None]['at'])}
184 </code>
180 185 % endif
181 186 </td>
182 187 <td>
@@ -203,21 +208,25 b''
203 208
204 209 ## SHOW ALL VERSIONS OF PR
205 210 <% ver_pr = None %>
211
206 212 % for data in reversed(list(enumerate(c.versions, 1))):
207 213 <% ver_pos = data[0] %>
208 214 <% ver = data[1] %>
209 215 <% ver_pr = ver.pull_request_version_id %>
210 216
211 <tr class="version-pr" style="display: ${'' if c.at_version == ver_pr else 'none'}">
217 <tr class="version-pr" style="display: ${'' if c.at_version_num == ver_pr else 'none'}">
212 218 <td>
213 % if c.at_version == ver_pr:
219 % if c.at_version_num == ver_pr:
214 220 <i class="icon-ok link"></i>
215 221 % else:
216 <i class="icon-comment"></i> <code>${len(c.inline_versions[ver_pr])}</code>
222 <i class="icon-comment"></i>
223 <code class="tooltip" title="${_('Comment from pull request version {0}, general:{1} inline{2}').format(ver_pos, len(c.comment_versions[ver_pr]['at']), len(c.inline_versions[ver_pr]['at']))}">
224 ${len(c.comment_versions[ver_pr]['at'])}/${len(c.inline_versions[ver_pr]['at'])}
225 </code>
217 226 % endif
218 227 </td>
219 228 <td>
220 <code class="tooltip" title="${_('Comment from pull request version {0}').format(ver_pos)}">
229 <code>
221 230 <a href="${h.url.current(version=ver_pr)}">v${ver_pos}</a>
222 231 </code>
223 232 </td>
@@ -228,7 +237,7 b''
228 237 ${_('created')} ${h.age_component(ver.updated_on)}
229 238 </td>
230 239 <td align="right">
231 % if c.at_version == ver_pr:
240 % if c.at_version_num == ver_pr:
232 241 <span id="show-pr-versions" class="btn btn-link" onclick="$('.version-pr').show(); $(this).hide(); return false">${_('Show all versions')}</span>
233 242 % endif
234 243 </td>
@@ -240,28 +249,39 b''
240 249 <td>
241 250 </td>
242 251
243 <% inline_comm_count_ver = len(c.inline_versions[ver_pr])%>
244 252 <td colspan="4" style="border-top: 1px dashed #dbd9da">
245 ${_('Comments for this version')}:
246 %if c.comments:
247 <a href="#comments">${_("%d General ") % len(c.comments)}</a>
253 <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %>
254 <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %>
255
256
257 % if c.at_version:
258 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['display']) %>
259 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['display']) %>
260 ${_('Comments at this version')}:
248 261 %else:
249 ${_("%d General ") % len(c.comments)}
262 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['until']) %>
263 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['until']) %>
264 ${_('Comments for this pull request')}:
250 265 %endif
251 266
252 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num])%>
267 %if general_comm_count_ver:
268 <a href="#comments">${_("%d General ") % general_comm_count_ver}</a>
269 %else:
270 ${_("%d General ") % general_comm_count_ver}
271 %endif
272
253 273 %if inline_comm_count_ver:
254 274 , <a href="#" onclick="return Rhodecode.comments.nextComment();" id="inline-comments-counter">${_("%d Inline") % inline_comm_count_ver}</a>
255 275 %else:
256 276 , ${_("%d Inline") % inline_comm_count_ver}
257 277 %endif
258 278
259 %if c.outdated_cnt:
260 , <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">${_("%d Outdated") % c.outdated_cnt}</a>
279 %if outdated_comm_count_ver:
280 , <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">${_("%d Outdated") % outdated_comm_count_ver}</a>
261 281 <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated comments')}</a>
262 282 <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated comments')}</a>
263 283 %else:
264 , ${_("%d Outdated") % c.outdated_cnt}
284 , ${_("%d Outdated") % outdated_comm_count_ver}
265 285 %endif
266 286 </td>
267 287 </tr>
@@ -459,7 +479,24 b' Changed files:'
459 479 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
460 480
461 481 ## render general comments
462 ${comment.generate_comments(include_pull_request=True, is_pull_request=True)}
482
483 <div id="comment-tr-show">
484 <div class="comment">
485 <div class="meta">
486 % if general_outdated_comm_count_ver:
487 % if general_outdated_comm_count_ver == 1:
488 ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)},
489 <a href="#" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a>
490 % else:
491 ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)},
492 <a href="#" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a>
493 % endif
494 % endif
495 </div>
496 </div>
497 </div>
498
499 ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)}
463 500
464 501 % if not c.pull_request.is_closed():
465 502 ## main comment form and it status
@@ -473,10 +510,19 b' Changed files:'
473 510 if (location.hash) {
474 511 var result = splitDelimitedHash(location.hash);
475 512 var line = $('html').find(result.loc);
513 // show hidden comments if we use location.hash
514 if (line.hasClass('comment-general')) {
515 $(line).show();
516 } else if (line.hasClass('comment-inline')) {
517 $(line).show();
518 var $cb = $(line).closest('.cb');
519 $cb.removeClass('cb-collapsed')
520 }
476 521 if (line.length > 0){
477 522 offsetScroll(line, 70);
478 523 }
479 524 }
525
480 526 $(function(){
481 527 ReviewerAutoComplete('user');
482 528 // custom code mirror
@@ -544,15 +590,14 b' Changed files:'
544 590 ReviewersPanel.init();
545 591
546 592 showOutdated = function(self){
547 $('.comment-outdated').show();
593 $('.comment-inline.comment-outdated').show();
548 594 $('.filediff-outdated').show();
549 595 $('.showOutdatedComments').hide();
550 596 $('.hideOutdatedComments').show();
551
552 597 };
553 598
554 599 hideOutdated = function(self){
555 $('.comment-outdated').hide();
600 $('.comment-inline.comment-outdated').hide();
556 601 $('.filediff-outdated').hide();
557 602 $('.hideOutdatedComments').hide();
558 603 $('.showOutdatedComments').show();
General Comments 0
You need to be logged in to leave comments. Login now