Show More
@@ -53,6 +53,7 b' class HomeView(BaseAppView):' | |||||
53 | query = self.request.GET.get('query') |
|
53 | query = self.request.GET.get('query') | |
54 | active = str2bool(self.request.GET.get('active') or True) |
|
54 | active = str2bool(self.request.GET.get('active') or True) | |
55 | include_groups = str2bool(self.request.GET.get('user_groups')) |
|
55 | include_groups = str2bool(self.request.GET.get('user_groups')) | |
|
56 | expand_groups = str2bool(self.request.GET.get('user_groups_expand')) | |||
56 |
|
57 | |||
57 | log.debug('generating user list, query:%s, active:%s, with_groups:%s', |
|
58 | log.debug('generating user list, query:%s, active:%s, with_groups:%s', | |
58 | query, active, include_groups) |
|
59 | query, active, include_groups) | |
@@ -63,7 +64,8 b' class HomeView(BaseAppView):' | |||||
63 | if include_groups: |
|
64 | if include_groups: | |
64 | # extend with user groups |
|
65 | # extend with user groups | |
65 | _user_groups = UserGroupModel().get_user_groups( |
|
66 | _user_groups = UserGroupModel().get_user_groups( | |
66 |
name_contains=query, only_active=active |
|
67 | name_contains=query, only_active=active, | |
|
68 | expand_groups=expand_groups) | |||
67 | _users = _users + _user_groups |
|
69 | _users = _users + _user_groups | |
68 |
|
70 | |||
69 | return {'suggestions': _users} |
|
71 | return {'suggestions': _users} | |
@@ -76,11 +78,14 b' class HomeView(BaseAppView):' | |||||
76 | def user_group_autocomplete_data(self): |
|
78 | def user_group_autocomplete_data(self): | |
77 | query = self.request.GET.get('query') |
|
79 | query = self.request.GET.get('query') | |
78 | active = str2bool(self.request.GET.get('active') or True) |
|
80 | active = str2bool(self.request.GET.get('active') or True) | |
|
81 | expand_groups = str2bool(self.request.GET.get('user_groups_expand')) | |||
|
82 | ||||
79 | log.debug('generating user group list, query:%s, active:%s', |
|
83 | log.debug('generating user group list, query:%s, active:%s', | |
80 | query, active) |
|
84 | query, active) | |
81 |
|
85 | |||
82 | _user_groups = UserGroupModel().get_user_groups( |
|
86 | _user_groups = UserGroupModel().get_user_groups( | |
83 |
name_contains=query, only_active=active |
|
87 | name_contains=query, only_active=active, | |
|
88 | expand_groups=expand_groups) | |||
84 | _user_groups = _user_groups |
|
89 | _user_groups = _user_groups | |
85 |
|
90 | |||
86 | return {'suggestions': _user_groups} |
|
91 | return {'suggestions': _user_groups} |
@@ -65,8 +65,23 b' class UserModel(BaseModel):' | |||||
65 | def get_user(self, user): |
|
65 | def get_user(self, user): | |
66 | return self._get_user(user) |
|
66 | return self._get_user(user) | |
67 |
|
67 | |||
|
68 | def _serialize_user(self, user): | |||
|
69 | import rhodecode.lib.helpers as h | |||
|
70 | ||||
|
71 | return { | |||
|
72 | 'id': user.user_id, | |||
|
73 | 'first_name': user.name, | |||
|
74 | 'last_name': user.lastname, | |||
|
75 | 'username': user.username, | |||
|
76 | 'email': user.email, | |||
|
77 | 'icon_link': h.gravatar_url(user.email, 30), | |||
|
78 | 'value_display': h.person(user), | |||
|
79 | 'value': user.username, | |||
|
80 | 'value_type': 'user', | |||
|
81 | 'active': user.active, | |||
|
82 | } | |||
|
83 | ||||
68 | def get_users(self, name_contains=None, limit=20, only_active=True): |
|
84 | def get_users(self, name_contains=None, limit=20, only_active=True): | |
69 | import rhodecode.lib.helpers as h |
|
|||
70 |
|
85 | |||
71 | query = self.sa.query(User) |
|
86 | query = self.sa.query(User) | |
72 | if only_active: |
|
87 | if only_active: | |
@@ -85,19 +100,7 b' class UserModel(BaseModel):' | |||||
85 | users = query.all() |
|
100 | users = query.all() | |
86 |
|
101 | |||
87 | _users = [ |
|
102 | _users = [ | |
88 | { |
|
103 | self._serialize_user(user) for user in users | |
89 | 'id': user.user_id, |
|
|||
90 | 'first_name': user.name, |
|
|||
91 | 'last_name': user.lastname, |
|
|||
92 | 'username': user.username, |
|
|||
93 | 'email': user.email, |
|
|||
94 | 'icon_link': h.gravatar_url(user.email, 30), |
|
|||
95 | 'value_display': h.person(user), |
|
|||
96 | 'value': user.username, |
|
|||
97 | 'value_type': 'user', |
|
|||
98 | 'active': user.active, |
|
|||
99 | } |
|
|||
100 | for user in users |
|
|||
101 | ] |
|
104 | ] | |
102 | return _users |
|
105 | return _users | |
103 |
|
106 |
@@ -30,12 +30,14 b' import traceback' | |||||
30 | from rhodecode.lib.utils2 import safe_str, safe_unicode |
|
30 | from rhodecode.lib.utils2 import safe_str, safe_unicode | |
31 | from rhodecode.model import BaseModel |
|
31 | from rhodecode.model import BaseModel | |
32 | from rhodecode.model.scm import UserGroupList |
|
32 | from rhodecode.model.scm import UserGroupList | |
33 |
from rhodecode.model.db import |
|
33 | from rhodecode.model.db import ( | |
34 | UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm,\ |
|
34 | true, func, User, UserGroupMember, UserGroup, | |
35 |
UserGroup |
|
35 | UserGroupRepoToPerm, Permission, UserGroupToPerm, UserUserGroupToPerm, | |
36 | from rhodecode.lib.exceptions import UserGroupAssignedException,\ |
|
36 | UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm) | |
37 | RepoGroupAssignmentError |
|
37 | from rhodecode.lib.exceptions import ( | |
38 | from rhodecode.lib.utils2 import get_current_rhodecode_user, action_logger_generic |
|
38 | UserGroupAssignedException, RepoGroupAssignmentError) | |
|
39 | from rhodecode.lib.utils2 import ( | |||
|
40 | get_current_rhodecode_user, action_logger_generic) | |||
39 |
|
41 | |||
40 | log = logging.getLogger(__name__) |
|
42 | log = logging.getLogger(__name__) | |
41 |
|
43 | |||
@@ -540,10 +542,28 b' class UserGroupModel(BaseModel):' | |||||
540 | log.debug('Adding user %s to user group %s', user.username, gr.users_group_name) |
|
542 | log.debug('Adding user %s to user group %s', user.username, gr.users_group_name) | |
541 | UserGroupModel().add_user_to_group(gr.users_group_name, user.username) |
|
543 | UserGroupModel().add_user_to_group(gr.users_group_name, user.username) | |
542 |
|
544 | |||
|
545 | def _serialize_user_group(self, user_group): | |||
|
546 | import rhodecode.lib.helpers as h | |||
|
547 | return { | |||
|
548 | 'id': user_group.users_group_id, | |||
|
549 | # TODO: marcink figure out a way to generate the url for the | |||
|
550 | # icon | |||
|
551 | 'icon_link': '', | |||
|
552 | 'value_display': 'Group: %s (%d members)' % ( | |||
|
553 | user_group.users_group_name, len(user_group.members),), | |||
|
554 | 'value': user_group.users_group_name, | |||
|
555 | 'description': user_group.user_group_description, | |||
|
556 | 'owner': user_group.user.username, | |||
|
557 | ||||
|
558 | 'owner_icon': h.gravatar_url(user_group.user.email, 30), | |||
|
559 | 'value_display_owner': h.person(user_group.user.email), | |||
|
560 | ||||
|
561 | 'value_type': 'user_group', | |||
|
562 | 'active': user_group.users_group_active, | |||
|
563 | } | |||
|
564 | ||||
543 | def get_user_groups(self, name_contains=None, limit=20, only_active=True, |
|
565 | def get_user_groups(self, name_contains=None, limit=20, only_active=True, | |
544 | expand_groups=False): |
|
566 | expand_groups=False): | |
545 | import rhodecode.lib.helpers as h |
|
|||
546 |
|
||||
547 | query = self.sa.query(UserGroup) |
|
567 | query = self.sa.query(UserGroup) | |
548 | if only_active: |
|
568 | if only_active: | |
549 | query = query.filter(UserGroup.users_group_active == true()) |
|
569 | query = query.filter(UserGroup.users_group_active == true()) | |
@@ -560,26 +580,19 b' class UserGroupModel(BaseModel):' | |||||
560 | perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] |
|
580 | perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] | |
561 | user_groups = UserGroupList(user_groups, perm_set=perm_set) |
|
581 | user_groups = UserGroupList(user_groups, perm_set=perm_set) | |
562 |
|
582 | |||
563 | _groups = [ |
|
583 | # store same serialize method to extract data from User | |
564 | { |
|
584 | from rhodecode.model.user import UserModel | |
565 | 'id': group.users_group_id, |
|
585 | serialize_user = UserModel()._serialize_user | |
566 | # TODO: marcink figure out a way to generate the url for the |
|
|||
567 | # icon |
|
|||
568 | 'icon_link': '', |
|
|||
569 | 'value_display': 'Group: %s (%d members)' % ( |
|
|||
570 | group.users_group_name, len(group.members),), |
|
|||
571 | 'value': group.users_group_name, |
|
|||
572 | 'description': group.user_group_description, |
|
|||
573 | 'owner': group.user.username, |
|
|||
574 |
|
586 | |||
575 | 'owner_icon': h.gravatar_url(group.user.email, 30), |
|
587 | _groups = [] | |
576 | 'value_display_owner': h.person(group.user.email), |
|
588 | for group in user_groups: | |
577 |
|
589 | entry = self._serialize_user_group(group) | ||
578 | 'value_type': 'user_group', |
|
590 | if expand_groups: | |
579 | 'active': group.users_group_active, |
|
591 | expanded_members = [] | |
580 | } |
|
592 | for member in group.members: | |
581 | for group in user_groups |
|
593 | expanded_members.append(serialize_user(member.user)) | |
582 | ] |
|
594 | entry['members'] = expanded_members | |
|
595 | _groups.append(entry) | |||
583 | return _groups |
|
596 | return _groups | |
584 |
|
597 | |||
585 | @staticmethod |
|
598 | @staticmethod |
@@ -198,8 +198,8 b' var initPullRequestsCodeMirror = functio' | |||||
198 | /** |
|
198 | /** | |
199 | * Reviewer autocomplete |
|
199 | * Reviewer autocomplete | |
200 | */ |
|
200 | */ | |
201 |
var ReviewerAutoComplete = function(input |
|
201 | var ReviewerAutoComplete = function(inputId) { | |
202 |
$( |
|
202 | $(inputId).autocomplete({ | |
203 | serviceUrl: pyroutes.url('user_autocomplete_data'), |
|
203 | serviceUrl: pyroutes.url('user_autocomplete_data'), | |
204 | minChars:2, |
|
204 | minChars:2, | |
205 | maxHeight:400, |
|
205 | maxHeight:400, | |
@@ -207,14 +207,26 b' var ReviewerAutoComplete = function(inpu' | |||||
207 | showNoSuggestionNotice: true, |
|
207 | showNoSuggestionNotice: true, | |
208 | tabDisabled: true, |
|
208 | tabDisabled: true, | |
209 | autoSelectFirst: true, |
|
209 | autoSelectFirst: true, | |
|
210 | params: { user_id: templateContext.rhodecode_user.user_id, user_groups:true, user_groups_expand:true }, | |||
210 | formatResult: autocompleteFormatResult, |
|
211 | formatResult: autocompleteFormatResult, | |
211 | lookupFilter: autocompleteFilterResult, |
|
212 | lookupFilter: autocompleteFilterResult, | |
212 |
onSelect: function( |
|
213 | onSelect: function(element, data) { | |
213 | var msg = _gettext('added manually by "{0}"'); |
|
214 | ||
214 |
var reasons = [ |
|
215 | var reasons = [_gettext('added manually by "{0}"').format(templateContext.rhodecode_user.username)]; | |
|
216 | if (data.value_type == 'user_group') { | |||
|
217 | reasons.push(_gettext('member of "{0}"').format(data.value_display)); | |||
|
218 | ||||
|
219 | $.each(data.members, function(index, member_data) { | |||
|
220 | addReviewMember(member_data.id, member_data.first_name, member_data.last_name, | |||
|
221 | member_data.username, member_data.icon_link, reasons); | |||
|
222 | }) | |||
|
223 | ||||
|
224 | } else { | |||
215 | addReviewMember(data.id, data.first_name, data.last_name, |
|
225 | addReviewMember(data.id, data.first_name, data.last_name, | |
216 | data.username, data.icon_link, reasons); |
|
226 | data.username, data.icon_link, reasons); | |
217 | $('#'+input_id).val(''); |
|
227 | } | |
|
228 | ||||
|
229 | $(inputId).val(''); | |||
218 | } |
|
230 | } | |
219 | }); |
|
231 | }); | |
220 | }; |
|
232 | }; |
@@ -886,7 +886,7 b'' | |||||
886 | AJAX_COMMENT_DELETE_URL = "/rhodecode-momentum/pull-request-comment/__COMMENT_ID__/delete"; |
|
886 | AJAX_COMMENT_DELETE_URL = "/rhodecode-momentum/pull-request-comment/__COMMENT_ID__/delete"; | |
887 |
|
887 | |||
888 | $(function(){ |
|
888 | $(function(){ | |
889 | ReviewerAutoComplete('user'); |
|
889 | ReviewerAutoComplete('#user'); | |
890 |
|
890 | |||
891 | $('#open_edit_reviewers').on('click', function(e){ |
|
891 | $('#open_edit_reviewers').on('click', function(e){ | |
892 | $('#open_edit_reviewers').hide(); |
|
892 | $('#open_edit_reviewers').hide(); |
@@ -115,7 +115,7 b'' | |||||
115 | <input type="hidden" name="__end__" value="review_members:sequence"> |
|
115 | <input type="hidden" name="__end__" value="review_members:sequence"> | |
116 | <div id="add_reviewer_input" class='ac'> |
|
116 | <div id="add_reviewer_input" class='ac'> | |
117 | <div class="reviewer_ac"> |
|
117 | <div class="reviewer_ac"> | |
118 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))} |
|
118 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))} | |
119 | <div id="reviewers_container"></div> |
|
119 | <div id="reviewers_container"></div> | |
120 | </div> |
|
120 | </div> | |
121 | </div> |
|
121 | </div> | |
@@ -584,7 +584,7 b'' | |||||
584 | loadDefaultReviewers(); |
|
584 | loadDefaultReviewers(); | |
585 | % endif |
|
585 | % endif | |
586 |
|
586 | |||
587 | ReviewerAutoComplete('user'); |
|
587 | ReviewerAutoComplete('#user'); | |
588 | }); |
|
588 | }); | |
589 | </script> |
|
589 | </script> | |
590 |
|
590 |
@@ -363,7 +363,7 b'' | |||||
363 | <div id="add_reviewer_input" class='ac' style="display: none;"> |
|
363 | <div id="add_reviewer_input" class='ac' style="display: none;"> | |
364 | %if c.allowed_to_update: |
|
364 | %if c.allowed_to_update: | |
365 | <div class="reviewer_ac"> |
|
365 | <div class="reviewer_ac"> | |
366 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))} |
|
366 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))} | |
367 | <div id="reviewers_container"></div> |
|
367 | <div id="reviewers_container"></div> | |
368 | </div> |
|
368 | </div> | |
369 | <div> |
|
369 | <div> | |
@@ -617,7 +617,7 b'' | |||||
617 |
|
617 | |||
618 |
|
618 | |||
619 | $(function(){ |
|
619 | $(function(){ | |
620 | ReviewerAutoComplete('user'); |
|
620 | ReviewerAutoComplete('#user'); | |
621 | // custom code mirror |
|
621 | // custom code mirror | |
622 | var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input'); |
|
622 | var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input'); | |
623 |
|
623 |
General Comments 0
You need to be logged in to leave comments.
Login now