feat: Add admin experiment management pages and components
- Implemented ExperimentPage for viewing and editing individual experiments. - Created ExperimentsAdminPage for managing all experiments with a list and a modal for creating new experiments. - Developed AnnotatePage for annotating experiments with different views based on annotation tools. - Added CreateExperimentModal for creating new experiments with dataset selection. - Introduced DeleteExperimentButton for confirming and executing experiment deletions. - Built EditableExperimentHeader for editing experiment details. - Created ExperimentsList component to display a list of experiments with links to their details.
This commit is contained in:
@@ -87,7 +87,7 @@ export async function saveAnnotations(
|
||||
|
||||
/** Returns all datasets (for the home page). */
|
||||
export async function getAllExperiments() {
|
||||
return db.select().from(experiment).orderBy(experiment.id);
|
||||
return db.select().from(experiment).where(eq(experiment.published, true)).orderBy(experiment.id);
|
||||
}
|
||||
|
||||
/** Returns annotation progress for the current user in a dataset. */
|
||||
|
||||
@@ -7,6 +7,24 @@ import { revalidatePath } from 'next/cache';
|
||||
import { removeAllDatasetEntries } from './remove-dataset-entries';
|
||||
import { requireAdmin } from '@/lib/auth';
|
||||
|
||||
export async function getAllDatasets() {
|
||||
const result = await requireAdmin();
|
||||
if (!result.authenticated || !result.admin) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
try {
|
||||
const datasets = await db
|
||||
.select()
|
||||
.from(dataset)
|
||||
.orderBy(dataset.name);
|
||||
return datasets;
|
||||
} catch (error) {
|
||||
console.error('Error fetching datasets:', error);
|
||||
throw new Error('Failed to fetch datasets');
|
||||
}
|
||||
}
|
||||
|
||||
export async function createDataset({ name, description }: { name: string; description?: string }) {
|
||||
const result = await requireAdmin();
|
||||
if (!result.authenticated || !result.admin) {
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
'use server';
|
||||
|
||||
import db from '@/lib/db';
|
||||
import { experiment } from '@/lib/model/experiment';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { auth, requireAdmin } from '@/lib/auth';
|
||||
import { headers } from 'next/headers';
|
||||
|
||||
export async function createExperiment({
|
||||
name,
|
||||
description,
|
||||
datasetId,
|
||||
annotationTool,
|
||||
published = false
|
||||
}: {
|
||||
name: string;
|
||||
description?: string;
|
||||
datasetId: number;
|
||||
annotationTool: string;
|
||||
published?: boolean;
|
||||
}) {
|
||||
const result = await requireAdmin();
|
||||
if (!result.authenticated || !result.admin) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
if (!name || !name.trim()) {
|
||||
throw new Error('Experiment name is required');
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await db.insert(experiment).values({
|
||||
name: name.trim(),
|
||||
description: description?.trim() || null,
|
||||
datasetId,
|
||||
annotationTool: annotationTool.trim(),
|
||||
published,
|
||||
});
|
||||
revalidatePath('/admin/experiments');
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('Error creating experiment:', error);
|
||||
throw new Error('Failed to create experiment');
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateExperiment(
|
||||
id: number,
|
||||
updates: { name?: string; description?: string, annotationTool?: string, published?: boolean }
|
||||
) {
|
||||
const result = await requireAdmin();
|
||||
if (!result.authenticated || !result.admin) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
if (updates.name !== undefined && !updates.name.trim()) {
|
||||
throw new Error('Experiment name cannot be empty');
|
||||
}
|
||||
|
||||
try {
|
||||
const updateData: any = {};
|
||||
if (updates.name !== undefined) {
|
||||
updateData.name = updates.name.trim();
|
||||
}
|
||||
if (updates.description !== undefined) {
|
||||
updateData.description = updates.description.trim() || null;
|
||||
}
|
||||
if (updates.annotationTool !== undefined) {
|
||||
updateData.annotationTool = updates.annotationTool;
|
||||
}
|
||||
if (updates.published !== undefined) {
|
||||
updateData.published = updates.published;
|
||||
}
|
||||
updateData.updatedAt = new Date();
|
||||
|
||||
const result = await db
|
||||
.update(experiment)
|
||||
.set(updateData)
|
||||
.where(eq(experiment.id, id));
|
||||
revalidatePath(`/admin/experiments/${id}`);
|
||||
revalidatePath('/admin/experiments');
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('Error updating experiment:', error);
|
||||
throw new Error('Failed to update experiment');
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteExperiment(id: number) {
|
||||
const result = await requireAdmin();
|
||||
if (!result.authenticated || !result.admin) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
try {
|
||||
// Delete the experiment
|
||||
await db.delete(experiment).where(eq(experiment.id, id));
|
||||
|
||||
revalidatePath('/admin/experiments');
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('Error deleting experiment:', error);
|
||||
throw new Error('Failed to delete experiment');
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExperimentsByDataset(datasetId: number) {
|
||||
const result = await requireAdmin();
|
||||
if (!result.authenticated || !result.admin) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
try {
|
||||
const experiments = await db
|
||||
.select()
|
||||
.from(experiment)
|
||||
.where(eq(experiment.datasetId, datasetId));
|
||||
return experiments;
|
||||
} catch (error) {
|
||||
console.error('Error fetching experiments:', error);
|
||||
throw new Error('Failed to fetch experiments');
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExperimentById(id: number) {
|
||||
const session = await auth.api.getSession({ headers: await headers() });
|
||||
if (!session) throw new Error('Nicht angemeldet');
|
||||
|
||||
|
||||
try { const experimentData = await db
|
||||
.select()
|
||||
.from(experiment)
|
||||
.where(
|
||||
and(
|
||||
eq(experiment.id, id),
|
||||
eq(experiment.published, true)
|
||||
))
|
||||
.limit(1);
|
||||
return experimentData[0] || null;
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Error fetching experiment:', error);
|
||||
throw new Error('Failed to fetch experiment');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user