Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 95 additions & 88 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import Project from 'pages/Project'
import Policy from 'pages/Policy'
import Maintenance from 'pages/Maintenance'
import PrivateRoute from 'components/AuthzRoute'
import ErrorProvider from 'providers/ErrorProvider'
import { HttpErrorBadRequest } from './utils/error'
import { NotistackProvider, SnackbarUtilsConfigurator } from './utils/snack'

Expand All @@ -76,94 +77,100 @@ function App() {
<Provider store={store}>
<DndProvider backend={HTML5Backend}>
<IoProvider>
<SessionProvider>
<ShellDrawerProvider>
<CollapseDrawerProvider>
<SettingsProvider defaultSettings={settings}>
<ThemeProvider>
<ThemeColorPresets>
<NotistackProvider>
<SnackbarUtilsConfigurator />
<CssBaseline />
{/* <ProgressBar /> */}
<Helmet titleTemplate='%s | Otomi' defaultTitle='Otomi' />
<Router basename={contextPath}>
<Switch>
{/* ! user && <Route path='/' component={Home} exact /> */}
<Route path='/' component={Dashboard} exact />
<PrivateRoute path='/apps/:teamId' component={Apps} exact />
<PrivateRoute path='/apps/:teamId/:appId' component={OtomiApp} exact />
<PrivateRoute path='/backups' component={Backups} adminRoute exact />
<PrivateRoute path='/clusters/:clusterId' component={Cluster} adminRoute exact />
<PrivateRoute path='/clusters' component={Clusters} adminRoute exact />
<PrivateRoute path='/create-team' component={Team} adminRoute exact />
<PrivateRoute path='/netpols' component={Netpols} adminRoute exact />
<PrivateRoute path='/policies' component={Policies} adminRoute exact />
<PrivateRoute path='/policies/:policyId' component={Policy} adminRoute exact />
<PrivateRoute path='/catalogs/:teamId' component={Catalogs} exact />
<PrivateRoute path='/catalogs/:teamId/:catalogName' component={Catalog} exact />
<PrivateRoute
path='/catalogs/:teamId/:catalogName/:workloadId'
component={Catalog}
exact
/>
<PrivateRoute path='/services' component={Services} adminRoute exact />
<PrivateRoute path='/secrets' component={Secrets} adminRoute exact />
<PrivateRoute path='/sealed-secrets' component={SealedSecrets} adminRoute exact />
<PrivateRoute path='/workloads' component={Workloads} adminRoute exact />
<PrivateRoute path='/settings' component={SettingsOverview} adminRoute exact />
<PrivateRoute path='/projects' component={Projects} adminRoute exact />
<PrivateRoute path='/builds' component={Builds} adminRoute exact />
<PrivateRoute path='/settings/:settingId' component={Setting} exact />
<PrivateRoute path='/shortcuts/:teamId' component={Shortcuts} exact />
<PrivateRoute path='/teams' component={Teams} adminRoute exact />
<PrivateRoute path='/teams/:teamId' component={Team} exact />
<PrivateRoute path='/teams/:teamId/create-backup' component={Backup} exact />
<PrivateRoute path='/teams/:teamId/create-netpol' component={Netpol} exact />
<PrivateRoute path='/teams/:teamId/create-secret' component={Secret} exact />
<PrivateRoute
path='/teams/:teamId/create-sealedsecret'
component={SealedSecret}
exact
/>
<PrivateRoute path='/teams/:teamId/create-service' component={Service} exact />
<PrivateRoute path='/teams/:teamId/create-project' component={Project} exact />
<PrivateRoute path='/teams/:teamId/create-build' component={Build} exact />
<PrivateRoute path='/teams/:teamId/secrets' component={Secrets} exact />
<PrivateRoute path='/teams/:teamId/sealed-secrets' component={SealedSecrets} exact />
<PrivateRoute path='/teams/:teamId/secrets/:secretId' component={Secret} exact />
<PrivateRoute
path='/teams/:teamId/sealed-secrets/:secretId'
component={SealedSecret}
exact
/>
<PrivateRoute path='/teams/:teamId/backups' component={Backups} exact />
<PrivateRoute path='/teams/:teamId/backups/:backupId' component={Backup} exact />
<PrivateRoute path='/teams/:teamId/netpols' component={Netpols} exact />
<PrivateRoute path='/teams/:teamId/netpols/:netpolId' component={Netpol} exact />
<PrivateRoute path='/teams/:teamId/projects' component={Projects} exact />
<PrivateRoute path='/teams/:teamId/projects/:projectId' component={Project} exact />
{/* <Route path='/teams/:teamId/builds' component={Builds} exact /> */}
<PrivateRoute exact path='/teams/:teamId/builds' component={Builds} />
<PrivateRoute path='/teams/:teamId/builds/:buildId' component={Build} exact />
<PrivateRoute path='/teams/:teamId/policies' component={Policies} exact />
<PrivateRoute path='/teams/:teamId/policies/:policyId' component={Policy} exact />
<PrivateRoute path='/teams/:teamId/workloads' component={Workloads} exact />
<PrivateRoute path='/teams/:teamId/services' component={Services} exact />
<PrivateRoute path='/teams/:teamId/services/:serviceId' component={Service} exact />
<PrivateRoute path='/maintenance' component={Maintenance} adminRoute exact />
<Route path='*'>
<Error error={new HttpErrorBadRequest()} />
</Route>
</Switch>
</Router>
</NotistackProvider>
</ThemeColorPresets>
</ThemeProvider>
</SettingsProvider>
</CollapseDrawerProvider>
</ShellDrawerProvider>
</SessionProvider>
<ErrorProvider>
<SessionProvider>
<ShellDrawerProvider>
<CollapseDrawerProvider>
<SettingsProvider defaultSettings={settings}>
<ThemeProvider>
<ThemeColorPresets>
<NotistackProvider>
<SnackbarUtilsConfigurator />
<CssBaseline />
{/* <ProgressBar /> */}
<Helmet titleTemplate='%s | Otomi' defaultTitle='Otomi' />
<Router basename={contextPath}>
<Switch>
{/* ! user && <Route path='/' component={Home} exact /> */}
<Route path='/' component={Dashboard} exact />
<PrivateRoute path='/apps/:teamId' component={Apps} exact />
<PrivateRoute path='/apps/:teamId/:appId' component={OtomiApp} exact />
<PrivateRoute path='/backups' component={Backups} adminRoute exact />
<PrivateRoute path='/clusters/:clusterId' component={Cluster} adminRoute exact />
<PrivateRoute path='/clusters' component={Clusters} adminRoute exact />
<PrivateRoute path='/create-team' component={Team} adminRoute exact />
<PrivateRoute path='/netpols' component={Netpols} adminRoute exact />
<PrivateRoute path='/policies' component={Policies} adminRoute exact />
<PrivateRoute path='/policies/:policyId' component={Policy} adminRoute exact />
<PrivateRoute path='/catalogs/:teamId' component={Catalogs} exact />
<PrivateRoute path='/catalogs/:teamId/:catalogName' component={Catalog} exact />
<PrivateRoute
path='/catalogs/:teamId/:catalogName/:workloadId'
component={Catalog}
exact
/>
<PrivateRoute path='/services' component={Services} adminRoute exact />
<PrivateRoute path='/secrets' component={Secrets} adminRoute exact />
<PrivateRoute path='/sealed-secrets' component={SealedSecrets} adminRoute exact />
<PrivateRoute path='/workloads' component={Workloads} adminRoute exact />
<PrivateRoute path='/settings' component={SettingsOverview} adminRoute exact />
<PrivateRoute path='/projects' component={Projects} adminRoute exact />
<PrivateRoute path='/builds' component={Builds} adminRoute exact />
<PrivateRoute path='/settings/:settingId' component={Setting} exact />
<PrivateRoute path='/shortcuts/:teamId' component={Shortcuts} exact />
<PrivateRoute path='/teams' component={Teams} adminRoute exact />
<PrivateRoute path='/teams/:teamId' component={Team} exact />
<PrivateRoute path='/teams/:teamId/create-backup' component={Backup} exact />
<PrivateRoute path='/teams/:teamId/create-netpol' component={Netpol} exact />
<PrivateRoute path='/teams/:teamId/create-secret' component={Secret} exact />
<PrivateRoute
path='/teams/:teamId/create-sealedsecret'
component={SealedSecret}
exact
/>
<PrivateRoute path='/teams/:teamId/create-service' component={Service} exact />
<PrivateRoute path='/teams/:teamId/create-project' component={Project} exact />
<PrivateRoute path='/teams/:teamId/create-build' component={Build} exact />
<PrivateRoute path='/teams/:teamId/secrets' component={Secrets} exact />
<PrivateRoute
path='/teams/:teamId/sealed-secrets'
component={SealedSecrets}
exact
/>
<PrivateRoute path='/teams/:teamId/secrets/:secretId' component={Secret} exact />
<PrivateRoute
path='/teams/:teamId/sealed-secrets/:secretId'
component={SealedSecret}
exact
/>
<PrivateRoute path='/teams/:teamId/backups' component={Backups} exact />
<PrivateRoute path='/teams/:teamId/backups/:backupId' component={Backup} exact />
<PrivateRoute path='/teams/:teamId/netpols' component={Netpols} exact />
<PrivateRoute path='/teams/:teamId/netpols/:netpolId' component={Netpol} exact />
<PrivateRoute path='/teams/:teamId/projects' component={Projects} exact />
<PrivateRoute path='/teams/:teamId/projects/:projectId' component={Project} exact />
{/* <Route path='/teams/:teamId/builds' component={Builds} exact /> */}
<PrivateRoute exact path='/teams/:teamId/builds' component={Builds} />
<PrivateRoute path='/teams/:teamId/builds/:buildId' component={Build} exact />
<PrivateRoute path='/teams/:teamId/policies' component={Policies} exact />
<PrivateRoute path='/teams/:teamId/policies/:policyId' component={Policy} exact />
<PrivateRoute path='/teams/:teamId/workloads' component={Workloads} exact />
<PrivateRoute path='/teams/:teamId/services' component={Services} exact />
<PrivateRoute path='/teams/:teamId/services/:serviceId' component={Service} exact />
<PrivateRoute path='/maintenance' component={Maintenance} adminRoute exact />
<Route path='*'>
<Error error={new HttpErrorBadRequest()} />
</Route>
</Switch>
</Router>
</NotistackProvider>
</ThemeColorPresets>
</ThemeProvider>
</SettingsProvider>
</CollapseDrawerProvider>
</ShellDrawerProvider>
</SessionProvider>
</ErrorProvider>
</IoProvider>
</DndProvider>
</Provider>
Expand Down
4 changes: 4 additions & 0 deletions src/components/Error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { setError } from 'redux/reducers'
import { makeStyles } from 'tss-react/mui'
import snack from 'utils/snack'
import { ApiError } from '../utils/error'
import ErrorApi from './ErrorApi'

const useStyles = makeStyles()((theme) => ({
root: {
Expand All @@ -28,6 +29,7 @@ const useStyles = makeStyles()((theme) => ({
interface Props {
error?: ApiError
}
const apiCodes = [403, 504, 666]

export default function ({ error }: Props): React.ReactElement {
const { classes } = useStyles()
Expand All @@ -40,6 +42,8 @@ export default function ({ error }: Props): React.ReactElement {
const code = error ? err.code : err.status
const message = error ? err.message : err.data.error
const msgKey = message || code || 'Unknown'
if (apiCodes.includes(code)) return React.createElement(ErrorApi, error)

const clearError = () => {
dispatch(setError(undefined))
}
Expand Down
22 changes: 22 additions & 0 deletions src/components/ErrorApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Box, CssBaseline, Typography } from '@mui/material'
import React from 'react'
import Empty from 'layouts/Empty'
import Iconify from './Iconify'

export default function (props: any): React.ReactElement {
const comp = (
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '32px' }}>
<CssBaseline />
<Typography sx={{ textAlign: 'center', color: '#fff' }} variant='h3'>
ERROR {props.code}: {props.extendedMessage.title}
</Typography>
<Iconify icon='nonicons:not-found-16' sx={{ color: '#fff', fontSize: '100px' }} />
<Typography
sx={{ textAlign: 'center', display: 'flex', justifyContent: 'space-around', color: '#fff', width: '50%' }}
>
{props.extendedMessage.message}
</Typography>
</Box>
)
return <Empty children={comp} />
}
41 changes: 28 additions & 13 deletions src/layouts/Empty.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
import { Container } from '@mui/material'
import { Card, Container, styled } from '@mui/material'
import React from 'react'
import { makeStyles } from 'tss-react/mui'
import MainLayout from './Base'

const useStyles = makeStyles()(() => ({
container: {
padding: 0,
},
}))
const StyledPage = styled(Container)({
backgroundColor: '#161c24',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
minWidth: '100vw',
overflow: 'hidden',
})

const StyledCard = styled(Card)({
backgroundColor: '#181B1F',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: '4vh',
boxSizing: 'border-box', // Ensures padding is included in width/height calculations
minWidth: '300px', // Minimum width to ensure content visibility
width: '50%', // Use 100% of the parent container's width
minHeight: '370px', // Minimum height to ensure content visibility at different zoom levels
maxHeight: '90vh', // Use a high percentage of the viewport height to ensure visibility at different zoom levels
overflow: 'auto', // Enable scroll if the content overflows
})

interface Props {
children?: any
title?: string
}

export default function ({ children, title }: Props): React.ReactElement {
const { classes } = useStyles()
return (
<MainLayout title={title}>
<Container className={classes.container}>{children}</Container>
</MainLayout>
<StyledPage>
<StyledCard>{children}</StyledCard>
</StyledPage>
)
}
24 changes: 24 additions & 0 deletions src/layouts/EmptyBase.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Container } from '@mui/material'
import React from 'react'
import { makeStyles } from 'tss-react/mui'
import MainLayout from './Base'

const useStyles = makeStyles()(() => ({
container: {
padding: 0,
},
}))

interface Props {
children?: any
title?: string
}

export default function ({ children, title }: Props): React.ReactElement {
const { classes } = useStyles()
return (
<MainLayout title={title}>
<Container className={classes.container}>{children}</Container>
</MainLayout>
)
}
2 changes: 1 addition & 1 deletion src/pages/Apps.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
import Apps from 'components/Apps'
import useAuthzSession from 'hooks/useAuthzSession'
import MainLayout from 'layouts/Empty'
import MainLayout from 'layouts/EmptyBase'
import React, { useEffect, useState } from 'react'
import { RouteComponentProps } from 'react-router-dom'
import { useAppSelector } from 'redux/hooks'
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Catalogs.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Catalogs from 'components/Catalogs'
import LoadingScreen from 'components/LoadingScreen'
import MainLayout from 'layouts/Empty'
import MainLayout from 'layouts/EmptyBase'
import { useSession } from 'providers/Session'
import React, { useEffect, useState } from 'react'
import { RouteComponentProps } from 'react-router-dom'
Expand Down
Loading