Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎨 [Frontend] Study (and Node) :size #7371

Merged
merged 21 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,19 @@ qx.Class.define("osparc.FlashMessenger", {
MAX_DISPLAYED: 3,

extractMessage: function(input, defaultMessage = "") {
const isValidString = val => {
return (
typeof val === "string" ||
(osparc.utils.Utils.isObject(val) && ("basename" in val) && (val.basename === "LocalizedString"))
);
}
if (input) {
if (typeof input === "string") {
if (isValidString(input)) {
return input;
} else if (osparc.utils.Utils.isObject(input) && "message" in input) {
if (typeof input["message"] === "string") {
if (isValidString(input["message"])) {
return input["message"];
} else if (osparc.utils.Utils.isObject(input["message"]) && "message" in input["message"] && typeof input["message"]["message"] === "string") {
} else if (osparc.utils.Utils.isObject(input["message"]) && "message" in input["message"] && isValidString(input["message"]["message"])) {
return input["message"]["message"];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const updatedStudyData = values[0];
const studyServices = values[1];
openButton.setFetching(false);
const updatableServices = osparc.metadata.ServicesInStudyUpdate.updatableNodeIds(updatedStudyData.workbench, studyServices["services"]);
const updatableServices = osparc.study.Utils.updatableNodeIds(updatedStudyData.workbench, studyServices["services"]);
if (updatableServices.length && osparc.data.model.Study.canIWrite(updatedStudyData["accessRights"])) {
this.__confirmUpdate();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,10 @@ qx.Class.define("osparc.data.Resources", {
method: "GET",
url: statics.API + "/storage/locations/{locationId}/paths?file_filter={path}&size=1000"
},
requestSize: {
method: "POST",
url: statics.API + "/storage/locations/0/paths/{pathId}:size"
},
}
},
/*
Expand All @@ -1230,6 +1234,26 @@ qx.Class.define("osparc.data.Resources", {
}
}
},
/*
* STORAGE ASYNC
*/
"storageAsyncJobs": {
useCache: false,
endpoints: {
jobStatus: {
method: "GET",
url: statics.API + "/storage/async-jobs/{jobId}/status"
},
jobResult: {
method: "GET",
url: statics.API + "/storage/async-jobs/{jobId}/result"
},
abortJob: {
method: "POST",
url: statics.API + "/storage/async-jobs/{jobId}/abort"
},
}
},
/*
* ACTIVITY
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ qx.Class.define("osparc.data.model.Node", {
},

initIframeHandler: function() {
if (this.isDynamic()) {
if (this.isDynamic() && this.__iframeHandler === null) {
this.__iframeHandler = new osparc.data.model.IframeHandler(this.getStudy(), this);
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* ************************************************************************

osparc - the simcore frontend

https://osparc.io

Copyright:
2025 IT'IS Foundation, https://itis.swiss

License:
MIT: https://opensource.org/licenses/MIT

Authors:
* Odei Maiz (odeimaiz)

************************************************************************ */

qx.Class.define("osparc.file.StorageAsyncJob", {
extend: qx.core.Object,

construct: function(jobId, interval = 1000) {
this.base(arguments);

this.setPollInterval(interval);

this.setJobId(jobId);
},

events: {
"resultReceived": "qx.event.type.Data",
"taskAborted": "qx.event.type.Event",
"pollingError": "qx.event.type.Data",
},

properties: {
pollInterval: {
check: "Number",
nullable: false,
init: 1000
},

jobId: {
check: "String",
nullable: false,
apply: "fetchStatus",
},
},

members: {
__retries: null,
__aborting: null,

fetchStatus: function() {
const jobId = this.getJobId();
osparc.data.Resources.fetch("storageAsyncJobs", "jobStatus", { url: { jobId } })
.then(status => {
if (this.__aborting) {
return;
}
if (status["done"]) {
this.__fetchResults();
} else {
setTimeout(() => this.fetchStatus(), this.getPollInterval());
}
})
.catch(err => {
if (this.__retries > 0) {
this.__retries--;
this.fetchStatus();
return;
}
this.fireDataEvent("pollingError", err);
});
},

__fetchResults: function() {
const jobId = this.getJobId();
osparc.data.Resources.fetch("storageAsyncJobs", "jobResult", { url: { jobId } })
.then(resp => {
this.fireDataEvent("resultReceived", resp["result"]);
})
.catch(err => {
console.error(err);
this.fireDataEvent("pollingError", err);
});
},

abortRequested: function() {
this.__aborting = true;
const jobId = this.getJobId();
osparc.data.Resources.fetch("storageAsyncJobs", "result", { url: { jobId } })
.then(() => this.fireEvent("taskAborted"))
.catch(err => {
throw err;
});
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,29 @@ qx.Class.define("osparc.file.TreeFolderView", {
_createChildControlImpl: function(id) {
let control;
switch (id) {
case "header-layout":
control = new qx.ui.container.Composite(new qx.ui.layout.HBox()).set({
marginLeft: 8
});
this._addAt(control, 0);
break;
case "reload-button":
control = new qx.ui.form.Button().set({
label: this.tr("Reload"),
font: "text-14",
icon: "@FontAwesome5Solid/sync-alt/14",
allowGrowX: false
});
this._add(control);
this.getChildControl("header-layout").add(control);
break;
case "total-size-label":
control = new qx.ui.basic.Atom().set({
label: this.tr("Calculating Size"),
font: "text-14",
icon: "@FontAwesome5Solid/spinner/14",
allowGrowX: false
});
this.getChildControl("header-layout").add(control);
break;
case "tree-folder-layout":
control = new qx.ui.splitpane.Pane("horizontal");
Expand Down Expand Up @@ -80,7 +95,6 @@ qx.Class.define("osparc.file.TreeFolderView", {
},

__buildLayout: function() {
this.getChildControl("reload-button");
const folderTree = this.getChildControl("folder-tree");
const folderViewer = this.getChildControl("folder-viewer");

Expand Down Expand Up @@ -146,6 +160,33 @@ qx.Class.define("osparc.file.TreeFolderView", {
} else {
folderViewer.resetFolder();
}
},

requestSize: function(pathId) {
const totalSize = this.getChildControl("total-size-label");
totalSize.getChildControl("icon").getContentElement().addClass("rotate");

osparc.data.Resources.fetch("storagePaths", "requestSize", { url: { pathId } })
.then(resp => {
const jobId = resp["job_id"];
if (jobId) {
const asyncJob = new osparc.file.StorageAsyncJob(jobId);
asyncJob.addListener("resultReceived", e => {
const size = e.getData();
totalSize.set({
icon: null,
label: this.tr("Total size: ") + osparc.utils.Utils.bytesToSize(size),
});
});
asyncJob.addListener("pollingError", e => {
totalSize.hide();
});
}
})
.catch(err => {
console.error(err);
totalSize.hide();
});
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,6 @@ qx.Class.define("osparc.metadata.ServicesInStudyUpdate", {
UPDATE_BUTTON: Object.keys(osparc.metadata.ServicesInStudy.GRID_POS).length+2
},

updatableNodeIds: function(workbench, studyServices) {
const nodeIds = [];
for (const nodeId in workbench) {
const node = workbench[nodeId];
const studyServiceFound = studyServices.find(studyService => studyService["key"] === node["key"] && studyService["release"]["version"] === node["version"]);
if (studyServiceFound && studyServiceFound["release"] && studyServiceFound["release"]["compatibility"]) {
nodeIds.push(nodeId);
}
}
return nodeIds;
},

colorVersionLabel: function(versionLabel, metadata) {
const isDeprecated = osparc.service.Utils.isDeprecated(metadata);
const isRetired = osparc.service.Utils.isRetired(metadata);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ qx.Class.define("osparc.store.Services", {
getLatestCompatible: function(key, version) {
const services = this.__servicesCached;
if (key in services && version in services[key]) {
const serviceMD = services[key][version];
if (serviceMD["compatibility"] && serviceMD["compatibility"]["canUpdateTo"]) {
const canUpdateTo = serviceMD["compatibility"]["canUpdateTo"];
const historyEntry = osparc.service.Utils.extractVersionFromHistory(services[key][version]);
if (historyEntry["compatibility"] && historyEntry["compatibility"]["canUpdateTo"]) {
const canUpdateTo = historyEntry["compatibility"]["canUpdateTo"];
return {
key: "key" in canUpdateTo ? canUpdateTo["key"] : key, // key is optional
version: canUpdateTo["version"]
Expand Down Expand Up @@ -240,7 +240,7 @@ qx.Class.define("osparc.store.Services", {
},

getStudyServicesMetadata: function(studyData) {
const wbServices = new Set(osparc.study.Utils.extractUniqueServices(studyData["workbench"]));
const wbServices = osparc.study.Utils.extractUniqueServices(studyData["workbench"]);
const promises = [];
wbServices.forEach(srv => {
promises.push(this.getService(srv["key"], srv["version"]));
Expand All @@ -251,7 +251,7 @@ qx.Class.define("osparc.store.Services", {
getInaccessibleServices: function(workbench) {
const allServices = this.__servicesCached;
const unaccessibleServices = [];
const wbServices = new Set(osparc.study.Utils.extractUniqueServices(workbench));
const wbServices = osparc.study.Utils.extractUniqueServices(workbench);
wbServices.forEach(srv => {
if (srv.key in allServices && srv.version in allServices[srv.key]) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ qx.Class.define("osparc.study.Utils", {
},

extractUniqueServices: function(workbench) {
const services = [];
const services = new Set([]);
Object.values(workbench).forEach(srv => {
services.push({
services.add({
key: srv.key,
version: srv.version
});
});
return services;
return Array.from(services);
},

getCantExecuteServices: function(studyServices = []) {
Expand Down Expand Up @@ -83,6 +83,18 @@ qx.Class.define("osparc.study.Utils", {
return isUpdatable;
},

updatableNodeIds: function(workbench, studyServices) {
const nodeIds = [];
for (const nodeId in workbench) {
const node = workbench[nodeId];
const studyServiceFound = studyServices.find(studyService => studyService["key"] === node["key"] && studyService["release"]["version"] === node["version"]);
if (studyServiceFound && studyServiceFound["release"] && studyServiceFound["release"]["compatibility"]) {
nodeIds.push(nodeId);
}
}
return nodeIds;
},


createStudyFromService: function(key, version, existingStudies, newStudyLabel, contextProps = {}) {
return new Promise((resolve, reject) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@ qx.Class.define("osparc.widget.StudyDataManager", {
const treeFolderView = this.getChildControl("tree-folder-view");
treeFolderView.getChildControl("folder-tree").setBackgroundColor("window-popup-background");

const reloadButton = treeFolderView.getChildControl("reload-button");
reloadButton.addListener("execute", () => this.__reloadTree(), this);

const selectedFileLayout = treeFolderView.getChildControl("folder-viewer").getChildControl("selected-file-layout");
selectedFileLayout.addListener("fileDeleted", e => this.__fileDeleted(e.getData()), this);
},
Expand All @@ -109,8 +106,10 @@ qx.Class.define("osparc.widget.StudyDataManager", {
foldersTree.resetCache();
if (this.getNodeId()) {
foldersTree.populateNodeTree(this.getStudyId(), this.getNodeId());
treeFolderView.requestSize(this.getStudyId(), this.getNodeId());
} else if (this.getStudyId()) {
foldersTree.populateStudyTree(this.getStudyId());
treeFolderView.requestSize(this.getStudyId());
}

const folderViewer = treeFolderView.getChildControl("folder-viewer");
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/tutorials/tutorialBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ class TutorialBase {

async openNodeFiles(nodeId) {
const pathFilter = `${this.__studyId}/${nodeId}`;
const path = "storage/locations/0/files/paths?file_filter=" + pathFilter;
const path = "storage/locations/0/paths?file_filter=" + pathFilter;
this.__responsesQueue.addResponseListener(path);
await auto.openNodeFiles(this.__page);
try {
Expand All @@ -459,7 +459,7 @@ class TutorialBase {

async openNodeFilesAppMode(nodeId) {
const pathFilter = `${this.__studyId}/${nodeId}`;
const path = "storage/locations/0/files/paths?file_filter=" + pathFilter;
const path = "storage/locations/0/paths?file_filter=" + pathFilter;
this.__responsesQueue.addResponseListener(path);
await auto.openNodeFilesAppMode(this.__page);
try {
Expand Down
Loading