"use client" // Upload and index: the browser sends the file to the files module (the kit's `uploadFile`), then // asks this module to index it (`knowledge.document.index`). The indexing itself is a worker job; // this form only ever waits on the request. import { type ProjectSlugs, uploadFile, useTransport } from "@conusai-kit/ui" import { type FormEvent, type ReactElement, useId, useState } from "react" import { INDEXABLE_CONTENT_TYPES, MAX_INDEX_BYTES } from "../contract/index.js" export interface IndexFormLabels { readonly heading: string readonly label: string readonly hint: string readonly submit: string readonly busy: string readonly done: string readonly failed: string } type State = { kind: "idle" } | { kind: "busy" } | { kind: "done" } | { kind: "failed"; detail: string } export function IndexForm({ slugs, collectionName, labels, }: { slugs: ProjectSlugs collectionName: string labels: IndexFormLabels }): ReactElement { const transport = useTransport() const { call, describe } = transport const inputId = useId() const hintId = useId() const [state, setState] = useState({ kind: "idle" }) const index = async (event: FormEvent): Promise => { event.preventDefault() const form = event.currentTarget const file = new FormData(form).get("file") if (!(file instanceof File) || file.size === 0) return setState({ kind: "busy" }) try { const stored = await uploadFile(transport, slugs, file) await call("knowledge.document.index", { ...slugs, collectionName, fileId: stored.fileId }) form.reset() setState({ kind: "done" }) window.location.reload() } catch (error) { setState({ kind: "failed", detail: describe(error) }) } } return (

{labels.heading}

void index(event)}>

{labels.hint} ยท {Math.round(MAX_INDEX_BYTES / 1024)} KB.

{state.kind === "done" ?

{labels.done}

: null} {state.kind === "failed" ?

{labels.failed.replace("{detail}", state.detail)}

: null}
) }