Преглед на файлове

# Feature/196, 198, 199 Grouping users
* Improve user-group-relation management page.

Tatsuya Ise преди 8 години
родител
ревизия
a584de94de
променени са 6 файла, в които са добавени 134 реда и са изтрити 142 реда
  1. 36 9
      lib/models/user-group-relation.js
  2. 2 65
      lib/models/user-group.js
  3. 59 41
      lib/routes/admin.js
  4. 33 13
      lib/views/admin/user-group-detail.html
  5. 4 13
      lib/views/admin/user-groups.html
  6. 0 1
      resource/js/legacy/crowi-admin.js

+ 36 - 9
lib/models/user-group-relation.js

@@ -21,7 +21,7 @@ module.exports = function(crowi) {
 
   // すべてのグループ所属関係を取得
   userGroupRelationSchema.statics.findAllRelation = function() {
-    debug('findAllGroups is called');
+    debug('findAllRelations is called');
     var UserGroupRelation = this;
 
     return new Promise(function(resolve, reject) {
@@ -38,14 +38,14 @@ module.exports = function(crowi) {
     });
   };
 
-  // すべてのグループ所属関係を取得
-  userGroupRelationSchema.statics.findAllRelationForUserGroup = function (group) {
-    debug('findAllGroups is called', group);
+  // 指定グループに対するすべてのグループ所属関係を取得
+  userGroupRelationSchema.statics.findAllRelationForUserGroup = function (userGroup) {
+    debug('findAllRelation is called', userGroup);
     var UserGroupRelation = this;
 
     return new Promise(function (resolve, reject) {
       UserGroupRelation
-        .find({ relatedGroup: group })
+        .find({ relatedGroup: userGroup })
         .populate('relatedUser')
         .exec(function (err, userGroupRelationData) {
           if (err) {
@@ -56,10 +56,30 @@ module.exports = function(crowi) {
     });
   };
 
+  // 指定グループリストに対するすべてのグループ所属関係を取得
+  userGroupRelationSchema.statics.findAllRelationForUserGroups = function (userGroups, callback) {
+    debug('findAllRelations is called', userGroups);
+    var UserGroupRelation = this;
+    var groupRelations = new Map();
+
+    return new Promise(function (resolve, reject) {
+      UserGroupRelation
+        .find({ relatedGroup: { $in: userGroups} })
+        .populate('relatedUser')
+        .exec(function (err, userGroupRelationData) {
+          if (err) {
+            return reject(err);
+          }
+          debug(userGroupRelationData);
+          return resolve(userGroupRelationData);
+        });
+    });
+  };
+
   // ページネーション利用の検索
-  userGroupRelationSchema.statics.findUserGroupRelationsWithPagination = function(options, callback) {
+  userGroupRelationSchema.statics.findUserGroupRelationsWithPagination = function (userGroup, options, callback) {
 
-    this.paginate({}, { page: options.page || 1, limit: options.limit || PAGE_ITEMS }, function(err, result) {
+    this.paginate({ relatedGroup: userGroup }, { page: options.page || 1, limit: options.limit || PAGE_ITEMS }, function(err, result) {
       if (err) {
         debug('Error on pagination:', err);
         return callback(err, null);
@@ -74,6 +94,9 @@ module.exports = function(crowi) {
     var UserGroupRelation = this
       , newUserGroupRelation = new UserGroupRelation();
 
+    if (userGroup == null || user == null) {
+      return callback(new Error('userGroup or user is null'));
+    }
     newUserGroupRelation.relatedGroup = userGroup;
     newUserGroupRelation.relatedUser = user;
     newUserGroupRelation.createdAt = Date.now();
@@ -104,11 +127,15 @@ module.exports = function(crowi) {
   userGroupRelationSchema.statics.removeById = function (id, callback) {
     var UserGroupRelation = this
     UserGroupRelation.findById(id, function (err, relationData) {
-      debug(relationData);
-      if (!relationData) {
+      if (err) {
         debug('Error on find a removing user-group-relation', err);
         return callback(err);
       }
+      debug('relationData is ', relationData);
+      if (relationData == null || relationData == undefined) {
+        debug('Cannot find user group relation by id', id);
+        return callback(new Error('Cannot find user group relation by id'));
+      }
 
       relationData.remove(function(err) {
         if (err) {

+ 2 - 65
lib/models/user-group.js

@@ -32,50 +32,10 @@ module.exports = function(crowi) {
     return this.updateImage(null, callback);
   };
 
-  // // グループ公開情報のフィルター
-  // userGroupSchema.statics.filterToPublicFields = function(userGroup) {
-  //   debug('UserGroup is', typeof userGroup, userGroup);
-  //   if (typeof userGroup !== 'object' || !userGroup._id) {
-  //     return userGroup;
-  //   }
-
-  //   var filteredGroup = {};
-  //   var fields = USER_GROUP_PUBLIC_FIELDS.split(' ');
-  //   for (var i = 0; i < fields.length; i++) {
-  //     var key = fields[i];
-  //     if (userGroup[key]) {
-  //       filteredGroup[key] = userGroup[key];
-  //     }
-  //   }
-
-  //   return filteredGroup;
-  // };
-
-  // TBD: グループ検索
-  // userGroupSchema.statics.findGroups = function(options, callback) {
-  //   var sort = options.sort || {createdAt: 1};
-
-  //   this.find()
-  //     .sort(sort)
-  //     .skip(options.skip || 0)
-  //     .limit(options.limit || 21)
-  //     .exec(function (err, userGroupData) {
-  //       callback(err, userGroupData);
-  //     });
-
-  // };
-
   // すべてのグループを取得(オプション指定可)
   userGroupSchema.statics.findAllGroups = function(option) {
-    debug('NoErrorOccured');
-
     var UserGroup = this;
-    // var option = option || {}
-    //   , sort = option.sort || {createdAt: -1}
-    //   , fields = option.fields || USER_GROUP_PUBLIC_FIELDS
-    //   ;
 
-    console.log('');
     return new Promise(function(resolve, reject) {
       UserGroup
         .find()
@@ -89,29 +49,6 @@ module.exports = function(crowi) {
     });
   };
 
-  // TBD: IDによるグループ検索
-  // userGroupSchema.statics.findGroupsByIds = function(ids, option) {
-  //   var UserGroup = this;
-  //   var option = option || {}
-  //     , sort = option.sort || {createdAt: -1}
-  //     , fields = option.fields || USER_GROUP_PUBLIC_FIELDS
-  //     ;
-
-  //   return new Promise(function(resolve, reject) {
-  //     UserGroup
-  //       .find({ _id: { $in: ids }})
-  //       .select(fields)
-  //       .sort(sort)
-  //       .exec(function (err, userGroupData) {
-  //         if (err) {
-  //           return reject(err);
-  //         }
-
-  //         return resolve(userGroupData);
-  //       });
-  //   });
-  // };
-
   // ページネーション利用のグループ検索
   userGroupSchema.statics.findUserGroupsWithPagination = function(options, callback) {
     var sort = options.sort || {name: 1, createdAt: 1};
@@ -140,7 +77,7 @@ module.exports = function(crowi) {
     });
   };
 
-  // TBD: 登録可能グループ名確認
+  // 登録可能グループ名確認
   userGroupSchema.statics.isRegisterableName = function(name, callback) {
     var UserGroup = this;
     var userGroupnameUsable = true;
@@ -153,7 +90,7 @@ module.exports = function(crowi) {
     });
   };
 
-  // TBD: グループの完全削除
+  // グループの完全削除
   userGroupSchema.statics.removeCompletelyById = function(id, callback) {
     var UserGroup = this;
     UserGroup.findById(id, function (err, userGroupData) {

+ 59 - 41
lib/routes/admin.js

@@ -481,25 +481,23 @@ module.exports = function(crowi, app) {
       const pager = createPager(result.total, result.limit, result.page, result.pages, MAX_PAGE_LIST);
       var userGroups = result.docs
       var groupRelations = new Map();
-      if (userGroups) {
-        userGroups.forEach(group => {
-          UserGroupRelation.findAllRelationForUserGroup(group)
-          .then(function(relations) {
-            debug(group);
-            debug(relations);
-            groupRelations.set(group, relations);
-            debug('groupRelations is ', groupRelations);
-          }).catch(function(err) {
+      UserGroupRelation.findAllRelationForUserGroups(userGroups)
+        .then( function(relations) {
+          userGroups.map((group) => {
+            groupRelations.set(group, relations.filter( function(target) {
+              return target.relatedGroup.toString() == group._id.toString();
+            }));
+          });
+          return res.render('admin/user-groups', {
+            userGroups: userGroups,
+            userGroupRelations: groupRelations,
+            pager: pager
+          });
+        })
+        .catch( function(err) {
             debug('Error on find all relations', err);
             return res.json(ApiResponse.error('Error'));
-          });
         });
-      }
-      return res.render('admin/user-groups', {
-        userGroups: userGroups,
-        userGroupRelations: groupRelations,
-        pager: pager
-      });
     });
   };
 
@@ -507,27 +505,46 @@ module.exports = function(crowi, app) {
   actions.userGroup.detail = function (req, res) {
     var name = req.params.name;
     UserGroup.findUserGroupByName(name)
-    .then( function(data) {
-      var userGroup = data
-      var groupRelations = [];
-      if (userGroup) {
-        UserGroupRelation.findAllRelationForUserGroup(userGroup)
-        .then(function (data) {
-          debug('user-group-detail succeed', data);
-          return res.render('admin/user-group-detail', {
-            userGroup: userGroup,
-            userGroupRelations: data
+      .then(function (userGroup) {
+        var groupRelations = [];
+        if (userGroup) {
+          UserGroupRelation.findAllRelationForUserGroup(userGroup)
+          .then(function (relations) {
+            User.findAllUsers(null)
+              .then(function (users) {
+                debug('users', users);
+                users = users.filter( function(user) {
+                  var relation = relations.find( function(relation) {
+                    return relation.relatedUser._id.toString() == user._id.toString();
+                  });
+                  return relation == null || relation == undefined;
+                });
+                debug('users', users);
+                debug('user-group-detail succeed', relations);
+                return res.render('admin/user-group-detail', {
+                  userGroup: userGroup,
+                  userGroupRelations: relations,
+                  notRelatedusers: users
+                });
+              })
+              .catch(function(err) {
+                debug('Error on find all relations', err);
+                return res.json(ApiResponse.error('Error'));
+              });
+          }).catch(function (err) {
+            debug('Error on find all relations', err);
+            return res.json(ApiResponse.error('Error'));
           });
-        }).catch(function (err) {
-          debug('Error on find all relations', err);
+        }
+        else {
+          debug('Error on get userGroupDetail', err);
           return res.json(ApiResponse.error('Error'));
-        });
-      }
-    })
-    .catch(function(err) {
-      debug('Error on get userGroupDetail', err);
-      return res.json(ApiResponse.error('Error'));
-    });
+        }
+      })
+      .catch(function(err) {
+        debug('Error on get userGroupDetail', err);
+        return res.json(ApiResponse.error('Error'));
+      });
   }
 
   //グループの生成
@@ -642,22 +659,23 @@ module.exports = function(crowi, app) {
         UserGroup.findById(req.body.user_group_id, function(err, userGroup) {
           if (err) {
             debug('Error on create user-group relation', err);
-            return res.json(ApiResponse.error('Error'));
+            req.flash('errorMessage', 'グループの取得に失敗しました');
+            return res.redirect('/admin/user-group-detail/' + userGroup.name);
           }
           // Relation を作成
           UserGroupRelation.createRelation(userGroup, user, function (err, data) {
             if (err) {
               debug('Error on create user-group relation', err);
-              return res.json(ApiResponse.error('Error'));
+              req.flash('errorMessage', 'ユーザの追加に失敗しました');
+              return res.redirect('/admin/user-group-detail/' + userGroup.name);
             }
-            return res.json(ApiResponse.success(data));
+            return res.redirect('/admin/user-group-detail/' + userGroup.name);
           });
-
         });
-
       }).catch((err) => {
         debug('Error on create user-group relation', err);
-        return res.json(ApiResponse.error('Error'));
+        req.flash('errorMessage', 'ユーザの取得に失敗しました');
+        return res.redirect('/admin/user-group-detail/' + userGroup.name);
       });
   }
 

+ 33 - 13
lib/views/admin/user-group-detail.html

@@ -32,6 +32,9 @@
     </div>
 
     <div class="col-md-9">
+          <a href="/admin/user-groups">
+            <i class="fa fa-arrow-left"></i> グループ一覧</a>
+
       <div class="modal fade" id="admin-add-user-group-relation-modal">
         <div class="modal-dialog">
           <div class="modal-content">
@@ -45,19 +48,36 @@
               <p>
                 ユーザ名を入力してください。
               </p>
-              <form role="form" action="/admin/user-group-relation/create" method="post">
-                <p>
-                  Add related user:
-                  <input type="text" name="user_name">
-                </p>
-
+              <form class="form-inline" role="form" action="/admin/user-group-relation/create" method="post">
+                <div class="form-group">
+                  <label for="inputRelatedUserName">Add related user:</label>
+                  <input type="text" name="user_name" class="form-control input-sm" id="inputRelatedUserName" placeholder="username">
+                </div>
                 <input type="hidden" name="user_group_id" value="{{userGroup.id}}">
                 <input type="hidden" name="_csrf" value="{{ csrf() }}">
-                <button type="submit" value="" class="btn btn-danger">
-                  実行
-                </button>
+                <button type="submit" class="btn btn-sm btn-danger">実行</button>
               </form>
 
+              {% if 0 < notRelatedusers.length %}
+              <hr>
+              <p>
+                ユーザ名を選択してください。
+              </p>
+
+              <ul class="list-inline">
+                {% for sUser in notRelatedusers %}
+                <li>
+                  <form role="form" action="/admin/user-group-relation/create" method="post">
+                    <!-- <input type="hidden" name="user_name" value="{{sUser.username}}"> -->
+                    <input type="hidden" name="user_group_id" value="{{userGroup.id}}">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" name="user_name" value="{{sUser.username}}" class="btn btn-xs btn-primary">{{sUser.username}}</button>
+                  </form>
+                </li>
+                {% endfor %}
+              </ul>
+              {% endif %}
+
             </div>
 
           </div>
@@ -104,12 +124,9 @@
                 </button>
                 <ul class="dropdown-menu" role="menu">
                   <li class="dropdown-header">編集メニュー</li>
-                  <li>
-                    <a href="">編集</a>
-                  </li>
                   <li class="divider"></li>
                   <li class="dropdown-button">
-                    <form action="/admin/user-group-relation/{{userGroup.name}}/remove-relation/{{ sRelation.relatedUser._id.toString() }}" method="post">
+                    <form action="/admin/user-group-relation/{{userGroup.name}}/remove-relation/{{ sRelation._id.toString() }}" method="post">
                       <input type="hidden" name="_csrf" value="{{ csrf() }}">
                       <button type="submit" class="btn btn-block btn-danger">グループから外す</button>
                     </form>
@@ -119,6 +136,8 @@
             </td>
           </tr>
           {% endfor %}
+
+          {% if 0 < notRelatedusers.length %}
           <tr>
             <td></td>
             <td><button type="button" class="btn btn-primary" data-target="#admin-add-user-group-relation-modal" data-toggle="modal"><i class="fa fa-plus"></i></button></td>
@@ -127,6 +146,7 @@
             <td></td>
             <td></td>
           </tr>
+          {% endif %}
         </tbody>
       </table>
 

+ 4 - 13
lib/views/admin/user-groups.html

@@ -82,14 +82,6 @@
               <p>
                 グループの削除を行うと元に戻すことはできませんのでご注意ください。
               </p>
-              <p>
-                Related users:
-                <ul class="list-inline">
-                  {% for dGroupRelatedUser in relatedUsers %}
-                  <li class="list-inline-item badge badge-primary">{{dGroupRelatedUser.name}}</li>
-                  {% endfor %}
-                </ul>
-              </p>
 
               <form method="post" id="admin-user-groups-delete">
                 <input type="hidden" name="user_group_id" value="">
@@ -128,29 +120,28 @@
             <td>{{ sGroup.name }}</td>
             <td><ul class="list-inline">
               {% for relation in userGroupRelations.get(sGroup) %}
-              <li class="list-inline-item badge badge-primary">{{relation.relatedUser.name}}</li>
+              <li class="list-inline-item badge badge-primary">{{relation.relatedUser.username}}</li>
               {% endfor %}
             </ul></td>
             <td>{{ sGroup.createdAt|date('Y-m-d', sGroup.createdAt.getTimezoneOffset()) }}</td>
             <td>
               <div class="btn-group admin-group-menu">
                 <button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
-                  編集
+                  操作
                   <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu" role="menu">
-                  <li class="dropdown-header">編集メニュー</li>
+                  <li class="dropdown-header">メニュー</li>
                   <li class="divider"></li>
 
                   <li class="dropdown-button">
-                    <a href="/admin/user-group-detail/{{sGroup.name}}" class="btn btn-block btn-default">編集</a>
+                    <a href="/admin/user-group-detail/{{sGroup.name}}" class="btn btn-block btn-default">詳細</a>
                   </li>
 
                   <li class="dropdown-button">
                     <a href="#"
                       data-user-group-id="{{ sGroup._id.toString() }}"
                       data-user-group-name="{{ sGroup.name.toString() }}"
-                      data-related-users="{{ userGroups }}"
                       data-target="#admin-delete-user-group-modal"
                       data-toggle="modal" class="btn btn-block btn-danger">
                       グループの削除

+ 0 - 1
resource/js/legacy/crowi-admin.js

@@ -57,7 +57,6 @@ $(function() {
     var data = $(button.relatedTarget);
     var userGroupId = data.data('user-group-id');
     var userGroupName = data.data('user-group-name');
-    var relatedUsers = data.data('related-users');
 
     $('#admin-delete-user-group-name').text(userGroupName);
     $('#admin-user-groups-delete input[name=user_group_id]').val(userGroupId);