Skip to content

Commit 9ede071

Browse files
DdeHoogmvegter
authored andcommitted
feat: added overview and detail screen for subsystem
1 parent 6c02600 commit 9ede071

5 files changed

Lines changed: 325 additions & 0 deletions

File tree

lib/public/Model.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020

2121
import Logs from './views/Logs/Logs.js';
2222
import Tags from './views/Tags/Tags.js';
23+
import Subsystems from './views/Subsystems/Subsystems.js';
2324

2425
/**
2526
* Root of model tree
@@ -53,6 +54,9 @@ export default class Model extends Observable {
5354
this.logs = new Logs(this);
5455
this.logs.bubbleTo(this);
5556

57+
this.subsystems = new Subsystems(this);
58+
this.subsystems.bubbleTo(this);
59+
5660
this.tags = new Tags(this);
5761
this.tags.bubbleTo(this);
5862

@@ -80,6 +84,21 @@ export default class Model extends Observable {
8084
case 'create-log-entry':
8185
this.logs.setMarkdownBox('text', { location: 'logs', name: 'setText' });
8286
break;
87+
case 'subsystem' :
88+
if (this.router.params.panel) {
89+
this.subsystems.fetchOneSubsystem(this.router.params.id);
90+
switch (this.router.params.panel) {
91+
case 'logs':
92+
this.subsystems.fetchLogsOfSubsystem(this.router.params.id);
93+
break;
94+
default:
95+
break;
96+
}
97+
}
98+
break;
99+
case 'subsystem-overview':
100+
this.subsystems.fetchAllSubsystems();
101+
break;
83102
case 'tag':
84103
if (this.router.params.panel) {
85104
this.tags.fetchOneTag(this.router.params.id);

lib/public/view.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { h, switchCase } from '/js/src/index.js';
1515
import NavBar from './components/NavBar/index.js';
1616
import LogsOverview from './views/Logs/Overview/index.js';
1717
import LogDetailView from './views/Logs/Details/index.js';
18+
import SubsystemDetail from './views/Subsystems/Details/index.js';
19+
import SubsystemOverview from './views/Subsystems/Overview/index.js';
1820
import CreateView from './views/Logs/Create/index.js';
1921
import TagDetail from './views/Tags/Details/index.js';
2022
import TagsOverview from './views/Tags/Overview/index.js';
@@ -28,12 +30,14 @@ export default (model) => {
2830
const navigationPages = {
2931
home: LogsOverview,
3032
'tag-overview': TagsOverview,
33+
'subsystem-overview': SubsystemOverview,
3134
};
3235

3336
const subPages = {
3437
entry: LogDetailView,
3538
'create-log-entry': CreateView,
3639
tag: TagDetail,
40+
subsystem: SubsystemDetail,
3741
};
3842

3943
return [
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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 spinner from '../../../components/common/spinner.js';
16+
import table from '../../../components/Table/index.js';
17+
import targetURL from '../../../utilities/targetURL.js';
18+
import ACTIVE_COLUMNS from '../../Logs/ActiveColumns/index.js';
19+
20+
/**
21+
* The VNode of the Subsystem Detail screen.
22+
*
23+
* @param {*} model Pass the model to access the defined functions.
24+
* @return {vnode} The VNode of the Subsystem Detail screen.
25+
*/
26+
const subsystemDetails = (model) => {
27+
if (!model.router.params.id) {
28+
model.router.go('?page=subsystem-overview');
29+
return;
30+
}
31+
32+
if (!model.router.params.panel) {
33+
model.router.go(targetURL(model, 'panel', 'main'), true);
34+
return;
35+
}
36+
37+
const data = model.subsystems.getSubsystem();
38+
const dataLogs = model.subsystems.getLogsOfSubsystem();
39+
40+
if (data.isSuccess()) {
41+
const activePanel = model.router.params.panel;
42+
43+
const panels = {
44+
main: {
45+
name: 'Main',
46+
content: 'content #1',
47+
},
48+
logs: {
49+
name: 'Logs with this subsystem',
50+
content: dataLogs.match({
51+
NotAsked: () => {},
52+
Loading: () => spinner({ absolute: false }),
53+
Success: (payload) => table(payload, ACTIVE_COLUMNS, (entry) => ({
54+
style: {
55+
cursor: 'pointer',
56+
},
57+
onclick: () => model.router.go(`?page=entry&id=${entry.id}`),
58+
})),
59+
Failure: (payload) => payload.map((error) => h('.alert.alert-danger', error.title)),
60+
}),
61+
},
62+
};
63+
64+
return [
65+
h('h2.mv2', { onremove: () => model.subsystems.clearSubsystem() }, `Subsystem: ${data.payload.name}`),
66+
h('.w-100', [
67+
h('ul.nav.nav-tabs', Object.entries(panels).map(([id, { name }]) =>
68+
h('li.nav-item', h(`a.nav-link${activePanel === id ? '.active' : ''}`, {
69+
onclick: (e) => activePanel !== id && model.router.handleLinkEvent(e),
70+
href: targetURL(model, 'panel', id),
71+
id: `${id}-tab`,
72+
}, name)))),
73+
h('.tab-content.p2', Object.entries(panels).map(([id, { content }]) =>
74+
h(`.tab-pane${activePanel === id ? '.active' : ''}`, { id: `${id}-pane` }, content))),
75+
]),
76+
];
77+
} else if (data.isLoading()) {
78+
return spinner();
79+
} else if (data.isFailure()) {
80+
return data.payload.map((error) => h('.alert.alert-danger', h('b', `${error.title}: `), error.detail));
81+
}
82+
};
83+
84+
export default (model) => subsystemDetails(model);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 spinner from '../../../components/common/spinner.js';
16+
import table from '../../../components/Table/index.js';
17+
18+
const ACTIVE_COLUMNS = {
19+
id: {
20+
name: 'Entry ID',
21+
visible: true,
22+
size: 'cell-l',
23+
primary: true,
24+
},
25+
name: {
26+
name: 'Name',
27+
visible: true,
28+
size: 'cell-l',
29+
},
30+
};
31+
32+
/**
33+
* The VNode of the Subsystem Overview screen.
34+
*
35+
* @param {*} model Pass the model to access the defined functions.
36+
* @return {vnode} The VNode of the Subsystem Overview screen.
37+
*/
38+
const subsystemOverview = (model) => {
39+
const data = model.subsystems.getSubsystems();
40+
41+
return [
42+
h('h2.mv2', { onremove: () => model.subsystems.clearSubsystems() }, 'Subsystems'),
43+
data.match({
44+
NotAsked: () => {},
45+
Loading: () => spinner(),
46+
Success: (payload) => table(payload, ACTIVE_COLUMNS, (entry) => ({
47+
style: 'cursor: pointer;',
48+
onclick: () => model.router.go(`?page=subsystem&id=${entry.id}`),
49+
})),
50+
Failure: (payload) => payload.map((error) => h('.alert.alert-danger', error.title)),
51+
}),
52+
];
53+
};
54+
55+
export default (model) => [h('', subsystemOverview(model))];
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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 { Observable, RemoteData, fetchClient } from '/js/src/index.js';
14+
15+
/**
16+
* Subsystem model
17+
*/
18+
class SubsystemModel extends Observable {
19+
/**
20+
* Creates a new `Subsystem Model` instance.
21+
*
22+
* @param {*} model Pass the model to access the defined functions.
23+
* @returns {undefined}
24+
*/
25+
constructor(model) {
26+
super();
27+
this.model = model;
28+
29+
// Overview
30+
this.clearSubsystems();
31+
32+
// Detail
33+
this.clearSubsystem();
34+
}
35+
36+
/**
37+
* Returns the Subsystem data.
38+
*
39+
* @returns {RemoteData} The Subsystem data.
40+
*/
41+
getSubsystem() {
42+
return this.subsystem;
43+
}
44+
45+
/**
46+
* Returns the Logs of a subsystem.
47+
*
48+
* @returns {RemoteData} The Logs of a Subsystem.
49+
*/
50+
getLogsOfSubsystem() {
51+
return this.logsOfSubsystem;
52+
}
53+
54+
/**
55+
* Returns the Subsystem data.
56+
*
57+
* @returns {RemoteData} The Subsystems data.
58+
*/
59+
getSubsystems() {
60+
return this.subsystems;
61+
}
62+
63+
/**
64+
* Fetches all Subsystems.
65+
*
66+
* @returns {undefined}
67+
*/
68+
async fetchAllSubsystems() {
69+
if (this.getSubsystems().isSuccess()) {
70+
// We already have this panel
71+
return;
72+
}
73+
74+
this.subsystems = RemoteData.loading();
75+
this.notify();
76+
77+
const response = await fetchClient('/api/subsystems');
78+
const result = await response.json();
79+
80+
if (result.data) {
81+
this.subsystems = RemoteData.success(result.data);
82+
} else {
83+
this.subsystems = RemoteData.failure(result.errors);
84+
}
85+
86+
this.notify();
87+
}
88+
89+
/**
90+
* Fetches the Subsystems data.
91+
*
92+
* @param {*} subsystemId Id of the subsystem.
93+
* @returns {undefined}
94+
*/
95+
async fetchOneSubsystem(subsystemId) {
96+
if (this.getSubsystem().isSuccess()) {
97+
// We already have this panel
98+
return;
99+
}
100+
101+
this.subsystem = RemoteData.loading();
102+
this.notify();
103+
104+
const response = await fetchClient(`/api/subsystems/${subsystemId}`);
105+
const result = await response.json();
106+
107+
if (result.data) {
108+
this.subsystem = RemoteData.success(result.data);
109+
} else {
110+
this.subsystem = RemoteData.failure(result.errors);
111+
}
112+
113+
this.notify();
114+
}
115+
116+
/**
117+
* Fetches the logs with provided subsystem.
118+
*
119+
* @param {*} subsystemId Id of the subsystem.
120+
* @returns {undefined}
121+
*/
122+
async fetchLogsOfSubsystem(subsystemId) {
123+
if (this.getLogsOfSubsystem().isSuccess()) {
124+
// We already have this panel
125+
return;
126+
}
127+
128+
this.logsOfSubsystem = RemoteData.loading();
129+
this.notify();
130+
131+
const response = await fetchClient(`/api/subsystems/${subsystemId}/logs`);
132+
const result = await response.json();
133+
134+
if (result.data) {
135+
this.logsOfSubsystem = RemoteData.success(result.data);
136+
} else {
137+
this.logsOfSubsystem = RemoteData.failure(result.errors);
138+
}
139+
140+
this.notify();
141+
}
142+
143+
/**
144+
* Sets all data related to the Subsystem to `NotAsked`.
145+
*
146+
* @returns {undefined}
147+
*/
148+
clearSubsystem() {
149+
this.subsystem = RemoteData.NotAsked();
150+
this.logsOfSubsystem = RemoteData.NotAsked();
151+
}
152+
153+
/**
154+
* Sets all data related to the Subsystem to `NotAsked`.
155+
*
156+
* @returns {undefined}
157+
*/
158+
clearSubsystems() {
159+
this.subsystems = RemoteData.NotAsked();
160+
}
161+
}
162+
163+
export default SubsystemModel;

0 commit comments

Comments
 (0)