feat(repo): add quick repository switcher to repo header (#38188)

Add a GitHub-style quick repo switcher: a caret next to the owner/repo
breadcrumb
opens a dropdown that lists and searches the current owner's
repositories and
navigates to the selected one. The current repository is marked with a
check, and
private/fork repos show an icon.

Also, fix various bugs in fomtantic dropdown remote query

## Screenshots

<img width="505" height="198" alt="image"
src="https://github.com/user-attachments/assets/9f673d1b-fe60-41f0-b9e2-b00dc43720b5"
/>

Fixes #38187

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
bircni
2026-08-17 20:08:15 +00:00
committed by GitHub
co-authored by wxiaoguang
parent e223c42ee6
commit 1cf904f101
15 changed files with 115 additions and 83 deletions
+22 -3
View File
@@ -431,7 +431,12 @@ $.fn.dropdown = function(parameters) {
module.refresh();
},
menu: function(values) {
$menu.html( templates.menu(values, fields,settings.preserveHTML,settings.className));
const $menuItems = $(templates.menu(values, fields,settings.preserveHTML,settings.className));
$menuItems.attr('data-item-dynamic', '');
$menu.find('[data-item-dynamic]').remove();
$menu.append(...$menuItems);
settings.onMenuUpdated();
$item = $menu.find(selector.item);
$divider = settings.hideDividers ? $item.parent().children(selector.divider) : $();
},
@@ -515,8 +520,10 @@ $.fn.dropdown = function(parameters) {
? callback
: function(){}
;
if(!module.can.show() && module.is.remote()) {
const dataKeyRemoteQueried = 'remote-queried';
if(module.is.remote() && !$module.data(dataKeyRemoteQueried)) {
module.debug('No API results retrieved, searching before show');
$module.data(dataKeyRemoteQueried, true)
module.queryRemote(module.get.query(), module.show);
}
if( module.can.show() && !module.is.active() ) {
@@ -793,6 +800,9 @@ $.fn.dropdown = function(parameters) {
},
queryRemote: function(query, callback) {
const dataKeyRemoteQuerying = 'remote-querying';
if ($module.data(dataKeyRemoteQuerying) === query) return;
$module.data(dataKeyRemoteQuerying, query);
var
apiSettings = {
errorDuration : false,
@@ -801,6 +811,11 @@ $.fn.dropdown = function(parameters) {
urlData : {
query: query
},
onComplete: function() {
if ($module.data(dataKeyRemoteQuerying) === query) {
$module.removeData(dataKeyRemoteQuerying);
}
},
onError: function() {
module.add.message(message.serverError);
callback();
@@ -3930,7 +3945,8 @@ $.fn.dropdown.settings = {
minCharacters : 0, // Minimum characters required to trigger API call
filterRemoteData : false, // Whether API results should be filtered after being returned for query term
saveRemoteData : true, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh
saveRemoteData : false, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh
// saveRemoteData is a wrong design and buggy, don't use it.
throttle : 200, // How long to wait after last user input to search remotely
@@ -3996,6 +4012,7 @@ $.fn.dropdown.settings = {
onLabelCreate : function(value, text) { return $(this); },
onLabelRemove : function(value) { return true; },
onNoResults : function(searchTerm) { return true; },
onMenuUpdated : function(){},
onShow : function(){},
onHide : function(){},
@@ -4222,6 +4239,8 @@ $.fn.dropdown.settings.templates = {
if(option[fields.divider]){
html += '<div class="'+className.divider+'"></div>';
}
} else if( itemType === 'html' ) {
html += option.html;
}
});
return html;