Skip to content

Commit a387fb7

Browse files
authored
🐛 [Frontend] Fix: New project from menu (ITISFoundation#7377)
1 parent 981f27a commit a387fb7

File tree

6 files changed

+198
-213
lines changed

6 files changed

+198
-213
lines changed

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

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,15 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
168168
if (plusButtonConfig["categories"]) {
169169
this.__addCategories(plusButtonConfig["categories"]);
170170
}
171-
plusButtonConfig["resources"].forEach(newStudyData => {
172-
if (newStudyData["showDisabled"]) {
173-
this.__addDisabledButton(newStudyData);
174-
} else if (newStudyData["resourceType"] === "study") {
175-
this.__addEmptyStudyButton(newStudyData);
176-
} else if (newStudyData["resourceType"] === "template") {
177-
this.__addFromTemplateButton(newStudyData, templates);
178-
} else if (newStudyData["resourceType"] === "service") {
179-
this.__addFromServiceButton(newStudyData);
171+
plusButtonConfig["resources"].forEach(buttonConfig => {
172+
if (buttonConfig["showDisabled"]) {
173+
this.__addDisabledButton(buttonConfig);
174+
} else if (buttonConfig["resourceType"] === "study") {
175+
this.__addEmptyStudyButton(buttonConfig);
176+
} else if (buttonConfig["resourceType"] === "template") {
177+
this.__addFromTemplateButton(buttonConfig, templates);
178+
} else if (buttonConfig["resourceType"] === "service") {
179+
this.__addFromServiceButton(buttonConfig);
180180
}
181181
});
182182
});
@@ -241,55 +241,55 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
241241
}
242242
},
243243

244-
__addDisabledButton: function(newStudyData) {
245-
const menuButton = this.self().createMenuButton(null, newStudyData["title"], newStudyData["reason"]);
246-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
244+
__addDisabledButton: function(buttonConfig) {
245+
const menuButton = this.self().createMenuButton(null, buttonConfig["title"], buttonConfig["reason"]);
246+
osparc.utils.Utils.setIdToWidget(menuButton, buttonConfig["idToWidget"]);
247247
menuButton.setEnabled(false);
248248

249-
this.__addIcon(menuButton, newStudyData);
250-
this.__addFromResourceButton(menuButton, newStudyData["category"]);
249+
this.__addIcon(menuButton, buttonConfig);
250+
this.__addFromResourceButton(menuButton, buttonConfig["category"]);
251251
},
252252

253-
__addEmptyStudyButton: function(newStudyData) {
254-
const menuButton = this.self().createMenuButton(null, newStudyData["title"]);
255-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
253+
__addEmptyStudyButton: function(buttonConfig) {
254+
const menuButton = this.self().createMenuButton(null, buttonConfig["title"]);
255+
osparc.utils.Utils.setIdToWidget(menuButton, buttonConfig["idToWidget"]);
256256

257257
menuButton.addListener("tap", () => {
258258
this.fireDataEvent("newEmptyStudyClicked", {
259-
newStudyLabel: newStudyData["newStudyLabel"],
259+
newStudyLabel: buttonConfig["newStudyLabel"],
260260
});
261261
});
262262

263-
this.__addIcon(menuButton, newStudyData);
264-
this.__addFromResourceButton(menuButton, newStudyData["category"]);
263+
this.__addIcon(menuButton, buttonConfig);
264+
this.__addFromResourceButton(menuButton, buttonConfig["category"]);
265265
},
266266

267-
__addFromTemplateButton: function(newStudyData, templates) {
268-
const menuButton = this.self().createMenuButton(null, newStudyData["title"]);
269-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
267+
__addFromTemplateButton: function(buttonConfig, templates) {
268+
const menuButton = this.self().createMenuButton(null, buttonConfig["title"]);
269+
osparc.utils.Utils.setIdToWidget(menuButton, buttonConfig["idToWidget"]);
270270
// disable it until found in templates store
271271
menuButton.setEnabled(false);
272272

273-
let templateMetadata = templates.find(t => t.name === newStudyData["expectedTemplateLabel"]);
273+
let templateMetadata = templates.find(t => t.name === buttonConfig["expectedTemplateLabel"]);
274274
if (templateMetadata) {
275275
menuButton.setEnabled(true);
276276
menuButton.addListener("tap", () => {
277277
this.fireDataEvent("newStudyFromTemplateClicked", {
278278
templateData: templateMetadata,
279-
newStudyLabel: newStudyData["newStudyLabel"],
279+
newStudyLabel: buttonConfig["newStudyLabel"],
280280
});
281281
});
282-
this.__addIcon(menuButton, newStudyData, templateMetadata);
283-
this.__addFromResourceButton(menuButton, newStudyData["category"]);
282+
this.__addIcon(menuButton, buttonConfig, templateMetadata);
283+
this.__addFromResourceButton(menuButton, buttonConfig["category"]);
284284
}
285285
},
286286

287-
__addFromServiceButton: function(newStudyData) {
287+
__addFromServiceButton: function(buttonConfig) {
288288
const addListenerToButton = (menuButton, latestMetadata) => {
289289
menuButton.addListener("tap", () => {
290290
this.fireDataEvent("newStudyFromServiceClicked", {
291291
serviceMetadata: latestMetadata,
292-
newStudyLabel: newStudyData["newStudyLabel"],
292+
newStudyLabel: buttonConfig["newStudyLabel"],
293293
});
294294
});
295295

@@ -299,30 +299,38 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
299299
e.stopPropagation();
300300
latestMetadata["resourceType"] = "service";
301301
const resourceDetails = new osparc.dashboard.ResourceDetails(latestMetadata);
302-
osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails);
302+
const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails);
303+
resourceDetails.addListener("openService", ev => {
304+
win.close();
305+
const openServiceData = ev.getData();
306+
this.fireDataEvent("newStudyFromServiceClicked", {
307+
serviceMetadata: openServiceData,
308+
newStudyLabel: buttonConfig["newStudyLabel"],
309+
});
310+
});
303311
}
304312
const infoButton = new osparc.ui.basic.IconButton(osparc.ui.hint.InfoHint.INFO_ICON + "/16", cb);
305313
// where the shortcut is supposed to go
306314
// eslint-disable-next-line no-underscore-dangle
307315
menuButton._add(infoButton, {column: 2});
308316
};
309317

310-
if ("expectedKey" in newStudyData) {
311-
const menuButton = this.self().createMenuButton(null, newStudyData["title"]);
312-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
318+
if ("expectedKey" in buttonConfig) {
319+
const menuButton = this.self().createMenuButton(null, buttonConfig["title"]);
320+
osparc.utils.Utils.setIdToWidget(menuButton, buttonConfig["idToWidget"]);
313321
// disable it until found in services store
314322
menuButton.setEnabled(false);
315323

316-
const key = newStudyData["expectedKey"];
324+
const key = buttonConfig["expectedKey"];
317325
const latestMetadata = osparc.store.Services.getLatest(key);
318326
if (!latestMetadata) {
319327
return;
320328
}
321329
menuButton.setEnabled(true);
322-
this.__addIcon(menuButton, newStudyData, latestMetadata);
323-
this.__addFromResourceButton(menuButton, newStudyData["category"]);
330+
this.__addIcon(menuButton, buttonConfig, latestMetadata);
331+
this.__addFromResourceButton(menuButton, buttonConfig["category"]);
324332
addListenerToButton(menuButton, latestMetadata);
325-
} else if ("myMostUsed" in newStudyData) {
333+
} else if ("myMostUsed" in buttonConfig) {
326334
const excludeFrontend = true;
327335
const excludeDeprecated = true
328336
osparc.store.Services.getServicesLatestList(excludeFrontend, excludeDeprecated)
@@ -331,7 +339,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
331339
"sort": "hits",
332340
"order": "down"
333341
});
334-
for (let i=0; i<newStudyData["myMostUsed"]; i++) {
342+
for (let i=0; i<buttonConfig["myMostUsed"]; i++) {
335343
const latestMetadata = servicesList[i];
336344
if (latestMetadata && latestMetadata["hits"] > 0) {
337345
const menuButton = new qx.ui.menu.Button().set({
@@ -340,7 +348,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
340348
allowGrowX: true,
341349
});
342350
this.__addIcon(menuButton, null, latestMetadata);
343-
this.__addFromResourceButton(menuButton, newStudyData["category"]);
351+
this.__addFromResourceButton(menuButton, buttonConfig["category"]);
344352
addListenerToButton(menuButton, latestMetadata);
345353
}
346354
}

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

Lines changed: 149 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
7676
this.addListener("appear", () => this._moreResourcesRequired());
7777
},
7878

79+
properties: {
80+
multiSelection: {
81+
check: "Boolean",
82+
init: false,
83+
nullable: false,
84+
event: "changeMultiSelection",
85+
apply: "_applyMultiSelection"
86+
},
87+
},
88+
7989
events: {
8090
"changeTab": "qx.event.type.Data",
8191
"publishTemplate": "qx.event.type.Data"
@@ -491,12 +501,147 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
491501
this.self().startStudyById(studyId, openCB, cancelCB, isStudyCreation);
492502
},
493503

494-
_createStudyFromTemplate: function() {
495-
throw new Error("Abstract method called!");
504+
_createStudyFromTemplate: function(templateData) {
505+
if (!this._checkLoggedIn()) {
506+
return;
507+
}
508+
509+
const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true});
510+
this._showLoadingPage(this.tr("Creating ") + (templateData.name || studyAlias));
511+
512+
if (osparc.desktop.credits.Utils.areWalletsEnabled()) {
513+
const studyOptions = new osparc.study.StudyOptions();
514+
// they will be patched once the study is created
515+
studyOptions.setPatchStudy(false);
516+
studyOptions.setStudyData(templateData);
517+
studyOptions.getChildControl("open-button").setLabel(this.tr("New"));
518+
const win = osparc.study.StudyOptions.popUpInWindow(studyOptions);
519+
win.moveItUp();
520+
const cancelStudyOptions = () => {
521+
this._hideLoadingPage();
522+
win.close();
523+
}
524+
win.addListener("cancel", () => cancelStudyOptions());
525+
studyOptions.addListener("cancel", () => cancelStudyOptions());
526+
studyOptions.addListener("startStudy", () => {
527+
const newName = studyOptions.getChildControl("title-field").getValue();
528+
const walletSelection = studyOptions.getChildControl("wallet-selector").getSelection();
529+
const nodesPricingUnits = studyOptions.getChildControl("study-pricing-units").getNodePricingUnits();
530+
win.close();
531+
532+
this._showLoadingPage(this.tr("Creating ") + (newName || studyAlias));
533+
osparc.study.Utils.createStudyFromTemplate(templateData, this._loadingPage)
534+
.then(newStudyData => {
535+
const studyId = newStudyData["uuid"];
536+
const openCB = () => {
537+
this._hideLoadingPage();
538+
};
539+
const cancelCB = () => {
540+
this._hideLoadingPage();
541+
const params = {
542+
url: {
543+
studyId
544+
}
545+
};
546+
osparc.data.Resources.fetch("studies", "delete", params);
547+
};
548+
549+
const promises = [];
550+
// patch the name
551+
if (newStudyData["name"] !== newName) {
552+
promises.push(osparc.study.StudyOptions.updateName(newStudyData, newName));
553+
}
554+
// patch the wallet
555+
if (walletSelection.length && walletSelection[0]["walletId"]) {
556+
const walletId = walletSelection[0]["walletId"];
557+
promises.push(osparc.study.StudyOptions.updateWallet(newStudyData["uuid"], walletId));
558+
}
559+
// patch the pricing units
560+
// the nodeIds are coming from the original template, they need to be mapped to the newStudy
561+
const workbench = newStudyData["workbench"];
562+
const nodesIdsListed = [];
563+
Object.keys(workbench).forEach(nodeId => {
564+
const nodeData = workbench[nodeId];
565+
if (osparc.study.StudyPricingUnits.includeInList(nodeData)) {
566+
nodesIdsListed.push(nodeId);
567+
}
568+
});
569+
nodesPricingUnits.forEach((nodePricingUnits, idx) => {
570+
const selectedPricingUnitId = nodePricingUnits.getPricingUnits().getSelectedUnitId();
571+
if (selectedPricingUnitId) {
572+
const nodeId = nodesIdsListed[idx];
573+
const pricingPlanId = nodePricingUnits.getPricingPlanId();
574+
promises.push(osparc.study.NodePricingUnits.patchPricingUnitSelection(studyId, nodeId, pricingPlanId, selectedPricingUnitId));
575+
}
576+
});
577+
578+
Promise.all(promises)
579+
.then(() => {
580+
win.close();
581+
const showStudyOptions = false;
582+
this._startStudyById(studyId, openCB, cancelCB, showStudyOptions);
583+
});
584+
})
585+
.catch(err => {
586+
this._hideLoadingPage();
587+
osparc.FlashMessenger.logError(err);
588+
});
589+
});
590+
} else {
591+
osparc.study.Utils.createStudyFromTemplate(templateData, this._loadingPage)
592+
.then(newStudyData => {
593+
const studyId = newStudyData["uuid"];
594+
const openCB = () => this._hideLoadingPage();
595+
const cancelCB = () => {
596+
this._hideLoadingPage();
597+
const params = {
598+
url: {
599+
studyId
600+
}
601+
};
602+
osparc.data.Resources.fetch("studies", "delete", params);
603+
};
604+
const isStudyCreation = true;
605+
this._startStudyById(studyId, openCB, cancelCB, isStudyCreation);
606+
})
607+
.catch(err => {
608+
this._hideLoadingPage();
609+
osparc.FlashMessenger.logError(err);
610+
});
611+
}
496612
},
497613

498-
_createStudyFromService: function() {
499-
throw new Error("Abstract method called!");
614+
_createStudyFromService: function(key, version) {
615+
if (!this._checkLoggedIn()) {
616+
return;
617+
}
618+
619+
const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true});
620+
this._showLoadingPage(this.tr("Creating ") + studyAlias);
621+
622+
osparc.study.Utils.createStudyFromService(key, version)
623+
.then(studyId => {
624+
const openCB = () => this._hideLoadingPage();
625+
const cancelCB = () => {
626+
this._hideLoadingPage();
627+
const params = {
628+
url: {
629+
studyId
630+
}
631+
};
632+
osparc.data.Resources.fetch("studies", "delete", params);
633+
};
634+
const isStudyCreation = true;
635+
this._startStudyById(studyId, openCB, cancelCB, isStudyCreation);
636+
})
637+
.catch(err => {
638+
this._hideLoadingPage();
639+
osparc.FlashMessenger.logError(err);
640+
});
641+
},
642+
643+
_applyMultiSelection: function(value) {
644+
return;
500645
},
501646

502647
_deleteResourceRequested: function(resourceId) {

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

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
3232
this.__sortBy = osparc.service.SortServicesButtons.DefaultSorting;
3333
},
3434

35-
properties: {
36-
multiSelection: {
37-
check: "Boolean",
38-
init: false,
39-
nullable: false,
40-
event: "changeMultiSelection",
41-
apply: "__applyMultiSelection"
42-
}
43-
},
44-
4535
members: {
4636
__sortBy: null,
4737

@@ -113,35 +103,6 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", {
113103
this.resetSelection();
114104
},
115105

116-
_createStudyFromService: function(key, version) {
117-
if (!this._checkLoggedIn()) {
118-
return;
119-
}
120-
121-
const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true});
122-
this._showLoadingPage(this.tr("Creating ") + studyAlias);
123-
124-
osparc.study.Utils.createStudyFromService(key, version)
125-
.then(studyId => {
126-
const openCB = () => this._hideLoadingPage();
127-
const cancelCB = () => {
128-
this._hideLoadingPage();
129-
const params = {
130-
url: {
131-
studyId
132-
}
133-
};
134-
osparc.data.Resources.fetch("studies", "delete", params);
135-
};
136-
const isStudyCreation = true;
137-
this._startStudyById(studyId, openCB, cancelCB, isStudyCreation);
138-
})
139-
.catch(err => {
140-
this._hideLoadingPage();
141-
osparc.FlashMessenger.logError(err);
142-
});
143-
},
144-
145106
// LAYOUT //
146107
_createLayout: function() {
147108
this._createSearchBar();

0 commit comments

Comments
 (0)