admin: new form to update history coefficient
This commit is contained in:
parent
2b75287d16
commit
ba5642da8f
5 changed files with 174 additions and 4 deletions
|
@ -23,6 +23,7 @@ func init() {
|
||||||
router.DELETE("/api/exercices/:eid", apiHandler(exerciceHandler(deleteExercice)))
|
router.DELETE("/api/exercices/:eid", apiHandler(exerciceHandler(deleteExercice)))
|
||||||
|
|
||||||
router.GET("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(getExerciceHistory)))
|
router.GET("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(getExerciceHistory)))
|
||||||
|
router.PATCH("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(updateExerciceHistory)))
|
||||||
router.DELETE("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(delExerciceHistory)))
|
router.DELETE("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(delExerciceHistory)))
|
||||||
|
|
||||||
router.GET("/api/exercices/:eid/files", apiHandler(exerciceHandler(listExerciceFiles)))
|
router.GET("/api/exercices/:eid/files", apiHandler(exerciceHandler(listExerciceFiles)))
|
||||||
|
@ -145,6 +146,16 @@ type uploadedExerciceHistory struct {
|
||||||
Kind string
|
Kind string
|
||||||
Time time.Time
|
Time time.Time
|
||||||
Secondary *int64
|
Secondary *int64
|
||||||
|
Coeff float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateExerciceHistory(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||||
|
var uh uploadedExerciceHistory
|
||||||
|
if err := json.Unmarshal(body, &uh); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return exercice.UpdateHistoryItem(uh.Coeff, uh.IdTeam, uh.Kind, uh.Time, uh.Secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
func delExerciceHistory(exercice fic.Exercice, body []byte) (interface{}, error) {
|
func delExerciceHistory(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||||
|
|
|
@ -1289,6 +1289,28 @@ angular.module("FICApp")
|
||||||
|
|
||||||
.controller("ExerciceHistoryController", function($scope, ExerciceHistory, $routeParams, $http, $rootScope) {
|
.controller("ExerciceHistoryController", function($scope, ExerciceHistory, $routeParams, $http, $rootScope) {
|
||||||
$scope.history = ExerciceHistory.query({ exerciceId: $routeParams.exerciceId });
|
$scope.history = ExerciceHistory.query({ exerciceId: $routeParams.exerciceId });
|
||||||
|
$scope.updHistory = function() {
|
||||||
|
var target = {
|
||||||
|
team_id: $("#updHistory").data("idteam"),
|
||||||
|
kind: $("#updHistory").data("kind"),
|
||||||
|
time: $("#updHistory").data("time"),
|
||||||
|
secondary: $("#updHistory").data("secondary") != "" ? $("#updHistory").data("secondary") : null,
|
||||||
|
coeff: parseFloat($('#historycoeff').val()),
|
||||||
|
};
|
||||||
|
if (target) {
|
||||||
|
$http({
|
||||||
|
url: "/api/exercices/" + $routeParams.exerciceId + "/history.json",
|
||||||
|
method: "PATCH",
|
||||||
|
data: target
|
||||||
|
}).then(function(response) {
|
||||||
|
$rootScope.staticFilesNeedUpdate++;
|
||||||
|
$scope.history = ExerciceHistory.query({ exerciceId: $routeParams.exerciceId });
|
||||||
|
$('#updHistory').modal('hide');
|
||||||
|
}, function(response) {
|
||||||
|
$rootScope.newBox('danger', 'An error occurs when updating history item: ', response.data.errmsg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
$scope.delHistory = function(row) {
|
$scope.delHistory = function(row) {
|
||||||
$http({
|
$http({
|
||||||
url: "/api/exercices/" + $routeParams.exerciceId + "/history.json",
|
url: "/api/exercices/" + $routeParams.exerciceId + "/history.json",
|
||||||
|
@ -1594,6 +1616,28 @@ angular.module("FICApp")
|
||||||
})
|
})
|
||||||
.controller("TeamHistoryController", function($scope, TeamHistory, $routeParams, $http, $rootScope) {
|
.controller("TeamHistoryController", function($scope, TeamHistory, $routeParams, $http, $rootScope) {
|
||||||
$scope.history = TeamHistory.query({ teamId: $routeParams.teamId });
|
$scope.history = TeamHistory.query({ teamId: $routeParams.teamId });
|
||||||
|
$scope.updHistory = function() {
|
||||||
|
var target = {
|
||||||
|
team_id: parseInt($routeParams.teamId),
|
||||||
|
kind: $("#updHistory").data("kind"),
|
||||||
|
time: $("#updHistory").data("time"),
|
||||||
|
secondary: $("#updHistory").data("secondary") != "" ? $("#updHistory").data("secondary") : null,
|
||||||
|
coeff: parseFloat($('#historycoeff').val()),
|
||||||
|
};
|
||||||
|
if (target) {
|
||||||
|
$http({
|
||||||
|
url: "/api/exercices/" + $("#updHistory").data("primary") + "/history.json",
|
||||||
|
method: "PATCH",
|
||||||
|
data: target
|
||||||
|
}).then(function(response) {
|
||||||
|
$rootScope.staticFilesNeedUpdate++;
|
||||||
|
$scope.history = TeamHistory.query({ teamId: $routeParams.teamId });
|
||||||
|
$('#updHistory').modal('hide');
|
||||||
|
}, function(response) {
|
||||||
|
$rootScope.newBox('danger', 'An error occurs when updating history item: ', response.data.errmsg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
$scope.delHistory = function(row) {
|
$scope.delHistory = function(row) {
|
||||||
$http({
|
$http({
|
||||||
url: "/api/teams/" + $routeParams.teamId + "/history.json",
|
url: "/api/teams/" + $routeParams.teamId + "/history.json",
|
||||||
|
|
|
@ -221,9 +221,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-2" style="overflow-y: scroll; height: 450px">
|
<div class="mt-2" style="overflow-y: scroll; height: 450px" ng-controller="ExerciceHistoryController">
|
||||||
<h3>Historique</h3>
|
<h3>Historique</h3>
|
||||||
<table ng-controller="ExerciceHistoryController" class="table table-hover table-striped table-bordered bg-primary text-light">
|
<table class="table table-hover table-striped table-bordered bg-primary text-light">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="row in history" ng-class="{'bg-ffound': row.kind == 'flag_found', 'bg-mfound': row.kind == 'mcq_found', 'bg-wchoices': row.kind == 'wchoices', 'bg-success': row.kind == 'solved', 'bg-info': row.kind == 'hint', 'bg-warning': row.kind == 'tries'}">
|
<tr ng-repeat="row in history" ng-class="{'bg-ffound': row.kind == 'flag_found', 'bg-mfound': row.kind == 'mcq_found', 'bg-wchoices': row.kind == 'wchoices', 'bg-success': row.kind == 'solved', 'bg-info': row.kind == 'hint', 'bg-warning': row.kind == 'tries'}">
|
||||||
<td>
|
<td>
|
||||||
|
@ -242,13 +242,55 @@
|
||||||
<span ng-if="!row.secondary_title && row.secondary && row.kind != 'solved'">: {{ row.secondary }}</span>
|
<span ng-if="!row.secondary_title && row.secondary && row.kind != 'solved'">: {{ row.secondary }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td style="vertical-align: middle; padding: 0; background-color: {{ row.team_color }}">
|
<td style="vertical-align: middle; padding: 0; background-color: {{ row.team_color }}">
|
||||||
|
<button type="button" data-toggle="modal" data-target="#updHistory" ng-if="row.kind != 'flag_found' && row.kind != 'tries' && row.kind != 'mcq_found'" data-idteam="{{ row.team_id }}" data-kind="{{ row.kind }}" data-time="{{ row.time }}" data-secondary="{{ row.secondary }}" data-coeff="{{ row.coefficient }}" class="float-right btn btn-sm btn-info"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button>
|
||||||
<button type="button" ng-click="delHistory(row)" class="float-right btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
<button type="button" ng-click="delHistory(row)" class="float-right btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="modal fade" id="updHistory" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Édition de l'historique</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form ng-submit="updHistory()">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="historycoeff">Coefficient</label>
|
||||||
|
<input class="form-control" id="historycoeff">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
||||||
|
<button type="button" class="btn btn-primary" ng-click="updHistory()">Mettre à jour</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#updHistory').on('shown.bs.modal', function (event) {
|
||||||
|
var button = $(event.relatedTarget);
|
||||||
|
var modal = $(this);
|
||||||
|
|
||||||
|
modal.data('idteam', button.data('idteam'));
|
||||||
|
modal.data('kind', button.data('kind'));
|
||||||
|
modal.data('time', button.data('time'));
|
||||||
|
modal.data('secondary', button.data('secondary'));
|
||||||
|
modal.data('coeff', button.data('coeff'));
|
||||||
|
$('#historycoeff').val(button.data('coeff'));
|
||||||
|
$('#historycoeff').focus();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
@ -129,8 +129,8 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-lg-4" style="overflow-y: scroll; height: 95vh">
|
<div class="col-lg-4" style="overflow-y: scroll; height: 95vh" ng-controller="TeamHistoryController">
|
||||||
<table ng-controller="TeamHistoryController" class="table table-hover table-striped table-bordered bg-primary text-light">
|
<table class="table table-hover table-striped table-bordered bg-primary text-light">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="row in history" ng-class="{'bg-ffound': row.kind == 'flag_found', 'bg-mfound': row.kind == 'mcq_found', 'bg-wchoices': row.kind == 'wchoices', 'bg-success': row.kind == 'solved', 'bg-info': row.kind == 'hint', 'bg-warning': row.kind == 'tries'}">
|
<tr ng-repeat="row in history" ng-class="{'bg-ffound': row.kind == 'flag_found', 'bg-mfound': row.kind == 'mcq_found', 'bg-wchoices': row.kind == 'wchoices', 'bg-success': row.kind == 'solved', 'bg-info': row.kind == 'hint', 'bg-warning': row.kind == 'tries'}">
|
||||||
<td>
|
<td>
|
||||||
|
@ -151,10 +151,52 @@
|
||||||
<span ng-if="!row.secondary_title && row.secondary && row.kind != 'solved'">: {{ row.secondary }}</span>
|
<span ng-if="!row.secondary_title && row.secondary && row.kind != 'solved'">: {{ row.secondary }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td style="vertical-align: middle; padding: 0">
|
<td style="vertical-align: middle; padding: 0">
|
||||||
|
<button type="button" data-toggle="modal" data-target="#updHistory" ng-if="row.kind != 'flag_found' && row.kind != 'tries' && row.kind != 'mcq_found'" data-kind="{{ row.kind }}" data-time="{{ row.time }}" data-primary="{{ row.primary }}" data-secondary="{{ row.secondary }}" data-coeff="{{ row.coefficient }}" class="float-right btn btn-sm btn-info"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button>
|
||||||
<button type="button" ng-click="delHistory(row)" class="float-right btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
<button type="button" ng-click="delHistory(row)" class="float-right btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="modal fade" id="updHistory" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Édition de l'historique</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form ng-submit="updHistory()">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="historycoeff">Coefficient</label>
|
||||||
|
<input class="form-control" id="historycoeff">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
||||||
|
<button type="button" class="btn btn-primary" ng-click="updHistory()">Mettre à jour</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#updHistory').on('shown.bs.modal', function (event) {
|
||||||
|
var button = $(event.relatedTarget);
|
||||||
|
var modal = $(this);
|
||||||
|
|
||||||
|
modal.data('kind', button.data('kind'));
|
||||||
|
modal.data('time', button.data('time'));
|
||||||
|
modal.data('primary', button.data('primary'));
|
||||||
|
modal.data('secondary', button.data('secondary'));
|
||||||
|
modal.data('coeff', button.data('coeff'));
|
||||||
|
$('#historycoeff').val(button.data('coeff'));
|
||||||
|
$('#historycoeff').focus();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
@ -56,6 +56,37 @@ func (e Exercice) GetHistory() ([]map[string]interface{}, error) {
|
||||||
return hist, nil
|
return hist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateHistoryItem sets values an entry from the history.
|
||||||
|
func (e Exercice) UpdateHistoryItem(coeff float32, tId int64, kind string, h time.Time, secondary *int64) (interface{}, error) {
|
||||||
|
if kind == "hint" && secondary != nil {
|
||||||
|
if res, err := DBExec("UPDATE team_hints SET coefficient = ?, time = ? WHERE id_team = ? AND time = ? AND id_hint = ?", coeff, h, tId, h, *secondary); err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else if nb, err := res.RowsAffected(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else {
|
||||||
|
return nb, err
|
||||||
|
}
|
||||||
|
} else if kind == "wchoices" && secondary != nil {
|
||||||
|
if res, err := DBExec("UPDATE team_wchoices SET coefficient = ?, time = ? WHERE id_team = ? AND time = ? AND id_flag = ?", coeff, h, tId, h, *secondary); err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else if nb, err := res.RowsAffected(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else {
|
||||||
|
return nb, err
|
||||||
|
}
|
||||||
|
} else if kind == "solved" {
|
||||||
|
if res, err := DBExec("UPDATE exercice_solved SET coefficient = ?, time = ? WHERE id_team = ? AND time = ? AND id_exercice = ?", coeff, h, tId, h, e.Id); err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else if nb, err := res.RowsAffected(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else {
|
||||||
|
return nb, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DelHistoryItem removes from the database an entry from the history.
|
// DelHistoryItem removes from the database an entry from the history.
|
||||||
func (e Exercice) DelHistoryItem(tId int64, kind string, h time.Time, secondary *int64) (interface{}, error) {
|
func (e Exercice) DelHistoryItem(tId int64, kind string, h time.Time, secondary *int64) (interface{}, error) {
|
||||||
if kind == "tries" {
|
if kind == "tries" {
|
||||||
|
|
Reference in a new issue