feat: add utterance field to dataset entries and update related components for filtering and display
This commit is contained in:
@@ -11,6 +11,7 @@ interface FilterParams {
|
||||
modelName?: string;
|
||||
dialect?: string;
|
||||
iteration?: number;
|
||||
utteranceId?: string;
|
||||
}
|
||||
|
||||
export async function getDatasetEntries(
|
||||
@@ -39,6 +40,10 @@ export async function getDatasetEntries(
|
||||
conditions.push(eq(dataset_entry.iteration, filters.iteration));
|
||||
}
|
||||
|
||||
if (filters?.utteranceId) {
|
||||
conditions.push(like(dataset_entry.utteranceId, `%${filters.utteranceId}%`));
|
||||
}
|
||||
|
||||
const whereClause = and(...conditions);
|
||||
|
||||
const entries = await db
|
||||
|
||||
@@ -15,11 +15,13 @@ export async function getFilterOptions(datasetId: number) {
|
||||
const modelNames = [...new Set(entries.map(e => e.modelName))].sort();
|
||||
const dialects = [...new Set(entries.map(e => e.dialect))].sort();
|
||||
const iterations = [...new Set(entries.map(e => e.iteration))].sort((a, b) => a - b);
|
||||
const utteranceIds = [...new Set(entries.map(e => e.utteranceId).filter((id): id is string => Boolean(id)))].sort();
|
||||
|
||||
return {
|
||||
speakerIds,
|
||||
modelNames,
|
||||
dialects,
|
||||
iterations,
|
||||
utteranceIds,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -131,6 +131,8 @@ export async function processDatasetEntries(
|
||||
externalId: row.id,
|
||||
speakerId: row.speaker,
|
||||
modelName: row.model,
|
||||
utteranceId: row.utt_id,
|
||||
utteranceText: row.text,
|
||||
fileName: relativePath,
|
||||
dialect: row.dialect,
|
||||
iteration: parseInt(row.iteration, 10),
|
||||
|
||||
@@ -87,6 +87,11 @@ export default async function DatasetEntryPage({ params }: DatasetEntryPageProps
|
||||
<p className="text-lg font-semibold">{entry.modelName}</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white border border-gray-200 p-4 rounded-lg">
|
||||
<p className="text-sm text-gray-600 mb-1">Utterance ID</p>
|
||||
<p className="text-lg font-semibold">{entry.utteranceId || '-'}</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white border border-gray-200 p-4 rounded-lg">
|
||||
<p className="text-sm text-gray-600 mb-1">Dialect</p>
|
||||
<p className="text-lg font-semibold">{entry.dialect}</p>
|
||||
@@ -102,6 +107,11 @@ export default async function DatasetEntryPage({ params }: DatasetEntryPageProps
|
||||
<p className="text-lg font-semibold break-all">{entry.fileName}</p>
|
||||
</div>
|
||||
|
||||
<div className="col-span-2 bg-white border border-gray-200 p-4 rounded-lg">
|
||||
<p className="text-sm text-gray-600 mb-1">Utterance Text</p>
|
||||
<p className="text-lg font-semibold break-words">{entry.utteranceText || '-'}</p>
|
||||
</div>
|
||||
|
||||
<div className="col-span-2 bg-white border border-gray-200 p-4 rounded-lg">
|
||||
<p className="text-sm text-gray-600 mb-3">Audio Player</p>
|
||||
<AudioPlayer datasetId={datasetIdNum} fileName={entry.fileName} externalId={entry.externalId} />
|
||||
|
||||
@@ -16,6 +16,8 @@ interface DatasetEntry {
|
||||
externalId: string;
|
||||
speakerId: string;
|
||||
modelName: string;
|
||||
utteranceId: string | null;
|
||||
utteranceText: string | null;
|
||||
fileName: string;
|
||||
dialect: string;
|
||||
iteration: number;
|
||||
@@ -28,6 +30,7 @@ interface FilterOptions {
|
||||
modelNames: string[];
|
||||
dialects: string[];
|
||||
iterations: number[];
|
||||
utteranceIds: string[];
|
||||
}
|
||||
|
||||
export default function DatasetEntriesList({
|
||||
@@ -45,6 +48,7 @@ export default function DatasetEntriesList({
|
||||
modelName: '',
|
||||
dialect: '',
|
||||
iteration: '',
|
||||
utteranceId: '',
|
||||
});
|
||||
|
||||
// Filter options
|
||||
@@ -53,6 +57,7 @@ export default function DatasetEntriesList({
|
||||
modelNames: [],
|
||||
dialects: [],
|
||||
iterations: [],
|
||||
utteranceIds: [],
|
||||
});
|
||||
|
||||
// Load filter options on mount
|
||||
@@ -81,6 +86,7 @@ export default function DatasetEntriesList({
|
||||
modelName: filters.modelName || undefined,
|
||||
dialect: filters.dialect || undefined,
|
||||
iteration: filters.iteration ? parseInt(filters.iteration, 10) : undefined,
|
||||
utteranceId: filters.utteranceId || undefined,
|
||||
};
|
||||
|
||||
const result = await getDatasetEntries(datasetId, pageNum, filterParams);
|
||||
@@ -107,6 +113,7 @@ export default function DatasetEntriesList({
|
||||
modelName: filters.modelName || undefined,
|
||||
dialect: filters.dialect || undefined,
|
||||
iteration: filters.iteration ? parseInt(filters.iteration, 10) : undefined,
|
||||
utteranceId: filters.utteranceId || undefined,
|
||||
};
|
||||
|
||||
const result = await getDatasetEntries(datasetId, page + 1, filterParams);
|
||||
@@ -134,6 +141,7 @@ export default function DatasetEntriesList({
|
||||
modelName: '',
|
||||
dialect: '',
|
||||
iteration: '',
|
||||
utteranceId: '',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -153,7 +161,7 @@ export default function DatasetEntriesList({
|
||||
Clear all
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Speaker ID
|
||||
@@ -222,6 +230,23 @@ export default function DatasetEntriesList({
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Utterance ID
|
||||
</label>
|
||||
<select
|
||||
value={filters.utteranceId}
|
||||
onChange={(e) => handleFilterChange('utteranceId', e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="">All utterance IDs</option>
|
||||
{filterOptions.utteranceIds.map((utt) => (
|
||||
<option key={utt} value={utt}>
|
||||
{utt}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -245,7 +270,7 @@ export default function DatasetEntriesList({
|
||||
Clear all
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Speaker ID
|
||||
@@ -314,6 +339,23 @@ export default function DatasetEntriesList({
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Utterance ID
|
||||
</label>
|
||||
<select
|
||||
value={filters.utteranceId}
|
||||
onChange={(e) => handleFilterChange('utteranceId', e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="">All utterance IDs</option>
|
||||
{filterOptions.utteranceIds.map((utt) => (
|
||||
<option key={utt} value={utt}>
|
||||
{utt}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -331,6 +373,8 @@ export default function DatasetEntriesList({
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">External ID</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Speaker ID</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Model Name</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Utterance ID</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Utterance Text</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Dialect</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">File Name</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Iteration</th>
|
||||
@@ -352,6 +396,8 @@ export default function DatasetEntriesList({
|
||||
</td>
|
||||
<td className="py-3 px-4">{entry.speakerId}</td>
|
||||
<td className="py-3 px-4">{entry.modelName}</td>
|
||||
<td className="py-3 px-4 truncate">{entry.utteranceId || '-'}</td>
|
||||
<td className="py-3 px-4 truncate">{entry.utteranceText || '-'}</td>
|
||||
<td className="py-3 px-4">{entry.dialect}</td>
|
||||
<td className="py-3 px-4 truncate">{entry.fileName}</td>
|
||||
<td className="py-3 px-4">{entry.iteration}</td>
|
||||
|
||||
@@ -7,6 +7,8 @@ export const dataset_entry = sqliteTable('dataset_entry', {
|
||||
externalId: text('external_id').notNull(),
|
||||
speakerId: text('speaker_id').notNull(),
|
||||
modelName: text('model_name').notNull(),
|
||||
utteranceId: text('utterance_id'),
|
||||
utteranceText: text('utterance_text'),
|
||||
datasetId: integer('dataset_id')
|
||||
.notNull()
|
||||
.references(() => dataset.id),
|
||||
|
||||
Reference in New Issue
Block a user