Skip to content
This repository was archived by the owner on Feb 18, 2026. It is now read-only.

Commit 9df0b9b

Browse files
Redesign dashboard
1 parent a2451ae commit 9df0b9b

File tree

7 files changed

+104
-86
lines changed

7 files changed

+104
-86
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"react-arborist": "^3.2.0",
2121
"react-dom": "^16.13.0",
2222
"react-dropzone": "^10.2.2",
23-
"react-google-charts": "^3.0.15",
2423
"react-redux": "^7.2.0",
2524
"react-router-dom": "^5.1.2",
2625
"react-scripts": "^5.0.0",

src/__tests__/integration/validation.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { integrationTest, moveNext, storeFile, waitFor, stepFinished } from './index';
22
import { createJob, executeJob, getJob, updateJob } from '../../common/services/jobService';
33
import { getFileContent, uploadFile } from '../../common/services/fileService';
4-
import { Chart } from 'react-google-charts';
54
import Progress from '../../common/components/shared/progress/Progress';
65
import Results from '../../common/components/layouts/pages/results/Results';
76

@@ -82,9 +81,7 @@ describe('Validation', () => {
8281

8382
// Once job is complete app should be redirected to Results summary page
8483
expect(component.find(Results)).toHaveLength(1);
85-
// Chart component loaded
86-
expect(component.find(Chart)).toHaveLength(1);
87-
expect(component.find('.summary__compliance').text()).toBe('50%compliant');
84+
expect(component.find('ul.list').text()).toMatch('Page:0 errors');
8885
expect(component.find('li.legend-item_passed').text()).toBe('1 checks passed');
8986
expect(component.find('li.legend-item_failed').text()).toBe('1 errors');
9087
})

src/common/components/layouts/pages/inspect/tree/Tree.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,11 +610,13 @@ export function sortChecksByPage(checks, errorsMap) {
610610
return newChecks;
611611
}
612612

613-
const SummaryInterface = PropTypes.shape({
613+
export const SummaryInterface = PropTypes.shape({
614614
clause: PropTypes.string.isRequired,
615615
testNumber: PropTypes.number.isRequired,
616616
description: PropTypes.string.isRequired,
617617
checks: PropTypes.arrayOf(PropTypes.object).isRequired,
618+
failedChecks: PropTypes.number.isRequired,
619+
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
618620
});
619621

620622
Tree.propTypes = {

src/common/components/layouts/pages/results/summary/Summary.js

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import React, { useMemo, useState } from 'react';
1+
import React, { useMemo } from 'react';
22
import PropTypes from 'prop-types';
33
import { connect } from 'react-redux';
44
import classNames from 'classnames';
5+
import _ from 'lodash';
56

67
import Paper from '@material-ui/core/Paper';
7-
import CircularProgress from '@material-ui/core/CircularProgress';
8-
import { useTheme } from '@material-ui/core/styles';
9-
import { Chart } from 'react-google-charts';
108
import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';
119
import HighlightOffIcon from '@material-ui/icons/HighlightOff';
1210
import ErrorOutline from '@material-ui/icons/ErrorOutline';
@@ -18,13 +16,17 @@ import { getFileNameLink } from '../../../../../store/pdfLink/selectors';
1816
import { getResultSummary, getJobEndStatus } from '../../../../../store/job/result/selectors';
1917
import { getProfileOptions } from '../../../../../store/validationProfiles/selectors';
2018
import { isFileUploadMode } from '../../../../../store/application/selectors';
19+
import { SummaryInterface as RuleSummariesInterface } from '../../inspect/tree/Tree';
2120

2221
import './Summary.scss';
2322

23+
import errorTags from '../../inspect/validationErrorTags.json';
24+
2425
const JOB_END_STATUS = {
2526
CANCELLED: 'cancelled',
2627
TIMEOUT: 'timeout',
2728
};
29+
const CATEGORY = 'Category';
2830

2931
function Summary({ fileName, profiles, selectedProfile, resultSummary, jobEndStatus }) {
3032
return (
@@ -41,26 +43,16 @@ function Summary({ fileName, profiles, selectedProfile, resultSummary, jobEndSta
4143
}
4244

4345
function ProcessedSummary({ resultSummary }) {
44-
const theme = useTheme();
45-
const [chartReady, setChartReady] = useState(false);
46-
const chartData = useMemo(() => buildChartData(resultSummary), [resultSummary]);
47-
const chartOptions = useMemo(() => getChartOptions(theme), [theme]);
48-
const chartEvents = useMemo(() => [{ eventName: 'ready', callback: () => setChartReady(true) }], [setChartReady]);
49-
const compliancePercent = useMemo(() => calculateCompliance(resultSummary), [resultSummary]);
46+
const listOfErrors = useMemo(() => getListOfErrors(resultSummary.ruleSummaries), [resultSummary]);
47+
5048
return (
5149
<>
52-
<section className="summary__chart">
53-
<Chart
54-
chartType="PieChart"
55-
loader={<CircularProgress />}
56-
data={chartData}
57-
options={chartOptions}
58-
chartEvents={chartEvents}
59-
/>
60-
<div className={classNames('summary__compliance', { summary__compliance_hidden: !chartReady })}>
61-
<span>{compliancePercent}%</span>
62-
compliant
63-
</div>
50+
<section className="summary__list">
51+
<ul className="list">
52+
{Object.keys(listOfErrors)?.map(key => (
53+
<ListItem key={key} label={key} value={listOfErrors[key]} hasError={listOfErrors[key] > 0} />
54+
))}
55+
</ul>
6456
</section>
6557
<ul className="legend">
6658
<LegendItem value={resultSummary.passedChecks ?? 0} label="checks passed" type="passed" />
@@ -88,35 +80,25 @@ function TimeoutSummary() {
8880
);
8981
}
9082

91-
function buildChartData({ passedChecks, failedChecks }) {
92-
return [
93-
['Check', 'Number'],
94-
['Passed', passedChecks],
95-
['Error', failedChecks],
96-
];
97-
}
98-
99-
function getChartOptions(theme) {
100-
return {
101-
pieHole: 0.7,
102-
title: '',
103-
slices: [{ color: theme.palette.success.main }, { color: theme.palette.error.main }],
104-
legend: 'none',
105-
pieSliceText: 'none',
106-
height: '300px',
107-
width: '300px',
108-
chartArea: {
109-
height: '80%',
110-
},
111-
};
112-
}
113-
114-
function calculateCompliance({ passedChecks, failedChecks }) {
115-
const total = passedChecks + failedChecks;
116-
if (total === 0) {
117-
return 100;
118-
}
119-
return Math.floor((passedChecks * 100) / total);
83+
function getListOfErrors(ruleSummaries) {
84+
const listOfErrors = {};
85+
const otherIndexes = [];
86+
const categoryTags = errorTags[CATEGORY].map(({ name }) => name);
87+
categoryTags.forEach(key => {
88+
listOfErrors[key] = ruleSummaries
89+
?.filter((rule, index) => {
90+
if (_.isNil(rule)) return false;
91+
// Avoid duplicated rules in different categories
92+
const isRuleShow = rule.tags?.includes(key) && !otherIndexes.includes(index);
93+
if (isRuleShow) {
94+
otherIndexes.push(index);
95+
}
96+
return isRuleShow;
97+
})
98+
.reduce((num, item) => num + item.failedChecks, 0);
99+
});
100+
const sortedList = _.fromPairs(_.sortBy(_.toPairs(listOfErrors), 1).reverse());
101+
return sortedList;
120102
}
121103

122104
function LegendItem({ label, value, type }) {
@@ -128,9 +110,22 @@ function LegendItem({ label, value, type }) {
128110
);
129111
}
130112

113+
function ListItem({ label, value, hasError }) {
114+
return (
115+
<li className={classNames('list-item', `list-item_${hasError ? 'failed' : 'passed'}`)}>
116+
<FiberManualRecordIcon className="list-item__icon" />
117+
{_.startCase(label)}:
118+
<span>
119+
{value} {value === 1 ? 'error' : 'errors'}
120+
</span>
121+
</li>
122+
);
123+
}
124+
131125
const SummaryInterface = PropTypes.shape({
132126
passedChecks: PropTypes.number,
133127
failedChecks: PropTypes.number,
128+
ruleSummaries: PropTypes.arrayOf(RuleSummariesInterface).isRequired,
134129
});
135130

136131
Summary.propTypes = {

src/common/components/layouts/pages/results/summary/Summary.scss

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,10 @@
1111
margin-bottom: 0;
1212
}
1313

14-
&__chart {
14+
&__list {
1515
@include centered-column;
16-
position: relative;
17-
height: 300px;
18-
19-
// Remove chart tooltip flickering
20-
svg > g > g:last-child {
21-
pointer-events: none
22-
}
16+
margin: 50px auto;
17+
min-width: fit-content;
2318
}
2419

2520
&__compliance {
@@ -65,6 +60,55 @@
6560
}
6661
}
6762

63+
.list {
64+
list-style: none;
65+
padding: 0;
66+
columns: 2;
67+
margin: 0 20px;
68+
-webkit-columns: 2;
69+
-moz-columns: 2;
70+
71+
&-item {
72+
margin: 0 10px;
73+
display: flex;
74+
align-items: center;
75+
font-weight: 500;
76+
margin-bottom: 9px;
77+
78+
.list-item__icon {
79+
font-size: 16px;
80+
margin-right: 5px;
81+
}
82+
83+
&_passed {
84+
.list-item__icon, span {
85+
color: $color-success;
86+
}
87+
}
88+
&_failed {
89+
.list-item__icon, span {
90+
color: $color-error;
91+
}
92+
}
93+
94+
span {
95+
padding-left: 5px;
96+
font-weight: 400
97+
}
98+
}
99+
100+
@media screen and (max-width: 490px) {
101+
columns: 1;
102+
-webkit-columns: 1;
103+
-moz-columns: 1;
104+
}
105+
106+
@media screen and (max-width: 290px) {
107+
margin: 0;
108+
}
109+
}
110+
111+
68112
.error-section {
69113
@include centered-column;
70114
margin: 30px;

src/common/store/job/result/selectors.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const getResultDetails = createSelector(getResult, result => result?.deta
99
export const getResultSummary = createSelector(getResultDetails, checks => ({
1010
passedChecks: checks?.passedChecks || null,
1111
failedChecks: checks?.failedChecks || null,
12+
ruleSummaries: checks?.ruleSummaries || null,
1213
}));
1314

1415
export const isCompliant = createSelector(getResult, result => result?.compliant || false);

yarn.lock

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8496,15 +8496,7 @@ path-type@^4.0.0:
84968496
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
84978497
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
84988498

8499-
pdfjs-dist@2.16.105:
8500-
version "2.16.105"
8501-
resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-2.16.105.tgz#937b9c4a918f03f3979c88209d84c1ce90122c2a"
8502-
integrity sha512-J4dn41spsAwUxCpEoVf6GVoz908IAA3mYiLmNxg8J9kfRXc2jxpbUepcP0ocp0alVNLFthTAM8DZ1RaHh8sU0A==
8503-
dependencies:
8504-
dommatrix "^1.0.3"
8505-
web-streams-polyfill "^3.2.1"
8506-
8507-
"pdfjs-dist@github:veraPDF/pdfjs-dist#v2.16.105-taggedPdf-0.1.18":
8499+
pdfjs-dist@2.16.105, "pdfjs-dist@github:veraPDF/pdfjs-dist#v2.16.105-taggedPdf-0.1.18":
85088500
version "2.16.105"
85098501
resolved "https://codeload.github.com/veraPDF/pdfjs-dist/tar.gz/7e5be3ffc8d2c521550eeae07e828a3d4d652901"
85108502
dependencies:
@@ -9431,13 +9423,6 @@ react-error-overlay@^6.0.11:
94319423
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"
94329424
integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==
94339425

9434-
react-google-charts@^3.0.15:
9435-
version "3.0.15"
9436-
resolved "https://registry.yarnpkg.com/react-google-charts/-/react-google-charts-3.0.15.tgz#30759a470f48336e744fd383d054122b039a1ff2"
9437-
integrity sha512-78s5xOQOJvL+jIewrWQZEHtlVk+5Yh4zZy+ODA1on1o1FaRjKWXxoo4n4JQl1XuqkF/A9NWque3KqM6pMggjzQ==
9438-
dependencies:
9439-
react-load-script "^0.0.6"
9440-
94419426
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.4, react-is@^16.8.6:
94429427
version "16.13.1"
94439428
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -9453,11 +9438,6 @@ react-is@^18.0.0:
94539438
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
94549439
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
94559440

9456-
react-load-script@^0.0.6:
9457-
version "0.0.6"
9458-
resolved "https://registry.yarnpkg.com/react-load-script/-/react-load-script-0.0.6.tgz#db6851236aaa25bb622677a2eb51dad4f8d2c258"
9459-
integrity sha512-aRGxDGP9VoLxcsaYvKWIW+LRrMOzz2eEcubTS4NvQPPugjk2VvMhow0wWTkSl7RxookomD1MwcP4l5UStg5ShQ==
9460-
94619441
react-pdf@6.2.2:
94629442
version "6.2.2"
94639443
resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-6.2.2.tgz#61dbf1cd32b49bb452c8dd26e7ee7b2f987e4904"

0 commit comments

Comments
 (0)