bug_fix Variantenerzeugung
All checks were successful
Deploy Development / deploy (push) Successful in 39s
Test Suite / pytest-backend (push) Successful in 37s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m35s
Test Suite / pytest-backend (pull_request) Successful in 36s
Test Suite / lint-backend (pull_request) Successful in 0s
Test Suite / build-frontend (pull_request) Successful in 13s
Test Suite / k6 /health Baseline (pull_request) Successful in 33s
Test Suite / playwright-tests (pull_request) Successful in 1m22s

This commit is contained in:
Lars 2026-05-22 07:14:03 +02:00
parent 5f67c01cef
commit 7245bbb1da

View File

@ -863,6 +863,33 @@ function ExerciseFormPageRoot() {
setVariants(rows)
}, [exerciseId, syncVariantsSavedSnapshot])
const createVariantFromDraft = useCallback(
async ({ showSuccessToast = false } = {}) => {
if (!exerciseId) return false
if (!variantDraftHasContent(variantDraft)) return true
const payload = buildVariantPayloadFromRow(variantDraft)
if (payload.variant_name.length < 3) {
toast.error('Variantenname mindestens 3 Zeichen')
return false
}
setVariantBusy(true)
try {
const created = await api.createExerciseVariant(exerciseId, payload)
setVariantDraft(emptyVariantDraft())
if (created?.id != null) setVariantEditSelection(created.id)
await refreshVariants()
if (showSuccessToast) toast.success('Variante angelegt.')
return true
} catch (e) {
toast.error(e.message || String(e))
return false
} finally {
setVariantBusy(false)
}
},
[exerciseId, variantDraft, refreshVariants, toast],
)
const persistPendingVariantChanges = useCallback(async () => {
if (!exerciseId) return true
@ -889,28 +916,9 @@ function ExerciseFormPageRoot() {
}
}
if (variantDraftHasContent(variantDraft)) {
const payload = buildVariantPayloadFromRow(variantDraft)
if (payload.variant_name.length < 3) {
toast.error('Variantenentwurf: Name mindestens 3 Zeichen, sonst Felder verwerfen oder ausfüllen.')
return false
}
setVariantBusy(true)
try {
const created = await api.createExerciseVariant(exerciseId, payload)
setVariantDraft(emptyVariantDraft())
if (created?.id != null) setVariantEditSelection(created.id)
await refreshVariants()
} catch (e) {
toast.error(e.message || String(e))
return false
} finally {
setVariantBusy(false)
}
}
return true
}, [exerciseId, variantDraft, variants, getDirtyVariantRows, refreshVariants, toast])
const draftOk = await createVariantFromDraft()
return draftOk
}, [exerciseId, variants, getDirtyVariantRows, refreshVariants, toast, createVariantFromDraft])
const performSaveAttempt = useCallback(
async ({ fromUnsavedDialog = false, closeAfter = false } = {}) => {
@ -1227,27 +1235,9 @@ function ExerciseFormPageRoot() {
}
}
const createVariantSubmit = async (e) => {
e.preventDefault()
if (!exerciseId) return
const payload = buildVariantPayloadFromRow(variantDraft)
if (payload.variant_name.length < 3) {
toast.error('Variantenname mindestens 3 Zeichen')
return
}
setVariantBusy(true)
try {
const created = await api.createExerciseVariant(exerciseId, payload)
setVariantDraft(emptyVariantDraft())
await refreshVariants()
if (created?.id != null) setVariantEditSelection(created.id)
else setVariantEditSelection(null)
} catch (err) {
toast.error(err.message || String(err))
} finally {
setVariantBusy(false)
}
}
const handleCreateVariantClick = useCallback(async () => {
await createVariantFromDraft({ showSuccessToast: true })
}, [createVariantFromDraft])
const selectedVariantForEdit =
typeof variantEditSelection === 'number' ? variants.find((v) => v.id === variantEditSelection) : null
@ -2085,9 +2075,8 @@ function ExerciseFormPageRoot() {
)}
{variantEditSelection === 'new' && (
<form
<div
className="exercise-variant-single-form"
onSubmit={createVariantSubmit}
style={{ marginTop: '14px', paddingTop: '14px', borderTop: '1px solid var(--border)' }}
>
<h3 style={{ marginTop: 0, fontSize: '1rem' }}>Neue Variante</h3>
@ -2103,10 +2092,19 @@ function ExerciseFormPageRoot() {
linkedExerciseMedia={isEdit ? mediaList : []}
onExerciseMediaListChanged={refreshMedia}
/>
<button type="submit" className="btn btn-primary" style={{ marginTop: '10px' }} disabled={variantBusy}>
<button
type="button"
className="btn btn-primary"
style={{ marginTop: '10px' }}
disabled={variantBusy}
onClick={handleCreateVariantClick}
>
{variantBusy ? 'Anlegen…' : 'Variante anlegen'}
</button>
</form>
<p className="exercise-form-panel__hint" style={{ marginTop: '8px', marginBottom: 0 }}>
Alternativ reicht Speichern in der Aktionsleiste der Entwurf wird dann mitgesichert.
</p>
</div>
)}
{selectedVariantForEdit && (