9f8d33c8b2b6bc61f6d02d781c4e02836f7099f9 max Fri Aug 21 02:05:42 2026 -0700 hgSession: new opt-in JavaScript "My Sessions" page; share gbModern.css with hgBlat. refs #38157 Applies the hgBlat facelift strategy (#37996) to hgSession: an opt-in, client-rendered "My Sessions" page gated by the sessionNewPage / sessionNewPageBanner hg.conf flags (mirroring blatNewForm / blatNewFormBanner), with a banner linking between the classic and new pages so neither is a one-way door. sessionNewPage also flips the site default. hgSession.c stays the data/action backend: it emits the session list and page config as an inline JSON global (hgSessionData) into an empty #sessionApp container, and the new hgSession.js builds the UI - a save-current-view card (name + optional description + "only I can load it"; empty name saves under a random share_ name), a "most recently saved session" one-click Update, a searchable/sortable/paged DataTable of sessions (assembly + position, created with last-used on hover, views, a lock icon on private sessions), inline Share (copy link / email / gallery), Edit (rename + description + private), Overwrite and Delete, and a bulk Select -> Delete-all-selected mode. The mutating actions POST to new JSON endpoints (hgS_doDeleteJson / doShareJson / doGalleryJson / doOverwriteJson / doDescribeJson) that run the same SQL as the classic full-page handlers and return JSON, so the table updates in place; loads, file up/downloads and custom-track backup stay as ordinary form submits/links. The Advanced panel keeps feature parity with the classic page (load another user's session, load from URL/file, save to file, back up custom tracks, reset), minus the login/ change-password links that now live in the top menu. Shared UCSC house-style components (design tokens, .gbPill, .gbCard, .gbStrip, .gbSection, .gbShareBox, .gbBanner, the .gbModal* dialog and a .gbTable) are factored into a new gbModern.css. hgBlat is migrated onto it: its generic .blat* classes are renamed to the shared .gb* names in hgBlat.css / hgBlat.js and the #blatResults / #blatFormBox containers get class="gbApp"; verified pixel-clean against the previous search form and results pages, including the rename modal. hgSession.css holds only session-specific layout. diff --git src/hg/utils/hgConfCatalog/hgConfCatalog.py src/hg/utils/hgConfCatalog/hgConfCatalog.py index dbb2f248d11..8c6543a9ca5 100755 --- src/hg/utils/hgConfCatalog/hgConfCatalog.py +++ src/hg/utils/hgConfCatalog/hgConfCatalog.py @@ -414,30 +414,48 @@ "the cart. It comes out once the new form replaces the old " "one, which is what makes it a gate rather than a knob."), h("blatNewFormBanner", "flag", "hg/hgBlat/hgBlat.c:825", default="follows blatNewForm", role="gate", verified=True, ticket="37893", note="Whether the classic BLAT search form carries a banner offering " "the new one. Defaults to whatever blatNewForm is set to: " "where the new form is enabled, a user who took its go-back " "link needs a way to return, and where it is disabled there is " "nothing to advertise. Set explicitly to override either way. " "The default is that nested read rather than a literal, so the " "sunset report cannot tell from the tree whether this one has " "shipped; it ships and goes away with blatNewForm. Sibling of " "blatNewPageBanner, which does the same job for the results " "page."), + h("sessionNewPage", "flag", "hg/hgSession/hgSession.c", default="FALSE", + role="gate", ticket="37996", + note="Replaces hgSession's classic C-generated 'My Sessions' page with " + "the JavaScript-built one in hg/js/hgSession.js (a save bar plus a " + "searchable, sortable session table with inline share/rename/" + "overwrite/delete). Off while the new page is being tested. Read " + "through cartUsualBoolean, so this is only the default: the page's " + "banner offers a per-user opt-in/opt-out that sets sessionNewPage " + "in the cart. Sibling of blatNewForm; comes out once the new page " + "replaces the old one."), + h("sessionNewPageBanner", "flag", "hg/hgSession/hgSession.c", + default="follows sessionNewPage", role="gate", ticket="37996", + note="Whether the classic and new Sessions pages carry the banner that " + "links to the other one. Defaults to whatever sessionNewPage is " + "set to: where the new page is enabled a user who took its go-back " + "link needs a way to return, and where it is disabled there is " + "nothing to advertise. Set explicitly to override either way. " + "Sibling of blatNewFormBanner."), h("quickLiftClipToChains", "flag", "hg/lib/quickLift.c:231", default="TRUE", role="gate", verified=True, ticket="38042", note="Whether an item too big for the chains quickLift loaded is " "pulled in to what they cover rather than dropped. Read once, " "in quickLiftIntervalsToBedClip, which is the display path; " "the details page calls quickLiftIntervalsToBed and always " "sees the item's true extent. Born TRUE, so it never gated a " "release: like alwaysItemRgb, the off position is the way the " "browser behaved before the change rather than anything about " "the machine, so it is a gate and should go once nobody has " "asked for the old behaviour."), ], }