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 9334861f11c..31524310535 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
@@ -116,7 +116,11 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
};
osparc.data.Resources.fetch("studies", "getWallet", params)
.then(wallet => {
- if (isStudyCreation || wallet === null || osparc.desktop.credits.Utils.getWallet(wallet["walletId"]) === null) {
+ if (
+ isStudyCreation ||
+ wallet === null ||
+ osparc.desktop.credits.Utils.getWallet(wallet["walletId"]) === null
+ ) {
// pop up study options if the study was just created or if it has no wallet assigned or user has no access to it
const resourceSelector = new osparc.study.StudyOptions(studyId);
const win = osparc.study.StudyOptions.popUpInWindow(resourceSelector);
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 a1ae4d742fa..76e9f628829 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js
@@ -364,7 +364,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const resourceData = this.__resourceData;
if (osparc.utils.Resources.isStudy(resourceData)) {
const id = "Billing";
- const title = this.tr("Billing Settings");
+ const title = this.tr("Tier Settings");
const iconSrc = "@FontAwesome5Solid/cogs/22";
const page = this.__billingSettings = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
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 7349d7d46b5..288290b06df 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
@@ -374,12 +374,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
newWorkspaceCard.setCardKey("new-workspace");
newWorkspaceCard.subscribeToFilterGroup("searchBarFilter");
[
- "createWorkspace",
- "updateWorkspace"
+ "workspaceCreated",
+ "workspaceDeleted",
+ "workspaceUpdated",
].forEach(e => {
- newWorkspaceCard.addListener(e, () => {
- this.__reloadWorkspaces();
- });
+ newWorkspaceCard.addListener(e, () => this.__reloadWorkspaces());
});
this._resourcesContainer.addNewWorkspaceCard(newWorkspaceCard);
},
@@ -1170,7 +1169,8 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
__newStudyBtnClicked: function(button) {
button.setValue(false);
const minStudyData = osparc.data.model.Study.createMinStudyObject();
- const title = osparc.utils.Utils.getUniqueStudyName(minStudyData.name, this._resourcesList);
+ const existingNames = this._resourcesList.map(study => study["name"]);
+ const title = osparc.utils.Utils.getUniqueName(minStudyData.name, existingNames);
minStudyData["name"] = title;
minStudyData["workspaceId"] = this.getCurrentWorkspaceId();
minStudyData["folderId"] = this.getCurrentFolderId();
@@ -1190,7 +1190,8 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
__newPlanBtnClicked: function(templateData, newStudyName) {
// do not override cached template data
const templateCopyData = osparc.utils.Utils.deepCloneObject(templateData);
- const title = osparc.utils.Utils.getUniqueStudyName(newStudyName, this._resourcesList);
+ const existingNames = this._resourcesList.map(study => study["name"]);
+ const title = osparc.utils.Utils.getUniqueName(newStudyName, existingNames);
templateCopyData.name = title;
this._showLoadingPage(this.tr("Creating ") + (newStudyName || osparc.product.Utils.getStudyAlias()));
const contextProps = {
@@ -1411,7 +1412,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
},
__getBillingMenuButton: function(card) {
- const text = osparc.utils.Utils.capitalize(this.tr("Billing Settings..."));
+ const text = osparc.utils.Utils.capitalize(this.tr("Tier Settings..."));
const studyBillingSettingsButton = new qx.ui.menu.Button(text);
studyBillingSettingsButton["billingSettingsButton"] = true;
studyBillingSettingsButton.addListener("tap", () => card.openBilling(), this);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowserHeader.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowserHeader.js
index 9e2ca51b434..87a6a366b58 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowserHeader.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowserHeader.js
@@ -339,10 +339,10 @@ qx.Class.define("osparc.dashboard.StudyBrowserHeader", {
__editWorkspace: function() {
const workspace = osparc.store.Workspaces.getInstance().getWorkspace(this.getCurrentWorkspaceId());
- const permissionsView = new osparc.editor.WorkspaceEditor(workspace);
+ const workspaceEditor = new osparc.editor.WorkspaceEditor(workspace);
const title = this.tr("Edit Workspace");
- const win = osparc.ui.window.Window.popUpInWindow(permissionsView, title, 300, 200);
- permissionsView.addListener("workspaceUpdated", () => {
+ const win = osparc.ui.window.Window.popUpInWindow(workspaceEditor, title, 300, 150);
+ workspaceEditor.addListener("workspaceUpdated", () => {
win.close();
this.__buildLayout();
}, this);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js
index 5581ec3212b..4d5253410bf 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js
@@ -185,7 +185,7 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonItem", {
const workspace = this.getWorkspace();
const workspaceEditor = new osparc.editor.WorkspaceEditor(workspace);
const title = this.tr("Edit Workspace");
- const win = osparc.ui.window.Window.popUpInWindow(workspaceEditor, title, 300, 200);
+ const win = osparc.ui.window.Window.popUpInWindow(workspaceEditor, title, 300, 150);
workspaceEditor.addListener("workspaceUpdated", () => {
win.close();
this.fireDataEvent("workspaceUpdated", workspace.getWorkspaceId());
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonNew.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonNew.js
index fc1526b387d..ac87579355e 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonNew.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonNew.js
@@ -46,26 +46,29 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonNew", {
},
events: {
- "createWorkspace": "qx.event.type.Data",
- "updateWorkspace": "qx.event.type.Data"
+ "workspaceCreated": "qx.event.type.Event",
+ "workspaceDeleted": "qx.event.type.Event",
+ "workspaceUpdated": "qx.event.type.Event",
},
members: {
__itemSelected: function(newVal) {
if (newVal) {
- const workspaceCreator = new osparc.editor.WorkspaceEditor();
+ const workspaceEditor = new osparc.editor.WorkspaceEditor();
const title = this.tr("New Workspace");
- const win = osparc.ui.window.Window.popUpInWindow(workspaceCreator, title, 300, 200);
- workspaceCreator.addListener("workspaceCreated", e => {
- win.close();
- const newWorkspace = e.getData();
- this.fireDataEvent("createWorkspace", newWorkspace.getWorkspaceId(), this);
- const permissionsView = new osparc.share.CollaboratorsWorkspace(newWorkspace);
- const title2 = qx.locale.Manager.tr("Share Workspace");
- osparc.ui.window.Window.popUpInWindow(permissionsView, title2, 500, 500);
- permissionsView.addListener("updateAccessRights", () => this.fireDataEvent("updateWorkspace", newWorkspace.getWorkspaceId()), this);
+ const win = osparc.ui.window.Window.popUpInWindow(workspaceEditor, title, 500, 500).set({
+ modal: true,
+ clickAwayClose: false,
});
- workspaceCreator.addListener("cancel", () => win.close());
+ workspaceEditor.addListener("workspaceCreated", () => this.fireEvent("workspaceCreated"));
+ workspaceEditor.addListener("workspaceDeleted", () => this.fireEvent("workspaceDeleted"));
+ workspaceEditor.addListener("workspaceUpdated", () => {
+ win.close();
+ this.fireEvent("workspaceUpdated");
+ }, this);
+ workspaceEditor.addListener("updateAccessRights", () => this.fireEvent("workspaceUpdated"));
+ win.getChildControl("close-button").addListener("tap", () => workspaceEditor.cancel());
+ workspaceEditor.addListener("cancel", () => win.close());
}
this.setValue(false);
}
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js
index c65318bfcd3..7f35c3ff320 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js
@@ -300,7 +300,7 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTree", {
if (oldParentFolderId === undefined) {
// it was removed, not moved
// remove it from the cached models
- const modelFound = this.__getModel(folder.getWorkspaceId(), folder.getParentFolderId());
+ const modelFound = this.__getModel(folder.getWorkspaceId(), folder.getFolderId());
if (modelFound) {
const index = this.__models.indexOf(modelFound);
if (index > -1) { // only splice array when item is found
diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationDetails.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationDetails.js
index 6871348d8a0..c9d0501c0cd 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationDetails.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationDetails.js
@@ -94,17 +94,9 @@ qx.Class.define("osparc.desktop.organizations.OrganizationDetails", {
__openEditOrganization: function() {
const org = this.__orgModel;
-
- const newOrg = false;
- const orgEditor = new osparc.editor.OrganizationEditor(newOrg);
- org.bind("gid", orgEditor, "gid");
- org.bind("label", orgEditor, "label");
- org.bind("description", orgEditor, "description");
- org.bind("thumbnail", orgEditor, "thumbnail", {
- converter: val => val ? val : ""
- });
const title = this.tr("Organization Details Editor");
- const win = osparc.ui.window.Window.popUpInWindow(orgEditor, title, 400, 250);
+ const orgEditor = new osparc.editor.OrganizationEditor(org);
+ const win = osparc.ui.window.Window.popUpInWindow(orgEditor, title, 400, 200);
orgEditor.addListener("updateOrg", () => {
this.__updateOrganization(win, orgEditor.getChildControl("save"), orgEditor);
});
diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js
index 740f54211fa..c2f8656ed83 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js
@@ -99,10 +99,9 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
allowGrowX: false
});
createOrgBtn.addListener("execute", function() {
- const newOrg = true;
- const orgEditor = new osparc.editor.OrganizationEditor(newOrg);
const title = this.tr("New Organization");
- const win = osparc.ui.window.Window.popUpInWindow(orgEditor, title, 400, 250);
+ const orgEditor = new osparc.editor.OrganizationEditor();
+ const win = osparc.ui.window.Window.popUpInWindow(orgEditor, title, 400, 200);
orgEditor.addListener("createOrg", () => {
this.__createOrganization(win, orgEditor.getChildControl("create"), orgEditor);
});
@@ -176,7 +175,7 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
}
},
- reloadOrganizations: function() {
+ reloadOrganizations: function(orgId) {
this.__orgsUIList.resetSelection();
const orgsModel = this.__orgsModel;
orgsModel.removeAll();
@@ -199,6 +198,9 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
orgsList.sort(this.self().sortOrganizations);
orgsList.forEach(org => orgsModel.append(qx.data.marshal.Json.createModel(org)));
this.setOrganizationsLoaded(true);
+ if (orgId) {
+ this.fireDataEvent("organizationSelected", orgId);
+ }
});
},
@@ -208,16 +210,9 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
return;
}
- const newOrg = false;
- const orgEditor = new osparc.editor.OrganizationEditor(newOrg);
- org.bind("gid", orgEditor, "gid");
- org.bind("label", orgEditor, "label");
- org.bind("description", orgEditor, "description");
- org.bind("thumbnail", orgEditor, "thumbnail", {
- converter: val => val ? val : ""
- });
const title = this.tr("Organization Details Editor");
- const win = osparc.ui.window.Window.popUpInWindow(orgEditor, title, 400, 250);
+ const orgEditor = new osparc.editor.OrganizationEditor(org);
+ const win = osparc.ui.window.Window.popUpInWindow(orgEditor, title, 400, 200);
orgEditor.addListener("updateOrg", () => {
this.__updateOrganization(win, orgEditor.getChildControl("save"), orgEditor);
});
@@ -287,14 +282,15 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
}
};
osparc.data.Resources.fetch("organizations", "post", params)
- .then(() => {
+ .then(org => {
osparc.FlashMessenger.getInstance().logAs(name + this.tr(" successfully created"));
button.setFetching(false);
osparc.store.Store.getInstance().reset("organizations");
// reload "profile", "organizations" are part of the information in this endpoint
osparc.data.Resources.getOne("profile", {}, null, false)
.then(() => {
- this.reloadOrganizations();
+ // open it
+ this.reloadOrganizations(org["gid"]);
});
})
.catch(err => {
diff --git a/services/static-webserver/client/source/class/osparc/editor/OrganizationEditor.js b/services/static-webserver/client/source/class/osparc/editor/OrganizationEditor.js
index f4be5233d2f..b528e760c01 100644
--- a/services/static-webserver/client/source/class/osparc/editor/OrganizationEditor.js
+++ b/services/static-webserver/client/source/class/osparc/editor/OrganizationEditor.js
@@ -18,7 +18,7 @@
qx.Class.define("osparc.editor.OrganizationEditor", {
extend: qx.ui.core.Widget,
- construct: function(newOrg = true) {
+ construct: function(organization) {
this.base(arguments);
this._setLayout(new qx.ui.layout.VBox(8));
@@ -29,7 +29,27 @@ qx.Class.define("osparc.editor.OrganizationEditor", {
manager.add(title);
this.getChildControl("description");
this.getChildControl("thumbnail");
- newOrg ? this.getChildControl("create") : this.getChildControl("save");
+ organization ? this.getChildControl("save") : this.getChildControl("create");
+
+ if (organization) {
+ organization.bind("gid", this, "gid");
+ organization.bind("label", this, "label");
+ organization.bind("description", this, "description");
+ organization.bind("thumbnail", this, "thumbnail", {
+ converter: val => val ? val : ""
+ });
+ } else {
+ osparc.store.Store.getInstance().getGroupsOrganizations()
+ .then(orgs => {
+ const existingNames = orgs.map(org => org["label"]);
+ const defaultName = osparc.utils.Utils.getUniqueName("New Organization", existingNames)
+ title.setValue(defaultName);
+ })
+ .catch(err => {
+ console.error(err);
+ title.setValue("New Organization");
+ });
+ }
this.addListener("appear", () => {
title.focus();
@@ -82,7 +102,7 @@ qx.Class.define("osparc.editor.OrganizationEditor", {
font: "text-14",
backgroundColor: "background-main",
placeholder: this.tr("Title"),
- height: 35
+ height: 30,
});
this.bind("label", control, "value");
control.bind("value", this, "label");
@@ -90,12 +110,10 @@ qx.Class.define("osparc.editor.OrganizationEditor", {
break;
}
case "description": {
- control = new qx.ui.form.TextArea().set({
+ control = new qx.ui.form.TextField().set({
font: "text-14",
placeholder: this.tr("Description"),
- autoSize: true,
- minHeight: 70,
- maxHeight: 140
+ height: 30,
});
this.bind("description", control, "value");
control.bind("value", this, "description");
@@ -106,7 +124,7 @@ qx.Class.define("osparc.editor.OrganizationEditor", {
control = new qx.ui.form.TextField().set({
font: "text-14",
placeholder: this.tr("Thumbnail"),
- height: 35
+ height: 30,
});
this.bind("thumbnail", control, "value");
control.bind("value", this, "thumbnail");
diff --git a/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js b/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js
index 6b89ee2af78..dab5a9807c3 100644
--- a/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js
+++ b/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js
@@ -33,20 +33,33 @@ qx.Class.define("osparc.editor.WorkspaceEditor", {
manager.add(title);
this.getChildControl("description");
this.getChildControl("thumbnail");
- workspace ? this.getChildControl("save") : this.getChildControl("create");
+ this.getChildControl("cancel");
+ this.getChildControl("save");
if (workspace) {
- this.__workspaceId = workspace.getWorkspaceId();
- this.set({
- label: workspace.getName(),
- description: workspace.getDescription(),
- thumbnail: workspace.getThumbnail(),
- });
+ // editing
+ this.setWorkspace(workspace);
+ } else {
+ // creating
+ this.__creatingWorkspace = true;
+ this.__createWorkspace()
+ .then(newWorkspace => {
+ this.setWorkspace(newWorkspace);
+ this.fireDataEvent("workspaceCreated");
+ this.getChildControl("sharing");
+ });
}
this.addListener("appear", this.__onAppear, this);
},
properties: {
+ workspace: {
+ check: "osparc.data.model.Workspace",
+ init: null,
+ nullable: false,
+ apply: "__applyWorkspace"
+ },
+
label: {
check: "String",
init: "",
@@ -70,13 +83,26 @@ qx.Class.define("osparc.editor.WorkspaceEditor", {
},
events: {
- "workspaceCreated": "qx.event.type.Data",
+ "workspaceCreated": "qx.event.type.Event",
+ "workspaceDeleted": "qx.event.type.Event",
"workspaceUpdated": "qx.event.type.Event",
+ "updateAccessRights": "qx.event.type.Event",
"cancel": "qx.event.type.Event"
},
+ statics: {
+ POS: {
+ INTRO: 0,
+ TITLE: 1,
+ DESCRIPTION: 2,
+ THUMBNAIL: 3,
+ SHARING: 4,
+ BUTTONS: 5,
+ }
+ },
+
members: {
- __workspaceId: null,
+ __creatingWorkspace: null,
_createChildControlImpl: function(id) {
let control;
@@ -89,7 +115,7 @@ qx.Class.define("osparc.editor.WorkspaceEditor", {
rich: true,
wrap: true
});
- this._add(control);
+ this._addAt(control, this.self().POS.INTRO);
break;
}
case "title": {
@@ -97,71 +123,64 @@ qx.Class.define("osparc.editor.WorkspaceEditor", {
font: "text-14",
backgroundColor: "background-main",
placeholder: this.tr("Title"),
- minHeight: 27
+ height: 30,
});
this.bind("label", control, "value");
control.bind("value", this, "label");
- this._add(control);
+ this._addAt(control, this.self().POS.TITLE);
break;
}
case "description": {
- control = new qx.ui.form.TextArea().set({
+ control = new qx.ui.form.TextField().set({
font: "text-14",
placeholder: this.tr("Description"),
- autoSize: true,
- minHeight: 70,
+ height: 30,
});
this.bind("description", control, "value");
control.bind("value", this, "description");
- this._add(control);
+ this._addAt(control, this.self().POS.DESCRIPTION);
break;
}
case "thumbnail": {
control = new qx.ui.form.TextField().set({
font: "text-14",
placeholder: this.tr("Thumbnail"),
+ height: 30,
});
this.bind("thumbnail", control, "value");
control.bind("value", this, "thumbnail");
- this._add(control);
+ this._addAt(control, this.self().POS.THUMBNAIL);
break;
}
- case "create": {
- const buttons = this.getChildControl("buttonsLayout");
- control = new osparc.ui.form.FetchButton(this.tr("Create")).set({
- appearance: "form-button"
- });
- control.addListener("execute", () => {
- if (this.__validator.validate()) {
- this.__createWorkspace(control);
- }
- }, this);
- buttons.addAt(control, 1);
+ case "sharing": {
+ control = new osparc.share.CollaboratorsWorkspace(this.getWorkspace());
+ control.addListener("updateAccessRights", () => this.fireDataEvent("updateAccessRights", this.getWorkspace().getWorkspaceId()), this);
+ this._addAt(control, this.self().POS.SHARING);
+ break;
+ }
+ case "buttons-layout": {
+ control = new qx.ui.container.Composite(new qx.ui.layout.HBox(8).set({
+ alignX: "right"
+ }));
+ this._addAt(control, this.self().POS.BUTTONS);
break;
}
case "save": {
- const buttons = this.getChildControl("buttonsLayout");
+ const buttons = this.getChildControl("buttons-layout");
control = new osparc.ui.form.FetchButton(this.tr("Save")).set({
appearance: "form-button"
});
- control.addListener("execute", () => {
- if (this.__validator.validate()) {
- this.__editWorkspace(control);
- }
- }, this);
+ control.addListener("execute", () => this.__saveWorkspace(control), this);
buttons.addAt(control, 1);
break;
}
- case "buttonsLayout": {
- control = new qx.ui.container.Composite(new qx.ui.layout.HBox(8).set({
- alignX: "right"
- }));
- const cancelButton = new qx.ui.form.Button(this.tr("Cancel")).set({
+ case "cancel": {
+ const buttons = this.getChildControl("buttons-layout");
+ control = new qx.ui.form.Button(this.tr("Cancel")).set({
appearance: "form-button-text"
});
- cancelButton.addListener("execute", () => this.fireEvent("cancel"), this);
- control.addAt(cancelButton, 0);
- this._add(control);
+ control.addListener("execute", () => this.cancel(), this);
+ buttons.addAt(control, 0);
break;
}
}
@@ -169,36 +188,55 @@ qx.Class.define("osparc.editor.WorkspaceEditor", {
return control || this.base(arguments, id);
},
- __createWorkspace: function(createButton) {
- createButton.setFetching(true);
+ __applyWorkspace: function(workspace) {
+ this.set({
+ label: workspace.getName(),
+ description: workspace.getDescription(),
+ thumbnail: workspace.getThumbnail(),
+ });
+ },
+
+ __createWorkspace: function() {
+ const workspaceStore = osparc.store.Workspaces.getInstance();
+ const workspaces = workspaceStore.getWorkspaces();
+ const existingNames = workspaces.map(workspace => workspace.getName());
+ const defaultName = osparc.utils.Utils.getUniqueName("New Workspace", existingNames)
const newWorkspaceData = {
- name: this.getLabel(),
+ name: this.getLabel() || defaultName,
description: this.getDescription(),
thumbnail: this.getThumbnail(),
};
- osparc.store.Workspaces.getInstance().postWorkspace(newWorkspaceData)
- .then(newWorkspace => this.fireDataEvent("workspaceCreated", newWorkspace))
- .catch(err => {
- console.error(err);
- osparc.FlashMessenger.logAs(err.message, "ERROR");
- })
- .finally(() => createButton.setFetching(false));
+ return workspaceStore.postWorkspace(newWorkspaceData)
},
- __editWorkspace: function(editButton) {
- editButton.setFetching(true);
- const updateData = {
- name: this.getLabel(),
- description: this.getDescription(),
- thumbnail: this.getThumbnail(),
- };
- osparc.store.Workspaces.getInstance().putWorkspace(this.__workspaceId, updateData)
- .then(() => this.fireEvent("workspaceUpdated"))
- .catch(err => {
- console.error(err);
- osparc.FlashMessenger.logAs(err.message, "ERROR");
- })
- .finally(() => editButton.setFetching(false));
+ __saveWorkspace: function(editButton) {
+ if (this.__validator.validate()) {
+ editButton.setFetching(true);
+ const updateData = {
+ name: this.getLabel(),
+ description: this.getDescription(),
+ thumbnail: this.getThumbnail(),
+ };
+ osparc.store.Workspaces.getInstance().putWorkspace(this.getWorkspace().getWorkspaceId(), updateData)
+ .then(() => this.fireEvent("workspaceUpdated"))
+ .catch(err => {
+ console.error(err);
+ osparc.FlashMessenger.logAs(err.message, "ERROR");
+ })
+ .finally(() => editButton.setFetching(false));
+ }
+ },
+
+ cancel: function() {
+ if (this.__creatingWorkspace) {
+ osparc.store.Workspaces.getInstance().deleteWorkspace(this.getWorkspace().getWorkspaceId())
+ .then(() => this.fireEvent("workspaceDeleted"))
+ .catch(err => {
+ console.error(err);
+ osparc.FlashMessenger.logAs(err.message, "ERROR");
+ });
+ }
+ this.fireEvent("cancel");
},
__onAppear: function() {
diff --git a/services/static-webserver/client/source/class/osparc/store/Workspaces.js b/services/static-webserver/client/source/class/osparc/store/Workspaces.js
index 8d803de0af5..253ac714a1d 100644
--- a/services/static-webserver/client/source/class/osparc/store/Workspaces.js
+++ b/services/static-webserver/client/source/class/osparc/store/Workspaces.js
@@ -197,6 +197,10 @@ qx.Class.define("osparc.store.Workspaces", {
return this.workspacesCached.find(w => w.getWorkspaceId() === workspaceId);
},
+ getWorkspaces: function() {
+ return this.workspacesCached;
+ },
+
__addToCache: function(workspace) {
const found = this.workspacesCached.find(w => w.getWorkspaceId() === workspace.getWorkspaceId());
if (!found) {
diff --git a/services/static-webserver/client/source/class/osparc/study/StudyOptions.js b/services/static-webserver/client/source/class/osparc/study/StudyOptions.js
index 54ba001d6d6..9922ec017e3 100644
--- a/services/static-webserver/client/source/class/osparc/study/StudyOptions.js
+++ b/services/static-webserver/client/source/class/osparc/study/StudyOptions.js
@@ -23,28 +23,17 @@ qx.Class.define("osparc.study.StudyOptions", {
this._setLayout(new qx.ui.layout.VBox(15));
- this.__studyId = studyId;
-
- const params = {
- url: {
- studyId
- }
- };
- Promise.all([
- osparc.data.Resources.getOne("studies", params),
- osparc.data.Resources.fetch("studies", "getWallet", params)
- ])
- .then(values => {
- const studyData = values[0];
- this.__studyData = osparc.data.model.Study.deepCloneStudyObject(studyData);
- if (values[1] && "walletId" in values[1]) {
- this.__projectWalletId = values[1]["walletId"];
- }
- this.__buildLayout();
- });
+ this.setStudyId(studyId);
},
properties: {
+ studyId: {
+ check: "String",
+ init: null,
+ nullable: false,
+ apply: "__fetchStudy"
+ },
+
wallet: {
check: "osparc.data.model.Wallet",
init: null,
@@ -93,9 +82,8 @@ qx.Class.define("osparc.study.StudyOptions", {
},
members: {
- __studyId: null,
__studyData: null,
- __projectWalletId: null,
+ __studyWalletId: null,
_createChildControlImpl: function(id) {
let control;
@@ -105,7 +93,7 @@ qx.Class.define("osparc.study.StudyOptions", {
this._addAt(control, 0);
break;
case "title-field":
- control = new qx.ui.form.TextField(this.__studyData["name"]).set({
+ control = new qx.ui.form.TextField().set({
maxWidth: 220
});
this.getChildControl("title-layout").add(control);
@@ -192,6 +180,27 @@ qx.Class.define("osparc.study.StudyOptions", {
return control || this.base(arguments, id);
},
+ __fetchStudy: function(studyId) {
+ const params = {
+ url: {
+ studyId
+ }
+ };
+ Promise.all([
+ osparc.data.Resources.getOne("studies", params),
+ osparc.data.Resources.fetch("studies", "getWallet", params)
+ ])
+ .then(values => {
+ const studyData = values[0];
+ this.__studyData = osparc.data.model.Study.deepCloneStudyObject(studyData);
+
+ if (values[1] && "walletId" in values[1]) {
+ this.__studyWalletId = values[1]["walletId"];
+ }
+ this.__buildLayout();
+ });
+ },
+
__applyWallet: function(wallet) {
if (wallet) {
const walletSelector = this.getChildControl("wallet-selector");
@@ -214,15 +223,16 @@ qx.Class.define("osparc.study.StudyOptions", {
__buildTopSummaryLayout: function() {
const store = osparc.store.Store.getInstance();
- this._createChildControlImpl("title-label");
const titleField = this.getChildControl("title-field");
+ if (this.__studyData) {
+ titleField.setValue(this.__studyData["name"]);
+ }
titleField.addListener("appear", () => {
titleField.focus();
titleField.activate();
});
// Wallet Selector
- this._createChildControlImpl("wallet-selector-label");
const walletSelector = this.getChildControl("wallet-selector");
const wallets = store.getWallets();
@@ -241,8 +251,8 @@ qx.Class.define("osparc.study.StudyOptions", {
}
});
const preferredWallet = store.getPreferredWallet();
- if (wallets.find(wallet => wallet.getWalletId() === parseInt(this.__projectWalletId))) {
- selectWallet(this.__projectWalletId);
+ if (wallets.find(wallet => wallet.getWalletId() === parseInt(this.__studyWalletId))) {
+ selectWallet(this.__studyWalletId);
} else if (preferredWallet) {
selectWallet(preferredWallet.getWalletId());
} else if (!osparc.desktop.credits.Utils.autoSelectActiveWallet(walletSelector)) {
@@ -283,17 +293,18 @@ qx.Class.define("osparc.study.StudyOptions", {
// first, update the name if necessary
const titleSelection = this.getChildControl("title-field").getValue();
- if (this.__studyData["name"] !== titleSelection) {
+ if (this.__studyData && this.__studyData["name"] !== titleSelection) {
await this.__updateName(this.__studyData, titleSelection);
}
// second, update the wallet if necessary
const store = osparc.store.Store.getInstance();
const walletSelection = this.getChildControl("wallet-selector").getSelection();
- if (walletSelection.length && walletSelection[0]["walletId"]) {
+ const studyId = this.getStudyId();
+ if (studyId && walletSelection.length && walletSelection[0]["walletId"]) {
const params = {
url: {
- "studyId": this.__studyData["uuid"],
+ studyId,
"walletId": walletSelection[0]["walletId"]
}
};
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 dab2bd53bd8..0240d263e47 100644
--- a/services/static-webserver/client/source/class/osparc/study/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/study/Utils.js
@@ -116,7 +116,8 @@ qx.Class.define("osparc.study.Utils", {
newStudyLabel = metadata["name"];
}
if (existingStudies) {
- const title = osparc.utils.Utils.getUniqueStudyName(newStudyLabel, existingStudies);
+ const existingNames = existingStudies.map(study => study["name"]);
+ const title = osparc.utils.Utils.getUniqueName(newStudyLabel, existingNames);
minStudyData["name"] = title;
} else {
minStudyData["name"] = newStudyLabel;
@@ -234,7 +235,7 @@ qx.Class.define("osparc.study.Utils", {
// update task
osparc.widget.ProgressSequence.updateTaskProgress(existingTask, {
value: percent,
- progressLabel: percent*100 + "%"
+ progressLabel: parseFloat((percent*100).toFixed(2)) + "%"
});
} else {
// new task
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 5c751c2ee8f..b095d95eee2 100644
--- a/services/static-webserver/client/source/class/osparc/utils/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/utils/Utils.js
@@ -277,12 +277,11 @@ qx.Class.define("osparc.utils.Utils", {
return reloadButton;
},
- getUniqueStudyName: function(preferredName, list) {
+ getUniqueName: function(preferredName, existingNames) {
let title = preferredName;
- const existingTitles = list.map(study => study.name);
- if (existingTitles.includes(title)) {
+ if (existingNames.includes(title)) {
let cont = 1;
- while (existingTitles.includes(`${title} (${cont})`)) {
+ while (existingNames.includes(`${title} (${cont})`)) {
cont++;
}
title += ` (${cont})`;
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 cacb9ffb83d..492544fa598 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
@@ -7,7 +7,7 @@
"steps": [{
"anchorEl": "osparc-test-id=dashboardTabs",
"title": "Dashboard Menu",
- "text": "The menu tabs give you quick access to a set of core elements of the platform, namely Projects, Tutorials, Services and Data.",
+ "text": "The menu tabs give you quick access to a set of core elements of the platform, namely Projects, Tutorials and Services.",
"placement": "bottom"
}, {
"beforeClick": {
@@ -28,7 +28,7 @@
"selector": "osparc-test-id=servicesTabBtn"
},
"anchorEl": "osparc-test-id=servicesTabBtn",
- "text": "Every Project in Sim4Life is composed of at lease one so-called Service.
Services 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 Project.",
+ "text": "Every Project in Sim4Life is composed of at lease 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"
}]
},