Skip to content

Commit

Permalink
[report] Replace example with proper report parsing (#11)
Browse files Browse the repository at this point in the history
This PR adds an initial working version of report parsing and include
the following additional changes:

1. Add jest dependencies.
2. Add a simple popup to display the details when clicking on "Link"
3. Updated types from interuss/monitoring schemas.

Few known issues:
- Requirements and child capabilities are not displayed at the same time
on a page.
- Error handling is probably too aggressive

Note that report_uspace.json will be removed before merge to not checkin
big files on the main branch.
  • Loading branch information
barroco committed Aug 17, 2023
1 parent 72e7581 commit 856d3a7
Show file tree
Hide file tree
Showing 11 changed files with 2,190 additions and 279 deletions.
12 changes: 11 additions & 1 deletion reports/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@
"prebuild": "cd ../tools && yarn generate-types",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
"preview": "vite preview",
"test": "jest"
},
"dependencies": {
"jsonpath": "^1.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0"
},
"devDependencies": {
"@types/jest": "^29.5.3",
"@types/jsonpath": "^0.2.0",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
Expand All @@ -25,8 +29,14 @@
"eslint": "^8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"jest": "^29.6.2",
"ts-jest": "^29.1.1",
"typescript": "^5.0.2",
"vite": "^4.4.5",
"vite-plugin-singlefile": "^0.13.5"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
}
}
15 changes: 10 additions & 5 deletions reports/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { RouterProvider, createHashRouter } from "react-router-dom";
import { useReport } from "./capability/useReport";
import "./App.css";

function App() {
// FIXME use the report from the config
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const configuration = JSON.stringify((window as any)["interuss"]);
const configuration = JSON.parse((window as any)["interuss"] || "{}");
console.log("Configuration:", configuration);

const { report, nav } = useReport();
const { loading, report, nav } = useReport(configuration);
if (loading) {
return <div>Loading report...</div>;
}
if (!report) {
return <div>Report not found</div>;
}
const router = createBrowserRouter(nav);
return <RouterProvider router={router} />;
const router = createHashRouter(nav);
return <>
<RouterProvider router={router} />
</>;
}

export default App;
81 changes: 65 additions & 16 deletions reports/src/capability/CapabilityTable.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,59 @@
import {
Capability,
Check,
Requirement,
exampleReport,
} from "./capabilityTypes";
import {useNavigate} from "react-router-dom";
import {Capability, Check, Requirement} from "./capabilityTypes";
import {useEffect, useState} from "react";

type CapabilityTableProps = {
capability?: Capability;
capability: Capability;
};

export const CheckLabel = ({name, docUrl}: {name: string; docUrl?: string}) => {
return docUrl ? <a href={docUrl}>{name}</a> : <>{name}</>;
};

export const CheckRow = ({ check }: { check: Check }) => {
export const CheckRow = ({check}: {check: Check}) => {
const [showDetails, setShowDetails] = useState(false);
const separator = " :: ";
const checkSource = (
<>
<CheckLabel {...check.scenario} />
{separator}
<CheckLabel {...check.case} />
{separator}
<CheckLabel {...check.step} />
{separator}
<CheckLabel name={check.name} />
</>
);

return (
<tr>
<td>{check.name}</td>
<td>{checkSource}</td>
<td className={check.result === "pass" ? "pass" : "fail"}>
{check.result === "pass" ? "PASS" : "FAIL"}
</td>
<td>
<a href={check.detailLink}>Link</a>
<a onClick={() => setShowDetails(true)}>Link</a>
{/* TODO: Beautify popup / move to a dedicated page */}
{showDetails && (
<div
style={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
background: "#fff",
}}
>
<a onClick={() => setShowDetails(false)}>
<i>Click anywhere to close.</i>
<h2>
{check.name} was evaluated in step {check.step.name}. Details:
</h2>
<pre>{JSON.stringify(check.details, null, 2)}</pre>
</a>
</div>
)}
</td>
</tr>
);
Expand Down Expand Up @@ -46,10 +82,13 @@ export const ChildCapabilityRow = ({
capability: Capability;
path: string;
}) => {
const navigate = useNavigate();
return (
<tr>
<td colSpan={2}>
<a href={path}>{capability.name}</a>
<a onClick={() => navigate(path, {relative: "path"})}>
{capability.name} ({capability.participant_id})
</a>
</td>
<td
className={capability.result === "pass" ? "pass" : "fail"}
Expand All @@ -70,7 +109,7 @@ const ChildCapabilityHeader = () => {
);
};

export const CapabilityRows = ({ capability }: { capability: Capability }) => {
export const CapabilityRows = ({capability}: {capability: Capability}) => {
const requirements = capability.requirements
.flatMap((r) => requirementRow(r))
.flat();
Expand All @@ -84,15 +123,24 @@ export const CapabilityRows = ({ capability }: { capability: Capability }) => {
const allRows = [...requirements, ...childTable];
return [
<tr>
<td rowSpan={allRows.length + 1}>{capability.name}</td>
<td rowSpan={allRows.length + 1}>
{capability.name} ({capability.participant_id})
</td>
</tr>,
...allRows,
];
};

export const CapabilityTable = ({
capability = exampleReport.capability,
}: CapabilityTableProps) => {
export const CapabilityDebug = ({capability}: {capability: Capability}) => {
// return <code><pre style={{textAlign:"left"}}>{JSON.stringify(capability, null, 2)}</pre></code>;
useEffect(
() => console.info("Displayed Capability: ", capability),
[capability]
);
return <></>;
};

export const CapabilityTable = ({capability}: CapabilityTableProps) => {
return (
<>
<table>
Expand All @@ -109,6 +157,7 @@ export const CapabilityTable = ({
<CapabilityRows capability={capability} />
</tbody>
</table>
<CapabilityDebug capability={capability} />
</>
);
};
132 changes: 18 additions & 114 deletions reports/src/capability/capabilityTypes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
type CapabilityResult = "pass" | "fail" | "missing";
type CheckResult = "pass" | "fail";
export type CheckResult = "pass" | "fail";

export type Check = {
result: CheckResult;
scenario: {
name: string;
docUrl: string;
}
case: {
name: string;
docUrl: string;
}
step: {
name: string;
docUrl: string;
}

name: string;
detailLink: string;
};
result: CheckResult
details: object; // Switch to a JSON path
}

export type Requirement = {
name: string;
Expand All @@ -14,6 +27,7 @@ export type Requirement = {

export type Capability = {
name: string;
participant_id?: string;
result: CapabilityResult;
requirements: Requirement[];
childCapabilities: Capability[];
Expand All @@ -22,113 +36,3 @@ export type Capability = {
export type Report = {
capability: Capability;
};

export const exampleReport: Report = {
capability: {
name: "ASTM Service Provider",
result: "fail",
requirements: [
{
name: "astm.f3548.v21.GEN0310",
checks: [
{
name: "Nominal behavior :: Setup :: Clear",
result: "pass",
detailLink: "Link to test details",
},
{
name: "SP polling :: Poll :: Valid data",
result: "pass",
detailLink: "Link to test details",
},
],
},
{
name: "astm.f3548.v21.OPIN0030",
checks: [
{
name: "...",
result: "fail",
detailLink: "Link to test details",
},
{
name: "...",
result: "pass",
detailLink: "Link to test details",
},
],
},
{
name: "astm.f3548.v21.SDC0015",
checks: [
// Should display "Not tested"
],
},
{
name: "astm.f3548.v21.GEN0200",
checks: [
{
name: "...",
result: "pass",
detailLink: "Link to test details",
},
],
},
],
childCapabilities: [
{
name: "ASTM SP Operator ID Provider",
result: "pass",
requirements: [
{
name: "child 1",
checks: [
{
name: "Nominal behavior :: Setup :: Clear",
result: "pass",
detailLink: "Link to test details",
},
{
name: "SP polling :: Poll :: Valid data",
result: "pass",
detailLink: "Link to test details",
},
],
},
{
name: "child 2",
checks: [
{
name: "...",
result: "fail",
detailLink: "Link to test details",
},
{
name: "...",
result: "pass",
detailLink: "Link to test details",
},
],
},
{
name: "child 3",
checks: [
// Should display "Not tested"
],
},
{
name: "child 4",
checks: [
{
name: "...",
result: "pass",
detailLink: "Link to test details",
},
],
},
],
childCapabilities: [],
},
],
},
};
Loading

0 comments on commit 856d3a7

Please sign in to comment.