Skip to content

Commit 2c424ad

Browse files
authored
✨ [Frontend] Feature: sync with projectDocument:updated WS (#8165)
1 parent d1f879d commit 2c424ad

File tree

15 files changed

+825
-173
lines changed

15 files changed

+825
-173
lines changed

services/static-webserver/client/source/class/osparc/data/model/Node.js

Lines changed: 103 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ qx.Class.define("osparc.data.model.Node", {
198198
"reloadModel": "qx.event.type.Event",
199199
"retrieveInputs": "qx.event.type.Data",
200200
"keyChanged": "qx.event.type.Event",
201+
"changePosition": "qx.event.type.Data",
202+
"createEdge": "qx.event.type.Data",
203+
"removeEdge": "qx.event.type.Data",
201204
"fileRequested": "qx.event.type.Data",
202205
"parameterRequested": "qx.event.type.Data",
203206
"filePickerRequested": "qx.event.type.Data",
@@ -237,6 +240,10 @@ qx.Class.define("osparc.data.model.Node", {
237240
"progress", // !! not a property but goes into the model
238241
],
239242

243+
getProperties: function() {
244+
return Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Node));
245+
},
246+
240247
isFrontend: function(metadata) {
241248
return (metadata && metadata.key && metadata.key.includes("/frontend/"));
242249
},
@@ -524,7 +531,7 @@ qx.Class.define("osparc.data.model.Node", {
524531
this.setPosition(nodeUIData.position);
525532
}
526533
if ("marker" in nodeUIData) {
527-
this.__addMarker(nodeUIData.marker);
534+
this.addMarker(nodeUIData.marker);
528535
}
529536
},
530537

@@ -682,11 +689,11 @@ qx.Class.define("osparc.data.model.Node", {
682689
if (this.getMarker()) {
683690
this.__removeMarker();
684691
} else {
685-
this.__addMarker();
692+
this.addMarker();
686693
}
687694
},
688695

689-
__addMarker: function(marker) {
696+
addMarker: function(marker) {
690697
if (marker === undefined) {
691698
marker = {
692699
color: osparc.utils.Utils.getRandomColor()
@@ -922,13 +929,14 @@ qx.Class.define("osparc.data.model.Node", {
922929

923930
removeInputNode: function(inputNodeId) {
924931
const index = this.__inputNodes.indexOf(inputNodeId);
925-
if (index > -1) {
926-
// remove node connection
927-
this.__inputNodes.splice(index, 1);
928-
this.fireEvent("changeInputNodes");
929-
return true;
932+
// make sure index is valid
933+
if (index < 0 || index >= this.__inputNodes.length) {
934+
return false;
930935
}
931-
return false;
936+
// remove node connection
937+
this.__inputNodes.splice(index, 1);
938+
this.fireEvent("changeInputNodes");
939+
return true;
932940
},
933941

934942
isInputNode: function(inputNodeId) {
@@ -1198,7 +1206,7 @@ qx.Class.define("osparc.data.model.Node", {
11981206
this.__deleteInBackend()
11991207
.then(() => {
12001208
resolve(true);
1201-
this.removeIFrame();
1209+
this.nodeRemoved();
12021210
})
12031211
.catch(err => {
12041212
console.error(err);
@@ -1207,6 +1215,10 @@ qx.Class.define("osparc.data.model.Node", {
12071215
});
12081216
},
12091217

1218+
nodeRemoved: function() {
1219+
this.removeIFrame();
1220+
},
1221+
12101222
__deleteInBackend: function() {
12111223
// remove node in the backend
12121224
const params = {
@@ -1250,6 +1262,11 @@ qx.Class.define("osparc.data.model.Node", {
12501262
},
12511263
"osparc-resource": "ui",
12521264
});
1265+
1266+
this.fireDataEvent("changePosition", {
1267+
x: this.__posX,
1268+
y: this.__posY
1269+
});
12531270
},
12541271

12551272
getPosition: function() {
@@ -1300,7 +1317,7 @@ qx.Class.define("osparc.data.model.Node", {
13001317

13011318
listenToChanges: function() {
13021319
const nodeId = this.getNodeId();
1303-
const propertyKeys = Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Node));
1320+
const nodePropertyKeys = this.self().getProperties();
13041321
this.self().ListenChangesProps.forEach(key => {
13051322
switch (key) {
13061323
case "inputs":
@@ -1394,7 +1411,7 @@ qx.Class.define("osparc.data.model.Node", {
13941411
}
13951412
break;
13961413
default:
1397-
if (propertyKeys.includes(key)) {
1414+
if (nodePropertyKeys.includes(key)) {
13981415
this.addListener("change" + qx.lang.String.firstUp(key), e => {
13991416
const data = e.getData();
14001417
this.fireDataEvent("projectDocumentChanged", {
@@ -1412,14 +1429,87 @@ qx.Class.define("osparc.data.model.Node", {
14121429
});
14131430
},
14141431

1432+
updateNodeFromPatch: function(nodePatches) {
1433+
const nodePropertyKeys = this.self().getProperties();
1434+
nodePatches.forEach(patch => {
1435+
const op = patch.op;
1436+
const path = patch.path;
1437+
const value = patch.value;
1438+
const nodeProperty = path.split("/")[3];
1439+
switch (nodeProperty) {
1440+
case "inputs": {
1441+
const updatedPortKey = path.split("/")[4];
1442+
const currentInputs = this.__getInputData();
1443+
currentInputs[updatedPortKey] = value;
1444+
this.__setInputData(currentInputs);
1445+
break;
1446+
}
1447+
case "inputsUnits": {
1448+
// this is never transmitted by the frontend
1449+
const updatedPortKey = path.split("/")[4];
1450+
const currentInputUnits = this.__getInputUnits();
1451+
currentInputUnits[updatedPortKey] = value;
1452+
this.__setInputUnits(currentInputUnits);
1453+
break;
1454+
}
1455+
case "inputNodes":
1456+
if (op === "add") {
1457+
const inputNodeId = value;
1458+
this.fireDataEvent("createEdge", {
1459+
nodeId1: inputNodeId,
1460+
nodeId2: this.getNodeId(),
1461+
});
1462+
} else if (op === "remove") {
1463+
// we don't have more information about the input node, so we just remove it by index
1464+
const index = path.split("/")[4];
1465+
// make sure index is valid
1466+
if (index >= 0 && index < this.__inputNodes.length) {
1467+
this.fireDataEvent("removeEdge", {
1468+
nodeId1: this.__inputNodes[index],
1469+
nodeId2: this.getNodeId(),
1470+
});
1471+
}
1472+
}
1473+
break;
1474+
case "inputsRequired":
1475+
console.warn(`To be implemented: patching ${nodeProperty} is not supported yet`);
1476+
break;
1477+
case "outputs": {
1478+
const updatedPortKey = path.split("/")[4];
1479+
const currentOutputs = this.isFilePicker() ? osparc.file.FilePicker.serializeOutput(this.getOutputs()) : this.__getOutputsData();
1480+
currentOutputs[updatedPortKey] = value;
1481+
this.setOutputData(currentOutputs);
1482+
break;
1483+
}
1484+
case "progress":
1485+
if (this.isFilePicker()) {
1486+
this.getStatus().setProgress(value);
1487+
} else {
1488+
console.warn(`To be implemented: patching ${nodeProperty} is not supported yet`);
1489+
}
1490+
break;
1491+
default:
1492+
if (nodePropertyKeys.includes(nodeProperty)) {
1493+
const setter = "set" + qx.lang.String.firstUp(nodeProperty);
1494+
if (this[setter]) {
1495+
this[setter](value);
1496+
} else {
1497+
console.warn(`Property "${nodeProperty}" does not have a setter in osparc.data.model.Node`);
1498+
}
1499+
}
1500+
break;
1501+
}
1502+
});
1503+
},
1504+
14151505
serialize: function() {
14161506
// node generic
14171507
let nodeEntry = {
14181508
key: this.getKey(),
14191509
version: this.getVersion(),
14201510
label: this.getLabel(),
14211511
inputs: this.__getInputData(),
1422-
inputsUnits: this.__getInputUnits(),
1512+
inputsUnits: this.__getInputUnits(), // this is not working
14231513
inputNodes: this.getInputNodes(),
14241514
inputsRequired: this.getInputsRequired(),
14251515
bootOptions: this.getBootOptions()

services/static-webserver/client/source/class/osparc/data/model/Study.js

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ qx.Class.define("osparc.data.model.Study", {
4444

4545
this.set({
4646
uuid: studyData.uuid || this.getUuid(),
47-
workspaceId: studyData.workspaceId || null,
48-
folderId: studyData.folderId || null,
47+
workspaceId: studyData.workspaceId || this.getWorkspaceId(),
48+
folderId: studyData.folderId || this.getFolderId(),
4949
name: studyData.name || this.getName(),
5050
description: studyData.description || this.getDescription(),
5151
thumbnail: studyData.thumbnail || this.getThumbnail(),
@@ -60,9 +60,9 @@ qx.Class.define("osparc.data.model.Study", {
6060
permalink: studyData.permalink || this.getPermalink(),
6161
dev: studyData.dev || this.getDev(),
6262
trashedAt: studyData.trashedAt ? new Date(studyData.trashedAt) : this.getTrashedAt(),
63-
trashedBy: studyData.trashedBy || null,
64-
type: studyData.type,
65-
templateType: studyData.templateType,
63+
trashedBy: studyData.trashedBy || this.getTrashedBy(),
64+
type: studyData.type || this.getType(),
65+
templateType: studyData.templateType || this.getTemplateType(),
6666
});
6767

6868
const wbData = studyData.workbench || this.getWorkbench();
@@ -143,7 +143,7 @@ qx.Class.define("osparc.data.model.Study", {
143143

144144
thumbnail: {
145145
check: "String",
146-
nullable: false,
146+
nullable: true,
147147
event: "changeThumbnail",
148148
init: ""
149149
},
@@ -747,23 +747,23 @@ qx.Class.define("osparc.data.model.Study", {
747747
* @param studyDiffs {Object} Diff Object coming from the JsonDiffPatch lib. Use only the keys, not the changes.
748748
* @param studySource {Object} Study object that was used to check the diffs on the frontend.
749749
*/
750-
patchStudyDelayed: function(studyDiffs, studySource) {
750+
patchStudyDiffs: function(studyDiffs, studySource) {
751751
const promises = [];
752752
if ("workbench" in studyDiffs) {
753-
promises.push(this.getWorkbench().patchWorkbenchDelayed(studyDiffs["workbench"], studySource["workbench"]));
753+
promises.push(this.getWorkbench().patchWorkbenchDiffs(studyDiffs["workbench"], studySource["workbench"]));
754754
delete studyDiffs["workbench"];
755755
}
756-
const fieldKeys = Object.keys(studyDiffs);
757-
if (fieldKeys.length) {
758-
fieldKeys.forEach(fieldKey => {
756+
const changedFields = Object.keys(studyDiffs);
757+
if (changedFields.length) {
758+
changedFields.forEach(changedField => {
759759
// OM: can this be called all together?
760760
const patchData = {};
761-
if (fieldKey === "ui") {
762-
patchData[fieldKey] = this.getUi().serialize();
761+
if (changedField === "ui") {
762+
patchData[changedField] = this.getUi().serialize();
763763
} else {
764-
const upKey = qx.lang.String.firstUp(fieldKey);
764+
const upKey = qx.lang.String.firstUp(changedField);
765765
const getter = "get" + upKey;
766-
patchData[fieldKey] = this[getter](studyDiffs[fieldKey]);
766+
patchData[changedField] = this[getter](studyDiffs[changedField]);
767767
}
768768
promises.push(osparc.store.Study.getInstance().patchStudy(this.getUuid(), patchData))
769769
});
@@ -772,6 +772,53 @@ qx.Class.define("osparc.data.model.Study", {
772772
.then(() => {
773773
return studySource;
774774
});
775-
}
775+
},
776+
777+
// unused in favor of updateStudyFromPatches
778+
updateStudyFromDiff: function(studyDiffs) {
779+
const studyPropertyKeys = this.self().getProperties();
780+
studyPropertyKeys.forEach(studyPropertyKey => {
781+
if (studyPropertyKey in studyDiffs) {
782+
const newValue = studyDiffs[studyPropertyKey][1];
783+
if ("lastChangeDate" === studyPropertyKey) {
784+
this.setLastChangeDate(new Date(newValue));
785+
} else {
786+
const upKey = qx.lang.String.firstUp(studyPropertyKey);
787+
const setter = "set" + upKey;
788+
this[setter](newValue);
789+
}
790+
delete studyDiffs[studyPropertyKey];
791+
}
792+
});
793+
},
794+
795+
// json PATCHES
796+
updateStudyFromPatches: function(studyPatches) {
797+
const studyPropertyKeys = this.self().getProperties();
798+
studyPatches.forEach(patch => {
799+
const op = patch.op;
800+
const path = patch.path;
801+
const value = patch.value;
802+
switch (op) {
803+
case "replace":
804+
const studyProperty = path.substring(1); // remove the leading "/"
805+
if (studyPropertyKeys.includes(studyProperty)) {
806+
if (path === "/lastChangeDate") {
807+
this.setLastChangeDate(new Date(value));
808+
} else {
809+
const setter = "set" + qx.lang.String.firstUp(studyProperty);
810+
if (this[setter]) {
811+
this[setter](value);
812+
} else {
813+
console.warn(`Property "${studyProperty}" does not have a setter in osparc.data.model.Study`);
814+
}
815+
}
816+
}
817+
break;
818+
default:
819+
console.warn(`Unhandled patch operation "${op}" for path "${path}" with value "${value}"`);
820+
}
821+
});
822+
},
776823
}
777824
});

0 commit comments

Comments
 (0)