Skip to content

Commit

Permalink
Display system stats and project size
Browse files Browse the repository at this point in the history
  • Loading branch information
randombenj committed Oct 17, 2024
1 parent e2b6876 commit ac18b83
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 13 deletions.
16 changes: 9 additions & 7 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { createHashRouter, RouterProvider } from 'react-router-dom'
import React from 'react'
import { ConfigDataProvider } from './data-providers/ConfigDataProvider'
import { MessageBannerProvider } from './data-providers/MessageBannerProvider'
import { ProjectDataProvider } from './data-providers/ProjectDataProvider'
import { SearchProvider } from './data-providers/SearchProvider'
import { StatsDataProvider } from './data-providers/StatsDataProvider'
import Claim from './pages/Claim'
import Delete from './pages/Delete'
import Docs from './pages/Docs'
import EscapeSlashForDocsPath from './pages/EscapeSlashForDocsPath'
import Help from './pages/Help'
import Home from './pages/Home'
import NotFound from './pages/NotFound'
import Upload from './pages/Upload'
import EscapeSlashForDocsPath from './pages/EscapeSlashForDocsPath'
import { MessageBannerProvider } from './data-providers/MessageBannerProvider'
import { SearchProvider } from './data-providers/SearchProvider'

function App(): JSX.Element {
const router = createHashRouter([
Expand Down Expand Up @@ -79,9 +79,11 @@ function App(): JSX.Element {
<MessageBannerProvider>
<ConfigDataProvider>
<ProjectDataProvider>
<SearchProvider>
<RouterProvider router={router} />
</SearchProvider>
<StatsDataProvider>
<SearchProvider>
<RouterProvider router={router} />
</SearchProvider>
</StatsDataProvider>
</ProjectDataProvider>
</ConfigDataProvider>
</MessageBannerProvider>
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type Project as ProjectType } from '../models/ProjectsResponse'
import ProjectRepository from '../repositories/ProjectRepository'
import styles from './../style/components/Project.module.css'

import { Box, Tooltip } from '@mui/material'
import { Box, Tooltip, Typography } from '@mui/material'
import FavoriteStar from './FavoriteStar'

interface Props {
Expand Down Expand Up @@ -81,6 +81,7 @@ export default function Project(props: Props): JSX.Element {
{props.project.versions.length === 1
? `${props.project.versions.length} version`
: `${props.project.versions.length} versions`}
<Typography sx={{ marginLeft: 1.5 }} fontSize={'0.9em'} component={'span'} fontWeight={300}>{props.project.storage}</Typography>
</div>

<FavoriteStar
Expand Down
86 changes: 86 additions & 0 deletions web/src/data-providers/StatsDataProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */
/*
We need any, because we don't know the type of the children,
and we need the return those children again which is an "unsafe return"
*/

import { createContext, useContext, useEffect, useState } from 'react'
import { useMessageBanner } from './MessageBannerProvider'


type Stats = {
n_projects: number
n_versions: number
storage: string
}

interface StatsState {
stats: Stats | null
loadingFailed: boolean
reload: () => void
}

const Context = createContext<StatsState>({
stats: null,
loadingFailed: false,
reload: (): void => {
console.warn('StatsProvider not initialized')
}
})

/**
* Provides the stats of the docat instance
* If reloading is required, call the reload function.
*/
export function StatsDataProvider({ children }: any): JSX.Element {
const { showMessage } = useMessageBanner()

const loadData = (): void => {
void (async (): Promise<void> => {
try {
const response = await fetch('/api/stats')

if (!response.ok) {
throw new Error(
`Failed to load stats, status code: ${response.status}`
)
}

const data: Stats = await response.json()
setState({
stats: data,
loadingFailed: false,
reload: loadData
})
} catch (e) {
console.error(e)

showMessage({
content: 'Failed to load stats',
type: 'error',
showMs: 6000
})

setState({
stats: null,
loadingFailed: true,
reload: loadData
})
}
})()
}

const [state, setState] = useState<StatsState>({
stats: null,
loadingFailed: false,
reload: loadData
})

useEffect(() => {
loadData()
}, [])

return <Context.Provider value={state}>{children}</Context.Provider>
}

export const useStats = (): StatsState => useContext(Context)
1 change: 1 addition & 0 deletions web/src/models/ProjectsResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type ProjectDetails from './ProjectDetails'
export interface Project {
name: string
logo: boolean
storage: string
versions: ProjectDetails[]
}

Expand Down
34 changes: 30 additions & 4 deletions web/src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import LoadingPage from './LoadingPage';

import { Box, Button, IconButton, Tooltip, Typography } from '@mui/material';
import SearchBar from '../components/SearchBar';
import { useStats } from '../data-providers/StatsDataProvider';
import styles from './../style/pages/Home.module.css';


export default function Home(): JSX.Element {
const { loadingFailed } = useProjects()
const { stats, loadingFailed: statsLoadingFailed } = useStats()
const { filteredProjects: projects, query, setQuery } = useSearch()
const [showAll, setShowAll] = useState(false);
const [favoriteProjects, setFavoriteProjects] = useState<Project[]>([])
Expand Down Expand Up @@ -54,7 +56,7 @@ export default function Home(): JSX.Element {
updateFavorites()
}, [projects])

if (loadingFailed) {
if (loadingFailed || statsLoadingFailed) {
return (
<div className={styles.home}>
<Header />
Expand All @@ -67,7 +69,7 @@ export default function Home(): JSX.Element {
)
}

if (projects == null) {
if (projects == null || stats == null) {
return <LoadingPage />
}

Expand All @@ -76,6 +78,9 @@ export default function Home(): JSX.Element {
<Header />

<div className={styles['project-overview']}>
<Box sx={{ width: '80%', maxWidth: '800px'}}>


<Box sx={{
display: 'flex',
marginTop: '24px',
Expand Down Expand Up @@ -148,7 +153,7 @@ export default function Home(): JSX.Element {
/>
:
<>
<Typography sx={{ marginLeft: '24px', marginBottom: 1.5 }} fontWeight={200} fontSize={20}>FAVOURITES</Typography>
<Typography sx={{ marginLeft: '24px', marginBottom: 1.5 }} fontWeight={300} fontSize={20}>FAVOURITES</Typography>
{ (favoriteProjects.length === 0) ?
<Box sx={{marginLeft: '24px'}}>
No docs favourited at the moment, search for docs or
Expand All @@ -168,7 +173,28 @@ export default function Home(): JSX.Element {
}
</>
}

</Box>
<Box sx={{
display: {
sm: 'block',
xs: 'none'
}, borderLeft: '1px solid #efefef', paddingLeft: 2, marginTop: 15, width: '400px'}}>
<Typography sx={{display: 'inline-block'}} fontWeight={300} fontSize={'1.1em'} component={'span'}>INSTANCE STATS</Typography>
<Box />

<Typography fontSize={'1em'} fontWeight={200} sx={{ opacity: 0.8 }} component={'span'}># </Typography>
<Typography sx={{width: 100, display: 'inline-block', marginTop: 1}} fontWeight={300} fontSize={'1em'} component={'span'}>DOCS </Typography>
<Typography fontSize={'1em'} fontWeight={200} sx={{ opacity: 0.8 }} component={'span'}>{stats.n_projects}</Typography>

<Box />
<Typography fontSize={'1em'} fontWeight={200} sx={{ opacity: 0.8 }} component={'span'}># </Typography>
<Typography sx={{width: 100, display: 'inline-block', marginTop: 0.4}} fontWeight={300} fontSize={'1em'} component={'span'}>VERSIONS </Typography>
<Typography fontSize={'1em'} fontWeight={200} sx={{ opacity: 0.8 }} component={'span'}>{stats.n_versions}</Typography>

<Box />
<Typography sx={{width: 115, display: 'inline-block', marginTop: 0.4}} fontWeight={300} fontSize={'1em'} component={'span'}>STORAGE </Typography>
<Typography fontSize={'1em'} fontWeight={200} sx={{ opacity: 0.8 }} component={'span'}>{stats.storage}</Typography>
</Box>
</div>
<Footer />
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/src/style/pages/Home.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

.project-overview {
display: flex;
flex-direction: column;
flex-direction: row;
}

.card {
Expand Down

0 comments on commit ac18b83

Please sign in to comment.