Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .context/app/questionnaire/ingestion.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Questionnaire — document ingestion

> How an uploaded document becomes a populated questionnaire graph. Built by
> **F1.1** ([`../planning/features/f1.1.md`](../planning/features/f1.1.md));
> **API-only** — the review/edit UI is P2. Every surface here is gated by
> `APP_QUESTIONNAIRES_ENABLED` (seeded off).
> **F1.1** ([`../planning/features/f1.1.md`](../planning/features/f1.1.md)); the
> review/edit UI is P2. Admins drive ingestion from the `UploadQuestionnaireDialog`
> on `/admin/questionnaires` (header button + empty-state CTA), which POSTs to the
> endpoint below. Every surface here is gated by `APP_QUESTIONNAIRES_ENABLED`
> (seeded off).

## The endpoint

Expand Down
48 changes: 26 additions & 22 deletions app/admin/questionnaires/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Metadata } from 'next';
import { notFound } from 'next/navigation';

import { QuestionnairesTable } from '@/components/admin/questionnaires/questionnaires-table';
import { UploadQuestionnaireDialog } from '@/components/admin/questionnaires/upload-questionnaire-dialog';
import { FieldHelp } from '@/components/ui/field-help';
import { API } from '@/lib/api/endpoints';
import { parseApiResponse, serverFetch } from '@/lib/api/server-fetch';
Expand Down Expand Up @@ -51,28 +52,31 @@ export default async function QuestionnairesListPage() {

return (
<div className="space-y-6">
<header className="bg-background sticky top-0 z-30 -mx-6 border-b px-6 pt-3 pb-3">
<h1 className="text-2xl font-semibold">
Questionnaires{' '}
<FieldHelp
title="What are questionnaires?"
contentClassName="w-96 max-h-80 overflow-y-auto"
>
<p>
A questionnaire is a structured set of sections and questions an end user completes
through a streaming conversation rather than a form. An admin ingests a source
document (PDF / DOCX / MD / TXT) and an agent extracts its structure.
</p>
<p className="text-foreground mt-2 font-medium">This page</p>
<p>
Browse every ingested questionnaire with its latest version and structure counts.
Click a row to view its versions and full section / question graph.
</p>
</FieldHelp>
</h1>
<p className="text-muted-foreground text-sm">
Ingest, review, and edit conversational questionnaires.
</p>
<header className="bg-background sticky top-0 z-30 -mx-6 flex items-start justify-between gap-4 border-b px-6 pt-3 pb-3">
<div>
<h1 className="text-2xl font-semibold">
Questionnaires{' '}
<FieldHelp
title="What are questionnaires?"
contentClassName="w-96 max-h-80 overflow-y-auto"
>
<p>
A questionnaire is a structured set of sections and questions an end user completes
through a streaming conversation rather than a form. An admin ingests a source
document (PDF / DOCX / MD / TXT) and an agent extracts its structure.
</p>
<p className="text-foreground mt-2 font-medium">This page</p>
<p>
Browse every ingested questionnaire with its latest version and structure counts.
Click a row to view its versions and full section / question graph.
</p>
</FieldHelp>
</h1>
<p className="text-muted-foreground text-sm">
Ingest, review, and edit conversational questionnaires.
</p>
</div>
<UploadQuestionnaireDialog />
</header>

<QuestionnairesTable initialItems={items} initialMeta={meta} />
Expand Down
15 changes: 10 additions & 5 deletions components/admin/questionnaires/questionnaires-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* Read-only admin list of questionnaires. Modelled on the orchestration
* `AgentsTable` but deliberately lean for the read-surface PR: debounced title
* search, a status filter, prev/next pagination, and click-through to the detail
* page. No mutations — create is the existing ingestion endpoint (no UI yet) and
* edit affordances land in F2.1b (PR2).
* page. Create is the ingestion endpoint, driven by the `UploadQuestionnaireDialog`
* (header button + empty-state CTA); edit affordances live on the detail page.
*
* Hydrates from server-fetched `initialItems` / `initialMeta`, then re-fetches
* `GET /api/v1/app/questionnaires` on filter/page changes. Fetch failures keep
Expand All @@ -18,6 +18,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { ChevronLeft, ChevronRight, Loader2, Search } from 'lucide-react';

import { UploadQuestionnaireDialog } from '@/components/admin/questionnaires/upload-questionnaire-dialog';
import { Badge } from '@/components/ui/badge';
import { Input } from '@/components/ui/input';
import {
Expand Down Expand Up @@ -183,9 +184,13 @@ export function QuestionnairesTable({ initialItems, initialMeta }: Questionnaire
<TableBody>
{items.length === 0 ? (
<TableRow>
<TableCell colSpan={6} className="text-muted-foreground py-10 text-center">
No questionnaires yet. Ingest a document via{' '}
<code className="text-xs">POST /api/v1/app/questionnaires</code> to create one.
<TableCell colSpan={6} className="py-10 text-center">
<div className="flex flex-col items-center gap-3">
<p className="text-muted-foreground">
No questionnaires yet. Upload a document to create your first one.
</p>
<UploadQuestionnaireDialog />
</div>
</TableCell>
</TableRow>
) : (
Expand Down
Loading