60e5e21fa51860f75ae9d43f0f2f7b336190e798
braney
  Wed Feb 28 09:30:33 2018 -0800
fix sorting issue in visible tracks

diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index d659b7b..ee0a12a 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -31,30 +31,31 @@
 struct track *trackList;
 struct trackDb *tdb;
 char *name;
 char *shortLabel;
 char *longLabel;
 char *visibility;
 unsigned long color;
 char *viewFunc;        // The method by which calculated tracks should be calculated
 char *missingMethod;   // How should missing data be treated in calculated tracks
 };
 
 struct trackDbRef 
 {
 struct trackDbRef *next;
 struct trackDb *tdb;
+struct grp *grp;
 int order;
 };
 
 static char *makeUnique(struct hash *nameHash, char *name)
 // Make the name of this track unique.
 {
 char *skipHub = trackHubSkipHubName(name);
 if (hashLookup(nameHash, skipHub) == NULL)
     {
     hashStore(nameHash, name);
     return skipHub;
     }
 
 unsigned count = 0;
 char buffer[4096];
@@ -173,84 +174,89 @@
     return FALSE;
 
 char *cartVis = cartOptionalString(cart, tdb->parent->track);
 boolean vis;
 if (cartVis != NULL) 
     vis =  differentString(cartVis, "hide");
 else if (tdbIsSuperTrack(tdb->parent))
     vis = tdb->parent->isShow;
 else
     vis = tdb->parent->visibility != tvHide;
 
 return vis;
 }
 
 
-static void checkForVisible(struct cart *cart, struct trackDbRef **list, struct trackDb *tdb)
+static void checkForVisible(struct cart *cart, struct hash *groupHash, struct trackDbRef **list, struct trackDb *tdb)
 /* Walk the trackDb hierarchy looking for visible leaf tracks. */
 {
 struct trackDb *subTdb;
 char buffer[4096];
 
 if (tdb->subtracks)
     {
     for(subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next)
-        checkForVisible(cart, list, subTdb);
+        checkForVisible(cart, groupHash, list, subTdb);
     }
 else
     {
     boolean isVisible = FALSE;
     if (tdb->parent == NULL) 
         {
         char *cartVis = cartOptionalString(cart, tdb->track);
         if (cartVis == NULL)
             isVisible =  tdb->visibility != tvHide;
         else
             isVisible =  differentString(cartVis, "hide");
         }
     else if (isParentVisible(cart, tdb) &&  isSubtrackVisible(cart, tdb))
         isVisible = TRUE;
 
     if (isVisible)
         {
         struct trackDbRef *tdbRef;
         AllocVar(tdbRef);
         tdbRef->tdb = tdb;
+        tdbRef->grp = hashMustFindVal(groupHash, tdb->grp);;
         slAddHead(list, tdbRef);
         safef(buffer, sizeof buffer, "%s_imgOrd", tdb->track);
 
         tdbRef->order = cartUsualInt(cart, buffer, tdb->priority);
         }
     }
 }
 
 static int tdbRefCompare (const void *va, const void *vb)
 // Compare to sort on imgTrack->order.
 {
 const struct trackDbRef *a = *((struct trackDbRef **)va);
 const struct trackDbRef *b = *((struct trackDbRef **)vb);
-return (a->order - b->order);
+
+int dif = a->grp->priority - b->grp->priority;
+if (dif == 0)
+    dif = a->order - b->order;
+return dif;
 }       
 
-static void addVisibleTracks(struct dyString *rootChildren, struct cart *cart, struct trackDb *trackList)
+static void addVisibleTracks(struct hash *groupHash, struct dyString *rootChildren, struct cart *cart, struct trackDb *trackList)
 // add the visible tracks table rows.
 {
 struct trackDb *tdb;
 struct trackDbRef *tdbRefList = NULL, *tdbRef;
 for(tdb = trackList; tdb; tdb = tdb->next)
     {
-    checkForVisible(cart, &tdbRefList, tdb);
+    checkForVisible(cart, groupHash, &tdbRefList, tdb);
     }
 
 slSort(&tdbRefList, tdbRefCompare);
 if (!isEmpty(rootChildren->string))
     dyStringPrintf(rootChildren, ",");
 dyStringPrintf(rootChildren, "{icon:'../images/folderC.png',id:'visible', text:'Visible Tracks', parent:'#'");
 if (tdbRefList != NULL)
     dyStringPrintf(rootChildren, ",children:true");
 dyStringPrintf(rootChildren, "}");
 
 jsInlineF("trackData['visible'] = [");
 for(tdbRef = tdbRefList; tdbRef; tdbRef = tdbRef->next)
     {
     printTrack("visible", tdbRef->tdb,  FALSE);
     if (tdbRef->next != NULL)
@@ -284,35 +290,38 @@
     return;
 
 struct trackDb *tdb;
 for(tdb = parentTdb->subtracks; tdb;  tdb = tdb->next)
     {
     dyStringPrintf(dy, ",'%s'", trackHubSkipHubName(tdb->track));
     addSubtrackNames(dy, tdb);
     }
 }
 
 static void doTable(struct cart *cart, char *db, struct grp *groupList, struct trackDb *trackList)
 // output the tree table
 {
 char *hubName = hubNameFromUrl(getHubName(cart, db));
 struct grp *curGroup;
+struct hash *groupHash = newHash(10);
+
 for(curGroup = groupList; curGroup;  curGroup = curGroup->next)
-    {
-    if ((hubName != NULL) && sameString(curGroup->name, hubName))
-        break;
-    }
+    hashAdd(groupHash, curGroup->name, curGroup);
+
+curGroup = NULL;
+if (hubName != NULL)
+    curGroup = hashFindVal(groupHash, hubName);
 
 jsInlineF("var collectionData = []; ");
 struct dyString *dy = newDyString(100);
 if (curGroup != NULL)
     {
     // print out all the tracks in all the collections
     struct trackDb *tdb;
     jsInlineF("collectionData['#'] = [");
     boolean first = TRUE;
     for(tdb = trackList; tdb;  tdb = tdb->next)
         {
         if (sameString(tdb->grp, hubName))
             {
             if (!first)
                 {
@@ -329,31 +338,31 @@
         {
         if ( sameString(tdb->grp, curGroup->name))
             {
             printSubtracks("collectionData", tdb, TRUE);
             addSubtrackNames(dy, tdb);
             }
         }
     }
 else
     jsInlineF("collectionData['#'] = [];");
 
 jsInlineF("var collectionNames = new Set([%s]);", dy->string);
 
 jsInlineF("var trackData = []; ");
 struct dyString *rootChildren = newDyString(512);
-addVisibleTracks(rootChildren, cart, trackList);
+addVisibleTracks(groupHash, rootChildren, cart, trackList);
 for(curGroup = groupList; curGroup;  curGroup = curGroup->next)
     {
     if ((hubName != NULL) && sameString(curGroup->name, hubName))
         continue;
     if (!isEmpty(rootChildren->string))
         dyStringPrintf(rootChildren, ",");
     dyStringPrintf(rootChildren, "{icon:'../images/folderC.png',id:'%s', text:'%s', parent:'#', children:true}", curGroup->name, curGroup->label);
     struct trackDb *tdb;
     jsInlineF("trackData['%s'] = [", curGroup->name);
     boolean first = TRUE;
     for(tdb = trackList; tdb;  tdb = tdb->next)
         {
         if ( sameString(tdb->grp, curGroup->name))
             {
             if (!first)