admin: display {hint,flag,mcq} dependancies on interface

This commit is contained in:
nemunaire 2020-01-23 14:23:02 +01:00
parent ac9361b4ce
commit 9d93331868
3 changed files with 111 additions and 5 deletions

View File

@ -3,6 +3,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"strings" "strings"
"time" "time"
@ -30,6 +31,7 @@ func init() {
router.GET("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(showExerciceHint))) router.GET("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(showExerciceHint)))
router.PUT("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(updateExerciceHint))) router.PUT("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(updateExerciceHint)))
router.DELETE("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(deleteExerciceHint))) router.DELETE("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(deleteExerciceHint)))
router.GET("/api/exercices/:eid/hints/:hid/dependancies", apiHandler(hintHandler(showExerciceHintDeps)))
router.GET("/api/exercices/:eid/flags", apiHandler(exerciceHandler(listExerciceFlags))) router.GET("/api/exercices/:eid/flags", apiHandler(exerciceHandler(listExerciceFlags)))
router.POST("/api/exercices/:eid/flags", apiHandler(exerciceHandler(createExerciceFlag))) router.POST("/api/exercices/:eid/flags", apiHandler(exerciceHandler(createExerciceFlag)))
@ -37,6 +39,7 @@ func init() {
router.PUT("/api/exercices/:eid/flags/:kid", apiHandler(flagKeyHandler(updateExerciceFlag))) router.PUT("/api/exercices/:eid/flags/:kid", apiHandler(flagKeyHandler(updateExerciceFlag)))
router.POST("/api/exercices/:eid/flags/:kid/try", apiHandler(flagKeyHandler(tryExerciceFlag))) router.POST("/api/exercices/:eid/flags/:kid/try", apiHandler(flagKeyHandler(tryExerciceFlag)))
router.DELETE("/api/exercices/:eid/flags/:kid", apiHandler(flagKeyHandler(deleteExerciceFlag))) router.DELETE("/api/exercices/:eid/flags/:kid", apiHandler(flagKeyHandler(deleteExerciceFlag)))
router.GET("/api/exercices/:eid/flags/:kid/dependancies", apiHandler(flagKeyHandler(showExerciceFlagDeps)))
router.GET("/api/exercices/:eid/flags/:kid/choices/", apiHandler(flagKeyHandler(listFlagChoices))) router.GET("/api/exercices/:eid/flags/:kid/choices/", apiHandler(flagKeyHandler(listFlagChoices)))
router.GET("/api/exercices/:eid/flags/:kid/choices/:cid", apiHandler(choiceHandler(showFlagChoice))) router.GET("/api/exercices/:eid/flags/:kid/choices/:cid", apiHandler(choiceHandler(showFlagChoice)))
router.POST("/api/exercices/:eid/flags/:kid/choices/", apiHandler(flagKeyHandler(createFlagChoice))) router.POST("/api/exercices/:eid/flags/:kid/choices/", apiHandler(flagKeyHandler(createFlagChoice)))
@ -47,6 +50,7 @@ func init() {
router.GET("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(showExerciceQuiz))) router.GET("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(showExerciceQuiz)))
router.PUT("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(updateExerciceQuiz))) router.PUT("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(updateExerciceQuiz)))
router.DELETE("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(deleteExerciceQuiz))) router.DELETE("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(deleteExerciceQuiz)))
router.GET("/api/exercices/:eid/quiz/:qid/dependancies", apiHandler(quizHandler(showExerciceQuizDeps)))
router.GET("/api/exercices/:eid/tags", apiHandler(exerciceHandler(listExerciceTags))) router.GET("/api/exercices/:eid/tags", apiHandler(exerciceHandler(listExerciceTags)))
router.POST("/api/exercices/:eid/tags", apiHandler(exerciceHandler(addExerciceTag))) router.POST("/api/exercices/:eid/tags", apiHandler(exerciceHandler(addExerciceTag)))
@ -111,6 +115,34 @@ func exportResolutionMovies(_ httprouter.Params, body []byte) (interface{}, erro
} }
} }
func loadFlags(n func () ([]fic.Flag, error)) (interface{}, error) {
if flags, err := n(); err != nil {
return nil, err
} else {
var ret []fic.Flag
for _, flag := range flags {
if f, ok := flag.(fic.FlagKey); ok {
if k, err := fic.GetFlagKey(f.Id); err != nil {
return nil, err
} else {
ret = append(ret, k)
}
} else if f, ok := flag.(fic.MCQ); ok {
if m, err := fic.GetMCQ(f.Id); err != nil {
return nil, err
} else {
ret = append(ret, m)
}
} else {
return nil, errors.New(fmt.Sprintf("Flag type %T not implemented for this flag.", f))
}
}
return ret, nil
}
}
func listExerciceHints(exercice fic.Exercice, body []byte) (interface{}, error) { func listExerciceHints(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetHints() return exercice.GetHints()
} }
@ -298,6 +330,10 @@ func showExerciceHint(hint fic.EHint, body []byte) (interface{}, error) {
return hint, nil return hint, nil
} }
func showExerciceHintDeps(hint fic.EHint, body []byte) (interface{}, error) {
return loadFlags(hint.GetDepends)
}
func updateExerciceHint(hint fic.EHint, body []byte) (interface{}, error) { func updateExerciceHint(hint fic.EHint, body []byte) (interface{}, error) {
var uh fic.EHint var uh fic.EHint
if err := json.Unmarshal(body, &uh); err != nil { if err := json.Unmarshal(body, &uh); err != nil {
@ -354,6 +390,10 @@ func showExerciceFlag(flag fic.FlagKey, _ fic.Exercice, body []byte) (interface{
return flag, nil return flag, nil
} }
func showExerciceFlagDeps(flag fic.FlagKey, _ fic.Exercice, body []byte) (interface{}, error) {
return loadFlags(flag.GetDepends)
}
func tryExerciceFlag(flag fic.FlagKey, _ fic.Exercice, body []byte) (interface{}, error) { func tryExerciceFlag(flag fic.FlagKey, _ fic.Exercice, body []byte) (interface{}, error) {
var uk uploadedFlag var uk uploadedFlag
if err := json.Unmarshal(body, &uk); err != nil { if err := json.Unmarshal(body, &uk); err != nil {
@ -457,6 +497,10 @@ func showExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, body []byte) (interface{}, e
return quiz, nil return quiz, nil
} }
func showExerciceQuizDeps(quiz fic.MCQ, _ fic.Exercice, body []byte) (interface{}, error) {
return loadFlags(quiz.GetDepends)
}
func updateExerciceQuiz(quiz fic.MCQ, exercice fic.Exercice, body []byte) (interface{}, error) { func updateExerciceQuiz(quiz fic.MCQ, exercice fic.Exercice, body []byte) (interface{}, error) {
var uq fic.MCQ var uq fic.MCQ
if err := json.Unmarshal(body, &uq); err != nil { if err := json.Unmarshal(body, &uq); err != nil {

View File

@ -250,15 +250,27 @@ angular.module("FICApp")
update: {method: 'PUT'} update: {method: 'PUT'}
}) })
}) })
.factory("ExerciceHintDeps", function($resource) {
return $resource("/api/exercices/:exerciceId/hints/:hintId/dependancies", { exerciceId: '@idExercice', hintId: '@id' })
})
.factory("ExerciceFlag", function($resource) { .factory("ExerciceFlag", function($resource) {
return $resource("/api/exercices/:exerciceId/flags/:flagId", { exerciceId: '@idExercice', flagId: '@id' }, { return $resource("/api/exercices/:exerciceId/flags/:flagId", { exerciceId: '@idExercice', flagId: '@id' }, {
update: {method: 'PUT'} update: {method: 'PUT'}
}) })
}) })
.factory("ExerciceFlagChoices", function($resource) {
return $resource("/api/exercices/:exerciceId/flags/:flagId/choices", { exerciceId: '@idExercice', flagId: '@id' })
})
.factory("ExerciceFlagDeps", function($resource) {
return $resource("/api/exercices/:exerciceId/flags/:flagId/dependancies", { exerciceId: '@idExercice', flagId: '@id' })
})
.factory("ExerciceMCQFlag", function($resource) { .factory("ExerciceMCQFlag", function($resource) {
return $resource("/api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, { return $resource("/api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, {
update: {method: 'PUT'} update: {method: 'PUT'}
}) })
})
.factory("ExerciceMCQDeps", function($resource) {
return $resource("/api/exercices/:exerciceId/quiz/:mcqId/dependancies", { exerciceId: '@idExercice', mcqId: '@id' })
}); });
angular.module("FICApp") angular.module("FICApp")
@ -293,6 +305,21 @@ angular.module("FICApp")
} }
}) })
.component('dependancy', {
bindings: {
dep: '=',
deleteDep: '=',
},
controller: function() {},
template: `
<li>
<span ng-if="$ctrl.dep.label">Flag {{ $ctrl.dep.label }}</span>
<span ng-if="$ctrl.dep.title">QCM {{ $ctrl.dep.title }}</span>
<button type="button" class="btn btn-sm btn-danger" ng-if="$ctrl.deleteDep" ng-click="$ctrl.deleteDep()"><span class="glyphicon glyphicon-trash"></span></button>
</li>
`
})
.directive('color', function() { .directive('color', function() {
return { return {
require: 'ngModel', require: 'ngModel',
@ -1542,6 +1569,12 @@ angular.module("FICApp")
}; };
}) })
.controller("ExerciceHintDepsController", function($scope, $routeParams, ExerciceHintDeps) {
$scope.init = function(hint) {
$scope.deps = ExerciceHintDeps.query({ exerciceId: $routeParams.exerciceId, hintId: hint.id });
}
})
.controller("ExerciceFlagsController", function($scope, ExerciceFlag, $routeParams, $rootScope, $http) { .controller("ExerciceFlagsController", function($scope, ExerciceFlag, $routeParams, $rootScope, $http) {
$scope.flags = ExerciceFlag.query({ exerciceId: $routeParams.exerciceId }); $scope.flags = ExerciceFlag.query({ exerciceId: $routeParams.exerciceId });
@ -1604,6 +1637,12 @@ angular.module("FICApp")
}; };
}) })
.controller("ExerciceFlagDepsController", function($scope, $routeParams, ExerciceFlagDeps) {
$scope.init = function(flag) {
$scope.deps = ExerciceFlagDeps.query({ exerciceId: $routeParams.exerciceId, flagId: flag.id });
}
})
.controller("ExerciceMCQFlagsController", function($scope, ExerciceMCQFlag, $routeParams, $rootScope) { .controller("ExerciceMCQFlagsController", function($scope, ExerciceMCQFlag, $routeParams, $rootScope) {
$scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId }); $scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId });
@ -1635,6 +1674,12 @@ angular.module("FICApp")
} }
}) })
.controller("ExerciceMCQDepsController", function($scope, $routeParams, ExerciceMCQDeps) {
$scope.init = function(flag) {
$scope.deps = ExerciceMCQDeps.query({ exerciceId: $routeParams.exerciceId, mcqId: flag.id });
}
})
.controller("TeamsListController", function($scope, $rootScope, Team, $location, $http) { .controller("TeamsListController", function($scope, $rootScope, Team, $location, $http) {
$scope.teams = Team.query(); $scope.teams = Team.query();
$scope.fields = ["id", "name"]; $scope.fields = ["id", "name"];

View File

@ -75,11 +75,7 @@
Dépend de la validation de : Dépend de la validation de :
<span ng-if="!file.depends">aucun flag</span> <span ng-if="!file.depends">aucun flag</span>
<ul ng-if="file.depends"> <ul ng-if="file.depends">
<li ng-repeat="dep in file.depends"> <dependancy ng-repeat="dep in file.depends" dep="dep" deleteDep="deleteFileDep"></dependancy>
<span ng-if="dep.label">Flag {{ dep.label }}</span>
<span ng-if="dep.title">QCM {{ dep.title }}</span>
<button type="button" class="btn btn-sm btn-danger" ng-click="deleteFileDep()"><span class="glyphicon glyphicon-trash"></span></button>
</li>
</ul> </ul>
</div> </div>
</form> </form>
@ -118,6 +114,13 @@
<button type="button" ng-click="deleteHint()" class="btn btn-sm btn-danger" ng-show="hint.id"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button> <button type="button" ng-click="deleteHint()" class="btn btn-sm btn-danger" ng-show="hint.id"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
</div> </div>
</div> </div>
<div ng-controller="ExerciceHintDepsController" ng-init="init(hint)">
Dépendances&nbsp;:
<ul ng-if="deps.length > 0">
<dependancy ng-repeat="dep in deps" dep="dep"></dependancy>
</ul>
<span ng-if="deps.length == 0"> sans</span>
</div>
</form> </form>
</div> </div>
</div> </div>
@ -177,6 +180,13 @@
<button class="btn btn-sm btn-warning" type="submit"><span class="glyphicon glyphicon-play" aria-hidden="true"></span></button> <button class="btn btn-sm btn-warning" type="submit"><span class="glyphicon glyphicon-play" aria-hidden="true"></span></button>
</div> </div>
</div> </div>
<div ng-controller="ExerciceFlagDepsController" ng-init="init(flag)">
Dépendances&nbsp;:
<ul ng-if="deps.length > 0">
<dependancy ng-repeat="dep in deps" dep="dep"></dependancy>
</ul>
<span ng-if="deps.length == 0"> sans</span>
</div>
</form> </form>
</div> </div>
</div> </div>
@ -222,6 +232,13 @@
<button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button> <button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
</div> </div>
</div> </div>
<div ng-controller="ExerciceMCQDepsController" ng-init="init(q)">
Dépendances&nbsp;:
<ul ng-if="deps.length > 0">
<dependancy ng-repeat="dep in deps" dep="dep"></dependancy>
</ul>
<span ng-if="deps.length == 0"> sans</span>
</div>
</form> </form>
</div> </div>
</div> </div>