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 3eb6718fa40c..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,
@@ -108,10 +107,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,
},