Skip to content
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,78 @@ export class RunsPerLhcPeriodOverviewModel extends RunsWithQcModel {

this._syncDetectors$.bubbleTo(this);

this._lhcPeriodId = null;
this._lhcPeriodStatistics$ = new ObservableData(RemoteData.notAsked());
this._lhcPeriodStatistics$.bubbleTo(this);

this._tabbedPanelModel = new RunsPerLhcPeriodTabbedPanelModel();
this._tabbedPanelModel.bubbleTo(this);
}

/**
* Fetch LHC period data which runs are fetched
* @return {Promise<void>} promise
*/
async _fetchLhcPeriod() {
this._lhcPeriodStatistics$.setCurrent(RemoteData.loading());
try {
const { data: [lhcPeriodStatistics] } = await jsonFetch(`/api/lhcPeriodsStatistics?filter[ids][]=${this._lhcPeriodId}`);
this._lhcPeriodStatistics$.setCurrent(RemoteData.success(lhcPeriodStatistics));
} catch (error) {
this._lhcPeriodStatistics$.setCurrent(RemoteData.failure(error));
}
}

/**
* @inheritdoc
*/
async load() {
if (!this._lhcPeriodId) {
return;
}

await this._fetchLhcPeriod();
super.load();
}

/**
* @inheritdoc
*/
getRootEndpoint() {
return buildUrl(super.getRootEndpoint(), {
filter: {
lhcPeriods: this._lhcPeriodName,
lhcPeriodIds: [this._lhcPeriodId],
runQualities: 'good',
definitions: 'PHYSICS',
},
});
}

/**
* Get name of current lhc period which runs are fetched
* Get LHC period which runs are fetched
*/
get lhcPeriodStatistics() {
return this._lhcPeriodStatistics$.getCurrent();
}

/**
* Set id of current LHC period which runs are fetched
*
* @param {string} lhcPeriodId id of a LHC period
*/
get lhcPeriodName() {
return this._lhcPeriodName;
set lhcPeriodId(lhcPeriodId) {
this._lhcPeriodId = lhcPeriodId;
this._tabbedPanelModel.lhcPeriodId = lhcPeriodId;
}

/**
* Set name of current lhc period which runs are fetched
* Set mcReproducibleAsNotBad flag
*
* @param {string} lhcPeriodName name of LHC period
* @param {boolean} mcReproducibleAsNotBad new value
*/
set lhcPeriodName(lhcPeriodName) {
this._lhcPeriodName = lhcPeriodName;
this._tabbedPanelModel.lhcPeriodName = lhcPeriodName;
setMcReproducibleAsNotBad(mcReproducibleAsNotBad) {
super.setMcReproducibleAsNotBad(mcReproducibleAsNotBad);
this._tabbedPanelModel.mcReproducibleAsNotBad = mcReproducibleAsNotBad;
}

/**
Expand Down Expand Up @@ -141,17 +181,18 @@ class RunsPerLhcPeriodTabbedPanelModel extends TabbedPanelModel {
* @return {Promise<void>} resolved once data are fetched
*/
async _fetchSynchronousQcSummary() {
if (this._lhcPeriodName) {
if (this._lhcPeriodId) {
this.currentPanelData = RemoteData.loading();
this.notify();
try {
const { data: [lhcPeriod] } = await jsonFetch(`/api/lhcPeriodsStatistics?filter[names][]=${this._lhcPeriodName}`);
if (!lhcPeriod) {
this.currentPanelData = RemoteData.failure([{ title: `Cannot find LHC period with name '${this._lhcPeriodName}'` }]);
} else {
const { data: qcSummary } = await jsonFetch(`/api/qcFlags/summary?lhcPeriodId=${lhcPeriod.id}`);
this.currentPanelData = RemoteData.success(qcSummary);
}
const { data: qcSummary } = await jsonFetch(buildUrl(
'/api/qcFlags/summary',
{
lhcPeriodId: this._lhcPeriodId,
mcReproducibleAsNotBad: this._mcReproducibleAsNotBad,
},
));
this.currentPanelData = RemoteData.success(qcSummary);
} catch (errors) {
this.currentPanelData = RemoteData.failure(errors);
}
Expand All @@ -160,12 +201,22 @@ class RunsPerLhcPeriodTabbedPanelModel extends TabbedPanelModel {
}

/**
* Set LHC period name
* Set LHC period id
*
* @param {id} lhcPeriodId id of LHC period
*/
set lhcPeriodId(lhcPeriodId) {
this._lhcPeriodId = lhcPeriodId;
this._fetchCurrentPanelData();
}

/**
* Set mcReproducibleAsNotBad flag
*
* @param {string} lhcPeriodName name of LHC period
* @param {boolean} mcReproducibleAsNotBad new value
*/
set lhcPeriodName(lhcPeriodName) {
this._lhcPeriodName = lhcPeriodName;
set mcReproducibleAsNotBad(mcReproducibleAsNotBad) {
this._mcReproducibleAsNotBad = mcReproducibleAsNotBad;
this._fetchCurrentPanelData();
}
}
123 changes: 73 additions & 50 deletions lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ import { runDetectorsSyncQcActiveColumns } from '../ActiveColumns/runDetectorsSy
import { tabbedPanelComponent } from '../../../components/TabbedPanel/tabbedPanelComponent.js';
import { RUNS_PER_LHC_PERIOD_PANELS_KEYS } from './RunsPerLhcPeriodOverviewModel.js';
import { PdpBeamType } from '../../../domain/enums/PdpBeamType.js';
import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js';
import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js';
import { mergeRemoteData } from '../../../utilities/mergeRemoteData.js';
import errorAlert from '../../../components/common/errorAlert.js';
import spinner from '../../../components/common/spinner.js';
import { mcReproducibleAsNotBadToggle } from '../mcReproducibleAsNotBadToggle.js';
import { exportTriggerAndModal } from '../../../components/common/dataExport/exportTriggerAndModal.js';

const TABLEROW_HEIGHT = 62;
Expand Down Expand Up @@ -53,44 +59,29 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel

const {
items: remoteRuns,
lhcPeriodStatistics: remoteLhcPeriodStatistics,
onlineDetectors: remoteOnlineDetectors,
syncDetectors: remoteSyncDetectors,
lhcPeriodName,
displayOptions,
sortModel,
tabbedPanelModel,
mcReproducibleAsNotBad,
} = perLhcPeriodOverviewModel;

const activeColumns = {
...runsActiveColumns,
...remoteRuns.match({
Success: (runs) => runs.some((run) => run.pdpBeamType === PdpBeamType.LEAD_LEAD)
? inelasticInteractionRateActiveColumnsForPbPb
: {},
Other: () => {},
}),
...remoteRuns.match({
Success: (runs) => runs.some((run) => run.pdpBeamType === PdpBeamType.PROTON_PROTON)
? inelasticInteractionRateActiveColumnsForProtonProton
: {},
Other: () => {},
}),
};

/**
* Render runs table with given detectors' active columns configuration
*
* @param {object} detectorsActiveColumns active columns
* @param {object} activeColumns common acctivte column
* @param {object} detectorsActiveColumns detectors specific columns
* @return {Component} table with pagination
*/
const getTableWithGivenDetectorsColumns = (detectorsActiveColumns) =>
const getTableWithGivenDetectorsColumns = (activeColumns, detectorsActiveColumns) =>
table(

/*
* Columns depends on detectors' list, it's not useful to render the table when detectors are missing
* TODO replace by RemoteData merging
*/
remoteOnlineDetectors.match({ Success: () => remoteRuns, Other: () => remoteOnlineDetectors }),
remoteRuns,
{
...activeColumns,
...detectorsActiveColumns,
Expand All @@ -104,37 +95,69 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel
{ sort: sortModel },
);

return h('.intermediate-flex-column', [
h('.flex-row.justify-between.g2', [
h('h2', `Good, physics runs of ${lhcPeriodName}`),
exportTriggerAndModal(perLhcPeriodOverviewModel.exportModel, modalModel),
]),
...tabbedPanelComponent(
tabbedPanelModel,
{
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.DETECTOR_QUALITIES]: 'Qualities of detectors',
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.SYNCHRONOUS_FLAGS]: 'Synchronous QC flags',
},
{
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.DETECTOR_QUALITIES]:
() => getTableWithGivenDetectorsColumns(runDetectorsQualitiesActiveColumns(
remoteOnlineDetectors.match({ Success: (payload) => payload, Other: () => [] }),
{ profiles: 'runsPerLhcPeriod' },
)),
return h(
'.intermediate-flex-column',
{ onremove: () => perLhcPeriodOverviewModel.reset(false) },
mergeRemoteData([remoteLhcPeriodStatistics, remoteRuns]).match({
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
Success: ([lhcPeriodStatistics, runs]) => {
const activeColumns = {
...runsActiveColumns,
...runs.some((run) => run.pdpBeamType === PdpBeamType.LEAD_LEAD) ? inelasticInteractionRateActiveColumnsForPbPb : {},
...runs.some((run) => run.pdpBeamType === PdpBeamType.PROTON_PROTON)
? inelasticInteractionRateActiveColumnsForProtonProton : {},
};

[RUNS_PER_LHC_PERIOD_PANELS_KEYS.SYNCHRONOUS_FLAGS]:
(remoteSynchronousQcSummary) => getTableWithGivenDetectorsColumns(runDetectorsSyncQcActiveColumns(
remoteSyncDetectors.match({ Success: (payload) => payload, Other: () => [] }),
return [
h('.flex-row.justify-between.items-center.g2', [
filtersPanelPopover(perLhcPeriodOverviewModel, activeColumns, { profile: 'runsPerLhcPeriod' }),
h('.pl2#runOverviewFilter', runNumbersFilter(perLhcPeriodOverviewModel.filteringModel.get('runNumbers'))),
h('h2', `Good, physics runs of ${lhcPeriodStatistics.lhcPeriod.name}`),
mcReproducibleAsNotBadToggle(
mcReproducibleAsNotBad,
() => perLhcPeriodOverviewModel.setMcReproducibleAsNotBad(!mcReproducibleAsNotBad),
),
exportTriggerAndModal(perLhcPeriodOverviewModel.exportModel, modalModel),
]),
...tabbedPanelComponent(
tabbedPanelModel,
{
profiles: 'runsPerLhcPeriod',
qcSummary: remoteSynchronousQcSummary.match({ Success: (qcSummary) => qcSummary, Other: () => null }),
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.DETECTOR_QUALITIES]: 'Qualities of detectors',
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.SYNCHRONOUS_FLAGS]: 'Synchronous QC flags',
},
)),
},
{
panelClass: ['scroll-auto'],
{
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.DETECTOR_QUALITIES]: () => remoteOnlineDetectors.match({
Success: (onlineDetectors) => getTableWithGivenDetectorsColumns(
activeColumns,
runDetectorsQualitiesActiveColumns(onlineDetectors, { profiles: 'runsPerLhcPeriod' }),
),
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
}),

[RUNS_PER_LHC_PERIOD_PANELS_KEYS.SYNCHRONOUS_FLAGS]: (remoteSynchronousQcSummary) =>
mergeRemoteData([remoteSynchronousQcSummary, remoteSyncDetectors]).match({
Success: ([synchronousQcSummary, syncDetectors]) => getTableWithGivenDetectorsColumns(
activeColumns,
runDetectorsSyncQcActiveColumns(syncDetectors, {
profiles: 'runsPerLhcPeriod',
qcSummary: synchronousQcSummary,
}),
),
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
}),
},
{ panelClass: ['scroll-auto'] },
),
paginationComponent(perLhcPeriodOverviewModel.pagination),
];
},
),
paginationComponent(perLhcPeriodOverviewModel.pagination),
]);
}),

);
};
6 changes: 3 additions & 3 deletions lib/public/views/Runs/RunsModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ export class RunsModel extends Observable {
/**
* Load runs overview data
* @param {object} params the parameters for the model
* @param {string} [params.lhcPeriodName] the name of the LHC period to display
* @param {string} [params.lhcPeriodId] the id of the LHC period to display
* @param {string} [params.panel] the key of the panel to display
* @return {void}
*/
loadPerLhcPeriodOverview({ lhcPeriodName, panel }) {
loadPerLhcPeriodOverview({ lhcPeriodId, panel }) {
this._perLhcPeriodOverviewModel.tabbedPanelModel.currentPanelKey = panel;
if (!this._perLhcPeriodOverviewModel.pagination.isInfiniteScrollEnabled) {
this._perLhcPeriodOverviewModel.lhcPeriodName = lhcPeriodName;
this._perLhcPeriodOverviewModel.lhcPeriodId = lhcPeriodId;
this._perLhcPeriodOverviewModel.load();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ export const lhcPeriodsActiveColumns = {
associatedRuns: {
name: 'Runs',
visible: true,
format: (_, { name, runsCount }) =>
format: (_, { id, runsCount }) =>
runsCount === 0
? 'No runs'
: frontLink(
badge(runsCount),
'runs-per-lhc-period',
{ lhcPeriodName: name },
{ lhcPeriodId: id },
),
classes: 'w-10',
},
Expand Down
6 changes: 3 additions & 3 deletions test/public/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -781,15 +781,15 @@ module.exports.testTableSortingByColumn = async (page, columnId) => {
const notOrderData = await getColumnCellsInnerTexts(page, columnId);

// Sort in ASCENDING manner
await this.pressElement(page, `th#${columnId}`);
await this.pressElement(page, `th#${columnId}`, true);
this.expectColumnValues(page, columnId, [...notOrderData].sort());

// Sort in DESCENDING manner
await this.pressElement(page, `th#${columnId}`);
await this.pressElement(page, `th#${columnId}`, true);
this.expectColumnValues(page, columnId, [...notOrderData].sort().reverse());

// Revoke sorting
await this.pressElement(page, `th#${columnId}`);
await this.pressElement(page, `th#${columnId}`, true);
this.expectColumnValues(page, columnId, notOrderData);
};

Expand Down
Loading
Loading