diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py --- a/rhodecode/controllers/pullrequests.py +++ b/rhodecode/controllers/pullrequests.py @@ -36,7 +36,8 @@ from pylons.decorators import jsonify from rhodecode.lib.compat import json from rhodecode.lib.base import BaseRepoController, render -from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\ + NotAnonymous from rhodecode.lib import helpers as h from rhodecode.lib import diffs from rhodecode.lib.utils import action_logger @@ -58,6 +59,9 @@ class PullrequestsController(BaseRepoCon 'repository.admin') def __before__(self): super(PullrequestsController, self).__before__() + repo_model = RepoModel() + c.users_array = repo_model.get_users_js() + c.users_groups_array = repo_model.get_users_groups_js() def _get_repo_refs(self, repo): hist_l = [] @@ -128,17 +132,10 @@ class PullrequestsController(BaseRepoCon } c.other_repos_info = json.dumps(other_repos_info) - c.review_members = [] - c.available_members = [] - for u in User.query().filter(User.username != 'default').all(): - uname = u.username - if org_repo.user == u: - uname = _('%s (owner)') % u.username - # auto add owner to pull-request recipients - c.review_members.append([u.user_id, uname]) - c.available_members.append([u.user_id, uname]) + c.review_members = [org_repo.user] return render('/pullrequests/pullrequest.html') + @NotAnonymous() def create(self, repo_name): req_p = request.POST org_repo = req_p['org_repo'] @@ -147,6 +144,7 @@ class PullrequestsController(BaseRepoCon other_ref = req_p['other_ref'] revisions = req_p.getall('revisions') reviewers = req_p.getall('review_members') + #TODO: wrap this into a FORM !!! title = req_p['pullrequest_title'] diff --git a/rhodecode/public/css/style.css b/rhodecode/public/css/style.css --- a/rhodecode/public/css/style.css +++ b/rhodecode/public/css/style.css @@ -1429,7 +1429,8 @@ tbody .yui-dt-editable { cursor: pointer margin: 0 0 0 0px; } -#content div.box div.form div.fields div.field div.input input { +#content div.box div.form div.fields div.field div.input input, +.reviewer_ac input { background: #FFF; border-top: 1px solid #b3b3b3; border-left: 1px solid #b3b3b3; @@ -1549,12 +1550,21 @@ input.disabled { padding: 5px 5px 5px 0; } -#content div.box div.form div.fields div.field input[type=text]:focus,#content div.box div.form div.fields div.field input[type=password]:focus,#content div.box div.form div.fields div.field input[type=file]:focus,#content div.box div.form div.fields div.field textarea:focus,#content div.box div.form div.fields div.field select:focus +#content div.box div.form div.fields div.field input[type=text]:focus, +#content div.box div.form div.fields div.field input[type=password]:focus, +#content div.box div.form div.fields div.field input[type=file]:focus, +#content div.box div.form div.fields div.field textarea:focus, +#content div.box div.form div.fields div.field select:focus, +.reviewer_ac input:focus { background: #f6f6f6; border-color: #666; } +.reviewer_ac { + padding:10px +} + div.form div.fields div.field div.button { margin: 0; padding: 0 0 0 8px; @@ -3783,6 +3793,11 @@ div#legend_container table td,div#legend padding:0px 0px 0px 10px; } +.reviewers_member{ + height: 15px; + padding:0px 0px 0px 10px; +} + .emails_wrap{ padding: 0px 20px; } diff --git a/rhodecode/public/js/rhodecode.js b/rhodecode/public/js/rhodecode.js --- a/rhodecode/public/js/rhodecode.js +++ b/rhodecode/public/js/rhodecode.js @@ -63,6 +63,18 @@ String.prototype.rstrip = function(char) return this.replace(new RegExp(''+char+'+$'),''); } + +if(!Array.prototype.indexOf) { + Array.prototype.indexOf = function(needle) { + for(var i = 0; i < this.length; i++) { + if(this[i] === needle) { + return i; + } + } + return -1; + }; +} + /** * SmartColorGenerator * @@ -1204,7 +1216,8 @@ var MentionsAutoComplete = function (div return [unam, chunks]; } return [null, null]; - }; + }; + ownerAC.textboxKeyUpEvent.subscribe(function(type, args){ var ac_obj = args[0]; @@ -1229,6 +1242,167 @@ var MentionsAutoComplete = function (div } +var PullRequestAutoComplete = function (divid, cont, users_list, groups_list) { + var myUsers = users_list; + var myGroups = groups_list; + + // Define a custom search function for the DataSource of users + var matchUsers = function (sQuery) { + // Case insensitive matching + var query = sQuery.toLowerCase(); + var i = 0; + var l = myUsers.length; + var matches = []; + + // Match against each name of each contact + for (; i < l; i++) { + contact = myUsers[i]; + if (((contact.fname+"").toLowerCase().indexOf(query) > -1) || + ((contact.lname+"").toLowerCase().indexOf(query) > -1) || + ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) { + matches[matches.length] = contact; + } + } + return matches; + }; + + // Define a custom search function for the DataSource of usersGroups + var matchGroups = function (sQuery) { + // Case insensitive matching + var query = sQuery.toLowerCase(); + var i = 0; + var l = myGroups.length; + var matches = []; + + // Match against each name of each contact + for (; i < l; i++) { + matched_group = myGroups[i]; + if (matched_group.grname.toLowerCase().indexOf(query) > -1) { + matches[matches.length] = matched_group; + } + } + return matches; + }; + + //match all + var matchAll = function (sQuery) { + u = matchUsers(sQuery); + return u + }; + + // DataScheme for owner + var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers); + + ownerDS.responseSchema = { + fields: ["id", "fname", "lname", "nname", "gravatar_lnk"] + }; + + // Instantiate AutoComplete for mentions + var reviewerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS); + reviewerAC.useShadow = false; + reviewerAC.resultTypeList = false; + reviewerAC.suppressInputUpdate = true; + reviewerAC.animVert = false; + reviewerAC.animHoriz = false; + reviewerAC.animSpeed = 0.1; + + // Helper highlight function for the formatter + var highlightMatch = function (full, snippet, matchindex) { + return full.substring(0, matchindex) + + "" + + full.substr(matchindex, snippet.length) + + "" + full.substring(matchindex + snippet.length); + }; + + // Custom formatter to highlight the matching letters + reviewerAC.formatResult = function (oResultData, sQuery, sResultMatch) { + var org_sQuery = sQuery; + if(this.dataSource.mentionQuery != null){ + sQuery = this.dataSource.mentionQuery; + } + + var query = sQuery.toLowerCase(); + var _gravatar = function(res, em, group){ + if (group !== undefined){ + em = '/images/icons/group.png' + } + tmpl = '
|
-
-
-
-
- ${_('Chosen reviewers')}
- ${h.select('review_members',[x[0] for x in c.review_members],c.review_members,multiple=True,size=8,style="min-width:210px")}
-
- ${_('Remove all elements')}
-
-
-
- -
-
- ${_('Available reviewers')}
- ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")}
-
-
- |
-