Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Simplify statistics code #2827

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ac46a35
feat: add pie chart to project statistics popup showing signal count …
PhilippMa Feb 25, 2025
a6ae64d
feat: properly deal with counting signals with undefined classifications
PhilippMa Feb 26, 2025
5aa5c53
feat: exclude classifications with no associated signals from pie chart
PhilippMa Feb 26, 2025
a4f6eda
test: update test for project statistics popup
PhilippMa Feb 26, 2025
5dbe24f
refactor: move text for project statistics charts to text.ts file
PhilippMa Feb 26, 2025
943c40d
refactor: move color definition for critical signal pie chart out of …
PhilippMa Feb 26, 2025
31ea3b8
refactor: remove criticality names enum
PhilippMa Feb 27, 2025
bcee7c1
refactor: improve usage of text constants
PhilippMa Feb 28, 2025
79b4314
feat: delete critical license table
PhilippMa Feb 26, 2025
663b648
refactor: delete ProjectLicensesTable component
PhilippMa Feb 26, 2025
6da9bd1
feat: add criticality column to SignalsPerSources table
PhilippMa Feb 26, 2025
36d63c9
test: update test for ProjectStatisticsPopup
PhilippMa Feb 26, 2025
8390425
test: fix e2e test for project statistics popup
PhilippMa Feb 26, 2025
864550a
refactor: move user-facing text from signal by source table text.ts
PhilippMa Feb 26, 2025
4ddb709
test: fix failing unit test for project statistics popup
PhilippMa Feb 26, 2025
f3313d6
feat: change criticality display to use icons instead of plain text i…
PhilippMa Feb 27, 2025
5030182
refactor: introduce subcomponents for signal per source table
PhilippMa Feb 28, 2025
d5d6355
feat: add classification column to signals per sources table in proje…
PhilippMa Feb 26, 2025
cff656d
feat: improve styling of signals per sources table for better readabi…
PhilippMa Feb 27, 2025
a93da94
test: fix failing unit test
PhilippMa Feb 27, 2025
3ec5278
chore: post-rebase cleanup
PhilippMa Feb 28, 2025
23ac1db
refactor: improve use of text constants
PhilippMa Feb 28, 2025
00961a4
refactor: text constant name change
PhilippMa Feb 28, 2025
03ade53
refactor: introduce simplified statistics code and use it for pie-charts
abraemer Feb 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/ElectronBackend/input/__tests__/importFromFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ const inputFileContent: ParsedOpossumInputFile = {
},
config: {
classifications: {
0: 'UNKNOWN',
1: 'CRITICAL',
0: 'GOOD',
1: 'BAD',
},
},
externalAttributions: {
Expand Down Expand Up @@ -115,8 +115,8 @@ const expectedFileContent: ParsedFileContent = {
resources: { a: 1, folder: {} },
config: {
classifications: {
0: 'UNKNOWN',
1: 'CRITICAL',
0: 'GOOD',
1: 'BAD',
},
},
manualAttributions: {
Expand Down Expand Up @@ -376,8 +376,8 @@ describe('Test of loading function', () => {
},
config: {
classifications: {
0: 'UNKNOWN',
1: 'CRITICAL',
0: 'GOOD',
1: 'BAD',
},
},
externalAttributions: {
Expand Down Expand Up @@ -438,8 +438,8 @@ describe('Test of loading function', () => {
resources: { a: 1 },
config: {
classifications: {
0: 'UNKNOWN',
1: 'CRITICAL',
0: 'GOOD',
1: 'BAD',
},
},
manualAttributions: {
Expand Down
4 changes: 2 additions & 2 deletions src/ElectronBackend/input/__tests__/parseFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const correctInput: ParsedOpossumInputFile = {
},
config: {
classifications: {
0: 'UNKNOWN',
1: 'CRITICAL',
0: 'GOOD',
1: 'BAD',
},
},
externalAttributions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ import MuiAccordionDetails from '@mui/material/AccordionDetails';
import MuiAccordionSummary from '@mui/material/AccordionSummary';
import MuiTypography from '@mui/material/Typography';

import {
PieChartCriticalityNames,
ProjectStatisticsPopupTitle,
} from '../../enums/enums';
import { OpossumColors } from '../../shared-styles';
import { PieChartData } from '../../types/types';
import { PieChart } from '../PieChart/PieChart';
Expand All @@ -37,34 +33,18 @@ interface AccordionProps {
data: Array<PieChartData>;
title: string;
defaultExpanded?: boolean;
pieChartColorMap?: { [segmentName: string]: string };
}

export function getColorsForPieChart(
pieChartData: Array<PieChartData>,
pieChartTitle: string,
pieChartColorMap?: { [segmentName: string]: string },
): Array<string> | undefined {
const pieChartColors: Array<string> = [];

if (
pieChartTitle === ProjectStatisticsPopupTitle.CriticalSignalsCountPieChart
) {
for (const pieChartSegment of pieChartData) {
switch (pieChartSegment.name) {
case PieChartCriticalityNames.HighCriticality:
pieChartColors.push(OpossumColors.orange);
break;
case PieChartCriticalityNames.MediumCriticality:
pieChartColors.push(OpossumColors.mediumOrange);
break;
default:
pieChartColors.push(OpossumColors.darkBlue);
break;
}
}
} else {
if (pieChartColorMap === undefined) {
return;
}
return pieChartColors;

return pieChartData.map(({ name }) => pieChartColorMap[name]);
}

export const AccordionWithPieChart: React.FC<AccordionProps> = (props) => {
Expand All @@ -87,7 +67,7 @@ export const AccordionWithPieChart: React.FC<AccordionProps> = (props) => {
<MuiAccordionDetails sx={classes.accordionDetails}>
<PieChart
segments={props.data}
colors={getColorsForPieChart(props.data, props.title)}
colors={getColorsForPieChart(props.data, props.pieChartColorMap)}
/>
</MuiAccordionDetails>
</MuiAccordion>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@
// SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
import { sortBy } from 'lodash';
import MuiBox from '@mui/material/Box';
import MuiTable from '@mui/material/Table';
import MuiTableBody from '@mui/material/TableBody';
import MuiTableContainer from '@mui/material/TableContainer';
import MuiTypography from '@mui/material/Typography';

import { LicenseCounts, LicenseNamesWithCriticality } from '../../types/types';
import { ProjectLicensesTable } from '../ProjectLicensesTable/ProjectLicensesTable';
import {
LicenseCounts,
LicenseNamesWithClassification,
LicenseNamesWithCriticality,
} from '../../types/types';
import { AttributionCountPerSourcePerLicenseTableFooter } from './AttributionCountPerSourcePerLicenseTableFooter/AttributionCountPerSourcePerLicenseTableFooter';
import { AttributionCountPerSourcePerLicenseTableHead } from './AttributionCountPerSourcePerLicenseTableHead/AttributionCountPerSourcePerLicenseTableHead';
import { AttributionCountPerSourcePerLicenseTableRow } from './AttributionCountPerSourcePerLicenseTableRow/AttributionCountPerSourcePerLicenseTableRow';

const classes = {
container: {
Expand All @@ -14,13 +24,10 @@ const classes = {
},
};

const LICENSE_COLUMN_NAME_IN_TABLE = 'License name';
const FOOTER_TITLE = 'Total';
const TOTAL_SOURCES_TITLE = 'Total';

interface AttributionCountPerSourcePerLicenseTableProps {
licenseCounts: LicenseCounts;
licenseNamesWithCriticality: LicenseNamesWithCriticality;
licenseNamesWithClassification: LicenseNamesWithClassification;
title: string;
}

Expand All @@ -31,43 +38,48 @@ export const AttributionCountPerSourcePerLicenseTable: React.FC<
props.licenseCounts.totalAttributionsPerSource,
);

const totalNumberOfAttributionsPerSource = sourceNames.map((sourceName) =>
props.licenseCounts.totalAttributionsPerSource[sourceName].toString(),
);
const totalNumberOfAttributions = Object.values(
props.licenseCounts.totalAttributionsPerSource,
)
.reduce((partialSum, num) => partialSum + num, 0)
.toString();

const footerRow = [FOOTER_TITLE]
.concat(totalNumberOfAttributionsPerSource)
.concat(totalNumberOfAttributions);
const headerRow = [LICENSE_COLUMN_NAME_IN_TABLE]
.concat(sourceNames)
.concat(TOTAL_SOURCES_TITLE)
.map(
(sourceName) => sourceName.charAt(0).toUpperCase() + sourceName.slice(1),
);

Object.entries(
props.licenseCounts.attributionCountPerSourcePerLicense,
).forEach(
([licenseName, value]) =>
(value[TOTAL_SOURCES_TITLE] =
props.licenseCounts.totalAttributionsPerLicense[licenseName]),
);

return (
<ProjectLicensesTable
title={props.title}
containerStyle={classes.container}
columnHeaders={headerRow}
columnNames={headerRow}
rowNames={sortBy(Object.keys(props.licenseNamesWithCriticality))}
tableContent={props.licenseCounts.attributionCountPerSourcePerLicense}
tableFooter={footerRow}
licenseNamesWithCriticality={props.licenseNamesWithCriticality}
/>
<MuiBox>
<MuiTypography variant="subtitle1">{props.title}</MuiTypography>
<MuiTableContainer sx={classes.container}>
<MuiTable size="small" stickyHeader>
<AttributionCountPerSourcePerLicenseTableHead
sourceNames={sourceNames}
/>
<MuiTableBody>
{Object.keys(props.licenseNamesWithCriticality)
.toSorted()
.map((licenseName, rowIndex) => (
<AttributionCountPerSourcePerLicenseTableRow
sourceNames={sourceNames}
signalCountsPerSource={
props.licenseCounts.attributionCountPerSourcePerLicense[
licenseName
]
}
licenseName={licenseName}
licenseCriticality={
props.licenseNamesWithCriticality[licenseName]
}
licenseClassification={
props.licenseNamesWithClassification[licenseName]
}
totalSignalCount={
props.licenseCounts.totalAttributionsPerLicense[licenseName]
}
key={rowIndex}
rowIndex={rowIndex}
/>
))}
</MuiTableBody>
<AttributionCountPerSourcePerLicenseTableFooter
sourceNames={sourceNames}
totalAttributionsPerSource={
props.licenseCounts.totalAttributionsPerSource
}
/>
</MuiTable>
</MuiTableContainer>
</MuiBox>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Meta Platforms, Inc. and its affiliates
// SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
import MuiTableCell from '@mui/material/TableCell';
import MuiTableFooter from '@mui/material/TableFooter';
import MuiTableRow from '@mui/material/TableRow';
import _ from 'lodash';

import { text } from '../../../../shared/text';
import { tableClasses } from '../../../shared-styles';

interface AttributionCountPerSourcePerLicenseTableFooterProps {
sourceNames: Array<string>;
totalAttributionsPerSource: { [sourceName: string]: number };
}

export const AttributionCountPerSourcePerLicenseTableFooter: React.FC<
AttributionCountPerSourcePerLicenseTableFooterProps
> = (props) => {
return (
<MuiTableFooter>
<MuiTableRow>
<MuiTableCell sx={tableClasses.footer} align={'left'}>
{text.attributionCountPerSourcePerLicenseTable.footerTitle}
</MuiTableCell>
<MuiTableCell sx={tableClasses.footer} />
<MuiTableCell sx={tableClasses.footer} />
{props.sourceNames.map((sourceName, sourceIdx) => (
<MuiTableCell
sx={tableClasses.footer}
key={sourceIdx}
align={'center'}
>
{props.totalAttributionsPerSource[sourceName]}
</MuiTableCell>
))}
<MuiTableCell sx={tableClasses.footer} align={'center'}>
{_.sum(Object.values(props.totalAttributionsPerSource))}
</MuiTableCell>
</MuiTableRow>
</MuiTableFooter>
);
};
Loading
Loading