user-group.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import mongoose, {
  2. Types, Schema, Model, Document,
  3. } from 'mongoose';
  4. import mongoosePaginate from 'mongoose-paginate-v2';
  5. import { getOrCreateModel } from '@growi/core';
  6. import { IUserGroup } from '~/interfaces/user';
  7. export interface UserGroupDocument extends IUserGroup, Document {}
  8. export interface UserGroupModel extends Model<UserGroupDocument> {
  9. [x:string]: any, // for old methods
  10. PAGE_ITEMS: 10,
  11. }
  12. /*
  13. * define schema
  14. */
  15. const ObjectId = mongoose.Schema.Types.ObjectId;
  16. const schema = new Schema<UserGroupDocument, UserGroupModel>({
  17. name: { type: String, required: true, unique: true },
  18. createdAt: { type: Date, default: new Date() },
  19. parent: { type: ObjectId, ref: 'UserGroup', index: true },
  20. description: { type: String, default: '' },
  21. });
  22. schema.plugin(mongoosePaginate);
  23. const PAGE_ITEMS = 10;
  24. schema.statics.findUserGroupsWithPagination = function(opts) {
  25. const query = { parent: null };
  26. const options = Object.assign({}, opts);
  27. if (options.page == null) {
  28. options.page = 1;
  29. }
  30. if (options.limit == null) {
  31. options.limit = PAGE_ITEMS;
  32. }
  33. return this.paginate(query, options)
  34. .catch((err) => {
  35. // debug('Error on pagination:', err); TODO: add logger
  36. });
  37. };
  38. schema.statics.findChildUserGroupsByParentIds = async function(parentIds, includeGrandChildren = false) {
  39. if (!Array.isArray(parentIds)) {
  40. throw Error('parentIds must be an array.');
  41. }
  42. const childUserGroups = await this.find({ parent: { $in: parentIds } });
  43. let grandChildUserGroups: UserGroupDocument[] | null = null;
  44. if (includeGrandChildren) {
  45. const childUserGroupIds = childUserGroups.map(group => group._id);
  46. grandChildUserGroups = await this.find({ parent: { $in: childUserGroupIds } });
  47. }
  48. return {
  49. childUserGroups,
  50. grandChildUserGroups,
  51. };
  52. };
  53. // schema.statics.removeCompletelyById = async function(deleteGroupId, action, transferToUserGroupId, user) { // TODO 85062: move this to the service layer
  54. // const UserGroupRelation = mongoose.model('UserGroupRelation') as any; // TODO 85062: Typescriptize model
  55. // const groupToDelete = await this.findById(deleteGroupId);
  56. // if (groupToDelete == null) {
  57. // throw Error(`UserGroup data is not exists. id: ${deleteGroupId}`);
  58. // }
  59. // const deletedGroup = await groupToDelete.remove();
  60. // await Promise.all([
  61. // UserGroupRelation.removeAllByUserGroup(deletedGroup),
  62. // crowi.pageService.handlePrivatePagesForDeletedGroup(deletedGroup, action, transferToUserGroupId, user),
  63. // ]);
  64. // return deletedGroup;
  65. // };
  66. schema.statics.countUserGroups = function() {
  67. return this.estimatedDocumentCount();
  68. };
  69. schema.statics.createGroup = async function(name, description, parentId) {
  70. // create without parent
  71. if (parentId == null) {
  72. return this.create({ name, description });
  73. }
  74. // create with parent
  75. const parent = await this.findOne({ _id: parentId });
  76. if (parent == null) {
  77. throw Error('Parent does not exist.');
  78. }
  79. return this.create({ name, description, parent });
  80. };
  81. schema.statics.findGroupsWithAncestorsRecursively = async function(group, ancestors = [group]) {
  82. if (group == null) {
  83. return ancestors;
  84. }
  85. const parent = await this.findOne({ _id: group.parent });
  86. if (parent == null) {
  87. return ancestors;
  88. }
  89. ancestors.push(parent);
  90. return this.findGroupsWithAncestorsRecursively(parent, ancestors);
  91. };
  92. schema.statics.findGroupsWithDescendantsRecursively = async function(groups, descendants = groups) {
  93. const nextGroups = await this.find({ parent: { $in: groups.map(g => g._id) } });
  94. if (nextGroups.length === 0) {
  95. return descendants;
  96. }
  97. return this.findGroupsWithDescendantsRecursively(nextGroups, descendants.concat(nextGroups));
  98. };
  99. export default getOrCreateModel<UserGroupDocument, UserGroupModel>('UserGroup', schema);