diff --git a/admin/sync/README.md b/admin/sync/README.md index 5ba597b5..d56c3647 100644 --- a/admin/sync/README.md +++ b/admin/sync/README.md @@ -28,7 +28,8 @@ Tous les textes doivent utiliser l'encodage UTF8. * `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ; * `[[flag_mcq.choice]]` : représente un choix, répétez autant de fois qu'il y a de choix : + `label = "Intitulé de la réponse"`, - + `value = true` : (facultatif, par défaut `false`) valeur attendue pour ce choix ; pour un QCM justifié, utilisez une chaîne de caractères (notez qu'il n'est pas possible de combiner des réponses vraies justifiées et justifiées) ; + + `value = true` : (facultatif, par défaut `false`) valeur attendue pour ce choix ; pour un QCM justifié, utilisez une chaîne de caractères (notez qu'il n'est pas possible de combiner des réponses vraies justifiées et justifiées), + + `help = "Flag correspondant"` : (facultatif) indication affichée dans le champ de texte des QCM justifiés ; - `[[flag_ucq]]` : drapeau sous forme de question à choix unique : * `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ; * `raw = 'MieH2athxuPhai6u'` : drapeau attendu parmi les propositions ; @@ -222,5 +223,5 @@ Exemple `DIGESTS.txt` {#exemple-digeststxt} --- title: Format des répertoires pour la synchronisation author: FIC team 2019 -date: "Dernière mise à jour du document : 27 novembre 2018" +date: "Dernière mise à jour du document : 1 décembre 2018" --- diff --git a/admin/sync/exercice_defines.go b/admin/sync/exercice_defines.go index c1958bdb..d5237856 100644 --- a/admin/sync/exercice_defines.go +++ b/admin/sync/exercice_defines.go @@ -39,6 +39,7 @@ type ExerciceFlag struct { type ExerciceFlagMCQChoice struct { Label string Value interface{} `toml:",omitempty"` + Help string `toml:",omitempty"` } // ExerciceFlagMCQ holds information about a MCQ flag. diff --git a/admin/sync/exercice_keys.go b/admin/sync/exercice_keys.go index ab8e62f2..e586b080 100644 --- a/admin/sync/exercice_keys.go +++ b/admin/sync/exercice_keys.go @@ -123,33 +123,44 @@ func SyncExerciceFlags(i Importer, exercice fic.Exercice) (errs []string) { isJustified := false for cid, choice := range quest.Choice { var val bool + var justify string + if choice.Value == nil { val = false } else if p, ok := choice.Value.(bool); ok { val = p + if len(choice.Help) > 0 { + errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: help field has to be used only with justified mcq.", path.Base(exercice.Path), nline + 1)) + continue + } if isJustified { errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1)) continue } } else if p, ok := choice.Value.(string); ok { val = true + if len(choice.Help) == 0 { + choice.Help = "Flag correspondant" + } if hasOne && !isJustified { errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1)) continue } isJustified = true - if _, err := exercice.AddRawFlag("%" + quest.Label + "%" + choice.Label, "", false, nil, []byte(p)); err != nil { - errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: %s", path.Base(exercice.Path), nline + 1, err)) - continue - } + justify = p } else { errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: has an invalid type. Expected true, false or a string", path.Base(exercice.Path), nline + 1, cid)) continue } - if _, err := flag.AddEntry(choice.Label, val); err != nil { + if e, err := flag.AddEntry(choice.Label, val); err != nil { errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err)) continue + } else if len(justify) > 0 { + if _, err := exercice.AddRawFlag(fmt.Sprintf("%%%d%%%s", e.Id, choice.Help), "", false, nil, []byte(justify)); err != nil { + errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: %s", path.Base(exercice.Path), nline + 1, err)) + continue + } } if val { diff --git a/backend/submission.go b/backend/submission.go index 052ed1cc..71120807 100644 --- a/backend/submission.go +++ b/backend/submission.go @@ -87,7 +87,7 @@ func treatSubmission(pathname string, team fic.Team, exercice_id string) { } else if mcq.IdExercice != exercice.Id { log.Println(id, "[ERR] We retrieve an invalid MCQ: from exercice", mcq.IdExercice, "whereas expected from exercice", exercice.Id) return - } else if key, err := mcq.GetJustifiedFlag(exercice, choice); err != nil { + } else if key, err := choice.GetJustifiedFlag(exercice); err != nil { // Most probably, we enter here because the selected choice has not to be justified // So, just ignore this case as it will be invalidated by the mcq validation continue diff --git a/frontend/static/js/challenge.js b/frontend/static/js/challenge.js index d7c1b7e6..8dbfe30e 100644 --- a/frontend/static/js/challenge.js +++ b/frontend/static/js/challenge.js @@ -233,18 +233,20 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"]) angular.forEach(data.exercices, function(exercice, eid) { angular.forEach(exercice.mcqs, function(mcq, mid) { angular.forEach(mcq.choices, function(choice, cid) { - this[cid] = { - label: choice, - value: mcq["checks_solved"] !== undefined && mcq["checks_solved"][cid] !== undefined && mcq["checks_solved"][cid] > 0 - }; - if (mcq["checks_solved"] !== undefined) { - this[cid].disabled = mcq["checks_solved"][cid] === undefined || mcq["checks_solved"][cid] >= 0; - this[cid].solved = mcq["checks_solved"][cid] !== undefined && mcq["checks_solved"][cid] >= 2; - } + if (!(choice instanceof Object)) + this[cid] = { + label: choice, + }; + + this[cid].disabled = mcq.solved || mcq.part_solved || this[cid].solved; + + if (!this[cid].help) + this[cid].help = "Flag correspondant"; + + if (!this[cid].disabled) + this[cid].value = $scope.my && $scope.my.exercices[eid] && $scope.my.exercices[eid].mcqs[mid] && $scope.my.exercices[eid].mcqs[mid].choices[cid] && $scope.my.exercices[eid].mcqs[mid].choices[cid].value if ($scope.my && $scope.my.exercices[eid] && $scope.my.exercices[eid].mcqs[mid] && $scope.my.exercices[eid].mcqs[mid].choices[cid]) { - if ($scope.my.exercices[eid].mcqs[mid].choices[cid].value !== undefined) - this[cid].value = $scope.my.exercices[eid].mcqs[mid].choices[cid].value; if ($scope.my.exercices[eid].mcqs[mid].choices[cid].justify !== undefined) this[cid].justify = $scope.my.exercices[eid].mcqs[mid].choices[cid].justify; } diff --git a/frontend/static/views/defi.html b/frontend/static/views/defi.html index 05f03c27..d9cc5327 100644 --- a/frontend/static/views/defi.html +++ b/frontend/static/views/defi.html @@ -98,7 +98,7 @@