diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a5252940..693d0545 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,15 +12,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + + - name: Install dependencies + run: npm install - - name: Format - run: npm run prettier + - name: Check formatting rules + run: npx prettier . --check - - name: lint + - name: Check code-quality rules run: npm run lint - - name: typescript - run: npm run typescript + - name: Check typescript type validity + run: npm run ts-lint - - name: build + - name: Build the web client run: npm run build --if-present diff --git a/.husky/pre-commit b/.husky/pre-commit index 36af2198..c37466e2 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -npx lint-staged +npx lint-staged \ No newline at end of file diff --git a/.prettier.json b/.prettier.json deleted file mode 100644 index 831df287..00000000 --- a/.prettier.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "trailingComma": "es5", - "bracketSpacing": true, - "printWidth": 80, - "tabWidth": 2, - "singleQuote": true, - "arrowParens": "always" -} diff --git a/.prettierignore b/.prettierignore index ab57381f..ef59e210 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,5 @@ node_modules build dist +.github +public diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/next.config.js b/next.config.js index 767719fc..658404ac 100644 --- a/next.config.js +++ b/next.config.js @@ -1,4 +1,4 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {} +const nextConfig = {}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/package.json b/package.json index c3ecf34b..387e7181 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "build": "next build", "start": "next start", "lint": "next lint", + "ts-lint": "tsc -noEmit -incremental", "postinstall": "node ./node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public", "prepare": "husky install" }, @@ -39,6 +40,7 @@ }, "lint-staged": { "*.{js,ts,jsx,tsx}": "eslint --cache --fix", - "*.{js,ts,jsx,tsx,css,md}": "prettier --write" + "*.{js,ts,jsx,tsx,css,md}": "prettier --write", + "*.{ts, tsx}": "tsc-files --noEmit" } } diff --git a/postcss.config.js b/postcss.config.js index 90d9fffc..a47ef4f9 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -2,4 +2,4 @@ module.exports = { plugins: { autoprefixer: {}, }, -} +}; diff --git a/src/app/dashboard/jobmonitor/[id]/page.tsx b/src/app/dashboard/jobmonitor/[id]/page.tsx index e7193c50..01b7137e 100644 --- a/src/app/dashboard/jobmonitor/[id]/page.tsx +++ b/src/app/dashboard/jobmonitor/[id]/page.tsx @@ -1,7 +1,3 @@ -export default function Page({ - params -}: { - params: {id: string} -}) { - return

Hello, Job Monitoring {params.id} Page!

- } \ No newline at end of file +export default function Page({ params }: { params: { id: string } }) { + return

Hello, Job Monitoring {params.id} Page!

; +} diff --git a/src/app/dashboard/jobmonitor/error.tsx b/src/app/dashboard/jobmonitor/error.tsx index 9b59d8e8..68cea11a 100644 --- a/src/app/dashboard/jobmonitor/error.tsx +++ b/src/app/dashboard/jobmonitor/error.tsx @@ -1,24 +1,22 @@ -'use client' - -import { useEffect } from 'react' - +"use client"; + +import { useEffect } from "react"; + export default function Error({ error, reset, }: { - error: Error - reset: () => void + error: Error; + reset: () => void; }) { useEffect(() => { - console.error(error) - }, [error]) - + console.error(error); + }, [error]); + return (

Something went wrong!

- +
- ) -} \ No newline at end of file + ); +} diff --git a/src/app/dashboard/jobmonitor/layout.tsx b/src/app/dashboard/jobmonitor/layout.tsx index b2876931..1f26a53c 100644 --- a/src/app/dashboard/jobmonitor/layout.tsx +++ b/src/app/dashboard/jobmonitor/layout.tsx @@ -1,7 +1,7 @@ export default function JobMonitorLayout({ children, }: { - children: React.ReactNode + children: React.ReactNode; }) { - return
{children}
-} \ No newline at end of file + return
{children}
; +} diff --git a/src/app/dashboard/jobmonitor/page.tsx b/src/app/dashboard/jobmonitor/page.tsx index d98be5be..4f9a4c3e 100644 --- a/src/app/dashboard/jobmonitor/page.tsx +++ b/src/app/dashboard/jobmonitor/page.tsx @@ -1,4 +1,4 @@ -import { JobDataGrid } from "@/app/components/JobDataGrid"; +import { JobDataGrid } from "@/components/JobDataGrid"; export default async function Page() { return ( diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index e21f8237..9a8e9f58 100644 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -1,20 +1,17 @@ -import React from 'react'; -import DashboardAppBar from '../components/DashboardAppBar'; -import { OIDCSecure } from '../components/OIDCUtils'; - +import React from "react"; +import DashboardAppBar from "@/components/DashboardAppBar"; +import { OIDCSecure } from "@/components/OIDCUtils"; export default function DashboardLayout({ children, }: { - children: React.ReactNode + children: React.ReactNode; }) { return ( -
- - - {children} - - -
+
+ + {children} + +
); -} \ No newline at end of file +} diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 631767e4..f171f6c0 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,9 +1,7 @@ export default function Page() { - return ( -
- - Hello User - -
- ); + return ( +
+ Hello User +
+ ); } diff --git a/src/app/error.tsx b/src/app/error.tsx index ba399e69..830a08fb 100644 --- a/src/app/error.tsx +++ b/src/app/error.tsx @@ -1,18 +1,16 @@ -'use client' - +"use client"; + export default function Error({ error, reset, }: { - error: Error - reset: () => void + error: Error; + reset: () => void; }) { return (

Something went wrong!

- +
- ) -} \ No newline at end of file + ); +} diff --git a/src/app/global-error.tsx b/src/app/global-error.tsx index 08bbecea..7e65847a 100644 --- a/src/app/global-error.tsx +++ b/src/app/global-error.tsx @@ -1,11 +1,11 @@ -'use client' - +"use client"; + export default function GlobalError({ error, reset, }: { - error: Error - reset: () => void + error: Error; + reset: () => void; }) { return ( @@ -14,5 +14,5 @@ export default function GlobalError({ - ) -} \ No newline at end of file + ); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 356f23df..4674d2f8 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ import "./globals.css"; import { Inter } from "next/font/google"; -import { OIDCProvider } from "./components/OIDCUtils"; +import { OIDCProvider } from "@/components/OIDCUtils"; +import { OidcConfiguration } from "@axa-fr/react-oidc"; const inter = Inter({ subsets: ["latin"] }); @@ -9,11 +10,11 @@ export const metadata = { description: "Distributed Infrastructure with Remote Agent Controller", }; -const configuration = { - client_id: process.env.DIRACX_CLIENT_ID, - redirect_uri: process.env.REDIRECT_URI, - scope: process.env.DEFAULT_SCOPE, - authority: process.env.NEXT_PUBLIC_DIRACX_URL, +const configuration: OidcConfiguration = { + client_id: process.env.DIRACX_CLIENT_ID || "", + redirect_uri: process.env.REDIRECT_URI || "", + scope: process.env.DEFAULT_SCOPE || "", + authority: process.env.NEXT_PUBLIC_DIRACX_URL || "", }; export default function RootLayout({ diff --git a/src/app/page.tsx b/src/app/page.tsx index 4adeb2b4..53503ec3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,4 @@ -import ShowcaseAppBar from "./components/ShowcaseAppBar"; +import ShowcaseAppBar from "@/components/ShowcaseAppBar"; const containerStyles = { marginLeft: "30%", diff --git a/src/components/DashboardAppBar.tsx b/src/components/DashboardAppBar.tsx index 40c294a9..debb40c6 100644 --- a/src/components/DashboardAppBar.tsx +++ b/src/components/DashboardAppBar.tsx @@ -21,8 +21,15 @@ import { DiracLogo } from "./DiracLogo"; import { Dashboard, FolderCopy } from "@mui/icons-material"; import { LoginButton } from "./LoginButton"; +interface DashboardAppBarProps { + children: React.ReactNode; +} + // Sections accessible to the users -const userSections = { +const userSections: Record< + string, + { icon: React.ComponentType; path: string } +> = { Dashboard: { icon: Dashboard, path: "/dashboard" }, "Job Monitor": { icon: MonitorIcon, path: "/dashboard/jobmonitor" }, "File Catalog": { icon: FolderCopy, path: "/dashboard/filecatalog" }, @@ -35,9 +42,7 @@ const userSections = { * @param props - children * @return an dashboard layout */ -export default function DashboardAppBar(props: Props) { - const { window } = props; - +export default function DashboardAppBar(props: DashboardAppBarProps) { /** State management for mobile drawer */ const [mobileOpen, setMobileOpen] = React.useState(false); const handleDrawerToggle = () => { @@ -45,11 +50,8 @@ export default function DashboardAppBar(props: Props) { }; /** State management for selected section in the drawer */ - const [selectedIndex, setSelectedIndex] = React.useState(true); - const handleListItemClick = ( - event: React.MouseEvent, - index: number, - ) => { + const [selectedIndex, setSelectedIndex] = React.useState(0); + const handleListItemClick = (index: number) => { setSelectedIndex(index); }; @@ -63,13 +65,13 @@ export default function DashboardAppBar(props: Props) { - {Object.keys(userSections).map((title, index) => ( + {Object.keys(userSections).map((title: string, index: number) => ( handleListItemClick(event, index)} + onClick={() => handleListItemClick(index)} > @@ -97,7 +99,7 @@ export default function DashboardAppBar(props: Props) { ); const container = - window !== undefined ? () => window().document.body : undefined; + window !== undefined ? () => window.document.body : undefined; /** Return an App bar embedding the drawer */ return ( diff --git a/src/components/DashboardButton.tsx b/src/components/DashboardButton.tsx index 951ab49a..972d83a1 100644 --- a/src/components/DashboardButton.tsx +++ b/src/components/DashboardButton.tsx @@ -8,7 +8,7 @@ import Link from "next/link"; * @returns a Button */ export function DashboardButton() { - const { accessToken, accessTokenPayload } = useOidcAccessToken(); + const { accessToken } = useOidcAccessToken(); if (!accessToken) { return null; diff --git a/src/components/JobDataGrid.tsx b/src/components/JobDataGrid.tsx index b84c4a49..21a993e9 100644 --- a/src/components/JobDataGrid.tsx +++ b/src/components/JobDataGrid.tsx @@ -19,7 +19,7 @@ export function JobDataGrid() { const { accessToken } = useOidcAccessToken(); // TODO: move fetcher to make it usable from other places - const fetcher = (params) => { + const fetcher = (params: string[]) => { const [path] = params; return fetch(process.env.NEXT_PUBLIC_DIRACX_URL + path, { method: "POST", diff --git a/src/components/OIDCUtils.tsx b/src/components/OIDCUtils.tsx index dddac219..062a4b3e 100644 --- a/src/components/OIDCUtils.tsx +++ b/src/components/OIDCUtils.tsx @@ -1,5 +1,19 @@ "use client"; -import { OidcProvider, OidcSecure } from "@axa-fr/react-oidc"; +import { + OidcConfiguration, + OidcProvider, + OidcSecure, +} from "@axa-fr/react-oidc"; +import React from "react"; + +interface OIDCProviderProps { + configuration: OidcConfiguration; + children: React.ReactNode; +} + +interface OIDCProps { + children: React.ReactNode; +} /** * Wrapper around the react-oidc OidcProvider component @@ -7,7 +21,7 @@ import { OidcProvider, OidcSecure } from "@axa-fr/react-oidc"; * @param props - configuration of the OIDC provider * @returns the wrapper around OidcProvider */ -export function OIDCProvider(props: Props) { +export function OIDCProvider(props: OIDCProviderProps) { const withCustomHistory = () => { return { replaceState: (url: string) => { @@ -35,7 +49,7 @@ export function OIDCProvider(props: Props) { * @param props - configuration of the OIDC provider * @returns the wrapper around OidcProvider */ -export function OIDCSecure({ children }) { +export function OIDCSecure({ children }: OIDCProps) { return ( <> {children} diff --git a/src/components/ShowcaseAppBar.tsx b/src/components/ShowcaseAppBar.tsx index f7e075c7..d6d7a7c9 100644 --- a/src/components/ShowcaseAppBar.tsx +++ b/src/components/ShowcaseAppBar.tsx @@ -13,30 +13,12 @@ import { Stack } from "@mui/material"; import { DashboardButton } from "./DashboardButton"; import Image from "next/image"; -/** - * Controls the response due to a scrolling - * @param props - children - * @returns an elevation of the children component - */ -function ElevationScroll(props: Props) { - const { children } = props; - - const trigger = useScrollTrigger({ - disableHysteresis: true, - threshold: 0, - }); - - return React.cloneElement(children, { - elevation: trigger ? 4 : 0, - }); -} - /** * Build the showcase content with an AppBar * @param props - children * @returns showcase content */ -export default function ShowcaseAppBar(props: Props) { +export default function ShowcaseAppBar() { const Item = styled(Paper)(({ theme }) => ({ padding: theme.spacing(6), elevation: 0, @@ -45,27 +27,25 @@ export default function ShowcaseAppBar(props: Props) { return ( - - - - - - - -
- - - - - - - - + + + + + + +
+ + + + + + +