Skip to content

Commit 97fafc4

Browse files
authored
🎨 [Frontend] Card Menu: Template menu on template, tutorial and hypertool cards (#7696)
1 parent c8bbdc2 commit 97fafc4

File tree

16 files changed

+262
-157
lines changed

16 files changed

+262
-157
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ qx.Class.define("osparc.dashboard.AppBrowser", {
165165
},
166166

167167
_populateCardMenu: function(card) {
168+
const studyData = card.getResourceData();
169+
if (studyData["resourceType"] === "hypertool") {
170+
// The App Browser can also list templates (hypertools)
171+
this._populateTemplateCardMenu(card);
172+
} else {
173+
this._populateServiceCardMenu(card);
174+
}
175+
},
176+
177+
_populateServiceCardMenu: function(card) {
168178
const menu = card.getMenu();
169179
const appData = card.getResourceData();
170180

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
4040
events: {
4141
"updateStudy": "qx.event.type.Data",
4242
"updateTemplate": "qx.event.type.Data",
43+
"updateTutorial": "qx.event.type.Data",
4344
"updateService": "qx.event.type.Data",
4445
"updateHypertool": "qx.event.type.Data",
4546
"publishTemplate": "qx.event.type.Data",
@@ -325,8 +326,9 @@ qx.Class.define("osparc.dashboard.CardBase", {
325326
check: [
326327
"study",
327328
"template",
328-
"service",
329+
"tutorial",
329330
"hypertool",
331+
"service",
330332
],
331333
init: true,
332334
nullable: true,
@@ -519,6 +521,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
519521
switch (resourceData["resourceType"]) {
520522
case "study":
521523
case "template":
524+
case "tutorial":
522525
case "hypertool":
523526
uuid = resourceData.uuid ? resourceData.uuid : null;
524527
owner = resourceData.prjOwner ? resourceData.prjOwner : "";
@@ -552,7 +555,12 @@ qx.Class.define("osparc.dashboard.CardBase", {
552555
workbench
553556
});
554557

555-
if (["study", "template", "hypertool"].includes(resourceData["resourceType"])) {
558+
if ([
559+
"study",
560+
"template",
561+
"tutorial",
562+
"hypertool"
563+
].includes(resourceData["resourceType"])) {
556564
osparc.store.Services.getStudyServices(resourceData.uuid)
557565
.then(resp => {
558566
const services = resp["services"];
@@ -1002,6 +1010,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
10021010
[
10031011
"updateStudy",
10041012
"updateTemplate",
1013+
"updateTutorial",
10051014
"updateService",
10061015
"updateHypertool",
10071016
].forEach(ev => {
@@ -1055,6 +1064,8 @@ qx.Class.define("osparc.dashboard.CardBase", {
10551064
toolTipText += osparc.product.Utils.getStudyAlias();
10561065
} else if (this.isResourceType("template")) {
10571066
toolTipText += osparc.product.Utils.getTemplateAlias();
1067+
} else if (this.isResourceType("tutorial")) {
1068+
toolTipText += osparc.product.Utils.getTutorialAlias();
10581069
} else if (this.isResourceType("hypertool")) {
10591070
toolTipText += osparc.product.Utils.getAppAlias();
10601071
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,12 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
185185
// overridden
186186
_applyLastChangeDate: function(value, old) {
187187
if (value) {
188-
if (["study", "template", "hypertool"].includes(this.getResourceType())) {
188+
if ([
189+
"study",
190+
"template",
191+
"tutorial",
192+
"hypertool",
193+
].includes(this.getResourceType())) {
189194
const dateBy = this.getChildControl("date-by");
190195
dateBy.set({
191196
date: value,

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,12 @@ qx.Class.define("osparc.dashboard.ListButtonItem", {
186186
// overridden
187187
_applyLastChangeDate: function(value, old) {
188188
if (value) {
189-
if (["study", "template", "hypertool"].includes(this.getResourceType())) {
189+
if ([
190+
"study",
191+
"template",
192+
"tutorial",
193+
"hypertool",
194+
].includes(this.getResourceType())) {
190195
const dateBy = this.getChildControl("date-by");
191196
dateBy.set({
192197
date: value,

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

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
287287
}
288288
resourcesContainer.addListener("updateStudy", e => this._updateStudyData(e.getData()));
289289
resourcesContainer.addListener("updateTemplate", e => this._updateTemplateData(e.getData()));
290+
resourcesContainer.addListener("updateTutorial", e => this._updateTutorialData(e.getData()));
290291
resourcesContainer.addListener("updateService", e => this._updateServiceData(e.getData()));
291292
resourcesContainer.addListener("updateHypertool", e => this._updateHypertoolData(e.getData()));
292293
resourcesContainer.addListener("publishTemplate", e => this.fireDataEvent("publishTemplate", e.getData()));
@@ -579,6 +580,111 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
579580
throw new Error("Abstract method called!");
580581
},
581582

583+
_populateTemplateCardMenu: function(card) {
584+
const menu = card.getMenu();
585+
const templateData = card.getResourceData();
586+
587+
const editButton = this.__getEditTemplateMenuButton(templateData);
588+
if (editButton) {
589+
menu.add(editButton);
590+
menu.addSeparator();
591+
}
592+
593+
const openButton = this._getOpenMenuButton(templateData);
594+
if (openButton) {
595+
menu.add(openButton);
596+
}
597+
598+
const shareButton = this._getShareMenuButton(card);
599+
if (shareButton) {
600+
menu.add(shareButton);
601+
}
602+
603+
const tagsButton = this._getTagsMenuButton(card);
604+
if (tagsButton) {
605+
menu.add(tagsButton);
606+
}
607+
608+
const deleteButton = this.__getDeleteTemplateMenuButton(templateData);
609+
if (deleteButton && editButton) {
610+
menu.addSeparator();
611+
menu.add(deleteButton);
612+
}
613+
},
614+
615+
__getEditTemplateMenuButton: function(templateData) {
616+
const isCurrentUserOwner = osparc.data.model.Study.canIWrite(templateData["accessRights"]);
617+
if (!isCurrentUserOwner) {
618+
return null;
619+
}
620+
621+
const editButton = new qx.ui.menu.Button(this.tr("Open"));
622+
editButton.addListener("execute", () => {
623+
const isStudyCreation = false;
624+
this._startStudyById(templateData["uuid"], null, null, isStudyCreation);
625+
}, this);
626+
return editButton;
627+
},
628+
629+
__getDeleteTemplateMenuButton: function(templateData) {
630+
const isCurrentUserOwner = osparc.data.model.Study.canIDelete(templateData["accessRights"]);
631+
if (!isCurrentUserOwner) {
632+
return null;
633+
}
634+
635+
const deleteButton = new qx.ui.menu.Button(this.tr("Delete"), "@FontAwesome5Solid/trash/12");
636+
deleteButton.set({
637+
appearance: "menu-button"
638+
});
639+
deleteButton.addListener("execute", () => this._deleteTemplateRequested(templateData), this);
640+
return deleteButton;
641+
},
642+
643+
_deleteTemplateRequested: function(templateData) {
644+
const rUSure = this.tr("Are you sure you want to delete ");
645+
const msg = rUSure + "<b>" + templateData.name + "</b>?";
646+
const win = new osparc.ui.window.Confirmation(msg).set({
647+
caption: this.tr("Delete"),
648+
confirmText: this.tr("Delete"),
649+
confirmAction: "delete"
650+
});
651+
win.center();
652+
win.open();
653+
win.addListener("close", () => {
654+
if (win.getConfirmed()) {
655+
this.__doDeleteTemplate(templateData);
656+
}
657+
}, this);
658+
},
659+
660+
__doDeleteTemplate: function(templateData) {
661+
const myGid = osparc.auth.Data.getInstance().getGroupId();
662+
const collabGids = Object.keys(templateData["accessRights"]);
663+
const amICollaborator = collabGids.indexOf(myGid) > -1;
664+
665+
let operationPromise = null;
666+
if (collabGids.length > 1 && amICollaborator) {
667+
const arCopy = osparc.utils.Utils.deepCloneObject(templateData["accessRights"]);
668+
// remove collaborator
669+
delete arCopy[myGid];
670+
operationPromise = osparc.store.Study.patchStudyData(templateData, "accessRights", arCopy);
671+
} else {
672+
// delete study
673+
operationPromise = osparc.store.Store.getInstance().deleteStudy(templateData.uuid);
674+
}
675+
operationPromise
676+
.then(() => this.__removeFromTemplateList(templateData.uuid))
677+
.catch(err => osparc.FlashMessenger.logError(err));
678+
},
679+
680+
__removeFromTemplateList: function(templateId) {
681+
const idx = this._resourcesList.findIndex(study => study["uuid"] === templateId);
682+
if (idx > -1) {
683+
this._resourcesList.splice(idx, 1);
684+
}
685+
this._resourcesContainer.removeCard(templateId);
686+
},
687+
582688
_updateTemplateData: function(templateData) {
583689
const templatesList = this._resourcesList;
584690
const index = templatesList.findIndex(template => template["uuid"] === templateData["uuid"]);
@@ -588,6 +694,10 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
588694
}
589695
},
590696

697+
updateTutorialData: function(tutorialData) {
698+
throw new Error("Abstract method called!");
699+
},
700+
591701
_updateServiceData: function(serviceData) {
592702
throw new Error("Abstract method called!");
593703
},
@@ -811,6 +921,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
811921
break;
812922
}
813923
case "template":
924+
case "tutorial":
814925
case "hypertool":
815926
this._createStudyFromTemplate(resourceData);
816927
break;
@@ -827,6 +938,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
827938
const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails);
828939
resourceDetails.addListener("updateStudy", e => this._updateStudyData(e.getData()));
829940
resourceDetails.addListener("updateTemplate", e => this._updateTemplateData(e.getData()));
941+
resourceDetails.addListener("updateTutorial", e => this._updateTutorialData(e.getData()));
830942
resourceDetails.addListener("updateService", e => this._updateServiceData(e.getData()));
831943
resourceDetails.addListener("updateHypertool", e => this._updateHypertoolData(e.getData()));
832944
resourceDetails.addListener("publishTemplate", e => {
@@ -839,15 +951,16 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
839951
const isStudyCreation = false;
840952
this._startStudyById(studyId, openCB, null, isStudyCreation);
841953
});
842-
resourceDetails.addListener("openTemplate", e => {
843-
win.close();
844-
const templateData = e.getData();
845-
this._createStudyFromTemplate(templateData);
846-
});
847-
resourceDetails.addListener("openHypertool", e => {
848-
win.close();
849-
const templateData = e.getData();
850-
this._createStudyFromTemplate(templateData);
954+
[
955+
"openTemplate",
956+
"openTutorial",
957+
"openHypertool",
958+
].forEach(eventName => {
959+
resourceDetails.addListener(eventName, e => {
960+
win.close();
961+
const templateData = e.getData();
962+
this._createStudyFromTemplate(templateData);
963+
});
851964
});
852965
resourceDetails.addListener("openService", e => {
853966
win.close();

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", {
6767
events: {
6868
"updateStudy": "qx.event.type.Data",
6969
"updateTemplate": "qx.event.type.Data",
70+
"updateTutorial": "qx.event.type.Data",
7071
"updateService": "qx.event.type.Data",
7172
"updateHypertool": "qx.event.type.Data",
7273
"publishTemplate": "qx.event.type.Data",
@@ -240,6 +241,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", {
240241
[
241242
"updateStudy",
242243
"updateTemplate",
244+
"updateTutorial",
243245
"updateService",
244246
"updateHypertool",
245247
"publishTemplate",

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
2727
switch (resourceData["resourceType"]) {
2828
case "study":
2929
case "template":
30+
case "tutorial":
3031
case "hypertool": {
3132
const params = {
3233
url: {
@@ -54,6 +55,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
5455
switch (resourceData["resourceType"]) {
5556
case "study":
5657
case "template":
58+
case "tutorial":
5759
case "hypertool":
5860
osparc.store.Services.getStudyServicesMetadata(latestResourceData)
5961
.finally(() => {
@@ -76,11 +78,14 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
7678

7779
events: {
7880
"pagesAdded": "qx.event.type.Event",
81+
"openStudy": "qx.event.type.Data",
7982
"openTemplate": "qx.event.type.Data",
83+
"openTutorial": "qx.event.type.Data",
8084
"openHypertool": "qx.event.type.Data",
8185
"openService": "qx.event.type.Data",
8286
"updateStudy": "qx.event.type.Data",
8387
"updateTemplate": "qx.event.type.Data",
88+
"updateTutorial": "qx.event.type.Data",
8489
"updateService": "qx.event.type.Data",
8590
"updateHypertool": "qx.event.type.Data",
8691
"publishTemplate": "qx.event.type.Data",
@@ -248,6 +253,9 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
248253
case "template":
249254
this.fireDataEvent("openTemplate", this.__resourceData);
250255
break;
256+
case "tutorial":
257+
this.fireDataEvent("openTutorial", this.__resourceData);
258+
break;
251259
case "hypertool":
252260
this.fireDataEvent("openHypertool", this.__resourceData);
253261
break;
@@ -384,6 +392,9 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
384392
case "template":
385393
this.fireDataEvent("updateTemplate", updatedData);
386394
break;
395+
case "tutorial":
396+
this.fireDataEvent("updateTutorial", updatedData);
397+
break;
387398
case "hypertool":
388399
this.fireDataEvent("updateHypertool", updatedData);
389400
break;
@@ -558,6 +569,8 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
558569
collaboratorsView.getChildControl("study-link").show();
559570
} else if (osparc.utils.Resources.isTemplate(resourceData)) {
560571
collaboratorsView.getChildControl("template-link").show();
572+
} else if (osparc.utils.Resources.isTutorial(resourceData)) {
573+
collaboratorsView.getChildControl("template-link").show();
561574
}
562575
collaboratorsView.addListener("updateAccessRights", e => {
563576
const updatedData = e.getData();
@@ -726,7 +739,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
726739
});
727740
page.addToContent(servicesBootOpts);
728741

729-
if (osparc.utils.Resources.isStudy(resourceData) || osparc.utils.Resources.isTemplate(resourceData)) {
742+
if (
743+
osparc.utils.Resources.isStudy(resourceData) ||
744+
osparc.utils.Resources.isTemplate(resourceData) ||
745+
osparc.utils.Resources.isTutorial(resourceData) ||
746+
osparc.utils.Resources.isHypertool(resourceData)
747+
) {
730748
if (osparc.product.Utils.showDisableServiceAutoStart()) {
731749
const study = new osparc.data.model.Study(resourceData);
732750
const autoStartButton = osparc.info.StudyUtils.createDisableServiceAutoStart(study).set({
@@ -846,18 +864,18 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
846864
__getProjectFilesPopUp: function() {
847865
const resourceData = this.__resourceData;
848866
if (!osparc.utils.Resources.isService(resourceData)) {
849-
const title = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + this.tr(" Files...");
867+
const title = osparc.product.Utils.resourceTypeToAlias(resourceData["resourceType"], {firstUpperCase: true}) + this.tr(" Files");
850868
const iconSrc = "@FontAwesome5Solid/file/22";
851869
const dataAccess = new qx.ui.basic.Atom().set({
852-
label: title,
870+
label: title + "...",
853871
icon: iconSrc,
854872
font: "text-14",
855873
padding: 8,
856874
paddingLeft: 12,
857875
gap: 14,
858876
cursor: "pointer",
859877
});
860-
dataAccess.addListener("tap", () => osparc.widget.StudyDataManager.popUpInWindow(resourceData["uuid"]));
878+
dataAccess.addListener("tap", () => osparc.widget.StudyDataManager.popUpInWindow(resourceData["uuid"], null, title));
861879
this.addWidgetToTabs(dataAccess);
862880

863881
if (resourceData["resourceType"] === "study") {

0 commit comments

Comments
 (0)