Skip to content

Commit

Permalink
Nodes tree UI/UX (#2606)
Browse files Browse the repository at this point in the history
  • Loading branch information
odeimaiz authored Oct 29, 2021
1 parent 3aff410 commit e82aea3
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,29 @@ qx.Class.define("osparc.component.widget.NodesTree", {
},

statics: {
getSortingValue: function(node) {
if (node.isFilePicker()) {
return osparc.utils.Services.getSorting("file");
} else if (node.isParameter()) {
return osparc.utils.Services.getSorting("parameter");
}
return osparc.utils.Services.getSorting(node.getMetaData().type);
},

convertModel: function(nodes) {
let children = [];
const children = [];
for (let nodeId in nodes) {
const node = nodes[nodeId];
let nodeInTree = {
label: "",
nodeId: node.getNodeId()
const nodeInTree = {
label: node.getLabel(),
children: node.isContainer() ? this.convertModel(node.getInnerNodes()) : [],
isContainer: node.isContainer(),
nodeId: node.getNodeId(),
sortingValue: this.self().getSortingValue(node)
};
nodeInTree.label = node.getLabel();
nodeInTree.isContainer = node.isContainer();
if (node.isContainer()) {
nodeInTree.children = this.convertModel(node.getInnerNodes());
}
children.push(nodeInTree);
}
// children.sort((firstEl, secondEl) => firstEl.sortingValue - secondEl.sortingValue);
return children;
}
},
Expand Down Expand Up @@ -111,11 +119,12 @@ qx.Class.define("osparc.component.widget.NodesTree", {
populateTree: function() {
const study = this.getStudy();
const topLevelNodes = study.getWorkbench().getNodes();
let data = {
const data = {
label: study.getName(),
children: this.self().convertModel(topLevelNodes),
isContainer: true,
nodeId: study.getUuid(),
isContainer: true
sortingValue: 0
};
let newModel = qx.data.marshal.Json.createModel(data, true);
let oldModel = this.getModel();
Expand All @@ -134,19 +143,15 @@ qx.Class.define("osparc.component.widget.NodesTree", {
bindItem: (c, item, id) => {
c.bindDefaultProperties(item, id);
c.bindProperty("nodeId", "nodeId", null, item, id);
const node = study.getWorkbench().getNode(item.getModel().getNodeId());
if (node) {
node.bind("label", item.getModel(), "label");
}
c.bindProperty("label", "label", null, item, id);
const node = study.getWorkbench().getNode(item.getModel().getNodeId());
if (item.getModel().getNodeId() === study.getUuid()) {
item.setIcon("@FontAwesome5Solid/home/14");
item.getChildControl("options-delete-button").exclude();
}
if (node) {
if (node.isDynamic()) {
item.getChildControl("fullscreen-button").show();
}
} else if (node) {
node.bind("label", item.getModel(), "label");

// set icon
if (node.isFilePicker()) {
const icon = osparc.utils.Services.getIcon("file");
item.setIcon(icon+"14");
Expand All @@ -159,15 +164,35 @@ qx.Class.define("osparc.component.widget.NodesTree", {
item.setIcon(icon+"14");
}
}

// bind running/interactive status to icon color
if (node.isDynamic()) {
node.getStatus().bind("interactive", item.getChildControl("icon"), "textColor", {
converter: status => osparc.utils.StatusUI.getColor(status)
}, this);
} else if (node.isComputational()) {
node.getStatus().bind("running", item.getChildControl("icon"), "textColor", {
converter: status => osparc.utils.StatusUI.getColor(status)
}, this);
}

// add fullscreen
if (node.isDynamic()) {
item.getChildControl("fullscreen-button").show();
}
}
},
configureItem: item => {
item.addListener("tap", () => {
this.__openItem(item.getModel().getNodeId());
this.nodeSelected(item.getModel().getNodeId());
}, this);
}
},
sorter: (itemA, itemB) => itemA.getSortingValue() - itemB.getSortingValue()
});
const nChildren = newModel.getChildren().length;
console.log(nChildren);
this.setHeight(nChildren*21 + 12);
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,30 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
return inputOutputNodesLayout;
},

__createServiceCatalog: function(winPos) {
openServiceCatalog: function(winPos, nodePos) {
const srvCat = new osparc.component.workbench.ServiceCatalog();
const maxLeft = this.getBounds().width - osparc.component.workbench.ServiceCatalog.Width;
const maxHeight = this.getBounds().height - osparc.component.workbench.ServiceCatalog.Height;
const posX = Math.min(winPos.x, maxLeft);
const posY = Math.min(winPos.y, maxHeight);
const posX = winPos ? Math.min(winPos.x, maxLeft) : 100;
const posY = winPos ? Math.min(winPos.y, maxHeight) : 100;
srvCat.moveTo(posX + this.__getLeftOffset(), posY + this.__getTopOffset());
srvCat.addListener("addService", e => {
const {
service,
nodeLeftId,
nodeRightId
} = e.getData();
const newNodeUI = this.__addNode(service, nodePos);
if (nodeLeftId !== null || nodeRightId !== null) {
const newNodeId = newNodeUI.getNodeId();
this._createEdgeBetweenNodes({
nodeId: nodeLeftId ? nodeLeftId : newNodeId
}, {
nodeId: nodeRightId ? nodeRightId : newNodeId
});
}
}, this);
srvCat.open();
return srvCat;
},

Expand Down Expand Up @@ -372,9 +389,11 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
},

_addNodeUIToWorkbench: function(nodeUI, position) {
if (!("x" in position) || isNaN(position["x"]) || position["x"] < 0) {
console.error("not a valid position");
return;
if (position === undefined || !("x" in position) || isNaN(position["x"]) || position["x"] < 0) {
position = {
x: 10,
y: 10
};
}
this.__updateWorkbenchLayoutSize(position);

Expand Down Expand Up @@ -681,32 +700,9 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {

if (this.__tempEdgeNodeId === dragNodeId) {
const winPos = this.__unscaleCoordinates(this.__pointerPos.x, this.__pointerPos.y);
const srvCat = this.__createServiceCatalog(winPos);
if (this.__tempEdgeIsInput === true) {
srvCat.setContext(null, dragNodeId);
} else {
srvCat.setContext(dragNodeId, null);
}
srvCat.addListener("addService", ev => {
const {
service,
nodeLeftId,
nodeRightId
} = ev.getData();
const newNodeUI = this.__addNode(service, this.__pointerPos);
if (nodeLeftId !== null || nodeRightId !== null) {
const newNodeId = newNodeUI.getNodeId();
this._createEdgeBetweenNodes({
nodeId: nodeLeftId ? nodeLeftId : newNodeId
}, {
nodeId: nodeRightId ? nodeRightId : newNodeId
});
}
}, this);
srvCat.addListener("close", () => {
this.__removeTempEdge();
}, this);
srvCat.open();
const srvCat = this.openServiceCatalog(winPos, this.__pointerPos);
this.__tempEdgeIsInput === true ? srvCat.setContext(null, dragNodeId) : srvCat.setContext(dragNodeId, null);
srvCat.addListener("close", () => this.__removeTempEdge(), this);
}
qx.bom.Element.removeListener(
this.__desktop,
Expand Down Expand Up @@ -1315,15 +1311,8 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", {
return;
}
const winPos = this.__pointerEventToWorkbenchPos(pointerEvent, false);
const scaledPos = this.__pointerEventToWorkbenchPos(pointerEvent, true);
const srvCat = this.__createServiceCatalog(winPos);
srvCat.addListener("addService", e => {
const {
service
} = e.getData();
this.__addNode(service, scaledPos);
}, this);
srvCat.open();
const nodePos = this.__pointerEventToWorkbenchPos(pointerEvent, true);
this.openServiceCatalog(winPos, nodePos);
}, this);

this.__workbenchLayout.addListener("resize", () => this.__updateHint(), this);
Expand Down
67 changes: 47 additions & 20 deletions services/web/client/source/class/osparc/desktop/WorkbenchView.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ qx.Class.define("osparc.desktop.WorkbenchView", {

this.setOffset(2);
osparc.desktop.WorkbenchView.decorateSplitter(this.getChildControl("splitter"));
osparc.desktop.WorkbenchView.decorateSlider(this.getChildControl("slider"));

this.__sidePanels = this.getChildControl("side-panels");
this.getChildControl("main-panel-tabs");
Expand All @@ -40,14 +41,24 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
TAB_BUTTON_HEIGHT: 50,

decorateSplitter: function(splitter) {
splitter.setWidth(2);
const colorManager = qx.theme.manager.Color.getInstance();
const binaryColor = osparc.utils.Utils.getRoundedBinaryColor(colorManager.resolve("background-main"));
splitter.setBackgroundColor(binaryColor);
splitter.set({
width: 2,
backgroundColor: binaryColor
});
colorManager.addListener("changeTheme", () => {
const newBinaryColor = osparc.utils.Utils.getRoundedBinaryColor(colorManager.resolve("background-main"));
splitter.setBackgroundColor(newBinaryColor);
}, this);
},

decorateSlider: function(slider) {
slider.set({
width: 2,
backgroundColor: "#007fd4", // Visual Studio blue
opacity: 1
});
}
},

Expand Down Expand Up @@ -88,6 +99,7 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
width: Math.min(parseInt(window.innerWidth * (0.16+0.24)), 550)
});
osparc.desktop.WorkbenchView.decorateSplitter(control.getChildControl("splitter"));
osparc.desktop.WorkbenchView.decorateSlider(control.getChildControl("slider"));
this.add(control, 0); // flex 0
break;
}
Expand Down Expand Up @@ -260,28 +272,38 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
const topBar = tabViewPrimary.getChildControl("bar");
this.__addTopBarSpacer(topBar);

const homeAndNodesTree = new qx.ui.container.Composite(new qx.ui.layout.VBox(0)).set({
const homeAndNodesTree = new qx.ui.container.Composite(new qx.ui.layout.VBox(15)).set({
backgroundColor: primaryColumnBGColor
});

const studyTreeItem = this.__studyTreeItem = new osparc.component.widget.StudyTitleOnlyTree().set({
alignY: "middle",
minHeight: 32,
maxHeight: 32,
backgroundColor: primaryColumnBGColor,
marginBottom: 5
backgroundColor: primaryColumnBGColor
});
studyTreeItem.setStudy(study);
homeAndNodesTree.add(studyTreeItem);

const nodesTree = this.__nodesTree = new osparc.component.widget.NodesTree().set({
backgroundColor: primaryColumnBGColor,
hideRoot: true
hideRoot: true,
allowGrowY: true,
minHeight: 5
});
nodesTree.setStudy(study);
homeAndNodesTree.add(nodesTree, {
flex: 1
homeAndNodesTree.add(nodesTree);

const addNewNodeBtn = new qx.ui.form.Button().set({
label: this.tr("Add new node"),
icon: "@FontAwesome5Solid/plus/14",
allowGrowX: false,
alignX: "left",
marginLeft: 14
});
addNewNodeBtn.addListener("execute", () => this.__workbenchUI.openServiceCatalog());
homeAndNodesTree.add(addNewNodeBtn);

const nodesPage = this.__createTabPage("@FontAwesome5Solid/list", this.tr("Nodes"), homeAndNodesTree, primaryColumnBGColor);
tabViewPrimary.add(nodesPage);

Expand All @@ -304,6 +326,10 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
const topBar = tabViewSecondary.getChildControl("bar");
this.__addTopBarSpacer(topBar);

const studyOptionsPage = this.__studyOptionsPage = this.__createTabPage("@FontAwesome5Solid/book", this.tr("Study options"));
studyOptionsPage.exclude();
tabViewSecondary.add(studyOptionsPage);

const infoPage = this.__infoPage = this.__createTabPage("@FontAwesome5Solid/info", this.tr("Information"));
infoPage.exclude();
tabViewSecondary.add(infoPage);
Expand Down Expand Up @@ -680,12 +706,15 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
},

__populateSecondPanel: function(node) {
this.__infoPage.removeAll();
this.__settingsPage.removeAll();
this.__outputsPage.removeAll();
this.__infoPage.getChildControl("button").exclude();
this.__settingsPage.getChildControl("button").exclude();
this.__outputsPage.getChildControl("button").exclude();
[
this.__studyOptionsPage,
this.__infoPage,
this.__settingsPage,
this.__outputsPage
].forEach(page => {
page.removeAll();
page.getChildControl("button").exclude();
});

if (node instanceof osparc.data.model.Study) {
this.__populateSecondPanelStudy(node);
Expand All @@ -699,10 +728,10 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
},

__populateSecondPanelStudy: function(study) {
this.__infoPage.getChildControl("button").show();
this.getChildControl("side-panel-right-tabs").setSelection([this.__infoPage]);
this.__studyOptionsPage.getChildControl("button").show();
this.getChildControl("side-panel-right-tabs").setSelection([this.__studyOptionsPage]);

this.__infoPage.add(new osparc.studycard.Medium(study), {
this.__studyOptionsPage.add(new osparc.studycard.Medium(study), {
flex: 1
});
},
Expand Down Expand Up @@ -865,9 +894,6 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
},

__attachEventHandlers: function() {
// const blocker = this.getBlocker();
// blocker.addListener("tap", this.getChildControl("side-panels").toggleCollapsed.bind(this.getChildControl("side-panels")));

const maximizeIframeCb = msg => {
this.__maximizeIframe(msg.getData());
};
Expand Down Expand Up @@ -963,6 +989,7 @@ qx.Class.define("osparc.desktop.WorkbenchView", {
return;
}
}
this.__maximizeIframe(false);
this.nodeSelected(this.getStudy().getUuid());
}
}
Expand Down
Loading

0 comments on commit e82aea3

Please sign in to comment.