0db69910b2561b37d888bdff69895117eea55175
chmalee
Thu Apr 23 12:00:09 2026 -0700
Make file names in hubSpace links to view/download the files. Add a copy icon next to each file that copies the url for easy linking to hub.txts, refs Max/Baihe email
diff --git src/hg/js/hgMyData.js src/hg/js/hgMyData.js
index d08d91f1d34..d7fae2f2bcc 100644
--- src/hg/js/hgMyData.js
+++ src/hg/js/hgMyData.js
@@ -1585,31 +1585,40 @@
render: DataTable.render.select(),
},
{
orderable: false, targets: 1,
data: "action", title: "",
render: function(data, type, row) {
if (type === "display") {
return dataTablePrintAction(row);
}
return '';
}
},
{
targets: 2,
render: function(data, type, row, meta) {
- return decodeURIComponent(data);
+ let decodedName = decodeURIComponent(data);
+ if (type !== "display" || row.fileType === "dir") {
+ return decodedName;
+ }
+ if (typeof uiState.userUrl === "undefined" || uiState.userUrl.length === 0) {
+ return decodedName;
+ }
+ let fileUrl = uiState.userUrl + cgiEncode(row.fullPath);
+ let copyIcon = '';
+ return '' + decodedName + '' + copyIcon;
}
},
{
targets: 3,
render: function(data, type, row, meta) {
if (type === "display") {
return dataTablePrintSize(data, type, row, meta);
}
return data;
}
},
{
targets: 5,
render: function(data, type, row) {
if (type === "display") {
@@ -1717,30 +1726,56 @@
});
} 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) {
indexes.forEach(function(i) {
doRowSelect(e.type, dt, i);
});
});
table.on("click", function(e) {
+ let copyIcon = e.target.closest ? e.target.closest(".copyLinkIcon") : null;
+ if (copyIcon) {
+ e.stopPropagation();
+ e.preventDefault();
+ let url = copyIcon.getAttribute("data-url");
+ navigator.clipboard.writeText(url).then(function() {
+ let feedback = document.createElement("span");
+ feedback.textContent = "copied";
+ feedback.style.marginLeft = "6px";
+ feedback.style.fontSize = "0.85em";
+ feedback.style.color = "#080";
+ copyIcon.parentNode.replaceChild(feedback, copyIcon);
+ setTimeout(function() {
+ if (feedback.parentNode) {
+ feedback.parentNode.replaceChild(copyIcon, feedback);
+ }
+ }, 1500);
+ }, function() {
+ alert("Failed to copy URL: " + url);
+ });
+ return;
+ }
+ if (e.target.closest && e.target.closest(".fileLink")) {
+ e.stopPropagation();
+ return;
+ }
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()) {
row.deselect();
doRowSelect("deselect", table, row.index());