diff --git a/services/static-webserver/client/source/class/osparc/DownloadLinkTracker.js b/services/static-webserver/client/source/class/osparc/DownloadLinkTracker.js
index 27128e42ad0..af259e97a8c 100644
--- a/services/static-webserver/client/source/class/osparc/DownloadLinkTracker.js
+++ b/services/static-webserver/client/source/class/osparc/DownloadLinkTracker.js
@@ -33,9 +33,10 @@ qx.Class.define("osparc.DownloadLinkTracker", {
downloadAnchorNode.setAttribute("href", url);
downloadAnchorNode.setAttribute("download", fileName);
downloadAnchorNode.setAttribute("osparc", "downloadFile");
+ document.body.appendChild(downloadAnchorNode);
this.setDownloading(true);
downloadAnchorNode.click();
- downloadAnchorNode.remove();
+ document.body.removeChild(downloadAnchorNode);
// This is needed to make it work in Firefox
setTimeout(() => this.setDownloading(false), 100);
}
diff --git a/services/static-webserver/client/source/class/osparc/admin/AdminCenter.js b/services/static-webserver/client/source/class/osparc/admin/AdminCenter.js
index 36329e85b97..bd821027575 100644
--- a/services/static-webserver/client/source/class/osparc/admin/AdminCenter.js
+++ b/services/static-webserver/client/source/class/osparc/admin/AdminCenter.js
@@ -24,7 +24,7 @@ qx.Class.define("osparc.admin.AdminCenter", {
const miniProfile = osparc.desktop.account.MyAccount.createMiniProfileView().set({
paddingRight: 10
});
- this.addWidgetOnTopOfTheTabs(miniProfile);
+ this.addWidgetToTabs(miniProfile);
this.__addPricingPlansPage();
this.__addMaintenancePage();
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js
index 25db4f49019..610f40e5e23 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js
@@ -963,8 +963,8 @@ qx.Class.define("osparc.dashboard.CardBase", {
},
openData: function() {
- const moreOpts = this.__openMoreOptions();
- moreOpts.openData();
+ const resourceData = this.getResourceData();
+ osparc.widget.StudyDataManager.popUpInWindow(resourceData["uuid"]);
},
openBilling: function() {
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
index 1b629b88585..259782e213f 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
@@ -93,7 +93,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
__resourceData: null,
__resourceModel: null,
__infoPage: null,
- __dataPage: null,
__servicesUpdatePage: null,
__permissionsPage: null,
__tagsPage: null,
@@ -216,10 +215,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
this._openPage(this.__infoPage);
},
- openData: function() {
- this._openPage(this.__dataPage);
- },
-
openUpdateServices: function() {
this._openPage(this.__servicesUpdatePage);
},
@@ -306,7 +301,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
this.__getBillingPage,
this.__getServicesUpdatePage,
this.__getServicesBootOptionsPage,
- this.__getDataPage,
this.__getCommentsPage,
this.__getPermissionsPage,
this.__getSaveAsTemplatePage,
@@ -323,6 +317,28 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
}
});
+ const resourceData = this.__resourceData;
+ if (!osparc.utils.Resources.isService(resourceData)) {
+ const title = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + this.tr(" Files...");
+ const iconSrc = "@FontAwesome5Solid/file/22";
+ const dataAccess = new qx.ui.basic.Atom().set({
+ label: title,
+ icon: iconSrc,
+ font: "text-14",
+ padding: 8,
+ paddingLeft: 12,
+ gap: 14,
+ cursor: "pointer",
+ });
+ dataAccess.addListener("tap", () => osparc.widget.StudyDataManager.popUpInWindow(resourceData["uuid"]));
+ this.addWidgetToTabs(dataAccess);
+
+ if (resourceData["resourceType"] === "study") {
+ const canShowData = osparc.study.Utils.canShowStudyData(resourceData);
+ dataAccess.setEnabled(canShowData);
+ }
+ }
+
if (selectedTabId) {
const pageFound = tabsView.getChildren().find(page => page.tabId === selectedTabId);
if (pageFound) {
@@ -486,33 +502,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
return page;
},
- __getDataPage: function() {
- const resourceData = this.__resourceData;
- if (osparc.utils.Resources.isService(resourceData)) {
- return null;
- }
-
- const id = "Data";
- const title = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + this.tr(" Files");
- const iconSrc = "@FontAwesome5Solid/file/22";
- const page = this.__dataPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
- this.__addOpenButton(page);
-
- if (this.__resourceData["resourceType"] === "study") {
- const studyData = this.__resourceData;
- const canBeOpened = osparc.study.Utils.canShowStudyData(studyData);
- page.setEnabled(canBeOpened);
- }
-
- const lazyLoadContent = () => {
- const studyDataManager = new osparc.widget.NodeDataManager(resourceData["uuid"]);
- page.addToContent(studyDataManager);
- }
- page.addListenerOnce("appear", lazyLoadContent, this);
-
- return page;
- },
-
__getPermissionsPage: function() {
const id = "Permissions";
const title = this.tr("Sharing");
diff --git a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js
index 9d7f33e55e3..26fa16ddff6 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js
@@ -722,7 +722,7 @@ qx.Class.define("osparc.desktop.StudyEditor", {
this.__workbenchView.showPipeline();
} else {
const currentNodeId = this.getStudy().getUi().getCurrentNodeId();
- if (currentNodeId) {
+ if (currentNodeId && this.getStudy().getWorkbench().getNode(currentNodeId)) {
const node = this.getStudy().getWorkbench().getNode(currentNodeId);
if (node && node.isDynamic()) {
this.__workbenchView.fullscreenNode(currentNodeId);
diff --git a/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js b/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js
index f1999ebb99f..6763a66b7c6 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js
@@ -54,11 +54,8 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
});
},
- openNodeDataManager: function(node) {
- const nodeDataManager = new osparc.widget.NodeDataManager(null, node.getNodeId());
- const win = osparc.ui.window.Window.popUpInWindow(nodeDataManager, node.getLabel(), 900, 600).set({
- appearance: "service-window"
- });
+ openStudyDataManager: function(node) {
+ const win = osparc.widget.StudyDataManager.popUpInWindow(null, node.getNodeId(), node.getLabel());
const closeBtn = win.getChildControl("close-button");
osparc.utils.Utils.setIdToWidget(closeBtn, "nodeDataManagerCloseBtn");
}
@@ -1049,7 +1046,7 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
allowGrowY: false
});
osparc.utils.Utils.setIdToWidget(nodeFilesBtn, "nodeFilesBtn");
- nodeFilesBtn.addListener("execute", () => this.self().openNodeDataManager(node));
+ nodeFilesBtn.addListener("execute", () => this.self().openStudyDataManager(node));
outputsBox.add(nodeFilesBtn);
const outputs = new osparc.desktop.PanelView(this.tr("Outputs"), outputsBox);
diff --git a/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js b/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js
index 0df1dc1d8be..05d2c4d2bb0 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js
@@ -24,7 +24,7 @@ qx.Class.define("osparc.desktop.account.MyAccount", {
const miniProfile = osparc.desktop.account.MyAccount.createMiniProfileView().set({
paddingRight: 10
});
- this.addWidgetOnTopOfTheTabs(miniProfile);
+ this.addWidgetToTabs(miniProfile);
this.__profilePage = this.__addProfilePage();
diff --git a/services/static-webserver/client/source/class/osparc/desktop/credits/BillingCenter.js b/services/static-webserver/client/source/class/osparc/desktop/credits/BillingCenter.js
index d27acc99fe0..5eaf26b6947 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/credits/BillingCenter.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/credits/BillingCenter.js
@@ -24,7 +24,7 @@ qx.Class.define("osparc.desktop.credits.BillingCenter", {
const miniWallet = this.self().createMiniWalletView().set({
paddingRight: 10
});
- this.addWidgetOnTopOfTheTabs(miniWallet);
+ this.addWidgetToTabs(miniWallet);
this.__walletsPage = this.__addWalletsPage();
this.__paymentMethodsPage = this.__addPaymentMethodsPage();
diff --git a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js
index 43113f880e2..2e270c26709 100644
--- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js
+++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js
@@ -108,23 +108,11 @@ qx.Class.define("osparc.file.FileLabelWithActions", {
setItemSelected: function(selectedItem) {
if (selectedItem) {
+ this.__selection = [selectedItem];
const isFile = osparc.file.FilesTree.isFile(selectedItem);
this.getChildControl("download-button").setEnabled(isFile);
- this.getChildControl("delete-button").setEnabled(isFile);
- const selectedLabel = this.getChildControl("selected-label");
- if (isFile) {
- this.__selection = [selectedItem];
- selectedLabel.set({
- value: selectedItem.getLabel(),
- toolTipText: selectedItem.getFileId()
- });
- } else {
- this.__selection = [];
- selectedLabel.set({
- value: "",
- toolTipText: ""
- });
- }
+ this.getChildControl("delete-button").setEnabled(true); // folders can also be deleted
+ this.getChildControl("selected-label").setValue(selectedItem.getLabel());
} else {
this.resetSelection();
}
@@ -138,7 +126,7 @@ qx.Class.define("osparc.file.FileLabelWithActions", {
} else {
const selectedLabel = this.getChildControl("selected-label");
selectedLabel.set({
- value: multiSelectionData.length + " files"
+ value: multiSelectionData.length + " items"
});
}
} else {
@@ -168,60 +156,86 @@ qx.Class.define("osparc.file.FileLabelWithActions", {
}
},
+ __retrieveURLAndDownloadFile: function(file) {
+ const fileId = file.getFileId();
+ const locationId = file.getLocation();
+ osparc.utils.Utils.retrieveURLAndDownload(locationId, fileId)
+ .then(data => {
+ if (data) {
+ osparc.DownloadLinkTracker.getInstance().downloadLinkUnattended(data.link, data.fileName);
+ }
+ });
+ },
+
__deleteSelected: function() {
+ const toBeDeleted = [];
+ let isFolderSelected = false;
if (this.isMultiSelect()) {
- const requests = [];
this.__selection.forEach(selection => {
- if (selection && osparc.file.FilesTree.isFile(selection)) {
- const request = this.__deleteFile(selection);
- if (request) {
- requests.push(request);
+ if (selection) {
+ toBeDeleted.push(selection);
+ if (osparc.file.FilesTree.isDir(selection)) {
+ isFolderSelected = true;
}
}
});
- Promise.all(requests)
- .then(datas => {
- if (datas.length) {
- this.fireDataEvent("fileDeleted", datas[0]);
- osparc.FlashMessenger.getInstance().logAs(this.tr("Files successfully deleted"), "INFO");
- }
- });
- requests
} else if (this.__selection.length) {
const selection = this.__selection[0];
- if (selection && osparc.file.FilesTree.isFile(selection)) {
- const request = this.__deleteFile(selection);
- if (request) {
- request
- .then(data => {
- this.fireDataEvent("fileDeleted", data);
- osparc.FlashMessenger.getInstance().logAs(this.tr("File successfully deleted"), "INFO");
- });
+ if (selection) {
+ if (osparc.file.FilesTree.isDir(selection)) {
+ isFolderSelected = true;
}
}
}
+
+ let msg = this.tr("This operation cannot be undone.");
+ msg += isFolderSelected ? ("
"+this.tr("All the content of the folders will be deleted.")) : "";
+ msg += "
" + this.tr("Do you want to proceed?");
+ const confirmationWin = new osparc.ui.window.Confirmation(msg).set({
+ caption: this.tr("Delete"),
+ confirmText: this.tr("Delete"),
+ confirmAction: "delete"
+ });
+ confirmationWin.center();
+ confirmationWin.open();
+ confirmationWin.addListener("close", () => {
+ if (confirmationWin.getConfirmed()) {
+ this.__doDeleteSelected(toBeDeleted);
+ }
+ }, this);
},
- __retrieveURLAndDownloadFile: function(file) {
- const fileId = file.getFileId();
- const locationId = file.getLocation();
- osparc.utils.Utils.retrieveURLAndDownload(locationId, fileId)
- .then(data => {
- if (data) {
- osparc.DownloadLinkTracker.getInstance().downloadLinkUnattended(data.link, data.fileName);
+ __doDeleteSelected: function(toBeDeleted) {
+ const requests = [];
+ toBeDeleted.forEach(selection => {
+ if (selection) {
+ let request = null;
+ if (osparc.file.FilesTree.isFile(selection)) {
+ request = this.__deleteItem(selection.getFileId(), selection.getLocation());
+ } else {
+ request = this.__deleteItem(selection.getPath(), selection.getLocation());
+ }
+ if (request) {
+ requests.push(request);
+ }
+ }
+ });
+ Promise.all(requests)
+ .then(datas => {
+ if (datas.length) {
+ this.fireDataEvent("fileDeleted", datas[0]);
+ osparc.FlashMessenger.getInstance().logAs(this.tr("Items successfully deleted"), "INFO");
}
});
},
- __deleteFile: function(file) {
- const fileId = file.getFileId();
- const locationId = file.getLocation();
+ __deleteItem: function(itemId, locationId) {
if (locationId !== 0 && locationId !== "0") {
- osparc.FlashMessenger.getInstance().logAs(this.tr("Only files in simcore.s3 can be deleted"));
+ osparc.FlashMessenger.getInstance().logAs(this.tr("Only items in simcore.s3 can be deleted"));
return null;
}
const dataStore = osparc.store.Data.getInstance();
- return dataStore.deleteFile(locationId, fileId);
+ return dataStore.deleteFile(locationId, itemId);
},
}
});
diff --git a/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js b/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js
index 5e7a4a02236..5b96a32dc8f 100644
--- a/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js
+++ b/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js
@@ -79,7 +79,7 @@ qx.Class.define("osparc.file.FileTreeItem", {
itemId: {
check: "String",
event: "changeItemId",
- apply: "_applyItemId",
+ apply: "__applyItemId",
nullable: true
},
@@ -144,7 +144,6 @@ qx.Class.define("osparc.file.FileTreeItem", {
// Add lastModified
const lastModifiedWidget = new qx.ui.basic.Label().set({
- width: 140,
maxWidth: 140,
textAlign: "right"
});
@@ -162,7 +161,6 @@ qx.Class.define("osparc.file.FileTreeItem", {
// Add size
const sizeWidget = new qx.ui.basic.Label().set({
- width: 70,
maxWidth: 70,
textAlign: "right"
});
@@ -175,39 +173,13 @@ qx.Class.define("osparc.file.FileTreeItem", {
}
});
this.addWidget(sizeWidget);
-
-
- const permissions = osparc.data.Permissions.getInstance();
- // Add Path
- const pathWidget = new qx.ui.basic.Label().set({
- width: 300,
- maxWidth: 300,
- textAlign: "right"
- });
- this.bind("path", pathWidget, "value");
- this.addWidget(pathWidget);
- permissions.bind("role", pathWidget, "visibility", {
- converter: () => permissions.canDo("study.nodestree.uuid.read") ? "visible" : "excluded"
- });
-
- // Add NodeId
- const fileIdWidget = new qx.ui.basic.Label().set({
- width: 300,
- maxWidth: 300,
- textAlign: "right"
- });
- this.bind("fileId", fileIdWidget, "value");
- this.addWidget(fileIdWidget);
- permissions.bind("role", fileIdWidget, "visibility", {
- converter: () => permissions.canDo("study.nodestree.uuid.read") ? "visible" : "excluded"
- });
},
- // override
- _applyItemId: function(value, old) {
+ __applyItemId: function(value, old) {
osparc.utils.Utils.setIdToWidget(this, "fileTreeItem_" + value);
},
+ // override
_applyIcon: function(value, old) {
this.base(arguments, value, old);
const icon = this.getChildControl("icon", true);
diff --git a/services/static-webserver/client/source/class/osparc/file/FilesTree.js b/services/static-webserver/client/source/class/osparc/file/FilesTree.js
index a682bbca1c2..1d828881cae 100644
--- a/services/static-webserver/client/source/class/osparc/file/FilesTree.js
+++ b/services/static-webserver/client/source/class/osparc/file/FilesTree.js
@@ -163,6 +163,10 @@ qx.Class.define("osparc.file.FilesTree", {
}
studyModel = this.getModel();
this.__filesToDataset("0", studyId, files, studyModel);
+
+ // select study item
+ this.setSelection(new qx.data.Array([studyModel]));
+ this.__selectionChanged();
});
},
@@ -189,8 +193,8 @@ qx.Class.define("osparc.file.FilesTree", {
}
this.openNode(rootNodeModel);
- const selected = new qx.data.Array([rootNodeModel]);
- this.setSelection(selected);
+ // select node item
+ this.setSelection(new qx.data.Array([rootNodeModel]));
this.__selectionChanged();
} else {
rootModel.getChildren().removeAll();
diff --git a/services/static-webserver/client/source/class/osparc/file/FolderContent.js b/services/static-webserver/client/source/class/osparc/file/FolderContent.js
index badadbadcf2..bc6c680d926 100644
--- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js
+++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js
@@ -36,7 +36,7 @@ qx.Class.define("osparc.file.FolderContent", {
mode: {
check: ["list", "icons"],
- init: "icons",
+ init: "list",
nullable: false,
event: "changeMode",
apply: "__reloadFolderContent"
@@ -80,7 +80,7 @@ qx.Class.define("osparc.file.FolderContent", {
T_POS: {
TYPE: 0,
NAME: 1,
- DATE: 2,
+ MODIFIED_DATE: 2,
SIZE: 3,
ID: 4
}
@@ -105,9 +105,9 @@ qx.Class.define("osparc.file.FolderContent", {
});
control.getTableColumnModel().setDataCellRenderer(this.self().T_POS.TYPE, new qx.ui.table.cellrenderer.Image());
control.setColumnWidth(this.self().T_POS.TYPE, 30);
- control.setColumnWidth(this.self().T_POS.NAME, 360);
- control.setColumnWidth(this.self().T_POS.DATE, 170);
- control.setColumnWidth(this.self().T_POS.SIZE, 70);
+ control.setColumnWidth(this.self().T_POS.NAME, 250);
+ control.setColumnWidth(this.self().T_POS.MODIFIED_DATE, 125);
+ control.setColumnWidth(this.self().T_POS.SIZE, 80);
this.bind("mode", control, "visibility", {
converter: mode => mode === "list" ? "visible" : "excluded"
});
@@ -144,6 +144,8 @@ qx.Class.define("osparc.file.FolderContent", {
};
datas.push(data);
});
+ // folders first
+ datas.sort((a, b) => osparc.file.FilesTree.isFile(a.entry) - osparc.file.FilesTree.isFile(b.entry));
const items = [];
if (this.getMode() === "list") {
datas.forEach(data => {
@@ -278,14 +280,14 @@ qx.Class.define("osparc.file.FolderContent", {
}
if (this.isMultiSelect()) {
// pass all buttons that are selected
- const selectedFiles = [];
+ const selectedItems = [];
const iconsLayout = this.getChildControl("icons-layout");
iconsLayout.getChildren().forEach(btn => {
- if (osparc.file.FilesTree.isFile(btn.entry) && btn.getValue()) {
- selectedFiles.push(btn.entry);
+ if (btn.getValue() && "entry" in btn) {
+ selectedItems.push(btn.entry);
}
});
- this.__selectionChanged(selectedFiles);
+ this.__selectionChanged(selectedItems);
} else {
// unselect the other items
const iconsLayout = this.getChildControl("icons-layout");
@@ -309,23 +311,23 @@ qx.Class.define("osparc.file.FolderContent", {
if (e.getNativeEvent().ctrlKey) {
this.setMultiSelect(true);
}
- const selectedFiles = [];
+ const selectedItems = [];
const selectionRanges = table.getSelectionModel().getSelectedRanges();
selectionRanges.forEach(range => {
for (let i=range.minIndex; i<=range.maxIndex; i++) {
const row = table.getTableModel().getRowData(i);
- if (osparc.file.FilesTree.isFile(row.entry)) {
- selectedFiles.push(row.entry);
+ if (row && "entry" in row) {
+ selectedItems.push(row.entry);
}
}
});
- this.__selectionChanged(selectedFiles);
+ this.__selectionChanged(selectedItems);
}, this);
table.addListener("cellDbltap", e => {
const selectedRow = e.getRow();
- const rowData = table.getTableModel().getRowData(selectedRow);
- if ("entry" in rowData) {
- this.__itemDblTapped(rowData.entry);
+ const row = table.getTableModel().getRowData(selectedRow);
+ if (row && "entry" in row) {
+ this.__itemDblTapped(row.entry);
}
}, this);
}
diff --git a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js
index af2ca15fb79..914709dbcdd 100644
--- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js
+++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js
@@ -22,7 +22,7 @@
qx.Class.define("osparc.file.FolderViewer", {
extend: qx.ui.core.Widget,
- construct: function(allowMultiselection = true) {
+ construct: function(allowMultiSelection = true) {
this.base(arguments);
this._setLayout(new qx.ui.layout.VBox(10));
@@ -33,11 +33,11 @@ qx.Class.define("osparc.file.FolderViewer", {
folderUpBtn.addListener("execute", () => this.fireDataEvent("folderUp", this.getFolder()), this);
this.getChildControl("folder-path");
let multiSelectButton = null;
- if (allowMultiselection) {
+ if (allowMultiSelection) {
multiSelectButton = this.getChildControl("multi-select-button");
}
- const gridViewButton = this.getChildControl("view-options-icons");
const listViewButton = this.getChildControl("view-options-list");
+ const gridViewButton = this.getChildControl("view-options-icons");
const folderContent = this.getChildControl("folder-content");
const selectedFileLayout = this.getChildControl("selected-file-layout");
@@ -51,7 +51,7 @@ qx.Class.define("osparc.file.FolderViewer", {
this.bind("folder", folderContent, "folder");
- if (allowMultiselection) {
+ if (allowMultiSelection) {
multiSelectButton.bind("value", folderContent, "multiSelect");
folderContent.bind("multiSelect", multiSelectButton, "value");
multiSelectButton.addListener("changeValue", e => {
@@ -142,12 +142,13 @@ qx.Class.define("osparc.file.FolderViewer", {
header.addAt(control, 2);
break;
}
- case "view-options-rgroup":
+ case "view-options-radio-group":
control = new qx.ui.form.RadioGroup();
break;
case "view-options-icons": {
control = new qx.ui.form.ToggleButton(null, "@MaterialIcons/apps/18");
- const group = this.getChildControl("view-options-rgroup");
+ osparc.utils.Utils.setIdToWidget(control, "folderGridView");
+ const group = this.getChildControl("view-options-radio-group");
group.add(control);
const header = this.getChildControl("header");
header.addAt(control, 3);
@@ -155,7 +156,7 @@ qx.Class.define("osparc.file.FolderViewer", {
}
case "view-options-list": {
control = new qx.ui.form.ToggleButton(null, "@MaterialIcons/reorder/18");
- const group = this.getChildControl("view-options-rgroup");
+ const group = this.getChildControl("view-options-radio-group");
group.add(control);
const header = this.getChildControl("header");
header.addAt(control, 4);
diff --git a/services/static-webserver/client/source/class/osparc/info/StudyLarge.js b/services/static-webserver/client/source/class/osparc/info/StudyLarge.js
index 6512e4a459d..719b8f582df 100644
--- a/services/static-webserver/client/source/class/osparc/info/StudyLarge.js
+++ b/services/static-webserver/client/source/class/osparc/info/StudyLarge.js
@@ -62,19 +62,9 @@ qx.Class.define("osparc.info.StudyLarge", {
const vBox = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
- const mainHBox = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
-
- const leftVBox = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
- mainHBox.add(leftVBox, {
- flex: 1
- });
-
- vBox.add(mainHBox);
-
- const extraInfo = this.__extraInfo();
- const extraInfoLayout = this.__createExtraInfo(extraInfo);
-
- leftVBox.add(extraInfoLayout);
+ const infoElements = this.__infoElements();
+ const infoLayout = osparc.info.StudyUtils.infoElementsToLayout(infoElements);
+ vBox.add(infoLayout);
let text = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + " Id";
if (this.__isTemplate) {
@@ -87,7 +77,7 @@ qx.Class.define("osparc.info.StudyLarge", {
allowGrowX: false
});
copyIdButton.addListener("execute", () => osparc.utils.Utils.copyTextToClipboard(this.getStudy().getUuid()));
- leftVBox.add(copyIdButton);
+ vBox.add(copyIdButton);
const scrollContainer = new qx.ui.container.Scroll();
scrollContainer.add(vBox);
@@ -97,8 +87,8 @@ qx.Class.define("osparc.info.StudyLarge", {
});
},
- __extraInfo: function() {
- const extraInfo = {
+ __infoElements: function() {
+ const infoLayout = {
"TITLE": {
label: this.tr("Title:"),
view: osparc.info.StudyUtils.createTitle(this.getStudy()),
@@ -166,7 +156,7 @@ qx.Class.define("osparc.info.StudyLarge", {
this.getStudy().getQuality() &&
osparc.metadata.Quality.isEnabled(this.getStudy().getQuality())
) {
- extraInfo["QUALITY"] = {
+ infoLayout["QUALITY"] = {
label: this.tr("Quality:"),
view: osparc.info.StudyUtils.createQuality(this.getStudy()),
action: {
@@ -178,7 +168,7 @@ qx.Class.define("osparc.info.StudyLarge", {
}
if (osparc.product.Utils.showClassifiers()) {
- extraInfo["CLASSIFIERS"] = {
+ infoLayout["CLASSIFIERS"] = {
label: this.tr("Classifiers:"),
view: osparc.info.StudyUtils.createClassifiers(this.getStudy()),
action: (this.getStudy().getClassifiers().length || this.__canIWrite()) ? {
@@ -192,18 +182,14 @@ qx.Class.define("osparc.info.StudyLarge", {
if (!this.__isTemplate) {
const pathLabel = new qx.ui.basic.Label();
pathLabel.setValue(this.getStudy().getLocationString());
- extraInfo["LOCATION"] = {
+ infoLayout["LOCATION"] = {
label: this.tr("Location:"),
view: pathLabel,
action: null
};
}
- return extraInfo;
- },
-
- __createExtraInfo: function(extraInfo) {
- return osparc.info.StudyUtils.createExtraInfoGrid(extraInfo);
+ return infoLayout;
},
__createStudyId: function() {
diff --git a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js
index 81d4feda078..9d2ef3bf7bc 100644
--- a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js
+++ b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js
@@ -252,7 +252,7 @@ qx.Class.define("osparc.info.StudyUtils", {
return titleLayout;
},
- createExtraInfoGrid: function(extraInfos) {
+ infoElementsToLayout: function(extraInfos) {
const positions = {
TITLE: {
column: 0,
@@ -308,18 +308,15 @@ qx.Class.define("osparc.info.StudyUtils", {
},
};
- const grid = new qx.ui.layout.Grid(15, 5);
+ const grid1 = new qx.ui.layout.Grid(15, 5);
+ grid1.setColumnAlign(0, "left", "top");
+ grid1.setColumnFlex(0, 1);
+ const mainInfoLayout = new qx.ui.container.Composite(grid1);
+
const grid2 = new qx.ui.layout.Grid(15, 5);
- grid.setColumnAlign(0, "left", "top");
- const container = new qx.ui.container.Composite(new qx.ui.layout.VBox());
- const moreInfo = new qx.ui.container.Composite(grid);
- const otherInfo = new qx.ui.container.Composite(grid2);
- grid.setColumnFlex(0, 1);
+ const extraInfoLayout = new qx.ui.container.Composite(grid2);
grid2.setColumnFlex(0, 1);
- const box = this.__createSectionBox(qx.locale.Manager.tr("Details"));
- const box2 = this.__createSectionBox(qx.locale.Manager.tr("Meta details"));
-
let row = 0;
let row2 = 0;
Object.keys(positions).forEach(key => {
@@ -335,7 +332,7 @@ qx.Class.define("osparc.info.StudyUtils", {
});
}
titleLayout.add(extraInfo.view);
- otherInfo.add(titleLayout, {
+ extraInfoLayout.add(titleLayout, {
row: row2,
column: gridInfo.column
});
@@ -344,25 +341,30 @@ qx.Class.define("osparc.info.StudyUtils", {
row2++;
} else {
const titleLayout = this.__titleWithEditLayout(extraInfo);
- moreInfo.add(titleLayout, {
+ mainInfoLayout.add(titleLayout, {
row,
column: gridInfo.column
});
row++;
- moreInfo.add(extraInfo.view, {
+ mainInfoLayout.add(extraInfo.view, {
row,
column: gridInfo.column
});
row++;
- grid.setRowHeight(row, 5); // spacer
+ grid1.setRowHeight(row, 5); // spacer
row++;
}
}
});
- box.add(moreInfo);
- box2.add(otherInfo);
- container.addAt(box, 0);
+
+ const container = new qx.ui.container.Composite(new qx.ui.layout.VBox());
+ const box1 = this.__createSectionBox(qx.locale.Manager.tr("Details"));
+ box1.add(mainInfoLayout);
+ container.addAt(box1, 0);
+
+ const box2 = this.__createSectionBox(qx.locale.Manager.tr("Meta details"));
+ box2.add(extraInfoLayout);
container.addAt(box2, 1);
return container;
diff --git a/services/static-webserver/client/source/class/osparc/po/POCenter.js b/services/static-webserver/client/source/class/osparc/po/POCenter.js
index 6141d5ffaf2..25c3fa01acd 100644
--- a/services/static-webserver/client/source/class/osparc/po/POCenter.js
+++ b/services/static-webserver/client/source/class/osparc/po/POCenter.js
@@ -24,7 +24,7 @@ qx.Class.define("osparc.po.POCenter", {
const miniProfile = osparc.desktop.account.MyAccount.createMiniProfileView().set({
paddingRight: 10
});
- this.addWidgetOnTopOfTheTabs(miniProfile);
+ this.addWidgetToTabs(miniProfile);
this.__addUsersPage();
this.__addPreRegistrationPage();
diff --git a/services/static-webserver/client/source/class/osparc/store/Data.js b/services/static-webserver/client/source/class/osparc/store/Data.js
index 322dc1313bd..d592f78ea67 100644
--- a/services/static-webserver/client/source/class/osparc/store/Data.js
+++ b/services/static-webserver/client/source/class/osparc/store/Data.js
@@ -283,6 +283,7 @@ qx.Class.define("osparc.store.Data", {
return true;
},
+ // if folder path is provided as fileUuid, it can also be deleted
deleteFile: function(locationId, fileUuid) {
if (!osparc.data.Permissions.getInstance().canDo("study.node.data.delete", true)) {
return null;
diff --git a/services/static-webserver/client/source/class/osparc/study/Utils.js b/services/static-webserver/client/source/class/osparc/study/Utils.js
index 54ec6fce3e4..60b7667b22a 100644
--- a/services/static-webserver/client/source/class/osparc/study/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/study/Utils.js
@@ -330,7 +330,7 @@ qx.Class.define("osparc.study.Utils", {
canShowStudyData: function(studyData) {
const blocked = this.__getBlockedState(studyData);
- return [false].includes(blocked);
+ return ["UNKNOWN_SERVICES", false].includes(blocked);
},
canShowPreview: function(studyData) {
diff --git a/services/static-webserver/client/source/class/osparc/tester/TesterCenter.js b/services/static-webserver/client/source/class/osparc/tester/TesterCenter.js
index 023fafb4dc5..547bd4ae3d2 100644
--- a/services/static-webserver/client/source/class/osparc/tester/TesterCenter.js
+++ b/services/static-webserver/client/source/class/osparc/tester/TesterCenter.js
@@ -24,7 +24,7 @@ qx.Class.define("osparc.tester.TesterCenter", {
const miniProfile = osparc.desktop.account.MyAccount.createMiniProfileView().set({
paddingRight: 10
});
- this.addWidgetOnTopOfTheTabs(miniProfile);
+ this.addWidgetToTabs(miniProfile);
this.__addSocketMessagesPage();
this.__addConsoleErrorsPage();
diff --git a/services/static-webserver/client/source/class/osparc/theme/ColorDark.js b/services/static-webserver/client/source/class/osparc/theme/ColorDark.js
index 64a3784c276..47b42050a36 100644
--- a/services/static-webserver/client/source/class/osparc/theme/ColorDark.js
+++ b/services/static-webserver/client/source/class/osparc/theme/ColorDark.js
@@ -122,28 +122,6 @@ qx.Theme.define("osparc.theme.ColorDark", {
"tooltip": "flash_message_bg",
"tooltip-text": "text",
- // table
- "table-header": "background-main",
- "table-header-foreground": "c09",
- "table-header-border": "c07",
- "table-focus-indicator": "background-main-5",
-
- // used in table code
- "table-header-cell": "background-main",
- "table-row-background-even": "background-main",
- "table-row-background-odd": "background-main",
- "table-row-background-focused": "background-main-1",
- "table-row-background-focused-selected": "background-main-2",
- "table-row-background-selected": "background-main-2",
-
- // foreground
- "table-row-selected": "c12",
- "table-row": "c09",
-
- // table grid color
- "table-row-line": "background-main",
- "table-column-line": "background-main",
-
// used in progressive code
"progressive-table-header": "c08",
"progressive-table-row-background-even": "background-main",
diff --git a/services/static-webserver/client/source/class/osparc/theme/ColorLight.js b/services/static-webserver/client/source/class/osparc/theme/ColorLight.js
index 6b798200e18..629e75ccef5 100644
--- a/services/static-webserver/client/source/class/osparc/theme/ColorLight.js
+++ b/services/static-webserver/client/source/class/osparc/theme/ColorLight.js
@@ -124,28 +124,6 @@ qx.Theme.define("osparc.theme.ColorLight", {
"tooltip-text": "text",
- // table
- "table-header": "background-main",
- "table-header-foreground": "c09",
- "table-header-border": "c07",
- "table-focus-indicator": "background-main-5",
-
- // used in table code
- "table-header-cell": "background-main",
- "table-row-background-even": "background-main",
- "table-row-background-odd": "background-main",
- "table-row-background-focused": "background-main-1",
- "table-row-background-focused-selected": "background-main-2",
- "table-row-background-selected": "background-main-2",
-
- // foreground
- "table-row-selected": "c12",
- "table-row": "c09",
-
- // table grid color
- "table-row-line": "background-main",
- "table-column-line": "background-main",
-
// used in progressive code
"progressive-table-header": "c08",
"progressive-table-row-background-even": "background-main",
diff --git a/services/static-webserver/client/source/class/osparc/theme/mixin/Color.js b/services/static-webserver/client/source/class/osparc/theme/mixin/Color.js
index 95883e8284f..f1224d1fe82 100644
--- a/services/static-webserver/client/source/class/osparc/theme/mixin/Color.js
+++ b/services/static-webserver/client/source/class/osparc/theme/mixin/Color.js
@@ -54,6 +54,29 @@ qx.Theme.define("osparc.theme.mixin.Color", {
"logger-warning-message": "warning-yellow",
"logger-error-message": "failed-red",
- "workbench-edge-selected": "busy-orange"
+ "workbench-edge-selected": "busy-orange",
+
+
+ // table
+ "table-header": "transparent",
+ "table-header-foreground": "text", // text color
+ "table-header-border": "text", // header underline
+ "table-header-cell": "transparent",
+
+ // used in table code
+ "table-focus-indicator": "transparent",
+ "table-row-background-even": "transparent",
+ "table-row-background-odd": "transparent",
+ "table-row-background-focused": "transparent",
+ "table-row-background-focused-selected": "background-main-2",
+ "table-row-background-selected": "background-main-2",
+
+ // foreground
+ "table-row-selected": "text",
+ "table-row": "text",
+
+ // table grid color
+ "table-row-line": "transparent",
+ "table-column-line": "transparent",
}
});
diff --git a/services/static-webserver/client/source/class/osparc/ui/window/TabbedView.js b/services/static-webserver/client/source/class/osparc/ui/window/TabbedView.js
index e3c75167676..6706b152f92 100644
--- a/services/static-webserver/client/source/class/osparc/ui/window/TabbedView.js
+++ b/services/static-webserver/client/source/class/osparc/ui/window/TabbedView.js
@@ -79,7 +79,7 @@ qx.Class.define("osparc.ui.window.TabbedView", {
return control || this.base(arguments, id);
},
- addWidgetOnTopOfTheTabs: function(widget) {
+ addWidgetToTabs: function(widget) {
this.getChildControl("tabs-view").getChildControl("bar").add(widget);
},
diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js
index 451a86083a1..edad4b3a2d7 100644
--- a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js
+++ b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js
@@ -25,7 +25,7 @@ qx.Class.define("osparc.vipMarket.Market", {
paddingRight: 10,
minWidth: 150,
});
- this.addWidgetOnTopOfTheTabs(miniWallet);
+ this.addWidgetToTabs(miniWallet);
const store = osparc.store.Store.getInstance();
const contextWallet = store.getContextWallet();
diff --git a/services/static-webserver/client/source/class/osparc/widget/ProgressSequence.js b/services/static-webserver/client/source/class/osparc/widget/ProgressSequence.js
index d9c3e257d81..09cadba98af 100644
--- a/services/static-webserver/client/source/class/osparc/widget/ProgressSequence.js
+++ b/services/static-webserver/client/source/class/osparc/widget/ProgressSequence.js
@@ -25,7 +25,8 @@ qx.Class.define("osparc.widget.ProgressSequence", {
this.set({
backgroundColor: "window-popup-background",
- paddingBottom: 8
+ paddingBottom: 8,
+ minWidth: 400,
});
this.__initLayout(title);
diff --git a/services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js b/services/static-webserver/client/source/class/osparc/widget/StudyDataManager.js
similarity index 86%
rename from services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js
rename to services/static-webserver/client/source/class/osparc/widget/StudyDataManager.js
index 397477d1d94..2626265b0cf 100644
--- a/services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js
+++ b/services/static-webserver/client/source/class/osparc/widget/StudyDataManager.js
@@ -25,12 +25,12 @@
* Here is a little example of how to use the widget.
*
*
- * let dataManager = new osparc.widget.NodeDataManager(null, nodeId); + * let dataManager = new osparc.widget.StudyDataManager(null, nodeId); * this.getRoot().add(dataManager); **/ -qx.Class.define("osparc.widget.NodeDataManager", { +qx.Class.define("osparc.widget.StudyDataManager", { extend: qx.ui.core.Widget, /** @@ -58,6 +58,16 @@ qx.Class.define("osparc.widget.NodeDataManager", { this.__reloadTree(); }, + statics: { + popUpInWindow: function(studyId, nodeId, title) { + const studyDataManager = new osparc.widget.StudyDataManager(studyId, nodeId); + if (!title) { + title = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + qx.locale.Manager.tr(" Files"); + } + return osparc.ui.window.Window.popUpInWindow(studyDataManager, title, osparc.dashboard.ResourceDetails.WIDTH, osparc.dashboard.ResourceDetails.HEIGHT); + }, + }, + properties: { studyId: { check: "String", diff --git a/tests/e2e-playwright/tests/sleepers/test_sleepers.py b/tests/e2e-playwright/tests/sleepers/test_sleepers.py index 4415fcf3e49..0940b37609d 100644 --- a/tests/e2e-playwright/tests/sleepers/test_sleepers.py +++ b/tests/e2e-playwright/tests/sleepers/test_sleepers.py @@ -67,6 +67,7 @@ def _get_expected_file_names_for_version(version: Version) -> list[str]: ) def _get_file_names(page: Page) -> list[str]: file_names_found = [] + page.get_by_test_id("folderGridView").click() for file in page.get_by_test_id("FolderViewerItem").all(): file_name = file.text_content() assert file_name diff --git a/tests/e2e/tutorials/tutorialBase.js b/tests/e2e/tutorials/tutorialBase.js index 6899d3bcb26..76c7edcb3de 100644 --- a/tests/e2e/tutorials/tutorialBase.js +++ b/tests/e2e/tutorials/tutorialBase.js @@ -484,6 +484,7 @@ class TutorialBase { async __checkNItemsInFolder(fileNames, openOutputsFolder = false) { await this.takeScreenshot("checkNodeOutputs_before"); + await this.waitAndClick("folderGridView"); console.log("N items in folder. Expected:", fileNames); if (openOutputsFolder) { const itemTexts = await this.__page.$$eval('[osparc-test-id="FolderViewerItem"]', @@ -506,8 +507,7 @@ class TutorialBase { } if (outputsFound) { await this.takeScreenshot("outputs_folder"); - } - else { + } else { throw ("outputs folder not found"); } } diff --git a/tests/e2e/utils/auto.js b/tests/e2e/utils/auto.js index 4e999201736..9af239e3ad9 100644 --- a/tests/e2e/utils/auto.js +++ b/tests/e2e/utils/auto.js @@ -363,6 +363,7 @@ async function openNodeFilesAppMode(page) { async function checkDataProducedByNode(page, nFiles = 1) { console.log("checking Data produced by Node. Expecting", nFiles, "file(s)"); + await utils.waitAndClick(page, '[osparc-test-id="folderGridView"]'); const iconsContent = await page.waitForSelector('[osparc-test-id="FolderViewerIconsContent"]', { timeout: 5000 });