Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nodes tree UI/UX #2606

Merged
merged 22 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions services/director/src/simcore_service_director/producer.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,8 +542,15 @@ def _to_datetime(datetime_str: str) -> datetime:
datetime_str = datetime_str[:N]
return datetime.strptime(datetime_str, "%Y-%m-%dT%H:%M:%S.%f")

task_state_update_time = _to_datetime(last_task["Status"]["Timestamp"])
log.debug("%s %s: time %s", service["ID"], task_state, task_state_update_time)
try:
odeimaiz marked this conversation as resolved.
Show resolved Hide resolved
task_state_update_time = _to_datetime(last_task["Status"]["Timestamp"])
log.debug("%s %s: time %s", service["ID"], task_state, task_state_update_time)
except:
log.exception(
"This could be 'unconverted data remains: Z'",
last_task["Status"]["Timestamp"],
)
raise

last_task_state = ServiceState.STARTING # default
last_task_error_msg = (
Expand Down
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,6 +164,22 @@ 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 => {
Expand All @@ -168,6 +189,7 @@ qx.Class.define("osparc.component.widget.NodesTree", {
}, this);
}
});
this.setHeight(newModel.getChildren().length*21 + 5);
}
},

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
63 changes: 46 additions & 17 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
Loading