Refactor annotation tools and implement quality choice annotation feature
- Updated the annotation label from "bewertet" to "annotiert" in the HomePage component. - Removed the SingleChoiceView component and replaced it with a new QualityChoiceEntryView component for handling quality choice annotations. - Introduced QualityChoiceView component to manage the flow of quality choice annotations, including navigation and progress tracking. - Updated EditableExperimentHeader to default to 'quality-choice' annotation tool. - Added unique index for annotations in the database schema to prevent duplicate entries. - Enhanced WaveformPlayer to support audio playback state management.
This commit is contained in:
@@ -66,7 +66,7 @@ export async function getAnnotationEntries(experimentId: number): Promise<Datase
|
||||
|
||||
/**
|
||||
* Persists a batch of ratings for the authenticated user.
|
||||
* Silently ignores duplicates (onConflictDoNothing).
|
||||
* Updates existing annotations with the same userId, experimentId, and datasetEntryId.
|
||||
*/
|
||||
export async function saveAnnotations(
|
||||
ratings: { entryId: number; rating: number; dialectLabel: string }[],
|
||||
@@ -81,7 +81,13 @@ export async function saveAnnotations(
|
||||
await db
|
||||
.insert(annotation)
|
||||
.values({experimentId, datasetEntryId: entryId, userId: session.user.id, rating, dialectLabel })
|
||||
.onConflictDoNothing();
|
||||
.onConflictDoUpdate({
|
||||
target: [annotation.userId, annotation.experimentId, annotation.datasetEntryId],
|
||||
set: {
|
||||
rating,
|
||||
dialectLabel,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import { headers } from 'next/headers';
|
||||
import Link from 'next/link';
|
||||
import { auth } from '@/lib/auth';
|
||||
import { getAnnotationEntries } from '@/app/actions/annotations';
|
||||
import SingleChoiceView from '@/components/AnnotationViews/SingleChoiceView';
|
||||
import { getExperimentById } from '@/app/actions/experiment';
|
||||
import QualityChoiceView from '@/components/AnnotationViews/QualityChoiceView';
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ experimentId: string}>;
|
||||
@@ -55,9 +55,11 @@ export default async function AnnotatePage({ params }: Props) {
|
||||
// Render based on prototype type
|
||||
const renderAnnotationView = () => {
|
||||
switch (prototype) {
|
||||
case 'single-choice':
|
||||
return <SingleChoiceView entries={entries} experimentId={experimentId} />;
|
||||
// Add more prototypes here as needed
|
||||
case 'quality-choice':
|
||||
return <QualityChoiceView entries={entries} experimentId={experimentId} />;
|
||||
case 'binary':
|
||||
//return <BinaryView entries={entries} experimentId={experimentId} />;
|
||||
return <div/>;
|
||||
default:
|
||||
return (
|
||||
<div className="max-w-xl mx-auto py-16 text-center">
|
||||
|
||||
@@ -73,7 +73,7 @@ export default async function HomePage() {
|
||||
{/* Progress */}
|
||||
<div className="mt-3">
|
||||
<div className="flex justify-between text-xs text-gray-400 mb-1">
|
||||
<span>{done} / {total} bewertet</span>
|
||||
<span>{done} / {total} annotiert</span>
|
||||
<span>{pct}%</span>
|
||||
</div>
|
||||
<div className="w-full bg-gray-200 rounded-full h-2">
|
||||
|
||||
Reference in New Issue
Block a user