admin: interface to edit teams
This commit is contained in:
parent
e1c4feaa1c
commit
d4110c70c8
|
@ -36,6 +36,7 @@ func init() {
|
|||
router.GET("/api/teams/:tid/", apiHandler(teamHandler(
|
||||
func(team fic.Team, _ []byte) (interface{}, error) {
|
||||
return team, nil })))
|
||||
router.PUT("/api/teams/:tid/", apiHandler(teamHandler(updateTeam)))
|
||||
router.POST("/api/teams/:tid/", apiHandler(teamHandler(addTeamMember)))
|
||||
router.DELETE("/api/teams/:tid/", apiHandler(teamHandler(
|
||||
func(team fic.Team, _ []byte) (interface{}, error) {
|
||||
|
@ -60,6 +61,8 @@ func init() {
|
|||
router.GET("/api/teams/:tid/members", apiHandler(teamHandler(
|
||||
func(team fic.Team, _ []byte) (interface{}, error) {
|
||||
return team.GetMembers() })))
|
||||
router.POST("/api/teams/:tid/members", apiHandler(teamHandler(addTeamMember)))
|
||||
router.PUT("/api/teams/:tid/members", apiHandler(teamHandler(setTeamMember)))
|
||||
router.GET("/api/teams/:tid/name", apiHandler(teamHandler(
|
||||
func(team fic.Team, _ []byte) (interface{}, error) {
|
||||
return team.InitialName, nil })))
|
||||
|
@ -141,6 +144,21 @@ func createTeam(_ httprouter.Params, body []byte) (interface{}, error) {
|
|||
return fic.CreateTeam(strings.TrimSpace(ut.Name), ut.Color)
|
||||
}
|
||||
|
||||
func updateTeam(team fic.Team, body []byte) (interface{}, error) {
|
||||
var ut fic.Team
|
||||
if err := json.Unmarshal(body, &ut); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ut.Id = team.Id
|
||||
|
||||
if _, err := ut.Update(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ut, nil
|
||||
}
|
||||
|
||||
func addTeamMember(team fic.Team, body []byte) (interface{}, error) {
|
||||
var members []uploadedMember
|
||||
if err := json.Unmarshal(body, &members); err != nil {
|
||||
|
@ -154,6 +172,20 @@ func addTeamMember(team fic.Team, body []byte) (interface{}, error) {
|
|||
return team.GetMembers()
|
||||
}
|
||||
|
||||
func setTeamMember(team fic.Team, body []byte) (interface{}, error) {
|
||||
var members []uploadedMember
|
||||
if err := json.Unmarshal(body, &members); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
team.ClearMembers()
|
||||
for _, member := range members {
|
||||
team.AddMember(strings.TrimSpace(member.Firstname), strings.TrimSpace(member.Lastname), strings.TrimSpace(member.Nickname), strings.TrimSpace(member.Company))
|
||||
}
|
||||
|
||||
return team.GetMembers()
|
||||
}
|
||||
|
||||
func dispMemberTeam(ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
if mid, err := strconv.Atoi(string(ps.ByName("mid"))); err != nil {
|
||||
return fic.Team{}, err
|
||||
|
|
|
@ -30,6 +30,10 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"])
|
|||
templateUrl: "views/team-list.html"
|
||||
})
|
||||
.when("/teams/:teamId", {
|
||||
controller: "TeamController",
|
||||
templateUrl: "views/team-edit.html"
|
||||
})
|
||||
.when("/teams/:teamId/stats", {
|
||||
controller: "TeamController",
|
||||
templateUrl: "views/team.html"
|
||||
})
|
||||
|
@ -80,7 +84,9 @@ angular.module("FICApp")
|
|||
})
|
||||
})
|
||||
.factory("TeamMember", function($resource) {
|
||||
return $resource("/api/teams/:teamId/members", { teamId: '@id' })
|
||||
return $resource("/api/teams/:teamId/members", { teamId: '@id' }, {
|
||||
'save': {method: 'PUT'},
|
||||
})
|
||||
})
|
||||
.factory("TeamMy", function($resource) {
|
||||
return $resource("/api/teams/:teamId/my.json", { teamId: '@id' })
|
||||
|
@ -146,6 +152,16 @@ angular.module("FICApp")
|
|||
return input.capitalize();
|
||||
}
|
||||
})
|
||||
.filter("toColor", function() {
|
||||
return function(input) {
|
||||
num >>>= 0;
|
||||
var b = num & 0xFF,
|
||||
g = (num & 0xFF00) >>> 8,
|
||||
r = (num & 0xFF0000) >>> 16,
|
||||
a = ( (num & 0xFF000000) >>> 24 ) / 255 ;
|
||||
return "#" + r.toString(16) + g.toString(16) + b.toString(16);
|
||||
}
|
||||
})
|
||||
.filter("size", function() {
|
||||
var units = [
|
||||
"o",
|
||||
|
@ -193,6 +209,31 @@ angular.module("FICApp")
|
|||
}
|
||||
})
|
||||
|
||||
.directive('color', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, ele, attr, ctrl){
|
||||
ctrl.$formatters.unshift(function(num){
|
||||
num >>>= 0;
|
||||
var b = num & 0xFF,
|
||||
g = (num & 0xFF00) >>> 8,
|
||||
r = (num & 0xFF0000) >>> 16,
|
||||
a = ( (num & 0xFF000000) >>> 24 ) / 255 ;
|
||||
return "#" + r.toString(16) + g.toString(16) + b.toString(16);
|
||||
});
|
||||
ctrl.$parsers.unshift(function(viewValue){
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(viewValue);
|
||||
return result ? (
|
||||
parseInt(result[1], 16) * 256 * 256 +
|
||||
parseInt(result[2], 16) * 256 +
|
||||
parseInt(result[3], 16)
|
||||
|
||||
) : 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('integer', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
|
@ -472,9 +513,44 @@ angular.module("FICApp")
|
|||
$location.url("/teams/" + id);
|
||||
};
|
||||
})
|
||||
.controller("TeamController", function($scope, Team, TeamMember, $routeParams) {
|
||||
.controller("TeamMembersController", function($scope, TeamMember, $routeParams) {
|
||||
$scope.fields = ["firstname", "lastname", "nickname", "company"];
|
||||
|
||||
})
|
||||
.controller("TeamController", function($scope, $location, Team, TeamMember, $routeParams) {
|
||||
$scope.team = Team.get({ teamId: $routeParams.teamId });
|
||||
$scope.fields = ["name", "color"];
|
||||
$scope.members = TeamMember.query({ teamId: $routeParams.teamId });
|
||||
|
||||
$scope.saveTeam = function() {
|
||||
if (this.team.id) {
|
||||
this.team.$update();
|
||||
} else {
|
||||
this.team.$save(function() {
|
||||
$location.url("/teams/" + $scope.team.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
$scope.deleteTeam = function() {
|
||||
this.team.$remove(function() { $location.url("/teams/");});
|
||||
}
|
||||
$scope.showStats = function() {
|
||||
$location.url("/teams/" + $scope.team.id + "/stats");
|
||||
}
|
||||
$scope.newMember = function() {
|
||||
$scope.members.push(new TeamMember());
|
||||
}
|
||||
$scope.saveTeamMembers = function() {
|
||||
if (this.team.id) {
|
||||
TeamMember.save({ teamId: this.team.id }, $scope.members);
|
||||
}
|
||||
}
|
||||
$scope.removeMember = function(member) {
|
||||
angular.forEach($scope.members, function(m, k) {
|
||||
if (member == m)
|
||||
$scope.members.splice(k, 1);
|
||||
});
|
||||
}
|
||||
})
|
||||
.controller("TeamStatsController", function($scope, TeamStats, $routeParams) {
|
||||
$scope.teamstats = TeamStats.get({ teamId: $routeParams.teamId });
|
||||
|
|
48
admin/static/views/team-edit.html
Normal file
48
admin/static/views/team-edit.html
Normal file
|
@ -0,0 +1,48 @@
|
|||
<h1>{{ team.name }}<span ng-show="team.name != team.initialName"> ({{ team.initialName}})</span> <small><span ng-repeat="member in members"><span ng-show="$last && !$first"> et </span><span ng-show="$middle">, </span>{{ member.firstname | capitalize }} <em ng-show="member.nickname">{{ member.nickname }}</em> {{ member.lastname | capitalize }}</span></small><a ng-click="showStats()" class="pull-right btn btn-primary" style="margin-right: 10px" ng-if="team.id"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> Statistiques</a></h1>
|
||||
|
||||
<form ng-submit="saveTeam()" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="idTeam" class="col-sm-2 control-label">Identifiant</label>
|
||||
<div class="col-sm-10">
|
||||
{{ team.id }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="initialName" class="col-sm-2 control-label">Nom initial</label>
|
||||
<div class="col-sm-10">
|
||||
{{ team.initialName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-repeat="field in fields">
|
||||
<label for="{{ field }}" class="col-sm-2 control-label">{{ field | capitalize }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="{{ field }}" ng-model="team[field]" ng-if="field != 'color'">
|
||||
<input type="color" class="form-control" id="{{ field }}{{ member.id }}" ng-model="team[field]" ng-if="field == 'color'" color>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right" ng-show="team.id">
|
||||
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Save</button>
|
||||
<a class="btn btn-danger" ng-click="deleteTeam()"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a>
|
||||
</div>
|
||||
<div class="text-right" ng-show="!team.id">
|
||||
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Create theme</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<form ng-submit="saveTeamMembers()" class="form-horizontal" ng-if="team.id">
|
||||
<h2>Membres <button type="submit" class="pull-right btn btn-success" style="margin-left: 10px"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Save members</button><a ng-click="newMember()" class="pull-right btn btn-primary"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add member</a></h2>
|
||||
|
||||
<div class="well" ng-controller="TeamMembersController" ng-repeat="member in members">
|
||||
<div class="form-group" ng-repeat="field in fields">
|
||||
<label for="{{ field }}{{ member.id }}" class="col-sm-2 control-label">{{ field | capitalize }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="{{ field }}{{ member.id }}" ng-model="member[field]">
|
||||
</div>
|
||||
<div class="col-sm-1" ng-if="$first">
|
||||
<a ng-click="removeMember(member)" class="pull-right btn btn-primary"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
|
@ -1,4 +1,4 @@
|
|||
<h2>Équipes</h2>
|
||||
<h2>Équipes<a ng-click="show('new')" class="pull-right btn btn-primary"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter une équipe</a></h2>
|
||||
|
||||
<p><input type="search" class="form-control" placeholder="Search" ng-model="query"></p>
|
||||
<table class="table table-hover table-bordered">
|
||||
|
|
|
@ -80,3 +80,13 @@ func (m Member) Delete() (int64, error) {
|
|||
return nb, err
|
||||
}
|
||||
}
|
||||
|
||||
func (t Team) ClearMembers() (int64, error) {
|
||||
if res, err := DBExec("DELETE FROM team_members WHERE id_team = ?", t.Id); err != nil {
|
||||
return 0, err
|
||||
} else if nb, err := res.RowsAffected(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return nb, err
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user