Skip to content

Commit f82060a

Browse files
authored
✨ App Mode: Run upstream dependencies for dynamic services (ITISFoundation#3057)
1 parent 850be24 commit f82060a

File tree

16 files changed

+375
-169
lines changed

16 files changed

+375
-169
lines changed

services/web/client/source/class/osparc/auth/ui/RegistrationView.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ qx.Class.define("osparc.auth.ui.RegistrationView", {
8383
// submit & cancel buttons
8484
const grp = new qx.ui.container.Composite(new qx.ui.layout.HBox(10));
8585

86-
const submitBtn = this.__submitBtn = new qx.ui.form.Button(this.tr("Submit"));
86+
const submitBtn = this.__submitBtn = new qx.ui.form.Button(this.tr("Submit")).set({
87+
center: true,
88+
appearance: "strong-button"
89+
});
8790
osparc.utils.Utils.setIdToWidget(submitBtn, "registrationSubmitBtn");
8891
grp.add(submitBtn, {
8992
flex:1

services/web/client/source/class/osparc/auth/ui/ResetPassRequestView.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ qx.Class.define("osparc.auth.ui.ResetPassRequestView", {
5353
// submit and cancel buttons
5454
const grp = new qx.ui.container.Composite(new qx.ui.layout.HBox(10));
5555

56-
const submitBtn = this.__submitBtn = new qx.ui.form.Button(this.tr("Submit"));
56+
const submitBtn = this.__submitBtn = new qx.ui.form.Button(this.tr("Submit")).set({
57+
center: true,
58+
appearance: "strong-button"
59+
});
5760
grp.add(submitBtn, {
5861
flex:1
5962
});

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

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
7272

7373
members: {
7474
_header: null,
75+
__inputsStateButton: null,
76+
__preparingInputs: null,
7577
__nodeStatusUI: null,
76-
__retrieveButton: null,
7778
_mainView: null,
7879
_settingsLayout: null,
7980
_iFrameLayout: null,
@@ -120,19 +121,22 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
120121
flex: 1
121122
});
122123

124+
const inputsStateBtn = this.__inputsStateButton = new qx.ui.form.Button().set({
125+
label: this.tr("Preparing inputs..."),
126+
icon: "@FontAwesome5Solid/circle-notch/14",
127+
backgroundColor: "transparent",
128+
toolTipText: this.tr("The view will remain disabled until the inputs are fetched")
129+
});
130+
inputsStateBtn.getChildControl("icon").getContentElement().addClass("rotate");
131+
inputsStateBtn.addListener("execute", () => this.showPreparingInputs(), this);
132+
header.add(inputsStateBtn);
133+
123134
const nodeStatusUI = this.__nodeStatusUI = new osparc.ui.basic.NodeStatusUI().set({
124135
backgroundColor: "background-main-4"
125136
});
126137
nodeStatusUI.getChildControl("label").setFont("text-14");
127138
header.add(nodeStatusUI);
128139

129-
const retrieveBtn = this.__retrieveButton = new qx.ui.form.Button(null, "@FontAwesome5Solid/spinner/14").set({
130-
backgroundColor: "transparent",
131-
toolTipText: this.tr("Retrieve")
132-
});
133-
retrieveBtn.addListener("execute", () => this.getNode().callRetrieveInputs(), this);
134-
header.add(retrieveBtn);
135-
136140
header.add(new qx.ui.core.Spacer(), {
137141
flex: 1
138142
});
@@ -175,12 +179,20 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
175179
return hBox;
176180
},
177181

182+
showPreparingInputs: function() {
183+
const title = this.tr("Preparing Inputs");
184+
const width = 600;
185+
const height = 500;
186+
osparc.ui.window.Window.popUpInWindow(this.__preparingInputs, title, width, height);
187+
},
188+
178189
__openNodeDataManager: function() {
179190
this.self().openNodeDataManager(this.getNode());
180191
},
181192

182193
__openServiceDetails: function() {
183-
const serviceDetails = new osparc.servicecard.Large(this.getNode().getMetaData(), this.getNode().getNodeId(), this.getStudy());
194+
const node = this.getNode();
195+
const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), node.getNodeId(), node.getStudy());
184196
const title = this.tr("Service information");
185197
const width = 600;
186198
const height = 700;
@@ -239,14 +251,52 @@ qx.Class.define("osparc.component.node.BaseNodeView", {
239251
throw new Error("Abstract method called!");
240252
},
241253

254+
__areInputsReady: function() {
255+
const wb = this.getNode().getStudy().getWorkbench();
256+
const upstreamNodeIds = wb.getUpstreamNodes(this.getNode(), false);
257+
for (let i=0; i<upstreamNodeIds.length; i++) {
258+
const upstreamNodeId = upstreamNodeIds[i];
259+
if (!osparc.data.model.NodeStatus.isCompNodeReady(wb.getNode(upstreamNodeId))) {
260+
return false;
261+
}
262+
}
263+
return true;
264+
},
265+
266+
__enableContent: function(enable) {
267+
this._mainView.setEnabled(enable);
268+
const iframe = this.getNode().getIFrame();
269+
if (iframe) {
270+
// enable/disable user interaction on iframe
271+
// eslint-disable-next-line no-underscore-dangle
272+
iframe.__iframe.getContentElement().setStyles({
273+
"pointer-events": enable ? "auto" : "none"
274+
});
275+
}
276+
},
277+
278+
setNotReadyDependencies: function(notReadyNodeIds = []) {
279+
const monitoredNodes = [];
280+
const workbench = this.getNode().getStudy().getWorkbench();
281+
notReadyNodeIds.forEach(notReadyNodeId => monitoredNodes.push(workbench.getNode(notReadyNodeId)));
282+
this.__preparingInputs.setMonitoredNodes(monitoredNodes);
283+
},
284+
285+
__dependeciesChanged: function() {
286+
const preparingNodes = this.__preparingInputs.getPreparingNodes();
287+
const waiting = Boolean(preparingNodes && preparingNodes.length);
288+
this.__inputsStateButton.setVisibility(waiting ? "visible" : "excluded");
289+
this.__enableContent(!waiting);
290+
},
291+
242292
__applyNode: function(node) {
243293
if (this.__nodeStatusUI) {
244294
this.__nodeStatusUI.setNode(node);
245295
}
246296

247-
if (this.__retrieveButton) {
248-
this.__retrieveButton.setVisibility(node.isDynamic() ? "visible" : "excluded");
249-
}
297+
this.__preparingInputs = new osparc.component.widget.PreparingInputs();
298+
this.__preparingInputs.addListener("changePreparingNodes", () => this.__dependeciesChanged());
299+
this.__dependeciesChanged();
250300

251301
this._mainView.removeAll();
252302
this._addSettings();

services/web/client/source/class/osparc/component/study/SaveAsTemplate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ qx.Class.define("osparc.component.study.SaveAsTemplate", {
9090
osparc.data.Resources.fetch("studies", "postToTemplate", params)
9191
.then(template => {
9292
this.fireDataEvent("finished", template);
93-
osparc.component.message.FlashMessenger.getInstance().logAs(this.tr("Study successfully saved as template."), "INFO");
93+
osparc.component.message.FlashMessenger.getInstance().logAs(this.__studyDataClone.name + this.tr(" successfully published as template."), "INFO");
9494
})
9595
.catch(err => {
9696
console.error(err);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,10 @@ qx.Class.define("osparc.component.widget.PersistentIframe", {
203203
let divSize = qx.bom.element.Dimension.getSize(domElement);
204204
this.__iframe.setLayoutProperties({
205205
top: divPos.top - iframeParentPos.top + 25,
206-
left: (divPos.left - iframeParentPos.left)
206+
left: divPos.left - iframeParentPos.left
207207
});
208208
this.__iframe.set({
209-
width: (divSize.width),
209+
width: divSize.width,
210210
height: divSize.height - 25
211211
});
212212
this.__restartButton.setLayoutProperties({
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2022 IT'IS Foundation, https://itis.swiss
9+
10+
License:
11+
MIT: https://opensource.org/licenses/MIT
12+
13+
Authors:
14+
* Odei Maiz (odeimaiz)
15+
16+
************************************************************************ */
17+
18+
qx.Class.define("osparc.component.widget.PreparingInputs", {
19+
extend: qx.ui.core.Widget,
20+
21+
construct: function(monitoredNodes = []) {
22+
this.base(arguments);
23+
24+
this._setLayout(new qx.ui.layout.VBox(10));
25+
26+
const text = this.tr("In order to move to this step, we need to prepare some inputs for you.<br>This might take a while, so enjoy checking the logs down here:");
27+
const title = new qx.ui.basic.Label(text).set({
28+
font: "text-14",
29+
rich: true
30+
});
31+
this._add(title);
32+
33+
const list = this.__monitoredNodesList = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
34+
this._add(list);
35+
this.setMonitoredNodes(monitoredNodes);
36+
37+
const loggerLayout = this.__loggerLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox());
38+
this._add(loggerLayout, {
39+
flex: 1
40+
});
41+
},
42+
43+
properties: {
44+
monitoredNodes: {
45+
check: "Array",
46+
init: null,
47+
apply: "__applyMonitoredNodes",
48+
event: "changeMonitoredNodes"
49+
}
50+
},
51+
52+
events: {
53+
"changePreparingNodes": "qx.event.type.Data"
54+
},
55+
56+
members: {
57+
__monitoredNodesList: null,
58+
59+
__applyMonitoredNodes: function(monitoredNodes) {
60+
monitoredNodes.forEach(monitoredNode => {
61+
[
62+
"changeRunning",
63+
"changeOutput"
64+
].forEach(changeEvent => {
65+
monitoredNode.getStatus().addListener(changeEvent, () => this.__updatePreparingNodes());
66+
});
67+
});
68+
this.__updateMonitoredNodesList();
69+
},
70+
71+
__updateMonitoredNodesList: function() {
72+
this.__monitoredNodesList.removeAll();
73+
const monitoredNodes = this.getMonitoredNodes();
74+
if (monitoredNodes && monitoredNodes.length) {
75+
const group = new qx.ui.form.RadioGroup();
76+
group.addListener("changeSelection", e => {
77+
const selectedButton = e.getData()[0];
78+
this.__loggerLayout.removeAll();
79+
const nodeLogger = selectedButton.node.getLogger();
80+
nodeLogger.getChildControl("pin-node").exclude();
81+
this.__loggerLayout.add(nodeLogger);
82+
}, this);
83+
monitoredNodes.forEach(node => {
84+
const nodeLayout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5).set({
85+
alignY: "middle"
86+
}));
87+
const showLoggerBtn = new qx.ui.form.ToggleButton(this.tr("Logs"));
88+
showLoggerBtn.node = node;
89+
nodeLayout.add(showLoggerBtn);
90+
group.add(showLoggerBtn);
91+
if (group.getSelection().length === 0) {
92+
group.setSelection([showLoggerBtn]);
93+
}
94+
const statusUI = new osparc.ui.basic.NodeStatusUI(node);
95+
nodeLayout.add(statusUI);
96+
nodeLayout.add(new qx.ui.basic.Label(node.getLabel()), {
97+
flex: 1
98+
});
99+
this.__monitoredNodesList.add(nodeLayout);
100+
});
101+
}
102+
},
103+
104+
getPreparingNodes: function() {
105+
const preparingNodes = [];
106+
const monitoredNodes = this.getMonitoredNodes();
107+
monitoredNodes.forEach(monitoredNode => {
108+
if (!osparc.data.model.NodeStatus.isCompNodeReady(monitoredNode)) {
109+
preparingNodes.push(monitoredNode);
110+
}
111+
});
112+
return preparingNodes;
113+
},
114+
115+
116+
__updatePreparingNodes: function() {
117+
this.fireDataEvent("changePreparingNodes", this.getPreparingNodes().length);
118+
}
119+
}
120+
});

services/web/client/source/class/osparc/component/widget/logger/LoggerTable.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
* <pre class='javascript'>
2828
* let tableModel = this.__logModel = new osparc.component.widget.logger.LoggerTable();
29-
* tableModel.setColumns(["Origin", "Message"], ["whoRich", "whatRich"]);
29+
* tableModel.setColumns(["Origin", "Timestamp", "Message"], ["whoRich", "whatRich", "whatRich"]);
3030
* let custom = {
3131
* tableColumnModel : function(obj) {
3232
* return new qx.ui.table.columnmodel.Resize(obj);
@@ -50,9 +50,11 @@ qx.Class.define("osparc.component.widget.logger.LoggerTable", {
5050

5151
this.setColumns([
5252
"Origin",
53+
"Time",
5354
"Message"
5455
], [
5556
"whoRich",
57+
"timeRich",
5658
"msgRich"
5759
]);
5860

@@ -136,6 +138,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerTable", {
136138
newRow["msgColor"] = this.self().getLevelColor(newRow.logLevel);
137139

138140
newRow["whoRich"] = this.self().addColorTag(newRow.label, newRow.nodeColor);
141+
newRow["timeRich"] = this.self().addColorTag(osparc.utils.Utils.formatTime(newRow.timeStamp, true), newRow.msgColor);
139142
newRow["msgRich"] = this.self().addColorTag(newRow.msg, newRow.msgColor);
140143

141144
this.__rawData.push(newRow);
@@ -159,6 +162,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerTable", {
159162
row["msgColor"] = this.self().getLevelColor(row.logLevel);
160163

161164
row["whoRich"] = this.self().addColorTag(row.label, row.nodeColor);
165+
row["timeRich"] = this.self().addColorTag(osparc.utils.Utils.formatTime(row.timeStamp, true), row.msgColor);
162166
row["msgRich"] = this.self().addColorTag(row.msg, row.msgColor);
163167
});
164168
},

services/web/client/source/class/osparc/component/widget/logger/LoggerView.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,13 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", {
201201
colModel.setDataCellRenderer(1, new osparc.ui.table.cellrenderer.Html().set({
202202
defaultCellStyle: "user-select: text"
203203
}));
204+
colModel.setDataCellRenderer(2, new osparc.ui.table.cellrenderer.Html().set({
205+
defaultCellStyle: "user-select: text"
206+
}));
204207
let resizeBehavior = colModel.getBehavior();
205-
resizeBehavior.setWidth(0, "20%");
206-
resizeBehavior.setWidth(1, "80%");
208+
resizeBehavior.setWidth(0, "15%");
209+
resizeBehavior.setWidth(1, "10%");
210+
resizeBehavior.setWidth(2, "75%");
207211

208212
this.__applyFilters();
209213

@@ -215,8 +219,8 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", {
215219
},
216220

217221
__currentNodeClicked: function(checked) {
218-
const currentNodeId = this.getCurrentNodeId();
219222
if (checked) {
223+
const currentNodeId = this.getCurrentNodeId();
220224
this.__nodeSelected(currentNodeId);
221225
}
222226
},
@@ -225,12 +229,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", {
225229
const study = osparc.store.Store.getInstance().getCurrentStudy();
226230
const workbench = study.getWorkbench();
227231
const node = workbench.getNode(nodeId);
228-
if (node) {
229-
this.__textFilterField.setValue(node.getLabel());
230-
} else {
231-
// Root selected
232-
this.__textFilterField.setValue("");
233-
}
232+
this.__textFilterField.setValue(node ? node.getLabel() : "");
234233
},
235234

236235
__copyLogsToClipboard: function() {
@@ -286,6 +285,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", {
286285
const msgLog = {
287286
nodeId,
288287
label,
288+
timeStamp: new Date(),
289289
msg,
290290
logLevel
291291
};

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,6 @@ qx.Class.define("osparc.data.model.Node", {
305305
return osparc.data.model.Node.isComputational(this.getMetaData());
306306
},
307307

308-
hasIteratorUpstream: function() {
309-
return osparc.data.model.Workbench.hasIteratorUpstream(this.getStudy().getWorkbench(), this);
310-
},
311-
312308
getMetaData: function() {
313309
return this.__metaData;
314310
},

0 commit comments

Comments
 (0)