0d082b749cf32760466ade27ce08093cdbc809f6 max Fri Sep 18 09:08:29 2026 -0700 hgSession: back-up-custom-tracks link goes above Advanced, not inside it #Preview2 week - bugs introduced now will need a build patch to fix refs #38311 diff --git src/hg/js/hgSession.js src/hg/js/hgSession.js index 8365635af3f..d78c515b506 100644 --- src/hg/js/hgSession.js +++ src/hg/js/hgSession.js @@ -1,23 +1,23 @@ // hgSession.js - the experimental client-rendered "My Sessions" page. // // An opt-in modern alternative to the classic server-rendered hgSession page, applying hgBlat's // facelift strategy (#37996): hgSession.c emits the session list and page config as an inline JSON // global (hgSessionData) into an empty #sessionApp container, and this file builds the UI - a -// save-current-view card, a searchable/sortable DataTable of saved sessions with inline -// Overwrite/Share/Edit/Delete, and an "Advanced" panel split into a load column and a save -// column, with the custom-track backup link across the top of both. +// save-current-view card, a custom-track backup link, a searchable/sortable DataTable of saved +// sessions with inline Overwrite/Share/Edit/Delete, and an "Advanced" panel split into a load +// column and a save column. // // The inline table actions POST to small JSON endpoints in hgSession.c (hgS_doDeleteJson, etc.) and // update the table in place. Navigation actions (load a session, load from URL/file, save to file, // reset) are ordinary form submits/links against the existing hgSession actions. // // Styling: shared house-style components in gbModern.css (.gbPill, .gbCard, .gbModal*, .gbTable, // .gbBanner, .gbSection), session-specific layout in hgSession.css. /* global $, hgSessionData, convertTitleTagsToMouseovers, titleTagToMouseover, addMouseover */ /* global htmlEncode, commify, gbShowTimingDialog */ // Cart action variables (must match the hgs* defines in hgSession.h; hgSessionPrefix is "hgS_"). var SESS_ACT = { save: 'hgS_doSaveSessionJson', rename: 'hgS_doRenameSessionJson', @@ -611,53 +611,55 @@ var saveFile = '<div class="sessAdvItem"><span class="lab">Save settings to a file</span>' + '<form class="sessAdvRow" action="hgSession" method="POST">' + sid + '<input class="sessAdvInput" type="text" name="hgS_saveLocalFileName" ' + 'placeholder="File name (blank = show in browser)">' + '<label class="sessSaveCheck"><input type="checkbox" name="hgS_saveLocalFileCompress" ' + 'value="gzip"> gzip</label>' + '<button type="submit" class="gbPill" name="hgS_doSaveLocal" value="submit" ' + 'title="Download the current browser settings as a session file">Save</button></form></div>'; var other = '<div class="sessAdvItem"><span class="lab">Other</span>' + '<div class="sessAdvLinks">' + '<a href="' + sessEnc(C.resetUrl) + '" ' + 'title="Reset all browser settings to their defaults">Reset the browser to defaults</a>' + '</div></div>'; - // A single link, not a button: custom-track backup used to be its own row down in the Save - // column; it now sits across the very top of the panel, above both columns. - var backup = - '<div class="sessAdvTop"><a href="hgSession?hgS_showDownload_=Submit&' + - sessEnc(C.cartVar) + '=' + sessEnc(C.hgsid) + '" ' + - 'title="Download your custom tracks as a .tar.gz archive you can reload later">' + - 'Back up custom tracks (.tar.gz)</a></div>'; // Two columns - what you load from, and what you save to - rather than one undifferentiated // list; "Other" (reset) belongs to neither, so it spans both underneath. return '<div class="sessAdv">' + '<div class="sessAdvHead" id="sessAdvHead"><span class="caret">▸</span>' + '<span>Advanced — load another user’s session, load from a URL or file, ' + 'save to a file, reset the browser</span></div>' + '<div class="sessAdvBody" id="sessAdvBody" style="display:none">' + - backup + '<div class="sessAdvCol"><div class="sessAdvColHead">Load</div>' + loadUser + loadUrl + loadFile + '</div>' + '<div class="sessAdvCol"><div class="sessAdvColHead">Save</div>' + saveFile + '</div>' + '<div class="sessAdvOther">' + other + '</div>' + '</div></div>'; } +function sessBackupHtml(C) { + // A single plain link, sitting on its own line right above the Advanced dropdown - visible + // without opening Advanced, but not a whole bar/button the way it once was. + if (!C.loggedIn) { return ''; } + return '<div class="sessBackupLink"><a href="hgSession?hgS_showDownload_=Submit&' + + sessEnc(C.cartVar) + '=' + sessEnc(C.hgsid) + '" ' + + 'title="Download your custom tracks as a .tar.gz archive you can reload later">' + + 'Back up custom tracks (.tar.gz)</a></div>'; +} + // ---- build the whole page ----------------------------------------------- function sessAccountHtml(C) { // The signed-in account line (Signed in as X · Sign out · Change password) now lives in the // top-right menu bar, so it is intentionally not rendered here. Kept commented out so QA can // add it back if wanted: /* if (C.loggedIn) { var s = 'Signed in as <b>' + sessEnc(C.userName) + '</b>'; if (C.logoutUrl) { s += ' · <a href="' + sessEnc(C.logoutUrl) + '">Sign out</a>'; } if (C.changePasswordUrl) { s += ' · <a href="' + sessEnc(C.changePasswordUrl) + '">Change password</a>'; } return s; } @@ -822,30 +824,31 @@ }); // The session most recently saved/overwritten (max lastUse), for the one-click "Overwrite now". // Only this server's own sessions: "Overwrite now" saves through this server's cart. var recent = null; (sessData.sessions || []).forEach(function(s) { if (s.remote) { return; } if (!recent || s.lastUseEpoch > recent.lastUseEpoch) { recent = s; } }); app.html( intro + '<div id="sessMsg" class="sessMsg"></div>' + sessRecentHtml(recent) + sessSaveCardHtml(C) + + sessBackupHtml(C) + sessAdvancedHtml(C) + sessTableHtml(C) ); // Save current view. Enter in either the name or the description field saves. $('#sessSaveBtn').on('click', sessDoSave); $('#sessSaveName, #sessSaveDesc').on('keydown', function(ev) { if (ev.key === 'Enter') { ev.preventDefault(); sessDoSave(); } }); // One-click overwrite of the most recently saved session. if (recent) { $('#sessUpdateNow').on('click', function() { sessConfirm({ title: 'Overwrite session',