feat: Bild in Annotieren-View löschen (Eintrag + Datei aus Directus)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
29
app.py
29
app.py
@@ -1727,12 +1727,37 @@ def directus_db_pictures_design_options():
|
|||||||
return jsonify({"choices": choices})
|
return jsonify({"choices": choices})
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/directus/db-pictures/<pic_id>", methods=["PATCH"])
|
@app.route("/api/directus/db-pictures/<pic_id>", methods=["PATCH", "DELETE"])
|
||||||
def directus_db_picture_patch(pic_id):
|
def directus_db_picture(pic_id):
|
||||||
token = request.headers.get("Authorization", "")
|
token = request.headers.get("Authorization", "")
|
||||||
|
if request.method == "PATCH":
|
||||||
data, status = _directus("PATCH", f"/items/db_pictures/{pic_id}", token, body=request.get_json(force=True, silent=True))
|
data, status = _directus("PATCH", f"/items/db_pictures/{pic_id}", token, body=request.get_json(force=True, silent=True))
|
||||||
return jsonify(data), status
|
return jsonify(data), status
|
||||||
|
|
||||||
|
# DELETE: erst picture-Eintrag laden, dann Eintrag + Datei löschen
|
||||||
|
pic_data, pic_status = _directus("GET", f"/items/db_pictures/{pic_id}?fields=id,picture", token)
|
||||||
|
if pic_status != 200:
|
||||||
|
return jsonify({"error": "Bild nicht gefunden"}), 404
|
||||||
|
file_uuid = (pic_data.get("data") or {}).get("picture")
|
||||||
|
|
||||||
|
# db_picture-Eintrag löschen
|
||||||
|
_, del_status = _directus("DELETE", f"/items/db_pictures/{pic_id}", token)
|
||||||
|
if del_status not in (200, 204):
|
||||||
|
return jsonify({"error": f"Fehler beim Löschen des Eintrags (Status {del_status})"}), del_status
|
||||||
|
|
||||||
|
# Prüfen ob wirklich gelöscht
|
||||||
|
_, check_status = _directus("GET", f"/items/db_pictures/{pic_id}?fields=id", token)
|
||||||
|
if check_status == 200:
|
||||||
|
return jsonify({"error": "Eintrag konnte nicht gelöscht werden"}), 500
|
||||||
|
|
||||||
|
# Datei löschen (nur wenn vorhanden)
|
||||||
|
if file_uuid:
|
||||||
|
_, file_del_status = _directus("DELETE", f"/files/{file_uuid}", token)
|
||||||
|
if file_del_status not in (200, 204):
|
||||||
|
return jsonify({"error": f"Eintrag gelöscht, aber Datei konnte nicht gelöscht werden (Status {file_del_status})"}), 500
|
||||||
|
|
||||||
|
return jsonify({}), 204
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/directus/db-objects", methods=["GET", "POST"])
|
@app.route("/api/directus/db-objects", methods=["GET", "POST"])
|
||||||
def directus_db_objects():
|
def directus_db_objects():
|
||||||
|
|||||||
@@ -347,6 +347,17 @@ export async function getDbPictures(token: string, status = 'draft'): Promise<Db
|
|||||||
return data.data as DbPicture[]
|
return data.data as DbPicture[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function deleteDbPicture(pictureId: string, token: string): Promise<void> {
|
||||||
|
const res = await fetch(`/api/directus/db-pictures/${pictureId}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
if (!res.ok) {
|
||||||
|
const data = await res.json().catch(() => ({}))
|
||||||
|
throw new Error(data.error || 'Fehler beim Löschen des Bildes')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateDbPicture(pictureId: string, fields: Record<string, unknown>, token: string): Promise<void> {
|
export async function updateDbPicture(pictureId: string, fields: Record<string, unknown>, token: string): Promise<void> {
|
||||||
const res = await fetch(`/api/directus/db-pictures/${pictureId}`, {
|
const res = await fetch(`/api/directus/db-pictures/${pictureId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
getDbPictures,
|
getDbPictures,
|
||||||
updateDbPicture,
|
updateDbPicture,
|
||||||
updateDbPictureStatus,
|
updateDbPictureStatus,
|
||||||
|
deleteDbPicture,
|
||||||
getDbObjects,
|
getDbObjects,
|
||||||
createDbObject,
|
createDbObject,
|
||||||
updateDbObject,
|
updateDbObject,
|
||||||
@@ -60,6 +61,7 @@ export default function DrawIt() {
|
|||||||
const [hasSelection, setHasSelection] = useState(false)
|
const [hasSelection, setHasSelection] = useState(false)
|
||||||
const [saving, setSaving] = useState(false)
|
const [saving, setSaving] = useState(false)
|
||||||
const [finishing, setFinishing] = useState(false)
|
const [finishing, setFinishing] = useState(false)
|
||||||
|
const [deleting, setDeleting] = useState(false)
|
||||||
const [statusMsg, setStatusMsg] = useState('')
|
const [statusMsg, setStatusMsg] = useState('')
|
||||||
const [statusError, setStatusError] = useState(false)
|
const [statusError, setStatusError] = useState(false)
|
||||||
const [imageLoaded, setImageLoaded] = useState(false)
|
const [imageLoaded, setImageLoaded] = useState(false)
|
||||||
@@ -288,6 +290,24 @@ export default function DrawIt() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteCurrentPicture = async () => {
|
||||||
|
if (!token || !currentPicture) return
|
||||||
|
if (!window.confirm('Bild wirklich löschen? Der Eintrag und die Datei werden dauerhaft aus Directus entfernt.')) return
|
||||||
|
setDeleting(true)
|
||||||
|
try {
|
||||||
|
await deleteDbPicture(currentPicture.id, token)
|
||||||
|
const newList = pictureList.filter(p => p.id !== currentPicture.id)
|
||||||
|
setPictureList(newList)
|
||||||
|
const nextIndex = Math.min(currentIndex, newList.length - 1)
|
||||||
|
setCurrentIndex(nextIndex)
|
||||||
|
showStatus('Bild gelöscht.')
|
||||||
|
} catch (e) {
|
||||||
|
showStatus(e instanceof Error ? e.message : 'Fehler beim Löschen.', true)
|
||||||
|
} finally {
|
||||||
|
setDeleting(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const imageNav = (
|
const imageNav = (
|
||||||
<div className="image-nav">
|
<div className="image-nav">
|
||||||
<button className="btn-icon" onClick={() => setCurrentIndex(i => i - 1)} disabled={currentIndex <= 0}>
|
<button className="btn-icon" onClick={() => setCurrentIndex(i => i - 1)} disabled={currentIndex <= 0}>
|
||||||
@@ -301,6 +321,15 @@ export default function DrawIt() {
|
|||||||
<button className="btn-icon" onClick={() => setCurrentIndex(i => i + 1)} disabled={currentIndex >= pictureList.length - 1}>
|
<button className="btn-icon" onClick={() => setCurrentIndex(i => i + 1)} disabled={currentIndex >= pictureList.length - 1}>
|
||||||
<ChevronRightIcon />
|
<ChevronRightIcon />
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn-icon"
|
||||||
|
onClick={deleteCurrentPicture}
|
||||||
|
disabled={deleting || !currentPicture}
|
||||||
|
title="Bild löschen"
|
||||||
|
style={{ color: 'var(--error, #dc2626)', marginLeft: 8 }}
|
||||||
|
>
|
||||||
|
<TrashIcon />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user