Skip to content
This repository has been archived by the owner on Oct 14, 2024. It is now read-only.

UI sync and fixes new #162

Merged
merged 3 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3,962 changes: 1,976 additions & 1,986 deletions ui/package-lock.json

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@turingpointde/cvss.js": "^1.4.7",
"classnames": "^2.3.2",
"formik": "^2.2.9",
"lodash": "^4.17.21",
Expand All @@ -20,16 +18,15 @@
"react-time-picker": "^5.2.0",
"react-tooltip": "^4.2.15",
"sass": "^1.58.0",
"spinners-react": "^1.0.7",
"web-vitals": "^2.1.4"
"spinners-react": "^1.0.7"
},
"overrides": {
"nth-check": "^2.0.1"
"nth-check": "^2.0.1",
"webpack": "^5.76.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Arrow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Arrow = ({name=ARROW_NAMES.TOP, onClick, disabled, small=false}) => {

return (
<Icon
name={ICON_NAMES.ARROW_LEFT}
name={ICON_NAMES.ARROW_HEAD_LEFT}
className={classnames("arrow-icon", `${name}-arrow`, {small}, {clickable: !!onClick})}
onClick={onClick}
disabled={disabled}
Expand Down
1 change: 1 addition & 0 deletions ui/src/components/Button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import './button.scss';

const Button = ({children, secondary, tertiary, disabled, onClick, className}) => (
<button
type="button"
className={classnames(
"clarity-button",
className,
Expand Down
7 changes: 0 additions & 7 deletions ui/src/components/CloseButton/close-button.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
$button-size-small: 14px;

.close-button {
cursor: pointer;

&.small {
width: $button-size-small;
height: $button-size-small;
}
}
3 changes: 1 addition & 2 deletions ui/src/components/CloseButton/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react';
import classnames from 'classnames';
import Icon, { ICON_NAMES } from 'components/Icon';

import './close-button.scss';

const CloseButton = ({onClose, small=false}) => (
<Icon name={ICON_NAMES.X_MARK} onClick={onClose} className={classnames("close-button", {small})} />
<Icon name={ICON_NAMES.X_MARK} onClick={onClose} className="close-button" size={small ? 14 : 22} />
)

export default CloseButton;
9 changes: 9 additions & 0 deletions ui/src/components/ContentContainer/content-container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@
box-shadow: 0px 0px 10px rgba(34, 43, 54, 0.12);
min-height: 500px;
position: relative;
display: flex;
flex-direction: column;

&.with-margin {
margin: $main-content-padding;
}
> * {
flex-grow: 1;
}
}
5 changes: 3 additions & 2 deletions ui/src/components/ContentContainer/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import classnames from 'classnames';

import './content-container.scss';

const ContentContainer = ({children}) => (
<div className="content-container-wrapper">
const ContentContainer = ({children, withMargin=false}) => (
<div className={classnames("content-container-wrapper", {"with-margin": withMargin})}>
{children}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
@import 'utils/scss_variables.module.scss';

.details-page-wrapper {
&.with-padding {
padding: $main-content-padding;
}
.details-page-content-wrapper {
.details-page-title {
display: flex;
Expand Down
7 changes: 4 additions & 3 deletions ui/src/components/DetailsPageWrapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ const DetailsContentWrapper = ({data, getTitleData, detailsContent: DetailsConte
)
}

const DetailsPageWrapper = ({className, backTitle, url, getUrl, getReplace, getTitleData, detailsContent}) => {
const DetailsPageWrapper = ({className, backTitle, url, getUrl, getTitleData, detailsContent, withPadding=false}) => {
const {pathname} = useLocation();
const params = useParams();
const {id} = params;
const innerPath = params["*"];

const [{loading, data, error}] = useFetch(!!url ? `${url}/${id}` : getUrl(params));

return (
<div className={classnames("details-page-wrapper", className)}>
<BackRouteButton title={backTitle} pathname={pathname.replace(!!getReplace ? getReplace(params) : `/${id}`, "")} />
<div className={classnames("details-page-wrapper", className, {"with-padding": withPadding})}>
<BackRouteButton title={backTitle} pathname={pathname.replace(!!innerPath ? `/${id}/${innerPath}` : `/${id}`, "")} />
{loading ? <Loader /> : (!!error ? null : <DetailsContentWrapper detailsContent={detailsContent} getTitleData={getTitleData} data={data} />)}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
> * {
width: 50%;
padding: $main-content-padding;
overflow-x: auto;
}
.left-pane-display {
border-right: 1px solid $color-grey-light;
Expand Down
28 changes: 27 additions & 1 deletion ui/src/components/Icon/IconTemplates.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion ui/src/components/Icon/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const ICON_NAMES = {
DASHBOARD: "dashboard",
SCANS: "scans",
ASSETS: "assets",
ASSET_SCANS: "asset-scans",
FINDINGS: "findings",
DUPLICATE: "duplicate",
X_MARK: "x-mark",
Expand All @@ -10,7 +11,8 @@ export const ICON_NAMES = {
SORT: "sort",
CHEVRON_RIGHT: "chevron-right",
CHEVRON_RIGHT_DOUBLE: "chevron-right-double",
ARROW_LEFT: "arrow-left",
ARROW_HEAD_LEFT: "arrow-head-left",
ARROW_UP: "ARROW_UP",
PLUS: "plus",
MINUS: "minus",
PLAY: "play",
Expand Down
12 changes: 10 additions & 2 deletions ui/src/components/LinksList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ import './links-list.scss';
const LinksList = ({items}) => {
const navigate = useNavigate();

const onItemClick = (path, callback) => {
if (!!callback) {
callback(path);
}

navigate(path);
}

return (
<div className="links-list-wrapper">
{
items.map(({path, component: Component}, index) => (
<div key={index} className="links-list-item" onClick={() => navigate(path)}>
items.map(({path, component: Component, callback}, index) => (
<div key={index} className="links-list-item" onClick={() => onItemClick(path, callback)}>
<div className="links-list-item-content"><Component /></div>
<Arrow name={ARROW_NAMES.RIGHT} />
</div>
Expand Down
14 changes: 12 additions & 2 deletions ui/src/components/ProgressBar/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import classnames from 'classnames';
import Icon, { ICON_NAMES } from 'components/Icon';
import IconWithTooltip from 'components/IconWithTooltip';

import COLORS from 'utils/scss_variables.module.scss';

Expand All @@ -14,18 +15,27 @@ export const STATUS_MAPPPING = {
WARNING: {value: "WARNING", icon: ICON_NAMES.WARNING, color: COLORS["color-success"], iconColor: COLORS["color-warning"]}
}

const ProgressBar = ({status=STATUS_MAPPPING.IN_PROGRESS.value, itemsCompleted=0, itemsLeft=0, width="100%"}) => {
const ProgressBar = ({status=STATUS_MAPPPING.IN_PROGRESS.value, itemsCompleted=0, itemsLeft=0, width="100%", message=null, messageTooltipId=null, customeTitle}) => {
const totalItems = itemsCompleted + itemsLeft;
const percent = status === STATUS_MAPPPING.IN_PROGRESS.value ? (!!totalItems ? Math.round((itemsCompleted / totalItems) * 100) : 0) : 100;

const {icon, color, iconColor} = STATUS_MAPPPING[status];
const progressIconColor = iconColor || color;
const IconComponent = !!message ? IconWithTooltip : Icon;

return (
<div className="progress-bar-wrapper">
<div className="progress-bar-container" style={{width}}>
<div className={classnames("progress-bar-filler", {done: percent === 100})} style={{width: `${percent}%`, backgroundColor: color}}></div>
</div>
{!!icon ? <Icon name={icon} style={{color: iconColor || color}} /> : <div className="progress-bar-title">{`${percent}%`}</div>}
{!icon ? <div className="progress-bar-title">{!!customeTitle ? customeTitle : `${percent}%`}</div> :
<IconComponent
name={icon}
style={{color: progressIconColor}}
tooltipId={`progress-bar-message-${messageTooltipId}`}
tooltipText={message}
/>
}
</div>
)
}
Expand Down
42 changes: 42 additions & 0 deletions ui/src/components/ScanProgressBar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import ProgressBar, { STATUS_MAPPPING } from 'components/ProgressBar';

import './scan-progress-bar.scss';

const SCAN_STATES_AND_REASONS_MAPPINGS = [
{state: "Pending", status: STATUS_MAPPPING.IN_PROGRESS.value},
{state: "Discovered", status: STATUS_MAPPPING.IN_PROGRESS.value},
{state: "InProgress", status: STATUS_MAPPPING.IN_PROGRESS.value},
{state: "Failed", stateReason: "Aborted", status: STATUS_MAPPPING.STOPPED.value},
{state: "Failed", stateReason: "TimedOut", status: STATUS_MAPPPING.WARNING.value},
{state: "Failed", stateReason: "OneOrMoreTargetFailedToScan", status: STATUS_MAPPPING.STOPPED.value, errorTitle: "Some of the elements were failed to be scanned"},
{state: "Failed", stateReason: "DiscoveryFailed", status: STATUS_MAPPPING.ERROR.value, errorTitle: "Discovery failed"},
{state: "Failed", stateReason: "Unexpected", status: STATUS_MAPPPING.ERROR.value, errorTitle: "Unexpected error occured"},
{state: "Done", status: STATUS_MAPPPING.SUCCESS.value}
];

const ScanProgressBar = ({itemsCompleted, itemsLeft, state, stateReason, stateMessage, barWidth, isMinimized=false, minimizedTooltipId=null}) => {
const {status, errorTitle} = SCAN_STATES_AND_REASONS_MAPPINGS
.find(item => item.state === state && (!item.stateReason || item.stateReason === stateReason)) || {};

return (
<div className="scan-progres-bar-wrapper">
<ProgressBar
status={status}
itemsCompleted={itemsCompleted}
itemsLeft={itemsLeft}
width={barWidth}
message={isMinimized ? errorTitle : null}
messageTooltipId={minimizedTooltipId}
/>
{!isMinimized && errorTitle &&
<div className="error-display-wrapper">
<div className="error-display-title">{errorTitle}</div>
<div className="error-display-message">{stateMessage || errorTitle}</div>
</div>
}
</div>
)
}

export default ScanProgressBar;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import 'utils/scss_variables.module.scss';

.scan-status-display-wrapper {
.scan-progres-bar-wrapper {
margin-bottom: 20px;

.error-display-wrapper {
Expand Down
30 changes: 30 additions & 0 deletions ui/src/components/SeverityDisplay/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import Icon from 'components/Icon';
import { toCapitalized } from 'utils/utils';
import { VULNERABILITIES_ICON_NAME } from 'utils/systemConsts';

import './severity-display.scss';

import COLORS from 'utils/scss_variables.module.scss';

export const SEVERITY_ITEMS = {
CRITICAL: {valueKey: "CRITICAL", color: COLORS["color-error-dark"]},
HIGH: {valueKey: "HIGH", color: COLORS["color-error"]},
MEDIUM: {valueKey: "MEDIUM", color: COLORS["color-warning"]},
LOW: {valueKey: "LOW", color: COLORS["color-warning-low"]},
NEGLIGIBLE: {valueKey: "NEGLIGIBLE", color: COLORS["color-status-blue"]},
NONE: {valueKey: "NONE", color: COLORS["color-status-blue"]}
}

const SeverityDisplay = ({severity, score}) => {
const {color} = SEVERITY_ITEMS[severity];

return (
<div className="severity-display">
{!!score ? <div style={{color}}>{score}</div> : <Icon name={VULNERABILITIES_ICON_NAME} size={25} style={{color}} />}
<div className="severity-title" style={!!score ? {color} : undefined}>{toCapitalized(severity)}</div>
</div>
)
}

export default SeverityDisplay;
8 changes: 8 additions & 0 deletions ui/src/components/SeverityDisplay/severity-display.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.severity-display {
display: flex;
align-items: center;

.severity-title {
margin-left: 5px;
}
}
25 changes: 25 additions & 0 deletions ui/src/components/SystemFiltersBanner/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import CloseButton from 'components/CloseButton';
import Arrow, { ARROW_NAMES } from 'components/Arrow';

import './system-filter-banner.scss';

const SystemFilterBanner = ({onClose, displayText, backPath, customDisplay: CustomDisplay}) => {
const navigate = useNavigate();

return (
<div className="system-filter-banner">
<div className="system-filter-content">
<Arrow name={ARROW_NAMES.LEFT} small onClick={() => navigate(backPath)} />
<div className="filter-content">{displayText}</div>
</div>
<div style={{display: "flex", alignItems: "center"}}>
{!!CustomDisplay && <CustomDisplay />}
<CloseButton small onClose={onClose} />
</div>
</div>
)
}

export default SystemFilterBanner;
Loading