subtasks.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. Subtasks = new Mongo.Collection('subtasks');
  2. Subtasks.attachSchema(new SimpleSchema({
  3. title: {
  4. type: String,
  5. },
  6. startAt: { // this is a predicted time
  7. type: Date,
  8. optional: true,
  9. },
  10. endAt: { // this is a predicted time
  11. type: Date,
  12. optional: true,
  13. },
  14. finishedAt: { // The date & time when it is marked as being done
  15. type: Date,
  16. optional: true,
  17. },
  18. createdAt: {
  19. type: Date,
  20. denyUpdate: false,
  21. autoValue() { // eslint-disable-line consistent-return
  22. if (this.isInsert) {
  23. return new Date();
  24. } else {
  25. this.unset();
  26. }
  27. },
  28. },
  29. sort: {
  30. type: Number,
  31. decimal: true,
  32. },
  33. isFinished: {
  34. type: Boolean,
  35. defaultValue: false,
  36. },
  37. cardId: {
  38. type: String,
  39. },
  40. }));
  41. Subtasks.helpers({
  42. isFinished() {
  43. return 0 !== this.itemCount() && this.itemCount() === this.finishedCount();
  44. },
  45. itemIndex(itemId) {
  46. const items = self.findOne({_id : this._id}).items;
  47. return _.pluck(items, '_id').indexOf(itemId);
  48. },
  49. });
  50. Subtasks.allow({
  51. insert(userId, doc) {
  52. return allowIsBoardMemberByCard(userId, Cards.findOne(doc.cardId));
  53. },
  54. update(userId, doc) {
  55. return allowIsBoardMemberByCard(userId, Cards.findOne(doc.cardId));
  56. },
  57. remove(userId, doc) {
  58. return allowIsBoardMemberByCard(userId, Cards.findOne(doc.cardId));
  59. },
  60. fetch: ['userId', 'cardId'],
  61. });
  62. Subtasks.before.insert((userId, doc) => {
  63. doc.createdAt = new Date();
  64. if (!doc.userId) {
  65. doc.userId = userId;
  66. }
  67. });
  68. // Mutations
  69. Subtasks.mutations({
  70. setTitle(title) {
  71. return { $set: { title } };
  72. },
  73. toggleItem() {
  74. return { $set: { isFinished: !this.isFinished } };
  75. },
  76. move(sortIndex) {
  77. const mutatedFields = {
  78. sort: sortIndex,
  79. };
  80. return {$set: mutatedFields};
  81. },
  82. });
  83. // Activities helper
  84. function itemCreation(userId, doc) {
  85. const card = Cards.findOne(doc.cardId);
  86. const boardId = card.boardId;
  87. Activities.insert({
  88. userId,
  89. activityType: 'addSubtaskItem',
  90. cardId: doc.cardId,
  91. boardId,
  92. subtaskItemId: doc._id,
  93. });
  94. }
  95. function itemRemover(userId, doc) {
  96. Activities.remove({
  97. subtaskItemId: doc._id,
  98. });
  99. }
  100. // Activities
  101. if (Meteor.isServer) {
  102. Meteor.startup(() => {
  103. Subtasks._collection._ensureIndex({ cardId: 1 });
  104. });
  105. Subtasks.after.insert((userId, doc) => {
  106. itemCreation(userId, doc);
  107. });
  108. Subtasks.after.remove((userId, doc) => {
  109. itemRemover(userId, doc);
  110. });
  111. }
  112. // APIs
  113. if (Meteor.isServer) {
  114. JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/subtasks/:itemId', function (req, res) {
  115. Authentication.checkUserId( req.userId);
  116. const paramItemId = req.params.itemId;
  117. const subtaskItem = Subtasks.findOne({ _id: paramItemId });
  118. if (subtaskItem) {
  119. JsonRoutes.sendResult(res, {
  120. code: 200,
  121. data: subtaskItem,
  122. });
  123. } else {
  124. JsonRoutes.sendResult(res, {
  125. code: 500,
  126. });
  127. }
  128. });
  129. JsonRoutes.add('PUT', '/api/boards/:boardId/cards/:cardId/subtasks/:itemId', function (req, res) {
  130. Authentication.checkUserId( req.userId);
  131. const paramItemId = req.params.itemId;
  132. if (req.body.hasOwnProperty('isFinished')) {
  133. Subtasks.direct.update({_id: paramItemId}, {$set: {isFinished: req.body.isFinished}});
  134. }
  135. if (req.body.hasOwnProperty('title')) {
  136. Subtasks.direct.update({_id: paramItemId}, {$set: {title: req.body.title}});
  137. }
  138. JsonRoutes.sendResult(res, {
  139. code: 200,
  140. data: {
  141. _id: paramItemId,
  142. },
  143. });
  144. });
  145. JsonRoutes.add('DELETE', '/api/boards/:boardId/cards/:cardId/subtasks/:itemId', function (req, res) {
  146. Authentication.checkUserId( req.userId);
  147. const paramItemId = req.params.itemId;
  148. Subtasks.direct.remove({ _id: paramItemId });
  149. JsonRoutes.sendResult(res, {
  150. code: 200,
  151. data: {
  152. _id: paramItemId,
  153. },
  154. });
  155. });
  156. }