Skip to content

Commit 063677b

Browse files
authored
🎨 [Frontend] Enh: Support multiple announcements (#6729)
1 parent 3d01610 commit 063677b

File tree

4 files changed

+106
-84
lines changed

4 files changed

+106
-84
lines changed

services/static-webserver/client/source/class/osparc/announcement/AnnouncementUIFactory.js

Lines changed: 82 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,8 @@ qx.Class.define("osparc.announcement.AnnouncementUIFactory", {
1919
extend: qx.core.Object,
2020
type: "singleton",
2121

22-
properties: {
23-
announcement: {
24-
check: "osparc.announcement.Announcement",
25-
init: null,
26-
nullable: false,
27-
event: "changeAnnouncement",
28-
apply: "__applyAnnouncement"
29-
}
22+
events: {
23+
"changeAnnouncements": "qx.event.type.Event",
3024
},
3125

3226
statics: {
@@ -63,14 +57,9 @@ qx.Class.define("osparc.announcement.AnnouncementUIFactory", {
6357
}
6458

6559
return loginAnnouncement;
66-
}
67-
},
68-
69-
members: {
70-
__ribbonAnnouncement: null,
60+
},
7161

72-
__isValid: function(widgetType) {
73-
const announcement = this.getAnnouncement();
62+
isValid: function(announcement, widgetType) {
7463
if (announcement) {
7564
const now = new Date();
7665
const validPeriod = now > announcement.getStart() && now < announcement.getEnd();
@@ -80,59 +69,105 @@ qx.Class.define("osparc.announcement.AnnouncementUIFactory", {
8069
}
8170
return false;
8271
},
72+
},
8373

84-
__applyAnnouncement: function() {
85-
if (this.__ribbonAnnouncement) {
86-
osparc.notification.RibbonNotifications.getInstance().removeNotification(this.__ribbonAnnouncement);
87-
this.__ribbonAnnouncement = null;
88-
}
89-
if (this.__hasRibbonAnnouncement()) {
90-
this.__addRibbonAnnouncement();
91-
}
74+
members: {
75+
__announcements: null,
76+
__ribbonAnnouncements: null,
77+
78+
setAnnouncementsData: function(announcementsData) {
79+
this.__announcements = [];
80+
announcementsData.forEach(announcementData => {
81+
const announcement = new osparc.announcement.Announcement(announcementData);
82+
this.__announcements.push(announcement);
83+
});
84+
this.fireEvent("changeAnnouncements");
85+
86+
this.__addToRibbon();
9287
},
9388

94-
hasLoginAnnouncement: function() {
95-
return this.__isValid("login");
89+
__addToRibbon: function() {
90+
if (this.__ribbonAnnouncements && this.__ribbonAnnouncements.length) {
91+
this.__ribbonAnnouncements.forEach(ribbonAnnouncement => {
92+
osparc.notification.RibbonNotifications.getInstance().removeNotification(ribbonAnnouncement);
93+
});
94+
}
95+
this.__ribbonAnnouncements = [];
96+
this.__announcements.forEach(announcement => {
97+
if (this.self().isValid(announcement, "ribbon")) {
98+
const ribbonAnnouncement = this.__addRibbonAnnouncement(announcement);
99+
if (ribbonAnnouncement) {
100+
this.__ribbonAnnouncements.push(ribbonAnnouncement);
101+
}
102+
}
103+
});
96104
},
97105

98-
__hasRibbonAnnouncement: function() {
99-
return this.__isValid("ribbon");
106+
hasLoginAnnouncement: function() {
107+
return this.__announcements && this.__announcements.some(announcement => this.self().isValid(announcement, "login"));
100108
},
101109

102110
hasUserMenuAnnouncement: function() {
103-
return this.__isValid("user-menu") && this.getAnnouncement().getLink();
111+
return this.__announcements && this.__announcements.some(announcement => this.self().isValid(announcement, "ribbon") && announcement.getLink());
104112
},
105113

106-
createLoginAnnouncement: function() {
107-
const announcement = this.getAnnouncement();
108-
const loginAnnouncement = this.self().createLoginAnnouncement(announcement.getTitle(), announcement.getDescription());
109-
return loginAnnouncement;
114+
createLoginAnnouncements: function() {
115+
const loginAnnouncements = [];
116+
this.__announcements.forEach(announcement => {
117+
if (this.self().isValid(announcement, "login")) {
118+
const loginAnnouncement = this.self().createLoginAnnouncement(announcement.getTitle(), announcement.getDescription())
119+
loginAnnouncement.setWidth(osparc.auth.core.BaseAuthPage.FORM_WIDTH-5); // show 1-2 pixel of the nearby announcement
120+
loginAnnouncements.push(loginAnnouncement);
121+
}
122+
});
123+
if (loginAnnouncements.length === 1) {
124+
return loginAnnouncements[0];
125+
}
126+
const slideBar = new osparc.widget.SlideBar().set({
127+
allowGrowX: true,
128+
});
129+
slideBar.getChildControl("button-backward").set({
130+
backgroundColor: "transparent"
131+
});
132+
slideBar.getChildControl("button-forward").set({
133+
backgroundColor: "transparent"
134+
});
135+
loginAnnouncements.forEach(loginAnnouncement => slideBar.add(loginAnnouncement));
136+
return slideBar;
110137
},
111138

112-
__addRibbonAnnouncement: function() {
113-
const announcement = this.getAnnouncement();
114-
139+
__addRibbonAnnouncement: function(announcement) {
115140
if (osparc.utils.Utils.localCache.isDontShowAnnouncement(announcement.getId())) {
116-
return;
141+
return null;
117142
}
118143

119-
let text = announcement.getTitle();
144+
let text = "";
145+
if (announcement.getTitle()) {
146+
text += announcement.getTitle();
147+
}
148+
if (announcement.getTitle() && announcement.getDescription()) {
149+
text += ": ";
150+
}
120151
if (announcement.getDescription()) {
121-
text += ": " + announcement.getDescription();
152+
text += announcement.getDescription();
122153
}
123-
124-
const ribbonAnnouncement = this.__ribbonAnnouncement = new osparc.notification.RibbonNotification(text, "announcement", true);
154+
const ribbonAnnouncement = new osparc.notification.RibbonNotification(text, "announcement", true);
125155
ribbonAnnouncement.announcementId = announcement.getId();
126156
osparc.notification.RibbonNotifications.getInstance().addNotification(ribbonAnnouncement);
157+
return ribbonAnnouncement;
127158
},
128159

129-
createUserMenuAnnouncement: function() {
130-
const announcement = this.getAnnouncement();
131-
132-
const link = announcement.getLink();
133-
const userMenuAnnouncement = new qx.ui.menu.Button(announcement.getTitle() + "...");
134-
userMenuAnnouncement.addListener("execute", () => window.open(link));
135-
return userMenuAnnouncement;
160+
createUserMenuAnnouncements: function() {
161+
const userMenuAnnouncements = [];
162+
this.__announcements.forEach(announcement => {
163+
if (this.self().isValid(announcement, "user-menu")) {
164+
const link = announcement.getLink();
165+
const userMenuAnnouncement = new qx.ui.menu.Button(announcement.getTitle() + "...");
166+
userMenuAnnouncement.addListener("execute", () => window.open(link));
167+
userMenuAnnouncements.push(userMenuAnnouncement);
168+
}
169+
});
170+
return userMenuAnnouncements;
136171
}
137172
}
138173
});

services/static-webserver/client/source/class/osparc/announcement/Tracker.js

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,13 @@ qx.Class.define("osparc.announcement.Tracker", {
2525

2626
members: {
2727
__checkInterval: null,
28-
__announcements: null,
2928

3029
checkAnnouncements: async function() {
31-
return new Promise(resolve => {
32-
osparc.data.Resources.get("announcements")
33-
.then(announcements => {
34-
if (announcements && announcements.length) {
35-
this.__setAnnouncements(announcements);
36-
} else {
37-
this.__setAnnouncements(null);
38-
}
39-
resolve();
40-
})
41-
.catch(err => console.error(err));
42-
});
30+
osparc.data.Resources.get("announcements")
31+
.then(announcements => {
32+
osparc.announcement.AnnouncementUIFactory.getInstance().setAnnouncementsData((announcements && announcements.length) ? announcements : []);
33+
})
34+
.catch(err => console.error(err));
4335
},
4436

4537
startTracker: function() {
@@ -52,15 +44,5 @@ qx.Class.define("osparc.announcement.Tracker", {
5244
clearInterval(this.__checkInterval);
5345
}
5446
},
55-
56-
__setAnnouncements: function(announcementsData) {
57-
this.__announcements = {};
58-
if (announcementsData) {
59-
announcementsData.forEach(announcementData => {
60-
const announcement = new osparc.announcement.Announcement(announcementData);
61-
osparc.announcement.AnnouncementUIFactory.getInstance().setAnnouncement(announcement);
62-
});
63-
}
64-
}
6547
}
6648
});

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,22 @@ qx.Class.define("osparc.auth.ui.LoginView", {
3737

3838
members: {
3939
__loginBtn: null,
40+
__loginAnnouncements: null,
4041

4142
// overrides base
4243
_buildPage: function() {
4344
const announcementUIFactory = osparc.announcement.AnnouncementUIFactory.getInstance();
45+
const addAnnouncements = () => {
46+
if (this.__loginAnnouncements) {
47+
this.remove(this.__loginAnnouncements);
48+
}
49+
this.__loginAnnouncements = announcementUIFactory.createLoginAnnouncements();
50+
this.addAt(this.__loginAnnouncements, 0);
51+
};
4452
if (announcementUIFactory.hasLoginAnnouncement()) {
45-
this.addAt(announcementUIFactory.createLoginAnnouncement(), 0);
53+
addAnnouncements();
4654
} else {
47-
announcementUIFactory.addListenerOnce("changeAnnouncement", e => {
48-
if (announcementUIFactory.hasLoginAnnouncement()) {
49-
this.addAt(announcementUIFactory.createLoginAnnouncement(), 0);
50-
}
51-
});
55+
announcementUIFactory.addListenerOnce("changeAnnouncements", () => addAnnouncements());
5256
}
5357

5458
// form

services/static-webserver/client/source/class/osparc/navigation/UserMenu.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,7 @@ qx.Class.define("osparc.navigation.UserMenu", {
177177
this.getChildControl("theme-switcher");
178178
this.addSeparator();
179179

180-
const announcementUIFactory = osparc.announcement.AnnouncementUIFactory.getInstance();
181-
if (announcementUIFactory.hasUserMenuAnnouncement()) {
182-
this.add(announcementUIFactory.createUserMenuAnnouncement());
183-
}
180+
this.__addAnnouncements();
184181
this.getChildControl("about");
185182
if (osparc.product.Utils.showAboutProduct()) {
186183
this.getChildControl("about-product");
@@ -196,6 +193,13 @@ qx.Class.define("osparc.navigation.UserMenu", {
196193
osparc.utils.Utils.prettifyMenu(this);
197194
},
198195

196+
__addAnnouncements: function() {
197+
const announcementUIFactory = osparc.announcement.AnnouncementUIFactory.getInstance();
198+
if (announcementUIFactory.hasUserMenuAnnouncement()) {
199+
announcementUIFactory.createUserMenuAnnouncements().forEach(announcement => this.add(announcement));
200+
}
201+
},
202+
199203
populateMenuCompact: function() {
200204
this.removeAll();
201205
const authData = osparc.auth.Data.getInstance();
@@ -233,10 +237,7 @@ qx.Class.define("osparc.navigation.UserMenu", {
233237
this.getChildControl("theme-switcher");
234238
this.addSeparator();
235239

236-
const announcementUIFactory = osparc.announcement.AnnouncementUIFactory.getInstance();
237-
if (announcementUIFactory.hasUserMenuAnnouncement()) {
238-
this.add(announcementUIFactory.createUserMenuAnnouncement());
239-
}
240+
this.__addAnnouncements();
240241
this.getChildControl("about");
241242
if (!osparc.product.Utils.isProduct("osparc")) {
242243
this.getChildControl("about-product");

0 commit comments

Comments
 (0)