diff --git a/app/components/ResultsTableSkeleton.tsx b/app/components/ResultsTableSkeleton.tsx
index d101630a..66ffa9ba 100644
--- a/app/components/ResultsTableSkeleton.tsx
+++ b/app/components/ResultsTableSkeleton.tsx
@@ -8,18 +8,20 @@ export default function ResultsTableSkeleton({
cols = 5,
}: ResultsTableSkeletonProps) {
return (
-
- {Array.from({ length: rows }).map((_, r) => (
-
- {Array.from({ length: cols }).map((_, c) => (
-
- ))}
-
- ))}
+
+
+ {Array.from({ length: rows }).map((_, r) => (
+
+ {Array.from({ length: cols }).map((_, c) => (
+
+ ))}
+
+ ))}
+
);
}
diff --git a/app/components/RunsListSkeleton.tsx b/app/components/RunsListSkeleton.tsx
index 010c585b..01e6e753 100644
--- a/app/components/RunsListSkeleton.tsx
+++ b/app/components/RunsListSkeleton.tsx
@@ -13,16 +13,20 @@ export default function RunsListSkeleton({ count = 5 }: RunsListSkeletonProps) {
-
diff --git a/app/components/evaluations/CreateDatasetForm.tsx b/app/components/evaluations/CreateDatasetForm.tsx
index eac56565..c571cbf8 100644
--- a/app/components/evaluations/CreateDatasetForm.tsx
+++ b/app/components/evaluations/CreateDatasetForm.tsx
@@ -20,7 +20,7 @@ interface CreateDatasetFormProps {
onFileSelect: (event: React.ChangeEvent
) => void;
onRemoveFile: () => void;
isUploading: boolean;
- handleCreateDataset: () => void;
+ handleCreateDataset: () => void | Promise;
resetForm: () => void;
}
diff --git a/app/components/evaluations/DatasetsTab.tsx b/app/components/evaluations/DatasetsTab.tsx
index dcf679f5..4d4b1788 100644
--- a/app/components/evaluations/DatasetsTab.tsx
+++ b/app/components/evaluations/DatasetsTab.tsx
@@ -5,8 +5,8 @@ import { Dataset, ViewDatasetModalData } from "@/app/lib/types/dataset";
import { useToast } from "@/app/components/Toast";
import { useAuth } from "@/app/lib/context/AuthContext";
import { apiFetch } from "@/app/lib/apiClient";
-import { DatabaseIcon } from "@/app/components/icons";
-import { DatasetListSkeleton } from "@/app/components";
+import { DatabaseIcon, PlusIcon } from "@/app/components/icons";
+import { Button, DatasetListSkeleton, Modal } from "@/app/components";
import DatasetCard from "./DatasetCard";
import CreateDatasetForm from "./CreateDatasetForm";
import ViewDatasetModal from "./ViewDatasetModal";
@@ -24,7 +24,7 @@ export interface DatasetsTabProps {
onFileSelect: (event: React.ChangeEvent) => void;
onRemoveFile: () => void;
isUploading: boolean;
- handleCreateDataset: () => void;
+ handleCreateDataset: () => Promise;
resetForm: () => void;
storedDatasets: Dataset[];
isDatasetsLoading: boolean;
@@ -80,6 +80,7 @@ export default function DatasetsTab({
const [deletingId, setDeletingId] = useState(null);
const [confirmDeleteId, setConfirmDeleteId] = useState(null);
const [viewingId, setViewingId] = useState(null);
+ const [isFormModalOpen, setIsFormModalOpen] = useState(false);
const [viewModalData, setViewModalData] =
useState(null);
@@ -146,14 +147,44 @@ export default function DatasetsTab({
? storedDatasets.find((d) => d.dataset_id === confirmDeleteId)
: undefined;
+ const handleCreate = async (): Promise => {
+ const success = await handleCreateDataset();
+ if (success) setIsFormModalOpen(false);
+ return success;
+ };
+
+ const formProps = {
+ datasetName,
+ setDatasetName,
+ datasetDescription,
+ setDatasetDescription,
+ duplicationFactor,
+ setDuplicationFactor,
+ uploadedFile,
+ onFileSelect,
+ onRemoveFile,
+ isUploading,
+ handleCreateDataset: handleCreate,
+ resetForm,
+ };
+
return (
-
+
Datasets
+
setIsFormModalOpen(true)}
+ className="lg:hidden"
+ >
+
+ New
+
{isDatasetsLoading ? (
@@ -165,7 +196,12 @@ export default function DatasetsTab({
No datasets yet
- Create your first dataset using the form on the right
+
+ Create your first dataset using the form on the right
+
+
+ Tap New to create your first dataset
+
) : (
@@ -186,26 +222,25 @@ export default function DatasetsTab({
+ {/* Right Panel - Create Dataset Form (lg+ only) */}
-
+
+ {/* Mobile/tablet — form rendered in a modal */}
+
setIsFormModalOpen(false)}
+ title="Create New Dataset"
+ maxWidth="max-w-2xl"
+ maxHeight="max-h-[90vh]"
+ >
+
+
+
{viewModalData && (
)}
-
-
+
+
{job.dataset_name && (
-
+
- {job.dataset_name}
+ {job.dataset_name}
)}
{job.assistant_id && assistantConfig?.name && (
-
+
{assistantConfig.name}
)}
@@ -103,7 +103,7 @@ export default function EvalRunCard({
)}
-
+
void;
onRefresh: () => void;
+ onCreateNew?: () => void;
}
export default function EvalRunsList({
@@ -24,6 +25,7 @@ export default function EvalRunsList({
statusFilter,
onStatusFilterChange,
onRefresh,
+ onCreateNew,
}: EvalRunsListProps) {
const filteredJobs =
statusFilter === "all"
@@ -33,7 +35,7 @@ export default function EvalRunsList({
return (
-
+
Evaluation Runs
@@ -59,6 +61,17 @@ export default function EvalRunsList({
className={`w-4 h-4 -scale-x-100 ${isLoading ? "animate-spin" : ""}`}
/>
+ {onCreateNew && (
+
+
+ New
+
+ )}
diff --git a/app/components/evaluations/EvaluationsTab.tsx b/app/components/evaluations/EvaluationsTab.tsx
index ec370779..7d934d73 100644
--- a/app/components/evaluations/EvaluationsTab.tsx
+++ b/app/components/evaluations/EvaluationsTab.tsx
@@ -5,6 +5,7 @@ import { apiFetch } from "@/app/lib/apiClient";
import { Dataset } from "@/app/lib/types/dataset";
import { EvalJob, AssistantConfig, Tab } from "@/app/lib/types/evaluation";
import { useAuth } from "@/app/lib/context/AuthContext";
+import { Modal } from "@/app/components";
import EvalRunsList from "./EvalRunsList";
import RunEvaluationForm from "./RunEvaluationForm";
@@ -46,6 +47,7 @@ export default function EvaluationsTab({
Map
>(new Map());
const [statusFilter, setStatusFilter] = useState("all");
+ const [isFormModalOpen, setIsFormModalOpen] = useState(false);
const selectedDataset = storedDatasets.find(
(d) => d.dataset_id.toString() === selectedDatasetId,
@@ -120,7 +122,26 @@ export default function EvaluationsTab({
const handleRun = async () => {
const success = await handleRunEvaluation();
- if (success) fetchEvaluations();
+ if (success) {
+ fetchEvaluations();
+ setIsFormModalOpen(false);
+ }
+ };
+
+ const formProps = {
+ storedDatasets,
+ selectedDataset,
+ selectedDatasetId,
+ setSelectedDatasetId,
+ selectedConfigId,
+ selectedConfigVersion,
+ onConfigSelect,
+ experimentName,
+ setExperimentName,
+ isEvaluating,
+ canRun,
+ onRun: handleRun,
+ setActiveTab,
};
return (
@@ -134,29 +155,27 @@ export default function EvaluationsTab({
statusFilter={statusFilter}
onStatusFilterChange={setStatusFilter}
onRefresh={fetchEvaluations}
+ onCreateNew={() => setIsFormModalOpen(true)}
/>
- {/* Right Panel - Configuration */}
+ {/* Right Panel - Configuration (lg+ only) */}
-
+
+
+ {/* Mobile/tablet — form rendered in a modal */}
+ setIsFormModalOpen(false)}
+ title="Run New Evaluation"
+ maxWidth="max-w-2xl"
+ maxHeight="max-h-[90vh]"
+ >
+
+
);
}