Skip to content

Commit 17f486e

Browse files
authored
🎨 [Frontend] UX: Create Study from Template (#6706)
1 parent a44de5c commit 17f486e

File tree

8 files changed

+259
-111
lines changed

8 files changed

+259
-111
lines changed

services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
9595
return isLogged;
9696
},
9797

98-
startStudyById: function(studyId, openCB, cancelCB, isStudyCreation = false) {
98+
startStudyById: function(studyId, openCB, cancelCB, showStudyOptions = false) {
9999
if (!osparc.dashboard.ResourceBrowserBase.checkLoggedIn()) {
100100
return;
101101
}
@@ -117,7 +117,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
117117
osparc.data.Resources.fetch("studies", "getWallet", params)
118118
.then(wallet => {
119119
if (
120-
isStudyCreation ||
120+
showStudyOptions ||
121121
wallet === null ||
122122
osparc.desktop.credits.Utils.getWallet(wallet["walletId"]) === null
123123
) {

services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
12291229
folderId: this.getCurrentFolderId(),
12301230
};
12311231
osparc.study.Utils.createStudyFromTemplate(templateCopyData, this._loadingPage, contextProps)
1232-
.then(studyId => this.__startStudyAfterCreating(studyId))
1232+
.then(studyData => this.__startStudyAfterCreating(studyData["uuid"]))
12331233
.catch(err => {
12341234
this._hideLoadingPage();
12351235
osparc.FlashMessenger.getInstance().logAs(err.message, "ERROR");

services/static-webserver/client/source/class/osparc/dashboard/TemplateBrowser.js

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,27 +137,85 @@ qx.Class.define("osparc.dashboard.TemplateBrowser", {
137137
return;
138138
}
139139

140-
this._showLoadingPage(this.tr("Creating ") + (templateData.name || osparc.product.Utils.getStudyAlias({firstUpperCase: true})));
141-
osparc.study.Utils.createStudyFromTemplate(templateData, this._loadingPage)
142-
.then(studyId => {
143-
const openCB = () => this._hideLoadingPage();
144-
const cancelCB = () => {
145-
this._hideLoadingPage();
146-
const params = {
147-
url: {
148-
studyId
149-
}
140+
const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true});
141+
this._showLoadingPage(this.tr("Creating ") + (templateData.name || studyAlias));
142+
143+
const studyOptions = new osparc.study.StudyOptions();
144+
// they will be patched once the study is created
145+
studyOptions.setPatchStudy(false);
146+
studyOptions.setStudyData(templateData);
147+
const win = osparc.study.StudyOptions.popUpInWindow(studyOptions);
148+
win.moveItUp();
149+
const cancelStudyOptions = () => {
150+
this._hideLoadingPage();
151+
win.close();
152+
}
153+
win.addListener("cancel", () => cancelStudyOptions());
154+
studyOptions.addListener("cancel", () => cancelStudyOptions());
155+
studyOptions.addListener("startStudy", () => {
156+
const newName = studyOptions.getChildControl("title-field").getValue();
157+
const walletSelection = studyOptions.getChildControl("wallet-selector").getSelection();
158+
const nodesPricingUnits = studyOptions.getChildControl("study-pricing-units").getNodePricingUnits();
159+
win.close();
160+
this._showLoadingPage(this.tr("Creating ") + (newName || studyAlias));
161+
osparc.study.Utils.createStudyFromTemplate(templateData, this._loadingPage)
162+
.then(newStudyData => {
163+
const studyId = newStudyData["uuid"];
164+
const openCB = () => {
165+
this._hideLoadingPage();
150166
};
151-
osparc.data.Resources.fetch("studies", "delete", params);
152-
};
153-
const isStudyCreation = true;
154-
this._startStudyById(studyId, openCB, cancelCB, isStudyCreation);
155-
})
156-
.catch(err => {
157-
this._hideLoadingPage();
158-
osparc.FlashMessenger.getInstance().logAs(err.message, "ERROR");
159-
console.error(err);
160-
});
167+
const cancelCB = () => {
168+
this._hideLoadingPage();
169+
const params = {
170+
url: {
171+
studyId
172+
}
173+
};
174+
osparc.data.Resources.fetch("studies", "delete", params);
175+
};
176+
177+
const promises = [];
178+
// patch the name
179+
if (newStudyData["name"] !== newName) {
180+
promises.push(osparc.study.StudyOptions.updateName(newStudyData, newName));
181+
}
182+
// patch the wallet
183+
if (walletSelection.length && walletSelection[0]["walletId"]) {
184+
const walletId = walletSelection[0]["walletId"];
185+
promises.push(osparc.study.StudyOptions.updateWallet(newStudyData["uuid"], walletId));
186+
}
187+
// patch the pricing units
188+
// the nodeIds are coming from the original template, they need to be mapped to the newStudy
189+
const workbench = newStudyData["workbench"];
190+
const nodesIdsListed = [];
191+
Object.keys(workbench).forEach(nodeId => {
192+
const node = workbench[nodeId];
193+
if (osparc.study.StudyPricingUnits.includeInList(node)) {
194+
nodesIdsListed.push(nodeId);
195+
}
196+
});
197+
nodesPricingUnits.forEach((nodePricingUnits, idx) => {
198+
const selectedPricingUnitId = nodePricingUnits.getPricingUnits().getSelectedUnitId();
199+
if (selectedPricingUnitId) {
200+
const nodeId = nodesIdsListed[idx];
201+
const pricingPlanId = nodePricingUnits.getPricingPlanId();
202+
promises.push(osparc.study.NodePricingUnits.patchPricingUnitSelection(studyId, nodeId, pricingPlanId, selectedPricingUnitId));
203+
}
204+
});
205+
206+
Promise.all(promises)
207+
.then(() => {
208+
win.close();
209+
const showStudyOptions = false;
210+
this._startStudyById(studyId, openCB, cancelCB, showStudyOptions);
211+
});
212+
})
213+
.catch(err => {
214+
this._hideLoadingPage();
215+
osparc.FlashMessenger.getInstance().logAs(err.message, "ERROR");
216+
console.error(err);
217+
});
218+
});
161219
},
162220

163221
// LAYOUT //

services/static-webserver/client/source/class/osparc/node/TierSelectionView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ qx.Class.define("osparc.node.TierSelectionView", {
105105
if (selection.length) {
106106
tierBox.setEnabled(false);
107107
const selectedUnitId = selection[0].getModel();
108-
osparc.study.NodePricingUnits.pricingUnitSelected(studyId, nodeId, pricingPlans["pricingPlanId"], selectedUnitId)
108+
osparc.study.NodePricingUnits.patchPricingUnitSelection(studyId, nodeId, pricingPlans["pricingPlanId"], selectedUnitId)
109109
.finally(() => {
110110
tierBox.setEnabled(true);
111111
showSelectedTier(selectedUnitId);

services/static-webserver/client/source/class/osparc/study/NodePricingUnits.js

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ qx.Class.define("osparc.study.NodePricingUnits", {
3030
layout: new qx.ui.layout.VBox()
3131
});
3232

33-
this.__studyId = studyId;
34-
this.__nodeId = nodeId;
33+
this.set({
34+
studyId,
35+
nodeId,
36+
});
3537
if (node instanceof osparc.data.model.Node) {
3638
this.__nodeKey = node.getKey();
3739
this.__nodeVersion = node.getVersion();
@@ -43,8 +45,35 @@ qx.Class.define("osparc.study.NodePricingUnits", {
4345
}
4446
},
4547

48+
properties: {
49+
studyId: {
50+
check: "String",
51+
init: null,
52+
nullable: false,
53+
},
54+
55+
nodeId: {
56+
check: "String",
57+
init: null,
58+
nullable: false,
59+
},
60+
61+
pricingPlanId: {
62+
check: "Number",
63+
init: null,
64+
nullable: false,
65+
},
66+
67+
patchNode: {
68+
check: "Boolean",
69+
init: true,
70+
nullable: false,
71+
event: "changePatchNode",
72+
},
73+
},
74+
4675
statics: {
47-
pricingUnitSelected: function(studyId, nodeId, planId, selectedUnitId) {
76+
patchPricingUnitSelection: function(studyId, nodeId, planId, selectedUnitId) {
4877
const params = {
4978
url: {
5079
studyId,
@@ -58,19 +87,18 @@ qx.Class.define("osparc.study.NodePricingUnits", {
5887
},
5988

6089
members: {
61-
__studyId: null,
62-
__nodeId: null,
6390
__nodeKey: null,
6491
__nodeVersion: null,
6592
__nodeLabel: null,
93+
__pricingUnits: null,
6694

6795
showPricingUnits: function(inGroupBox = true) {
6896
return new Promise(resolve => {
6997
const nodeKey = this.__nodeKey;
7098
const nodeVersion = this.__nodeVersion;
7199
const nodeLabel = this.__nodeLabel;
72-
const studyId = this.__studyId;
73-
const nodeId = this.__nodeId;
100+
const studyId = this.getStudyId();
101+
const nodeId = this.getNodeId();
74102

75103
const plansParams = {
76104
url: osparc.data.Resources.getServiceUrl(
@@ -79,37 +107,47 @@ qx.Class.define("osparc.study.NodePricingUnits", {
79107
)
80108
};
81109
osparc.data.Resources.fetch("services", "pricingPlans", plansParams)
82-
.then(pricingPlans => {
83-
if (pricingPlans) {
110+
.then(pricingPlan => {
111+
if (pricingPlan) {
84112
const unitParams = {
85113
url: {
86114
studyId,
87115
nodeId
88116
}
89117
};
118+
this.set({
119+
pricingPlanId: pricingPlan["pricingPlanId"]
120+
});
90121
osparc.data.Resources.fetch("studies", "getPricingUnit", unitParams)
91122
.then(preselectedPricingUnit => {
92-
if (pricingPlans && "pricingUnits" in pricingPlans && pricingPlans["pricingUnits"].length) {
93-
const unitButtons = new osparc.study.PricingUnits(pricingPlans["pricingUnits"], preselectedPricingUnit);
123+
if (pricingPlan && "pricingUnits" in pricingPlan && pricingPlan["pricingUnits"].length) {
124+
const pricingUnitButtons = this.__pricingUnits = new osparc.study.PricingUnits(pricingPlan["pricingUnits"], preselectedPricingUnit);
94125
if (inGroupBox) {
95126
const pricingUnitsLayout = osparc.study.StudyOptions.createGroupBox(nodeLabel);
96-
pricingUnitsLayout.add(unitButtons);
127+
pricingUnitsLayout.add(pricingUnitButtons);
97128
this._add(pricingUnitsLayout);
98129
} else {
99-
this._add(unitButtons);
130+
this._add(pricingUnitButtons);
100131
}
101-
unitButtons.addListener("changeSelectedUnitId", e => {
102-
unitButtons.setEnabled(false);
103-
const selectedPricingUnitId = e.getData();
104-
this.self().pricingUnitSelected(this.__studyId, this.__nodeId, pricingPlans["pricingPlanId"], selectedPricingUnitId)
105-
.finally(() => unitButtons.setEnabled(true));
132+
pricingUnitButtons.addListener("changeSelectedUnitId", e => {
133+
if (this.isPatchNode()) {
134+
pricingUnitButtons.setEnabled(false);
135+
const pricingPlanId = this.getPricingPlanId();
136+
const selectedPricingUnitId = e.getData();
137+
this.self().patchPricingUnitSelection(studyId, nodeId, pricingPlanId, selectedPricingUnitId)
138+
.finally(() => pricingUnitButtons.setEnabled(true));
139+
}
106140
});
107141
}
108142
})
109143
.finally(() => resolve());
110144
}
111145
});
112146
});
113-
}
147+
},
148+
149+
getPricingUnits: function() {
150+
return this.__pricingUnits;
151+
},
114152
}
115153
});

0 commit comments

Comments
 (0)