From 60df82ebb38db786712e75ebd066d7d21ed5f430 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Fri, 31 Jul 2026 14:20:42 +0200 Subject: [PATCH 1/3] Generalize BeamTypeFilterModel to accept a provider --- .../LhcFillsFilter/BeamTypeFilterModel.js | 20 ++++--------- .../beamTypes/pdpBeamTypesProvider.js | 30 +++++++++++++++++++ .../Overview/LhcFillsOverviewModel.js | 3 +- .../views/Runs/Overview/RunsOverviewModel.js | 5 +++- 4 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 lib/public/services/beamTypes/pdpBeamTypesProvider.js diff --git a/lib/public/components/Filters/LhcFillsFilter/BeamTypeFilterModel.js b/lib/public/components/Filters/LhcFillsFilter/BeamTypeFilterModel.js index fc0964da04..0341616057 100644 --- a/lib/public/components/Filters/LhcFillsFilter/BeamTypeFilterModel.js +++ b/lib/public/components/Filters/LhcFillsFilter/BeamTypeFilterModel.js @@ -11,26 +11,18 @@ * or submit itself to any jurisdiction. */ -import { beamTypesProvider } from '../../../services/beamTypes/beamTypesProvider.js'; -import { SelectionModel } from '../../common/selection/SelectionModel.js'; +import { ObservableBasedSelectionDropdownModel } from '../../detector/ObservableBasedSelectionDropdownModel.js'; /** * Beam type filter model */ -export class BeamTypeFilterModel extends SelectionModel { +export class BeamTypeFilterModel extends ObservableBasedSelectionDropdownModel { /** * Constructor + * + * @param {ObservableData>} beamTypes$ observable remote data of objects representing beam types */ - constructor() { - super({}); - - beamTypesProvider.items$.observe(() => { - beamTypesProvider.items$.getCurrent().apply({ - Success: (types) => { - const beamTypes = types.map((type) => ({ value: type.beam_type })); - this.setAvailableOptions(beamTypes); - }, - }); - }); + constructor(beamTypes$) { + super(beamTypes$, ({ name, beam_type }) => ({ value: name ?? beam_type })); } } diff --git a/lib/public/services/beamTypes/pdpBeamTypesProvider.js b/lib/public/services/beamTypes/pdpBeamTypesProvider.js new file mode 100644 index 0000000000..fd99ad92a3 --- /dev/null +++ b/lib/public/services/beamTypes/pdpBeamTypesProvider.js @@ -0,0 +1,30 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. 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-o2.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 { getRemoteData } from '../../utilities/fetch/getRemoteData.js'; +import { RemoteDataProvider } from '../RemoteDataProvider.js'; + +/** + * Service class to fetch beams types from the backend + */ +export class PdpBeamTypesProvider extends RemoteDataProvider { + /** + * @inheritDoc + */ + async getRemoteData() { + const { data } = await getRemoteData('/api/runs/pdpBeamTypes'); + return data; + } +} + +export const pdpBeamTypesProvider = new PdpBeamTypesProvider(); diff --git a/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js b/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js index 3e73c2fa0f..4ab9ed78d4 100644 --- a/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js +++ b/lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js @@ -18,6 +18,7 @@ import { TextComparisonFilterModel } from '../../../components/Filters/common/fi import { TimeRangeFilterModel } from '../../../components/Filters/RunsFilter/TimeRangeFilter.js'; import { ToggleFilterModel } from '../../../components/Filters/common/filters/ToggleFilterModel.js'; import { FilterableOverviewPageModel } from '../../../models/FilterableOverviewPageModel.js'; +import { beamTypesProvider } from '../../../services/beamTypes/beamTypesProvider.js'; /** * Model for the LHC fills overview page @@ -43,7 +44,7 @@ export class LhcFillsOverviewModel extends FilterableOverviewPageModel { hasStableBeams: new ToggleFilterModel(stableBeamsOnly, true), stableBeamsStart: new TimeRangeFilterModel(), stableBeamsEnd: new TimeRangeFilterModel(), - beamTypes: new BeamTypeFilterModel(), + beamTypes: new BeamTypeFilterModel(beamTypesProvider.items$), schemeName: new RawTextFilterModel(), }, ); diff --git a/lib/public/views/Runs/Overview/RunsOverviewModel.js b/lib/public/views/Runs/Overview/RunsOverviewModel.js index af658e36ad..42dc413f8a 100644 --- a/lib/public/views/Runs/Overview/RunsOverviewModel.js +++ b/lib/public/views/Runs/Overview/RunsOverviewModel.js @@ -32,6 +32,8 @@ import { DataExportModel } from '../../../models/DataExportModel.js'; import { runsActiveColumns as dataExportConfiguration } from '../ActiveColumns/runsActiveColumns.js'; import { BeamModeFilterModel } from '../../../components/Filters/RunsFilter/BeamModeFilterModel.js'; import { beamModesProvider } from '../../../services/beamModes/beamModesProvider.js'; +import { pdpBeamTypesProvider } from '../../../services/beamTypes/pdpBeamTypesProvider.js'; +import { beamTypesProvider } from '../../../services/beamTypes/beamTypesProvider.js'; import { RadioButtonFilterModel } from '../../../components/Filters/common/RadioButtonFilterModel.js'; import { SelectionModel } from '../../../components/common/selection/SelectionModel.js'; import { TRIGGER_VALUES } from '../../../domain/enums/TriggerValue.js'; @@ -96,7 +98,8 @@ export class RunsOverviewModel extends FilterableOverviewPageModel { dcs: new RadioButtonFilterModel([{ label: 'ANY' }, { label: 'ON', value: true }, { label: 'OFF', value: false }]), epn: new RadioButtonFilterModel([{ label: 'ANY' }, { label: 'ON', value: true }, { label: 'OFF', value: false }]), triggerValues: new SelectionModel({ availableOptions: TRIGGER_VALUES.map((value) => ({ label: value, value })) }), - beamTypes: new BeamTypeFilterModel(), + beamTypes: new BeamTypeFilterModel(beamTypesProvider.items$), + pdpBeamTypes: new BeamTypeFilterModel(pdpBeamTypesProvider.items$), }, ); From 34ad98673dd024131d85bbbd440183551ef05b77 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Fri, 31 Jul 2026 14:20:50 +0200 Subject: [PATCH 2/3] Add widget for filtering on runs by pdp beam type --- .../views/Runs/ActiveColumns/runsActiveColumns.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/public/views/Runs/ActiveColumns/runsActiveColumns.js b/lib/public/views/Runs/ActiveColumns/runsActiveColumns.js index f121d791ad..46dd31bfed 100644 --- a/lib/public/views/Runs/ActiveColumns/runsActiveColumns.js +++ b/lib/public/views/Runs/ActiveColumns/runsActiveColumns.js @@ -44,7 +44,6 @@ import { numericalComparisonFilter } from '../../../components/Filters/common/fi import { checkboxes } from '../../../components/Filters/common/filters/checkboxFilter.js'; import radioButtonFilter from '../../../components/Filters/common/filters/radioButtonFilter.js'; import { textInputFilter } from '../../../components/Filters/common/filters/textInputFilter.js'; -import { beamTypeFilter } from '../../../components/Filters/LhcFillsFilter/beamTypeFilter.js'; /** * List of active columns for a generic runs table @@ -588,11 +587,18 @@ export const runsActiveColumns = { pdpBeamType: { name: 'PDP Beam Type', visible: false, + filter: (runsOverviewModel) => selectionDropdown( + runsOverviewModel.filteringModel.get('pdpBeamTypes'), + { selectorPrefix: 'pdp-beam-types' }, + ), }, beamType: { name: 'Beam Type', visible: false, - filter: (runsOverviewModel) => beamTypeFilter(runsOverviewModel.filteringModel.get('beamTypes')), + filter: (runsOverviewModel) => selectionDropdown( + runsOverviewModel.filteringModel.get('beamTypes'), + { selectorPrefix: 'beam-types' }, + ), }, readoutCfgUri: { name: 'Readout Config URI', From 97eacb4ea460ea9bc0ebd74a6e67ac610e558617 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Fri, 31 Jul 2026 14:38:39 +0200 Subject: [PATCH 3/3] Fix tests on overview lhc fills --- .../Filters/LhcFillsFilter/beamTypeFilter.js | 22 ------------------- .../ActiveColumns/lhcFillsActiveColumns.js | 7 ++++-- test/public/lhcFills/overview.test.js | 5 +++-- 3 files changed, 8 insertions(+), 26 deletions(-) delete mode 100644 lib/public/components/Filters/LhcFillsFilter/beamTypeFilter.js diff --git a/lib/public/components/Filters/LhcFillsFilter/beamTypeFilter.js b/lib/public/components/Filters/LhcFillsFilter/beamTypeFilter.js deleted file mode 100644 index 83f1487922..0000000000 --- a/lib/public/components/Filters/LhcFillsFilter/beamTypeFilter.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @license - * Copyright CERN and copyright holders of ALICE O2. 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-o2.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 { checkboxes } from '../common/filters/checkboxFilter.js'; - -/** - * Renders a list of checkboxes that lets the user look for beam types - * - * @param {BeamTypeFilterModel} beamTypeFilterModel beamTypeFilterModel - * @return {Component} the filter - */ -export const beamTypeFilter = (beamTypeFilterModel) => checkboxes(beamTypeFilterModel, { selector: 'beam-types' }); diff --git a/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js b/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js index be4311d7e4..afc49d80f2 100644 --- a/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js +++ b/lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js @@ -21,11 +21,11 @@ import { formatRunsList } from '../../Runs/format/formatRunsList.js'; import { formatLhcFillsTimeLoss } from '../format/formatLhcFillsTimeLoss.js'; import { buttonLinkWithDropdown } from '../../../components/common/selection/infoLoggerButtonGroup/buttonLinkWithDropdown.js'; import { infologgerLinksComponents } from '../../../components/common/externalLinks/infologgerLinksComponents.js'; +import { selectionDropdown } from '../../../components/common/selection/dropdown/selectionDropdown.js'; import { formatBeamType } from '../../../utilities/formatting/formatBeamType.js'; import { frontLink } from '../../../components/common/navigation/frontLink.js'; import { toggleFilter } from '../../../components/Filters/common/filters/toggleFilter.js'; import { durationFilter } from '../../../components/Filters/LhcFillsFilter/durationFilter.js'; -import { beamTypeFilter } from '../../../components/Filters/LhcFillsFilter/beamTypeFilter.js'; import { timeRangeFilter } from '../../../components/Filters/common/filters/timeRangeFilter.js'; import { textInputFilter } from '../../../components/Filters/common/filters/textInputFilter.js'; @@ -187,7 +187,10 @@ export const lhcFillsActiveColumns = { visible: true, size: 'w-8', format: (value) => formatBeamType(value), - filter: (lhcFillModel) => beamTypeFilter(lhcFillModel.filteringModel.get('beamTypes')), + filter: (lhcFillModel) => selectionDropdown( + lhcFillModel.filteringModel.get('beamTypes'), + { selectorPrefix: 'beam-types' }, + ), }, collidingBunches: { name: 'Colliding bunches', diff --git a/test/public/lhcFills/overview.test.js b/test/public/lhcFills/overview.test.js index e5acd2c10e..dc083605c2 100644 --- a/test/public/lhcFills/overview.test.js +++ b/test/public/lhcFills/overview.test.js @@ -349,13 +349,14 @@ module.exports = () => { }); it('should successfully apply beam types filter', async () => { - const filterBeamTypeP_Pb = '#beam-types-checkbox-p-Pb'; - const filterBeamTypePb_Pb = '#beam-types-checkbox-Pb-Pb'; + const filterBeamTypeP_Pb = '#beam-types-dropdown-option-p-Pb'; + const filterBeamTypePb_Pb = '#beam-types-dropdown-option-Pb-Pb'; await goToPage(page, 'lhc-fill-overview'); await waitForTableLength(page, 5); await openFilteringPanel(page); + await pressElement(page, '.beamType-filter .dropdown-trigger', true); await pressElement(page, filterBeamTypeP_Pb); await waitForTableLength(page, 1);