Skip to content

Commit d3e389a

Browse files
committed
[O2B-1546] Add and adjust synchronous QC Flags active columns and tests
Introduce a dedicated synchronousQcFlagsActiveColumns config. Make formatQcFlagStart/End accept an inline flag and pass it through to formatTimestamp so From/To and Created views can render date/time on one line. Adjust a seeder row to mark a QC flag as deleted so it's text colour can be tested. Update synchronous overview tests to validate combined From/To and CreatedBy cell contents, check comment/createdBy popovers, and assert Deleted cell text and styling.
1 parent e575a0f commit d3e389a

6 files changed

Lines changed: 111 additions & 24 deletions

File tree

lib/database/seeders/20240404100811-qc-flags.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ module.exports = {
253253
// Run : 56, FT0
254254
{
255255
id: 100,
256-
deleted: false,
256+
deleted: true,
257257
from: null,
258258
to: '2019-08-08 20:50:00',
259259
comment: 'first part good',
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
import { h } from '/js/src/index.js';
15+
import { qcFlagsActiveColumns } from './qcFlagsActiveColumns.js';
16+
import { formatQcFlagStart } from '../format/formatQcFlagStart.js';
17+
import { formatQcFlagEnd } from '../format/formatQcFlagEnd.js';
18+
import { formatQcFlagCreatedBy } from '../format/formatQcFlagCreatedBy.js';
19+
import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.js';
20+
21+
/**
22+
* Active columns configuration for synchronous QC flags table
23+
*/
24+
export const synchronousQcFlagsActiveColumns = {
25+
id: {
26+
name: 'Id',
27+
visible: false,
28+
},
29+
flagType: {
30+
...qcFlagsActiveColumns.flagType,
31+
classes: 'w-15',
32+
},
33+
from: {
34+
name: 'From/To',
35+
visible: true,
36+
format: (_, qcFlag) => h('', [
37+
h('.flex-row', ['From: ', formatQcFlagStart(qcFlag, true)]),
38+
h('.flex-row', ['To: ', formatQcFlagEnd(qcFlag, true)]),
39+
]),
40+
classes: 'w-15',
41+
},
42+
comment: {
43+
...qcFlagsActiveColumns.comment,
44+
balloon: true,
45+
},
46+
deleted: {
47+
name: 'Deleted',
48+
visible: true,
49+
classes: 'w-5',
50+
format: (deleted) => deleted ? h('.danger', 'Yes') : 'No',
51+
},
52+
createdBy: {
53+
name: 'Created',
54+
visible: true,
55+
balloon: true,
56+
format: (_, qcFlag) => h('', [
57+
h('.flex-row', ['By: ', formatQcFlagCreatedBy(qcFlag)]),
58+
h('.flex-row', ['At: ', formatTimestamp(qcFlag.createdAt)]),
59+
]),
60+
},
61+
};

lib/public/views/QcFlags/Synchronous/SynchronousQcFlagsOverviewPage.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { h } from '/js/src/index.js';
1616
import { estimateDisplayableRowsCount } from '../../../utilities/estimateDisplayableRowsCount.js';
1717
import { table } from '../../../components/common/table/table.js';
1818
import { paginationComponent } from '../../../components/Pagination/paginationComponent.js';
19-
import { qcFlagsActiveColumns } from '../ActiveColumns/qcFlagsActiveColumns.js';
19+
import { synchronousQcFlagsActiveColumns } from '../ActiveColumns/synchronousQcFlagsActiveColumns.js';
2020
import { qcFlagsBreadcrumbs } from '../../../components/qcFlags/qcFlagsBreadcrumbs.js';
2121
import { mergeRemoteData } from '../../../utilities/mergeRemoteData.js';
2222
import errorAlert from '../../../components/common/errorAlert.js';
@@ -46,16 +46,6 @@ export const SynchronousQcFlagsOverviewPage = ({ qcFlags: { synchronousOverviewM
4646
PAGE_USED_HEIGHT,
4747
));
4848

49-
const activeColumns = {
50-
qcFlagId: {
51-
name: 'Id',
52-
visible: false,
53-
classes: 'w-5',
54-
},
55-
...qcFlagsActiveColumns,
56-
};
57-
delete activeColumns.verified;
58-
5949
return h(
6050
'',
6151
{ onremove: () => synchronousOverviewModel.reset() },
@@ -70,8 +60,8 @@ export const SynchronousQcFlagsOverviewPage = ({ qcFlags: { synchronousOverviewM
7060
h('.w-100.flex-column', [
7161
table(
7262
qcFlags,
73-
activeColumns,
74-
{ classes: '.table-sm' },
63+
synchronousQcFlagsActiveColumns,
64+
{ classes: '.table-sm.f6' },
7565
null,
7666
{ sort: sortModel },
7767
),

lib/public/views/QcFlags/format/formatQcFlagEnd.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.j
1717
* Format QC flag `to` timestamp
1818
*
1919
* @param {QcFlag} qcFlag QC flag
20+
* @param {boolean} inline if true, date and time are on a single line
2021
* @return {Component} formatted `to` timestamp
2122
*/
22-
export const formatQcFlagEnd = ({ from, to }) => {
23+
export const formatQcFlagEnd = ({ from, to }, inline = false) => {
2324
if (to) {
24-
return formatTimestamp(to, false);
25+
return formatTimestamp(to, inline);
2526
} else {
2627
return from
2728
? 'Until run end'

lib/public/views/QcFlags/format/formatQcFlagStart.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.j
1717
* Format QC flag `from` timestamp
1818
*
1919
* @param {QcFlag} qcFlag QC flag
20+
* @param {boolean} inline if true, date and time are on a single line
2021
* @return {Component} formatted `from` timestamp
2122
*/
22-
export const formatQcFlagStart = ({ from, to }) => {
23+
export const formatQcFlagStart = ({ from, to }, inline = false) => {
2324
if (from) {
24-
return formatTimestamp(from, false);
25+
return formatTimestamp(from, inline);
2526
} else {
2627
return to
2728
? 'Since run start'

test/public/qcFlags/synchronousOverview.test.js

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const {
2222
expectUrlParams,
2323
waitForNavigation,
2424
getColumnCellsInnerTexts,
25+
getPopoverContent,
2526
} = require('../defaults.js');
2627

2728
const { expect } = chai;
@@ -59,14 +60,21 @@ module.exports = () => {
5960

6061
it('shows correct datatypes in respective columns', async () => {
6162
// eslint-disable-next-line require-jsdoc
62-
const validateDate = (date) => date === '-' || !isNaN(dateAndTime.parse(date, 'DD/MM/YYYY hh:mm:ss'));
63+
const validateDate = (date) => date === '-' || !isNaN(dateAndTime.parse(date, 'DD/MM/YYYY, hh:mm:ss'));
6364
const tableDataValidators = {
6465
flagType: (flagType) => flagType && flagType !== '-',
65-
createdBy: (userName) => userName && userName !== '-',
66-
from: (timestamp) => timestamp === 'Whole run coverage' || timestamp === 'Since run start' || validateDate(timestamp),
67-
to: (timestamp) => timestamp === 'Whole run coverage' || timestamp === 'Until run end' || validateDate(timestamp),
68-
createdAt: validateDate,
69-
updatedAt: validateDate,
66+
from: (cellContent) => {
67+
const match = cellContent.match(/^From:\s*(.+)\nTo:\s*(.+)$/);
68+
if (!match) return false;
69+
const [, from, to] = match;
70+
return (['Whole run coverage', 'Since run start'].includes(from) || validateDate(from))
71+
&& (['Whole run coverage', 'Until run end'].includes(to) || validateDate(to));
72+
},
73+
deleted: (value) => value === 'Yes' || value === 'No',
74+
createdBy: (cellContent) => {
75+
const match = cellContent.match(/^By:\s*(.+)\nAt:\s*(.+)$/);
76+
return match && match[1] !== '-' && validateDate(match[2]);
77+
},
7078
};
7179

7280
await validateTableData(page, new Map(Object.entries(tableDataValidators)));
@@ -80,6 +88,32 @@ module.exports = () => {
8088
await expectInnerText(page, '#totalRowsCount', '2');
8189
});
8290

91+
it('should display Comment tooltip with full information', async () => {
92+
let popoverTrigger = await page.$(`#row100-comment .popover-trigger`);
93+
expect(popoverTrigger).to.not.be.null;
94+
95+
const popoverContent = await getPopoverContent(popoverTrigger);
96+
expect(popoverContent).to.equal('first part good');
97+
});
98+
99+
it('should display CreatedBy tooltip with full information', async () => {
100+
let popoverTrigger = await page.$(`#row100-createdBy .popover-trigger`);
101+
expect(popoverTrigger).to.not.be.null;
102+
103+
const popoverContent = await getPopoverContent(popoverTrigger);
104+
expect(popoverContent).to.equal('By: Jan JansenAt: 12/08/2024, 12:00:00');
105+
});
106+
107+
it('should display correct Deleted text colour', async () => {
108+
const deletedCell = await page.$('#row100-deleted-text:nth-child(1)');
109+
110+
const deletedCellText = await page.evaluate(cell => cell.textContent.trim(), deletedCell);
111+
expect(deletedCellText).to.equal('Yes');
112+
113+
const deletedCellFirstChildClass = await page.evaluate(cell => cell.firstElementChild.className, deletedCell);
114+
expect(deletedCellFirstChildClass).to.include('danger');
115+
});
116+
83117
it('can navigate to run details page from breadcrumbs link', async () => {
84118
await waitForNavigation(page, () => pressElement(page, '#breadcrumb-run-number'));
85119
expectUrlParams(page, { page: 'run-detail', runNumber: '56' });

0 commit comments

Comments
 (0)