diff --git a/truthinquiry/routes/routes_admin.py b/truthinquiry/routes/routes_admin.py index a4d23b7..2044499 100644 --- a/truthinquiry/routes/routes_admin.py +++ b/truthinquiry/routes/routes_admin.py @@ -35,11 +35,27 @@ def npc(npc_id): answer_list = [answer.TEXT for answer in answer_type.TEXT_LOCALE.TEXTS] npc_answers.append(answer_list) + reactions = [{ + "id": reaction.TRAIT.TRAIT_ID, + "name": reaction.TRAIT.NAME_LOCALE.get_text(DEFAULT_LANG).TEXT, + "url": "/api/v1/getReaction?uuid="+reaction.REACTION_UUID + } for reaction in npc_obj.REACTIONS] + + reactions_to_add = [] + for trait in db.session.query(Trait).all(): + if trait.TRAIT_ID not in [reaction.TRAIT.TRAIT_ID for reaction in npc_obj.REACTIONS]: + reactions_to_add.append({ + "id": trait.TRAIT_ID, + "name": trait.NAME_LOCALE.get_text(DEFAULT_LANG).TEXT + }) + npc_dict = { "id": npc_obj.NPC_ID, "name": npc_obj.NAME_LOCALE.get_text(DEFAULT_LANG).TEXT, "img": npc_obj.NPC_ID, "answers": npc_answers, + "reactions": reactions, + "reactions_to_add": reactions_to_add, } return flask.render_template("admin/npc.html", npc=npc_dict) diff --git a/truthinquiry/routes/routes_api_admin.py b/truthinquiry/routes/routes_api_admin.py index 09ad261..b267825 100644 --- a/truthinquiry/routes/routes_api_admin.py +++ b/truthinquiry/routes/routes_api_admin.py @@ -1,7 +1,7 @@ import os import flask -from sqlalchemy import select, delete, or_ +from sqlalchemy import select, delete, and_ from truthinquiry.ext.database.models import * from truthinquiry.ext.database.fsa import db @@ -176,3 +176,36 @@ def delete_npc(): db.session.execute(delete(Npc).where(Npc.NPC_ID==input_npc_id)) db.session.commit() return {} + +@routes_api_admin.route("/setReaction", methods=["GET", "POST"]) +@require_admin(api=True) +def setReaction(): + input_npc_id = flask.request.values["npc_id"] + input_trait_id = flask.request.values["trait_id"] + + row = db.session.execute( + select(Reaction) + .where(and_( + Reaction.NPC_ID==input_npc_id, + Reaction.TRAIT_ID==input_trait_id + )) + ).first() + + reaction = None if row == None else row[0] + + + if len(flask.request.files) == 0: # want to delete + if reaction: + db.session.delete(reaction) + else: + return {"msg": "No such reaction"} # Not an error because this can be intentional + else: + input_reaction_file = flask.request.files['file'] + if not reaction: + reaction = Reaction(None, input_npc_id, input_trait_id) + db.session.add(reaction) + reaction.IMG = input_reaction_file.read() + + db.session.commit() + + return {} diff --git a/truthinquiry/static/js/admin_npc.js b/truthinquiry/static/js/admin_npc.js index 0b345d0..b495208 100644 --- a/truthinquiry/static/js/admin_npc.js +++ b/truthinquiry/static/js/admin_npc.js @@ -1,4 +1,7 @@ -function createOrUpdateNpc() { + +const reactionsDelta = {} + +async function createOrUpdateNpc() { const data = {}; data["id"] = document.querySelector("#npc_id").value; data["name"] = document.querySelector("#npc_name").value; @@ -16,9 +19,36 @@ function createOrUpdateNpc() { }); } - makeAPIRequest("admin/setNpc", {"npc": data, "lang": "FR"}, {"content": "json"}).then(() => { - alert("Opération effectuée avec succès"); - }); + await makeAPIRequest("admin/setNpc", {"npc": data, "lang": "FR"}, {"content": "json"}); + + await uploadReactionsDelta(); + + alert("Opération effectuée avec succès"); +} + +async function uploadReactionsDelta() { + let requests = []; + + + for(const [traitId, reactionNode] of Object.entries(reactionsDelta)){ + const formData = new FormData(); + formData.append("npc_id", npc_id.value); + formData.append("trait_id", traitId); + + if(reactionNode === null) formData.append("file", "null"); + else{ + const file = reactionNode.querySelector(".img_input").files[0] + formData.append("file", file ? file : ""); + } + + requests.push(makeAPIRequest("admin/setReaction", formData, {"content": "form"})); + } + + for(request of requests){ + await request; + } + + } async function deleteNpc() { @@ -31,3 +61,52 @@ async function deleteNpc() { alert("Opération effectuée avec succès"); document.location = "/admin"; } + +function changeReaction(inputNode){ + const parentNode = inputNode.parentNode; + const imgNode = parentNode.querySelector('img'); + const traitId = parentNode.querySelector('.trait_id').value; + + const reader = new FileReader(); + reader.onload = (e)=>{ + imgNode.src = e.target.result + } + reader.readAsDataURL(inputNode.files[0]); + + reactionsDelta[traitId] = parentNode; +} + +function deleteReaction(node){ + const reactionNode = node.parentNode; + const traitId = reactionNode.querySelector(".trait_id").value; + const reactionName = reactionNode.querySelector("p").innerText; + + reactionNode.parentNode.removeChild(reactionNode); + + const option = document.createElement("option"); + option.value = traitId + option.innerText = reactionName + + reactions_to_add.appendChild(option); + + reactionsDelta[traitId] = null; +} + +function addReaction(selectNode){ + const selectedOptionNode = selectNode.selectedOptions[0]; + + const traitId = selectedOptionNode.value; + const reactionName = selectedOptionNode.innerText; + + selectNode.removeChild(selectedOptionNode); + + const newReaction = reactions.querySelector("div").cloneNode(true); + newReaction.querySelector("img").src = ""; + newReaction.querySelector(".img_input").value = null; + newReaction.querySelector(".trait_id").value = traitId + newReaction.querySelector("p").innerText = reactionName + + reactions.appendChild(newReaction); + + reactionsDelta[traitId] = newReaction; +} \ No newline at end of file diff --git a/truthinquiry/static/js/api.js b/truthinquiry/static/js/api.js index b49f660..a55b5bc 100644 --- a/truthinquiry/static/js/api.js +++ b/truthinquiry/static/js/api.js @@ -17,6 +17,8 @@ async function makeAPIRequest(endpoint, body, options={}) { if (options["content"] === 'json') { fetchOptions["headers"]["Content-Type"] = 'application/json' fetchOptions["body"] = JSON.stringify(body) + } else if (options["content"] === 'form') { + fetchOptions["body"] = body; } else { fetchOptions["body"] = new URLSearchParams(body); } diff --git a/truthinquiry/templates/admin/npc.html b/truthinquiry/templates/admin/npc.html index 1742f65..972a8b8 100644 --- a/truthinquiry/templates/admin/npc.html +++ b/truthinquiry/templates/admin/npc.html @@ -34,6 +34,28 @@

Image du personnage

{{'Image du personnage' + (' ' + npc.get('name') if npc.get('name') else '')}} + +
+

Réactions

+ + {%for reaction in npc.get("reactions")%} +
+

{{reaction.get('name')}}

+ + + + +
+ {%endfor%} +
+ + +

Réponses aux questions lors de l'interrogation