a029a389a46082c6ab69d5053d5c17912dd72bf6
chmalee
  Thu Mar 5 12:18:56 2026 -0800
Make menubar assembly link clicks add to recents list, refs #36535

diff --git src/hg/lib/web.c src/hg/lib/web.c
index acdf382ab03..1bcd7dcd2c1 100644
--- src/hg/lib/web.c
+++ src/hg/lib/web.c
@@ -19,30 +19,31 @@
 #include "dbDb.h"
 #include "hgColors.h"
 #include "hubConnect.h"
 #include "search.h"
 #include "geoMirror.h"
 #include "trackHub.h"
 #include "versionInfo.h"
 #include "asmAlias.h"
 #include "cart.h"
 
 #ifndef GBROWSE
 #include "axtInfo.h"
 #include "wikiLink.h"
 #include "googleAnalytics.h"
 #include "jsHelper.h"
+#include "jsonParse.h"
 #endif /* GBROWSE */
 
 
 /* flag that tell if the CGI header has already been outputed */
 boolean webHeadAlreadyOutputed = FALSE;
 /* flag that tell if text CGI header has been outputed */
 boolean webInTextMode = FALSE;
 
 struct hash *includedResourceFiles = NULL;
 
 static char *dbCgiName = "db";
 static char *orgCgiName = "org";
 static char *cladeCgiName = "clade";
 static char *extraStyle = NULL;
 
@@ -1780,30 +1781,65 @@
 
 // links to hgTracks need to use the web browser width and set the hgTracks image
 // size in pixels correctly to match the hgGateway "GO" button
 jsInline("$(\"#tools1 ul li a\").each( function (a) {\n"
 "    if (this.href && this.href.indexOf(\"hgTracks\") !== -1) {\n"
 "        var obj = this;\n"
 "        obj.onclick = function(e) {\n"
 "            var pix = calculateHgTracksWidth();\n"
 "            e.currentTarget.href += \"&pix=\" + pix;\n"
 "        }\n"
 "    }\n"
 "});\n");
 // if the user has previously searched for assemblies, add them to the "Genomes" menu heading,
 // above the "other" assemblies link
 jsInline("addRecentGenomesToMenuBar();\n");
+
+// If the user explicitly navigated to this genome (db= in CGI params), add it to recent genomes
+if (db && cgiOptionalString("db"))
+    {
+    struct dbDb *dbInfo = hDbDb(db);
+    if (dbInfo)
+        {
+        char *bareDb = jsonStringEscape(trackHubSkipHubName(db));
+        char *safeOrganism = jsonStringEscape(trackHubSkipHubName(dbInfo->organism));
+        char *safeDescription = jsonStringEscape(trackHubSkipHubName(dbInfo->description));
+        struct dyString *jsCall = dyStringNew(512);
+        dyStringPrintf(jsCall,
+            "addRecentGenome({db:'%s', genome:'%s', label:'%s - %s (%s)', commonName:'%s'",
+            bareDb, bareDb, safeOrganism, safeDescription, bareDb, safeOrganism);
+        if (dbInfo->taxId > 0)
+            dyStringPrintf(jsCall, ", taxId:%d", dbInfo->taxId);
+        // For hub/GenArk assemblies, include hubUrl and category so hgGateway can route correctly
+        struct trackHubGenome *hubGenome = trackHubGetGenome(db);
+        if (hubGenome && hubGenome->trackHub)
+            {
+            char *safeHubUrl = jsonStringEscape(hubGenome->trackHub->url);
+            dyStringPrintf(jsCall, ", hubUrl:'%s'", safeHubUrl);
+            if (startsWith("/gbdb", hubGenome->trackHub->url))
+                dyStringAppend(jsCall, ", category:'UCSC Curated'");
+            else
+                dyStringAppend(jsCall, ", category:'Assembly Hub'");
+            }
+        else
+            dyStringAppend(jsCall, ", category:'UCSC Curated'");
+        dyStringAppend(jsCall, "});\n");
+        jsInline(dyStringContents(jsCall));
+        dyStringFree(&jsCall);
+        }
+    }
+
 return menuStr;
 }
 
 void checkForGeoMirrorRedirect(struct cart *cart)
 // Implement Geo/IP based redirection.
 {
 char *thisNodeStr = geoMirrorNode();
 if (thisNodeStr)   // if geo-mirroring is enabled
     {
     char *redirectCookie = findCookieData("redirect");
     char *redirect = cgiOptionalString("redirect");
 
     // if we're not already redirected
     if (redirect == NULL && redirectCookie == NULL) 
         {