Skip to content

Commit

Permalink
Merge pull request #1065 from vasily-pozdnyakov/highlight_resources_w…
Browse files Browse the repository at this point in the history
…ith_critical_licenses

Highlight resources with critical licenses
  • Loading branch information
leslielazzarino authored Oct 12, 2022
2 parents bdb431c + f142c2f commit 7352dd6
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 8 deletions.
29 changes: 26 additions & 3 deletions src/Frontend/Components/Icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
} from '../../shared-styles';
import { SxProps } from '@mui/material';
import RectangleIcon from '@mui/icons-material/Rectangle';
import { Criticality } from '../../../shared/shared-types';

const classes = {
clickableIcon,
Expand All @@ -49,10 +50,26 @@ const classes = {
},
};

const criticalityTooltipText = {
high: 'has high criticality signals',
medium: 'has medium criticality signals',
undefined: 'has signals',
};

const criticalityColor = {
high: OpossumColors.orange,
medium: OpossumColors.mediumOrange,
undefined: OpossumColors.darkBlue,
};

interface IconProps {
sx?: SxProps;
}

interface SignalIconProps {
criticality?: Criticality;
}

interface LabelDetailIconProps extends IconProps {
labelDetail?: string;
disabled?: boolean;
Expand Down Expand Up @@ -102,12 +119,18 @@ export function FollowUpIcon(props: IconProps): ReactElement {
);
}

export function SignalIcon(): ReactElement {
export function SignalIcon(props: SignalIconProps): ReactElement {
return (
<MuiTooltip sx={classes.tooltip} title="has signals">
<MuiTooltip
sx={classes.tooltip}
title={criticalityTooltipText[props.criticality ?? 'undefined']}
>
<AnnouncementIcon
aria-label={'Signal icon'}
sx={classes.nonClickableIcon}
sx={{
...baseIcon,
color: criticalityColor[props.criticality ?? 'undefined'],
}}
/>
</MuiTooltip>
);
Expand Down
74 changes: 73 additions & 1 deletion src/Frontend/Components/Icons/__tests__/Icons.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
//
// SPDX-License-Identifier: Apache-2.0

import { render, screen } from '@testing-library/react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import React from 'react';
import { Criticality } from '../../../../shared/shared-types';
import {
BreakpointIcon,
CommentIcon,
DirectoryIcon,
ExcludeFromNoticeIcon,
FileIcon,
FirstPartyIcon,
FollowUpIcon,
IncompletePackagesIcon,
PreSelectedIcon,
SearchPackagesIcon,
SignalIcon,
} from '../Icons';

describe('The Icons', () => {
Expand Down Expand Up @@ -50,4 +56,70 @@ describe('The Icons', () => {

expect(screen.getByLabelText('File icon'));
});

it('renders SignalIcon', () => {
render(<SignalIcon />);

expect(screen.getByLabelText('Signal icon'));
});

it('renders BreakpointIcon', () => {
render(<BreakpointIcon />);

expect(screen.getByLabelText('Breakpoint icon'));
});

it('renders IncompletePackagesIcon', () => {
render(<IncompletePackagesIcon />);

expect(screen.getByLabelText('Incomplete icon'));
});

it('renders PreSelectedIcon', () => {
render(<PreSelectedIcon />);

expect(screen.getByLabelText('Pre-selected icon'));
});

it('renders SearchPackagesIcon', () => {
render(<SearchPackagesIcon />);

expect(screen.getByLabelText('Search packages icon'));
});
});

describe('The SignalIcon', () => {
jest.useFakeTimers();
it('renders high criticality SignalIcon', () => {
render(<SignalIcon criticality={Criticality.High} />);

const icon = screen.getByLabelText('Signal icon');
fireEvent.mouseOver(icon);
act(() => {
jest.runAllTimers();
});
screen.getByText('has high criticality signals');
});

it('renders medium criticality SignalIcon', () => {
render(<SignalIcon criticality={Criticality.Medium} />);

const icon = screen.getByLabelText('Signal icon');
fireEvent.mouseOver(icon);
act(() => {
jest.runAllTimers();
});
screen.getByText('has medium criticality signals');
});

it('renders no criticality SignalIcon', () => {
render(<SignalIcon criticality={undefined} />);

const icon = screen.getByLabelText('Signal icon');
fireEvent.mouseOver(icon);
act(() => {
jest.runAllTimers();
});
screen.getByText('has signals');
});
});
6 changes: 4 additions & 2 deletions src/Frontend/Components/ResourceBrowser/ResourceBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import React, { ReactElement } from 'react';
import { useAppDispatch, useAppSelector } from '../../state/hooks';
import {
getAttributionBreakpoints,
getExternalData,
getFilesWithChildren,
getManualAttributions,
getResources,
Expand Down Expand Up @@ -101,7 +102,7 @@ export function ResourceBrowser(): ReactElement | null {

const attributionBreakpoints = useAppSelector(getAttributionBreakpoints);
const filesWithChildren = useAppSelector(getFilesWithChildren);

const externalData = useAppSelector(getExternalData);
const dispatch = useAppDispatch();

function handleToggle(nodeIdsToExpand: Array<string>): void {
Expand Down Expand Up @@ -140,7 +141,8 @@ export function ResourceBrowser(): ReactElement | null {
resourcesWithManualAttributedChildren,
resolvedExternalAttributions,
getAttributionBreakpointCheck(attributionBreakpoints),
getFileWithChildrenCheck(filesWithChildren)
getFileWithChildrenCheck(filesWithChildren),
externalData
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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 { Criticality } from '../../../../shared/shared-types';
import { getCriticality } from '../get-tree-item-label';

describe('Tree item labels', () => {
it('checks resource getCriticality', () => {
const resourcesToExternalAttributions = {
'/test_file1.ts': ['attr1', 'attr2'],
'/test_file2.ts': ['attr3'],
'/test_file3.ts': ['attr2', 'attr3'],
};
const externalAttributions = {
attr1: { criticality: Criticality.High },
attr2: { criticality: Criticality.Medium },
attr3: {},
};
const expectedCriticalities: {
[resource: string]: Criticality | undefined;
} = {
'/test_file1.ts': Criticality.High,
'/test_file2.ts': undefined,
'/test_file3.ts': Criticality.Medium,
};

for (const nodeId of Object.keys(resourcesToExternalAttributions)) {
const criticality = getCriticality(
nodeId,
resourcesToExternalAttributions,
externalAttributions
);
expect(criticality).toEqual(expectedCriticalities[nodeId]);
}
});
});
36 changes: 35 additions & 1 deletion src/Frontend/Components/ResourceBrowser/get-tree-item-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
// SPDX-License-Identifier: Apache-2.0

import {
AttributionData,
Attributions,
Criticality,
Resources,
ResourcesToAttributions,
ResourcesWithAttributedChildren,
Expand All @@ -25,7 +27,8 @@ export function getTreeItemLabel(
resourcesWithManualAttributedChildren: ResourcesWithAttributedChildren,
resolvedExternalAttributions: Set<string>,
isAttributionBreakpoint: PathPredicate,
isFileWithChildren: PathPredicate
isFileWithChildren: PathPredicate,
externalData: AttributionData
): ReactElement {
const canHaveChildren = resource !== 1;

Expand Down Expand Up @@ -60,6 +63,11 @@ export function getTreeItemLabel(
nodeId,
resourcesWithManualAttributedChildren
)}
criticality={getCriticality(
nodeId,
resourcesToExternalAttributions,
externalData.attributions
)}
isAttributionBreakpoint={isAttributionBreakpoint(nodeId)}
showFolderIcon={canHaveChildren && !isFileWithChildren(nodeId)}
containsResourcesWithOnlyExternalAttribution={
Expand All @@ -75,6 +83,32 @@ export function getTreeItemLabel(
);
}

export function getCriticality(
nodeId: string,
resourcesToExternalAttributions: ResourcesToAttributions,
externalAttributions: Attributions
): Criticality | undefined {
if (hasExternalAttribution(nodeId, resourcesToExternalAttributions)) {
const attributionsForResource = resourcesToExternalAttributions[nodeId];

for (const attribution of attributionsForResource) {
if (externalAttributions[attribution].criticality === Criticality.High) {
return Criticality.High;
}
}

for (const attribution of attributionsForResource) {
if (
externalAttributions[attribution].criticality === Criticality.Medium
) {
return Criticality.Medium;
}
}

return undefined;
}
}

function isRootResource(resourceName: string): boolean {
return resourceName === '';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { OpossumColors, tooltipStyle } from '../../shared-styles';
import { SxProps } from '@mui/material';
import MuiBox from '@mui/material/Box';
import { Criticality } from '../../../shared/shared-types';

const classes = {
manualIcon: {
Expand Down Expand Up @@ -83,6 +84,7 @@ interface StyledTreeItemProps {
isAttributionBreakpoint: boolean;
showFolderIcon: boolean;
containsResourcesWithOnlyExternalAttribution: boolean;
criticality?: Criticality;
}

export function StyledTreeItemLabel(props: StyledTreeItemProps): ReactElement {
Expand Down Expand Up @@ -145,7 +147,9 @@ export function StyledTreeItemLabel(props: StyledTreeItemProps): ReactElement {
>
{props.labelText}
</MuiTypography>
{props.hasExternalAttribution ? <SignalIcon /> : null}
{props.hasExternalAttribution ? (
<SignalIcon criticality={props.criticality} />
) : null}
</MuiBox>
);
}

0 comments on commit 7352dd6

Please sign in to comment.