Optimierung KI-Scuhe + Ki-Überarbeitungen der Übungen #49

Merged
Lars merged 16 commits from develop into main 2026-05-23 07:54:21 +02:00
Showing only changes of commit 905bce198f - Show all commits

View File

@ -75,6 +75,11 @@ export default function ExercisePickerModal({
const usePlanningSearch = Boolean(planningContext?.unitId && Number(planningContext.unitId) > 0)
const effectivePickerQuery = useMemo(
() => [debouncedSearch, debouncedAi].filter(Boolean).join(' ').trim(),
[debouncedSearch, debouncedAi]
)
const {
title: quickTitle,
sketch: quickSketch,
@ -83,7 +88,7 @@ export default function ExercisePickerModal({
setSketch: setQuickSketch,
setFocusAreaId: setQuickFocusAreaId,
resetQuickCreateFields,
} = useExerciseAiQuickCreateFields(debouncedSearch, { enabled: open && enableQuickCreateDraft })
} = useExerciseAiQuickCreateFields(effectivePickerQuery, { enabled: open && enableQuickCreateDraft })
const toggleMultiPick = (ex) => {
setMultiPicked((prev) =>
@ -106,7 +111,7 @@ export default function ExercisePickerModal({
catalogsReady &&
!loading &&
list.length === 0 &&
(usePlanningSearch || debouncedSearch.length >= 3)
(usePlanningSearch || effectivePickerQuery.length >= 3)
useEffect(() => {
if (!open) return
@ -246,6 +251,7 @@ export default function ExercisePickerModal({
if (filters.include_archived) q.include_archived = true
if (debouncedSearch) q.search = debouncedSearch
if (debouncedAi) q.ai_search = debouncedAi
if (!debouncedSearch && debouncedAi) q.search = debouncedAi
if (
Array.isArray(exerciseKindAny) &&
exerciseKindAny.length > 0
@ -260,7 +266,7 @@ export default function ExercisePickerModal({
setLoading(true)
try {
if (usePlanningSearch) {
const query = [debouncedSearch, debouncedAi].filter(Boolean).join(' ').trim()
const query = effectivePickerQuery
const res = await api.suggestPlanningExercises({
unit_id: Number(planningContext.unitId),
section_order_index:
@ -338,6 +344,7 @@ export default function ExercisePickerModal({
queryBase,
usePlanningSearch,
planningContext,
effectivePickerQuery,
debouncedSearch,
debouncedAi,
exerciseKindAny,
@ -571,14 +578,14 @@ export default function ExercisePickerModal({
<div style={{ display: 'grid', gap: '0.65rem' }}>
<div>
<label className="form-label">
{usePlanningSearch ? 'Planungs-Suche' : 'Volltextsuche'}
{usePlanningSearch ? 'Planungs-Anfrage' : 'Volltextsuche'}
</label>
<input
type="search"
className="form-input"
placeholder={
usePlanningSearch
? 'z. B. nächste Übung, Vertiefung, Reaktion mit Partner …'
? 'z. B. Schlage mir die nächste Übung vor, Vertiefung, Reaktion mit Partner …'
: 'Stichwort, Titelfragment…'
}
value={searchInput}
@ -588,17 +595,30 @@ export default function ExercisePickerModal({
</div>
<div>
<label className="form-label">
Semantisch /{' '}
<span title="aktuell gleiche Datenbanksuche wie Volltext; später KI-Verfeinerung möglich">KI-Feld</span>
{usePlanningSearch ? 'Planungs-Anfrage (Zusatz, optional)' : 'Semantisch / '}
{!usePlanningSearch ? (
<span title="aktuell gleiche Datenbanksuche wie Volltext; später KI-Verfeinerung möglich">
KI-Feld
</span>
) : null}
</label>
<input
type="search"
className="form-input"
placeholder="zweites Suchkonzept oder Umschreibung…"
placeholder={
usePlanningSearch
? 'Alternative Formulierung — wird mit oben kombiniert'
: 'zweites Suchkonzept oder Umschreibung…'
}
value={aiSearchInput}
onChange={(e) => setAiSearchInput(e.target.value)}
autoComplete="off"
/>
{usePlanningSearch ? (
<p style={{ margin: '4px 0 0', fontSize: '11px', color: 'var(--text3)' }}>
Beide Felder bilden eine gemeinsame Planungs-Anfrage.
</p>
) : null}
</div>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center' }}>
<button type="button" className="btn btn-secondary" onClick={() => setFilterOpen(!filterOpen)}>
@ -755,7 +775,7 @@ export default function ExercisePickerModal({
) : list.length === 0 ? (
showQuickCreateOffer ? (
<ExerciseAiQuickCreateOffer
searchLabel={debouncedSearch}
searchLabel={effectivePickerQuery}
title={quickTitle}
onTitleChange={setQuickTitle}
sketch={quickSketch}
@ -770,9 +790,13 @@ export default function ExercisePickerModal({
/>
) : (
<p style={{ color: 'var(--text2)', textAlign: 'center' }}>
{debouncedSearch.length >= 3
? 'Keine Treffer.'
: 'Suchbegriff eingeben (mind. 3 Zeichen) …'}
{usePlanningSearch
? effectivePickerQuery
? 'Keine KI-Vorschläge für diese Anfrage.'
: 'Keine Vorschläge — Einheit speichern und Planungskontext prüfen, oder Anfrage eingeben.'
: effectivePickerQuery.length >= 3
? 'Keine Treffer.'
: 'Suchbegriff eingeben (mind. 3 Zeichen) …'}
</p>
)
) : (