parent
117fd8a78d
commit
ee063c9f43
4 changed files with 176 additions and 0 deletions
@ -0,0 +1,77 @@ |
||||
import { useContext } from 'react'; |
||||
|
||||
import { Box } from '@material-ui/core'; |
||||
import { makeStyles } from '@material-ui/core/styles'; |
||||
import { BodyText, HeaderText } from '../Text'; |
||||
import { Panel, InnerPanel, PanelHeader } from '../Panels'; |
||||
import SharedStorageHost from './FileSystemsHost'; |
||||
import PeriodicFetch from '../../lib/fetchers/periodicFetch'; |
||||
import { AnvilContext } from '../AnvilContext'; |
||||
import Spinner from '../Spinner'; |
||||
|
||||
const useStyles = makeStyles((theme) => ({ |
||||
header: { |
||||
paddingTop: '.1em', |
||||
paddingRight: '.7em', |
||||
}, |
||||
root: { |
||||
overflow: 'auto', |
||||
height: '78vh', |
||||
paddingLeft: '.3em', |
||||
[theme.breakpoints.down('md')]: { |
||||
height: '100%', |
||||
}, |
||||
}, |
||||
})); |
||||
|
||||
const SharedStorage = ({ anvil }: { anvil: AnvilListItem[] }): JSX.Element => { |
||||
const classes = useStyles(); |
||||
const { uuid } = useContext(AnvilContext); |
||||
const { data, isLoading } = PeriodicFetch<AnvilSharedStorage>( |
||||
`${process.env.NEXT_PUBLIC_API_URL}/get_shared_storage?anvil_uuid=${uuid}`, |
||||
); |
||||
return ( |
||||
<Panel> |
||||
<HeaderText text="Shared Storage" /> |
||||
{!isLoading ? ( |
||||
<Box className={classes.root}> |
||||
{data?.file_systems && |
||||
data.file_systems.map( |
||||
(fs: AnvilSharedStorageFileSystem): JSX.Element => ( |
||||
<InnerPanel key={fs.mount_point}> |
||||
<PanelHeader> |
||||
<Box display="flex" width="100%" className={classes.header}> |
||||
<Box> |
||||
<BodyText text={fs.mount_point} /> |
||||
</Box> |
||||
</Box> |
||||
</PanelHeader> |
||||
{fs?.hosts && |
||||
fs.hosts.map( |
||||
( |
||||
host: AnvilSharedStorageHost, |
||||
index: number, |
||||
): JSX.Element => ( |
||||
<SharedStorageHost |
||||
host={{ |
||||
...host, |
||||
...anvil[ |
||||
anvil.findIndex((a) => a.anvil_uuid === uuid) |
||||
].hosts[index], |
||||
}} |
||||
key={fs.hosts[index].free} |
||||
/> |
||||
), |
||||
)} |
||||
</InnerPanel> |
||||
), |
||||
)} |
||||
</Box> |
||||
) : ( |
||||
<Spinner /> |
||||
)} |
||||
</Panel> |
||||
); |
||||
}; |
||||
|
||||
export default SharedStorage; |
@ -0,0 +1,80 @@ |
||||
import { Box } from '@material-ui/core'; |
||||
import { makeStyles } from '@material-ui/core/styles'; |
||||
import * as prettyBytes from 'pretty-bytes'; |
||||
import { AllocationBar } from '../Bars'; |
||||
import { BodyText } from '../Text'; |
||||
import Decorator from '../Decorator'; |
||||
|
||||
const useStyles = makeStyles(() => ({ |
||||
fs: { |
||||
paddingLeft: '.7em', |
||||
paddingRight: '.7em', |
||||
paddingTop: '1.2em', |
||||
}, |
||||
bar: { |
||||
paddingLeft: '.7em', |
||||
paddingRight: '.7em', |
||||
}, |
||||
decoratorBox: { |
||||
paddingRight: '.3em', |
||||
}, |
||||
})); |
||||
|
||||
const SharedStorageHost = ({ |
||||
host, |
||||
}: { |
||||
host: AnvilSharedStorageHost; |
||||
}): JSX.Element => { |
||||
const classes = useStyles(); |
||||
return ( |
||||
<> |
||||
<Box display="flex" width="100%" className={classes.fs}> |
||||
<Box flexGrow={1}> |
||||
<BodyText text={host.host_name || 'Not Available'} /> |
||||
</Box> |
||||
<Box className={classes.decoratorBox}> |
||||
<Decorator colour={host.is_mounted ? 'ok' : 'error'} /> |
||||
</Box> |
||||
<Box> |
||||
<BodyText text={host.is_mounted ? 'Mounted' : 'Not Mounted'} /> |
||||
</Box> |
||||
</Box> |
||||
{host.is_mounted && ( |
||||
<> |
||||
<Box display="flex" width="100%" className={classes.fs}> |
||||
<Box flexGrow={1}> |
||||
<BodyText |
||||
text={`Used: ${prettyBytes.default(host.total - host.free, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Box> |
||||
<Box> |
||||
<BodyText |
||||
text={`Free: ${prettyBytes.default(host.free, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Box> |
||||
</Box> |
||||
<Box display="flex" width="100%" className={classes.bar}> |
||||
<Box flexGrow={1}> |
||||
<AllocationBar |
||||
allocated={((host.total - host.free) / host.total) * 100} |
||||
/> |
||||
</Box> |
||||
</Box> |
||||
<Box display="flex" justifyContent="center" width="100%"> |
||||
<BodyText |
||||
text={`Total Storage: ${prettyBytes.default(host.total, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Box> |
||||
</> |
||||
)} |
||||
</> |
||||
); |
||||
}; |
||||
|
||||
export default SharedStorageHost; |
@ -0,0 +1,3 @@ |
||||
import SharedStorage from './FileSystems'; |
||||
|
||||
export default SharedStorage; |
@ -0,0 +1,16 @@ |
||||
declare type AnvilSharedStorageHost = { |
||||
host_uuid: string; |
||||
host_name: string; |
||||
is_mounted: boolean; |
||||
total: number; |
||||
free: number; |
||||
}; |
||||
|
||||
declare type AnvilSharedStorageFileSystem = { |
||||
mount_point: string; |
||||
hosts: Array<AnvilSharedStorageHost>; |
||||
}; |
||||
|
||||
declare type AnvilSharedStorage = { |
||||
file_systems: Array<AnvilSharedStorageFileSystem>; |
||||
}; |
Loading…
Reference in new issue