Skip to content

Commit

Permalink
[OGUI-1510] Add separate task summary table for ODC (#2397)
Browse files Browse the repository at this point in the history
* adds a separate summary table for EPNs in env-details page
  • Loading branch information
graduta authored May 27, 2024
1 parent 64ed5a0 commit 8813ef7
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 19 deletions.
16 changes: 16 additions & 0 deletions Control/public/common/enums/HardwareComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,19 @@ export const HARDWARE_COMPONENTS = Object.keys(HardwareComponent)
return a.localeCompare(b);
}
});

/**
* List of possible hardware components sorted alphabetically with FLP first
* @return {Array<String>} list of hardware components
*/
export const HARDWARE_COMPONENTS_WITHOUT_EPN = Object.keys(HardwareComponent)
.filter((component) => component !== HardwareComponent.EPN)
.sort((a, b) => {
if (a === 'FLP') {
return -1;
} else if (b === 'FLP') {
return 1;
} else {
return a.localeCompare(b);
}
});
73 changes: 62 additions & 11 deletions Control/public/common/enums/TaskState.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* or submit itself to any jurisdiction.
*/

export const TaskState = Object.freeze({
export const FlpTaskState = Object.freeze({
ERROR: 'ERROR',
RUNNING: 'RUNNING',
STANDBY: 'STANDBY',
Expand All @@ -26,7 +26,7 @@ export const TaskState = Object.freeze({
* List of possible states for a task sorted alphabetically with ERROR first and RUNNING second and CONFIGURED third
* @return {Array<String>} list of task states
*/
export const TASK_STATES = Object.values(TaskState)
export const FLP_TASK_STATES = Object.values(FlpTaskState)
.sort((a, b) => {
if (a === 'ERROR') {
return -1;
Expand All @@ -45,13 +45,64 @@ export const TASK_STATES = Object.values(TaskState)
}
});

export const TaskStateClassAssociation = Object.freeze({
ERROR: '.danger',
RUNNING: '.success',
CONFIGURED: '.primary',
STANDBY: '',
DONE: '',
MIXED: '',
UNKNOWN: '',
INVARIANT: '',
export const EpnTaskState = Object.freeze({
IDLE: 'IDLE',
EXITING: 'EXITING',
RESETTING_DEVICE: 'RESETTING DEVICE',
INITIALIZING_DEVICE: 'INITIALIZING DEVICE',
INITIALIZED: 'INITIALIZED',
BINDING: 'BINDING',
BOUND: 'BOUND',
CONNECTING: 'CONNECTING',
DEVICE_READY: 'DEVICE READY',
INITIALIZING_TASK: 'INITIALIZING TASK',
READY: 'READY',
RUNNING: 'RUNNING',
RESETTING_TASK: 'RESETTING TASK',
OK: 'OK',
ERROR: 'ERROR',
});

/**
* List of possible states for a task sorted alphabetically with ERROR first and RUNNING second and CONFIGURED third
* @return {Array<String>} list of task states
*/
export const EPN_TASK_STATES = Object.values(EpnTaskState)
.sort((a, b) => {
if (a === 'ERROR') {
return -1;
} else if (b === 'ERROR') {
return 1;
} else if (a === 'RUNNING') {
return -1;
} else if (b === 'RUNNING') {
return 1;
} else if (a === 'READY') {
return -1;
} else if (b === 'READY') {
return 1;
} else {
return a.localeCompare(b);
}
});

/**
* Given a hardware component task state, return the class associated with the state
* @param {FlpTaskState|EpnTaskState} state - task state to get the class for
* @return {String} - CSS class to be used in the HTML
*/
export function getTaskStateClassAssociation(state) {
switch (state) {
case FlpTaskState.ERROR:
case EpnTaskState.ERROR:
return '.danger';
case FlpTaskState.RUNNING:
case EpnTaskState.RUNNING:
return '.success';
case FlpTaskState.CONFIGURED:
case EpnTaskState.READY:
return '.primary';
default:
return '';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @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 {EPN_TASK_STATES, getTaskStateClassAssociation} from './../../common/enums/TaskState.js';
import {h} from '/js/src/index.js';

/**
* Build a table with the summary of the tasks states for the environment grouped by component (FLP, EPN, QC, CTP Readout) and detector
* @param {EnvironmentInfo} environment
* @return {vnode} - component with an HTML table
*/
export const environmentEpnTasksSummaryTable = (environment) => {
const {hardware} = environment;
return h('table.table-ecs.table-ecs-sm.shadow-level1', [
h('thead', [
hardwareComponentsTableHeaderRow(hardware),
]),
h('tbody', [
EPN_TASK_STATES.map((state) => rowForTaskSate(state, hardware)),
])
]);
};

/**
* Build the HTML header row of the table with the components present as hardware in the environment
* @param {Object<['flp', 'qc', 'epn', 'trg'], Object>} hardware - object with the hardware components and details
* @return {vnode} - component with an HTML table row
*/
const hardwareComponentsTableHeaderRow = (hardware) => h('tr', [
h('th', 'EPN States'),
h('th.break-space-cell.text-center', `#hosts:${hardware?.epn?.hosts ?? '-'}`)
]);

/**
* Build a row of the table with the summary of the tasks for specified state for the environment
* @param {String} state - task state
* @param {Object<['flp', 'qc', 'epn', 'trg'], Object>} hardware - object with the hardware components and details
* @return {vnode} - component with an HTML table row
*/
const rowForTaskSate = (state, hardware) => {
const taskClass = getTaskStateClassAssociation(state);
console.log(state, taskClass)
return h('tr', [
h(`td${taskClass}`, state), h(`td.text-center${taskClass}`, hardware?.epn?.tasks?.states[state] ?? '-'),
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
* or submit itself to any jurisdiction.
*/

import {HARDWARE_COMPONENTS, HardwareComponent} from '../../common/enums/HardwareComponent.js';
import {TASK_STATES, TaskStateClassAssociation} from './../../common/enums/TaskState.js';
import {HARDWARE_COMPONENTS_WITHOUT_EPN, HardwareComponent} from '../../common/enums/HardwareComponent.js';
import {FLP_TASK_STATES, getTaskStateClassAssociation} from './../../common/enums/TaskState.js';
import {h} from '/js/src/index.js';

/**
Expand All @@ -29,7 +29,7 @@ export const environmentTasksSummaryTable = (environment) => {
detectorsTableHeaderRow(hardware),
]),
h('tbody', [
TASK_STATES.map((state) => rowForTaskSate(state, hardware)),
FLP_TASK_STATES.map((state) => rowForTaskSate(state, hardware)),
])
]);
};
Expand All @@ -41,7 +41,8 @@ export const environmentTasksSummaryTable = (environment) => {
*/
const hardwareComponentsTableHeaderRow = (hardware) => h('tr', [
h('th', 'Tasks Summary'),
HARDWARE_COMPONENTS
HARDWARE_COMPONENTS_WITHOUT_EPN
.filter(component => component !== 'EPN')
.map((component) => {
const componentInLowerCase = component.toLocaleLowerCase();
const colspan = hardware[componentInLowerCase]?.detectorCounters
Expand All @@ -61,7 +62,7 @@ const hardwareComponentsTableHeaderRow = (hardware) => h('tr', [
const detectorsTableHeaderRow = ({flp: {detectorCounters = {}} = {}}) => h('tr', [
h('th', 'States\\Detectors'),
Object.keys(detectorCounters).map((detector) => h('th.text-center', detector)),
h('th.text-center', {colspan: HARDWARE_COMPONENTS.length - 1}, ''), // empty cell to align with the rest of the table
h('th.text-center', {colspan: HARDWARE_COMPONENTS_WITHOUT_EPN.length - 1}, ''), // empty cell to align with the rest of the table
]);

/**
Expand All @@ -71,10 +72,10 @@ const detectorsTableHeaderRow = ({flp: {detectorCounters = {}} = {}}) => h('tr',
* @return {vnode} - component with an HTML table row
*/
const rowForTaskSate = (state, hardware) => {
const taskClass = TaskStateClassAssociation[state];
const taskClass = getTaskStateClassAssociation(state);
return h('tr', [
h(`td${taskClass}`, state),
HARDWARE_COMPONENTS
HARDWARE_COMPONENTS_WITHOUT_EPN
.map((component) => {
const componentInLowerCase = component.toLocaleLowerCase();
if (componentInLowerCase === 'flp') {
Expand Down
6 changes: 5 additions & 1 deletion Control/public/environment/environmentPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {h} from '/js/src/index.js';
import {environmentActionPanel} from './components/environmentActionPanel.js';
import {environmentNavigationTabs} from './components/environmentNavigationTabs.js';
import {environmentTasksSummaryTable} from './components/environmentTasksSummaryTable.js';
import {environmentEpnTasksSummaryTable} from './components/environmentEpnTasksSummaryTable.js';
import {monitoringRunningPlotsPanel} from './components/monitoringRunningPlotsPanel.js';
import pageLoading from '../common/pageLoading.js';
import errorPage from '../common/errorPage.js';
Expand Down Expand Up @@ -59,7 +60,10 @@ const showEnvironmentPage = (model, environmentInfo) => {
environmentHeader(environmentInfo),
environmentActionPanel(model, environmentInfo),
isRunningStable && monitoringRunningPlotsPanel(environmentInfo),
environmentTasksSummaryTable(environmentInfo),
h('.flex-row.g2', [
environmentTasksSummaryTable(environmentInfo),
environmentEpnTasksSummaryTable(environmentInfo),
]),
environmentNavigationTabs(model, environmentInfo),
]);
};

0 comments on commit 8813ef7

Please sign in to comment.