Skip to content

Commit 045cba6

Browse files
[O2B-1125] Implement Simulation Passes per Data Pass view (#1370)
* seeders completed * test completed * ad controller * api completed * amend test| * test * test completed * add model and view * view works * expose view * cleanup * add model * use common styling * test wip, change strability * change sortability * extend test * extend tests * test completed * amend test * extract jiraId * rename * change types * fix * amend * add jira links * add per data pass * a * expose anchored * rename * test WIP * rename * rename * amend test * one migration file * add comment * rename * one migration file * association def * asso as plural * remove queryBuilder * amend test * remove filed specifier * enhance test * rename asso * separate * resize, balloon * cleanup * cleanup * restore queryBuilder * amend cells values types checking * rename to anchored * rename page name * add balloon * correct docs * change error * revoke * add \n * sync in scheduler * cleanup * cleanup * prettify * rename * rename * restore * add one more sim pass * cleanup * typo * refactor * update expected length * revoke changes * extend test * add get one sim pass endpoint * amend test * add fetching period * add title * greater gap * docs * cleanup * change regex * remove slash * typo * typo * docs * simplify function * docs * rename MonALISA to MonAlisa * rename * rename * rename * refactor * docs * update docs * correct * hide stuff * amend test * rename ALISA to Alisa * rename files * add counts: * update test * update test * use breadcrumbs * rename * rename * docs * cleanup * test WIP * test ok * add breadcumbs checking * revoke * tmp test amend * typo * refactor * rename * revoke * tests * tests ok * extend seeder * amend test * amend * merge main * t WIP * waitForTableReaload * refactor * extract function * typo{ * typo * apply comments * docs * restyle * refactor * refactor * typo * refactor * refactor breadcrumbs * tesfactor * change unit display to use () * change unit display to use () * extract only needed information * Update lib/public/utilities/formatting/formatItemsCount.js Co-authored-by: Martin Boulais <31805063+martinboulais@users.noreply.github.com> * Update lib/public/components/common/navigation/breadcrumbs.js Co-authored-by: Martin Boulais <31805063+martinboulais@users.noreply.github.com> * linter * refactor * refactor{ * fix * simplify error message * cleanup * refactor * rename * title no wrap * linter * update test * typod * refactor * refactor newlines * update test * amend test * test * test * amend test * refactor * refactor * fixes * comments * extend ordering test * test ok * rename * rename --------- Co-authored-by: Martin Boulais <31805063+martinboulais@users.noreply.github.com>
1 parent e2bcdad commit 045cba6

10 files changed

Lines changed: 469 additions & 4 deletions

File tree

lib/public/Model.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ export default class Model extends Observable {
174174
case 'simulation-passes-per-lhc-period-overview':
175175
this.simulationPasses.loadPerLhcPeriodOverview(this.router.params);
176176
break;
177+
case 'anchored-simulation-passes-overview':
178+
this.simulationPasses.loadAnchoredOverview(this.router.params);
179+
break;
177180
case 'env-overview':
178181
this.envs.loadOverview();
179182
break;

lib/public/view.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { HomePage } from './views/Home/Overview/HomePage.js';
3939
import { DataPassesPerLhcPeriodOverviewPage } from './views/DataPasses/PerLhcPeriodOverview/DataPassesPerLhcPeriodOverviewView.js';
4040
import { SimulationPassesPerLhcPeriodOverviewPage }
4141
from './views/SimulationPasses/PerLhcPeriodOverview/SimulationPassesPerLhcPeriodOverviewPage.js';
42+
import { AnchoredSimulationPassessOverviewPage } from './views/SimulationPasses/AnchoredOverview/AnchoredSimulationPassesOverviewPage.js';
4243
import { RunsPerDataPassOverviewPage } from './views/Runs/RunPerDataPass/RunsPerDataPassOverviewPage.js';
4344
import { LogReplyPage } from './views/Logs/Create/LogReplyPage.js';
4445

@@ -55,6 +56,7 @@ export default (model) => {
5556

5657
'data-passes-per-lhc-period-overview': DataPassesPerLhcPeriodOverviewPage,
5758
'simulation-passes-per-lhc-period-overview': SimulationPassesPerLhcPeriodOverviewPage,
59+
'anchored-simulation-passes-overview': AnchoredSimulationPassessOverviewPage,
5860

5961
'log-overview': LogsOverview,
6062
'log-detail': LogTreeViewPage,

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ export const dataPassesActiveColumns = {
2727
namesFilterModel,
2828
{ class: 'w-75 mt1', placeholder: 'e.g. LHC22a_apass1, ...' },
2929
),
30-
classes: 'w-20',
3130
balloon: true,
31+
classes: 'w-20',
3232
},
3333

3434
associatedRuns: {
@@ -45,26 +45,34 @@ export const dataPassesActiveColumns = {
4545
classes: 'w-10',
4646
},
4747

48+
anchoredSimulationPasses: {
49+
name: 'Anchored',
50+
visible: true,
51+
format: (_, { id }) => frontLink('Anchored', 'anchored-simulation-passes-overview', { dataPassId: id }),
52+
classes: 'w-20',
53+
balloon: true,
54+
},
55+
4856
description: {
4957
name: 'Description',
5058
visible: true,
5159
sortable: false,
60+
balloon: true,
5261
},
5362

5463
reconstructedEventsCount: {
5564
name: 'Reconstructed Events',
5665
format: (reconstructedEventsCount) => reconstructedEventsCount ? reconstructedEventsCount.toLocaleString('en-US') : '-',
5766
visible: true,
5867
sortable: true,
59-
classes: 'w-15',
68+
classes: 'w-10',
6069
},
6170

6271
outputSize: {
6372
name: 'Output Size (B)',
6473
visible: true,
6574
format: (outputSize) => outputSize ? outputSize.toLocaleString('en-US') : '-',
6675
sortable: true,
67-
classes: 'w-15',
76+
classes: 'w-10',
6877
},
69-
7078
};
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
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 { SortModel } from '../../../components/common/table/SortModel.js';
16+
import { TextTokensFilterModel } from '../../../components/Filters/common/filters/TextTokensFilterModel.js';
17+
import { OverviewPageModel } from '../../../models/OverviewModel.js';
18+
import { getRemoteData } from '../../../utilities/fetch/getRemoteData.js';
19+
import { ObservableData } from '../../../utilities/ObservableData.js';
20+
21+
/**
22+
* Simulation Passes Per Data Pass overview model
23+
*/
24+
export class AnchoredSimulationPassesOverviewModel extends OverviewPageModel {
25+
/**
26+
* Constructor
27+
*/
28+
constructor() {
29+
super();
30+
this._sortModel = new SortModel();
31+
this._sortModel.observe(() => {
32+
this._pagination.silentlySetCurrentPage(1);
33+
this.load();
34+
});
35+
this._sortModel.visualChange$.bubbleTo(this);
36+
37+
this._namesFilterModel = new TextTokensFilterModel();
38+
this._registerFilter(this._namesFilterModel);
39+
40+
this._dataPass = new ObservableData(RemoteData.notAsked());
41+
}
42+
43+
/**
44+
* Fetch data pass info which simulation passes are fetched
45+
* @return {Promise<void>} promise
46+
*/
47+
async _fetchDataPass() {
48+
this._dataPass.setCurrent(RemoteData.loading());
49+
try {
50+
const { data: [dataPass] } = await getRemoteData(`/api/dataPasses/?filter[ids][]=${this._dataPassId}`);
51+
this._dataPass.setCurrent(RemoteData.success(dataPass));
52+
} catch (error) {
53+
this._dataPass.setCurrent(RemoteData.failure(error));
54+
}
55+
}
56+
57+
// eslint-disable-next-line valid-jsdoc
58+
/**
59+
* @inheritdoc
60+
*/
61+
async load() {
62+
this._fetchDataPass();
63+
super.load();
64+
}
65+
66+
// eslint-disable-next-line valid-jsdoc
67+
/**
68+
* @inheritdoc
69+
*/
70+
getRootEndpoint() {
71+
const params = {
72+
filter: {
73+
names: this._namesFilterModel.normalized,
74+
dataPassIds: [this._dataPassId],
75+
},
76+
};
77+
78+
const { appliedOn: sortOn, appliedDirection: sortDirection } = this._sortModel;
79+
if (sortOn && sortDirection) {
80+
params[`sort[${sortOn}]`] = sortDirection;
81+
}
82+
83+
return buildUrl('/api/simulationPasses', params);
84+
}
85+
86+
/**
87+
* Reset this model to its default
88+
*
89+
* @returns {void}
90+
*/
91+
reset() {
92+
this._namesFilterModel.reset();
93+
super.reset();
94+
}
95+
96+
/**
97+
* Set id of current data pass which simulation passes are fetched
98+
* @param {number} dataPassId data pass id
99+
*/
100+
set dataPassId(dataPassId) {
101+
this._dataPassId = dataPassId;
102+
}
103+
104+
/**
105+
* Get current data pass which simulation passes are fetched
106+
*/
107+
get dataPass() {
108+
return this._dataPass.getCurrent();
109+
}
110+
111+
/**
112+
* Returns the model handling the overview page table sort
113+
*
114+
* @return {SortModel} the sort model
115+
*/
116+
get sortModel() {
117+
return this._sortModel;
118+
}
119+
120+
/**
121+
* Returns data passes names filter model
122+
* @return {TextTokensFilterModel} data passes names filter model
123+
*/
124+
get namesFilterModel() {
125+
return this._namesFilterModel;
126+
}
127+
128+
/**
129+
* Register a new filter model
130+
* @param {FilterModel} filterModel the filter model to register
131+
* @return {void}
132+
* @private
133+
*/
134+
_registerFilter(filterModel) {
135+
filterModel.visualChange$.bubbleTo(this);
136+
filterModel.observe(() => {
137+
this._pagination.silentlySetCurrentPage(1);
138+
this.load();
139+
});
140+
}
141+
142+
/**
143+
* States whether any filter is active
144+
* @return {boolean} true if any filter is active
145+
*/
146+
isAnyFilterActive() {
147+
return !this._namesFilterModel.isEmpty();
148+
}
149+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @license
3+
* Copyright 2019-2020 CERN and copyright holders of ALICE O2.
4+
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
5+
* All rights not expressly granted are reserved.
6+
*
7+
* This software is distributed under the terms of the GNU General Public
8+
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
9+
*
10+
* In applying this license CERN does not waive the privileges and immunities
11+
* granted to it by virtue of its status as an Intergovernmental Organization
12+
* or submit itself to any jurisdiction.
13+
*/
14+
15+
import { h, iconWarning } from '/js/src/index.js';
16+
import { table } from '../../../components/common/table/table.js';
17+
import { paginationComponent } from '../../../components/Pagination/paginationComponent.js';
18+
import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js';
19+
import { estimateDisplayableRowsCount } from '../../../utilities/estimateDisplayableRowsCount.js';
20+
import { simulationPassesActiveColumns } from '../ActiveColumns/simulationPassesActiveColumns.js';
21+
import { breadcrumbs } from '../../../components/common/navigation/breadcrumbs.js';
22+
import spinner from '../../../components/common/spinner.js';
23+
import { tooltip } from '../../../components/common/popover/tooltip.js';
24+
25+
const TABLEROW_HEIGHT = 42;
26+
// Estimate of the navbar and pagination elements height total; Needs to be updated in case of changes;
27+
const PAGE_USED_HEIGHT = 215;
28+
29+
/**
30+
* Render Simulation Passes per Data Pass overview page
31+
* @param {Model} model The overall model object.
32+
* @returns {Component} The overview screen
33+
*/
34+
export const AnchoredSimulationPassessOverviewPage = ({
35+
simulationPasses: { anchoredOverviewModel: anchoredSimulationPassesOverviewModel },
36+
}) => {
37+
anchoredSimulationPassesOverviewModel.pagination.provideDefaultItemsPerPage(estimateDisplayableRowsCount(
38+
TABLEROW_HEIGHT,
39+
PAGE_USED_HEIGHT,
40+
));
41+
42+
const { items, dataPass, pagination } = anchoredSimulationPassesOverviewModel;
43+
44+
const commonTitle = h('h2', { style: 'white-space: nowrap;' }, 'Anchored MC');
45+
46+
return h(
47+
'',
48+
{
49+
onremove: () => anchoredSimulationPassesOverviewModel.reset(),
50+
},
51+
[
52+
h('.flex-row.items-center.g2', [
53+
filtersPanelPopover(anchoredSimulationPassesOverviewModel, simulationPassesActiveColumns),
54+
h(
55+
'.flex-row.g1.items-center',
56+
dataPass.match({
57+
Success: (payload) => breadcrumbs([commonTitle, h('h2', payload.name)]),
58+
Failure: () => [commonTitle, tooltip(h('.f3', iconWarning()), 'Not able to load data pass info')],
59+
Loading: () => [commonTitle, spinner({ size: 2, absolute: false })],
60+
NotAsked: () => [commonTitle, tooltip(h('.f3', iconWarning()), 'No data was asked for')],
61+
}),
62+
),
63+
]),
64+
h('.w-100.flex-column', [
65+
table(
66+
items,
67+
simulationPassesActiveColumns,
68+
{ classes: '.table-sm' },
69+
null,
70+
{ sort: anchoredSimulationPassesOverviewModel.sortModel },
71+
),
72+
paginationComponent(pagination),
73+
]),
74+
],
75+
);
76+
};

lib/public/views/SimulationPasses/SimulationPassesModel.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import { Observable } from '/js/src/index.js';
1515
import { SimulationPassesPerLhcPeriodOverviewModel } from './PerLhcPeriodOverview/SimulationPassesPerLhcPeriodOverviewModel.js';
16+
import { AnchoredSimulationPassesOverviewModel } from './AnchoredOverview/AnchoredSimulationPassesOverviewModel.js';
1617

1718
/**
1819
* Simulation Passes model
@@ -26,6 +27,9 @@ export class SimulationPassesModel extends Observable {
2627

2728
this._perLhcPeriodOverviewModel = new SimulationPassesPerLhcPeriodOverviewModel();
2829
this._perLhcPeriodOverviewModel.bubbleTo(this);
30+
31+
this._anchoredOverviewModel = new AnchoredSimulationPassesOverviewModel();
32+
this._anchoredOverviewModel.bubbleTo(this);
2933
}
3034

3135
/**
@@ -56,4 +60,31 @@ export class SimulationPassesModel extends Observable {
5660
get perLhcPeriodOverviewModel() {
5761
return this._perLhcPeriodOverviewModel;
5862
}
63+
64+
/**
65+
* Load the overview page model
66+
* @param {string} [params.dataPassId] data pass id which Simulation Passes should be fetched
67+
* @returns {void}
68+
*/
69+
loadAnchoredOverview({ dataPassId }) {
70+
this._anchoredOverviewModel.dataPassId = dataPassId;
71+
this._anchoredOverviewModel.load();
72+
}
73+
74+
/**
75+
* Reset the overview page model to its default state
76+
* @returns {void}
77+
*/
78+
clearAnchoredOverview() {
79+
this._anchoredOverviewModel.reset();
80+
}
81+
82+
/**
83+
* Returns the model for the overview page
84+
*
85+
* @return {AnchoredSimulationPassesOverviewModel} the overview model
86+
*/
87+
get anchoredOverviewModel() {
88+
return this._anchoredOverviewModel;
89+
}
5990
}

test/public/dataPasses/overviewPerLhcPeriod.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ module.exports = () => {
5353
const headerDatatypes = {
5454
name: (name) => periodNameRegex.test(name),
5555
associatedRuns: (display) => /(No runs)|(\d+\nRuns)/.test(display),
56+
anchoredSimulationPasses: (display) => display === 'Anchored',
5657
description: (description) => /(-)|(.+)/.test(description),
5758
reconstructedEventsCount: (reconstructedEventsCount) => !isNaN(reconstructedEventsCount.replace(/,/g, ''))
5859
|| reconstructedEventsCount === '-',

0 commit comments

Comments
 (0)