diff --git a/src/renderer/components/Data/Data.tsx b/src/renderer/components/Data/Data.tsx index f63623385032522f783e4b2b799783c68937636f..5894d2129ad207edb370cb48ce9ad4610c67a9bb 100644 --- a/src/renderer/components/Data/Data.tsx +++ b/src/renderer/components/Data/Data.tsx @@ -5,6 +5,7 @@ import { StoreIcon } from 'lucide-react'; import DataStore from './DataStore'; import LocalDatasets from './LocalDatasets'; +import GeneratedDatasets from './GeneratedDatasets' export default function Data() { return ( @@ -22,6 +23,7 @@ export default function Data() { > <TabList> <Tab>Local Datasets</Tab> + <Tab>Generated Datasets</Tab> <Tab> <StoreIcon color="grey" /> Dataset Store @@ -31,6 +33,9 @@ export default function Data() { <LocalDatasets /> </TabPanel> <TabPanel value={1} sx={{ overflow: 'hidden' }}> + <GeneratedDatasets /> + </TabPanel> + <TabPanel value={2} sx={{ overflow: 'hidden' }}> <DataStore /> </TabPanel> </Tabs> diff --git a/src/renderer/components/Data/GeneratedDatasets.tsx b/src/renderer/components/Data/GeneratedDatasets.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a109f980b3887f4b51751b77ef0ba60732e84cd5 --- /dev/null +++ b/src/renderer/components/Data/GeneratedDatasets.tsx @@ -0,0 +1,216 @@ +import { useState } from 'react'; + +import useSWR from 'swr'; + +import { + Box, + Button, + FormControl, + Grid, + Input, + LinearProgress, + Sheet, + CircularProgress, + FormLabel, + Typography, +} from '@mui/joy'; +import { PlusIcon, SearchIcon, StoreIcon } from 'lucide-react'; +import { Link as ReactRouterLink } from 'react-router-dom'; + +import * as chatAPI from '../../lib/transformerlab-api-sdk'; +import DatasetCard from './DatasetCard'; +import NewDatasetModal from './NewDatasetModal'; + +const fetcher = (url) => fetch(url).then((res) => res.json()); + +export function filterByFiltersDatasetID(data, searchText = '', filters = {}) { + return data.filter((row) => { + if (row.dataset_id.toLowerCase().includes(searchText.toLowerCase())) { + for (const filterKey in filters) { + console.log(filterKey, filters[filterKey]); + if (filters[filterKey] !== 'All') { + if (row[filterKey] !== filters[filterKey]) { + return false; + } + } + } + return true; + } + return false; + }); +} +export default function GeneratedDatasets() { + const [searchText, setSearchText] = useState(''); + // const [newDatasetModalOpen, setNewDatasetModalOpen] = useState(false); + // const [downloadingDataset, setDownloadingDataset] = useState(null); + + const { data, error, isLoading, mutate } = useSWR( + chatAPI.Endpoints.Dataset.GeneratedList(), + fetcher + ); + + if (error) return 'An error has occurred.'; + if (isLoading) return <LinearProgress />; + + console.log(data); + + return ( + <Sheet + sx={{ + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + height: '100%', + }} + > + {/* <NewDatasetModal + open={newDatasetModalOpen} + setOpen={setNewDatasetModalOpen} + /> */} + <Box + className="SearchAndFilters-tabletUp" + sx={{ + borderRadius: 'sm', + pb: 2, + display: 'flex', + flexWrap: 'wrap', + gap: 1.5, + '& > *': { + minWidth: { + xs: '120px', + md: '160px', + }, + }, + }} + > + <FormControl sx={{ flex: 2 }} size="sm"> + <Input + placeholder="Search" + value={searchText} + onChange={(e) => setSearchText(e.target.value)} + startDecorator={<SearchIcon />} + /> + </FormControl> + </Box> + <Sheet + className="OrderTableContainer" + variant="outlined" + sx={{ + width: '100%', + height: '100%', + borderRadius: 'md', + flex: 1, + overflow: 'auto', + minHeight: 0, + padding: 2, + }} + > + <Grid container spacing={2} sx={{ flexGrow: 1 }}> + {data && + filterByFiltersDatasetID(data, searchText).map((row) => ( + <Grid xs={4}> + <DatasetCard + name={row?.dataset_id} + size={row?.size} + key={row.id} + description={row?.description} + repo={row.huggingfacerepo} + location={row?.location} + downloaded={true} + local={true} + parentMutate={mutate} + /> + </Grid> + ))} + + {data?.length === 0 && ( + <Typography level="body-lg" justifyContent="center" margin={5}> + You do not have any generated datasets. You can + download a dataset by going to the Generate Tab in an experiment. + {/* <ReactRouterLink to="/generate"> + <StoreIcon /> + Generated Tab + </ReactRouterLink> + . */} + </Typography> + )} + </Grid> + </Sheet> + {/* <Box + sx={{ + justifyContent: 'space-between', + display: 'flex', + width: '100%', + paddingTop: '12px', + }} + > + <> + <FormControl> + <Input + placeholder="Open-Orca/OpenOrca" + name="download-dataset-name" + endDecorator={ + <Button + onClick={async (e) => { + const dataset = document.getElementsByName( + 'download-dataset-name' + )[0].value; + // only download if valid model is entered + if (dataset) { + // this triggers UI changes while download is in progress + setDownloadingDataset(dataset); + + // Datasets can be very large so do this asynchronously + fetch(chatAPI.Endpoints.Dataset.Download(dataset)) + .then((response) => { + if (!response.ok) { + console.log(response); + throw new Error(`HTTP Status: ${response.status}`); + } + return response.json(); + }) + .then((response_json) => { + if (response_json?.status == 'error') { + throw new Error(response_json.message); + } + // now mutate: + mutate(); + setDownloadingDataset(null); + }) + .catch((error) => { + setDownloadingDataset(null); + alert('Download failed:\n' + error); + }); + } + }} + startDecorator={ + downloadingDataset ? ( + <CircularProgress size="sm" thickness={2} /> + ) : ( + '' + ) + } + > + {downloadingDataset ? 'Downloading' : 'Download 🤗 Dataset'} + </Button> + } + sx={{ width: '500px' }} + /> + </FormControl> + <> + {/* <Button + size="sm" + sx={{ height: '30px' }} + endDecorator={<PlusIcon />} + onClick={() => { + setNewDatasetModalOpen(true); + }} + > + New + </Button> */} + {/* </> + </> + </Box> */} + </Sheet> + ); +} diff --git a/src/renderer/components/Data/LocalDatasets.tsx b/src/renderer/components/Data/LocalDatasets.tsx index 6ed6393a3e0d612fa56de201256f8b5bf857ca92..64e2d5512acf2f8863fb063e2840d10e9cc05b10 100644 --- a/src/renderer/components/Data/LocalDatasets.tsx +++ b/src/renderer/components/Data/LocalDatasets.tsx @@ -45,7 +45,7 @@ export default function LocalDatasets() { const [downloadingDataset, setDownloadingDataset] = useState(null); const { data, error, isLoading, mutate } = useSWR( - chatAPI.Endpoints.Dataset.LocalList(), + chatAPI.Endpoints.Dataset.LocalList(false), fetcher ); diff --git a/src/renderer/components/Data/NewDatasetModal.tsx b/src/renderer/components/Data/NewDatasetModal.tsx index b234b64c8341ee92b720ee7d357ed595b9c77a21..f4b3be7b6bb6544a06bb8bd2ab64533a6e919f4b 100644 --- a/src/renderer/components/Data/NewDatasetModal.tsx +++ b/src/renderer/components/Data/NewDatasetModal.tsx @@ -34,7 +34,7 @@ export default function DatasetDetailsModal({ open, setOpen }) { // setNewDatasetName(''); // }, [open]); const { data, isLoading, mutate } = useSWR( - chatAPI.Endpoints.Dataset.LocalList(), + chatAPI.Endpoints.Dataset.LocalList(false), fetcher ); //Resetting state variables diff --git a/src/renderer/lib/transformerlab-api-sdk.ts b/src/renderer/lib/transformerlab-api-sdk.ts index 627d694f61d529d23f20fd570370f3d015638acc..d208cfbb99fa8d98b0080deb1163ed6d3dabf680 100644 --- a/src/renderer/lib/transformerlab-api-sdk.ts +++ b/src/renderer/lib/transformerlab-api-sdk.ts @@ -980,6 +980,7 @@ function convertSlashInUrl(url: string) { return url.replace(/\//g, '~~~'); } + Endpoints.Dataset = { Gallery: () => API_URL() + 'data/gallery', Info: (datasetId: string) => API_URL() + 'data/info?dataset_id=' + datasetId, @@ -1018,7 +1019,8 @@ Endpoints.Dataset = { Create: (datasetId: string) => API_URL() + 'data/new?dataset_id=' + datasetId, Download: (datasetId: string) => API_URL() + 'data/download?dataset_id=' + datasetId, - LocalList: () => API_URL() + 'data/list', + LocalList: (generated: boolean = true) => API_URL() + 'data/list?generated=' + generated, + GeneratedList: () => API_URL() + 'data/generated_datasets_list', FileUpload: (datasetId: string) => API_URL() + 'data/fileupload?dataset_id=' + datasetId, }; @@ -1100,7 +1102,7 @@ Endpoints.Documents = { experimentId + '/documents/delete/' + document_name, - CreateFolder: (experimentId: string, folderName: string) => + CreateFolder: (experimentId: string, folderName: string) => API_URL() + 'experiment/' + experimentId +