diff options
Diffstat (limited to 'models/cards.js')
-rw-r--r-- | models/cards.js | 132 |
1 files changed, 100 insertions, 32 deletions
diff --git a/models/cards.js b/models/cards.js index 17abf430..8b917ee3 100644 --- a/models/cards.js +++ b/models/cards.js @@ -18,9 +18,12 @@ Cards.attachSchema(new SimpleSchema({ listId: { type: String, }, - // The system could work without this `boardId` information (we could deduce - // the board identifier from the card), but it would make the system more - // difficult to manage and less efficient. + swimlaneId: { + type: String, + }, + // The system could work without this `boardId` information (we could deduce + // the board identifier from the card), but it would make the system more + // difficult to manage and less efficient. boardId: { type: String, }, @@ -71,6 +74,10 @@ Cards.attachSchema(new SimpleSchema({ type: [String], optional: true, }, + receivedAt: { + type: Date, + optional: true, + }, startAt: { type: Date, optional: true, @@ -79,8 +86,22 @@ Cards.attachSchema(new SimpleSchema({ type: Date, optional: true, }, - // XXX Should probably be called `authorId`. Is it even needed since we have - // the `members` field? + endAt: { + type: Date, + optional: true, + }, + spentTime: { + type: Number, + decimal: true, + optional: true, + }, + isOvertime: { + type: Boolean, + defaultValue: false, + optional: true, + }, + // XXX Should probably be called `authorId`. Is it even needed since we have + // the `members` field? userId: { type: String, autoValue() { // eslint-disable-line consistent-return @@ -151,13 +172,13 @@ Cards.helpers({ cover() { const cover = Attachments.findOne(this.coverId); - // if we return a cover before it is fully stored, we will get errors when we try to display it - // todo XXX we could return a default "upload pending" image in the meantime? + // if we return a cover before it is fully stored, we will get errors when we try to display it + // todo XXX we could return a default "upload pending" image in the meantime? return cover && cover.url() && cover; }, checklists() { - return Checklists.find({cardId: this._id}, {sort: {createdAt: 1}}); + return Checklists.find({cardId: this._id}, {sort: { sort: 1 } }); }, checklistItemCount() { @@ -219,6 +240,14 @@ Cards.helpers({ cardId: this._id, }); }, + + canBeRestored() { + const list = Lists.findOne({_id: this.listId}); + if(!list.getWipLimit('soft') && list.getWipLimit('enabled') && list.getWipLimit('value') === list.cards().count()){ + return false; + } + return true; + }, }); Cards.mutations({ @@ -238,11 +267,15 @@ Cards.mutations({ return {$set: {description}}; }, - move(listId, sortIndex) { - const mutatedFields = {listId}; - if (sortIndex) { - mutatedFields.sort = sortIndex; - } + move(swimlaneId, listId, sortIndex) { + const list = Lists.findOne(listId); + const mutatedFields = { + swimlaneId, + listId, + boardId: list.boardId, + sort: sortIndex, + }; + return {$set: mutatedFields}; }, @@ -312,6 +345,14 @@ Cards.mutations({ return {$unset: {coverId: ''}}; }, + setReceived(receivedAt) { + return {$set: {receivedAt}}; + }, + + unsetReceived() { + return {$unset: {receivedAt: ''}}; + }, + setStart(startAt) { return {$set: {startAt}}; }, @@ -327,6 +368,26 @@ Cards.mutations({ unsetDue() { return {$unset: {dueAt: ''}}; }, + + setEnd(endAt) { + return {$set: {endAt}}; + }, + + unsetEnd() { + return {$unset: {endAt: ''}}; + }, + + setOvertime(isOvertime) { + return {$set: {isOvertime}}; + }, + + setSpentTime(spentTime) { + return {$set: {spentTime}}; + }, + + unsetSpentTime() { + return {$unset: {spentTime: '', isOvertime: false}}; + }, }); @@ -371,7 +432,7 @@ function cardMembers(userId, doc, fieldNames, modifier) { if (!_.contains(fieldNames, 'members')) return; let memberId; - // Say hello to the new member + // Say hello to the new member if (modifier.$addToSet && modifier.$addToSet.members) { memberId = modifier.$addToSet.members; if (!_.contains(doc.members, memberId)) { @@ -385,10 +446,10 @@ function cardMembers(userId, doc, fieldNames, modifier) { } } - // Say goodbye to the former member + // Say goodbye to the former member if (modifier.$pull && modifier.$pull.members) { memberId = modifier.$pull.members; - // Check that the former member is member of the card + // Check that the former member is member of the card if (_.contains(doc.members, memberId)) { Activities.insert({ userId, @@ -428,8 +489,8 @@ function cardRemover(userId, doc) { if (Meteor.isServer) { - // Cards are often fetched within a board, so we create an index to make these - // queries more efficient. + // Cards are often fetched within a board, so we create an index to make these + // queries more efficient. Meteor.startup(() => { Cards._collection._ensureIndex({boardId: 1, createdAt: -1}); }); @@ -438,31 +499,31 @@ if (Meteor.isServer) { cardCreation(userId, doc); }); - // New activity for card (un)archivage + // New activity for card (un)archivage Cards.after.update((userId, doc, fieldNames) => { cardState(userId, doc, fieldNames); }); - //New activity for card moves + //New activity for card moves Cards.after.update(function (userId, doc, fieldNames) { const oldListId = this.previous.listId; cardMove(userId, doc, fieldNames, oldListId); }); - // Add a new activity if we add or remove a member to the card + // Add a new activity if we add or remove a member to the card Cards.before.update((userId, doc, fieldNames, modifier) => { cardMembers(userId, doc, fieldNames, modifier); }); - // Remove all activities associated with a card if we remove the card - // Remove also card_comments / checklists / attachments + // Remove all activities associated with a card if we remove the card + // Remove also card_comments / checklists / attachments Cards.after.remove((userId, doc) => { cardRemover(userId, doc); }); } //LISTS REST API if (Meteor.isServer) { - JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function (req, res, next) { + JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function (req, res) { const paramBoardId = req.params.boardId; const paramListId = req.params.listId; Authentication.checkBoardAccess(req.userId, paramBoardId); @@ -478,7 +539,7 @@ if (Meteor.isServer) { }); }); - JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) { + JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res) { const paramBoardId = req.params.boardId; const paramListId = req.params.listId; const paramCardId = req.params.cardId; @@ -489,11 +550,12 @@ if (Meteor.isServer) { }); }); - JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function (req, res, next) { + JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function (req, res) { Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; const check = Users.findOne({_id: req.body.authorId}); + const members = req.body.members || [req.body.authorId]; if (typeof check !== 'undefined') { const id = Cards.direct.insert({ title: req.body.title, @@ -501,8 +563,9 @@ if (Meteor.isServer) { listId: paramListId, description: req.body.description, userId: req.body.authorId, + swimlaneId: req.body.swimlaneId, sort: 0, - members: [req.body.authorId], + members, }); JsonRoutes.sendResult(res, { code: 200, @@ -521,7 +584,7 @@ if (Meteor.isServer) { } }); - JsonRoutes.add('PUT', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) { + JsonRoutes.add('PUT', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res) { Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; @@ -530,12 +593,12 @@ if (Meteor.isServer) { if (req.body.hasOwnProperty('title')) { const newTitle = req.body.title; Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false}, - {$set: {title: newTitle}}); + {$set: {title: newTitle}}); } if (req.body.hasOwnProperty('listId')) { const newParamListId = req.body.listId; Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false}, - {$set: {listId: newParamListId}}); + {$set: {listId: newParamListId}}); const card = Cards.findOne({_id: paramCardId} ); cardMove(req.body.authorId, card, {fieldName: 'listId'}, paramListId); @@ -544,7 +607,12 @@ if (Meteor.isServer) { if (req.body.hasOwnProperty('description')) { const newDescription = req.body.description; Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false}, - {$set: {description: newDescription}}); + {$set: {description: newDescription}}); + } + if (req.body.hasOwnProperty('labelIds')) { + const newlabelIds = req.body.labelIds; + Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false}, + {$set: {labelIds: newlabelIds}}); } JsonRoutes.sendResult(res, { code: 200, @@ -555,7 +623,7 @@ if (Meteor.isServer) { }); - JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) { + JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res) { Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; |