Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAN-847]: datasets page added #1246

Merged
merged 3 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 229 additions & 0 deletions client/app/settings/datasets/[id]/DatasetCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import ConfirmationDialog from "components/ConfirmationDialog";
import Card from "components/card";
import { useRouter } from "next/navigation";
import React, { useState } from "react";
import { toast } from "react-toastify";
import { IDatasetDetails } from "../datasets-interface";
import { convertToCSV } from "@/utils/convertToCSV";
import { useDeleteDataset, useUpdateDatasetCard } from "@/hooks/useDatasets";
import { Loader } from "@/components/loader/Loader";
import { DeleteDataset } from "@/services/datasets";
import { axiosInstance } from "@/utils/apiUtils";

interface IProps {
dataframe: IDatasetDetails;
}

const DatasetCard = ({ dataframe }: IProps) => {
const [isEditFormOpen, setIsEditFormOpen] = useState(false);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isDownloadLoading, setIsDownloadLoading] = useState(false);

const { mutateAsync: editDatasetCard, isPending: isEditDatasetLoading } =
useUpdateDatasetCard();
const { mutateAsync: deleteDatasetCard, isPending: isDeleteDatasetLoading } =
useDeleteDataset();

const [datasetForm, setDatasetForm] = useState({
name: dataframe?.name,
description: dataframe?.description,
});

const router = useRouter();

const handleChange = (e) => {
const { name, value } = e.target;
setDatasetForm({
...datasetForm,
[name]: value,
});
};

const onSuccess = (response: any) => {
toast.success(response?.data?.message);
setIsEditFormOpen(false);
setIsDeleteModalOpen(false);
};

const onError = (error: any) => {
toast.error(
error?.response?.data?.message
? error?.response?.data?.message
: error.message
);
};

const handleSubmit = async () => {
const dataSet = {
name: datasetForm.name,
description: datasetForm.description,
};
editDatasetCard(
{
id: dataframe.id,
body: dataSet,
},
{ onSuccess, onError }
);
};

const handleDownload = async () => {
setIsDownloadLoading(true);
await axiosInstance
.get(`/v1/datasets/download/${dataframe.id}`, {
responseType: "blob",
})
.then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", `${dataframe.id}.csv`);
document.body.appendChild(link);
link.click();
// Cleanup
link.parentNode.removeChild(link);
window.URL.revokeObjectURL(url);
})
.catch((error) => {
toast.error(
error?.response?.data?.message
? error?.response?.data?.message
: error?.message
);
});
};

const handleDelete = async () => {
deleteDatasetCard(
{
id: dataframe.id,
},
{
onSuccess(response) {
toast.success(response?.data?.message);
setIsDeleteModalOpen(false);
router.push("/settings/datasets");
},
onError(error: any) {
toast.error(
error?.response?.data?.message
? error?.response?.data?.message
: error?.message
);
},
}
);
};

return (
<>
{!isEditFormOpen ? (
<Card extra={"w-full py-4 px-6 h-full mb-4"}>
<div className="flex flex-col justify-between min-h-[170px]">
<div>
<h3 className="font-bold text-[20px] mb-1">
{datasetForm?.name}
</h3>
<h3 className="font-bold text-sm mb-1">
<span className="font-normal">{datasetForm?.description}</span>
</h3>
</div>
<div className="flex justify-start gap-4 items-center">
<Button
type="button"
onClick={() => {
setIsEditFormOpen(true);
}}
disabled={isEditDatasetLoading || isDeleteDatasetLoading}
>
Edit
</Button>
<Button
type="button"
onClick={() => {
handleDownload();
}}
disabled={isEditDatasetLoading || isDeleteDatasetLoading}
>
Download
</Button>
<Button
type="button"
variant="destructive"
disabled={isEditDatasetLoading || isDeleteDatasetLoading}
onClick={() => setIsDeleteModalOpen(true)}
>
Delete
</Button>
</div>
</div>
</Card>
) : (
<Card extra={"w-full py-4 px-6 h-full mb-4"}>
<div className="flex flex-col justify-between min-h-[170px]">
<div className="mt-2">
<Input
name="name"
type="text"
placeholder="Add Dataset name"
autoComplete="off"
value={datasetForm.name}
onChange={handleChange}
/>
</div>
<div className="mt-1">
<Textarea
name="description"
placeholder="Add Dataset name"
autoComplete="off"
value={datasetForm.description}
onChange={handleChange}
/>
</div>

<div className="flex justify-start gap-4 items-center flex-wrap">
<Button
type="button"
onClick={() => {
handleSubmit();
}}
disabled={isEditDatasetLoading || isDeleteDatasetLoading}
>
{isEditDatasetLoading ? (
<Loader height="h-6" width="w-10" />
) : (
"Save"
)}
</Button>
<Button
type="button"
variant="destructive"
disabled={isEditDatasetLoading || isDeleteDatasetLoading}
onClick={() => setIsEditFormOpen(false)}
>
Cancel
</Button>
</div>
</div>
</Card>
)}

{isDeleteModalOpen && (
<ConfirmationDialog
text={`Are you sure you want to delete this Datasets?`}
onCancel={() => {
setIsDeleteModalOpen(false);
}}
isLoading={isDeleteLoading}
onSubmit={handleDelete}
/>
)}
</>
);
};

export default DatasetCard;
41 changes: 41 additions & 0 deletions client/app/settings/datasets/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";
import React from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import DatasetCard from "./DatasetCard";
import { DatasetCardLoading } from "@/components/Skeletons";
import { useGetDatasetDetails } from "@/hooks/useDatasets";

const DatasetDetailsPage = () => {
const params: { id: string } = useParams();

const {
data: datasetDetailsResponse,
isLoading: isDatasetDetailsResponseLoading,
} = useGetDatasetDetails(params.id);

const dataframe = datasetDetailsResponse?.data?.dataset;

return (
<>
<div className="w-full h-full overflow-y-auto custom-scroll mt-5 px-2 md:px-4">
<h1 className="text-2xl font-bold dark:text-white mb-10">
<Link href="/settings/datasets">Datasets</Link>
<small>{` › ${dataframe?.name || ""}`}</small>
</h1>

<div className="flex flex-col p-2 md:p-4 font-montserrat">
<div className="flex items-center justify-center w-[50%]">
{isDatasetDetailsResponseLoading ? (
<DatasetCardLoading />
) : (
<DatasetCard dataframe={dataframe} />
)}
</div>
</div>
</div>
</>
);
};

export default DatasetDetailsPage;
Loading
Loading