79 lines
3.1 KiB
TypeScript
79 lines
3.1 KiB
TypeScript
import { PanelFrame } from "./PanelFrame";
|
||
import type { QueryState } from "../state/types";
|
||
|
||
interface QueryPanelProps {
|
||
value: QueryState;
|
||
onChange: (next: QueryState) => void;
|
||
onApplyBatchFormat: () => void;
|
||
onNormalize: (saveCase: boolean) => Promise<void> | void;
|
||
busy: boolean;
|
||
useMock: boolean;
|
||
onUseMockChange: (next: boolean) => void;
|
||
errorMessage: string;
|
||
}
|
||
|
||
export function QueryPanel({
|
||
value,
|
||
onChange,
|
||
onApplyBatchFormat,
|
||
onNormalize,
|
||
busy,
|
||
useMock,
|
||
onUseMockChange,
|
||
errorMessage
|
||
}: QueryPanelProps) {
|
||
return (
|
||
<PanelFrame title="Запрос пользователя" subtitle="NDC semantic front-end: нормализуем, но не отвечаем за бухгалтерскую суть.">
|
||
<div className="grid-two">
|
||
<label className="full-width">
|
||
Raw user question
|
||
<textarea
|
||
value={value.userQuestion}
|
||
onChange={(event) => onChange({ ...value, userQuestion: event.target.value })}
|
||
rows={6}
|
||
placeholder="Например: По каким покупателям у нас на конец июня висят отгрузки без оплаты..."
|
||
/>
|
||
</label>
|
||
<label className="full-width">
|
||
Batch queries (`;` separator)
|
||
<textarea
|
||
value={value.batchQuestionsRaw}
|
||
onChange={(event) => onChange({ ...value, batchQuestionsRaw: event.target.value })}
|
||
onBlur={() => onApplyBatchFormat()}
|
||
rows={8}
|
||
placeholder="Вопрос 1; Вопрос 2; Вопрос 3"
|
||
/>
|
||
</label>
|
||
<label>
|
||
Optional period context
|
||
<input value={value.periodHint} onChange={(event) => onChange({ ...value, periodHint: event.target.value })} />
|
||
</label>
|
||
<label>
|
||
Optional business context
|
||
<input value={value.businessContext} onChange={(event) => onChange({ ...value, businessContext: event.target.value })} />
|
||
</label>
|
||
<label>
|
||
Optional expected route (eval)
|
||
<input value={value.expectedRoute} onChange={(event) => onChange({ ...value, expectedRoute: event.target.value })} />
|
||
</label>
|
||
</div>
|
||
<div className="button-row">
|
||
<label className="checkbox-row">
|
||
<input type="checkbox" checked={useMock} onChange={(event) => onUseMockChange(event.target.checked)} />
|
||
Mock-режим (без вызова OpenAI)
|
||
</label>
|
||
<button type="button" onClick={() => onApplyBatchFormat()} disabled={busy || !value.batchQuestionsRaw.trim()}>
|
||
Применить `;` в переносы
|
||
</button>
|
||
<button type="button" onClick={() => onNormalize(false)} disabled={busy || !value.userQuestion.trim()}>
|
||
{busy ? "Нормализуем..." : "Normalize"}
|
||
</button>
|
||
<button type="button" onClick={() => onNormalize(true)} disabled={busy || !value.userQuestion.trim()}>
|
||
{busy ? "Сохраняем..." : "Normalize + Save as test case"}
|
||
</button>
|
||
</div>
|
||
{errorMessage ? <p className="error-text">{errorMessage}</p> : null}
|
||
</PanelFrame>
|
||
);
|
||
}
|