Skip to content

Commit ddda87b

Browse files
committed
Merge branch 'feature/functinos-browser' of github.com:odeimaiz/osparc-simcore into feature/functinos-browser
2 parents e95dfb9 + 2196795 commit ddda87b

File tree

27 files changed

+419
-130
lines changed

27 files changed

+419
-130
lines changed

.env-devel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ WEBSERVER_PROJECTS={}
395395
WEBSERVER_PROMETHEUS_API_VERSION=v1
396396
WEBSERVER_PROMETHEUS_URL=http://prometheus:9090
397397
WEBSERVER_PUBLICATIONS=1
398+
WEBSERVER_REALTIME_COLLABORATION='{"RTC_MAX_NUMBER_OF_USERS":3}'
398399
WEBSERVER_SCICRUNCH={}
399400
WEBSERVER_SESSION_SECRET_KEY='REPLACE_ME_with_result__Fernet_generate_key='
400401
WEBSERVER_SOCKETIO=1

packages/postgres-database/docker/Dockerfile

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,5 @@ COPY entrypoint.bash /home/entrypoint.bash
5555

5656
RUN chmod +x /home/entrypoint.bash
5757

58-
ENV POSTGRES_USER=scu \
59-
POSTGRES_PASSWORD=adminadmin \
60-
POSTGRES_HOST=postgres \
61-
POSTGRES_PORT=5432 \
62-
POSTGRES_DB=simcoredb
63-
6458
ENTRYPOINT [ "/bin/bash", "/home/entrypoint.bash" ]
6559
CMD [ "sc-pg", "upgrade" ]

services/dask-sidecar/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ARG PYTHON_VERSION="3.11.9"
55
ARG UV_VERSION="0.7"
66
FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv_build
77
# we docker image is built based on debian
8-
FROM --platform=${TARGETPLATFORM} python:${PYTHON_VERSION}-slim-bookworm AS base
8+
FROM python:${PYTHON_VERSION}-slim-bookworm AS base
99
ARG TARGETPLATFORM
1010
ARG BUILDPLATFORM
1111
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log

services/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ services:
673673
SWARM_STACK_NAME: ${SWARM_STACK_NAME}
674674

675675
WEBSERVER_DEV_FEATURES_ENABLED: ${WEBSERVER_DEV_FEATURES_ENABLED}
676+
WEBSERVER_REALTIME_COLLABORATION: ${WEBSERVER_REALTIME_COLLABORATION}
676677

677678
WEBSERVER_LOGLEVEL: ${WEBSERVER_LOGLEVEL}
678679
WEBSERVER_PROFILING: ${WEBSERVER_PROFILING}

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/outputs/_manager.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ def __init__(
118118

119119
self._port_key_tracker = _PortKeyTracker()
120120
self._task_uploading: Task | None = None
121+
self._task_uploading_followup: Task | None = None
121122
self._task_scheduler_worker: Task | None = None
122123
self._schedule_all_ports_for_upload: bool = False
123124

@@ -171,14 +172,22 @@ def _remove_downloads(future: Future) -> None:
171172
except Exception as e: # pylint: disable=broad-except
172173
self._last_upload_error_tracker[port_key] = e
173174

174-
create_task(self._port_key_tracker.remove_all_uploading())
175+
self._task_uploading_followup = create_task(
176+
self._port_key_tracker.remove_all_uploading()
177+
)
175178

176179
self._task_uploading.add_done_callback(_remove_downloads)
177180

178181
async def _uploading_task_cancel(self) -> None:
179182
if self._task_uploading is not None:
180183
await _cancel_task(self._task_uploading, self.task_cancellation_timeout_s)
181184
await self._port_key_tracker.move_all_uploading_to_pending()
185+
self._task_uploading = None
186+
if self._task_uploading_followup is not None:
187+
await _cancel_task(
188+
self._task_uploading_followup, self.task_cancellation_timeout_s
189+
)
190+
self._task_uploading_followup = None
182191

183192
async def _scheduler_worker(self) -> None:
184193
if await self._port_key_tracker.are_pending_ports_uploading():

services/migration/Dockerfile

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,7 @@ FROM base AS production
8484

8585
ENV PYTHONOPTIMIZE=TRUE
8686

87-
# testing defaults
88-
ENV POSTGRES_USER=scu \
89-
POSTGRES_PASSWORD=adminadmin \
90-
POSTGRES_HOST=postgres \
91-
POSTGRES_PORT=5432 \
92-
POSTGRES_DB=simcoredb \
93-
SC_DONE_MARK_FILE=migration.done
94-
87+
ENV SC_DONE_MARK_FILE=migration.done
9588

9689
WORKDIR /home/scu
9790

services/static-webserver/client/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ follow-dev-logs: ## follow the logs of the qx compiler
4444
.PHONY: compile touch upgrade
4545
compile: ## qx compiles host' 'source' -> image's 'build-output'
4646
# qx compile 'source' within $(docker_image) image [itisfoundation/qooxdoo-kit:${QOOXDOO_KIT_TAG}]
47-
@docker --debug buildx build \
47+
@docker buildx build \
4848
--load \
4949
--file $(docker_file) \
5050
--tag $(docker_image) \
@@ -58,7 +58,7 @@ compile: ## qx compiles host' 'source' -> image's 'build-output'
5858

5959
touch: ## minimal image build with /project/output-build inside
6060
# touch /project/output-build such that multi-stage 'services/web/Dockerfile' can build development target (fixes #1097)
61-
@docker --debug buildx build \
61+
@docker buildx build \
6262
--load \
6363
--file $(docker_file) \
6464
--tag $(docker_image) \

services/static-webserver/client/source/class/osparc/dashboard/CardBase.js

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ qx.Class.define("osparc.dashboard.CardBase", {
2424
construct: function() {
2525
this.base(arguments);
2626

27+
if (osparc.utils.DisabledPlugins.isSimultaneousAccessEnabled()) {
28+
// "IN_USE" is not a blocker anymore
29+
const inUseIdx = qx.util.PropertyUtil.getProperties(osparc.dashboard.CardBase).blocked.check.indexOf("IN_USE");
30+
if (inUseIdx > -1) {
31+
qx.util.PropertyUtil.getProperties(osparc.dashboard.CardBase).blocked.check.splice(inUseIdx, 1);
32+
}
33+
}
34+
2735
[
2836
"pointerover",
2937
"focus"
@@ -780,13 +788,22 @@ qx.Class.define("osparc.dashboard.CardBase", {
780788
},
781789

782790
__applyState: function(state) {
783-
let lockInUse = false;
791+
let projectInUse = false;
784792
if ("locked" in state && "value" in state["locked"]) {
785-
lockInUse = state["locked"]["value"];
793+
projectInUse = state["locked"]["value"];
786794
}
787-
this.setBlocked(lockInUse ? "IN_USE" : false);
788-
if (lockInUse) {
789-
this.__showBlockedCardFromStatus("IN_USE", state["locked"]);
795+
796+
if (osparc.utils.DisabledPlugins.isSimultaneousAccessEnabled()) {
797+
if (projectInUse && state["locked"]["status"] === "OPENED") {
798+
this.__showWhoIsIn(state["locked"]["owner"]);
799+
} else {
800+
this.__showWhoIsIn(null);
801+
}
802+
} else {
803+
this.setBlocked(projectInUse ? "IN_USE" : false);
804+
if (projectInUse) {
805+
this.__showBlockedCardFromStatus("IN_USE", state["locked"]);
806+
}
790807
}
791808

792809
const pipelineState = ("state" in state) ? state["state"]["value"] : undefined;
@@ -866,6 +883,30 @@ qx.Class.define("osparc.dashboard.CardBase", {
866883
});
867884
},
868885

886+
__showWhoIsIn: function(whoIsIn) {
887+
let users = [];
888+
if (whoIsIn) {
889+
// replace this once the backend returns a list of group__ids
890+
const allUsers = [
891+
{ name: "Alice", avatar: "https://i.pravatar.cc/150?img=1" },
892+
{ name: "Bob", avatar: "https://i.pravatar.cc/150?img=2" },
893+
{ name: "Charlie", avatar: "https://i.pravatar.cc/150?img=3" },
894+
{ name: "Dana", avatar: "https://i.pravatar.cc/150?img=4" },
895+
{ name: "Eve", avatar: "https://i.pravatar.cc/150?img=5" },
896+
{ name: "Frank", avatar: "https://i.pravatar.cc/150?img=6" },
897+
];
898+
// Random number of users between 1 and 6
899+
const randomCount = Math.floor(Math.random() * 6) + 1;
900+
// Shuffle the array and take the first randomCount users
901+
const shuffled = allUsers.sort(() => 0.5 - Math.random());
902+
users = shuffled.slice(0, randomCount);
903+
}
904+
if (osparc.utils.DisabledPlugins.isSimultaneousAccessEnabled() && this.getResourceType() === "study") {
905+
const avatarGroup = this.getChildControl("avatar-group");
906+
avatarGroup.setUsers(users);
907+
}
908+
},
909+
869910
__showBlockedCardFromStatus: function(reason, moreInfo) {
870911
switch (reason) {
871912
case "IN_USE":

services/static-webserver/client/source/class/osparc/dashboard/GridButtonBase.js

Lines changed: 38 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -43,35 +43,41 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
4343
statics: {
4444
ITEM_WIDTH: 190,
4545
ITEM_HEIGHT: 220,
46-
PADDING: 10,
47-
TITLE_PADDING: 6,
48-
SPACING_IN: 5,
46+
PADDING: 6,
4947
SPACING: 15,
5048
THUMBNAIL_SIZE: 50,
5149
POS: {
5250
TITLE: {
5351
row: 0,
5452
column: 0,
55-
rowSpan: 1,
56-
colSpan: 4
5753
},
58-
THUMBNAIL: {
59-
row: 2,
54+
BODY: {
55+
row: 1,
6056
column: 0,
61-
rowSpan: 1,
62-
colSpan: 4
63-
},
64-
TAGS: {
65-
row: 3,
66-
column: 0
6757
},
6858
FOOTER: {
69-
row: 4,
59+
row: 2,
7060
column: 0,
71-
rowSpan: 1,
72-
colSpan: 4
7361
}
7462
},
63+
HPOS: {
64+
ICON: {
65+
column: 0,
66+
row: 0,
67+
},
68+
TITLE: {
69+
column: 1,
70+
row: 0,
71+
},
72+
SUBTITLE_ICON: {
73+
column: 0,
74+
row: 1,
75+
},
76+
SUBTITLE_TEXT: {
77+
column: 1,
78+
row: 1,
79+
},
80+
},
7581
FPOS: {
7682
MODIFIED: {
7783
row: 0,
@@ -97,7 +103,7 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
97103
row: 1,
98104
column: 2,
99105
}
100-
}
106+
},
101107
},
102108

103109
events: {
@@ -113,20 +119,21 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
113119
switch (id) {
114120
case "main-layout": {
115121
const grid = new qx.ui.layout.Grid();
116-
grid.setSpacing(this.self().SPACING_IN);
117-
grid.setRowFlex(2, 1);
122+
grid.setRowFlex(this.self().POS.BODY.row, 1);
118123
grid.setColumnFlex(0, 1);
119124

120125
control = new qx.ui.container.Composite().set({
126+
minWidth: this.self().ITEM_WIDTH,
127+
minHeight: this.self().ITEM_HEIGHT,
121128
maxWidth: this.self().ITEM_WIDTH,
122-
maxHeight: this.self().ITEM_HEIGHT
129+
maxHeight: this.self().ITEM_HEIGHT,
123130
});
124131
control.setLayout(grid);
125132
const header = this.getChildControl("header");
126133
const body = this.getChildControl("body");
127134
const footer = this.getChildControl("footer");
128135
control.add(header, this.self().POS.TITLE);
129-
control.add(body, this.self().POS.THUMBNAIL);
136+
control.add(body, this.self().POS.BODY);
130137
control.add(footer, this.self().POS.FOOTER);
131138
this._add(control, {
132139
top: 0,
@@ -140,8 +147,8 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
140147
const hGrid = new qx.ui.layout.Grid().set({
141148
spacing: 6,
142149
});
143-
hGrid.setRowFlex(0, 1);
144-
hGrid.setColumnFlex(1, 1);
150+
hGrid.setRowFlex(this.self().HPOS.TITLE.row, 1);
151+
hGrid.setColumnFlex(this.self().HPOS.TITLE.column, 1);
145152
hGrid.setColumnAlign(0, "right", "middle");
146153
hGrid.setColumnAlign(1, "left", "middle");
147154
hGrid.setColumnAlign(2, "center", "middle");
@@ -157,24 +164,17 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
157164
break;
158165
}
159166
case "body":
160-
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(5)).set({
161-
decorator: "main",
162-
allowGrowY: true,
163-
allowGrowX: true,
164-
allowShrinkX: true,
165-
padding: this.self().PADDING
166-
});
167-
control.getContentElement().setStyles({
168-
"border-width": 0
167+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(6)).set({
168+
padding: this.self().PADDING,
169169
});
170170
break;
171171
case "footer": {
172172
const fGrid = new qx.ui.layout.Grid();
173173
fGrid.setSpacing(2);
174-
fGrid.setColumnFlex(0, 1);
174+
fGrid.setColumnFlex(this.self().FPOS.MODIFIED.row, 1);
175175
control = new qx.ui.container.Composite().set({
176176
backgroundColor: "background-card-overlay",
177-
padding: this.self().PADDING - 2,
177+
padding: this.self().PADDING,
178178
maxWidth: this.self().ITEM_WIDTH,
179179
maxHeight: this.self().ITEM_HEIGHT
180180
});
@@ -184,10 +184,7 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
184184
case "icon": {
185185
control = osparc.dashboard.CardBase.createCardIcon();
186186
layout = this.getChildControl("header");
187-
layout.add(control, {
188-
column: 0,
189-
row: 0,
190-
});
187+
layout.add(control, this.self().HPOS.ICON);
191188
break;
192189
}
193190
case "title":
@@ -196,21 +193,15 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
196193
font: "text-14",
197194
});
198195
layout = this.getChildControl("header");
199-
layout.add(control, {
200-
column: 1,
201-
row: 0,
202-
});
196+
layout.add(control, this.self().HPOS.TITLE);
203197
break;
204198
case "subtitle-icon": {
205199
control = new qx.ui.basic.Image().set({
206200
allowGrowX: false,
207201
allowShrinkX: false,
208202
});
209203
layout = this.getChildControl("header");
210-
layout.add(control, {
211-
column: 0,
212-
row: 1,
213-
});
204+
layout.add(control, this.self().HPOS.SUBTITLE_ICON);
214205
break;
215206
}
216207
case "subtitle-text": {
@@ -225,10 +216,7 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
225216
allowGrowY: false
226217
});
227218
layout = this.getChildControl("header");
228-
layout.add(control, {
229-
column: 1,
230-
row: 1,
231-
});
219+
layout.add(control, this.self().HPOS.SUBTITLE_TEXT);
232220
break;
233221
}
234222
case "thumbnail": {
@@ -322,32 +310,6 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
322310
return;
323311
},
324312

325-
__fitThumbnailHeight: function() {
326-
const thumbnailLayout = this.getChildControl("thumbnail");
327-
let maxHeight = this.getHeight() - this.getPaddingTop() - this.getPaddingBottom() - 5;
328-
const checkThis = [
329-
"title",
330-
"body",
331-
"footer",
332-
"tags"
333-
];
334-
const layout = this.getChildControl("main-layout");
335-
// eslint-disable-next-line no-underscore-dangle
336-
layout._getChildren().forEach(child => {
337-
if (checkThis.includes(child.getSubcontrolId()) && child.getBounds()) {
338-
maxHeight -= (child.getBounds().height + this.self().SPACING_IN);
339-
if (child.getSubcontrolId() === "tags") {
340-
maxHeight -= 8;
341-
}
342-
}
343-
});
344-
// maxHeight -= 4; // for Roboto
345-
maxHeight -= 18; // for Manrope
346-
thumbnailLayout.getChildControl("image").setMaxHeight(maxHeight);
347-
thumbnailLayout.setMaxHeight(maxHeight);
348-
thumbnailLayout.recheckSize();
349-
},
350-
351313
/**
352314
* Event handler for the pointer over event.
353315
*/

0 commit comments

Comments
 (0)