diff options
Diffstat (limited to 'models/wekanCreator.js')
-rw-r--r-- | models/wekanCreator.js | 150 |
1 files changed, 100 insertions, 50 deletions
diff --git a/models/wekanCreator.js b/models/wekanCreator.js index 3cd65fd7..4551979b 100644 --- a/models/wekanCreator.js +++ b/models/wekanCreator.js @@ -14,6 +14,7 @@ export class WekanCreator { board: null, cards: {}, lists: {}, + swimlanes: {}, }; // The object creator Wekan Id, indexed by the object Wekan id // (so we only parse actions once!) @@ -23,6 +24,8 @@ export class WekanCreator { // Map of labels Wekan ID => Wekan ID this.labels = {}; + // Map of swimlanes Wekan ID => Wekan ID + this.swimlanes = {}; // Map of lists Wekan ID => Wekan ID this.lists = {}; // Map of cards Wekan ID => Wekan ID @@ -33,6 +36,8 @@ export class WekanCreator { this.attachmentIds = {}; // Map of checklists Wekan ID => Wekan ID this.checklists = {}; + // Map of checklistItems Wekan ID => Wekan ID + this.checklistItems = {}; // The comments, indexed by Wekan card id (to map when importing cards) this.comments = {}; // the members, indexed by Wekan member id => Wekan user ID @@ -121,59 +126,62 @@ export class WekanCreator { })]); } + checkSwimlanes(wekanSwimlanes) { + check(wekanSwimlanes, [Match.ObjectIncluding({ + archived: Boolean, + title: String, + })]); + } + checkChecklists(wekanChecklists) { check(wekanChecklists, [Match.ObjectIncluding({ cardId: String, title: String, - items: [Match.ObjectIncluding({ - isFinished: Boolean, - title: String, - })], + })]); + } + + checkChecklistItems(wekanChecklistItems) { + check(wekanChecklistItems, [Match.ObjectIncluding({ + cardId: String, + title: String, })]); } // You must call parseActions before calling this one. - createBoardAndLabels(wekanBoard) { + createBoardAndLabels(boardToImport) { const boardToCreate = { - archived: wekanBoard.archived, - color: wekanBoard.color, + archived: boardToImport.archived, + color: boardToImport.color, // very old boards won't have a creation activity so no creation date - createdAt: this._now(wekanBoard.createdAt), + createdAt: this._now(boardToImport.createdAt), labels: [], members: [{ userId: Meteor.userId(), - isAdmin: true, + wekanId: Meteor.userId(), isActive: true, + isAdmin: true, isCommentOnly: false, + swimlaneId: false, }], // Standalone Export has modifiedAt missing, adding modifiedAt to fix it - modifiedAt: this._now(wekanBoard.modifiedAt), - permission: wekanBoard.permission, - slug: getSlug(wekanBoard.title) || 'board', + modifiedAt: this._now(boardToImport.modifiedAt), + permission: boardToImport.permission, + slug: getSlug(boardToImport.title) || 'board', stars: 0, - title: wekanBoard.title, + title: boardToImport.title, }; // now add other members - if(wekanBoard.members) { - wekanBoard.members.forEach((wekanMember) => { - const wekanId = wekanMember.userId; - // do we have a mapping? - if(this.members[wekanId]) { - const wekanId = this.members[wekanId]; - // do we already have it in our list? - const wekanMember = boardToCreate.members.find((wekanMember) => wekanMember.userId === wekanId); - if(!wekanMember) { - boardToCreate.members.push({ - userId: wekanId, - isAdmin: wekanMember.isAdmin, - isActive: true, - isCommentOnly: false, - }); - } - } + if(boardToImport.members) { + boardToImport.members.forEach((wekanMember) => { + // do we already have it in our list? + if(!boardToCreate.members.some((member) => member.wekanId === wekanMember.wekanId)) + boardToCreate.members.push({ + ... wekanMember, + userId: wekanMember.wekanId, + }); }); } - wekanBoard.labels.forEach((label) => { + boardToImport.labels.forEach((label) => { const labelToCreate = { _id: Random.id(6), color: label.color, @@ -192,7 +200,7 @@ export class WekanCreator { boardId, createdAt: this._now(), source: { - id: wekanBoard.id, + id: boardToImport.id, system: 'Wekan', }, // We attribute the import to current user, @@ -220,11 +228,15 @@ export class WekanCreator { dateLastActivity: this._now(), description: card.description, listId: this.lists[card.listId], + swimlaneId: this.swimlanes[card.swimlaneId], sort: card.sort, title: card.title, // we attribute the card to its creator if available userId: this._user(this.createdBy.cards[card._id]), + isOvertime: card.isOvertime || false, + startAt: card.startAt ? this._now(card.startAt) : null, dueAt: card.dueAt ? this._now(card.dueAt) : null, + spentTime: card.spentTime || null, }; // add labels if (card.labelIds) { @@ -378,7 +390,7 @@ export class WekanCreator { } createLists(wekanLists, boardId) { - wekanLists.forEach((list) => { + wekanLists.forEach((list, listIndex) => { const listToCreate = { archived: list.archived, boardId, @@ -388,6 +400,7 @@ export class WekanCreator { // we require. createdAt: this._now(this.createdAt.lists[list.id]), title: list.title, + sort: list.sort ? list.sort : listIndex, }; const listId = Lists.direct.insert(listToCreate); Lists.direct.update(listId, {$set: {'updatedAt': this._now()}}); @@ -409,7 +422,27 @@ export class WekanCreator { }); } + createSwimlanes(wekanSwimlanes, boardId) { + wekanSwimlanes.forEach((swimlane, swimlaneIndex) => { + const swimlaneToCreate = { + archived: swimlane.archived, + boardId, + // We are being defensing here by providing a default date (now) if the + // creation date wasn't found on the action log. This happen on old + // Wekan boards (eg from 2013) that didn't log the 'createList' action + // we require. + createdAt: this._now(this.createdAt.swimlanes[swimlane._id]), + title: swimlane.title, + sort: swimlane.sort ? swimlane.sort : swimlaneIndex, + }; + const swimlaneId = Swimlanes.direct.insert(swimlaneToCreate); + Swimlanes.direct.update(swimlaneId, {$set: {'updatedAt': this._now()}}); + this.swimlanes[swimlane._id] = swimlaneId; + }); + } + createChecklists(wekanChecklists) { + const result = []; wekanChecklists.forEach((checklist, checklistIndex) => { // Create the checklist const checklistToCreate = { @@ -419,19 +452,24 @@ export class WekanCreator { sort: checklist.sort ? checklist.sort : checklistIndex, }; const checklistId = Checklists.direct.insert(checklistToCreate); - // keep track of Wekan id => WeKan id this.checklists[checklist._id] = checklistId; - // Now add the items to the checklist - const itemsToCreate = []; - checklist.items.forEach((item, itemIndex) => { - itemsToCreate.push({ - _id: checklistId + itemsToCreate.length, - title: item.title, - isFinished: item.isFinished, - sort: item.sort ? item.sort : itemIndex, - }); - }); - Checklists.direct.update(checklistId, {$set: {items: itemsToCreate}}); + result.push(checklistId); + }); + return result; + } + + createChecklistItems(wekanChecklistItems) { + wekanChecklistItems.forEach((checklistitem, checklistitemIndex) => { + // Create the checklistItem + const checklistItemTocreate = { + title: checklistitem.title, + checklistId: this.checklists[checklistitem.checklistId], + cardId: this.cards[checklistitem.cardId], + sort: checklistitem.sort ? checklistitem.sort : checklistitemIndex, + isFinished: checklistitem.isFinished, + }; + const checklistItemId = ChecklistItems.direct.insert(checklistItemTocreate); + this.checklistItems[checklistitem._id] = checklistItemId; }); } @@ -445,14 +483,17 @@ export class WekanCreator { const wekanAttachment = wekanBoard.attachments.filter((attachment) => { return attachment._id === activity.attachmentId; })[0]; - if(wekanAttachment.url || wekanAttachment.file) { + + if ( typeof wekanAttachment !== 'undefined' && wekanAttachment ) { + if(wekanAttachment.url || wekanAttachment.file) { // we cannot actually create the Wekan attachment, because we don't yet // have the cards to attach it to, so we store it in the instance variable. - const wekanCardId = activity.cardId; - if(!this.attachments[wekanCardId]) { - this.attachments[wekanCardId] = []; + const wekanCardId = activity.cardId; + if(!this.attachments[wekanCardId]) { + this.attachments[wekanCardId] = []; + } + this.attachments[wekanCardId].push(wekanAttachment); } - this.attachments[wekanCardId].push(wekanAttachment); } break; } @@ -481,6 +522,11 @@ export class WekanCreator { const listId = activity.listId; this.createdAt.lists[listId] = activity.createdAt; break; + } + case 'createSwimlane': { + const swimlaneId = activity.swimlaneId; + this.createdAt.swimlanes[swimlaneId] = activity.createdAt; + break; }} }); } @@ -602,8 +648,10 @@ export class WekanCreator { this.checkBoard(board); this.checkLabels(board.labels); this.checkLists(board.lists); + this.checkSwimlanes(board.swimlanes); this.checkCards(board.cards); this.checkChecklists(board.checklists); + this.checkChecklistItems(board.checklistItems); } catch (e) { throw new Meteor.Error('error-json-schema'); } @@ -620,8 +668,10 @@ export class WekanCreator { this.parseActivities(board); const boardId = this.createBoardAndLabels(board); this.createLists(board.lists, boardId); + this.createSwimlanes(board.swimlanes, boardId); this.createCards(board.cards, boardId); this.createChecklists(board.checklists); + this.createChecklistItems(board.checklistItems); this.importActivities(board.activities, boardId); // XXX add members return boardId; |