Optimierung KI-Scuhe + Ki-Überarbeitungen der Übungen #49
|
|
@ -75,6 +75,11 @@ export default function ExercisePickerModal({
|
||||||
|
|
||||||
const usePlanningSearch = Boolean(planningContext?.unitId && Number(planningContext.unitId) > 0)
|
const usePlanningSearch = Boolean(planningContext?.unitId && Number(planningContext.unitId) > 0)
|
||||||
|
|
||||||
|
const effectivePickerQuery = useMemo(
|
||||||
|
() => [debouncedSearch, debouncedAi].filter(Boolean).join(' ').trim(),
|
||||||
|
[debouncedSearch, debouncedAi]
|
||||||
|
)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
title: quickTitle,
|
title: quickTitle,
|
||||||
sketch: quickSketch,
|
sketch: quickSketch,
|
||||||
|
|
@ -83,7 +88,7 @@ export default function ExercisePickerModal({
|
||||||
setSketch: setQuickSketch,
|
setSketch: setQuickSketch,
|
||||||
setFocusAreaId: setQuickFocusAreaId,
|
setFocusAreaId: setQuickFocusAreaId,
|
||||||
resetQuickCreateFields,
|
resetQuickCreateFields,
|
||||||
} = useExerciseAiQuickCreateFields(debouncedSearch, { enabled: open && enableQuickCreateDraft })
|
} = useExerciseAiQuickCreateFields(effectivePickerQuery, { enabled: open && enableQuickCreateDraft })
|
||||||
|
|
||||||
const toggleMultiPick = (ex) => {
|
const toggleMultiPick = (ex) => {
|
||||||
setMultiPicked((prev) =>
|
setMultiPicked((prev) =>
|
||||||
|
|
@ -106,7 +111,7 @@ export default function ExercisePickerModal({
|
||||||
catalogsReady &&
|
catalogsReady &&
|
||||||
!loading &&
|
!loading &&
|
||||||
list.length === 0 &&
|
list.length === 0 &&
|
||||||
(usePlanningSearch || debouncedSearch.length >= 3)
|
(usePlanningSearch || effectivePickerQuery.length >= 3)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) return
|
if (!open) return
|
||||||
|
|
@ -246,6 +251,7 @@ export default function ExercisePickerModal({
|
||||||
if (filters.include_archived) q.include_archived = true
|
if (filters.include_archived) q.include_archived = true
|
||||||
if (debouncedSearch) q.search = debouncedSearch
|
if (debouncedSearch) q.search = debouncedSearch
|
||||||
if (debouncedAi) q.ai_search = debouncedAi
|
if (debouncedAi) q.ai_search = debouncedAi
|
||||||
|
if (!debouncedSearch && debouncedAi) q.search = debouncedAi
|
||||||
if (
|
if (
|
||||||
Array.isArray(exerciseKindAny) &&
|
Array.isArray(exerciseKindAny) &&
|
||||||
exerciseKindAny.length > 0
|
exerciseKindAny.length > 0
|
||||||
|
|
@ -260,7 +266,7 @@ export default function ExercisePickerModal({
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
if (usePlanningSearch) {
|
if (usePlanningSearch) {
|
||||||
const query = [debouncedSearch, debouncedAi].filter(Boolean).join(' ').trim()
|
const query = effectivePickerQuery
|
||||||
const res = await api.suggestPlanningExercises({
|
const res = await api.suggestPlanningExercises({
|
||||||
unit_id: Number(planningContext.unitId),
|
unit_id: Number(planningContext.unitId),
|
||||||
section_order_index:
|
section_order_index:
|
||||||
|
|
@ -338,6 +344,7 @@ export default function ExercisePickerModal({
|
||||||
queryBase,
|
queryBase,
|
||||||
usePlanningSearch,
|
usePlanningSearch,
|
||||||
planningContext,
|
planningContext,
|
||||||
|
effectivePickerQuery,
|
||||||
debouncedSearch,
|
debouncedSearch,
|
||||||
debouncedAi,
|
debouncedAi,
|
||||||
exerciseKindAny,
|
exerciseKindAny,
|
||||||
|
|
@ -571,14 +578,14 @@ export default function ExercisePickerModal({
|
||||||
<div style={{ display: 'grid', gap: '0.65rem' }}>
|
<div style={{ display: 'grid', gap: '0.65rem' }}>
|
||||||
<div>
|
<div>
|
||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
{usePlanningSearch ? 'Planungs-Suche' : 'Volltextsuche'}
|
{usePlanningSearch ? 'Planungs-Anfrage' : 'Volltextsuche'}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
className="form-input"
|
className="form-input"
|
||||||
placeholder={
|
placeholder={
|
||||||
usePlanningSearch
|
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…'
|
: 'Stichwort, Titelfragment…'
|
||||||
}
|
}
|
||||||
value={searchInput}
|
value={searchInput}
|
||||||
|
|
@ -588,17 +595,30 @@ export default function ExercisePickerModal({
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
Semantisch /{' '}
|
{usePlanningSearch ? 'Planungs-Anfrage (Zusatz, optional)' : 'Semantisch / '}
|
||||||
<span title="aktuell gleiche Datenbanksuche wie Volltext; später KI-Verfeinerung möglich">KI-Feld</span>
|
{!usePlanningSearch ? (
|
||||||
|
<span title="aktuell gleiche Datenbanksuche wie Volltext; später KI-Verfeinerung möglich">
|
||||||
|
KI-Feld
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
className="form-input"
|
className="form-input"
|
||||||
placeholder="zweites Suchkonzept oder Umschreibung…"
|
placeholder={
|
||||||
|
usePlanningSearch
|
||||||
|
? 'Alternative Formulierung — wird mit oben kombiniert'
|
||||||
|
: 'zweites Suchkonzept oder Umschreibung…'
|
||||||
|
}
|
||||||
value={aiSearchInput}
|
value={aiSearchInput}
|
||||||
onChange={(e) => setAiSearchInput(e.target.value)}
|
onChange={(e) => setAiSearchInput(e.target.value)}
|
||||||
autoComplete="off"
|
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>
|
||||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center' }}>
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center' }}>
|
||||||
<button type="button" className="btn btn-secondary" onClick={() => setFilterOpen(!filterOpen)}>
|
<button type="button" className="btn btn-secondary" onClick={() => setFilterOpen(!filterOpen)}>
|
||||||
|
|
@ -755,7 +775,7 @@ export default function ExercisePickerModal({
|
||||||
) : list.length === 0 ? (
|
) : list.length === 0 ? (
|
||||||
showQuickCreateOffer ? (
|
showQuickCreateOffer ? (
|
||||||
<ExerciseAiQuickCreateOffer
|
<ExerciseAiQuickCreateOffer
|
||||||
searchLabel={debouncedSearch}
|
searchLabel={effectivePickerQuery}
|
||||||
title={quickTitle}
|
title={quickTitle}
|
||||||
onTitleChange={setQuickTitle}
|
onTitleChange={setQuickTitle}
|
||||||
sketch={quickSketch}
|
sketch={quickSketch}
|
||||||
|
|
@ -770,9 +790,13 @@ export default function ExercisePickerModal({
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<p style={{ color: 'var(--text2)', textAlign: 'center' }}>
|
<p style={{ color: 'var(--text2)', textAlign: 'center' }}>
|
||||||
{debouncedSearch.length >= 3
|
{usePlanningSearch
|
||||||
? 'Keine Treffer.'
|
? effectivePickerQuery
|
||||||
: 'Suchbegriff eingeben (mind. 3 Zeichen) …'}
|
? '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>
|
</p>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user