admin: improve claims with related exercices
This commit is contained in:
parent
2e3f7c6894
commit
32dc9c1a8c
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
@ -11,9 +12,12 @@ import (
|
||||
|
||||
func init() {
|
||||
// Tasks
|
||||
router.GET("/api/claims/", apiHandler(getClaims))
|
||||
router.POST("/api/claims/", apiHandler(newClaim))
|
||||
router.DELETE("/api/claims/", apiHandler(clearClaims))
|
||||
router.GET("/api/claims", apiHandler(getClaims))
|
||||
router.POST("/api/claims", apiHandler(newClaim))
|
||||
router.DELETE("/api/claims", apiHandler(clearClaims))
|
||||
router.GET("/api/teams/:tid/claims", apiHandler(teamHandler(getTeamClaims)))
|
||||
router.GET("/api/exercices/:eid/claims", apiHandler(exerciceHandler(getExerciceClaims)))
|
||||
router.GET("/api/themes/:thid/exercices/:eid/claims", apiHandler(exerciceHandler(getExerciceClaims)))
|
||||
|
||||
router.GET("/api/claims/:cid", apiHandler(claimHandler(showClaim)))
|
||||
router.PUT("/api/claims/:cid", apiHandler(claimHandler(updateClaim)))
|
||||
@ -21,8 +25,8 @@ func init() {
|
||||
router.DELETE("/api/claims/:cid", apiHandler(claimHandler(deleteClaim)))
|
||||
|
||||
// Assignees
|
||||
router.GET("/api/claims-assignees/", apiHandler(getAssignees))
|
||||
router.POST("/api/claims-assignees/", apiHandler(newAssignee))
|
||||
router.GET("/api/claims-assignees", apiHandler(getAssignees))
|
||||
router.POST("/api/claims-assignees", apiHandler(newAssignee))
|
||||
|
||||
router.GET("/api/claims-assignees/:aid", apiHandler(claimAssigneeHandler(showClaimAssignee)))
|
||||
router.PUT("/api/claims-assignees/:aid", apiHandler(claimAssigneeHandler(updateClaimAssignee)))
|
||||
@ -33,6 +37,14 @@ func getClaims(_ httprouter.Params, _ []byte) (interface{}, error) {
|
||||
return fic.GetClaims()
|
||||
}
|
||||
|
||||
func getTeamClaims(team fic.Team, _ []byte) (interface{}, error) {
|
||||
return team.GetClaims()
|
||||
}
|
||||
|
||||
func getExerciceClaims(exercice fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return exercice.GetClaims()
|
||||
}
|
||||
|
||||
type ClaimExported struct {
|
||||
Id int64 `json:"id"`
|
||||
Subject string `json:"subject"`
|
||||
@ -97,6 +109,10 @@ func newClaim(_ httprouter.Params, body []byte) (interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if uc.Subject == "" {
|
||||
return nil, errors.New("Claim's subject cannot be empty.")
|
||||
}
|
||||
|
||||
var t *fic.Team
|
||||
if uc.Team != nil {
|
||||
if team, err := fic.GetTeam(*uc.Team); err != nil {
|
||||
@ -130,6 +146,10 @@ func newClaim(_ httprouter.Params, body []byte) (interface{}, error) {
|
||||
a = nil
|
||||
}
|
||||
|
||||
if uc.Priority == "" {
|
||||
uc.Priority = "medium"
|
||||
}
|
||||
|
||||
return fic.NewClaim(uc.Subject, t, e, a, uc.Priority)
|
||||
}
|
||||
|
||||
|
@ -229,6 +229,9 @@ angular.module("FICApp")
|
||||
patch: {method: 'PATCH'}
|
||||
})
|
||||
})
|
||||
.factory("ExerciceClaims", function($resource) {
|
||||
return $resource("/api/exercices/:exerciceId/claims", { exerciceId: '@idExercice'})
|
||||
})
|
||||
.factory("ExerciceTags", function($resource) {
|
||||
return $resource("/api/exercices/:exerciceId/tags", { exerciceId: '@idExercice'}, {
|
||||
update: {method: 'PUT'}
|
||||
@ -267,7 +270,7 @@ angular.module("FICApp")
|
||||
}
|
||||
})
|
||||
.filter("toColor", function() {
|
||||
return function(input) {
|
||||
return function(num) {
|
||||
num >>>= 0;
|
||||
var b = num & 0xFF,
|
||||
g = (num & 0xFF00) >>> 8,
|
||||
@ -1056,14 +1059,14 @@ angular.module("FICApp")
|
||||
$location.url("/claims/" + id);
|
||||
};
|
||||
})
|
||||
.controller("ClaimController", function($scope, Claim, ClaimAssignee, Teams, Exercice, $routeParams, $location, $http) {
|
||||
.controller("ClaimController", function($scope, Claim, ClaimAssignee, Teams, Exercice, $routeParams, $location, $http, $rootScope) {
|
||||
$scope.claim = Claim.get({ claimId: $routeParams.claimId }, function(v) {
|
||||
v.id_team = "" + v.id_team;
|
||||
if (!v.priority)
|
||||
v.priority = "medium";
|
||||
});
|
||||
if ($routeParams.claimId == "new")
|
||||
$scope.fields = ["id_team", "subject", "priority", "id_exercice", "id_assignee"];
|
||||
$scope.fields = ["id_team", "id_exercice", "subject", "priority", "id_assignee"];
|
||||
else
|
||||
$scope.fields = ["state", "subject", "priority", "id_exercice", "id_assignee", "id_team", "creation"];
|
||||
$scope.assignees = ClaimAssignee.query();
|
||||
@ -1132,6 +1135,8 @@ angular.module("FICApp")
|
||||
if (!this.ndescription)
|
||||
this.ndescription = "Création de la tâche";
|
||||
$scope.saveDescription();
|
||||
}, function(response) {
|
||||
$rootScope.newBox('danger', 'An error occurs when trying to save claim:', response.data.errmsg);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1362,6 +1367,22 @@ angular.module("FICApp")
|
||||
}
|
||||
})
|
||||
|
||||
.controller("ExerciceClaimsController", function($scope, ExerciceClaims, Team, ClaimAssignee, $routeParams, $location) {
|
||||
$scope.claims = ExerciceClaims.query({ exerciceId: $routeParams.exerciceId });
|
||||
$scope.assignees = ClaimAssignee.query();
|
||||
|
||||
$scope.claims.$promise.then(function(claims) {
|
||||
claims.forEach(function(claim, cid) {
|
||||
$scope.claims[cid].team = Team.get({ teamId: claim.id_team });
|
||||
})
|
||||
});
|
||||
|
||||
$scope.showClosed = false;
|
||||
$scope.show = function(id) {
|
||||
$location.url("/claims/" + id);
|
||||
};
|
||||
})
|
||||
|
||||
.controller("ExerciceTagsController", function($scope, ExerciceTags, $routeParams, $rootScope) {
|
||||
$scope.tags = ExerciceTags.query({ exerciceId: $routeParams.exerciceId });
|
||||
|
||||
|
@ -9,8 +9,13 @@
|
||||
<input type="text" class="form-control form-control-sm" id="{{ field }}" ng-model="claim[field]" ng-if="field != 'state' && field != 'priority' && field != 'creation' && field != 'id_team' && field != 'id_exercice' && field != 'id_assignee' && field != 'description'">
|
||||
<input type="datetime" class="form-control form-control-sm" id="{{ field }}" ng-model="claim[field]" ng-if="field == 'creation' && claim.id">
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="k as v for (k, v) in states" ng-if="field == 'state'"></select>
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="k as v for (k, v) in priorities" ng-if="field == 'priority'"><option value="medium">Par défaut</option></select>
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="ex.id as ex.title group by ex.path.split('/')[0] for ex in exercices" ng-if="field == 'id_exercice'"><option></option></select>
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="k as v for (k, v) in priorities" ng-if="field == 'priority'"></select>
|
||||
<div class="input-group" ng-if="field == 'id_exercice'">
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="ex.id as ex.title group by ex.path.split('/')[0] for ex in exercices"><option></option></select>
|
||||
<div class="input-group-append" ng-if="claim.id_exercice">
|
||||
<a type="button" class="btn btn-sm btn-outline-secondary" ng-href="exercices/{{ claim.id_exercice }}">Aller au challenge</a>
|
||||
</div>
|
||||
</div>
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="k as t.name for (k, t) in teams" ng-if="field == 'id_team' && !claim.id"><option></option></select>
|
||||
<div class="input-group" ng-if="field == 'id_team' && claim.id">
|
||||
<select class="custom-select custom-select-sm" id="{{ field }}" ng-model="claim[field]" ng-options="k as t.name for (k, t) in teams"><option></option></select>
|
||||
|
@ -35,6 +35,20 @@
|
||||
</form>
|
||||
|
||||
<div class="col-md-4 accordion" ng-show="exercice.id" id="accordionExercice">
|
||||
|
||||
<div class="mb-2" style="overflow-y: auto; max-height: 250px" ng-controller="ExerciceClaimsController" ng-show="claims.length">
|
||||
<table class="table table-sm table-hover table-striped">
|
||||
<tbody>
|
||||
<tr ng-repeat="claim in claims | orderBy: 'priority'" ng-click="show(claim.id)" ng-class="{'table-info': claim.priority == 'medium', 'table-warning': claim.priority == 'high', 'table-danger': claim.priority == 'critical'}" ng-if="showClosed || (claim.state != 'closed' && claim.state != 'invalid')">
|
||||
<td ng-bind="claim.subject"></td>
|
||||
<td><a ng-href="teams/{{ claim.id_team}}" style="background-color: {{ claim.team.color | toColor }}" ng-bind="claim.team.name"></a></td>
|
||||
<td ng-bind="claim.state"></td>
|
||||
<td ng-repeat="assignee in assignees" ng-if="assignee.id == claim.id_assignee" ng-bind="assignee.name"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card border-secondary" ng-controller="ExerciceFilesController">
|
||||
<div class="card-header bg-secondary text-light" type="button" data-toggle="collapse" data-target="#collapseFiles" aria-expanded="true" aria-controls="collapseFiles">
|
||||
<h4 class="m-0"><small class="glyphicon glyphicon-chevron-right" aria-hidden="true"></small> Téléchargements</h4>
|
||||
|
@ -46,7 +46,27 @@ func GetClaims() (res []Claim, err error) {
|
||||
// GetClaims returns a list of all Claim registered for the Team.
|
||||
func (t Team) GetClaims() (res []Claim, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = DBQuery("SELECT id_claim, subject, id_team, id_exercice, id_assignee, creation, state, priority FROM claims WHERE IdTeam = ?", t.Id); err != nil {
|
||||
if rows, err = DBQuery("SELECT id_claim, subject, id_team, id_exercice, id_assignee, creation, state, priority FROM claims WHERE id_team = ?", t.Id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var c Claim
|
||||
if err = rows.Scan(&c.Id, &c.Subject, &c.IdTeam, &c.IdExercice, &c.IdAssignee, &c.Creation, &c.State, &c.Priority); err != nil {
|
||||
return
|
||||
}
|
||||
res = append(res, c)
|
||||
}
|
||||
err = rows.Err()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetExercices returns a list of all Claim registered for the Exercice.
|
||||
func (e Exercice) GetClaims() (res []Claim, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = DBQuery("SELECT id_claim, subject, id_team, id_exercice, id_assignee, creation, state, priority FROM claims WHERE id_exercice = ?", e.Id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
Loading…
Reference in New Issue
Block a user