##// END OF EJS Templates
authentication: introduce a group sync flag for plugins....
authentication: introduce a group sync flag for plugins. - we'll skip any syncing on plugins which simply don't get any group information - we let plugins define if they wish to sync groups - prevent from odd cases in which someone sets user groups as syncing, and using regular plugin. In this case memebership of that group would be wiped, and it's generaly bad behaviour.

File last commit:

r2484:3775edd6 default
r2495:4f076134 default
Show More
pullrequest.mako
530 lines | 18.8 KiB | application/x-mako | MakoHtmlLexer
templating: use .mako as extensions for template files.
r1282 <%inherit file="/base/base.mako"/>
<%def name="title()">
${c.repo_name} ${_('New pull request')}
</%def>
<%def name="breadcrumbs_links()">
${_('New pull request')}
</%def>
<%def name="menu_bar_nav()">
${self.menu_items(active='repositories')}
</%def>
<%def name="menu_bar_subnav()">
${self.repo_menu(active='showpullrequest')}
</%def>
<%def name="main()">
<div class="box">
<div class="title">
${self.repo_page_title(c.rhodecode_db_repo)}
</div>
forms: unified usage of h.secure_form. Make sure we ALWAYS pass in...
r2105 ${h.secure_form(h.route_path('pullrequest_create', repo_name=c.repo_name, _query=request.GET.mixed()), id='pull_request_form', request=request)}
pull-requests: expose author in creation view to be consistent with show view.
r1786
${self.breadcrumbs()}
templating: use .mako as extensions for template files.
r1282 <div class="box pr-summary">
<div class="summary-details block-left">
pull-requests: expose author in creation view to be consistent with show view.
r1786
<div class="pr-details-title">
${_('Pull request summary')}
</div>
<div class="form" style="padding-top: 10px">
templating: use .mako as extensions for template files.
r1282 <!-- fields -->
<div class="fields" >
<div class="field">
<div class="label">
<label for="pullrequest_title">${_('Title')}:</label>
</div>
<div class="input">
${h.text('pullrequest_title', c.default_title, class_="medium autogenerated-title")}
</div>
</div>
<div class="field">
<div class="label label-textarea">
<label for="pullrequest_desc">${_('Description')}:</label>
</div>
<div class="textarea text-area editor">
${h.textarea('pullrequest_desc',size=30, )}
helper-blocks: fix pre formatting only for auth plugin helper texts....
r1470 <span class="help-block">${_('Write a short description on this pull request')}</span>
templating: use .mako as extensions for template files.
r1282 </div>
</div>
<div class="field">
<div class="label label-textarea">
<label for="pullrequest_desc">${_('Commit flow')}:</label>
</div>
## TODO: johbo: Abusing the "content" class here to get the
## desired effect. Should be replaced by a proper solution.
##ORG
<div class="content">
pull-request: extended default reviewers functionality....
r1769 <strong>${_('Source repository')}:</strong>
templating: use .mako as extensions for template files.
r1282 ${c.rhodecode_db_repo.description}
</div>
<div class="content">
${h.hidden('source_repo')}
${h.hidden('source_ref')}
</div>
##OTHER, most Probably the PARENT OF THIS FORK
<div class="content">
## filled with JS
<div id="target_repo_desc"></div>
</div>
<div class="content">
${h.hidden('target_repo')}
${h.hidden('target_ref')}
<span id="target_ref_loading" style="display: none">
${_('Loading refs...')}
</span>
</div>
</div>
<div class="field">
<div class="label label-textarea">
<label for="pullrequest_submit"></label>
</div>
<div class="input">
<div class="pr-submit-button">
${h.submit('save',_('Submit Pull Request'),class_="btn")}
</div>
<div id="pr_open_message"></div>
</div>
</div>
<div class="pr-spacing-container"></div>
</div>
</div>
</div>
<div>
pull-requests: expose author in creation view to be consistent with show view.
r1786 ## AUTHOR
<div class="reviewers-title block-right">
<div class="pr-details-title">
${_('Author of this pull request')}
</div>
</div>
<div class="block-right pr-details-content reviewers">
<ul class="group_members">
<li>
${self.gravatar_with_user(c.rhodecode_user.email, 16)}
</li>
</ul>
</div>
## REVIEW RULES
pull-request: extended default reviewers functionality....
r1769 <div id="review_rules" style="display: none" class="reviewers-title block-right">
<div class="pr-details-title">
${_('Reviewer rules')}
</div>
<div class="pr-reviewer-rules">
## review rules will be appended here, by default reviewers logic
</div>
</div>
## REVIEWERS
templating: use .mako as extensions for template files.
r1282 <div class="reviewers-title block-right">
<div class="pr-details-title">
${_('Pull request reviewers')}
<span class="calculate-reviewers"> - ${_('loading...')}</span>
</div>
</div>
<div id="reviewers" class="block-right pr-details-content reviewers">
## members goes here, filled via JS based on initial selection !
<input type="hidden" name="__start__" value="review_members:sequence">
<ul id="review_members" class="group_members"></ul>
<input type="hidden" name="__end__" value="review_members:sequence">
<div id="add_reviewer_input" class='ac'>
<div class="reviewer_ac">
pull-request-reviewers: added option to add reviewers by picking an user group for pull requests....
r1678 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
templating: use .mako as extensions for template files.
r1282 <div id="reviewers_container"></div>
</div>
</div>
</div>
</div>
</div>
<div class="box">
<div>
## overview pulled by ajax
<div id="pull_request_overview"></div>
</div>
</div>
${h.end_form()}
</div>
<script type="text/javascript">
$(function(){
var defaultSourceRepo = '${c.default_repo_data['source_repo_name']}';
var defaultSourceRepoData = ${c.default_repo_data['source_refs_json']|n};
var defaultTargetRepo = '${c.default_repo_data['target_repo_name']}';
var defaultTargetRepoData = ${c.default_repo_data['target_refs_json']|n};
var $pullRequestForm = $('#pull_request_form');
var $sourceRepo = $('#source_repo', $pullRequestForm);
var $targetRepo = $('#target_repo', $pullRequestForm);
var $sourceRef = $('#source_ref', $pullRequestForm);
var $targetRef = $('#target_ref', $pullRequestForm);
pull-request: extended default reviewers functionality....
r1769 var sourceRepo = function() { return $sourceRepo.eq(0).val() };
var sourceRef = function() { return $sourceRef.eq(0).val().split(':') };
var targetRepo = function() { return $targetRepo.eq(0).val() };
var targetRef = function() { return $targetRef.eq(0).val().split(':') };
templating: use .mako as extensions for template files.
r1282 var calculateContainerWidth = function() {
var maxWidth = 0;
var repoSelect2Containers = ['#source_repo', '#target_repo'];
$.each(repoSelect2Containers, function(idx, value) {
$(value).select2('container').width('auto');
var curWidth = $(value).select2('container').width();
if (maxWidth <= curWidth) {
maxWidth = curWidth;
}
$.each(repoSelect2Containers, function(idx, value) {
$(value).select2('container').width(maxWidth + 10);
});
});
};
var initRefSelection = function(selectedRef) {
return function(element, callback) {
// translate our select2 id into a text, it's a mapping to show
// simple label when selecting by internal ID.
var id, refData;
if (selectedRef === undefined) {
id = element.val();
refData = element.val().split(':');
} else {
id = selectedRef;
refData = selectedRef.split(':');
}
var text = refData[1];
if (refData[0] === 'rev') {
text = text.substring(0, 12);
}
var data = {id: id, text: text};
callback(data);
};
};
var formatRefSelection = function(item) {
var prefix = '';
var refData = item.id.split(':');
if (refData[0] === 'branch') {
prefix = '<i class="icon-branch"></i>';
}
else if (refData[0] === 'book') {
prefix = '<i class="icon-bookmark"></i>';
}
else if (refData[0] === 'tag') {
prefix = '<i class="icon-tag"></i>';
}
var originalOption = item.element;
return prefix + item.text;
};
// custom code mirror
var codeMirrorInstance = initPullRequestsCodeMirror('#pullrequest_desc');
pull-request: extended default reviewers functionality....
r1769 reviewersController = new ReviewersController();
templating: use .mako as extensions for template files.
r1282 var queryTargetRepo = function(self, query) {
// cache ALL results if query is empty
var cacheKey = query.term || '__';
var cachedData = self.cachedDataSource[cacheKey];
if (cachedData) {
query.callback({results: cachedData.results});
} else {
$.ajax({
pull-request: extended default reviewers functionality....
r1769 url: pyroutes.url('pullrequest_repo_destinations', {'repo_name': templateContext.repo_name}),
templating: use .mako as extensions for template files.
r1282 data: {query: query.term},
dataType: 'json',
type: 'GET',
success: function(data) {
self.cachedDataSource[cacheKey] = data;
query.callback({results: data.results});
},
error: function(data, textStatus, errorThrown) {
alert(
"Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
}
});
}
};
var queryTargetRefs = function(initialData, query) {
var data = {results: []};
// filter initialData
$.each(initialData, function() {
var section = this.text;
var children = [];
$.each(this.children, function() {
if (query.term.length === 0 ||
this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ) {
children.push({'id': this.id, 'text': this.text})
}
});
data.results.push({'text': section, 'children': children})
});
query.callback({results: data.results});
};
var loadRepoRefDiffPreview = function() {
var url_data = {
pull-request: extended default reviewers functionality....
r1769 'repo_name': targetRepo(),
'target_repo': sourceRepo(),
'source_ref': targetRef()[2],
templating: use .mako as extensions for template files.
r1282 'source_ref_type': 'rev',
pull-request: extended default reviewers functionality....
r1769 'target_ref': sourceRef()[2],
templating: use .mako as extensions for template files.
r1282 'target_ref_type': 'rev',
'merge': true,
'_': Date.now() // bypass browser caching
}; // gather the source/target ref and repo here
pull-request: extended default reviewers functionality....
r1769 if (sourceRef().length !== 3 || targetRef().length !== 3) {
prButtonLock(true, "${_('Please select source and target')}");
templating: use .mako as extensions for template files.
r1282 return;
}
compare: migrated code from pylons to pyramid views.
r1957 var url = pyroutes.url('repo_compare', url_data);
templating: use .mako as extensions for template files.
r1282
// lock PR button, so we cannot send PR before it's calculated
prButtonLock(true, "${_('Loading compare ...')}", 'compare');
if (loadRepoRefDiffPreview._currentRequest) {
loadRepoRefDiffPreview._currentRequest.abort();
}
loadRepoRefDiffPreview._currentRequest = $.get(url)
.error(function(data, textStatus, errorThrown) {
pull-requests: don't report abort type of ajax requests as errors.
r2480 if (textStatus !== 'abort') {
alert(
"Error while processing request.\nError code {0} ({1}).".format(
data.status, data.statusText));
}
templating: use .mako as extensions for template files.
r1282 })
.done(function(data) {
loadRepoRefDiffPreview._currentRequest = null;
$('#pull_request_overview').html(data);
pull-request: extended default reviewers functionality....
r1769
templating: use .mako as extensions for template files.
r1282 var commitElements = $(data).find('tr[commit_id]');
pull-request: extended default reviewers functionality....
r1769 var prTitleAndDesc = getTitleAndDescription(
sourceRef()[1], commitElements, 5);
templating: use .mako as extensions for template files.
r1282
var title = prTitleAndDesc[0];
var proposedDescription = prTitleAndDesc[1];
var useGeneratedTitle = (
$('#pullrequest_title').hasClass('autogenerated-title') ||
$('#pullrequest_title').val() === "");
if (title && useGeneratedTitle) {
// use generated title if we haven't specified our own
$('#pullrequest_title').val(title);
$('#pullrequest_title').addClass('autogenerated-title');
}
var useGeneratedDescription = (
!codeMirrorInstance._userDefinedDesc ||
codeMirrorInstance.getValue() === "");
if (proposedDescription && useGeneratedDescription) {
// set proposed content, if we haven't defined our own,
// or we don't have description written
codeMirrorInstance._userDefinedDesc = false; // reset state
codeMirrorInstance.setValue(proposedDescription);
}
var msg = '';
if (commitElements.length === 1) {
translation: unified usage of pluralize function ungettext....
r1945 msg = "${_ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 1)}";
templating: use .mako as extensions for template files.
r1282 } else {
translation: unified usage of pluralize function ungettext....
r1945 msg = "${_ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 2)}";
templating: use .mako as extensions for template files.
r1282 }
msg += ' <a id="pull_request_overview_url" href="{0}" target="_blank">${_('Show detailed compare.')}</a>'.format(url);
if (commitElements.length) {
var commitsLink = '<a href="#pull_request_overview"><strong>{0}</strong></a>'.format(commitElements.length);
prButtonLock(false, msg.replace('__COMMITS__', commitsLink), 'compare');
}
else {
prButtonLock(true, "${_('There are no commits to merge.')}", 'compare');
}
});
};
var Select2Box = function(element, overrides) {
var globalDefaults = {
dropdownAutoWidth: true,
containerCssClass: "drop-menu",
dropdownCssClass: "drop-menu-dropdown"
};
var initSelect2 = function(defaultOptions) {
var options = jQuery.extend(globalDefaults, defaultOptions, overrides);
element.select2(options);
};
return {
initRef: function() {
var defaultOptions = {
minimumResultsForSearch: 5,
formatSelection: formatRefSelection
};
initSelect2(defaultOptions);
},
initRepo: function(defaultValue, readOnly) {
var defaultOptions = {
initSelection : function (element, callback) {
var data = {id: defaultValue, text: defaultValue};
callback(data);
}
};
initSelect2(defaultOptions);
element.select2('val', defaultSourceRepo);
if (readOnly === true) {
element.select2('readonly', true);
}
}
};
};
var initTargetRefs = function(refsData, selectedRef){
Select2Box($targetRef, {
query: function(query) {
queryTargetRefs(refsData, query);
},
initSelection : initRefSelection(selectedRef)
}).initRef();
if (!(selectedRef === undefined)) {
$targetRef.select2('val', selectedRef);
}
};
var targetRepoChanged = function(repoData) {
// generate new DESC of target repo displayed next to select
pull-requests: add link to switch base based on the target.
r2469 var prLink = pyroutes.url('pullrequest_new', {'repo_name': repoData['name']});
templating: use .mako as extensions for template files.
r1282 $('#target_repo_desc').html(
default-reviewers: introduce new voting rule logic that allows...
r2484 "<strong>${_('Target repository')}</strong>: {0}. <a href=\"{1}\">Switch base, and use as source.</a>".format(repoData['description'], prLink)
templating: use .mako as extensions for template files.
r1282 );
// generate dynamic select2 for refs.
initTargetRefs(repoData['refs']['select2_refs'],
repoData['refs']['selected_ref']);
};
pull-request: extended default reviewers functionality....
r1769 var sourceRefSelect2 = Select2Box($sourceRef, {
templating: use .mako as extensions for template files.
r1282 placeholder: "${_('Select commit reference')}",
query: function(query) {
var initialData = defaultSourceRepoData['refs']['select2_refs'];
queryTargetRefs(initialData, query)
},
initSelection: initRefSelection()
}
);
var sourceRepoSelect2 = Select2Box($sourceRepo, {
query: function(query) {}
});
var targetRepoSelect2 = Select2Box($targetRepo, {
cachedDataSource: {},
query: $.debounce(250, function(query) {
queryTargetRepo(this, query);
}),
formatResult: formatResult
});
sourceRefSelect2.initRef();
sourceRepoSelect2.initRepo(defaultSourceRepo, true);
targetRepoSelect2.initRepo(defaultTargetRepo, false);
$sourceRef.on('change', function(e){
loadRepoRefDiffPreview();
pull-request: extended default reviewers functionality....
r1769 reviewersController.loadDefaultReviewers(
sourceRepo(), sourceRef(), targetRepo(), targetRef());
templating: use .mako as extensions for template files.
r1282 });
$targetRef.on('change', function(e){
loadRepoRefDiffPreview();
pull-request: extended default reviewers functionality....
r1769 reviewersController.loadDefaultReviewers(
sourceRepo(), sourceRef(), targetRepo(), targetRef());
templating: use .mako as extensions for template files.
r1282 });
$targetRepo.on('change', function(e){
var repoName = $(this).val();
calculateContainerWidth();
$targetRef.select2('destroy');
$('#target_ref_loading').show();
$.ajax({
url: pyroutes.url('pullrequest_repo_refs',
pull-request: extended default reviewers functionality....
r1769 {'repo_name': templateContext.repo_name, 'target_repo_name':repoName}),
templating: use .mako as extensions for template files.
r1282 data: {},
dataType: 'json',
type: 'GET',
success: function(data) {
$('#target_ref_loading').hide();
targetRepoChanged(data);
loadRepoRefDiffPreview();
},
error: function(data, textStatus, errorThrown) {
alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
}
})
});
pull-request: extended default reviewers functionality....
r1769 prButtonLock(true, "${_('Please select source and target')}", 'all');
templating: use .mako as extensions for template files.
r1282
// auto-load on init, the target refs select2
calculateContainerWidth();
targetRepoChanged(defaultTargetRepoData);
$('#pullrequest_title').on('keyup', function(e){
$(this).removeClass('autogenerated-title');
});
% if c.default_source_ref:
pull-request: extended default reviewers functionality....
r1769 // in case we have a pre-selected value, use it now
$sourceRef.select2('val', '${c.default_source_ref}');
loadRepoRefDiffPreview();
reviewersController.loadDefaultReviewers(
sourceRepo(), sourceRef(), targetRepo(), targetRef());
templating: use .mako as extensions for template files.
r1282 % endif
pull-request-reviewers: added option to add reviewers by picking an user group for pull requests....
r1678 ReviewerAutoComplete('#user');
templating: use .mako as extensions for template files.
r1282 });
</script>
</%def>