Browse Source

Import board: import comments and log activities

Xavier Priour 9 years ago
parent
commit
4540bd36c4

+ 31 - 25
client/components/activities/activities.jade

@@ -14,41 +14,56 @@ template(name="boardActivities")
       p.activity-desc
         +memberName(user=user)
 
-        if($eq activityType 'createBoard')
-          | {{_ 'activity-created' boardLabel}}.
+        if($eq activityType 'addAttachment')
+          | {{{_ 'activity-attached' attachmentLink cardLink}}}.
 
-        if($eq activityType 'createList')
-          | {{_ 'activity-added' list.title boardLabel}}.
+        if($eq activityType 'addBoardMember')
+          | {{{_ 'activity-added' memberLink boardLabel}}}.
+
+        if($eq activityType 'addComment')
+          | {{{_ 'activity-on' cardLink}}}
+          a.activity-comment(href="{{ card.absoluteUrl }}")
+            +viewer
+              = comment.text
+
+        if($eq activityType 'archivedCard')
+          | {{{_ 'activity-archived' cardLink}}}.
 
         if($eq activityType 'archivedList')
           | {{_ 'activity-archived' list.title}}.
 
+        if($eq activityType 'createBoard')
+          | {{_ 'activity-created' boardLabel}}.
+
         if($eq activityType 'createCard')
           | {{{_ 'activity-added' cardLink boardLabel}}}.
 
+        if($eq activityType 'createList')
+          | {{_ 'activity-added' list.title boardLabel}}.
+
+        if($eq activityType 'importBoard')
+          | {{{_ 'activity-imported-board' boardLabel sourceLink}}}.
+
         if($eq activityType 'importCard')
           | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}.
 
-        if($eq activityType 'archivedCard')
-          | {{{_ 'activity-archived' cardLink}}}.
+        if($eq activityType 'importList')
+          | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}.
 
-        if($eq activityType 'restoredCard')
-          | {{{_ 'activity-sent' cardLink boardLabel}}}.
+        if($eq activityType 'joinMember')
+          if($eq currentUser._id member._id)
+            | {{{_ 'activity-joined' cardLink}}}.
+          else
+            | {{{_ 'activity-added' memberLink cardLink}}}.
 
         if($eq activityType 'moveCard')
           | {{{_ 'activity-moved' cardLink oldList.title list.title}}}.
 
-        if($eq activityType 'addBoardMember')
-          | {{{_ 'activity-added' memberLink boardLabel}}}.
-
         if($eq activityType 'removeBoardMember')
           | {{{_ 'activity-excluded' memberLink boardLabel}}}.
 
-        if($eq activityType 'joinMember')
-          if($eq currentUser._id member._id)
-            | {{{_ 'activity-joined' cardLink}}}.
-          else
-            | {{{_ 'activity-added' memberLink cardLink}}}.
+        if($eq activityType 'restoredCard')
+          | {{{_ 'activity-sent' cardLink boardLabel}}}.
 
         if($eq activityType 'unjoinMember')
           if($eq currentUser._id member._id)
@@ -56,15 +71,6 @@ template(name="boardActivities")
           else
             | {{{_ 'activity-removed' memberLink cardLink}}}.
 
-        if($eq activityType 'addComment')
-          | {{{_ 'activity-on' cardLink}}}
-          a.activity-comment(href="{{ card.absoluteUrl }}")
-            +viewer
-              = comment.text
-
-        if($eq activityType 'addAttachment')
-          | {{{_ 'activity-attached' attachmentLink cardLink}}}.
-
         span.activity-meta {{ moment createdAt }}
 
 template(name="cardActivities")

+ 14 - 3
client/components/activities/activities.js

@@ -60,11 +60,22 @@ BlazeComponent.extendComponent({
     }, card.title));
   },
 
+  listLabel() {
+    return this.currentData().list().title;
+  },
+
   sourceLink() {
     const source = this.currentData().source;
-    return source && Blaze.toHTML(HTML.A({
-      href: source.url,
-    }, source.system));
+    if(source) {
+      if(source.url) {
+        return Blaze.toHTML(HTML.A({
+          href: source.url,
+        }, source.system));
+      } else {
+        return source.system;
+      }
+    }
+    return null;
   },
 
   memberLink() {

+ 1 - 1
client/components/import/import.js

@@ -46,7 +46,7 @@ const ImportPopup = BlazeComponent.extendComponent({
 
   onFinish() {
     Popup.close();
-  }
+  },
 });
 
 ImportPopup.extendComponent({

+ 1 - 0
i18n/en.i18n.json

@@ -8,6 +8,7 @@
     "activity-created": "created %s",
     "activity-excluded": "excluded %s from %s",
     "activity-imported": "imported %s into %s from %s",
+    "activity-imported-board": "imported %s from %s",
     "activity-joined": "joined %s",
     "activity-moved": "moved %s from %s to %s",
     "activity-on": "on %s",

+ 117 - 49
models/import.js

@@ -10,12 +10,14 @@ class TrelloCreator {
     this.labels = {};
     // the lists we created, indexed by Trello id (to map when importing cards)
     this.lists = {};
+    // the comments, indexed by Trello card id (to map when importing cards)
+    this.comments = {};
   }
 
   /**
    * must call parseActions before calling this one
    */
-  createBoardAndLabels(trelloBoard, dateOfImport) {
+  createBoardAndLabels(trelloBoard) {
     const createdAt = this.createdAt.board;
     const boardToCreate = {
       archived: trelloBoard.closed,
@@ -35,7 +37,7 @@ class TrelloCreator {
       title: trelloBoard.name,
     };
     trelloBoard.labels.forEach((label) => {
-      labelToCreate = {
+      const labelToCreate = {
         _id: Random.id(6),
         color: label.color,
         name: label.name,
@@ -45,11 +47,23 @@ class TrelloCreator {
       boardToCreate.labels.push(labelToCreate);
     });
     const boardId = Boards.direct.insert(boardToCreate);
-    // XXX add activities
+    // log activity
+    Activities.direct.insert({
+      activityType: 'importBoard',
+      boardId,
+      createdAt: new Date(),
+      source: {
+        id: trelloBoard.id,
+        system: 'Trello',
+        url: trelloBoard.url,
+      },
+      // we attribute the import to current user, not the one from the original object
+      userId: Meteor.userId(),
+    });
     return boardId;
   }
 
-  createLists(trelloLists, boardId, dateOfImport) {
+  createLists(trelloLists, boardId) {
     trelloLists.forEach((list) => {
       const listToCreate = {
         archived: list.closed,
@@ -60,17 +74,29 @@ class TrelloCreator {
       };
       listToCreate._id = Lists.direct.insert(listToCreate);
       this.lists[list.id] = listToCreate;
-      // XXX add activities
+      // log activity
+      Activities.direct.insert({
+        activityType: 'importList',
+        boardId,
+        createdAt: new Date(),
+        listId: listToCreate._id,
+        source: {
+          id: list.id,
+          system: 'Trello',
+        },
+        // we attribute the import to current user, not the one from the original object
+        userId: Meteor.userId(),
+      });
     });
   }
 
-  createCards(trelloCards, boardId, dateOfImport) {
+  createCardsAndComments(trelloCards, boardId) {
     trelloCards.forEach((card) => {
       const cardToCreate = {
         archived: card.closed,
         boardId,
         createdAt: this.createdAt.cards[card.id],
-        dateLastActivity: dateOfImport,
+        dateLastActivity: new Date(),
         description: card.desc,
         listId: this.lists[card.idList]._id,
         sort: card.pos,
@@ -84,37 +110,102 @@ class TrelloCreator {
           return this.labels[trelloId]._id;
         });
       }
-      Cards.direct.insert(cardToCreate);
-      // XXX add comments
+      // insert card
+      const cardId = Cards.direct.insert(cardToCreate);
+      // log activity
+      Activities.direct.insert({
+        activityType: 'importCard',
+        boardId,
+        cardId,
+        createdAt: new Date(),
+        listId: cardToCreate.listId,
+        source: {
+          id: card.id,
+          system: 'Trello',
+          url: card.url,
+        },
+        // we attribute the import to current user, not the one from the original card
+        userId: Meteor.userId(),
+      });
+      // add comments
+      const comments = this.comments[card.id];
+      if(comments) {
+        comments.forEach((comment) => {
+          const commentToCreate = {
+            boardId,
+            cardId,
+            createdAt: comment.date,
+            text: comment.data.text,
+            // XXX use the original comment user instead
+            userId: Meteor.userId(),
+          };
+          const commentId = CardComments.direct.insert(commentToCreate);
+          Activities.direct.insert({
+            activityType: 'addComment',
+            boardId: commentToCreate.boardId,
+            cardId: commentToCreate.cardId,
+            commentId,
+            createdAt: commentToCreate.createdAt,
+            userId: commentToCreate.userId,
+          });
+        });
+      }
       // XXX add attachments
-      // XXX add activities
     });
   }
 
   parseActions(trelloActions) {
-    trelloActions.forEach((action) =>{
+    trelloActions.forEach((action) => {
       switch (action.type) {
-        case 'createBoard':
-          this.createdAt.board = action.date;
-          break;
-        case 'createCard':
-          const cardId = action.data.card.id;
-          this.createdAt.cards[cardId] = action.date;
-          break;
-        case 'createList':
-          const listId = action.data.list.id;
-          this.createdAt.lists[listId] = action.date;
-          break;
-        // XXX extract comments as well
-        default:
-          // do nothing
-          break;
+      case 'createBoard':
+        this.createdAt.board = action.date;
+        break;
+      case 'createCard':
+        const cardId = action.data.card.id;
+        this.createdAt.cards[cardId] = action.date;
+        break;
+      case 'createList':
+        const listId = action.data.list.id;
+        this.createdAt.lists[listId] = action.date;
+        break;
+      case 'commentCard':
+        const id = action.data.card.id;
+        if(this.comments[id]) {
+          this.comments[id].push(action);
+        } else {
+          this.comments[id] = [action];
+        }
+        break;
+      default:
+        // do nothing
+        break;
       }
     });
   }
 }
 
 Meteor.methods({
+  importTrelloBoard(trelloBoard, data) {
+    const trelloCreator = new TrelloCreator();
+    // 1. check parameters are ok from a syntax point of view
+    try {
+      // XXX do proper checking
+      check(trelloBoard, Object);
+      check(data, Object);
+    } catch(e) {
+      throw new Meteor.Error('error-json-schema');
+    }
+    // 2. check parameters are ok from a business point of view (exist & authorized)
+    // XXX check we are allowed
+    // 3. create all elements
+    trelloCreator.parseActions(trelloBoard.actions);
+    const boardId = trelloCreator.createBoardAndLabels(trelloBoard);
+    trelloCreator.createLists(trelloBoard.lists, boardId);
+    trelloCreator.createCardsAndComments(trelloBoard.cards, boardId);
+    // XXX set modifiedAt or lastActivity
+    // XXX add members
+    return boardId;
+  },
   importTrelloCard(trelloCard, data) {
     // 1. check parameters are ok from a syntax point of view
     const DateString = Match.Where(function (dateAsString) {
@@ -245,27 +336,4 @@ Meteor.methods({
     });
     return cardId;
   },
-  importTrelloBoard(trelloBoard, data) {
-    const trelloCreator = new TrelloCreator();
-    // 1. check parameters are ok from a syntax point of view
-    try {
-      // XXX do proper checking
-      check(trelloBoard, Object);
-      check(data, Object);
-    } catch(e) {
-      throw new Meteor.Error('error-json-schema');
-    }
-    // 2. check parameters are ok from a business point of view (exist & authorized)
-    // XXX check we are allowed
-    // 3. create all elements
-    const dateOfImport = new Date();
-    trelloCreator.parseActions(trelloBoard.actions);
-    const boardId = trelloCreator.createBoardAndLabels(trelloBoard, dateOfImport);
-    trelloCreator.createLists(trelloBoard.lists, boardId, dateOfImport);
-    trelloCreator.createCards(trelloBoard.cards, boardId, dateOfImport);
-    // XXX add activities
-    // XXX set modifiedAt or lastActivity
-    // XXX add members
-    return boardId;
-  },
 });