Skip to content

Commit ba60b12

Browse files
authored
Toolbar with Breadcrumbs, improved Start/Stop and more (#2098)
- New toolbar: Breadcrumbs - New toolbar: Node Status icon in breadcrumb + tooltip (only guided) - New toolbar: Prev/Next buttons (only guided) - New toolbar: Run/Stop buttons - Run Button with Run", Run Node(s)" and "Run All" - Quality can be viewed/updated by clicking the stars on card - SVG layer initialization improved
1 parent ebae9d0 commit ba60b12

30 files changed

+936
-531
lines changed

services/web/client/source/class/explorer/NavigationBar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
************************************************************************ */
1717

1818
qx.Class.define("explorer.NavigationBar", {
19-
extend: osparc.desktop.NavigationBar,
19+
extend: osparc.navigation.NavigationBar,
2020

2121
members: {
2222
buildLayout: function() {

services/web/client/source/class/osparc/component/metadata/QualityEditor.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,12 @@ qx.Class.define("osparc.component.metadata.QualityEditor", {
594594
__isUserOwner: function() {
595595
const myGid = osparc.auth.Data.getInstance().getGroupId();
596596
if (myGid) {
597-
if (osparc.utils.Resources.isService(this.__resourceData)) {
597+
if ("access_rights" in this.__resourceData) {
598598
return osparc.component.export.ServicePermissions.canGroupWrite(this.__resourceData["access_rights"], myGid);
599599
}
600-
return osparc.component.export.StudyPermissions.canGroupWrite(this.__resourceData["accessRights"], myGid);
600+
if ("accessRights" in this.__resourceData) {
601+
return osparc.component.export.StudyPermissions.canGroupWrite(this.__resourceData["accessRights"], myGid);
602+
}
601603
}
602604
return false;
603605
}

services/web/client/source/class/osparc/component/widget/Thumbnail.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,7 @@ qx.Class.define("osparc.component.widget.Thumbnail", {
5757
});
5858
});
5959

60-
const image = this.getChildControl("image").set({
61-
scale: true,
62-
allowStretchX: true,
63-
allowStretchY: true
64-
});
60+
const image = this.getChildControl("image");
6561

6662
if (source) {
6763
image.setSource(source);
@@ -91,6 +87,9 @@ qx.Class.define("osparc.component.widget.Thumbnail", {
9187
switch (id) {
9288
case "image":
9389
control = new qx.ui.basic.Image().set({
90+
scale: true,
91+
allowStretchX: true,
92+
allowStretchY: true,
9493
alignX: "center",
9594
alignY: "middle"
9695
});

services/web/client/source/class/osparc/component/workbench/SvgWidget.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,12 @@ qx.Class.define("osparc.component.workbench.SvgWidget", {
3838
construct: function() {
3939
this.base();
4040
this.addListenerOnce("appear", () => {
41-
const randomID = Math.random().toString(36).substring(7);
4241
const el = this.getContentElement().getDomElement();
43-
qx.bom.element.Attribute.set(el, "id", randomID);
4442
const svgWrapper = osparc.wrapper.Svg.getInstance();
4543
svgWrapper.init()
4644
.then(() => {
4745
if (this.__canvas === null) {
48-
this.__canvas = svgWrapper.createEmptyCanvas(randomID);
46+
this.__canvas = svgWrapper.createEmptyCanvas(el);
4947
this.setReady(true);
5048
this.fireDataEvent("SvgWidgetReady", true);
5149
}

services/web/client/source/class/osparc/component/workbench/WorkbenchUI.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
137137
return borderStyle;
138138
},
139139

140+
TOP_OFFSET: 50 + 46,
141+
140142
ZoomValues: [0.25, 0.4, 0.5, 0.6, 0.8, 1, 1.25, 1.5, 2, 3]
141143
},
142144

@@ -282,7 +284,7 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
282284
const maxHeight = this.getBounds().height - osparc.component.workbench.ServiceCatalog.Height;
283285
const posX = Math.min(winPos.x, maxLeft);
284286
const posY = Math.min(winPos.y, maxHeight);
285-
srvCat.moveTo(posX + this.__getSidePanelWidth(), posY + 50);
287+
srvCat.moveTo(posX + this.__getSidePanelWidth(), posY + this.self().TOP_OFFSET);
286288
srvCat.addListener("addService", e => {
287289
this.__addServiceFromCatalog(e.getData(), srvPos);
288290
}, this);
@@ -410,6 +412,14 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
410412
return this.__selectedNodes;
411413
},
412414

415+
getSelectedNodeIDs: function() {
416+
const selectedNodeIDs = [];
417+
this.__selectedNodes.forEach(nodeUI => {
418+
selectedNodeIDs.push(nodeUI.getNodeId());
419+
});
420+
return selectedNodeIDs;
421+
},
422+
413423
resetSelectedNodes: function() {
414424
this.__selectedNodes.forEach(node => node.removeState("selected"));
415425
this.__selectedNodes = [];
@@ -725,11 +735,10 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
725735
},
726736

727737
__pointerEventToWorkbenchPos: function(pointerEvent, scale = false) {
728-
const topOffset = 50;
729738
const leftOffset = this.__getSidePanelWidth();
730739
const inputNodesLayoutWidth = this.__inputNodesLayout.isVisible() ? this.__inputNodesLayout.getWidth() : 0;
731740
const x = pointerEvent.getDocumentLeft() - leftOffset - inputNodesLayoutWidth;
732-
const y = pointerEvent.getDocumentTop() - topOffset;
741+
const y = pointerEvent.getDocumentTop() - this.self().TOP_OFFSET;
733742
if (scale) {
734743
return this.__scaleCoordinates(x, y);
735744
}
@@ -1105,9 +1114,9 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
11051114

11061115
const commandDel = new qx.ui.command.Command("Delete");
11071116
commandDel.addListener("execute", () => {
1108-
const selectedNodes = this.getSelectedNodes();
1109-
if (selectedNodes.length === 1) {
1110-
this.fireDataEvent("removeNode", selectedNodes[0].getNodeId());
1117+
const selectedNodeIDs = this.getSelectedNodeIDs();
1118+
if (selectedNodeIDs.length === 1) {
1119+
this.fireDataEvent("removeNode", selectedNodeIDs[0]);
11111120
}
11121121
});
11131122

services/web/client/source/class/osparc/dashboard/ExploreBrowser.js

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,13 @@ qx.Class.define("osparc.dashboard.ExploreBrowser", {
349349
this.self().sortTemplateList(tempStudyList);
350350
tempStudyList.forEach(tempStudy => {
351351
tempStudy["resourceType"] = "template";
352-
this.__templatesContainer.add(this.__createStudyItem(tempStudy));
352+
const templateItem = this.__createStudyItem(tempStudy);
353+
templateItem.addListener("updateQualityTemplate", e => {
354+
const updatedTemplateData = e.getData();
355+
updatedTemplateData["resourceType"] = "template";
356+
this._resetTemplateItem(updatedTemplateData);
357+
}, this);
358+
this.__templatesContainer.add(templateItem);
353359
});
354360
osparc.component.filter.UIFilterController.dispatch("sideSearchFilter");
355361
},
@@ -370,7 +376,13 @@ qx.Class.define("osparc.dashboard.ExploreBrowser", {
370376
this.__servicesContainer.removeAll();
371377
servicesList.forEach(service => {
372378
service["resourceType"] = "service";
373-
this.__servicesContainer.add(this.__createStudyItem(service));
379+
const serviceItem = this.__createStudyItem(service);
380+
serviceItem.addListener("updateQualityService", e => {
381+
const updatedServiceData = e.getData();
382+
updatedServiceData["resourceType"] = "service";
383+
this._resetServiceItem(updatedServiceData);
384+
}, this);
385+
this.__servicesContainer.add(serviceItem);
374386
});
375387
osparc.component.filter.UIFilterController.dispatch("sideSearchFilter");
376388
},
@@ -462,11 +474,7 @@ qx.Class.define("osparc.dashboard.ExploreBrowser", {
462474

463475
const permissionsButton = new qx.ui.menu.Button(this.tr("Permissions"));
464476
permissionsButton.addListener("execute", () => {
465-
if (osparc.utils.Resources.isTemplate(studyData)) {
466-
this.__openTemplatePermissions(studyData);
467-
} else if (osparc.utils.Resources.isService(studyData)) {
468-
this.__openServicePermissions(studyData);
469-
}
477+
this.__openPermissions(studyData);
470478
}, this);
471479
return permissionsButton;
472480
},
@@ -483,27 +491,6 @@ qx.Class.define("osparc.dashboard.ExploreBrowser", {
483491
return classifiersButton;
484492
},
485493

486-
__openClassifiers: function(studyData) {
487-
const title = this.tr("Classifiers");
488-
let classifiers = null;
489-
if (osparc.data.model.Study.isOwner(studyData)) {
490-
classifiers = new osparc.component.metadata.ClassifiersEditor(studyData);
491-
osparc.ui.window.Window.popUpInWindow(classifiers, title, 400, 400);
492-
classifiers.addListener("updateResourceClassifiers", e => {
493-
if (osparc.utils.Resources.isTemplate(studyData)) {
494-
const studyId = e.getData();
495-
this._reloadTemplate(studyId);
496-
} else if (osparc.utils.Resources.isService(studyData)) {
497-
const serviceKey = e.getData();
498-
this.__reloadService(serviceKey, studyData.version);
499-
}
500-
}, this);
501-
} else {
502-
classifiers = new osparc.component.metadata.ClassifiersViewer(studyData);
503-
}
504-
osparc.ui.window.Window.popUpInWindow(classifiers, title, 400, 400);
505-
},
506-
507494
__getStudyServicesMenuButton: function(studyData) {
508495
if (osparc.utils.Resources.isService(studyData)) {
509496
return null;
@@ -579,6 +566,14 @@ qx.Class.define("osparc.dashboard.ExploreBrowser", {
579566
});
580567
},
581568

569+
__openPermissions: function(studyData) {
570+
if (osparc.utils.Resources.isTemplate(studyData)) {
571+
this.__openTemplatePermissions(studyData);
572+
} else if (osparc.utils.Resources.isService(studyData)) {
573+
this.__openServicePermissions(studyData);
574+
}
575+
},
576+
582577
__openServicePermissions: function(serviceData) {
583578
const permissionsView = new osparc.component.export.ServicePermissions(serviceData);
584579
const title = this.tr("Available to");
@@ -600,6 +595,27 @@ qx.Class.define("osparc.dashboard.ExploreBrowser", {
600595
});
601596
},
602597

598+
__openClassifiers: function(studyData) {
599+
const title = this.tr("Classifiers");
600+
let classifiers = null;
601+
if (osparc.data.model.Study.isOwner(studyData)) {
602+
classifiers = new osparc.component.metadata.ClassifiersEditor(studyData);
603+
osparc.ui.window.Window.popUpInWindow(classifiers, title, 400, 400);
604+
classifiers.addListener("updateResourceClassifiers", e => {
605+
if (osparc.utils.Resources.isTemplate(studyData)) {
606+
const studyId = e.getData();
607+
this._reloadTemplate(studyId);
608+
} else if (osparc.utils.Resources.isService(studyData)) {
609+
const serviceKey = e.getData();
610+
this.__reloadService(serviceKey, studyData.version);
611+
}
612+
}, this);
613+
} else {
614+
classifiers = new osparc.component.metadata.ClassifiersViewer(studyData);
615+
}
616+
osparc.ui.window.Window.popUpInWindow(classifiers, title, 400, 400);
617+
},
618+
603619
__deleteTemplate: function(studyData) {
604620
const myGid = osparc.auth.Data.getInstance().getGroupId();
605621
const collabGids = Object.keys(studyData["accessRights"]);

services/web/client/source/class/osparc/dashboard/StudyBrowser.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,13 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
350350
if (osparc.data.model.Study.isStudySecondary(userStudy)) {
351351
return;
352352
}
353-
this.__userStudyContainer.add(this.__createStudyItem(userStudy));
353+
const studyItem = this.__createStudyItem(userStudy);
354+
studyItem.addListener("updateQualityStudy", e => {
355+
const updatedStudyData = e.getData();
356+
updatedStudyData["resourceType"] = "study";
357+
this._resetStudyItem(updatedStudyData);
358+
}, this);
359+
this.__userStudyContainer.add(studyItem);
354360
});
355361
osparc.component.filter.UIFilterController.dispatch("sideSearchFilter");
356362
},
@@ -455,13 +461,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
455461
__getPermissionsMenuButton: function(studyData) {
456462
const permissionsButton = new qx.ui.menu.Button(this.tr("Permissions"));
457463
permissionsButton.addListener("execute", () => {
458-
const permissionsView = new osparc.component.export.StudyPermissions(studyData);
459-
const title = this.tr("Share with Collaborators and Organizations");
460-
osparc.ui.window.Window.popUpInWindow(permissionsView, title, 400, 300);
461-
permissionsView.addListener("updateStudy", e => {
462-
const studyId = e.getData();
463-
this._reloadStudy(studyId);
464-
}, this);
464+
this.__openPermissions(studyData);
465465
}, this);
466466
return permissionsButton;
467467
},
@@ -478,6 +478,16 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
478478
return classifiersButton;
479479
},
480480

481+
__openPermissions: function(studyData) {
482+
const permissionsView = new osparc.component.export.StudyPermissions(studyData);
483+
const title = this.tr("Share with Collaborators and Organizations");
484+
osparc.ui.window.Window.popUpInWindow(permissionsView, title, 400, 300);
485+
permissionsView.addListener("updateStudy", e => {
486+
const studyId = e.getData();
487+
this._reloadStudy(studyId);
488+
}, this);
489+
},
490+
481491
__openClassifiers: function(studyData) {
482492
const title = this.tr("Classifiers");
483493
let classifiers = null;

services/web/client/source/class/osparc/dashboard/StudyBrowserButtonBase.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ qx.Class.define("osparc.dashboard.StudyBrowserButtonBase", {
3939

4040
this._setLayout(new qx.ui.layout.Canvas());
4141

42-
const mainLayout = this._mainLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(6));
42+
const mainLayout = this._mainLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(6)).set({
43+
maxWidth: this.self().ITEM_WIDTH - 2*this.self().PADDING,
44+
maxHeight: this.self().ITEM_HEIGHT - 2*this.self().PADDING
45+
});
4346
this._add(mainLayout, {
4447
top: 0,
4548
right: 0,
@@ -125,7 +128,7 @@ qx.Class.define("osparc.dashboard.StudyBrowserButtonBase", {
125128
}
126129
case "icon": {
127130
const maxWidth = this.self().ITEM_WIDTH - 2*this.self().PADDING;
128-
const image = new osparc.component.widget.Thumbnail(null, maxWidth, 130);
131+
const image = new osparc.component.widget.Thumbnail(null, maxWidth, 124);
129132
control = image.getChildControl("image").set({
130133
anonymous: true
131134
});

services/web/client/source/class/osparc/dashboard/StudyBrowserButtonItem.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ qx.Class.define("osparc.dashboard.StudyBrowserButtonItem", {
129129
}
130130
},
131131

132+
events: {
133+
"updateQualityStudy": "qx.event.type.Data",
134+
"updateQualityTemplate": "qx.event.type.Data",
135+
"updateQualityService": "qx.event.type.Data"
136+
},
137+
132138
statics: {
133139
MENU_BTN_WIDTH: 25,
134140
SHARED_USER: "@FontAwesome5Solid/user/14",
@@ -428,6 +434,12 @@ qx.Class.define("osparc.dashboard.StudyBrowserButtonItem", {
428434
nStars: 4,
429435
showScore: true
430436
});
437+
// Stop propagation of the pointer event in case the tag is inside a button that we don't want to trigger
438+
tsrRating.addListener("tap", e => {
439+
e.stopPropagation();
440+
this.__openQualityEditor();
441+
}, this);
442+
tsrRating.addListener("pointerdown", e => e.stopPropagation());
431443
}
432444
},
433445

@@ -488,6 +500,25 @@ qx.Class.define("osparc.dashboard.StudyBrowserButtonItem", {
488500
});
489501
},
490502

503+
__openQualityEditor: function() {
504+
const resourceData = this.getResourceData();
505+
const qualityEditor = new osparc.component.metadata.QualityEditor(resourceData);
506+
const title = resourceData.name + " - " + this.tr("Quality Assessment");
507+
osparc.ui.window.Window.popUpInWindow(qualityEditor, title, 650, 760);
508+
qualityEditor.addListener("updateStudy", e => {
509+
const updatedStudyData = e.getData();
510+
this.fireDataEvent("updateQualityStudy", updatedStudyData);
511+
});
512+
qualityEditor.addListener("updateTemplate", e => {
513+
const updatedTemplateData = e.getData();
514+
this.fireDataEvent("updateQualityTemplate", updatedTemplateData);
515+
});
516+
qualityEditor.addListener("updateService", e => {
517+
const updatedServiceData = e.getData();
518+
this.fireDataEvent("updateQualityService", updatedServiceData);
519+
});
520+
},
521+
491522
__filterText: function(text) {
492523
if (text) {
493524
const checks = [

services/web/client/source/class/osparc/data/model/StudyUI.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ qx.Class.define("osparc.data.model.StudyUI", {
5757
}
5858
},
5959

60+
statics: {
61+
getSortedNodes: function(study) {
62+
const slideShow = study.getUi().getSlideshow();
63+
const nodes = [];
64+
for (let nodeId in slideShow) {
65+
const node = slideShow[nodeId];
66+
nodes.push({
67+
...node,
68+
nodeId
69+
});
70+
}
71+
nodes.sort((a, b) => (a.position > b.position) ? 1 : -1);
72+
return nodes;
73+
}
74+
},
75+
6076
members: {
6177
serialize: function() {
6278
const currentStudy = osparc.store.Store.getInstance().getCurrentStudy();

0 commit comments

Comments
 (0)