Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
455 changes: 227 additions & 228 deletions Control/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Control/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"protobuf/"
],
"dependencies": {
"@aliceo2/web-ui": "2.8.4",
"@aliceo2/web-ui": "2.9.0",
"@grpc/grpc-js": "1.14.0",
"@grpc/proto-loader": "0.8.0",
"google-protobuf": "4.0.0",
Expand Down
46 changes: 10 additions & 36 deletions Control/public/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
*/

// Import frontend framework
import {Observable, WebSocketClient, QueryRouter, Loader, sessionService, RemoteData} from '/js/src/index.js';
import {
Observable, WebSocketClient, QueryRouter, Loader, sessionService, RemoteData, showNativeBrowserNotification
} from '/js/src/index.js';
import {Notification as O2Notification} from '/js/src/index.js';
import Lock from './lock/Lock.js';
import Environment from './environment/Environment.js';
Expand Down Expand Up @@ -153,7 +155,7 @@ export default class Model extends Observable {
if (this.detectors.selected || this.session.role == ROLES.Guest) {
this.handleLocationChange();
}
this.requestBrowserNotificationPermissions()

this.notify();
}

Expand All @@ -170,10 +172,14 @@ export default class Model extends Observable {
const { payload: task } = message;
if (task?.taskId) {
// Notification is for the first task in error from an environment
this.showNativeNotification({
showNativeBrowserNotification({
title: `TASK in ${task.state ?? 'unknown'} state`,
body: `Task ${task.id} in environment ${task.environmentId} is in ${task.state ?? 'unknown'} state`,
url: `?page=environment&id=${task.environmentId}`
icon: '/o2_icon.png',
onclick: (event) => {
event?.preventDefault();
this.router.go(`?page=environment&id=${task.environmentId}`, '_blank');
}
});
}
break;
Expand Down Expand Up @@ -361,36 +367,4 @@ export default class Model extends Observable {
this.notify();
}
}

/**
* Display a browser notification(Notification - Web API)
* @param {String} message
*/
showNativeNotification(message) {
const notification = new Notification(message.title, {body: message.body, icon: '/o2_icon.png'});
notification.onclick = (event) => {
event.preventDefault();
this.router.go(message.url, '_blank');
}
}

/**
* Request notification permission
*/
requestBrowserNotificationPermissions() {
if (this.checkBrowserNotificationPermissions()) {
Notification.requestPermission();
}
}

/**
* Defines policy when user can trigger request for enabling notifications
* This is used to display/hide enable button
* @returns {boolean} True when notifications are not enabled and HTTPS is used
*/
checkBrowserNotificationPermissions() {
return (Notification.permission === 'denied' ||
Notification.permission === 'default') &&
window.location.protocol === "https:";
}
}
13 changes: 8 additions & 5 deletions Control/public/common/appHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* or submit itself to any jurisdiction.
*/

import {h, iconPerson} from '/js/src/index.js';
import {h, iconPerson, areBrowserNotificationsGranted, requestBrowserNotificationPermissions} from '/js/src/index.js';

/**
* Application header (left part): lockpad button and application name
Expand All @@ -39,11 +39,14 @@ const loginButton = (model) => h('.dropdown', {class: model.accountMenuEnabled ?
h('button.btn', {onclick: () => model.toggleAccountMenu()}, iconPerson()),
h('.dropdown-menu', [
h('p.m3.mv2.text-ellipsis', `Welcome ${model.session.name}`, h('sup', model.session.role)),
model.session.personid === 0 // anonymous user has id 0
model.session.personid === 0 // anonymous user has id 0
&& h('p.m3.gray-darker', 'You are connected as anonymous, no authentification needed for this application.'),
model.checkBrowserNotificationPermissions() &&
h('a.menu-item', {onclick: () => {
model.toggleAccountMenu(); model.requestBrowserNotificationPermissions()}
!areBrowserNotificationsGranted()
&& h('a.menu-item', {
onclick: () => {
requestBrowserNotificationPermissions();
model.toggleAccountMenu();
}
}, 'Enable notifications'),
model.session.personid !== 0 &&
h('a.menu-item', {onclick: () => alert(`Not implemented`)}, 'Logout')
Expand Down
Loading
Loading