// -- GESTION DU FORMULAIRE PERMETTANT DE SAISIR / ÉDITER LES QUIZS ET LEURS DÉPENDANCES (LIENS, IMAGES, TAGS, ETC.)
/// Vérifie que l'utilisateur est bien connecté, a le bon statut et le redirige vers le formulaire d'inscription si ce n'est pas le cas.
/// Si c'est ok, propose un moteur de recherche permettant de chercher un quiz
/// Si un id est passé par l'url on affiche les informations du quiz dans un formulaire permettant de l'éditer/supprimer avec une liste des éléments liés (liens, illustrations, questions...) pouvant eux-mêmes être édités/supprimés.
/// Si le nombre max configuré pour chacun de ses éléments n'est pas atteint, il est aussi proposé d'ajouter un nouvel élément.
/// Sinon pas d'id passé par l'url, on affiche un formulaire vide permettant d'en saisir un nouveau quiz avec ses tags.
// Fichier de configuration côté client :
import { apiUrl, availableLangs, theme } from "../../config/instance.js";
const lang=availableLangs[0];
const config = require("../../config/instance.js");
const configIllustrations = require("../../config/illustrations.js");
const configLinks = require("../../config/links.js");
const configQuestionnaires = require("../../config/questionnaires.js");
const configTemplate = require("../../views/"+theme+"/config/"+lang+".js");
// Fonctions utiles au script :
import { getLocaly, removeLocaly } from "./tools/clientstorage.js";
import { addElement } from "./tools/dom.js";
import { helloDev, updateAccountLink } from "./tools/everywhere.js";
import { empyAndHideForm, getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
import { dateFormat, isEmpty } from "../../tools/main";
import { getUrlParams } from "./tools/url.js";
import { checkSession, getConfig } from "./tools/users.js";
// Dictionnaires :
const { addOkMessage, deleteBtnTxt, serverError, updateBtnTxt } = require("../../lang/"+lang+"/general");
const { addIllustrationTxt, defaultAlt, introNoIllustration, introTitleForIllustration } = require("../../lang/"+lang+"/illustration");
const { addLinkTxt, defaultValueForLink, introNoLink, introTitleForLink } = require("../../lang/"+lang+"/link");
const { addQuestionTxt, introNoQuestion, introTitleForQuestion } = require("../../lang/"+lang+"/question");
const { nextDateWithoutQuestionnaire, nextQuestionnairesList, questionnaireNeedBeCompleted, searchQuestionnaireWithNoResult } = require("../../lang/"+lang+"/questionnaire");
const { needBeConnected } = require("../../lang/"+lang+"/user");
// Principaux éléments du DOM manipulés :
const divMain = document.getElementById("main-content");
const divMessage = document.getElementById("message");
const divResponse = document.getElementById("response");
const divCrash = document.getElementById("crash");
const formQuestionnaire = document.getElementById("questionnaires");
const inputClassification = document.getElementById("classification");
const helpClassification = document.getElementById("helpClassification");
const helpPublishingAt = document.getElementById("helpPublishingAt");
const deleteCheckBox = document.getElementById("deleteOkLabel");
const btnNewQuestionnaire = document.getElementById("wantNewQuestionnaire");
const btnPreviewQuestionnaire = document.getElementById("previewQuestionnaire");
const divQuestionnaires = document.getElementById("questionnairesList");
const formSearch = document.getElementById("search");
const divSearchResult = document.getElementById("searchResult");
const formLink = document.getElementById("links");
const formIllustration = document.getElementById("illustrations");
const formQuestion = document.getElementById("questions");
const divLinks = document.getElementById("linksList");
const divIllustrations = document.getElementById("illustrationsList");
const divQuestions = document.getElementById("questionsList");
helloDev();
const initialise = async () =>
{
try
{
const isConnected=await checkSession(["manager", "admin"], "/"+configTemplate.connectionPage, { message: needBeConnected, color:"error" }, window.location);
if(isConnected)
{
divMain.style.display="block";
if(!isEmpty(getLocaly("message")))
{
addElement(divMessage, "p", getLocaly("message", true).message, "", [getLocaly("message", true).color], "", false);
removeLocaly("message");
}
const user=getLocaly("user", true);
updateAccountLink(user.status, configTemplate);
// Initialisation du formulaire de recherche :
setAttributesToInputs(configQuestionnaires, formSearch);
// Initialise le formulaire permettant de mettre à jour les infos de base du questionnaire :
setAttributesToInputs(configQuestionnaires.Questionnaire, formQuestionnaire);
// Case de suppression cachée par défaut, car inutile pour formulaire de création
deleteCheckBox.style.display="none";
// Fonction vidant et cachant tous les formulaires annexes
const hideAllForms = () =>
{
empyAndHideForm(formLink);
if(defaultValueForLink!=0)
document.getElementById("anchor").value=defaultValueForLink;
empyAndHideForm(formIllustration);
empyAndHideForm(formQuestion);
}
hideAllForms();
// Affiche les infos connues concernant les liens
const showLinkInfos = (Links) =>
{
addElement(divLinks, "h2", introTitleForLink);
let listLinks="";
for(let i in Links)
listLinks+="
";
addElement(divQuestions, "ul", listQuestions, "", [], "", false);// à intégrer d'abord dans le DOM pour pouvoir ajouter des Listeners ensuite
for(let i in Questions)
{
document.getElementById("#updateQuestion"+Questions[i].Question.id).addEventListener("click", function(e)
{
e.preventDefault();
showFormQuestionInfos(Questions[i]);
window.location.assign("#links");
});
document.getElementById("#deleteQuestion"+Questions[i].Question.id).addEventListener("click", function(e)
{
e.preventDefault();
showFormQuestionInfos(Questions[i]);
formQuestion.elements["deleteOk"].value=true;
sendQuestionForm();
});
}
if(config.nbQuestionsMax > Questions.length || config.nbQuestionsMax===0)
{
let newBtn=""+addQuestionTxt+"";
addElement(divQuestions, "p", newBtn, "", [], { }, false);
document.getElementById("newQuestion").addEventListener("click", function(e)
{
e.preventDefault();
hideAllForms();
formQuestion.style.display="block";
formQuestion.elements["QuestionnaireId"].value=formQuestionnaire.elements["id"].value;
formQuestion.elements["rank"].value=(Questions.length===0) ? configQuestionnaires.Question.rank.defaultValue : Questions.length+1;
window.location.assign("#questions");
setAttributesToInputs(configQuestionnaires.Question, formQuestion);
});
}
}
// Fonction affichant les infos d'un lien dans le formulaire adhoc
const showFormLinkInfos = (Link) =>
{
// on commence par cacher et vider tous les formulaires annexes
hideAllForms();
// puis on affiche celui dont l'id est passé avec ses données connues
formLink.style.display="block";
// + les contraintes de champ & valeurs par défaut :
setAttributesToInputs(configLinks, formLink);
for(let data in Link)
{
if(formLink.elements[data]!==undefined)
formLink.elements[data].value=Link[data];
}
}
// Fonction affichant les infos d'une illustration dans le formulaire adhoc
const showFormIllustrationInfos = (Illustration) =>
{
// on commence par cacher et vider tous les formulaires annexes
hideAllForms();
// puis on affiche celui dont l'id est passé avec ses données connues
formIllustration.style.display="block";
// + les contraintes de champ & valeurs par défaut :
setAttributesToInputs(configIllustrations, formIllustration);
// !! le champ file qui n'est plus requis, quand un fichier existe déjà !
formIllustration.elements["image"].removeAttribute("required");
for(let data in Illustration)
{
if(formIllustration.elements[data]!==undefined)
formIllustration.elements[data].value=Illustration[data];
}
}
// Fonction affichant les infos d'une question + ses réponses possibles dans le formulaire adhoc
const showFormQuestionInfos = (Question) =>
{
// on commence par cacher et vider tous les formulaires annexes
hideAllForms();
// puis on affiche celui dont l'id est passé avec ses données connues
formQuestion.style.display="block";
for(let data in Question.Question)
{
if(formQuestion.elements[data]!==undefined)
formQuestion.elements[data].value=Question.Question[data];
}
// + les contraintes de champ & valeurs par défaut :
setAttributesToInputs(configQuestionnaires.Question, formQuestion);
for(let data in Question.Choices)
{
if(formQuestion.elements["choiceText"+data]!==undefined)
{
formQuestion.elements["choiceText"+data].value=Question.Choices[data].text;
if(Question.Choices[data].isCorrect==true)
formQuestion.elements["choiceIsCorrect"+data].checked=true;
formQuestion.elements["idChoice"+data].value=Question.Choices[data].id;
}
}
}
// Fonction affichant les infos connues concernant un questionnaire et ses dépendances
const showFormQuestionnaireInfos = (id) =>
{
const xhrGetInfos = new XMLHttpRequest();
xhrGetInfos.open("GET", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.getQuestionnaireRoutes+"/"+id);
xhrGetInfos.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
{
let response=JSON.parse(this.responseText);
if (this.status === 200 && response.Questionnaire != undefined)
{
formQuestionnaire.reset();// pour ne pas garder les données déjà affichées si vide dans ce qui est retourné
for(let data in response.Questionnaire)
{
if(formQuestionnaire.elements[data]!==undefined)
{
if(data==="publishingAt" && response.Questionnaire[data]!==null)
formQuestionnaire.elements[data].value=dateFormat(response.Questionnaire[data], "form");// !! revoir car format pouvant poser soucis si navigateur ne gère pas les champs de type "date"
else
formQuestionnaire.elements[data].value=response.Questionnaire[data];
}
}
deleteCheckBox.style.display="block";
}
if(response.Tags != undefined)
{
let classification="";
for(let i in response.Tags)
{
if(i==0)
classification+=response.Tags[i].name;
else
classification+=","+response.Tags[i].name;
}
formQuestionnaire.elements["classification"].value=classification;
}
divLinks.style.display="block";
divQuestions.style.display="block";
divIllustrations.style.display="block";
if(response.Links != undefined)
showLinkInfos(response.Links);
if(response.Questions != undefined)
showQuestionInfos(response.Questions);
if(response.Illustrations != undefined)
showIllustrationInfos(response.Illustrations);
helpPublishingAt.style.display="none";// info utile pour "placer" un nouveau quiz
// à revoir : remplacer lien pour un bouton + reset complet du formulaire, y compris champs hidden :
btnNewQuestionnaire.style.display="block";
btnNewQuestionnaire.setAttribute("href", configTemplate.questionnairesManagementPage);
btnPreviewQuestionnaire.style.display="block";
if(response.Questionnaire["isPublished"]===false)
btnPreviewQuestionnaire.setAttribute("href", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.previewQuestionnaireRoutes+"/"+id+"/"+user.token);
else
btnPreviewQuestionnaire.setAttribute("href", config.siteUrl+configQuestionnaires.publishedQuestionnaireRoutes+response.Questionnaire["slug"]+".html");
}
}
xhrGetInfos.send();
}
// Si un id est passé par l'url, on essaye d'afficher le questionnaire :
let urlDatas=getUrlParams();
if(urlDatas && urlDatas.id!==undefined)
showFormQuestionnaireInfos(urlDatas.id);
// Traitement du lancement d'une recherche
formSearch.addEventListener("submit", function(e)
{
e.preventDefault();
let datas=getDatasFromInputs(formSearch);
const xhrSearch = new XMLHttpRequest();
xhrSearch.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.searchAdminQuestionnairesRoute);
xhrSearch.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
{
let response=JSON.parse(this.responseText);
if (this.status === 200 && Array.isArray(response))
{
if(response.length===0)
addElement(divSearchResult, "p", searchQuestionnaireWithNoResult, "", ["info"]);
else
{
let selectHTML="";
for(let i in response)
selectHTML+="";
addElement(divSearchResult, "select", selectHTML, "selectSearch");
const searchSelect=document.getElementById("selectSearch");
searchSelect.addEventListener("change", function()
{
if(searchSelect.value!=="")
showFormQuestionnaireInfos(searchSelect.value);
});
}
}
else
addElement(divSearchResult, "p", serverError, "", ["error"]);
}
}
xhrSearch.setRequestHeader("Content-Type", "application/json");
xhrSearch.setRequestHeader("Authorization", "Bearer "+user.token);
if(datas)
xhrSearch.send(JSON.stringify(datas));
});
// Les questionnaires bientôt publiés. Dans une fonction car devant être rechargé.
const showNextQuestionnaires = () =>
{
const xhrNextQuestionnaires = new XMLHttpRequest();
xhrNextQuestionnaires.open("GET", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.getListNextQuestionnaires);
xhrNextQuestionnaires.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
{
let response=JSON.parse(this.responseText);
if (this.status === 200 && Array.isArray(response.questionnaires))
{
let listHTML="", dayStr, optionsDayStr = { weekday: 'long'};
for(let i in response.questionnaires)
{
dayStr=new Intl.DateTimeFormat(lang, optionsDayStr).format(new Date(response.questionnaires[i].datePublishing));
listHTML+="