Skip to content

Commit 93689a7

Browse files
authored
[O2B-1116] Implement runs per data pass view (#1333)
* rename * reduce test data size * docs * refactor * typo * typo * docs * rename * docs * cleanup * remove dead code * add service * cleanup * add filtering by periods * add data passes seeders * rename * add data passes service tests * test * revoke unfound changes * add controllers * rename * refactor * refactor * refactor * no dependency * refactor * refactor * refactor: * reaname' * rename * cleanup * docs * reaname * refactor * add router * restore * amend test * expose api * add test * add tests * amend * docs * amend test * amend * add Data Passes page * expose page * styling * add reset method * rename * use sorting * add unit * docs * add filtering by data pass id * add test * amend test * amend test * init * use name instead of id * amend test * rename * use name instead of id * put instance * add to view and model * page openable * amend profiles * show qualities * refactor * cleanup * rename * rename * use filtering by name * add test * use generic model * aboid undefined destruciton error * use proper method * amend cell expected content * use in RunsOverviewModel * rename * rename * touched getAllRuns * extend pai * add styling and css * rename * amend test * cleanup * linter * make uppercase * amend test * add test * use correct page * amend dtest * amend test * amend tst * cleanup * amend * use id * use builder * refactor, add spinner * reset exportableItems * corrent condition * refactor * cleanup * replace build href * cleanup * correct filter values: * fixes * cleanup * make detectors fetching prvate * refactor * rename * rename * change error store * refactor * wip * cleanup * amend view * cleanup * unify title styling * unify title styling in RunsPerLhcPeriod * rename * docs correct * refactor * docs * amend test * fix * modify cell value checking * modify width * add badge * amend tests * amend test * docs * use apply * revoke * no by lambda * revoke change * amend apply * amend apply * refactor * refactor * use match * cleanup * rename * rename * revoke export changes * cleanup * refactor * correct docs * change load * typo * add export test * refactor * refactor * test title * Revert "add export test" This reverts commit 7ff5833. * add reverted file * remove reloadPage * linter * add logs * Revert "add logs" This reverts commit 15f4ce9. * change selectors * simplify * amed test WIP * cleanup * amed test WIP * add title * change title * add export test * Revert "add export test" This reverts commit 79e805f. * fix test * add spinner * typo
1 parent d749d57 commit 93689a7

20 files changed

Lines changed: 579 additions & 56 deletions

lib/database/adapters/DataPassAdapter.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ class DataPassAdapter {
3838
lastRunNumber,
3939
} = databaseObject;
4040

41+
const runsCount = databaseObject.get('runsCount');
42+
4143
return {
4244
id,
4345
name,
4446
description,
4547
outputSize,
4648
reconstructedEventsCount,
4749
lastRunNumber,
50+
runsCount,
4851
};
4952
}
5053
}

lib/public/Model.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ export default class Model extends Observable {
192192
case 'runs-per-lhc-period':
193193
this.runs.loadPerLhcPeriodOverview(this.router.params);
194194
break;
195+
case 'runs-per-data-pass':
196+
this.runs.loadPerDataPassOverview(this.router.params);
197+
break;
195198
case 'run-detail':
196199
this.runs.loadDetails(this.router.params);
197200
break;

lib/public/view.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { LhcPeriodsOverviewPage } from './views/lhcPeriods/Overview/LhcPeriodsOv
3737
import { RunsPerLhcPeriodOverviewPage } from './views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewPage.js';
3838
import { HomePage } from './views/Home/Overview/HomePage.js';
3939
import { DataPassesPerLhcPeriodOverviewPage } from './views/DataPasses/PerLhcPeriodOverview/DataPassesPerLhcPeriodOverviewView.js';
40+
import { RunsPerDataPassOverviewPage } from './views/Runs/RunPerDataPass/RunsPerDataPassOverviewPage.js';
4041

4142
/**
4243
* Main view layout
@@ -64,6 +65,7 @@ export default (model) => {
6465
'run-overview': RunsOverviewPage,
6566
'run-detail': RunDetailsPage,
6667
'runs-per-lhc-period': RunsPerLhcPeriodOverviewPage,
68+
'runs-per-data-pass': RunsPerDataPassOverviewPage,
6769

6870
statistics: StatisticsPage,
6971

lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
* or submit itself to any jurisdiction.
1212
*/
1313

14+
import { h } from '/js/src/index.js';
1415
import { textFilter } from '../../../components/Filters/common/filters/textFilter.js';
16+
import { frontLink } from '../../../components/common/navigation/frontLink.js';
1517

1618
/**
1719
* List of active columns for a generic data passes table
@@ -20,12 +22,27 @@ export const dataPassesActiveColumns = {
2022
name: {
2123
name: 'Name',
2224
visible: true,
23-
format: (name) => name,
2425
sortable: true,
2526
filter: ({ namesFilterModel }) => textFilter(
2627
namesFilterModel,
2728
{ class: 'w-75 mt1', placeholder: 'e.g. LHC22a_apass1, ...' },
2829
),
30+
classes: 'w-20',
31+
balloon: true,
32+
},
33+
34+
associatedRuns: {
35+
name: 'Runs',
36+
visible: true,
37+
format: (_, { id, runsCount }) =>
38+
runsCount === 0
39+
? 'No runs'
40+
: frontLink(
41+
h('.flex-row.g3', [h('.f6.badge.bg-gray-light.black', runsCount), 'Runs']),
42+
'runs-per-data-pass',
43+
{ dataPassId: id },
44+
),
45+
classes: 'w-10',
2946
},
3047

3148
description: {
@@ -39,13 +56,15 @@ export const dataPassesActiveColumns = {
3956
format: (reconstructedEventsCount) => reconstructedEventsCount ? reconstructedEventsCount.toLocaleString('en-US') : '-',
4057
visible: true,
4158
sortable: true,
59+
classes: 'w-15',
4260
},
4361

4462
outputSize: {
4563
name: 'Output Size [B]',
4664
visible: true,
4765
format: (outputSize) => outputSize ? outputSize.toLocaleString('en-US') : '-',
4866
sortable: true,
67+
classes: 'w-15',
4968
},
5069

5170
};

lib/public/views/Runs/ActiveColumns/runDetectorsActiveColumns.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ import { formatDetectorQuality } from '../format/formatDetectorQuality.js';
1515
/**
1616
* Factory for detectors related active columns configuration
1717
* @param {Detector[]} detectors detectors list
18+
* @param {object} [options] additional options
19+
* @param {object|string|string[]} [options.profiles] profiles to which the column is restricted to
1820
* @return {object} active columns configuration
1921
*/
20-
export const createRunDetectorsActiveColumns = (detectors) => Object.fromEntries(detectors?.map(({ name: detectorName }) => [
22+
export const createRunDetectorsActiveColumns = (detectors, { profiles } = {}) => Object.fromEntries(detectors?.map(({ name: detectorName }) => [
2123
detectorName, {
2224
name: detectorName.toUpperCase(),
2325
visible: true,
2426
format: (_, run) => formatDetectorQuality(run.detectorsQualities.find(({ name }) => name === detectorName)?.quality),
25-
profiles: ['runsPerLhcPeriod'],
27+
profiles,
2628
},
2729
]) ?? []);

lib/public/views/Runs/ActiveColumns/runsActiveColumns.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,15 @@ export const runsActiveColumns = {
8484
],
8585
),
8686
profiles: {
87+
home: true,
8788
lhcFill: true,
8889
environment: true,
8990
runsPerLhcPeriod: {
9091
classes: 'w-7 f6 w-wrapped',
9192
},
92-
home: true,
93+
runsPerDataPass: {
94+
classes: 'w-7 f6 w-wrapped',
95+
},
9396
},
9497
},
9598
detectors: {
@@ -120,6 +123,9 @@ export const runsActiveColumns = {
120123
runsPerLhcPeriod: {
121124
classes: 'w-2 f6',
122125
},
126+
runsPerDataPass: {
127+
classes: 'w-2 f6',
128+
},
123129
},
124130
classes: 'w-5 f6',
125131
format: (fill, run) => fill !== null && run.lhcBeamMode === BeamModes.STABLE_BEAMS
@@ -152,6 +158,10 @@ export const runsActiveColumns = {
152158
runsPerLhcPeriod: {
153159
classes: 'f6 w-wrapped',
154160
},
161+
runsPerDataPass: {
162+
classes: 'f6 w-wrapped',
163+
},
164+
155165
},
156166
},
157167
timeO2End: {
@@ -172,6 +182,9 @@ export const runsActiveColumns = {
172182
runsPerLhcPeriod: {
173183
classes: 'f6 w-wrapped',
174184
},
185+
runsPerDataPass: {
186+
classes: 'f6 w-wrapped',
187+
},
175188
},
176189
},
177190
timeTrgStart: {
@@ -185,6 +198,10 @@ export const runsActiveColumns = {
185198
visible: true,
186199
classes: 'f6 w-wrapped',
187200
},
201+
runsPerDataPass: {
202+
visible: true,
203+
classes: 'f6 w-wrapped',
204+
},
188205
},
189206
},
190207
timeTrgEnd: {
@@ -198,6 +215,10 @@ export const runsActiveColumns = {
198215
visible: true,
199216
classes: 'f6 w-wrapped',
200217
},
218+
runsPerDataPass: {
219+
visible: true,
220+
classes: 'f6 w-wrapped',
221+
},
201222
},
202223
},
203224
timeSincePreviousRun: {
@@ -405,12 +426,12 @@ export const runsActiveColumns = {
405426
name: 'L3 [A]',
406427
visible: true,
407428
format: (_, run) => formatAliceCurrent(run.aliceL3Polarity, run.aliceL3Current),
408-
profiles: ['runsPerLhcPeriod'],
429+
profiles: ['runsPerLhcPeriod', 'runsPerDataPass'],
409430
},
410431
dipoleCurrent: {
411432
name: 'Dipole [A]',
412433
visible: true,
413434
format: (_, run) => formatAliceCurrent(run.aliceDipolePolarity, run.aliceDipoleCurrent),
414-
profiles: ['runsPerLhcPeriod'],
435+
profiles: ['runsPerLhcPeriod', 'runsPerDataPass'],
415436
},
416437
};
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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+
import { RemoteData } from '/js/src/index.js';
14+
import { buildUrl } from '../../../utilities/fetch/buildUrl.js';
15+
import { detectorsProvider } from '../../../services/detectors/detectorsProvider.js';
16+
import { RunsOverviewModel } from '../Overview/RunsOverviewModel.js';
17+
import { ObservableData } from '../../../utilities/ObservableData.js';
18+
import { getRemoteDataSlice } from '../../../utilities/fetch/getRemoteDataSlice.js';
19+
20+
/**
21+
* Runs Per Data Pass overview model
22+
*/
23+
export class RunsPerDataPassOverviewModel extends RunsOverviewModel {
24+
/**
25+
* Constructor
26+
* @param {Model} model global model
27+
*/
28+
constructor(model) {
29+
super(model);
30+
this._detectors = new ObservableData(RemoteData.notAsked());
31+
this._detectors.bubbleTo(this);
32+
this._dataPass = new ObservableData(RemoteData.notAsked());
33+
this._dataPass.bubbleTo(this);
34+
}
35+
36+
/**
37+
* Retrieve a list of detector types from detectorsProvider
38+
*
39+
* @return {Promise<void>} resolves once the data has been fetched
40+
* @private
41+
*/
42+
async _fetchDetectors() {
43+
this._detectors.setCurrent(RemoteData.loading());
44+
try {
45+
this._detectors.setCurrent(RemoteData.success(await detectorsProvider.getAll()));
46+
} catch (error) {
47+
this._detectors.setCurrent(RemoteData.failure(error));
48+
}
49+
}
50+
51+
/**
52+
* Fetch data pass data which runs are fetched
53+
* @return {Promise<void>} promise
54+
*/
55+
async _fetchDataPass() {
56+
this._dataPass.setCurrent(RemoteData.loading());
57+
try {
58+
const { items: [dataPass] = [] } = await getRemoteDataSlice(`/api/dataPasses?filter[ids][]=${this._dataPassId}`);
59+
this._dataPass.setCurrent(RemoteData.success(dataPass));
60+
} catch (error) {
61+
this._dataPass.setCurrent(RemoteData.failure(error));
62+
}
63+
}
64+
65+
// eslint-disable-next-line valid-jsdoc
66+
/**
67+
* @inheritdoc
68+
*/
69+
async load() {
70+
if (!this._dataPassId) {
71+
return;
72+
}
73+
this._fetchDetectors();
74+
this._fetchDataPass();
75+
super.load();
76+
}
77+
78+
// eslint-disable-next-line valid-jsdoc
79+
/**
80+
* @inheritdoc
81+
*/
82+
getRootEndpoint() {
83+
const endpint = super.getRootEndpoint();
84+
return buildUrl(endpint, { filter: {
85+
dataPassIds: [this._dataPassId],
86+
runQualities: 'good',
87+
definitions: 'PHYSICS',
88+
} });
89+
}
90+
91+
/**
92+
* Set id of data pass which runs are to be fetched
93+
* @param {number} dataPassId id of Data Pass
94+
*/
95+
set dataPassId(dataPassId) {
96+
this._dataPassId = dataPassId;
97+
}
98+
99+
/**
100+
* Get current data pass which runs are fetched
101+
*/
102+
get dataPass() {
103+
return this._dataPass.getCurrent();
104+
}
105+
106+
/**
107+
* Get all detectors
108+
* @return {RemoteData<Detector[]>} detectors
109+
*/
110+
get detectors() {
111+
return this._detectors.getCurrent();
112+
}
113+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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 { table } from '../../../components/common/table/table.js';
16+
import { createRunDetectorsActiveColumns } from '../ActiveColumns/runDetectorsActiveColumns.js';
17+
import { paginationComponent } from '../../../components/Pagination/paginationComponent.js';
18+
import { estimateDisplayableRowsCount } from '../../../utilities/estimateDisplayableRowsCount.js';
19+
import { exportRunsTriggerAndModal } from '../Overview/exportRunsTriggerAndModal.js';
20+
import { runsActiveColumns } from '../ActiveColumns/runsActiveColumns.js';
21+
import spinner from '../../../components/common/spinner.js';
22+
23+
const TABLEROW_HEIGHT = 59;
24+
// Estimate of the navbar and pagination elements height total; Needs to be updated in case of changes;
25+
const PAGE_USED_HEIGHT = 215;
26+
27+
/**
28+
* Render Runs Per LHC Period overview page
29+
* @param {Model} model The overall model object.
30+
* @param {Model} [model.runs.perDataPassOverviewModel] model holding state for of the page
31+
* @return {Component} The overview page
32+
*/
33+
export const RunsPerDataPassOverviewPage = ({ runs: { perDataPassOverviewModel }, modalModel }) => {
34+
perDataPassOverviewModel.pagination.provideDefaultItemsPerPage(estimateDisplayableRowsCount(
35+
TABLEROW_HEIGHT,
36+
PAGE_USED_HEIGHT,
37+
));
38+
39+
const { items: runs, detectors, dataPass } = perDataPassOverviewModel;
40+
41+
const activeColumns = {
42+
...runsActiveColumns,
43+
...createRunDetectorsActiveColumns(detectors.match({
44+
Success: (payload) => payload,
45+
Other: () => [],
46+
}), { profiles: 'runsPerDataPass' }),
47+
};
48+
49+
return h('', [
50+
h('.flex-row.justify-between.items-center', [
51+
dataPass.match({
52+
Success: (payload) => h('h2', `Good, physics runs of ${payload.name}`),
53+
Failure: () => h('h2.danger', 'Failed to fetch Data Pass information'),
54+
Loading: () => h('.p1', spinner({ size: 2, absolute: false })),
55+
NotAsked: () => h('h2', 'Good, physics runs'),
56+
}),
57+
exportRunsTriggerAndModal(perDataPassOverviewModel, modalModel),
58+
]),
59+
h('.flex-column.w-100', [
60+
table(runs, activeColumns, null, { profile: 'runsPerDataPass' }),
61+
paginationComponent(perDataPassOverviewModel.pagination),
62+
]),
63+
]);
64+
};

0 commit comments

Comments
 (0)