diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/AppBrowser.js
similarity index 77%
rename from services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js
rename to services/static-webserver/client/source/class/osparc/dashboard/AppBrowser.js
index 50305eb14085..1aeea174faa5 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/AppBrowser.js
@@ -22,7 +22,7 @@
* @ignore(fetch)
*/
-qx.Class.define("osparc.dashboard.ServiceBrowser", {
+qx.Class.define("osparc.dashboard.AppBrowser", {
extend: osparc.dashboard.ResourceBrowserBase,
construct: function() {
@@ -43,8 +43,12 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
this._resourcesInitialized = true;
this._resourcesList = [];
- osparc.store.Services.getServicesLatest()
- .then(services => {
+ Promise.all([
+ osparc.store.Services.getServicesLatest(),
+ osparc.store.Templates.getTemplatesHypertools(),
+ ])
+ .then(resps => {
+ const services = resps[0];
// Show "Contact Us" message if services.length === 0
// Most probably is a product-stranger user (it can also be that the catalog is down)
if (Object.keys(services).length === 0) {
@@ -65,30 +69,52 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
reloadResources: function() {
this.__loadServices();
+ this.__loadHypertools();
},
__loadServices: function() {
const excludeFrontend = true;
const excludeDeprecated = true
osparc.store.Services.getServicesLatestList(excludeFrontend, excludeDeprecated)
- .then(servicesList => this.__setServicesToList(servicesList.filter(service => service !== null)));
+ .then(servicesList => {
+ servicesList.forEach(service => service["resourceType"] = "service");
+ this._resourcesList.push(...servicesList.filter(service => service !== null));
+ this.__sortAndReload();
+ });
+ },
+
+ __loadHypertools: function() {
+ osparc.store.Templates.getTemplatesHypertools()
+ .then(hypertoolsList => {
+ hypertoolsList.forEach(hypertool => hypertool["resourceType"] = "hypertool");
+ this._resourcesList.push(...hypertoolsList.filter(hypertool => hypertool !== null));
+ this.__sortAndReload();
+ });
+ },
+
+ __sortAndReload: function() {
+ osparc.service.Utils.sortObjectsBasedOn(this._resourcesList, this.__sortBy);
+ this._reloadCards();
},
_updateServiceData: function(serviceData) {
serviceData["resourceType"] = "service";
- const servicesList = this._resourcesList;
- const index = servicesList.findIndex(service => service["key"] === serviceData["key"] && service["version"] === serviceData["version"]);
+ const appsList = this._resourcesList;
+ const index = appsList.findIndex(service => service["key"] === serviceData["key"] && service["version"] === serviceData["version"]);
if (index !== -1) {
- servicesList[index] = serviceData;
+ appsList[index] = serviceData;
this._reloadCards();
}
},
- __setServicesToList: function(servicesList) {
- servicesList.forEach(service => service["resourceType"] = "service");
- osparc.service.Utils.sortObjectsBasedOn(servicesList, this.__sortBy);
- this._resourcesList = servicesList;
- this._reloadCards();
+ _updateHypertoolData: function(hypertoolData) {
+ hypertoolData["resourceType"] = "hypertool";
+ const appsList = this._resourcesList;
+ const index = appsList.findIndex(service => service["uuid"] === hypertoolData["uuid"]);
+ if (index !== -1) {
+ appsList[index] = hypertoolData;
+ this._reloadCards();
+ }
},
_reloadCards: function() {
@@ -103,8 +129,8 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
},
__itemClicked: function(card) {
- const serviceData = card.getResourceData();
- this._openResourceDetails(serviceData);
+ const appData = card.getResourceData();
+ this._openResourceDetails(appData);
this.resetSelection();
},
@@ -126,6 +152,28 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
return this._resourcesContainer;
},
+ __addSortingButtons: function() {
+ const containerSortButtons = new osparc.service.SortServicesButtons();
+ containerSortButtons.set({
+ appearance: "form-button-outlined"
+ });
+ containerSortButtons.addListener("sortBy", e => {
+ this.__sortBy = e.getData();
+ this.__sortAndReload();
+ }, this);
+ this._toolbar.add(containerSortButtons);
+ },
+
+ _populateCardMenu: function(card) {
+ const menu = card.getMenu();
+ const appData = card.getResourceData();
+
+ const openButton = this._getOpenMenuButton(appData);
+ if (openButton) {
+ menu.add(openButton);
+ }
+ },
+
__addNewServiceButtons: function() {
const platformName = osparc.store.StaticInfo.getInstance().getPlatformName();
const hasRights = osparc.data.Permissions.getInstance().canDo("studies.template.create.productAll");
@@ -140,7 +188,7 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
this._toolbar.add(testDataButton);
}
- const addServiceButton = new qx.ui.form.Button(this.tr("Submit new service"), "@FontAwesome5Solid/plus-circle/14");
+ const addServiceButton = new qx.ui.form.Button(this.tr("Submit new app"), "@FontAwesome5Solid/plus-circle/14");
addServiceButton.set({
appearance: "form-button-outlined",
visibility: hasRights ? "visible" : "excluded"
@@ -149,30 +197,8 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
this._toolbar.add(addServiceButton);
},
- __addSortingButtons: function() {
- const containerSortButtons = new osparc.service.SortServicesButtons();
- containerSortButtons.set({
- appearance: "form-button-outlined"
- });
- containerSortButtons.addListener("sortBy", e => {
- this.__sortBy = e.getData();
- this.__setServicesToList(this._resourcesList);
- }, this);
- this._toolbar.add(containerSortButtons);
- },
-
- _populateCardMenu: function(card) {
- const menu = card.getMenu();
- const serviceData = card.getResourceData();
-
- const openButton = this._getOpenMenuButton(serviceData);
- if (openButton) {
- menu.add(openButton);
- }
- },
-
__displayServiceSubmissionForm: function(formData) {
- const addServiceWindow = new osparc.ui.window.Window(this.tr("Submit a new service")).set({
+ const addServiceWindow = new osparc.ui.window.Window(this.tr("Submit a new app")).set({
modal: true,
autoDestroy: true,
showMinimize: false,
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js
index 63eead024d00..94338bb42b3b 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js
@@ -41,6 +41,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
"updateStudy": "qx.event.type.Data",
"updateTemplate": "qx.event.type.Data",
"updateService": "qx.event.type.Data",
+ "updateHypertool": "qx.event.type.Data",
"publishTemplate": "qx.event.type.Data",
"tagClicked": "qx.event.type.Data",
"emptyStudyClicked": "qx.event.type.Data"
@@ -160,10 +161,10 @@ qx.Class.define("osparc.dashboard.CardBase", {
return false;
},
- filterServiceType: function(resourceType, metadata, serviceType) {
- if (serviceType && resourceType === "service") {
+ filterAppType: function(resourceType, metadata, appType) {
+ if (appType && ["service", "hypertool"].includes(resourceType)) {
if (metadata && metadata.type) {
- const matches = metadata.type === serviceType;
+ const matches = metadata.type === appType;
return !matches;
}
return false;
@@ -221,11 +222,11 @@ qx.Class.define("osparc.dashboard.CardBase", {
const organizations = groupsStore.getOrganizations();
const myGroupId = groupsStore.getMyGroupId();
- const sharedGrps = [];
const groups = [];
groups.push(groupEveryone);
groups.push(groupProductEveryone);
groups.push(...Object.values(organizations));
+ const sharedGrps = [];
groups.forEach(group => {
const idx = gids.indexOf(group.getGroupId());
if (idx > -1) {
@@ -260,7 +261,10 @@ qx.Class.define("osparc.dashboard.CardBase", {
sharedGrpLabels.push("...");
break;
}
- const sharedGrpLabel = sharedGrps[i].getLabel();
+ let sharedGrpLabel = sharedGrps[i].getLabel();
+ if ([groupEveryone, groupProductEveryone].includes(sharedGrps[i])) {
+ sharedGrpLabel = "Public";
+ }
if (!sharedGrpLabels.includes(sharedGrpLabel)) {
sharedGrpLabels.push(sharedGrpLabel);
}
@@ -315,7 +319,12 @@ qx.Class.define("osparc.dashboard.CardBase", {
},
resourceType: {
- check: ["study", "template", "service"],
+ check: [
+ "study",
+ "template",
+ "service",
+ "hypertool",
+ ],
init: true,
nullable: true,
event: "changeResourceType"
@@ -506,11 +515,8 @@ qx.Class.define("osparc.dashboard.CardBase", {
let icon = null;
switch (resourceData["resourceType"]) {
case "study":
- uuid = resourceData.uuid ? resourceData.uuid : null;
- owner = resourceData.prjOwner ? resourceData.prjOwner : "";
- workbench = resourceData.workbench ? resourceData.workbench : {};
- break;
case "template":
+ case "hypertool":
uuid = resourceData.uuid ? resourceData.uuid : null;
owner = resourceData.prjOwner ? resourceData.prjOwner : "";
workbench = resourceData.workbench ? resourceData.workbench : {};
@@ -543,7 +549,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
workbench
});
- if (resourceData["resourceType"] === "study" || resourceData["resourceType"] === "template") {
+ if (["study", "template", "hypertool"].includes(resourceData["resourceType"])) {
osparc.store.Services.getStudyServices(resourceData.uuid)
.then(resp => {
const services = resp["services"];
@@ -993,7 +999,8 @@ qx.Class.define("osparc.dashboard.CardBase", {
[
"updateStudy",
"updateTemplate",
- "updateService"
+ "updateService",
+ "updateHypertool",
].forEach(ev => {
resourceDetails.addListener(ev, e => this.fireDataEvent(ev, e.getData()));
});
@@ -1045,6 +1052,8 @@ qx.Class.define("osparc.dashboard.CardBase", {
toolTipText += osparc.product.Utils.getStudyAlias();
} else if (this.isResourceType("template")) {
toolTipText += osparc.product.Utils.getTemplateAlias();
+ } else if (this.isResourceType("hypertool")) {
+ toolTipText += osparc.product.Utils.getAppAlias();
}
const control = new qx.ui.basic.Image().set({
source: "@FontAwesome5Solid/times-circle/14",
@@ -1103,10 +1112,10 @@ qx.Class.define("osparc.dashboard.CardBase", {
return this.self().filterSharedWith(checks, sharedWith);
},
- _filterServiceType: function(serviceType) {
+ __filterAppType: function(appType) {
const resourceType = this.getResourceType();
const resourceData = this.getResourceData();
- return this.self().filterServiceType(resourceType, resourceData, serviceType);
+ return this.self().filterAppType(resourceType, resourceData, appType);
},
_filterClassifiers: function(classifiers) {
@@ -1117,7 +1126,14 @@ qx.Class.define("osparc.dashboard.CardBase", {
_shouldApplyFilter: function(data) {
let filterId = "searchBarFilter";
if (this.isPropertyInitialized("resourceType")) {
- filterId += "-" + this.getResourceType();
+ switch (this.getResourceType()) {
+ case "hypertool":
+ filterId += "-service";
+ break;
+ default:
+ filterId += "-" + this.getResourceType();
+ break;
+ }
}
data = filterId in data ? data[filterId] : data;
if (this._filterText(data.text)) {
@@ -1129,7 +1145,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
if (this._filterSharedWith(data.sharedWith)) {
return true;
}
- if (this._filterServiceType(data.serviceType)) {
+ if (this.__filterAppType(data.appType)) {
return true;
}
if (this._filterClassifiers(data.classifiers)) {
@@ -1141,7 +1157,14 @@ qx.Class.define("osparc.dashboard.CardBase", {
_shouldReactToFilter: function(data) {
let filterId = "searchBarFilter";
if (this.isPropertyInitialized("resourceType")) {
- filterId += "-" + this.getResourceType();
+ switch (this.getResourceType()) {
+ case "hypertool":
+ filterId += "-service";
+ break;
+ default:
+ filterId += "-" + this.getResourceType();
+ break;
+ }
}
data = filterId in data ? data[filterId] : data;
if (data.text && data.text.length > 1) {
@@ -1153,7 +1176,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
if (data.sharedWith) {
return true;
}
- if ("serviceType" in data) {
+ if ("appType" in data) {
return true;
}
if (data.classifiers && data.classifiers.length) {
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js
index 63b9566d3540..7c600e351f7c 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js
@@ -19,7 +19,7 @@
* Widget containing a TabView including:
* - StudyBrowser
* - TemplateBrowser
- * - ServiceBrowser
+ * - AppBrowser
* - DataBrowser
*
* *Example*
@@ -79,8 +79,7 @@ qx.Class.define("osparc.dashboard.Dashboard", {
members: {
__studyBrowser: null,
__templateBrowser: null,
- __hypertoolBrowser: null,
- __serviceBrowser: null,
+ __appBrowser: null,
__dataBrowser: null,
getStudyBrowser: function() {
@@ -91,12 +90,8 @@ qx.Class.define("osparc.dashboard.Dashboard", {
return this.__templateBrowser;
},
- getHypertoolBrowser: function() {
- return this.__hypertoolBrowser;
- },
-
- getServiceBrowser: function() {
- return this.__serviceBrowser;
+ getAppBrowser: function() {
+ return this.__appBrowser;
},
__createMainViewLayout: function() {
@@ -123,24 +118,14 @@ qx.Class.define("osparc.dashboard.Dashboard", {
icon: "@FontAwesome5Solid/copy/"+tabIconSize,
buildLayout: this.__createTemplateBrowser
});
- if (osparc.product.Utils.isS4LProduct() && osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled()) {
- tabs.push({
- id: "hypertoolsTab",
- buttonId: "hypertoolsTabBtn",
- label: this.tr("HYPERTOOLS"),
- icon: "@FontAwesome5Solid/copy/"+tabIconSize,
- // initVisibility: "excluded",
- buildLayout: this.__createHypertoolsBrowser
- });
- }
}
if (permissions.canDo("dashboard.services.read")) {
tabs.push({
- id: "servicesTab",
- buttonId: "servicesTabBtn",
- label: this.tr("SERVICES"),
+ id: "appsTab",
+ buttonId: "appsTabBtn",
+ label: this.tr("APPS"),
icon: "@FontAwesome5Solid/cogs/"+tabIconSize,
- buildLayout: this.__createServiceBrowser
+ buildLayout: this.__createAppBrowser
});
}
if (permissions.canDo("dashboard.data.read")) {
@@ -152,7 +137,7 @@ qx.Class.define("osparc.dashboard.Dashboard", {
buildLayout: this.__createDataBrowser
});
}
- tabs.forEach(({id, buttonId, label, icon, initVisibility, buildLayout}) => {
+ tabs.forEach(({id, buttonId, label, icon, buildLayout}) => {
const tabPage = new qx.ui.tabview.Page(label, icon).set({
appearance: "dashboard-page"
});
@@ -161,7 +146,6 @@ qx.Class.define("osparc.dashboard.Dashboard", {
tabButton.set({
minWidth: 50,
maxHeight: 36,
- visibility: initVisibility ? initVisibility : "visible",
});
tabButton.ttt = label;
tabButton.getChildControl("label").set({
@@ -206,8 +190,8 @@ qx.Class.define("osparc.dashboard.Dashboard", {
if (this.__studyBrowser) {
this.__studyBrowser.initResources();
}
- if (this.__serviceBrowser) {
- this.__serviceBrowser.initResources();
+ if (this.__appBrowser) {
+ this.__appBrowser.initResources();
}
if (this.__dataBrowser) {
this.__dataBrowser.initResources();
@@ -233,15 +217,9 @@ qx.Class.define("osparc.dashboard.Dashboard", {
return templatesView;
},
- __createHypertoolsBrowser: function() {
- const templateType = osparc.data.model.StudyUI.HYPERTOOL_TYPE;
- const hypertoolsView = this.__hypertoolBrowser = new osparc.dashboard.TemplateBrowser(templateType);
- return hypertoolsView;
- },
-
- __createServiceBrowser: function() {
- const servicesView = this.__serviceBrowser = new osparc.dashboard.ServiceBrowser();
- return servicesView;
+ __createAppBrowser: function() {
+ const appsView = this.__appBrowser = new osparc.dashboard.AppBrowser();
+ return appsView;
},
__createDataBrowser: function() {
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js
index ad0bf2ec3ae7..10d755424cd8 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js
@@ -185,7 +185,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
// overridden
_applyLastChangeDate: function(value, old) {
if (value) {
- if (this.isResourceType("study") || this.isResourceType("template")) {
+ if (["study", "template", "hypertool"].includes(this.getResourceType())) {
const dateBy = this.getChildControl("date-by");
dateBy.set({
date: value,
@@ -198,7 +198,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
// overridden
_applyTrashedAt: function(value) {
if (value && value.getTime() !== new Date(0).getTime()) {
- if (this.isResourceType("study") || this.isResourceType("template")) {
+ if (["study", "template"].includes(this.getResourceType())) {
const dateBy = this.getChildControl("date-by");
dateBy.set({
date: value,
@@ -211,7 +211,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
// overridden
_applyTrashedBy: function(gid) {
if (gid) {
- if (this.isResourceType("study") || this.isResourceType("template")) {
+ if (["study", "template"].includes(this.getResourceType())) {
const dateBy = this.getChildControl("date-by");
dateBy.setGroupId(gid);
}
@@ -220,7 +220,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
__createOwner: function(label) {
if (label === osparc.auth.Data.getInstance().getEmail()) {
- const resourceAlias = osparc.utils.Utils.resourceTypeToAlias(this.getResourceType());
+ const resourceAlias = osparc.product.Utils.resourceTypeToAlias(this.getResourceType(), {firstUpperCase: true});
return qx.locale.Manager.tr(`My ${resourceAlias}`);
}
return osparc.utils.Utils.getNameFromEmail(label);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js
index 3cfb70d3b7d7..d79717bb8f72 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js
@@ -186,7 +186,7 @@ qx.Class.define("osparc.dashboard.ListButtonItem", {
// overridden
_applyLastChangeDate: function(value, old) {
if (value) {
- if (this.isResourceType("study") || this.isResourceType("template")) {
+ if (["study", "template", "hypertool"].includes(this.getResourceType())) {
const dateBy = this.getChildControl("date-by");
dateBy.set({
date: value,
@@ -199,7 +199,7 @@ qx.Class.define("osparc.dashboard.ListButtonItem", {
// overridden
_applyTrashedAt: function(value) {
if (value && value.getTime() !== new Date(0).getTime()) {
- if (this.isResourceType("study") || this.isResourceType("template")) {
+ if (["study", "template"].includes(this.getResourceType())) {
const dateBy = this.getChildControl("date-by");
dateBy.set({
date: value,
@@ -212,7 +212,7 @@ qx.Class.define("osparc.dashboard.ListButtonItem", {
// overridden
_applyTrashedBy: function(gid) {
if (gid) {
- if (this.isResourceType("study") || this.isResourceType("template")) {
+ if (["study", "template"].includes(this.getResourceType())) {
const dateBy = this.getChildControl("date-by");
dateBy.setGroupId(gid);
}
@@ -221,7 +221,7 @@ qx.Class.define("osparc.dashboard.ListButtonItem", {
__createOwner: function(label) {
if (label === osparc.auth.Data.getInstance().getEmail()) {
- const resourceAlias = osparc.utils.Utils.resourceTypeToAlias(this.getResourceType());
+ const resourceAlias = osparc.product.Utils.resourceTypeToAlias(this.getResourceType(), {firstUpperCase: true});
return qx.locale.Manager.tr(`My ${resourceAlias}`);
}
return osparc.utils.Utils.getNameFromEmail(label);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js b/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js
index 3e4592eac750..f75eb12cedf2 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js
@@ -160,12 +160,10 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
__addItems: function() {
this.__addUIConfigItems();
- if (osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled()) {
- if (osparc.product.Utils.isS4LProduct()) {
- this.__addHypertools();
- }
- this.__addOtherTabsAccess();
+ if (osparc.product.Utils.isS4LProduct()) {
+ this.__addHypertools();
}
+ this.__addOtherTabsAccess();
this.getChildControl("new-folder");
},
@@ -235,7 +233,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
if (permissions.canDo("dashboard.services.read")) {
const servicesButton = this.self().createMenuButton("@FontAwesome5Solid/cog/16", this.tr("Services..."));
- servicesButton.addListener("execute", () => this.fireDataEvent("changeTab", "servicesTab"), this);
+ servicesButton.addListener("execute", () => this.fireDataEvent("changeTab", "appsTab"), this);
moreMenu.add(servicesButton);
}
moreMenuButton.setVisibility(moreMenu.getChildren().length ? "visible" : "excluded");
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
index d244902d3511..5ff218af4518 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
@@ -288,6 +288,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
resourcesContainer.addListener("updateStudy", e => this._updateStudyData(e.getData()));
resourcesContainer.addListener("updateTemplate", e => this._updateTemplateData(e.getData()));
resourcesContainer.addListener("updateService", e => this._updateServiceData(e.getData()));
+ resourcesContainer.addListener("updateHypertool", e => this._updateHypertoolData(e.getData()));
resourcesContainer.addListener("publishTemplate", e => this.fireDataEvent("publishTemplate", e.getData()));
resourcesContainer.addListener("tagClicked", e => this._searchBarFilter.addTagActiveFilter(e.getData()));
resourcesContainer.addListener("emptyStudyClicked", e => this._deleteResourceRequested(e.getData()));
@@ -411,7 +412,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
},
_addResourceFilter: function() {
- const resourceFilter = this._resourceFilter = new osparc.dashboard.ResourceFilter(this._resourceType).set({
+ const resourceFilter = this._resourceFilter = new osparc.dashboard.ResourceBrowserFilter(this._resourceType).set({
marginTop: 20,
maxWidth: this.self().SIDE_SPACER_WIDTH,
width: this.self().SIDE_SPACER_WIDTH
@@ -432,9 +433,9 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
this._searchBarFilter.setTagsActiveFilter(selectedTagIds);
}, this);
- resourceFilter.addListener("changeServiceType", e => {
- const serviceType = e.getData();
- this._searchBarFilter.setServiceTypeActiveFilter(serviceType.id, serviceType.label);
+ resourceFilter.addListener("changeAppType", e => {
+ const appType = e.getData();
+ this._searchBarFilter.setAppTypeActiveFilter(appType.appType, appType.label);
}, this);
this._searchBarFilter.addListener("filterChanged", e => {
@@ -529,6 +530,10 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
throw new Error("Abstract method called!");
},
+ _updateHypertoolData: function(serviceData) {
+ throw new Error("Abstract method called!");
+ },
+
_startStudyById: function(studyId, openCB, cancelCB, isStudyCreation = false) {
if (isStudyCreation) {
this.fireDataEvent("changeTab", "studiesTab");
@@ -744,6 +749,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
break;
}
case "template":
+ case "hypertool":
this._createStudyFromTemplate(resourceData);
break;
case "service":
@@ -760,6 +766,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
resourceDetails.addListener("updateStudy", e => this._updateStudyData(e.getData()));
resourceDetails.addListener("updateTemplate", e => this._updateTemplateData(e.getData()));
resourceDetails.addListener("updateService", e => this._updateServiceData(e.getData()));
+ resourceDetails.addListener("updateHypertool", e => this._updateHypertoolData(e.getData()));
resourceDetails.addListener("publishTemplate", e => {
win.close();
this.fireDataEvent("publishTemplate", e.getData());
@@ -775,6 +782,11 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
const templateData = e.getData();
this._createStudyFromTemplate(templateData);
});
+ resourceDetails.addListener("openHypertool", e => {
+ win.close();
+ const templateData = e.getData();
+ this._createStudyFromTemplate(templateData);
+ });
resourceDetails.addListener("openService", e => {
win.close();
const openServiceData = e.getData();
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserFilter.js
similarity index 75%
rename from services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js
rename to services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserFilter.js
index 352e45955a6d..29a98376cf71 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserFilter.js
@@ -16,7 +16,7 @@
************************************************************************ */
-qx.Class.define("osparc.dashboard.ResourceFilter", {
+qx.Class.define("osparc.dashboard.ResourceBrowserFilter", {
extend: qx.ui.core.Widget,
construct: function(resourceType) {
@@ -27,7 +27,7 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
this.__resourceType = resourceType;
this.__sharedWithButtons = [];
this.__tagButtons = [];
- this.__serviceTypeButtons = [];
+ this.__appTypeButtons = [];
this._setLayout(new qx.ui.layout.VBox(15));
this.__buildLayout();
@@ -40,7 +40,7 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
"trashFolderRequested": "qx.event.type.Data",
"changeSharedWith": "qx.event.type.Data",
"changeSelectedTags": "qx.event.type.Data",
- "changeServiceType": "qx.event.type.Data"
+ "changeAppType": "qx.event.type.Data",
},
members: {
@@ -49,7 +49,7 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
__trashButton: null,
__sharedWithButtons: null,
__tagButtons: null,
- __serviceTypeButtons: null,
+ __appTypeButtons: null,
__buildLayout: function() {
const filtersSpacer = new qx.ui.core.Spacer(10, 10);
@@ -57,7 +57,6 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
case "study": {
this._add(this.__createWorkspacesAndFoldersTree());
this._add(this.__createTrashBin());
- // this._add(this.__createResourceTypeContextButtons());
this._add(filtersSpacer);
const scrollView = new qx.ui.container.Scroll();
scrollView.add(this.__createTagsFilterLayout());
@@ -67,7 +66,6 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
break;
}
case "template": {
- // this._add(this.__createResourceTypeContextButtons());
this._add(filtersSpacer);
this._add(this.__createSharedWithFilterLayout());
const scrollView = new qx.ui.container.Scroll();
@@ -78,10 +76,9 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
break;
}
case "service":
- // this._add(this.__createResourceTypeContextButtons());
this._add(filtersSpacer);
this._add(this.__createSharedWithFilterLayout());
- this._add(this.__createServiceTypeFilterLayout());
+ this._add(this.__createAppTypeFilterLayout());
break;
}
},
@@ -222,91 +219,6 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
},
/* /TRASH BIN */
- /* RESOURCE TYPE CONTEXT */
- __createResourceTypeContextButtons: function() {
- const resourceTypeContextButtons = new qx.ui.container.Composite(new qx.ui.layout.VBox(2));
-
- const studiesButton = this.__createStudiesButton().set({
- value: this.__resourceType === "study",
- visibility: this.__resourceType === "study" ? "excluded" : "visible",
- });
- resourceTypeContextButtons.add(studiesButton);
-
- const permissions = osparc.data.Permissions.getInstance();
- const templatesButton = this.__createTemplatesButton().set({
- value: this.__resourceType === "template",
- });
- if (permissions.canDo("dashboard.templates.read")) {
- resourceTypeContextButtons.add(templatesButton);
- }
-
- const servicesButton = this.__createServicesButton().set({
- value: this.__resourceType === "service",
- });
- if (permissions.canDo("dashboard.services.read")) {
- resourceTypeContextButtons.add(servicesButton);
- }
-
- return resourceTypeContextButtons;
- },
-
- __createStudiesButton: function() {
- const studyAlias = osparc.product.Utils.getStudyAlias({
- firstUpperCase: true,
- plural: true
- });
- const studiesButton = new qx.ui.toolbar.RadioButton().set({
- value: false,
- appearance: "filter-toggle-button",
- label: studyAlias,
- icon: "@FontAwesome5Solid/file/16",
- paddingLeft: 10, // align it with the context
- });
- osparc.utils.Utils.setIdToWidget(studiesButton, "studiesTabBtn");
- studiesButton.addListener("tap", () => {
- studiesButton.setValue(this.__resourceType === "study");
- this.fireDataEvent("changeTab", "studiesTab");
- });
- return studiesButton;
- },
-
- __createTemplatesButton: function() {
- const templateAlias = osparc.product.Utils.getTemplateAlias({
- firstUpperCase: true,
- plural: true
- });
- const templatesButton = new qx.ui.toolbar.RadioButton().set({
- value: false,
- appearance: "filter-toggle-button",
- label: templateAlias,
- icon: "@FontAwesome5Solid/copy/16",
- paddingLeft: 10, // align it with the context
- });
- osparc.utils.Utils.setIdToWidget(templatesButton, "templatesTabBtn");
- templatesButton.addListener("tap", () => {
- templatesButton.setValue(this.__resourceType === "template");
- this.fireDataEvent("changeTab", "templatesTab");
- });
- return templatesButton;
- },
-
- __createServicesButton: function() {
- const servicesButton = new qx.ui.toolbar.RadioButton().set({
- value: false,
- appearance: "filter-toggle-button",
- label: this.tr("Services"),
- icon: "@FontAwesome5Solid/cogs/16",
- paddingLeft: 10, // align it with the context
- });
- osparc.utils.Utils.setIdToWidget(servicesButton, "servicesTabBtn");
- servicesButton.addListener("tap", () => {
- servicesButton.setValue(this.__resourceType === "service");
- this.fireDataEvent("changeTab", "servicesTab");
- });
- return servicesButton;
- },
- /* /RESOURCE TYPE CONTEXT */
-
/* SHARED WITH */
__createSharedWithFilterLayout: function() {
const sharedWithLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(2));
@@ -442,39 +354,44 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
/* /TAGS */
/* SERVICE TYPE */
- __createServiceTypeFilterLayout: function() {
+ __createAppTypeFilterLayout: function() {
const layout = new qx.ui.container.Composite(new qx.ui.layout.VBox(2));
const radioGroup = new qx.ui.form.RadioGroup();
radioGroup.setAllowEmptySelection(true);
+ const iconSize = 20;
const serviceTypes = osparc.service.Utils.TYPES;
Object.keys(serviceTypes).forEach(serviceId => {
if (!["computational", "dynamic"].includes(serviceId)) {
return;
}
const serviceType = serviceTypes[serviceId];
- const iconSize = 20;
const button = new qx.ui.toolbar.RadioButton(serviceType.label, serviceType.icon+iconSize);
- button.id = serviceId;
+ button.appType = serviceId;
osparc.utils.Utils.setIdToWidget(button, this.__resourceType + "-serviceTypeFilterItem");
- button.set({
+ this.__appTypeButtons.push(button);
+ });
+
+ // hypertools filter
+ const button = new qx.ui.toolbar.RadioButton("Hypertools", "@FontAwesome5Solid/wrench/"+iconSize);
+ button.appType = "hypertool";
+ this.__appTypeButtons.push(button);
+
+ this.__appTypeButtons.forEach(btn => {
+ btn.set({
appearance: "filter-toggle-button",
value: false
});
-
- layout.add(button);
- radioGroup.add(button);
-
- button.addListener("execute", () => {
- const checked = button.getValue();
- this.fireDataEvent("changeServiceType", {
- id: checked ? serviceId : null,
- label: checked ? serviceType.label : null
+ layout.add(btn);
+ radioGroup.add(btn);
+ btn.addListener("execute", () => {
+ const checked = btn.getValue();
+ this.fireDataEvent("changeAppType", {
+ appType: checked ? btn.appType : null,
+ label: checked ? btn.getLabel() : null
});
}, this);
-
- this.__serviceTypeButtons.push(button);
});
return layout;
@@ -493,9 +410,9 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
btn.setValue(filterData["tags"].includes(btn.id));
});
}
- if ("serviceType" in filterData) {
- this.__serviceTypeButtons.forEach(btn => {
- btn.setValue(filterData["serviceType"] === btn.id);
+ if ("appType" in filterData) {
+ this.__appTypeButtons.forEach(btn => {
+ btn.setValue(filterData["appType"] === btn.appType);
});
}
}
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js
index 6f89b6abd086..6ca49e333c83 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js
@@ -66,6 +66,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", {
"updateStudy": "qx.event.type.Data",
"updateTemplate": "qx.event.type.Data",
"updateService": "qx.event.type.Data",
+ "updateHypertool": "qx.event.type.Data",
"publishTemplate": "qx.event.type.Data",
"tagClicked": "qx.event.type.Data",
"emptyStudyClicked": "qx.event.type.Data",
@@ -238,6 +239,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", {
"updateStudy",
"updateTemplate",
"updateService",
+ "updateHypertool",
"publishTemplate",
"tagClicked",
"emptyStudyClicked"
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
index d543206295de..d066ff1ab103 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
@@ -26,7 +26,8 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
let latestPromise = null;
switch (resourceData["resourceType"]) {
case "study":
- case "template": {
+ case "template":
+ case "hypertool": {
const params = {
url: {
"studyId": resourceData["uuid"]
@@ -47,7 +48,8 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
this.__resourceData["resourceType"] = resourceData["resourceType"];
switch (resourceData["resourceType"]) {
case "study":
- case "template": {
+ case "template":
+ case "hypertool":
osparc.store.Services.getStudyServicesMetadata(latestResourceData)
.finally(() => {
this.__resourceModel = new osparc.data.model.Study(latestResourceData);
@@ -56,7 +58,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
this.__addPages();
})
break;
- }
case "service": {
this.__resourceModel = new osparc.data.model.Service(latestResourceData);
this.__resourceModel["resourceType"] = resourceData["resourceType"];
@@ -71,10 +72,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
events: {
"pagesAdded": "qx.event.type.Event",
"openTemplate": "qx.event.type.Data",
+ "openHypertool": "qx.event.type.Data",
"openService": "qx.event.type.Data",
"updateStudy": "qx.event.type.Data",
"updateTemplate": "qx.event.type.Data",
"updateService": "qx.event.type.Data",
+ "updateHypertool": "qx.event.type.Data",
"publishTemplate": "qx.event.type.Data",
},
@@ -85,7 +88,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
popUpInWindow: function(resourceDetails) {
// eslint-disable-next-line no-underscore-dangle
- const resourceAlias = osparc.utils.Utils.resourceTypeToAlias(resourceDetails.__resourceData["resourceType"]);
+ const resourceAlias = osparc.product.Utils.resourceTypeToAlias(resourceDetails.__resourceData["resourceType"], {firstUpperCase: true});
// eslint-disable-next-line no-underscore-dangle
const title = `${resourceAlias} ${qx.locale.Manager.tr("Details")} - ${resourceDetails.__resourceData.name}`;
const win = osparc.ui.window.Window.popUpInWindow(resourceDetails, title, this.WIDTH, this.HEIGHT).set({
@@ -240,6 +243,9 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
case "template":
this.fireDataEvent("openTemplate", this.__resourceData);
break;
+ case "hypertool":
+ this.fireDataEvent("openHypertool", this.__resourceData);
+ break;
case "service":
this.fireDataEvent("openService", this.__resourceData);
break;
@@ -382,6 +388,23 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
this.fireEvent("pagesAdded");
},
+ __fireUpdateEvent: function(resourceData, updatedData) {
+ switch (resourceData["resourceType"]) {
+ case "study":
+ this.fireDataEvent("updateStudy", updatedData);
+ break;
+ case "template":
+ this.fireDataEvent("updateTemplate", updatedData);
+ break;
+ case "hypertool":
+ this.fireDataEvent("updateHypertool", updatedData);
+ break;
+ case "service":
+ this.fireDataEvent("updateService", updatedData);
+ break;
+ }
+ },
+
__getInfoPage: function() {
const id = "Information";
const title = this.tr("Overview");
@@ -397,19 +420,13 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
infoCard = new osparc.info.ServiceLarge(resourceData, null, false);
infoCard.addListener("updateService", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isService(resourceData)) {
- this.fireDataEvent("updateService", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
});
} else {
infoCard = new osparc.info.StudyLarge(resourceModel, false);
infoCard.addListener("updateStudy", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
});
infoCard.addListener("openTags", () => this.openTags());
}
@@ -545,9 +562,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
collaboratorsView = new osparc.share.CollaboratorsService(resourceData);
collaboratorsView.addListener("updateAccessRights", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isService(resourceData)) {
- this.fireDataEvent("updateService", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
}, this);
} else {
collaboratorsView = new osparc.share.CollaboratorsStudy(resourceData);
@@ -558,11 +573,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
}
collaboratorsView.addListener("updateAccessRights", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
}, this);
}
page.addToContent(collaboratorsView);
@@ -595,13 +606,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
classifiers = new osparc.metadata.ClassifiersEditor(resourceData);
classifiers.addListener("updateClassifiers", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- } else if (osparc.utils.Resources.isService(resourceData)) {
- this.fireDataEvent("updateService", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
}, this);
} else {
classifiers = new osparc.metadata.ClassifiersViewer(resourceData);
@@ -633,11 +638,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const qualityEditor = new osparc.metadata.QualityEditor(resourceData);
qualityEditor.addListener("updateQuality", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- }
+ this.__fireUpdateEvent(updatedData);
});
page.addToContent(qualityEditor);
}
@@ -668,11 +669,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
tagManager.addListener("updateTags", e => {
const updatedData = e.getData();
tagManager.setStudyData(updatedData);
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
}, this);
page.addToContent(tagManager);
}
@@ -703,11 +700,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const servicesUpdate = new osparc.metadata.ServicesInStudyUpdate(resourceData);
servicesUpdate.addListener("updateService", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
});
page.addToContent(servicesUpdate);
}
@@ -741,11 +734,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const servicesBootOpts = new osparc.metadata.ServicesInStudyBootOpts(resourceData);
servicesBootOpts.addListener("updateService", e => {
const updatedData = e.getData();
- if (osparc.utils.Resources.isStudy(resourceData)) {
- this.fireDataEvent("updateStudy", updatedData);
- } else if (osparc.utils.Resources.isTemplate(resourceData)) {
- this.fireDataEvent("updateTemplate", updatedData);
- }
+ this.__fireUpdateEvent(resourceData, updatedData);
});
page.addToContent(servicesBootOpts);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js
index 062c963ef8f2..5886834d6ad0 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js
@@ -45,6 +45,9 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
HEIGHT: 36,
getSharedWithOptions: function(resourceType) {
+ if (resourceType === "service") {
+ resourceType = "app";
+ }
return [{
id: "show-all",
label: qx.locale.Manager.tr("All") + " " + osparc.product.Utils.resourceTypeToAlias(resourceType, {
@@ -147,7 +150,7 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
this.__addSharedWith(sharedWithButton);
menu.add(sharedWithButton);
- if (this.__resourceType !== "service") {
+ if (["study", "template"].includes(this.__resourceType)) {
const tagsButton = new qx.ui.menu.Button(this.tr("Tags"), "@FontAwesome5Solid/tags/12");
osparc.utils.Utils.setIdToWidget(tagsButton, "searchBarFilter-tags-button");
this.__addTags(tagsButton);
@@ -159,9 +162,9 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
}
if (this.__resourceType === "service") {
- const serviceTypeButton = new qx.ui.menu.Button(this.tr("Service Type"), "@FontAwesome5Solid/cogs/12");
- this.__addServiceTypes(serviceTypeButton);
- menu.add(serviceTypeButton);
+ const appTypeButton = new qx.ui.menu.Button(this.tr("App Type"), "@FontAwesome5Solid/cogs/12");
+ this.__addAppTypes(appTypeButton);
+ menu.add(appTypeButton);
}
},
@@ -258,20 +261,26 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
}
},
- __addServiceTypes: function(menuButton) {
+ __addAppTypes: function(menuButton) {
const serviceTypeMenu = new qx.ui.menu.Menu();
menuButton.setMenu(serviceTypeMenu);
+
+ const iconSize = 12;
const serviceTypes = osparc.service.Utils.TYPES;
Object.keys(serviceTypes).forEach(serviceId => {
if (!["computational", "dynamic"].includes(serviceId)) {
return;
}
const serviceType = serviceTypes[serviceId];
- const iconSize = 12;
const serviceTypeButton = new qx.ui.menu.Button(serviceType.label, serviceType.icon+iconSize);
serviceTypeMenu.add(serviceTypeButton);
- serviceTypeButton.addListener("execute", () => this.__addChip("service-type", serviceId, serviceType.label), this);
+ serviceTypeButton.addListener("execute", () => this.__addChip("app-type", serviceId, serviceType.label), this);
});
+
+ // hypertools filter
+ const hypertoolTypeButton = new qx.ui.menu.Button("Hypertools", "@FontAwesome5Solid/wrench/"+iconSize);
+ serviceTypeMenu.add(hypertoolTypeButton);
+ hypertoolTypeButton.addListener("execute", () => this.__addChip("app-type", "hypertool", "Hypertools"), this);
},
addTagActiveFilter: function(tag) {
@@ -300,10 +309,10 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
}
},
- setServiceTypeActiveFilter: function(optionId, optionLabel) {
- this.__removeChips("service-type");
- if (optionId && optionLabel) {
- this.__addChip("service-type", optionId, optionLabel);
+ setAppTypeActiveFilter: function(appType, optionLabel) {
+ this.__removeChips("app-type");
+ if (appType && optionLabel) {
+ this.__addChip("app-type", appType, optionLabel);
} else {
this.__filter();
}
@@ -369,7 +378,7 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
tags: [],
classifiers: [],
sharedWith: null,
- serviceType: null,
+ appType: null,
text: ""
};
const textFilter = this.getTextFilterValue();
@@ -385,8 +394,8 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", {
case "shared-with":
filterData.sharedWith = chip.id === "show-all" ? null : chip.id;
break;
- case "service-type":
- filterData.serviceType = chip.id;
+ case "app-type":
+ filterData.appType = chip.id;
break;
}
});
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
index 27d9e6ec4112..e08c03584069 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
@@ -1516,10 +1516,8 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
const duplicateStudyButton = this.__getDuplicateMenuButton(studyData);
menu.add(duplicateStudyButton);
- if (osparc.product.Utils.hasConvertToPipelineEnabled()) {
- const convertToPipelineButton = this.__getConvertToPipelineMenuButton(studyData);
- menu.add(convertToPipelineButton);
- }
+ const convertToPipelineButton = this.__getConvertToPipelineMenuButton(studyData);
+ menu.add(convertToPipelineButton);
if (osparc.product.Utils.hasExportCMisEnabled()) {
const exportStudyButton = this.__getExportCMisMenuButton(studyData);
diff --git a/services/static-webserver/client/source/class/osparc/data/SubJob.js b/services/static-webserver/client/source/class/osparc/data/SubJob.js
index e6143c2dc5db..6642827635a5 100644
--- a/services/static-webserver/client/source/class/osparc/data/SubJob.js
+++ b/services/static-webserver/client/source/class/osparc/data/SubJob.js
@@ -24,12 +24,14 @@ qx.Class.define("osparc.data.SubJob", {
this.set({
projectUuid: subJobData["projectUuid"],
nodeId: subJobData["nodeId"],
- nodeName: subJobData["nodeId"],
+ nodeName: subJobData["nodeName"],
state: subJobData["state"],
progress: subJobData["progress"],
startedAt: subJobData["startedAt"] ? new Date(subJobData["startedAt"]) : null,
endedAt: subJobData["endedAt"] ? new Date(subJobData["endedAt"]) : null,
+ osparcCredits: subJobData["osparcCredits"] || null,
image: subJobData["image"] || {},
+ logDownloadLink: subJobData["logDownloadLink"] || null,
});
},
@@ -76,11 +78,23 @@ qx.Class.define("osparc.data.SubJob", {
nullable: true,
},
+ osparcCredits: {
+ check: "Number",
+ nullable: true,
+ init: null,
+ },
+
image: {
check: "Object",
nullable: false,
init: null,
},
+
+ logDownloadLink: {
+ check: "String",
+ nullable: true,
+ init: null,
+ },
},
members: {
diff --git a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js
index 8204b8250d1b..6d6095b2d4aa 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js
@@ -27,7 +27,7 @@
* - Dashboard Stack
* - StudyBrowser
* - TemplateBrowser
- * - ServiceBrowser
+ * - AppBrowser
* - DataManager
* - StudyEditor
*
@@ -69,9 +69,7 @@ qx.Class.define("osparc.desktop.MainPage", {
preloadPromises.push(osparc.store.Tags.getInstance().fetchTags());
preloadPromises.push(osparc.store.Products.getInstance().fetchUiConfig());
preloadPromises.push(osparc.store.PollTasks.getInstance().fetchTasks());
- if (osparc.utils.DisabledPlugins.isJobsEnabled()) {
- preloadPromises.push(osparc.store.Jobs.getInstance().fetchJobs());
- }
+ preloadPromises.push(osparc.store.Jobs.getInstance().fetchJobs());
Promise.all(preloadPromises)
.then(() => {
const mainStack = this.__createMainStack();
@@ -251,7 +249,7 @@ qx.Class.define("osparc.desktop.MainPage", {
pollTasks.createPollingTask(fetchPromise)
.then(task => {
const templateBrowser = this.__dashboard.getTemplateBrowser();
- const hypertoolBrowser = this.__dashboard.getHypertoolBrowser();
+ const appBrowser = this.__dashboard.getAppBrowser();
if (templateBrowser) {
templateBrowser.taskToTemplateReceived(task, studyName);
}
@@ -267,8 +265,9 @@ qx.Class.define("osparc.desktop.MainPage", {
if (templateBrowser) {
templateBrowser.reloadResources();
}
- if (hypertoolBrowser) {
- hypertoolBrowser.reloadResources();
+ if (appBrowser) {
+ // OM: reload hypertools only
+ appBrowser.reloadResources();
}
});
}
diff --git a/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js b/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js
index b7021976228b..ade394646951 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js
@@ -438,18 +438,16 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
this.__addTopBarSpacer(topBar);
- if (osparc.utils.DisabledPlugins.isConversationEnabled()) {
- const commentsButton = new qx.ui.form.Button().set({
- appearance: "form-button-outlined",
- toolTipText: this.tr("Conversations"),
- icon: "@FontAwesome5Solid/comments/16",
- marginRight: 10,
- marginTop: 7,
- ...osparc.navigation.NavigationBar.BUTTON_OPTIONS
- });
- commentsButton.addListener("execute", () => osparc.study.Conversations.popUpInWindow(study.serialize()));
- topBar.add(commentsButton);
- }
+ const commentsButton = new qx.ui.form.Button().set({
+ appearance: "form-button-outlined",
+ toolTipText: this.tr("Conversations"),
+ icon: "@FontAwesome5Solid/comments/16",
+ marginRight: 10,
+ marginTop: 7,
+ ...osparc.navigation.NavigationBar.BUTTON_OPTIONS
+ });
+ commentsButton.addListener("execute", () => osparc.study.Conversations.popUpInWindow(study.serialize()));
+ topBar.add(commentsButton);
const startAppButtonTB = this.__startAppButtonTB = new qx.ui.form.Button().set({
appearance: "form-button-outlined",
diff --git a/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js b/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js
index d87c450c2de4..6a9274cea418 100644
--- a/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js
+++ b/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js
@@ -15,6 +15,7 @@ qx.Class.define("osparc.filter.CollaboratorToggleButton", {
construct: function(collaborator) {
this.base(arguments);
+
this._setLayout(new qx.ui.layout.HBox(8).set({
alignY: "middle"
}));
@@ -23,11 +24,15 @@ qx.Class.define("osparc.filter.CollaboratorToggleButton", {
appearance: "tagbutton"
});
- let label = collaborator.getLabel();
- if ("getEmail" in collaborator && collaborator.getEmail()) {
- label += ` (${collaborator.getEmail()})`;
+ if (collaborator["collabType"] === 0) {
+ this.setLabel(this.tr("Public"));
+ } else {
+ let label = collaborator.getLabel();
+ if ("getEmail" in collaborator && collaborator.getEmail()) {
+ label += ` (${collaborator.getEmail()})`;
+ }
+ this.setLabel(label);
}
- this.setLabel(label);
if (collaborator.getDescription()) {
const ttt = collaborator.getLabel() + "
" + collaborator.getDescription();
diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsWindow.js b/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js
similarity index 70%
rename from services/static-webserver/client/source/class/osparc/jobs/RunsWindow.js
rename to services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js
index f10b604ebdfd..cd56d3198f6d 100644
--- a/services/static-webserver/client/source/class/osparc/jobs/RunsWindow.js
+++ b/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js
@@ -15,11 +15,11 @@
************************************************************************ */
-qx.Class.define("osparc.jobs.RunsWindow", {
+qx.Class.define("osparc.jobs.ActivityCenterWindow", {
extend: osparc.ui.window.SingletonWindow,
construct: function() {
- this.base(arguments, "runs", this.tr("Runs and Clusters"));
+ this.base(arguments, "runs", this.tr("Activity Center"));
this.set({
layout: new qx.ui.layout.VBox(),
@@ -35,7 +35,7 @@ qx.Class.define("osparc.jobs.RunsWindow", {
statics: {
openWindow: function() {
- const runsWindow = new osparc.jobs.RunsWindow();
+ const runsWindow = new osparc.jobs.ActivityCenterWindow();
runsWindow.center();
runsWindow.open();
return runsWindow;
@@ -49,12 +49,12 @@ qx.Class.define("osparc.jobs.RunsWindow", {
flex: 1
});
- const runsAndClusters = new osparc.jobs.RunsAndClusters();
+ const runsBrowser = new osparc.jobs.RunsBrowser();
const subRunsBrowser = new osparc.jobs.SubRunsBrowser();
- stack.add(runsAndClusters);
+ stack.add(runsBrowser);
stack.add(subRunsBrowser);
- runsAndClusters.addListener("runSelected", e => {
+ runsBrowser.addListener("runSelected", e => {
const project = e.getData();
subRunsBrowser.setProject(project);
this.getChildControl("title").setValue(this.tr("Runs"));
@@ -62,13 +62,13 @@ qx.Class.define("osparc.jobs.RunsWindow", {
});
subRunsBrowser.addListener("backToRuns", () => {
- runsAndClusters.getChildControl("runs-browser").reloadRuns();
- this.getChildControl("title").setValue(this.tr("Runs and Clusters"));
- stack.setSelection([runsAndClusters]);
+ runsBrowser.reloadRuns();
+ this.getChildControl("title").setValue(this.tr("Activity Center"));
+ stack.setSelection([runsBrowser]);
});
this.addListener("close", () => {
- runsAndClusters.getChildControl("runs-browser").stopInterval();
+ runsBrowser.stopInterval();
subRunsBrowser.stopInterval();
});
},
diff --git a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js
index f3b4d0fac0df..c0df3017ee9c 100644
--- a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js
+++ b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js
@@ -28,10 +28,10 @@ qx.Class.define("osparc.jobs.JobsButton", {
alignX: "center",
cursor: "pointer",
visibility: "excluded",
- toolTipText: this.tr("Runs and Clusters"),
+ toolTipText: this.tr("Activity Center"),
});
- this.addListener("tap", () => osparc.jobs.RunsWindow.openWindow(), this);
+ this.addListener("tap", () => osparc.jobs.ActivityCenterWindow.openWindow(), this);
const jobsStore = osparc.store.Jobs.getInstance();
jobsStore.addListener("changeJobs", e => this.__updateJobsButton(), this);
diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsAndClusters.js b/services/static-webserver/client/source/class/osparc/jobs/RunsAndClusters.js
deleted file mode 100644
index ebc68a6cd0de..000000000000
--- a/services/static-webserver/client/source/class/osparc/jobs/RunsAndClusters.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/* ************************************************************************
-
- 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.jobs.RunsAndClusters", {
- extend: qx.ui.tabview.TabView,
-
- construct: function() {
- this.base(arguments);
-
- this.set({
- contentPadding: 5,
- barPosition: "top",
- });
-
- const runsBrowser = this.getChildControl("runs-browser");
- runsBrowser.addListener("runSelected", e => this.fireDataEvent("runSelected", e.getData()));
-
- this.getChildControl("clusters-browser");
- },
-
- events: {
- "runSelected": "qx.event.type.Data",
- },
-
- statics: {
- popUpInWindow: function(jobsAndClusters) {
- if (!jobsAndClusters) {
- jobsAndClusters = new osparc.jobs.RunsAndClusters();
- }
- const title = qx.locale.Manager.tr("Runs and Clusters");
- const win = osparc.ui.window.Window.popUpInWindow(jobsAndClusters, title, 1100, 500);
- win.open();
- return win;
- }
- },
-
- members: {
- _createChildControlImpl: function(id) {
- let control;
- switch (id) {
- case "jobs-page":
- control = new qx.ui.tabview.Page(this.tr("Runs")).set({
- layout: new qx.ui.layout.VBox(10)
- });
- this.add(control);
- break;
- case "runs-browser": {
- control = new osparc.jobs.RunsBrowser();
- const scroller = new qx.ui.container.Scroll();
- scroller.add(control);
- this.getChildControl("jobs-page").add(scroller);
- break;
- }
- case "clusters-page":
- control = new qx.ui.tabview.Page(this.tr("Clusters")).set({
- layout: new qx.ui.layout.VBox(10)
- });
- this.add(control);
- break;
- case "clusters-browser": {
- control = new osparc.jobs.ClustersBrowser();
- const scroller = new qx.ui.container.Scroll();
- scroller.add(control);
- this.getChildControl("clusters-page").add(scroller);
- break;
- }
- }
- return control || this.base(arguments, id);
- },
-
- reloadRuns: function() {
- const runsBrowser = this.getChildControl("runs-browser");
- runsBrowser.reloadRuns();
- },
- }
-});
diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js b/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js
index 4b75bdb13bac..ff9e5414b840 100644
--- a/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js
+++ b/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js
@@ -25,7 +25,6 @@ qx.Class.define("osparc.jobs.RunsBrowser", {
this._setLayout(new qx.ui.layout.VBox(10));
const jobsFilter = this.getChildControl("jobs-filter");
- this.getChildControl("jobs-ongoing");
const jobsTable = this.getChildControl("runs-table");
jobsFilter.getChildControl("textfield").addListener("input", e => {
@@ -61,14 +60,6 @@ qx.Class.define("osparc.jobs.RunsBrowser", {
flex: 1
});
break;
- case "jobs-ongoing":
- control = new qx.ui.form.CheckBox().set({
- label: "Hide finished jobs",
- value: true,
- enabled: false,
- });
- this.getChildControl("header-filter").add(control);
- break;
case "runs-table":
control = new osparc.jobs.RunsTable();
control.addListener("runSelected", e => this.fireDataEvent("runSelected", e.getData()));
diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js
index cf7c68e00bfa..41fc06821a0c 100644
--- a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js
+++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js
@@ -36,10 +36,6 @@ qx.Class.define("osparc.jobs.RunsTable", {
Object.values(this.self().COLS).forEach(col => columnModel.setColumnWidth(col.column, col.width));
- const iconPathRun = "osparc/circle-play-text.svg";
- const fontButtonRendererRun = new osparc.ui.table.cellrenderer.ImageButtonRenderer("run", iconPathRun);
- columnModel.setDataCellRenderer(this.self().COLS.ACTION_RUN.column, fontButtonRendererRun);
-
const iconPathStop = "osparc/circle-stop-text.svg";
const fontButtonRendererStop = new osparc.ui.table.cellrenderer.ImageButtonRenderer("stop", iconPathStop);
columnModel.setDataCellRenderer(this.self().COLS.ACTION_STOP.column, fontButtonRendererStop);
@@ -62,7 +58,7 @@ qx.Class.define("osparc.jobs.RunsTable", {
PROJECT_NAME: {
id: "projectName",
column: 1,
- label: qx.locale.Manager.tr("Project Name"),
+ label: qx.locale.Manager.tr("Project"),
width: 170,
sortable: true
},
@@ -75,7 +71,7 @@ qx.Class.define("osparc.jobs.RunsTable", {
SUBMIT: {
id: "submit",
column: 3,
- label: qx.locale.Manager.tr("Submitted"),
+ label: qx.locale.Manager.tr("Queued"),
width: 130,
sortable: true
},
@@ -93,15 +89,9 @@ qx.Class.define("osparc.jobs.RunsTable", {
width: 130,
sortable: true
},
- ACTION_RUN: {
- id: "action_run",
- column: 6,
- label: "",
- width: 40
- },
ACTION_STOP: {
id: "action_stop",
- column: 7,
+ column: 6,
label: "",
width: 40
},
diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js
index 28f2806200d4..2f457bb3efbb 100644
--- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js
+++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js
@@ -39,7 +39,11 @@ qx.Class.define("osparc.jobs.SubRunsTable", {
const iconPathInfo = "osparc/circle-info-text.svg";
const fontButtonRendererInfo = new osparc.ui.table.cellrenderer.ImageButtonRenderer("info", iconPathInfo);
- columnModel.setDataCellRenderer(this.self().COLS.IMAGE.column, fontButtonRendererInfo);
+ columnModel.setDataCellRenderer(this.self().COLS.INFO.column, fontButtonRendererInfo);
+
+ const iconPathLogs = "osparc/logs-text.svg";
+ const fontButtonRendererLogs = new osparc.ui.table.cellrenderer.ImageButtonRenderer("logs", iconPathLogs);
+ columnModel.setDataCellRenderer(this.self().COLS.LOGS.column, fontButtonRendererLogs);
this.__attachHandlers();
},
@@ -61,13 +65,13 @@ qx.Class.define("osparc.jobs.SubRunsTable", {
NODE_NAME: {
id: "nodeName",
column: 2,
- label: qx.locale.Manager.tr("Node Name"),
+ label: qx.locale.Manager.tr("Node"),
width: 170
},
- SOLVER: {
- id: "solver",
+ APP: {
+ id: "app",
column: 3,
- label: qx.locale.Manager.tr("Solver"),
+ label: qx.locale.Manager.tr("App"),
width: 150
},
STATE: {
@@ -100,12 +104,24 @@ qx.Class.define("osparc.jobs.SubRunsTable", {
label: qx.locale.Manager.tr("Duration"),
width: 70
},
- IMAGE: {
- id: "image",
+ CREDITS: {
+ id: "credits",
column: 9,
+ label: qx.locale.Manager.tr("Credits"),
+ width: 70
+ },
+ INFO: {
+ id: "info",
+ column: 10,
label: qx.locale.Manager.tr("Info"),
width: 40
},
+ LOGS: {
+ id: "logs",
+ column: 11,
+ label: qx.locale.Manager.tr("Logs"),
+ width: 40
+ },
}
},
diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js
index 4c9077d60180..33f65f03a85d 100644
--- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js
+++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js
@@ -73,8 +73,14 @@ qx.Class.define("osparc.jobs.SubRunsTableModel", {
const data = [];
const subJobsCols = osparc.jobs.SubRunsTable.COLS;
subJobs.forEach(subJob => {
- const nodeName = subJob.getImage()["name"].split("/").pop();
- const version = osparc.store.Services.getVersionDisplay(subJob.getImage()["name"], subJob.getImage()["tag"]) || subJob.getImage()["tag"];
+ const serviceKey = subJob.getImage()["name"];
+ const serviceVersion = subJob.getImage()["tag"];
+ const serviceMetadata = osparc.store.Services.getLatest(serviceKey);
+ let appName = serviceKey.split("/").pop();
+ if (serviceMetadata) {
+ appName = serviceMetadata["name"];
+ }
+ const displayVersion = osparc.store.Services.getVersionDisplay(serviceKey, serviceVersion) || serviceVersion;
const startedAt = subJob.getStartedAt();
const endedAt = subJob.getEndedAt();
let duration = "-";
@@ -89,12 +95,13 @@ qx.Class.define("osparc.jobs.SubRunsTableModel", {
[subJobsCols.PROJECT_UUID.id]: subJob.getProjectUuid(),
[subJobsCols.NODE_ID.id]: subJob.getNodeId(),
[subJobsCols.NODE_NAME.id]: subJob.getNodeName(),
- [subJobsCols.SOLVER.id]: nodeName + ":" + version,
+ [subJobsCols.APP.id]: appName + ":" + displayVersion,
[subJobsCols.STATE.id]: subJob.getState(),
[subJobsCols.PROGRESS.id]: subJob.getProgress() * 100 + "%",
[subJobsCols.START.id]: startedAt ? osparc.utils.Utils.formatDateAndTime(startedAt) : "-",
[subJobsCols.END.id]: endedAt ? osparc.utils.Utils.formatDateAndTime(endedAt) : "-",
[subJobsCols.DURATION.id]: duration,
+ [subJobsCols.CREDITS.id]: subJob.getOsparcCredits() === null ? "-" : subJob.getOsparcCredits(),
});
});
return data;
diff --git a/services/static-webserver/client/source/class/osparc/navigation/StudyTitleWOptions.js b/services/static-webserver/client/source/class/osparc/navigation/StudyTitleWOptions.js
index 4d593c765292..1b86bfab8564 100644
--- a/services/static-webserver/client/source/class/osparc/navigation/StudyTitleWOptions.js
+++ b/services/static-webserver/client/source/class/osparc/navigation/StudyTitleWOptions.js
@@ -110,12 +110,8 @@ qx.Class.define("osparc.navigation.StudyTitleWOptions", {
optionsMenu.setAppearance("menu-wider");
optionsMenu.add(this.getChildControl("study-menu-info"));
optionsMenu.add(this.getChildControl("study-menu-reload"));
- if (osparc.utils.DisabledPlugins.isConversationEnabled()) {
- optionsMenu.add(this.getChildControl("study-menu-conversations"));
- }
- if (osparc.product.Utils.hasConvertToPipelineEnabled()) {
- optionsMenu.add(this.getChildControl("study-menu-convert-to-pipeline"));
- }
+ optionsMenu.add(this.getChildControl("study-menu-conversations"));
+ optionsMenu.add(this.getChildControl("study-menu-convert-to-pipeline"));
optionsMenu.add(this.getChildControl("study-menu-restore"));
optionsMenu.add(this.getChildControl("study-menu-open-logger"));
control = new qx.ui.form.MenuButton().set({
@@ -161,19 +157,15 @@ qx.Class.define("osparc.navigation.StudyTitleWOptions", {
converter: mode => mode === "standalone" ? "visible" : "excluded"
});
- if (osparc.utils.DisabledPlugins.isConversationEnabled()) {
- const conversationsButton = this.getChildControl("study-menu-conversations");
- study.getUi().bind("mode", conversationsButton, "visibility", {
- converter: mode => mode === "standalone" ? "visible" : "excluded"
- });
- }
+ const conversationsButton = this.getChildControl("study-menu-conversations");
+ study.getUi().bind("mode", conversationsButton, "visibility", {
+ converter: mode => mode === "standalone" ? "visible" : "excluded"
+ });
- if (osparc.product.Utils.hasConvertToPipelineEnabled()) {
- const convertToPipelineButton = this.getChildControl("study-menu-convert-to-pipeline");
- study.getUi().bind("mode", convertToPipelineButton, "visibility", {
- converter: mode => mode === "standalone" ? "visible" : "excluded"
- });
- }
+ const convertToPipelineButton = this.getChildControl("study-menu-convert-to-pipeline");
+ study.getUi().bind("mode", convertToPipelineButton, "visibility", {
+ converter: mode => mode === "standalone" ? "visible" : "excluded"
+ });
const restoreButton = this.getChildControl("study-menu-restore");
study.getUi().bind("mode", restoreButton, "visibility", {
diff --git a/services/static-webserver/client/source/class/osparc/product/Utils.js b/services/static-webserver/client/source/class/osparc/product/Utils.js
index 249f7575cf63..987ee0ef5f30 100644
--- a/services/static-webserver/client/source/class/osparc/product/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/product/Utils.js
@@ -102,6 +102,36 @@ qx.Class.define("osparc.product.Utils", {
return alias;
},
+ getHypertoolAlias: function(options = {}) {
+ let alias = qx.locale.Manager.tr("hypertool");
+ if (options.plural) {
+ alias = qx.locale.Manager.tr("hypertools");
+ }
+
+ if (options.firstUpperCase) {
+ alias = osparc.utils.Utils.capitalize(alias);
+ } else if (options.allUpperCase) {
+ alias = alias.toUpperCase();
+ }
+
+ return alias;
+ },
+
+ getAppAlias: function(options = {}) {
+ let alias = qx.locale.Manager.tr("app");
+ if (options.plural) {
+ alias = qx.locale.Manager.tr("Apps");
+ }
+
+ if (options.firstUpperCase) {
+ alias = osparc.utils.Utils.capitalize(alias);
+ } else if (options.allUpperCase) {
+ alias = alias.toUpperCase();
+ }
+
+ return alias;
+ },
+
resourceTypeToAlias: function(resourceType, options) {
switch (resourceType) {
case "study":
@@ -110,6 +140,10 @@ qx.Class.define("osparc.product.Utils", {
return this.getTemplateAlias(options);
case "service":
return this.getServiceAlias(options);
+ case "hypertool":
+ return this.getHypertoolAlias(options);
+ case "app":
+ return this.getAppAlias(options);
}
return resourceType;
},
@@ -188,10 +222,6 @@ qx.Class.define("osparc.product.Utils", {
return "REGISTER";
},
- hasConvertToPipelineEnabled: function() {
- return osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled();
- },
-
// oSPARC only
hasExportCMisEnabled: function() {
const product = this.getProductName();
diff --git a/services/static-webserver/client/source/class/osparc/service/Utils.js b/services/static-webserver/client/source/class/osparc/service/Utils.js
index b7499816eac4..82d7ec021b97 100644
--- a/services/static-webserver/client/source/class/osparc/service/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/service/Utils.js
@@ -98,11 +98,14 @@ qx.Class.define("osparc.service.Utils", {
}
servicesArray.sort((a, b) => {
if (basedOn.sort === "hits") {
- if (a[basedOn.sort] !== b[basedOn.sort]) {
+ const aHits = a["hits"] === undefined ? -1 : a["hits"]; // Treat undefined hits as -1
+ const bHits = b["hits"] === undefined ? -1 : b["hits"]; // Treat undefined hits as -1
+
+ if (aHits !== bHits) {
if (basedOn.order === "down") {
- return b[basedOn.sort] - a[basedOn.sort];
+ return bHits - aHits;
}
- return a[basedOn.sort] - b[basedOn.sort];
+ return aHits - bHits;
}
return a["name"].localeCompare(b["name"]);
} else if (basedOn.sort === "name") {
diff --git a/services/static-webserver/client/source/class/osparc/share/Collaborators.js b/services/static-webserver/client/source/class/osparc/share/Collaborators.js
index 2ee15429b167..ca26799687ad 100644
--- a/services/static-webserver/client/source/class/osparc/share/Collaborators.js
+++ b/services/static-webserver/client/source/class/osparc/share/Collaborators.js
@@ -194,6 +194,7 @@ qx.Class.define("osparc.share.Collaborators", {
switch (this._resourceType) {
case "study":
case "template":
+ case "hypertool":
canIShare = osparc.data.model.Study.canIWrite(this._serializedDataCopy["accessRights"]);
break;
case "service":
@@ -218,6 +219,7 @@ qx.Class.define("osparc.share.Collaborators", {
switch (this._resourceType) {
case "study":
case "template":
+ case "hypertool":
fullOptions = osparc.data.model.Study.canIDelete(this._serializedDataCopy["accessRights"]);
break;
case "service":
@@ -238,6 +240,7 @@ qx.Class.define("osparc.share.Collaborators", {
switch (this._resourceType) {
case "study":
case "template":
+ case "hypertool":
rolesLayout = osparc.data.Roles.createRolesStudyInfo();
break;
case "service":
@@ -342,7 +345,7 @@ qx.Class.define("osparc.share.Collaborators", {
item.addListener("removeMember", e => {
const orgMember = e.getData();
if (
- ["study", "template"].includes(this._resourceType) &&
+ ["study", "template", "hypertool"].includes(this._resourceType) &&
!osparc.share.CollaboratorsStudy.canCollaboratorBeRemoved(this._serializedDataCopy, orgMember["gid"])
) {
let msg = this.tr("Collaborator can't be removed:");
@@ -370,7 +373,7 @@ qx.Class.define("osparc.share.Collaborators", {
__getLeaveStudyButton: function() {
const myGid = osparc.auth.Data.getInstance().getGroupId();
if (
- ["study", "template"].includes(this._resourceType) &&
+ ["study", "template", "hypertool"].includes(this._resourceType) &&
osparc.share.CollaboratorsStudy.canCollaboratorBeRemoved(this._serializedDataCopy, myGid)
) {
const leaveText = this.tr("Leave") + " " + osparc.product.Utils.getStudyAlias({
diff --git a/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js b/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js
index aed7b56d89ce..71655ea452f5 100644
--- a/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js
+++ b/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js
@@ -34,10 +34,7 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
this.__potentialCollaborators = {};
this.__reloadPotentialCollaborators();
- this.__shareWithEmailEnabled = false;
- if (this.__resourceData["resourceType"] === "study") {
- this.__shareWithEmailEnabled = osparc.utils.DisabledPlugins.isShareWithEmailEnabled();
- }
+ this.__shareWithEmailEnabled = this.__resourceData["resourceType"] === "study";
if (preselectCollaboratorGids && preselectCollaboratorGids.length) {
preselectCollaboratorGids.forEach(preselectCollaboratorGid => {
@@ -256,6 +253,9 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
} else if (this.__resourceData && this.__resourceData["resourceType"] === "service") {
// all users can share services with ProductEveryone
showProductEveryone = true;
+ } else if (this.__resourceData && this.__resourceData["resourceType"] === "hypertool") {
+ // all users can share hypertool with ProductEveryone
+ showProductEveryone = true;
}
return showProductEveryone;
},
diff --git a/services/static-webserver/client/source/class/osparc/store/Templates.js b/services/static-webserver/client/source/class/osparc/store/Templates.js
index 6a0a2483849e..8b6deb996880 100644
--- a/services/static-webserver/client/source/class/osparc/store/Templates.js
+++ b/services/static-webserver/client/source/class/osparc/store/Templates.js
@@ -58,7 +58,10 @@ qx.Class.define("osparc.store.Templates", {
getTemplatesHypertools: function() {
return this.getTemplates()
.then(templates => {
- return templates.filter(t => osparc.study.Utils.extractTemplateType(t) === osparc.data.model.StudyUI.HYPERTOOL_TYPE);
+ const hypertools = templates.filter(t => osparc.study.Utils.extractTemplateType(t) === osparc.data.model.StudyUI.HYPERTOOL_TYPE);
+ // required for filtering
+ hypertools.forEach(hypertool => hypertool.type = osparc.data.model.StudyUI.HYPERTOOL_TYPE);
+ return hypertools;
});
},
diff --git a/services/static-webserver/client/source/class/osparc/study/SaveAsTemplate.js b/services/static-webserver/client/source/class/osparc/study/SaveAsTemplate.js
index 8fde68b678fc..c29755d08a1c 100644
--- a/services/static-webserver/client/source/class/osparc/study/SaveAsTemplate.js
+++ b/services/static-webserver/client/source/class/osparc/study/SaveAsTemplate.js
@@ -56,7 +56,7 @@ qx.Class.define("osparc.study.SaveAsTemplate", {
});
form.add(publishWithData, this.tr("Publish with data"), null, "publishWithData");
- if (osparc.utils.DisabledPlugins.isHypertoolsEnabled()) {
+ if (osparc.product.Utils.isS4LProduct()) {
const templateTypeSB = new qx.ui.form.SelectBox().set({
allowGrowX: false,
});
diff --git a/services/static-webserver/client/source/class/osparc/study/Utils.js b/services/static-webserver/client/source/class/osparc/study/Utils.js
index cdaa3ca712db..d4e5d59d4cd0 100644
--- a/services/static-webserver/client/source/class/osparc/study/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/study/Utils.js
@@ -258,10 +258,6 @@ qx.Class.define("osparc.study.Utils", {
},
canCreateFunction: function(workbench) {
- if (!osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled()) {
- return false;
- }
-
// in order to create a function, the pipeline needs:
// - at least one parameter (or file-picker (file type parameter))
// - at least one probe
diff --git a/services/static-webserver/client/source/class/osparc/theme/Appearance.js b/services/static-webserver/client/source/class/osparc/theme/Appearance.js
index a1bc3cd837b1..84467571190c 100644
--- a/services/static-webserver/client/source/class/osparc/theme/Appearance.js
+++ b/services/static-webserver/client/source/class/osparc/theme/Appearance.js
@@ -125,6 +125,16 @@ qx.Theme.define("osparc.theme.Appearance", {
}
},
+ "pb-hypertool": {
+ include: "pb-listitem",
+ style: function(states) {
+ const style = {
+ backgroundColor: "pb-template"
+ };
+ return style;
+ }
+ },
+
"pb-dynamic": {
include: "pb-listitem",
style: function(states) {
diff --git a/services/static-webserver/client/source/class/osparc/ui/list/CollaboratorListItem.js b/services/static-webserver/client/source/class/osparc/ui/list/CollaboratorListItem.js
index cc6b575d06f2..8962431206a9 100644
--- a/services/static-webserver/client/source/class/osparc/ui/list/CollaboratorListItem.js
+++ b/services/static-webserver/client/source/class/osparc/ui/list/CollaboratorListItem.js
@@ -76,7 +76,7 @@ qx.Class.define("osparc.ui.list.CollaboratorListItem", {
members: {
__getRoleInfo: function(id) {
const resource = this.getResourceType();
- if (resource === "study" || resource === "template") {
+ if (["study", "template", "hypertool"].includes(resource)) {
return osparc.data.Roles.STUDY[id];
} else if (resource === "service") {
return osparc.data.Roles.SERVICES[id];
@@ -113,6 +113,24 @@ qx.Class.define("osparc.ui.list.CollaboratorListItem", {
return control || this.base(arguments, id);
},
+ // overridden
+ _applyTitle: function(value) {
+ if (value === null) {
+ return;
+ }
+ const groupsStore = osparc.store.Groups.getInstance();
+ const everyoneGroupIds = [
+ groupsStore.getEveryoneProductGroup().getGroupId(),
+ groupsStore.getEveryoneGroup().getGroupId(),
+ ];
+ const label = this.getChildControl("title");
+ if (everyoneGroupIds.includes(this.getModel())) {
+ label.setValue(this.tr("Public"));
+ } else {
+ label.setValue(value);
+ }
+ },
+
// overridden
_applyThumbnail: function(value) {
if (value === null) {
diff --git a/services/static-webserver/client/source/class/osparc/ui/list/ListItem.js b/services/static-webserver/client/source/class/osparc/ui/list/ListItem.js
index 5b45f066022c..89f0d7c87b7c 100644
--- a/services/static-webserver/client/source/class/osparc/ui/list/ListItem.js
+++ b/services/static-webserver/client/source/class/osparc/ui/list/ListItem.js
@@ -90,7 +90,7 @@ qx.Class.define("osparc.ui.list.ListItem", {
title: {
check : "String",
- apply : "__applyTitle",
+ apply : "_applyTitle",
nullable : true
},
@@ -228,7 +228,7 @@ qx.Class.define("osparc.ui.list.ListItem", {
thumbnail.setSource(value);
},
- __applyTitle: function(value) {
+ _applyTitle: function(value) {
if (value === null) {
return;
}
diff --git a/services/static-webserver/client/source/class/osparc/utils/DisabledPlugins.js b/services/static-webserver/client/source/class/osparc/utils/DisabledPlugins.js
index 225e775f047b..0578f4b73f9a 100644
--- a/services/static-webserver/client/source/class/osparc/utils/DisabledPlugins.js
+++ b/services/static-webserver/client/source/class/osparc/utils/DisabledPlugins.js
@@ -52,25 +52,6 @@ qx.Class.define("osparc.utils.DisabledPlugins", {
return this.__isPluginDisabled(this.LICENSES);
},
- isShareWithEmailEnabled: function() {
- return osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled();
- },
-
- isJobsEnabled: function() {
- return osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled();
- },
-
- isHypertoolsEnabled: function() {
- if (osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled() && osparc.product.Utils.isS4LProduct()) {
- return true;
- }
- return false;
- },
-
- isConversationEnabled: function() {
- return osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled();
- },
-
__isPluginDisabled: function(key) {
const statics = osparc.store.Store.getInstance().get("statics");
if (statics) {
diff --git a/services/static-webserver/client/source/class/osparc/utils/Resources.js b/services/static-webserver/client/source/class/osparc/utils/Resources.js
index 701480b0d7e4..b5045092a918 100644
--- a/services/static-webserver/client/source/class/osparc/utils/Resources.js
+++ b/services/static-webserver/client/source/class/osparc/utils/Resources.js
@@ -31,8 +31,12 @@ qx.Class.define("osparc.utils.Resources", {
return ((templateData["resourceType"] === "template") && ("uuid" in templateData));
},
+ isHypertool: function(hypertoolData) {
+ return ((hypertoolData["resourceType"] === "hypertool") && ("uuid" in hypertoolData));
+ },
+
isService: function(serviceData) {
return ((serviceData["resourceType"] === "service") && ("key" in serviceData) && ("version" in serviceData));
- }
+ },
}
});
diff --git a/services/static-webserver/client/source/class/osparc/utils/Utils.js b/services/static-webserver/client/source/class/osparc/utils/Utils.js
index ea48b14120f1..9d57a035e29c 100644
--- a/services/static-webserver/client/source/class/osparc/utils/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/utils/Utils.js
@@ -457,21 +457,6 @@ qx.Class.define("osparc.utils.Utils", {
return (["dev", "master"].includes(platformName));
},
- resourceTypeToAlias: function(resourceType) {
- switch (resourceType) {
- case "study":
- resourceType = osparc.product.Utils.getStudyAlias({firstUpperCase: true});
- break;
- case "template":
- resourceType = osparc.product.Utils.getTemplateAlias({firstUpperCase: true});
- break;
- case "service":
- resourceType = qx.locale.Manager.tr("Service");
- break;
- }
- return resourceType;
- },
-
getEditButton: function(isVisible = true) {
return new qx.ui.form.Button(null, "@FontAwesome5Solid/pencil-alt/12").set({
appearance: "form-button-outlined",
diff --git a/services/static-webserver/client/source/resource/osparc/circle-play-text.svg b/services/static-webserver/client/source/resource/osparc/circle-play-text.svg
deleted file mode 100644
index 922e5c5d6f0b..000000000000
--- a/services/static-webserver/client/source/resource/osparc/circle-play-text.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/services/static-webserver/client/source/resource/osparc/tours/osparc_tours.json b/services/static-webserver/client/source/resource/osparc/tours/osparc_tours.json
index 24ff1e63ef10..1d0d098e8f25 100644
--- a/services/static-webserver/client/source/resource/osparc/tours/osparc_tours.json
+++ b/services/static-webserver/client/source/resource/osparc/tours/osparc_tours.json
@@ -60,9 +60,9 @@
"placement": "bottom"
}, {
"beforeClick": {
- "selector": "osparc-test-id=servicesTabBtn"
+ "selector": "osparc-test-id=appsTabBtn"
},
- "anchorEl": "osparc-test-id=servicesTabBtn",
+ "anchorEl": "osparc-test-id=appsTabBtn",
"text": "Every Study in oSparc is composed of so-called Services.
These are building blocks for Studies and can provide data/files, visualize results (2D, 3D), implement code in Jupyter notebooks or perform computations to execute simulations within a Study.",
"placement": "bottom"
}, {
diff --git a/services/static-webserver/client/source/resource/osparc/tours/s4l_tours.json b/services/static-webserver/client/source/resource/osparc/tours/s4l_tours.json
index 0e5f056a68ce..f08e7937c80d 100644
--- a/services/static-webserver/client/source/resource/osparc/tours/s4l_tours.json
+++ b/services/static-webserver/client/source/resource/osparc/tours/s4l_tours.json
@@ -60,9 +60,9 @@
"placement": "bottom"
}, {
"beforeClick": {
- "selector": "osparc-test-id=servicesTabBtn"
+ "selector": "osparc-test-id=appsTabBtn"
},
- "anchorEl": "osparc-test-id=servicesTabBtn",
+ "anchorEl": "osparc-test-id=appsTabBtn",
"text": "Every Project in Sim4Life is composed of at least one so-called Service.
Services are building blocks for Projects and can provide data/files, visualize results (2D, 3D), implement code in Jupyter notebooks or perform computations to execute simulations within a Project.",
"placement": "bottom"
}]
diff --git a/tests/e2e-frontend/tests/navigationBar/navigationBar.spec.js b/tests/e2e-frontend/tests/navigationBar/navigationBar.spec.js
index c6bb8752f334..8f77bff20165 100644
--- a/tests/e2e-frontend/tests/navigationBar/navigationBar.spec.js
+++ b/tests/e2e-frontend/tests/navigationBar/navigationBar.spec.js
@@ -175,7 +175,7 @@ for (const product in products) {
};
await checkButton("templatesTabBtn", isTemplatesVisible, templatesLabel);
- await checkButton("servicesTabBtn", isServicesVisible, servicesLabel);
+ await checkButton("appsTabBtn", isServicesVisible, servicesLabel);
await checkButton("dataTabBtn", isDataVisible, dataLabel);
});
diff --git a/tests/e2e-frontend/tests/serviceBrowser/leftFilters.spec.js b/tests/e2e-frontend/tests/serviceBrowser/leftFilters.spec.js
index 247f5def5822..eb08072dd1f4 100644
--- a/tests/e2e-frontend/tests/serviceBrowser/leftFilters.spec.js
+++ b/tests/e2e-frontend/tests/serviceBrowser/leftFilters.spec.js
@@ -28,7 +28,7 @@ test.describe.serial(`Left Filters:`, () => {
await responsePromise;
- await page.getByTestId("servicesTabBtn").click();
+ await page.getByTestId("appsTabBtn").click();
});
test.afterAll(async ({ browser }) => {
diff --git a/tests/e2e-frontend/tests/serviceBrowser/mainView.spec.js b/tests/e2e-frontend/tests/serviceBrowser/mainView.spec.js
index c3077e467e70..b7ac9c8cc4db 100644
--- a/tests/e2e-frontend/tests/serviceBrowser/mainView.spec.js
+++ b/tests/e2e-frontend/tests/serviceBrowser/mainView.spec.js
@@ -7,7 +7,7 @@ import { LoginPage } from '../fixtures/loginPage';
import products from '../products.json';
import users from '../users.json';
-const servicesTabExposed = {
+const appsTabExposed = {
"osparc": {
"areServicesExposed": true,
},
@@ -29,8 +29,8 @@ const servicesTabExposed = {
}
for (const product in products) {
- expect(servicesTabExposed[product]).toBeDefined();
- if (!servicesTabExposed[product]["areServicesExposed"]) {
+ expect(appsTabExposed[product]).toBeDefined();
+ if (!appsTabExposed[product]["areServicesExposed"]) {
continue;
}
@@ -62,7 +62,7 @@ for (const product in products) {
expect("data" in resp && "_meta" in resp["data"] && "total" in resp["data"]["_meta"]);
console.log("N Services in Response:", resp["data"]["_meta"]["total"]);
- await page.getByTestId("servicesTabBtn").click();
+ await page.getByTestId("appsTabBtn").click();
});
test.afterAll(async ({ browser }) => {
diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py
index 60e92755190e..45c200022290 100644
--- a/tests/e2e-playwright/tests/conftest.py
+++ b/tests/e2e-playwright/tests/conftest.py
@@ -663,7 +663,7 @@ def _(
service_key_prefix: str | None,
) -> None:
with log_context(logging.INFO, f"Finding {service_name=} in dashboard"):
- page.get_by_test_id("servicesTabBtn").click()
+ page.get_by_test_id("appsTabBtn").click()
_textbox = page.get_by_test_id("searchBarFilter-textField-service")
_textbox.fill(service_name)
_textbox.press("Enter")
diff --git a/tests/e2e/utils/auto.js b/tests/e2e/utils/auto.js
index f9a723059d5b..25c11b8c6637 100644
--- a/tests/e2e/utils/auto.js
+++ b/tests/e2e/utils/auto.js
@@ -101,7 +101,7 @@ async function __dashboardTemplatesBrowser(page) {
async function __dashboardServicesBrowser(page) {
console.log("Navigating through Services");
- await utils.waitAndClick(page, '[osparc-test-id="servicesTabBtn"]');
+ await utils.waitAndClick(page, '[osparc-test-id="appsTabBtn"]');
}
async function dashboardNewTIPlan(page) {