Skip to content

Commit

Permalink
Merge pull request #412 from tapis-project/task/TUI-407-single-datase…
Browse files Browse the repository at this point in the history
…t-details

Add DatasetDetails, Download Dataset and Dataset Card button to downl…
  • Loading branch information
NotChristianGarcia authored Jul 30, 2024
2 parents 22db795 + 4e9378c commit 5510090
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 2 deletions.
63 changes: 63 additions & 0 deletions src/app/MlHub/Datasets/DatasetDetails.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.dataset-details {
padding-left: 1em;
padding-right: 1em;
}

.buttons-container {
display: flex;
flex-direction: column;
position: absolute;
top: 0px;
right: 0px;
gap: 20px;
}

.dataset-details-wrapper {
display: flex;
flex-direction: row;
width: 100%;
position: relative;
}

.dataset-details {
display: flex;
flex-direction: column;
gap: 16px;
flex: 1;
}

.dataset-title {
padding-bottom: 8px;
margin-left: 10px;
}

.dataset-detail {
display: flex;
flex-direction: row;
}

.dataset-title {
font-weight: bold;
width: 10vw;
}

.detail-info {
margin-left: 8px;
text-align: left;
}

.dataset-title-container {
border-bottom: 1px solid black;
margin-bottom: 8px;
}

.download-links {
flex-grow: 1;
display: flex;
flex-direction: column;
padding-bottom: 5px;
}

.download-url-button {
height: 40px;
}
238 changes: 238 additions & 0 deletions src/app/MlHub/Datasets/DatasetDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import React, { useState } from 'react';
import { Datasets } from '@tapis/tapis-typescript';
import { MLHub as Hooks } from '@tapis/tapisui-hooks';
import { QueryWrapper } from '@tapis/tapisui-common';
import { Button } from 'reactstrap';
import styles from './DatasetDetails.module.scss';
import { Icon, JSONDisplay, GenericModal } from '@tapis/tapisui-common';

type DatasetDetailsProps = {
datasetId: string;
};

const DatasetDetails: React.FC<DatasetDetailsProps> = ({ datasetId }) => {
const { data, isLoading, error } = Hooks.Datasets.useDetails({ datasetId });
const dataset: Datasets.DatasetFullInfo = data?.result ?? {};
return (
<QueryWrapper
isLoading={isLoading}
error={error}
className={styles['dataset-details']}
>
<div className={`${styles['dataset-title-container']}`}>
<div className={`${styles['dataset-title']}`}>
<b>{datasetId}</b>
</div>
</div>
<div className={`${styles['dataset-details-wrapper']}`}>
<div className={`${styles['dataset-details']}`}>
{dataset.author && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>author:</div>
<div className={`${styles['dataset-info']}`}>
{dataset.author}
</div>
</div>
)}

{dataset.downloads && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>downloads:</div>
<div className={`${styles['detail-info']}`}>
{dataset.downloads}
</div>
</div>
)}

{dataset.created_at && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>created_at:</div>
<div className={`${styles['detail-info']}`}>
{dataset.created_at}
</div>
</div>
)}

{dataset.last_modified && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>last_modified:</div>
<div className={`${styles['detail-info']}`}>
{dataset.last_modified}
</div>
</div>
)}

{dataset.tags && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>tags:</div>
<div className={`${styles['detail-info']}`}>{dataset.tags}</div>
</div>
)}

{dataset.sha && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>sha:</div>
<div className={`${styles['detail-info']}`}>{dataset.sha}</div>
</div>
)}

{dataset.repository_content && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>
repository_content:
</div>

<div className={`${styles['detail-info']}`}>
{dataset.repository_content && (
<JSONDisplay json={dataset.repository_content}></JSONDisplay>
)}
</div>
</div>
)}

{dataset.description && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>description:</div>
<div className={`${styles['detail-info']}`}>
{dataset.description}
</div>
</div>
)}

{dataset.paperswithcode_id && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>
paperswithcode_id:
</div>
<div className={`${styles['detail-info']}`}>
{dataset.paperswithcode_id}
</div>
</div>
)}

{dataset.citation && (
<div className={`${styles['dataset-detail']}`}>
<div className={`${styles['dataset-title']}`}>citation:</div>
<div className={`${styles['detail-info']}`}>
{dataset.citation}
</div>
</div>
)}
</div>
<Buttons datasetId={datasetId} />
</div>
</QueryWrapper>
);
};

const Buttons: React.FC<{ datasetId: string }> = ({ datasetId }) => {
const [currentDataset, setCurrentDataset] = useState<string | undefined>(
undefined
);

const { data, error, isLoading } = Hooks.Datasets.useDetails({ datasetId });

const datasetCardDetails: Datasets.DatasetFullInfo = data?.result ?? {};

const {
data: downloadLinkData,
error: downloadLinkError,
isLoading: downloadLinkIsLoading,
} = Hooks.Datasets.useDownloadLinks({ datasetId });

const downloadLinkInfo: Datasets.DatasetDownloadInfo =
downloadLinkData?.result ?? {};

const downloadOnClick = (url: string, filename: string) => {
fetch(url).then((response) => {
response.blob().then((blob) => {
const fileURL = window.URL.createObjectURL(blob);
let alink = document.createElement('a');
alink.href = fileURL;
alink.download = filename;
document.body.appendChild(alink);
alink.click();
document.body.removeChild(alink);

window.URL.revokeObjectURL(fileURL);
});
});
};

return (
<div className={`${styles['buttons-container']}`}>
<Button
onClick={() => {
setCurrentDataset('downloaddataset');
}}
>
{'Download Dataset '}
<span>
<Icon name="push-right" />
</span>
</Button>

<Button
onClick={() => {
setCurrentDataset('datasetcard');
}}
>
{'Dataset Card '}
<span>
<Icon name="push-right" />
</span>
</Button>

{currentDataset === 'datasetcard' && (
<GenericModal
toggle={() => {
setCurrentDataset(undefined);
}}
title="Dataset Card"
body={
<div>
{datasetId}
{datasetCardDetails.card_data && (
<JSONDisplay json={datasetCardDetails.card_data} />
)}
</div>
}
/>
)}

{currentDataset === 'downloaddataset' && (
<GenericModal
toggle={() => {
setCurrentDataset(undefined);
}}
title="Download Dataset"
body={
<div className={`${styles['download-body']}`}>
{downloadLinkInfo?.download_links &&
Object.entries(downloadLinkInfo.download_links).map(
([filename, url]) => {
return (
<div className={`${styles['download-links']}`}>
<div>{filename}:</div>
<div></div>
<div className={`${styles['download-url-button']}`}>
<Button
onClick={() => downloadOnClick(url, filename)}
>
{' '}
Download{' '}
</Button>
</div>
</div>
);
}
)}
</div>
}
/>
)}
</div>
);
};

export default DatasetDetails;
12 changes: 12 additions & 0 deletions src/app/MlHub/Datasets/_Router/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
RouteComponentProps,
} from 'react-router-dom';
import Datasets from '../Datasets';
import DatasetDetails from '../DatasetDetails';

const Router: React.FC = () => {
const { path } = useRouteMatch();
Expand All @@ -14,6 +15,17 @@ const Router: React.FC = () => {
<Route path={`${path}`} exact>
<Datasets />
</Route>

<Route
path={`${path}/:datasetId+`}
render={({
match: {
params: { datasetId },
},
}: RouteComponentProps<{ datasetId: string }>) => {
return <DatasetDetails datasetId={datasetId} />;
}}
/>
</Switch>
);
};
Expand Down
63 changes: 63 additions & 0 deletions src/app/MlHub/Models/InferenceServerInfo.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.model-details {
padding-left: 1em;
padding-right: 1em;
}

.buttons-container {
display: flex;
flex-direction: column;
position: absolute;
top: 0px;
right: 0px;
gap: 20px;
}

.model-details-wrapper {
display: flex;
flex-direction: row;
width: 100%;
position: relative;
}

.model-details {
display: flex;
flex-direction: column;
gap: 16px;
flex: 1;
}

.model-title {
padding-bottom: 8px;
margin-left: 10px;
}

.model-detail {
display: flex;
flex-direction: row;
}

.detail-title {
font-weight: bold;
width: 15vw;
}

.detail-info {
margin-left: 8px;
text-align: left;
}

.model-title-container {
border-bottom: 1px solid black;
margin-bottom: 8px;
}

.download-links {
flex-grow: 1;
display: flex;
flex-direction: column;
padding-bottom: 5px;
}

.download-url-button {
height: 40px;
}
Loading

0 comments on commit 5510090

Please sign in to comment.