Commit 61d4f32694a7eea32f66bf3c37ecf7da5b506010

Authored by Geoffrey PREUD'HOMME
1 parent 74d33075

Gestion des dossiers

Fix #5
app/models/ConvModl.js
@@ -4,6 +4,10 @@ module.exports = mongoose.model('Conv', { @@ -4,6 +4,10 @@ module.exports = mongoose.model('Conv', {
4 titre: { 4 titre: {
5 type: String, 5 type: String,
6 default: "Conversation" 6 default: "Conversation"
  7 + },
  8 + parent: {
  9 + type: String,
  10 + default: 'lost'
7 } 11 }
8 // TODO Visibilité (brouillon) 12 // TODO Visibilité (brouillon)
9 // TODO Répertoire 13 // TODO Répertoire
app/models/DossModl.js 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +var mongoose = require('mongoose');
  2 +
  3 +module.exports = mongoose.model('Doss', {
  4 + titre: {
  5 + type: String,
  6 + default: "Dossier"
  7 + },
  8 + parent: {
  9 + type: String,
  10 + default: 'lost'
  11 + },
  12 + special: {
  13 + type: String,
  14 + default: ''
  15 + }
  16 + // TODO Visibilité (brouillon)
  17 +});
app/routes/ApiRtes.js
1 var MembresServ = require('../services/MembresServ'); 1 var MembresServ = require('../services/MembresServ');
2 var PolyUserServ = require('../services/PolyUserServ'); 2 var PolyUserServ = require('../services/PolyUserServ');
3 var DecryptServ = require('../services/DecryptServ'); 3 var DecryptServ = require('../services/DecryptServ');
  4 +var DosssServ = require('../services/DosssServ');
4 var ConvsServ = require('../services/ConvsServ'); 5 var ConvsServ = require('../services/ConvsServ');
5 var MessServ = require('../services/MessServ'); 6 var MessServ = require('../services/MessServ');
6 var fs = require('fs'); 7 var fs = require('fs');
@@ -94,6 +95,8 @@ sessionData = function (session, cb) { @@ -94,6 +95,8 @@ sessionData = function (session, cb) {
94 session.canDelConv = session.bureau; 95 session.canDelConv = session.bureau;
95 session.canAddMess = true; 96 session.canAddMess = true;
96 session.canDelMess = session.bureau; 97 session.canDelMess = session.bureau;
  98 + session.canAddDoss = session.bureau;
  99 + session.canDelDoss = session.bureau;
97 cb(session); 100 cb(session);
98 }); 101 });
99 }); 102 });
@@ -184,17 +187,58 @@ api.delete('/membres/:membre_id', reqPerm('canDelMembre'), function (req, res) { @@ -184,17 +187,58 @@ api.delete('/membres/:membre_id', reqPerm('canDelMembre'), function (req, res) {
184 }); 187 });
185 }); 188 });
186 189
  190 +// Dossiers
  191 +api.get('/dosss/:doss_id', function (req, res) { // Un doss
  192 + // TODO Assertion 404 existe, transformer req.body.id avec la vraie id (ou redirect)
  193 + // TODO Requêtes séparées ?
  194 + DosssServ.get(req.params.doss_id, function (err, doss) { // TODO Async
  195 + if (err) {
  196 + res.status(500).send(err);
  197 + } else if (!doss) {
  198 + res.status(404);
  199 + } else {
  200 + DosssServ.children(doss._id, function (err, dosss) {
  201 + if (err) {
  202 + res.status(500).send(err);
  203 + } else {
  204 + doss.dosss = dosss;
  205 + ConvsServ.children(doss._id, function (err, convs) {
  206 + if (err) {
  207 + res.status(500).send(err);
  208 + } else {
  209 + doss.convs = convs;
  210 + res.json(doss);
  211 + }
  212 + });
  213 + }
  214 + });
  215 + }
  216 + });
  217 +});
187 218
188 -// Conversations  
189 -api.get('/convs', function (req, res) { // Liste des convs  
190 - ConvsServ.list(function (err, convs) { 219 +api.post('/dosss', reqPerm('canAddDoss'), function (req, res) { // Ajout d'un doss
  220 + // TODO Assertion 404 existe, transformer req.body.id avec la vraie id (ou redirect)
  221 + DosssServ.getId(req.body.parent, function (parent) { // TODO Async
  222 + req.body.parent = parent;
  223 + DosssServ.add(req.body, function (err, doss) {
  224 + if (err)
  225 + res.status(500).send(err);
  226 + else
  227 + res.json(doss);
  228 + });
  229 + });
  230 +});
  231 +
  232 +api.delete('/dosss/:doss_id', reqPerm('canDelDoss'), function (req, res) { // Supression d'un doss
  233 + DosssServ.remove(req.params.doss_id, function (err, doss) {
191 if (err) 234 if (err)
192 res.status(500).send(err); 235 res.status(500).send(err);
193 else 236 else
194 - res.json(convs); 237 + res.json(null);
195 }); 238 });
196 }); 239 });
197 240
  241 +// Conversations
198 api.get('/convs/:conv_id', function (req, res) { // Une conv 242 api.get('/convs/:conv_id', function (req, res) { // Une conv
199 ConvsServ.get(req.params.conv_id, function (err, conv) { 243 ConvsServ.get(req.params.conv_id, function (err, conv) {
200 if (err) 244 if (err)
@@ -205,11 +249,15 @@ api.get('/convs/:conv_id', function (req, res) { // Une conv @@ -205,11 +249,15 @@ api.get('/convs/:conv_id', function (req, res) { // Une conv
205 }); 249 });
206 250
207 api.post('/convs', reqPerm('canAddConv'), function (req, res) { // Ajout d'un conv 251 api.post('/convs', reqPerm('canAddConv'), function (req, res) { // Ajout d'un conv
208 - ConvsServ.add(req.body, function (err, conv) {  
209 - if (err)  
210 - res.status(500).send(err);  
211 - else  
212 - res.json(conv); 252 + // TODO Assertion 404 existe, transformer req.body.id avec la vraie id (ou redirect)
  253 + DosssServ.getId(req.body.parent, function (parent) { // TODO Async
  254 + req.body.parent = parent;
  255 + ConvsServ.add(req.body, function (err, conv) {
  256 + if (err)
  257 + res.status(500).send(err);
  258 + else
  259 + res.json(conv);
  260 + });
213 }); 261 });
214 }); 262 });
215 263
app/services/ConvsServ.js
@@ -42,9 +42,18 @@ ConvsServ.list = function (cb) { // TODO Visibilité @@ -42,9 +42,18 @@ ConvsServ.list = function (cb) { // TODO Visibilité
42 }); 42 });
43 }; 43 };
44 44
  45 +ConvsServ.children = function (id, cb) {
  46 + ConvModl.find({
  47 + parent: id
  48 + }).lean().exec(function (err, Conv) {
  49 + async.mapSeries(Conv, ConvsServ.addData, cb);
  50 + });
  51 +};
  52 +
45 ConvsServ.add = function (data, cb) { 53 ConvsServ.add = function (data, cb) {
46 ConvModl.create({ 54 ConvModl.create({
47 - titre: data.titre 55 + titre: data.titre,
  56 + parent: data.parent
48 }, function (err, Conv) { 57 }, function (err, Conv) {
49 ConvsServ.get(Conv._id, cb); 58 ConvsServ.get(Conv._id, cb);
50 }); 59 });
app/services/DosssServ.js 0 → 100644
@@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
  1 +var DossModl = require('../models/DossModl');
  2 +// var PolyUserServ = require('../services/PolyUserServ');
  3 +var async = require('async');
  4 +
  5 +var DosssServ = {};
  6 +
  7 +(function init() {
  8 + DossModl.find({
  9 + special: 'root'
  10 + }).exec(function (err, data) {
  11 + if (data.length < 1) {
  12 + DossModl.create({
  13 + special: 'root',
  14 + titre: 'Racine'
  15 + });
  16 + }
  17 + });
  18 +})();
  19 +
  20 +DosssServ.addData = function (doss, cb) {
  21 + // PolyUserServ.get(Doss.login, function (err, nom) {
  22 + // if (nom) {
  23 + // Doss.nom = nom;
  24 + // } else {
  25 + // Doss.nom = Doss.login;
  26 + // }
  27 + // cb(null, Doss);
  28 + // });
  29 + // TODO Dernier message
  30 + cb(null, doss);
  31 +};
  32 +
  33 +DosssServ.exists = function (id, cb) {
  34 + DossModl.findById(id).exec(function (err, doss) {
  35 + if (err)
  36 + cb(err);
  37 + else
  38 + cb(null, true);
  39 + });
  40 +};
  41 +
  42 +DosssServ.getId = function (special, cb) {
  43 + DossModl.findById(special).exec(function (err, doss) {
  44 + if (!err && doss) {
  45 + cb(doss._id); // Équivalent à cb(special)
  46 + } else {
  47 +
  48 + DossModl.findOne({
  49 + special: special
  50 + }).exec(function (err2, doss) {
  51 + if (!err2 && doss) {
  52 + cb(doss._id);
  53 + } else {
  54 + cb(null);
  55 + }
  56 + });
  57 + }
  58 + });
  59 +};
  60 +
  61 +DosssServ.get = function (special, cb) {
  62 + DosssServ.getId(special, function (id) { // TODO À enlever avec api.get('/dosss/:doss_id')
  63 + DossModl.findById(id).lean().exec(function (err, doss) {
  64 + if (err) {
  65 + cb(err);
  66 + } else {
  67 + DosssServ.addData(doss, cb);
  68 + }
  69 + });
  70 + });
  71 +};
  72 +
  73 +DosssServ.list = function (cb) {
  74 + DossModl.find({}).lean().exec(function (err, Dosss) {
  75 + async.mapSeries(Dosss, DosssServ.addData, cb);
  76 + });
  77 +};
  78 +
  79 +DosssServ.children = function (id, cb) {
  80 + DossModl.find({
  81 + parent: id
  82 + }).lean().exec(function (err, Dosss) {
  83 + async.mapSeries(Dosss, DosssServ.addData, cb);
  84 + });
  85 +};
  86 +
  87 +DosssServ.add = function (data, cb) {
  88 + DossModl.create({
  89 + titre: data.titre,
  90 + parent: data.parent
  91 + }, function (err, Doss) {
  92 + if (err) {
  93 + cb(err);
  94 + } else {
  95 + DosssServ.get(Doss._id, cb);
  96 + }
  97 + });
  98 +};
  99 +
  100 +DosssServ.canWriteIn = function (id, login, cb) {
  101 + DosssServ.exists(id, cb);
  102 +};
  103 +
  104 +DosssServ.remove = function (id, cb) {
  105 + // TODO Trash
  106 + DossModl.remove({
  107 + _id: id
  108 + }, cb);
  109 +};
  110 +
  111 +module.exports = DosssServ;
@@ -8,9 +8,9 @@ angular.module(&#39;ciApp&#39;, [&#39;ngAnimate&#39;, &#39;ngRoute&#39;, &#39;ConnectCtrl&#39;, &#39;MembreCtrl&#39;, &#39;F @@ -8,9 +8,9 @@ angular.module(&#39;ciApp&#39;, [&#39;ngAnimate&#39;, &#39;ngRoute&#39;, &#39;ConnectCtrl&#39;, &#39;MembreCtrl&#39;, &#39;F
8 controller: 'MembreCtrl' 8 controller: 'MembreCtrl'
9 }) 9 })
10 .when('/forum', { 10 .when('/forum', {
11 - redirectTo: 'forum/dir/0' 11 + redirectTo: 'forum/dir/root'
12 }) 12 })
13 - .when('/forum/dir/:dir_id', { 13 + .when('/forum/dir/:doss_id', {
14 templateUrl: 'views/forumDir.html', 14 templateUrl: 'views/forumDir.html',
15 controller: 'ForumDirCtrl' 15 controller: 'ForumDirCtrl'
16 }) 16 })
public/js/controllers/ForumDirCtrl.js
1 angular.module('ForumDirCtrl', ['SessionsServ', 'ApiServ']) 1 angular.module('ForumDirCtrl', ['SessionsServ', 'ApiServ'])
2 - .controller('ForumDirCtrl', function ($scope, SessionServ, ApiServ) { 2 + .controller('ForumDirCtrl', function ($scope, $routeParams, SessionServ, ApiServ) {
3 $scope.convs = []; 3 $scope.convs = [];
4 - $scope.formData = {}; 4 + $scope.dosss = [];
  5 + $scope.formDoss = {};
  6 + $scope.formConv = {};
5 7
6 $scope.session = SessionServ.cur; 8 $scope.session = SessionServ.cur;
7 SessionServ.onChange(function () { 9 SessionServ.onChange(function () {
8 $scope.session = SessionServ.cur; 10 $scope.session = SessionServ.cur;
9 }); 11 });
10 12
11 - ApiServ("récupération des conversations", 'get', 'convs', function (err, convs) {  
12 - if (!err)  
13 - $scope.convs = convs; 13 + ApiServ("récupération du dossier", 'get', 'dosss', $routeParams.doss_id, function (err, doss) {
  14 + if (err) {
  15 + console.error(err);
  16 + } else {
  17 + if (doss) {
  18 + $scope.dosss = doss.dosss;
  19 + $scope.convs = doss.convs;
  20 + }
  21 + }
14 }); 22 });
15 23
  24 + // Dossiers
  25 + $scope.createDoss = function () {
  26 + $scope.formDoss.parent = $routeParams.doss_id;
  27 + ApiServ("création du dossier", 'post', 'dosss', $scope.formDoss, function (err, doss) {
  28 + if (!err) {
  29 + $scope.formDoss = {};
  30 + $scope.dosss.push(doss);
  31 + }
  32 + });
  33 + };
  34 +
  35 + $scope.deleteDoss = function (index) {
  36 + ApiServ("suppression du dossier", 'delete', 'dosss', $scope.dosss[index]._id, function (err) {
  37 + if (!err)
  38 + $scope.dosss.splice(index, 1);
  39 + });
  40 + };
  41 +
  42 + // Conversations
16 $scope.createConv = function () { 43 $scope.createConv = function () {
17 - ApiServ("création de la conversation", 'post', 'convs', $scope.formData, function (err, conv) { 44 + $scope.formConv.parent = $routeParams.doss_id;
  45 + ApiServ("création de la conversation", 'post', 'convs', $scope.formConv, function (err, conv) {
18 if (!err) { 46 if (!err) {
19 - $scope.formData = {}; 47 + $scope.formConv = {};
20 $scope.convs.push(conv); 48 $scope.convs.push(conv);
21 } 49 }
22 }); 50 });
23 }; 51 };
24 52
25 $scope.deleteConv = function (index) { 53 $scope.deleteConv = function (index) {
26 - ApiServ("création de la conversation", 'delete', 'convs', $scope.convs[index]._id, function (err) { 54 + ApiServ("suppression de la conversation", 'delete', 'convs', $scope.convs[index]._id, function (err) {
27 if (!err) 55 if (!err)
28 $scope.convs.splice(index, 1); 56 $scope.convs.splice(index, 1);
29 }); 57 });
public/js/services/ApiServ.js
1 angular.module('ApiServ', ['NotifyServ']) 1 angular.module('ApiServ', ['NotifyServ'])
2 .service('ApiServ', function ($http, NotifyServ) { 2 .service('ApiServ', function ($http, NotifyServ) {
3 return function (name, method, href) { 3 return function (name, method, href) {
  4 + var cb;
4 link = '/api/' + href; 5 link = '/api/' + href;
5 arglen = arguments.length; 6 arglen = arguments.length;
6 if (typeof arguments[arglen - 1] == 'function') { 7 if (typeof arguments[arglen - 1] == 'function') {
public/views/forumConv.html
1 <div class="container"> 1 <div class="container">
2 <ol class="breadcrumb"> 2 <ol class="breadcrumb">
3 - <li><a href="#">Forum</a></li> 3 + <li><a href="/forum">Forum</a></li>
4 <li><a href="#">Conversations</a></li> 4 <li><a href="#">Conversations</a></li>
5 <li class="active">{{ conv.titre }}</li> 5 <li class="active">{{ conv.titre }}</li>
6 </ol> 6 </ol>
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 </div> 31 </div>
32 </div> 32 </div>
33 </div> 33 </div>
34 - <nav> 34 + <!-- <nav>
35 <ul class="pagination"> 35 <ul class="pagination">
36 <li> 36 <li>
37 <a href="#" aria-label="Previous"> 37 <a href="#" aria-label="Previous">
@@ -49,5 +49,5 @@ @@ -49,5 +49,5 @@
49 </a> 49 </a>
50 </li> 50 </li>
51 </ul> 51 </ul>
52 - </nav> 52 + </nav> -->
53 </div> 53 </div>
54 \ No newline at end of file 54 \ No newline at end of file
public/views/forumDir.html
1 <div class="container"> 1 <div class="container">
2 <ol class="breadcrumb"> 2 <ol class="breadcrumb">
3 - <li><a href="#">Forum</a></li> 3 + <li><a href="/forum">Forum</a></li>
4 <li><a href="#">Dossiers</a></li> 4 <li><a href="#">Dossiers</a></li>
5 - <li class="active">{{ dossier.name }}</li> 5 + <li class="active">{{ dossier.titre }}</li>
6 </ol> 6 </ol>
  7 + <h1>{{ doss.titre }}</h1>
  8 + <h2>Dossiers</h2>
  9 + <div class="panel panel-default" ng-repeat="doss in dosss">
  10 + <div class="panel-heading">
  11 + <h3 class="panel-title">
  12 + <a href="/forum/dir/{{ doss._id }}">
  13 + <span class="glyphicon glyphicon-folder-open" aria-hidden="true"></span> {{ doss.titre }}
  14 + </a>
  15 + </h3>
  16 + </div>
  17 + <div class="panel-body">
  18 + <!-- <strong>Date : </strong>{{ doss.date }}<br/> -->
  19 + <button ng-if="session.canDelDoss" type="button" class="btn btn-danger" ng-click="deleteDoss($index)">
  20 + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Supprimer
  21 + </button>
  22 + </div>
  23 + </div>
  24 + <div class="form-group" ng-if="session.canAddDoss">
  25 + <div class="panel panel-default">
  26 + <div class="panel-heading">
  27 + <h3 class="panel-title">
  28 + <input type="text" class="form-control" placeholder="Titre du dossier" ng-model="formDoss.titre" />
  29 + </h3>
  30 + </div>
  31 + <div class="panel-body">
  32 + <button type="submit" class="btn btn-primary" aria-label="Ajouter" ng-click="createDoss()">
  33 + <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter
  34 + </button>
  35 + </div>
  36 + </div>
  37 + </div>
  38 + <h2>Conversations</h2>
7 <div class="panel panel-default" ng-repeat="conv in convs"> 39 <div class="panel panel-default" ng-repeat="conv in convs">
8 <div class="panel-heading"> 40 <div class="panel-heading">
9 - <a href="/forum/conv/{{ conv._id }}">  
10 - <h3 class="panel-title">{{ conv.titre }}</h3>  
11 - </a> 41 + <h3 class="panel-title">
  42 + <a href="/forum/conv/{{ conv._id }}">
  43 + <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span> {{ conv.titre }}
  44 + </a>
  45 + </h3>
12 </div> 46 </div>
13 <div class="panel-body"> 47 <div class="panel-body">
14 <!-- <strong>Date : </strong>{{ conv.date }}<br/> --> 48 <!-- <strong>Date : </strong>{{ conv.date }}<br/> -->
@@ -21,18 +55,18 @@ @@ -21,18 +55,18 @@
21 <div class="panel panel-default"> 55 <div class="panel panel-default">
22 <div class="panel-heading"> 56 <div class="panel-heading">
23 <h3 class="panel-title"> 57 <h3 class="panel-title">
24 - <input type="text" class="form-control" placeholder="Titre" ng-model="formData.titre" /> 58 + <input type="text" class="form-control" placeholder="Titre de la conversation" ng-model="formConv.titre" />
25 </h3> 59 </h3>
26 </div> 60 </div>
27 <div class="panel-body"> 61 <div class="panel-body">
28 - <textarea class="form-control" rows="3"></textarea> 62 + <!-- <textarea class="form-control" rows="3"></textarea> -->
29 <button type="submit" class="btn btn-primary" aria-label="Ajouter" ng-click="createConv()"> 63 <button type="submit" class="btn btn-primary" aria-label="Ajouter" ng-click="createConv()">
30 <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter 64 <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter
31 </button> 65 </button>
32 </div> 66 </div>
33 </div> 67 </div>
34 </div> 68 </div>
35 - <nav> 69 + <!-- <nav>
36 <ul class="pagination"> 70 <ul class="pagination">
37 <li> 71 <li>
38 <a href="#" aria-label="Previous"> 72 <a href="#" aria-label="Previous">
@@ -50,5 +84,5 @@ @@ -50,5 +84,5 @@
50 </a> 84 </a>
51 </li> 85 </li>
52 </ul> 86 </ul>
53 - </nav> 87 + </nav> -->
54 </div> 88 </div>
55 \ No newline at end of file 89 \ No newline at end of file