feat: resource task add Image Manifest Url
Signed-off-by: zhaoxinxin <1186037180@qq.com>
This commit is contained in:
parent
4f67755fa7
commit
f033feccee
|
@ -14,7 +14,8 @@ describe('Clear', () => {
|
|||
cy.viewport(1440, 1080);
|
||||
});
|
||||
|
||||
it('when no data is loaded', () => {
|
||||
describe('when no data is loaded', () => {
|
||||
it('when search by url has no data to load', () => {
|
||||
cy.get('#no-task').should('not.exist');
|
||||
|
||||
cy.get('#light').should('exist');
|
||||
|
@ -66,6 +67,32 @@ describe('Clear', () => {
|
|||
cy.get('#no-task').should('exist');
|
||||
});
|
||||
|
||||
it('when search by image manifest url has no data to load', () => {
|
||||
cy.get('#no-task').should('not.exist');
|
||||
|
||||
cy.get('#serach-image-manifest-url').click();
|
||||
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'post',
|
||||
url: '/api/v1/jobs',
|
||||
},
|
||||
async (req) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
req.reply({
|
||||
statusCode: 200,
|
||||
body: {},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
cy.get('#image-manifest-url').type('https://example.com/path/to/file{enter}');
|
||||
|
||||
// Shou You don't find any results!
|
||||
cy.get('#no-image-manifest-URL-task').should('exist').and('contain', `You don't find any results!`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when data is loaded', () => {
|
||||
it('click the `CANCEL button', () => {
|
||||
cy.get('#url').click();
|
||||
|
@ -309,13 +336,13 @@ describe('Clear', () => {
|
|||
// Show is loading.
|
||||
cy.get('#isLoading').should('exist');
|
||||
|
||||
// Display cache information.
|
||||
cy.get('#blobs').should('have.text', '5');
|
||||
cy.get('#scheduler-id-0').should('exist', 'ID : 1');
|
||||
|
||||
cy.get('#isLoading').should('not.exist');
|
||||
|
||||
cy.get('#scheduler-1-hostname-0').should('have.text', 'kind-worker1');
|
||||
cy.get('#scheduler-1-ip-0').should('have.text', '172.18.0.4');
|
||||
cy.get('#scheduler-1-total-0').should('have.text', 'Total 2');
|
||||
cy.get('#scheduler-1-proportion-0').should('contain', '60.00%');
|
||||
|
||||
// Should display URL.
|
||||
cy.get('#scheduler-1-url-0').click();
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
"hostname": "kind-worker1",
|
||||
"layers": [
|
||||
{
|
||||
"url": "https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:f1ffc4b5459e82dc8e7ddd1d1a2ec469e85a1f076090c22851a1f2ce6f71e1a6"
|
||||
"url": "https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:f1ffc4b5459e82dc8e7ddd1d1a2ec469e85a1f076090c22851a1f2ce6f71e1a6?format=json"
|
||||
},
|
||||
{
|
||||
"url": "https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:c1d6d1b2d5a367259e6e51a7f4d1ccd66a28cc9940d6599d8a8ea9544dd4b4a8"
|
||||
},
|
||||
{
|
||||
"url": "https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:c1d6d1b2d5a367259e6e51a7f4d1ccd66a28cc9940d6599d8a8ea9544dd4b4a7"
|
||||
}
|
||||
],
|
||||
"scheduler_cluster_id": 1
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<svg t="1751448383394" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="56778" width="200" height="200">
|
||||
<path
|
||||
d="M118.979048 637.074286l137.99619 66.243047 255.171048 123.587048 246.076952-119.222857 147.163429-70.485334a73.142857 73.142857 0 0 1-34.230857 97.109334l-327.119239 158.427428a73.142857 73.142857 0 0 1-63.780571 0L153.136762 734.305524A73.142857 73.142857 0 0 1 118.979048 637.074286z m786.090666-153.063619a73.142857 73.142857 0 0 1-33.913904 97.767619L544.01219 740.205714a73.142857 73.142857 0 0 1-63.780571 0L153.136762 581.778286A73.142857 73.142857 0 0 1 117.51619 487.862857l362.300953 170.886095 32.329143 15.652572 327.119238-158.427429 65.80419-31.939047zM544.036571 139.190857l327.094858 158.403048a73.142857 73.142857 0 0 1 0 131.657143l-327.094858 158.427428a73.142857 73.142857 0 0 1-63.780571 0L153.136762 429.251048a73.142857 73.142857 0 0 1 0-131.657143L480.256 139.215238a73.142857 73.142857 0 0 1 63.780571 0z m-31.890285 65.828572L185.027048 363.422476l327.119238 158.427429 327.119238-158.427429L512.146286 205.04381z"
|
||||
p-id="56779" fill="currentColor"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,12 @@
|
|||
<svg t="1751448525528" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="61090" width="200" height="200">
|
||||
<path
|
||||
d="M539.450983 15.110813h-0.503689v467.927137h468.934515C1007.579596 224.544724 798.044947 15.110813 539.450983 15.110813z"
|
||||
fill="currentColor" p-id="61091"></path>
|
||||
<path
|
||||
d="M486.563632 82.101458h-15.110672c-62.961132 0-125.2171 12.592226-183.141342 37.172252C114.337417 193.013789 1.309592 363.663642 1.208854 552.647778c-0.201476 260.105031 210.542027 471.150747 470.747795 471.352222h0.705165c259.903555-0.201476 470.445582-211.045716 470.244106-470.949271v-15.614361H486.563632v-455.33491z m425.919469 485.556254c-1.712543 54.196943-13.498867 107.487245-34.553069 157.4532-94.794281 224.141632-353.388244 328.908956-577.429139 234.114675C142.644742 892.33568 37.877417 740.221584 31.631673 569.068041c-8.76419-243.281816 181.328062-447.678837 424.710615-456.443026v455.032697h456.140813z"
|
||||
fill="currentColor" p-id="61092"></path>
|
||||
<path
|
||||
d="M1022.992481 482.836474C1022.791005 215.98201 806.305447-0.201335 539.450983 0.000141H523.836623v498.14848h499.155858v-15.110671-0.201476zM554.057966 467.927278V30.42296c238.647877 7.454598 430.452671 198.856441 438.511696 437.504318H554.057966z"
|
||||
fill="currentColor" p-id="61093"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -64,7 +64,7 @@
|
|||
|
||||
.schedulerClusterWrapper {
|
||||
border: 1px solid #d5d2d2;
|
||||
padding: 0.2rem 0.4rem;
|
||||
padding: 0.1rem 0.3rem;
|
||||
border-radius: 0.3rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
@ -115,6 +115,29 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.cacheHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
}
|
||||
|
||||
.bolbWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--palette-table-title-text-color);
|
||||
}
|
||||
|
||||
.bolbText {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
border-radius: 0.3rem;
|
||||
background-color: var(--palette-background-inactive);
|
||||
}
|
||||
|
||||
.hostnameContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -130,7 +153,6 @@
|
|||
display: inline-flex;
|
||||
padding: 0.3rem 0.5rem;
|
||||
align-items: center;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.hostnameIcon {
|
||||
|
@ -142,7 +164,7 @@
|
|||
border-color: var(--palette-palette-divider) !important;
|
||||
background-color: var(--palette-background-inactive) !important;
|
||||
border-radius: var(--menu-border-radius) !important;
|
||||
padding: 0.6rem 0.4rem;
|
||||
padding: 0.6rem 0.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
|
@ -155,31 +177,57 @@
|
|||
}
|
||||
|
||||
.urlIcon {
|
||||
height: 1.2rem !important;
|
||||
width: 8%;
|
||||
height: 1.4rem !important;
|
||||
color: var(--palette-detail-lable-color);
|
||||
}
|
||||
|
||||
.clusterWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.cluster {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.cardCantainer {
|
||||
gap: calc(1rem);
|
||||
gap: calc(1.2rem);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.totalContainer {
|
||||
.bolbProportionContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.3rem;
|
||||
background-color: var(--palette-grey-background-color) !important;
|
||||
background-color: var(--palette-button-color) !important;
|
||||
border-radius: var(--menu-border-radius) !important;
|
||||
margin-right: 0.4rem;
|
||||
color: var(--palette-scopes-icon-color);
|
||||
}
|
||||
|
||||
.totalIcon {
|
||||
.bolbIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
/* color: var(--palette-description-color); */
|
||||
}
|
||||
|
||||
.totalText {
|
||||
color: var(--palette-description-color);
|
||||
padding-left: 0.3rem;
|
||||
.bolbProportionText {
|
||||
padding-left: 0.4rem;
|
||||
}
|
||||
|
||||
.bolbIconWrapper {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 0.6rem !important;
|
||||
transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
z-index: 0;
|
||||
color: var(--palette-color) !important;
|
||||
background-image: none;
|
||||
padding: 0.4rem;
|
||||
background-color: var(--palette-background-paper) !important;
|
||||
box-shadow: var(--palette-card-box-shadow) !important;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,14 @@ import DeleteIcon from '@mui/icons-material/Delete';
|
|||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import MoreTimeIcon from '@mui/icons-material/MoreTime';
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import { getTaskJobResponse, createTaskJob, getTaskJob, createGetImageDistributionJob } from '../../../../lib/api';
|
||||
import { getDatetime, getPaginatedList } from '../../../../lib/utils';
|
||||
import {
|
||||
getTaskJobResponse,
|
||||
createTaskJob,
|
||||
getTaskJob,
|
||||
createGetImageDistributionJob,
|
||||
createGetImageDistributionJobResponse,
|
||||
} from '../../../../lib/api';
|
||||
import { extractSHA256Regex, getDatetime, getPaginatedList } from '../../../../lib/utils';
|
||||
import _ from 'lodash';
|
||||
import SearchTaskAnimation from '../../../search-task-animation';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
@ -55,6 +61,9 @@ import { ReactComponent as IP } from '../../../../assets/images/resource/task/cl
|
|||
import { ReactComponent as Hostnames } from '../../../../assets/images/resource/task/clear-hostname.svg';
|
||||
import { ReactComponent as URL } from '../../../../assets/images/job/preheat/url.svg';
|
||||
import { ReactComponent as Total } from '../../../../assets/images/cluster/total.svg';
|
||||
import { ReactComponent as Proportion } from '../../../../assets/images/resource/task/proportion.svg';
|
||||
|
||||
import { ReactComponent as Layer } from '../../../../assets/images/resource/task/layer.svg';
|
||||
|
||||
const StyledToggleButtonGroup = styled(ToggleButtonGroup)(({ theme }) => ({
|
||||
[`& .${toggleButtonGroupClasses.grouped}`]: {
|
||||
|
@ -71,14 +80,18 @@ const StyledToggleButtonGroup = styled(ToggleButtonGroup)(({ theme }) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
type Layer = {
|
||||
type Layers = {
|
||||
url: string;
|
||||
};
|
||||
|
||||
type Image = {
|
||||
layers: Layers[];
|
||||
};
|
||||
|
||||
type OriginalPeer = {
|
||||
ip: string;
|
||||
hostname: string;
|
||||
layers: Layer[];
|
||||
layers: Layers[];
|
||||
scheduler_cluster_id?: number;
|
||||
};
|
||||
|
||||
|
@ -89,12 +102,13 @@ type ClusteredPeer = {
|
|||
|
||||
type TransformedImage = {
|
||||
peers: ClusteredPeer[];
|
||||
image: Image;
|
||||
};
|
||||
|
||||
function transformImages(images: { peers: OriginalPeer[] }): TransformedImage {
|
||||
function transformImages(images: createGetImageDistributionJobResponse): TransformedImage {
|
||||
const clusters = new Map<number, Omit<OriginalPeer, 'scheduler_cluster_id'>[]>();
|
||||
|
||||
for (const peer of images.peers) {
|
||||
for (const peer of images.peers || []) {
|
||||
const clusterId = peer.scheduler_cluster_id ?? 1;
|
||||
|
||||
if (!clusters.has(clusterId)) {
|
||||
|
@ -115,9 +129,65 @@ function transformImages(images: { peers: OriginalPeer[] }): TransformedImage {
|
|||
scheduler_cluster_id: id,
|
||||
}));
|
||||
|
||||
return { peers: resultPeers };
|
||||
return { peers: resultPeers, image: images.image };
|
||||
}
|
||||
|
||||
const img = {
|
||||
image: {
|
||||
layers: [
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:c7c72808bf776cd122bdaf4630a4a35ea319603d6a3b6cbffddd4c7fd6d2d269',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:9986a736f7d3d24bb01b0a560fa0f19c4b57e56c646e1f998941529d28710e6b',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:fdb99fa1c8f89464e911dce77afd5e26c6c09e9db625014431a4df3be4021359',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:fc5951fb196d09e569f4592b50e3a71ad01d11da229b8a500fea278eba0170c5',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:edbf1aa1d62d9c17605c1ee2d9dff43489bc0f8ae056367734386c35bfae226a',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:f7307687fd72fb79eadd7f38f8cb9675b76480e32365a5d282a06f788944e9f2',
|
||||
},
|
||||
],
|
||||
},
|
||||
peers: [
|
||||
{
|
||||
ip: '172.18.0.2',
|
||||
hostname: 'kind-worker',
|
||||
layers: [
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:9986a736f7d3d24bb01b0a560fa0f19c4b57e56c646e1f998941529d28710e6b?token=abc123&format=json',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:fdb99fa1c8f89464e911dce77afd5e26c6c09e9db625014431a4df3be4021359',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:c7c72808bf776cd122bdaf4630a4a35ea319603d6a3b6cbffddd4c7fd6d2d269?token=abc123&format=json',
|
||||
},
|
||||
],
|
||||
scheduler_cluster_id: 1,
|
||||
},
|
||||
{
|
||||
ip: '172.18.0.4',
|
||||
hostname: 'kind-worker2',
|
||||
layers: [
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:fdb99fa1c8f89464e911dce77afd5e26c6c09e9db625014431a4df3be4021359',
|
||||
},
|
||||
{
|
||||
url: 'https://ghcr.io/v2/dragonflyoss/scheduler/blobs/sha256:c7c72808bf776cd122bdaf4630a4a35ea319603d6a3b6cbffddd4c7fd6d2d269',
|
||||
},
|
||||
],
|
||||
scheduler_cluster_id: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default function Clear() {
|
||||
const [errorMessage, setErrorMessage] = useState(false);
|
||||
const [errorMessageText, setErrorMessageText] = useState('');
|
||||
|
@ -156,12 +226,15 @@ export default function Clear() {
|
|||
piece_length: 0,
|
||||
});
|
||||
const [imageManifestURL, setImageManifestURL] = useState<TransformedImage>();
|
||||
const [layer, setLayer] = useState(0);
|
||||
const [pageStates, setPageStates] = useState<any>({});
|
||||
|
||||
const { url, tag, application, filtered_query_params } = searchData;
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
|
||||
const imagem = transformImages(img);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchJob = async () => {
|
||||
try {
|
||||
|
@ -861,7 +934,6 @@ export default function Clear() {
|
|||
|
||||
try {
|
||||
event.preventDefault();
|
||||
const data = new FormData(event.currentTarget);
|
||||
|
||||
const form = {
|
||||
args: {
|
||||
|
@ -871,12 +943,11 @@ export default function Clear() {
|
|||
};
|
||||
|
||||
const imageManifest = await createGetImageDistributionJob(form);
|
||||
const imageManifestTask = transformImages(imageManifest);
|
||||
|
||||
setImageManifestURL(imageManifestTask);
|
||||
setLayer(imageManifestTask?.image?.layers?.length || 0);
|
||||
setSearchImageManifestISLodaing(false);
|
||||
|
||||
const res = transformImages(imageManifest);
|
||||
|
||||
setImageManifestURL(res);
|
||||
setIsLoading(false);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
|
@ -984,6 +1055,30 @@ export default function Clear() {
|
|||
<LinkOutlinedIcon sx={{ mr: '0.4rem' }} />
|
||||
Search by URL
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
id="serach-image-manifest-url"
|
||||
value="image-manifest-url"
|
||||
size="small"
|
||||
sx={{
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'var(--palette-save-color)',
|
||||
color: '#FFFFFF',
|
||||
boxShadow: 'rgba(145, 158, 171, 0.2) 0px 0px 2px 0px, rgba(145, 158, 171, 0.12) 0px 12px 24px -4px',
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--palette-save-color)',
|
||||
},
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
p: '0.3rem 0.5rem',
|
||||
color: 'var(--palette-dark-400Channel)',
|
||||
textTransform: 'none',
|
||||
}}
|
||||
>
|
||||
<ImageManifest className={styles.contentForCalculatingTaskIDIcon} />
|
||||
Search by Image Manifest URL
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
id="serach-task-id"
|
||||
value="task-id"
|
||||
|
@ -1032,30 +1127,6 @@ export default function Clear() {
|
|||
<ContentForCalculatingTaskID className={styles.contentForCalculatingTaskIDIcon} />
|
||||
Search by Calculating Task ID
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
id="serach-image-manifest-url"
|
||||
value="image-manifest-url"
|
||||
size="small"
|
||||
sx={{
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'var(--palette-save-color)',
|
||||
color: '#FFFFFF',
|
||||
boxShadow: 'rgba(145, 158, 171, 0.2) 0px 0px 2px 0px, rgba(145, 158, 171, 0.12) 0px 12px 24px -4px',
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--palette-save-color)',
|
||||
},
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
p: '0.3rem 0.5rem',
|
||||
color: 'var(--palette-dark-400Channel)',
|
||||
textTransform: 'none',
|
||||
}}
|
||||
>
|
||||
<ImageManifest className={styles.contentForCalculatingTaskIDIcon} />
|
||||
Search by Image Manifest URL
|
||||
</ToggleButton>
|
||||
</StyledToggleButtonGroup>
|
||||
</Paper>
|
||||
{search === 'task-id' ? (
|
||||
|
@ -1218,7 +1289,7 @@ export default function Clear() {
|
|||
<SchedulerCluster className={styles.schedulerClusterIcon} />
|
||||
<Typography
|
||||
id="schedulerTotal"
|
||||
variant="subtitle2"
|
||||
variant="caption"
|
||||
fontFamily="mabry-bold"
|
||||
component="div"
|
||||
pl="0.3rem"
|
||||
|
@ -1428,9 +1499,25 @@ export default function Clear() {
|
|||
) : Array.isArray(imageManifestURL?.peers) ? (
|
||||
imageManifestURL?.peers.length > 0 ? (
|
||||
<Box>
|
||||
<Typography variant="h6" m="1rem 0" fontFamily="mabry-bold">
|
||||
<Box className={styles.cacheHeader}>
|
||||
<Typography variant="h6" fontFamily="mabry-bold" mr="0.6rem">
|
||||
Cache
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box className={styles.bolbWrapper}>
|
||||
<Typography variant="body2" fontFamily="mabry-bold" component="div" pr="0.3rem">
|
||||
Blobs
|
||||
</Typography>
|
||||
<Typography
|
||||
id="blobs"
|
||||
variant="body2"
|
||||
fontFamily="mabry-bold"
|
||||
component="div"
|
||||
className={styles.bolbText}
|
||||
>
|
||||
{layer || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
{imageManifestURL?.peers.map((item, index) => {
|
||||
const schedulerClusterId = item.scheduler_cluster_id;
|
||||
const totalPage = Math.ceil(item.peer.length / 5);
|
||||
|
@ -1446,7 +1533,7 @@ export default function Clear() {
|
|||
<Box className={styles.schedulerClusterWrapper} id={`scheduler-id-${index}`}>
|
||||
<SchedulerCluster className={styles.schedulerClusterIcon} />
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
variant="caption"
|
||||
fontFamily="mabry-bold"
|
||||
component="div"
|
||||
pl="0.3rem"
|
||||
|
@ -1457,9 +1544,9 @@ export default function Clear() {
|
|||
</Box>
|
||||
</Box>
|
||||
<Divider />
|
||||
{paginatedPeers?.map((items, index) => {
|
||||
{paginatedPeers?.map((items, peerIndex) => {
|
||||
return (
|
||||
<Box key={index}>
|
||||
<Box key={peerIndex}>
|
||||
<Accordion
|
||||
disableGutters
|
||||
elevation={0}
|
||||
|
@ -1477,22 +1564,24 @@ export default function Clear() {
|
|||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel1-content"
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-url-${index}`}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-url-${peerIndex}`}
|
||||
>
|
||||
<Box className={styles.imageManifestHeader}>
|
||||
<Box className={styles.hostnameContainer}>
|
||||
<Box width="16%">
|
||||
<Box
|
||||
className={styles.hostnameWrapper}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-hostname-${index}`}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-hostname-${peerIndex}`}
|
||||
>
|
||||
<Hostnames className={styles.hostnameIcon} />
|
||||
<Typography variant="subtitle2" ml="0.4rem" fontFamily="mabry-bold">
|
||||
{items?.hostname}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
className={styles.hostnameWrapper}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-ip-${index}`}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-ip-${peerIndex}`}
|
||||
>
|
||||
<IP className={styles.hostnameIcon} />
|
||||
<Typography variant="subtitle2" ml="0.4rem" fontFamily="mabry-bold">
|
||||
|
@ -1501,34 +1590,47 @@ export default function Clear() {
|
|||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
className={styles.totalContainer}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-total-${index}`}
|
||||
className={styles.bolbProportionContainer}
|
||||
id={`scheduler-${item?.scheduler_cluster_id}-proportion-${peerIndex}`}
|
||||
>
|
||||
<Total className={styles.totalIcon} />
|
||||
<Typography component="span" variant="subtitle2" fontFamily="mabry-bold" pl="0.3rem">
|
||||
{`Total ${items?.layers.length}`}
|
||||
<Proportion className={styles.bolbIcon} />
|
||||
<Typography
|
||||
component="span"
|
||||
variant="subtitle2"
|
||||
className={styles.bolbProportionText}
|
||||
>
|
||||
{`Bolb: ${((items?.layers?.length / layer) * 100).toFixed(2) || 0}%`}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails
|
||||
key={index}
|
||||
key={peerIndex}
|
||||
sx={{
|
||||
padding: '1rem',
|
||||
backgroundColor: 'var(--palette-background-paper)',
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<Typography component="div" variant="subtitle1" fontFamily="mabry-bold" mb="1rem">
|
||||
URL
|
||||
<Box className={styles.clusterWrapper}>
|
||||
<Paper variant="outlined" className={styles.bolbIconWrapper}>
|
||||
<Layer className={styles.cluster} />
|
||||
</Paper>
|
||||
<Typography component="div" variant="body1" fontFamily="mabry-bold" ml="0.5rem">
|
||||
Blob
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box className={styles.cardCantainer}>
|
||||
{items?.layers.map((item: any, urlIndex: any) => (
|
||||
<Box key={index} className={styles.urlsWrapper}>
|
||||
<URL className={styles.urlIcon} />
|
||||
<Tooltip title={item?.url || '-'} placement="top">
|
||||
<Typography id={`url-${index}`} className={styles.url} variant="body2">
|
||||
{item?.url}
|
||||
{items?.layers.map((item: any, bolbIndex: any) => (
|
||||
<Box key={bolbIndex} className={styles.urlsWrapper}>
|
||||
<Tooltip title={extractSHA256Regex(item?.url) || '-'} placement="top">
|
||||
<Typography
|
||||
id={`url-${bolbIndex}`}
|
||||
className={styles.url}
|
||||
fontFamily="mabry-bold"
|
||||
variant="body2"
|
||||
>
|
||||
{extractSHA256Regex(item?.url)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
@ -1537,8 +1639,7 @@ export default function Clear() {
|
|||
</Box>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
|
||||
{index !== paginatedPeers.length - 1 && <Divider />}
|
||||
{peerIndex !== paginatedPeers.length - 1 && <Divider />}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
|
@ -1560,7 +1661,10 @@ export default function Clear() {
|
|||
})}
|
||||
</Box>
|
||||
) : (
|
||||
<Box id="no-task" sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', mt: '6rem' }}>
|
||||
<Box
|
||||
id="no-image-manifest-URL-task"
|
||||
sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', mt: '6rem' }}
|
||||
>
|
||||
<NoSearch className={styles.noSearch} />
|
||||
<Box>
|
||||
<Typography variant="h5" component="span">
|
||||
|
|
|
@ -994,7 +994,7 @@ interface ImageDistributionpeers {
|
|||
}
|
||||
|
||||
export interface createGetImageDistributionJobResponse {
|
||||
image: layers[];
|
||||
image: { layers: layers[] };
|
||||
peers: ImageDistributionpeers[];
|
||||
}
|
||||
|
||||
|
|
|
@ -168,3 +168,8 @@ export const parseTimeDuration = (input: string) => {
|
|||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const extractSHA256Regex = (url: string) => {
|
||||
const match = url.match(/\/sha256:([a-f0-9]{64})/);
|
||||
return match ? match[1] : null;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue