Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.
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
7 changes: 4 additions & 3 deletions app/config/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
* or submit itself to any jurisdiction.
*/

const { roles, detectors, pageNames, filterTypes, filterInputTypes, fieldNames, quality, mapping } = require('./rct-data');
const { roles, detectors, pageNames, filterTypes, filterInputTypes, fieldNames, quality, mapping, dataAccess } = require('./rct-data');
const { bookkeeping } = require('./outerServices');

module.exports = { // Properties that will be provided to frontend in the public folder
dataAccess,
messageTimeout: 200,
outerServices: { bookkeeping },
filterTypes: filterTypes,
filterInputTypes: filterInputTypes,
Expand All @@ -35,7 +37,6 @@ module.exports = { // Properties that will be provided to frontend in the public
login: 'post',
logout: 'post',
rctData: 'get',
date: 'get',
insertData: 'post',
authControl: 'get',
},
Expand All @@ -51,7 +52,7 @@ module.exports = { // Properties that will be provided to frontend in the public
rowsOnSite: 50,
},

dataRespondFields: {
dataResponseFields: {
totalRowsCount: 'totalRowsCount',
rows: 'rows',
fields: 'fields',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@
* or submit itself to any jurisdiction.
*/

.ehevi .sort-down-20.selected {
background-color: var(--color-primary) !important;
border-radius: 10px;
}
const states = require('./states.js');

.ehevi .sort-up-20.selected {
background-color: var(--color-primary) !important;
border-radius: 10px;
}
module.exports = {
states: states,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,11 @@
* or submit itself to any jurisdiction.
*/

.ehevi .input-label {
margin: 0px;
padding: 0px;
margin-bottom: 4px;
font-size: 14px;
font-weight: bold;
}
const states = {
default: 'default',
serviceUnavailable: 'serviceUnavailable',
sessionError: 'sessionError',
dataAccess: 'dataAccess',
};

.ehevi .icon-input {
width: 100%;
margin-top: 0px;
padding-top: 0px;
height: 50px;
}
module.exports = states;
2 changes: 2 additions & 0 deletions app/config/rct-data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ const physicalParticlesData = require('./physicalParticlesData.js');
const healthcheckQueries = require('./healthcheckQueries.js');
const quality = require('./quality');
const mapping = require('./mapping');
const dataAccess = require('./dataAccess');

module.exports = {
dataAccess,
pageNames,
viewTypes,
mapping,
Expand Down
2 changes: 1 addition & 1 deletion app/lib/database/DatabaseService.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const config = require('./../config/configProvider.js');
const {distinct} = require('../utils')

const DRP = config.public.dataReqParams;
const DRF = config.public.dataRespondFields;
const DRF = config.public.dataResponseFields;

/**
* This class handle communication with postgres database using 'pg' package
Expand Down
66 changes: 17 additions & 49 deletions app/public/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@

import { Observable, sessionService, QueryRouter, Loader } from '/js/src/index.js';
import DataAccessModel from './model/DataAccessModel.js';
import ServiceUnavailableModel from './model/ServiceUnavailableModel.js';
import { RCT } from './config.js';
import Flags from './views/flags/Flags.js';
import Detectors from './views/detectors/Detectors.js';
import Runs from './views/runs/Runs.js';
const { roles } = RCT;
const { roles, dataAccess } = RCT;

export default class Model extends Observable {
constructor() {
Expand All @@ -35,9 +34,6 @@ export default class Model extends Observable {

this.loader = new Loader();

this.mode = null;
this.submodels = {};

this.runs = new Runs(this);
this.runs.bubbleTo(this);

Expand All @@ -47,26 +43,29 @@ export default class Model extends Observable {
this.detectors = new Detectors(this);
this.detectors.bubbleTo(this);

this.logginEndpoint = '/api/login/';
this.dataAccess = new DataAccessModel(this);
this.dataAccess.bubbleTo(this);
this.dataAccess.setState(dataAccess.states.default);

this.loginEndpoint = `/api${RCT.endpoints.login}`;
this.login('physicist');
}

async login(username) {
this.mode = null;
this.dataAccess.setState(dataAccess.states.default);
this.notify();
const { status, result, ok } = await this.postLoginPasses(username);
this._tokenExpirationHandler(status);

const { status, result, ok } = await this.loader.post(this.loginEndpoint, { username: username });
await this._tokenExpirationHandler(status);
if (ok) {
this.setDataAccessSubmodel();
localStorage.token = sessionService.session.token;
this.dataAccess.setState(dataAccess.states.dataAccess);
this.notify();
} else if (/5\d\d/.test(status)) {
this.setServiceUnavailableModel(result);
this.dataAccess.setState(dataAccess.states.serviceUnavailable, result);
}
}

postLoginPasses(username) {
return this.loader.post(this.logginEndpoint, { username: username });
}

isDetectorRole(role) {
return role.toUpperCase().startsWith(role.meta.SSO_DET_ROLE.toUpperCase());
}
Expand All @@ -88,50 +87,19 @@ export default class Model extends Observable {
return [roles.dict.Guest];
}

setServiceUnavailableModel(result) {
const messageShowTimeout = 200;
const modeName = 'serviceUnavailable';
if (!this.submodels[modeName]) {
this.submodels[modeName] = new ServiceUnavailableModel(this);
this.submodels[modeName].bubbleTo(this);
}
this.mode = modeName;
this.notify();
const model = this;
setTimeout(() => {
model.submodels[modeName].unsetResult(result);
model.notify();
setTimeout(() => {
model.submodels[modeName].setResult(result);
model.notify();
}, messageShowTimeout);
}, messageShowTimeout);
}

setDataAccessSubmodel() {
const modeName = 'dataAccess';
localStorage.token = sessionService.session.token;
this.submodels[modeName] = new DataAccessModel(this);
this.submodels[modeName].bubbleTo(this);
this.mode = modeName;
this.notify();
}

_tokenExpirationHandler(status) {
async _tokenExpirationHandler(status) {
if (status == 403) {
localStorage.token = null;
alert('Auth token expired!');
this.router.unobserve(this.primary.routerCallback);
this.router.go('/', true);
this.primary = null;
this.mode = 'default';
this.dataAccess.setState(dataAccess.states.sessionError);
document.location.reload(true);
}
}

async controlServerRequest(name = '/api/auth-control/') {
const { status } = this.loader.get(name);
this._tokenExpirationHandler(status);
await this._tokenExpirationHandler(status);
}

restoreSession() {
Expand Down
6 changes: 3 additions & 3 deletions app/public/components/flags/flagBreadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ const { pageNames } = RCT;
export default function flagBreadCrumbs(model, dataPass, run, detector) {
return [
title(pageNames.flags),
h('.forward-20'),
h('.forward-20-primary'),
flagsIndexChip(model.navigation, pageNames.dataPasses, extractPeriodName(dataPass), dataPass),
h('.forward-20'),
h('.forward-20-primary'),
flagsIndexChip(model.navigation, pageNames.runsPerDataPass, dataPass, run),
h('.forward-20'),
h('.forward-20-primary'),
h('h3.ph-15.text-primary', detector),
];
}
24 changes: 24 additions & 0 deletions app/public/components/messagePanel/messagePanel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @license
* Copyright 2019-2020 CERN and copyright holders of ALICE O2.
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
* All rights not expressly granted are reserved.
*
* This software is distributed under the terms of the GNU General Public
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
*
* In applying this license CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/

import { h } from '/js/src/index.js';

export default function messagePanel(imageClass, reason, message, buttons, notification = null) {
return h('.panel.abs-center',
h(`.${imageClass}`),
h('h3', reason),
h('h5', message),
notification ? notification : '',
h('.flex-wrap.justify-center', buttons));
}
26 changes: 25 additions & 1 deletion app/public/model/DataAccessModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ import { Observable, Loader } from '/js/src/index.js';
import FetchedDataManager from './data/FetchedDataManager.js';
import { defaultIndex, defaultIndexString } from '../utils/defaults.js';
import Navigation from './navigation/Navigation.js';
import ServiceUnavailable from './ServiceUnavailable.js';
import { RCT } from '../config.js';
const { messageTimeout } = RCT;
const { states } = RCT.dataAccess;

export default class DataAccessModel extends Observable {
constructor(parent) {
super();
this.state = states.default;
this.parent = parent;
this.router = this.parent.router;

this.serviceUnavailable = new ServiceUnavailable(parent);
this.fetchedData = new FetchedDataManager(this.router, this);

this.searchFieldsVisible = false;
Expand All @@ -33,6 +39,24 @@ export default class DataAccessModel extends Observable {
this.navigation = new Navigation(parent, this);
}

setState(state, result = null) {
this.state = state;
this.handleStateChange(result);
}

handleStateChange(result) {
if (this.state === states.serviceUnavailable) {
setTimeout(() => {
this.serviceUnavailable.hideResult(result);
this.parent.notify();
setTimeout(() => {
this.serviceUnavailable.showResult(result);
this.parent.notify();
}, messageTimeout);
}, messageTimeout);
}
}

changeSearchFieldsVisibility() {
this.searchFieldsVisible = !this.searchFieldsVisible;
this.notify();
Expand All @@ -46,7 +70,7 @@ export default class DataAccessModel extends Observable {
async logout() {
const logoutEndpoint = '/api/logout/';
const { result, status, ok } = this.loader.post(logoutEndpoint);
this.parent._tokenExpirationHandler(status);
await this.parent._tokenExpirationHandler(status);

localStorage.token = null;
this.parent.mode = 'default';
Expand Down
41 changes: 41 additions & 0 deletions app/public/model/ServiceUnavailable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @license
* Copyright 2019-2020 CERN and copyright holders of ALICE O2.
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
* All rights not expressly granted are reserved.
*
* This software is distributed under the terms of the GNU General Public
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
*
* In applying this license CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/

import { Observable } from '/js/src/index.js';

export default class ServiceUnavailable extends Observable {
constructor(model) {
super();
this.model = model;
this.messageFieldId = 'serviceUnavailableMessageFieldID';
}

showResult(result) {
const field = document.getElementById(this.messageFieldId);
if (field) {
field.innerText = result.message ? result.message : result;
field.classList.remove('notification-close');
field.classList.add('notification-open');
}
}

hideResult() {
const field = document.getElementById(this.messageFieldId);
if (field) {
field.innerText = '';
field.classList.add('notification-close');
field.classList.remove('notification-open');
}
}
}
43 changes: 0 additions & 43 deletions app/public/model/ServiceUnavailableModel.js

This file was deleted.

2 changes: 1 addition & 1 deletion app/public/model/data/FetchedData.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const defaultRowsOnSite = 50;
const defaultSite = 1;

import { RCT } from '../../../config.js';
const DRF = RCT.dataRespondFields;
const DRF = RCT.dataResponseFields;

/**
* Object of this class is used to hold data fetched from backend
Expand Down
Loading