QA: add a list of team's exercices
This commit is contained in:
parent
911bcb032e
commit
ea334a8a2f
11
libfic/db.go
11
libfic/db.go
@ -457,6 +457,17 @@ CREATE TABLE IF NOT EXISTS teams_qa_todo(
|
||||
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice),
|
||||
FOREIGN KEY(id_team) REFERENCES teams(id_team)
|
||||
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||||
`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS teams_qa_view(
|
||||
id_view INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
id_team INTEGER NOT NULL,
|
||||
id_exercice INTEGER NOT NULL,
|
||||
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice),
|
||||
FOREIGN KEY(id_team) REFERENCES teams(id_team)
|
||||
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||||
`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
31
libfic/qa.go
31
libfic/qa.go
@ -238,3 +238,34 @@ func (t Team) NewQATodo(idExercice int64) (QATodo, error) {
|
||||
return QATodo{tid, t.Id, idExercice}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// QAView
|
||||
|
||||
func (t Team) GetQAView() (res []QATodo, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = DBQuery("SELECT id_view, id_exercice FROM teams_qa_view WHERE id_team = ?", t.Id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var t QATodo
|
||||
if err = rows.Scan(&t.Id, &t.IdExercice); err != nil {
|
||||
return
|
||||
}
|
||||
res = append(res, t)
|
||||
}
|
||||
err = rows.Err()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (t Team) NewQAView(idExercice int64) (QATodo, error) {
|
||||
if res, err := DBExec("INSERT INTO teams_qa_view (id_team, id_exercice) VALUES (?, ?)", t.Id, idExercice); err != nil {
|
||||
return QATodo{}, err
|
||||
} else if tid, err := res.LastInsertId(); err != nil {
|
||||
return QATodo{}, err
|
||||
} else {
|
||||
return QATodo{tid, t.Id, idExercice}, nil
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
func init() {
|
||||
router.GET("/api/qa_exercices.json", apiHandler(getExerciceTested))
|
||||
router.GET("/api/qa_mywork.json", apiHandler(getQAWork))
|
||||
router.GET("/api/qa_myexercices.json", apiHandler(getQAView))
|
||||
router.POST("/api/qa_my_exercices.json", apiHandler(addQAView))
|
||||
router.GET("/api/qa_work.json", apiHandler(getQATodo))
|
||||
router.POST("/api/qa_work.json", apiHandler(createQATodo))
|
||||
}
|
||||
@ -42,6 +44,14 @@ func getExerciceTested(u QAUser, ps httprouter.Params, body []byte) (interface{}
|
||||
}
|
||||
}
|
||||
|
||||
func getQAView(u QAUser, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
if team, err := fic.GetTeam(u.TeamId); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return team.GetQAView()
|
||||
}
|
||||
}
|
||||
|
||||
func getQAWork(u QAUser, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
if team, err := fic.GetTeam(u.TeamId); err != nil {
|
||||
return nil, err
|
||||
@ -74,3 +84,20 @@ func createQATodo(u QAUser, ps httprouter.Params, body []byte) (interface{}, err
|
||||
return team.NewQATodo(ut.IdExercice)
|
||||
}
|
||||
}
|
||||
|
||||
func addQAView(u QAUser, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
if u.User != "nemunaire" {
|
||||
return nil, errors.New("Restricted")
|
||||
}
|
||||
|
||||
var ut fic.QATodo
|
||||
if err := json.Unmarshal(body, &ut); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if team, err := fic.GetTeam(ut.IdTeam); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return team.NewQAView(ut.IdExercice)
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,9 @@ angular.module("FICApp")
|
||||
.factory("TodoWorked", function($resource) {
|
||||
return $resource("api/qa_mywork.json")
|
||||
})
|
||||
.factory("MyExercices", function($resource) {
|
||||
return $resource("api/qa_myexercices.json")
|
||||
})
|
||||
.factory("ExercicesTested", function($resource) {
|
||||
return $resource("api/qa_exercices.json")
|
||||
})
|
||||
@ -240,6 +243,14 @@ angular.module("FICApp")
|
||||
};
|
||||
})
|
||||
|
||||
.controller("MyExercicesController", function($scope, MyExercices, $location) {
|
||||
$scope.my_exercices = MyExercices.query();
|
||||
|
||||
$scope.show = function(id) {
|
||||
$location.url("/exercices/" + id);
|
||||
};
|
||||
})
|
||||
|
||||
.controller("ThemesListController", function($scope, Theme, $location, $rootScope, $http) {
|
||||
$scope.themes = Theme.query();
|
||||
$scope.fields = ["name", "authors", "headline"];
|
||||
@ -342,7 +353,27 @@ angular.module("FICApp")
|
||||
})
|
||||
|
||||
.controller("ExerciceQAController", function($scope, $rootScope, ExerciceQA, $routeParams, $location, $http) {
|
||||
if ($routeParams.exerciceId) {
|
||||
$scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId });
|
||||
} else {
|
||||
$scope.queries = ExerciceQA.query({ exerciceId: $scope.todo.id_exercice });
|
||||
}
|
||||
$scope.queriesNSolved = "N/A"
|
||||
$scope.queriesNClosed = "N/A"
|
||||
$scope.queries.$promise.then(function (queries) {
|
||||
var nbResolved = 0;
|
||||
var nbClosed = 0;
|
||||
queries.forEach(function(q) {
|
||||
if (q.solved) {
|
||||
nbResolved++;
|
||||
}
|
||||
if (q.closed) {
|
||||
nbClosed++;
|
||||
}
|
||||
})
|
||||
$scope.queriesNSolved = queries.length - nbResolved
|
||||
$scope.queriesNClosed = queries.length - nbClosed
|
||||
})
|
||||
$scope.fields = ["state", "subject", "user", "creation"];
|
||||
$scope.namedFields = {
|
||||
"state": "État",
|
||||
|
@ -1,9 +1,17 @@
|
||||
<div class="jumbotron text-light bg-dark">
|
||||
<h1 class="display-5">Interface QA du challenge</h1>
|
||||
<div class="jumbotron">
|
||||
<div class="row">
|
||||
<div class="col" ng-controller="ToDoController">
|
||||
<table class="table table-stripped">
|
||||
<tr ng-repeat="todo in todos" ng-controller="MyTodoExerciceController" ng-class="{'bg-dark': !tododone[todo.id_exercice] && !exo_done[todo.id_exercice], 'bg-warning': !tododone[todo.id_exercice] && exo_done[todo.id_exercice] == 'access', 'bg-info': !tododone[todo.id_exercice] && (exo_done[todo.id_exercice] == 'tried' || exo_done[todo.id_exercice] == 'solved'), 'bg-success': tododone[todo.id_exercice]}" ng-click="show(todo.id_exercice)">
|
||||
<div class="col-6" ng-controller="ToDoController">
|
||||
<h3>Challenges à valider</h3>
|
||||
<table class="table table-stripped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Avancement</th>
|
||||
<th>Scénario</th>
|
||||
<th>Défi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="todo in todos" ng-controller="MyTodoExerciceController" ng-class="{'text-light': !tododone[todo.id_exercice] && !exo_done[todo.id_exercice], 'table-dark': !tododone[todo.id_exercice] && !exo_done[todo.id_exercice], 'table-warning': !tododone[todo.id_exercice] && exo_done[todo.id_exercice] == 'access', 'table-info': !tododone[todo.id_exercice] && (exo_done[todo.id_exercice] == 'tried' || exo_done[todo.id_exercice] == 'solved'), 'table-success': tododone[todo.id_exercice]}" ng-click="show(todo.id_exercice)">
|
||||
<td ng-if="!tododone[todo.id_exercice] && (!exo_done[todo.id_exercice] || exo_done[todo.id_exercice] == 'access')">
|
||||
À tester
|
||||
</td>
|
||||
@ -20,6 +28,29 @@
|
||||
{{ myexercice.title }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-6" ng-controller="MyExercicesController">
|
||||
<h3>Vos challenges</h3>
|
||||
<table class="table table-stripped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Défi</th>
|
||||
<th>Requêtes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="todo in my_exercices" ng-controller="ExerciceQAController" ng-class="{'table-success': queries.length > 0, 'table-warning': queriesNSolved > 0}" ng-click="show(todo.id_exercice)">
|
||||
<td ng-controller="MyTodoExerciceController">
|
||||
<span ng-if="mytheme.name">{{ mytheme.name }} –</span>
|
||||
{{ myexercice.title }}
|
||||
</td>
|
||||
<td>
|
||||
{{ queriesNSolved }} / {{ queriesNClosed }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user