e2002b80518d8b522ac768713cda4126cf3b5dc0 chmalee Thu Mar 20 12:21:10 2025 -0700 Make wording changes to hubSpace UI. Make checkbox selection not recursive, fix bug in deselect all rows checkbox, refs #31058 diff --git src/hg/js/hgMyData.js src/hg/js/hgMyData.js index aed680bbca2..d94658e4b84 100644 --- src/hg/js/hgMyData.js +++ src/hg/js/hgMyData.js @@ -304,67 +304,85 @@ let cartData = {deleteFile: {fileList: []}}; cart.setCgi("hgHubConnect"); _.forEach(data, (d) => { cartData.deleteFile.fileList.push({ fileName: d.fileName, fileType: d.fileType, parentDir: d.parentDir, genome: d.genome, fullPath: d.fullPath, }); }); cart.send(cartData, deleteFileSuccess); cart.flush(); } - function updateSelectedFileDiv(data) { + function updateSelectedFileDiv(data, isFolderSelect = false) { // update the div that shows how many files are selected let numSelected = data !== null ? Object.entries(data).length : 0; let infoDiv = document.getElementById("selectedFileInfo"); let span = document.getElementById("numberSelectedFiles"); let spanParentDiv = span.parentElement; - span.textContent = `${numSelected} ${numSelected > 1 ? "files" : "file"}`; if (numSelected > 0) { + if (isFolderSelect || span.textContent.endsWith("hub") || span.textContent.endsWith("hubs")) { + span.textContent = `${numSelected} ${numSelected > 1 ? "hubs" : "hub"}`; + } else { + span.textContent = `${numSelected} ${numSelected > 1 ? "files" : "file"}`; + } // (re) set up the handlers for the selected file info div: let viewBtn = document.getElementById("viewSelectedFiles"); - selectedData = data; viewBtn.addEventListener("click", viewAllInGenomeBrowser); - viewBtn.textContent = numSelected === 1 ? "View selected file in Genome Browser" : "View all selected files in Genome Browser"; + viewBtn.textContent = "View selected"; let deleteBtn = document.getElementById("deleteSelectedFiles"); deleteBtn.addEventListener("click", deleteFileList); - deleteBtn.textContent = numSelected === 1 ? "Delete selected file" : "Delete selected files"; + deleteBtn.textContent = "Delete selected"; + } else { + span.textContent = ""; } // set the visibility of the placeholder text and info text spanParentDiv.style.display = numSelected === 0 ? "none": "block"; let placeholder = document.getElementById("placeHolderInfo"); placeholder.style.display = numSelected === 0 ? "block" : "none"; } - function handleCheckboxSelect(evtype, table, row) { + function handleCheckboxSelect(evtype, table, selectedRow) { // depending on the state of the checkbox, we will be adding information - // to the div, or removing information. We will also be potentially checking/unchecking - // all of the checkboxes if the selectAll box was clicked. The data variable - // will hold all the information we want to keep visible in the info div - let data = {}; + // to the div, or removing information. We also potentially checked/unchecked + // all of the checkboxes if the selectAll box was clicked. If isFolderSelect + // is true, then in the info div, display that a hub was selected and not just + // a file(s) + + // The data variable will hold all the information we want to keep visible in the info div + let data = []; + // The selectedData global holds the actual information needed for the view/delete buttons + // to work, so data plus any child rows + selectedData = {}; // get all of the currently selected rows (may be more than just the one that // was most recently clicked) table.rows({selected: true}).data().each(function(row, ix) { - data[ix] = row; + data.push(row); + selectedData[row.fullPath] = row; + // add any newly checked rows children to the selectedData structure for the view/delete + if (row.children) { + row.children.forEach(function(child) { + selectedData[child.fullPath] = child; + }); + } }); - updateSelectedFileDiv(data); + updateSelectedFileDiv(data, selectedRow.data().fileType === "dir"); } function createOneCrumb(table, dirName, dirFullPath, doAddEvent) { // make a new span that can be clicked to nav through the table let newSpan = document.createElement("span"); newSpan.id = dirName; newSpan.textContent = decodeURIComponent(dirName); newSpan.classList.add("breadcrumb"); if (doAddEvent) { newSpan.addEventListener("click", function(e) { dataTableShowDir(table, dirName, dirFullPath); table.draw(); dataTableCustomOrder(table, {"fullPath": dirFullPath}); table.draw(); }); @@ -646,43 +664,31 @@ // show all the new rows we just added, note the double draw, we need // to have the new rows rendered to do the order because the order // will copy the actual DOM node parseFileListIntoHash(uiState.fileList); dataTableShowDir(table, hubDirData.fileName, hubDirData.fullPath); table.draw(); dataTableCustomOrder(table, hubDirData); table.draw(); } function doRowSelect(evtype, table, indexes) { let selectedRow = table.row(indexes); let rowTr = selectedRow.node(); if (rowTr) { - let rowCheckbox = rowTr.childNodes[0].firstChild; - let rowChildren = uiState.filesHash[selectedRow.data().fullPath].children; - // we need to manually check the children - if (rowChildren) { - for (let child of rowChildren) { - if (evtype === "select") { - table.row((idx,data) => data.fullPath === child.fullPath).select(); - } else { - table.row((idx,data) => data.fullPath === child.fullPath).deselect(); - } - } - } - handleCheckboxSelect(evtype, table, rowTr); + handleCheckboxSelect(evtype, table, selectedRow); } } function indentActionButton(rowTr, rowData) { let numIndents = "0px"; //data.parentDir !== "" ? data.fullPath.split('/').length - 1: 0; if (rowData.fileType !== "dir") { numIndents = "10px"; } rowTr.childNodes[1].style.textIndent = numIndents; } let tableInitOptions = { select: { items: 'row', selector: 'td:first-child', @@ -843,31 +849,33 @@ document.getElementById("rootBreadcrumb").addEventListener("click", function(e) { dataTableShowTopLevel(table); dataTableCustomOrder(table); dataTableEmptyBreadcrumb(table); table.draw(); }); } else { table.buttons(".uploadButton").disable(); } table.on("select", function(e, dt, type, indexes) { indexes.forEach(function(i) { doRowSelect(e.type, dt, i); }); }); table.on("deselect", function(e, dt, type, indexes) { - doRowSelect(e.type, dt, indexes); + indexes.forEach(function(i) { + doRowSelect(e.type, dt, i); + }); }); table.on("click", function(e) { if (e.target.className !== "dt-select-checkbox") { e.stopPropagation(); // we've clicked somewhere not on the checkbox itself, we need to: // 1. open the directory if the clicked row is a directory // 2. select the file if the clicked row is a regular file let row = table.row(e.target); let data = row.data(); if (data.children && data.children.length > 0) { dataTableShowDir(table, data.fileName, data.fullPath); dataTableCustomOrder(table, {"fullPath": data.fullPath}); table.draw(); } else { if (row.selected()) {