Skip to content

Commit 5f92eca

Browse files
authored
✨ [Frontend] Read product.ui from backend (#7220)
1 parent 510d846 commit 5f92eca

File tree

13 files changed

+319
-284
lines changed

13 files changed

+319
-284
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Makefile @pcrespov @sanderegg
3636
/services/payments/ @pcrespov @matusdrobuliak66
3737
/services/resource-usage-tracker/ @matusdrobuliak66
3838
/services/static-webserver/ @GitHK
39-
/services/static-webserver/client/ @jsaq007 @odeimaiz @ignapas
39+
/services/static-webserver/client/ @odeimaiz
4040
/services/storage/ @sanderegg
4141
/services/web/server/ @pcrespov @sanderegg @GitHK @matusdrobuliak66
4242
/tests/e2e-frontend/ @odeimaiz

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
4848
SPACING_IN: 5,
4949
SPACING: 15,
5050
ICON_SIZE: 32,
51-
// TITLE_MAX_HEIGHT: 34, // two lines in Roboto
52-
TITLE_MAX_HEIGHT: 40, // two lines in Manrope
5351
THUMBNAIL_SIZE: 50,
5452
POS: {
5553
TITLE: {
@@ -119,7 +117,6 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
119117
grid.setSpacing(this.self().SPACING_IN);
120118
grid.setRowFlex(2, 1);
121119
grid.setColumnFlex(0, 1);
122-
grid.setRowMaxHeight(0, this.self().TITLE_MAX_HEIGHT);
123120

124121
control = new qx.ui.container.Composite().set({
125122
maxWidth: this.self().ITEM_WIDTH,
@@ -205,7 +202,6 @@ qx.Class.define("osparc.dashboard.GridButtonBase", {
205202
font: "text-14",
206203
padding: this.self().TITLE_PADDING,
207204
maxWidth: this.self().ITEM_WIDTH,
208-
maxHeight: this.self().TITLE_MAX_HEIGHT,
209205
});
210206
layout = this.getChildControl("header");
211207
layout.addAt(control, 0, {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
9393
break;
9494
case "menu-button":
9595
this.getChildControl("title").set({
96-
maxWidth: osparc.dashboard.GridButtonBase.ITEM_WIDTH - osparc.dashboard.GridButtonBase.ICON_SIZE - this.self().MENU_BTN_DIMENSIONS,
96+
maxWidth: osparc.dashboard.GridButtonBase.ITEM_WIDTH - osparc.dashboard.GridButtonBase.ICON_SIZE - this.self().MENU_BTN_DIMENSIONS - 2,
9797
});
9898
control = new qx.ui.form.MenuButton().set({
9999
appearance: "form-button-outlined",

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

Lines changed: 75 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,45 @@
1515
1616
************************************************************************ */
1717

18+
/**
19+
Supports:
20+
"categories": [{
21+
"id": "string", // required
22+
"title": "string", // required
23+
"description": "string" // optional
24+
}],
25+
"resources": [{
26+
"resourceType": "study", // it will start an empty study
27+
"title": "string", // required
28+
"icon": "fontAwesome inner link | url", // optional
29+
"newStudyLabel": "string", // optional
30+
"idToWidget": "string" // optional
31+
}, {
32+
"resourceType": "template", // it will create a study from the template
33+
"expectedTemplateLabel": "string", // required
34+
"title": "string", // required
35+
"icon": "fontAwesome inner link | url", // optional
36+
"newStudyLabel": "string", // optional
37+
"category": "categories.id", // optional
38+
"idToWidget": "string" // optional
39+
}, {
40+
"resourceType": "service", // it will create a study from the service
41+
"expectedKey": "service.key", // required
42+
"title": "string", // required
43+
"icon": "fontAwesome inner link | url", // optional
44+
"newStudyLabel": "string", // optional
45+
"category": "categories.id", // optional
46+
"idToWidget": "string" // optional
47+
}, {
48+
"showDisabled": true, // it will show a disabled button on the defined item
49+
"title": "string", // required
50+
"icon": "fontAwesome inner link | url", // optional
51+
"reason": "string", // optional
52+
"newStudyLabel": "string", // optional
53+
"category": "categories.id", // optional
54+
"idToWidget": "string" // optional
55+
}]
56+
*/
1857
qx.Class.define("osparc.dashboard.NewPlusMenu", {
1958
extend: qx.ui.menu.Menu,
2059

@@ -51,6 +90,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
5190
"replace_me_product_name",
5291
osparc.store.StaticInfo.getInstance().getDisplayName()
5392
);
93+
title = title.replace(/<br>/g, " ");
5494
const menuButton = new qx.ui.menu.Button().set({
5595
icon: icon || null,
5696
label: title,
@@ -66,7 +106,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
66106
});
67107
if (infoText) {
68108
infoText = osparc.utils.Utils.replaceTokens(
69-
title,
109+
infoText,
70110
"replace_me_product_name",
71111
osparc.store.StaticInfo.getInstance().getDisplayName()
72112
);
@@ -116,27 +156,24 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
116156
},
117157

118158
__addNewStudyItems: async function() {
119-
await Promise.all([
120-
osparc.store.Products.getInstance().getNewStudyConfig(),
121-
osparc.data.Resources.get("templates")
122-
]).then(values => {
123-
const newStudiesData = values[0];
124-
const templates = values[1];
125-
if (newStudiesData["categories"]) {
126-
this.__addCategories(newStudiesData["categories"]);
127-
}
128-
newStudiesData["resources"].forEach(newStudyData => {
129-
if (newStudyData["showDisabled"]) {
130-
this.__addDisabledButton(newStudyData);
131-
} else if (newStudyData["resourceType"] === "study") {
132-
this.__addEmptyStudyButton(newStudyData);
133-
} else if (newStudyData["resourceType"] === "template") {
134-
this.__addFromTemplateButton(newStudyData, templates);
135-
} else if (newStudyData["resourceType"] === "service") {
136-
this.__addFromServiceButton(newStudyData);
159+
await osparc.data.Resources.get("templates")
160+
.then(templates => {
161+
const plusButtonConfig = osparc.store.Products.getInstance().getPlusButtonUiConfig();
162+
if (plusButtonConfig["categories"]) {
163+
this.__addCategories(plusButtonConfig["categories"]);
137164
}
165+
plusButtonConfig["resources"].forEach(newStudyData => {
166+
if (newStudyData["showDisabled"]) {
167+
this.__addDisabledButton(newStudyData);
168+
} else if (newStudyData["resourceType"] === "study") {
169+
this.__addEmptyStudyButton(newStudyData);
170+
} else if (newStudyData["resourceType"] === "template") {
171+
this.__addFromTemplateButton(newStudyData, templates);
172+
} else if (newStudyData["resourceType"] === "service") {
173+
this.__addFromServiceButton(newStudyData);
174+
}
175+
});
138176
});
139-
});
140177
},
141178

142179
__getLastIdxFromCategory: function(categoryId) {
@@ -165,7 +202,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
165202
__addIcon: function(menuButton, resourceInfo, resourceMetadata) {
166203
let source = null;
167204
if (resourceInfo && "icon" in resourceInfo) {
168-
// first the one set in the new_studies
205+
// first the one set in the ui_config
169206
source = resourceInfo["icon"];
170207
} else if (resourceMetadata && "thumbnail" in resourceMetadata) {
171208
// second the one from the resource
@@ -200,55 +237,55 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
200237
},
201238

202239
__addDisabledButton: function(newStudyData) {
203-
const menuButton = this.self().createMenuButton(null, newStudyData.title, newStudyData.reason);
204-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData.idToWidget);
240+
const menuButton = this.self().createMenuButton(null, newStudyData["title"], newStudyData["reason"]);
241+
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
205242
menuButton.setEnabled(false);
206243

207244
this.__addIcon(menuButton, newStudyData);
208-
this.__addFromResourceButton(menuButton, newStudyData.category);
245+
this.__addFromResourceButton(menuButton, newStudyData["category"]);
209246
},
210247

211248
__addEmptyStudyButton: function(newStudyData) {
212-
const menuButton = this.self().createMenuButton(null, newStudyData.title);
213-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData.idToWidget);
249+
const menuButton = this.self().createMenuButton(null, newStudyData["title"]);
250+
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
214251

215252
menuButton.addListener("tap", () => {
216253
this.fireDataEvent("newEmptyStudyClicked", {
217-
newStudyLabel: newStudyData.newStudyLabel,
254+
newStudyLabel: newStudyData["newStudyLabel"],
218255
});
219256
});
220257

221258
this.__addIcon(menuButton, newStudyData);
222-
this.__addFromResourceButton(menuButton, newStudyData.category);
259+
this.__addFromResourceButton(menuButton, newStudyData["category"]);
223260
},
224261

225262
__addFromTemplateButton: function(newStudyData, templates) {
226-
const menuButton = this.self().createMenuButton(null, newStudyData.title);
227-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData.idToWidget);
263+
const menuButton = this.self().createMenuButton(null, newStudyData["title"]);
264+
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
228265
// disable it until found in templates store
229266
menuButton.setEnabled(false);
230267

231-
let templateMetadata = templates.find(t => t.name === newStudyData.expectedTemplateLabel);
268+
let templateMetadata = templates.find(t => t.name === newStudyData["expectedTemplateLabel"]);
232269
if (templateMetadata) {
233270
menuButton.setEnabled(true);
234271
menuButton.addListener("tap", () => {
235272
this.fireDataEvent("newStudyFromTemplateClicked", {
236273
templateData: templateMetadata,
237-
newStudyLabel: newStudyData.newStudyLabel,
274+
newStudyLabel: newStudyData["newStudyLabel"],
238275
});
239276
});
240277
this.__addIcon(menuButton, newStudyData, templateMetadata);
241-
this.__addFromResourceButton(menuButton, newStudyData.category);
278+
this.__addFromResourceButton(menuButton, newStudyData["category"]);
242279
}
243280
},
244281

245282
__addFromServiceButton: function(newStudyData) {
246-
const menuButton = this.self().createMenuButton(null, newStudyData.title);
247-
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData.idToWidget);
283+
const menuButton = this.self().createMenuButton(null, newStudyData["title"]);
284+
osparc.utils.Utils.setIdToWidget(menuButton, newStudyData["idToWidget"]);
248285
// disable it until found in services store
249286
menuButton.setEnabled(false);
250287

251-
const key = newStudyData.expectedKey;
288+
const key = newStudyData["expectedKey"];
252289
// Include deprecated versions, they should all be updatable to a non deprecated version
253290
const versions = osparc.service.Utils.getVersions(key, false);
254291
if (versions.length && newStudyData) {
@@ -265,7 +302,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
265302
menuButton.addListener("tap", () => {
266303
this.fireDataEvent("newStudyFromServiceClicked", {
267304
serviceMetadata: latestMetadata,
268-
newStudyLabel: newStudyData.newStudyLabel,
305+
newStudyLabel: newStudyData["newStudyLabel"],
269306
});
270307
});
271308

@@ -283,7 +320,7 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", {
283320
menuButton._add(infoButton, {column: 2});
284321

285322
this.__addIcon(menuButton, newStudyData, latestMetadata);
286-
this.__addFromResourceButton(menuButton, newStudyData.category);
323+
this.__addFromResourceButton(menuButton, newStudyData["category"]);
287324
})
288325
}
289326
},

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,10 @@ qx.Class.define("osparc.dashboard.NewStudies", {
182182
const title = templateInfo.title;
183183
const desc = templateInfo.description;
184184
const newPlanButton = new osparc.dashboard.GridButtonNew(title, desc);
185-
newPlanButton.setCardKey(templateInfo.idToWidget);
186-
osparc.utils.Utils.setIdToWidget(newPlanButton, templateInfo.idToWidget);
185+
if (templateInfo["idToWidget"]) {
186+
newPlanButton.setCardKey(templateInfo["idToWidget"]);
187+
osparc.utils.Utils.setIdToWidget(newPlanButton, templateInfo["idToWidget"]);
188+
}
187189
newPlanButton.addListener("tap", () => newStudyClicked());
188190
return newPlanButton;
189191
},

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

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
1616
************************************************************************ */
1717

18-
/**
19-
* @asset(osparc/new_studies.json")
20-
*/
21-
2218
/**
2319
* Widget that shows lists user's studies.
2420
*
@@ -979,39 +975,36 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
979975
this._resourcesContainer.addNonResourceCard(newPlansBtn);
980976
newPlansBtn.setEnabled(false);
981977

982-
osparc.utils.Utils.fetchJSON("/resource/osparc/new_studies.json")
983-
.then(newStudiesData => {
984-
const product = osparc.product.Utils.getProductName()
985-
if (product in newStudiesData) {
986-
newPlansBtn.setEnabled(true);
987-
988-
newPlansBtn.addListener("tap", () => {
989-
osparc.data.Resources.get("templates")
990-
.then(templates => {
991-
if (templates) {
992-
const newStudies = new osparc.dashboard.NewStudies(newStudiesData[product]);
993-
newStudies.addListener("templatesLoaded", () => {
994-
newStudies.setGroupBy("category");
995-
const winTitle = this.tr("New Plan");
996-
const win = osparc.ui.window.Window.popUpInWindow(newStudies, winTitle, osparc.dashboard.NewStudies.WIDTH+40, 300).set({
997-
clickAwayClose: false,
998-
resizable: true
999-
});
1000-
newStudies.addListener("newStudyClicked", e => {
1001-
win.close();
1002-
const templateInfo = e.getData();
1003-
const templateData = templates.find(t => t.name === templateInfo.expectedTemplateLabel);
1004-
if (templateData) {
1005-
this.__newPlanBtnClicked(templateData, templateInfo.newStudyLabel);
1006-
}
1007-
});
1008-
osparc.utils.Utils.setIdToWidget(win, "newStudiesWindow");
1009-
});
1010-
}
978+
const newStudiesData = osparc.store.Products.getInstance().getNewStudiesUiConfig();
979+
if (newStudiesData) {
980+
newPlansBtn.setEnabled(true);
981+
982+
newPlansBtn.addListener("tap", () => {
983+
osparc.data.Resources.get("templates")
984+
.then(templates => {
985+
if (templates) {
986+
const newStudies = new osparc.dashboard.NewStudies(newStudiesData);
987+
newStudies.addListener("templatesLoaded", () => {
988+
newStudies.setGroupBy("category");
989+
const winTitle = this.tr("New Plan");
990+
const win = osparc.ui.window.Window.popUpInWindow(newStudies, winTitle, osparc.dashboard.NewStudies.WIDTH+40, 300).set({
991+
clickAwayClose: false,
992+
resizable: true
993+
});
994+
newStudies.addListener("newStudyClicked", e => {
995+
win.close();
996+
const templateInfo = e.getData();
997+
const templateData = templates.find(t => t.name === templateInfo.expectedTemplateLabel);
998+
if (templateData) {
999+
this.__newPlanBtnClicked(templateData, templateInfo.newStudyLabel);
1000+
}
1001+
});
1002+
osparc.utils.Utils.setIdToWidget(win, "newStudiesWindow");
10111003
});
1004+
}
10121005
});
1013-
}
10141006
});
1007+
}
10151008
},
10161009

10171010
// Used in S4L products
@@ -1033,7 +1026,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
10331026
const mode = this._resourcesContainer.getMode();
10341027
const newStudyFromServiceButton = (mode === "grid") ? new osparc.dashboard.GridButtonNew(title, desc) : new osparc.dashboard.ListButtonNew(title, desc);
10351028
newStudyFromServiceButton.setCardKey("new-"+key);
1036-
osparc.utils.Utils.setIdToWidget(newStudyFromServiceButton, newButtonInfo.idToWidget);
1029+
if (newButtonInfo["idToWidget"]) {
1030+
osparc.utils.Utils.setIdToWidget(newStudyFromServiceButton, newButtonInfo["idToWidget"]);
1031+
}
10371032
newStudyFromServiceButton.addListener("tap", () => this.__newStudyFromServiceBtnClicked(latestMetadata["key"], latestMetadata["version"], newButtonInfo.newStudyLabel));
10381033
this._resourcesContainer.addNonResourceCard(newStudyFromServiceButton);
10391034
})
@@ -1042,16 +1037,13 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
10421037

10431038
__addPlusButtonsFromServices: function() {
10441039
// add new plus buttons if key services exists
1045-
osparc.utils.Utils.fetchJSON("/resource/osparc/new_studies.json")
1046-
.then(newStudiesData => {
1047-
const product = osparc.product.Utils.getProductName()
1048-
if (product in newStudiesData) {
1049-
const newButtonsInfo = newStudiesData[product].resources;
1050-
newButtonsInfo.forEach(newButtonInfo => {
1051-
this.__addNewStudyFromServiceButtons(newButtonInfo.expectedKey, newButtonInfo);
1052-
});
1053-
}
1040+
const newStudiesData = osparc.store.Products.getInstance().getNewStudiesUiConfig();
1041+
if (newStudiesData) {
1042+
const newButtonsInfo = newStudiesData["resources"];
1043+
newButtonsInfo.forEach(newButtonInfo => {
1044+
this.__addNewStudyFromServiceButtons(newButtonInfo.expectedKey, newButtonInfo);
10541045
});
1046+
}
10551047
},
10561048

10571049
// LAYOUT //

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,11 @@ qx.Class.define("osparc.data.Resources", {
981981
updateEmailTemplate: {
982982
method: "PUT",
983983
url: statics.API + "/products/{productName}/templates/{templateId}"
984-
}
984+
},
985+
getUiConfig: {
986+
method: "GET",
987+
url: statics.API + "/products/current/ui"
988+
},
985989
}
986990
},
987991
"invitations": {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ qx.Class.define("osparc.desktop.MainPage", {
6767
}
6868
preloadPromises.push(store.getAllClassifiers(true));
6969
preloadPromises.push(osparc.store.Tags.getInstance().fetchTags());
70+
preloadPromises.push(osparc.store.Products.getInstance().fetchUiConfig());
7071
Promise.all(preloadPromises)
7172
.then(() => {
7273
const mainStack = this.__createMainStack();

0 commit comments

Comments
 (0)