summaryrefslogtreecommitdiffstats
path: root/models/wekanCreator.js
diff options
context:
space:
mode:
Diffstat (limited to 'models/wekanCreator.js')
-rw-r--r--models/wekanCreator.js150
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;