524d04aa83224bad2d1dcda060506694c858db0f
chmalee
  Thu Nov 14 16:22:50 2024 -0800
Style the batch change selectors better, add a batch change hub name input

diff --git src/hg/js/hgMyData.js src/hg/js/hgMyData.js
index 9c6ccb4..61d16a5 100644
--- src/hg/js/hgMyData.js
+++ src/hg/js/hgMyData.js
@@ -1,33 +1,34 @@
 /* jshint esnext: true */
 var debugCartJson = true;
 var hubNameDefault = "MyFirstHub";
 
 function prettyFileSize(num) {
     if (!num) {return "n/a";}
     if (num < (1000 * 1024)) {
-        return `${(num/1000).toFixed(1)}kb`;
+        return `${(num/1000).toFixed(1)}KB`;
     } else if (num < (1000 * 1000 * 1024)) {
-        return `${((num/1000)/1000).toFixed(1)}mb`;
+        return `${((num/1000)/1000).toFixed(1)}MB`;
     } else {
-        return `${(((num/1000)/1000)/1000).toFixed(1)}gb`;
+        return `${(((num/1000)/1000)/1000).toFixed(1)}GB`;
     }
 }
 
 // make our Uppy instance:
 const uppy = new Uppy.Uppy({
     debug: true,
+    allowMultipleUploadBatches: false,
     onBeforeUpload: (files) => {
         // set all the fileTypes and genomes from their selects
         let doUpload = true;
         for (let [key, file] of Object.entries(files)) {
             if (!file.meta.genome) {
                 uppy.info(`Error: No genome selected for file ${file.name}!`, 'error', 2000);
                 doUpload = false;
                 continue;
             } else if  (!file.meta.fileType) {
                 uppy.info(`Error: File type not supported, please rename file: ${file.name}!`, 'error', 2000);
                 doUpload = false;
                 continue;
             }
             uppy.setFileMeta(file.id, {
                 fileName: file.name,
@@ -900,59 +901,113 @@
                     */
                 }
             }
 
             removeBatchSelectsFromDashboard() {
                 let batchSelectDiv = document.getElementById("batch-selector-div");
                 if (batchSelectDiv) {
                     batchSelectDiv.remove();
                 }
             }
 
             addBatchSelectsToDashboard() {
                 if (!document.getElementById("batch-selector-div")) {
                     let batchSelectDiv = document.createElement("div");
                     batchSelectDiv.id = "batch-selector-div";
-                    let batchDbSelect = document.createElement("select");
-                    //let batchTypeSelect = document.createElement("select");
-                    this.createOptsForSelect(batchDbSelect, makeGenomeSelectOptions());
-                    //this.createOptsForSelect(batchTypeSelect, makeTypeSelectOptions());
-                    batchSelectDiv.textContent = "Change options for all files";
-                    batchSelectDiv.appendChild(batchDbSelect);
-                    //batchSelectDiv.appendChild(batchTypeSelect);
-                    batchSelectDiv.style.display = "flex";
-                    batchSelectDiv.style.justifyContent = "center";
+                    batchSelectDiv.style.display = "grid";
+                    batchSelectDiv.style.width = "80%";
+                    // the grid syntax is 2 columns, 3 rows
+                    batchSelectDiv.style.gridTemplateColumns = "50% 50%";
+                    batchSelectDiv.style.gridTemplateRows = "25px 25px 25px";
+                    batchSelectDiv.style.margin = "10px auto"; // centers this div
                     if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
                         batchSelectDiv.style.color = "#eaeaea";
                     }
+
+                    // first just explanatory text:
+                    let batchSelectText = document.createElement("div");
+                    batchSelectText.textContent = "Change options for all files:";
+                    // syntax here is rowStart / columnStart / rowEnd / columnEnd
+                    batchSelectText.style.gridArea = "1 / 1 / 1 / 2";
+
+                    // the batch change db select
+                    let batchDbSelect = document.createElement("select");
+                    this.createOptsForSelect(batchDbSelect, makeGenomeSelectOptions());
+                    batchDbSelect.id = "batchDbSelect";
+                    batchDbSelect.style.gridArea = "2 / 2 / 2 / 2";
+                    batchDbSelect.style.margin = "1px 1px auto";
+                    let batchDbLabel = document.createElement("label");
+                    batchDbLabel.textContent = "Genome";
+                    batchDbLabel.for = "batchDbSelect";
+                    batchDbLabel.style.gridArea = "2 / 1 / 2 / 1";
+
+                    // the batch change hub name
+                    let batchParentDirInput = document.createElement("input");
+                    batchParentDirInput.id = "batchParentDir";
+                    batchParentDirInput.value = hubNameDefault;
+                    batchParentDirInput.style.gridArea = "3 / 2 / 3 / 2";
+                    batchParentDirInput.style.margin= "1px 1px auto";
+                    let batchParentDirLabel = document.createElement("label");
+                    batchParentDirLabel.textContent = "Hub Name";
+                    batchParentDirLabel.for = "batchParentDir";
+                    batchParentDirLabel.style.gridArea = "3 / 1 / 3 / 1";
+
+                    // add event handlers to change metadata, use an arrow function
+                    // because otherwise 'this' keyword will be the element instead of
+                    // our class
+                    batchDbSelect.addEventListener("change", (ev) => {
+                        let files = this.uppy.getFiles();
+                        let val = ev.target.value;
+                        for (let [key, file] of Object.entries(files)) {
+                            this.uppy.setFileMeta(file.id, {genome: val});
+                        }
+                    });
+                    batchParentDirInput.addEventListener("change", (ev) => {
+                        let files = this.uppy.getFiles();
+                        let val = ev.target.value;
+                        for (let [key, file] of Object.entries(files)) {
+                            this.uppy.setFileMeta(file.id, {parentDir: val});
+                        }
+                    });
+
+                    batchSelectDiv.appendChild(batchSelectText);
+                    batchSelectDiv.appendChild(batchDbLabel);
+                    batchSelectDiv.appendChild(batchDbSelect);
+                    batchSelectDiv.appendChild(batchParentDirLabel);
+                    batchSelectDiv.appendChild(batchParentDirInput);
+
                     // append the batch changes to the bottom of the file list, for some reason
                     // I can't append to the actual Dashboard-files, it must be getting emptied
                     // and re-rendered or something
                     let uppyFilesDiv = document.querySelector(".uppy-Dashboard-progressindicators");
                     if (uppyFilesDiv) {
                         uppyFilesDiv.insertBefore(batchSelectDiv, uppyFilesDiv.firstChild);
                     }
                 }
             }
 
             install() {
                 this.uppy.on("file-added", (file) => {
                     // add default meta data for genome and fileType
                     console.log("file-added");
                     this.uppy.setFileMeta(file.id, {"genome": defaultDb(), "fileType": defaultFileType(file.name), "parentDir": hubNameDefault});
                     if (this.uppy.getFiles().length > 1) {
                         this.addBatchSelectsToDashboard();
+                    } else {
+                        // only open the file editor when there is one file
+                        const dash = uppy.getPlugin("Dashboard");
+                        dash.toggleFileCard(true, file.id);
                     }
                 });
                 this.uppy.on("file-removed", (file) => {
                     // remove the batch change selects if now <2 files present
                     if (this.uppy.getFiles().length < 2) {
                         this.removeBatchSelectsFromDashboard();
                     }
                 });
 
                 this.uppy.on("dashboard:modal-open", () => {
                     // check if there were already files chosen from before:
                     if (this.uppy.getFiles().length > 2) {
                         this.addBatchSelectsToDashboard();
                     }
                     if (this.uppy.getFiles().length < 2) {
@@ -987,78 +1042,68 @@
                             value: value,
                             onChange: e => {
                                 onChange(e.target.value);
                                 file.meta.fileType = detectFileType(e.target.value);
                             },
                             required: required,
                             form: form,
                             }
                         );
                     },
                 },
                 {
                     id: 'genome',
                     name: 'Genome',
                     render: ({value, onChange}, h) => {
-                        return h('select',
-                            {onChange: e => onChange(e.target.value)}, 
-                            makeGenomeSelectOptions().map( (genomeObj) => {
-                                return h('option', genomeObj, genomeObj.label);
-                            })
-                        );
-                    },
-                },
-                /*
-                fields.push({
-                    id: 'fileType',
-                    name: 'File Type',
-                    render: ({value, onChange}, h) => {
-                        return h( 'select',
-                            {onChange: e => {
-                                if (e.target.value === "Auto-detect from extension") {
-                                    onChange(detectFileType(file.name));
-                                } else {
+                        return h('select', {
+                            onChange: e => {
                                 onChange(e.target.value);
+                                file.meta.genome = e.target.value;
                             }
-                            }},
-                            makeTypeSelectOptions().map( (typeObj) => {
-                                return h('option', typeObj, typeObj.label);
+                            },
+                            makeGenomeSelectOptions().map( (genomeObj) => {
+                                return h('option', {
+                                    value: genomeObj.value,
+                                    label: genomeObj.label,
+                                    selected: file.meta.genome !== null ? genomeObj.value === file.meta.genome : genomeObj.value === defaultDb()
+                                });
                             })
                         );
                     },
-                });
-                */
+                },
                 {
                     id: 'parentDir',
                     name: 'Hub Name',
                     render: ({value, onChange, required, form}, h) => {
                         return h('input',
                             {type: 'text',
+                             value: value,
+                             onChange: e => {
+                                onChange(e.target.value);
+                             },
                              required: required,
                              form: form,
-                             value: hubNameDefault,
                             }
                         );
                     },
                 }];
                 return fields;
             },
             restricted: {requiredMetaFields: ["genome"]},
             closeModalOnClickOutside: true,
             closeAfterFinish: true,
             theme: 'auto',
-            autoOpen: "metaEditor",
         };
         let tusOptions = {
             endpoint: getTusdEndpoint(),
             withCredentials: true,
             retryDelays: null,
         };
         uppy.use(Uppy.Dashboard, uppyOptions);
         uppy.use(Uppy.Tus, tusOptions);
         uppy.use(BatchChangePlugin, {target: Uppy.Dashboard});
         uppy.on('upload-success', (file, response) => {
             const metadata = file.meta;
             const d = new Date(metadata.lastModified);
             newReqObj = {
                 "uploadTime": Date.now(),
                 "lastModified": d.toJSON(),