diff --git a/lib/domain/dtos/filters/LhcFillsFilterDto.js b/lib/domain/dtos/filters/LhcFillsFilterDto.js index 2942844758..b21ae09255 100644 --- a/lib/domain/dtos/filters/LhcFillsFilterDto.js +++ b/lib/domain/dtos/filters/LhcFillsFilterDto.js @@ -28,4 +28,5 @@ exports.LhcFillsFilterDto = Joi.object({ }), runDurationOperator: Joi.string().trim().min(1).max(2), beamsType: Joi.string(), + schemeName: Joi.string().trim(), }); diff --git a/lib/public/components/Filters/LhcFillsFilter/schemeNameFilter.js b/lib/public/components/Filters/LhcFillsFilter/schemeNameFilter.js new file mode 100644 index 0000000000..a4b8dfb643 --- /dev/null +++ b/lib/public/components/Filters/LhcFillsFilter/schemeNameFilter.js @@ -0,0 +1,25 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE Trg. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-Trg.web.cern.ch/license for full licensing information. + * + * 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 { rawTextFilter } from '../common/filters/rawTextFilter.js'; + +/** + * Component to filter LHC-fills by scheme name + * + * @param {RawTextFilterModel} filterModel the filter model + * @returns {Component} the text field + */ +export const schemeNameFilter = (filterModel) => rawTextFilter( + filterModel, + { classes: ['w-100', 'scheme-name-filter'], placeholder: 'e.g. Single_12b_8_1024_8_2018' }, +); diff --git a/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js b/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js index 897b407d13..6ad8935c48 100644 --- a/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js +++ b/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js @@ -28,6 +28,7 @@ import { fillNumberFilter } from '../../../components/Filters/LhcFillsFilter/fil import { beamDurationFilter } from '../../../components/Filters/LhcFillsFilter/beamDurationFilter.js'; import { runDurationFilter } from '../../../components/Filters/LhcFillsFilter/runDurationFilter.js'; import { beamsTypeFilter } from '../../../components/Filters/LhcFillsFilter/beamsTypeFilter.js'; +import { schemeNameFilter } from '../../../components/Filters/LhcFillsFilter/schemeNameFilter.js'; /** * List of active columns for a lhc fills table @@ -184,6 +185,7 @@ export const lhcFillsActiveColumns = { visible: true, size: 'w-10', format: (value) => value ? value : '-', + filter: (lhcFillModel) => schemeNameFilter(lhcFillModel.filteringModel.get('schemeName')), balloon: true, }, runs: { diff --git a/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js b/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js index 5689428c96..a3eeccc8d9 100644 --- a/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js +++ b/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js @@ -44,6 +44,7 @@ export class LhcFillsOverviewModel extends OverviewPageModel { runDuration: new RawTextFilterModel(), hasStableBeams: new StableBeamFilterModel(), beamsType: new BeamsTypeFilterModel(), + schemeName: new RawTextFilterModel(), }); this._beamDurationOperator = defaultBeamDurationOperator; diff --git a/lib/usecases/lhcFill/GetAllLhcFillsUseCase.js b/lib/usecases/lhcFill/GetAllLhcFillsUseCase.js index 958f07cbe2..753f4afa35 100644 --- a/lib/usecases/lhcFill/GetAllLhcFillsUseCase.js +++ b/lib/usecases/lhcFill/GetAllLhcFillsUseCase.js @@ -47,7 +47,8 @@ class GetAllLhcFillsUseCase { let associatedStatisticsRequired = false; if (filter) { - const { hasStableBeams, fillNumbers, beamDurationOperator, beamDuration, runDurationOperator, runDuration, beamsType } = filter; + const { hasStableBeams, fillNumbers, schemeName, beamDurationOperator, + beamDuration, runDurationOperator, runDuration, beamsType } = filter; if (hasStableBeams) { // For now, if a stableBeamsStart is present, then a beam is stable queryBuilder.where('stableBeamsStart').not().is(null); @@ -64,6 +65,11 @@ class GetAllLhcFillsUseCase { } } + // Scheme name filter + if (schemeName) { + queryBuilder.where('filling_scheme_name').substring(schemeName); + } + // Run duration filter and corresponding operator. if (runDuration !== null && runDuration !== undefined && runDurationOperator) { associatedStatisticsRequired = true; diff --git a/test/lib/usecases/lhcFill/GetAllLhcFillsUseCase.test.js b/test/lib/usecases/lhcFill/GetAllLhcFillsUseCase.test.js index c9284001f5..883c77e07f 100644 --- a/test/lib/usecases/lhcFill/GetAllLhcFillsUseCase.test.js +++ b/test/lib/usecases/lhcFill/GetAllLhcFillsUseCase.test.js @@ -66,7 +66,7 @@ module.exports = () => { }) it('should only contain specified fill numbers, range', async () => { - getAllLhcFillsDto.query = { filter: { hasStableBeams: true, fillNumbers: '1-3,6' } }; + getAllLhcFillsDto.query = { filter: { bhasStableBeams: true, fillNumbers: '1-3,6' } }; const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto); @@ -101,6 +101,30 @@ module.exports = () => { }); }) + it('should only contain matching scheme name, one precise', async () => { + getAllLhcFillsDto.query = { filter: { hasStableBeams: true, schemeName: 'schemename' } }; + const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto); + + + expect(lhcFills).to.be.an('array').and.lengthOf(3) + + lhcFills.forEach((lhcFill) => { + expect(lhcFill.fillingSchemeName).to.equal('schemename') + }); + }) + + it('should only contain matching scheme name, one partial', async () => { + getAllLhcFillsDto.query = { filter: { schemeName: '25ns_2352b_2340_2004_2133' } }; + const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto); + + + expect(lhcFills).to.be.an('array').and.lengthOf(1) + + lhcFills.forEach((lhcFill) => { + expect(lhcFill.fillingSchemeName).to.equal('25ns_2352b_2340_2004_2133_108bpi_24inj') + }); + }) + // Beam duration filter tests it('should only contain specified stable beam durations, < 12:00:00', async () => { getAllLhcFillsDto.query = { filter: { beamDuration: '43200', beamDurationOperator: '<' } }; diff --git a/test/public/lhcFills/overview.test.js b/test/public/lhcFills/overview.test.js index adea7f85fa..39db64559a 100644 --- a/test/public/lhcFills/overview.test.js +++ b/test/public/lhcFills/overview.test.js @@ -255,6 +255,7 @@ module.exports = () => { const meanRunDurationExpect = { selector: 'tbody tr:nth-child(1) td:nth-child(6)', value: '01:40:00' }; const totalRunsDurationExpect = { selector: 'tbody tr:nth-child(1) td:nth-child(7)', value: '05:00:00' }; const efficiencyExpect = { selector: 'tbody tr:nth-child(1) td:nth-child(8)', value: '41.67%' }; + const schemeNameExpect = { selector: '#row6-fillingSchemeName > div:nth-child(1) > div:nth-child(1)', value: 'Single_12b_8_1024_8_2018'}; await goToPage(page, 'lhc-fill-overview'); @@ -264,6 +265,7 @@ module.exports = () => { await expectInnerText(page, meanRunDurationExpect.selector, meanRunDurationExpect.value); await expectInnerText(page, totalRunsDurationExpect.selector, totalRunsDurationExpect.value); await expectInnerText(page, efficiencyExpect.selector, efficiencyExpect.value); + await expectInnerText(page, schemeNameExpect.selector, schemeNameExpect.value); }); it('should successfully display filter elements', async () => { @@ -274,7 +276,7 @@ module.exports = () => { const filterRunDurationExpect = {selector: 'div.flex-row:nth-child(4) > div:nth-child(1)', value: 'Total runs duration'} const filterRunDurationPlaceholderExpect = {selector: '.run-duration-filter', value: 'e.g 16:14:15 (HH:MM:SS)'} const filterBeamTypeExpect = {selector: 'div.flex-row:nth-child(5) > div:nth-child(1)', value: 'Beam Type'} - + const filterSchemeNamePlaceholderExpect = {selector: '.scheme-name-filter', value: 'e.g. Single_12b_8_1024_8_2018'} await goToPage(page, 'lhc-fill-overview'); // Open the filtering panel @@ -286,6 +288,7 @@ module.exports = () => { await expectInnerText(page, filterRunDurationExpect.selector, filterRunDurationExpect.value); await expectAttributeValue(page, filterRunDurationPlaceholderExpect.selector, 'placeholder', filterRunDurationPlaceholderExpect.value); await expectInnerText(page, filterBeamTypeExpect.selector, filterBeamTypeExpect.value); + await expectAttributeValue(page, filterSchemeNamePlaceholderExpect.selector, 'placeholder', filterSchemeNamePlaceholderExpect.value); }); it('should successfully un-apply Stable Beam filter menu', async () => {