From 8159090843dc7bfab712e1fc4e2f2d8686d67ffb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 22 Dec 2025 13:13:20 +0100 Subject: [PATCH 1/2] reporting updates --- src/pages/dashboardv2/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/dashboardv2/index.js b/src/pages/dashboardv2/index.js index 3eb6718fa40c..654f8d8370f1 100644 --- a/src/pages/dashboardv2/index.js +++ b/src/pages/dashboardv2/index.js @@ -108,10 +108,10 @@ const Page = () => { TenantName: organization.data?.displayName || "", Domain: currentTenant || "", TestResultSummary: { - IdentityPassed: testsApi.data.TestCounts?.Successful || 0, - IdentityTotal: testsApi.data.TestCounts?.Total || 0, - DevicesPassed: testsApi.data.TestCounts?.Successful || 0, - DevicesTotal: testsApi.data.TestCounts?.Total || 0, + IdentityPassed: testsApi.data.TestCounts?.Identity?.Passed || 0, + IdentityTotal: testsApi.data.TestCounts?.Identity?.Total || 0, + DevicesPassed: testsApi.data.TestCounts?.Devices?.Passed || 0, + DevicesTotal: testsApi.data.TestCounts?.Devices?.Total || 0, DataPassed: 0, DataTotal: 0, }, From b0d7b6dd02d7d83479dc164a8ccc6b2f66f38493 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:41:30 +0100 Subject: [PATCH 2/2] Reporting --- src/components/CippTable/CippDataTable.js | 16 ++ src/pages/dashboardv2/devices/index.js | 329 ++++++++++++++++++++-- src/pages/dashboardv2/identity/index.js | 329 ++++++++++++++++++++-- src/pages/dashboardv2/index.js | 1 - 4 files changed, 638 insertions(+), 37 deletions(-) diff --git a/src/components/CippTable/CippDataTable.js b/src/components/CippTable/CippDataTable.js index 5a1590ac1fde..7322168d728e 100644 --- a/src/components/CippTable/CippDataTable.js +++ b/src/components/CippTable/CippDataTable.js @@ -97,6 +97,7 @@ export const CippDataTable = (props) => { simple = false, cardButton, offCanvas = false, + offCanvasOnRowClick = false, noCard = false, hideTitle = false, refreshFunction, @@ -286,6 +287,21 @@ export const CippDataTable = (props) => { top: table.getState().isFullScreen ? 64 : undefined, }, }), + muiTableBodyRowProps: + offCanvasOnRowClick && offCanvas + ? ({ row }) => ({ + onClick: () => { + setOffCanvasData(row.original); + setOffcanvasVisible(true); + }, + sx: { + cursor: "pointer", + "&:hover": { + backgroundColor: "action.hover", + }, + }, + }) + : undefined, // Add global styles to target the specific filter components enableColumnFilterModes: true, muiTableHeadCellProps: { diff --git a/src/pages/dashboardv2/devices/index.js b/src/pages/dashboardv2/devices/index.js index a4c96d300f0d..13de6730b648 100644 --- a/src/pages/dashboardv2/devices/index.js +++ b/src/pages/dashboardv2/devices/index.js @@ -1,28 +1,321 @@ -import { Container, Typography, Card, CardContent, CardHeader, Box } from "@mui/material"; +import { + Container, + Typography, + Card, + CardContent, + CardHeader, + Box, + Stack, + Chip, +} from "@mui/material"; import { TabbedLayout } from "/src/layouts/TabbedLayout"; import { Layout as DashboardLayout } from "/src/layouts/index.js"; import tabOptions from "../tabOptions"; +import { useSettings } from "/src/hooks/use-settings"; +import { ApiGetCall } from "/src/api/ApiCall.jsx"; +import { CippDataTable } from "/src/components/CippTable/CippDataTable"; +import ReactMarkdown from "react-markdown"; +import { Grid } from "@mui/system"; const Page = () => { + const settings = useSettings(); + const { currentTenant } = settings; + + const testsApi = ApiGetCall({ + url: "/api/ListTests", + data: { tenantFilter: currentTenant, reportId: "d5d1e123-bce0-482d-971f-be6ed820dd92" }, + queryKey: `${currentTenant}-ListTests-d5d1e123-bce0-482d-971f-be6ed820dd92`, + }); + + const deviceTests = + testsApi.data?.TestResults?.filter((test) => test.TestType === "Devices") || []; + + const getStatusColor = (status) => { + switch (status?.toLowerCase()) { + case "passed": + return "success"; + case "failed": + return "error"; + case "investigate": + return "warning"; + case "skipped": + return "default"; + default: + return "default"; + } + }; + + const getRiskColor = (risk) => { + switch (risk?.toLowerCase()) { + case "high": + return "error"; + case "medium": + return "warning"; + case "low": + return "info"; + default: + return "default"; + } + }; + + const getImpactColor = (impact) => { + switch (impact?.toLowerCase()) { + case "high": + return "error"; + case "medium": + return "warning"; + case "low": + return "info"; + default: + return "default"; + } + }; + + const offCanvas = { + extendedInfoFields: ["Name", "Risk", "Status", "Category"], + size: "lg", + children: (row) => { + return ( + + + + ({ + xs: `1px solid ${theme.palette.divider}`, + md: "none", + }), + borderRight: (theme) => ({ + md: `1px solid ${theme.palette.divider}`, + }), + }} + > + + + + Risk Level + + + + + + + + ({ + xs: `1px solid ${theme.palette.divider}`, + md: "none", + }), + borderRight: (theme) => ({ + md: `1px solid ${theme.palette.divider}`, + }), + }} + > + + + + User Impact + + + + + + + + + + + + Implementation Effort + + + + + + + + + + + {row.ResultMarkdown && ( + + + + {row.Name} + + + theme.palette.primary.main, + textDecoration: "underline", + "&:hover": { + textDecoration: "none", + }, + }, + color: "text.secondary", + fontSize: "0.875rem", + lineHeight: 1.43, + "& p": { + my: 1, + }, + "& ul": { + my: 1, + pl: 2, + }, + "& li": { + my: 0.5, + }, + "& h1, & h2, & h3, & h4, & h5, & h6": { + mt: 2, + mb: 1, + fontWeight: "bold", + }, + "& code": { + backgroundColor: "action.hover", + padding: "2px 6px", + borderRadius: 1, + fontSize: "0.85em", + }, + "& pre": { + backgroundColor: "action.hover", + padding: 2, + borderRadius: 1, + overflow: "auto", + }, + }} + > + ( + + {children} + + ), + }} + > + {row.ResultMarkdown} + + + + + )} + + + + + + What did we check + + + {row.Category && ( + + + Category + + {row.Category} + + )} + + + + This test verifies that device compliance policies are properly configured in + Microsoft Intune. Compliance policies define the requirements that devices must + meet to access corporate resources, such as encryption, password requirements, + and operating system versions. + + + Why this matters: Non-compliant devices pose significant + security risks to your organization. They may lack critical security updates, + have weak authentication, or be missing essential security features like + encryption. Properly configured compliance policies ensure only secure devices + can access sensitive data. + + + Recommendation: Create comprehensive compliance policies that + cover all device platforms (Windows, iOS, Android, macOS). Configure Conditional + Access to block non-compliant devices and set up automated remediation actions + to help users bring their devices back into compliance. + + + + + + + ); + }, + }; + + const filters = [ + { + filterName: "Passed", + value: [{ id: "Status", value: "Passed" }], + type: "column", + }, + { + filterName: "Failed", + value: [{ id: "Status", value: "Failed" }], + type: "column", + }, + { + filterName: "Investigate", + value: [{ id: "Status", value: "Investigate" }], + type: "column", + }, + { + filterName: "Skipped", + value: [{ id: "Status", value: "Skipped" }], + type: "column", + }, + { + filterName: "High Risk", + value: [{ id: "Risk", value: "High" }], + type: "column", + }, + { + filterName: "Medium Risk", + value: [{ id: "Risk", value: "Medium" }], + type: "column", + }, + { + filterName: "Low Risk", + value: [{ id: "Risk", value: "Low" }], + type: "column", + }, + ]; + return ( - - - - - - Device Test Results - - - This tab will display detailed device test results and recommendations. - - - Review device compliance policies, enrollment restrictions, and management - configurations to enhance your device security posture. - - - - + ); }; diff --git a/src/pages/dashboardv2/identity/index.js b/src/pages/dashboardv2/identity/index.js index 78b76b13e131..81870c3172b8 100644 --- a/src/pages/dashboardv2/identity/index.js +++ b/src/pages/dashboardv2/identity/index.js @@ -1,28 +1,321 @@ -import { Container, Typography, Card, CardContent, CardHeader, Box } from "@mui/material"; +import { + Container, + Typography, + Card, + CardContent, + CardHeader, + Box, + Stack, + Chip, +} from "@mui/material"; import { TabbedLayout } from "/src/layouts/TabbedLayout"; import { Layout as DashboardLayout } from "/src/layouts/index.js"; import tabOptions from "../tabOptions"; +import { useSettings } from "/src/hooks/use-settings"; +import { ApiGetCall } from "/src/api/ApiCall.jsx"; +import { CippDataTable } from "/src/components/CippTable/CippDataTable"; +import { Info } from "@mui/icons-material"; +import ReactMarkdown from "react-markdown"; +import { Grid } from "@mui/system"; const Page = () => { + const settings = useSettings(); + const { currentTenant } = settings; + + const testsApi = ApiGetCall({ + url: "/api/ListTests", + data: { tenantFilter: currentTenant, reportId: "d5d1e123-bce0-482d-971f-be6ed820dd92" }, + queryKey: `${currentTenant}-ListTests-d5d1e123-bce0-482d-971f-be6ed820dd92`, + }); + + const identityTests = + testsApi.data?.TestResults?.filter((test) => test.TestType === "Identity") || []; + + const getStatusColor = (status) => { + switch (status?.toLowerCase()) { + case "passed": + return "success"; + case "failed": + return "error"; + case "investigate": + return "warning"; + case "skipped": + return "default"; + default: + return "default"; + } + }; + + const getRiskColor = (risk) => { + switch (risk?.toLowerCase()) { + case "high": + return "error"; + case "medium": + return "warning"; + case "low": + return "info"; + default: + return "default"; + } + }; + + const getImpactColor = (impact) => { + switch (impact?.toLowerCase()) { + case "high": + return "error"; + case "medium": + return "warning"; + case "low": + return "info"; + default: + return "default"; + } + }; + + const offCanvas = { + size: "lg", + children: (row) => { + return ( + + + + ({ + xs: `1px solid ${theme.palette.divider}`, + md: "none", + }), + borderRight: (theme) => ({ + md: `1px solid ${theme.palette.divider}`, + }), + }} + > + + + + Risk Level + + + + + + + + ({ + xs: `1px solid ${theme.palette.divider}`, + md: "none", + }), + borderRight: (theme) => ({ + md: `1px solid ${theme.palette.divider}`, + }), + }} + > + + + + User Impact + + + + + + + + + + + + Implementation Effort + + + + + + + + + + + {row.ResultMarkdown && ( + + + + {row.Name} + + + theme.palette.primary.main, + textDecoration: "underline", + "&:hover": { + textDecoration: "none", + }, + }, + color: "text.secondary", + fontSize: "0.875rem", + lineHeight: 1.43, + "& p": { + my: 1, + }, + "& ul": { + my: 1, + pl: 2, + }, + "& li": { + my: 0.5, + }, + "& h1, & h2, & h3, & h4, & h5, & h6": { + mt: 2, + mb: 1, + fontWeight: "bold", + }, + "& code": { + backgroundColor: "action.hover", + padding: "2px 6px", + borderRadius: 1, + fontSize: "0.85em", + }, + "& pre": { + backgroundColor: "action.hover", + padding: 2, + borderRadius: 1, + overflow: "auto", + }, + }} + > + ( + + {children} + + ), + }} + > + {row.ResultMarkdown} + + + + + )} + + + + + + What did we check + + + {row.Category && ( + + + Category + + {row.Category} + + )} + + + + This test verifies that Multi-Factor Authentication (MFA) is enabled for all + administrative accounts in your Microsoft 365 tenant. Administrative accounts + have elevated privileges and are prime targets for attackers. Enabling MFA adds + an additional layer of security by requiring a second form of verification + beyond just a password. + + + Why this matters: According to Microsoft, MFA can block over + 99.9% of account compromise attacks. Without MFA, compromised administrator + credentials can lead to complete tenant takeover, data breaches, and significant + business disruption. + + + Recommendation: Ensure all users with administrative roles have + MFA enabled through Conditional Access policies or per-user MFA settings. + Consider using stronger authentication methods like FIDO2 security keys or the + Microsoft Authenticator app for your most privileged accounts. + + + + + + + ); + }, + }; + + const filters = [ + { + filterName: "Passed", + value: [{ id: "Status", value: "Passed" }], + type: "column", + }, + { + filterName: "Failed", + value: [{ id: "Status", value: "Failed" }], + type: "column", + }, + { + filterName: "Investigate", + value: [{ id: "Status", value: "Investigate" }], + type: "column", + }, + { + filterName: "Skipped", + value: [{ id: "Status", value: "Skipped" }], + type: "column", + }, + { + filterName: "High Risk", + value: [{ id: "Risk", value: "High" }], + type: "column", + }, + { + filterName: "Medium Risk", + value: [{ id: "Risk", value: "Medium" }], + type: "column", + }, + { + filterName: "Low Risk", + value: [{ id: "Risk", value: "Low" }], + type: "column", + }, + ]; + return ( - - - - - - Identity Test Results - - - This tab will display detailed identity test results and recommendations. - - - Configure your identity policies and authentication methods to improve your zero trust - posture. - - - - + ); }; diff --git a/src/pages/dashboardv2/index.js b/src/pages/dashboardv2/index.js index 654f8d8370f1..a74e4be1cf39 100644 --- a/src/pages/dashboardv2/index.js +++ b/src/pages/dashboardv2/index.js @@ -25,7 +25,6 @@ import { Bar, PieChart, Pie, - Cell, RadialBarChart, RadialBar, PolarAngleAxis,