Skip to content

Commit 71579eb

Browse files
authored
Study Editor redesign (ITISFoundation#2571)
1 parent ee99322 commit 71579eb

39 files changed

+1435
-1185
lines changed

services/web/client/source/class/osparc/component/form/ToggleButtonContainer.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,8 @@ qx.Class.define("osparc.component.form.ToggleButtonContainer", {
3636
add: function(child, options) {
3737
if (child instanceof qx.ui.form.ToggleButton) {
3838
this.base(arguments, child, options);
39-
child.addListener("changeValue", e => {
40-
this.fireDataEvent("changeSelection", this.getSelection());
41-
}, this);
42-
child.addListener("changeVisibility", e => {
43-
this.fireDataEvent("changeVisibility", this.getVisibles());
44-
}, this);
39+
child.addListener("changeValue", () => this.fireDataEvent("changeSelection", this.getSelection()), this);
40+
child.addListener("changeVisibility", () => this.fireDataEvent("changeVisibility", this.getVisibles()), this);
4541
if (this.getMode() === "list") {
4642
const width = this.getBounds().width - 15;
4743
child.setWidth(width);
@@ -57,6 +53,7 @@ qx.Class.define("osparc.component.form.ToggleButtonContainer", {
5753
resetSelection: function() {
5854
this.getChildren().map(button => button.setValue(false));
5955
this.__lastSelectedIdx = null;
56+
this.fireDataEvent("changeSelection", this.getSelection());
6057
},
6158

6259
/**

services/web/client/source/class/osparc/component/form/renderer/PropForm.js

Lines changed: 67 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
2424
this.setStudy(study);
2525
}
2626
this.__ctrlLinkMap = {};
27-
this.__ctrlParamMap = {};
27+
this.__linkUnlinkStackMap = {};
2828
this.__fieldOptsBtnMap = {};
2929

3030
this.base(arguments, form, node);
3131

3232
this.__addLinkCtrls();
33-
this.__addParamCtrls();
3433

3534
this.setDroppable(true);
3635
this.__attachDragoverHighlighter();
3736
},
3837

3938
events: {
4039
"linkFieldModified": "qx.event.type.Data",
40+
"fileRequested": "qx.event.type.Data",
4141
"filePickerRequested": "qx.event.type.Data",
4242
"parameterNodeRequested": "qx.event.type.Data",
4343
"changeChildVisibility": "qx.event.type.Event"
@@ -91,16 +91,33 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
9191
},
9292

9393
__ctrlLinkMap: null,
94-
__ctrlParamMap: null,
94+
__linkUnlinkStackMap: null,
9595
__fieldOptsBtnMap: null,
9696

97-
__createFieldOpts: function(field) {
97+
__createLinkUnlinkStack: function(field) {
98+
const linkUnlinkStack = new qx.ui.container.Stack();
99+
100+
const linkOptions = this.__createLinkOpts(field);
101+
linkUnlinkStack.add(linkOptions);
102+
103+
const unlinkBtn = new qx.ui.form.Button(null, "@FontAwesome5Solid/unlink/12").set({
104+
toolTipText: this.tr("Unlink")
105+
});
106+
unlinkBtn.addListener("execute", () => this.removePortLink(field.key), this);
107+
linkUnlinkStack.add(unlinkBtn);
108+
109+
this.__linkUnlinkStackMap[field.key] = linkUnlinkStack;
110+
111+
return linkUnlinkStack;
112+
},
113+
114+
__createLinkOpts: function(field) {
98115
const optionsMenu = new qx.ui.menu.Menu().set({
99-
position: "bottom-right"
116+
position: "bottom-left"
100117
});
101118
const fieldOptsBtn = new qx.ui.form.MenuButton().set({
102119
menu: optionsMenu,
103-
icon: "@FontAwesome5Solid/ellipsis-v/14",
120+
icon: "@FontAwesome5Solid/link/12",
104121
focusable: false,
105122
allowGrowX: false,
106123
alignX: "center"
@@ -125,8 +142,12 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
125142
optionsMenu.addSeparator();
126143
}
127144

145+
const studyUI = this.getStudy().getUi();
128146
if (["FileButton"].includes(field.widgetType)) {
129147
const menuButton = this.__getSelectFileButton(field.key);
148+
studyUI.bind("mode", menuButton, "visibility", {
149+
converter: mode => mode === "workbench" ? "visible" : "excluded"
150+
});
130151
optionsMenu.add(menuButton);
131152
}
132153
if (this.self().isFieldParametrizable(field)) {
@@ -142,8 +163,8 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
142163
newParamBtn,
143164
paramsMenuBtn
144165
].forEach(btn => {
145-
field.bind("visibility", btn, "visibility", {
146-
converter: visibility => (visibility === "visible" && areParamsEnabled) ? "visible" : "excluded"
166+
studyUI.bind("mode", btn, "visibility", {
167+
converter: mode => mode === "workbench" && areParamsEnabled ? "visible" : "excluded"
147168
});
148169
});
149170
});
@@ -199,7 +220,7 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
199220

200221
__getSelectFileButton: function(portId) {
201222
const selectFileButton = new qx.ui.menu.Button(this.tr("Select File"));
202-
selectFileButton.addListener("execute", () => this.fireDataEvent("filePickerRequested", portId), this);
223+
selectFileButton.addListener("execute", () => this.fireDataEvent("fileRequested", portId), this);
203224
return selectFileButton;
204225
},
205226

@@ -278,11 +299,11 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
278299
for (let i = 0; i < items.length; i++) {
279300
const item = items[i];
280301

281-
const fieldOpts = this.__createFieldOpts(item);
302+
const fieldOpts = this.__createLinkUnlinkStack(item);
282303
if (fieldOpts) {
283304
this._add(fieldOpts, {
284305
row,
285-
column: this.self().gridPos.fieldOptions
306+
column: this.self().gridPos.fieldLinkUnlink
286307
});
287308
}
288309

@@ -464,12 +485,24 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
464485
}
465486

466487
const compatible = destinations[node2Id][portId];
467-
if (compatible === true) {
488+
if (compatible) {
468489
// stop propagation, so that the form doesn't attend it (and preventDefault it)
469490
e.stopPropagation();
470491
this.__highlightCompatibles(portId);
471492
}
472493
}
494+
495+
if (e.supportsType("osparc-file-link")) {
496+
const data = e.getData("osparc-file-link");
497+
if ("dragData" in data && "type" in uiElement) {
498+
const compatible = uiElement.type.includes("data:");
499+
if (compatible) {
500+
// stop propagation, so that the form doesn't attend it (and preventDefault it)
501+
e.stopPropagation();
502+
this.__highlightCompatibles(portId);
503+
}
504+
}
505+
}
473506
}, this);
474507

475508
uiElement.addListener("drop", e => {
@@ -480,6 +513,15 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
480513
const port1Key = data["port1Key"];
481514
this.getNode().addPortLink(port2Key, node1Id, port1Key);
482515
}
516+
if (e.supportsType("osparc-file-link")) {
517+
const data = e.getData("osparc-file-link");
518+
this.fireDataEvent("filePickerRequested", {
519+
portId,
520+
file: {
521+
data: data["dragData"]
522+
}
523+
});
524+
}
483525
}, this);
484526
}
485527
},
@@ -600,37 +642,25 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
600642
});
601643
},
602644

603-
__linkAdded: function(portId, fromNodeId, fromPortId) {
645+
__portLinkAdded: function(portId, fromNodeId, fromPortId) {
604646
let data = this._getCtrlFieldChild(portId);
605647
if (data) {
606648
let child = data.child;
607649
const idx = data.idx;
608650
const layoutProps = child.getLayoutProperties();
609651
this._remove(child);
610652

611-
const hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));
612-
613-
hBox.add(this.getControlLink(portId), {
614-
flex: 1
615-
});
616-
617-
const unlinkBtn = new qx.ui.form.Button(null, "@FontAwesome5Solid/unlink/14").set({
618-
toolTipText: this.tr("Unlink")
619-
});
620-
unlinkBtn.addListener("execute", function() {
621-
this.removePortLink(portId);
622-
}, this);
623-
hBox.add(unlinkBtn);
624-
625-
hBox.key = portId;
626-
627-
this._addAt(hBox, idx, {
653+
const ctrlLink = this.getControlLink(portId);
654+
ctrlLink.setEnabled(false);
655+
ctrlLink.key = portId;
656+
this._addAt(ctrlLink, idx, {
628657
row: layoutProps.row,
629658
column: this.self().gridPos.ctrlField
630659
});
631660

632-
if (portId in this.__fieldOptsBtnMap) {
633-
this.__fieldOptsBtnMap[portId].setEnabled(false);
661+
if (portId in this.__linkUnlinkStackMap) {
662+
const stack = this.__linkUnlinkStackMap[portId];
663+
stack.setSelection([stack.getSelectables()[1]]);
634664
}
635665

636666
const linkFieldModified = {
@@ -645,14 +675,9 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
645675

646676
__portLinkRemoved: function(portId) {
647677
if (this.__resetCtrlField(portId)) {
648-
// enable fieldOpts button
649-
const fieldOpts = this._getFieldOptsChild(portId);
650-
if (fieldOpts) {
651-
fieldOpts.child.setEnabled(true);
652-
}
653-
654-
if (portId in this.__fieldOptsBtnMap) {
655-
this.__fieldOptsBtnMap[portId].setEnabled(true);
678+
if (portId in this.__linkUnlinkStackMap) {
679+
const stack = this.__linkUnlinkStackMap[portId];
680+
stack.setSelection([stack.getSelectables()[0]]);
656681
}
657682

658683
const linkFieldModified = {
@@ -703,7 +728,7 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
703728
converter: label => label + ": " + fromPortLabel
704729
});
705730

706-
this.__linkAdded(toPortId, fromNodeId, fromPortId);
731+
this.__portLinkAdded(toPortId, fromNodeId, fromPortId);
707732

708733
return true;
709734
},
@@ -723,42 +748,7 @@ qx.Class.define("osparc.component.form.renderer.PropForm", {
723748
}
724749

725750
this.__portLinkRemoved(toPortId);
726-
},
727-
/* /LINKS */
728-
729-
/* PARAMETERS */
730-
getControlParam: function(key) {
731-
return this.__ctrlParamMap[key];
732-
},
733-
734-
__addParamCtrl: function(portId) {
735-
const controlParam = this.__createFieldCtrl(portId);
736-
this.__ctrlParamMap[portId] = controlParam;
737-
},
738-
739-
__addParamCtrls: function() {
740-
this.__getPortKeys().forEach(portId => {
741-
this.__addParamCtrl(portId);
742-
});
743-
},
744-
745-
__parameterRemoved: function(portId) {
746-
this.__resetCtrlField(portId);
747-
},
748-
749-
removeParameter: function(portId) {
750-
this.getControlParam(portId).setEnabled(false);
751-
let ctrlField = this._form.getControl(portId);
752-
if (ctrlField && "parameter" in ctrlField) {
753-
delete ctrlField.parameter;
754-
}
755-
756-
this.__parameterRemoved(portId);
757-
},
758-
/* /PARAMETERS */
759-
760-
__getRetrieveFieldChild: function(portId) {
761-
return this._getLayoutChild(portId, this.self().gridPos.retrieveStatus);
762751
}
752+
/* /LINKS */
763753
}
764754
});

services/web/client/source/class/osparc/component/form/renderer/PropFormBase.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,13 @@ qx.Class.define("osparc.component.form.renderer.PropFormBase", {
6060
info: 1,
6161
ctrlField: 2,
6262
unit: 3,
63-
fieldOptions: 4
63+
fieldLinkUnlink: 4
6464
},
6565

6666
getDisableables: function() {
6767
return [
6868
this.gridPos.label,
69-
this.gridPos.ctrlField,
70-
this.gridPos.fieldOptions
69+
this.gridPos.ctrlField
7170
];
7271
}
7372
},
@@ -243,10 +242,6 @@ qx.Class.define("osparc.component.form.renderer.PropFormBase", {
243242

244243
_getCtrlFieldChild: function(portId) {
245244
return this._getLayoutChild(portId, this.self().gridPos.ctrlField);
246-
},
247-
248-
_getFieldOptsChild: function(portId) {
249-
return this._getLayoutChild(portId, this.self().gridPos.fieldOptions);
250245
}
251246
}
252247
});

services/web/client/source/class/osparc/component/node/BaseNodeView.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
4242
layout: new qx.ui.layout.VBox()
4343
});
4444
return settingsGroupBox;
45+
},
46+
47+
openNodeDataManager: function(node) {
48+
const nodeDataManager = new osparc.component.widget.NodeDataManager(node);
49+
const win = osparc.ui.window.Window.popUpInWindow(nodeDataManager, node.getLabel(), 900, 600).set({
50+
appearance: "service-window"
51+
});
52+
const closeBtn = win.getChildControl("close-button");
53+
osparc.utils.Utils.setIdToWidget(closeBtn, "nodeDataManagerCloseBtn");
4554
}
4655
},
4756

@@ -249,7 +258,7 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
249258

250259
const buttonsLayout = this.__buttonContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));
251260
const filesBtn = this.__outFilesButton = new qx.ui.form.Button(this.tr("Output Files"), "@FontAwesome5Solid/folder-open/14");
252-
osparc.utils.Utils.setIdToWidget(filesBtn, "nodeViewFilesBtn");
261+
osparc.utils.Utils.setIdToWidget(filesBtn, "nodeOutputFilesBtn");
253262
filesBtn.addListener("execute", () => this.__openNodeDataManager(), this);
254263
buttonsLayout.add(filesBtn);
255264

@@ -375,12 +384,7 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
375384
},
376385

377386
__openNodeDataManager: function() {
378-
const nodeDataManager = new osparc.component.widget.NodeDataManager(this.getNode());
379-
const win = osparc.ui.window.Window.popUpInWindow(nodeDataManager, this.getNode().getLabel(), 900, 600).set({
380-
appearance: "service-window"
381-
});
382-
const closeBtn = win.getChildControl("close-button");
383-
osparc.utils.Utils.setIdToWidget(closeBtn, "nodeDataManagerCloseBtn");
387+
this.self().openNodeDataManager(this.getNode());
384388
},
385389

386390
__openServiceDetails: function() {

0 commit comments

Comments
 (0)