Skip to content

Commit

Permalink
Report viewer (#8)
Browse files Browse the repository at this point in the history
- [x] Create a report structure that reflects the UI structure
- [x] Routing to go through capability children
- [x] Display table for a given capability

<img width="858" alt="Screenshot 2023-08-14 at 16 45 02"
src="https://github.com/Orbitalize/reports/assets/1410314/47f92ab3-b0ce-4b42-8b83-3a3ff5bc4fd4">

TODO: 
- [ ] Parse the report to create the internal report structure
  • Loading branch information
ChrisJamesC authored Aug 15, 2023
1 parent 04f514d commit 72e7581
Show file tree
Hide file tree
Showing 12 changed files with 394 additions and 57 deletions.
3 changes: 3 additions & 0 deletions reports/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Report examples
public/monitoring-tests-reports

# Logs
logs
*.log
Expand Down
5 changes: 2 additions & 3 deletions reports/index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>Report</title>
<!--
To configure the application, set the window.interuss object.
See TemplatedReportApplicationConfiguration in [1] for details about the expected structure.
Expand All @@ -13,7 +13,6 @@
Do not remove the next commented tag since it used by the templating engine to automate configuration injection.
-->
<!-- Configuration goes here -->

</head>
<body>
<div id="root"></div>
Expand Down
4 changes: 3 additions & 1 deletion reports/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "vite",
"dev": "vite",
"prebuild": "cd ../tools && yarn generate-types",
"build": "tsc && vite build",
Expand All @@ -12,7 +13,8 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
Expand Down
49 changes: 25 additions & 24 deletions reports/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,39 @@
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
table {
border-collapse: collapse;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);

table, th, td {
border: 1px solid black;
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);

th, td {
padding: 4px;
text-align: left;
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
td {
&.fail {
background-color: red;
color: white;
font-weight: 600;
}
to {
transform: rotate(360deg);
&.pass {
background-color: green;
color: white;
font-weight: 600;
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
th {
background-color: lightgray;
}

.read-the-docs {
color: #888;
}
@media (prefers-color-scheme: dark) {
th {
background-color: dimgray;
}
}
43 changes: 14 additions & 29 deletions reports/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
import './App.css'

import { ReportsReportTestRunReport } from './types/TestRunReport'

// TODO: Replace with actual JSON report. Placeholder to verify proper typing.
const report: ReportsReportTestRunReport =
{
baseline_signature: '',
codebase_version: '',
commit_hash: '',
report: {},
configuration: {
action: {},
resources: {
resource_declarations: {}
}
},
file_signatures: {}
}
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { useReport } from "./capability/useReport";
import "./App.css";

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

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

export default App
export default App;
114 changes: 114 additions & 0 deletions reports/src/capability/CapabilityTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import {
Capability,
Check,
Requirement,
exampleReport,
} from "./capabilityTypes";

type CapabilityTableProps = {
capability?: Capability;
};

export const CheckRow = ({ check }: { check: Check }) => {
return (
<tr>
<td>{check.name}</td>
<td className={check.result === "pass" ? "pass" : "fail"}>
{check.result === "pass" ? "PASS" : "FAIL"}
</td>
<td>
<a href={check.detailLink}>Link</a>
</td>
</tr>
);
};

const requirementRow = (requirement: Requirement) => {
const checks = requirement.checks.map((c) => <CheckRow check={c} />);
const requirementHeader = (
<tr>
<td rowSpan={checks.length + 1}>{requirement.name}</td>
{!checks.length && <td colSpan={3}>Not tested</td>}
</tr>
);

if (checks.length) {
return [requirementHeader, ...checks];
} else {
return [requirementHeader];
}
};

export const ChildCapabilityRow = ({
capability,
path,
}: {
capability: Capability;
path: string;
}) => {
return (
<tr>
<td colSpan={2}>
<a href={path}>{capability.name}</a>
</td>
<td
className={capability.result === "pass" ? "pass" : "fail"}
colSpan={2}
>
{capability.result === "pass" ? "PASS" : "FAIL"}
</td>
</tr>
);
};

const ChildCapabilityHeader = () => {
return (
<tr>
<th colSpan={2}>Child Capability</th>
<th colSpan={2}>Result</th>
</tr>
);
};

export const CapabilityRows = ({ capability }: { capability: Capability }) => {
const requirements = capability.requirements
.flatMap((r) => requirementRow(r))
.flat();
const childCapabilities = capability.childCapabilities.map((c, i) => (
<ChildCapabilityRow capability={c} path={i.toString()} />
));
const childTable = childCapabilities
? [<ChildCapabilityHeader />, ...childCapabilities]
: [];

const allRows = [...requirements, ...childTable];
return [
<tr>
<td rowSpan={allRows.length + 1}>{capability.name}</td>
</tr>,
...allRows,
];
};

export const CapabilityTable = ({
capability = exampleReport.capability,
}: CapabilityTableProps) => {
return (
<>
<table>
<thead>
<tr>
<th>Capability</th>
<th>Requirement</th>
<th>Test Check</th>
<th>Result</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<CapabilityRows capability={capability} />
</tbody>
</table>
</>
);
};
Loading

0 comments on commit 72e7581

Please sign in to comment.