7545a188d43c6e1ea33f692b0d833ec96a7f76c5
chmalee
  Wed Aug 14 09:21:15 2024 -0700
refactor some methods into userdata.c for writing hub.txt files. Finish trackHubWizard.c back end for writing hub.txt and clean up the html. Start of adding a modal dialog for creating hub.txt

diff --git src/hg/js/hgMyData.js src/hg/js/hgMyData.js
index 23d174b..e015aeb 100644
--- src/hg/js/hgMyData.js
+++ src/hg/js/hgMyData.js
@@ -421,32 +421,68 @@
         }
     }
 
     function addNewUploadedFileToTable(req) {
         // req is an object with properties of an uploaded file, make a new row
         // for it in the filesTable
         let table = null;
         if ($.fn.dataTable.isDataTable("#filesTable")) {
             table = $("#filesTable").DataTable();
             let newRow = table.row.add(req).draw();
         } else {
             showExistingFiles([req]);
         }
     }
 
+    function createHubSuccess(jqXhr, textStatus) {
+        console.log(jqXhr);
+        $("#newTrackHubDialog").dialog("close");
+    }
+
+    function createHub(db, hubName) {
+        // send a request to hgHubConnect to create a hub for this user
+        cart.setCgi("hgHubConnect");
+        cart.send({createHub: {db: db, name: hubName}}, createHubSuccess, null);
+        cart.flush();
+    }
+
+    function startHubCreate() {
+        // put up a dialog to walk a user through setting up a track hub
+        console.log("create a hub button clicked!");
+        $("#newTrackHubDialog").dialog({
+            minWidth: $("#newTrackHubDialog").width(),
+        });
+        // attach the event handler to save this hub to this users hubspace
+        let saveBtn = document.getElementById("doNewCollection");
+        saveBtn.addEventListener("click", (e) => {
+            let db = document.getElementById("db").value;
+            let hubName = document.getElementById("hubName").value;
+            // TODO: add a spinner while we wait for the request to complete
+            createHub(db, hubName);
+        });
+        $("#newTrackHubDialog").dialog("open");
+    }
+
     let tableInitOptions = {
-        //columnDefs: [{orderable: false, targets: [0,1]}],
+        layout: {
+            topStart: {
+                buttons: [
+                    {text: 'Create hub',
+                     action: startHubCreate},
+                ]
+            }
+        },
         columnDefs: [
             {
                 orderable: false, targets: 0,
                 title: "<input type=\"checkbox\"></input>",
                 render: function(data, type, row) {
                     return "<input type=\"checkbox\"></input>";
                 }
             },
             {
                 orderable: false, targets: 1,
                 data: "action", title: "Action",
                 render: function(data, type, row) {
                     // click to call hgHubDelete file
                     return "<button class='deleteFileBtn'>Delete</button><button class='viewInBtn'>View In GB</button>";
                 }
@@ -480,32 +516,38 @@
                 });
             }
             btns = document.querySelectorAll('.viewInBtn');
             for (i = 0; i < numRows; i++) {
                 let fname = table.cell(i, 2).data();
                 let genome = table.cell(i, 5).data();
                 btns[i].addEventListener("click", (e) => {
                     viewInGenomeBrowser(fname, genome);
                 });
             }
         },
     };
 
     function showExistingFiles(d) {
         // Make the DataTable for each file
+        // make buttons have the same style as other buttons
+        $.fn.dataTable.Buttons.defaults.dom.button.className = 'button';
         tableInitOptions.data = d;
-        $("#filesTable").DataTable(tableInitOptions);
+        let table = new DataTable("#filesTable", tableInitOptions);
+        let toRemove = document.getElementById("welcomeDiv");
+        if (d.length > 0 && toRemove !== null) {
+            toRemove.remove();
+        }
     }
 
     function checkJsonData(jsonData, callerName) {
         // Return true if jsonData isn't empty and doesn't contain an error;
         // otherwise complain on behalf of caller.
         if (! jsonData) {
             alert(callerName + ': empty response from server');
         } else if (jsonData.error) {
             console.error(jsonData.error);
             alert(callerName + ': error from server: ' + jsonData.error);
         } else if (jsonData.warning) {
             alert("Warning: " + jsonData.warning);
             return true;
         } else {
             if (debugCartJson) {
@@ -561,51 +603,55 @@
             if (debugCartJson) {
                 console.log('from server:\n', cartJson);
             }
             _.assign(uiState,cartJson);
             saveHistory(cartJson, urlParts, true);
         } else {
             // no cartJson object means we are coming to the page for the first time:
             //cart.send({ getUiState: {} }, handleRefreshState);
             //cart.flush();
             // TODO: initialize buttons, check if there are already files
             // TODO: write functions for
             //     after picking files
             //     choosing file types
             //     creating default trackDbs
             //     editing trackDbs
-            // TODO: make hgHubConnect respond to requests
-            // TODO: initialize tus-client
-            // TODO: get user name
-            // TODO: send a request with username
-            // TODO: have tusd respond on server
-            let uploadSection = document.getElementById("chosenFilesSection");
-            if (uploadSection.style.display === "none") {
-                uploadSection.style.display = "";
-            }
+            let welcomeDiv = document.createElement("div");
+            welcomeDiv.id = "welcomeDiv";
+            welcomeDiv.textContent = "Once files are uploaded they will display here. Click \"Choose files\" above or \"Create Hub\" below to get started";
+            let fileDiv = document.getElementById('filesDiv');
+            fileDiv.insertBefore(welcomeDiv, fileDiv.firstChild);
             if (typeof userFiles !== 'undefined' && typeof userFiles.fileList !== 'undefined' &&
                     userFiles.fileList.length > 0) { 
                 uiState.fileList= userFiles.fileList;
                 uiState.userUrl = userFiles.userUrl;
-                showExistingFiles(uiState.fileList);
             }
+            showExistingFiles(uiState.fileList);
             inputBtn.addEventListener("click", (e) => uiState.input.click());
             //uiState.input.addEventListener("change", listPickedFiles);
             // TODO: add event handler for when file is succesful upload
             // TODO: add event handlers for editing defaults, grouping into hub
             // TODO: display quota somewhere
             // TODO: customize the li to remove the picked file
         }
+        $("#newTrackHubDialog").dialog({
+            modal: true,
+            autoOpen: false,
+            title: "Create new track hub",
+            closeOnEscape: true,
+            minWidth: 400,
+            minHeight: 120
+        });
     }
     return { init: init,
              uiState: uiState,
            };
 
 }());
 
 
 // when a user reaches this page from the back button we can display our saved state
 // instead of sending another network request
 window.onpopstate = function(event) {
     event.preventDefault();
     hubCreate.updateStateAndPage(event.state, false);
 };