feature: implements mid trimming long text; implements repo length truncation
This commit is contained in:
parent
1906b1960f
commit
e0b2043c71
21 changed files with 311 additions and 96 deletions
|
|
@ -70,6 +70,7 @@
|
|||
"<%= dirs.js.src_rc %>/i18n/select2/translations.js",
|
||||
"<%= dirs.js.src %>/rhodecode/utils/array.js",
|
||||
"<%= dirs.js.src %>/rhodecode/utils/string.js",
|
||||
"<%= dirs.js.src %>/rhodecode/utils/trimText.js",
|
||||
"<%= dirs.js.src %>/rhodecode/utils/pyroutes.js",
|
||||
"<%= dirs.js.src %>/rhodecode/utils/ajax.js",
|
||||
"<%= dirs.js.src %>/rhodecode/utils/autocomplete.js",
|
||||
|
|
|
|||
|
|
@ -2452,3 +2452,19 @@ def get_directory_statistics(start_path):
|
|||
total_size += dir_size
|
||||
|
||||
return total_files, total_size, directory_stats
|
||||
|
||||
|
||||
def truncate_middle(text_, max_length=100):
|
||||
ellipsis = "..."
|
||||
min_limit = 5
|
||||
|
||||
if len(text_) <= max_length:
|
||||
return text_
|
||||
|
||||
max_length = max(min_limit, max_length)
|
||||
|
||||
keep = max_length - len(ellipsis)
|
||||
left = math.ceil(keep / 2)
|
||||
right = math.ceil(keep / 2)
|
||||
|
||||
return text_[:left] + ellipsis + text_[-right:]
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ def get_diff_info(source_repo, source_ref, target_repo, target_ref, get_authors=
|
|||
target_scm = target_repo.scm_instance()
|
||||
|
||||
ancestor_id = target_scm.get_common_ancestor(target_ref, source_ref, source_scm)
|
||||
if not ancestor_id:
|
||||
if not ancestor_id or (isinstance(ancestor_id, str) and ancestor_id.lower() == "none"):
|
||||
raise ValueError(
|
||||
"cannot calculate diff info without a common ancestor. "
|
||||
"Make sure both repositories are related, and have a common forking commit."
|
||||
|
|
|
|||
|
|
@ -208,6 +208,10 @@
|
|||
|
||||
.fieldset {
|
||||
|
||||
pre {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.left-label { // similar to form legend
|
||||
display: block;
|
||||
margin: 0;
|
||||
|
|
|
|||
|
|
@ -186,7 +186,6 @@ table.dataTable {
|
|||
&.truncate, .truncate-wrap {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 350px;
|
||||
}
|
||||
}
|
||||
|
|
@ -345,9 +344,6 @@ table.dataTable {
|
|||
max-width: 450px;
|
||||
width: 300px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
-ms-text-overflow: ellipsis;
|
||||
|
||||
&.autoexpand {
|
||||
width: 120px;
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ var tooltipActivate = function () {
|
|||
};
|
||||
|
||||
// Formatting values in a Select2 dropdown of commit references
|
||||
var formatSelect2SelectionRefs = function(commit_ref){
|
||||
var formatSelect2SelectionRefs = function(commit_ref, tripTextFn){
|
||||
var tmpl = '';
|
||||
if (!commit_ref.text || commit_ref.type === 'sha'){
|
||||
return commit_ref.text;
|
||||
|
|
@ -345,6 +345,10 @@ var formatSelect2SelectionRefs = function(commit_ref){
|
|||
} else if (commit_ref.type === 'book'){
|
||||
tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
|
||||
}
|
||||
if (tripTextFn !== undefined) {
|
||||
return tmpl.concat(tripTextFn(escapeHtml(commit_ref.text)));
|
||||
}
|
||||
|
||||
return tmpl.concat(escapeHtml(commit_ref.text));
|
||||
};
|
||||
|
||||
|
|
|
|||
153
rhodecode/public/js/src/rhodecode/utils/trimText.js
Normal file
153
rhodecode/public/js/src/rhodecode/utils/trimText.js
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
const DEFAULT_LIMIT = 30; // used only if auto can't compute
|
||||
const MIN_LIMIT = 5;
|
||||
const ELLIPSIS = "...";
|
||||
const FILL = 0.90; // use 90% of available width
|
||||
|
||||
// Cache average char width per font+letterSpacing
|
||||
const avgCharWidthCache = new Map();
|
||||
|
||||
function toChars(s) {
|
||||
return Array.from(s);
|
||||
} // unicode-safe
|
||||
|
||||
function truncateMiddle(str, maxLen) {
|
||||
maxLen = parseInt(maxLen, 10);
|
||||
if (!Number.isFinite(maxLen)) maxLen = DEFAULT_LIMIT;
|
||||
maxLen = Math.max(MIN_LIMIT, maxLen);
|
||||
|
||||
const full = (str || "").trim();
|
||||
const chars = toChars(full);
|
||||
if (chars.length <= maxLen) return full;
|
||||
|
||||
const keep = maxLen - ELLIPSIS.length; // remaining visible chars besides "..."
|
||||
const left = Math.ceil(keep / 2);
|
||||
const right = Math.floor(keep / 2);
|
||||
|
||||
return chars.slice(0, left).join("") + ELLIPSIS + chars.slice(chars.length - right).join("");
|
||||
}
|
||||
|
||||
function ensureTextSpan($a) {
|
||||
let $span = $a.find("span.js-midcut").first();
|
||||
if ($span.length) return $span;
|
||||
|
||||
const textNodes = $a.contents().filter(function () {
|
||||
return this.nodeType === 3 && this.nodeValue && this.nodeValue.trim().length > 0;
|
||||
});
|
||||
if (!textNodes.length) return null;
|
||||
|
||||
const full = textNodes.map(function () {
|
||||
return this.nodeValue;
|
||||
}).get().join(" ").trim();
|
||||
textNodes.remove();
|
||||
|
||||
$span = $("<span/>", {class: "js-midcut", text: full})
|
||||
.attr("data-full", full)
|
||||
.attr("title", full);
|
||||
|
||||
$a.append($span);
|
||||
return $span;
|
||||
}
|
||||
|
||||
function getAvgCharWidthPx(el) {
|
||||
const cs = window.getComputedStyle(el);
|
||||
|
||||
// Include letter-spacing because it affects width
|
||||
const key = [
|
||||
cs.fontStyle, cs.fontVariant, cs.fontWeight,
|
||||
cs.fontSize, cs.fontFamily, cs.letterSpacing
|
||||
].join("|");
|
||||
|
||||
if (avgCharWidthCache.has(key)) return avgCharWidthCache.get(key);
|
||||
|
||||
// Measure using a hidden span with same font + letter spacing
|
||||
const sample = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
const repeat = 6; // 62*6 = 372 chars -> stable average
|
||||
const text = sample.repeat(repeat);
|
||||
|
||||
const meas = document.createElement("span");
|
||||
meas.style.position = "absolute";
|
||||
meas.style.visibility = "hidden";
|
||||
meas.style.whiteSpace = "nowrap";
|
||||
meas.style.left = "-99999px";
|
||||
meas.style.top = "-99999px";
|
||||
meas.style.fontStyle = cs.fontStyle;
|
||||
meas.style.fontVariant = cs.fontVariant;
|
||||
meas.style.fontWeight = cs.fontWeight;
|
||||
meas.style.fontSize = cs.fontSize;
|
||||
meas.style.fontFamily = cs.fontFamily;
|
||||
meas.style.letterSpacing = cs.letterSpacing;
|
||||
meas.textContent = text;
|
||||
|
||||
document.body.appendChild(meas);
|
||||
const width = meas.getBoundingClientRect().width;
|
||||
document.body.removeChild(meas);
|
||||
|
||||
const avg = width / text.length || 8; // fallback if something weird
|
||||
avgCharWidthCache.set(key, avg);
|
||||
return avg;
|
||||
}
|
||||
|
||||
// Auto maxLen from width (px) → chars, using 90% available width
|
||||
function autoMaxLenForAnchor($a) {
|
||||
const aEl = $a[0];
|
||||
const $truncate = $a.closest(".truncate");
|
||||
const containerEl = $truncate[0] || aEl;
|
||||
|
||||
const containerW = containerEl.getBoundingClientRect().width;
|
||||
if (!containerW) return null;
|
||||
|
||||
// Subtract widths of non-text children (icons etc.), exclude our span
|
||||
let nonTextW = 0;
|
||||
$a.children().not("span.js-midcut").each(function () {
|
||||
nonTextW += $(this).outerWidth(true) || 0;
|
||||
});
|
||||
|
||||
const availablePx = Math.max(0, (containerW - nonTextW) * FILL);
|
||||
if (!availablePx) return null;
|
||||
|
||||
const avgCharW = getAvgCharWidthPx(aEl);
|
||||
if (!avgCharW) return null;
|
||||
|
||||
const est = Math.floor(availablePx / avgCharW);
|
||||
return Math.max(MIN_LIMIT, est);
|
||||
}
|
||||
|
||||
// limitOverride: optional manual max length for all elements in this call
|
||||
function applyMiddleCut(selector, limitOverride) {
|
||||
$(selector).each(function () {
|
||||
const $el = $(this);
|
||||
|
||||
const $span = ensureTextSpan($el);
|
||||
if (!$span) return;
|
||||
|
||||
const full = $span.attr("data-full") || $span.text();
|
||||
|
||||
// 1) per-element override (if you can add attributes)
|
||||
// <div class="truncate" data-maxlen="20"> OR <a data-maxlen="20">
|
||||
const perEl =
|
||||
$el.closest(".truncate").attr("data-maxlen") ||
|
||||
$el.attr("data-maxlen");
|
||||
|
||||
// 2) manual override passed to function
|
||||
// 3) auto-detected from width
|
||||
// 4) fallback default
|
||||
const autoLen = autoMaxLenForAnchor($el);
|
||||
const limit = perEl || limitOverride || autoLen || DEFAULT_LIMIT;
|
||||
|
||||
const trimmed = truncateMiddle(full, limit);
|
||||
if ($span.text() !== trimmed) $span.text(trimmed);
|
||||
});
|
||||
}
|
||||
|
||||
function trimRepoTitleName() {
|
||||
const $repoNameTitle = $("#repo-name-title");
|
||||
let text = $repoNameTitle.text();
|
||||
let arr = text.split(": ");
|
||||
if (arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
let repoName = arr[arr.length - 1];
|
||||
let symbolsCnt = autoMaxLenForAnchor($repoNameTitle);
|
||||
const trimmedName = truncateMiddle(repoName, symbolsCnt);
|
||||
$repoNameTitle.text(arr[0] + ": " + trimmedName);
|
||||
}
|
||||
|
|
@ -37,8 +37,8 @@
|
|||
</%def>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
<div class="panel-heading truncate">
|
||||
<h3 class="panel-title" id="repo-name-title">
|
||||
%if c.repo:
|
||||
${_('Current Integrations for Repository: {repo_name}').format(repo_name=c.repo.repo_name)}
|
||||
%elif c.repo_group:
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
<td colspan="7">
|
||||
|
||||
%if c.repo:
|
||||
${_('No {type} integrations for repo {repo} exist yet.').format(type=integration_type, repo=c.repo.repo_name)}
|
||||
${_('No {type} integrations for repo {repo} exist yet.').format(type=integration_type, repo=h.truncate_middle(c.repo.repo_name))}
|
||||
%elif c.repo_group:
|
||||
${_('No {type} integrations for repogroup {repogroup} exist yet.').format(type=integration_type, repogroup=c.repo_group.group_name)}
|
||||
%else:
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
%if c.current_IntegrationType:
|
||||
<%
|
||||
if c.repo:
|
||||
create_url = h.route_path('repo_integrations_create', repo_name=c.repo.repo_name, integration=c.current_IntegrationType.key)
|
||||
create_url = h.route_path('repo_integrations_create', repo_name=h.truncate_middle(c.repo.repo_name), integration=c.current_IntegrationType.key)
|
||||
elif c.repo_group:
|
||||
create_url = h.route_path('repo_group_integrations_create', repo_group_name=c.repo_group.group_name, integration=c.current_IntegrationType.key)
|
||||
else:
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
<td class="td-scope">
|
||||
%if integration.repo:
|
||||
<a href="${h.route_path('repo_summary', repo_name=integration.repo.repo_name)}">
|
||||
${_('repo')}:${integration.repo.repo_name}
|
||||
${_('repo')}:${h.truncate_middle(integration.repo.repo_name)}
|
||||
</a>
|
||||
%elif integration.repo_group:
|
||||
<a href="${h.route_path('repo_group_home', repo_group_name=integration.repo_group.group_name)}">
|
||||
|
|
@ -216,4 +216,5 @@
|
|||
e.preventDefault();
|
||||
delete_integration(this);
|
||||
});
|
||||
trimRepoTitleName();
|
||||
</script>
|
||||
|
|
@ -19,7 +19,8 @@ ${h.secure_form(h.route_path('repo_create'), request=request)}
|
|||
${h.select('repo_group', request.GET.get('parent_group'), c.repo_groups, class_="medium")}
|
||||
<div class="repo-create-spacer"> / </div>
|
||||
<div class="repo-name-input-container">
|
||||
${h.text('repo_name', class_="medium", id="repo_name_input")}
|
||||
${h.text('repo_name', class_="medium", id="repo_name_input", maxlength=192)}
|
||||
<div id="repo_name_error" class="error" aria-live="polite" style="display:none; color: #c00; margin-top: 6px; font-size: 0.9rem;"></div>
|
||||
<div class="repo-check-container check-progress" id="repo_check" style="display: none"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -282,6 +283,7 @@ ${h.secure_form(h.route_path('repo_create'), request=request)}
|
|||
}
|
||||
})
|
||||
|
||||
})
|
||||
trimRepoTitleName();
|
||||
});
|
||||
</script>
|
||||
${h.end_form()}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
%>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" id="advanced-info" >
|
||||
<h3 class="panel-title">${_('Repository: %s') % c.rhodecode_db_repo.repo_name} <a class="permalink" href="#advanced-info"> ¶</a></h3>
|
||||
<div class="panel-heading truncate" id="advanced-info" >
|
||||
<h3 class="panel-title" id="repo-name-title">${_('Repository: %s') % c.rhodecode_db_repo.repo_name} <a class="permalink" href="#advanced-info"> ¶</a></h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
${base.dt_info_panel(elems)}
|
||||
|
|
@ -241,7 +241,7 @@
|
|||
|
||||
<div class="field">
|
||||
<button class="btn btn-small btn-danger" type="submit"
|
||||
onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository'), _gettext('Delete'), '${c.rhodecode_db_repo.repo_name}')"
|
||||
onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository'), _gettext('Delete'), '${h.truncate_middle(c.rhodecode_db_repo.repo_name, 50)}')"
|
||||
>
|
||||
${_('Delete this repository')}
|
||||
</button>
|
||||
|
|
@ -263,7 +263,6 @@
|
|||
|
||||
|
||||
<script>
|
||||
|
||||
var currentRepoId = ${c.rhodecode_db_repo.repo_id};
|
||||
|
||||
var repoTypeFilter = function(data) {
|
||||
|
|
@ -330,6 +329,6 @@ function syncHelpVisibility() {
|
|||
$checkbox.on('change', syncHelpVisibility)
|
||||
|
||||
syncHelpVisibility();
|
||||
|
||||
trimRepoTitleName();
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -21,3 +21,7 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
applyMiddleCut('.rctable .td-componentname a, .rctable .td-componentname', 70);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<%namespace name="base" file="/base/base.mako"/>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${_('Settings for Repository: %s') % c.rhodecode_db_repo.repo_name}</h3>
|
||||
<div class="panel-heading truncate">
|
||||
<h3 id="repo-name-title" class="panel-title">${_('Settings for Repository: %s') % c.rhodecode_db_repo.repo_name}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
${h.secure_form(h.route_path('edit_repo', repo_name=c.rhodecode_db_repo.repo_name), request=request)}
|
||||
|
|
@ -332,5 +332,7 @@
|
|||
};
|
||||
|
||||
UsersAutoComplete('repo_owner', '${c.rhodecode_user.user_id}');
|
||||
|
||||
trimRepoTitleName();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -141,6 +141,10 @@ $(document).ready(function() {
|
|||
})
|
||||
);
|
||||
|
||||
$(document).on("draw.dt", function () {
|
||||
applyMiddleCut('#repo_list_table .truncate a', 60);
|
||||
applyMiddleCut('.truncate-wrap');
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -854,7 +854,7 @@
|
|||
|
||||
var tmpl = '';
|
||||
var repoType = data['repo_type'];
|
||||
var repoName = data['text'];
|
||||
var repoName = truncateMiddle(data['text'], 60);
|
||||
|
||||
if(data && data.type == 'repo'){
|
||||
if(repoType === 'hg'){
|
||||
|
|
@ -1222,6 +1222,9 @@
|
|||
window.updateStickyHeader();
|
||||
}
|
||||
}
|
||||
})()
|
||||
$(function () {
|
||||
applyMiddleCut('#context-bar .title a');
|
||||
});
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@
|
|||
|
||||
var enable_fields = ${"false" if c.preview_mode else "true"};
|
||||
$("#compare_source").select2({
|
||||
placeholder: "${'%s@%s' % (c.source_repo.repo_name, c.source_ref)}",
|
||||
placeholder: "${'%s@%s' % (h.truncate_middle(c.source_repo.repo_name), c.source_ref)}",
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
formatSelection: formatSelection("${c.source_repo.repo_name}"),
|
||||
|
|
@ -238,7 +238,7 @@
|
|||
}).select2("enable", enable_fields);
|
||||
|
||||
$("#compare_target").select2({
|
||||
placeholder: "${'%s@%s' % (c.target_repo.repo_name, c.target_ref)}",
|
||||
placeholder: "${'%s@%s' % (h.truncate_middle(c.target_repo.repo_name), c.target_ref)}",
|
||||
dropdownAutoWidth: true,
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
|
|
|
|||
|
|
@ -402,10 +402,10 @@ ${h.style_metatag(tag_type, tag)|n,trim}
|
|||
|
||||
%>
|
||||
## Source
|
||||
<code class="pr-source-info"><i class="icon-${pr_ref_type_to_icon(pull_request.source_ref_parts.type)}"></i>${pull_request.source_ref_parts.name}</code>
|
||||
<code class="pr-source-info"><i class="icon-${pr_ref_type_to_icon(pull_request.source_ref_parts.type)}"></i>${h.truncate_middle(pull_request.source_ref_parts.name, 70)}</code>
|
||||
→
|
||||
## Target
|
||||
<code class="pr-target-info"><i class="icon-${pr_ref_type_to_icon(pull_request.target_ref_parts.type)}"></i>${pull_request.target_ref_parts.name}</code>
|
||||
<code class="pr-target-info"><i class="icon-${pr_ref_type_to_icon(pull_request.target_ref_parts.type)}"></i>${h.truncate_middle(pull_request.target_ref_parts.name, 90)}</code>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
|
|
|
|||
|
|
@ -286,9 +286,17 @@
|
|||
query.callback(data);
|
||||
};
|
||||
|
||||
const truncateSelection = function(item) {
|
||||
return truncateMiddle(item, 35);
|
||||
}
|
||||
|
||||
const truncateResult = function(item) {
|
||||
return truncateMiddle(item, 60);
|
||||
}
|
||||
|
||||
var select2RefFileSwitcher = function (targetElement, loadUrl, initialData) {
|
||||
var formatResult = function (result, container, query) {
|
||||
return formatSelect2SelectionRefs(result);
|
||||
return formatSelect2SelectionRefs(result, truncateResult);
|
||||
};
|
||||
|
||||
var formatSelection = function (data, container) {
|
||||
|
|
@ -299,7 +307,7 @@
|
|||
tmpl = (commit_ref.raw_id || "").substr(0,8);
|
||||
} else if (commit_ref.type === 'branch') {
|
||||
tmpl = tmpl.concat('<i class="icon-branch"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text));
|
||||
tmpl = tmpl.concat(truncateSelection(escapeHtml(commit_ref.text)));
|
||||
} else if (commit_ref.type === 'tag') {
|
||||
tmpl = tmpl.concat('<i class="icon-tag"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
</div>
|
||||
|
||||
${h.hidden('refs_filter')}
|
||||
<!-- ////-->
|
||||
|
||||
<div class="info_box_elem next">
|
||||
<a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class=" ${('disabled' if c.url_next == '#' else '')}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a>
|
||||
|
|
|
|||
|
|
@ -225,7 +225,9 @@
|
|||
|
||||
},
|
||||
});
|
||||
|
||||
$(document).on("draw.dt", function () {
|
||||
applyMiddleCut('.truncate-wrap .truncate a, .truncate-wrap'); // auto
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -315,8 +315,7 @@
|
|||
prefix = '<i class="icon-tag"></i>';
|
||||
}
|
||||
|
||||
var originalOption = data.element;
|
||||
return prefix + escapeMarkup(data.text);
|
||||
return prefix + escapeMarkup(truncateMiddle(data.text, 35));
|
||||
};
|
||||
|
||||
// custom code mirror
|
||||
|
|
@ -423,6 +422,20 @@
|
|||
reviewersController = new ReviewersController();
|
||||
reviewersController.diffDataHandler = diffDataHandler;
|
||||
|
||||
function truncateSelection(item) {
|
||||
if (item.text !== undefined) {
|
||||
return truncateMiddle(item.text, 35);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
function truncateResult(item) {
|
||||
if (item.text !== undefined) {
|
||||
return truncateMiddle(item.text, 60);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
var queryTargetRepo = function(self, query) {
|
||||
// cache ALL results if query is empty
|
||||
var cacheKey = query.term || '__';
|
||||
|
|
@ -470,7 +483,9 @@
|
|||
var globalDefaults = {
|
||||
dropdownAutoWidth: true,
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown"
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
formatSelection: truncateSelection,
|
||||
formatResult: truncateResult
|
||||
};
|
||||
|
||||
var initSelect2 = function(defaultOptions) {
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@
|
|||
<div class="pr-commit-flow">
|
||||
## Source
|
||||
%if c.pull_request.source_ref_parts.type == 'branch':
|
||||
<a href="${h.route_path('repo_commits', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}"><code class="pr-source-info">${c.pull_request.source_ref_parts.type}:${c.pull_request.source_ref_parts.name}</code></a>
|
||||
<a href="${h.route_path('repo_commits', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}"><code class="pr-source-info">${c.pull_request.source_ref_parts.type}:${h.truncate_middle(c.pull_request.source_ref_parts.name, 40)}</code></a>
|
||||
%else:
|
||||
<code class="pr-source-info">${'{}:{}'.format(c.pull_request.source_ref_parts.type, c.pull_request.source_ref_parts.name)}</code>
|
||||
<code class="pr-source-info">${'{}:{}'.format(c.pull_request.source_ref_parts.type, h.truncate_middle(c.pull_request.source_ref_parts.name, 40))}</code>
|
||||
%endif
|
||||
${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.repo_name}</a>
|
||||
${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${h.truncate_middle(c.pull_request.source_repo.repo_name, 40)}</a>
|
||||
→
|
||||
## Target
|
||||
%if c.pull_request.target_ref_parts.type == 'branch':
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
<code class="pr-target-info">${'{}:{}'.format(c.pull_request.target_ref_parts.type, c.pull_request.target_ref_parts.name)}</code>
|
||||
%endif
|
||||
|
||||
${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.repo_name}</a>
|
||||
${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${h.truncate_middle(c.pull_request.target_repo.repo_name, 40)}</a>
|
||||
|
||||
<a class="source-details-action" href="#expand-source-details" onclick="return toggleElement(this, '.source-details')" data-toggle-on='<i class="icon-angle-down">more details</i>' data-toggle-off='<i class="icon-angle-up">less details</i>'>
|
||||
<i class="icon-angle-down">more details</i>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue