diff --git a/ui/src/app/api/datasets/delete/route.tsx b/ui/src/app/api/datasets/delete/route.tsx
new file mode 100644
index 00000000..a35b2182
--- /dev/null
+++ b/ui/src/app/api/datasets/delete/route.tsx
@@ -0,0 +1,24 @@
+import { NextResponse } from 'next/server';
+import fs from 'fs';
+import path from 'path';
+import { getDatasetsRoot } from '@/app/api/datasets/utils';
+
+export async function POST(request: Request) {
+ try {
+ const body = await request.json();
+ const { name } = body;
+ let datasetsPath = await getDatasetsRoot();
+ let datasetPath = path.join(datasetsPath, name);
+
+ // if folder doesnt exist, ignore
+ if (!fs.existsSync(datasetPath)) {
+ return NextResponse.json({ success: true });
+ }
+
+ // delete it and return success
+ fs.rmdirSync(datasetPath, { recursive: true });
+ return NextResponse.json({ success: true });
+ } catch (error) {
+ return NextResponse.json({ error: 'Failed to create dataset' }, { status: 500 });
+ }
+}
diff --git a/ui/src/app/datasets/page.tsx b/ui/src/app/datasets/page.tsx
index b5304c04..77851c18 100644
--- a/ui/src/app/datasets/page.tsx
+++ b/ui/src/app/datasets/page.tsx
@@ -1,11 +1,13 @@
'use client';
import { useEffect, useState } from 'react';
-import Card from '@/components/Card';
import { Modal } from '@/components/Modal';
import Link from 'next/link';
import { TextInput } from '@/components/formInputs';
import useDatasetList from '@/hooks/useDatasetList';
+import { Button } from '@headlessui/react';
+import { FaRegTrashAlt } from 'react-icons/fa';
+import { openConfirm } from '@/components/ConfirmModal';
export default function Datasets() {
const { datasets, status, refreshDatasets } = useDatasetList();
@@ -13,36 +15,70 @@ export default function Datasets() {
const [isNewDatasetModalOpen, setIsNewDatasetModalOpen] = useState(false);
return (
<>
-
-
-
-
Datasets
-
-
-
-
+
+
+
Datasets
-
- {status === 'loading' && Loading...
}
- {status === 'error' && Error fetching datasets
}
- {status === 'success' && (
-
- {datasets.length === 0 &&
No datasets found
}
- {datasets.map((dataset: string) => (
-
- {dataset}
-
- ))}
-
- )}
-
+
+
+
+
+
+
+ {status === 'loading' &&
Loading...
}
+ {status === 'error' &&
Error fetching datasets
}
+ {status === 'success' && (
+
+ {datasets.length === 0 &&
No datasets found
}
+ {datasets.map((dataset: string) => (
+
+
+
+ {dataset}
+
+
+
+
+
+
+
+ ))}
+
+ )}
(null);
+export const openConfirm = (confirmProps: ConfirmState) => {
+ confirmstate.set(confirmProps);
+};
export default function ConfirmModal() {
-
const [confirm, setConfirm] = confirmstate.use();
- const open = confirm !== null;
+ const [isOpen, setIsOpen] = useState(false);
+
+ useEffect(() => {
+ if (confirm) {
+ setIsOpen(true);
+ }
+ }, [confirm]);
+
+ useEffect(() => {
+ if (!isOpen) {
+ // use timeout to allow the dialog to close before resetting the state
+ setTimeout(() => {
+ setConfirm(null);
+ }, 500);
+ }
+ }, [isOpen]);
const onCancel = () => {
if (confirm?.onCancel) {
confirm.onCancel();
}
- setConfirm(null);
+ setIsOpen(false);
};
const onConfirm = () => {
if (confirm?.onConfirm) {
confirm.onConfirm();
}
- setConfirm(null);
+ setIsOpen(false);
};
let Icon = FaExclamationTriangle;
@@ -46,45 +63,61 @@ export default function ConfirmModal() {
// Color mapping for background colors
const getBgColor = () => {
switch (color) {
- case 'danger': return 'bg-red-500';
- case 'warning': return 'bg-yellow-500';
- case 'info': return 'bg-blue-500';
- default: return 'bg-red-500';
+ case 'danger':
+ return 'bg-red-500';
+ case 'warning':
+ return 'bg-yellow-500';
+ case 'info':
+ return 'bg-blue-500';
+ default:
+ return 'bg-red-500';
}
};
// Color mapping for text colors
const getTextColor = () => {
switch (color) {
- case 'danger': return 'text-red-950';
- case 'warning': return 'text-yellow-950';
- case 'info': return 'text-blue-950';
- default: return 'text-red-950';
+ case 'danger':
+ return 'text-red-950';
+ case 'warning':
+ return 'text-yellow-950';
+ case 'info':
+ return 'text-blue-950';
+ default:
+ return 'text-red-950';
}
};
// Color mapping for titles
const getTitleColor = () => {
switch (color) {
- case 'danger': return 'text-red-500';
- case 'warning': return 'text-yellow-500';
- case 'info': return 'text-blue-500';
- default: return 'text-red-500';
+ case 'danger':
+ return 'text-red-500';
+ case 'warning':
+ return 'text-yellow-500';
+ case 'info':
+ return 'text-blue-500';
+ default:
+ return 'text-red-500';
}
};
// Button background color mapping
const getButtonBgColor = () => {
switch (color) {
- case 'danger': return 'bg-red-700 hover:bg-red-500';
- case 'warning': return 'bg-yellow-700 hover:bg-yellow-500';
- case 'info': return 'bg-blue-700 hover:bg-blue-500';
- default: return 'bg-red-700 hover:bg-red-500';
+ case 'danger':
+ return 'bg-red-700 hover:bg-red-500';
+ case 'warning':
+ return 'bg-yellow-700 hover:bg-yellow-500';
+ case 'info':
+ return 'bg-blue-700 hover:bg-blue-500';
+ default:
+ return 'bg-red-700 hover:bg-red-500';
}
};
return (
-