Revue formulaire création/mise à jour des quizs + intégration thème WikiLerni + compilation JS front

This commit is contained in:
Fabrice PENHOËT 2020-10-06 11:38:07 +02:00
parent f593f8e654
commit b208b3f6d8
27 changed files with 2389 additions and 1872 deletions

View File

@ -52,10 +52,11 @@ module.exports =
// Links:
nbLinksMin: 1,
nbLinksMax: 1,
// Questions & responses:
nbQuestionsMin: 1,
nbQuestionsMax: 0,
nbChoicesMax: 10,
// à supprimer quand tous les "require" à jour:
nbQuestionsMin: questionnaires.nbQuestionsMin,
nbQuestionsMax: questionnaires.nbQuestionsMax,
nbChoicesMax: questionnaires.nbChoicesMax,
passwordMinLength: users.password.minlength,
dirCacheUsers: users.dirCacheUsers,
dirCacheUsersAnswers: users.dirCacheUsersAnswers,

View File

@ -38,6 +38,8 @@ module.exports =
{
text: { maxlength: 255, required: true }
},
search: { minlength: 3, required: true },
/* valeurs en fait définies dans instance.js donc à supprimer quand plus utilisées ailleurs */
nbQuestionsMin: 1,
nbQuestionsMax: 0,
nbChoicesMax: 10,

View File

@ -28,7 +28,7 @@ module.exports =
newPassword: { minlength: 8, maxlength:72 },
codeGodfather: { maxlength: 255 },
cguOk: { value: "true", required: true },
search: { minlength: 3, required: true },
search: { minlength: 1, required: true },
timeDifferenceMin: -720,
timeDifferenceMax:840,
// JSON dir

View File

@ -466,13 +466,13 @@ const checkQuestionnaireIsPublishable = (datas, checkDate=true) =>
return false;
}
}
if(datas.Questions==undefined || datas.Questions.length < config.nbQuestionsMin) // le nombre de réponses mini étant contrôlé au moment de l'enregistrement de la question
if(datas.Questions==undefined || datas.Questions.length < config.nbQuestionsMin)
return false;// le nombre de réponses mini étant contrôlé au moment de l'enregistrement de la question
if(datas.Tags==undefined || datas.Tags.length < config.nbTagsMin)
return false;
if(datas.Tags==undefined || datas.Tags.length < configTags.nbTagsMin)
if(datas.Links==undefined || datas.Links.length < config.nbLinksMin)
return false;
if(datas.Links==undefined || datas.Links.length < configLinks.nbLinksMin)
return false;
if(datas.Illustrations==undefined || datas.Illustrations.length < configIllustrations.nbIllustrationsMin)
if(datas.Illustrations==undefined || datas.Illustrations.length < config.nbIllustrationsMin)
return false;
return true;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,262 +1,185 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Saisie et mise à jour des quizs">
<meta name="robots" content="noindex">
<title>Les quizs</title>
<title>Gestion des quizs</title>
<!-- Version lisible des scripts : https://gitlab.com/lefablab/wikilerni/-/tree/master/front/src -->
<script src="/JS/polyfill.app.js" defer></script>
<script src="/JS/manageQuestionnaires.app.js" defer></script>
<link rel="shortcut icon" href="/img/favicon.ico">
<link rel="stylesheet" href="/themes/default/CSS/pure-min.css">
<link rel="stylesheet" href="/themes/default/CSS/grids-responsive-min.css">
<link rel="stylesheet" href="/themes/default/CSS/wikilerni.css">
<link rel="canonical" href="https://www.wililerni.com/gestion-quizs.html">
</head>
<link rel="stylesheet" href="/themes/wikilerni/css/style.css">
</head>
<body>
<header class="pure-g menu">
<div class="pure-u-1 pure-u-lg-1-8 menu-heading">
<a class="pure-menu-heading" href="/">WikiLerni</a>
</div>
<div class="pure-u-1 pure-u-lg-7-8">
<ul class="pure-g">
<li class="pure-menu-item pure-u-1 pure-u-lg-1-4">
<a class="pure-menu-link" href="/">Accueil</a>
</li>
<li class="pure-menu-item pure-u-1 pure-u-lg-1-4">
<a class="pure-menu-link" href="/connexion.html" id="accountHeadLink">Mon compte</a>
</li>
<li class="pure-menu-item pure-u-1 pure-u-lg-1-4">
<a class="pure-menu-link" href="/a-propos.html">À propos</a>
</li>
<li class="pure-menu-item pure-u-1 pure-u-lg-1-4">
<a class="pure-menu-link" href="/contact.html">Contact</a>
</li>
<body class="cardboard">
<!-- En tête -->
<header class="cardboard">
<a href="/" title="Page d'accueil WikLerni"><img src="/themes/wikilerni/img/wikilerni-purple-2-128.png" alt="WikiLerni (logo)" title="Accéder à la page d'accueil de WikiLerni" /></a>
<ul id="headLinks">
<li><a href="/contact.html" rel="nofollow">Contact</a></li>
<li><a href="/quizs/" id="indexHeadLink" title="Les derniers quizs">Parcourir</a></li>
<li><a href="/connexion.html" id="accountHeadLink">Mon compte</a></li>
<li><a href="/a-propos.html">À propos</a></li>
<li><a href="/" title="Page d'accueil de WikiLerni">Accueil</a></li>
</ul>
</div>
</header>
<div id="crash"></div>
<section id="main-content" class="needJS">
<div class="pure-menu pure-menu-horizontal">
<a href="/gestion.html" class="pure-menu-heading pure-menu-link">Gestion WikiLerni</a>
<ul id="classement" class="pure-menu-list">
<li class="pure-menu-item"><a href="/gestion-quizs.html" title="Publication des quizs" class="pure-menu-link" >Les quizs</a></li>
<li class="pure-menu-item"><a href="/gestion-utilisateurs.html" title="Les comptes utilisateurs" class="pure-menu-link">Les abonné(e)s</a></li>
<li class="pure-menu-item"><a href="/sortie.html" title="Sortie des artistes !" class="pure-menu-link">Me déconnecter</a></li>
<ul id="menu" class="cardboard">
<li><a href="/gestion.html">Gestion WikiLerni</a></li>
<li><a href="/gestion-quizs.html" title="Publication des quizs">Les quizs</a></li>
<li><a href="/gestion-utilisateurs.html" title="Les comptes utilisateurs">Les abonné(e)s</a></li>
<li><a href="/sortie.html">Me déconnecter</a></li>
</ul>
</div>
<div class="content">
<h2 class="content-head is-center" id="infos">Les quizs</h2>
<div id="manageQuestionnaires" class="cardboard">
<form class="pure-form pure-u-1" id="search" method="POST">
<fieldset>
<legend>Chercher un quiz</legend>
<input id="searchQuestionnaires" type="txt" name="searchQuestionnaires" placeholder="Votre recherche">
<button type="submit" class="pure-button pure-button-primary">Chercher</button>
<h1 class="cardboard" id="infos">Les quizs</h1>
<h2>Chercher un quiz</h2>
<form id="search" method="POST">
<input id="searchQuestionnaires" type="text" name="searchQuestionnaires" placeholder="Votre recherche" class="cardboard" />
<div class="input_wrapper"><input type="submit" value="Chercher" class="cardboard" /></div>
<div id="searchResult"></div>
</fieldset>
</form>
<div class="pure-g">
<div class="l-box-lrg pure-u-1">
<div id="message"></div>
<form class="pure-form pure-form-aligned" id="questionnaires" method="POST">
<form id="questionnaires" method="POST">
<h2>Informations du quiz</h2>
<fieldset><label for="title">Titre</label><input id="title" type="text" name="title" class="cardboard"></fieldset>
<fieldset><label for="slug">Slug</label><input id="slug" type="text" name="slug" class="cardboard"></fieldset>
<fieldset><label for="introduction">Introduction</label><textarea id="introduction" name="introduction" rows="10" class="cardboard"></textarea></fieldset>
<fieldset><label for="keywords">Mots-clés</label><textarea id="keywords" name="keywords" rows="3" class="cardboard"></textarea></fieldset>
<fieldset><label for="publishingAt">Date de publication</label><input id="publishingAt" type="date" name="publishingAt" class="cardboard"><span class="info" id="helpPublishingAt"></span></fieldset>
<fieldset>
<legend>Informations du quiz</legend>
<div class="pure-control-group">
<label for="title">Titre</label>
<input id="title" type="text" name="title">
<span class="pure-form-message-inline"></span>
</div>
<div class="pure-control-group">
<label for="slug">Page html</label>
<input id="slug" type="text" name="slug">.html
</div>
<div class="pure-control-group">
<label for="introduction">Introduction</label>
<textarea id="introduction" name="introduction" rows="5"></textarea>
</div>
<div class="pure-control-group">
<label for="keywords">Mots-clés</label>
<textarea id="keywords" name="keywords" rows="5"></textarea>
</div>
<div class="pure-control-group">
<label for="publishingAt">Date de publication</label>
<input id="publishingAt" type="date" name="publishingAt"> <span class="information" id="helpPublishingAt"></span>
</div>
<div class="pure-control-group">
<label for="estimatedTime">Durée de lecture estimée</label>
<select name="estimatedTime" id="estimatedTime">
<select id="estimatedTime" name="estimatedTime" class="cardboard">
<option value="short">Court</option>
<option value="medium">Moyen</option>
<option value="long">Long</option>
</select>
</div>
<div class="pure-control-group">
<label for="classification">Catégories de classement</label>
<input id="classification" type="text" name="classification"> <span class="information" id="helpClassification">Séparer les rubriques par des virgules</span>
</div>
<div class="pure-controls">
<label for="deleteOk" class="pure-checkbox error" id="deleteOkLabel">
<input type="checkbox" id="deleteOk" name="deleteOk" value="true" /> Je souhaite supprimer ce quiz
</label>
</fieldset>
<fieldset><label for="classification">Catégories de classement</label><input id="classification" type="text" name="classification" class="cardboard"><br><span class="info" id="helpClassification">Séparer les rubriques par des virgules</span></fieldset>
<ul class="checkbox_li">
<li class="checkbox_li">
<label for="deleteOk" class="check" id="deleteOkLabel"><input type="checkbox" id="deleteOk" name="deleteOk" value="true" /><div class="checkbox_override"></div> <span class="error">Je souhaite supprimer ce quiz.</span></label>
</li>
</ul>
<input type="hidden" name="id" id="id" value="">
<button type="submit" class="pure-button pure-button-primary" id="submitDatas">Valider</button>
<a href="#questionnaires" class="pure-button pure-button-primary needJS" id="wantNewQuestionnaire">Nouveau questionnaire</a>
<a href="#questionnaires" class="pure-button pure-button-primary needJS" id="previewQuestionnaire" target=="_blank">Voir le quiz</a>
</div>
<div class="input_wrapper"><input type="submit" value="Valider." class="cardboard" id="submitDatas" /></div>
<div class="input_wrapper"><a href="#questionnaires" class="button cardboard" id="wantNewQuestionnaire">Nouveau questionnaire</a></div>
<div class="input_wrapper"><a href="#questionnaires" class="button cardboard" id="previewQuestionnaire" target=="_blank">Voir le quiz</a></div>
<div id="response"></div>
<div id="linksList" class="needJS"></div>
<div id="illustrationsList" class="needJS"></div>
<div id="questionsList" class="needJS"></div>
</fieldset>
</form>
<form class="pure-form pure-form-aligned" id="links" method="POST">
<fieldset>
<legend>Informations du lien</legend>
<div class="pure-control-group">
<label for="url">Url</label>
<input id="url" type="url" name="url">
<span class="pure-form-message-inline"></span>
</div>
<div class="pure-control-group">
<label for="anchor">Texte du lien</label>
<input id="anchor" type="text" name="anchor" value="Lire l'article sur Wikipédia.">
</div>
<div class="pure-controls">
<form id="links" method="POST">
<h2>Informations du lien</h2>
<fieldset><label for="url">Url</label><input id="url" type="url" name="url" class="cardboard"></fieldset>
<fieldset><label for="anchor">Texte du lien</label><input id="anchor" type="text" name="anchor" class="cardboard" value="Lire l'article sur Wikipédia."></fieldset>
<input type="hidden" name="id" id="idLink" value="">
<input type="hidden" name="QuestionnaireId" id="QuestionnaireIdLink" value="">
<input type="hidden" name="deleteOk" id="deleteOkLink" value="">
<button type="submit" class="pure-button pure-button-primary">Valider</button>
</div>
<div class="input_wrapper"><input type="submit" value="Valider." class="cardboard" /></div>
<div id="responseLink"></div>
</fieldset>
</form>
<form class="pure-form pure-form-aligned" id="illustrations" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>Informations de l'illustration</legend>
<div class="pure-control-group">
<label for="image">Sélectionnez le fichier à utiliser</label>
<input type="file" id="image" name="image">
</div>
<div class="pure-control-group">
<label for="alt">Propriété "alt"</label>
<input id="alt" type="text" name="alt">
</div>
<div class="pure-control-group">
<label for="title">Propriété "title"</label>
<input id="title" type="text" name="title">
</div>
<div class="pure-control-group">
<label for="caption">Légende</label>
<input id="caption" type="text" name="caption">
</div>
<div class="pure-controls">
<form id="illustrations" method="POST">
<h2>Informations de l'illustration</h2>
<fieldset><label for="image">Sélectionnez le fichier à utiliser</label><input id="image" type="file" name="image" class="cardboard"></fieldset>
<fieldset><label for="alt">Propriété "alt"</label><input id="alt" type="text" name="alt" class="cardboard"></fieldset>
<fieldset><label for="title">Propriété "title"</label><input id="title" type="text" name="title" class="cardboard"></fieldset>
<fieldset><label for="caption">Légende</label><input id="caption" type="text" name="caption" class="cardboard" value="Crédit : "></fieldset>
<input type="hidden" name="id" id="idIllustration" value="">
<input type="hidden" name="QuestionnaireId" id="QuestionnaireIdIllustration" value="">
<input type="hidden" name="deleteOk" id="deleteOkIllustration" value="">
<button type="submit" class="pure-button pure-button-primary">Valider</button>
</div>
<div class="input_wrapper"><input type="submit" value="Valider." class="cardboard" /></div>
<div id="responseIllustration"></div>
</fieldset>
</form>
<form id="questions" method="POST">
<h2>La question et les réponses proposées</h2>
<fieldset><label for="text">Question</label><input id="text" type="text" name="text" class="cardboard"></fieldset> <fieldset><label for="rank">Rang</label><input id="rank" type="number" name="rank" class="cardboard" value="1"> <span class="info">Permet de fixer l'ordre d'affichage des questions.</span></fieldset>
<fieldset><label for="explanation">Explications</label><textarea id="explanation" name="explanation" rows="5" class="cardboard"></textarea></fieldset>
<form class="pure-form pure-form-aligned" id="questions" method="POST">
<fieldset>
<legend>La question et les réponses proposées</legend>
<div class="pure-control-group">
<label for="text">Question</label>
<input id="text" type="text" name="text">
<span class="pure-form-message-inline"></span>
</div>
<div class="pure-control-group">
<label for="rank">Rang</label>
<input id="rank" type="number" name="rank" value="1"> <span class="information">Permet de fixer l'ordre d'affichage des questions.</span>
</div>
<div class="pure-control-group">
<label for="explanation">Explications</label>
<textarea id="explanation" name="explanation" rows="5"></textarea>
</div>
<legend>Réponses proposées</legend>
<div class="pure-control-group">
<input id="choiceText0" type="text" name="choiceText0" maxlength="255" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect0" name="choiceIsCorrect0" value="true" /> Réponse correcte
<h3>Réponses proposées</h3>
<ul class="responses_li">
<li class="responses_li">
<input id="choiceText0" type="text" name="choiceText0" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect0" class="check"><input type="checkbox" id="choiceIsCorrect0" name="choiceIsCorrect0" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice0" id="idChoice0" value="">
</div>
<div class="pure-control-group">
<input id="choiceText1" type="text" name="choiceText1" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect1" name="choiceIsCorrect1" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText1" type="text" name="choiceText1" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect1" class="check"><input type="checkbox" id="choiceIsCorrect1" name="choiceIsCorrect1" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice1" id="idChoice1" value="">
</div>
<div class="pure-control-group">
<input id="choiceText2" type="text" name="choiceText2" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect2" name="choiceIsCorrect2" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText2" type="text" name="choiceText2" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect2" class="check"><input type="checkbox" id="choiceIsCorrect2" name="choiceIsCorrect2" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice2" id="idChoice2" value="">
</div>
<div class="pure-control-group">
<input id="choiceText3" type="text" name="choiceText3" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect3" name="choiceIsCorrect3" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText3" type="text" name="choiceText3" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect3" class="check"><input type="checkbox" id="choiceIsCorrect3" name="choiceIsCorrect3" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice3" id="idChoice3" value="">
</div>
<div class="pure-control-group">
<input id="choiceText4" type="text" name="choiceText4" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect4" name="choiceIsCorrect4" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText4" type="text" name="choiceText4" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect4" class="check"><input type="checkbox" id="choiceIsCorrect4" name="choiceIsCorrect4" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice4" id="idChoice4" value="">
</div>
<div class="pure-control-group">
<input id="choiceText5" type="text" name="choiceText5" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect5" name="choiceIsCorrect5" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText5" type="text" name="choiceText5" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect5" class="check"><input type="checkbox" id="choiceIsCorrect5" name="choiceIsCorrect5" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice5" id="idChoice5" value="">
</div>
<div class="pure-control-group">
<input id="choiceText6" type="text" name="choiceText6" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect6" name="choiceIsCorrect6" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText6" type="text" name="choiceText6" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect6" class="check"><input type="checkbox" id="choiceIsCorrect6" name="choiceIsCorrect6" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice6" id="idChoice6" value="">
</div>
<div class="pure-control-group">
<input id="choiceText7" type="text" name="choiceText7" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect7" name="choiceIsCorrect7" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText7" type="text" name="choiceText7" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect7" class="check"><input type="checkbox" id="choiceIsCorrect7" name="choiceIsCorrect7" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice7" id="idChoice7" value="">
</div>
<div class="pure-control-group">
<input id="choiceText8" type="text" name="choiceText8" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect8" name="choiceIsCorrect8" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText8" type="text" name="choiceText8" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect8" class="check"><input type="checkbox" id="choiceIsCorrect8" name="choiceIsCorrect8" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice8" id="idChoice8" value="">
</div>
<div class="pure-control-group">
<input id="choiceText9" type="text" name="choiceText9" maxlength="255">&nbsp;<input type="checkbox" id="choiceIsCorrect9" name="choiceIsCorrect9" value="true" /> Réponse correcte
</li>
<li class="responses_li">
<input id="choiceText9" type="text" name="choiceText9" maxlength="255" maxlength="255" class="cardboard">
<label for="choiceIsCorrect9" class="check"><input type="checkbox" id="choiceIsCorrect9" name="choiceIsCorrect9" value="true" /><div class="checkbox_override"></div> Réponse correcte.</label>
<input type="hidden" name="idChoice9" id="idChoice9" value="">
</div>
<div class="pure-controls">
</li>
</ul>
<input type="hidden" name="id" id="idQuestion" value="">
<input type="hidden" name="QuestionnaireId" id="QuestionnaireIdQuestion" value="">
<input type="hidden" name="deleteOk" id="deleteOkQuestion" value="">
<button type="submit" class="pure-button pure-button-primary">Valider</button>
</div>
<div class="input_wrapper"><input type="submit" value="Valider." class="cardboard" /></div>
<div id="responseQuestion"></div>
</fieldset>
</form>
<div class="l-box-lrg pure-u-1" id="questionnairesList"></div>
</div>
</div>
</div>
</section>
<footer class="footer l-box is-center">
<ul class="pure-g">
<li class="pure-u-1 pure-u-lg-1-5">
<a href="/mentions-legales.html">Crédits</a>
</li>
<li class="pure-u-1 pure-u-lg-1-5">
<a href="/mentions-legales.html">Mentions légales</a>
</li>
<li class="pure-u-1 pure-u-lg-1-5">
<a href="/donnees.html">Données personnelles</a>
</li>
<li><a href="/CGV-CGU.html">CGV &amp; CGU</a></li>
<footer class="cardboard">
<ul id="footLinks">
<li><a href="https://framasphere.org/people/7e54b7a0b53201389eef2a0000053625" title="Blog WikiLerni sur diaspora*">Blog</a></li>
<li><a href="/credits.html">Crédits</a></li>
<li><a href="/mentions-legales.html" rel="nofollow">Mentions légales</a></li>
<li><a href="/donnees.html">Données personnelles</a></li>
<li><a href="/CGV-CGU.html" rel="nofollow">CGV &amp; CGU</a></li>
</ul>
</footer>
</body>
</body>
</html>

View File

@ -3,9 +3,8 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Gestion des abonnés.">
<meta name="robots" content="noindex">
<title>Mon WikiLerni</title>
<title>Gestion des abonnés</title>
<!-- Version lisible des scripts : https://gitlab.com/lefablab/wikilerni/-/tree/master/front/src -->
<script src="/JS/polyfill.app.js" defer></script>
<script src="/JS/manageUsers.app.js" defer></script>
@ -13,7 +12,6 @@
<link rel="stylesheet" href="/themes/wikilerni/css/style.css">
</head>
<body class="cardboard">
<!-- En tête -->
<header class="cardboard">
@ -73,7 +71,7 @@
</fieldset>
<fieldset><label for="timeDifference">Décalage horaire</label><input id="timeDifference" type="number" name="timeDifference" readonly class="cardboard"></fieldset>
<fieldset><label for="newPassword">Nouveau mot de passe</label><input id="newPassword" type="password" name="newPassword" class="cardboard">
<div id="newPasswordMessage"><span class="info">Laisser vide sauf si vous souhaitez le changer.</span></div></fieldset>
<div id="newPasswordMessage"> <span class="info">Laisser vide sauf si vous souhaitez le changer.</span></div></fieldset>
<fieldset><label for="adminComments">Commentaires</label><textarea id="adminComments" name="adminComments" rows="5" class="cardboard"></textarea></fieldset>
<fieldset><label for="numberOfDays">Durée totale de l'abonnement</label><input id="numberOfDays" type="number" name="numberOfDays" class="cardboard"><span class="info">Depuis la création de son compte.</span></fieldset>
<div class="framed">

View File

@ -29,7 +29,7 @@ font-family: Arial, Helvetica, sans-serif;
/* texture de fond des éléments */
.cardboard
{
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
}
/* Cache un contenu du DOM devant être réintégrer via JavaScript */
.needJS
@ -64,7 +64,7 @@ text-shadow:none;
/* Liens de navigation entre pages de résultats */
#next a, #previous a, #tagsList a
{
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
}
nav#pagination, nav#tagsList
{
@ -83,7 +83,6 @@ nav#pagination div, nav#tagsList div
margin: 1em;
}
/* Boutons médias sociaux */
#zerozozio
{
@ -234,7 +233,7 @@ line-height: 1.25em;
}
.info,.success,.error
{
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
}
.info {background-color: #8c599c;}
.success {background-color: #00c684;}
@ -259,9 +258,10 @@ padding:0;
margin:0;
}
input[type=submit], input[type=text], input[type=email], input[type=password], input[type=number],
select, textarea, .button
input[type=file], input[type=date], input[type=url], select, textarea, .button
{
background-color: #8c599c;
background-image: url("../img/background-texture.png");
padding: 10px;
border: 0;
border-radius: 3px;
@ -279,11 +279,16 @@ input[type=submit]:hover, .button:hover
margin-top: 2px;
box-shadow: inset 0px 1px 0px rgba(255,255,255,0.66), inset 0px -1px 0px rgba(0, 0, 0,0.66), 0px 0px 5px rgba(0,0,0,0.66);
}
input[type=text], input[type=password], input[type=email], textarea
input[type=text], input[type=password], input[type=email],
input[type=number], input[type=file], input[type=date], input[type=url], select, textarea
{
box-shadow: inset 0 1px 0 rgba(0,0,0,0.66), inset 0 -1px 0 rgba(255,255,255,0.66), inset 0 3px 8px rgba(0,0,0,0.66);
}
input[type=text], input[type=password], input[type=email], input[type=url], textarea
{
width: 95%;
}
input[type=checkbox]
{
width:15px;
@ -334,19 +339,45 @@ input:-webkit-autofill:focus
-webkit-box-shadow: 0 0 0 1000px #8c599c inset !important;
-webkit-text-fill-color: white !important;
}
ul.checkbox_li
ul.checkbox_li, ul.responses_li
{
list-style-type: none;
text-align: left;
padding-left: 0.7em;
font-family: sans;
}
form ul.checkbox_li li
form ul.checkbox_li li,form ul.responses_li li
{
margin-bottom:0.5em;
}
#searchQuestionnaires
{
width:90%;
}
#selectSearch
{
background-image: url("../img/background-texture.png");
}
/* explications sous formulaires */
#helpClassification a
{
font-size:1.2em;
padding: 0.2em 0.3em;
}
#publishingAt
{
margin-right:100%;
}
#helpPublishingAt
{
font-size:1.2em;
}
#manageQuestionnaires #questionnairesList li
{
font-size:1.1em;
margin-top: 1em;
}
/* textes en annexes des formulaires */
#explanations
{
padding: 0.2em;
@ -357,6 +388,37 @@ margin:1.5em;
text-align:left;
line-height:1.5em;
}
#linksList, #illustrationsList, #questionsList
{
margin:3em 1em;
text-align: left;
}
#linksList ul, #illustrationsList ul, #questionsList ul
{
padding:0;
list-style-type: none;
}
#linksList li, #illustrationsList li, #questionsList li
{
padding:0;
margin: 1em 0;
}
#linksList a, #illustrationsList a, #questionsList a
{
margin-right:3em;
}
#linksList br, #illustrationsList br, #questionsList br
{
line-height: 3em;
}
#questionsList p
{
margin:3em 0;
}
#questionsList p a
{
font-size:1.5em;
}
/* Sous-menu pour tags ou utilisateur connecté, etc. */
@ -471,7 +533,7 @@ font-size:1em;
}
/* Propriétés générales à mobiles en mode paysage + petites tablettes ou grandes tablettes en mode portrait */
/* Propriétés générales à partir des mobiles en mode paysage */
@media screen and (min-width: 480px)
{
/* header & footer */
@ -535,6 +597,15 @@ font-size:1em;
{
padding:0.2em 1em;
}
#searchQuestionnaires
{
width:65%;
}
#manageQuestionnaires #questionnairesList li
{
font-size:1.2em;
margin-top: 0.5em;
}
}
@ -626,12 +697,21 @@ font-size:1em;
{
margin:1em 10%;
}
form ul.responses_li
{
margin:1em 0;
}
form li.responses_li
{
width:80%;
margin: auto;
}
/* Contenus textuels, paragraphes, etc. */
.framed
{
padding-top: 0.5em;
padding-bottom: 0.5em;
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
font-size:0.8em;
}
#explanations
@ -772,7 +852,7 @@ border-top: 1px solid rgba(255,255,255,0.5);
border-bottom: 1px solid rgba(0,0,0,0.75);
padding-top: 0.25em;
padding-bottom: 0.25em;
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
}
#home h2
{
@ -1159,13 +1239,13 @@ display:inline;
{
display:inline;
background-color: #00c684;
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
}
.isNotCorrect em
{
display:inline;
background-color: red;
background-image: url('../img/background-texture.png');
background-image: url("../img/background-texture.png");
}
li.checkbox_li em
{
@ -1288,7 +1368,7 @@ font-size:1.1em;
}
/*----------------- Déclaration générales pour les pages avec des formulaires de connexion, inscription, etc. --------------*/
#signup, #login, #account
#signup, #login, #account, #manageQuestionnaires
{
width: 85%;
margin: auto;
@ -1303,7 +1383,7 @@ background-color: #FF8800;
box-shadow: 0 0 5px rgba(0,0,0,0.75);
text-align:center;
}
#signup h1, #login h1, #account h1
#signup h1, #login h1, #account h1, #manageQuestionnaires h1
{
background-color: #FF8800;
box-shadow: 0 0 5px rgba(0,0,0,0.75);
@ -1317,21 +1397,24 @@ border-top: 1px solid rgba(255,255,255,0.5);
border-bottom: 1px solid rgba(0,0,0,0.66);
font-size:0.9em;
}
#signup h2, #login h2, #account h2
#signup h2, #login h2, #account h2, #manageQuestionnaires h2
{
margin-bottom: 0;
}
#signup p, #login p, #account p
#signup p, #login p, #account p, #manageQuestionnaires p
{
text-align: left;
padding-left: 1em;
}
#signup .framed .engraved, #login .framed .engraved, #account .framed .engraved
#signup .framed .engraved,
#login .framed .engraved,
#account .framed .engraved,
#manageQuestionnaires .framed .engraved
{
text-align: left;
margin: 1em;
}
#signup div.framed, #login div.framed, #account div.framed
#signup div.framed, #login div.framed, #account div.framed, #manageQuestionnaires div.framed
{
font-size:0.9em;
margin-left: 1em;
@ -1344,7 +1427,7 @@ width: 85%;
{
width: 75%;
}
#signup div.framed, #login div.framed, #account div.framed
#signup div.framed, #login div.framed, #account div.framed, #manageQuestionnaires div.framed
{
width: 90%;
}
@ -1374,7 +1457,7 @@ width: 85%;
{
display:inline;
}
#signup div.framed, #login div.framed, #account div.framed
#signup div.framed, #login div.framed, #account div.framed, #manageQuestionnaires div.framed
{
width: 95%;
}
@ -1387,7 +1470,7 @@ width: 85%;
@media screen and (min-width: 1024px)
{
#signup, #login, #account
#signup, #login, #account, #manageQuestionnaires
{
width: 60%;
}

View File

@ -4,36 +4,40 @@
/// 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 avec ses tags.
/// 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 configFrontEnd = require("../../views/"+theme+"/config/"+lang+".js");
// Fonctions utiles au script : !! revoir quand le reste sera fini pour vérifier si tout est utile
import { getLocaly, removeLocaly, saveLocaly } from "./tools/clientstorage.js";
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, empyForm, getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
import { dateFormat, isEmpty, replaceAll } from "../../tools/main";
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 txt = require("../../lang/"+lang+"/general");
const txtUsers = require("../../lang/"+lang+"/user");
const txtQuestionnaire = require("../../lang/"+lang+"/questionnaire");
const txtQuestion = require("../../lang/"+lang+"/question");
const txtLink = require("../../lang/"+lang+"/link");
const txtIllustration = require("../../lang/"+lang+"/illustration");
helloDev();
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");
@ -41,12 +45,9 @@ 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");
@ -54,16 +55,13 @@ const divLinks = document.getElementById("linksList");
const divIllustrations = document.getElementById("illustrationsList");
const divQuestions = document.getElementById("questionsList");
helloDev();
const initialise = async () =>
{
try
{
const config = await getConfig();
if(!config)
addElement(divMessage, "p", txt.serverError, "", ["error"]);
else
{
const isConnected=await checkSession(["manager", "admin"], "/"+configFrontEnd.connectionPage, { message: txtUsers.needBeConnected, color:"error" }, window.location);
const isConnected=await checkSession(["manager", "admin"], "/"+configTemplate.connectionPage, { message: needBeConnected, color:"error" }, window.location);
if(isConnected)
{
divMain.style.display="block";
@ -73,13 +71,13 @@ const initialise = async () =>
removeLocaly("message");
}
const user=getLocaly("user", true);
updateAccountLink(user.status, configFrontEnd);
updateAccountLink(user.status, configTemplate);
// Initialisation du formulaire de recherche :
setAttributesToInputs(config, formSearch);
setAttributesToInputs(configQuestionnaires, formSearch);
// Initialise le formulaire permettant de mettre à jour les infos de base du questionnaire :
setAttributesToInputs(config.Questionnaire, formQuestionnaire);
setAttributesToInputs(configQuestionnaires.Questionnaire, formQuestionnaire);
// Case de suppression cachée par défaut, car inutile pour formulaire de création
deleteCheckBox.style.display="none";
@ -87,8 +85,8 @@ const initialise = async () =>
const hideAllForms = () =>
{
empyAndHideForm(formLink);
if(txtLink.defaultValue!=0)
document.getElementById("anchor").value=txtLink.defaultValue;
if(defaultValueForLink!=0)
document.getElementById("anchor").value=defaultValueForLink;
empyAndHideForm(formIllustration);
empyAndHideForm(formQuestion);
}
@ -97,13 +95,13 @@ const initialise = async () =>
// Affiche les infos connues concernant les liens
const showLinkInfos = (Links) =>
{
addElement(divLinks, "h4", txtLink.introTitle);// remplace l'existant dans divLinks
addElement(divLinks, "h2", introTitleForLink);
let listLinks="";
for(let i in Links)
listLinks+="<li><a href='"+Links[i].url+"' target='_blank'>"+Links[i].anchor+"</a> | <a href='#updateLink"+Links[i].id+"' id='#updateLink"+Links[i].id+"' >"+txt.updateBtnTxt+"</a> | <a href='#deleteLink"+Links[i].id+"' id='#deleteLink"+Links[i].id+"' >"+txt.deleteBtnTxt+"</a></li>";
listLinks+="<li><a href='"+Links[i].url+"' target='_blank'>"+Links[i].anchor+"</a><br><a href='#updateLink"+Links[i].id+"' id='#updateLink"+Links[i].id+"' class='button' >"+updateBtnTxt+"</a> <a href='#deleteLink"+Links[i].id+"' id='#deleteLink"+Links[i].id+"' class='button' >"+deleteBtnTxt+"</a></li>";
if(listLinks==="")
listLinks="<li>"+txtLink.introNoLink+"</li>";
addElement(divLinks, "ul", listLinks, "", ["information"], "", false);// à intégrer dans le DOM pour pouvoir ajouter des addEventListener ensuite
listLinks="<li>"+introNoLink+"</li>";
addElement(divLinks, "ul", listLinks, "", [], "", false);// à intégrer d'abord dans le DOM pour pouvoir ajouter des Listeners ensuite
for(let i in Links)
{
document.getElementById("#updateLink"+Links[i].id).addEventListener("click", function(e)
@ -122,18 +120,16 @@ const initialise = async () =>
}
if(config.nbLinksMax > Links.length || config.nbLinksMax===0)
{
if(Links.length < config.nbLinksMin)
addElement(divLinks, "a", txt.addBtnTxt, "#newLink", ["error"], { href:"#newLink" }, false);
else
addElement(divLinks, "a", txt.addBtnTxt, "#newLink", ["information"], { href:"#newLink" }, false);
document.getElementById("#newLink").addEventListener("click", function(e)
let newBtn="<a href='#newLink' id='newLink' class='button'>"+addLinkTxt+"</a>";
addElement(divLinks, "p", newBtn, "", [], { }, false);
document.getElementById("newLink").addEventListener("click", function(e)
{
e.preventDefault();
hideAllForms();
formLink.style.display="block";
formLink.elements["QuestionnaireId"].value=formQuestionnaire.elements["id"].value;
window.location.assign("#links");
setAttributesToInputs(config.Link, formLink);
setAttributesToInputs(configLinks, formLink);
});
}
}
@ -141,13 +137,13 @@ const initialise = async () =>
// Affiche les infos connues concernant les illustrations
const showIllustrationInfos = (Illustrations) =>
{
addElement(divIllustrations, "h4", txtIllustration.introTitle);// remplace l'existant dans divIllustrations
addElement(divIllustrations, "h2", introTitleForIllustration);
let listIllustrations="";
for(let i in Illustrations)
listIllustrations+="<li><a href='"+configFrontEnd.illustrationDir+Illustrations[i].url+"' target='_blank'><img src='"+configFrontEnd.illustrationDir+Illustrations[i].url+"' alt='"+txtIllustration.defaultAlt+"' style='max-height:150px'></a> | <a href='#updateIllustration"+Illustrations[i].id+"' id='#updateIllustration"+Illustrations[i].id+"' >"+txt.updateBtnTxt+"</a> | <a href='#deleteIllustration"+Illustrations[i].id+"' id='#deleteIllustration"+Illustrations[i].id+"' >"+txt.deleteBtnTxt+"</a></li>";
listIllustrations+="<li><a href='"+configTemplate.illustrationDir+Illustrations[i].url+"' target='_blank'><img src='"+configTemplate.illustrationDir+Illustrations[i].url+"' alt='"+defaultAlt+"' style='max-height:150px'></a><br><a href='#updateIllustration"+Illustrations[i].id+"' id='#updateIllustration"+Illustrations[i].id+"' class='button'>"+updateBtnTxt+"</a> <a href='#deleteIllustration"+Illustrations[i].id+"' id='#deleteIllustration"+Illustrations[i].id+"' class='button'>"+deleteBtnTxt+"</a></li>";
if(listIllustrations==="")
listIllustrations="<li>"+txtIllustration.introNoIllustration+"</li>";
addElement(divIllustrations, "ul", listIllustrations, "", ["information"], "", false);// à intégrer dans le DOM pour pouvoir ajouter des addEventListener ensuite
listIllustrations="<li>"+introNoIllustration+"</li>";
addElement(divIllustrations, "ul", listIllustrations, "", [], "", false);// à intégrer d'abord dans le DOM pour pouvoir ajouter des Listeners ensuite
for(let i in Illustrations)
{
document.getElementById("#updateIllustration"+Illustrations[i].id).addEventListener("click", function(e)
@ -166,18 +162,16 @@ const initialise = async () =>
}
if(config.nbIllustrationsMax > Illustrations.length || config.nbIllustrationsMax===0)
{
if(Illustrations.length < config.nbIllustrationsMin)
addElement(divIllustrations, "a", txt.addBtnTxt, "#newIllustration", ["error"], { href:"#newIllustration" }, false);
else
addElement(divIllustrations, "a", txt.addBtnTxt, "#newIllustration", ["information"], { href:"#newIllustration" }, false);
document.getElementById("#newIllustration").addEventListener("click", function(e)
let newBtn="<a href='#newIllustration' id='newIllustration' class='button'>"+addIllustrationTxt+"</a>";
addElement(divIllustrations, "p", newBtn, "", [], { }, false);
document.getElementById("newIllustration").addEventListener("click", function(e)
{
e.preventDefault();
hideAllForms();
formIllustration.style.display="block";
formIllustration.elements["QuestionnaireId"].value=formQuestionnaire.elements["id"].value;
window.location.assign("#illustrations");
setAttributesToInputs(config.Illustration, formIllustration);
setAttributesToInputs(configIllustrations, formIllustration);
});
}
}
@ -185,13 +179,13 @@ const initialise = async () =>
// Affiche les infos connues concernant les questions
const showQuestionInfos = (Questions) =>
{
addElement(divQuestions, "h4", txtQuestion.introTitle);// remplace l'existant dans divQuestions
addElement(divQuestions, "h2", introTitleForQuestion);
let listQuestions="";
for(let i in Questions)
listQuestions+="<li>"+Questions[i].Question.rank+" - "+Questions[i].Question.text+" | <a href='#updateQuestion"+Questions[i].Question.id+"' id='#updateQuestion"+Questions[i].Question.id+"' >"+txt.updateBtnTxt+"</a> | <a href='#deleteQuestion"+Questions[i].Question.id+"' id='#deleteQuestion"+Questions[i].Question.id+"' >"+txt.deleteBtnTxt+"</a></li>";
listQuestions+="<li>"+Questions[i].Question.rank+" - "+Questions[i].Question.text+"<br><a href='#updateQuestion"+Questions[i].Question.id+"' id='#updateQuestion"+Questions[i].Question.id+"' class='button'>"+updateBtnTxt+"</a> <a href='#deleteQuestion"+Questions[i].Question.id+"' id='#deleteQuestion"+Questions[i].Question.id+"' class='button'>"+deleteBtnTxt+"</a></li>";
if(listQuestions==="")
listQuestions="<li>"+txtQuestion.introNoQuestion+"</li>";
addElement(divQuestions, "ul", listQuestions, "", ["information"], "", false);// à intégrer dans le DOM pour pouvoir ajouter des addEventListener ensuite
listQuestions="<li>"+introNoQuestion+"</li>";
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)
@ -208,22 +202,19 @@ const initialise = async () =>
sendQuestionForm();
});
}
if(config.nbQuestionsMax > Questions.length || config.nbQuestionsMax===0)
{
if(Questions.length < config.nbQuestionsMin)
addElement(divQuestions, "a", txt.addBtnTxt, "#newQuestion", ["error"], { href:"#newQuestion" }, false);
else
addElement(divQuestions, "a", txt.addBtnTxt, "#newQuestion", ["information"], { href:"#newQuestion" }, false);
document.getElementById("#newQuestion").addEventListener("click", function(e)
let newBtn="<a href='#newQuestion' id='newQuestion' class='button'>"+addQuestionTxt+"</a>";
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) ? config.Question.rank.defaultValue : Questions.length+1;
formQuestion.elements["rank"].value=(Questions.length===0) ? configQuestionnaires.Question.rank.defaultValue : Questions.length+1;
window.location.assign("#questions");
setAttributesToInputs(config.Question, formQuestion);
setAttributesToInputs(configQuestionnaires.Question, formQuestion);
});
}
}
@ -235,13 +226,13 @@ const initialise = async () =>
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];
}
// + les contraintes de champ :
setAttributesToInputs(config.Link, formLink);
}
// Fonction affichant les infos d'une illustration dans le formulaire adhoc
@ -251,15 +242,15 @@ const initialise = async () =>
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];
}
// + les contraintes de champ :
setAttributesToInputs(config.Illustration, formIllustration);
// sauf le champ file qui n'est plus requis quand un fichier existe déjà !
formIllustration.elements["image"].removeAttribute("required");
}
// Fonction affichant les infos d'une question + ses réponses possibles dans le formulaire adhoc
@ -274,6 +265,8 @@ const initialise = async () =>
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)
@ -284,15 +277,13 @@ const initialise = async () =>
formQuestion.elements["idChoice"+data].value=Question.Choices[data].id;
}
}
// + les contraintes de champ :
setAttributesToInputs(config.Question, formQuestion);
}
// Fonction affichant les infos connues concernant un questionnaire et ses dépendances
const showFormQuestionnaireInfos = (id) =>
{
const xhrGetInfos = new XMLHttpRequest();
xhrGetInfos.open("GET", apiUrl+config.questionnaireRoutes+config.getQuestionnaireRoutes+"/"+id);
xhrGetInfos.open("GET", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.getQuestionnaireRoutes+"/"+id);
xhrGetInfos.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -300,7 +291,7 @@ const initialise = async () =>
let response=JSON.parse(this.responseText);
if (this.status === 200 && response.Questionnaire != undefined)
{
formQuestionnaire.reset();// pour ne pas garder données déjà affichées si vide dans ce qui est retourné
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)
@ -337,12 +328,12 @@ const initialise = async () =>
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", configFrontEnd.questionnairesManagementPage);
btnNewQuestionnaire.setAttribute("href", configTemplate.questionnairesManagementPage);
btnPreviewQuestionnaire.style.display="block";
if(response.Questionnaire["isPublished"]===false)
btnPreviewQuestionnaire.setAttribute("href", apiUrl+config.questionnaireRoutes+config.previewQuestionnaireRoutes+"/"+id+"/"+user.token);
btnPreviewQuestionnaire.setAttribute("href", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.previewQuestionnaireRoutes+"/"+id+"/"+user.token);
else
btnPreviewQuestionnaire.setAttribute("href", config.siteUrl+config.publishedQuestionnaireRoutes+response.Questionnaire["slug"]+".html");
btnPreviewQuestionnaire.setAttribute("href", config.siteUrl+configQuestionnaires.publishedQuestionnaireRoutes+response.Questionnaire["slug"]+".html");
}
}
xhrGetInfos.send();
@ -359,7 +350,7 @@ const initialise = async () =>
e.preventDefault();
let datas=getDatasFromInputs(formSearch);
const xhrSearch = new XMLHttpRequest();
xhrSearch.open("POST", apiUrl+config.questionnaireRoutes+config.searchAdminQuestionnairesRoute);
xhrSearch.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.searchAdminQuestionnairesRoute);
xhrSearch.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -368,7 +359,7 @@ const initialise = async () =>
if (this.status === 200 && Array.isArray(response))
{
if(response.length===0)
addElement(divSearchResult, "p", txtQuestionnaire.notFound, "", ["information"]);
addElement(divSearchResult, "p", searchQuestionnaireWithNoResult, "", ["info"]);
else
{
let selectHTML="<option value=''></option>";
@ -384,7 +375,7 @@ const initialise = async () =>
}
}
else
addElement(divSearchResult, "p", txt.serverError, "", ["error"]);
addElement(divSearchResult, "p", serverError, "", ["error"]);
}
}
xhrSearch.setRequestHeader("Content-Type", "application/json");
@ -397,7 +388,7 @@ const initialise = async () =>
const showNextQuestionnaires = () =>
{
const xhrNextQuestionnaires = new XMLHttpRequest();
xhrNextQuestionnaires.open("GET", apiUrl+config.questionnaireRoutes+config.getListNextQuestionnaires);
xhrNextQuestionnaires.open("GET", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.getListNextQuestionnaires);
xhrNextQuestionnaires.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -409,14 +400,14 @@ const initialise = async () =>
for(let i in response.questionnaires)
{
dayStr=new Intl.DateTimeFormat(lang, optionsDayStr).format(new Date(response.questionnaires[i].datePublishing));
listHTML+="<li>"+dayStr+" "+dateFormat(response.questionnaires[i].datePublishing, "fr")+": <a href='"+configFrontEnd.questionnairesManagementPage+"?id="+response.questionnaires[i].id+"' id='questionnaire_"+response.questionnaires[i].id+"'>"+response.questionnaires[i].title+"</a>";
listHTML+="<li>"+dayStr+" "+dateFormat(response.questionnaires[i].datePublishing, "fr")+": <a href='"+configTemplate.questionnairesManagementPage+"?id="+response.questionnaires[i].id+"' id='questionnaire_"+response.questionnaires[i].id+"'>"+response.questionnaires[i].title+"</a>";
if(response.questionnaires[i].isPublishable===false)
listHTML+=" <span class='error'>("+txtQuestionnaire.needBeCompleted+")</li>";
listHTML+=" <span class='error'>("+questionnaireNeedBeCompleted+")</li>";
listHTML+="</li>";
}
if(response.questionnaires.length!==0)
addElement(divQuestionnaires, "h3", txtQuestionnaire.nextQuestionnairesList.replace("#NB", response.questionnaires.length));
addElement(helpPublishingAt, "em", txtQuestionnaire.nextDateWithoutQuestionnaire+dateFormat(new Date(response.dateNeeded), "fr"));
addElement(divQuestionnaires, "h3", nextQuestionnairesList.replace("#NB", response.questionnaires.length));
addElement(helpPublishingAt, "em", nextDateWithoutQuestionnaire+dateFormat(new Date(response.dateNeeded), "fr"));
addElement(divQuestionnaires, "ul", listHTML, "", "", "", false);
for(let i in response.questionnaires)
{
@ -444,10 +435,10 @@ const initialise = async () =>
const lastTag=tags[0].trim();
if(lastTag.length >= 2)
{
// à revoir : importer la liste des tags lors de l'initialisation pour éviter les appels multiples
// à revoir : importer la liste des tags lors de l'initialisation pour éviter les appels multiples ?
// mais dans ce cas actualiser cette liste après chaque mise à jour.
const xhrSearchTags = new XMLHttpRequest();
xhrSearchTags.open("POST", apiUrl+config.questionnaireRoutes+config.tagsSearchRoute);
xhrSearchTags.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.tagsSearchRoute);
xhrSearchTags.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -458,7 +449,7 @@ const initialise = async () =>
helpClassification.innerHTML="";
for(let i in response)
{
addElement(helpClassification, "a", response[i].name, "#tag"+response[i].id, ["information"], { href:"#tag"+response[i].id }, false);
addElement(helpClassification, "a", response[i].name, "#tag"+response[i].id, ["info"], { href:"#tag"+response[i].id }, false);
document.getElementById("#tag"+response[i].id).addEventListener("click", function(e)
{
e.preventDefault();
@ -485,11 +476,11 @@ const initialise = async () =>
let datas=getDatasFromInputs(formQuestionnaire);
const xhrQuestionnaireDatas = new XMLHttpRequest();
if(!isEmpty(datas.id) && (datas.deleteOk!==undefined))
xhrQuestionnaireDatas.open("DELETE", apiUrl+config.questionnaireRoutes+"/"+datas.id);
xhrQuestionnaireDatas.open("DELETE", apiUrl+configQuestionnaires.questionnaireRoutes+"/"+datas.id);
else if(!isEmpty(datas.id))
xhrQuestionnaireDatas.open("PUT", apiUrl+config.questionnaireRoutes+"/"+datas.id);
xhrQuestionnaireDatas.open("PUT", apiUrl+configQuestionnaires.questionnaireRoutes+"/"+datas.id);
else
xhrQuestionnaireDatas.open("POST", apiUrl+config.questionnaireRoutes+"/");
xhrQuestionnaireDatas.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+"/");
xhrQuestionnaireDatas.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -497,7 +488,7 @@ const initialise = async () =>
let response=JSON.parse(this.responseText);
if (this.status === 201 && response.id!=undefined)
{
addElement(divResponse, "p", txt.addOkMessage, "", ["success"]);
addElement(divResponse, "p", addOkMessage, "", ["success"]);
datas.id=response.id;
showNextQuestionnaires();// peut avoir évolué suivant ce qui s'est passé
}
@ -515,11 +506,11 @@ const initialise = async () =>
if(Array.isArray(response.errors))
response.errors = response.errors.join("<br>");
else
response.errors = txt.serverError;
response.errors = serverError;
addElement(divResponse, "p", response.errors, "", ["error"]);
}
else
addElement(divResponse, "p", txt.serverError, "", ["error"]);
addElement(divResponse, "p", serverError, "", ["error"]);
if(datas.deleteOk===undefined)
showFormQuestionnaireInfos(datas.id);
else
@ -540,11 +531,11 @@ const initialise = async () =>
let datas=getDatasFromInputs(formLink);
const xhrLinkDatas = new XMLHttpRequest();
if(!isEmpty(datas.id) && (!isEmpty(datas.deleteOk)))
xhrLinkDatas.open("DELETE", apiUrl+config.linksRoute+datas.id);
xhrLinkDatas.open("DELETE", apiUrl+configLinks.linksRoute+datas.id);
else if(!isEmpty(datas.id))
xhrLinkDatas.open("PUT", apiUrl+config.linksRoute+datas.id);
xhrLinkDatas.open("PUT", apiUrl+configLinks.linksRoute+datas.id);
else
xhrLinkDatas.open("POST", apiUrl+config.linksRoute);
xhrLinkDatas.open("POST", apiUrl+configLinks.linksRoute);
xhrLinkDatas.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -567,11 +558,11 @@ const initialise = async () =>
if(Array.isArray(response.errors))
response.errors = response.errors.join("<br>");
else
response.errors = txt.serverError;
response.errors = serverError;
addElement(divResponseLink, "p", response.errors, "", ["error"]);
}
else
addElement(divResponseLink, "p", txt.serverError, "", ["error"]);
addElement(divResponseLink, "p", serverError, "", ["error"]);
}
}
xhrLinkDatas.setRequestHeader("Content-Type", "application/json");
@ -584,7 +575,7 @@ const initialise = async () =>
sendLinkForm();
});
// L'envoi des données d'un lien peut être généré par le bouton formulaire ou par le lien supprimer
// L'envoi des données d'une illustration peut être généré par le bouton formulaire ou par le lien supprimer
const sendIllustrationForm = () =>
{
const divResponseIllustration=document.getElementById("responseIllustration");
@ -593,11 +584,11 @@ const initialise = async () =>
let datasWithFiles=new FormData(formIllustration); // il me manque les informations du fichier avec ma fonction getDatasFromInputs
const xhrIllustrationDatas = new XMLHttpRequest();
if(!isEmpty(datas.id) && (!isEmpty(datas.deleteOk)))
xhrIllustrationDatas.open("DELETE", apiUrl+config.illustrationsRoute+datas.id);
xhrIllustrationDatas.open("DELETE", apiUrl+configIllustrations.illustrationsRoute+datas.id);
else if(!isEmpty(datas.id))
xhrIllustrationDatas.open("PUT", apiUrl+config.illustrationsRoute+datas.id);
xhrIllustrationDatas.open("PUT", apiUrl+configIllustrations.illustrationsRoute+datas.id);
else
xhrIllustrationDatas.open("POST", apiUrl+config.illustrationsRoute);
xhrIllustrationDatas.open("POST", apiUrl+configIllustrations.illustrationsRoute);
xhrIllustrationDatas.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -620,11 +611,11 @@ const initialise = async () =>
if(Array.isArray(response.errors))
response.errors = response.errors.join("<br>");
else
response.errors = txt.serverError;
response.errors = serverError;
addElement(divResponseIllustration, "p", response.errors, "", ["error"]);
}
else
addElement(divResponseIllustration, "p", txt.serverError, "", ["error"]);
addElement(divResponseIllustration, "p", serverError, "", ["error"]);
}
}
xhrIllustrationDatas.setRequestHeader("Authorization", "Bearer "+user.token);
@ -636,7 +627,6 @@ const initialise = async () =>
sendIllustrationForm();
});
// L'envoi des données d'une question et de ses réponse qui peut être généré par le bouton submit ou par le lien supprimer
const sendQuestionForm = () =>
{
@ -645,11 +635,11 @@ const initialise = async () =>
let datas=getDatasFromInputs(formQuestion);
const xhrQuestionDatas = new XMLHttpRequest();
if(!isEmpty(datas.id) && (!isEmpty(datas.deleteOk)))
xhrQuestionDatas.open("DELETE", apiUrl+config.questionsRoute+datas.id);
xhrQuestionDatas.open("DELETE", apiUrl+configQuestionnaires.questionsRoute+datas.id);
else if(!isEmpty(datas.id))
xhrQuestionDatas.open("PUT", apiUrl+config.questionsRoute+datas.id);
xhrQuestionDatas.open("PUT", apiUrl+configQuestionnaires.questionsRoute+datas.id);
else
xhrQuestionDatas.open("POST", apiUrl+config.questionsRoute);
xhrQuestionDatas.open("POST", apiUrl+configQuestionnaires.questionsRoute);
xhrQuestionDatas.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE)
@ -672,11 +662,11 @@ const initialise = async () =>
if(Array.isArray(response.errors))
response.errors = response.errors.join("<br>");
else
response.errors = txt.serverError;
response.errors = serverError;
addElement(divResponseQuestion, "p", response.errors, "", ["error"]);
}
else
addElement(divResponseQuestion, "p", txt.serverError, "", ["error"]);
addElement(divResponseQuestion, "p", serverError, "", ["error"]);
}
}
xhrQuestionDatas.setRequestHeader("Content-Type", "application/json");
@ -690,11 +680,10 @@ const initialise = async () =>
});
}
}
}
catch(e)
{
console.error(e);
addElement(divMessage, "p", txt.serverError, "", ["error"]);
addElement(divCrash, "p", serverError, "", ["error"]);
}
}
initialise();

View File

@ -1,5 +1,6 @@
module.exports =
{
addIllustrationTxt: "Ajouter une illustration",
needUrl : "Merci de fournir une url pour l'image.",
needUniqueUrl : "L'url est déjà utilisée par une autre image.",
needGoodLongUrl : "L'url de l'image doit contenir entre 5 et 255 caractères.",
@ -14,6 +15,6 @@ module.exports =
updatedOkMessage: "L'illustration a bien été modifiée.",
deletedOkMessage: "L'illustration a bien été supprimée.",
defaultAlt : "Illustration du quiz",
introTitle : "Illustrations du quiz",
introTitleForIllustration : "Illustrations du quiz",
introNoIllustration : "Aucune illustration pour l'instant."
};

View File

@ -1,5 +1,6 @@
module.exports =
{
addLinkTxt: "Ajouter un lien",
needUrl : "Merci de saisir l'url du lien.",
needValidUrl : "Merci de saisir un url ayant un format valide.",
needNotTooLongUrl : "Merci de saisir un url ne comptant pas plus de 255 caractères.",
@ -11,7 +12,7 @@ module.exports =
addedOkMessage: "Le lien a bien été ajouté.",
deletedOkMessage: "Le lien a bien été supprimé.",
notFound : "L'enregistrement du lien n'a pas été trouvé.",
introTitle : "Lectures proposées",
introTitleForLink : "Lectures proposées",
introNoLink : "Aucun lien pour l'instant.",
defaultValue: "Lire l'article sur Wikipédia."
defaultValueForLink: "Lire l'article sur Wikipédia."
};

View File

@ -1,5 +1,6 @@
module.exports =
{
addQuestionTxt: "Ajouter une question",
needText: "Merci de saisir le texte de la question !",
needNotTooLongText: "La question ne doit pas compter plus de 255 caractères.",
needQuestionnaire: "Le questionnaire concerné n'a pas été trouvé.",
@ -8,7 +9,7 @@ module.exports =
addOkMessage: "La question a bien été ajoutée.",
updateOkMessage: "La question a bien été modifiée.",
deleteOkMessage: "La question a bien été supprimée.",
introTitle: "Les questions enregistrées",
introTitleForQuestion: "Les questions enregistrées",
introNoQuestion: "Aucune question n'a été saisie pour l'instant",
needNumberForRank : "Vous devez fournir un nombre supérieur ou égal à 1 pour le rang de cette question."
};

View File

@ -11,7 +11,7 @@ module.exports =
needEstimatedTime: "Merci de sélectionner une estimation de la durée de ce quiz.",
notFound : "Aucun quiz n'a pas été trouvé.",
searchResultTitle : "Résultat pour votre recherche",
searchNoResult : "Aucun résultat n'a été trouvé pour votre recherche",
searchQuestionnaireWithNoResult : "Aucun quiz n'a été trouvé pour votre recherche.",
searchWithResult : "Voici #NB quizs pour votre recherche :",
questionnairesName: "quiz",
publishedBy: "Quiz publié par",
@ -33,7 +33,7 @@ module.exports =
btnShowQuestionnaire: "Afficher le quiz !",
btnShareQuizTxt: "Partager ce quiz sur ",
nextQuestionnairesList: "Les #NB prochains quizs devant être publiés",
needBeCompleted: "Quiz incomplet",
questionnaireNeedBeCompleted: "Quiz incomplet",
nextDateWithoutQuestionnaire: "Prochaine date sans quiz programmé : ",
haveBeenPublished : ":NB nouveaux questionnaires ont été publiés.",
haveBeenRegenerated : "Les fichiers HTML de #NB1 questionnaires et #NB2 rubriques ont été regénérés."