diff --git a/app.py b/app.py index 7311e24..347d6e8 100644 --- a/app.py +++ b/app.py @@ -1877,6 +1877,88 @@ def directus_db_object_pairs(obj_id): return jsonify({"ok": True, "pair_id": pair_id, "statement_id": stmt_id, "question_id": q_id}) +@app.route("/api/directus/db-pairs/", methods=["PATCH", "DELETE"]) +def directus_db_pair(pair_id): + """PATCH: level + question/statement inline aktualisieren. + DELETE: Pair + alle verknüpften Junctions + Question + Statement entfernen.""" + token = request.headers.get("Authorization", "") + + if request.method == "PATCH": + body = request.get_json(force=True, silent=True) or {} + + # Pair-Level updaten + if "level" in body: + _directus("PATCH", f"/items/db_pairs/{pair_id}", token, {"level": body["level"]}) + + # Statement updaten (nur erstes verknüpftes) + if "statement_de" in body: + s_junc, _ = _directus("GET", + f"/items/db_pairs_db_statement?filter[db_pairs_id][_eq]={pair_id}&fields=db_statement_id&limit=1", token) + for e in (s_junc.get("data") or []): + sid = e.get("db_statement_id") + if sid: + _directus("PATCH", f"/items/db_statement/{sid}", token, + {"statement_de": body["statement_de"], "level": body.get("level", 50)}) + + # Question updaten/anlegen + if "question_de" in body: + question_de = (body["question_de"] or "").strip() + q_junc, _ = _directus("GET", + f"/items/db_pairs_db_question?filter[db_pairs_id][_eq]={pair_id}&fields=db_question_id&limit=1", token) + existing_q = (q_junc.get("data") or []) + if existing_q: + qid = existing_q[0].get("db_question_id") + if question_de: + _directus("PATCH", f"/items/db_question/{qid}", token, + {"question_de": question_de, "level": body.get("level", 50)}) + else: + # Frage gelöscht → Junction + Item entfernen + _directus("DELETE", f"/items/db_pairs_db_question", token, + [e["id"] for e in existing_q if e.get("id")]) + _directus("DELETE", f"/items/db_question/{qid}", token) + elif question_de: + # Neue Frage anlegen und verknüpfen + q_resp, s = _directus("POST", "/items/db_question", token, + {"status": "draft", "question_de": question_de, + "level": body.get("level", 50)}) + if s in (200, 201): + qid = q_resp["data"]["id"] + _directus("POST", "/items/db_pairs_db_question", token, + {"db_pairs_id": pair_id, "db_question_id": qid}) + + return jsonify({"ok": True}) + + else: # DELETE + # Junction zu Objekten entfernen + obj_junc, _ = _directus("GET", + f"/items/db_objects_db_pairs?filter[db_pairs_id][_eq]={pair_id}&fields=id&limit=100", token) + obj_junc_ids = [e["id"] for e in (obj_junc.get("data") or []) if e.get("id")] + if obj_junc_ids: + _directus("DELETE", "/items/db_objects_db_pairs", token, obj_junc_ids) + + # Questions löschen + q_junc, _ = _directus("GET", + f"/items/db_pairs_db_question?filter[db_pairs_id][_eq]={pair_id}&fields=id,db_question_id&limit=100", token) + for e in (q_junc.get("data") or []): + if e.get("id"): + _directus("DELETE", f"/items/db_pairs_db_question/{e['id']}", token) + if e.get("db_question_id"): + _directus("DELETE", f"/items/db_question/{e['db_question_id']}", token) + + # Statements löschen + s_junc, _ = _directus("GET", + f"/items/db_pairs_db_statement?filter[db_pairs_id][_eq]={pair_id}&fields=id,db_statement_id&limit=100", token) + for e in (s_junc.get("data") or []): + if e.get("id"): + _directus("DELETE", f"/items/db_pairs_db_statement/{e['id']}", token) + if e.get("db_statement_id"): + _directus("DELETE", f"/items/db_statement/{e['db_statement_id']}", token) + + # Pair selbst löschen + _, s = _directus("DELETE", f"/items/db_pairs/{pair_id}", token) + return jsonify({"ok": s in (200, 204)}) + + if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, debug=True) diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 8a8b68e..89e1a4b 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -453,3 +453,24 @@ export async function createDbPair( if (!res.ok) throw new Error(data.error || 'Fehler beim Erstellen des Pairs') return data } + +export async function updateDbPair( + pairId: string, + payload: { level?: number; question_de?: string; statement_de?: string }, + token: string +): Promise { + const res = await fetch(`/api/directus/db-pairs/${pairId}`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, + body: JSON.stringify(payload), + }) + if (!res.ok) throw new Error('Fehler beim Aktualisieren des Pairs') +} + +export async function deleteDbPair(pairId: string, token: string): Promise { + const res = await fetch(`/api/directus/db-pairs/${pairId}`, { + method: 'DELETE', + headers: { Authorization: `Bearer ${token}` }, + }) + if (!res.ok) throw new Error('Fehler beim Löschen des Pairs') +} diff --git a/frontend/src/pages/GenerateIt.tsx b/frontend/src/pages/GenerateIt.tsx index c4ecdf1..a7cd0ff 100644 --- a/frontend/src/pages/GenerateIt.tsx +++ b/frontend/src/pages/GenerateIt.tsx @@ -7,6 +7,8 @@ import { getDbObjects, getDbObjectPairs, createDbPair, + updateDbPair, + deleteDbPair, directusAssetUrl, } from '../api' import { useAuth } from '../context/AuthContext' @@ -207,14 +209,44 @@ interface PairsListProps { function PairsList({ pairs, loading, objectId, token, onRefresh }: PairsListProps) { const [showForm, setShowForm] = useState(false) + const [editingId, setEditingId] = useState(null) + const [editLevel, setEditLevel] = useState(50) + const [editQuestion, setEditQuestion] = useState('') + const [editStatement, setEditStatement] = useState('') + const [saving, setSaving] = useState(false) - const handleSaved = () => { - setShowForm(false) + const startEdit = (pair: DbPair) => { + setEditingId(pair.id) + setEditLevel(pair.level) + setEditStatement(pair.statements[0]?.statement_de ?? '') + setEditQuestion(pair.questions[0]?.question_de ?? '') + } + + const saveEdit = async () => { + if (!editingId) return + setSaving(true) + try { + await updateDbPair(editingId, { + level: editLevel, + statement_de: editStatement, + question_de: editQuestion, + }, token) + setEditingId(null) + onRefresh() + } finally { + setSaving(false) + } + } + + const handleDelete = async (pairId: string) => { + if (!confirm('Pair wirklich löschen?')) return + await deleteDbPair(pairId, token) onRefresh() } - if (loading) return
Lade…
+ const handleSaved = () => { setShowForm(false); onRefresh() } + if (loading) return
Lade…
if (!objectId) return
Kein Objekt gewählt.
return ( @@ -228,31 +260,65 @@ function PairsList({ pairs, loading, objectId, token, onRefresh }: PairsListProp {pairs.map(pair => (
- {/* Level badge */} -
- L{pair.level} - {pair.status} -
- - {/* Statements */} - {pair.statements.map(s => ( -
- Aussage: - {s.statement_de} + {editingId === pair.id ? ( + /* ── Inline-Edit-Formular ── */ +
+
+ + setEditLevel(Number(e.target.value))} + style={{ flex: 1 }} /> +
+