##// END OF EJS Templates
caches: use individual namespaces per user to prevent beaker caching problems....
caches: use individual namespaces per user to prevent beaker caching problems. - especially for mysql in case large number of data in caches there could be critical errors storing cache, and thus preventing users from authentication. This is caused by the fact that we used single namespace for ALL users. It means it grew as number of users grew reaching mysql single column limit. This changes the behaviour and now we use namespace per-user it means that each user-id will have it's own cache namespace fragmenting maximum column data to a single user cache. Which we should never reach.

File last commit:

r2555:1d84c2ba stable
r2572:5b07455a default
Show More
pullrequest.mako
537 lines | 19.0 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;
pull-requests: fixed cases with default expected refs are closed or unavailable....
r2555 if (selectedRef === undefined || selectedRef === null) {
templating: use .mako as extensions for template files.
r1282 id = element.val();
refData = element.val().split(':');
pull-requests: fixed cases with default expected refs are closed or unavailable....
r2555
if (refData.length !== 3){
refData = ["", "", ""]
}
templating: use .mako as extensions for template files.
r1282 } 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);
}
}
};
};
pull-requests: fixed cases with default expected refs are closed or unavailable....
r2555 var initTargetRefs = function(refsData, selectedRef) {
templating: use .mako as extensions for template files.
r1282 Select2Box($targetRef, {
pull-requests: fixed cases with default expected refs are closed or unavailable....
r2555 placeholder: "${_('Select commit reference')}",
templating: use .mako as extensions for template files.
r1282 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}');
pull-requests: fixed cases with default expected refs are closed or unavailable....
r2555 // diff preview load
pull-request: extended default reviewers functionality....
r1769 loadRepoRefDiffPreview();
pull-requests: fixed cases with default expected refs are closed or unavailable....
r2555 // default reviewers
pull-request: extended default reviewers functionality....
r1769 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>