##// END OF EJS Templates
commits/pr pages various fixes....
marcink -
r4485:ac1b264f default
parent child
Show More
@@ -0,0 +1,134
1 ## snippet for sidebar elements
2 ## usage:
3 ## <%namespace name="sidebar" file="/base/sidebar.mako"/>
4 ## ${sidebar.comments_table()}
5 <%namespace name="base" file="/base/base.mako"/>
6
7 <%def name="comments_table(comments, counter_num, todo_comments=False, existing_ids=None, is_pr=True)">
8 <%
9 if todo_comments:
10 cls_ = 'todos-content-table'
11 def sorter(entry):
12 user_id = entry.author.user_id
13 resolved = '1' if entry.resolved else '0'
14 if user_id == c.rhodecode_user.user_id:
15 # own comments first
16 user_id = 0
17 return '{}'.format(str(entry.comment_id).zfill(10000))
18 else:
19 cls_ = 'comments-content-table'
20 def sorter(entry):
21 user_id = entry.author.user_id
22 return '{}'.format(str(entry.comment_id).zfill(10000))
23
24 existing_ids = existing_ids or []
25
26 %>
27
28 <table class="todo-table ${cls_}" data-total-count="${len(comments)}" data-counter="${counter_num}">
29
30 % for loop_obj, comment_obj in h.looper(reversed(sorted(comments, key=sorter))):
31 <%
32 display = ''
33 _cls = ''
34 %>
35
36 <%
37 comment_ver_index = comment_obj.get_index_version(getattr(c, 'versions', []))
38 prev_comment_ver_index = 0
39 if loop_obj.previous:
40 prev_comment_ver_index = loop_obj.previous.get_index_version(getattr(c, 'versions', []))
41
42 ver_info = None
43 if getattr(c, 'versions', []):
44 ver_info = c.versions[comment_ver_index-1] if comment_ver_index else None
45 %>
46 <% hidden_at_ver = comment_obj.outdated_at_version_js(c.at_version_num) %>
47 <% is_from_old_ver = comment_obj.older_than_version_js(c.at_version_num) %>
48 <%
49 if (prev_comment_ver_index > comment_ver_index):
50 comments_ver_divider = comment_ver_index
51 else:
52 comments_ver_divider = None
53 %>
54
55 % if todo_comments:
56 % if comment_obj.resolved:
57 <% _cls = 'resolved-todo' %>
58 <% display = 'none' %>
59 % endif
60 % else:
61 ## SKIP TODOs we display them in other area
62 % if comment_obj.is_todo:
63 <% display = 'none' %>
64 % endif
65 ## Skip outdated comments
66 % if comment_obj.outdated:
67 <% display = 'none' %>
68 <% _cls = 'hidden-comment' %>
69 % endif
70 % endif
71
72 % if not todo_comments and comments_ver_divider:
73 <tr class="old-comments-marker">
74 <td colspan="3">
75 % if ver_info:
76 <code>v${comments_ver_divider} ${h.age_component(ver_info.created_on, time_is_local=True, tooltip=False)}</code>
77 % else:
78 <code>v${comments_ver_divider}</code>
79 % endif
80 </td>
81 </tr>
82
83 % endif
84
85 <tr class="${_cls}" style="display: ${display};" data-sidebar-comment-id="${comment_obj.comment_id}">
86 <td class="td-todo-number">
87
88 <a class="${('todo-resolved' if comment_obj.resolved else '')} permalink"
89 href="#comment-${comment_obj.comment_id}"
90 onclick="return Rhodecode.comments.scrollToComment($('#comment-${comment_obj.comment_id}'), 0, ${hidden_at_ver})">
91
92 <%
93 version_info = ''
94 if is_pr:
95 version_info = (' made in older version (v{})'.format(comment_ver_index) if is_from_old_ver == 'true' else ' made in this version')
96 %>
97
98 % if todo_comments:
99 % if comment_obj.is_inline:
100 <i class="tooltip icon-code" title="Inline TODO comment${version_info}."></i>
101 % else:
102 <i class="tooltip icon-comment" title="General TODO comment${version_info}."></i>
103 % endif
104 % else:
105 % if comment_obj.outdated:
106 <i class="tooltip icon-comment-toggle" title="Inline Outdated made in v${comment_ver_index}."></i>
107 % elif comment_obj.is_inline:
108 <i class="tooltip icon-code" title="Inline comment${version_info}."></i>
109 % else:
110 <i class="tooltip icon-comment" title="General comment${version_info}."></i>
111 % endif
112 % endif
113
114 </a>
115 ## NEW, since refresh
116 % if existing_ids and comment_obj.comment_id not in existing_ids:
117 <span class="tag">NEW</span>
118 % endif
119 </td>
120
121 <td class="td-todo-gravatar">
122 ${base.gravatar(comment_obj.author.email, 16, user=comment_obj.author, tooltip=True, extra_class=['no-margin'])}
123 </td>
124 <td class="todo-comment-text-wrapper">
125 <div class="tooltip todo-comment-text timeago ${('todo-resolved' if comment_obj.resolved else '')} " title="${h.format_date(comment_obj.created_on)}" datetime="${comment_obj.created_on}${h.get_timezone(comment_obj.created_on, time_is_local=True)}">
126 <code>${h.chop_at_smart(comment_obj.text, '\n', suffix_if_chopped='...')}</code>
127 </div>
128 </td>
129 </tr>
130 % endfor
131
132 </table>
133
134 </%def> No newline at end of file
@@ -485,23 +485,10 class TestRepoCommitCommentsView(TestCon
485
485
486
486
487 def assert_comment_links(response, comments, inline_comments):
487 def assert_comment_links(response, comments, inline_comments):
488 if comments == 1:
488 response.mustcontain(
489 comments_text = "%d General" % comments
489 '<span class="display-none" id="general-comments-count">{}</span>'.format(comments))
490 else:
490 response.mustcontain(
491 comments_text = "%d General" % comments
491 '<span class="display-none" id="inline-comments-count">{}</span>'.format(inline_comments))
492
493 if inline_comments == 1:
494 inline_comments_text = "%d Inline" % inline_comments
495 else:
496 inline_comments_text = "%d Inline" % inline_comments
497
492
498 if comments:
499 response.mustcontain('<a href="#comments">%s</a>,' % comments_text)
500 else:
501 response.mustcontain(comments_text)
502
493
503 if inline_comments:
494
504 response.mustcontain(
505 'id="inline-comments-counter">%s' % inline_comments_text)
506 else:
507 response.mustcontain(inline_comments_text)
@@ -18,8 +18,8
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
22 import logging
21 import logging
22 import collections
23
23
24 from pyramid.httpexceptions import (
24 from pyramid.httpexceptions import (
25 HTTPNotFound, HTTPBadRequest, HTTPFound, HTTPForbidden, HTTPConflict)
25 HTTPNotFound, HTTPBadRequest, HTTPFound, HTTPForbidden, HTTPConflict)
@@ -34,14 +34,14 from rhodecode.apps.file_store.exception
34 from rhodecode.lib import diffs, codeblocks
34 from rhodecode.lib import diffs, codeblocks
35 from rhodecode.lib.auth import (
35 from rhodecode.lib.auth import (
36 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired)
36 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired)
37
37 from rhodecode.lib.ext_json import json
38 from rhodecode.lib.compat import OrderedDict
38 from rhodecode.lib.compat import OrderedDict
39 from rhodecode.lib.diffs import (
39 from rhodecode.lib.diffs import (
40 cache_diff, load_cached_diff, diff_cache_exist, get_diff_context,
40 cache_diff, load_cached_diff, diff_cache_exist, get_diff_context,
41 get_diff_whitespace_flag)
41 get_diff_whitespace_flag)
42 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError, CommentVersionMismatch
42 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError, CommentVersionMismatch
43 import rhodecode.lib.helpers as h
43 import rhodecode.lib.helpers as h
44 from rhodecode.lib.utils2 import safe_unicode, str2bool
44 from rhodecode.lib.utils2 import safe_unicode, str2bool, StrictAttributeDict
45 from rhodecode.lib.vcs.backends.base import EmptyCommit
45 from rhodecode.lib.vcs.backends.base import EmptyCommit
46 from rhodecode.lib.vcs.exceptions import (
46 from rhodecode.lib.vcs.exceptions import (
47 RepositoryError, CommitDoesNotExistError)
47 RepositoryError, CommitDoesNotExistError)
@@ -87,7 +87,6 class RepoCommitsView(RepoAppView):
87 diff_limit = c.visual.cut_off_limit_diff
87 diff_limit = c.visual.cut_off_limit_diff
88 file_limit = c.visual.cut_off_limit_file
88 file_limit = c.visual.cut_off_limit_file
89
89
90
91 # get ranges of commit ids if preset
90 # get ranges of commit ids if preset
92 commit_range = commit_id_range.split('...')[:2]
91 commit_range = commit_id_range.split('...')[:2]
93
92
@@ -116,6 +115,7 class RepoCommitsView(RepoAppView):
116 except Exception:
115 except Exception:
117 log.exception("General failure")
116 log.exception("General failure")
118 raise HTTPNotFound()
117 raise HTTPNotFound()
118 single_commit = len(c.commit_ranges) == 1
119
119
120 c.changes = OrderedDict()
120 c.changes = OrderedDict()
121 c.lines_added = 0
121 c.lines_added = 0
@@ -129,23 +129,48 class RepoCommitsView(RepoAppView):
129 c.inline_comments = []
129 c.inline_comments = []
130 c.files = []
130 c.files = []
131
131
132 c.statuses = []
133 c.comments = []
132 c.comments = []
134 c.unresolved_comments = []
133 c.unresolved_comments = []
135 c.resolved_comments = []
134 c.resolved_comments = []
136 if len(c.commit_ranges) == 1:
135
136 # Single commit
137 if single_commit:
137 commit = c.commit_ranges[0]
138 commit = c.commit_ranges[0]
138 c.comments = CommentsModel().get_comments(
139 c.comments = CommentsModel().get_comments(
139 self.db_repo.repo_id,
140 self.db_repo.repo_id,
140 revision=commit.raw_id)
141 revision=commit.raw_id)
141 c.statuses.append(ChangesetStatusModel().get_status(
142
142 self.db_repo.repo_id, commit.raw_id))
143 # comments from PR
143 # comments from PR
144 statuses = ChangesetStatusModel().get_statuses(
144 statuses = ChangesetStatusModel().get_statuses(
145 self.db_repo.repo_id, commit.raw_id,
145 self.db_repo.repo_id, commit.raw_id,
146 with_revisions=True)
146 with_revisions=True)
147 prs = set(st.pull_request for st in statuses
147
148 if st.pull_request is not None)
148 prs = set()
149 reviewers = list()
150 reviewers_duplicates = set() # to not have duplicates from multiple votes
151 for c_status in statuses:
152
153 # extract associated pull-requests from votes
154 if c_status.pull_request:
155 prs.add(c_status.pull_request)
156
157 # extract reviewers
158 _user_id = c_status.author.user_id
159 if _user_id not in reviewers_duplicates:
160 reviewers.append(
161 StrictAttributeDict({
162 'user': c_status.author,
163
164 # fake attributed for commit, page that we don't have
165 # but we share the display with PR page
166 'mandatory': False,
167 'reasons': [],
168 'rule_user_group_data': lambda: None
169 })
170 )
171 reviewers_duplicates.add(_user_id)
172
173 c.allowed_reviewers = reviewers
149 # from associated statuses, check the pull requests, and
174 # from associated statuses, check the pull requests, and
150 # show comments from them
175 # show comments from them
151 for pr in prs:
176 for pr in prs:
@@ -156,6 +181,37 class RepoCommitsView(RepoAppView):
156 c.resolved_comments = CommentsModel()\
181 c.resolved_comments = CommentsModel()\
157 .get_commit_resolved_todos(commit.raw_id)
182 .get_commit_resolved_todos(commit.raw_id)
158
183
184 c.inline_comments_flat = CommentsModel()\
185 .get_commit_inline_comments(commit.raw_id)
186
187 review_statuses = ChangesetStatusModel().aggregate_votes_by_user(
188 statuses, reviewers)
189
190 c.commit_review_status = ChangesetStatus.STATUS_NOT_REVIEWED
191
192 c.commit_set_reviewers_data_json = collections.OrderedDict({'reviewers': []})
193
194 for review_obj, member, reasons, mandatory, status in review_statuses:
195 member_reviewer = h.reviewer_as_json(
196 member, reasons=reasons, mandatory=mandatory,
197 user_group=None
198 )
199
200 current_review_status = status[0][1].status if status else ChangesetStatus.STATUS_NOT_REVIEWED
201 member_reviewer['review_status'] = current_review_status
202 member_reviewer['review_status_label'] = h.commit_status_lbl(current_review_status)
203 member_reviewer['allowed_to_update'] = False
204 c.commit_set_reviewers_data_json['reviewers'].append(member_reviewer)
205
206 c.commit_set_reviewers_data_json = json.dumps(c.commit_set_reviewers_data_json)
207
208 # NOTE(marcink): this uses the same voting logic as in pull-requests
209 c.commit_review_status = ChangesetStatusModel().calculate_status(review_statuses)
210 c.commit_broadcast_channel = u'/repo${}$/commit/{}'.format(
211 c.repo_name,
212 commit.raw_id
213 )
214
159 diff = None
215 diff = None
160 # Iterate over ranges (default commit view is always one commit)
216 # Iterate over ranges (default commit view is always one commit)
161 for commit in c.commit_ranges:
217 for commit in c.commit_ranges:
@@ -397,6 +453,7 class RepoCommitsView(RepoAppView):
397 }
453 }
398 if comment:
454 if comment:
399 c.co = comment
455 c.co = comment
456 c.at_version_num = 0
400 rendered_comment = render(
457 rendered_comment = render(
401 'rhodecode:templates/changeset/changeset_comment_block.mako',
458 'rhodecode:templates/changeset/changeset_comment_block.mako',
402 self._get_template_context(c), self.request)
459 self._get_template_context(c), self.request)
@@ -39,7 +39,7 from rhodecode.lib.ext_json import json
39 from rhodecode.lib.auth import (
39 from rhodecode.lib.auth import (
40 LoginRequired, HasRepoPermissionAny, HasRepoPermissionAnyDecorator,
40 LoginRequired, HasRepoPermissionAny, HasRepoPermissionAnyDecorator,
41 NotAnonymous, CSRFRequired)
41 NotAnonymous, CSRFRequired)
42 from rhodecode.lib.utils2 import str2bool, safe_str, safe_unicode
42 from rhodecode.lib.utils2 import str2bool, safe_str, safe_unicode, safe_int
43 from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason
43 from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason
44 from rhodecode.lib.vcs.exceptions import (
44 from rhodecode.lib.vcs.exceptions import (
45 CommitDoesNotExistError, RepositoryRequirementError, EmptyRepositoryError)
45 CommitDoesNotExistError, RepositoryRequirementError, EmptyRepositoryError)
@@ -474,9 +474,6 class RepoPullRequestsView(RepoAppView,
474
474
475 c.pull_request_set_reviewers_data_json = json.dumps(c.pull_request_set_reviewers_data_json)
475 c.pull_request_set_reviewers_data_json = json.dumps(c.pull_request_set_reviewers_data_json)
476
476
477
478
479
480 general_comments, inline_comments = \
477 general_comments, inline_comments = \
481 self.register_comments_vars(c, pull_request_latest, versions)
478 self.register_comments_vars(c, pull_request_latest, versions)
482
479
@@ -980,7 +977,7 class RepoPullRequestsView(RepoAppView,
980 version = self.request.GET.get('version')
977 version = self.request.GET.get('version')
981
978
982 _render = self.request.get_partial_renderer(
979 _render = self.request.get_partial_renderer(
983 'rhodecode:templates/pullrequests/pullrequest_show.mako')
980 'rhodecode:templates/base/sidebar.mako')
984 c = _render.get_call_context()
981 c = _render.get_call_context()
985
982
986 (pull_request_latest,
983 (pull_request_latest,
@@ -999,7 +996,11 class RepoPullRequestsView(RepoAppView,
999
996
1000 self.register_comments_vars(c, pull_request_latest, versions)
997 self.register_comments_vars(c, pull_request_latest, versions)
1001 all_comments = c.inline_comments_flat + c.comments
998 all_comments = c.inline_comments_flat + c.comments
1002 return _render('comments_table', all_comments, len(all_comments))
999
1000 existing_ids = filter(
1001 lambda e: e, map(safe_int, self.request.POST.getall('comments[]')))
1002 return _render('comments_table', all_comments, len(all_comments),
1003 existing_ids=existing_ids)
1003
1004
1004 @LoginRequired()
1005 @LoginRequired()
1005 @NotAnonymous()
1006 @NotAnonymous()
@@ -1017,7 +1018,7 class RepoPullRequestsView(RepoAppView,
1017 version = self.request.GET.get('version')
1018 version = self.request.GET.get('version')
1018
1019
1019 _render = self.request.get_partial_renderer(
1020 _render = self.request.get_partial_renderer(
1020 'rhodecode:templates/pullrequests/pullrequest_show.mako')
1021 'rhodecode:templates/base/sidebar.mako')
1021 c = _render.get_call_context()
1022 c = _render.get_call_context()
1022 (pull_request_latest,
1023 (pull_request_latest,
1023 pull_request_at_ver,
1024 pull_request_at_ver,
@@ -1039,7 +1040,10 class RepoPullRequestsView(RepoAppView,
1039 .get_pull_request_resolved_todos(pull_request)
1040 .get_pull_request_resolved_todos(pull_request)
1040
1041
1041 all_comments = c.unresolved_comments + c.resolved_comments
1042 all_comments = c.unresolved_comments + c.resolved_comments
1042 return _render('comments_table', all_comments, len(c.unresolved_comments), todo_comments=True)
1043 existing_ids = filter(
1044 lambda e: e, map(safe_int, self.request.POST.getall('comments[]')))
1045 return _render('comments_table', all_comments, len(c.unresolved_comments),
1046 todo_comments=True, existing_ids=existing_ids)
1043
1047
1044 @LoginRequired()
1048 @LoginRequired()
1045 @NotAnonymous()
1049 @NotAnonymous()
@@ -354,34 +354,37 class ChangesetStatusModel(BaseModel):
354 Session().add(new_status)
354 Session().add(new_status)
355 return new_statuses
355 return new_statuses
356
356
357 def aggregate_votes_by_user(self, commit_statuses, reviewers_data):
358
359 commit_statuses_map = collections.defaultdict(list)
360 for st in commit_statuses:
361 commit_statuses_map[st.author.username] += [st]
362
363 reviewers = []
364
365 def version(commit_status):
366 return commit_status.version
367
368 for obj in reviewers_data:
369 if not obj.user:
370 continue
371 statuses = commit_statuses_map.get(obj.user.username, None)
372 if statuses:
373 status_groups = itertools.groupby(
374 sorted(statuses, key=version), version)
375 statuses = [(x, list(y)[0]) for x, y in status_groups]
376
377 reviewers.append((obj, obj.user, obj.reasons, obj.mandatory, statuses))
378
379 return reviewers
380
357 def reviewers_statuses(self, pull_request):
381 def reviewers_statuses(self, pull_request):
358 _commit_statuses = self.get_statuses(
382 _commit_statuses = self.get_statuses(
359 pull_request.source_repo,
383 pull_request.source_repo,
360 pull_request=pull_request,
384 pull_request=pull_request,
361 with_revisions=True)
385 with_revisions=True)
362
386
363 commit_statuses = collections.defaultdict(list)
387 return self.aggregate_votes_by_user(_commit_statuses, pull_request.reviewers)
364 for st in _commit_statuses:
365 commit_statuses[st.author.username] += [st]
366
367 pull_request_reviewers = []
368
369 def version(commit_status):
370 return commit_status.version
371
372 for obj in pull_request.reviewers:
373 if not obj.user:
374 continue
375 statuses = commit_statuses.get(obj.user.username, None)
376 if statuses:
377 status_groups = itertools.groupby(
378 sorted(statuses, key=version), version)
379 statuses = [(x, list(y)[0]) for x, y in status_groups]
380
381 pull_request_reviewers.append(
382 (obj, obj.user, obj.reasons, obj.mandatory, statuses))
383
384 return pull_request_reviewers
385
388
386 def calculated_review_status(self, pull_request, reviewers_statuses=None):
389 def calculated_review_status(self, pull_request, reviewers_statuses=None):
387 """
390 """
@@ -228,6 +228,14 class CommentsModel(BaseModel):
228
228
229 return todos
229 return todos
230
230
231 def get_commit_inline_comments(self, commit_id):
232 inline_comments = Session().query(ChangesetComment) \
233 .filter(ChangesetComment.line_no != None) \
234 .filter(ChangesetComment.f_path != None) \
235 .filter(ChangesetComment.revision == commit_id)
236 inline_comments = inline_comments.all()
237 return inline_comments
238
231 def _log_audit_action(self, action, action_data, auth_user, comment):
239 def _log_audit_action(self, action, action_data, auth_user, comment):
232 audit_logger.store(
240 audit_logger.store(
233 action=action,
241 action=action,
@@ -55,3 +55,16
55 margin: 0 auto 35px auto;
55 margin: 0 auto 35px auto;
56 }
56 }
57 }
57 }
58
59 .alert-text-success {
60 color: @alert1;
61
62 }
63
64 .alert-text-error {
65 color: @alert2;
66 }
67
68 .alert-text-warning {
69 color: @alert3;
70 }
@@ -254,7 +254,7 input[type="button"] {
254
254
255 .btn-group-actions {
255 .btn-group-actions {
256 position: relative;
256 position: relative;
257 z-index: 100;
257 z-index: 50;
258
258
259 &:not(.open) .btn-action-switcher-container {
259 &:not(.open) .btn-action-switcher-container {
260 display: none;
260 display: none;
@@ -1078,10 +1078,16 input.filediff-collapse-state {
1078 background: @color5;
1078 background: @color5;
1079 color: white;
1079 color: white;
1080 }
1080 }
1081
1081 &[op="comments"] { /* comments on file */
1082 &[op="comments"] { /* comments on file */
1082 background: @grey4;
1083 background: @grey4;
1083 color: white;
1084 color: white;
1084 }
1085 }
1086
1087 &[op="options"] { /* context menu */
1088 background: @grey6;
1089 color: black;
1090 }
1085 }
1091 }
1086 }
1092 }
1087
1093
@@ -31,6 +31,10 a { cursor: pointer; }
31 clear: both;
31 clear: both;
32 }
32 }
33
33
34 .display-none {
35 display: none;
36 }
37
34 .pull-right {
38 .pull-right {
35 float: right !important;
39 float: right !important;
36 }
40 }
@@ -83,6 +83,11 body {
83 }
83 }
84 }
84 }
85
85
86 .flex-container {
87 display: flex;
88 justify-content: space-between;
89 }
90
86 .action-link{
91 .action-link{
87 margin-left: @padding;
92 margin-left: @padding;
88 padding-left: @padding;
93 padding-left: @padding;
@@ -482,6 +487,15 ul.auth_plugins {
482 text-align: left;
487 text-align: left;
483 overflow: hidden;
488 overflow: hidden;
484 white-space: pre-line;
489 white-space: pre-line;
490 padding-top: 5px
491 }
492
493 #add_reviewer {
494 padding-top: 10px;
495 }
496
497 #add_reviewer_input {
498 padding-top: 10px
485 }
499 }
486
500
487 .pr-details-title-author-pref {
501 .pr-details-title-author-pref {
@@ -1169,9 +1183,12 label {
1169 a {
1183 a {
1170 color: @grey5
1184 color: @grey5
1171 }
1185 }
1172 @media screen and (max-width: 1200px) {
1186
1187 // 1024px or smaller
1188 @media screen and (max-width: 1180px) {
1173 display: none;
1189 display: none;
1174 }
1190 }
1191
1175 }
1192 }
1176
1193
1177 img {
1194 img {
@@ -1553,6 +1570,7 table.integrations {
1553 width: 16px;
1570 width: 16px;
1554 padding: 0;
1571 padding: 0;
1555 color: black;
1572 color: black;
1573 cursor: pointer;
1556 }
1574 }
1557
1575
1558 .reviewer_member_mandatory_remove {
1576 .reviewer_member_mandatory_remove {
@@ -1682,7 +1700,7 table.group_members {
1682 }
1700 }
1683
1701
1684 .reviewer_ac .ac-input {
1702 .reviewer_ac .ac-input {
1685 width: 92%;
1703 width: 100%;
1686 margin-bottom: 1em;
1704 margin-bottom: 1em;
1687 }
1705 }
1688
1706
@@ -2756,7 +2774,7 table.rctable td.td-search-results div {
2756 }
2774 }
2757
2775
2758 #help_kb .modal-content{
2776 #help_kb .modal-content{
2759 max-width: 750px;
2777 max-width: 800px;
2760 margin: 10% auto;
2778 margin: 10% auto;
2761
2779
2762 table{
2780 table{
@@ -3053,4 +3071,141 form.markup-form {
3053
3071
3054 .pr-hovercard-title {
3072 .pr-hovercard-title {
3055 padding-top: 5px;
3073 padding-top: 5px;
3056 } No newline at end of file
3074 }
3075
3076 .action-divider {
3077 opacity: 0.5;
3078 }
3079
3080 .details-inline-block {
3081 display: inline-block;
3082 position: relative;
3083 }
3084
3085 .details-inline-block summary {
3086 list-style: none;
3087 }
3088
3089 details:not([open]) > :not(summary) {
3090 display: none !important;
3091 }
3092
3093 .details-reset > summary {
3094 list-style: none;
3095 }
3096
3097 .details-reset > summary::-webkit-details-marker {
3098 display: none;
3099 }
3100
3101 .details-dropdown {
3102 position: absolute;
3103 top: 100%;
3104 width: 185px;
3105 list-style: none;
3106 background-color: #fff;
3107 background-clip: padding-box;
3108 border: 1px solid @grey5;
3109 box-shadow: 0 8px 24px rgba(149, 157, 165, .2);
3110 left: -150px;
3111 text-align: left;
3112 z-index: 90;
3113 }
3114
3115 .dropdown-divider {
3116 display: block;
3117 height: 0;
3118 margin: 8px 0;
3119 border-top: 1px solid @grey5;
3120 }
3121
3122 .dropdown-item {
3123 display: block;
3124 padding: 4px 8px 4px 16px;
3125 overflow: hidden;
3126 text-overflow: ellipsis;
3127 white-space: nowrap;
3128 font-weight: normal;
3129 }
3130
3131 .right-sidebar {
3132 position: fixed;
3133 top: 0px;
3134 bottom: 0;
3135 right: 0;
3136
3137 background: #fafafa;
3138 z-index: 50;
3139 }
3140
3141 .right-sidebar {
3142 border-left: 1px solid @grey5;
3143 }
3144
3145 .right-sidebar.right-sidebar-expanded {
3146 width: 300px;
3147 overflow: scroll;
3148 }
3149
3150 .right-sidebar.right-sidebar-collapsed {
3151 width: 40px;
3152 padding: 0;
3153 display: block;
3154 overflow: hidden;
3155 }
3156
3157 .sidenav {
3158 float: right;
3159 will-change: min-height;
3160 background: #fafafa;
3161 width: 100%;
3162 }
3163
3164 .sidebar-toggle {
3165 height: 30px;
3166 text-align: center;
3167 margin: 15px 0px 0 0;
3168 }
3169
3170 .sidebar-toggle a {
3171
3172 }
3173
3174 .sidebar-content {
3175 margin-left: 15px;
3176 margin-right: 15px;
3177 }
3178
3179 .sidebar-heading {
3180 font-size: 1.2em;
3181 font-weight: 700;
3182 margin-top: 10px;
3183 }
3184
3185 .sidebar-element {
3186 margin-top: 20px;
3187 }
3188
3189 .right-sidebar-collapsed-state {
3190 display: flex;
3191 flex-direction: column;
3192 justify-content: center;
3193 align-items: center;
3194 padding: 0 10px;
3195 cursor: pointer;
3196 font-size: 1.3em;
3197 margin: 0 -15px;
3198 }
3199
3200 .right-sidebar-collapsed-state:hover {
3201 background-color: @grey5;
3202 }
3203
3204 .old-comments-marker {
3205 text-align: left;
3206 }
3207
3208 .old-comments-marker td {
3209 padding-top: 15px;
3210 border-bottom: 1px solid @grey5;
3211 }
@@ -790,7 +790,7 input {
790
790
791 &.main_filter_input {
791 &.main_filter_input {
792 padding: 5px 10px;
792 padding: 5px 10px;
793 min-width: 340px;
793
794 color: @grey7;
794 color: @grey7;
795 background: @black;
795 background: @black;
796 min-height: 18px;
796 min-height: 18px;
@@ -800,11 +800,34 input {
800 color: @grey2 !important;
800 color: @grey2 !important;
801 background: white !important;