Skip to content

Commit

Permalink
feat: create analysis html report (#307)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonylyjones authored Jun 28, 2024
1 parent 8911863 commit 54d3eaa
Show file tree
Hide file tree
Showing 69 changed files with 6,196 additions and 520 deletions.
1 change: 1 addition & 0 deletions cli/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ out
local
src/**/*.js
*.tgz
resources/report.html
1 change: 1 addition & 0 deletions cli/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ src/*.test.ts
jest.config.js
tsconfig.json
*.tgz
html-report
16 changes: 16 additions & 0 deletions cli/html-report/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"@typescript-eslint/ban-ts-comment": "off",
"react-refresh/only-export-components": "off",
},
}
24 changes: 24 additions & 0 deletions cli/html-report/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
39 changes: 39 additions & 0 deletions cli/html-report/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Azimutt Html Report

Azimutt Html Report generates the html template file for the `analyze cli`

## Developing

The project uses ViteJS + React.

Start by installing dependencies

```bash
pnpm install
```

Launch developer mode to visualize changes with hot reload

```bash
pnpm run dev
```

Launch tests with

```bash
pnpm run test
```

### Customize mock data

In development mode, the app loads report data from the file `src/constants/report.constants.ts`

## Publish

Build the react app

```bash
pnpm run build
```

In production mode, the data is set in the global variable `__REPORT__` each time the `analyze cli` is called.
76 changes: 76 additions & 0 deletions cli/html-report/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
17 changes: 17 additions & 0 deletions cli/html-report/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
13 changes: 13 additions & 0 deletions cli/html-report/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default {
preset: "ts-jest",
testEnvironment: "jest-environment-jsdom",
transform: {
"^.+\\.tsx?$": "ts-jest",
// process `*.tsx` files with `ts-jest`
},
moduleNameMapper: {
"\\.(gif|ttf|eot|svg|png)$": "<rootDir>/test/__ mocks __/fileMock.js",
"@/(.*)": "<rootDir>/src/$1",
},
setupFiles: ["./setup-test.ts"],
}
55 changes: 55 additions & 0 deletions cli/html-report/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "html-report",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"test": "jest"
},
"dependencies": {
"@azimutt/models": "workspace:^",
"@azimutt/utils": "workspace:^",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"jest-environment-jsdom": "^29.7.0",
"lucide-react": "^0.395.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@testing-library/dom": "^10.1.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.12",
"@types/node": "^20.14.5",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"jest": "^29.7.0",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.4",
"ts-jest": "^29.1.5",
"typescript": "^5.2.2",
"vite": "^5.2.0",
"vite-plugin-singlefile": "^2.0.1"
}
}
6 changes: 6 additions & 0 deletions cli/html-report/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
16 changes: 16 additions & 0 deletions cli/html-report/report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Azimutt Report</title>
<script id="data"></script>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

</html>
22 changes: 22 additions & 0 deletions cli/html-report/setup-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
jest.mock("./src/constants/env.constants.ts", () => ({
ENVIRONMENT: "development",
PROD: false,
}))

class MockPointerEvent extends Event {
button: number
ctrlKey: boolean
pointerType: string

constructor(type: string, props: PointerEventInit) {
super(type, props)
this.button = props.button || 0
this.ctrlKey = props.ctrlKey || false
this.pointerType = props.pointerType || "mouse"
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
window.PointerEvent = MockPointerEvent as any
window.HTMLElement.prototype.scrollIntoView = jest.fn()
window.HTMLElement.prototype.releasePointerCapture = jest.fn()
50 changes: 50 additions & 0 deletions cli/html-report/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { REPORT } from "./constants/report.constants"
import { MainLayout } from "./components/layout/MainLayout/MainLayout"
import { ReportContext } from "./context/ReportContext"
import { RuleLevel } from "@azimutt/models"
import { useState } from "react"
import { ReportStats } from "./components/report/ReportStats/ReportStats"
import { ReportFilters } from "./components/report/ReportFilters/ReportFilters"
import { ViolationsList } from "./components/report/ViolationsList/ViolationsList"

function App() {
const [selectedLevels, setSelectedLevels] = useState<RuleLevel[]>([])
const [selectedCategories, setSelectedCategories] = useState<string[]>([])
const [selectedRules, setSelectedRules] = useState<string[]>([])
const [selectedTables, setSelectedTables] = useState<string[]>([])

const handleChange =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(setter: React.Dispatch<React.SetStateAction<any[]>>) => (value: any[]) => {
setter(value)
}

return (
<ReportContext.Provider
value={{
report: REPORT,
filters: {
levels: selectedLevels,
categories: selectedCategories,
rules: selectedRules,
tables: selectedTables,
},
}}
>
<MainLayout>
<div className="grid gap-5 grid-cols-1">
<ReportStats />
<ReportFilters
onSeveritiesChange={handleChange(setSelectedLevels)}
onCategoriesChange={handleChange(setSelectedCategories)}
onRulesChange={handleChange(setSelectedRules)}
onTablesChange={handleChange(setSelectedTables)}
/>
<ViolationsList />
</div>
</MainLayout>
</ReportContext.Provider>
)
}

export default App
14 changes: 14 additions & 0 deletions cli/html-report/src/components/azimutt/Logo/Logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface LogoProps {
className?: string
}

export const Logo = ({ className }: LogoProps) => {
return (
<img
className={className}
src={`https://azimutt.app/images/logo_dark.svg`}
style={{ height: 32 }}
alt="Azimutt logo"
/>
)
}
13 changes: 13 additions & 0 deletions cli/html-report/src/components/layout/AppBar/AppBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Logo } from "@/components/azimutt/Logo/Logo"

export interface AppBarProps {}

export const AppBar = () => {
return (
<div className="p-4 flex justify-between border-b border-solid">
<a href="https://azimutt.app" target="_blank" rel="noreferrer">
<Logo />
</a>
</div>
)
}
Loading

0 comments on commit 54d3eaa

Please sign in to comment.