diff --git a/reports/src/capability/CapabilityTable.tsx b/reports/src/capability/CapabilityTable.tsx index a8ce5aa..9a36b8a 100644 --- a/reports/src/capability/CapabilityTable.tsx +++ b/reports/src/capability/CapabilityTable.tsx @@ -1,226 +1,17 @@ -import { Link as RouterLink } from "react-router-dom"; -import { - Accordion, - AccordionDetails, - AccordionSummary, - Box, - Breadcrumbs, - Chip, - Dialog, - DialogContent, - Link, - Typography, -} from "@mui/material"; -import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; - -import { Capability, Check, Requirement } from "./capabilityTypes"; -import { useEffect, useState } from "react"; +import { Box, Breadcrumbs, Typography } from "@mui/material"; +import { Capability } from "./capabilityTypes"; import { useMatches } from "react-router-dom"; import { ReactNode } from "react"; import { Report } from "./capabilityTypes"; import { CapabilityTableHeader } from "./CapabilityTableHeader"; +import { RequirementTable } from "./RequirementTable"; +import { ChildCapabilityTable } from "./ChildCapabilityTable"; type CapabilityTableProps = { capability: Capability; report: Report; }; -export const CheckLabel = ({ - name, - docUrl, -}: { - name: string; - docUrl?: string; -}) => { - return docUrl ? {name} : <>{name}; -}; - -const getCheckId = (check: Check): string => { - return [ - check.scenario.name, - check.case.name, - check.step.name, - check.name, - ].join("-"); -}; - -const CheckStatusTag = ({ check }: { check: Check }) => { - const [showDetails, setShowDetails] = useState(false); - return ( -
- setShowDetails(true)} - /> - setShowDetails(false)} - open={showDetails} - > - - - {check.name} was evaluated in step {check.step.name} - - Details: -
{JSON.stringify(check.details, null, 2)}
-
-
-
- ); -}; - -const AggregatedStatusTag = ({ checks }: { checks: Check[] }) => { - const successfulChecks = checks.reduce( - (acc, check) => acc + (check.result === "pass" ? 1 : 0), - 0 - ); - const pass = successfulChecks === checks.length; - return ( - - ); -}; - -const CheckAggregateRow = ({ checks }: { checks: Check[] }) => { - const separator = " :: "; - const checkSource = ( - <> - - {separator} - - {separator} - - {separator} - - - ); - return ( - - - - } - aria-controls="panel1a-content" - id="panel1a-header" - sx={{ - "& .MuiAccordionSummary-content": { - display: "flex", - justifyContent: "space-between", - }, - }} - > - {checkSource} - - - - - {checks.map((c) => ( - - ))} - - - - - - ); -}; - -const checkAggregatedRows = (requirement: Requirement) => { - // Group checks by ID - const aggregatedChecks = requirement.checks.reduce((acc, check) => { - const checkId = getCheckId(check); - if (checkId in acc) { - return { ...acc, [checkId]: [...acc[checkId], check] }; - } else { - return { ...acc, [checkId]: [check] }; - } - }, {} as Record); - - // For each check, display a checkRow - // Aggregate titles by check ID - return Object.keys(aggregatedChecks) - .map((key) => { - const checks = aggregatedChecks[key]; - return ; - }) - .flat(); -}; - -const requirementRow = (requirement: Requirement) => { - const checks = checkAggregatedRows(requirement); - const requirementHeader = ( - - {requirement.name} - {!checks.length && Not tested} - - ); - - if (checks.length) { - return [requirementHeader, ...checks]; - } else { - return [requirementHeader]; - } -}; - -export const ChildCapabilityRow = ({ - capability, - path, -}: { - capability: Capability; - path: string; -}) => { - const pass = capability.result === "pass"; - return ( - - - - {capability.name} ({capability.participant_id}) - - - - - - - ); -}; - -const ChildCapabilityHeader = () => { - return ( - - Child Capability - Result - - ); -}; - -export const CapabilityRows = ({ capability }: { capability: Capability }) => { - const requirements = capability.requirements - .flatMap((r) => requirementRow(r)) - .flat(); - const childCapabilities = capability.childCapabilities.map((c, i) => ( - - )); - const childTable = childCapabilities - ? [, ...childCapabilities] - : []; - - const allRows = [...requirements, ...childTable]; - return [...allRows]; -}; - -export const CapabilityDebug = ({ capability }: { capability: Capability }) => { - // return
{JSON.stringify(capability, null, 2)}
; - useEffect( - () => console.info("Displayed Capability: ", capability), - [capability] - ); - return <>; -}; - type CrumbHandle = { crumb: () => ReactNode }; function CapabilityBreadcrumbs() { @@ -244,6 +35,7 @@ export const CapabilityTable = ({ if (!capability) { return Capability not found; } + return ( <> @@ -254,27 +46,19 @@ export const CapabilityTable = ({ theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[900], - // flexGrow: 1, - // height: "100vh", - // overflow: "auto", padding: 8, paddingTop: 10, }} > -
- - - - - - - - - - -
RequirementTest Check
- + + Requirements + + + + Child capabilities + + ); diff --git a/reports/src/capability/ChildCapabilityTable.tsx b/reports/src/capability/ChildCapabilityTable.tsx new file mode 100644 index 0000000..0c629be --- /dev/null +++ b/reports/src/capability/ChildCapabilityTable.tsx @@ -0,0 +1,49 @@ +import { Chip, Link } from "@mui/material"; +import { Link as RouterLink } from "react-router-dom"; +import { Capability } from "./capabilityTypes"; +export const ChildCapabilityRow = ({ + capability, + path, +}: { + capability: Capability; + path: string; +}) => { + const pass = capability.result === "pass"; + return ( + + + + {capability.name} ({capability.participant_id}) + + + + + + + ); +}; + +export const ChildCapabilityTable = ({ + capability, +}: { + capability: Capability; +}) => { + const childCapabilities = capability.childCapabilities.map((c, i) => ( + + )); + + return ( + + + + + + + + {childCapabilities} +
Child CapabilityResult
+ ); +}; diff --git a/reports/src/capability/RequirementTable.tsx b/reports/src/capability/RequirementTable.tsx new file mode 100644 index 0000000..3983398 --- /dev/null +++ b/reports/src/capability/RequirementTable.tsx @@ -0,0 +1,170 @@ +import { useState } from "react"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Chip, + Dialog, + DialogContent, + Typography, + Link, +} from "@mui/material"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; + +import { Capability, Check, Requirement } from "./capabilityTypes"; + +const CheckLabel = ({ name, docUrl }: { name: string; docUrl?: string }) => { + return docUrl ? {name} : <>{name}; +}; +const CheckStatusTag = ({ check }: { check: Check }) => { + const [showDetails, setShowDetails] = useState(false); + return ( +
+ setShowDetails(true)} + /> + setShowDetails(false)} + open={showDetails} + > + + + {check.name} was evaluated in step {check.step.name} + + Details: +
{JSON.stringify(check.details, null, 2)}
+
+
+
+ ); +}; +const AggregatedStatusTag = ({ checks }: { checks: Check[] }) => { + const successfulChecks = checks.reduce( + (acc, check) => acc + (check.result === "pass" ? 1 : 0), + 0 + ); + const pass = successfulChecks === checks.length; + return ( + + ); +}; + +const CheckAggregateRow = ({ checks }: { checks: Check[] }) => { + const separator = " :: "; + const checkSource = ( + <> + + {separator} + + {separator} + + {separator} + + + ); + return ( + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + sx={{ + "& .MuiAccordionSummary-content": { + display: "flex", + justifyContent: "space-between", + }, + }} + > + {checkSource} + + + + + {checks.map((c) => ( + + ))} + + + + + + ); +}; + +const getCheckId = (check: Check): string => { + return [ + check.scenario.name, + check.case.name, + check.step.name, + check.name, + ].join("-"); +}; + +const checkAggregatedRows = (requirement: Requirement) => { + // Group checks by ID + const aggregatedChecks = requirement.checks.reduce((acc, check) => { + const checkId = getCheckId(check); + if (checkId in acc) { + return { ...acc, [checkId]: [...acc[checkId], check] }; + } else { + return { ...acc, [checkId]: [check] }; + } + }, {} as Record); + + // For each check, display a checkRow + // Aggregate titles by check ID + return Object.keys(aggregatedChecks) + .map((key) => { + const checks = aggregatedChecks[key]; + return ; + }) + .flat(); +}; +const requirementRow = (requirement: Requirement) => { + const checks = checkAggregatedRows(requirement); + const requirementHeader = ( + + {requirement.name} + {!checks.length && Not tested} + + ); + + if (checks.length) { + return [requirementHeader, ...checks]; + } else { + return [requirementHeader]; + } +}; + +export const RequirementTable = ({ + capability, +}: { + capability: Capability; +}) => { + const requirements = capability.requirements + .sort((a, b) => (a.name > b.name ? 1 : -1)) + .flatMap((r) => requirementRow(r)) + .flat(); + + return ( + + + + + + + + + {/* */} + {requirements} + +
RequirementTest Check
+ ); +};