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

Add New Chart Components and Client Dashboard #160

Merged
merged 101 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
5192fe0
✨ feat: Add ClientDashboard component to main.tsx
caverav Oct 26, 2024
5e7fc23
✨ feat: Add ClientDashboard component and export functionality with d…
caverav Oct 26, 2024
7a97170
♻️ refactor: update import paths for dashboard components and adjust …
caverav Oct 26, 2024
8f782c5
🚑 fix: Handle clientName in AverageCVSS component and ClientDashboard
caverav Oct 28, 2024
15194c8
feat: added selection for client
Oct 29, 2024
efa3b07
fix: returns company data instead of client
Oct 29, 2024
3bfcd0a
fix: removed unused variable
Oct 29, 2024
5b35576
fix: fixed type in variable
Oct 29, 2024
2494d4c
✨ feat: Add recharts library to package.json and create CIATriadChart…
caverav Nov 2, 2024
e069211
✨ feat: Added new components CVSSChart and CWECloud
caverav Nov 2, 2024
e932bf7
✨ feat: Add RemediationPriorityChart component for displaying average…
caverav Nov 2, 2024
c1ae324
✨ feat: Add SeverityPieChart component for displaying vulnerabilities…
caverav Nov 2, 2024
614d66b
✨ feat: Add TimePerAuditChart component for displaying audit time data
caverav Nov 2, 2024
37c8a02
♻️ refactor: remove redundant header elements in chart components
caverav Nov 2, 2024
a4dbaa5
💄 style: adjust chart container dimensions in CWECloud and SeverityPi…
caverav Nov 2, 2024
7891059
♻️ refactor: use chart.js instead of recharts
caverav Nov 2, 2024
f166605
🚑 fix: Correct import order and duplicates in TimePerAuditChart compo…
caverav Nov 2, 2024
427bc30
🚑 fix: Reorder imports in SeverityPieChart.tsx for consistency.
caverav Nov 2, 2024
fb73cd4
🚑 fix: Reorder imports in RemediationPriorityChart.tsx
caverav Nov 2, 2024
15f50c9
style(key): add missing key prop to dynamically generated elements in…
caverav Nov 2, 2024
9ec970c
🚑 fix: Reorder imports in CVSSChart.tsx for consistency
caverav Nov 2, 2024
5354398
🚑 fix: Reorder imports in CIATriadChart.tsx to improve consistency
caverav Nov 2, 2024
2961488
♻️ refactor: remove redundant chart titles in several components
caverav Nov 2, 2024
02481a6
🚑 fix: Set maintainAspectRatio to true and update layout for Severity…
caverav Nov 2, 2024
ca213dc
♻️ refactor: adjust styling for SeverityPieChart and add TimePerAudit…
caverav Nov 2, 2024
3a2aff8
♻️ refactor: Remove unused data declarations and console log statemen…
caverav Nov 2, 2024
a85426c
♻️ refactor: Extract CVSS score calculation and severity determinatio…
caverav Nov 2, 2024
e53a111
🚑 fix: calculate and update total severity correctly for vulnerabilit…
caverav Nov 2, 2024
b7fcb09
♻️ refactor: update CIATriadChart and ClientDashboard components
caverav Nov 2, 2024
2e331c0
♻️ refactor: improve variable naming and data structure in client das…
caverav Nov 2, 2024
7a38374
♻️ refactor: organize priority data initialization and processing in …
caverav Nov 2, 2024
c50d597
✨ feat: Integrate @visx/wordcloud library for visualizing CWE items
caverav Nov 2, 2024
ef8dd66
🚑 fix: Remove hard-coded string and dynamically set most common CWE I…
caverav Nov 2, 2024
e11880f
♻️ refactor: Remove commented out data arrays and unused code in Clie…
caverav Nov 2, 2024
6259083
✨ feat: Remove unused state variable `audits` in ClientDashboard
caverav Nov 2, 2024
0111d24
♻️ refactor: removed unused type ClientData in dashboard.tsx
caverav Nov 2, 2024
b3d321f
🚑 fix: Update conditional rendering logic in ClientDashboard component
caverav Nov 2, 2024
5c1404d
✨ feat: update time data in ClientDashboard component and TimePerAudi…
caverav Nov 2, 2024
faa8ce1
🚑 fix: update chart rendering logic and data processing in Remediatio…
caverav Nov 2, 2024
6dd9488
🚑 fix: Remove unnecessary tick callback function in RemediationPriori…
caverav Nov 2, 2024
576370a
🚑 fix: Remove outdated 'Target' data and associated styles in CIATria…
caverav Nov 2, 2024
e7f86aa
🚑 fix: update suggestedMax to 2 and display tick callback in CIATriad…
caverav Nov 2, 2024
6848407
♻️ refactor: optimize CWECloud component rendering in CWECloud.tsx
caverav Nov 2, 2024
be518b2
♻️ refactor(dashboard): optimize audit data processing with async map…
caverav Nov 2, 2024
d3f26c5
🚑 fix: Make 'remediationComplexity' and 'priority' optional in Findin…
caverav Nov 2, 2024
646eeb5
🚑 fix: remove unnecessary state variables in ClientDashboard
caverav Nov 2, 2024
4f89955
♻️ refactor: Remove unused code and setLoading calls in ClientDashboa…
caverav Nov 2, 2024
3b3faa3
🚑 fix: Update condition in RemediationPriority component
caverav Nov 2, 2024
22e506e
🚑 fix: handle empty data in various chart components
caverav Nov 2, 2024
dfc2393
🚑 fix: Update cvssStringTo function with missing value for 'N' vulner…
caverav Nov 2, 2024
9295c4b
🚑 fix: Ensure remediationComplexity is defined before checking its value
caverav Nov 2, 2024
fbbc971
🐛 fix: Remove unnecesary then calls
caverav Nov 2, 2024
199596d
🚑 fix: Remove 'M' value from cvssStringTo integrity calculation
caverav Nov 3, 2024
ac388fa
🚑 fix: Update cvssStringTo function values
caverav Nov 3, 2024
469ad06
Merge branch 'development' into feature/client-dashboard
caverav Nov 3, 2024
179402f
🚑 fix: Correct key generation in CWECloud component map function
caverav Nov 3, 2024
d7243a9
♻️ refactor: update most common label in CWECloud component
caverav Nov 3, 2024
a4b760f
🔧 chore: update most common text in en-US translation file
caverav Nov 3, 2024
4bd1ca5
🚑 fix: Update label key in CWECloud.tsx to match translation updates
caverav Nov 3, 2024
e58cf6a
💄 style: Add a colon after "mostCommon" in CWECloud component
caverav Nov 3, 2024
b5c556c
🚑 fix: Add 'Found in total' translation key in en-US index.ts
caverav Nov 3, 2024
3c32f5e
🚑 fix: Update text in SeverityPieChart to include i18n for 'found in …
caverav Nov 3, 2024
8f334b2
🚑 fix: Update title attribute in Card component to use i18n translati…
caverav Nov 3, 2024
28255c2
🔧 chore: Update English translation for 'Vulnerabilities by severity'…
caverav Nov 3, 2024
b45b7ef
🚑 fix: Update title prop in Dashboard component to use translation fu…
caverav Nov 3, 2024
ad4209e
🚑 fix: Add 'timesPerAudit' key to en-US translation file
caverav Nov 3, 2024
fb9cbce
🚑 fix: Update title attribute in Card component for CWEs found in Cli…
caverav Nov 3, 2024
993cb66
🔧 chore: Update English translations for CWEs found in the application
caverav Nov 3, 2024
2a346e3
🚑 fix: update title prop in dashboard Card component to use i18n tran…
caverav Nov 3, 2024
608b34b
🚑 fix: Add 'Average CIA triad' translation in en-US index.ts
caverav Nov 3, 2024
150f190
🚑 fix: Update title attribute in CVSS chart component to use translat…
caverav Nov 3, 2024
2d68be8
🚑 fix: Add missing translation for 'Average CVSS' in en-US locale
caverav Nov 3, 2024
006dbaf
🚑 fix: Change title attribute in Card component from static text to d…
caverav Nov 3, 2024
b336ae2
✨ feat: Add 'Average Remediation Priority' to English language settin…
caverav Nov 4, 2024
f1abf23
🚑 fix: Update placeholder text in client dropdown to 'clientSelect'
caverav Nov 4, 2024
67f6aef
🚑 fix: Add missing i18n key for client selection in en-US translation
caverav Nov 4, 2024
1fa07ab
🚑 fix: Update types in CIATriadChart component to restrict current an…
caverav Nov 4, 2024
6c20283
🚑 fix: Update data types for current and target values in ClientDashb…
caverav Nov 4, 2024
5828b70
🚑 fix: update tmpCiaData type definition in fetchAuditsbyClient
caverav Nov 4, 2024
7c3af69
💄 style: add vertical scrolling to the dashboard container
caverav Nov 4, 2024
725d5f5
🚑 fix: Filter out timeData with zero execution and remediation values…
caverav Nov 4, 2024
6d44e41
🚑 fix: Increment correct priority count in ClientDashboard
caverav Nov 4, 2024
0f110bd
🚑 fix: Correct typo in dashboard title from 'cweFound' to 'cwesFound'
caverav Nov 4, 2024
bed5c69
🚑 fix: calculate average CVSS score per audit finding
caverav Nov 4, 2024
198fd95
♻️ refactor: update CVSSChart background color logic based on score r…
caverav Nov 4, 2024
455ddd4
🚑 fix: Update state initialization for currentClient in ClientDashboard
caverav Nov 4, 2024
96b0e2a
✨ feat: Added FaBug icon to CWECloud component and updated rendering …
caverav Nov 4, 2024
cc991fb
🐛 fix(CWECloud): move key prop to correct position in map function
caverav Nov 4, 2024
e017736
🐛 fix(i18n): correct typo in 'occurrences' translation key
caverav Nov 4, 2024
39d0e64
✏️ fix(i18n): correct typo in 'occurrences' key in en-US translations
caverav Nov 4, 2024
34223b9
♻️ refactor: re-order field assignments in CIATriad.tsx and dashboard…
caverav Nov 4, 2024
32968b0
🐛 fix: correct CVSS vector values and chart max value
caverav Nov 4, 2024
0e8f253
🚑 fix: Handle case where finding.cvssv3 is of length 44 in ClientDash…
caverav Nov 4, 2024
6da8f29
🚑 fix: Make cvssv3 field optional in Finding interface
caverav Nov 4, 2024
e18caca
🚑 fix: Handle null values properly when calculating CVSS scores and s…
caverav Nov 4, 2024
6191cb2
🚑 fix: Handle potential null value in CVSS severity conversion for fi…
caverav Nov 4, 2024
501622c
🚑 fix: Update ChartJS registration and add average CVSS annotation in…
caverav Nov 4, 2024
ee6fe69
🚑 fix: Use const assertion for 'type' property in CVSSChart component…
caverav Nov 4, 2024
be063ee
🚑 fix: Update CVSSChart to parse averageCVSS as float before setting …
caverav Nov 4, 2024
0ae0fdd
✨ feat: Add Tooltip component and functionality to CWECloud chart
caverav Nov 4, 2024
24f70b1
💄 style(CWECloud): reorder imports for better readability
caverav Nov 4, 2024
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
4 changes: 4 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"@types/react-router-dom": "^5.3.3",
"@visx/text": "^3.3.0",
"@visx/wordcloud": "^3.3.0",
"ae-cvss-calculator": "^1.0.2",
"chart.js": "^4.4.4",
"chartjs-plugin-annotation": "^3.0.1",
Expand All @@ -42,6 +45,7 @@
"react-chartjs-2": "^5.2.0",
"react-dom": "^18.3.1",
"react-i18next": "^15.0.0",
"react-icons": "^5.3.0",
"react-quill-new": "^3.3.0",
"react-router-dom": "^6.25.1",
"sonner": "^1.5.0",
Expand Down
115 changes: 115 additions & 0 deletions frontend/src/components/charts/CIATriadChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {
Chart as ChartJS,
Filler,
Legend,
LineElement,
PointElement,
RadialLinearScale,
Tooltip,
} from 'chart.js';
import { t } from 'i18next';
import React from 'react';
import { Radar } from 'react-chartjs-2';

ChartJS.register(
RadialLinearScale,
PointElement,
LineElement,
Filler,
Tooltip,
Legend,
);
caverav marked this conversation as resolved.
Show resolved Hide resolved

type CIAData = {
subject: string;
current: 0 | 1 | 2;
target: 0 | 1 | 2;
};

type Props = {
data: CIAData[];
};

export const CIATriadChart: React.FC<Props> = ({ data }) => {
if (!data.length) {
return (
<p className="text-sm text-gray-500">{t('err.noMatchingRecords')}</p>
);
}
const chartData = {
labels: data.map(d => d.subject),
datasets: [
{
label: 'Average',
data: data.map(d => d.current),
backgroundColor: 'rgba(130, 202, 157, 0.5)',
borderColor: 'rgb(130, 202, 157)',
borderWidth: 1,
},
],
};
caverav marked this conversation as resolved.
Show resolved Hide resolved

const options = {
responsive: true,
maintainAspectRatio: false,
scales: {
r: {
angleLines: {
display: true,
color: 'rgba(255, 255, 255, 0.1)',
},
suggestedMin: 0,
suggestedMax: 2,
ticks: {
stepSize: 1,
callback: (value: number | string) => {
if (value === 0) {
return 'None';
}
if (value === 1) {
return 'Low';
}
if (value === 2) {
return 'High';
}
return value;
},
display: true,
color: 'black',
},
pointLabels: {
font: {
size: 14,
},
color: 'white',
},
grid: {
color: 'rgba(255, 255, 255, 0.1)',
},
},
},
plugins: {
legend: {
position: 'bottom' as const,
labels: {
color: 'white',
boxWidth: 20,
padding: 20,
},
},
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0.8)',
titleColor: 'white',
bodyColor: 'white',
borderColor: 'white',
borderWidth: 1,
},
},
};
caverav marked this conversation as resolved.
Show resolved Hide resolved

return (
<div className="h-[300px] w-full">
<Radar data={chartData} options={options} />
</div>
);
};
caverav marked this conversation as resolved.
Show resolved Hide resolved
107 changes: 107 additions & 0 deletions frontend/src/components/charts/CVSSChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {
BarElement,
CategoryScale,
Chart as ChartJS,
LinearScale,
Title,
Tooltip,
} from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
import { t } from 'i18next';
import React from 'react';
import { Bar } from 'react-chartjs-2';

ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
annotationPlugin,
);

type CVSSData = {
name: string;
score: number;
};

type Props = {
data: CVSSData[];
};
caverav marked this conversation as resolved.
Show resolved Hide resolved

export const CVSSChart: React.FC<Props> = ({ data }) => {
if (!data.length) {
return (
<p className="text-sm text-gray-500">{t('err.noMatchingRecords')}</p>
);
}

const averageCVSS = (
data.reduce((acc, d) => acc + d.score, 0) / data.length
).toFixed(2);

const chartData = {
labels: data.map(d => d.name),
datasets: [
{
data: data.map(d => d.score),
backgroundColor: data.map(d => {
if (d.score >= 9.0) {
return '#dc3545';
} else if (d.score >= 7.0) {
return '#fd7e14';
} else if (d.score >= 4.0) {
return '#ffc107';
} else if (d.score >= 0.1) {
return '#28a745';
} else {
return '#6c757d';
}
}),
caverav marked this conversation as resolved.
Show resolved Hide resolved
},
],
};

const options = {
responsive: true,
maintainAspectRatio: false,
indexAxis: 'y' as const,
plugins: {
legend: {
display: false,
},
annotation: {
annotations: {
line1: {
type: 'line' as const,
xMin: parseFloat(averageCVSS),
xMax: parseFloat(averageCVSS),
borderColor: '#2ecc71',
borderWidth: 2,
borderDash: [5, 5],
},
},
},
},
scales: {
x: {
min: 0,
max: 10,
grid: {
drawOnChartArea: true,
},
},
},
};

return (
<div className="relative">
<div className="absolute top-0 left-0 w-full text-right pr-4 text-green-400 text-sm">
Average CVSS: {averageCVSS}
</div>
<div className="h-[300px] w-full">
<Bar data={chartData} options={options} />
</div>
</div>
);
};
61 changes: 61 additions & 0 deletions frontend/src/components/charts/CWECloud.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { t } from 'i18next';
import React from 'react';
import { FaBug } from 'react-icons/fa';

import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '../ui/tooltip';

type CWEItem = {
id: string;
size: number;
};

type Props = {
items: CWEItem[];
mostCommon: string;
};
caverav marked this conversation as resolved.
Show resolved Hide resolved

export const CWECloud: React.FC<Props> = ({ items, mostCommon }) => {
items = items.filter(item => item.id !== '');
if (!items.length) {
return (
<p className="text-sm text-gray-500">{t('err.noMatchingRecords')}</p>
);
}
caverav marked this conversation as resolved.
Show resolved Hide resolved

return (
<div className="bg-gray-900 rounded-lg p-4">
<p className="text-sm text-gray-400 mb-4">
{t('mostCommon')}: {mostCommon}
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
<TooltipProvider>
{items.map(item => (
<Tooltip key={item.id}>
<TooltipTrigger>
<div className="bg-gray-800 p-4 rounded-lg shadow-md flex items-center">
<FaBug className="text-red-500 mr-3" size={24} />
<div>
<p className="text-white text-lg font-semibold">
{item.id.split(' ')[0].replace(':', '')}
</p>
<p className="text-gray-400">
{t('occurrences')}: {item.size}
</p>
</div>
</div>
caverav marked this conversation as resolved.
Show resolved Hide resolved
</TooltipTrigger>
<TooltipContent>
<p>{item.id}</p>
</TooltipContent>
</Tooltip>
))}
</TooltipProvider>
</div>
</div>
);
};
69 changes: 69 additions & 0 deletions frontend/src/components/charts/RemediationPriorityChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
BarElement,
CategoryScale,
Chart as ChartJS,
Legend,
LinearScale,
Title,
Tooltip,
} from 'chart.js';
import { t } from 'i18next';
import React from 'react';
import { Bar } from 'react-chartjs-2';

ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
);

type PriorityData = {
name: string;
count: number;
color: string;
};

type Props = {
data: PriorityData[];
};

export const RemediationPriorityChart: React.FC<Props> = ({ data }) => {
if (!data.length) {
return (
<p className="text-sm text-gray-500">{t('err.noMatchingRecords')}</p>
);
}
const chartData = {
labels: data.map(d => d.name),
datasets: [
{
data: data.map(d => d.count),
backgroundColor: data.map(d => d.color),
},
],
};

const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
},
scales: {
y: {
beginAtZero: true,
},
},
};

return (
<div className="h-[300px] w-full">
<Bar data={chartData} options={options} />
</div>
);
};
Loading