diff --git a/striker-ui/components/CPU.tsx b/striker-ui/components/CPU.tsx index 2dcea74d..a913d60c 100644 --- a/striker-ui/components/CPU.tsx +++ b/striker-ui/components/CPU.tsx @@ -5,6 +5,7 @@ import { AllocationBar } from './Bars'; import { HeaderText, BodyText } from './Text'; import PeriodicFetch from '../lib/fetchers/periodicFetch'; import { AnvilContext } from './AnvilContext'; +import Spinner from './Spinner'; const CPU = (): JSX.Element => { const { uuid } = useContext(AnvilContext); @@ -19,26 +20,33 @@ const CPU = (): JSX.Element => { return ( - - - - - - - - - - - - - - - - + {!isLoading ? ( + <> + {' '} + + + + + + + + + + + + + + + + + + ) : ( + + )} ); }; diff --git a/striker-ui/components/Hosts/index.tsx b/striker-ui/components/Hosts/index.tsx index dc9d525b..16afa04b 100644 --- a/striker-ui/components/Hosts/index.tsx +++ b/striker-ui/components/Hosts/index.tsx @@ -4,25 +4,32 @@ import { HeaderText } from '../Text'; import AnvilHost from './AnvilHost'; import PeriodicFetch from '../../lib/fetchers/periodicFetch'; import { AnvilContext } from '../AnvilContext'; +import Spinner from '../Spinner'; const Hosts = ({ anvil }: { anvil: AnvilListItem[] }): JSX.Element => { const { uuid } = useContext(AnvilContext); - const { data } = PeriodicFetch( + const { data, isLoading } = PeriodicFetch( `${process.env.NEXT_PUBLIC_API_URL}/get_status?anvil_uuid=${uuid}`, ); return ( - {anvil.findIndex((a) => a.anvil_uuid === uuid) !== -1 && data && ( - a.anvil_uuid === uuid)].hosts.map( - (host, index) => { - return data.hosts[index]; - }, + {!isLoading ? ( + <> + {anvil.findIndex((a) => a.anvil_uuid === uuid) !== -1 && data && ( + a.anvil_uuid === uuid) + ].hosts.map((host, index) => { + return data.hosts[index]; + })} + /> )} - /> + + ) : ( + )} ); diff --git a/striker-ui/components/Memory.tsx b/striker-ui/components/Memory.tsx index 44aab3e8..adf4aeb5 100644 --- a/striker-ui/components/Memory.tsx +++ b/striker-ui/components/Memory.tsx @@ -6,6 +6,7 @@ import { AllocationBar } from './Bars'; import { HeaderText, BodyText } from './Text'; import PeriodicFetch from '../lib/fetchers/periodicFetch'; import { AnvilContext } from './AnvilContext'; +import Spinner from './Spinner'; const Memory = (): JSX.Element => { const { uuid } = useContext(AnvilContext); @@ -19,41 +20,48 @@ const Memory = (): JSX.Element => { return ( - - - - - - + {' '} + + + + + + + + + + + + + + + - - - - - - - - - - + })} | Reserved: ${prettyBytes.default(memoryData.reserved, { + binary: true, + })}`} + /> + + + ) : ( + + )} ); }; diff --git a/striker-ui/components/Network/Network.tsx b/striker-ui/components/Network/Network.tsx index 6f9515c4..04b2eece 100644 --- a/striker-ui/components/Network/Network.tsx +++ b/striker-ui/components/Network/Network.tsx @@ -8,6 +8,7 @@ import { DIVIDER } from '../../lib/consts/DEFAULT_THEME'; import processNetworkData from './processNetwork'; import { AnvilContext } from '../AnvilContext'; import Decorator, { Colours } from '../Decorator'; +import Spinner from '../Spinner'; const useStyles = makeStyles((theme) => ({ container: { @@ -48,7 +49,7 @@ const Network = (): JSX.Element => { const { uuid } = useContext(AnvilContext); const classes = useStyles(); - const { data } = PeriodicFetch( + const { data, isLoading } = PeriodicFetch( `${process.env.NEXT_PUBLIC_API_URL}/get_networks?anvil_uuid=${uuid}`, ); @@ -56,40 +57,44 @@ const Network = (): JSX.Element => { return ( - - {data && - processed.bonds.map((bond: ProcessedBond) => { - return ( - <> - - - - - - - - - {bond.hosts.map( - (host): JSX.Element => ( - - - - + {!isLoading ? ( + + {data && + processed.bonds.map((bond: ProcessedBond) => { + return ( + <> + + + + + + + + + {bond.hosts.map( + (host): JSX.Element => ( + + + + + - - ), - )} - - - - ); - })} - + ), + )} + + + + ); + })} + + ) : ( + + )} ); }; diff --git a/striker-ui/components/Servers.tsx b/striker-ui/components/Servers.tsx index 08dfc6d4..0da3097e 100644 --- a/striker-ui/components/Servers.tsx +++ b/striker-ui/components/Servers.tsx @@ -8,6 +8,7 @@ import { HOVER, DIVIDER } from '../lib/consts/DEFAULT_THEME'; import { AnvilContext } from './AnvilContext'; import serverState from '../lib/consts/SERVERS'; import Decorator, { Colours } from './Decorator'; +import Spinner from './Spinner'; const useStyles = makeStyles((theme) => ({ root: { @@ -49,64 +50,69 @@ const Servers = ({ anvil }: { anvil: AnvilListItem[] }): JSX.Element => { const { uuid } = useContext(AnvilContext); const classes = useStyles(); - const { data } = PeriodicFetch( + const { data, isLoading } = PeriodicFetch( `${process.env.NEXT_PUBLIC_API_URL}/get_servers?anvil_uuid=${uuid}`, ); + return (
- - - {data && - data.servers.map((server: AnvilServer) => { - return ( - <> - - - - - - - - + {!isLoading ? ( + + + {data && + data.servers.map((server: AnvilServer) => { + return ( + <> + + + + + + + + + + {server.server_state !== 'shut_off' && + server.server_state !== 'crashed' && + anvil[ + anvil.findIndex((a) => a.anvil_uuid === uuid) + ].hosts.map( + (host: AnvilStatusHost): JSX.Element => ( + + + + ), + )} - {server.server_state !== 'shut_off' && - server.server_state !== 'crashed' && - anvil[ - anvil.findIndex((a) => a.anvil_uuid === uuid) - ].hosts.map( - (host: AnvilStatusHost): JSX.Element => ( - - - - ), - )} - - - - - ); - })} - - + + + + ); + })} + + + ) : ( + + )}
); }; diff --git a/striker-ui/components/SharedStorage/SharedStorage.tsx b/striker-ui/components/SharedStorage/SharedStorage.tsx index 5212fe10..bdbb7158 100644 --- a/striker-ui/components/SharedStorage/SharedStorage.tsx +++ b/striker-ui/components/SharedStorage/SharedStorage.tsx @@ -7,6 +7,7 @@ import { Panel, InnerPanel, PanelHeader } from '../Panels'; import SharedStorageHost from './SharedStorageHost'; import PeriodicFetch from '../../lib/fetchers/periodicFetch'; import { AnvilContext } from '../AnvilContext'; +import Spinner from '../Spinner'; const useStyles = makeStyles((theme) => ({ header: { @@ -26,45 +27,49 @@ const useStyles = makeStyles((theme) => ({ const SharedStorage = ({ anvil }: { anvil: AnvilListItem[] }): JSX.Element => { const classes = useStyles(); const { uuid } = useContext(AnvilContext); - const { data } = PeriodicFetch( + const { data, isLoading } = PeriodicFetch( `${process.env.NEXT_PUBLIC_API_URL}/get_shared_storage?anvil_uuid=${uuid}`, ); return ( - - {data?.file_systems && - data.file_systems.map( - (fs: AnvilSharedStorageFileSystem): JSX.Element => ( - - - - - + {!isLoading ? ( + + {data?.file_systems && + data.file_systems.map( + (fs: AnvilSharedStorageFileSystem): JSX.Element => ( + + + + + + - - - {fs?.hosts && - fs.hosts.map( - ( - host: AnvilSharedStorageHost, - index: number, - ): JSX.Element => ( - a.anvil_uuid === uuid) - ].hosts[index], - }} - key={fs.hosts[index].free} - /> - ), - )} - - ), - )} - + + {fs?.hosts && + fs.hosts.map( + ( + host: AnvilSharedStorageHost, + index: number, + ): JSX.Element => ( + a.anvil_uuid === uuid) + ].hosts[index], + }} + key={fs.hosts[index].free} + /> + ), + )} + + ), + )} + + ) : ( + + )} ); }; diff --git a/striker-ui/components/Spinner.tsx b/striker-ui/components/Spinner.tsx new file mode 100644 index 00000000..19cf8f96 --- /dev/null +++ b/striker-ui/components/Spinner.tsx @@ -0,0 +1,31 @@ +import { makeStyles } from '@material-ui/core/styles'; +import CircularProgress from '@material-ui/core/CircularProgress'; + +const useStyles = makeStyles(() => ({ + root: { + display: 'flex', + /* '& > * + *': { + marginLeft: theme.spacing(2), + }, */ + alignItems: 'center', + justifyContent: 'center', + marginTop: '3em', + }, + spinner: { + color: '#FFF', + variant: 'indeterminate', + size: '50em', + }, +})); + +const Spinner = (): JSX.Element => { + const classes = useStyles(); + + return ( +
+ +
+ ); +}; + +export default Spinner;