Skip to content

Commit ed99d2f

Browse files
kalinchernevdegliwe
authored andcommitted
refactor(demo): visualize enrichment results - EUBFR-267 (#227)
* Add documentation working with demo dashboard locally without deployments * Basic display * Mark enriched projects * Add pager * Move to projects * Add file-level stats regarding enriched project locations * Add file-level stats regarding enriched budget items * Add pie charts * Add loading message * Increase size charts * Listing improvements * Per field * Split code * Correction * Correction * Consolidate reports * Refactoring * Refactoring
1 parent d453138 commit ed99d2f

File tree

15 files changed

+962
-315
lines changed

15 files changed

+962
-315
lines changed

demo/dashboard/client/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
"react": "16.8.6",
2020
"react-collapsible": "2.6.0",
2121
"react-dom": "16.8.6",
22+
"react-json-view": "1.19.1",
23+
"react-pager-component": "1.0.0",
2224
"react-router": "5.0.0",
2325
"react-router-dom": "5.0.0",
2426
"react-s3-uploader": "4.8.0",

demo/dashboard/client/src/App.css

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,8 @@
6969

7070
/* Collapsible assumes structure and does not get ECL too well */
7171

72-
.Collapsible {
73-
background-color: white;
74-
}
7572
.Collapsible__contentInner {
76-
border: 1px solid #ebebeb;
77-
border-top: 0;
73+
padding: 0 0 20px 0;
7874
}
7975
.Collapsible__contentInner p {
8076
margin-bottom: 10px;
@@ -89,23 +85,69 @@
8985
font-weight: 400;
9086
text-decoration: none;
9187
position: relative;
92-
border: 1px solid white;
93-
padding: 10px;
94-
background: #f3f3f3;
88+
padding: 10px 30px 10px 0;
9589
color: black;
9690
}
9791
.Collapsible__trigger:hover {
9892
cursor: pointer;
9993
}
100-
94+
.Collapsible__trigger:after {
95+
font-family: 'EuropaIcons';
96+
content: '\e81f';
97+
position: absolute;
98+
right: 10px;
99+
top: 10px;
100+
display: block;
101+
transition: transform 300ms;
102+
}
103+
.Collapsible__trigger.is-open:after {
104+
transform: rotateZ(180deg);
105+
}
101106
.Collapsible__trigger.is-disabled {
102107
opacity: 0.5;
103108
background-color: grey;
104109
}
105-
.CustomTriggerCSS {
106-
background-color: lightcoral;
107-
transition: background-color 200ms ease;
110+
111+
/* Pager */
112+
.Pager {
113+
border-top: 2px solid #000;
114+
color: #004494;
115+
font: normal normal 400 1rem/1.25rem Arial, sans-serif;
116+
margin: 0;
117+
padding-bottom: 1rem;
118+
padding-top: 1rem;
119+
justify-content: center;
120+
}
121+
122+
.Pager .PagerButton {
123+
display: flex;
124+
flex-grow: 0;
125+
margin-right: 1.5rem;
126+
}
127+
128+
.Pager .PagerButton--Prev {
129+
flex-basis: auto;
130+
}
131+
132+
.PagerButton.is-active {
133+
display: flex;
134+
flex-grow: 0;
135+
margin-right: 1.5rem;
136+
border: 2px solid #000;
137+
border-radius: 10rem;
138+
justify-content: center;
139+
min-width: 1.3rem;
140+
}
141+
142+
.Pager .PagerButton--Next {
143+
flex-basis: auto;
144+
margin-right: 0;
145+
}
146+
147+
.Pager .PagerButton--GoLast {
148+
margin-left: 1.5rem;
108149
}
109-
.CustomTriggerCSS--open {
110-
background-color: darkslateblue;
150+
151+
.Pager .PagerButton.is-disabled {
152+
display: none;
111153
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* eslint camelcase: "off" */
2+
3+
/**
4+
* Adds a new property to {Project} accumulating results of the enrichment loop.
5+
* @param {Array<Project>} projects
6+
* @returns {Array<Object>} The original {Array<Project>} with a new property "enrichmentResults".
7+
*/
8+
const enrichmentDecorator = projects =>
9+
projects.map(project => {
10+
// Focus on potentially enriched fields.
11+
const { budget, project_locations } = project._source;
12+
const { eu_contrib, total_cost } = budget;
13+
14+
// Different fields have different means of marking information as enriched.
15+
const hasEnrichedLocation = project_locations.find(l => l.enriched);
16+
const hasEnrichedEuContrib = eu_contrib._original;
17+
const hasEnrichedTotalCost = total_cost._original;
18+
19+
if (hasEnrichedLocation || hasEnrichedEuContrib || hasEnrichedTotalCost) {
20+
return {
21+
enrichmentResults: {
22+
project_locations,
23+
budget,
24+
},
25+
...project,
26+
};
27+
}
28+
29+
return project;
30+
});
31+
32+
export default enrichmentDecorator;

demo/dashboard/client/src/lib/formatQualityReport.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
export default report => {
1+
/**
2+
* Takes an object containing per-field coverage report about project records.
3+
*
4+
* @see resources/elasticsearch/mappings/quality-report.js
5+
* @see resources/elasticsearch/mappings/project.js
6+
* @see demo/dashboard/client/src/clientFactory/esIndices.js
7+
*
8+
* @param {Object} report
9+
* @returns {Array} Formatted report containing information about a selected list of properties.
10+
*/
11+
const formatQualityReport = report => {
212
const formattedReport = [];
313

414
// As requested here https://webgate.ec.europa.eu/CITnet/jira/browse/EUBFR-175?focusedCommentId=2739406&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-2739406
@@ -34,3 +44,5 @@ export default report => {
3444

3545
return formattedReport;
3646
};
47+
48+
export default formatQualityReport;

demo/dashboard/client/src/pages/files/File.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import Spinner from '../../components/Spinner';
1212
import FormUpload from '../../components/FormUpload';
1313

1414
import LogsTab from './file/Logs';
15-
import ProjectsTab from './file/Projects';
16-
import ReportsTab from './file/Reports';
15+
import ProjectsTab from './file/Projects/index';
16+
import ReportsTab from './file/Reports/index';
1717

1818
import './File.css';
1919

@@ -239,7 +239,6 @@ class File extends React.Component {
239239
<span className="ecl-icon ecl-icon--left" />
240240
Go Back to My Files
241241
</Link>
242-
243242
<div className="ecl-row ecl-u-mv-m">
244243
<div className="ecl-col-md-4 ecl-u-d-flex ecl-u-justify-content-center ecl-u-align-items-baseline">
245244
<span className="ecl-u-fs-xxl">
@@ -259,7 +258,6 @@ class File extends React.Component {
259258
</span>
260259
</div>
261260
</div>
262-
263261
<nav className="ecl-navigation-list-wrapper">
264262
<h2 className="ecl-u-sr-only">Navigation Menu</h2>
265263
<ul className="ecl-navigation-list ecl-navigation-list--tabs">
@@ -284,25 +282,24 @@ class File extends React.Component {
284282
</li>
285283
<li className="ecl-navigation-list__item">
286284
<NavLink
287-
to={`${match.url}/logs`}
285+
to={`${match.url}/reports`}
288286
className="ecl-navigation-list__link ecl-link"
289287
activeClassName="ecl-navigation-list__link--active"
290288
>
291-
Logs
289+
Reports
292290
</NavLink>
293291
</li>
294292
<li className="ecl-navigation-list__item">
295293
<NavLink
296-
to={`${match.url}/reports`}
294+
to={`${match.url}/logs`}
297295
className="ecl-navigation-list__link ecl-link"
298296
activeClassName="ecl-navigation-list__link--active"
299297
>
300-
Reports
298+
Logs
301299
</NavLink>
302300
</li>
303301
</ul>
304302
</nav>
305-
306303
<Route
307304
exact
308305
path={`${match.url}`}

demo/dashboard/client/src/pages/files/file/Logs.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* eslint-disable no-underscore-dangle */
2-
31
import React from 'react';
42
import PropTypes from 'prop-types';
53
import Spinner from '../../../components/Spinner';

demo/dashboard/client/src/pages/files/file/Projects.js

Lines changed: 0 additions & 104 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, { Fragment } from 'react';
2+
import PropTypes from 'prop-types';
3+
import Collapsible from 'react-collapsible';
4+
import Pager from 'react-pager-component';
5+
import JsonView from 'react-json-view';
6+
7+
const Listing = ({
8+
current,
9+
enrichmentResults,
10+
onHandlePageChange,
11+
pagerLength,
12+
projectsEnriched,
13+
}) => (
14+
<Fragment>
15+
<p>Enriched on this page: {projectsEnriched}</p>
16+
<ul className="ecl-listing">
17+
{enrichmentResults.map((project, key) => {
18+
const { _source: doc } = project;
19+
const { title, description } = doc;
20+
21+
return (
22+
<li className="ecl-list-item" key={key} tabIndex={key}>
23+
<Collapsible trigger={title}>
24+
<Fragment>
25+
<p
26+
className="ecl-paragraph"
27+
dangerouslySetInnerHTML={{
28+
__html: description,
29+
}}
30+
/>
31+
{project.enrichmentResults
32+
? Object.keys(project.enrichmentResults).map(
33+
(enrichedProperty, i) => (
34+
<Fragment key={i}>
35+
<h3>
36+
Enrichment in <code>{enrichedProperty}</code>
37+
</h3>
38+
<JsonView
39+
collapsed={true}
40+
displayObjectSize={false}
41+
name={enrichedProperty}
42+
src={project.enrichmentResults[enrichedProperty]}
43+
/>
44+
</Fragment>
45+
)
46+
)
47+
: ''}
48+
</Fragment>
49+
</Collapsible>
50+
</li>
51+
);
52+
})}
53+
</ul>
54+
<Pager
55+
length={pagerLength}
56+
current={current}
57+
onChange={onHandlePageChange}
58+
/>
59+
</Fragment>
60+
);
61+
62+
Listing.propTypes = {
63+
current: PropTypes.number,
64+
enrichmentResults: PropTypes.array,
65+
onHandlePageChange: PropTypes.func,
66+
pagerLength: PropTypes.number,
67+
projects: PropTypes.array,
68+
projectsEnriched: PropTypes.number,
69+
};
70+
71+
export default Listing;

0 commit comments

Comments
 (0)