Implemented loading screen state accross app.
Signed-off-by: Raul Kele <raulkeleblk@gmail.com>
This commit is contained in:
parent
2a3320fb64
commit
dce87afba9
28
src/App.css
28
src/App.css
@ -18,7 +18,10 @@
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
animation: bounce 1s;
|
||||
animation-direction: alternate;
|
||||
animation-timing-function: cubic-bezier(.5, 0.05, 1, .5);
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,3 +48,26 @@
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes bounce {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(0, 50px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(0, 50px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.bounce {
|
||||
-webkit-animation-name: bounce;
|
||||
animation-name: bounce;
|
||||
}
|
@ -9,6 +9,7 @@ import makeStyles from '@mui/styles/makeStyles';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { host } from '../host';
|
||||
import Monitor from '../assets/Monitor.png';
|
||||
import Loading from './Loading';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
card: {
|
||||
@ -69,9 +70,10 @@ function DependsOn(props) {
|
||||
const [images, setImages] = useState([]);
|
||||
const { name } = props;
|
||||
const classes = useStyles();
|
||||
// const [isLoaded, setIsLoaded] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
api
|
||||
.get(`${host()}${endpoints.dependsOnForImage(name)}`)
|
||||
.then((response) => {
|
||||
@ -79,29 +81,16 @@ function DependsOn(props) {
|
||||
let images = response.data.data.BaseImageList;
|
||||
setImages(images);
|
||||
}
|
||||
setIsLoading(false);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div data-testid="depends-on-container">
|
||||
<Typography
|
||||
variant="h4"
|
||||
gutterBottom
|
||||
component="div"
|
||||
align="left"
|
||||
className={classes.title}
|
||||
style={{ color: 'rgba(0, 0, 0, 0.87)', fontSize: '1.5rem', fontWeight: '600', paddingTop: '0.5rem' }}
|
||||
>
|
||||
Depends On
|
||||
</Typography>
|
||||
<Divider
|
||||
variant="fullWidth"
|
||||
sx={{ margin: '5% 0% 5% 0%', background: 'rgba(0, 0, 0, 0.38)', height: '0.00625rem', width: '100%' }}
|
||||
/>
|
||||
{images?.length ? (
|
||||
const renderDependencies = () => {
|
||||
return images?.length ? (
|
||||
<Card className={classes.card} raised>
|
||||
<CardContent>
|
||||
<Typography className={classes.content}>
|
||||
@ -120,7 +109,26 @@ function DependsOn(props) {
|
||||
<img src={Monitor} alt="Monitor" className={classes.monitor}></img>
|
||||
<Typography className={classes.none}> Nothing found </Typography>
|
||||
</div>
|
||||
)}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div data-testid="depends-on-container">
|
||||
<Typography
|
||||
variant="h4"
|
||||
gutterBottom
|
||||
component="div"
|
||||
align="left"
|
||||
className={classes.title}
|
||||
style={{ color: 'rgba(0, 0, 0, 0.87)', fontSize: '1.5rem', fontWeight: '600', paddingTop: '0.5rem' }}
|
||||
>
|
||||
Depends On
|
||||
</Typography>
|
||||
<Divider
|
||||
variant="fullWidth"
|
||||
sx={{ margin: '5% 0% 5% 0%', background: 'rgba(0, 0, 0, 0.38)', height: '0.00625rem', width: '100%' }}
|
||||
/>
|
||||
{isLoading ? <Loading /> : renderDependencies()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ function Explore() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
api
|
||||
.get(`${host()}${endpoints.globalSearch({ searchQuery: search, filter: buildFilterQuery() })}`)
|
||||
.then((response) => {
|
||||
@ -89,10 +90,6 @@ function Explore() {
|
||||
});
|
||||
}, [search, queryParams, imageFilters, osFilters, archFilters]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(false);
|
||||
}, []);
|
||||
|
||||
const renderRepoCards = () => {
|
||||
return (
|
||||
exploreData &&
|
||||
@ -148,7 +145,9 @@ function Explore() {
|
||||
|
||||
return (
|
||||
<Container maxWidth="lg">
|
||||
{isLoading && <Loading />}
|
||||
{isLoading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<Grid container className={classes.gridWrapper}>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={0}></Grid>
|
||||
@ -189,6 +188,7 @@ function Explore() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import makeStyles from '@mui/styles/makeStyles';
|
||||
import { host } from '../host';
|
||||
import Monitor from '../assets/Monitor.png';
|
||||
import { isEmpty } from 'lodash';
|
||||
import Loading from './Loading';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
card: {
|
||||
@ -141,6 +142,35 @@ function HistoryLayers(props) {
|
||||
}
|
||||
}, [name]);
|
||||
|
||||
const renderHistoryData = () => {
|
||||
return (
|
||||
historyData && (
|
||||
<Card className={classes.card} raised>
|
||||
<CardContent className={classes.content}>
|
||||
<Grid item xs={11}>
|
||||
<Stack sx={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<Typography variant="body1" align="left" className={classes.title}>
|
||||
Command
|
||||
</Typography>
|
||||
<Typography variant="body1" align="left" className={classes.values}>
|
||||
{transform.formatBytes(historyData[selectedIndex].Layer?.Size)}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Grid>
|
||||
<Typography variant="body1" align="left" className={classes.title} sx={{ backgroundColor: '#F7F7F7' }}>
|
||||
{historyData[selectedIndex].HistoryDescription?.CreatedBy}
|
||||
</Typography>
|
||||
{!historyData[selectedIndex].HistoryDescription?.EmptyLayer ? (
|
||||
<Typography data-testid="hash-typography">#: {historyData[selectedIndex].Layer?.Digest}</Typography>
|
||||
) : (
|
||||
<Typography data-testid="no-hash-typography"></Typography>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography
|
||||
@ -181,30 +211,7 @@ function HistoryLayers(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLoaded && historyData && (
|
||||
<Card className={classes.card} raised>
|
||||
<CardContent className={classes.content}>
|
||||
<Grid item xs={11}>
|
||||
<Stack sx={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<Typography variant="body1" align="left" className={classes.title}>
|
||||
Command
|
||||
</Typography>
|
||||
<Typography variant="body1" align="left" className={classes.values}>
|
||||
{transform.formatBytes(historyData[selectedIndex].Layer?.Size)}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Grid>
|
||||
<Typography variant="body1" align="left" className={classes.title} sx={{ backgroundColor: '#F7F7F7' }}>
|
||||
{historyData[selectedIndex].HistoryDescription?.CreatedBy}
|
||||
</Typography>
|
||||
{!historyData[selectedIndex].HistoryDescription?.EmptyLayer ? (
|
||||
<Typography data-testid="hash-typography">#: {historyData[selectedIndex].Layer?.Digest}</Typography>
|
||||
) : (
|
||||
<Typography data-testid="no-hash-typography"></Typography>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
{!isLoaded ? <Loading /> : renderHistoryData()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import PreviewCard from './PreviewCard';
|
||||
import RepoCard from './RepoCard';
|
||||
import { mapToRepo } from 'utilities/objectModels';
|
||||
import Loading from './Loading';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
gridWrapper: {
|
||||
@ -61,11 +62,13 @@ const useStyles = makeStyles(() => ({
|
||||
}));
|
||||
|
||||
function Home({ data, updateData }) {
|
||||
// const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [homeData, setHomeData] = useState([]);
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
setIsLoading(true);
|
||||
api
|
||||
.get(`${host()}${endpoints.repoList}`)
|
||||
.then((response) => {
|
||||
@ -75,7 +78,7 @@ function Home({ data, updateData }) {
|
||||
return mapToRepo(responseRepo);
|
||||
});
|
||||
updateData(repoData);
|
||||
// setIsLoading(false);
|
||||
setIsLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
@ -149,6 +152,10 @@ function Home({ data, updateData }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<Stack spacing={4} alignItems="center" className={classes.gridWrapper}>
|
||||
<Grid container item xs={12} sx={{ mt: 2, mb: 1 }} justifyContent="center">
|
||||
<Stack sx={{ display: 'inline' }} direction="row" justifyContent="center" spacing={1}>
|
||||
@ -174,6 +181,8 @@ function Home({ data, updateData }) {
|
||||
</Typography>
|
||||
{renderRecentlyUpdated()}
|
||||
</Stack>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import makeStyles from '@mui/styles/makeStyles';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { host } from '../host';
|
||||
import Monitor from '../assets/Monitor.png';
|
||||
import Loading from './Loading';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
card: {
|
||||
@ -69,9 +70,10 @@ function IsDependentOn(props) {
|
||||
const [images, setImages] = useState([]);
|
||||
const { name } = props;
|
||||
const classes = useStyles();
|
||||
//const [isLoaded, setIsLoaded] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
api
|
||||
.get(`${host()}${endpoints.isDependentOnForImage(name)}`)
|
||||
.then((response) => {
|
||||
@ -79,32 +81,16 @@ function IsDependentOn(props) {
|
||||
let images = response.data.data.DerivedImageList;
|
||||
setImages(images);
|
||||
}
|
||||
setIsLoading(false);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
//setImages([]);
|
||||
setIsLoading(false);
|
||||
});
|
||||
//setIsLoaded(true);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography
|
||||
variant="h4"
|
||||
gutterBottom
|
||||
component="div"
|
||||
align="left"
|
||||
className={classes.title}
|
||||
style={{ color: 'rgba(0, 0, 0, 0.87)', fontSize: '1.5rem', fontWeight: '600', paddingTop: '0.5rem' }}
|
||||
>
|
||||
Is Dependent On
|
||||
</Typography>
|
||||
<Divider
|
||||
variant="fullWidth"
|
||||
sx={{ margin: '5% 0% 5% 0%', background: 'rgba(0, 0, 0, 0.38)', height: '0.00625rem', width: '100%' }}
|
||||
/>
|
||||
|
||||
{images?.length ? (
|
||||
const renderDependents = () => {
|
||||
return images?.length ? (
|
||||
<Card className={classes.card} raised>
|
||||
<CardContent>
|
||||
<Typography className={classes.content}>
|
||||
@ -123,7 +109,26 @@ function IsDependentOn(props) {
|
||||
<img src={Monitor} alt="Monitor" className={classes.monitor}></img>
|
||||
<Typography className={classes.none}> Nothing found </Typography>
|
||||
</div>
|
||||
)}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography
|
||||
variant="h4"
|
||||
gutterBottom
|
||||
component="div"
|
||||
align="left"
|
||||
className={classes.title}
|
||||
style={{ color: 'rgba(0, 0, 0, 0.87)', fontSize: '1.5rem', fontWeight: '600', paddingTop: '0.5rem' }}
|
||||
>
|
||||
Is Dependent On
|
||||
</Typography>
|
||||
<Divider
|
||||
variant="fullWidth"
|
||||
sx={{ margin: '5% 0% 5% 0%', background: 'rgba(0, 0, 0, 0.38)', height: '0.00625rem', width: '100%' }}
|
||||
/>
|
||||
{isLoading ? <Loading /> : renderDependents()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import logo from '../assets/Zot2.svg';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
wrapper: {
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
position: 'relative',
|
||||
top: '10%',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
@ -13,9 +13,8 @@ const useStyles = makeStyles(() => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginTop: 6,
|
||||
paddingRight: 20,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.3)'
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -33,6 +33,7 @@ import repocube3 from '../assets/repocube-3.png';
|
||||
import repocube4 from '../assets/repocube-4.png';
|
||||
import { TabContext, TabList, TabPanel } from '@mui/lab';
|
||||
import RepoDetailsMetadata from './RepoDetailsMetadata';
|
||||
import Loading from './Loading';
|
||||
|
||||
// @ts-ignore
|
||||
const useStyles = makeStyles(() => ({
|
||||
@ -132,7 +133,7 @@ const randomImage = () => {
|
||||
function RepoDetails() {
|
||||
const [repoDetailData, setRepoDetailData] = useState({});
|
||||
// @ts-ignore
|
||||
//const [isLoading, setIsLoading] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [selectedTab, setSelectedTab] = useState('Overview');
|
||||
|
||||
// get url param from <Route here (i.e. image name)
|
||||
@ -150,8 +151,6 @@ function RepoDetails() {
|
||||
images: repoInfo.Images,
|
||||
lastUpdated: repoInfo.Summary?.LastUpdated,
|
||||
size: repoInfo.Summary?.Size,
|
||||
//latestDigest: repoInfo.Summary?.NewestImage.Digest,
|
||||
//layers: repoInfo.Summary?.NewestImage.Layers,
|
||||
platforms: repoInfo.Summary?.Platforms,
|
||||
vendors: repoInfo.Summary?.Vendors,
|
||||
newestTag: repoInfo.Summary?.NewestImage,
|
||||
@ -162,12 +161,13 @@ function RepoDetails() {
|
||||
overview: repoInfo.Summary?.NewestImage.Documentation
|
||||
};
|
||||
setRepoDetailData(imageData);
|
||||
//setIsLoading(false);
|
||||
}
|
||||
setIsLoading(false);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
setRepoDetailData({});
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, [name]);
|
||||
//function that returns a random element from an array
|
||||
@ -261,6 +261,10 @@ function RepoDetails() {
|
||||
// };
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<div className={classes.pageWrapper}>
|
||||
<Card className={classes.cardRoot}>
|
||||
<CardContent>
|
||||
@ -386,6 +390,8 @@ function RepoDetails() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import git from '../assets/Git.png';
|
||||
// styling
|
||||
import { makeStyles } from '@mui/styles';
|
||||
import { Card, CardContent } from '@mui/material';
|
||||
import Loading from './Loading';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
cardContainer: {
|
||||
@ -105,11 +106,14 @@ export default function SignIn({ isAuthEnabled, setIsAuthEnabled, isLoggedIn, se
|
||||
const [password, setPassword] = useState(null);
|
||||
const [requestProcessing, setRequestProcessing] = useState(false);
|
||||
const [requestError, setRequestError] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
if (isAuthEnabled && isLoggedIn) {
|
||||
setIsLoading(false);
|
||||
navigate('/home');
|
||||
} else {
|
||||
api
|
||||
@ -118,11 +122,13 @@ export default function SignIn({ isAuthEnabled, setIsAuthEnabled, isLoggedIn, se
|
||||
if (response.status === 200) {
|
||||
setIsAuthEnabled(false);
|
||||
setIsLoggedIn(true);
|
||||
setIsLoading(false);
|
||||
navigate('/home');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setIsAuthEnabled(true);
|
||||
setIsLoading(false);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
@ -190,6 +196,9 @@ export default function SignIn({ isAuthEnabled, setIsAuthEnabled, isLoggedIn, se
|
||||
|
||||
return (
|
||||
<Box className={classes.cardContainer} data-testid="signin-container">
|
||||
{isLoading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<Card className={classes.loginCard}>
|
||||
<CardContent className={classes.loginCardContent}>
|
||||
<CssBaseline />
|
||||
@ -316,6 +325,7 @@ export default function SignIn({ isAuthEnabled, setIsAuthEnabled, isLoggedIn, se
|
||||
<TermsOfService sx={{ mt: 2, mb: 4 }} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import PestControlIcon from '@mui/icons-material/PestControl';
|
||||
import Monitor from '../assets/Monitor.png';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Loading from './Loading';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
card: {
|
||||
@ -258,10 +259,11 @@ function VulnerabilitiyCard(props) {
|
||||
function VulnerabilitiesDetails(props) {
|
||||
const classes = useStyles();
|
||||
const [cveData, setCveData] = useState({});
|
||||
// const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const { name } = props;
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
api
|
||||
.get(`${host()}${endpoints.vulnerabilitiesForRepo(name)}`)
|
||||
.then((response) => {
|
||||
@ -271,7 +273,7 @@ function VulnerabilitiesDetails(props) {
|
||||
cveList: cveInfo?.CVEList
|
||||
};
|
||||
setCveData(cveListData);
|
||||
// setIsLoading(false);
|
||||
setIsLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
@ -323,9 +325,13 @@ function VulnerabilitiesDetails(props) {
|
||||
width: '100%'
|
||||
}}
|
||||
/>
|
||||
{renderCVEs(
|
||||
{isLoading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
renderCVEs(
|
||||
// @ts-ignore
|
||||
cveData?.cveList
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user