##// END OF EJS Templates
commit-ranges: enable combined diff compare directly from range selector.
milka -
r4552:a0029748 default
parent child Browse files
Show More
@@ -1,802 +1,816 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
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 import logging
21 import logging
22 import collections
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)
26 from pyramid.view import view_config
26 from pyramid.view import view_config
27 from pyramid.renderers import render
27 from pyramid.renderers import render
28 from pyramid.response import Response
28 from pyramid.response import Response
29
29
30 from rhodecode.apps._base import RepoAppView
30 from rhodecode.apps._base import RepoAppView
31 from rhodecode.apps.file_store import utils as store_utils
31 from rhodecode.apps.file_store import utils as store_utils
32 from rhodecode.apps.file_store.exceptions import FileNotAllowedException, FileOverSizeException
32 from rhodecode.apps.file_store.exceptions import FileNotAllowedException, FileOverSizeException
33
33
34 from rhodecode.lib import diffs, codeblocks, channelstream
34 from rhodecode.lib import diffs, codeblocks, channelstream
35 from rhodecode.lib.auth import (
35 from rhodecode.lib.auth import (
36 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired)
36 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired)
37 from rhodecode.lib.ext_json import json
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, StrictAttributeDict
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)
48 from rhodecode.model.db import ChangesetComment, ChangesetStatus, FileStore, \
48 from rhodecode.model.db import ChangesetComment, ChangesetStatus, FileStore, \
49 ChangesetCommentHistory
49 ChangesetCommentHistory
50 from rhodecode.model.changeset_status import ChangesetStatusModel
50 from rhodecode.model.changeset_status import ChangesetStatusModel
51 from rhodecode.model.comment import CommentsModel
51 from rhodecode.model.comment import CommentsModel
52 from rhodecode.model.meta import Session
52 from rhodecode.model.meta import Session
53 from rhodecode.model.settings import VcsSettingsModel
53 from rhodecode.model.settings import VcsSettingsModel
54
54
55 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
56
56
57
57
58 def _update_with_GET(params, request):
58 def _update_with_GET(params, request):
59 for k in ['diff1', 'diff2', 'diff']:
59 for k in ['diff1', 'diff2', 'diff']:
60 params[k] += request.GET.getall(k)
60 params[k] += request.GET.getall(k)
61
61
62
62
63 class RepoCommitsView(RepoAppView):
63 class RepoCommitsView(RepoAppView):
64 def load_default_context(self):
64 def load_default_context(self):
65 c = self._get_local_tmpl_context(include_app_defaults=True)
65 c = self._get_local_tmpl_context(include_app_defaults=True)
66 c.rhodecode_repo = self.rhodecode_vcs_repo
66 c.rhodecode_repo = self.rhodecode_vcs_repo
67
67
68 return c
68 return c
69
69
70 def _is_diff_cache_enabled(self, target_repo):
70 def _is_diff_cache_enabled(self, target_repo):
71 caching_enabled = self._get_general_setting(
71 caching_enabled = self._get_general_setting(
72 target_repo, 'rhodecode_diff_cache')
72 target_repo, 'rhodecode_diff_cache')
73 log.debug('Diff caching enabled: %s', caching_enabled)
73 log.debug('Diff caching enabled: %s', caching_enabled)
74 return caching_enabled
74 return caching_enabled
75
75
76 def _commit(self, commit_id_range, method):
76 def _commit(self, commit_id_range, method):
77 _ = self.request.translate
77 _ = self.request.translate
78 c = self.load_default_context()
78 c = self.load_default_context()
79 c.fulldiff = self.request.GET.get('fulldiff')
79 c.fulldiff = self.request.GET.get('fulldiff')
80 redirect_to_combined = str2bool(self.request.GET.get('redirect_combined'))
80
81
81 # fetch global flags of ignore ws or context lines
82 # fetch global flags of ignore ws or context lines
82 diff_context = get_diff_context(self.request)
83 diff_context = get_diff_context(self.request)
83 hide_whitespace_changes = get_diff_whitespace_flag(self.request)
84 hide_whitespace_changes = get_diff_whitespace_flag(self.request)
84
85
85 # diff_limit will cut off the whole diff if the limit is applied
86 # diff_limit will cut off the whole diff if the limit is applied
86 # otherwise it will just hide the big files from the front-end
87 # otherwise it will just hide the big files from the front-end
87 diff_limit = c.visual.cut_off_limit_diff
88 diff_limit = c.visual.cut_off_limit_diff
88 file_limit = c.visual.cut_off_limit_file
89 file_limit = c.visual.cut_off_limit_file
89
90
90 # get ranges of commit ids if preset
91 # get ranges of commit ids if preset
91 commit_range = commit_id_range.split('...')[:2]
92 commit_range = commit_id_range.split('...')[:2]
92
93
93 try:
94 try:
94 pre_load = ['affected_files', 'author', 'branch', 'date',
95 pre_load = ['affected_files', 'author', 'branch', 'date',
95 'message', 'parents']
96 'message', 'parents']
96 if self.rhodecode_vcs_repo.alias == 'hg':
97 if self.rhodecode_vcs_repo.alias == 'hg':
97 pre_load += ['hidden', 'obsolete', 'phase']
98 pre_load += ['hidden', 'obsolete', 'phase']
98
99
99 if len(commit_range) == 2:
100 if len(commit_range) == 2:
100 commits = self.rhodecode_vcs_repo.get_commits(
101 commits = self.rhodecode_vcs_repo.get_commits(
101 start_id=commit_range[0], end_id=commit_range[1],
102 start_id=commit_range[0], end_id=commit_range[1],
102 pre_load=pre_load, translate_tags=False)
103 pre_load=pre_load, translate_tags=False)
103 commits = list(commits)
104 commits = list(commits)
104 else:
105 else:
105 commits = [self.rhodecode_vcs_repo.get_commit(
106 commits = [self.rhodecode_vcs_repo.get_commit(
106 commit_id=commit_id_range, pre_load=pre_load)]
107 commit_id=commit_id_range, pre_load=pre_load)]
107
108
108 c.commit_ranges = commits
109 c.commit_ranges = commits
109 if not c.commit_ranges:
110 if not c.commit_ranges:
110 raise RepositoryError('The commit range returned an empty result')
111 raise RepositoryError('The commit range returned an empty result')
111 except CommitDoesNotExistError as e:
112 except CommitDoesNotExistError as e:
112 msg = _('No such commit exists. Org exception: `{}`').format(e)
113 msg = _('No such commit exists. Org exception: `{}`').format(e)
113 h.flash(msg, category='error')
114 h.flash(msg, category='error')
114 raise HTTPNotFound()
115 raise HTTPNotFound()
115 except Exception:
116 except Exception:
116 log.exception("General failure")
117 log.exception("General failure")
117 raise HTTPNotFound()
118 raise HTTPNotFound()
118 single_commit = len(c.commit_ranges) == 1
119 single_commit = len(c.commit_ranges) == 1
119
120
121 if redirect_to_combined and not single_commit:
122 source_ref = getattr(c.commit_ranges[0].parents[0]
123 if c.commit_ranges[0].parents else h.EmptyCommit(), 'raw_id')
124 target_ref = c.commit_ranges[-1].raw_id
125 next_url = h.route_path(
126 'repo_compare',
127 repo_name=c.repo_name,
128 source_ref_type='rev',
129 source_ref=source_ref,
130 target_ref_type='rev',
131 target_ref=target_ref)
132 raise HTTPFound(next_url)
133
120 c.changes = OrderedDict()
134 c.changes = OrderedDict()
121 c.lines_added = 0
135 c.lines_added = 0
122 c.lines_deleted = 0
136 c.lines_deleted = 0
123
137
124 # auto collapse if we have more than limit
138 # auto collapse if we have more than limit
125 collapse_limit = diffs.DiffProcessor._collapse_commits_over
139 collapse_limit = diffs.DiffProcessor._collapse_commits_over
126 c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
140 c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
127
141
128 c.commit_statuses = ChangesetStatus.STATUSES
142 c.commit_statuses = ChangesetStatus.STATUSES
129 c.inline_comments = []
143 c.inline_comments = []
130 c.files = []
144 c.files = []
131
145
132 c.comments = []
146 c.comments = []
133 c.unresolved_comments = []
147 c.unresolved_comments = []
134 c.resolved_comments = []
148 c.resolved_comments = []
135
149
136 # Single commit
150 # Single commit
137 if single_commit:
151 if single_commit:
138 commit = c.commit_ranges[0]
152 commit = c.commit_ranges[0]
139 c.comments = CommentsModel().get_comments(
153 c.comments = CommentsModel().get_comments(
140 self.db_repo.repo_id,
154 self.db_repo.repo_id,
141 revision=commit.raw_id)
155 revision=commit.raw_id)
142
156
143 # comments from PR
157 # comments from PR
144 statuses = ChangesetStatusModel().get_statuses(
158 statuses = ChangesetStatusModel().get_statuses(
145 self.db_repo.repo_id, commit.raw_id,
159 self.db_repo.repo_id, commit.raw_id,
146 with_revisions=True)
160 with_revisions=True)
147
161
148 prs = set()
162 prs = set()
149 reviewers = list()
163 reviewers = list()
150 reviewers_duplicates = set() # to not have duplicates from multiple votes
164 reviewers_duplicates = set() # to not have duplicates from multiple votes
151 for c_status in statuses:
165 for c_status in statuses:
152
166
153 # extract associated pull-requests from votes
167 # extract associated pull-requests from votes
154 if c_status.pull_request:
168 if c_status.pull_request:
155 prs.add(c_status.pull_request)
169 prs.add(c_status.pull_request)
156
170
157 # extract reviewers
171 # extract reviewers
158 _user_id = c_status.author.user_id
172 _user_id = c_status.author.user_id
159 if _user_id not in reviewers_duplicates:
173 if _user_id not in reviewers_duplicates:
160 reviewers.append(
174 reviewers.append(
161 StrictAttributeDict({
175 StrictAttributeDict({
162 'user': c_status.author,
176 'user': c_status.author,
163
177
164 # fake attributed for commit, page that we don't have
178 # fake attributed for commit, page that we don't have
165 # but we share the display with PR page
179 # but we share the display with PR page
166 'mandatory': False,
180 'mandatory': False,
167 'reasons': [],
181 'reasons': [],
168 'rule_user_group_data': lambda: None
182 'rule_user_group_data': lambda: None
169 })
183 })
170 )
184 )
171 reviewers_duplicates.add(_user_id)
185 reviewers_duplicates.add(_user_id)
172
186
173 c.reviewers_count = len(reviewers)
187 c.reviewers_count = len(reviewers)
174 c.observers_count = 0
188 c.observers_count = 0
175
189
176 # from associated statuses, check the pull requests, and
190 # from associated statuses, check the pull requests, and
177 # show comments from them
191 # show comments from them
178 for pr in prs:
192 for pr in prs:
179 c.comments.extend(pr.comments)
193 c.comments.extend(pr.comments)
180
194
181 c.unresolved_comments = CommentsModel()\
195 c.unresolved_comments = CommentsModel()\
182 .get_commit_unresolved_todos(commit.raw_id)
196 .get_commit_unresolved_todos(commit.raw_id)
183 c.resolved_comments = CommentsModel()\
197 c.resolved_comments = CommentsModel()\
184 .get_commit_resolved_todos(commit.raw_id)
198 .get_commit_resolved_todos(commit.raw_id)
185
199
186 c.inline_comments_flat = CommentsModel()\
200 c.inline_comments_flat = CommentsModel()\
187 .get_commit_inline_comments(commit.raw_id)
201 .get_commit_inline_comments(commit.raw_id)
188
202
189 review_statuses = ChangesetStatusModel().aggregate_votes_by_user(
203 review_statuses = ChangesetStatusModel().aggregate_votes_by_user(
190 statuses, reviewers)
204 statuses, reviewers)
191
205
192 c.commit_review_status = ChangesetStatus.STATUS_NOT_REVIEWED
206 c.commit_review_status = ChangesetStatus.STATUS_NOT_REVIEWED
193
207
194 c.commit_set_reviewers_data_json = collections.OrderedDict({'reviewers': []})
208 c.commit_set_reviewers_data_json = collections.OrderedDict({'reviewers': []})
195
209
196 for review_obj, member, reasons, mandatory, status in review_statuses:
210 for review_obj, member, reasons, mandatory, status in review_statuses:
197 member_reviewer = h.reviewer_as_json(
211 member_reviewer = h.reviewer_as_json(
198 member, reasons=reasons, mandatory=mandatory, role=None,
212 member, reasons=reasons, mandatory=mandatory, role=None,
199 user_group=None
213 user_group=None
200 )
214 )
201
215
202 current_review_status = status[0][1].status if status else ChangesetStatus.STATUS_NOT_REVIEWED
216 current_review_status = status[0][1].status if status else ChangesetStatus.STATUS_NOT_REVIEWED
203 member_reviewer['review_status'] = current_review_status
217 member_reviewer['review_status'] = current_review_status
204 member_reviewer['review_status_label'] = h.commit_status_lbl(current_review_status)
218 member_reviewer['review_status_label'] = h.commit_status_lbl(current_review_status)
205 member_reviewer['allowed_to_update'] = False
219 member_reviewer['allowed_to_update'] = False
206 c.commit_set_reviewers_data_json['reviewers'].append(member_reviewer)
220 c.commit_set_reviewers_data_json['reviewers'].append(member_reviewer)
207
221
208 c.commit_set_reviewers_data_json = json.dumps(c.commit_set_reviewers_data_json)
222 c.commit_set_reviewers_data_json = json.dumps(c.commit_set_reviewers_data_json)
209
223
210 # NOTE(marcink): this uses the same voting logic as in pull-requests
224 # NOTE(marcink): this uses the same voting logic as in pull-requests
211 c.commit_review_status = ChangesetStatusModel().calculate_status(review_statuses)
225 c.commit_review_status = ChangesetStatusModel().calculate_status(review_statuses)
212 c.commit_broadcast_channel = channelstream.comment_channel(c.repo_name, commit_obj=commit)
226 c.commit_broadcast_channel = channelstream.comment_channel(c.repo_name, commit_obj=commit)
213
227
214 diff = None
228 diff = None
215 # Iterate over ranges (default commit view is always one commit)
229 # Iterate over ranges (default commit view is always one commit)
216 for commit in c.commit_ranges:
230 for commit in c.commit_ranges:
217 c.changes[commit.raw_id] = []
231 c.changes[commit.raw_id] = []
218
232
219 commit2 = commit
233 commit2 = commit
220 commit1 = commit.first_parent
234 commit1 = commit.first_parent
221
235
222 if method == 'show':
236 if method == 'show':
223 inline_comments = CommentsModel().get_inline_comments(
237 inline_comments = CommentsModel().get_inline_comments(
224 self.db_repo.repo_id, revision=commit.raw_id)
238 self.db_repo.repo_id, revision=commit.raw_id)
225 c.inline_cnt = len(CommentsModel().get_inline_comments_as_list(
239 c.inline_cnt = len(CommentsModel().get_inline_comments_as_list(
226 inline_comments))
240 inline_comments))
227 c.inline_comments = inline_comments
241 c.inline_comments = inline_comments
228
242
229 cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path(
243 cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path(
230 self.db_repo)
244 self.db_repo)
231 cache_file_path = diff_cache_exist(
245 cache_file_path = diff_cache_exist(
232 cache_path, 'diff', commit.raw_id,
246 cache_path, 'diff', commit.raw_id,
233 hide_whitespace_changes, diff_context, c.fulldiff)
247 hide_whitespace_changes, diff_context, c.fulldiff)
234
248
235 caching_enabled = self._is_diff_cache_enabled(self.db_repo)
249 caching_enabled = self._is_diff_cache_enabled(self.db_repo)
236 force_recache = str2bool(self.request.GET.get('force_recache'))
250 force_recache = str2bool(self.request.GET.get('force_recache'))
237
251
238 cached_diff = None
252 cached_diff = None
239 if caching_enabled:
253 if caching_enabled:
240 cached_diff = load_cached_diff(cache_file_path)
254 cached_diff = load_cached_diff(cache_file_path)
241
255
242 has_proper_diff_cache = cached_diff and cached_diff.get('diff')
256 has_proper_diff_cache = cached_diff and cached_diff.get('diff')
243 if not force_recache and has_proper_diff_cache:
257 if not force_recache and has_proper_diff_cache:
244 diffset = cached_diff['diff']
258 diffset = cached_diff['diff']
245 else:
259 else:
246 vcs_diff = self.rhodecode_vcs_repo.get_diff(
260 vcs_diff = self.rhodecode_vcs_repo.get_diff(
247 commit1, commit2,
261 commit1, commit2,
248 ignore_whitespace=hide_whitespace_changes,
262 ignore_whitespace=hide_whitespace_changes,
249 context=diff_context)
263 context=diff_context)
250
264
251 diff_processor = diffs.DiffProcessor(
265 diff_processor = diffs.DiffProcessor(
252 vcs_diff, format='newdiff', diff_limit=diff_limit,
266 vcs_diff, format='newdiff', diff_limit=diff_limit,
253 file_limit=file_limit, show_full_diff=c.fulldiff)
267 file_limit=file_limit, show_full_diff=c.fulldiff)
254
268
255 _parsed = diff_processor.prepare()
269 _parsed = diff_processor.prepare()
256
270
257 diffset = codeblocks.DiffSet(
271 diffset = codeblocks.DiffSet(
258 repo_name=self.db_repo_name,
272 repo_name=self.db_repo_name,
259 source_node_getter=codeblocks.diffset_node_getter(commit1),
273 source_node_getter=codeblocks.diffset_node_getter(commit1),
260 target_node_getter=codeblocks.diffset_node_getter(commit2))
274 target_node_getter=codeblocks.diffset_node_getter(commit2))
261
275
262 diffset = self.path_filter.render_patchset_filtered(
276 diffset = self.path_filter.render_patchset_filtered(
263 diffset, _parsed, commit1.raw_id, commit2.raw_id)
277 diffset, _parsed, commit1.raw_id, commit2.raw_id)
264
278
265 # save cached diff
279 # save cached diff
266 if caching_enabled:
280 if caching_enabled:
267 cache_diff(cache_file_path, diffset, None)
281 cache_diff(cache_file_path, diffset, None)
268
282
269 c.limited_diff = diffset.limited_diff
283 c.limited_diff = diffset.limited_diff
270 c.changes[commit.raw_id] = diffset
284 c.changes[commit.raw_id] = diffset
271 else:
285 else:
272 # TODO(marcink): no cache usage here...
286 # TODO(marcink): no cache usage here...
273 _diff = self.rhodecode_vcs_repo.get_diff(
287 _diff = self.rhodecode_vcs_repo.get_diff(
274 commit1, commit2,
288 commit1, commit2,
275 ignore_whitespace=hide_whitespace_changes, context=diff_context)
289 ignore_whitespace=hide_whitespace_changes, context=diff_context)
276 diff_processor = diffs.DiffProcessor(
290 diff_processor = diffs.DiffProcessor(
277 _diff, format='newdiff', diff_limit=diff_limit,
291 _diff, format='newdiff', diff_limit=diff_limit,
278 file_limit=file_limit, show_full_diff=c.fulldiff)
292 file_limit=file_limit, show_full_diff=c.fulldiff)
279 # downloads/raw we only need RAW diff nothing else
293 # downloads/raw we only need RAW diff nothing else
280 diff = self.path_filter.get_raw_patch(diff_processor)
294 diff = self.path_filter.get_raw_patch(diff_processor)
281 c.changes[commit.raw_id] = [None, None, None, None, diff, None, None]
295 c.changes[commit.raw_id] = [None, None, None, None, diff, None, None]
282
296
283 # sort comments by how they were generated
297 # sort comments by how they were generated
284 c.comments = sorted(c.comments, key=lambda x: x.comment_id)
298 c.comments = sorted(c.comments, key=lambda x: x.comment_id)
285 c.at_version_num = None
299 c.at_version_num = None
286
300
287 if len(c.commit_ranges) == 1:
301 if len(c.commit_ranges) == 1:
288 c.commit = c.commit_ranges[0]
302 c.commit = c.commit_ranges[0]
289 c.parent_tmpl = ''.join(
303 c.parent_tmpl = ''.join(
290 '# Parent %s\n' % x.raw_id for x in c.commit.parents)
304 '# Parent %s\n' % x.raw_id for x in c.commit.parents)
291
305
292 if method == 'download':
306 if method == 'download':
293 response = Response(diff)
307 response = Response(diff)
294 response.content_type = 'text/plain'
308 response.content_type = 'text/plain'
295 response.content_disposition = (
309 response.content_disposition = (
296 'attachment; filename=%s.diff' % commit_id_range[:12])
310 'attachment; filename=%s.diff' % commit_id_range[:12])
297 return response
311 return response
298 elif method == 'patch':
312 elif method == 'patch':
299 c.diff = safe_unicode(diff)
313 c.diff = safe_unicode(diff)
300 patch = render(
314 patch = render(
301 'rhodecode:templates/changeset/patch_changeset.mako',
315 'rhodecode:templates/changeset/patch_changeset.mako',
302 self._get_template_context(c), self.request)
316 self._get_template_context(c), self.request)
303 response = Response(patch)
317 response = Response(patch)
304 response.content_type = 'text/plain'
318 response.content_type = 'text/plain'
305 return response
319 return response
306 elif method == 'raw':
320 elif method == 'raw':
307 response = Response(diff)
321 response = Response(diff)
308 response.content_type = 'text/plain'
322 response.content_type = 'text/plain'
309 return response
323 return response
310 elif method == 'show':
324 elif method == 'show':
311 if len(c.commit_ranges) == 1:
325 if len(c.commit_ranges) == 1:
312 html = render(
326 html = render(
313 'rhodecode:templates/changeset/changeset.mako',
327 'rhodecode:templates/changeset/changeset.mako',
314 self._get_template_context(c), self.request)
328 self._get_template_context(c), self.request)
315 return Response(html)
329 return Response(html)
316 else:
330 else:
317 c.ancestor = None
331 c.ancestor = None
318 c.target_repo = self.db_repo
332 c.target_repo = self.db_repo
319 html = render(
333 html = render(
320 'rhodecode:templates/changeset/changeset_range.mako',
334 'rhodecode:templates/changeset/changeset_range.mako',
321 self._get_template_context(c), self.request)
335 self._get_template_context(c), self.request)
322 return Response(html)
336 return Response(html)
323
337
324 raise HTTPBadRequest()
338 raise HTTPBadRequest()
325
339
326 @LoginRequired()
340 @LoginRequired()
327 @HasRepoPermissionAnyDecorator(
341 @HasRepoPermissionAnyDecorator(
328 'repository.read', 'repository.write', 'repository.admin')
342 'repository.read', 'repository.write', 'repository.admin')
329 @view_config(
343 @view_config(
330 route_name='repo_commit', request_method='GET',
344 route_name='repo_commit', request_method='GET',
331 renderer=None)
345 renderer=None)
332 def repo_commit_show(self):
346 def repo_commit_show(self):
333 commit_id = self.request.matchdict['commit_id']
347 commit_id = self.request.matchdict['commit_id']
334 return self._commit(commit_id, method='show')
348 return self._commit(commit_id, method='show')
335
349
336 @LoginRequired()
350 @LoginRequired()
337 @HasRepoPermissionAnyDecorator(
351 @HasRepoPermissionAnyDecorator(
338 'repository.read', 'repository.write', 'repository.admin')
352 'repository.read', 'repository.write', 'repository.admin')
339 @view_config(
353 @view_config(
340 route_name='repo_commit_raw', request_method='GET',
354 route_name='repo_commit_raw', request_method='GET',
341 renderer=None)
355 renderer=None)
342 @view_config(
356 @view_config(
343 route_name='repo_commit_raw_deprecated', request_method='GET',
357 route_name='repo_commit_raw_deprecated', request_method='GET',
344 renderer=None)
358 renderer=None)
345 def repo_commit_raw(self):
359 def repo_commit_raw(self):
346 commit_id = self.request.matchdict['commit_id']
360 commit_id = self.request.matchdict['commit_id']
347 return self._commit(commit_id, method='raw')
361 return self._commit(commit_id, method='raw')
348
362
349 @LoginRequired()
363 @LoginRequired()
350 @HasRepoPermissionAnyDecorator(
364 @HasRepoPermissionAnyDecorator(
351 'repository.read', 'repository.write', 'repository.admin')
365 'repository.read', 'repository.write', 'repository.admin')
352 @view_config(
366 @view_config(
353 route_name='repo_commit_patch', request_method='GET',
367 route_name='repo_commit_patch', request_method='GET',
354 renderer=None)
368 renderer=None)
355 def repo_commit_patch(self):
369 def repo_commit_patch(self):
356 commit_id = self.request.matchdict['commit_id']
370 commit_id = self.request.matchdict['commit_id']
357 return self._commit(commit_id, method='patch')
371 return self._commit(commit_id, method='patch')
358
372
359 @LoginRequired()
373 @LoginRequired()
360 @HasRepoPermissionAnyDecorator(
374 @HasRepoPermissionAnyDecorator(
361 'repository.read', 'repository.write', 'repository.admin')
375 'repository.read', 'repository.write', 'repository.admin')
362 @view_config(
376 @view_config(
363 route_name='repo_commit_download', request_method='GET',
377 route_name='repo_commit_download', request_method='GET',
364 renderer=None)
378 renderer=None)
365 def repo_commit_download(self):
379 def repo_commit_download(self):
366 commit_id = self.request.matchdict['commit_id']
380 commit_id = self.request.matchdict['commit_id']
367 return self._commit(commit_id, method='download')
381 return self._commit(commit_id, method='download')
368
382
369 @LoginRequired()
383 @LoginRequired()
370 @NotAnonymous()
384 @NotAnonymous()
371 @HasRepoPermissionAnyDecorator(
385 @HasRepoPermissionAnyDecorator(
372 'repository.read', 'repository.write', 'repository.admin')
386 'repository.read', 'repository.write', 'repository.admin')
373 @CSRFRequired()
387 @CSRFRequired()
374 @view_config(
388 @view_config(
375 route_name='repo_commit_comment_create', request_method='POST',
389 route_name='repo_commit_comment_create', request_method='POST',
376 renderer='json_ext')
390 renderer='json_ext')
377 def repo_commit_comment_create(self):
391 def repo_commit_comment_create(self):
378 _ = self.request.translate
392 _ = self.request.translate
379 commit_id = self.request.matchdict['commit_id']
393 commit_id = self.request.matchdict['commit_id']
380
394
381 c = self.load_default_context()
395 c = self.load_default_context()
382 status = self.request.POST.get('changeset_status', None)
396 status = self.request.POST.get('changeset_status', None)
383 is_draft = str2bool(self.request.POST.get('draft'))
397 is_draft = str2bool(self.request.POST.get('draft'))
384 text = self.request.POST.get('text')
398 text = self.request.POST.get('text')
385 comment_type = self.request.POST.get('comment_type')
399 comment_type = self.request.POST.get('comment_type')
386 resolves_comment_id = self.request.POST.get('resolves_comment_id', None)
400 resolves_comment_id = self.request.POST.get('resolves_comment_id', None)
387 f_path = self.request.POST.get('f_path')
401 f_path = self.request.POST.get('f_path')
388 line_no = self.request.POST.get('line')
402 line_no = self.request.POST.get('line')
389 target_elem_id = 'file-{}'.format(h.safeid(h.safe_unicode(f_path)))
403 target_elem_id = 'file-{}'.format(h.safeid(h.safe_unicode(f_path)))
390
404
391 if status:
405 if status:
392 text = text or (_('Status change %(transition_icon)s %(status)s')
406 text = text or (_('Status change %(transition_icon)s %(status)s')
393 % {'transition_icon': '>',
407 % {'transition_icon': '>',
394 'status': ChangesetStatus.get_status_lbl(status)})
408 'status': ChangesetStatus.get_status_lbl(status)})
395
409
396 multi_commit_ids = []
410 multi_commit_ids = []
397 for _commit_id in self.request.POST.get('commit_ids', '').split(','):
411 for _commit_id in self.request.POST.get('commit_ids', '').split(','):
398 if _commit_id not in ['', None, EmptyCommit.raw_id]:
412 if _commit_id not in ['', None, EmptyCommit.raw_id]:
399 if _commit_id not in multi_commit_ids:
413 if _commit_id not in multi_commit_ids:
400 multi_commit_ids.append(_commit_id)
414 multi_commit_ids.append(_commit_id)
401
415
402 commit_ids = multi_commit_ids or [commit_id]
416 commit_ids = multi_commit_ids or [commit_id]
403
417
404 data = {}
418 data = {}
405 # Multiple comments for each passed commit id
419 # Multiple comments for each passed commit id
406 for current_id in filter(None, commit_ids):
420 for current_id in filter(None, commit_ids):
407 comment = CommentsModel().create(
421 comment = CommentsModel().create(
408 text=text,
422 text=text,
409 repo=self.db_repo.repo_id,
423 repo=self.db_repo.repo_id,
410 user=self._rhodecode_db_user.user_id,
424 user=self._rhodecode_db_user.user_id,
411 commit_id=current_id,
425 commit_id=current_id,
412 f_path=f_path,
426 f_path=f_path,
413 line_no=line_no,
427 line_no=line_no,
414 status_change=(ChangesetStatus.get_status_lbl(status)
428 status_change=(ChangesetStatus.get_status_lbl(status)
415 if status else None),
429 if status else None),
416 status_change_type=status,
430 status_change_type=status,
417 comment_type=comment_type,
431 comment_type=comment_type,
418 is_draft=is_draft,
432 is_draft=is_draft,
419 resolves_comment_id=resolves_comment_id,
433 resolves_comment_id=resolves_comment_id,
420 auth_user=self._rhodecode_user,
434 auth_user=self._rhodecode_user,
421 send_email=not is_draft, # skip notification for draft comments
435 send_email=not is_draft, # skip notification for draft comments
422 )
436 )
423 is_inline = comment.is_inline
437 is_inline = comment.is_inline
424
438
425 # get status if set !
439 # get status if set !
426 if status:
440 if status:
427 # if latest status was from pull request and it's closed
441 # if latest status was from pull request and it's closed
428 # disallow changing status !
442 # disallow changing status !
429 # dont_allow_on_closed_pull_request = True !
443 # dont_allow_on_closed_pull_request = True !
430
444
431 try:
445 try:
432 ChangesetStatusModel().set_status(
446 ChangesetStatusModel().set_status(
433 self.db_repo.repo_id,
447 self.db_repo.repo_id,
434 status,
448 status,
435 self._rhodecode_db_user.user_id,
449 self._rhodecode_db_user.user_id,
436 comment,
450 comment,
437 revision=current_id,
451 revision=current_id,
438 dont_allow_on_closed_pull_request=True
452 dont_allow_on_closed_pull_request=True
439 )
453 )
440 except StatusChangeOnClosedPullRequestError:
454 except StatusChangeOnClosedPullRequestError:
441 msg = _('Changing the status of a commit associated with '
455 msg = _('Changing the status of a commit associated with '
442 'a closed pull request is not allowed')
456 'a closed pull request is not allowed')
443 log.exception(msg)
457 log.exception(msg)
444 h.flash(msg, category='warning')
458 h.flash(msg, category='warning')
445 raise HTTPFound(h.route_path(
459 raise HTTPFound(h.route_path(
446 'repo_commit', repo_name=self.db_repo_name,
460 'repo_commit', repo_name=self.db_repo_name,
447 commit_id=current_id))
461 commit_id=current_id))
448
462
449 # skip notifications for drafts
463 # skip notifications for drafts
450 if not is_draft:
464 if not is_draft:
451 commit = self.db_repo.get_commit(current_id)
465 commit = self.db_repo.get_commit(current_id)
452 CommentsModel().trigger_commit_comment_hook(
466 CommentsModel().trigger_commit_comment_hook(
453 self.db_repo, self._rhodecode_user, 'create',
467 self.db_repo, self._rhodecode_user, 'create',
454 data={'comment': comment, 'commit': commit})
468 data={'comment': comment, 'commit': commit})
455
469
456 comment_id = comment.comment_id
470 comment_id = comment.comment_id
457 data[comment_id] = {
471 data[comment_id] = {
458 'target_id': target_elem_id
472 'target_id': target_elem_id
459 }
473 }
460 c.co = comment
474 c.co = comment
461 c.at_version_num = 0
475 c.at_version_num = 0
462 c.is_new = True
476 c.is_new = True
463 rendered_comment = render(
477 rendered_comment = render(
464 'rhodecode:templates/changeset/changeset_comment_block.mako',
478 'rhodecode:templates/changeset/changeset_comment_block.mako',
465 self._get_template_context(c), self.request)
479 self._get_template_context(c), self.request)
466
480
467 data[comment_id].update(comment.get_dict())
481 data[comment_id].update(comment.get_dict())
468 data[comment_id].update({'rendered_text': rendered_comment})
482 data[comment_id].update({'rendered_text': rendered_comment})
469
483
470 # skip channelstream for draft comments
484 # skip channelstream for draft comments
471 if not is_draft:
485 if not is_draft:
472 comment_broadcast_channel = channelstream.comment_channel(
486 comment_broadcast_channel = channelstream.comment_channel(
473 self.db_repo_name, commit_obj=commit)
487 self.db_repo_name, commit_obj=commit)
474
488
475 comment_data = data
489 comment_data = data
476 posted_comment_type = 'inline' if is_inline else 'general'
490 posted_comment_type = 'inline' if is_inline else 'general'
477 channelstream.comment_channelstream_push(
491 channelstream.comment_channelstream_push(
478 self.request, comment_broadcast_channel, self._rhodecode_user,
492 self.request, comment_broadcast_channel, self._rhodecode_user,
479 _('posted a new {} comment').format(posted_comment_type),
493 _('posted a new {} comment').format(posted_comment_type),
480 comment_data=comment_data)
494 comment_data=comment_data)
481
495
482 # finalize, commit and redirect
496 # finalize, commit and redirect
483 Session().commit()
497 Session().commit()
484
498
485 return data
499 return data
486
500
487 @LoginRequired()
501 @LoginRequired()
488 @NotAnonymous()
502 @NotAnonymous()
489 @HasRepoPermissionAnyDecorator(
503 @HasRepoPermissionAnyDecorator(
490 'repository.read', 'repository.write', 'repository.admin')
504 'repository.read', 'repository.write', 'repository.admin')
491 @CSRFRequired()
505 @CSRFRequired()
492 @view_config(
506 @view_config(
493 route_name='repo_commit_comment_preview', request_method='POST',
507 route_name='repo_commit_comment_preview', request_method='POST',
494 renderer='string', xhr=True)
508 renderer='string', xhr=True)
495 def repo_commit_comment_preview(self):
509 def repo_commit_comment_preview(self):
496 # Technically a CSRF token is not needed as no state changes with this
510 # Technically a CSRF token is not needed as no state changes with this
497 # call. However, as this is a POST is better to have it, so automated
511 # call. However, as this is a POST is better to have it, so automated
498 # tools don't flag it as potential CSRF.
512 # tools don't flag it as potential CSRF.
499 # Post is required because the payload could be bigger than the maximum
513 # Post is required because the payload could be bigger than the maximum
500 # allowed by GET.
514 # allowed by GET.
501
515
502 text = self.request.POST.get('text')
516 text = self.request.POST.get('text')
503 renderer = self.request.POST.get('renderer') or 'rst'
517 renderer = self.request.POST.get('renderer') or 'rst'
504 if text:
518 if text:
505 return h.render(text, renderer=renderer, mentions=True,
519 return h.render(text, renderer=renderer, mentions=True,
506 repo_name=self.db_repo_name)
520 repo_name=self.db_repo_name)
507 return ''
521 return ''
508
522
509 @LoginRequired()
523 @LoginRequired()
510 @HasRepoPermissionAnyDecorator(
524 @HasRepoPermissionAnyDecorator(
511 'repository.read', 'repository.write', 'repository.admin')
525 'repository.read', 'repository.write', 'repository.admin')
512 @CSRFRequired()
526 @CSRFRequired()
513 @view_config(
527 @view_config(
514 route_name='repo_commit_comment_history_view', request_method='POST',
528 route_name='repo_commit_comment_history_view', request_method='POST',
515 renderer='string', xhr=True)
529 renderer='string', xhr=True)
516 def repo_commit_comment_history_view(self):
530 def repo_commit_comment_history_view(self):
517 c = self.load_default_context()
531 c = self.load_default_context()
518
532
519 comment_history_id = self.request.matchdict['comment_history_id']
533 comment_history_id = self.request.matchdict['comment_history_id']
520 comment_history = ChangesetCommentHistory.get_or_404(comment_history_id)
534 comment_history = ChangesetCommentHistory.get_or_404(comment_history_id)
521 is_repo_comment = comment_history.comment.repo.repo_id == self.db_repo.repo_id
535 is_repo_comment = comment_history.comment.repo.repo_id == self.db_repo.repo_id
522
536
523 if is_repo_comment:
537 if is_repo_comment:
524 c.comment_history = comment_history
538 c.comment_history = comment_history
525
539
526 rendered_comment = render(
540 rendered_comment = render(
527 'rhodecode:templates/changeset/comment_history.mako',
541 'rhodecode:templates/changeset/comment_history.mako',
528 self._get_template_context(c)
542 self._get_template_context(c)
529 , self.request)
543 , self.request)
530 return rendered_comment
544 return rendered_comment
531 else:
545 else:
532 log.warning('No permissions for user %s to show comment_history_id: %s',
546 log.warning('No permissions for user %s to show comment_history_id: %s',
533 self._rhodecode_db_user, comment_history_id)
547 self._rhodecode_db_user, comment_history_id)
534 raise HTTPNotFound()
548 raise HTTPNotFound()
535
549
536 @LoginRequired()
550 @LoginRequired()
537 @NotAnonymous()
551 @NotAnonymous()
538 @HasRepoPermissionAnyDecorator(
552 @HasRepoPermissionAnyDecorator(
539 'repository.read', 'repository.write', 'repository.admin')
553 'repository.read', 'repository.write', 'repository.admin')
540 @CSRFRequired()
554 @CSRFRequired()
541 @view_config(
555 @view_config(
542 route_name='repo_commit_comment_attachment_upload', request_method='POST',
556 route_name='repo_commit_comment_attachment_upload', request_method='POST',
543 renderer='json_ext', xhr=True)
557 renderer='json_ext', xhr=True)
544 def repo_commit_comment_attachment_upload(self):
558 def repo_commit_comment_attachment_upload(self):
545 c = self.load_default_context()
559 c = self.load_default_context()
546 upload_key = 'attachment'
560 upload_key = 'attachment'
547
561
548 file_obj = self.request.POST.get(upload_key)
562 file_obj = self.request.POST.get(upload_key)
549
563
550 if file_obj is None:
564 if file_obj is None:
551 self.request.response.status = 400
565 self.request.response.status = 400
552 return {'store_fid': None,
566 return {'store_fid': None,
553 'access_path': None,
567 'access_path': None,
554 'error': '{} data field is missing'.format(upload_key)}
568 'error': '{} data field is missing'.format(upload_key)}
555
569
556 if not hasattr(file_obj, 'filename'):
570 if not hasattr(file_obj, 'filename'):
557 self.request.response.status = 400
571 self.request.response.status = 400
558 return {'store_fid': None,
572 return {'store_fid': None,
559 'access_path': None,
573 'access_path': None,
560 'error': 'filename cannot be read from the data field'}
574 'error': 'filename cannot be read from the data field'}
561
575
562 filename = file_obj.filename
576 filename = file_obj.filename
563 file_display_name = filename
577 file_display_name = filename
564
578
565 metadata = {
579 metadata = {
566 'user_uploaded': {'username': self._rhodecode_user.username,
580 'user_uploaded': {'username': self._rhodecode_user.username,
567 'user_id': self._rhodecode_user.user_id,
581 'user_id': self._rhodecode_user.user_id,
568 'ip': self._rhodecode_user.ip_addr}}
582 'ip': self._rhodecode_user.ip_addr}}
569
583
570 # TODO(marcink): allow .ini configuration for allowed_extensions, and file-size
584 # TODO(marcink): allow .ini configuration for allowed_extensions, and file-size
571 allowed_extensions = [
585 allowed_extensions = [
572 'gif', '.jpeg', '.jpg', '.png', '.docx', '.gz', '.log', '.pdf',
586 'gif', '.jpeg', '.jpg', '.png', '.docx', '.gz', '.log', '.pdf',
573 '.pptx', '.txt', '.xlsx', '.zip']
587 '.pptx', '.txt', '.xlsx', '.zip']
574 max_file_size = 10 * 1024 * 1024 # 10MB, also validated via dropzone.js
588 max_file_size = 10 * 1024 * 1024 # 10MB, also validated via dropzone.js
575
589
576 try:
590 try:
577 storage = store_utils.get_file_storage(self.request.registry.settings)
591 storage = store_utils.get_file_storage(self.request.registry.settings)
578 store_uid, metadata = storage.save_file(
592 store_uid, metadata = storage.save_file(
579 file_obj.file, filename, extra_metadata=metadata,
593 file_obj.file, filename, extra_metadata=metadata,
580 extensions=allowed_extensions, max_filesize=max_file_size)
594 extensions=allowed_extensions, max_filesize=max_file_size)
581 except FileNotAllowedException:
595 except FileNotAllowedException:
582 self.request.response.status = 400
596 self.request.response.status = 400
583 permitted_extensions = ', '.join(allowed_extensions)
597 permitted_extensions = ', '.join(allowed_extensions)
584 error_msg = 'File `{}` is not allowed. ' \
598 error_msg = 'File `{}` is not allowed. ' \
585 'Only following extensions are permitted: {}'.format(
599 'Only following extensions are permitted: {}'.format(
586 filename, permitted_extensions)
600 filename, permitted_extensions)
587 return {'store_fid': None,
601 return {'store_fid': None,
588 'access_path': None,
602 'access_path': None,
589 'error': error_msg}
603 'error': error_msg}
590 except FileOverSizeException:
604 except FileOverSizeException:
591 self.request.response.status = 400
605 self.request.response.status = 400
592 limit_mb = h.format_byte_size_binary(max_file_size)
606 limit_mb = h.format_byte_size_binary(max_file_size)
593 return {'store_fid': None,
607 return {'store_fid': None,
594 'access_path': None,
608 'access_path': None,
595 'error': 'File {} is exceeding allowed limit of {}.'.format(
609 'error': 'File {} is exceeding allowed limit of {}.'.format(
596 filename, limit_mb)}
610 filename, limit_mb)}
597
611
598 try:
612 try:
599 entry = FileStore.create(
613 entry = FileStore.create(
600 file_uid=store_uid, filename=metadata["filename"],
614 file_uid=store_uid, filename=metadata["filename"],
601 file_hash=metadata["sha256"], file_size=metadata["size"],
615 file_hash=metadata["sha256"], file_size=metadata["size"],
602 file_display_name=file_display_name,
616 file_display_name=file_display_name,
603 file_description=u'comment attachment `{}`'.format(safe_unicode(filename)),
617 file_description=u'comment attachment `{}`'.format(safe_unicode(filename)),
604 hidden=True, check_acl=True, user_id=self._rhodecode_user.user_id,
618 hidden=True, check_acl=True, user_id=self._rhodecode_user.user_id,
605 scope_repo_id=self.db_repo.repo_id
619 scope_repo_id=self.db_repo.repo_id
606 )
620 )
607 Session().add(entry)
621 Session().add(entry)
608 Session().commit()
622 Session().commit()
609 log.debug('Stored upload in DB as %s', entry)
623 log.debug('Stored upload in DB as %s', entry)
610 except Exception:
624 except Exception:
611 log.exception('Failed to store file %s', filename)
625 log.exception('Failed to store file %s', filename)
612 self.request.response.status = 400
626 self.request.response.status = 400
613 return {'store_fid': None,
627 return {'store_fid': None,
614 'access_path': None,
628 'access_path': None,
615 'error': 'File {} failed to store in DB.'.format(filename)}
629 'error': 'File {} failed to store in DB.'.format(filename)}
616
630
617 Session().commit()
631 Session().commit()
618
632
619 return {
633 return {
620 'store_fid': store_uid,
634 'store_fid': store_uid,
621 'access_path': h.route_path(
635 'access_path': h.route_path(
622 'download_file', fid=store_uid),
636 'download_file', fid=store_uid),
623 'fqn_access_path': h.route_url(
637 'fqn_access_path': h.route_url(
624 'download_file', fid=store_uid),
638 'download_file', fid=store_uid),
625 'repo_access_path': h.route_path(
639 'repo_access_path': h.route_path(
626 'repo_artifacts_get', repo_name=self.db_repo_name, uid=store_uid),
640 'repo_artifacts_get', repo_name=self.db_repo_name, uid=store_uid),
627 'repo_fqn_access_path': h.route_url(
641 'repo_fqn_access_path': h.route_url(
628 'repo_artifacts_get', repo_name=self.db_repo_name, uid=store_uid),
642 'repo_artifacts_get', repo_name=self.db_repo_name, uid=store_uid),
629 }
643 }
630
644
631 @LoginRequired()
645 @LoginRequired()
632 @NotAnonymous()
646 @NotAnonymous()
633 @HasRepoPermissionAnyDecorator(
647 @HasRepoPermissionAnyDecorator(
634 'repository.read', 'repository.write', 'repository.admin')
648 'repository.read', 'repository.write', 'repository.admin')
635 @CSRFRequired()
649 @CSRFRequired()
636 @view_config(
650 @view_config(
637 route_name='repo_commit_comment_delete', request_method='POST',
651 route_name='repo_commit_comment_delete', request_method='POST',
638 renderer='json_ext')
652 renderer='json_ext')
639 def repo_commit_comment_delete(self):
653 def repo_commit_comment_delete(self):
640 commit_id = self.request.matchdict['commit_id']
654 commit_id = self.request.matchdict['commit_id']
641 comment_id = self.request.matchdict['comment_id']
655 comment_id = self.request.matchdict['comment_id']
642
656
643 comment = ChangesetComment.get_or_404(comment_id)
657 comment = ChangesetComment.get_or_404(comment_id)
644 if not comment:
658 if not comment:
645 log.debug('Comment with id:%s not found, skipping', comment_id)
659 log.debug('Comment with id:%s not found, skipping', comment_id)
646 # comment already deleted in another call probably
660 # comment already deleted in another call probably
647 return True
661 return True
648
662
649 if comment.immutable:
663 if comment.immutable:
650 # don't allow deleting comments that are immutable
664 # don't allow deleting comments that are immutable
651 raise HTTPForbidden()
665 raise HTTPForbidden()
652
666
653 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name)
667 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name)
654 super_admin = h.HasPermissionAny('hg.admin')()
668 super_admin = h.HasPermissionAny('hg.admin')()
655 comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id)
669 comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id)
656 is_repo_comment = comment.repo.repo_id == self.db_repo.repo_id
670 is_repo_comment = comment.repo.repo_id == self.db_repo.repo_id
657 comment_repo_admin = is_repo_admin and is_repo_comment
671 comment_repo_admin = is_repo_admin and is_repo_comment
658
672
659 if super_admin or comment_owner or comment_repo_admin:
673 if super_admin or comment_owner or comment_repo_admin:
660 CommentsModel().delete(comment=comment, auth_user=self._rhodecode_user)
674 CommentsModel().delete(comment=comment, auth_user=self._rhodecode_user)
661 Session().commit()
675 Session().commit()
662 return True
676 return True
663 else:
677 else:
664 log.warning('No permissions for user %s to delete comment_id: %s',
678 log.warning('No permissions for user %s to delete comment_id: %s',
665 self._rhodecode_db_user, comment_id)
679 self._rhodecode_db_user, comment_id)
666 raise HTTPNotFound()
680 raise HTTPNotFound()
667
681
668 @LoginRequired()
682 @LoginRequired()
669 @NotAnonymous()
683 @NotAnonymous()
670 @HasRepoPermissionAnyDecorator(
684 @HasRepoPermissionAnyDecorator(
671 'repository.read', 'repository.write', 'repository.admin')
685 'repository.read', 'repository.write', 'repository.admin')
672 @CSRFRequired()
686 @CSRFRequired()
673 @view_config(
687 @view_config(
674 route_name='repo_commit_comment_edit', request_method='POST',
688 route_name='repo_commit_comment_edit', request_method='POST',
675 renderer='json_ext')
689 renderer='json_ext')
676 def repo_commit_comment_edit(self):
690 def repo_commit_comment_edit(self):
677 self.load_default_context()
691 self.load_default_context()
678
692
679 comment_id = self.request.matchdict['comment_id']
693 comment_id = self.request.matchdict['comment_id']
680 comment = ChangesetComment.get_or_404(comment_id)
694 comment = ChangesetComment.get_or_404(comment_id)
681
695
682 if comment.immutable:
696 if comment.immutable:
683 # don't allow deleting comments that are immutable
697 # don't allow deleting comments that are immutable
684 raise HTTPForbidden()
698 raise HTTPForbidden()
685
699
686 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name)
700 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name)
687 super_admin = h.HasPermissionAny('hg.admin')()
701 super_admin = h.HasPermissionAny('hg.admin')()
688 comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id)
702 comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id)
689 is_repo_comment = comment.repo.repo_id == self.db_repo.repo_id
703 is_repo_comment = comment.repo.repo_id == self.db_repo.repo_id
690 comment_repo_admin = is_repo_admin and is_repo_comment
704 comment_repo_admin = is_repo_admin and is_repo_comment
691
705
692 if super_admin or comment_owner or comment_repo_admin:
706 if super_admin or comment_owner or comment_repo_admin:
693 text = self.request.POST.get('text')
707 text = self.request.POST.get('text')
694 version = self.request.POST.get('version')
708 version = self.request.POST.get('version')
695 if text == comment.text:
709 if text == comment.text:
696 log.warning(
710 log.warning(
697 'Comment(repo): '
711 'Comment(repo): '
698 'Trying to create new version '
712 'Trying to create new version '
699 'with the same comment body {}'.format(
713 'with the same comment body {}'.format(
700 comment_id,
714 comment_id,
701 )
715 )
702 )
716 )
703 raise HTTPNotFound()
717 raise HTTPNotFound()
704
718
705 if version.isdigit():
719 if version.isdigit():
706 version = int(version)
720 version = int(version)
707 else:
721 else:
708 log.warning(
722 log.warning(
709 'Comment(repo): Wrong version type {} {} '
723 'Comment(repo): Wrong version type {} {} '
710 'for comment {}'.format(
724 'for comment {}'.format(
711 version,
725 version,
712 type(version),
726 type(version),
713 comment_id,
727 comment_id,
714 )
728 )
715 )
729 )
716 raise HTTPNotFound()
730 raise HTTPNotFound()
717
731
718 try:
732 try:
719 comment_history = CommentsModel().edit(
733 comment_history = CommentsModel().edit(
720 comment_id=comment_id,
734 comment_id=comment_id,
721 text=text,
735 text=text,
722 auth_user=self._rhodecode_user,
736 auth_user=self._rhodecode_user,
723 version=version,
737 version=version,
724 )
738 )
725 except CommentVersionMismatch:
739 except CommentVersionMismatch:
726 raise HTTPConflict()
740 raise HTTPConflict()
727
741
728 if not comment_history:
742 if not comment_history:
729 raise HTTPNotFound()
743 raise HTTPNotFound()
730
744
731 commit_id = self.request.matchdict['commit_id']
745 commit_id = self.request.matchdict['commit_id']
732 commit = self.db_repo.get_commit(commit_id)
746 commit = self.db_repo.get_commit(commit_id)
733 CommentsModel().trigger_commit_comment_hook(
747 CommentsModel().trigger_commit_comment_hook(
734 self.db_repo, self._rhodecode_user, 'edit',
748 self.db_repo, self._rhodecode_user, 'edit',
735 data={'comment': comment, 'commit': commit})
749 data={'comment': comment, 'commit': commit})
736
750
737 Session().commit()
751 Session().commit()
738 return {
752 return {
739 'comment_history_id': comment_history.comment_history_id,
753 'comment_history_id': comment_history.comment_history_id,
740 'comment_id': comment.comment_id,
754 'comment_id': comment.comment_id,
741 'comment_version': comment_history.version,
755 'comment_version': comment_history.version,
742 'comment_author_username': comment_history.author.username,
756 'comment_author_username': comment_history.author.username,
743 'comment_author_gravatar': h.gravatar_url(comment_history.author.email, 16),
757 'comment_author_gravatar': h.gravatar_url(comment_history.author.email, 16),
744 'comment_created_on': h.age_component(comment_history.created_on,
758 'comment_created_on': h.age_component(comment_history.created_on,
745 time_is_local=True),
759 time_is_local=True),
746 }
760 }
747 else:
761 else:
748 log.warning('No permissions for user %s to edit comment_id: %s',
762 log.warning('No permissions for user %s to edit comment_id: %s',
749 self._rhodecode_db_user, comment_id)
763 self._rhodecode_db_user, comment_id)
750 raise HTTPNotFound()
764 raise HTTPNotFound()
751
765
752 @LoginRequired()
766 @LoginRequired()
753 @HasRepoPermissionAnyDecorator(
767 @HasRepoPermissionAnyDecorator(
754 'repository.read', 'repository.write', 'repository.admin')
768 'repository.read', 'repository.write', 'repository.admin')
755 @view_config(
769 @view_config(
756 route_name='repo_commit_data', request_method='GET',
770 route_name='repo_commit_data', request_method='GET',
757 renderer='json_ext', xhr=True)
771 renderer='json_ext', xhr=True)
758 def repo_commit_data(self):
772 def repo_commit_data(self):
759 commit_id = self.request.matchdict['commit_id']
773 commit_id = self.request.matchdict['commit_id']
760 self.load_default_context()
774 self.load_default_context()
761
775
762 try:
776 try:
763 return self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
777 return self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
764 except CommitDoesNotExistError as e:
778 except CommitDoesNotExistError as e:
765 return EmptyCommit(message=str(e))
779 return EmptyCommit(message=str(e))
766
780
767 @LoginRequired()
781 @LoginRequired()
768 @HasRepoPermissionAnyDecorator(
782 @HasRepoPermissionAnyDecorator(
769 'repository.read', 'repository.write', 'repository.admin')
783 'repository.read', 'repository.write', 'repository.admin')
770 @view_config(
784 @view_config(
771 route_name='repo_commit_children', request_method='GET',
785 route_name='repo_commit_children', request_method='GET',
772 renderer='json_ext', xhr=True)
786 renderer='json_ext', xhr=True)
773 def repo_commit_children(self):
787 def repo_commit_children(self):
774 commit_id = self.request.matchdict['commit_id']
788 commit_id = self.request.matchdict['commit_id']
775 self.load_default_context()
789 self.load_default_context()
776
790
777 try:
791 try:
778 commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
792 commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
779 children = commit.children
793 children = commit.children
780 except CommitDoesNotExistError:
794 except CommitDoesNotExistError:
781 children = []
795 children = []
782
796
783 result = {"results": children}
797 result = {"results": children}
784 return result
798 return result
785
799
786 @LoginRequired()
800 @LoginRequired()
787 @HasRepoPermissionAnyDecorator(
801 @HasRepoPermissionAnyDecorator(
788 'repository.read', 'repository.write', 'repository.admin')
802 'repository.read', 'repository.write', 'repository.admin')
789 @view_config(
803 @view_config(
790 route_name='repo_commit_parents', request_method='GET',
804 route_name='repo_commit_parents', request_method='GET',
791 renderer='json_ext')
805 renderer='json_ext')
792 def repo_commit_parents(self):
806 def repo_commit_parents(self):
793 commit_id = self.request.matchdict['commit_id']
807 commit_id = self.request.matchdict['commit_id']
794 self.load_default_context()
808 self.load_default_context()
795
809
796 try:
810 try:
797 commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
811 commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
798 parents = commit.parents
812 parents = commit.parents
799 except CommitDoesNotExistError:
813 except CommitDoesNotExistError:
800 parents = []
814 parents = []
801 result = {"results": parents}
815 result = {"results": parents}
802 return result
816 return result
@@ -1,3240 +1,3239 b''
1 //Primary CSS
1 //Primary CSS
2
2
3 //--- IMPORTS ------------------//
3 //--- IMPORTS ------------------//
4
4
5 @import 'helpers';
5 @import 'helpers';
6 @import 'mixins';
6 @import 'mixins';
7 @import 'rcicons';
7 @import 'rcicons';
8 @import 'variables';
8 @import 'variables';
9 @import 'bootstrap-variables';
9 @import 'bootstrap-variables';
10 @import 'form-bootstrap';
10 @import 'form-bootstrap';
11 @import 'codemirror';
11 @import 'codemirror';
12 @import 'legacy_code_styles';
12 @import 'legacy_code_styles';
13 @import 'readme-box';
13 @import 'readme-box';
14 @import 'progress-bar';
14 @import 'progress-bar';
15
15
16 @import 'type';
16 @import 'type';
17 @import 'alerts';
17 @import 'alerts';
18 @import 'buttons';
18 @import 'buttons';
19 @import 'tags';
19 @import 'tags';
20 @import 'code-block';
20 @import 'code-block';
21 @import 'examples';
21 @import 'examples';
22 @import 'login';
22 @import 'login';
23 @import 'main-content';
23 @import 'main-content';
24 @import 'select2';
24 @import 'select2';
25 @import 'comments';
25 @import 'comments';
26 @import 'panels-bootstrap';
26 @import 'panels-bootstrap';
27 @import 'panels';
27 @import 'panels';
28 @import 'deform';
28 @import 'deform';
29 @import 'tooltips';
29 @import 'tooltips';
30 @import 'sweetalert2';
30 @import 'sweetalert2';
31
31
32
32
33 //--- BASE ------------------//
33 //--- BASE ------------------//
34 .noscript-error {
34 .noscript-error {
35 top: 0;
35 top: 0;
36 left: 0;
36 left: 0;
37 width: 100%;
37 width: 100%;
38 z-index: 101;
38 z-index: 101;
39 text-align: center;
39 text-align: center;
40 font-size: 120%;
40 font-size: 120%;
41 color: white;
41 color: white;
42 background-color: @alert2;
42 background-color: @alert2;
43 padding: 5px 0 5px 0;
43 padding: 5px 0 5px 0;
44 font-weight: @text-semibold-weight;
44 font-weight: @text-semibold-weight;
45 font-family: @text-semibold;
45 font-family: @text-semibold;
46 }
46 }
47
47
48 html {
48 html {
49 display: table;
49 display: table;
50 height: 100%;
50 height: 100%;
51 width: 100%;
51 width: 100%;
52 }
52 }
53
53
54 body {
54 body {
55 display: table-cell;
55 display: table-cell;
56 width: 100%;
56 width: 100%;
57 }
57 }
58
58
59 //--- LAYOUT ------------------//
59 //--- LAYOUT ------------------//
60
60
61 .hidden{
61 .hidden{
62 display: none !important;
62 display: none !important;
63 }
63 }
64
64
65 .box{
65 .box{
66 float: left;
66 float: left;
67 width: 100%;
67 width: 100%;
68 }
68 }
69
69
70 .browser-header {
70 .browser-header {
71 clear: both;
71 clear: both;
72 }
72 }
73 .main {
73 .main {
74 clear: both;
74 clear: both;
75 padding:0 0 @pagepadding;
75 padding:0 0 @pagepadding;
76 height: auto;
76 height: auto;
77
77
78 &:after { //clearfix
78 &:after { //clearfix
79 content:"";
79 content:"";
80 clear:both;
80 clear:both;
81 width:100%;
81 width:100%;
82 display:block;
82 display:block;
83 }
83 }
84 }
84 }
85
85
86 .flex-container {
86 .flex-container {
87 display: flex;
87 display: flex;
88 justify-content: space-between;
88 justify-content: space-between;
89 }
89 }
90
90
91 .action-link{
91 .action-link{
92 margin-left: @padding;
92 margin-left: @padding;
93 padding-left: @padding;
93 padding-left: @padding;
94 border-left: @border-thickness solid @border-default-color;
94 border-left: @border-thickness solid @border-default-color;
95 }
95 }
96
96
97 .cursor-pointer {
97 .cursor-pointer {
98 cursor: pointer;
98 cursor: pointer;
99 }
99 }
100
100
101 input + .action-link, .action-link.first{
101 input + .action-link, .action-link.first{
102 border-left: none;
102 border-left: none;
103 }
103 }
104
104
105 .link-disabled {
105 .link-disabled {
106 color: @grey4;
106 color: @grey4;
107 cursor: default;
107 cursor: default;
108 }
108 }
109
109
110 .action-link.last{
110 .action-link.last{
111 margin-right: @padding;
111 margin-right: @padding;
112 padding-right: @padding;
112 padding-right: @padding;
113 }
113 }
114
114
115 .action-link.active,
115 .action-link.active,
116 .action-link.active a{
116 .action-link.active a{
117 color: @grey4;
117 color: @grey4;
118 }
118 }
119
119
120 .action-link.disabled {
120 .action-link.disabled {
121 color: @grey4;
121 color: @grey4;
122 cursor: inherit;
122 cursor: inherit;
123 }
123 }
124
124
125 .grey-link-action {
125 .grey-link-action {
126 cursor: pointer;
126 cursor: pointer;
127 &:hover {
127 &:hover {
128 color: @grey2;
128 color: @grey2;
129 }
129 }
130 color: @grey4;
130 color: @grey4;
131 }
131 }
132
132
133 .clipboard-action {
133 .clipboard-action {
134 cursor: pointer;
134 cursor: pointer;
135 margin-left: 5px;
135 margin-left: 5px;
136
136
137 &:not(.no-grey) {
137 &:not(.no-grey) {
138
138
139 &:hover {
139 &:hover {
140 color: @grey2;
140 color: @grey2;
141 }
141 }
142 color: @grey4;
142 color: @grey4;
143 }
143 }
144 }
144 }
145
145
146 ul.simple-list{
146 ul.simple-list{
147 list-style: none;
147 list-style: none;
148 margin: 0;
148 margin: 0;
149 padding: 0;
149 padding: 0;
150 }
150 }
151
151
152 .main-content {
152 .main-content {
153 padding-bottom: @pagepadding;
153 padding-bottom: @pagepadding;
154 }
154 }
155
155
156 .wide-mode-wrapper {
156 .wide-mode-wrapper {
157 max-width:4000px !important;
157 max-width:4000px !important;
158 }
158 }
159
159
160 .wrapper {
160 .wrapper {
161 position: relative;
161 position: relative;
162 max-width: @wrapper-maxwidth;
162 max-width: @wrapper-maxwidth;
163 margin: 0 auto;
163 margin: 0 auto;
164 }
164 }
165
165
166 #content {
166 #content {
167 clear: both;
167 clear: both;
168 padding: 0 @contentpadding;
168 padding: 0 @contentpadding;
169 }
169 }
170
170
171 .advanced-settings-fields{
171 .advanced-settings-fields{
172 input{
172 input{
173 margin-left: @textmargin;
173 margin-left: @textmargin;
174 margin-right: @padding/2;
174 margin-right: @padding/2;
175 }
175 }
176 }
176 }
177
177
178 .cs_files_title {
178 .cs_files_title {
179 margin: @pagepadding 0 0;
179 margin: @pagepadding 0 0;
180 }
180 }
181
181
182 input.inline[type="file"] {
182 input.inline[type="file"] {
183 display: inline;
183 display: inline;
184 }
184 }
185
185
186 .error_page {
186 .error_page {
187 margin: 10% auto;
187 margin: 10% auto;
188
188
189 h1 {
189 h1 {
190 color: @grey2;
190 color: @grey2;
191 }
191 }
192
192
193 .alert {
193 .alert {
194 margin: @padding 0;
194 margin: @padding 0;
195 }
195 }
196
196
197 .error-branding {
197 .error-branding {
198 color: @grey4;
198 color: @grey4;
199 font-weight: @text-semibold-weight;
199 font-weight: @text-semibold-weight;
200 font-family: @text-semibold;
200 font-family: @text-semibold;
201 }
201 }
202
202
203 .error_message {
203 .error_message {
204 font-family: @text-regular;
204 font-family: @text-regular;
205 }
205 }
206
206
207 .sidebar {
207 .sidebar {
208 min-height: 275px;
208 min-height: 275px;
209 margin: 0;
209 margin: 0;
210 padding: 0 0 @sidebarpadding @sidebarpadding;
210 padding: 0 0 @sidebarpadding @sidebarpadding;
211 border: none;
211 border: none;
212 }
212 }
213
213
214 .main-content {
214 .main-content {
215 position: relative;
215 position: relative;
216 margin: 0 @sidebarpadding @sidebarpadding;
216 margin: 0 @sidebarpadding @sidebarpadding;
217 padding: 0 0 0 @sidebarpadding;
217 padding: 0 0 0 @sidebarpadding;
218 border-left: @border-thickness solid @grey5;
218 border-left: @border-thickness solid @grey5;
219
219
220 @media (max-width:767px) {
220 @media (max-width:767px) {
221 clear: both;
221 clear: both;
222 width: 100%;
222 width: 100%;
223 margin: 0;
223 margin: 0;
224 border: none;
224 border: none;
225 }
225 }
226 }
226 }
227
227
228 .inner-column {
228 .inner-column {
229 float: left;
229 float: left;
230 width: 29.75%;
230 width: 29.75%;
231 min-height: 150px;
231 min-height: 150px;
232 margin: @sidebarpadding 2% 0 0;
232 margin: @sidebarpadding 2% 0 0;
233 padding: 0 2% 0 0;
233 padding: 0 2% 0 0;
234 border-right: @border-thickness solid @grey5;
234 border-right: @border-thickness solid @grey5;
235
235
236 @media (max-width:767px) {
236 @media (max-width:767px) {
237 clear: both;
237 clear: both;
238 width: 100%;
238 width: 100%;
239 border: none;
239 border: none;
240 }
240 }
241
241
242 ul {
242 ul {
243 padding-left: 1.25em;
243 padding-left: 1.25em;
244 }
244 }
245
245
246 &:last-child {
246 &:last-child {
247 margin: @sidebarpadding 0 0;
247 margin: @sidebarpadding 0 0;
248 border: none;
248 border: none;
249 }
249 }
250
250
251 h4 {
251 h4 {
252 margin: 0 0 @padding;
252 margin: 0 0 @padding;
253 font-weight: @text-semibold-weight;
253 font-weight: @text-semibold-weight;
254 font-family: @text-semibold;
254 font-family: @text-semibold;
255 }
255 }
256 }
256 }
257 }
257 }
258 .error-page-logo {
258 .error-page-logo {
259 width: 130px;
259 width: 130px;
260 height: 160px;
260 height: 160px;
261 }
261 }
262
262
263 // HEADER
263 // HEADER
264 .header {
264 .header {
265
265
266 min-height: 49px;
266 min-height: 49px;
267 min-width: 1024px;
267 min-width: 1024px;
268
268
269 position: relative;
269 position: relative;
270 vertical-align: bottom;
270 vertical-align: bottom;
271 padding: 0 @header-padding;
271 padding: 0 @header-padding;
272 background-color: @grey1;
272 background-color: @grey1;
273 color: @grey5;
273 color: @grey5;
274
274
275 .title {
275 .title {
276 overflow: visible;
276 overflow: visible;
277 }
277 }
278
278
279 &:before,
279 &:before,
280 &:after {
280 &:after {
281 content: "";
281 content: "";
282 clear: both;
282 clear: both;
283 width: 100%;
283 width: 100%;
284 }
284 }
285
285
286 // TODO: johbo: Avoids breaking "Repositories" chooser
286 // TODO: johbo: Avoids breaking "Repositories" chooser
287 .select2-container .select2-choice .select2-arrow {
287 .select2-container .select2-choice .select2-arrow {
288 display: none;
288 display: none;
289 }
289 }
290 }
290 }
291
291
292 #header-inner {
292 #header-inner {
293 &.title {
293 &.title {
294 margin: 0;
294 margin: 0;
295 }
295 }
296 &:before,
296 &:before,
297 &:after {
297 &:after {
298 content: "";
298 content: "";
299 clear: both;
299 clear: both;
300 }
300 }
301 }
301 }
302
302
303 // Gists
303 // Gists
304 #files_data {
304 #files_data {
305 clear: both; //for firefox
305 clear: both; //for firefox
306 padding-top: 10px;
306 padding-top: 10px;
307 }
307 }
308
308
309 #gistid {
309 #gistid {
310 margin-right: @padding;
310 margin-right: @padding;
311 }
311 }
312
312
313 // Global Settings Editor
313 // Global Settings Editor
314 .textarea.editor {
314 .textarea.editor {
315 float: left;
315 float: left;
316 position: relative;
316 position: relative;
317 max-width: @texteditor-width;
317 max-width: @texteditor-width;
318
318
319 select {
319 select {
320 position: absolute;
320 position: absolute;
321 top:10px;
321 top:10px;
322 right:0;
322 right:0;
323 }
323 }
324
324
325 .CodeMirror {
325 .CodeMirror {
326 margin: 0;
326 margin: 0;
327 }
327 }
328
328
329 .help-block {
329 .help-block {
330 margin: 0 0 @padding;
330 margin: 0 0 @padding;
331 padding:.5em;
331 padding:.5em;
332 background-color: @grey6;
332 background-color: @grey6;
333 &.pre-formatting {
333 &.pre-formatting {
334 white-space: pre;
334 white-space: pre;
335 }
335 }
336 }
336 }
337 }
337 }
338
338
339 ul.auth_plugins {
339 ul.auth_plugins {
340 margin: @padding 0 @padding @legend-width;
340 margin: @padding 0 @padding @legend-width;
341 padding: 0;
341 padding: 0;
342
342
343 li {
343 li {
344 margin-bottom: @padding;
344 margin-bottom: @padding;
345 line-height: 1em;
345 line-height: 1em;
346 list-style-type: none;
346 list-style-type: none;
347
347
348 .auth_buttons .btn {
348 .auth_buttons .btn {
349 margin-right: @padding;
349 margin-right: @padding;
350 }
350 }
351
351
352 }
352 }
353 }
353 }
354
354
355
355
356 // My Account PR list
356 // My Account PR list
357
357
358 #show_closed {
358 #show_closed {
359 margin: 0 1em 0 0;
359 margin: 0 1em 0 0;
360 }
360 }
361
361
362 #pull_request_list_table {
362 #pull_request_list_table {
363 .closed {
363 .closed {
364 background-color: @grey6;
364 background-color: @grey6;
365 }
365 }
366
366
367 .state-creating,
367 .state-creating,
368 .state-updating,
368 .state-updating,
369 .state-merging
369 .state-merging
370 {
370 {
371 background-color: @grey6;
371 background-color: @grey6;
372 }
372 }
373
373
374 .log-container .truncate {
374 .log-container .truncate {
375 height: 2.75em;
375 height: 2.75em;
376 white-space: pre-line;
376 white-space: pre-line;
377 }
377 }
378 table.rctable .user {
378 table.rctable .user {
379 padding-left: 0;
379 padding-left: 0;
380 }
380 }
381 .td-status {
381 .td-status {
382 padding: 0 0px 0px 10px;
382 padding: 0 0px 0px 10px;
383 width: 15px;
383 width: 15px;
384 }
384 }
385 table.rctable {
385 table.rctable {
386 td.td-description,
386 td.td-description,
387 .rc-user {
387 .rc-user {
388 min-width: auto;
388 min-width: auto;
389 }
389 }
390 }
390 }
391 }
391 }
392
392
393 // Pull Requests
393 // Pull Requests
394
394
395 .pullrequests_section_head {
395 .pullrequests_section_head {
396 display: block;
396 display: block;
397 clear: both;
397 clear: both;
398 margin: @padding 0;
398 margin: @padding 0;
399 font-weight: @text-bold-weight;
399 font-weight: @text-bold-weight;
400 font-family: @text-bold;
400 font-family: @text-bold;
401 }
401 }
402
402
403 .pr-commit-flow {
403 .pr-commit-flow {
404 position: relative;
404 position: relative;
405 font-weight: 600;
405 font-weight: 600;
406
406
407 .tag {
407 .tag {
408 display: inline-block;
408 display: inline-block;
409 margin: 0 1em .5em 0;
409 margin: 0 1em .5em 0;
410 }
410 }
411
411
412 .clone-url {
412 .clone-url {
413 display: inline-block;
413 display: inline-block;
414 margin: 0 0 .5em 0;
414 margin: 0 0 .5em 0;
415 padding: 0;
415 padding: 0;
416 line-height: 1.2em;
416 line-height: 1.2em;
417 }
417 }
418 }
418 }
419
419
420 .pr-mergeinfo {
420 .pr-mergeinfo {
421 min-width: 95% !important;
421 min-width: 95% !important;
422 padding: 0 !important;
422 padding: 0 !important;
423 border: 0;
423 border: 0;
424 }
424 }
425 .pr-mergeinfo-copy {
425 .pr-mergeinfo-copy {
426 padding: 0 0;
426 padding: 0 0;
427 }
427 }
428
428
429 .pr-pullinfo {
429 .pr-pullinfo {
430 min-width: 95% !important;
430 min-width: 95% !important;
431 padding: 0 !important;
431 padding: 0 !important;
432 border: 0;
432 border: 0;
433 }
433 }
434 .pr-pullinfo-copy {
434 .pr-pullinfo-copy {
435 padding: 0 0;
435 padding: 0 0;
436 }
436 }
437
437
438 .pr-title-input {
438 .pr-title-input {
439 width: 100%;
439 width: 100%;
440 font-size: 18px;
440 font-size: 18px;
441 margin: 0 0 4px 0;
441 margin: 0 0 4px 0;
442 padding: 0;
442 padding: 0;
443 line-height: 1.7em;
443 line-height: 1.7em;
444 color: @text-color;
444 color: @text-color;
445 letter-spacing: .02em;
445 letter-spacing: .02em;
446 font-weight: @text-bold-weight;
446 font-weight: @text-bold-weight;
447 font-family: @text-bold;
447 font-family: @text-bold;
448
448
449 &:hover {
449 &:hover {
450 box-shadow: none;
450 box-shadow: none;
451 }
451 }
452 }
452 }
453
453
454 #pr-title {
454 #pr-title {
455 input {
455 input {
456 border: 1px transparent;
456 border: 1px transparent;
457 color: black;
457 color: black;
458 opacity: 1;
458 opacity: 1;
459 background: #fff;
459 background: #fff;
460 font-size: 18px;
460 font-size: 18px;
461 }
461 }
462 }
462 }
463
463
464 .pr-title-closed-tag {
464 .pr-title-closed-tag {
465 font-size: 16px;
465 font-size: 16px;
466 }
466 }
467
467
468 #pr-desc {
468 #pr-desc {
469 padding: 10px 0;
469 padding: 10px 0;
470
470
471 .markdown-block {
471 .markdown-block {
472 padding: 0;
472 padding: 0;
473 margin-bottom: -30px;
473 margin-bottom: -30px;
474 }
474 }
475 }
475 }
476
476
477 #pullrequest_title {
477 #pullrequest_title {
478 width: 100%;
478 width: 100%;
479 box-sizing: border-box;
479 box-sizing: border-box;
480 }
480 }
481
481
482 #pr_open_message {
482 #pr_open_message {
483 border: @border-thickness solid #fff;
483 border: @border-thickness solid #fff;
484 border-radius: @border-radius;
484 border-radius: @border-radius;
485 text-align: left;
485 text-align: left;
486 overflow: hidden;
486 overflow: hidden;
487 white-space: pre-line;
487 white-space: pre-line;
488 padding-top: 5px
488 padding-top: 5px
489 }
489 }
490
490
491 #add_reviewer {
491 #add_reviewer {
492 padding-top: 10px;
492 padding-top: 10px;
493 }
493 }
494
494
495 #add_reviewer_input,
495 #add_reviewer_input,
496 #add_observer_input {
496 #add_observer_input {
497 padding-top: 10px
497 padding-top: 10px
498 }
498 }
499
499
500 .pr-details-title-author-pref {
500 .pr-details-title-author-pref {
501 padding-right: 10px
501 padding-right: 10px
502 }
502 }
503
503
504 .label-pr-detail {
504 .label-pr-detail {
505 display: table-cell;
505 display: table-cell;
506 width: 120px;
506 width: 120px;
507 padding-top: 7.5px;
507 padding-top: 7.5px;
508 padding-bottom: 7.5px;
508 padding-bottom: 7.5px;
509 padding-right: 7.5px;
509 padding-right: 7.5px;
510 }
510 }
511
511
512 .source-details ul {
512 .source-details ul {
513 padding: 10px 16px;
513 padding: 10px 16px;
514 }
514 }
515
515
516 .source-details-action {
516 .source-details-action {
517 color: @grey4;
517 color: @grey4;
518 font-size: 11px
518 font-size: 11px
519 }
519 }
520
520
521 .pr-submit-button {
521 .pr-submit-button {
522 float: right;
522 float: right;
523 margin: 0 0 0 5px;
523 margin: 0 0 0 5px;
524 }
524 }
525
525
526 .pr-spacing-container {
526 .pr-spacing-container {
527 padding: 20px;
527 padding: 20px;
528 clear: both
528 clear: both
529 }
529 }
530
530
531 #pr-description-input {
531 #pr-description-input {
532 margin-bottom: 0;
532 margin-bottom: 0;
533 }
533 }
534
534
535 .pr-description-label {
535 .pr-description-label {
536 vertical-align: top;
536 vertical-align: top;
537 }
537 }
538
538
539 #open_edit_pullrequest {
539 #open_edit_pullrequest {
540 padding: 0;
540 padding: 0;
541 }
541 }
542
542
543 #close_edit_pullrequest {
543 #close_edit_pullrequest {
544
544
545 }
545 }
546
546
547 #delete_pullrequest {
547 #delete_pullrequest {
548 clear: inherit;
548 clear: inherit;
549
549
550 form {
550 form {
551 display: inline;
551 display: inline;
552 }
552 }
553
553
554 }
554 }
555
555
556 .perms_section_head {
556 .perms_section_head {
557 min-width: 625px;
557 min-width: 625px;
558
558
559 h2 {
559 h2 {
560 margin-bottom: 0;
560 margin-bottom: 0;
561 }
561 }
562
562
563 .label-checkbox {
563 .label-checkbox {
564 float: left;
564 float: left;
565 }
565 }
566
566
567 &.field {
567 &.field {
568 margin: @space 0 @padding;
568 margin: @space 0 @padding;
569 }
569 }
570
570
571 &:first-child.field {
571 &:first-child.field {
572 margin-top: 0;
572 margin-top: 0;
573
573
574 .label {
574 .label {
575 margin-top: 0;
575 margin-top: 0;
576 padding-top: 0;
576 padding-top: 0;
577 }
577 }
578
578
579 .radios {
579 .radios {
580 padding-top: 0;
580 padding-top: 0;
581 }
581 }
582 }
582 }
583
583
584 .radios {
584 .radios {
585 position: relative;
585 position: relative;
586 width: 505px;
586 width: 505px;
587 }
587 }
588 }
588 }
589
589
590 //--- MODULES ------------------//
590 //--- MODULES ------------------//
591
591
592
592
593 // Server Announcement
593 // Server Announcement
594 #server-announcement {
594 #server-announcement {
595 width: 95%;
595 width: 95%;
596 margin: @padding auto;
596 margin: @padding auto;
597 padding: @padding;
597 padding: @padding;
598 border-width: 2px;
598 border-width: 2px;
599 border-style: solid;
599 border-style: solid;
600 .border-radius(2px);
600 .border-radius(2px);
601 font-weight: @text-bold-weight;
601 font-weight: @text-bold-weight;
602 font-family: @text-bold;
602 font-family: @text-bold;
603
603
604 &.info { border-color: @alert4; background-color: @alert4-inner; }
604 &.info { border-color: @alert4; background-color: @alert4-inner; }
605 &.warning { border-color: @alert3; background-color: @alert3-inner; }
605 &.warning { border-color: @alert3; background-color: @alert3-inner; }
606 &.error { border-color: @alert2; background-color: @alert2-inner; }
606 &.error { border-color: @alert2; background-color: @alert2-inner; }
607 &.success { border-color: @alert1; background-color: @alert1-inner; }
607 &.success { border-color: @alert1; background-color: @alert1-inner; }
608 &.neutral { border-color: @grey3; background-color: @grey6; }
608 &.neutral { border-color: @grey3; background-color: @grey6; }
609 }
609 }
610
610
611 // Fixed Sidebar Column
611 // Fixed Sidebar Column
612 .sidebar-col-wrapper {
612 .sidebar-col-wrapper {
613 padding-left: @sidebar-all-width;
613 padding-left: @sidebar-all-width;
614
614
615 .sidebar {
615 .sidebar {
616 width: @sidebar-width;
616 width: @sidebar-width;
617 margin-left: -@sidebar-all-width;
617 margin-left: -@sidebar-all-width;
618 }
618 }
619 }
619 }
620
620
621 .sidebar-col-wrapper.scw-small {
621 .sidebar-col-wrapper.scw-small {
622 padding-left: @sidebar-small-all-width;
622 padding-left: @sidebar-small-all-width;
623
623
624 .sidebar {
624 .sidebar {
625 width: @sidebar-small-width;
625 width: @sidebar-small-width;
626 margin-left: -@sidebar-small-all-width;
626 margin-left: -@sidebar-small-all-width;
627 }
627 }
628 }
628 }
629
629
630
630
631 // FOOTER
631 // FOOTER
632 #footer {
632 #footer {
633 padding: 0;
633 padding: 0;
634 text-align: center;
634 text-align: center;
635 vertical-align: middle;
635 vertical-align: middle;
636 color: @grey2;
636 color: @grey2;
637 font-size: 11px;
637 font-size: 11px;
638
638
639 p {
639 p {
640 margin: 0;
640 margin: 0;
641 padding: 1em;
641 padding: 1em;
642 line-height: 1em;
642 line-height: 1em;
643 }
643 }
644
644
645 .server-instance { //server instance
645 .server-instance { //server instance
646 display: none;
646 display: none;
647 }
647 }
648
648
649 .title {
649 .title {
650 float: none;
650 float: none;
651 margin: 0 auto;
651 margin: 0 auto;
652 }
652 }
653 }
653 }
654
654
655 button.close {
655 button.close {
656 padding: 0;
656 padding: 0;
657 cursor: pointer;
657 cursor: pointer;
658 background: transparent;
658 background: transparent;
659 border: 0;
659 border: 0;
660 .box-shadow(none);
660 .box-shadow(none);
661 -webkit-appearance: none;
661 -webkit-appearance: none;
662 }
662 }
663
663
664 .close {
664 .close {
665 float: right;
665 float: right;
666 font-size: 21px;
666 font-size: 21px;
667 font-family: @text-bootstrap;
667 font-family: @text-bootstrap;
668 line-height: 1em;
668 line-height: 1em;
669 font-weight: bold;
669 font-weight: bold;
670 color: @grey2;
670 color: @grey2;
671
671
672 &:hover,
672 &:hover,
673 &:focus {
673 &:focus {
674 color: @grey1;
674 color: @grey1;
675 text-decoration: none;
675 text-decoration: none;
676 cursor: pointer;
676 cursor: pointer;
677 }
677 }
678 }
678 }
679
679
680 // GRID
680 // GRID
681 .sorting,
681 .sorting,
682 .sorting_desc,
682 .sorting_desc,
683 .sorting_asc {
683 .sorting_asc {
684 cursor: pointer;
684 cursor: pointer;
685 }
685 }
686 .sorting_desc:after {
686 .sorting_desc:after {
687 content: "\00A0\25B2";
687 content: "\00A0\25B2";
688 font-size: .75em;
688 font-size: .75em;
689 }
689 }
690 .sorting_asc:after {
690 .sorting_asc:after {
691 content: "\00A0\25BC";
691 content: "\00A0\25BC";
692 font-size: .68em;
692 font-size: .68em;
693 }
693 }
694
694
695
695
696 .user_auth_tokens {
696 .user_auth_tokens {
697
697
698 &.truncate {
698 &.truncate {
699 white-space: nowrap;
699 white-space: nowrap;
700 overflow: hidden;
700 overflow: hidden;
701 text-overflow: ellipsis;
701 text-overflow: ellipsis;
702 }
702 }
703
703
704 .fields .field .input {
704 .fields .field .input {
705 margin: 0;
705 margin: 0;
706 }
706 }
707
707
708 input#description {
708 input#description {
709 width: 100px;
709 width: 100px;
710 margin: 0;
710 margin: 0;
711 }
711 }
712
712
713 .drop-menu {
713 .drop-menu {
714 // TODO: johbo: Remove this, should work out of the box when
714 // TODO: johbo: Remove this, should work out of the box when
715 // having multiple inputs inline
715 // having multiple inputs inline
716 margin: 0 0 0 5px;
716 margin: 0 0 0 5px;
717 }
717 }
718 }
718 }
719 #user_list_table {
719 #user_list_table {
720 .closed {
720 .closed {
721 background-color: @grey6;
721 background-color: @grey6;
722 }
722 }
723 }
723 }
724
724
725
725
726 input, textarea {
726 input, textarea {
727 &.disabled {
727 &.disabled {
728 opacity: .5;
728 opacity: .5;
729 }
729 }
730
730
731 &:hover {
731 &:hover {
732 border-color: @grey3;
732 border-color: @grey3;
733 box-shadow: @button-shadow;
733 box-shadow: @button-shadow;
734 }
734 }
735
735
736 &:focus {
736 &:focus {
737 border-color: @rcblue;
737 border-color: @rcblue;
738 box-shadow: @button-shadow;
738 box-shadow: @button-shadow;
739 }
739 }
740 }
740 }
741
741
742 // remove extra padding in firefox
742 // remove extra padding in firefox
743 input::-moz-focus-inner { border:0; padding:0 }
743 input::-moz-focus-inner { border:0; padding:0 }
744
744
745 .adjacent input {
745 .adjacent input {
746 margin-bottom: @padding;
746 margin-bottom: @padding;
747 }
747 }
748
748
749 .permissions_boxes {
749 .permissions_boxes {
750 display: block;
750 display: block;
751 }
751 }
752
752
753 //FORMS
753 //FORMS
754
754
755 .medium-inline,
755 .medium-inline,
756 input#description.medium-inline {
756 input#description.medium-inline {
757 display: inline;
757 display: inline;
758 width: @medium-inline-input-width;
758 width: @medium-inline-input-width;
759 min-width: 100px;
759 min-width: 100px;
760 }
760 }
761
761
762 select {
762 select {
763 //reset
763 //reset
764 -webkit-appearance: none;
764 -webkit-appearance: none;
765 -moz-appearance: none;
765 -moz-appearance: none;
766
766
767 display: inline-block;
767 display: inline-block;
768 height: 28px;
768 height: 28px;
769 width: auto;
769 width: auto;
770 margin: 0 @padding @padding 0;
770 margin: 0 @padding @padding 0;
771 padding: 0 18px 0 8px;
771 padding: 0 18px 0 8px;
772 line-height:1em;
772 line-height:1em;
773 font-size: @basefontsize;
773 font-size: @basefontsize;
774 border: @border-thickness solid @grey5;
774 border: @border-thickness solid @grey5;
775 border-radius: @border-radius;
775 border-radius: @border-radius;
776 background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%;
776 background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%;
777 color: @grey4;
777 color: @grey4;
778 box-shadow: @button-shadow;
778 box-shadow: @button-shadow;
779
779
780 &:after {
780 &:after {
781 content: "\00A0\25BE";
781 content: "\00A0\25BE";
782 }
782 }
783
783
784 &:focus, &:hover {
784 &:focus, &:hover {
785 outline: none;
785 outline: none;
786 border-color: @grey4;
786 border-color: @grey4;
787 color: @rcdarkblue;
787 color: @rcdarkblue;
788 }
788 }
789 }
789 }
790
790
791 option {
791 option {
792 &:focus {
792 &:focus {
793 outline: none;
793 outline: none;
794 }
794 }
795 }
795 }
796
796
797 input,
797 input,
798 textarea {
798 textarea {
799 padding: @input-padding;
799 padding: @input-padding;
800 border: @input-border-thickness solid @border-highlight-color;
800 border: @input-border-thickness solid @border-highlight-color;
801 .border-radius (@border-radius);
801 .border-radius (@border-radius);
802 font-family: @text-light;
802 font-family: @text-light;
803 font-size: @basefontsize;
803 font-size: @basefontsize;
804
804
805 &.input-sm {
805 &.input-sm {
806 padding: 5px;
806 padding: 5px;
807 }
807 }
808
808
809 &#description {
809 &#description {
810 min-width: @input-description-minwidth;
810 min-width: @input-description-minwidth;
811 min-height: 1em;
811 min-height: 1em;
812 padding: 10px;
812 padding: 10px;
813 }
813 }
814 }
814 }
815
815
816 .field-sm {
816 .field-sm {
817 input,
817 input,
818 textarea {
818 textarea {
819 padding: 5px;
819 padding: 5px;
820 }
820 }
821 }
821 }
822
822
823 textarea {
823 textarea {
824 display: block;
824 display: block;
825 clear: both;
825 clear: both;
826 width: 100%;
826 width: 100%;
827 min-height: 100px;
827 min-height: 100px;
828 margin-bottom: @padding;
828 margin-bottom: @padding;
829 .box-sizing(border-box);
829 .box-sizing(border-box);
830 overflow: auto;
830 overflow: auto;
831 }
831 }
832
832
833 label {
833 label {
834 font-family: @text-light;
834 font-family: @text-light;
835 }
835 }
836
836
837 // GRAVATARS
837 // GRAVATARS
838 // centers gravatar on username to the right
838 // centers gravatar on username to the right
839
839
840 .gravatar {
840 .gravatar {
841 display: inline;
841 display: inline;
842 min-width: 16px;
842 min-width: 16px;
843 min-height: 16px;
843 min-height: 16px;
844 margin: -5px 0;
844 margin: -5px 0;
845 padding: 0;
845 padding: 0;
846 line-height: 1em;
846 line-height: 1em;
847 box-sizing: content-box;
847 box-sizing: content-box;
848 border-radius: 50%;
848 border-radius: 50%;
849
849
850 &.gravatar-large {
850 &.gravatar-large {
851 margin: -0.5em .25em -0.5em 0;
851 margin: -0.5em .25em -0.5em 0;
852 }
852 }
853
853
854 & + .user {
854 & + .user {
855 display: inline;
855 display: inline;
856 margin: 0;
856 margin: 0;
857 padding: 0 0 0 .17em;
857 padding: 0 0 0 .17em;
858 line-height: 1em;
858 line-height: 1em;
859 }
859 }
860
860
861 & + .no-margin {
861 & + .no-margin {
862 margin: 0
862 margin: 0
863 }
863 }
864
864
865 }
865 }
866
866
867 .user-inline-data {
867 .user-inline-data {
868 display: inline-block;
868 display: inline-block;
869 float: left;
869 float: left;
870 padding-left: .5em;
870 padding-left: .5em;
871 line-height: 1.3em;
871 line-height: 1.3em;
872 }
872 }
873
873
874 .rc-user { // gravatar + user wrapper
874 .rc-user { // gravatar + user wrapper
875 float: left;
875 float: left;
876 position: relative;
876 position: relative;
877 min-width: 100px;
877 min-width: 100px;
878 max-width: 200px;
878 max-width: 200px;
879 min-height: (@gravatar-size + @border-thickness * 2); // account for border
879 min-height: (@gravatar-size + @border-thickness * 2); // account for border
880 display: block;
880 display: block;
881 padding: 0 0 0 (@gravatar-size + @basefontsize/4);
881 padding: 0 0 0 (@gravatar-size + @basefontsize/4);
882
882
883
883
884 .gravatar {
884 .gravatar {
885 display: block;
885 display: block;
886 position: absolute;
886 position: absolute;
887 top: 0;
887 top: 0;
888 left: 0;
888 left: 0;
889 min-width: @gravatar-size;
889 min-width: @gravatar-size;
890 min-height: @gravatar-size;
890 min-height: @gravatar-size;
891 margin: 0;
891 margin: 0;
892 }
892 }
893
893
894 .user {
894 .user {
895 display: block;
895 display: block;
896 max-width: 175px;
896 max-width: 175px;
897 padding-top: 2px;
897 padding-top: 2px;
898 overflow: hidden;
898 overflow: hidden;
899 text-overflow: ellipsis;
899 text-overflow: ellipsis;
900 }
900 }
901 }
901 }
902
902
903 .gist-gravatar,
903 .gist-gravatar,
904 .journal_container {
904 .journal_container {
905 .gravatar-large {
905 .gravatar-large {
906 margin: 0 .5em -10px 0;
906 margin: 0 .5em -10px 0;
907 }
907 }
908 }
908 }
909
909
910 .gist-type-fields {
910 .gist-type-fields {
911 line-height: 30px;
911 line-height: 30px;
912 height: 30px;
912 height: 30px;
913
913
914 .gist-type-fields-wrapper {
914 .gist-type-fields-wrapper {
915 vertical-align: middle;
915 vertical-align: middle;
916 display: inline-block;
916 display: inline-block;
917 line-height: 25px;
917 line-height: 25px;
918 }
918 }
919 }
919 }
920
920
921 // ADMIN SETTINGS
921 // ADMIN SETTINGS
922
922
923 // Tag Patterns
923 // Tag Patterns
924 .tag_patterns {
924 .tag_patterns {
925 .tag_input {
925 .tag_input {
926 margin-bottom: @padding;
926 margin-bottom: @padding;
927 }
927 }
928 }
928 }
929
929
930 .locked_input {
930 .locked_input {
931 position: relative;
931 position: relative;
932
932
933 input {
933 input {
934 display: inline;
934 display: inline;
935 margin: 3px 5px 0px 0px;
935 margin: 3px 5px 0px 0px;
936 }
936 }
937
937
938 br {
938 br {
939 display: none;
939 display: none;
940 }
940 }
941
941
942 .error-message {
942 .error-message {
943 float: left;
943 float: left;
944 width: 100%;
944 width: 100%;
945 }
945 }
946
946
947 .lock_input_button {
947 .lock_input_button {
948 display: inline;
948 display: inline;
949 }
949 }
950
950
951 .help-block {
951 .help-block {
952 clear: both;
952 clear: both;
953 }
953 }
954 }
954 }
955
955
956 // Notifications
956 // Notifications
957
957
958 .notifications_buttons {
958 .notifications_buttons {
959 margin: 0 0 @space 0;
959 margin: 0 0 @space 0;
960 padding: 0;
960 padding: 0;
961
961
962 .btn {
962 .btn {
963 display: inline-block;
963 display: inline-block;
964 }
964 }
965 }
965 }
966
966
967 .notification-list {
967 .notification-list {
968
968
969 div {
969 div {
970 vertical-align: middle;
970 vertical-align: middle;
971 }
971 }
972
972
973 .container {
973 .container {
974 display: block;
974 display: block;
975 margin: 0 0 @padding 0;
975 margin: 0 0 @padding 0;
976 }
976 }
977
977
978 .delete-notifications {
978 .delete-notifications {
979 margin-left: @padding;
979 margin-left: @padding;
980 text-align: right;
980 text-align: right;
981 cursor: pointer;
981 cursor: pointer;
982 }
982 }
983
983
984 .read-notifications {
984 .read-notifications {
985 margin-left: @padding/2;
985 margin-left: @padding/2;
986 text-align: right;
986 text-align: right;
987 width: 35px;
987 width: 35px;
988 cursor: pointer;
988 cursor: pointer;
989 }
989 }
990
990
991 .icon-minus-sign {
991 .icon-minus-sign {
992 color: @alert2;
992 color: @alert2;
993 }
993 }
994
994
995 .icon-ok-sign {
995 .icon-ok-sign {
996 color: @alert1;
996 color: @alert1;
997 }
997 }
998 }
998 }
999
999
1000 .user_settings {
1000 .user_settings {
1001 float: left;
1001 float: left;
1002 clear: both;
1002 clear: both;
1003 display: block;
1003 display: block;
1004 width: 100%;
1004 width: 100%;
1005
1005
1006 .gravatar_box {
1006 .gravatar_box {
1007 margin-bottom: @padding;
1007 margin-bottom: @padding;
1008
1008
1009 &:after {
1009 &:after {
1010 content: " ";
1010 content: " ";
1011 clear: both;
1011 clear: both;
1012 width: 100%;
1012 width: 100%;
1013 }
1013 }
1014 }
1014 }
1015
1015
1016 .fields .field {
1016 .fields .field {
1017 clear: both;
1017 clear: both;
1018 }
1018 }
1019 }
1019 }
1020
1020
1021 .advanced_settings {
1021 .advanced_settings {
1022 margin-bottom: @space;
1022 margin-bottom: @space;
1023
1023
1024 .help-block {
1024 .help-block {
1025 margin-left: 0;
1025 margin-left: 0;
1026 }
1026 }
1027
1027
1028 button + .help-block {
1028 button + .help-block {
1029 margin-top: @padding;
1029 margin-top: @padding;
1030 }
1030 }
1031 }
1031 }
1032
1032
1033 // admin settings radio buttons and labels
1033 // admin settings radio buttons and labels
1034 .label-2 {
1034 .label-2 {
1035 float: left;
1035 float: left;
1036 width: @label2-width;
1036 width: @label2-width;
1037
1037
1038 label {
1038 label {
1039 color: @grey1;
1039 color: @grey1;
1040 }
1040 }
1041 }
1041 }
1042 .checkboxes {
1042 .checkboxes {
1043 float: left;
1043 float: left;
1044 width: @checkboxes-width;
1044 width: @checkboxes-width;
1045 margin-bottom: @padding;
1045 margin-bottom: @padding;
1046
1046
1047 .checkbox {
1047 .checkbox {
1048 width: 100%;
1048 width: 100%;
1049
1049
1050 label {
1050 label {
1051 margin: 0;
1051 margin: 0;
1052 padding: 0;
1052 padding: 0;
1053 }
1053 }
1054 }
1054 }
1055
1055
1056 .checkbox + .checkbox {
1056 .checkbox + .checkbox {
1057 display: inline-block;
1057 display: inline-block;
1058 }
1058 }
1059
1059
1060 label {
1060 label {
1061 margin-right: 1em;
1061 margin-right: 1em;
1062 }
1062 }
1063 }
1063 }
1064
1064
1065 // CHANGELOG
1065 // CHANGELOG
1066 .container_header {
1066 .container_header {
1067 float: left;
1067 float: left;
1068 display: block;
1068 display: block;
1069 width: 100%;
1069 width: 100%;
1070 margin: @padding 0 @padding;
1070 margin: @padding 0 @padding;
1071
1071
1072 #filter_changelog {
1072 #filter_changelog {
1073 float: left;
1073 float: left;
1074 margin-right: @padding;
1074 margin-right: @padding;
1075 }
1075 }
1076
1076
1077 .breadcrumbs_light {
1077 .breadcrumbs_light {
1078 display: inline-block;
1078 display: inline-block;
1079 }
1079 }
1080 }
1080 }
1081
1081
1082 .info_box {
1082 .info_box {
1083 float: right;
1083 float: right;
1084 }
1084 }
1085
1085
1086
1086
1087
1087
1088 #graph_content{
1088 #graph_content{
1089
1089
1090 // adjust for table headers so that graph renders properly
1090 // adjust for table headers so that graph renders properly
1091 // #graph_nodes padding - table cell padding
1091 // #graph_nodes padding - table cell padding
1092 padding-top: (@space - (@basefontsize * 2.4));
1092 padding-top: (@space - (@basefontsize * 2.4));
1093
1093
1094 &.graph_full_width {
1094 &.graph_full_width {
1095 width: 100%;
1095 width: 100%;
1096 max-width: 100%;
1096 max-width: 100%;
1097 }
1097 }
1098 }
1098 }
1099
1099
1100 #graph {
1100 #graph {
1101
1101
1102 .pagination-left {
1102 .pagination-left {
1103 float: left;
1103 float: left;
1104 clear: both;
1104 clear: both;
1105 }
1105 }
1106
1106
1107 .log-container {
1107 .log-container {
1108 max-width: 345px;
1108 max-width: 345px;
1109
1109
1110 .message{
1110 .message{
1111 max-width: 340px;
1111 max-width: 340px;
1112 }
1112 }
1113 }
1113 }
1114
1114
1115 .graph-col-wrapper {
1115 .graph-col-wrapper {
1116
1116
1117 #graph_nodes {
1117 #graph_nodes {
1118 width: 100px;
1118 width: 100px;
1119 position: absolute;
1119 position: absolute;
1120 left: 70px;
1120 left: 70px;
1121 z-index: -1;
1121 z-index: -1;
1122 }
1122 }
1123 }
1123 }
1124
1124
1125 .load-more-commits {
1125 .load-more-commits {
1126 text-align: center;
1126 text-align: center;
1127 }
1127 }
1128 .load-more-commits:hover {
1128 .load-more-commits:hover {
1129 background-color: @grey7;
1129 background-color: @grey7;
1130 }
1130 }
1131 .load-more-commits {
1131 .load-more-commits {
1132 a {
1132 a {
1133 display: block;
1133 display: block;
1134 }
1134 }
1135 }
1135 }
1136 }
1136 }
1137
1137
1138 .obsolete-toggle {
1138 .obsolete-toggle {
1139 line-height: 30px;
1139 line-height: 30px;
1140 margin-left: -15px;
1140 margin-left: -15px;
1141 }
1141 }
1142
1142
1143 #rev_range_container, #rev_range_clear, #rev_range_more {
1143 #rev_range_action {
1144 margin-top: -5px;
1144 margin-bottom: -8px;
1145 margin-bottom: -5px;
1146 }
1145 }
1147
1146
1148 #filter_changelog {
1147 #filter_changelog {
1149 float: left;
1148 float: left;
1150 }
1149 }
1151
1150
1152
1151
1153 //--- THEME ------------------//
1152 //--- THEME ------------------//
1154
1153
1155 #logo {
1154 #logo {
1156 float: left;
1155 float: left;
1157 margin: 9px 0 0 0;
1156 margin: 9px 0 0 0;
1158
1157
1159 .header {
1158 .header {
1160 background-color: transparent;
1159 background-color: transparent;
1161 }
1160 }
1162
1161
1163 a {
1162 a {
1164 display: inline-block;
1163 display: inline-block;
1165 }
1164 }
1166
1165
1167 img {
1166 img {
1168 height:30px;
1167 height:30px;
1169 }
1168 }
1170 }
1169 }
1171
1170
1172 .logo-wrapper {
1171 .logo-wrapper {
1173 float:left;
1172 float:left;
1174 }
1173 }
1175
1174
1176 .branding {
1175 .branding {
1177 float: left;
1176 float: left;
1178 padding: 9px 2px;
1177 padding: 9px 2px;
1179 line-height: 1em;
1178 line-height: 1em;
1180 font-size: @navigation-fontsize;
1179 font-size: @navigation-fontsize;
1181
1180
1182 a {
1181 a {
1183 color: @grey5
1182 color: @grey5
1184 }
1183 }
1185
1184
1186 // 1024px or smaller
1185 // 1024px or smaller
1187 @media screen and (max-width: 1180px) {
1186 @media screen and (max-width: 1180px) {
1188 display: none;
1187 display: none;
1189 }
1188 }
1190
1189
1191 }
1190 }
1192
1191
1193 img {
1192 img {
1194 border: none;
1193 border: none;
1195 outline: none;
1194 outline: none;
1196 }
1195 }
1197 user-profile-header
1196 user-profile-header
1198 label {
1197 label {
1199
1198
1200 input[type="checkbox"] {
1199 input[type="checkbox"] {
1201 margin-right: 1em;
1200 margin-right: 1em;
1202 }
1201 }
1203 input[type="radio"] {
1202 input[type="radio"] {
1204 margin-right: 1em;
1203 margin-right: 1em;
1205 }
1204 }
1206 }
1205 }
1207
1206
1208 .review-status {
1207 .review-status {
1209 &.under_review {
1208 &.under_review {
1210 color: @alert3;
1209 color: @alert3;
1211 }
1210 }
1212 &.approved {
1211 &.approved {
1213 color: @alert1;
1212 color: @alert1;
1214 }
1213 }
1215 &.rejected,
1214 &.rejected,
1216 &.forced_closed{
1215 &.forced_closed{
1217 color: @alert2;
1216 color: @alert2;
1218 }
1217 }
1219 &.not_reviewed {
1218 &.not_reviewed {
1220 color: @grey5;
1219 color: @grey5;
1221 }
1220 }
1222 }
1221 }
1223
1222
1224 .review-status-under_review {
1223 .review-status-under_review {
1225 color: @alert3;
1224 color: @alert3;
1226 }
1225 }
1227 .status-tag-under_review {
1226 .status-tag-under_review {
1228 border-color: @alert3;
1227 border-color: @alert3;
1229 }
1228 }
1230
1229
1231 .review-status-approved {
1230 .review-status-approved {
1232 color: @alert1;
1231 color: @alert1;
1233 }
1232 }
1234 .status-tag-approved {
1233 .status-tag-approved {
1235 border-color: @alert1;
1234 border-color: @alert1;
1236 }
1235 }
1237
1236
1238 .review-status-rejected,
1237 .review-status-rejected,
1239 .review-status-forced_closed {
1238 .review-status-forced_closed {
1240 color: @alert2;
1239 color: @alert2;
1241 }
1240 }
1242 .status-tag-rejected,
1241 .status-tag-rejected,
1243 .status-tag-forced_closed {
1242 .status-tag-forced_closed {
1244 border-color: @alert2;
1243 border-color: @alert2;
1245 }
1244 }
1246
1245
1247 .review-status-not_reviewed {
1246 .review-status-not_reviewed {
1248 color: @grey5;
1247 color: @grey5;
1249 }
1248 }
1250 .status-tag-not_reviewed {
1249 .status-tag-not_reviewed {
1251 border-color: @grey5;
1250 border-color: @grey5;
1252 }
1251 }
1253
1252
1254 .test_pattern_preview {
1253 .test_pattern_preview {
1255 margin: @space 0;
1254 margin: @space 0;
1256
1255
1257 p {
1256 p {
1258 margin-bottom: 0;
1257 margin-bottom: 0;
1259 border-bottom: @border-thickness solid @border-default-color;
1258 border-bottom: @border-thickness solid @border-default-color;
1260 color: @grey3;
1259 color: @grey3;
1261 }
1260 }
1262
1261
1263 .btn {
1262 .btn {
1264 margin-bottom: @padding;
1263 margin-bottom: @padding;
1265 }
1264 }
1266 }
1265 }
1267 #test_pattern_result {
1266 #test_pattern_result {
1268 display: none;
1267 display: none;
1269 &:extend(pre);
1268 &:extend(pre);
1270 padding: .9em;
1269 padding: .9em;
1271 color: @grey3;
1270 color: @grey3;
1272 background-color: @grey7;
1271 background-color: @grey7;
1273 border-right: @border-thickness solid @border-default-color;
1272 border-right: @border-thickness solid @border-default-color;
1274 border-bottom: @border-thickness solid @border-default-color;
1273 border-bottom: @border-thickness solid @border-default-color;
1275 border-left: @border-thickness solid @border-default-color;
1274 border-left: @border-thickness solid @border-default-color;
1276 }
1275 }
1277
1276
1278 #repo_vcs_settings {
1277 #repo_vcs_settings {
1279 #inherit_overlay_vcs_default {
1278 #inherit_overlay_vcs_default {
1280 display: none;
1279 display: none;
1281 }
1280 }
1282 #inherit_overlay_vcs_custom {
1281 #inherit_overlay_vcs_custom {
1283 display: custom;
1282 display: custom;
1284 }
1283 }
1285 &.inherited {
1284 &.inherited {
1286 #inherit_overlay_vcs_default {
1285 #inherit_overlay_vcs_default {
1287 display: block;
1286 display: block;
1288 }
1287 }
1289 #inherit_overlay_vcs_custom {
1288 #inherit_overlay_vcs_custom {
1290 display: none;
1289 display: none;
1291 }
1290 }
1292 }
1291 }
1293 }
1292 }
1294
1293
1295 .issue-tracker-link {
1294 .issue-tracker-link {
1296 color: @rcblue;
1295 color: @rcblue;
1297 }
1296 }
1298
1297
1299 // Issue Tracker Table Show/Hide
1298 // Issue Tracker Table Show/Hide
1300 #repo_issue_tracker {
1299 #repo_issue_tracker {
1301 #inherit_overlay {
1300 #inherit_overlay {
1302 display: none;
1301 display: none;
1303 }
1302 }
1304 #custom_overlay {
1303 #custom_overlay {
1305 display: custom;
1304 display: custom;
1306 }
1305 }
1307 &.inherited {
1306 &.inherited {
1308 #inherit_overlay {
1307 #inherit_overlay {
1309 display: block;
1308 display: block;
1310 }
1309 }
1311 #custom_overlay {
1310 #custom_overlay {
1312 display: none;
1311 display: none;
1313 }
1312 }
1314 }
1313 }
1315 }
1314 }
1316 table.issuetracker {
1315 table.issuetracker {
1317 &.readonly {
1316 &.readonly {
1318 tr, td {
1317 tr, td {
1319 color: @grey3;
1318 color: @grey3;
1320 }
1319 }
1321 }
1320 }
1322 .edit {
1321 .edit {
1323 display: none;
1322 display: none;
1324 }
1323 }
1325 .editopen {
1324 .editopen {
1326 .edit {
1325 .edit {
1327 display: inline;
1326 display: inline;
1328 }
1327 }
1329 .entry {
1328 .entry {
1330 display: none;
1329 display: none;
1331 }
1330 }
1332 }
1331 }
1333 tr td.td-action {
1332 tr td.td-action {
1334 min-width: 117px;
1333 min-width: 117px;
1335 }
1334 }
1336 td input {
1335 td input {
1337 max-width: none;
1336 max-width: none;
1338 min-width: 30px;
1337 min-width: 30px;
1339 width: 80%;
1338 width: 80%;
1340 }
1339 }
1341 .issuetracker_pref input {
1340 .issuetracker_pref input {
1342 width: 40%;
1341 width: 40%;
1343 }
1342 }
1344 input.edit_issuetracker_update {
1343 input.edit_issuetracker_update {
1345 margin-right: 0;
1344 margin-right: 0;
1346 width: auto;
1345 width: auto;
1347 }
1346 }
1348 }
1347 }
1349
1348
1350 table.integrations {
1349 table.integrations {
1351 .td-icon {
1350 .td-icon {
1352 width: 20px;
1351 width: 20px;
1353 .integration-icon {
1352 .integration-icon {
1354 height: 20px;
1353 height: 20px;
1355 width: 20px;
1354 width: 20px;
1356 }
1355 }
1357 }
1356 }
1358 }
1357 }
1359
1358
1360 .integrations {
1359 .integrations {
1361 a.integration-box {
1360 a.integration-box {
1362 color: @text-color;
1361 color: @text-color;
1363 &:hover {
1362 &:hover {
1364 .panel {
1363 .panel {
1365 background: #fbfbfb;
1364 background: #fbfbfb;
1366 }
1365 }
1367 }
1366 }
1368 .integration-icon {
1367 .integration-icon {
1369 width: 30px;
1368 width: 30px;
1370 height: 30px;
1369 height: 30px;
1371 margin-right: 20px;
1370 margin-right: 20px;
1372 float: left;
1371 float: left;
1373 }
1372 }
1374
1373
1375 .panel-body {
1374 .panel-body {
1376 padding: 10px;
1375 padding: 10px;
1377 }
1376 }
1378 .panel {
1377 .panel {
1379 margin-bottom: 10px;
1378 margin-bottom: 10px;
1380 }
1379 }
1381 h2 {
1380 h2 {
1382 display: inline-block;
1381 display: inline-block;
1383 margin: 0;
1382 margin: 0;
1384 min-width: 140px;
1383 min-width: 140px;
1385 }
1384 }
1386 }
1385 }
1387 a.integration-box.dummy-integration {
1386 a.integration-box.dummy-integration {
1388 color: @grey4
1387 color: @grey4
1389 }
1388 }
1390 }
1389 }
1391
1390
1392 //Permissions Settings
1391 //Permissions Settings
1393 #add_perm {
1392 #add_perm {
1394 margin: 0 0 @padding;
1393 margin: 0 0 @padding;
1395 cursor: pointer;
1394 cursor: pointer;
1396 }
1395 }
1397
1396
1398 .perm_ac {
1397 .perm_ac {
1399 input {
1398 input {
1400 width: 95%;
1399 width: 95%;
1401 }
1400 }
1402 }
1401 }
1403
1402
1404 .autocomplete-suggestions {
1403 .autocomplete-suggestions {
1405 width: auto !important; // overrides autocomplete.js
1404 width: auto !important; // overrides autocomplete.js
1406 min-width: 278px;
1405 min-width: 278px;
1407 margin: 0;
1406 margin: 0;
1408 border: @border-thickness solid @grey5;
1407 border: @border-thickness solid @grey5;
1409 border-radius: @border-radius;
1408 border-radius: @border-radius;
1410 color: @grey2;
1409 color: @grey2;
1411 background-color: white;
1410 background-color: white;
1412 }
1411 }
1413
1412
1414 .autocomplete-qfilter-suggestions {
1413 .autocomplete-qfilter-suggestions {
1415 width: auto !important; // overrides autocomplete.js
1414 width: auto !important; // overrides autocomplete.js
1416 max-height: 100% !important;
1415 max-height: 100% !important;
1417 min-width: 376px;
1416 min-width: 376px;
1418 margin: 0;
1417 margin: 0;
1419 border: @border-thickness solid @grey5;
1418 border: @border-thickness solid @grey5;
1420 color: @grey2;
1419 color: @grey2;
1421 background-color: white;
1420 background-color: white;
1422 }
1421 }
1423
1422
1424 .autocomplete-selected {
1423 .autocomplete-selected {
1425 background: #F0F0F0;
1424 background: #F0F0F0;
1426 }
1425 }
1427
1426
1428 .ac-container-wrap {
1427 .ac-container-wrap {
1429 margin: 0;
1428 margin: 0;
1430 padding: 8px;
1429 padding: 8px;
1431 border-bottom: @border-thickness solid @grey5;
1430 border-bottom: @border-thickness solid @grey5;
1432 list-style-type: none;
1431 list-style-type: none;
1433 cursor: pointer;
1432 cursor: pointer;
1434
1433
1435 &:hover {
1434 &:hover {
1436 background-color: @grey7;
1435 background-color: @grey7;
1437 }
1436 }
1438
1437
1439 img {
1438 img {
1440 height: @gravatar-size;
1439 height: @gravatar-size;
1441 width: @gravatar-size;
1440 width: @gravatar-size;
1442 margin-right: 1em;
1441 margin-right: 1em;
1443 }
1442 }
1444
1443
1445 strong {
1444 strong {
1446 font-weight: normal;
1445 font-weight: normal;
1447 }
1446 }
1448 }
1447 }
1449
1448
1450 // Settings Dropdown
1449 // Settings Dropdown
1451 .user-menu .container {
1450 .user-menu .container {
1452 padding: 0 4px;
1451 padding: 0 4px;
1453 margin: 0;
1452 margin: 0;
1454 }
1453 }
1455
1454
1456 .user-menu .gravatar {
1455 .user-menu .gravatar {
1457 cursor: pointer;
1456 cursor: pointer;
1458 }
1457 }
1459
1458
1460 .codeblock {
1459 .codeblock {
1461 margin-bottom: @padding;
1460 margin-bottom: @padding;
1462 clear: both;
1461 clear: both;
1463
1462
1464 .stats {
1463 .stats {
1465 overflow: hidden;
1464 overflow: hidden;
1466 }
1465 }
1467
1466
1468 .message{
1467 .message{
1469 textarea{
1468 textarea{
1470 margin: 0;
1469 margin: 0;
1471 }
1470 }
1472 }
1471 }
1473
1472
1474 .code-header {
1473 .code-header {
1475 .stats {
1474 .stats {
1476 line-height: 2em;
1475 line-height: 2em;
1477
1476
1478 .revision_id {
1477 .revision_id {
1479 margin-left: 0;
1478 margin-left: 0;
1480 }
1479 }
1481 .buttons {
1480 .buttons {
1482 padding-right: 0;
1481 padding-right: 0;
1483 }
1482 }
1484 }
1483 }
1485
1484
1486 .item{
1485 .item{
1487 margin-right: 0.5em;
1486 margin-right: 0.5em;
1488 }
1487 }
1489 }
1488 }
1490
1489
1491 #editor_container {
1490 #editor_container {
1492 position: relative;
1491 position: relative;
1493 margin: @padding 10px;
1492 margin: @padding 10px;
1494 }
1493 }
1495 }
1494 }
1496
1495
1497 #file_history_container {
1496 #file_history_container {
1498 display: none;
1497 display: none;
1499 }
1498 }
1500
1499
1501 .file-history-inner {
1500 .file-history-inner {
1502 margin-bottom: 10px;
1501 margin-bottom: 10px;
1503 }
1502 }
1504
1503
1505 // Pull Requests
1504 // Pull Requests
1506 .summary-details {
1505 .summary-details {
1507 width: 100%;
1506 width: 100%;
1508 }
1507 }
1509 .pr-summary {
1508 .pr-summary {
1510 border-bottom: @border-thickness solid @grey5;
1509 border-bottom: @border-thickness solid @grey5;
1511 margin-bottom: @space;
1510 margin-bottom: @space;
1512 }
1511 }
1513
1512
1514 .reviewers {
1513 .reviewers {
1515 width: 98%;
1514 width: 98%;
1516 }
1515 }
1517
1516
1518 .reviewers ul li {
1517 .reviewers ul li {
1519 position: relative;
1518 position: relative;
1520 width: 100%;
1519 width: 100%;
1521 padding-bottom: 8px;
1520 padding-bottom: 8px;
1522 list-style-type: none;
1521 list-style-type: none;
1523 }
1522 }
1524
1523
1525 .reviewer_entry {
1524 .reviewer_entry {
1526 min-height: 55px;
1525 min-height: 55px;
1527 }
1526 }
1528
1527
1529 .reviewer_reason {
1528 .reviewer_reason {
1530 padding-left: 20px;
1529 padding-left: 20px;
1531 line-height: 1.5em;
1530 line-height: 1.5em;
1532 }
1531 }
1533 .reviewer_status {
1532 .reviewer_status {
1534 display: inline-block;
1533 display: inline-block;
1535 width: 20px;
1534 width: 20px;
1536 min-width: 20px;
1535 min-width: 20px;
1537 height: 1.2em;
1536 height: 1.2em;
1538 line-height: 1em;
1537 line-height: 1em;
1539 }
1538 }
1540
1539
1541 .reviewer_name {
1540 .reviewer_name {
1542 display: inline-block;
1541 display: inline-block;
1543 max-width: 83%;
1542 max-width: 83%;
1544 padding-right: 20px;
1543 padding-right: 20px;
1545 vertical-align: middle;
1544 vertical-align: middle;
1546 line-height: 1;
1545 line-height: 1;
1547
1546
1548 .rc-user {
1547 .rc-user {
1549 min-width: 0;
1548 min-width: 0;
1550 margin: -2px 1em 0 0;
1549 margin: -2px 1em 0 0;
1551 }
1550 }
1552
1551
1553 .reviewer {
1552 .reviewer {
1554 float: left;
1553 float: left;
1555 }
1554 }
1556 }
1555 }
1557
1556
1558 .reviewer_member_mandatory {
1557 .reviewer_member_mandatory {
1559 width: 16px;
1558 width: 16px;
1560 font-size: 11px;
1559 font-size: 11px;
1561 margin: 0;
1560 margin: 0;
1562 padding: 0;
1561 padding: 0;
1563 color: black;
1562 color: black;
1564 opacity: 0.4;
1563 opacity: 0.4;
1565 }
1564 }
1566
1565
1567 .reviewer_member_mandatory_remove,
1566 .reviewer_member_mandatory_remove,
1568 .reviewer_member_remove {
1567 .reviewer_member_remove {
1569 width: 16px;
1568 width: 16px;
1570 padding: 0;
1569 padding: 0;
1571 color: black;
1570 color: black;
1572 cursor: pointer;
1571 cursor: pointer;
1573 }
1572 }
1574
1573
1575 .reviewer_member_mandatory_remove {
1574 .reviewer_member_mandatory_remove {
1576 color: @grey4;
1575 color: @grey4;
1577 }
1576 }
1578
1577
1579 .reviewer_member_status {
1578 .reviewer_member_status {
1580 margin-top: 5px;
1579 margin-top: 5px;
1581 }
1580 }
1582 .pr-summary #summary{
1581 .pr-summary #summary{
1583 width: 100%;
1582 width: 100%;
1584 }
1583 }
1585 .pr-summary .action_button:hover {
1584 .pr-summary .action_button:hover {
1586 border: 0;
1585 border: 0;
1587 cursor: pointer;
1586 cursor: pointer;
1588 }
1587 }
1589 .pr-details-title {
1588 .pr-details-title {
1590 height: 20px;
1589 height: 20px;
1591 line-height: 16px;
1590 line-height: 16px;
1592
1591
1593 padding-bottom: 4px;
1592 padding-bottom: 4px;
1594 border-bottom: @border-thickness solid @grey5;
1593 border-bottom: @border-thickness solid @grey5;
1595
1594
1596 .action_button.disabled {
1595 .action_button.disabled {
1597 color: @grey4;
1596 color: @grey4;
1598 cursor: inherit;
1597 cursor: inherit;
1599 }
1598 }
1600 .action_button {
1599 .action_button {
1601 color: @rcblue;
1600 color: @rcblue;
1602 }
1601 }
1603 }
1602 }
1604 .pr-details-content {
1603 .pr-details-content {
1605 margin-top: @textmargin - 5;
1604 margin-top: @textmargin - 5;
1606 margin-bottom: @textmargin - 5;
1605 margin-bottom: @textmargin - 5;
1607 }
1606 }
1608
1607
1609 .pr-reviewer-rules {
1608 .pr-reviewer-rules {
1610 padding: 10px 0px 20px 0px;
1609 padding: 10px 0px 20px 0px;
1611 }
1610 }
1612
1611
1613 .todo-resolved {
1612 .todo-resolved {
1614 text-decoration: line-through;
1613 text-decoration: line-through;
1615 }
1614 }
1616
1615
1617 .todo-table, .comments-table {
1616 .todo-table, .comments-table {
1618 width: 100%;
1617 width: 100%;
1619
1618
1620 td {
1619 td {
1621 padding: 5px 0px;
1620 padding: 5px 0px;
1622 }
1621 }
1623
1622
1624 .td-todo-number {
1623 .td-todo-number {
1625 text-align: left;
1624 text-align: left;
1626 white-space: nowrap;
1625 white-space: nowrap;
1627 width: 1%;
1626 width: 1%;
1628 padding-right: 2px;
1627 padding-right: 2px;
1629 }
1628 }
1630
1629
1631 .td-todo-gravatar {
1630 .td-todo-gravatar {
1632 width: 5%;
1631 width: 5%;
1633
1632
1634 img {
1633 img {
1635 margin: -3px 0;
1634 margin: -3px 0;
1636 }
1635 }
1637 }
1636 }
1638
1637
1639 }
1638 }
1640
1639
1641 .todo-comment-text-wrapper {
1640 .todo-comment-text-wrapper {
1642 display: inline-grid;
1641 display: inline-grid;
1643 }
1642 }
1644
1643
1645 .todo-comment-text {
1644 .todo-comment-text {
1646 margin-left: 5px;
1645 margin-left: 5px;
1647 white-space: nowrap;
1646 white-space: nowrap;
1648 overflow: hidden;
1647 overflow: hidden;
1649 text-overflow: ellipsis;
1648 text-overflow: ellipsis;
1650 }
1649 }
1651
1650
1652 table.group_members {
1651 table.group_members {
1653 width: 100%
1652 width: 100%
1654 }
1653 }
1655
1654
1656 .group_members {
1655 .group_members {
1657 margin-top: 0;
1656 margin-top: 0;
1658 padding: 0;
1657 padding: 0;
1659
1658
1660 img {
1659 img {
1661 height: @gravatar-size;
1660 height: @gravatar-size;
1662 width: @gravatar-size;
1661 width: @gravatar-size;
1663 margin-right: .5em;
1662 margin-right: .5em;
1664 margin-left: 3px;
1663 margin-left: 3px;
1665 }
1664 }
1666
1665
1667 .to-delete {
1666 .to-delete {
1668 .user {
1667 .user {
1669 text-decoration: line-through;
1668 text-decoration: line-through;
1670 }
1669 }
1671 }
1670 }
1672 }
1671 }
1673
1672
1674 .compare_view_commits_title {
1673 .compare_view_commits_title {
1675 .disabled {
1674 .disabled {
1676 cursor: inherit;
1675 cursor: inherit;
1677 &:hover{
1676 &:hover{
1678 background-color: inherit;
1677 background-color: inherit;
1679 color: inherit;
1678 color: inherit;
1680 }
1679 }
1681 }
1680 }
1682 }
1681 }
1683
1682
1684 .subtitle-compare {
1683 .subtitle-compare {
1685 margin: -15px 0px 0px 0px;
1684 margin: -15px 0px 0px 0px;
1686 }
1685 }
1687
1686
1688 // new entry in group_members
1687 // new entry in group_members
1689 .td-author-new-entry {
1688 .td-author-new-entry {
1690 background-color: rgba(red(@alert1), green(@alert1), blue(@alert1), 0.3);
1689 background-color: rgba(red(@alert1), green(@alert1), blue(@alert1), 0.3);
1691 }
1690 }
1692
1691
1693 .usergroup_member_remove {
1692 .usergroup_member_remove {
1694 width: 16px;
1693 width: 16px;
1695 margin-bottom: 10px;
1694 margin-bottom: 10px;
1696 padding: 0;
1695 padding: 0;
1697 color: black !important;
1696 color: black !important;
1698 cursor: pointer;
1697 cursor: pointer;
1699 }
1698 }
1700
1699
1701 .reviewer_ac .ac-input {
1700 .reviewer_ac .ac-input {
1702 width: 98%;
1701 width: 98%;
1703 margin-bottom: 1em;
1702 margin-bottom: 1em;
1704 }
1703 }
1705
1704
1706 .observer_ac .ac-input {
1705 .observer_ac .ac-input {
1707 width: 98%;
1706 width: 98%;
1708 margin-bottom: 1em;
1707 margin-bottom: 1em;
1709 }
1708 }
1710
1709
1711 .rule-table {
1710 .rule-table {
1712 width: 100%;
1711 width: 100%;
1713 }
1712 }
1714
1713
1715 .rule-table td {
1714 .rule-table td {
1716
1715
1717 }
1716 }
1718
1717
1719 .rule-table .td-role {
1718 .rule-table .td-role {
1720 width: 100px
1719 width: 100px
1721 }
1720 }
1722
1721
1723 .rule-table .td-mandatory {
1722 .rule-table .td-mandatory {
1724 width: 100px
1723 width: 100px
1725 }
1724 }
1726
1725
1727 .rule-table .td-group-votes {
1726 .rule-table .td-group-votes {
1728 width: 150px
1727 width: 150px
1729 }
1728 }
1730
1729
1731 .compare_view_commits tr{
1730 .compare_view_commits tr{
1732 height: 20px;
1731 height: 20px;
1733 }
1732 }
1734 .compare_view_commits td {
1733 .compare_view_commits td {
1735 vertical-align: top;
1734 vertical-align: top;
1736 padding-top: 10px;
1735 padding-top: 10px;
1737 }
1736 }
1738 .compare_view_commits .author {
1737 .compare_view_commits .author {
1739 margin-left: 5px;
1738 margin-left: 5px;
1740 }
1739 }
1741
1740
1742 .compare_view_commits {
1741 .compare_view_commits {
1743 .color-a {
1742 .color-a {
1744 color: @alert1;
1743 color: @alert1;
1745 }
1744 }
1746
1745
1747 .color-c {
1746 .color-c {
1748 color: @color3;
1747 color: @color3;
1749 }
1748 }
1750
1749
1751 .color-r {
1750 .color-r {
1752 color: @color5;
1751 color: @color5;
1753 }
1752 }
1754
1753
1755 .color-a-bg {
1754 .color-a-bg {
1756 background-color: @alert1;
1755 background-color: @alert1;
1757 }
1756 }
1758
1757
1759 .color-c-bg {
1758 .color-c-bg {
1760 background-color: @alert3;
1759 background-color: @alert3;
1761 }
1760 }
1762
1761
1763 .color-r-bg {
1762 .color-r-bg {
1764 background-color: @alert2;
1763 background-color: @alert2;
1765 }
1764 }
1766
1765
1767 .color-a-border {
1766 .color-a-border {
1768 border: 1px solid @alert1;
1767 border: 1px solid @alert1;
1769 }
1768 }
1770
1769
1771 .color-c-border {
1770 .color-c-border {
1772 border: 1px solid @alert3;
1771 border: 1px solid @alert3;
1773 }
1772 }
1774
1773
1775 .color-r-border {
1774 .color-r-border {
1776 border: 1px solid @alert2;
1775 border: 1px solid @alert2;
1777 }
1776 }
1778
1777
1779 .commit-change-indicator {
1778 .commit-change-indicator {
1780 width: 15px;
1779 width: 15px;
1781 height: 15px;
1780 height: 15px;
1782 position: relative;
1781 position: relative;
1783 left: 15px;
1782 left: 15px;
1784 }
1783 }
1785
1784
1786 .commit-change-content {
1785 .commit-change-content {
1787 text-align: center;
1786 text-align: center;
1788 vertical-align: middle;
1787 vertical-align: middle;
1789 line-height: 15px;
1788 line-height: 15px;
1790 }
1789 }
1791 }
1790 }
1792
1791
1793 .compare_view_filepath {
1792 .compare_view_filepath {
1794 color: @grey1;
1793 color: @grey1;
1795 }
1794 }
1796
1795
1797 .show_more {
1796 .show_more {
1798 display: inline-block;
1797 display: inline-block;
1799 width: 0;
1798 width: 0;
1800 height: 0;
1799 height: 0;
1801 vertical-align: middle;
1800 vertical-align: middle;
1802 content: "";
1801 content: "";
1803 border: 4px solid;
1802 border: 4px solid;
1804 border-right-color: transparent;
1803 border-right-color: transparent;
1805 border-bottom-color: transparent;
1804 border-bottom-color: transparent;
1806 border-left-color: transparent;
1805 border-left-color: transparent;
1807 font-size: 0;
1806 font-size: 0;
1808 }
1807 }
1809
1808
1810 .journal_more .show_more {
1809 .journal_more .show_more {
1811 display: inline;
1810 display: inline;
1812
1811
1813 &:after {
1812 &:after {
1814 content: none;
1813 content: none;
1815 }
1814 }
1816 }
1815 }
1817
1816
1818 .compare_view_commits .collapse_commit:after {
1817 .compare_view_commits .collapse_commit:after {
1819 cursor: pointer;
1818 cursor: pointer;
1820 content: "\00A0\25B4";
1819 content: "\00A0\25B4";
1821 margin-left: -3px;
1820 margin-left: -3px;
1822 font-size: 17px;
1821 font-size: 17px;
1823 color: @grey4;
1822 color: @grey4;
1824 }
1823 }
1825
1824
1826 .diff_links {
1825 .diff_links {
1827 margin-left: 8px;
1826 margin-left: 8px;
1828 }
1827 }
1829
1828
1830 #pull_request_overview {
1829 #pull_request_overview {
1831 div.ancestor {
1830 div.ancestor {
1832 margin: -33px 0;
1831 margin: -33px 0;
1833 }
1832 }
1834 }
1833 }
1835
1834
1836 div.ancestor {
1835 div.ancestor {
1837
1836
1838 }
1837 }
1839
1838
1840 .cs_icon_td input[type="checkbox"] {
1839 .cs_icon_td input[type="checkbox"] {
1841 display: none;
1840 display: none;
1842 }
1841 }
1843
1842
1844 .cs_icon_td .expand_file_icon:after {
1843 .cs_icon_td .expand_file_icon:after {
1845 cursor: pointer;
1844 cursor: pointer;
1846 content: "\00A0\25B6";
1845 content: "\00A0\25B6";
1847 font-size: 12px;
1846 font-size: 12px;
1848 color: @grey4;
1847 color: @grey4;
1849 }
1848 }
1850
1849
1851 .cs_icon_td .collapse_file_icon:after {
1850 .cs_icon_td .collapse_file_icon:after {
1852 cursor: pointer;
1851 cursor: pointer;
1853 content: "\00A0\25BC";
1852 content: "\00A0\25BC";
1854 font-size: 12px;
1853 font-size: 12px;
1855 color: @grey4;
1854 color: @grey4;
1856 }
1855 }
1857
1856
1858 /*new binary
1857 /*new binary
1859 NEW_FILENODE = 1
1858 NEW_FILENODE = 1
1860 DEL_FILENODE = 2
1859 DEL_FILENODE = 2
1861 MOD_FILENODE = 3
1860 MOD_FILENODE = 3
1862 RENAMED_FILENODE = 4
1861 RENAMED_FILENODE = 4
1863 COPIED_FILENODE = 5
1862 COPIED_FILENODE = 5
1864 CHMOD_FILENODE = 6
1863 CHMOD_FILENODE = 6
1865 BIN_FILENODE = 7
1864 BIN_FILENODE = 7
1866 */
1865 */
1867 .cs_files_expand {
1866 .cs_files_expand {
1868 font-size: @basefontsize + 5px;
1867 font-size: @basefontsize + 5px;
1869 line-height: 1.8em;
1868 line-height: 1.8em;
1870 float: right;
1869 float: right;
1871 }
1870 }
1872
1871
1873 .cs_files_expand span{
1872 .cs_files_expand span{
1874 color: @rcblue;
1873 color: @rcblue;
1875 cursor: pointer;
1874 cursor: pointer;
1876 }
1875 }
1877 .cs_files {
1876 .cs_files {
1878 clear: both;
1877 clear: both;
1879 padding-bottom: @padding;
1878 padding-bottom: @padding;
1880
1879
1881 .cur_cs {
1880 .cur_cs {
1882 margin: 10px 2px;
1881 margin: 10px 2px;
1883 font-weight: bold;
1882 font-weight: bold;
1884 }
1883 }
1885
1884
1886 .node {
1885 .node {
1887 float: left;
1886 float: left;
1888 }
1887 }
1889
1888
1890 .changes {
1889 .changes {
1891 float: right;
1890 float: right;
1892 color: white;
1891 color: white;
1893 font-size: @basefontsize - 4px;
1892 font-size: @basefontsize - 4px;
1894 margin-top: 4px;
1893 margin-top: 4px;
1895 opacity: 0.6;
1894 opacity: 0.6;
1896 filter: Alpha(opacity=60); /* IE8 and earlier */
1895 filter: Alpha(opacity=60); /* IE8 and earlier */
1897
1896
1898 .added {
1897 .added {
1899 background-color: @alert1;
1898 background-color: @alert1;
1900 float: left;
1899 float: left;
1901 text-align: center;
1900 text-align: center;
1902 }
1901 }
1903
1902
1904 .deleted {
1903 .deleted {
1905 background-color: @alert2;
1904 background-color: @alert2;
1906 float: left;
1905 float: left;
1907 text-align: center;
1906 text-align: center;
1908 }
1907 }
1909
1908
1910 .bin {
1909 .bin {
1911 background-color: @alert1;
1910 background-color: @alert1;
1912 text-align: center;
1911 text-align: center;
1913 }
1912 }
1914
1913
1915 /*new binary*/
1914 /*new binary*/
1916 .bin.bin1 {
1915 .bin.bin1 {
1917 background-color: @alert1;
1916 background-color: @alert1;
1918 text-align: center;
1917 text-align: center;
1919 }
1918 }
1920
1919
1921 /*deleted binary*/
1920 /*deleted binary*/
1922 .bin.bin2 {
1921 .bin.bin2 {
1923 background-color: @alert2;
1922 background-color: @alert2;
1924 text-align: center;
1923 text-align: center;
1925 }
1924 }
1926
1925
1927 /*mod binary*/
1926 /*mod binary*/
1928 .bin.bin3 {
1927 .bin.bin3 {
1929 background-color: @grey2;
1928 background-color: @grey2;
1930 text-align: center;
1929 text-align: center;
1931 }
1930 }
1932
1931
1933 /*rename file*/
1932 /*rename file*/
1934 .bin.bin4 {
1933 .bin.bin4 {
1935 background-color: @alert4;
1934 background-color: @alert4;
1936 text-align: center;
1935 text-align: center;
1937 }
1936 }
1938
1937
1939 /*copied file*/
1938 /*copied file*/
1940 .bin.bin5 {
1939 .bin.bin5 {
1941 background-color: @alert4;
1940 background-color: @alert4;
1942 text-align: center;
1941 text-align: center;
1943 }
1942 }
1944
1943
1945 /*chmod file*/
1944 /*chmod file*/
1946 .bin.bin6 {
1945 .bin.bin6 {
1947 background-color: @grey2;
1946 background-color: @grey2;
1948 text-align: center;
1947 text-align: center;
1949 }
1948 }
1950 }
1949 }
1951 }
1950 }
1952
1951
1953 .cs_files .cs_added, .cs_files .cs_A,
1952 .cs_files .cs_added, .cs_files .cs_A,
1954 .cs_files .cs_added, .cs_files .cs_M,
1953 .cs_files .cs_added, .cs_files .cs_M,
1955 .cs_files .cs_added, .cs_files .cs_D {
1954 .cs_files .cs_added, .cs_files .cs_D {
1956 height: 16px;
1955 height: 16px;
1957 padding-right: 10px;
1956 padding-right: 10px;
1958 margin-top: 7px;
1957 margin-top: 7px;
1959 text-align: left;
1958 text-align: left;
1960 }
1959 }
1961
1960
1962 .cs_icon_td {
1961 .cs_icon_td {
1963 min-width: 16px;
1962 min-width: 16px;
1964 width: 16px;
1963 width: 16px;
1965 }
1964 }
1966
1965
1967 .pull-request-merge {
1966 .pull-request-merge {
1968 border: 1px solid @grey5;
1967 border: 1px solid @grey5;
1969 padding: 10px 0px 20px;
1968 padding: 10px 0px 20px;
1970 margin-top: 10px;
1969 margin-top: 10px;
1971 margin-bottom: 20px;
1970 margin-bottom: 20px;
1972 }
1971 }
1973
1972
1974 .pull-request-merge-refresh {
1973 .pull-request-merge-refresh {
1975 margin: 2px 7px;
1974 margin: 2px 7px;
1976 a {
1975 a {
1977 color: @grey3;
1976 color: @grey3;
1978 }
1977 }
1979 }
1978 }
1980
1979
1981 .pull-request-merge ul {
1980 .pull-request-merge ul {
1982 padding: 0px 0px;
1981 padding: 0px 0px;
1983 }
1982 }
1984
1983
1985 .pull-request-merge li {
1984 .pull-request-merge li {
1986 list-style-type: none;
1985 list-style-type: none;
1987 }
1986 }
1988
1987
1989 .pull-request-merge .pull-request-wrap {
1988 .pull-request-merge .pull-request-wrap {
1990 height: auto;
1989 height: auto;
1991 padding: 0px 0px;
1990 padding: 0px 0px;
1992 text-align: right;
1991 text-align: right;
1993 }
1992 }
1994
1993
1995 .pull-request-merge span {
1994 .pull-request-merge span {
1996 margin-right: 5px;
1995 margin-right: 5px;
1997 }
1996 }
1998
1997
1999 .pull-request-merge-actions {
1998 .pull-request-merge-actions {
2000 min-height: 30px;
1999 min-height: 30px;
2001 padding: 0px 0px;
2000 padding: 0px 0px;
2002 }
2001 }
2003
2002
2004 .pull-request-merge-info {
2003 .pull-request-merge-info {
2005 padding: 0px 5px 5px 0px;
2004 padding: 0px 5px 5px 0px;
2006 }
2005 }
2007
2006
2008 .merge-status {
2007 .merge-status {
2009 margin-right: 5px;
2008 margin-right: 5px;
2010 }
2009 }
2011
2010
2012 .merge-message {
2011 .merge-message {
2013 font-size: 1.2em
2012 font-size: 1.2em
2014 }
2013 }
2015
2014
2016 .merge-message.success i,
2015 .merge-message.success i,
2017 .merge-icon.success i {
2016 .merge-icon.success i {
2018 color:@alert1;
2017 color:@alert1;
2019 }
2018 }
2020
2019
2021 .merge-message.warning i,
2020 .merge-message.warning i,
2022 .merge-icon.warning i {
2021 .merge-icon.warning i {
2023 color: @alert3;
2022 color: @alert3;
2024 }
2023 }
2025
2024
2026 .merge-message.error i,
2025 .merge-message.error i,
2027 .merge-icon.error i {
2026 .merge-icon.error i {
2028 color:@alert2;
2027 color:@alert2;
2029 }
2028 }
2030
2029
2031 .pr-versions {
2030 .pr-versions {
2032 font-size: 1.1em;
2031 font-size: 1.1em;
2033 padding: 7.5px;
2032 padding: 7.5px;
2034
2033
2035 table {
2034 table {
2036
2035
2037 }
2036 }
2038
2037
2039 td {
2038 td {
2040 line-height: 15px;
2039 line-height: 15px;
2041 }
2040 }
2042
2041
2043 .compare-radio-button {
2042 .compare-radio-button {
2044 position: relative;
2043 position: relative;
2045 top: -3px;
2044 top: -3px;
2046 }
2045 }
2047 }
2046 }
2048
2047
2049
2048
2050 #close_pull_request {
2049 #close_pull_request {
2051 margin-right: 0px;
2050 margin-right: 0px;
2052 }
2051 }
2053
2052
2054 .empty_data {
2053 .empty_data {
2055 color: @grey4;
2054 color: @grey4;
2056 }
2055 }
2057
2056
2058 #changeset_compare_view_content {
2057 #changeset_compare_view_content {
2059 clear: both;
2058 clear: both;
2060 width: 100%;
2059 width: 100%;
2061 box-sizing: border-box;
2060 box-sizing: border-box;
2062 .border-radius(@border-radius);
2061 .border-radius(@border-radius);
2063
2062
2064 .help-block {
2063 .help-block {
2065 margin: @padding 0;
2064 margin: @padding 0;
2066 color: @text-color;
2065 color: @text-color;
2067 &.pre-formatting {
2066 &.pre-formatting {
2068 white-space: pre;
2067 white-space: pre;
2069 }
2068 }
2070 }
2069 }
2071
2070
2072 .empty_data {
2071 .empty_data {
2073 margin: @padding 0;
2072 margin: @padding 0;
2074 }
2073 }
2075
2074
2076 .alert {
2075 .alert {
2077 margin-bottom: @space;
2076 margin-bottom: @space;
2078 }
2077 }
2079 }
2078 }
2080
2079
2081 .table_disp {
2080 .table_disp {
2082 .status {
2081 .status {
2083 width: auto;
2082 width: auto;
2084 }
2083 }
2085 }
2084 }
2086
2085
2087
2086
2088 .creation_in_progress {
2087 .creation_in_progress {
2089 color: @grey4
2088 color: @grey4
2090 }
2089 }
2091
2090
2092 .status_box_menu {
2091 .status_box_menu {
2093 margin: 0;
2092 margin: 0;
2094 }
2093 }
2095
2094
2096 .notification-table{
2095 .notification-table{
2097 margin-bottom: @space;
2096 margin-bottom: @space;
2098 display: table;
2097 display: table;
2099 width: 100%;
2098 width: 100%;
2100
2099
2101 .container{
2100 .container{
2102 display: table-row;
2101 display: table-row;
2103
2102
2104 .notification-header{
2103 .notification-header{
2105 border-bottom: @border-thickness solid @border-default-color;
2104 border-bottom: @border-thickness solid @border-default-color;
2106 }
2105 }
2107
2106
2108 .notification-subject{
2107 .notification-subject{
2109 display: table-cell;
2108 display: table-cell;
2110 }
2109 }
2111 }
2110 }
2112 }
2111 }
2113
2112
2114 // Notifications
2113 // Notifications
2115 .notification-header{
2114 .notification-header{
2116 display: table;
2115 display: table;
2117 width: 100%;
2116 width: 100%;
2118 padding: floor(@basefontsize/2) 0;
2117 padding: floor(@basefontsize/2) 0;
2119 line-height: 1em;
2118 line-height: 1em;
2120
2119
2121 .desc, .delete-notifications, .read-notifications{
2120 .desc, .delete-notifications, .read-notifications{
2122 display: table-cell;
2121 display: table-cell;
2123 text-align: left;
2122 text-align: left;
2124 }
2123 }
2125
2124
2126 .delete-notifications, .read-notifications{
2125 .delete-notifications, .read-notifications{
2127 width: 35px;
2126 width: 35px;
2128 min-width: 35px; //fixes when only one button is displayed
2127 min-width: 35px; //fixes when only one button is displayed
2129 }
2128 }
2130 }
2129 }
2131
2130
2132 .notification-body {
2131 .notification-body {
2133 .markdown-block,
2132 .markdown-block,
2134 .rst-block {
2133 .rst-block {
2135 padding: @padding 0;
2134 padding: @padding 0;
2136 }
2135 }
2137
2136
2138 .notification-subject {
2137 .notification-subject {
2139 padding: @textmargin 0;
2138 padding: @textmargin 0;
2140 border-bottom: @border-thickness solid @border-default-color;
2139 border-bottom: @border-thickness solid @border-default-color;
2141 }
2140 }
2142 }
2141 }
2143
2142
2144 .notice-messages {
2143 .notice-messages {
2145 .markdown-block,
2144 .markdown-block,
2146 .rst-block {
2145 .rst-block {
2147 padding: 0;
2146 padding: 0;
2148 }
2147 }
2149 }
2148 }
2150
2149
2151 .notifications_buttons{
2150 .notifications_buttons{
2152 float: right;
2151 float: right;
2153 }
2152 }
2154
2153
2155 #notification-status{
2154 #notification-status{
2156 display: inline;
2155 display: inline;
2157 }
2156 }
2158
2157
2159 // Repositories
2158 // Repositories
2160
2159
2161 #summary.fields{
2160 #summary.fields{
2162 display: table;
2161 display: table;
2163
2162
2164 .field{
2163 .field{
2165 display: table-row;
2164 display: table-row;
2166
2165
2167 .label-summary{
2166 .label-summary{
2168 display: table-cell;
2167 display: table-cell;
2169 min-width: @label-summary-minwidth;
2168 min-width: @label-summary-minwidth;
2170 padding-top: @padding/2;
2169 padding-top: @padding/2;
2171 padding-bottom: @padding/2;
2170 padding-bottom: @padding/2;
2172 padding-right: @padding/2;
2171 padding-right: @padding/2;
2173 }
2172 }
2174
2173
2175 .input{
2174 .input{
2176 display: table-cell;
2175 display: table-cell;
2177 padding: @padding/2;
2176 padding: @padding/2;
2178
2177
2179 input{
2178 input{
2180 min-width: 29em;
2179 min-width: 29em;
2181 padding: @padding/4;
2180 padding: @padding/4;
2182 }
2181 }
2183 }
2182 }
2184 .statistics, .downloads{
2183 .statistics, .downloads{
2185 .disabled{
2184 .disabled{
2186 color: @grey4;
2185 color: @grey4;
2187 }
2186 }
2188 }
2187 }
2189 }
2188 }
2190 }
2189 }
2191
2190
2192 #summary{
2191 #summary{
2193 width: 70%;
2192 width: 70%;
2194 }
2193 }
2195
2194
2196
2195
2197 // Journal
2196 // Journal
2198 .journal.title {
2197 .journal.title {
2199 h5 {
2198 h5 {
2200 float: left;
2199 float: left;
2201 margin: 0;
2200 margin: 0;
2202 width: 70%;
2201 width: 70%;
2203 }
2202 }
2204
2203
2205 ul {
2204 ul {
2206 float: right;
2205 float: right;
2207 display: inline-block;
2206 display: inline-block;
2208 margin: 0;
2207 margin: 0;
2209 width: 30%;
2208 width: 30%;
2210 text-align: right;
2209 text-align: right;
2211
2210
2212 li {
2211 li {
2213 display: inline;
2212 display: inline;
2214 font-size: @journal-fontsize;
2213 font-size: @journal-fontsize;
2215 line-height: 1em;
2214 line-height: 1em;
2216
2215
2217 list-style-type: none;
2216 list-style-type: none;
2218 }
2217 }
2219 }
2218 }
2220 }
2219 }
2221
2220
2222 .filterexample {
2221 .filterexample {
2223 position: absolute;
2222 position: absolute;
2224 top: 95px;
2223 top: 95px;
2225 left: @contentpadding;
2224 left: @contentpadding;
2226 color: @rcblue;
2225 color: @rcblue;
2227 font-size: 11px;
2226 font-size: 11px;
2228 font-family: @text-regular;
2227 font-family: @text-regular;
2229 cursor: help;
2228 cursor: help;
2230
2229
2231 &:hover {
2230 &:hover {
2232 color: @rcdarkblue;
2231 color: @rcdarkblue;
2233 }
2232 }
2234
2233
2235 @media (max-width:768px) {
2234 @media (max-width:768px) {
2236 position: relative;
2235 position: relative;
2237 top: auto;
2236 top: auto;
2238 left: auto;
2237 left: auto;
2239 display: block;
2238 display: block;
2240 }
2239 }
2241 }
2240 }
2242
2241
2243
2242
2244 #journal{
2243 #journal{
2245 margin-bottom: @space;
2244 margin-bottom: @space;
2246
2245
2247 .journal_day{
2246 .journal_day{
2248 margin-bottom: @textmargin/2;
2247 margin-bottom: @textmargin/2;
2249 padding-bottom: @textmargin/2;
2248 padding-bottom: @textmargin/2;
2250 font-size: @journal-fontsize;
2249 font-size: @journal-fontsize;
2251 border-bottom: @border-thickness solid @border-default-color;
2250 border-bottom: @border-thickness solid @border-default-color;
2252 }
2251 }
2253
2252
2254 .journal_container{
2253 .journal_container{
2255 margin-bottom: @space;
2254 margin-bottom: @space;
2256
2255
2257 .journal_user{
2256 .journal_user{
2258 display: inline-block;
2257 display: inline-block;
2259 }
2258 }
2260 .journal_action_container{
2259 .journal_action_container{
2261 display: block;
2260 display: block;
2262 margin-top: @textmargin;
2261 margin-top: @textmargin;
2263
2262
2264 div{
2263 div{
2265 display: inline;
2264 display: inline;
2266 }
2265 }
2267
2266
2268 div.journal_action_params{
2267 div.journal_action_params{
2269 display: block;
2268 display: block;
2270 }
2269 }
2271
2270
2272 div.journal_repo:after{
2271 div.journal_repo:after{
2273 content: "\A";
2272 content: "\A";
2274 white-space: pre;
2273 white-space: pre;
2275 }
2274 }
2276
2275
2277 div.date{
2276 div.date{
2278 display: block;
2277 display: block;
2279 margin-bottom: @textmargin;
2278 margin-bottom: @textmargin;
2280 }
2279 }
2281 }
2280 }
2282 }
2281 }
2283 }
2282 }
2284
2283
2285 // Files
2284 // Files
2286 .edit-file-title {
2285 .edit-file-title {
2287 font-size: 16px;
2286 font-size: 16px;
2288
2287
2289 .title-heading {
2288 .title-heading {
2290 padding: 2px;
2289 padding: 2px;
2291 }
2290 }
2292 }
2291 }
2293
2292
2294 .edit-file-fieldset {
2293 .edit-file-fieldset {
2295 margin: @sidebarpadding 0;
2294 margin: @sidebarpadding 0;
2296
2295
2297 .fieldset {
2296 .fieldset {
2298 .left-label {
2297 .left-label {
2299 width: 13%;
2298 width: 13%;
2300 }
2299 }
2301 .right-content {
2300 .right-content {
2302 width: 87%;
2301 width: 87%;
2303 max-width: 100%;
2302 max-width: 100%;
2304 }
2303 }
2305 .filename-label {
2304 .filename-label {
2306 margin-top: 13px;
2305 margin-top: 13px;
2307 }
2306 }
2308 .commit-message-label {
2307 .commit-message-label {
2309 margin-top: 4px;
2308 margin-top: 4px;
2310 }
2309 }
2311 .file-upload-input {
2310 .file-upload-input {
2312 input {
2311 input {
2313 display: none;
2312 display: none;
2314 }
2313 }
2315 margin-top: 10px;
2314 margin-top: 10px;
2316 }
2315 }
2317 .file-upload-label {
2316 .file-upload-label {
2318 margin-top: 10px;
2317 margin-top: 10px;
2319 }
2318 }
2320 p {
2319 p {
2321 margin-top: 5px;
2320 margin-top: 5px;
2322 }
2321 }
2323
2322
2324 }
2323 }
2325 .custom-path-link {
2324 .custom-path-link {
2326 margin-left: 5px;
2325 margin-left: 5px;
2327 }
2326 }
2328 #commit {
2327 #commit {
2329 resize: vertical;
2328 resize: vertical;
2330 }
2329 }
2331 }
2330 }
2332
2331
2333 .delete-file-preview {
2332 .delete-file-preview {
2334 max-height: 250px;
2333 max-height: 250px;
2335 }
2334 }
2336
2335
2337 .new-file,
2336 .new-file,
2338 #filter_activate,
2337 #filter_activate,
2339 #filter_deactivate {
2338 #filter_deactivate {
2340 float: right;
2339 float: right;
2341 margin: 0 0 0 10px;
2340 margin: 0 0 0 10px;
2342 }
2341 }
2343
2342
2344 .file-upload-transaction-wrapper {
2343 .file-upload-transaction-wrapper {
2345 margin-top: 57px;
2344 margin-top: 57px;
2346 clear: both;
2345 clear: both;
2347 }
2346 }
2348
2347
2349 .file-upload-transaction-wrapper .error {
2348 .file-upload-transaction-wrapper .error {
2350 color: @color5;
2349 color: @color5;
2351 }
2350 }
2352
2351
2353 .file-upload-transaction {
2352 .file-upload-transaction {
2354 min-height: 200px;
2353 min-height: 200px;
2355 padding: 54px;
2354 padding: 54px;
2356 border: 1px solid @grey5;
2355 border: 1px solid @grey5;
2357 text-align: center;
2356 text-align: center;
2358 clear: both;
2357 clear: both;
2359 }
2358 }
2360
2359
2361 .file-upload-transaction i {
2360 .file-upload-transaction i {
2362 font-size: 48px
2361 font-size: 48px
2363 }
2362 }
2364
2363
2365 h3.files_location{
2364 h3.files_location{
2366 line-height: 2.4em;
2365 line-height: 2.4em;
2367 }
2366 }
2368
2367
2369 .browser-nav {
2368 .browser-nav {
2370 width: 100%;
2369 width: 100%;
2371 display: table;
2370 display: table;
2372 margin-bottom: 20px;
2371 margin-bottom: 20px;
2373
2372
2374 .info_box {
2373 .info_box {
2375 float: left;
2374 float: left;
2376 display: inline-table;
2375 display: inline-table;
2377 height: 2.5em;
2376 height: 2.5em;
2378
2377
2379 .browser-cur-rev, .info_box_elem {
2378 .browser-cur-rev, .info_box_elem {
2380 display: table-cell;
2379 display: table-cell;
2381 vertical-align: middle;
2380 vertical-align: middle;
2382 }
2381 }
2383
2382
2384 .drop-menu {
2383 .drop-menu {
2385 margin: 0 10px;
2384 margin: 0 10px;
2386 }
2385 }
2387
2386
2388 .info_box_elem {
2387 .info_box_elem {
2389 border-top: @border-thickness solid @grey5;
2388 border-top: @border-thickness solid @grey5;
2390 border-bottom: @border-thickness solid @grey5;
2389 border-bottom: @border-thickness solid @grey5;
2391 box-shadow: @button-shadow;
2390 box-shadow: @button-shadow;
2392
2391
2393 #at_rev, a {
2392 #at_rev, a {
2394 padding: 0.6em 0.4em;
2393 padding: 0.6em 0.4em;
2395 margin: 0;
2394 margin: 0;
2396 .box-shadow(none);
2395 .box-shadow(none);
2397 border: 0;
2396 border: 0;
2398 height: 12px;
2397 height: 12px;
2399 color: @grey2;
2398 color: @grey2;
2400 }
2399 }
2401
2400
2402 input#at_rev {
2401 input#at_rev {
2403 max-width: 50px;
2402 max-width: 50px;
2404 text-align: center;
2403 text-align: center;
2405 }
2404 }
2406
2405
2407 &.previous {
2406 &.previous {
2408 border: @border-thickness solid @grey5;
2407 border: @border-thickness solid @grey5;
2409 border-top-left-radius: @border-radius;
2408 border-top-left-radius: @border-radius;
2410 border-bottom-left-radius: @border-radius;
2409 border-bottom-left-radius: @border-radius;
2411
2410
2412 &:hover {
2411 &:hover {
2413 border-color: @grey4;
2412 border-color: @grey4;
2414 }
2413 }
2415
2414
2416 .disabled {
2415 .disabled {
2417 color: @grey5;
2416 color: @grey5;
2418 cursor: not-allowed;
2417 cursor: not-allowed;
2419 opacity: 0.5;
2418 opacity: 0.5;
2420 }
2419 }
2421 }
2420 }
2422
2421
2423 &.next {
2422 &.next {
2424 border: @border-thickness solid @grey5;
2423 border: @border-thickness solid @grey5;
2425 border-top-right-radius: @border-radius;
2424 border-top-right-radius: @border-radius;
2426 border-bottom-right-radius: @border-radius;
2425 border-bottom-right-radius: @border-radius;
2427
2426
2428 &:hover {
2427 &:hover {
2429 border-color: @grey4;
2428 border-color: @grey4;
2430 }
2429 }
2431
2430
2432 .disabled {
2431 .disabled {
2433 color: @grey5;
2432 color: @grey5;
2434 cursor: not-allowed;
2433 cursor: not-allowed;
2435 opacity: 0.5;
2434 opacity: 0.5;
2436 }
2435 }
2437 }
2436 }
2438 }
2437 }
2439
2438
2440 .browser-cur-rev {
2439 .browser-cur-rev {
2441
2440
2442 span{
2441 span{
2443 margin: 0;
2442 margin: 0;
2444 color: @rcblue;
2443 color: @rcblue;
2445 height: 12px;
2444 height: 12px;
2446 display: inline-block;
2445 display: inline-block;
2447 padding: 0.7em 1em ;
2446 padding: 0.7em 1em ;
2448 border: @border-thickness solid @rcblue;
2447 border: @border-thickness solid @rcblue;
2449 margin-right: @padding;
2448 margin-right: @padding;
2450 }
2449 }
2451 }
2450 }
2452
2451
2453 }
2452 }
2454
2453
2455 .select-index-number {
2454 .select-index-number {
2456 margin: 0 0 0 20px;
2455 margin: 0 0 0 20px;
2457 color: @grey3;
2456 color: @grey3;
2458 }
2457 }
2459
2458
2460 .search_activate {
2459 .search_activate {
2461 display: table-cell;
2460 display: table-cell;
2462 vertical-align: middle;
2461 vertical-align: middle;
2463
2462
2464 input, label{
2463 input, label{
2465 margin: 0;
2464 margin: 0;
2466 padding: 0;
2465 padding: 0;
2467 }
2466 }
2468
2467
2469 input{
2468 input{
2470 margin-left: @textmargin;
2469 margin-left: @textmargin;
2471 }
2470 }
2472
2471
2473 }
2472 }
2474 }
2473 }
2475
2474
2476 .browser-cur-rev{
2475 .browser-cur-rev{
2477 margin-bottom: @textmargin;
2476 margin-bottom: @textmargin;
2478 }
2477 }
2479
2478
2480 #node_filter_box_loading{
2479 #node_filter_box_loading{
2481 .info_text;
2480 .info_text;
2482 }
2481 }
2483
2482
2484 .browser-search {
2483 .browser-search {
2485 margin: -25px 0px 5px 0px;
2484 margin: -25px 0px 5px 0px;
2486 }
2485 }
2487
2486
2488 .files-quick-filter {
2487 .files-quick-filter {
2489 float: right;
2488 float: right;
2490 width: 180px;
2489 width: 180px;
2491 position: relative;
2490 position: relative;
2492 }
2491 }
2493
2492
2494 .files-filter-box {
2493 .files-filter-box {
2495 display: flex;
2494 display: flex;
2496 padding: 0px;
2495 padding: 0px;
2497 border-radius: 3px;
2496 border-radius: 3px;
2498 margin-bottom: 0;
2497 margin-bottom: 0;
2499
2498
2500 a {
2499 a {
2501 border: none !important;
2500 border: none !important;
2502 }
2501 }
2503
2502
2504 li {
2503 li {
2505 list-style-type: none
2504 list-style-type: none
2506 }
2505 }
2507 }
2506 }
2508
2507
2509 .files-filter-box-path {
2508 .files-filter-box-path {
2510 line-height: 33px;
2509 line-height: 33px;
2511 padding: 0;
2510 padding: 0;
2512 width: 20px;
2511 width: 20px;
2513 position: absolute;
2512 position: absolute;
2514 z-index: 11;
2513 z-index: 11;
2515 left: 5px;
2514 left: 5px;
2516 }
2515 }
2517
2516
2518 .files-filter-box-input {
2517 .files-filter-box-input {
2519 margin-right: 0;
2518 margin-right: 0;
2520
2519
2521 input {
2520 input {
2522 border: 1px solid @white;
2521 border: 1px solid @white;
2523 padding-left: 25px;
2522 padding-left: 25px;
2524 width: 145px;
2523 width: 145px;
2525
2524
2526 &:hover {
2525 &:hover {
2527 border-color: @grey6;
2526 border-color: @grey6;
2528 }
2527 }
2529
2528
2530 &:focus {
2529 &:focus {
2531 border-color: @grey5;
2530 border-color: @grey5;
2532 }
2531 }
2533 }
2532 }
2534 }
2533 }
2535
2534
2536 .browser-result{
2535 .browser-result{
2537 td a{
2536 td a{
2538 margin-left: 0.5em;
2537 margin-left: 0.5em;
2539 display: inline-block;
2538 display: inline-block;
2540
2539
2541 em {
2540 em {
2542 font-weight: @text-bold-weight;
2541 font-weight: @text-bold-weight;
2543 font-family: @text-bold;
2542 font-family: @text-bold;
2544 }
2543 }
2545 }
2544 }
2546 }
2545 }
2547
2546
2548 .browser-highlight{
2547 .browser-highlight{
2549 background-color: @grey5-alpha;
2548 background-color: @grey5-alpha;
2550 }
2549 }
2551
2550
2552
2551
2553 .edit-file-fieldset #location,
2552 .edit-file-fieldset #location,
2554 .edit-file-fieldset #filename {
2553 .edit-file-fieldset #filename {
2555 display: flex;
2554 display: flex;
2556 width: -moz-available; /* WebKit-based browsers will ignore this. */
2555 width: -moz-available; /* WebKit-based browsers will ignore this. */
2557 width: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
2556 width: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
2558 width: fill-available;
2557 width: fill-available;
2559 border: 0;
2558 border: 0;
2560 }
2559 }
2561
2560
2562 .path-items {
2561 .path-items {
2563 display: flex;
2562 display: flex;
2564 padding: 0;
2563 padding: 0;
2565 border: 1px solid #eeeeee;
2564 border: 1px solid #eeeeee;
2566 width: 100%;
2565 width: 100%;
2567 float: left;
2566 float: left;
2568
2567
2569 .breadcrumb-path {
2568 .breadcrumb-path {
2570 line-height: 30px;
2569 line-height: 30px;
2571 padding: 0 4px;
2570 padding: 0 4px;
2572 white-space: nowrap;
2571 white-space: nowrap;
2573 }
2572 }
2574
2573
2575 .upload-form {
2574 .upload-form {
2576 margin-top: 46px;
2575 margin-top: 46px;
2577 }
2576 }
2578
2577
2579 .location-path {
2578 .location-path {
2580 width: -moz-available; /* WebKit-based browsers will ignore this. */
2579 width: -moz-available; /* WebKit-based browsers will ignore this. */
2581 width: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
2580 width: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
2582 width: fill-available;
2581 width: fill-available;
2583
2582
2584 .file-name-input {
2583 .file-name-input {
2585 padding: 0.5em 0;
2584 padding: 0.5em 0;
2586 }
2585 }
2587
2586
2588 }
2587 }
2589
2588
2590 ul {
2589 ul {
2591 display: flex;
2590 display: flex;
2592 margin: 0;
2591 margin: 0;
2593 padding: 0;
2592 padding: 0;
2594 width: 100%;
2593 width: 100%;
2595 }
2594 }
2596
2595
2597 li {
2596 li {
2598 list-style-type: none;
2597 list-style-type: none;
2599 }
2598 }
2600
2599
2601 }
2600 }
2602
2601
2603 .editor-items {
2602 .editor-items {
2604 height: 40px;
2603 height: 40px;
2605 margin: 10px 0 -17px 10px;
2604 margin: 10px 0 -17px 10px;
2606
2605
2607 .editor-action {
2606 .editor-action {
2608 cursor: pointer;
2607 cursor: pointer;
2609 }
2608 }
2610
2609
2611 .editor-action.active {
2610 .editor-action.active {
2612 border-bottom: 2px solid #5C5C5C;
2611 border-bottom: 2px solid #5C5C5C;
2613 }
2612 }
2614
2613
2615 li {
2614 li {
2616 list-style-type: none;
2615 list-style-type: none;
2617 }
2616 }
2618 }
2617 }
2619
2618
2620 .edit-file-fieldset .message textarea {
2619 .edit-file-fieldset .message textarea {
2621 border: 1px solid #eeeeee;
2620 border: 1px solid #eeeeee;
2622 }
2621 }
2623
2622
2624 #files_data .codeblock {
2623 #files_data .codeblock {
2625 background-color: #F5F5F5;
2624 background-color: #F5F5F5;
2626 }
2625 }
2627
2626
2628 #editor_preview {
2627 #editor_preview {
2629 background: white;
2628 background: white;
2630 }
2629 }
2631
2630
2632 .show-editor {
2631 .show-editor {
2633 padding: 10px;
2632 padding: 10px;
2634 background-color: white;
2633 background-color: white;
2635
2634
2636 }
2635 }
2637
2636
2638 .show-preview {
2637 .show-preview {
2639 padding: 10px;
2638 padding: 10px;
2640 background-color: white;
2639 background-color: white;
2641 border-left: 1px solid #eeeeee;
2640 border-left: 1px solid #eeeeee;
2642 }
2641 }
2643 // quick filter
2642 // quick filter
2644 .grid-quick-filter {
2643 .grid-quick-filter {
2645 float: right;
2644 float: right;
2646 position: relative;
2645 position: relative;
2647 }
2646 }
2648
2647
2649 .grid-filter-box {
2648 .grid-filter-box {
2650 display: flex;
2649 display: flex;
2651 padding: 0px;
2650 padding: 0px;
2652 border-radius: 3px;
2651 border-radius: 3px;
2653 margin-bottom: 0;
2652 margin-bottom: 0;
2654
2653
2655 a {
2654 a {
2656 border: none !important;
2655 border: none !important;
2657 }
2656 }
2658
2657
2659 li {
2658 li {
2660 list-style-type: none
2659 list-style-type: none
2661 }
2660 }
2662
2661
2663 }
2662 }
2664
2663
2665 .grid-filter-box-icon {
2664 .grid-filter-box-icon {
2666 line-height: 33px;
2665 line-height: 33px;
2667 padding: 0;
2666 padding: 0;
2668 width: 20px;
2667 width: 20px;
2669 position: absolute;
2668 position: absolute;
2670 z-index: 11;
2669 z-index: 11;
2671 left: 5px;
2670 left: 5px;
2672 }
2671 }
2673
2672
2674 .grid-filter-box-input {
2673 .grid-filter-box-input {
2675 margin-right: 0;
2674 margin-right: 0;
2676
2675
2677 input {
2676 input {
2678 border: 1px solid @white;
2677 border: 1px solid @white;
2679 padding-left: 25px;
2678 padding-left: 25px;
2680 width: 145px;
2679 width: 145px;
2681
2680
2682 &:hover {
2681 &:hover {
2683 border-color: @grey6;
2682 border-color: @grey6;
2684 }
2683 }
2685
2684
2686 &:focus {
2685 &:focus {
2687 border-color: @grey5;
2686 border-color: @grey5;
2688 }
2687 }
2689 }
2688 }
2690 }
2689 }
2691
2690
2692
2691
2693
2692
2694 // Search
2693 // Search
2695
2694
2696 .search-form{
2695 .search-form{
2697 #q {
2696 #q {
2698 width: @search-form-width;
2697 width: @search-form-width;
2699 }
2698 }
2700 .fields{
2699 .fields{
2701 margin: 0 0 @space;
2700 margin: 0 0 @space;
2702 }
2701 }
2703
2702
2704 label{
2703 label{
2705 display: inline-block;
2704 display: inline-block;
2706 margin-right: @textmargin;
2705 margin-right: @textmargin;
2707 padding-top: 0.25em;
2706 padding-top: 0.25em;
2708 }
2707 }
2709
2708
2710
2709
2711 .results{
2710 .results{
2712 clear: both;
2711 clear: both;
2713 margin: 0 0 @padding;
2712 margin: 0 0 @padding;
2714 }
2713 }
2715
2714
2716 .search-tags {
2715 .search-tags {
2717 padding: 5px 0;
2716 padding: 5px 0;
2718 }
2717 }
2719 }
2718 }
2720
2719
2721 div.search-feedback-items {
2720 div.search-feedback-items {
2722 display: inline-block;
2721 display: inline-block;
2723 }
2722 }
2724
2723
2725 div.search-code-body {
2724 div.search-code-body {
2726 background-color: #ffffff; padding: 5px 0 5px 10px;
2725 background-color: #ffffff; padding: 5px 0 5px 10px;
2727 pre {
2726 pre {
2728 .match { background-color: #faffa6;}
2727 .match { background-color: #faffa6;}
2729 .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; }
2728 .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; }
2730 }
2729 }
2731 }
2730 }
2732
2731
2733 .expand_commit.search {
2732 .expand_commit.search {
2734 .show_more.open {
2733 .show_more.open {
2735 height: auto;
2734 height: auto;
2736 max-height: none;
2735 max-height: none;
2737 }
2736 }
2738 }
2737 }
2739
2738
2740 .search-results {
2739 .search-results {
2741
2740
2742 h2 {
2741 h2 {
2743 margin-bottom: 0;
2742 margin-bottom: 0;
2744 }
2743 }
2745 .codeblock {
2744 .codeblock {
2746 border: none;
2745 border: none;
2747 background: transparent;
2746 background: transparent;
2748 }
2747 }
2749
2748
2750 .codeblock-header {
2749 .codeblock-header {
2751 border: none;
2750 border: none;
2752 background: transparent;
2751 background: transparent;
2753 }
2752 }
2754
2753
2755 .code-body {
2754 .code-body {
2756 border: @border-thickness solid @grey6;
2755 border: @border-thickness solid @grey6;
2757 .border-radius(@border-radius);
2756 .border-radius(@border-radius);
2758 }
2757 }
2759
2758
2760 .td-commit {
2759 .td-commit {
2761 &:extend(pre);
2760 &:extend(pre);
2762 border-bottom: @border-thickness solid @border-default-color;
2761 border-bottom: @border-thickness solid @border-default-color;
2763 }
2762 }
2764
2763
2765 .message {
2764 .message {
2766 height: auto;
2765 height: auto;
2767 max-width: 350px;
2766 max-width: 350px;
2768 white-space: normal;
2767 white-space: normal;
2769 text-overflow: initial;
2768 text-overflow: initial;
2770 overflow: visible;
2769 overflow: visible;
2771
2770
2772 .match { background-color: #faffa6;}
2771 .match { background-color: #faffa6;}
2773 .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; }
2772 .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; }
2774 }
2773 }
2775
2774
2776 .path {
2775 .path {
2777 border-bottom: none !important;
2776 border-bottom: none !important;
2778 border-left: 1px solid @grey6 !important;
2777 border-left: 1px solid @grey6 !important;
2779 border-right: 1px solid @grey6 !important;
2778 border-right: 1px solid @grey6 !important;
2780 }
2779 }
2781 }
2780 }
2782
2781
2783 table.rctable td.td-search-results div {
2782 table.rctable td.td-search-results div {
2784 max-width: 100%;
2783 max-width: 100%;
2785 }
2784 }
2786
2785
2787 #tip-box, .tip-box{
2786 #tip-box, .tip-box{
2788 padding: @menupadding/2;
2787 padding: @menupadding/2;
2789 display: block;
2788 display: block;
2790 border: @border-thickness solid @border-highlight-color;
2789 border: @border-thickness solid @border-highlight-color;
2791 .border-radius(@border-radius);
2790 .border-radius(@border-radius);
2792 background-color: white;
2791 background-color: white;
2793 z-index: 99;
2792 z-index: 99;
2794 white-space: pre-wrap;
2793 white-space: pre-wrap;
2795 }
2794 }
2796
2795
2797 #linktt {
2796 #linktt {
2798 width: 79px;
2797 width: 79px;
2799 }
2798 }
2800
2799
2801 #help_kb .modal-content{
2800 #help_kb .modal-content{
2802 max-width: 800px;
2801 max-width: 800px;
2803 margin: 10% auto;
2802 margin: 10% auto;
2804
2803
2805 table{
2804 table{
2806 td,th{
2805 td,th{
2807 border-bottom: none;
2806 border-bottom: none;
2808 line-height: 2.5em;
2807 line-height: 2.5em;
2809 }
2808 }
2810 th{
2809 th{
2811 padding-bottom: @textmargin/2;
2810 padding-bottom: @textmargin/2;
2812 }
2811 }
2813 td.keys{
2812 td.keys{
2814 text-align: center;
2813 text-align: center;
2815 }
2814 }
2816 }
2815 }
2817
2816
2818 .block-left{
2817 .block-left{
2819 width: 45%;
2818 width: 45%;
2820 margin-right: 5%;
2819 margin-right: 5%;
2821 }
2820 }
2822 .modal-footer{
2821 .modal-footer{
2823 clear: both;
2822 clear: both;
2824 }
2823 }
2825 .key.tag{
2824 .key.tag{
2826 padding: 0.5em;
2825 padding: 0.5em;
2827 background-color: @rcblue;
2826 background-color: @rcblue;
2828 color: white;
2827 color: white;
2829 border-color: @rcblue;
2828 border-color: @rcblue;
2830 .box-shadow(none);
2829 .box-shadow(none);
2831 }
2830 }
2832 }
2831 }
2833
2832
2834
2833
2835
2834
2836 //--- IMPORTS FOR REFACTORED STYLES ------------------//
2835 //--- IMPORTS FOR REFACTORED STYLES ------------------//
2837
2836
2838 @import 'statistics-graph';
2837 @import 'statistics-graph';
2839 @import 'tables';
2838 @import 'tables';
2840 @import 'forms';
2839 @import 'forms';
2841 @import 'diff';
2840 @import 'diff';
2842 @import 'summary';
2841 @import 'summary';
2843 @import 'navigation';
2842 @import 'navigation';
2844
2843
2845 //--- SHOW/HIDE SECTIONS --//
2844 //--- SHOW/HIDE SECTIONS --//
2846
2845
2847 .btn-collapse {
2846 .btn-collapse {
2848 float: right;
2847 float: right;
2849 text-align: right;
2848 text-align: right;
2850 font-family: @text-light;
2849 font-family: @text-light;
2851 font-size: @basefontsize;
2850 font-size: @basefontsize;
2852 cursor: pointer;
2851 cursor: pointer;
2853 border: none;
2852 border: none;
2854 color: @rcblue;
2853 color: @rcblue;
2855 }
2854 }
2856
2855
2857 table.rctable,
2856 table.rctable,
2858 table.dataTable {
2857 table.dataTable {
2859 .btn-collapse {
2858 .btn-collapse {
2860 float: right;
2859 float: right;
2861 text-align: right;
2860 text-align: right;
2862 }
2861 }
2863 }
2862 }
2864
2863
2865 table.rctable {
2864 table.rctable {
2866 &.permissions {
2865 &.permissions {
2867
2866
2868 th.td-owner {
2867 th.td-owner {
2869 padding: 0;
2868 padding: 0;
2870 }
2869 }
2871
2870
2872 th {
2871 th {
2873 font-weight: normal;
2872 font-weight: normal;
2874 padding: 0 5px;
2873 padding: 0 5px;
2875 }
2874 }
2876
2875
2877 }
2876 }
2878 }
2877 }
2879
2878
2880
2879
2881 // TODO: johbo: Fix for IE10, this avoids that we see a border
2880 // TODO: johbo: Fix for IE10, this avoids that we see a border
2882 // and padding around checkboxes and radio boxes. Move to the right place,
2881 // and padding around checkboxes and radio boxes. Move to the right place,
2883 // or better: Remove this once we did the form refactoring.
2882 // or better: Remove this once we did the form refactoring.
2884 input[type=checkbox],
2883 input[type=checkbox],
2885 input[type=radio] {
2884 input[type=radio] {
2886 padding: 0;
2885 padding: 0;
2887 border: none;
2886 border: none;
2888 }
2887 }
2889
2888
2890 .toggle-ajax-spinner{
2889 .toggle-ajax-spinner{
2891 height: 16px;
2890 height: 16px;
2892 width: 16px;
2891 width: 16px;
2893 }
2892 }
2894
2893
2895
2894
2896 .markup-form .clearfix {
2895 .markup-form .clearfix {
2897 .border-radius(@border-radius);
2896 .border-radius(@border-radius);
2898 margin: 0px;
2897 margin: 0px;
2899 }
2898 }
2900
2899
2901 .markup-form-area {
2900 .markup-form-area {
2902 padding: 8px 12px;
2901 padding: 8px 12px;
2903 border: 1px solid @grey4;
2902 border: 1px solid @grey4;
2904 .border-radius(@border-radius);
2903 .border-radius(@border-radius);
2905 }
2904 }
2906
2905
2907 .markup-form-area-header .nav-links {
2906 .markup-form-area-header .nav-links {
2908 display: flex;
2907 display: flex;
2909 flex-flow: row wrap;
2908 flex-flow: row wrap;
2910 -webkit-flex-flow: row wrap;
2909 -webkit-flex-flow: row wrap;
2911 width: 100%;
2910 width: 100%;
2912 }
2911 }
2913
2912
2914 .markup-form-area-footer {
2913 .markup-form-area-footer {
2915 display: flex;
2914 display: flex;
2916 }
2915 }
2917
2916
2918 .markup-form-area-footer .toolbar {
2917 .markup-form-area-footer .toolbar {
2919
2918
2920 }
2919 }
2921
2920
2922 // markup Form
2921 // markup Form
2923 div.markup-form {
2922 div.markup-form {
2924 margin-top: 20px;
2923 margin-top: 20px;
2925 }
2924 }
2926
2925
2927 .markup-form strong {
2926 .markup-form strong {
2928 display: block;
2927 display: block;
2929 margin-bottom: 15px;
2928 margin-bottom: 15px;
2930 }
2929 }
2931
2930
2932 .markup-form textarea {
2931 .markup-form textarea {
2933 width: 100%;
2932 width: 100%;
2934 height: 100px;
2933 height: 100px;
2935 font-family: @text-monospace;
2934 font-family: @text-monospace;
2936 }
2935 }
2937
2936
2938 form.markup-form {
2937 form.markup-form {
2939 margin-top: 10px;
2938 margin-top: 10px;
2940 margin-left: 10px;
2939 margin-left: 10px;
2941 }
2940 }
2942
2941
2943 .markup-form .comment-block-ta,
2942 .markup-form .comment-block-ta,
2944 .markup-form .preview-box {
2943 .markup-form .preview-box {
2945 .border-radius(@border-radius);
2944 .border-radius(@border-radius);
2946 .box-sizing(border-box);
2945 .box-sizing(border-box);
2947 background-color: white;
2946 background-color: white;
2948 }
2947 }
2949
2948
2950 .markup-form .preview-box.unloaded {
2949 .markup-form .preview-box.unloaded {
2951 height: 50px;
2950 height: 50px;
2952 text-align: center;
2951 text-align: center;
2953 padding: 20px;
2952 padding: 20px;
2954 background-color: white;
2953 background-color: white;
2955 }
2954 }
2956
2955
2957
2956
2958 .dropzone-wrapper {
2957 .dropzone-wrapper {
2959 border: 1px solid @grey5;
2958 border: 1px solid @grey5;
2960 padding: 20px;
2959 padding: 20px;
2961 }
2960 }
2962
2961
2963 .dropzone,
2962 .dropzone,
2964 .dropzone-pure {
2963 .dropzone-pure {
2965 border: 2px dashed @grey5;
2964 border: 2px dashed @grey5;
2966 border-radius: 5px;
2965 border-radius: 5px;
2967 background: white;
2966 background: white;
2968 min-height: 200px;
2967 min-height: 200px;
2969 padding: 54px;
2968 padding: 54px;
2970
2969
2971 .dz-message {
2970 .dz-message {
2972 font-weight: 700;
2971 font-weight: 700;
2973 text-align: center;
2972 text-align: center;
2974 margin: 2em 0;
2973 margin: 2em 0;
2975 }
2974 }
2976
2975
2977 }
2976 }
2978
2977
2979 .dz-preview {
2978 .dz-preview {
2980 margin: 10px 0 !important;
2979 margin: 10px 0 !important;
2981 position: relative;
2980 position: relative;
2982 vertical-align: top;
2981 vertical-align: top;
2983 padding: 10px;
2982 padding: 10px;
2984 border-bottom: 1px solid @grey5;
2983 border-bottom: 1px solid @grey5;
2985 }
2984 }
2986
2985
2987 .dz-filename {
2986 .dz-filename {
2988 font-weight: 700;
2987 font-weight: 700;
2989 float: left;
2988 float: left;
2990 }
2989 }
2991
2990
2992 .dz-sending {
2991 .dz-sending {
2993 float: right;
2992 float: right;
2994 }
2993 }
2995
2994
2996 .dz-response {
2995 .dz-response {
2997 clear: both
2996 clear: both
2998 }
2997 }
2999
2998
3000 .dz-filename-size {
2999 .dz-filename-size {
3001 float: right
3000 float: right
3002 }
3001 }
3003
3002
3004 .dz-error-message {
3003 .dz-error-message {
3005 color: @alert2;
3004 color: @alert2;
3006 padding-top: 10px;
3005 padding-top: 10px;
3007 clear: both;
3006 clear: both;
3008 }
3007 }
3009
3008
3010
3009
3011 .user-hovercard {
3010 .user-hovercard {
3012 padding: 5px;
3011 padding: 5px;
3013 }
3012 }
3014
3013
3015 .user-hovercard-icon {
3014 .user-hovercard-icon {
3016 display: inline;
3015 display: inline;
3017 padding: 0;
3016 padding: 0;
3018 box-sizing: content-box;
3017 box-sizing: content-box;
3019 border-radius: 50%;
3018 border-radius: 50%;
3020 float: left;
3019 float: left;
3021 }
3020 }
3022
3021
3023 .user-hovercard-name {
3022 .user-hovercard-name {
3024 float: right;
3023 float: right;
3025 vertical-align: top;
3024 vertical-align: top;
3026 padding-left: 10px;
3025 padding-left: 10px;
3027 min-width: 150px;
3026 min-width: 150px;
3028 }
3027 }
3029
3028
3030 .user-hovercard-bio {
3029 .user-hovercard-bio {
3031 clear: both;
3030 clear: both;
3032 padding-top: 10px;
3031 padding-top: 10px;
3033 }
3032 }
3034
3033
3035 .user-hovercard-header {
3034 .user-hovercard-header {
3036 clear: both;
3035 clear: both;
3037 min-height: 10px;
3036 min-height: 10px;
3038 }
3037 }
3039
3038
3040 .user-hovercard-footer {
3039 .user-hovercard-footer {
3041 clear: both;
3040 clear: both;
3042 min-height: 10px;
3041 min-height: 10px;
3043 }
3042 }
3044
3043
3045 .user-group-hovercard {
3044 .user-group-hovercard {
3046 padding: 5px;
3045 padding: 5px;
3047 }
3046 }
3048
3047
3049 .user-group-hovercard-icon {
3048 .user-group-hovercard-icon {
3050 display: inline;
3049 display: inline;
3051 padding: 0;
3050 padding: 0;
3052 box-sizing: content-box;
3051 box-sizing: content-box;
3053 border-radius: 50%;
3052 border-radius: 50%;
3054 float: left;
3053 float: left;
3055 }
3054 }
3056
3055
3057 .user-group-hovercard-name {
3056 .user-group-hovercard-name {
3058 float: left;
3057 float: left;
3059 vertical-align: top;
3058 vertical-align: top;
3060 padding-left: 10px;
3059 padding-left: 10px;
3061 min-width: 150px;
3060 min-width: 150px;
3062 }
3061 }
3063
3062
3064 .user-group-hovercard-icon i {
3063 .user-group-hovercard-icon i {
3065 border: 1px solid @grey4;
3064 border: 1px solid @grey4;
3066 border-radius: 4px;
3065 border-radius: 4px;
3067 }
3066 }
3068
3067
3069 .user-group-hovercard-bio {
3068 .user-group-hovercard-bio {
3070 clear: both;
3069 clear: both;
3071 padding-top: 10px;
3070 padding-top: 10px;
3072 line-height: 1.0em;
3071 line-height: 1.0em;
3073 }
3072 }
3074
3073
3075 .user-group-hovercard-header {
3074 .user-group-hovercard-header {
3076 clear: both;
3075 clear: both;
3077 min-height: 10px;
3076 min-height: 10px;
3078 }
3077 }
3079
3078
3080 .user-group-hovercard-footer {
3079 .user-group-hovercard-footer {
3081 clear: both;
3080 clear: both;
3082 min-height: 10px;
3081 min-height: 10px;
3083 }
3082 }
3084
3083
3085 .pr-hovercard-header {
3084 .pr-hovercard-header {
3086 clear: both;
3085 clear: both;
3087 display: block;
3086 display: block;
3088 line-height: 20px;
3087 line-height: 20px;
3089 }
3088 }
3090
3089
3091 .pr-hovercard-user {
3090 .pr-hovercard-user {
3092 display: flex;
3091 display: flex;
3093 align-items: center;
3092 align-items: center;
3094 padding-left: 5px;
3093 padding-left: 5px;
3095 }
3094 }
3096
3095
3097 .pr-hovercard-title {
3096 .pr-hovercard-title {
3098 padding-top: 5px;
3097 padding-top: 5px;
3099 }
3098 }
3100
3099
3101 .action-divider {
3100 .action-divider {
3102 opacity: 0.5;
3101 opacity: 0.5;
3103 }
3102 }
3104
3103
3105 .details-inline-block {
3104 .details-inline-block {
3106 display: inline-block;
3105 display: inline-block;
3107 position: relative;
3106 position: relative;
3108 }
3107 }
3109
3108
3110 .details-inline-block summary {
3109 .details-inline-block summary {
3111 list-style: none;
3110 list-style: none;
3112 }
3111 }
3113
3112
3114 details:not([open]) > :not(summary) {
3113 details:not([open]) > :not(summary) {
3115 display: none !important;
3114 display: none !important;
3116 }
3115 }
3117
3116
3118 .details-reset > summary {
3117 .details-reset > summary {
3119 list-style: none;
3118 list-style: none;
3120 }
3119 }
3121
3120
3122 .details-reset > summary::-webkit-details-marker {
3121 .details-reset > summary::-webkit-details-marker {
3123 display: none;
3122 display: none;
3124 }
3123 }
3125
3124
3126 .details-dropdown {
3125 .details-dropdown {
3127 position: absolute;
3126 position: absolute;
3128 top: 100%;
3127 top: 100%;
3129 width: 185px;
3128 width: 185px;
3130 list-style: none;
3129 list-style: none;
3131 background-color: #fff;
3130 background-color: #fff;
3132 background-clip: padding-box;
3131 background-clip: padding-box;
3133 border: 1px solid @grey5;
3132 border: 1px solid @grey5;
3134 box-shadow: 0 8px 24px rgba(149, 157, 165, .2);
3133 box-shadow: 0 8px 24px rgba(149, 157, 165, .2);
3135 left: -150px;
3134 left: -150px;
3136 text-align: left;
3135 text-align: left;
3137 z-index: 90;
3136 z-index: 90;
3138 }
3137 }
3139
3138
3140 .dropdown-divider {
3139 .dropdown-divider {
3141 display: block;
3140 display: block;
3142 height: 0;
3141 height: 0;
3143 margin: 8px 0;
3142 margin: 8px 0;
3144 border-top: 1px solid @grey5;
3143 border-top: 1px solid @grey5;
3145 }
3144 }
3146
3145
3147 .dropdown-item {
3146 .dropdown-item {
3148 display: block;
3147 display: block;
3149 padding: 4px 8px 4px 16px;
3148 padding: 4px 8px 4px 16px;
3150 overflow: hidden;
3149 overflow: hidden;
3151 text-overflow: ellipsis;
3150 text-overflow: ellipsis;
3152 white-space: nowrap;
3151 white-space: nowrap;
3153 font-weight: normal;
3152 font-weight: normal;
3154 }
3153 }
3155
3154
3156 .right-sidebar {
3155 .right-sidebar {
3157 position: fixed;
3156 position: fixed;
3158 top: 0px;
3157 top: 0px;
3159 bottom: 0;
3158 bottom: 0;
3160 right: 0;
3159 right: 0;
3161
3160
3162 background: #fafafa;
3161 background: #fafafa;
3163 z-index: 50;
3162 z-index: 50;
3164 }
3163 }
3165
3164
3166 .right-sidebar {
3165 .right-sidebar {
3167 border-left: 1px solid @grey5;
3166 border-left: 1px solid @grey5;
3168 }
3167 }
3169
3168
3170 .right-sidebar.right-sidebar-expanded {
3169 .right-sidebar.right-sidebar-expanded {
3171 width: 300px;
3170 width: 300px;
3172 overflow: scroll;
3171 overflow: scroll;
3173 }
3172 }
3174
3173
3175 .right-sidebar.right-sidebar-collapsed {
3174 .right-sidebar.right-sidebar-collapsed {
3176 width: 40px;
3175 width: 40px;
3177 padding: 0;
3176 padding: 0;
3178 display: block;
3177 display: block;
3179 overflow: hidden;
3178 overflow: hidden;
3180 }
3179 }
3181
3180
3182 .sidenav {
3181 .sidenav {
3183 float: right;
3182 float: right;
3184 will-change: min-height;
3183 will-change: min-height;
3185 background: #fafafa;
3184 background: #fafafa;
3186 width: 100%;
3185 width: 100%;
3187 }
3186 }
3188
3187
3189 .sidebar-toggle {
3188 .sidebar-toggle {
3190 height: 30px;
3189 height: 30px;
3191 text-align: center;
3190 text-align: center;
3192 margin: 15px 0px 0 0;
3191 margin: 15px 0px 0 0;
3193 }
3192 }
3194
3193
3195 .sidebar-toggle a {
3194 .sidebar-toggle a {
3196
3195
3197 }
3196 }
3198
3197
3199 .sidebar-content {
3198 .sidebar-content {
3200 margin-left: 15px;
3199 margin-left: 15px;
3201 margin-right: 15px;
3200 margin-right: 15px;
3202 }
3201 }
3203
3202
3204 .sidebar-heading {
3203 .sidebar-heading {
3205 font-size: 1.2em;
3204 font-size: 1.2em;
3206 font-weight: 700;
3205 font-weight: 700;
3207 margin-top: 10px;
3206 margin-top: 10px;
3208 }
3207 }
3209
3208
3210 .sidebar-element {
3209 .sidebar-element {
3211 margin-top: 20px;
3210 margin-top: 20px;
3212
3211
3213 .icon-draft {
3212 .icon-draft {
3214 color: @color-draft
3213 color: @color-draft
3215 }
3214 }
3216 }
3215 }
3217
3216
3218
3217
3219 .right-sidebar-collapsed-state {
3218 .right-sidebar-collapsed-state {
3220 display: flex;
3219 display: flex;
3221 flex-direction: column;
3220 flex-direction: column;
3222 justify-content: center;
3221 justify-content: center;
3223 align-items: center;
3222 align-items: center;
3224 padding: 0 10px;
3223 padding: 0 10px;
3225 cursor: pointer;
3224 cursor: pointer;
3226 font-size: 1.3em;
3225 font-size: 1.3em;
3227 margin: 0 -15px;
3226 margin: 0 -15px;
3228 }
3227 }
3229
3228
3230 .right-sidebar-collapsed-state:hover {
3229 .right-sidebar-collapsed-state:hover {
3231 background-color: @grey5;
3230 background-color: @grey5;
3232 }
3231 }
3233
3232
3234 .old-comments-marker {
3233 .old-comments-marker {
3235 text-align: left;
3234 text-align: left;
3236 }
3235 }
3237
3236
3238 .old-comments-marker td {
3237 .old-comments-marker td {
3239 padding-top: 15px;
3238 padding-top: 15px;
3240 }
3239 }
@@ -1,326 +1,353 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%inherit file="/base/base.mako"/>
3 <%inherit file="/base/base.mako"/>
4
4
5 <%def name="title()">
5 <%def name="title()">
6 ${_('%s Changelog') % c.repo_name}
6 ${_('%s Changelog') % c.repo_name}
7 %if c.changelog_for_path:
7 %if c.changelog_for_path:
8 /${c.changelog_for_path}
8 /${c.changelog_for_path}
9 %endif
9 %endif
10 %if c.rhodecode_name:
10 %if c.rhodecode_name:
11 &middot; ${h.branding(c.rhodecode_name)}
11 &middot; ${h.branding(c.rhodecode_name)}
12 %endif
12 %endif
13 </%def>
13 </%def>
14
14
15 <%def name="breadcrumbs_links()">
15 <%def name="breadcrumbs_links()">
16 %if c.changelog_for_path:
16 %if c.changelog_for_path:
17 /${c.changelog_for_path}
17 /${c.changelog_for_path}
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='commits')}
26 ${self.repo_menu(active='commits')}
27 </%def>
27 </%def>
28
28
29 <%def name="main()">
29 <%def name="main()">
30
30
31 <div class="box">
31 <div class="box">
32
32
33 <div class="title">
33 <div class="title">
34 <div id="filter_changelog">
34 <div id="filter_changelog">
35 ${h.hidden('branch_filter')}
35 ${h.hidden('branch_filter')}
36 %if c.selected_name:
36 %if c.selected_name:
37 <div class="btn btn-default" id="clear_filter" >
37 <div class="btn btn-default" id="clear_filter" >
38 ${_('Clear filter')}
38 ${_('Clear filter')}
39 </div>
39 </div>
40 %endif
40 %endif
41 </div>
41 </div>
42 <div class="pull-left obsolete-toggle">
42 <div class="pull-left obsolete-toggle">
43 % if h.is_hg(c.rhodecode_repo):
43 % if h.is_hg(c.rhodecode_repo):
44 % if c.show_hidden:
44 % if c.show_hidden:
45 <a class="action-link" href="${h.current_route_path(request, evolve=0)}">${_('Hide obsolete/hidden')}</a>
45 <a class="action-link" href="${h.current_route_path(request, evolve=0)}">${_('Hide obsolete/hidden')}</a>
46 % else:
46 % else:
47 <a class="action-link" href="${h.current_route_path(request, evolve=1)}">${_('Show obsolete/hidden')}</a>
47 <a class="action-link" href="${h.current_route_path(request, evolve=1)}">${_('Show obsolete/hidden')}</a>
48 % endif
48 % endif
49 % else:
49 % else:
50 <span class="action-link disabled">${_('Show hidden')}</span>
50 <span class="action-link disabled">${_('Show hidden')}</span>
51 % endif
51 % endif
52 </div>
52 </div>
53 <ul class="links">
53 <ul class="links">
54 <li>
54 <li>
55
55
56 %if c.rhodecode_db_repo.fork:
56 %if c.rhodecode_db_repo.fork:
57 <span>
57 <span>
58 <a id="compare_fork_button"
58 <a id="compare_fork_button"
59 title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
59 title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
60 class="btn btn-small"
60 class="btn btn-small"
61 href="${h.route_path('repo_compare',
61 href="${h.route_path('repo_compare',
62 repo_name=c.rhodecode_db_repo.fork.repo_name,
62 repo_name=c.rhodecode_db_repo.fork.repo_name,
63 source_ref_type=c.rhodecode_db_repo.landing_ref_type,
63 source_ref_type=c.rhodecode_db_repo.landing_ref_type,
64 source_ref=c.rhodecode_db_repo.landing_ref_name,
64 source_ref=c.rhodecode_db_repo.landing_ref_name,
65 target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_ref_type,
65 target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_ref_type,
66 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_ref_name,
66 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_ref_name,
67 _query=dict(merge=1, target_repo=c.repo_name))}"
67 _query=dict(merge=1, target_repo=c.repo_name))}"
68 >
68 >
69 ${_('Compare fork with Parent (%s)' % c.rhodecode_db_repo.fork.repo_name)}
69 ${_('Compare fork with Parent (%s)' % c.rhodecode_db_repo.fork.repo_name)}
70 </a>
70 </a>
71 </span>
71 </span>
72 %endif
72 %endif
73
73
74 ## pr open link
74 ## pr open link
75 %if h.is_hg(c.rhodecode_repo) or h.is_git(c.rhodecode_repo):
75 %if h.is_hg(c.rhodecode_repo) or h.is_git(c.rhodecode_repo):
76 <span>
76 <span>
77 <a id="open_new_pull_request" class="btn btn-small btn-success" href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">
77 <a id="open_new_pull_request" class="btn btn-small btn-success" href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">
78 ${_('Open new pull request')}
78 ${_('Open new pull request')}
79 </a>
79 </a>
80 </span>
80 </span>
81 %endif
81 %endif
82
82
83 </li>
83 </li>
84 </ul>
84 </ul>
85 </div>
85 </div>
86
86
87 % if c.pagination:
87 % if c.pagination:
88 <script type="text/javascript" src="${h.asset('js/src/plugins/jquery.commits-graph.js')}"></script>
88 <script type="text/javascript" src="${h.asset('js/src/plugins/jquery.commits-graph.js')}"></script>
89
89
90 <div class="graph-header">
90 <div class="graph-header">
91 ${self.breadcrumbs('breadcrumbs_light')}
91 ${self.breadcrumbs('breadcrumbs_light')}
92 </div>
92 </div>
93
93
94 <div id="graph">
94 <div id="graph">
95 <div class="graph-col-wrapper">
95 <div class="graph-col-wrapper">
96 <div id="graph_nodes">
96 <div id="graph_nodes">
97 <div id="graph_canvas"></div>
97 <div id="graph_canvas"></div>
98 </div>
98 </div>
99 <div id="graph_content" class="graph_full_width">
99 <div id="graph_content" class="graph_full_width">
100
100
101 <div class="table">
101 <div class="table">
102 <table id="changesets" class="rctable table-bordered">
102 <table id="changesets" class="rctable table-bordered">
103 <tr>
103 <tr>
104 ## checkbox
104 ## checkbox
105 <th colspan="4">
105 <th colspan="4">
106 ## clear selection
106 ## clear selection
107 <div title="${_('Clear selection')}" class="btn btn-sm" id="rev_range_clear" style="display:none">
107 <div title="${_('Clear selection')}" class="btn btn-sm" id="rev_range_clear" style="display:none">
108 <i class="icon-cancel-circled2"></i>
108 <i class="icon-cancel-circled2"></i>
109 </div>
109 </div>
110 <div class="btn btn-sm disabled" disabled="disabled" id="rev_range_more" style="display:none;">${_('Select second commit')}</div>
110 <div class="btn btn-sm disabled" disabled="disabled" id="rev_range_more" style="display:none;">${_('Select second commit')}</div>
111 <a href="#" class="btn btn-success btn-sm" id="rev_range_container" style="display:none;"></a>
111
112 <div id="rev_range_action" class="btn-group btn-group-actions" style="display:none;">
113 <a href="#" class="btn btn-success btn-sm" id="rev_range_container" style="display:none;"></a>
114
115 <a class="btn btn-success btn-sm btn-more-option" data-toggle="dropdown" aria-pressed="false" role="button">
116 <i class="icon-down"></i>
117 </a>
118
119 <div class="btn-action-switcher-container right-align">
120 <ul class="btn-action-switcher" role="menu" style="min-width: 220px; width: max-content">
121 <li>
122 ## JS fills the URL
123 <a id="rev_range_combined_url" class="btn btn-primary btn-sm" href="">
124 ${_('Show combined diff')}
125 </a>
126 </li>
127 </ul>
128 </div>
129 </div>
130
112 </th>
131 </th>
113
132
114 ## commit message expand arrow
133 ## commit message expand arrow
115 <th></th>
134 <th></th>
116 <th>${_('Commit Message')}</th>
135 <th>${_('Commit Message')}</th>
117
136
118 <th>${_('Age')}</th>
137 <th>${_('Age')}</th>
119 <th>${_('Author')}</th>
138 <th>${_('Author')}</th>
120
139
121 <th>${_('Refs')}</th>
140 <th>${_('Refs')}</th>
122 ## comments
141 ## comments
123 <th></th>
142 <th></th>
124 </tr>
143 </tr>
125
144
126 <tbody class="commits-range">
145 <tbody class="commits-range">
127 <%include file='changelog_elements.mako'/>
146 <%include file='changelog_elements.mako'/>
128 </tbody>
147 </tbody>
129 </table>
148 </table>
130 </div>
149 </div>
131 </div>
150 </div>
132 <div class="pagination-wh pagination-left">
151 <div class="pagination-wh pagination-left">
133 ${c.pagination.render()}
152 ${c.pagination.render()}
134 </div>
153 </div>
135 <div id="commit-counter" data-total=${c.total_cs} class="pull-right">
154 <div id="commit-counter" data-total=${c.total_cs} class="pull-right">
136 ${_ungettext('showing %d out of %d commit', 'showing %d out of %d commits', c.showing_commits) % (c.showing_commits, c.total_cs)}
155 ${_ungettext('showing %d out of %d commit', 'showing %d out of %d commits', c.showing_commits) % (c.showing_commits, c.total_cs)}
137 </div>
156 </div>
138 </div>
157 </div>
139
158
140 <script type="text/javascript">
159 <script type="text/javascript">
141 var cache = {};
160 var cache = {};
142 $(function(){
161 $(function(){
143
162
144 // Create links to commit ranges when range checkboxes are selected
163 // Create links to commit ranges when range checkboxes are selected
145 var $commitCheckboxes = $('.commit-range');
164 var $commitCheckboxes = $('.commit-range');
146 // cache elements
165 // cache elements
147 var $commitRangeMore = $('#rev_range_more');
166 var $commitRangeMore = $('#rev_range_more');
148 var $commitRangeContainer = $('#rev_range_container');
167 var $commitRangeContainer = $('#rev_range_container');
149 var $commitRangeClear = $('#rev_range_clear');
168 var $commitRangeClear = $('#rev_range_clear');
169 var $commitRangeAction = $('#rev_range_action');
170 var $commitRangeCombinedUrl = $('#rev_range_combined_url');
171 var $compareFork = $('#compare_fork_button');
150
172
151 var checkboxRangeSelector = function(e){
173 var checkboxRangeSelector = function(e){
152 var selectedCheckboxes = [];
174 var selectedCheckboxes = [];
153 for (pos in $commitCheckboxes){
175 for (pos in $commitCheckboxes){
154 if($commitCheckboxes[pos].checked){
176 if($commitCheckboxes[pos].checked){
155 selectedCheckboxes.push($commitCheckboxes[pos]);
177 selectedCheckboxes.push($commitCheckboxes[pos]);
156 }
178 }
157 }
179 }
158 var open_new_pull_request = $('#open_new_pull_request');
180 var open_new_pull_request = $('#open_new_pull_request');
159
181
160 if (open_new_pull_request) {
182 if (open_new_pull_request) {
161 var selected_changes = selectedCheckboxes.length;
183 var selected_changes = selectedCheckboxes.length;
162 open_new_pull_request.hide();
184 open_new_pull_request.hide();
163 if (selected_changes == 1) {
185 if (selected_changes == 1) {
164 open_new_pull_request.html(_gettext('Open new pull request for selected commit'));
186 open_new_pull_request.html(_gettext('Open new pull request for selected commit'));
165 } else {
187 } else {
166 open_new_pull_request.html(_gettext('Open new pull request'));
188 open_new_pull_request.html(_gettext('Open new pull request'));
167 }
189 }
168 open_new_pull_request.show();
190 open_new_pull_request.show();
169 }
191 }
170
192
171 if (selectedCheckboxes.length > 0) {
193 if (selectedCheckboxes.length > 0) {
172 $('#compare_fork_button').hide();
194 $compareFork.hide();
173 var commitStart = $(selectedCheckboxes[selectedCheckboxes.length-1]).data();
195 var commitStart = $(selectedCheckboxes[selectedCheckboxes.length-1]).data();
174
175 var revStart = commitStart.commitId;
196 var revStart = commitStart.commitId;
176
197
177 var commitEnd = $(selectedCheckboxes[0]).data();
198 var commitEnd = $(selectedCheckboxes[0]).data();
178 var revEnd = commitEnd.commitId;
199 var revEnd = commitEnd.commitId;
179
200
180 var lbl_start = '{0}'.format(commitStart.commitIdx, commitStart.shortId);
201 var lbl_start = '{0}'.format(commitStart.commitIdx, commitStart.shortId);
181 var lbl_end = '{0}'.format(commitEnd.commitIdx, commitEnd.shortId);
202 var lbl_end = '{0}'.format(commitEnd.commitIdx, commitEnd.shortId);
182
203
183 var url = pyroutes.url('repo_commit', {'repo_name': '${c.repo_name}', 'commit_id': revStart+'...'+revEnd});
204 var url = pyroutes.url('repo_commit', {'repo_name': '${c.repo_name}', 'commit_id': revStart+'...'+revEnd});
184 var link = _gettext('Show commit range {0} ... {1}').format(lbl_start, lbl_end);
205 var urlCombined = pyroutes.url('repo_commit', {'repo_name': '${c.repo_name}', 'commit_id': revStart+'...'+revEnd, 'redirect_combined': '1'});
206
207 var link = _gettext('Show commit range {0}<i class="icon-angle-right"></i>{1}').format(lbl_start, lbl_end);
185
208
186 if (selectedCheckboxes.length > 1) {
209 if (selectedCheckboxes.length > 1) {
187 $commitRangeClear.show();
210 $commitRangeClear.show();
188 $commitRangeMore.hide();
211 $commitRangeMore.hide();
189
212
190 $commitRangeContainer
213 $commitRangeContainer
191 .attr('href',url)
214 .attr('href',url)
192 .html(link)
215 .html(link)
193 .show();
216 .show();
194
217
218 $commitRangeCombinedUrl.attr('href', urlCombined);
219 $commitRangeAction.show();
195
220
196 } else {
221 } else {
197 $commitRangeContainer.hide();
222 $commitRangeContainer.hide();
223 $commitRangeAction.hide();
198 $commitRangeClear.show();
224 $commitRangeClear.show();
199 $commitRangeMore.show();
225 $commitRangeMore.show();
200 }
226 }
201
227
202 // pull-request link
228 // pull-request link
203 if (selectedCheckboxes.length == 1){
229 if (selectedCheckboxes.length == 1){
204 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'commit': revEnd});
230 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'commit': revEnd});
205 open_new_pull_request.attr('href', _url);
231 open_new_pull_request.attr('href', _url);
206 } else {
232 } else {
207 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
233 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
208 open_new_pull_request.attr('href', _url);
234 open_new_pull_request.attr('href', _url);
209 }
235 }
210
236
211 } else {
237 } else {
212 $commitRangeContainer.hide();
238 $commitRangeContainer.hide();
213 $commitRangeClear.hide();
239 $commitRangeClear.hide();
214 $commitRangeMore.hide();
240 $commitRangeMore.hide();
241 $commitRangeAction.hide();
215
242
216 %if c.branch_name:
243 %if c.branch_name:
217 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'branch':'${c.branch_name}'});
244 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'branch':'${c.branch_name}'});
218 open_new_pull_request.attr('href', _url);
245 open_new_pull_request.attr('href', _url);
219 %else:
246 %else:
220 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
247 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
221 open_new_pull_request.attr('href', _url);
248 open_new_pull_request.attr('href', _url);
222 %endif
249 %endif
223 $('#compare_fork_button').show();
250 $compareFork.show();
224 }
251 }
225 };
252 };
226
253
227 $commitCheckboxes.on('click', checkboxRangeSelector);
254 $commitCheckboxes.on('click', checkboxRangeSelector);
228
255
229 $commitRangeClear.on('click',function(e) {
256 $commitRangeClear.on('click',function(e) {
230 $commitCheckboxes.attr('checked', false);
257 $commitCheckboxes.attr('checked', false);
231 checkboxRangeSelector();
258 checkboxRangeSelector();
232 e.preventDefault();
259 e.preventDefault();
233 });
260 });
234
261
235 // make sure the buttons are consistent when navigate back and forth
262 // make sure the buttons are consistent when navigate back and forth
236 checkboxRangeSelector();
263 checkboxRangeSelector();
237
264
238 var msgs = $('.message');
265 var msgs = $('.message');
239 // get first element height
266 // get first element height
240 var el = $('#graph_content .container')[0];
267 var el = $('#graph_content .container')[0];
241 var row_h = el.clientHeight;
268 var row_h = el.clientHeight;
242 for (var i=0; i < msgs.length; i++) {
269 for (var i=0; i < msgs.length; i++) {
243 var m = msgs[i];
270 var m = msgs[i];
244
271
245 var h = m.clientHeight;
272 var h = m.clientHeight;
246 var pad = $(m).css('padding');
273 var pad = $(m).css('padding');
247 if (h > row_h) {
274 if (h > row_h) {
248 var offset = row_h - (h+12);
275 var offset = row_h - (h+12);
249 $(m.nextElementSibling).css('display','block');
276 $(m.nextElementSibling).css('display','block');
250 $(m.nextElementSibling).css('margin-top',offset+'px');
277 $(m.nextElementSibling).css('margin-top',offset+'px');
251 }
278 }
252 }
279 }
253
280
254 $("#clear_filter").on("click", function() {
281 $("#clear_filter").on("click", function() {
255 var filter = {'repo_name': '${c.repo_name}'};
282 var filter = {'repo_name': '${c.repo_name}'};
256 window.location = pyroutes.url('repo_commits', filter);
283 window.location = pyroutes.url('repo_commits', filter);
257 });
284 });
258
285
259 $("#branch_filter").select2({
286 $("#branch_filter").select2({
260 'dropdownAutoWidth': true,
287 'dropdownAutoWidth': true,
261 'width': 'resolve',
288 'width': 'resolve',
262 'placeholder': "${c.selected_name or _('Branch filter')}",
289 'placeholder': "${c.selected_name or _('Branch filter')}",
263 containerCssClass: "drop-menu",
290 containerCssClass: "drop-menu",
264 dropdownCssClass: "drop-menu-dropdown",
291 dropdownCssClass: "drop-menu-dropdown",
265 query: function(query){
292 query: function(query){
266 var key = 'cache';
293 var key = 'cache';
267 var cached = cache[key] ;
294 var cached = cache[key] ;
268 if(cached) {
295 if(cached) {
269 var data = {results: []};
296 var data = {results: []};
270 //filter results
297 //filter results
271 $.each(cached.results, function(){
298 $.each(cached.results, function(){
272 var section = this.text;
299 var section = this.text;
273 var children = [];
300 var children = [];
274 $.each(this.children, function(){
301 $.each(this.children, function(){
275 if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
302 if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
276 children.push({'id': this.id, 'text': this.text, 'type': this.type})
303 children.push({'id': this.id, 'text': this.text, 'type': this.type})
277 }
304 }
278 });
305 });
279 data.results.push({'text': section, 'children': children});
306 data.results.push({'text': section, 'children': children});
280 query.callback({results: data.results});
307 query.callback({results: data.results});
281 });
308 });
282 }else{
309 }else{
283 $.ajax({
310 $.ajax({
284 url: pyroutes.url('repo_refs_changelog_data', {'repo_name': '${c.repo_name}'}),
311 url: pyroutes.url('repo_refs_changelog_data', {'repo_name': '${c.repo_name}'}),
285 data: {},
312 data: {},
286 dataType: 'json',
313 dataType: 'json',
287 type: 'GET',
314 type: 'GET',
288 success: function(data) {
315 success: function(data) {
289 cache[key] = data;
316 cache[key] = data;
290 query.callback({results: data.results});
317 query.callback({results: data.results});
291 }
318 }
292 })
319 })
293 }
320 }
294 }
321 }
295 });
322 });
296 $('#branch_filter').on('change', function(e){
323 $('#branch_filter').on('change', function(e){
297 var data = $('#branch_filter').select2('data');
324 var data = $('#branch_filter').select2('data');
298 //type: branch_closed
325 //type: branch_closed
299 var selected = data.text;
326 var selected = data.text;
300 var filter = {'repo_name': '${c.repo_name}'};
327 var filter = {'repo_name': '${c.repo_name}'};
301 if(data.type == 'branch' || data.type == 'branch_closed'){
328 if(data.type == 'branch' || data.type == 'branch_closed'){
302 filter["branch"] = selected;
329 filter["branch"] = selected;
303 if (data.type == 'branch_closed') {
330 if (data.type == 'branch_closed') {
304 filter["evolve"] = '1';
331 filter["evolve"] = '1';
305 }
332 }
306 }
333 }
307 else if (data.type == 'book'){
334 else if (data.type == 'book'){
308 filter["bookmark"] = selected;
335 filter["bookmark"] = selected;
309 }
336 }
310 window.location = pyroutes.url('repo_commits', filter);
337 window.location = pyroutes.url('repo_commits', filter);
311 });
338 });
312
339
313 commitsController = new CommitsController();
340 commitsController = new CommitsController();
314 % if not c.changelog_for_path:
341 % if not c.changelog_for_path:
315 commitsController.reloadGraph();
342 commitsController.reloadGraph();
316 % endif
343 % endif
317
344
318 });
345 });
319
346
320 </script>
347 </script>
321 </div>
348 </div>
322 % else:
349 % else:
323 ${_('There are no changes yet')}
350 ${_('There are no changes yet')}
324 % endif
351 % endif
325 </div>
352 </div>
326 </%def>
353 </%def>
General Comments 0
You need to be logged in to leave comments. Login now