Skip to content

Commit

Permalink
convert loading with callbacks to react-router-loaders (...suite, fix…
Browse files Browse the repository at this point in the history
… authenticated api calls...)
  • Loading branch information
benjaminpochat committed Aug 16, 2024
1 parent c4c9245 commit 03c43f2
Show file tree
Hide file tree
Showing 14 changed files with 2,099 additions and 2,398 deletions.
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Faire fonctionner le la modification d'un abattage bovin
4,264 changes: 1,974 additions & 2,290 deletions frontend/app/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions frontend/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"react-hook-form": "^7.46.1",
"react-hook-form-mui": "^6.8.0",
"react-router-dom": "^6.23.0",
"react-scripts": "5.0.1",
"react-scripts": "^5.0.1",
"typescript": "^5.2.2",
"web-vitals": "^2.1.4"
},
Expand Down Expand Up @@ -64,7 +64,7 @@
},
"devDependencies": {
"@mui/x-data-grid": "^6.18.1",
"@openapitools/openapi-generator-cli": "^2.13.4",
"@openapitools/openapi-generator-cli": "^2.7.0",
"@types/jest": "^29.5.8",
"@types/node": "^20.9.2",
"@types/react": "^18.2.37",
Expand Down
15 changes: 6 additions & 9 deletions frontend/app/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
import Keycloak from 'keycloak-js'
import { ReactKeycloakProvider } from '@react-keycloak/web'

import { CookiesProvider } from 'react-cookie';
import { RouterProvider } from "react-router-dom";
import { CookiesProvider } from 'react-cookie'

import './App.css'
import { ThemeFactory } from './layouts/ThemeFactory.ts'

import { RouterFactory } from './layouts/RouterFactory.tsx';

import './App.css';
import { ThemeFactory } from './layouts/ThemeFactory.ts';
import ViandeEnDirectRouterProvider from './layouts/ViandeEnDirectRouterProvider.tsx'


function App() {

const keycloakClient = new Keycloak(window.location.origin + '/config/keycloak.json')
const routerFactory = new RouterFactory()
const themeFactory = new ThemeFactory()

const keycloakClient = new Keycloak(window.location.origin + '/config/keycloak.json')
const keycloakInitOptions = {
checkLoginIframe: false,
onLoad: 'check-sso',
Expand All @@ -32,7 +29,7 @@ function App() {
<ReactKeycloakProvider authClient={keycloakClient} initOptions={keycloakInitOptions}>
<ThemeProvider theme={themeFactory.createTheme()}>
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="fr">
<RouterProvider router={routerFactory.getRouter(keycloakClient)} />
<ViandeEnDirectRouterProvider></ViandeEnDirectRouterProvider>
</LocalizationProvider>
</ThemeProvider>
</ReactKeycloakProvider>
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/src/api/ApiBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DefaultApi } from '@viandeendirect/api/dist/apis/DefaultApi'
import { MockApi } from './mock/MockApi.ts'
import { UrlService } from '../domains/commons/service/UrlService.ts'
import { Configuration } from '@viandeendirect/api/dist/runtime'
import { DefaultApi } from '@viandeendirect/api/dist/apis/DefaultApi'

export class ApiBuilder {

Expand All @@ -17,7 +17,7 @@ export class ApiBuilder {
return new MockApi()
} else {
const configuration = new Configuration({
accessToken: keycloak.token,
accessToken: () => `Bearer ${keycloak.token}`,
basePath: await this.urlService.getBackendUrl()
});
return new DefaultApi(configuration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function DashboardAccount() {
const [producer, setProducer] = useState<Producer>()

useEffect(() => {
producerService.loadProducer(setProducer)
producerService.asyncLoadProducer().then(loadedProducer => setProducer(loadedProducer))
}, [keycloak])


Expand Down
1 change: 0 additions & 1 deletion frontend/app/src/domains/dashboard/views/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import { Typography } from "@mui/material"
import './Dashboard.css'
import DashboardAccount from '../components/DashboardAccount.tsx'
import AuthenticatedLayout from '../../../layouts/producer/AuthenticatedLayout.tsx'
import DashboardProductions from '../components/DashboardProductions.tsx'
import DashboardSales from '../components/DashboardSales.tsx'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,14 @@ export default function BeefProductionCard({
const [beefProduction, setBeefProduction] = useState(production)
const { keycloak, initialized } = useKeycloak()
const apiBuilder = new ApiBuilder()

useEffect(() => {
apiBuilder.getAuthenticatedApi(keycloak).then(api => {
apiBuilder.invokeAuthenticatedApi(() => {
api.getBeefProduction(production.id, (error, data, response) => {
if (error) {
console.error(error);
} else {
console.log('api.getBeefProduction called successfully. Returned data: ' + data);
setBeefProduction(data)
}
})
}, keycloak)
})
const loadBeefProduction = async () => {
const api = await apiBuilder.getAuthenticatedApi(keycloak)
const loadBeefProduction = await api.getBeefProduction({beefProductionId: production.id})
setBeefProduction(loadBeefProduction)
}
loadBeefProduction()
}, [keycloak])

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import BeefProduction from "@viandeendirect/api/dist/models/BeefProduction.js"
import PackageLotsCreator from '../PackageLotsCreator.tsx'
import { ApiInvoker } from '../../../../api/ApiInvoker.ts'
import { useKeycloak } from '@react-keycloak/web'
import { useNavigate, useParams } from 'react-router-dom'
import { useLoaderData, useNavigate, useParams } from 'react-router-dom'
import { ApiBuilder } from '../../../../api/ApiBuilder.ts'

export default function BeefProductionView() {

Expand All @@ -22,21 +23,13 @@ export default function BeefProductionView() {
const apiInvoker = new ApiInvoker()
const { keycloak } = useKeycloak()
const navigate = useNavigate();
const loadedProduction = useLoaderData()


const [currentTab, setCurrentTab] = useState<number>(BREEDING_PROPERTIES_TAB)
const [readOnly, setReadOnly] = useState<boolean>(true)
const [production, setProduction] = useState<BeefProduction>({})

let { beefProductionId } = useParams()
const [production, setProduction] = useState<BeefProduction>(loadedProduction)

useEffect(() => {
apiInvoker.callApiAuthenticatedly(
keycloak,
api => api.getBeefProduction,
beefProductionId,
setProduction,
console.error)
}, [keycloak])

const [saveEnabled, setSaveEnabled] = useState<boolean>(true)
const [alerts, setAlerts] = useState<string>(undefined)
Expand Down Expand Up @@ -185,4 +178,12 @@ export default function BeefProductionView() {
return <Alert severity="error">{alerts}</Alert>
}
}
}

export async function loadBeefProductionViewData(beefProductionId: number, keycloakClient): Promise<BeefProduction> {
const apiBuilder = new ApiBuilder()
const api = await apiBuilder.getAuthenticatedApi(keycloakClient)
const beefProduction = await api.getBeefProduction({beefProductionId: beefProductionId})
return beefProduction

}
6 changes: 3 additions & 3 deletions frontend/app/src/layouts/RouterFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ export class RouterFactory {
producerRouterFactory: ProducerRouterFactory = new ProducerRouterFactory()
customerRouterFactory: CustomerRouterFactory = new CustomerRouterFactory()

getRouter(keycloakClient) {
getRouter(keycloak) {
if(process.env.REACT_APP_MODE === 'CUSTOMER') {
return this.customerRouterFactory.getRouter(keycloakClient)
return this.customerRouterFactory.getRouter(keycloak)
}
if(process.env.REACT_APP_MODE === 'PRODUCER') {
return this.producerRouterFactory.getRouter(keycloakClient)
return this.producerRouterFactory.getRouter(keycloak)
}
return createBrowserRouter([
{
Expand Down
12 changes: 12 additions & 0 deletions frontend/app/src/layouts/ViandeEnDirectRouterProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import { useKeycloak } from "@react-keycloak/web";
import { RouterProvider } from "react-router-dom";

import {RouterFactory} from './RouterFactory.tsx'

export default function ViandeEnDirectRouterProvider() {
const {keycloak, initialized} = useKeycloak()
const routerFactory = new RouterFactory()

return <RouterProvider router={routerFactory.getRouter(keycloak)} ></RouterProvider>
}
13 changes: 8 additions & 5 deletions frontend/app/src/layouts/producer/AnonymousLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { styled } from '@mui/material/styles';
import { AppBar, Box, Typography, CssBaseline, Toolbar, Grid, Paper, Button } from "@mui/material";
import { useKeycloak } from '@react-keycloak/web'
import React from 'react';
import { Navigate } from 'react-router-dom';

function AnonymousLayout() {
export default function AnonymousLayout() {

const { keycloak, initialized } = useKeycloak()

Expand All @@ -23,8 +24,8 @@ function AnonymousLayout() {
keycloak.register()
}

return (
<Box>
function getAnonymousLayout() {
return <Box>
<CssBaseline />
<AppBar
position="fixed"
Expand Down Expand Up @@ -61,7 +62,9 @@ function AnonymousLayout() {

</Box>
</Box>
}

return (
<>{keycloak.authenticated ? <Navigate to='/'></Navigate> : getAnonymousLayout()}</>
)
}

export default AnonymousLayout
115 changes: 62 additions & 53 deletions frontend/app/src/layouts/producer/AuthenticatedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,25 @@ import {AppBar, Box, CssBaseline, IconButton, Toolbar, Typography} from '@mui/ma
import {Close, Logout, Menu} from '@mui/icons-material'


import Producer from '@viandeendirect/api/dist/models/Producer.js';
import { Producer } from '@viandeendirect/api/dist/models/Producer.js';
import SideMenu from './SideMenu.jsx'
import { AuthenticationService } from '../../authentication/service/AuthenticationService.ts';
import { ProducerService } from '../../domains/commons/service/ProducerService.ts';
import { Outlet, useNavigate } from 'react-router-dom';
import { Navigate, Outlet, useNavigate } from 'react-router-dom';


export default function AuthenticatedLayout(props) {
export default function AuthenticatedLayout() {
const { keycloak } = useKeycloak()
const navigate = useNavigate()
const [sideMenuOpen, setSideMenuOpen] = useState(false)
const [producer, setProducer] = useState<Producer>()
const [unauthorized, setUnauthorized] = useState<Boolean>(false)
const authenticationService = new AuthenticationService(keycloak)
const producerService = new ProducerService(keycloak)

useEffect(() => {
/*
producerService.loadProducer(setProducer, setUnauthorized)
*/
}, [keycloak])


Expand All @@ -40,57 +41,65 @@ export default function AuthenticatedLayout(props) {
return <Menu/>
}
}


if (!authenticationService.isAuthenticated()) {
navigate('/authentication')
function getAuthenticatedLayout() {
if(unauthorized) {
return <Navigate to='/unauthorized'/>
}
return <Box sx={{ display: 'flex' }}>
<CssBaseline />
<AppBar
position="fixed"
sx={{
zIndex: (theme) => theme.zIndex.drawer + 1,
}}
>
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
onClick={handleSideMenuToggle}
sx={{
mr: 2,
display: { xs: 'block', sm: 'none' }
}}
>
{getIcon()}
</IconButton>
<Typography variant="h5" component="div" sx={{ flexGrow: 1 }}>
Viande en direct
</Typography>
<Typography>{authenticationService.getCurrentUserFirstName() } {authenticationService.getCurrentUserLastName()}</Typography>
<IconButton onClick={keycloak.logout} color="inherit">
<Logout/>
</IconButton>
</Toolbar>
</AppBar>
<SideMenu
open={sideMenuOpen}
onClose={handleSideMenuToggle}
width={sideMenuWidth}>
</SideMenu>
<Box
component="main"
sx={{ flexGrow: 1, p: 3 }}
width={'100%'}>
<Toolbar />
<Outlet/>
</Box>
</Box>
}
if (unauthorized) {
navigate('/unauthorized')

function getUnauthenticatedLayout() {
return <Navigate to='/authentication'></Navigate>
}
return (
<Box sx={{ display: 'flex' }}>
<CssBaseline />
<AppBar
position="fixed"
sx={{
zIndex: (theme) => theme.zIndex.drawer + 1,
}}
>
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
onClick={handleSideMenuToggle}
sx={{
mr: 2,
display: { xs: 'block', sm: 'none' }
}}
>
{getIcon()}
</IconButton>
<Typography variant="h5" component="div" sx={{ flexGrow: 1 }}>
Viande en direct
</Typography>
<Typography>{authenticationService.getCurrentUserFirstName() } {authenticationService.getCurrentUserLastName()}</Typography>
<IconButton onClick={keycloak.logout} color="inherit">
<Logout/>
</IconButton>
</Toolbar>
</AppBar>
<SideMenu
open={sideMenuOpen}
onClose={handleSideMenuToggle}
width={sideMenuWidth}>
</SideMenu>
<Box
component="main"
sx={{ flexGrow: 1, p: 3 }}
width={'100%'}>
<Toolbar />
<Outlet/>
</Box>
</Box>

return (<>
{authenticationService.isAuthenticated() ? getAuthenticatedLayout() : getUnauthenticatedLayout()}
</>
)

}
Loading

0 comments on commit 03c43f2

Please sign in to comment.