Skip to content

Commit

Permalink
[O2B-536] Improve runs overview run number filter
Browse files Browse the repository at this point in the history
  • Loading branch information
martinboulais committed Feb 3, 2025
1 parent f9a22d3 commit 2f6964b
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@
import { h } from '/js/src/index.js';

/**
* Returns the author filter component
* @param {RunsOverviewModel} runsOverviewModel the runs overview model
* @return {vnode} A text box that lets the user look for logs with a specific author
* Component to filter runs on run number
* @param {RawTextFilterModel} filterModel the filter model
* @return {Component} the filter
*/
const runNumberFilter = (runsOverviewModel) => h('input', {
type: 'text',
id: 'runNumber',
value: runsOverviewModel.getRunNumberFilter(),
placeholder: 'e.g. 534454, 534455...',
oninput: (e) => runsOverviewModel.setRunsFilter(e.target.value),
}, '');

export default runNumberFilter;
export const runNumbersFilter = (filterModel) => h(
'input',
{
type: 'text',
class: 'run-numbers-filter',
value: filterModel.value,
placeholder: 'e.g. 534454, 534455...',
onchange: (e) => {
filterModel.value = e.target.value;
},
},
);
59 changes: 59 additions & 0 deletions lib/public/components/Filters/common/filters/RawTextFilterModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { FilterModel } from '../FilterModel.js';

const EMPTY_VALUE = '';

/**
* Filtering model to handle raw text value
*/
export class RawTextFilterModel extends FilterModel {
/**
* Constructor
*/
constructor() {
super();
this._value = EMPTY_VALUE;
}

// eslint-disable-next-line valid-jsdoc
/**
* @inheritDoc
*/
reset() {
this._value = EMPTY_VALUE;
}

// eslint-disable-next-line valid-jsdoc
/**
* @inheritDoc
*/
get isEmpty() {
return this._value === EMPTY_VALUE;
}

// eslint-disable-next-line valid-jsdoc
/**
* @inheritDoc
*/
get normalized() {
return this._value;
}

/**
* Return the filter current value
*
* @return {string} the current value
*/
get value() {
return this._value;
}

/**
* Sets the filter current value
*
* @param {string} value the current value
*/
set value(value) {
this._value = value;
this.notify();
}
}
11 changes: 9 additions & 2 deletions lib/public/views/Runs/ActiveColumns/runsActiveColumns.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/

import { h } from '/js/src/index.js';
import runNumberFilter from '../../../components/Filters/RunsFilter/runNumber.js';
import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js';
import environmentIdFilter from '../../../components/Filters/RunsFilter/environmentId.js';
import nDetectorsFilter from '../../../components/Filters/RunsFilter/nDetectors.js';
import nFlpsFilter from '../../../components/Filters/RunsFilter/nFlps.js';
Expand Down Expand Up @@ -70,7 +70,14 @@ export const runsActiveColumns = {
visible: true,
classes: 'w-10 f6 w-wrapped',
sortable: true,
filter: runNumberFilter,

/**
* Run number filter component
*
* @param {RunsOverviewModel} runsOverviewModel the runs overview model
* @return {Component} the filter component
*/
filter: (runsOverviewModel) => runNumbersFilter(runsOverviewModel.filteringModel.get('runNumbers')),
format: (runNumber, run) => buttonLinkWithDropdown(
runNumber,
'run-detail',
Expand Down
26 changes: 2 additions & 24 deletions lib/public/views/Runs/Overview/RunsOverviewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { tagsProvider } from '../../../services/tag/tagsProvider.js';
import { eorReasonTypeProvider } from '../../../services/eorReason/eorReasonTypeProvider.js';
import { runTypesProvider } from '../../../services/runTypes/runTypesProvider.js';
import { TimeRangeFilterModel } from '../../../components/Filters/RunsFilter/TimeRangeFilter.js';
import { RawTextFilterModel } from '../../../components/Filters/common/filters/RawTextFilterModel.js';

/**
* Model representing handlers for runs page
Expand All @@ -46,6 +47,7 @@ export class RunsOverviewModel extends OverviewPageModel {
super();

this._filteringModel = new FilteringModel({
runNumbers: new RawTextFilterModel(),
detectors: new DetectorsFilterModel(detectorsProvider.dataTaking$),
tags: new TagFilterModel(
tagsProvider.items$,
Expand Down Expand Up @@ -164,8 +166,6 @@ export class RunsOverviewModel extends OverviewPageModel {
resetFiltering(fetch = true) {
this._filteringModel.reset();

this.runFilterOperation = 'AND';
this.runFilterValues = '';
this._runDefinitionFilter = [];

this._fillNumbersFilter = '';
Expand Down Expand Up @@ -205,7 +205,6 @@ export class RunsOverviewModel extends OverviewPageModel {
*/
isAnyFilterActive() {
return this._filteringModel.isAnyFilterActive()
|| this.runFilterValues !== ''
|| this._runDefinitionFilter.length > 0
|| this._fillNumbersFilter !== ''
|| this._runDurationFilter !== null
Expand Down Expand Up @@ -254,24 +253,6 @@ export class RunsOverviewModel extends OverviewPageModel {
this.notify();
}

/**
* Returns the current runNumber substring filter
* @return {String} The current runNumber substring filter
*/
getRunNumberFilter() {
return this.runFilterValues;
}

/**
* Sets the run Number substring filter if no new inputs were detected for 200 milliseconds
* @param {string} runs The number of the run to apply to the filter
* @return {undefined}
*/
setRunsFilter(runs) {
this.runFilterValues = runs.trim();
this._applyFilters();
}

/**
* States if the given definition is currently in the run definition filter, and it's the only one
*
Expand Down Expand Up @@ -653,9 +634,6 @@ export class RunsOverviewModel extends OverviewPageModel {
*/
_getFilterQueryParams() {
return {
...this.runFilterValues && {
'filter[runNumbers]': this.runFilterValues,
},
...this._runDefinitionFilter.length > 0 && {
'filter[definitions]': this._runDefinitionFilter.join(','),
},
Expand Down
4 changes: 2 additions & 2 deletions lib/public/views/Runs/Overview/RunsOverviewPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { filtersPanelPopover } from '../../../components/Filters/common/filtersP
import { paginationComponent } from '../../../components/Pagination/paginationComponent.js';
import { runsActiveColumns } from '../ActiveColumns/runsActiveColumns.js';
import { table } from '../../../components/common/table/table.js';
import runNumberFilter from '../../../components/Filters/RunsFilter/runNumber.js';
import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js';
import { switchInput } from '../../../components/common/form/switchInput.js';
import { RunDefinition } from '../../../domain/enums/RunDefinition.js';

Expand Down Expand Up @@ -54,7 +54,7 @@ export const RunsOverviewPage = ({ runs: { overviewModel: runsOverviewModel }, m
return h('', [
h('.flex-row.header-container.g2.pv2', [
filtersPanelPopover(runsOverviewModel, runsActiveColumns),
h('.pl2#runOverviewFilter', runNumberFilter(runsOverviewModel)),
h('.pl2#runOverviewFilter', runNumbersFilter(runsOverviewModel.filteringModel.get('runNumbers'))),
togglePhysicsOnlyFilter(runsOverviewModel),
exportRunsTriggerAndModal(runsOverviewModel, modalModel),
]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { createRunDetectorsAsyncQcActiveColumns } from '../ActiveColumns/runDete
import { inelasticInteractionRateActiveColumnsForPbPb } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForPbPb.js';
import { inelasticInteractionRateActiveColumnsForProtonProton } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForProtonProton.js';
import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js';
import runNumberFilter from '../../../components/Filters/RunsFilter/runNumber.js';
import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js';
import { qcSummaryLegendTooltip } from '../../../components/qcFlags/qcSummaryLegendTooltip.js';
import { isRunNotSubjectToQc } from '../../../components/qcFlags/isRunSubjectToQc.js';
import { frontLink } from '../../../components/common/navigation/frontLink.js';
Expand Down Expand Up @@ -94,7 +94,7 @@ const skimmableControl = (dataPass, onclick, requestResult) => {
/**
* Render Runs Per LHC Period overview page
* @param {Model} model The overall model object.
* @param {Model} [model.runs.perDataPassOverviewModel] model holding state for of the page
* @param {RunsPerDataPassOverviewModel} [model.runs.perDataPassOverviewModel] model holding state for of the page
* @return {Component} The overview page
*/
export const RunsPerDataPassOverviewPage = ({
Expand Down Expand Up @@ -205,7 +205,7 @@ export const RunsPerDataPassOverviewPage = ({
return h('', { onremove: () => perDataPassOverviewModel.reset(false) }, [
h('.flex-row.justify-between.items-center.g2', [
filtersPanelPopover(perDataPassOverviewModel, activeColumns, { profile: 'runsPerDataPass' }),
h('.pl2#runOverviewFilter', runNumberFilter(perDataPassOverviewModel)),
h('.pl2#runOverviewFilter', runNumbersFilter(perDataPassOverviewModel.filteringModel.get('runNumbers'))),
h(
'.flex-row.g1.items-center',
remoteDataPass.match({
Expand Down
2 changes: 1 addition & 1 deletion test/public/runs/detail.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const banIconPath =
*/
const goToRunDetails = async (page, runNumber) => {
await waitForNavigation(page, () => pressElement(page, '#run-overview'));
await fillInput(page, '#runNumber', `${runNumber},${runNumber}`);
await fillInput(page, '.run-numbers-filter', `${runNumber},${runNumber}`, ['change']);
return waitForNavigation(page, () => pressElement(page, `a[href="?page=run-detail&runNumber=${runNumber}"]`));
};

Expand Down
75 changes: 30 additions & 45 deletions test/public/runs/overview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module.exports = () => {

let table;
let firstRowId;
const runNumberInputSelector = '.runNumber-filter input';
const filterPanelRunNumbersInputSelector = '.runNumber-filter input';

before(async () => {
[page, browser] = await defaultBefore(page, browser);
Expand Down Expand Up @@ -268,21 +268,16 @@ module.exports = () => {
await goToPage(page, 'run-overview');

await pressElement(page, '#openFilterToggle');
await page.waitForSelector(runNumberInputSelector);

// Run 106 has detectors and tags that overflow
await page.type(runNumberInputSelector, '106');
await fillInput(page, runNumberInputSelector, '106');
await fillInput(page, filterPanelRunNumbersInputSelector, '106', ['change']);
await waitForTableLength(page, 1);

await checkColumnBalloon(page, 1, 2);
await checkColumnBalloon(page, 1, 3);

await pressElement(page, '#openFilterToggle');
await page.waitForSelector(runNumberInputSelector);

// Run 1 has eor reasons that overflow
await page.type(runNumberInputSelector, '1');
await fillInput(page, filterPanelRunNumbersInputSelector, '1,1', ['change']);
await waitForTableLength(page, 1);

await checkColumnBalloon(page, 1, 16);
Expand Down Expand Up @@ -622,12 +617,13 @@ module.exports = () => {

/**
* This is the sequence to test filtering the runs on run numbers.
*
* @param {string} selector the filter input selector
* @return {void}
*/
const filterOnRun = async () => {
await page.waitForSelector(runNumberInputSelector);
expect(await page.$eval(runNumberInputSelector, (input) => input.placeholder)).to.equal('e.g. 534454, 534455...');
await fillInput(page, runNumberInputSelector, inputValue);
const filterOnRun = async (selector) => {
await expectAttributeValue(page, selector, 'placeholder', 'e.g. 534454, 534455...');
await fillInput(page, selector, inputValue, ['change']);
await waitForTableLength(page, 2);
// Validate amount in the table
const table = await page.$$('tbody tr');
Expand All @@ -636,18 +632,17 @@ module.exports = () => {
};

// First filter validation on the main page.
await filterOnRun();
await filterOnRun('#runOverviewFilter .run-numbers-filter');

// Validate if the filter tab value is equal to the main page value.
await page.$eval('#openFilterToggle', (element) => element.click());
expect(await page.$eval(runNumberInputSelector, (input) => input.value)).to.equal(inputValue);
await expectInputValue(page, filterPanelRunNumbersInputSelector, inputValue);

// Test if it works in the filter tab.
await goToPage(page, 'run-overview');
await page.$eval('#openFilterToggle', (element) => element.click());
await pressElement(page, '#openFilterToggle');
await pressElement(page, '#reset-filters');

// Run the same test sequence on the filter tab.
await filterOnRun();
await filterOnRun(filterPanelRunNumbersInputSelector);
});

it('should successfully filter on a single run number and inform the user about it', async () => {
Expand All @@ -656,46 +651,36 @@ module.exports = () => {

/**
* This is the sequence to test filtering the runs on run numbers.
*
* @param {string} selector the filter input selector
* @return {void}
*/
const filterOnRun = async () => {
await page.waitForSelector(runNumberInputSelector);
expect(await page.$eval(runNumberInputSelector, (input) => input.placeholder)).to.equal('e.g. 534454, 534455...');
await fillInput(page, runNumberInputSelector, inputValue);
const filterOnRun = async (selector) => {
await expectAttributeValue(page, selector, 'placeholder', 'e.g. 534454, 534455...');
await fillInput(page, selector, inputValue, ['change']);
await waitForTableLength(page, 8);
// Validate amount in the first page table
const firstPageTable = await page.$$('tbody tr');
expect(firstPageTable.length).to.equal(8);

const firstPageRows = ['row108', 'row107', 'row106', 'row105', 'row104', 'row103', 'row102', 'row101'];
expect(await page.$$eval('tbody tr', (rows) => rows.map((row) => row.id))).to.eql(firstPageRows);
// Results are filtered over 2 pages
await expectColumnValues(page, 'runNumber', ['108', '107', '106', '105', '104', '103', '102', '101']);

await page.$eval('#pageMoveRight', (element) => element.click());
await pressElement(page, '#pageMoveRight', true);
await waitForTableLength(page, 2);

// Validate amount in the second page table
const secondPageTable = await page.$$('tbody tr');
expect(secondPageTable.length).to.equal(2);

const secondPageRows = ['row100', 'row10'];
expect(await page.$$eval('tbody tr', (rows) => rows.map((row) => row.id))).to.eql(secondPageRows);
await expectColumnValues(page, 'runNumber', ['100', '10']);
};

// First filter validation on the main page.
await filterOnRun();
await filterOnRun('#runOverviewFilter .run-numbers-filter');

// Validate if the filter tab value is equal to the main page value.
await page.$eval('#openFilterToggle', (element) => element.click());
await page.waitForSelector('#eorCategories');
expect(await page.$eval(runNumberInputSelector, (input) => input.value)).to.equal(inputValue);
await expectInputValue(page, filterPanelRunNumbersInputSelector, inputValue);

// Test if it works in the filter tab.
await goToPage(page, 'run-overview');
await page.$eval('#openFilterToggle', (element) => element.click());
await page.waitForSelector('#eorCategories');
await pressElement(page, '#openFilterToggle');
await pressElement(page, '#reset-filters');

// Run the same test sequence on the filter tab.
await filterOnRun();
await filterOnRun(filterPanelRunNumbersInputSelector);
});

it('should successfully filter on a list of fill numbers and inform the user about it', async () => {
Expand Down Expand Up @@ -918,7 +903,7 @@ module.exports = () => {
await pressElement(page, '#openFilterToggle');

// Type a fake run number to have no runs
await fillInput(page, runNumberInputSelector, '99999999999');
await fillInput(page, filterPanelRunNumbersInputSelector, '99999999999', ['change']);
await pressElement(page, '#openFilterToggle');

await page.waitForSelector(`${EXPORT_RUNS_TRIGGER_SELECTOR}:disabled`);
Expand Down Expand Up @@ -1038,12 +1023,12 @@ module.exports = () => {

await expectLink(page, `${popoverSelector} a:nth-of-type(1)`, {
href: 'http://localhost:8081/?q={%22partition%22:{%22match%22:%22TDI59So3d%22},'
+ '%22run%22:{%22match%22:%22104%22},%22severity%22:{%22in%22:%22W%20E%20F%22}}',
+ '%22run%22:{%22match%22:%22104%22},%22severity%22:{%22in%22:%22W%20E%20F%22}}',
innerText: 'Infologger FLP',
});
await expectLink(page, `${popoverSelector} a:nth-of-type(2)`, {
href: 'http://localhost:8082/' +
'?page=layoutShow&runNumber=104&definition=COMMISSIONING&detector=CPV&pdpBeamType=cosmic&runType=COSMICS',
'?page=layoutShow&runNumber=104&definition=COMMISSIONING&detector=CPV&pdpBeamType=cosmic&runType=COSMICS',
innerText: 'QCG',
});

Expand Down
Loading

0 comments on commit 2f6964b

Please sign in to comment.