@@ -14,17 +14,6 @@ See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
1616
17- // Top navigation shared with the Go template (see web.go webNavItems).
18- var NAV_ITEMS = [
19- { to : "/status" , title : "Status" } ,
20- { to : "/daily" , title : "Daily" } ,
21- { to : "/compare" , title : "Compare" } ,
22- { to : "/fk" , title : "Foreign Keys" } ,
23- { to : "/pr" , title : "PR" } ,
24- { to : "/history" , title : "History" } ,
25- { to : "/" , title : "Home" } ,
26- ] ;
27-
2817// setTheme applies and persists the light/dark/system theme. "system" clears the
2918// stored preference and follows the OS setting.
3019function setTheme ( mode ) {
@@ -39,29 +28,96 @@ function setTheme(mode) {
3928 }
4029}
4130
31+ // toggleTheme flips between dark and light based on the current document state,
32+ // mirroring the React ModeToggle. The Sun/Moon icons animate via CSS
33+ // transition-transform when the `dark` class on <html> changes.
34+ function toggleTheme ( ) {
35+ var isDark = document . documentElement . classList . contains ( "dark" ) ;
36+ setTheme ( isDark ? "light" : "dark" ) ;
37+ }
38+
4239// commandPalette is the Alpine.js data factory for the Cmd/Ctrl+K palette.
40+ // commandPalette backs the header "Search a commit…" box (Cmd/Ctrl+K), mirroring
41+ // the React CommandMenu: typing a commit SHA / git ref and pressing Enter jumps
42+ // to the History page filtered by that ref (/history?gitRef=…).
4343function commandPalette ( ) {
4444 return {
4545 open : false ,
4646 query : "" ,
47- items : NAV_ITEMS ,
4847 show ( ) {
4948 this . open = true ;
5049 this . query = "" ;
5150 this . $nextTick ( ( ) => {
5251 if ( this . $refs . search ) this . $refs . search . focus ( ) ;
5352 } ) ;
5453 } ,
55- filtered ( ) {
54+ enter ( ) {
55+ var q = this . query . trim ( ) ;
56+ if ( ! q ) return ;
57+ window . location . href = "/history?gitRef=" + encodeURIComponent ( q ) ;
58+ } ,
59+ } ;
60+ }
61+
62+ // compareForm backs the Compare page's Old/New ref pickers. Each field is a
63+ // button that opens a shared command-palette dialog listing the vitess refs
64+ // (grouped into Branches/Releases), mirroring the React VitessRefsCommand. The
65+ // ref list and initial values are read from data-* attributes on the <form>;
66+ // the chosen names feed hidden inputs that the form submits (server resolves
67+ // names -> SHAs). Typing in the dialog and pressing Enter commits the raw text,
68+ // so a pasted commit SHA works too.
69+ function compareForm ( ) {
70+ return {
71+ refs : [ ] ,
72+ oldVal : "" ,
73+ newVal : "" ,
74+ open : false , // false | "old" | "new"
75+ query : "" ,
76+ init ( ) {
77+ try {
78+ this . refs = JSON . parse ( this . $el . dataset . refs || "[]" ) ;
79+ } catch ( e ) {
80+ this . refs = [ ] ;
81+ }
82+ this . oldVal = this . $el . dataset . old || "" ;
83+ this . newVal = this . $el . dataset . new || "" ;
84+ } ,
85+ show ( field ) {
86+ this . open = field ;
87+ this . query = "" ;
88+ this . $nextTick (
89+ function ( ) {
90+ if ( this . $refs . search ) this . $refs . search . focus ( ) ;
91+ } . bind ( this )
92+ ) ;
93+ } ,
94+ matches ( kind ) {
5695 var q = this . query . trim ( ) . toLowerCase ( ) ;
57- if ( ! q ) return this . items ;
58- return this . items . filter ( function ( i ) {
59- return i . title . toLowerCase ( ) . includes ( q ) || i . to . toLowerCase ( ) . includes ( q ) ;
96+ return this . refs . filter ( function ( r ) {
97+ return r . kind === kind && ( ! q || r . name . toLowerCase ( ) . indexOf ( q ) !== - 1 ) ;
6098 } ) ;
6199 } ,
100+ branches ( ) {
101+ return this . matches ( "branch" ) ;
102+ } ,
103+ releases ( ) {
104+ return this . matches ( "release" ) ;
105+ } ,
106+ commit ( value ) {
107+ if ( this . open === "new" ) this . newVal = value ;
108+ else this . oldVal = value ;
109+ this . open = false ;
110+ } ,
111+ select ( name ) {
112+ this . commit ( name ) ;
113+ } ,
62114 enter ( ) {
63- var f = this . filtered ( ) ;
64- if ( f . length ) window . location . href = f [ 0 ] . to ;
115+ var q = this . query . trim ( ) ;
116+ if ( ! q ) {
117+ this . open = false ;
118+ return ;
119+ }
120+ this . commit ( q ) ;
65121 } ,
66122 } ;
67123}
@@ -220,18 +276,15 @@ function copyCompareMarkdown(btn) {
220276 if ( ! ta ) return ;
221277 navigator . clipboard . writeText ( ta . value ) . then ( function ( ) {
222278 var label = btn . querySelector ( "[data-copy-label]" ) ;
223- var icon = btn . querySelector ( "i" ) ;
279+ var copyIcon = btn . querySelector ( "[data-copy-icon]" ) ;
280+ var checkIcon = btn . querySelector ( "[data-check-icon]" ) ;
224281 if ( label ) label . textContent = "Copied!" ;
225- if ( icon ) {
226- icon . classList . remove ( "fa-copy" ) ;
227- icon . classList . add ( "fa-check" ) ;
228- }
282+ if ( copyIcon ) copyIcon . classList . add ( "hidden" ) ;
283+ if ( checkIcon ) checkIcon . classList . remove ( "hidden" ) ;
229284 setTimeout ( function ( ) {
230285 if ( label ) label . textContent = "Copy as markdown" ;
231- if ( icon ) {
232- icon . classList . remove ( "fa-check" ) ;
233- icon . classList . add ( "fa-copy" ) ;
234- }
286+ if ( copyIcon ) copyIcon . classList . remove ( "hidden" ) ;
287+ if ( checkIcon ) checkIcon . classList . add ( "hidden" ) ;
235288 } , 2000 ) ;
236289 } ) ;
237290}
@@ -446,6 +499,12 @@ function tooltip() {
446499// global "Compare Versions" widget (see partials/compare_widget.html). It tracks
447500// a translate offset updated on mouse drag; the widget's visibility and the
448501// old/new refs themselves live in the global $store.compare.
502+ // compareWidget backs the draggable "Compare Versions" card (see
503+ // partials/compare_widget.html), mirroring the React CompareActionsWrapper. The
504+ // staged old/new refs live in the $store.compare; this component owns the drag
505+ // state and the shared ref-picker dialog (open/query) used by the Old/New
506+ // fields. Interactive controls carry the .cancel-drag class so a click on them
507+ // does not start a drag.
449508function compareWidget ( ) {
450509 return {
451510 dragging : false ,
@@ -455,7 +514,11 @@ function compareWidget() {
455514 oy : 0 ,
456515 sx : 0 ,
457516 sy : 0 ,
517+ open : false , // false | "old" | "new"
518+ query : "" ,
458519 startDrag ( e ) {
520+ if ( e . target . closest && e . target . closest ( ".cancel-drag" ) ) return ;
521+ if ( e . preventDefault ) e . preventDefault ( ) ;
459522 this . dragging = true ;
460523 this . sx = e . clientX ;
461524 this . sy = e . clientY ;
@@ -473,14 +536,53 @@ function compareWidget() {
473536 style ( ) {
474537 return "transform: translate(" + this . x + "px," + this . y + "px)" ;
475538 } ,
539+ showPicker ( field ) {
540+ if ( ! this . $store . compare . visible ) return ;
541+ this . $store . compare . loadRefs ( ) ;
542+ this . open = field ;
543+ this . query = "" ;
544+ this . $nextTick (
545+ function ( ) {
546+ if ( this . $refs . search ) this . $refs . search . focus ( ) ;
547+ } . bind ( this )
548+ ) ;
549+ } ,
550+ matches ( kind ) {
551+ var q = this . query . trim ( ) . toLowerCase ( ) ;
552+ return ( this . $store . compare . refs || [ ] ) . filter ( function ( r ) {
553+ return r . kind === kind && ( ! q || r . name . toLowerCase ( ) . indexOf ( q ) !== - 1 ) ;
554+ } ) ;
555+ } ,
556+ branches ( ) {
557+ return this . matches ( "branch" ) ;
558+ } ,
559+ releases ( ) {
560+ return this . matches ( "release" ) ;
561+ } ,
562+ commit ( value ) {
563+ if ( this . open === "new" ) this . $store . compare . new = value ;
564+ else this . $store . compare . old = value ;
565+ this . open = false ;
566+ } ,
567+ select ( name ) {
568+ this . commit ( name ) ;
569+ } ,
570+ enter ( ) {
571+ var q = this . query . trim ( ) ;
572+ if ( ! q ) {
573+ this . open = false ;
574+ return ;
575+ }
576+ this . commit ( q ) ;
577+ } ,
476578 } ;
477579}
478580
479581// The global compare store backs the cross-page "Compare Versions" widget,
480- // mirroring the React CompareContext. Row actions on the History ( and, later,
481- // Status) tables call addOld/addNew to stage commits; go() navigates to the
482- // /compare page. Vitess ref names are fetched lazily from the JSON API to
483- // populate the input datalist , failing silently if unavailable.
582+ // mirroring the React CompareContext. Row actions on the History and Status
583+ // tables call addOld/addNew to stage commits; go() navigates to the /compare
584+ // page. Vitess refs ({name, kind}) are fetched lazily from the JSON API to feed
585+ // the widget's ref pickers , failing silently if unavailable.
484586document . addEventListener ( "alpine:init" , function ( ) {
485587 Alpine . store ( "compare" , {
486588 old : "" ,
@@ -523,10 +625,10 @@ document.addEventListener("alpine:init", function () {
523625 if ( ! d ) return ;
524626 var out = [ ] ;
525627 ( d . branches || [ ] ) . forEach ( function ( b ) {
526- if ( b && b . name ) out . push ( b . name ) ;
628+ if ( b && b . name ) out . push ( { name : b . name , kind : "branch" } ) ;
527629 } ) ;
528630 ( d . tags || [ ] ) . forEach ( function ( t ) {
529- if ( t && t . name ) out . push ( t . name ) ;
631+ if ( t && t . name ) out . push ( { name : t . name , kind : "release" } ) ;
530632 } ) ;
531633 self . refs = out ;
532634 } )
0 commit comments