Skip to content

Commit b857ace

Browse files
authored
🎨 [Frontend] Small screens: Let them go (#6390)
1 parent adac8d0 commit b857ace

File tree

12 files changed

+186
-36
lines changed

12 files changed

+186
-36
lines changed

services/static-webserver/client/source/class/osparc/Application.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,13 @@ qx.Class.define("osparc.Application", {
6363
return;
6464
}
6565

66-
const intlTelInput = osparc.wrapper.IntlTelInput.getInstance();
67-
intlTelInput.init();
66+
// libs
67+
osparc.wrapper.IntlTelInput.getInstance().init();
68+
osparc.wrapper.Three.getInstance().init();
6869

69-
const threejs = osparc.wrapper.Three.getInstance();
70-
threejs.init();
71-
72-
const announcementsTracker = osparc.announcement.Tracker.getInstance();
73-
announcementsTracker.startTracker();
70+
// trackers
71+
osparc.announcement.Tracker.getInstance().startTracker();
72+
osparc.WindowSizeTracker.getInstance().startTracker();
7473

7574
const webSocket = osparc.wrapper.WebSocket.getInstance();
7675
webSocket.addListener("connect", () => osparc.WatchDog.getInstance().setOnline(true));
@@ -467,6 +466,7 @@ qx.Class.define("osparc.Application", {
467466

468467
__loadMainPage: function(studyId = null) {
469468
// logged in
469+
osparc.WindowSizeTracker.getInstance().evaluateTooSmallDialog();
470470
osparc.data.Resources.getOne("profile")
471471
.then(profile => {
472472
if (profile) {
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 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.TooSmallDialog", {
19+
extend: osparc.ui.window.SingletonWindow,
20+
21+
construct: function() {
22+
this.base(arguments, "too-small-logout", this.tr("Window too small"));
23+
24+
this.set({
25+
layout: new qx.ui.layout.VBox(10),
26+
contentPadding: 15,
27+
modal: true,
28+
showMaximize: false,
29+
showMinimize: false,
30+
});
31+
32+
this.__buildLayout();
33+
},
34+
35+
statics: {
36+
openWindow: function() {
37+
const orgsWindow = new osparc.TooSmallDialog();
38+
orgsWindow.center();
39+
orgsWindow.open();
40+
return orgsWindow;
41+
}
42+
},
43+
44+
members: {
45+
__buildLayout: function() {
46+
const message = this.__createMessage();
47+
this.add(message);
48+
49+
// if the user is logged in, let them log out, the user menu might be unreachable
50+
const logoutButton = this.__createLogoutButton();
51+
this.add(logoutButton);
52+
},
53+
54+
__createMessage: function() {
55+
const introText = this.tr("The application can't perform in such a small window.");
56+
const introLabel = new qx.ui.basic.Label(introText);
57+
return introLabel;
58+
},
59+
60+
__createLogoutButton: function() {
61+
const layout = new qx.ui.container.Composite(new qx.ui.layout.HBox().set({
62+
alignX: "right"
63+
}));
64+
65+
const button = new qx.ui.form.Button().set({
66+
allowGrowX: false
67+
});
68+
button.addListener("execute", () => qx.core.Init.getApplication().logout());
69+
layout.add(button);
70+
71+
const authData = osparc.auth.Data.getInstance();
72+
authData.bind("loggedIn", layout, "visibility", {
73+
converter: isLoggedIn => isLoggedIn ? "visible" : "excluded"
74+
});
75+
authData.bind("guest", button, "label", {
76+
converter: isGuest => isGuest ? this.tr("Exit") : this.tr("Log out")
77+
});
78+
79+
return layout;
80+
},
81+
}
82+
});

services/static-webserver/client/source/class/osparc/WindowSizeTracker.js

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,22 @@ qx.Class.define("osparc.WindowSizeTracker", {
4040
},
4141

4242
tooSmall: {
43-
check: [null, "shortText", "longText"], // display short message, long one or none
43+
check: [null, "logout", "shortText", "longText"],
4444
init: null,
4545
nullable: true,
4646
apply: "__applyTooSmall"
4747
}
4848
},
4949

5050
statics: {
51+
WIDTH_LOGOUT_BREAKPOINT: 600,
52+
WIDTH_COMPACT_BREAKPOINT: 1100,
5153
WIDTH_BREAKPOINT: 1180, // - iPad Pro 11" 1194x834 inclusion
5254
HEIGHT_BREAKPOINT: 720, // - iPad Pro 11" 1194x834 inclusion
53-
WIDTH_COMPACT_BREAKPOINT: 1100
5455
},
5556

5657
members: {
58+
__tooSmallDialog: null,
5759
__lastRibbonMessage: null,
5860

5961
startTracker: function() {
@@ -69,8 +71,12 @@ qx.Class.define("osparc.WindowSizeTracker", {
6971

7072
this.setCompactVersion(width < this.self().WIDTH_COMPACT_BREAKPOINT);
7173

72-
if (width < this.self().WIDTH_BREAKPOINT || height < this.self().HEIGHT_BREAKPOINT) {
73-
this.setTooSmall(width < this.self().WIDTH_COMPACT_BREAKPOINT ? "shortText" : "longText");
74+
if (width < this.self().WIDTH_LOGOUT_BREAKPOINT) {
75+
this.setTooSmall("logout");
76+
} else if (width < this.self().WIDTH_COMPACT_BREAKPOINT) {
77+
this.setTooSmall("shortText");
78+
} else if (width < this.self().WIDTH_BREAKPOINT) {
79+
this.setTooSmall("longText");
7480
} else {
7581
this.setTooSmall(null);
7682
}
@@ -89,14 +95,16 @@ qx.Class.define("osparc.WindowSizeTracker", {
8995
}
9096

9197
let notification = null;
92-
if (tooSmall === "shortText") {
98+
if (tooSmall === "logout" || tooSmall === "shortText") {
9399
notification = new osparc.notification.RibbonNotification(null, "smallWindow", true);
94100
} else if (tooSmall === "longText") {
95101
const text = this.__getLongText(true);
96102
notification = new osparc.notification.RibbonNotification(text, "smallWindow", true);
97103
}
98104
osparc.notification.RibbonNotifications.getInstance().addNotification(notification);
99105
this.__lastRibbonMessage = notification;
106+
107+
this.evaluateTooSmallDialog();
100108
},
101109

102110
__getLongText: function() {
@@ -111,6 +119,21 @@ qx.Class.define("osparc.WindowSizeTracker", {
111119
osparc.notification.RibbonNotifications.getInstance().removeNotification(this.__lastRibbonMessage);
112120
this.__lastRibbonMessage = null;
113121
}
122+
},
123+
124+
evaluateTooSmallDialog: function() {
125+
const tooSmall = this.getTooSmall();
126+
if (tooSmall === "logout") {
127+
if (this.__tooSmallDialog) {
128+
this.__tooSmallDialog.center();
129+
this.__tooSmallDialog.open();
130+
} else {
131+
this.__tooSmallDialog = osparc.TooSmallDialog.openWindow();
132+
this.__tooSmallDialog.addListener("close", () => this.__tooSmallDialog = null, this);
133+
}
134+
} else if (this.__tooSmallDialog) {
135+
this.__tooSmallDialog.close();
136+
}
114137
}
115138
}
116139
});

services/static-webserver/client/source/class/osparc/auth/Data.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ qx.Class.define("osparc.auth.Data", {
5858
auth: {
5959
init: null,
6060
nullable: true,
61-
check: "osparc.io.request.authentication.Token"
61+
check: "osparc.io.request.authentication.Token",
62+
apply: "__applyAuth"
6263
},
6364

6465
/**
@@ -104,10 +105,21 @@ qx.Class.define("osparc.auth.Data", {
104105
nullable: true,
105106
check: "Date",
106107
event: "changeExpirationDate"
108+
},
109+
110+
loggedIn: {
111+
check: "Boolean",
112+
nullable: false,
113+
init: false,
114+
event: "changeLoggedIn",
107115
}
108116
},
109117

110118
members: {
119+
__applyAuth: function(auth) {
120+
this.setLoggedIn(auth !== null && auth instanceof osparc.io.request.authentication.Token);
121+
},
122+
111123
__applyRole: function(role) {
112124
if (role && ["user", "tester", "product_owner", "admin"].includes(role)) {
113125
this.setGuest(false);

services/static-webserver/client/source/class/osparc/auth/Manager.js

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,10 @@ qx.Class.define("osparc.auth.Manager", {
2626
extend: qx.core.Object,
2727
type: "singleton",
2828

29-
/*
30-
*****************************************************************************
31-
EVENTS
32-
*****************************************************************************
33-
*/
34-
3529
events: {
3630
"loggedOut": "qx.event.type.Event"
3731
},
3832

39-
40-
/*
41-
*****************************************************************************
42-
MEMBERS
43-
*****************************************************************************
44-
*/
45-
4633
members: {
4734
register: function(userData) {
4835
const params = {
@@ -130,11 +117,7 @@ qx.Class.define("osparc.auth.Manager", {
130117
},
131118

132119
isLoggedIn: function() {
133-
// TODO: how to store this locally?? See http://www.qooxdoo.org/devel/pages/data_binding/stores.html#offline-store
134-
// TODO: check if expired??
135-
// TODO: request server if token is still valid (e.g. expired, etc)
136-
const auth = osparc.auth.Data.getInstance().getAuth();
137-
return auth !== null && auth instanceof osparc.io.request.authentication.Token;
120+
return osparc.auth.Data.getInstance().isLoggedIn();
138121
},
139122

140123
/*

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
170170
},
171171

172172
__reloadFolders: function() {
173+
if (!osparc.auth.Manager.getInstance().isLoggedIn()) {
174+
return;
175+
}
176+
173177
if (osparc.utils.DisabledPlugins.isFoldersEnabled()) {
174178
const folderId = this.getCurrentFolderId();
175179
const workspaceId = this.getCurrentWorkspaceId();
@@ -186,7 +190,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
186190
},
187191

188192
__reloadStudies: function() {
189-
if (this._loadingResourcesBtn.isFetching()) {
193+
if (this._loadingResourcesBtn.isFetching() || !osparc.auth.Manager.getInstance().isLoggedIn()) {
190194
return;
191195
}
192196
const workspaceId = this.getCurrentWorkspaceId();

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,39 @@ qx.Class.define("osparc.data.model.Study", {
443443
});
444444
},
445445

446+
__getFoldersPath: function(childId, foldersPath = []) {
447+
foldersPath.unshift(childId);
448+
const childFolder = osparc.store.Folders.getInstance().getFolder(childId);
449+
if (childFolder) {
450+
const parentFolder = osparc.store.Folders.getInstance().getFolder(childFolder.getParentFolderId());
451+
if (parentFolder) {
452+
this.__getFoldersPath(parentFolder.getFolderId(), foldersPath);
453+
}
454+
}
455+
return foldersPath;
456+
},
457+
458+
getLocationString: function() {
459+
const location = [];
460+
461+
if (this.getWorkspaceId()) {
462+
const workspace = osparc.store.Workspaces.getInstance().getWorkspace(this.getWorkspaceId());
463+
location.push(workspace.getName());
464+
} else {
465+
location.push(qx.locale.Manager.tr("My Workspace"));
466+
}
467+
468+
const foldersPathIds = this.__getFoldersPath(this.getFolderId());
469+
foldersPathIds.forEach(folderId => {
470+
const folder = osparc.store.Folders.getInstance().getFolder(folderId);
471+
if (folder) {
472+
location.push(folder.getName());
473+
}
474+
});
475+
476+
return location.join(" / ");
477+
},
478+
446479
// Used for updating some node data through the "nodeUpdated" websocket event
447480
nodeUpdated: function(nodeUpdatedData) {
448481
const studyId = nodeUpdatedData["project_id"];

services/static-webserver/client/source/class/osparc/desktop/MainPage.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ qx.Class.define("osparc.desktop.MainPage", {
5454
this._add(navBar);
5555

5656
// Some resources request before building the main stack
57-
osparc.WindowSizeTracker.getInstance().startTracker();
5857
osparc.MaintenanceTracker.getInstance().startTracker();
5958
osparc.CookieExpirationTracker.getInstance().startTracker();
6059
osparc.NewUITracker.getInstance().startTracker();

services/static-webserver/client/source/class/osparc/info/StudyLarge.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ qx.Class.define("osparc.info.StudyLarge", {
189189
};
190190
}
191191

192+
if (osparc.utils.DisabledPlugins.isFoldersEnabled() && !this.__isTemplate) {
193+
const pathLabel = new qx.ui.basic.Label();
194+
pathLabel.setValue(this.getStudy().getLocationString());
195+
extraInfo["LOCATION"] = {
196+
label: this.tr("Location:"),
197+
view: pathLabel,
198+
action: null
199+
};
200+
}
201+
192202
return extraInfo;
193203
},
194204

services/static-webserver/client/source/class/osparc/info/StudyUtils.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,12 @@ qx.Class.define("osparc.info.StudyUtils", {
299299
inline: true,
300300
column: 0,
301301
row: 6,
302-
}
302+
},
303+
LOCATION: {
304+
inline: true,
305+
column: 0,
306+
row: 7,
307+
},
303308
};
304309

305310
const grid = new qx.ui.layout.Grid(15, 5);

0 commit comments

Comments
 (0)