From 1222d6d69a7589ec42b97a46b9e6cc886dd4d652 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 3 Dec 2024 14:50:59 +0100 Subject: [PATCH 01/28] refactor --- .../source/class/osparc/file/FolderContent.js | 256 ++++++++++++++++++ .../source/class/osparc/file/FolderViewer.js | 232 +--------------- 2 files changed, 270 insertions(+), 218 deletions(-) create mode 100644 services/static-webserver/client/source/class/osparc/file/FolderContent.js diff --git a/services/static-webserver/client/source/class/osparc/file/FolderContent.js b/services/static-webserver/client/source/class/osparc/file/FolderContent.js new file mode 100644 index 00000000000..4330672866f --- /dev/null +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -0,0 +1,256 @@ +/* ************************************************************************ + + osparc - the simcore frontend + + https://osparc.io + + Copyright: + 2024 IT'IS Foundation, https://itis.swiss + + License: + MIT: https://opensource.org/licenses/MIT + + Authors: + * Odei Maiz (odeimaiz) + +************************************************************************ */ + +qx.Class.define("osparc.file.FolderContent", { + extend: qx.ui.container.Stack, + + construct: function() { + this.base(arguments); + + this.getChildControl("icons-layout"); + this.getChildControl("table"); + }, + + properties: { + folder: { + check: "qx.core.Object", + init: null, + nullable: true, + event: "changeFolder", + apply: "__applyFolder" + }, + + mode: { + check: ["list", "icons"], + init: "icons", + nullable: false, + event: "changeMode", + apply: "__reloadFolderContent" + }, + }, + + events: { + "selectionChanged": "qx.event.type.Data", // tap + "itemSelected": "qx.event.type.Data", // dbltap + "requestDatasetFiles": "qx.event.type.Data", + }, + + statics: { + getItemButton: function() { + const item = new qx.ui.form.ToggleButton().set({ + iconPosition: "top", + width: 100, + height: 80, + padding: 3 + }); + item.getChildControl("label").set({ + rich: true, + textAlign: "center", + maxWidth: 100, + maxHeight: 31 + }); + osparc.utils.Utils.setIdToWidget(item, "FolderViewerItem"); + return item; + }, + + T_POS: { + TYPE: 0, + NAME: 1, + DATE: 2, + SIZE: 3, + ID: 4 + } + }, + + members: { + _createChildControlImpl: function(id) { + let control; + switch (id) { + case "table": { + const tableModel = new qx.ui.table.model.Simple(); + tableModel.setColumns([ + "", + this.tr("Name"), + this.tr("Date Modified"), + this.tr("Size"), + this.tr("Id") + ]); + control = new osparc.ui.table.Table(tableModel, { + // tableColumnModel: obj => new qx.ui.table.columnmodel.Resize(obj), + initiallyHiddenColumns: [this.self().T_POS.ID] + }); + 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); + this.bind("mode", control, "visibility", { + converter: mode => mode === "list" ? "visible" : "excluded" + }); + const scroll = new qx.ui.container.Scroll(); + scroll.add(control); + this.add(scroll); + break; + } + case "icons-layout": { + control = new qx.ui.container.Composite(new qx.ui.layout.Flow(5, 5)); + osparc.utils.Utils.setIdToWidget(control, "FolderViewerIconsContent"); + this.bind("mode", control, "visibility", { + converter: mode => mode === "icons" ? "visible" : "excluded" + }); + const scroll = new qx.ui.container.Scroll(); + scroll.add(control); + this.add(scroll); + break; + } + } + return control || this.base(arguments, id); + }, + + __convertEntries: function(content) { + const items = []; + if (this.getMode() === "list") { + content.forEach(entry => { + const row = []; + row.push(entry.getIcon ? entry.getIcon() : this.__getIcon(entry)); + row.push(entry.getLabel()); + row.push(entry.getLastModified ? osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())) : ""); + row.push(entry.getSize ? osparc.utils.Utils.bytesToSize(entry.getSize()) : ""); + if (entry.getItemId) { + row.push(entry.getItemId()); + } + row.entry = entry; + items.push(row); + }); + } else if (this.getMode() === "icons") { + content.forEach(entry => { + let tt = entry.getLabel(); + if (entry.getSize) { + tt += "
" + osparc.utils.Utils.bytesToSize(entry.getSize()); + } + if (entry.getLastModified) { + tt += "
" + osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())); + } + const item = this.self().getItemButton().set({ + label: entry.getLabel(), + icon: entry.getIcon ? entry.getIcon() : this.__getIcon(entry), + toolTipText: tt + }); + const icon = item.getChildControl("icon", true); + if (icon.getSource() === "@FontAwesome5Solid/circle-notch/12") { + icon.setPadding(0); + icon.setMarginRight(4); + icon.getContentElement().addClass("rotate"); + } + + if (entry.getItemId) { + item.itemId = entry.getItemId(); + this.__attachListenersToItems(item, entry); + } + items.push(item); + }); + } + return items; + }, + + __getIcon: function(entry) { + return osparc.file.FilesTree.isDir(entry) ? "@MaterialIcons/folder" : "@MaterialIcons/insert_drive_file"; + }, + + __getEntries: function() { + if (this.getFolder()) { + const children = this.getFolder().getChildren().toArray(); + return this.__convertEntries(children); + } + return []; + }, + + __applyFolder: function(folder) { + if (folder) { + if (folder.getLoaded && !folder.getLoaded()) { + this.fireDataEvent("requestDatasetFiles", { + locationId: folder.getLocation(), + datasetId: folder.getPath() + }); + } + + folder.getChildren().addListener("change", () => { + this.__reloadFolderContent(); + }, this); + } + + this.__reloadFolderContent(); + }, + + __reloadFolderContent: function() { + const entries = this.__getEntries(); + if (this.getMode() === "list") { + const table = this.getChildControl("table"); + table.setData(entries); + this.__attachListenersTotable(table); + } else if (this.getMode() === "icons") { + const iconsLayout = this.getChildControl("icons-layout"); + iconsLayout.removeAll(); + const iconsGroup = new qx.ui.form.RadioGroup().set({ + allowEmptySelection: true + }); + entries.forEach(entry => { + iconsGroup.add(entry); + iconsLayout.add(entry); + }); + } + this.setSelection([this.getSelectables()[this.getMode() === "icons" ? 0 : 1]]); + }, + + __itemTapped: function(item) { + this.fireDataEvent("selectionChanged", item); + }, + + __itemDblTapped: function(item) { + this.fireDataEvent("itemSelected", item); + if (osparc.file.FilesTree.isDir(item)) { + this.setFolder(item); + } + }, + + __attachListenersToItems: function(btn, entry) { + btn.addListener("tap", () => { + this.__itemTapped(entry); + }, this); + btn.addListener("dbltap", () => { + this.__itemDblTapped(entry); + }, this); + }, + + __attachListenersTotable: function(table) { + table.addListener("cellTap", e => { + const selectedRow = e.getRow(); + const rowData = table.getTableModel().getRowData(selectedRow); + if ("entry" in rowData) { + this.__itemTapped(rowData.entry); + } + }, this); + table.addListener("cellDbltap", e => { + const selectedRow = e.getRow(); + const rowData = table.getTableModel().getRowData(selectedRow); + if ("entry" in rowData) { + this.__itemDblTapped(rowData.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 26fb4433bf3..f326823c3b6 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -32,10 +32,9 @@ qx.Class.define("osparc.file.FolderViewer", { const folderUpBtn = this.getChildControl("folder-up"); folderUpBtn.addListener("execute", () => this.fireDataEvent("folderUp", this.getFolder()), this); this.getChildControl("folder-path"); - this.getChildControl("view-options-icons"); - this.getChildControl("view-options-list"); - this.getChildControl("icons-layout"); - this.getChildControl("table"); + const iconsButton = this.getChildControl("view-options-icons"); + const listButton = this.getChildControl("view-options-list"); + const folderContent = this.getChildControl("folder-content"); this.bind("folder", this.getChildControl("folder-up"), "enabled", { converter: folder => Boolean(folder && folder.getPathLabel && folder.getPathLabel().length > 1) @@ -44,6 +43,15 @@ qx.Class.define("osparc.file.FolderViewer", { this.bind("folder", this.getChildControl("folder-path"), "value", { converter: folder => folder ? folder.getPathLabel().join(" / ") : this.tr("Select folder") }); + + this.bind("folder", folderContent, "folder"); + + iconsButton.addListener("execute", () => folderContent.setMode("icons")); + listButton.addListener("execute", () => folderContent.setMode("list")); + + folderContent.addListener("selectionChanged", e => this.fireDataEvent("selectionChanged", e.getData())); + folderContent.addListener("itemSelected", e => this.fireDataEvent("itemSelected", e.getData())); + folderContent.addListener("requestDatasetFiles", e => this.fireDataEvent("requestDatasetFiles", e.getData())); }, properties: { @@ -52,16 +60,7 @@ qx.Class.define("osparc.file.FolderViewer", { init: null, nullable: true, event: "changeFolder", - apply: "__applyFolder" }, - - mode: { - check: ["list", "icons"], - init: "icons", - nullable: false, - event: "changeMode", - apply: "__reloadFolderContent" - } }, events: { @@ -71,33 +70,6 @@ qx.Class.define("osparc.file.FolderViewer", { "requestDatasetFiles": "qx.event.type.Data" }, - statics: { - getItemButton: function() { - const item = new qx.ui.form.ToggleButton().set({ - iconPosition: "top", - width: 100, - height: 80, - padding: 3 - }); - item.getChildControl("label").set({ - rich: true, - textAlign: "center", - maxWidth: 100, - maxHeight: 31 - }); - osparc.utils.Utils.setIdToWidget(item, "FolderViewerItem"); - return item; - }, - - T_POS: { - TYPE: 0, - NAME: 1, - DATE: 2, - SIZE: 3, - ID: 4 - } - }, - members: { _createChildControlImpl: function(id) { let control; @@ -135,9 +107,6 @@ qx.Class.define("osparc.file.FolderViewer", { control = new qx.ui.form.ToggleButton(null, "@MaterialIcons/apps/18"); const group = this.getChildControl("view-options-rgroup"); group.add(control); - control.addListener("execute", () => { - this.setMode("icons"); - }); const header = this.getChildControl("header"); header.addAt(control, 2); break; @@ -146,192 +115,19 @@ qx.Class.define("osparc.file.FolderViewer", { control = new qx.ui.form.ToggleButton(null, "@MaterialIcons/reorder/18"); const group = this.getChildControl("view-options-rgroup"); group.add(control); - control.addListener("execute", () => { - this.setMode("list"); - }); const header = this.getChildControl("header"); header.addAt(control, 3); break; } - case "content-stack": { - control = new qx.ui.container.Stack(); + case "folder-content": { + control = new osparc.file.FolderContent(); this._add(control, { flex: 1 }); break; } - case "table": { - const tableModel = new qx.ui.table.model.Simple(); - tableModel.setColumns([ - "", - this.tr("Name"), - this.tr("Date Modified"), - this.tr("Size"), - this.tr("Id") - ]); - control = new osparc.ui.table.Table(tableModel, { - // tableColumnModel: obj => new qx.ui.table.columnmodel.Resize(obj), - initiallyHiddenColumns: [this.self().T_POS.ID] - }); - 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); - this.bind("mode", control, "visibility", { - converter: mode => mode === "list" ? "visible" : "excluded" - }); - const scroll = new qx.ui.container.Scroll(); - scroll.add(control); - this.getChildControl("content-stack").add(scroll); - break; - } - case "icons-layout": { - control = new qx.ui.container.Composite(new qx.ui.layout.Flow(5, 5)); - osparc.utils.Utils.setIdToWidget(control, "FolderViewerIconsContent"); - this.bind("mode", control, "visibility", { - converter: mode => mode === "icons" ? "visible" : "excluded" - }); - const scroll = new qx.ui.container.Scroll(); - scroll.add(control); - this.getChildControl("content-stack").add(scroll); - break; - } } return control || this.base(arguments, id); }, - - __convertEntries: function(content) { - const items = []; - if (this.getMode() === "list") { - content.forEach(entry => { - const row = []; - row.push(entry.getIcon ? entry.getIcon() : this.__getIcon(entry)); - row.push(entry.getLabel()); - row.push(entry.getLastModified ? osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())) : ""); - row.push(entry.getSize ? osparc.utils.Utils.bytesToSize(entry.getSize()) : ""); - if (entry.getItemId) { - row.push(entry.getItemId()); - } - row.entry = entry; - items.push(row); - }); - } else if (this.getMode() === "icons") { - content.forEach(entry => { - let tt = entry.getLabel(); - if (entry.getSize) { - tt += "
" + osparc.utils.Utils.bytesToSize(entry.getSize()); - } - if (entry.getLastModified) { - tt += "
" + osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())); - } - const item = this.self().getItemButton().set({ - label: entry.getLabel(), - icon: entry.getIcon ? entry.getIcon() : this.__getIcon(entry), - toolTipText: tt - }); - const icon = item.getChildControl("icon", true); - if (icon.getSource() === "@FontAwesome5Solid/circle-notch/12") { - icon.setPadding(0); - icon.setMarginRight(4); - icon.getContentElement().addClass("rotate"); - } - - if (entry.getItemId) { - item.itemId = entry.getItemId(); - this.__attachListenersToItems(item, entry); - } - items.push(item); - }); - } - return items; - }, - - __getIcon: function(entry) { - return osparc.file.FilesTree.isDir(entry) ? "@MaterialIcons/folder" : "@MaterialIcons/insert_drive_file"; - }, - - __getEntries: function() { - if (this.getFolder()) { - const children = this.getFolder().getChildren().toArray(); - return this.__convertEntries(children); - } - return []; - }, - - __applyFolder: function(folder) { - if (folder) { - if (folder.getLoaded && !folder.getLoaded()) { - this.fireDataEvent("requestDatasetFiles", { - locationId: folder.getLocation(), - datasetId: folder.getPath() - }); - } - - folder.getChildren().addListener("change", () => { - this.__reloadFolderContent(); - }, this); - } - - this.__reloadFolderContent(); - }, - - __reloadFolderContent: function() { - const entries = this.__getEntries(); - if (this.getMode() === "list") { - const table = this.getChildControl("table"); - table.setData(entries); - this.__attachListenersTotable(table); - } else if (this.getMode() === "icons") { - const iconsLayout = this.getChildControl("icons-layout"); - iconsLayout.removeAll(); - const iconsGroup = new qx.ui.form.RadioGroup().set({ - allowEmptySelection: true - }); - entries.forEach(entry => { - iconsGroup.add(entry); - iconsLayout.add(entry); - }); - } - const stack = this.getChildControl("content-stack"); - stack.setSelection([stack.getSelectables()[this.getMode() === "icons" ? 0 : 1]]); - }, - - __itemTapped: function(item) { - this.fireDataEvent("selectionChanged", item); - }, - - __itemDblTapped: function(item) { - this.fireDataEvent("itemSelected", item); - if (osparc.file.FilesTree.isDir(item)) { - this.setFolder(item); - } - }, - - __attachListenersToItems: function(btn, entry) { - btn.addListener("tap", () => { - this.__itemTapped(entry); - }, this); - btn.addListener("dbltap", () => { - this.__itemDblTapped(entry); - }, this); - }, - - __attachListenersTotable: function(table) { - table.addListener("cellTap", e => { - const selectedRow = e.getRow(); - const rowData = table.getTableModel().getRowData(selectedRow); - if ("entry" in rowData) { - this.__itemTapped(rowData.entry); - } - }, this); - table.addListener("cellDbltap", e => { - const selectedRow = e.getRow(); - const rowData = table.getTableModel().getRowData(selectedRow); - if ("entry" in rowData) { - this.__itemDblTapped(rowData.entry); - } - }, this); - } } }); From 74c1fd8bd2d675c26cbd7b1a2424a78577f0c8bc Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 3 Dec 2024 15:08:03 +0100 Subject: [PATCH 02/28] multiselect propoerty --- .../source/class/osparc/file/FolderContent.js | 8 ++++++++ .../source/class/osparc/file/FolderViewer.js | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) 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 4330672866f..5165795fb24 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -41,6 +41,14 @@ qx.Class.define("osparc.file.FolderContent", { event: "changeMode", apply: "__reloadFolderContent" }, + + multiSelect: { + check: "Boolean", + init: false, + nullable: false, + event: "changeMultiSelect", + apply: "__reloadFolderContent" + }, }, events: { 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 f326823c3b6..15f71fc61fb 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -32,6 +32,7 @@ qx.Class.define("osparc.file.FolderViewer", { const folderUpBtn = this.getChildControl("folder-up"); folderUpBtn.addListener("execute", () => this.fireDataEvent("folderUp", this.getFolder()), this); this.getChildControl("folder-path"); + const multiSelectButton = this.getChildControl("multi-select-button"); const iconsButton = this.getChildControl("view-options-icons"); const listButton = this.getChildControl("view-options-list"); const folderContent = this.getChildControl("folder-content"); @@ -46,6 +47,7 @@ qx.Class.define("osparc.file.FolderViewer", { this.bind("folder", folderContent, "folder"); + multiSelectButton.addListener("changeValue", e => folderContent.setMultiSelect(e.getData())); iconsButton.addListener("execute", () => folderContent.setMode("icons")); listButton.addListener("execute", () => folderContent.setMode("list")); @@ -100,6 +102,14 @@ qx.Class.define("osparc.file.FolderViewer", { }); break; } + case "multi-select-button": + control = new qx.ui.form.ToggleButton(this.tr("Multiselect")).set({ + value: false, + marginRight: 10, + }); + const header = this.getChildControl("header"); + header.addAt(control, 2); + break; case "view-options-rgroup": control = new qx.ui.form.RadioGroup(); break; @@ -108,7 +118,7 @@ qx.Class.define("osparc.file.FolderViewer", { const group = this.getChildControl("view-options-rgroup"); group.add(control); const header = this.getChildControl("header"); - header.addAt(control, 2); + header.addAt(control, 3); break; } case "view-options-list": { @@ -116,7 +126,7 @@ qx.Class.define("osparc.file.FolderViewer", { const group = this.getChildControl("view-options-rgroup"); group.add(control); const header = this.getChildControl("header"); - header.addAt(control, 3); + header.addAt(control, 4); break; } case "folder-content": { From 67ed884949c7c7c9ac7b0bbfb3fe11429d716e96 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 3 Dec 2024 15:30:22 +0100 Subject: [PATCH 03/28] refactor --- .../source/class/osparc/file/FolderContent.js | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) 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 5165795fb24..71643ff9e43 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -130,33 +130,45 @@ qx.Class.define("osparc.file.FolderContent", { }, __convertEntries: function(content) { + const datas = []; + content.forEach(entry => { + const data = { + icon: entry.getIcon ? entry.getIcon() : this.__getIcon(entry), + label: entry.getLabel(), + lastModified: entry.getLastModified ? osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())) : "", + size: entry.getSize ? osparc.utils.Utils.bytesToSize(entry.getSize()) : "", + itemId: entry.getItemId ? entry.getItemId() : null, + entry: entry, + }; + datas.push(data); + }); const items = []; if (this.getMode() === "list") { - content.forEach(entry => { + datas.forEach(data => { const row = []; - row.push(entry.getIcon ? entry.getIcon() : this.__getIcon(entry)); - row.push(entry.getLabel()); - row.push(entry.getLastModified ? osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())) : ""); - row.push(entry.getSize ? osparc.utils.Utils.bytesToSize(entry.getSize()) : ""); - if (entry.getItemId) { - row.push(entry.getItemId()); + row.push(data["icon"]); + row.push(data["label"]); + row.push(data["lastModified"]); + row.push(data["size"]); + if (data["itemId"]) { + row.push(data["itemId"]); } - row.entry = entry; + row.entry = data["entry"]; items.push(row); }); } else if (this.getMode() === "icons") { - content.forEach(entry => { - let tt = entry.getLabel(); - if (entry.getSize) { - tt += "
" + osparc.utils.Utils.bytesToSize(entry.getSize()); + datas.forEach(data => { + let toolTip = data["label"]; + if (data["size"]) { + toolTip += "
" + data["size"]; } - if (entry.getLastModified) { - tt += "
" + osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())); + if (data["lastModified"]) { + toolTip += "
" + data["lastModified"]; } const item = this.self().getItemButton().set({ - label: entry.getLabel(), - icon: entry.getIcon ? entry.getIcon() : this.__getIcon(entry), - toolTipText: tt + label: data["label"], + icon: data["icon"], + toolTipText: toolTip }); const icon = item.getChildControl("icon", true); if (icon.getSource() === "@FontAwesome5Solid/circle-notch/12") { @@ -164,10 +176,9 @@ qx.Class.define("osparc.file.FolderContent", { icon.setMarginRight(4); icon.getContentElement().addClass("rotate"); } - - if (entry.getItemId) { - item.itemId = entry.getItemId(); - this.__attachListenersToItems(item, entry); + if (data["itemId"]) { + item.itemId = data["itemId"]; + this.__attachListenersToItems(item, data["entry"]); } items.push(item); }); From 7cc1727a67765005a6ef838cddf6a04f983541ea Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 3 Dec 2024 16:06:25 +0100 Subject: [PATCH 04/28] more compact icon --- .../client/source/class/osparc/file/FolderContent.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 71643ff9e43..6b2ca0f9ba5 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -63,13 +63,14 @@ qx.Class.define("osparc.file.FolderContent", { iconPosition: "top", width: 100, height: 80, - padding: 3 + padding: 2 }); item.getChildControl("label").set({ + font: "text-12", rich: true, textAlign: "center", maxWidth: 100, - maxHeight: 31 + maxHeight: 33 // two lines }); osparc.utils.Utils.setIdToWidget(item, "FolderViewerItem"); return item; From b5988fdc007a0b4d96877d1a8a4b80b2f34be032 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 3 Dec 2024 16:26:45 +0100 Subject: [PATCH 05/28] aesthetics --- .../client/source/class/osparc/file/FileTreeItem.js | 5 +++++ 1 file changed, 5 insertions(+) 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 45fe07c10ce..5e7a4a02236 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js +++ b/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js @@ -45,6 +45,11 @@ qx.Class.define("osparc.file.FileTreeItem", { construct: function() { this.base(arguments); + this.set({ + indent: 12, // defaults to 19, + decorator: "rounded", + }); + // create a date format like "Oct. 19, 2018 11:31 AM" this._dateFormat = new qx.util.format.DateFormat( qx.locale.Date.getDateFormat("medium") + " " + From d12974492206a3ac536322fa5baee4e5cf8c7e8c Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 3 Dec 2024 16:40:00 +0100 Subject: [PATCH 06/28] [skip ci] allowMultiselection --- .../client/source/class/osparc/file/FilePicker.js | 3 ++- .../client/source/class/osparc/file/FolderViewer.js | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/file/FilePicker.js b/services/static-webserver/client/source/class/osparc/file/FilePicker.js index 67d67c8455a..0a04558952d 100644 --- a/services/static-webserver/client/source/class/osparc/file/FilePicker.js +++ b/services/static-webserver/client/source/class/osparc/file/FilePicker.js @@ -545,7 +545,8 @@ qx.Class.define("osparc.file.FilePicker", { flex: 1 }); treeFolderLayout.add(treeLayout, 0); - const folderViewer = new osparc.file.FolderViewer(); + const allowMultiselection = false; + const folderViewer = new osparc.file.FolderViewer(allowMultiselection); treeFolderLayout.add(folderViewer, 1); filesTree.addListener("selectionChanged", () => { 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 15f71fc61fb..218c3a90a49 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() { + construct: function(allowMultiselection = true) { this.base(arguments); this._setLayout(new qx.ui.layout.VBox(10)); @@ -32,7 +32,10 @@ qx.Class.define("osparc.file.FolderViewer", { const folderUpBtn = this.getChildControl("folder-up"); folderUpBtn.addListener("execute", () => this.fireDataEvent("folderUp", this.getFolder()), this); this.getChildControl("folder-path"); - const multiSelectButton = this.getChildControl("multi-select-button"); + let multiSelectButton = null; + if (allowMultiselection) { + multiSelectButton = this.getChildControl("multi-select-button"); + } const iconsButton = this.getChildControl("view-options-icons"); const listButton = this.getChildControl("view-options-list"); const folderContent = this.getChildControl("folder-content"); @@ -47,7 +50,9 @@ qx.Class.define("osparc.file.FolderViewer", { this.bind("folder", folderContent, "folder"); - multiSelectButton.addListener("changeValue", e => folderContent.setMultiSelect(e.getData())); + if (allowMultiselection) { + multiSelectButton.addListener("changeValue", e => folderContent.setMultiSelect(e.getData())); + } iconsButton.addListener("execute", () => folderContent.setMode("icons")); listButton.addListener("execute", () => folderContent.setMode("list")); From a95fc6e0662066e7997d01ad2f1727dbab14186f Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Wed, 4 Dec 2024 11:58:09 +0100 Subject: [PATCH 07/28] minor --- .../client/source/class/osparc/file/FolderContent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6b2ca0f9ba5..e4bbde452ae 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -179,8 +179,8 @@ qx.Class.define("osparc.file.FolderContent", { } if (data["itemId"]) { item.itemId = data["itemId"]; - this.__attachListenersToItems(item, data["entry"]); } + this.__attachListenersToItems(item, data["entry"]); items.push(item); }); } From 82c013d369774f91c312395e55e241a280fd7710 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Wed, 4 Dec 2024 12:36:50 +0100 Subject: [PATCH 08/28] multiSelectionChanged --- .../client/source/class/osparc/file/FolderContent.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 e4bbde452ae..7424f89ed45 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -53,6 +53,7 @@ qx.Class.define("osparc.file.FolderContent", { events: { "selectionChanged": "qx.event.type.Data", // tap + "multiSelectionChanged": "qx.event.type.Data", // tap "itemSelected": "qx.event.type.Data", // dbltap "requestDatasetFiles": "qx.event.type.Data", }, @@ -229,7 +230,9 @@ qx.Class.define("osparc.file.FolderContent", { allowEmptySelection: true }); entries.forEach(entry => { - iconsGroup.add(entry); + if (!this.isMultiSelect()) { + iconsGroup.add(entry); + } iconsLayout.add(entry); }); } @@ -237,7 +240,11 @@ qx.Class.define("osparc.file.FolderContent", { }, __itemTapped: function(item) { - this.fireDataEvent("selectionChanged", item); + if (this.isMultiSelect()) { + this.fireDataEvent("multiSelectionChanged", item); + } else { + this.fireDataEvent("selectionChanged", item); + } }, __itemDblTapped: function(item) { From 0d7e0e5562f877a57a02b7ad27a808c672fa6064 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Wed, 4 Dec 2024 13:35:50 +0100 Subject: [PATCH 09/28] renaming --- .../source/class/osparc/file/FolderContent.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) 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 7424f89ed45..2110a5b6195 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -181,7 +181,7 @@ qx.Class.define("osparc.file.FolderContent", { if (data["itemId"]) { item.itemId = data["itemId"]; } - this.__attachListenersToItems(item, data["entry"]); + this.__attachListenersToGridItem(item, data["entry"]); items.push(item); }); } @@ -222,7 +222,7 @@ qx.Class.define("osparc.file.FolderContent", { if (this.getMode() === "list") { const table = this.getChildControl("table"); table.setData(entries); - this.__attachListenersTotable(table); + this.__attachListenersToTableItem(table); } else if (this.getMode() === "icons") { const iconsLayout = this.getChildControl("icons-layout"); iconsLayout.removeAll(); @@ -239,22 +239,22 @@ qx.Class.define("osparc.file.FolderContent", { this.setSelection([this.getSelectables()[this.getMode() === "icons" ? 0 : 1]]); }, - __itemTapped: function(item) { + __itemTapped: function(entry) { if (this.isMultiSelect()) { - this.fireDataEvent("multiSelectionChanged", item); + this.fireDataEvent("multiSelectionChanged", entry); } else { - this.fireDataEvent("selectionChanged", item); + this.fireDataEvent("selectionChanged", entry); } }, - __itemDblTapped: function(item) { - this.fireDataEvent("itemSelected", item); - if (osparc.file.FilesTree.isDir(item)) { - this.setFolder(item); + __itemDblTapped: function(entry) { + this.fireDataEvent("itemSelected", entry); + if (osparc.file.FilesTree.isDir(entry)) { + this.setFolder(entry); } }, - __attachListenersToItems: function(btn, entry) { + __attachListenersToGridItem: function(btn, entry) { btn.addListener("tap", () => { this.__itemTapped(entry); }, this); @@ -263,7 +263,7 @@ qx.Class.define("osparc.file.FolderContent", { }, this); }, - __attachListenersTotable: function(table) { + __attachListenersToTableItem: function(table) { table.addListener("cellTap", e => { const selectedRow = e.getRow(); const rowData = table.getTableModel().getRowData(selectedRow); From 592cf3d8be20082f54aea32f67eb6eabda682fea Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Wed, 4 Dec 2024 13:37:35 +0100 Subject: [PATCH 10/28] [skip ci] folders can't be selected --- .../client/source/class/osparc/file/FolderContent.js | 4 ++++ 1 file changed, 4 insertions(+) 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 2110a5b6195..bcbb4dcdde3 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -257,6 +257,10 @@ qx.Class.define("osparc.file.FolderContent", { __attachListenersToGridItem: function(btn, entry) { btn.addListener("tap", () => { this.__itemTapped(entry); + // folders can't be selected + if (osparc.file.FilesTree.isDir(entry)) { + btn.setValue(false); + } }, this); btn.addListener("dbltap", () => { this.__itemDblTapped(entry); From 669e7a2e55bd2cbcff941c7ac1c2c71ea5a36fb7 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Wed, 11 Dec 2024 15:29:25 +0100 Subject: [PATCH 11/28] linting --- .../client/source/class/osparc/file/FolderViewer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 218c3a90a49..47593ad30ab 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -107,7 +107,7 @@ qx.Class.define("osparc.file.FolderViewer", { }); break; } - case "multi-select-button": + case "multi-select-button": { control = new qx.ui.form.ToggleButton(this.tr("Multiselect")).set({ value: false, marginRight: 10, @@ -115,6 +115,7 @@ qx.Class.define("osparc.file.FolderViewer", { const header = this.getChildControl("header"); header.addAt(control, 2); break; + } case "view-options-rgroup": control = new qx.ui.form.RadioGroup(); break; From 906f050dac215631be522e3b530d8f3a98263fe5 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Wed, 11 Dec 2024 16:35:58 +0100 Subject: [PATCH 12/28] [skip ci] resetItemSelected --- .../class/osparc/file/FileLabelWithActions.js | 40 ++++++++++++------- .../source/class/osparc/file/FolderContent.js | 6 ++- .../class/osparc/file/TreeFolderView.js | 2 + 3 files changed, 31 insertions(+), 17 deletions(-) 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 1343ce73a13..20bf9b61f39 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -89,25 +89,35 @@ qx.Class.define("osparc.file.FileLabelWithActions", { }, setItemSelected: function(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() - }); + if (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 = null; + selectedLabel.set({ + value: "", + toolTipText: "" + }); + } } else { - this.__selection = null; - selectedLabel.set({ - value: "", - toolTipText: "" - }); + this.resetItemSelected(); } }, + resetItemSelected: function() { + this.getChildControl("download-button").setEnabled(false); + this.getChildControl("delete-button").setEnabled(false); + this.getChildControl("selected-label").resetValue(); + }, + getItemSelected: function() { const selectedItem = this.__selection; if (selectedItem && osparc.file.FilesTree.isFile(selectedItem)) { 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 bcbb4dcdde3..e095dce6f2a 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -239,9 +239,11 @@ qx.Class.define("osparc.file.FolderContent", { this.setSelection([this.getSelectables()[this.getMode() === "icons" ? 0 : 1]]); }, - __itemTapped: function(entry) { + __itemTapped: function(entry, buttonSelected) { if (this.isMultiSelect()) { this.fireDataEvent("multiSelectionChanged", entry); + } else if (buttonSelected === false) { + this.fireDataEvent("selectionChanged", null); } else { this.fireDataEvent("selectionChanged", entry); } @@ -256,7 +258,7 @@ qx.Class.define("osparc.file.FolderContent", { __attachListenersToGridItem: function(btn, entry) { btn.addListener("tap", () => { - this.__itemTapped(entry); + this.__itemTapped(entry, btn.getValue()); // folders can't be selected if (osparc.file.FilesTree.isDir(entry)) { btn.setValue(false); diff --git a/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js b/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js index 9e88b2d688e..234f0b0f566 100644 --- a/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js +++ b/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js @@ -106,6 +106,8 @@ qx.Class.define("osparc.file.TreeFolderView", { const selectionData = e.getData(); if (selectionData) { selectedFileLayout.setItemSelected(selectionData); + } else { + selectedFileLayout.resetItemSelected(selectionData); } }, this); From b5ab786d95bcc446cd960eef1040dfe2bf33db6c Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 08:35:38 +0100 Subject: [PATCH 13/28] openCategory --- .../client/source/class/osparc/vipMarket/Market.js | 6 +++++- .../client/source/class/osparc/vipMarket/MarketWindow.js | 6 +----- 2 files changed, 6 insertions(+), 6 deletions(-) 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 8bd65242eb2..028a41acbee 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js @@ -18,7 +18,7 @@ qx.Class.define("osparc.vipMarket.Market", { extend: osparc.ui.window.TabbedView, - construct: function() { + construct: function(category) { this.base(arguments); const miniWallet = osparc.desktop.credits.BillingCenter.createMiniWalletView().set({ @@ -51,6 +51,10 @@ qx.Class.define("osparc.vipMarket.Market", { }].forEach(marketInfo => { this.__buildViPMarketPage(marketInfo); }); + + if (category) { + this.openCategory(category); + } }); }, diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js b/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js index c610abf36b3..6ef7b07fe75 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js @@ -30,14 +30,10 @@ qx.Class.define("osparc.vipMarket.MarketWindow", { height }); - const vipMarket = this.__vipMarket = new osparc.vipMarket.Market().set({ + const vipMarket = this.__vipMarket = new osparc.vipMarket.Market(category).set({ openBy: nodeId ? nodeId : null, }); this._setTabbedView(vipMarket); - - if (category) { - vipMarket.openCategory(category); - } }, statics: { From 1f8a4ad4e5f1107d07a17808458360656b8a216d Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 08:53:56 +0100 Subject: [PATCH 14/28] refactor --- .../class/osparc/dashboard/DataBrowser.js | 2 +- .../source/class/osparc/file/FolderViewer.js | 21 ++++++++++++++++ .../class/osparc/file/TreeFolderView.js | 25 +++---------------- .../class/osparc/widget/NodeDataManager.js | 2 +- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/DataBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/DataBrowser.js index 9d6683a832e..f8ffd3d73d0 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/DataBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/DataBrowser.js @@ -75,7 +75,7 @@ qx.Class.define("osparc.dashboard.DataBrowser", { const reloadButton = treeFolderView.getChildControl("reload-button"); reloadButton.addListener("execute", () => this.__reloadTree(), this); - const selectedFileLayout = treeFolderView.getChildControl("selected-file-layout"); + const selectedFileLayout = treeFolderView.getChildControl("folder-viewer").getChildControl("selected-file-layout"); selectedFileLayout.addListener("fileDeleted", e => this.__fileDeleted(e.getData()), 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 47593ad30ab..4fa041f7c20 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -39,6 +39,7 @@ qx.Class.define("osparc.file.FolderViewer", { const iconsButton = this.getChildControl("view-options-icons"); const listButton = this.getChildControl("view-options-list"); const folderContent = this.getChildControl("folder-content"); + const selectedFileLayout = this.getChildControl("selected-file-layout"); this.bind("folder", this.getChildControl("folder-up"), "enabled", { converter: folder => Boolean(folder && folder.getPathLabel && folder.getPathLabel().length > 1) @@ -59,6 +60,15 @@ qx.Class.define("osparc.file.FolderViewer", { folderContent.addListener("selectionChanged", e => this.fireDataEvent("selectionChanged", e.getData())); folderContent.addListener("itemSelected", e => this.fireDataEvent("itemSelected", e.getData())); folderContent.addListener("requestDatasetFiles", e => this.fireDataEvent("requestDatasetFiles", e.getData())); + + this.addListener("selectionChanged", e => { + const selectionData = e.getData(); + if (selectionData) { + selectedFileLayout.setItemSelected(selectionData); + } else { + selectedFileLayout.resetItemSelected(selectionData); + } + }, this); }, properties: { @@ -67,6 +77,7 @@ qx.Class.define("osparc.file.FolderViewer", { init: null, nullable: true, event: "changeFolder", + apply: "__applyFolder", }, }, @@ -142,8 +153,18 @@ qx.Class.define("osparc.file.FolderViewer", { }); break; } + case "selected-file-layout": + control = new osparc.file.FileLabelWithActions().set({ + alignY: "middle" + }); + this._add(control); + break; } return control || this.base(arguments, id); }, + + __applyFolder: function() { + this.getChildControl("selected-file-layout").resetItemSelected(); + } } }); diff --git a/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js b/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js index 234f0b0f566..a22d2afd564 100644 --- a/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js +++ b/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js @@ -75,12 +75,6 @@ qx.Class.define("osparc.file.TreeFolderView", { treeFolderLayout.add(control, 1); break; } - case "selected-file-layout": - control = new osparc.file.FileLabelWithActions().set({ - alignY: "middle" - }); - this._add(control); - break; } return control || this.base(arguments, id); }, @@ -89,25 +83,12 @@ qx.Class.define("osparc.file.TreeFolderView", { this.getChildControl("reload-button"); const folderTree = this.getChildControl("folder-tree"); const folderViewer = this.getChildControl("folder-viewer"); - const selectedFileLayout = this.getChildControl("selected-file-layout"); // Connect elements folderTree.addListener("selectionChanged", () => { - const selectionData = folderTree.getSelectedItem(); - if (selectionData) { - selectedFileLayout.setItemSelected(selectionData); - if (osparc.file.FilesTree.isDir(selectionData) || (selectionData.getChildren && selectionData.getChildren().length)) { - folderViewer.setFolder(selectionData); - } - } - }, this); - - folderViewer.addListener("selectionChanged", e => { - const selectionData = e.getData(); - if (selectionData) { - selectedFileLayout.setItemSelected(selectionData); - } else { - selectedFileLayout.resetItemSelected(selectionData); + const selectedFolder = folderTree.getSelectedItem(); + if (selectedFolder && (osparc.file.FilesTree.isDir(selectedFolder) || (selectedFolder.getChildren && selectedFolder.getChildren().length))) { + folderViewer.setFolder(selectedFolder); } }, this); diff --git a/services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js b/services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js index 641e98c58a0..2785f658c6c 100644 --- a/services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js +++ b/services/static-webserver/client/source/class/osparc/widget/NodeDataManager.js @@ -94,7 +94,7 @@ qx.Class.define("osparc.widget.NodeDataManager", { const reloadButton = treeFolderView.getChildControl("reload-button"); reloadButton.addListener("execute", () => this.__reloadTree(), this); - const selectedFileLayout = treeFolderView.getChildControl("selected-file-layout"); + const selectedFileLayout = treeFolderView.getChildControl("folder-viewer").getChildControl("selected-file-layout"); selectedFileLayout.addListener("fileDeleted", e => this.__fileDeleted(e.getData()), this); }, From db82dde8077eefa258142acad09bc6f5c674002b Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 08:55:21 +0100 Subject: [PATCH 15/28] more refactor --- .../client/source/class/osparc/file/FolderViewer.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 4fa041f7c20..0c9de334283 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -57,11 +57,9 @@ qx.Class.define("osparc.file.FolderViewer", { iconsButton.addListener("execute", () => folderContent.setMode("icons")); listButton.addListener("execute", () => folderContent.setMode("list")); - folderContent.addListener("selectionChanged", e => this.fireDataEvent("selectionChanged", e.getData())); folderContent.addListener("itemSelected", e => this.fireDataEvent("itemSelected", e.getData())); folderContent.addListener("requestDatasetFiles", e => this.fireDataEvent("requestDatasetFiles", e.getData())); - - this.addListener("selectionChanged", e => { + folderContent.addListener("selectionChanged", e => { const selectionData = e.getData(); if (selectionData) { selectedFileLayout.setItemSelected(selectionData); @@ -82,7 +80,6 @@ qx.Class.define("osparc.file.FolderViewer", { }, events: { - "selectionChanged": "qx.event.type.Data", // tap "itemSelected": "qx.event.type.Data", // dbltap "folderUp": "qx.event.type.Data", "requestDatasetFiles": "qx.event.type.Data" From 4a9f185960df7c206e375a3e993ba746430705e6 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:01:01 +0100 Subject: [PATCH 16/28] [skip ci] minor --- .../client/source/class/osparc/vipMarket/VipMarket.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js index 1385264933e..a6e334e7ec5 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js @@ -71,7 +71,6 @@ qx.Class.define("osparc.vipMarket.VipMarket", { members: { __anatomicalModels: null, - __purchasesItems: null, __anatomicalModelsModel: null, _createChildControlImpl: function(id) { @@ -214,7 +213,6 @@ qx.Class.define("osparc.vipMarket.VipMarket", { .then(values => { const licensedItems = values[0]; const purchasesItems = values[1]; - this.__purchasesItems = purchasesItems; this.__anatomicalModels = []; allAnatomicalModels.forEach(model => { From 6c249177c591ad284fdd52cfaefb230a79d44590 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:10:10 +0100 Subject: [PATCH 17/28] [skip ci] minor fix --- .../source/class/osparc/file/FolderContent.js | 3 -- .../source/class/osparc/file/FolderViewer.js | 28 ++++++++++++------- 2 files changed, 18 insertions(+), 13 deletions(-) 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 e095dce6f2a..097609016f5 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -251,9 +251,6 @@ qx.Class.define("osparc.file.FolderContent", { __itemDblTapped: function(entry) { this.fireDataEvent("itemSelected", entry); - if (osparc.file.FilesTree.isDir(entry)) { - this.setFolder(entry); - } }, __attachListenersToGridItem: function(btn, entry) { 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 0c9de334283..90b5c771793 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -36,8 +36,8 @@ qx.Class.define("osparc.file.FolderViewer", { if (allowMultiselection) { multiSelectButton = this.getChildControl("multi-select-button"); } - const iconsButton = this.getChildControl("view-options-icons"); - const listButton = this.getChildControl("view-options-list"); + const gridViewButton = this.getChildControl("view-options-icons"); + const listViewButton = this.getChildControl("view-options-list"); const folderContent = this.getChildControl("folder-content"); const selectedFileLayout = this.getChildControl("selected-file-layout"); @@ -54,19 +54,27 @@ qx.Class.define("osparc.file.FolderViewer", { if (allowMultiselection) { multiSelectButton.addListener("changeValue", e => folderContent.setMultiSelect(e.getData())); } - iconsButton.addListener("execute", () => folderContent.setMode("icons")); - listButton.addListener("execute", () => folderContent.setMode("list")); + gridViewButton.addListener("execute", () => { + folderContent.setMode("icons"); + selectedFileLayout.resetItemSelected(); + }); + listViewButton.addListener("execute", () => { + folderContent.setMode("list"); + selectedFileLayout.resetItemSelected(); + }); - folderContent.addListener("itemSelected", e => this.fireDataEvent("itemSelected", e.getData())); folderContent.addListener("requestDatasetFiles", e => this.fireDataEvent("requestDatasetFiles", e.getData())); folderContent.addListener("selectionChanged", e => { const selectionData = e.getData(); - if (selectionData) { - selectedFileLayout.setItemSelected(selectionData); - } else { - selectedFileLayout.resetItemSelected(selectionData); - } + selectionData ? selectedFileLayout.setItemSelected(selectionData) : selectedFileLayout.resetItemSelected(); }, this); + folderContent.addListener("itemSelected", e => { + const entry = e.getData(); + this.fireDataEvent("itemSelected", entry); + if (osparc.file.FilesTree.isDir(entry)) { + this.setFolder(entry); + } + }); }, properties: { From 4f02c036089a346ad934b6c36fb70cdaeb3a1f05 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:13:45 +0100 Subject: [PATCH 18/28] rename event --- .../client/source/class/osparc/file/FolderContent.js | 4 ++-- .../client/source/class/osparc/file/FolderViewer.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 097609016f5..bec650f742a 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -54,7 +54,7 @@ qx.Class.define("osparc.file.FolderContent", { events: { "selectionChanged": "qx.event.type.Data", // tap "multiSelectionChanged": "qx.event.type.Data", // tap - "itemSelected": "qx.event.type.Data", // dbltap + "openItemSelected": "qx.event.type.Data", // dbltap "requestDatasetFiles": "qx.event.type.Data", }, @@ -250,7 +250,7 @@ qx.Class.define("osparc.file.FolderContent", { }, __itemDblTapped: function(entry) { - this.fireDataEvent("itemSelected", entry); + this.fireDataEvent("openItemSelected", entry); }, __attachListenersToGridItem: function(btn, entry) { 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 90b5c771793..d4434d8a12e 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -68,7 +68,7 @@ qx.Class.define("osparc.file.FolderViewer", { const selectionData = e.getData(); selectionData ? selectedFileLayout.setItemSelected(selectionData) : selectedFileLayout.resetItemSelected(); }, this); - folderContent.addListener("itemSelected", e => { + folderContent.addListener("openItemSelected", e => { const entry = e.getData(); this.fireDataEvent("itemSelected", entry); if (osparc.file.FilesTree.isDir(entry)) { From 72a4279876a8ed1ab62268855db04753f7f8b961 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:15:18 +0100 Subject: [PATCH 19/28] more renaming --- .../client/source/class/osparc/file/FilePicker.js | 2 +- .../client/source/class/osparc/file/FolderViewer.js | 4 ++-- .../client/source/class/osparc/file/TreeFolderView.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/file/FilePicker.js b/services/static-webserver/client/source/class/osparc/file/FilePicker.js index 0a04558952d..fdce6e4aec9 100644 --- a/services/static-webserver/client/source/class/osparc/file/FilePicker.js +++ b/services/static-webserver/client/source/class/osparc/file/FilePicker.js @@ -563,7 +563,7 @@ qx.Class.define("osparc.file.FilePicker", { const selectionData = e.getData(); this.__selectionChanged(selectionData); }, this); - folderViewer.addListener("itemSelected", e => { + folderViewer.addListener("openItemSelected", e => { const selectionData = e.getData(); this.__selectionChanged(selectionData); if (osparc.file.FilesTree.isFile(selectionData)) { 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 d4434d8a12e..f0df2f2e12b 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -70,7 +70,7 @@ qx.Class.define("osparc.file.FolderViewer", { }, this); folderContent.addListener("openItemSelected", e => { const entry = e.getData(); - this.fireDataEvent("itemSelected", entry); + this.fireDataEvent("openItemSelected", entry); if (osparc.file.FilesTree.isDir(entry)) { this.setFolder(entry); } @@ -88,7 +88,7 @@ qx.Class.define("osparc.file.FolderViewer", { }, events: { - "itemSelected": "qx.event.type.Data", // dbltap + "openItemSelected": "qx.event.type.Data", // dbltap "folderUp": "qx.event.type.Data", "requestDatasetFiles": "qx.event.type.Data" }, diff --git a/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js b/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js index a22d2afd564..d9349713218 100644 --- a/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js +++ b/services/static-webserver/client/source/class/osparc/file/TreeFolderView.js @@ -92,7 +92,7 @@ qx.Class.define("osparc.file.TreeFolderView", { } }, this); - folderViewer.addListener("itemSelected", e => { + folderViewer.addListener("openItemSelected", e => { const data = e.getData(); folderTree.openNodeAndParents(data); folderTree.setSelection(new qx.data.Array([data])); From ce6dfd8d3413a0903287bf2cf8f0c34791eb87a3 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:22:54 +0100 Subject: [PATCH 20/28] [skip ci] multiSelect prop --- .../class/osparc/file/FileLabelWithActions.js | 17 +++++++++++++++++ .../source/class/osparc/file/FolderViewer.js | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) 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 20bf9b61f39..77ad075e52f 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -55,8 +55,19 @@ qx.Class.define("osparc.file.FileLabelWithActions", { "fileDeleted": "qx.event.type.Data" }, + properties: { + multiSelect: { + check: "Boolean", + init: false, + nullable: false, + event: "changeMultiSelect", + apply: "__enableMultiSelection", + }, + }, + members: { __selection: null, + __multiSelection: null, _createChildControlImpl: function(id) { let control; @@ -88,6 +99,11 @@ qx.Class.define("osparc.file.FileLabelWithActions", { return control || this.base(arguments, id); }, + __enableMultiSelection: function() { + this.resetItemSelected(); + this.__multiSelection = []; + }, + setItemSelected: function(selectedItem) { if (selectedItem) { const isFile = osparc.file.FilesTree.isFile(selectedItem); @@ -113,6 +129,7 @@ qx.Class.define("osparc.file.FileLabelWithActions", { }, resetItemSelected: function() { + this.__selection = null; this.getChildControl("download-button").setEnabled(false); this.getChildControl("delete-button").setEnabled(false); this.getChildControl("selected-label").resetValue(); 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 f0df2f2e12b..8287dcbe20c 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -52,7 +52,10 @@ qx.Class.define("osparc.file.FolderViewer", { this.bind("folder", folderContent, "folder"); if (allowMultiselection) { - multiSelectButton.addListener("changeValue", e => folderContent.setMultiSelect(e.getData())); + multiSelectButton.addListener("changeValue", e => { + folderContent.setMultiSelect(e.getData()); + selectedFileLayout.setMultiSelect(e.getData()); + }); } gridViewButton.addListener("execute", () => { folderContent.setMode("icons"); From 5f2b900d2d78d8f7df69830b05d6ff82b1809191 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:37:21 +0100 Subject: [PATCH 21/28] [skip ci] pass multiSelectionChanged --- .../class/osparc/file/FileLabelWithActions.js | 4 ++++ .../source/class/osparc/file/FolderContent.js | 14 +++++++++++++- .../source/class/osparc/file/FolderViewer.js | 6 +++++- 3 files changed, 22 insertions(+), 2 deletions(-) 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 77ad075e52f..3fb90e59f9e 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -128,6 +128,10 @@ qx.Class.define("osparc.file.FileLabelWithActions", { } }, + setMultiItemSelected: function(multiSelectionData) { + console.log("multiSelectionData", multiSelectionData); + }, + resetItemSelected: function() { this.__selection = null; this.getChildControl("download-button").setEnabled(false); 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 bec650f742a..0054903aad5 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -255,7 +255,19 @@ qx.Class.define("osparc.file.FolderContent", { __attachListenersToGridItem: function(btn, entry) { btn.addListener("tap", () => { - this.__itemTapped(entry, btn.getValue()); + if (this.isMultiSelect()) { + // pass all buttons that are selected + const selectedFiles = []; + const iconsLayout = this.getChildControl("icons-layout"); + iconsLayout.getChildren().forEach(gridItem => { + if (osparc.file.FilesTree.isFile(gridItem) && gridItem.getValue()) { + selectedFiles.push(gridItem); + } + }); + this.__itemTapped(selectedFiles, btn.getValue()); + } else { + this.__itemTapped(entry, btn.getValue()); + } // folders can't be selected if (osparc.file.FilesTree.isDir(entry)) { btn.setValue(false); 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 8287dcbe20c..c44f48cbe27 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js @@ -69,7 +69,11 @@ qx.Class.define("osparc.file.FolderViewer", { folderContent.addListener("requestDatasetFiles", e => this.fireDataEvent("requestDatasetFiles", e.getData())); folderContent.addListener("selectionChanged", e => { const selectionData = e.getData(); - selectionData ? selectedFileLayout.setItemSelected(selectionData) : selectedFileLayout.resetItemSelected(); + selectedFileLayout.setItemSelected(selectionData); + }, this); + folderContent.addListener("multiSelectionChanged", e => { + const multiSelectionData = e.getData(); + selectedFileLayout.setMultiItemSelected(multiSelectionData); }, this); folderContent.addListener("openItemSelected", e => { const entry = e.getData(); From 0c22a6052991b6a58b6e18b259ed8ec5e23d091d Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:44:14 +0100 Subject: [PATCH 22/28] [skip ci] refactor --- .../source/class/osparc/file/FolderContent.js | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) 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 0054903aad5..d58ffea16be 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -167,22 +167,23 @@ qx.Class.define("osparc.file.FolderContent", { if (data["lastModified"]) { toolTip += "
" + data["lastModified"]; } - const item = this.self().getItemButton().set({ + const gridItem = this.self().getItemButton().set({ label: data["label"], icon: data["icon"], toolTipText: toolTip }); - const icon = item.getChildControl("icon", true); + const icon = gridItem.getChildControl("icon", true); if (icon.getSource() === "@FontAwesome5Solid/circle-notch/12") { icon.setPadding(0); icon.setMarginRight(4); icon.getContentElement().addClass("rotate"); } if (data["itemId"]) { - item.itemId = data["itemId"]; + gridItem.itemId = data["itemId"]; } - this.__attachListenersToGridItem(item, data["entry"]); - items.push(item); + gridItem.entry = data["entry"]; + this.__attachListenersToGridItem(gridItem); + items.push(gridItem); }); } return items; @@ -253,28 +254,28 @@ qx.Class.define("osparc.file.FolderContent", { this.fireDataEvent("openItemSelected", entry); }, - __attachListenersToGridItem: function(btn, entry) { - btn.addListener("tap", () => { + __attachListenersToGridItem: function(gridItem) { + gridItem.addListener("tap", () => { if (this.isMultiSelect()) { // pass all buttons that are selected const selectedFiles = []; const iconsLayout = this.getChildControl("icons-layout"); - iconsLayout.getChildren().forEach(gridItem => { - if (osparc.file.FilesTree.isFile(gridItem) && gridItem.getValue()) { - selectedFiles.push(gridItem); + iconsLayout.getChildren().forEach(btn => { + if (osparc.file.FilesTree.isFile(btn.entry) && btn.getValue()) { + selectedFiles.push(btn); } }); - this.__itemTapped(selectedFiles, btn.getValue()); + this.__itemTapped(selectedFiles, gridItem.getValue()); } else { - this.__itemTapped(entry, btn.getValue()); + this.__itemTapped(gridItem.entry, gridItem.getValue()); } // folders can't be selected - if (osparc.file.FilesTree.isDir(entry)) { - btn.setValue(false); + if (osparc.file.FilesTree.isDir(gridItem.entry)) { + gridItem.setValue(false); } }, this); - btn.addListener("dbltap", () => { - this.__itemDblTapped(entry); + gridItem.addListener("dbltap", () => { + this.__itemDblTapped(gridItem.entry); }, this); }, From c6dcd3bf6162b9318feb01d0e19aa01c25e59604 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:53:01 +0100 Subject: [PATCH 23/28] [skip ci] refactor --- .../class/osparc/file/FileLabelWithActions.js | 80 ++++++++++++------- 1 file changed, 50 insertions(+), 30 deletions(-) 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 3fb90e59f9e..a9d10b22621 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -45,10 +45,10 @@ qx.Class.define("osparc.file.FileLabelWithActions", { this.getChildControl("selected-label"); const downloadBtn = this.getChildControl("download-button"); - downloadBtn.addListener("execute", () => this.__retrieveURLAndDownload(), this); + downloadBtn.addListener("execute", () => this.__retrieveURLAndDownloadSelected(), this); const deleteBtn = this.getChildControl("delete-button"); - deleteBtn.addListener("execute", () => this.__deleteFile(), this); + deleteBtn.addListener("execute", () => this.__deleteSelected(), this); }, events: { @@ -129,11 +129,24 @@ qx.Class.define("osparc.file.FileLabelWithActions", { }, setMultiItemSelected: function(multiSelectionData) { - console.log("multiSelectionData", multiSelectionData); + this.__multiSelection = multiSelectionData; + if (multiSelectionData && multiSelectionData.length) { + if (multiSelectionData.length === 1) { + this.setItemSelected(multiSelectionData[0].entry); + } else { + const selectedLabel = this.getChildControl("selected-label"); + selectedLabel.set({ + value: multiSelectionData.length + " files" + }); + } + } else { + this.resetItemSelected(); + } }, resetItemSelected: function() { this.__selection = null; + this.__multiSelection = []; this.getChildControl("download-button").setEnabled(false); this.getChildControl("delete-button").setEnabled(false); this.getChildControl("selected-label").resetValue(); @@ -147,40 +160,47 @@ qx.Class.define("osparc.file.FileLabelWithActions", { return null; }, - // Request to the server and download - __retrieveURLAndDownload: function() { + __retrieveURLAndDownloadSelected: function() { let selection = this.getItemSelected(); if (selection) { - const fileId = selection.getFileId(); - const locationId = selection.getLocation(); - osparc.utils.Utils.retrieveURLAndDownload(locationId, fileId) - .then(data => { - if (data) { - osparc.DownloadLinkTracker.getInstance().downloadLinkUnattended(data.link, data.fileName); - } - }); + this.__retrieveURLAndDownloadFile(selection); } }, - __deleteFile: function() { - let selection = this.getItemSelected(); + __deleteSelected: function() { + const selection = this.getItemSelected(); if (selection) { - console.log("Delete ", selection); - const fileId = selection.getFileId(); - const locationId = selection.getLocation(); - if (locationId !== 0 && locationId !== "0") { - osparc.FlashMessenger.getInstance().logAs(this.tr("Only files in simcore.s3 can be deleted")); - return false; - } - const dataStore = osparc.store.Data.getInstance(); - dataStore.addListenerOnce("deleteFile", e => { - if (e) { - this.fireDataEvent("fileDeleted", e.getData()); - } - }, this); - return dataStore.deleteFile(locationId, fileId); + return this.__deleteFile(selection); } return false; - } + }, + + __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); + } + }); + }, + + __deleteFile: function(file) { + console.log("Delete ", file); + const fileId = file.getFileId(); + const locationId = file.getLocation(); + if (locationId !== 0 && locationId !== "0") { + osparc.FlashMessenger.getInstance().logAs(this.tr("Only files in simcore.s3 can be deleted")); + return false; + } + const dataStore = osparc.store.Data.getInstance(); + dataStore.addListenerOnce("deleteFile", e => { + if (e) { + this.fireDataEvent("fileDeleted", e.getData()); + } + }, this); + return dataStore.deleteFile(locationId, fileId); + }, } }); From 589e9aa33d1f04626f76385bf6a02a6d9b6ba66c Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 09:57:46 +0100 Subject: [PATCH 24/28] multi action --- .../class/osparc/file/FileLabelWithActions.js | 27 +++++++++++++------ .../source/class/osparc/file/FolderContent.js | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) 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 a9d10b22621..3d0289f6291 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -132,7 +132,7 @@ qx.Class.define("osparc.file.FileLabelWithActions", { this.__multiSelection = multiSelectionData; if (multiSelectionData && multiSelectionData.length) { if (multiSelectionData.length === 1) { - this.setItemSelected(multiSelectionData[0].entry); + this.setItemSelected(multiSelectionData[0]); } else { const selectedLabel = this.getChildControl("selected-label"); selectedLabel.set({ @@ -161,18 +161,29 @@ qx.Class.define("osparc.file.FileLabelWithActions", { }, __retrieveURLAndDownloadSelected: function() { - let selection = this.getItemSelected(); - if (selection) { - this.__retrieveURLAndDownloadFile(selection); + if (this.isMultiSelect()) { + this.__multiSelection.forEach(selection => { + this.__retrieveURLAndDownloadFile(selection); + }); + } else { + const selection = this.getItemSelected(); + if (selection) { + this.__retrieveURLAndDownloadFile(selection); + } } }, __deleteSelected: function() { - const selection = this.getItemSelected(); - if (selection) { - return this.__deleteFile(selection); + if (this.isMultiSelect()) { + this.__multiSelection.forEach(selection => { + this.__deleteFile(selection); + }); + } else { + const selection = this.getItemSelected(); + if (selection) { + this.__deleteFile(selection); + } } - return false; }, __retrieveURLAndDownloadFile: function(file) { 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 d58ffea16be..ced22a52c1a 100644 --- a/services/static-webserver/client/source/class/osparc/file/FolderContent.js +++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js @@ -262,7 +262,7 @@ qx.Class.define("osparc.file.FolderContent", { const iconsLayout = this.getChildControl("icons-layout"); iconsLayout.getChildren().forEach(btn => { if (osparc.file.FilesTree.isFile(btn.entry) && btn.getValue()) { - selectedFiles.push(btn); + selectedFiles.push(btn.entry); } }); this.__itemTapped(selectedFiles, gridItem.getValue()); From 99ff70b59424ec52d8c4f1ad1303baed06d36f54 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 11:31:02 +0100 Subject: [PATCH 25/28] Promise all --- .../class/osparc/file/FileLabelWithActions.js | 30 +++++++++++++------ .../client/source/class/osparc/store/Data.js | 10 ++----- 2 files changed, 24 insertions(+), 16 deletions(-) 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 3d0289f6291..8b61b69d742 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -175,13 +175,32 @@ qx.Class.define("osparc.file.FileLabelWithActions", { __deleteSelected: function() { if (this.isMultiSelect()) { + const requests = []; this.__multiSelection.forEach(selection => { - this.__deleteFile(selection); + const request = this.__deleteFile(selection); + if (request) { + requests.push(request); + } }); + Promise.all(requests) + .then(datas => { + if (datas.length) { + this.fireDataEvent("fileDeleted", datas[0]); + osparc.FlashMessenger.getInstance().logAs(this.tr("Files successfully deleted"), "ERROR"); + } + }); + requests } else { const selection = this.getItemSelected(); if (selection) { - this.__deleteFile(selection); + const request = this.__deleteFile(selection); + if (request) { + request + .then(data => { + this.fireDataEvent("fileDeleted", data); + osparc.FlashMessenger.getInstance().logAs(this.tr("File successfully deleted"), "ERROR"); + }); + } } } }, @@ -198,19 +217,12 @@ qx.Class.define("osparc.file.FileLabelWithActions", { }, __deleteFile: function(file) { - console.log("Delete ", file); const fileId = file.getFileId(); const locationId = file.getLocation(); if (locationId !== 0 && locationId !== "0") { osparc.FlashMessenger.getInstance().logAs(this.tr("Only files in simcore.s3 can be deleted")); - return false; } const dataStore = osparc.store.Data.getInstance(); - dataStore.addListenerOnce("deleteFile", e => { - if (e) { - this.fireDataEvent("fileDeleted", e.getData()); - } - }, this); return dataStore.deleteFile(locationId, fileId); }, } 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 b514b7b3144..322dc1313bd 100644 --- a/services/static-webserver/client/source/class/osparc/store/Data.js +++ b/services/static-webserver/client/source/class/osparc/store/Data.js @@ -33,7 +33,6 @@ qx.Class.define("osparc.store.Data", { events: { "fileCopied": "qx.event.type.Data", - "deleteFile": "qx.event.type.Data" }, members: { @@ -286,7 +285,7 @@ qx.Class.define("osparc.store.Data", { deleteFile: function(locationId, fileUuid) { if (!osparc.data.Permissions.getInstance().canDo("study.node.data.delete", true)) { - return false; + return null; } // Deletes File @@ -296,22 +295,19 @@ qx.Class.define("osparc.store.Data", { fileUuid: encodeURIComponent(fileUuid) } }; - osparc.data.Resources.fetch("storageFiles", "delete", params) + return osparc.data.Resources.fetch("storageFiles", "delete", params) .then(files => { const data = { data: files, locationId: locationId, fileUuid: fileUuid }; - this.fireDataEvent("deleteFile", data); + return data; }) .catch(err => { console.error(err); osparc.FlashMessenger.getInstance().logAs(this.tr("Failed deleting file"), "ERROR"); - this.fireDataEvent("deleteFile", null); }); - - return true; } } }); From e4c88358573fff8c23667f987843febd1ade6512 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 11:32:09 +0100 Subject: [PATCH 26/28] minor --- .../client/source/class/osparc/file/FileLabelWithActions.js | 1 + 1 file changed, 1 insertion(+) 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 8b61b69d742..15eec413914 100644 --- a/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js +++ b/services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js @@ -221,6 +221,7 @@ qx.Class.define("osparc.file.FileLabelWithActions", { const locationId = file.getLocation(); if (locationId !== 0 && locationId !== "0") { osparc.FlashMessenger.getInstance().logAs(this.tr("Only files in simcore.s3 can be deleted")); + return null; } const dataStore = osparc.store.Data.getInstance(); return dataStore.deleteFile(locationId, fileId); From 49e850e6d3a6600028c524835287e6ff809f5e7b Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 14:31:08 +0100 Subject: [PATCH 27/28] "importMessageSent" --- .../client/source/class/osparc/vipMarket/Market.js | 5 +++++ .../client/source/class/osparc/vipMarket/MarketWindow.js | 9 +++++++++ .../client/source/class/osparc/vipMarket/VipMarket.js | 5 +++++ 3 files changed, 19 insertions(+) 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 028a41acbee..53d605635e2 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js @@ -58,6 +58,10 @@ qx.Class.define("osparc.vipMarket.Market", { }); }, + events: { + "importMessageSent": "qx.event.type.Data", + }, + properties: { openBy: { check: "String", @@ -74,6 +78,7 @@ qx.Class.define("osparc.vipMarket.Market", { metadataUrl: marketInfo["url"], }); this.bind("openBy", vipMarketView, "openBy"); + vipMarketView.addListener("importMessageSent", () => this.fireEvent("importMessageSent")); const page = this.addTab(marketInfo["label"], marketInfo["icon"], vipMarketView); page.category = marketInfo["category"]; return page; diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js b/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js index 6ef7b07fe75..74a754693c2 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js @@ -40,6 +40,7 @@ qx.Class.define("osparc.vipMarket.MarketWindow", { openWindow: function(nodeId, category) { if (osparc.product.Utils.showS4LStore()) { const storeWindow = new osparc.vipMarket.MarketWindow(nodeId, category); + storeWindow.getVipMarket().addListener("importMessageSent", () => storeWindow.close()); storeWindow.center(); storeWindow.open(); return storeWindow; @@ -47,4 +48,12 @@ qx.Class.define("osparc.vipMarket.MarketWindow", { return null; } }, + + members: { + __vipMarket: null, + + getVipMarket: function() { + return this.__vipMarket; + }, + }, }); diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js index a6e334e7ec5..605a4c67f55 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js @@ -26,6 +26,10 @@ qx.Class.define("osparc.vipMarket.VipMarket", { this.__buildLayout(); }, + events: { + "importMessageSent": "qx.event.type.Data" + }, + properties: { openBy: { check: "String", @@ -373,6 +377,7 @@ qx.Class.define("osparc.vipMarket.VipMarket", { }, }; node.getIFrame().sendMessageToIframe(msg); + this.fireEvent("importMessageSent"); } } }, From 0881037e3fca297d76cfe6c860dbb0e65bcf0d10 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Thu, 12 Dec 2024 14:49:04 +0100 Subject: [PATCH 28/28] sendMessageToIframe and sendCloseMessage --- .../source/class/osparc/data/model/Study.js | 11 ++++++++ .../source/class/osparc/vipMarket/Market.js | 12 +++++++++ .../class/osparc/vipMarket/MarketWindow.js | 5 ++++ .../class/osparc/vipMarket/VipMarket.js | 25 ++++++++----------- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/model/Study.js b/services/static-webserver/client/source/class/osparc/data/model/Study.js index e8929c93adf..af4b639cd44 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Study.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Study.js @@ -635,6 +635,17 @@ qx.Class.define("osparc.data.model.Study", { return !this.getUi().getSlideshow().isEmpty(); }, + sendMessageToIframe: function(nodeId, msg) { + if (nodeId) { + const node = this.getWorkbench().getNode(nodeId); + if (node && node.getIFrame()) { + node.getIFrame().sendMessageToIframe(msg); + return true; + } + } + return false; + }, + patchStudy: function(studyChanges) { const matches = this.self().OwnPatch.filter(el => Object.keys(studyChanges).indexOf(el) !== -1); if (matches.length) { 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 53d605635e2..dbffeefed8e 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js @@ -92,5 +92,17 @@ qx.Class.define("osparc.vipMarket.Market", { } return false; }, + + sendCloseMessage: function() { + const store = osparc.store.Store.getInstance(); + const currentStudy = store.getCurrentStudy(); + const nodeId = this.getOpenBy(); + if (currentStudy && nodeId) { + const msg = { + "type": "closeMarket", + }; + currentStudy.sendMessageToIframe(nodeId, msg); + } + }, } }); diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js b/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js index 74a754693c2..c238f5618b8 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/MarketWindow.js @@ -41,6 +41,11 @@ qx.Class.define("osparc.vipMarket.MarketWindow", { if (osparc.product.Utils.showS4LStore()) { const storeWindow = new osparc.vipMarket.MarketWindow(nodeId, category); storeWindow.getVipMarket().addListener("importMessageSent", () => storeWindow.close()); + storeWindow.addListenerOnce("close", () => { + if (storeWindow.getVipMarket()) { + storeWindow.getVipMarket().sendCloseMessage(); + } + }); storeWindow.center(); storeWindow.open(); return storeWindow; diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js index 605a4c67f55..f7a0125f3c0 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js @@ -361,22 +361,17 @@ qx.Class.define("osparc.vipMarket.VipMarket", { }, __sendImportModelMessage: function(modelId) { + const store = osparc.store.Store.getInstance(); + const currentStudy = store.getCurrentStudy(); const nodeId = this.getOpenBy(); - if (nodeId) { - const store = osparc.store.Store.getInstance(); - const currentStudy = store.getCurrentStudy(); - if (!currentStudy) { - return; - } - const node = currentStudy.getWorkbench().getNode(nodeId); - if (node && node.getIFrame()) { - const msg = { - "type": "importModel", - "message": { - "modelId": modelId, - }, - }; - node.getIFrame().sendMessageToIframe(msg); + if (currentStudy && nodeId) { + const msg = { + "type": "importModel", + "message": { + "modelId": modelId, + }, + }; + if (currentStudy.sendMessageToIframe(nodeId, msg)) { this.fireEvent("importMessageSent"); } }