diff --git a/src/components/home/Home.tsx b/src/components/home/Home.tsx index 5160044..e9e1417 100644 --- a/src/components/home/Home.tsx +++ b/src/components/home/Home.tsx @@ -3,6 +3,7 @@ import { useState, useEffect } from "react"; import { List, ListItemButton, Box, Typography } from "@mui/material"; import axios from "../../api/axios"; import useAuth from "../../hooks/useAuth"; +import Tag from "../../interfaces/Tag"; import Repository from "../../interfaces/Repositoriy"; const Home: React.FC = () => { @@ -10,6 +11,77 @@ const Home: React.FC = () => { const [repositories, setRepositories] = useState([]); + const getTagInfo = async(newRepositories: Repository[]) => { + let promises: Promise[] = []; + newRepositories.forEach((repository: Repository) => { + repository.tags.forEach((tag: Tag) => { + let promise = axios.get( + "/" + repository.name + "/manifests/" + tag.label, + { + headers:{ + Accept: "application/vnd.docker.distribution.manifest.v2+json", + }, + auth: { + username: auth.username, + password: auth.password + } + } + ).then((response) => { + tag.digest = response?.headers['docker-content-digest']; + return axios.get( + "/" + repository.name + "/blobs/" + response?.data?.config['digest'], + { + headers:{ + Accept: "application/vnd.docker.distribution.manifest.v2+json", + }, + auth: { + username: auth.username, + password: auth.password + } + } + ).then((res) => { + tag.architecture = res?.data?.architecture; + tag.os = res?.data?.os; + tag.created = new Date(res?.data?.created); + }); + }); + promises.push(promise); + }); + }); + return Promise.all(promises); + }; + + const getTags = async(newRepositories: Repository[]) => { + let promises: Promise[] = []; + newRepositories.forEach((repository: Repository) => { + let promise = axios.get( + "/" + repository.name + "/tags/list", + { + auth: { + username: auth.username, + password: auth.password + } + } + ).then((res) => { + let tags: Tag[] = []; + res?.data?.tags.forEach((tagLabel: string) => { + let tag: Tag = { + label: tagLabel, + architecture: "", + os: "", + created: undefined, + digest: "" + } + tags.push(tag); + }); + repository.tags = tags; + }); + promises.push(promise); + }); + await Promise.all(promises); + return getTagInfo(newRepositories); + }; + const listRepositories = async() => { const response = await axios.get( @@ -30,6 +102,7 @@ const Home: React.FC = () => { } newRepositories.push(newRepository); }); + await getTags(newRepositories) setRepositories(newRepositories); }; @@ -40,15 +113,14 @@ const Home: React.FC = () => { return( - {repositories.map((repositoriy: Repository) => { + {repositories.map((repository: Repository) => { return( - {repositoriy.name} - - + {repository.name} + {repository.tags.map((tag: Tag) => (tag.created ? tag.created.toDateString() : "Time created not available")).join(" ")} ); diff --git a/src/interfaces/Repositoriy.tsx b/src/interfaces/Repositoriy.tsx index ff1678a..9f4c124 100644 --- a/src/interfaces/Repositoriy.tsx +++ b/src/interfaces/Repositoriy.tsx @@ -1,7 +1,4 @@ -interface Tag { - label: string; - architecture: string; -} +import Tag from "./Tag"; interface Repository { name: string; diff --git a/src/interfaces/Tag.tsx b/src/interfaces/Tag.tsx new file mode 100644 index 0000000..cfe6c29 --- /dev/null +++ b/src/interfaces/Tag.tsx @@ -0,0 +1,9 @@ +interface Tag { + label: string; + architecture: string; + os: string; + created: Date | undefined; + digest: string; +} + +export default Tag; \ No newline at end of file diff --git a/src/interfaces/Utils.tsx b/src/interfaces/Utils.tsx new file mode 100644 index 0000000..6d8591a --- /dev/null +++ b/src/interfaces/Utils.tsx @@ -0,0 +1,10 @@ + +const digestDisplay = (digest: string): string => { + let digestInfo = digest.split(':'); + if (digestInfo.length >= 2) { + return digestInfo[1].slice(0,12); + } + return digest; +}; + +export { digestDisplay }; \ No newline at end of file