| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 | 
							- import Boards from './boards';
 
- export class CsvCreator {
 
-   constructor(data) {
 
-     // date to be used for timestamps during import
 
-     this._nowDate = new Date();
 
-     // index to help keep track of what information a column stores
 
-     // each row represents a card
 
-     this.fieldIndex = {};
 
-     this.lists = {};
 
-     // Map of members using username => wekanid
 
-     this.members = data.membersMapping ? data.membersMapping : {};
 
-     this.swimlane = null;
 
-   }
 
-   /**
 
-    * If dateString is provided,
 
-    * return the Date it represents.
 
-    * If not, will return the date when it was first called.
 
-    * This is useful for us, as we want all import operations to
 
-    * have the exact same date for easier later retrieval.
 
-    *
 
-    * @param {String} dateString a properly formatted Date
 
-    */
 
-   _now(dateString) {
 
-     if (dateString) {
 
-       return new Date(dateString);
 
-     }
 
-     if (!this._nowDate) {
 
-       this._nowDate = new Date();
 
-     }
 
-     return this._nowDate;
 
-   }
 
-   _user(wekanUserId) {
 
-     if (wekanUserId && this.members[wekanUserId]) {
 
-       return this.members[wekanUserId];
 
-     }
 
-     return Meteor.userId();
 
-   }
 
-   /**
 
-    * Map the header row titles to an index to help assign proper values to the cards' fields
 
-    * Valid headers (name of card fields):
 
-    * title, description, status, owner, member, label, due date, start date, finish date, created at, updated at
 
-    * Some header aliases can also be accepted.
 
-    * Headers are NOT case-sensitive.
 
-    *
 
-    * @param {Array} headerRow array from row of headers of imported CSV/TSV for cards
 
-    */
 
-   mapHeadertoCardFieldIndex(headerRow) {
 
-     const index = {};
 
-     for (let i = 0; i < headerRow.length; i++) {
 
-       switch (headerRow[i].trim().toLowerCase()) {
 
-         case 'title':
 
-           index.title = i;
 
-           break;
 
-         case 'description':
 
-           index.description = i;
 
-           break;
 
-         case 'stage':
 
-         case 'status':
 
-         case 'state':
 
-           index.stage = i;
 
-           break;
 
-         case 'owner':
 
-           index.owner = i;
 
-           break;
 
-         case 'members':
 
-         case 'member':
 
-           index.members = i;
 
-           break;
 
-         case 'labels':
 
-         case 'label':
 
-           index.labels = i;
 
-           break;
 
-         case 'due date':
 
-         case 'deadline':
 
-         case 'due at':
 
-           index.dueAt = i;
 
-           break;
 
-         case 'start date':
 
-         case 'start at':
 
-           index.startAt = i;
 
-           break;
 
-         case 'finish date':
 
-         case 'end at':
 
-           index.endAt = i;
 
-           break;
 
-         case 'creation date':
 
-         case 'created at':
 
-           index.createdAt = i;
 
-           break;
 
-         case 'update date':
 
-         case 'updated at':
 
-         case 'modified at':
 
-         case 'modified on':
 
-           index.modifiedAt = i;
 
-           break;
 
-       }
 
-     }
 
-     this.fieldIndex = index;
 
-   }
 
-   createBoard(csvData) {
 
-     const boardToCreate = {
 
-       archived: false,
 
-       color: 'belize',
 
-       createdAt: this._now(),
 
-       labels: [],
 
-       members: [
 
-         {
 
-           userId: Meteor.userId(),
 
-           wekanId: Meteor.userId(),
 
-           isActive: true,
 
-           isAdmin: true,
 
-           isNoComments: false,
 
-           isCommentOnly: false,
 
-           swimlaneId: false,
 
-         },
 
-       ],
 
-       modifiedAt: this._now(),
 
-       //default is private, should inform user.
 
-       permission: 'private',
 
-       slug: 'board',
 
-       stars: 0,
 
-       title: `Imported Board ${this._now()}`,
 
-     };
 
-     // create labels
 
-     const labelsToCreate = new Set();
 
-     for (let i = 1; i < csvData.length; i++) {
 
-       if (csvData[i][this.fieldIndex.labels]) {
 
-         for (const importedLabel of csvData[i][this.fieldIndex.labels].split(
 
-           ' ',
 
-         )) {
 
-           if (importedLabel && importedLabel.length > 0) {
 
-             labelsToCreate.add(importedLabel);
 
-           }
 
-         }
 
-       }
 
-     }
 
-     for (const label of labelsToCreate) {
 
-       let labelName, labelColor;
 
-       if (label.indexOf('-') > -1) {
 
-         labelName = label.split('-')[0];
 
-         labelColor = label.split('-')[1];
 
-       } else {
 
-         labelName = label;
 
-       }
 
-       const labelToCreate = {
 
-         _id: Random.id(6),
 
-         color: labelColor ? labelColor : 'black',
 
-         name: labelName,
 
-       };
 
-       boardToCreate.labels.push(labelToCreate);
 
-     }
 
-     const boardId = Boards.direct.insert(boardToCreate);
 
-     Boards.direct.update(boardId, {
 
-       $set: {
 
-         modifiedAt: this._now(),
 
-       },
 
-     });
 
-     // log activity
 
-     Activities.direct.insert({
 
-       activityType: 'importBoard',
 
-       boardId,
 
-       createdAt: this._now(),
 
-       source: {
 
-         id: boardId,
 
-         system: 'CSV/TSV',
 
-       },
 
-       // We attribute the import to current user,
 
-       // not the author from the original object.
 
-       userId: this._user(),
 
-     });
 
-     return boardId;
 
-   }
 
-   createSwimlanes(boardId) {
 
-     const swimlaneToCreate = {
 
-       archived: false,
 
-       boardId,
 
-       createdAt: this._now(),
 
-       title: 'Default',
 
-       sort: 1,
 
-     };
 
-     const swimlaneId = Swimlanes.direct.insert(swimlaneToCreate);
 
-     Swimlanes.direct.update(swimlaneId, { $set: { updatedAt: this._now() } });
 
-     this.swimlane = swimlaneId;
 
-   }
 
-   createLists(csvData, boardId) {
 
-     let numOfCreatedLists = 0;
 
-     for (let i = 1; i < csvData.length; i++) {
 
-       const listToCreate = {
 
-         archived: false,
 
-         boardId,
 
-         createdAt: this._now(),
 
-       };
 
-       if (csvData[i][this.fieldIndex.stage]) {
 
-         const existingList = Lists.find({
 
-           title: csvData[i][this.fieldIndex.stage],
 
-           boardId,
 
-         }).fetch();
 
-         if (existingList.length > 0) {
 
-           continue;
 
-         } else {
 
-           listToCreate.title = csvData[i][this.fieldIndex.stage];
 
-         }
 
-       } else listToCreate.title = `Imported List ${this._now()}`;
 
-       const listId = Lists.direct.insert(listToCreate);
 
-       this.lists[csvData[i][this.fieldIndex.stage]] = listId;
 
-       numOfCreatedLists++;
 
-       Lists.direct.update(listId, {
 
-         $set: {
 
-           updatedAt: this._now(),
 
-           sort: numOfCreatedLists,
 
-         },
 
-       });
 
-     }
 
-   }
 
-   createCards(csvData, boardId) {
 
-     for (let i = 1; i < csvData.length; i++) {
 
-       const cardToCreate = {
 
-         archived: false,
 
-         boardId,
 
-         createdAt: csvData[i][this.fieldIndex.createdAt]
 
-           ? this._now(new Date(csvData[i][this.fieldIndex.createdAt]))
 
-           : null,
 
-         dateLastActivity: this._now(),
 
-         description: csvData[i][this.fieldIndex.description],
 
-         listId: this.lists[csvData[i][this.fieldIndex.stage]],
 
-         swimlaneId: this.swimlane,
 
-         sort: -1,
 
-         title: csvData[i][this.fieldIndex.title],
 
-         userId: this._user(),
 
-         startAt: csvData[i][this.fieldIndex.startAt]
 
-           ? this._now(new Date(csvData[i][this.fieldIndex.startAt]))
 
-           : null,
 
-         dueAt: csvData[i][this.fieldIndex.dueAt]
 
-           ? this._now(new Date(csvData[i][this.fieldIndex.dueAt]))
 
-           : null,
 
-         endAt: csvData[i][this.fieldIndex.endAt]
 
-           ? this._now(new Date(csvData[i][this.fieldIndex.endAt]))
 
-           : null,
 
-         spentTime: null,
 
-         labelIds: [],
 
-         modifiedAt: csvData[i][this.fieldIndex.modifiedAt]
 
-           ? this._now(new Date(csvData[i][this.fieldIndex.modifiedAt]))
 
-           : null,
 
-       };
 
-       // add the labels
 
-       if (csvData[i][this.fieldIndex.labels]) {
 
-         const board = Boards.findOne(boardId);
 
-         for (const importedLabel of csvData[i][this.fieldIndex.labels].split(
 
-           ' ',
 
-         )) {
 
-           if (importedLabel && importedLabel.length > 0) {
 
-             let labelToApply;
 
-             if (importedLabel.indexOf('-') === -1) {
 
-               labelToApply = board.getLabel(importedLabel, 'black');
 
-             } else {
 
-               labelToApply = board.getLabel(
 
-                 importedLabel.split('-')[0],
 
-                 importedLabel.split('-')[1],
 
-               );
 
-             }
 
-             cardToCreate.labelIds.push(labelToApply._id);
 
-           }
 
-         }
 
-       }
 
-       // add the members
 
-       if (csvData[i][this.fieldIndex.members]) {
 
-         const wekanMembers = [];
 
-         for (const importedMember of csvData[i][this.fieldIndex.members].split(
 
-           ' ',
 
-         )) {
 
-           if (this.members[importedMember]) {
 
-             const wekanId = this.members[importedMember];
 
-             if (!wekanMembers.find(wId => wId === wekanId)) {
 
-               wekanMembers.push(wekanId);
 
-             }
 
-           }
 
-         }
 
-         if (wekanMembers.length > 0) {
 
-           cardToCreate.members = wekanMembers;
 
-         }
 
-       }
 
-       Cards.direct.insert(cardToCreate);
 
-     }
 
-   }
 
-   create(board, currentBoardId) {
 
-     const isSandstorm =
 
-       Meteor.settings &&
 
-       Meteor.settings.public &&
 
-       Meteor.settings.public.sandstorm;
 
-     if (isSandstorm && currentBoardId) {
 
-       const currentBoard = Boards.findOne(currentBoardId);
 
-       currentBoard.archive();
 
-     }
 
-     this.mapHeadertoCardFieldIndex(board[0]);
 
-     const boardId = this.createBoard(board);
 
-     this.createLists(board, boardId);
 
-     this.createSwimlanes(boardId);
 
-     this.createCards(board, boardId);
 
-     return boardId;
 
-   }
 
- }
 
 
  |