diff options
author | Lauri Ojansivu <x@xet7.org> | 2019-02-27 21:03:54 +0200 |
---|---|---|
committer | Lauri Ojansivu <x@xet7.org> | 2019-02-27 21:03:54 +0200 |
commit | 82a728df7111413e4a1b106f4cd18265da5f397b (patch) | |
tree | 103291d880fcd494c115b216616a4e90bbff0832 /models | |
parent | 3f067c793cba98df663fb7646d5d3aafc79efe09 (diff) | |
parent | 904b5bf0f5f6e36131bf2d081a5d08fef408ac81 (diff) | |
download | wekan-82a728df7111413e4a1b106f4cd18265da5f397b.tar.gz wekan-82a728df7111413e4a1b106f4cd18265da5f397b.tar.bz2 wekan-82a728df7111413e4a1b106f4cd18265da5f397b.zip |
Merge branch 'edge' into meteor-1.8
Diffstat (limited to 'models')
-rw-r--r-- | models/boards.js | 110 | ||||
-rw-r--r-- | models/cardComments.js | 6 | ||||
-rw-r--r-- | models/cards.js | 33 | ||||
-rw-r--r-- | models/checklists.js | 13 | ||||
-rw-r--r-- | models/lists.js | 59 | ||||
-rw-r--r-- | models/swimlanes.js | 74 | ||||
-rw-r--r-- | models/users.js | 86 |
7 files changed, 374 insertions, 7 deletions
diff --git a/models/boards.js b/models/boards.js index 71831a63..0db2e48e 100644 --- a/models/boards.js +++ b/models/boards.js @@ -304,10 +304,32 @@ Boards.attachSchema(new SimpleSchema({ defaultValue: false, optional: true, }, + type: { + /** + * The type of board + */ + type: String, + defaultValue: 'board', + }, })); Boards.helpers({ + copy() { + const oldId = this._id; + delete this._id; + const _id = Boards.insert(this); + + // Copy all swimlanes in board + Swimlanes.find({ + boardId: oldId, + archived: false, + }).forEach((swimlane) => { + swimlane.type = 'swimlane'; + swimlane.boardId = _id; + swimlane.copy(oldId); + }); + }, /** * Is supplied user authorized to view this board? */ @@ -456,6 +478,75 @@ Boards.helpers({ return _id; }, + searchBoards(term) { + check(term, Match.OneOf(String, null, undefined)); + + const query = { boardId: this._id }; + query.type = 'cardType-linkedBoard'; + query.archived = false; + + const projection = { limit: 10, sort: { createdAt: -1 } }; + + if (term) { + const regex = new RegExp(term, 'i'); + + query.$or = [ + { title: regex }, + { description: regex }, + ]; + } + + return Cards.find(query, projection); + }, + + searchSwimlanes(term) { + check(term, Match.OneOf(String, null, undefined)); + + const query = { boardId: this._id }; + if (this.isTemplatesBoard()) { + query.type = 'template-swimlane'; + query.archived = false; + } else { + query.type = {$nin: ['template-swimlane']}; + } + const projection = { limit: 10, sort: { createdAt: -1 } }; + + if (term) { + const regex = new RegExp(term, 'i'); + + query.$or = [ + { title: regex }, + { description: regex }, + ]; + } + + return Swimlanes.find(query, projection); + }, + + searchLists(term) { + check(term, Match.OneOf(String, null, undefined)); + + const query = { boardId: this._id }; + if (this.isTemplatesBoard()) { + query.type = 'template-list'; + query.archived = false; + } else { + query.type = {$nin: ['template-list']}; + } + const projection = { limit: 10, sort: { createdAt: -1 } }; + + if (term) { + const regex = new RegExp(term, 'i'); + + query.$or = [ + { title: regex }, + { description: regex }, + ]; + } + + return Lists.find(query, projection); + }, + searchCards(term, excludeLinked) { check(term, Match.OneOf(String, null, undefined)); @@ -463,6 +554,12 @@ Boards.helpers({ if (excludeLinked) { query.linkedId = null; } + if (this.isTemplatesBoard()) { + query.type = 'template-card'; + query.archived = false; + } else { + query.type = {$nin: ['template-card']}; + } const projection = { limit: 10, sort: { createdAt: -1 } }; if (term) { @@ -559,6 +656,13 @@ Boards.helpers({ }); }, + isTemplateBoard() { + return this.type === 'template-board'; + }, + + isTemplatesBoard() { + return this.type === 'template-container'; + }, }); @@ -907,7 +1011,7 @@ if (Meteor.isServer) { * @param {string} userId the ID of the user to retrieve the data * @return_type [{_id: string, title: string}] - */ + */ JsonRoutes.add('GET', '/api/users/:userId/boards', function (req, res) { try { Authentication.checkLoggedIn(req.userId); @@ -944,7 +1048,7 @@ if (Meteor.isServer) { * * @return_type [{_id: string, title: string}] - */ + */ JsonRoutes.add('GET', '/api/boards', function (req, res) { try { Authentication.checkUserId(req.userId); @@ -1015,7 +1119,7 @@ if (Meteor.isServer) { * * @return_type {_id: string, defaultSwimlaneId: string} - */ + */ JsonRoutes.add('POST', '/api/boards', function (req, res) { try { Authentication.checkUserId(req.userId); diff --git a/models/cardComments.js b/models/cardComments.js index 974c5ec9..fcb97104 100644 --- a/models/cardComments.js +++ b/models/cardComments.js @@ -67,6 +67,12 @@ CardComments.allow({ }); CardComments.helpers({ + copy(newCardId) { + this.cardId = newCardId; + delete this._id; + CardComments.insert(this); + }, + user() { return Users.findOne(this.userId); }, diff --git a/models/cards.js b/models/cards.js index ff19a9a0..c733c7f8 100644 --- a/models/cards.js +++ b/models/cards.js @@ -246,7 +246,7 @@ Cards.attachSchema(new SimpleSchema({ * type of the card */ type: String, - defaultValue: '', + defaultValue: 'cardType-card', }, linkedId: { /** @@ -272,6 +272,31 @@ Cards.allow({ }); Cards.helpers({ + copy() { + const oldId = this._id; + delete this._id; + const _id = Cards.insert(this); + + // copy checklists + Checklists.find({cardId: oldId}).forEach((ch) => { + ch.copy(_id); + }); + + // copy subtasks + Cards.find({parentId: oldId}).forEach((subtask) => { + subtask.parentId = _id; + subtask._id = null; + Cards.insert(subtask); + }); + + // copy card comments + CardComments.find({cardId: oldId}).forEach((cmt) => { + cmt.copy(_id); + }); + + return _id; + }, + list() { return Lists.findOne(this.listId); }, @@ -930,6 +955,10 @@ Cards.helpers({ return this.assignedBy; } }, + + isTemplateCard() { + return this.type === 'template-card'; + }, }); Cards.mutations({ @@ -1230,7 +1259,7 @@ Cards.mutations({ function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId) { if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) || - (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){ + (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){ Activities.insert({ userId, oldListId, diff --git a/models/checklists.js b/models/checklists.js index a372fafa..9e763f1a 100644 --- a/models/checklists.js +++ b/models/checklists.js @@ -48,6 +48,19 @@ Checklists.attachSchema(new SimpleSchema({ })); Checklists.helpers({ + copy(newCardId) { + const oldChecklistId = this._id; + this._id = null; + this.cardId = newCardId; + const newChecklistId = Checklists.insert(this); + ChecklistItems.find({checklistId: oldChecklistId}).forEach((item) => { + item._id = null; + item.checklistId = newChecklistId; + item.cardId = newCardId; + ChecklistItems.insert(item); + }); + }, + itemCount() { return ChecklistItems.find({ checklistId: this._id }).count(); }, diff --git a/models/lists.js b/models/lists.js index 54e7d037..d76c961c 100644 --- a/models/lists.js +++ b/models/lists.js @@ -27,6 +27,13 @@ Lists.attachSchema(new SimpleSchema({ */ type: String, }, + swimlaneId: { + /** + * the swimlane associated to this list. Used for templates + */ + type: String, + defaultValue: '', + }, createdAt: { /** * creation date @@ -107,6 +114,13 @@ Lists.attachSchema(new SimpleSchema({ 'saddlebrown', 'paleturquoise', 'mistyrose', 'indigo', ], }, + type: { + /** + * The type of list + */ + type: String, + defaultValue: 'list', + }, })); Lists.allow({ @@ -123,6 +137,37 @@ Lists.allow({ }); Lists.helpers({ + copy(swimlaneId) { + const oldId = this._id; + const oldSwimlaneId = this.swimlaneId || null; + let _id = null; + existingListWithSameName = Lists.findOne({ + boardId: this.boardId, + title: this.title, + archived: false, + }); + if (existingListWithSameName) { + _id = existingListWithSameName._id; + } else { + delete this._id; + delete this.swimlaneId; + _id = Lists.insert(this); + } + + // Copy all cards in list + Cards.find({ + swimlaneId: oldSwimlaneId, + listId: oldId, + archived: false, + }).forEach((card) => { + card.type = 'cardType-card'; + card.listId = _id; + card.boardId = this.boardId; + card.swimlaneId = swimlaneId; + card.copy(); + }); + }, + cards(swimlaneId) { const selector = { listId: this._id, @@ -169,6 +214,10 @@ Lists.helpers({ return this.color; return ''; }, + + isTemplateList() { + return this.type === 'template-list'; + }, }); Lists.mutations({ @@ -177,10 +226,20 @@ Lists.mutations({ }, archive() { + if (this.isTemplateList()) { + this.cards().forEach((card) => { + return card.archive(); + }); + } return { $set: { archived: true } }; }, restore() { + if (this.isTemplateList()) { + this.allCards().forEach((card) => { + return card.restore(); + }); + } return { $set: { archived: false } }; }, diff --git a/models/swimlanes.js b/models/swimlanes.js index e2c3925c..a3427fc6 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -78,6 +78,13 @@ Swimlanes.attachSchema(new SimpleSchema({ } }, }, + type: { + /** + * The type of swimlane + */ + type: String, + defaultValue: 'swimlane', + }, })); Swimlanes.allow({ @@ -94,6 +101,28 @@ Swimlanes.allow({ }); Swimlanes.helpers({ + copy(oldBoardId) { + const oldId = this._id; + delete this._id; + const _id = Swimlanes.insert(this); + + const query = { + swimlaneId: {$in: [oldId, '']}, + archived: false, + }; + if (oldBoardId) { + query.boardId = oldBoardId; + } + + // Copy all lists in swimlane + Lists.find(query).forEach((list) => { + list.type = 'list'; + list.swimlaneId = oldId; + list.boardId = this.boardId; + list.copy(_id); + }); + }, + cards() { return Cards.find(Filter.mongoSelector({ swimlaneId: this._id, @@ -101,6 +130,18 @@ Swimlanes.helpers({ }), { sort: ['sort'] }); }, + lists() { + return Lists.find(Filter.mongoSelector({ + boardId: this.boardId, + swimlaneId: {$in: [this._id, '']}, + archived: false, + }), { sort: ['sort'] }); + }, + + allLists() { + return Lists.find({ swimlaneId: this._id }); + }, + allCards() { return Cards.find({ swimlaneId: this._id }); }, @@ -114,6 +155,29 @@ Swimlanes.helpers({ return this.color; return ''; }, + + isTemplateSwimlane() { + return this.type === 'template-swimlane'; + }, + + isTemplateContainer() { + return this.type === 'template-container'; + }, + + isListTemplatesSwimlane() { + const user = Users.findOne(Meteor.userId()); + return user.profile.listTemplatesSwimlaneId === this._id; + }, + + isCardTemplatesSwimlane() { + const user = Users.findOne(Meteor.userId()); + return user.profile.cardTemplatesSwimlaneId === this._id; + }, + + isBoardTemplatesSwimlane() { + const user = Users.findOne(Meteor.userId()); + return user.profile.boardTemplatesSwimlaneId === this._id; + }, }); Swimlanes.mutations({ @@ -122,10 +186,20 @@ Swimlanes.mutations({ }, archive() { + if (this.isTemplateSwimlane()) { + this.lists().forEach((list) => { + return list.archive(); + }); + } return { $set: { archived: true } }; }, restore() { + if (this.isTemplateSwimlane()) { + this.allLists().forEach((list) => { + return list.restore(); + }); + } return { $set: { archived: false } }; }, diff --git a/models/users.js b/models/users.js index c6c0f857..0dd9c1d6 100644 --- a/models/users.js +++ b/models/users.js @@ -159,6 +159,34 @@ Users.attachSchema(new SimpleSchema({ 'board-view-cal', ], }, + 'profile.templatesBoardId': { + /** + * Reference to the templates board + */ + type: String, + defaultValue: '', + }, + 'profile.cardTemplatesSwimlaneId': { + /** + * Reference to the card templates swimlane Id + */ + type: String, + defaultValue: '', + }, + 'profile.listTemplatesSwimlaneId': { + /** + * Reference to the list templates swimlane Id + */ + type: String, + defaultValue: '', + }, + 'profile.boardTemplatesSwimlaneId': { + /** + * Reference to the board templates swimlane Id + */ + type: String, + defaultValue: '', + }, services: { /** * services field of the user @@ -328,6 +356,14 @@ Users.helpers({ const profile = this.profile || {}; return profile.language || 'en'; }, + + getTemplatesBoardId() { + return this.profile.templatesBoardId; + }, + + getTemplatesBoardSlug() { + return Boards.findOne(this.profile.templatesBoardId).slug; + }, }); Users.mutations({ @@ -675,7 +711,6 @@ if (Meteor.isServer) { CollectionHooks.getUserId = () => { return fakeUserId.get() || getUserId(); }; - /* if (!isSandstorm) { Users.after.insert((userId, doc) => { const fakeUser = { @@ -685,6 +720,7 @@ if (Meteor.isServer) { }; fakeUserId.withValue(doc._id, () => { + /* // Insert the Welcome Board Boards.insert({ title: TAPi18n.__('welcome-board'), @@ -701,10 +737,56 @@ if (Meteor.isServer) { Lists.insert({title: TAPi18n.__(title), boardId, sort: titleIndex}, fakeUser); }); }); + */ + + Boards.insert({ + title: TAPi18n.__('templates'), + permission: 'private', + type: 'template-container', + }, fakeUser, (err, boardId) => { + + // Insert the reference to our templates board + Users.update(fakeUserId.get(), {$set: {'profile.templatesBoardId': boardId}}); + + // Insert the card templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('card-templates-swimlane'), + boardId, + sort: 1, + type: 'template-container', + }, fakeUser, (err, swimlaneId) => { + + // Insert the reference to out card templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.cardTemplatesSwimlaneId': swimlaneId}}); + }); + + // Insert the list templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('list-templates-swimlane'), + boardId, + sort: 2, + type: 'template-container', + }, fakeUser, (err, swimlaneId) => { + + // Insert the reference to out list templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.listTemplatesSwimlaneId': swimlaneId}}); + }); + + // Insert the board templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('board-templates-swimlane'), + boardId, + sort: 3, + type: 'template-container', + }, fakeUser, (err, swimlaneId) => { + + // Insert the reference to out board templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.boardTemplatesSwimlaneId': swimlaneId}}); + }); + }); }); }); } - */ Users.after.insert((userId, doc) => { |