Files
NODEDC_1C/llm_normalizer/frontend/src/components/QueryPanel.tsx
T
2026-03-26 10:38:25 +03:00

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>
);
}