Bladeren bron

Add first draft of data model and user interface. No actions.

Andrés Manelli 6 jaren geleden
bovenliggende
commit
0a53ee87b9

+ 0 - 6
client/components/boards/boardArchive.js

@@ -1,9 +1,3 @@
-Template.boardListHeaderBar.events({
-  'click .js-open-archived-board'() {
-    Modal.open('archivedBoards');
-  },
-});
-
 BlazeComponent.extendComponent({
 BlazeComponent.extendComponent({
   onCreated() {
   onCreated() {
     this.subscribe('archivedBoards');
     this.subscribe('archivedBoards');

+ 3 - 0
client/components/boards/boardsList.jade

@@ -36,3 +36,6 @@ template(name="boardListHeaderBar")
     a.board-header-btn.js-open-archived-board
     a.board-header-btn.js-open-archived-board
       i.fa.fa-archive
       i.fa.fa-archive
       span {{_ 'archives'}}
       span {{_ 'archives'}}
+    a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
+      i.fa.fa-clone
+      span {{_ 'templates'}}

+ 16 - 0
client/components/boards/boardsList.js

@@ -1,5 +1,20 @@
 const subManager = new SubsManager();
 const subManager = new SubsManager();
 
 
+Template.boardListHeaderBar.events({
+  'click .js-open-archived-board'() {
+    Modal.open('archivedBoards');
+  },
+});
+
+Template.boardListHeaderBar.helpers({
+  templatesBoardId() {
+      return Meteor.user().getTemplatesBoard().id;
+  },
+  templatesBoardSlug() {
+      return Meteor.user().getTemplatesBoard().slug;
+  },
+});
+
 BlazeComponent.extendComponent({
 BlazeComponent.extendComponent({
   onCreated() {
   onCreated() {
     Meteor.subscribe('setting');
     Meteor.subscribe('setting');
@@ -9,6 +24,7 @@ BlazeComponent.extendComponent({
     return Boards.find({
     return Boards.find({
       archived: false,
       archived: false,
       'members.userId': Meteor.userId(),
       'members.userId': Meteor.userId(),
+      type: 'board',
     }, {
     }, {
       sort: ['title'],
       sort: ['title'],
     });
     });

+ 3 - 0
client/components/cards/cardDetails.jade

@@ -247,6 +247,9 @@ template(name="cardDetailsActionsPopup")
       unless archived
       unless archived
         li: a.js-archive {{_ 'archive-card'}}
         li: a.js-archive {{_ 'archive-card'}}
       li: a.js-more {{_ 'cardMorePopup-title'}}
       li: a.js-more {{_ 'cardMorePopup-title'}}
+    hr
+    ul.pop-over-list
+      li: a.js-template-card {{_ 'cardTemplatePopup-title'}}
 
 
 template(name="moveCardPopup")
 template(name="moveCardPopup")
   +boardsAndLists
   +boardsAndLists

+ 3 - 0
client/components/cards/cardDetails.js

@@ -365,6 +365,9 @@ Template.cardDetailsActionsPopup.events({
       if (!err && ret) Popup.close();
       if (!err && ret) Popup.close();
     });
     });
   },
   },
+  'click .js-template-card' () {
+      console.log('REMOVE Creating template card');
+  },
 });
 });
 
 
 Template.editCardTitleForm.onRendered(function () {
 Template.editCardTitleForm.onRendered(function () {

+ 3 - 0
client/components/users/userHeader.jade

@@ -20,6 +20,9 @@ template(name="memberMenuPopup")
     if currentUser.isAdmin
     if currentUser.isAdmin
       li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}}
       li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}}
   hr
   hr
+  ul.pop-over-list
+    li: a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") {{_ 'templates'}}
+  hr
   ul.pop-over-list
   ul.pop-over-list
     li: a.js-logout {{_ 'log-out'}}
     li: a.js-logout {{_ 'log-out'}}
 
 

+ 9 - 0
client/components/users/userHeader.js

@@ -3,6 +3,15 @@ Template.headerUserBar.events({
   'click .js-change-avatar': Popup.open('changeAvatar'),
   'click .js-change-avatar': Popup.open('changeAvatar'),
 });
 });
 
 
+Template.memberMenuPopup.helpers({
+  templatesBoardId() {
+      return Meteor.user().getTemplatesBoard().id;
+  },
+  templatesBoardSlug() {
+      return Meteor.user().getTemplatesBoard().slug;
+  },
+});
+
 Template.memberMenuPopup.events({
 Template.memberMenuPopup.events({
   'click .js-edit-profile': Popup.open('editProfile'),
   'click .js-edit-profile': Popup.open('editProfile'),
   'click .js-change-settings': Popup.open('changeSettings'),
   'click .js-change-settings': Popup.open('changeSettings'),

+ 6 - 0
i18n/en.i18n.json

@@ -92,6 +92,7 @@
     "restore-board": "Restore Board",
     "restore-board": "Restore Board",
     "no-archived-boards": "No Boards in Archive.",
     "no-archived-boards": "No Boards in Archive.",
     "archives": "Archive",
     "archives": "Archive",
+    "templates": "Templates",
     "assign-member": "Assign member",
     "assign-member": "Assign member",
     "attached": "attached",
     "attached": "attached",
     "attachment": "Attachment",
     "attachment": "Attachment",
@@ -143,6 +144,7 @@
     "cardLabelsPopup-title": "Labels",
     "cardLabelsPopup-title": "Labels",
     "cardMembersPopup-title": "Members",
     "cardMembersPopup-title": "Members",
     "cardMorePopup-title": "More",
     "cardMorePopup-title": "More",
+    "cardTemplatePopup-title": "Create template",
     "cards": "Cards",
     "cards": "Cards",
     "cards-count": "Cards",
     "cards-count": "Cards",
     "casSignIn" : "Sign In with CAS",
     "casSignIn" : "Sign In with CAS",
@@ -453,6 +455,10 @@
     "welcome-swimlane": "Milestone 1",
     "welcome-swimlane": "Milestone 1",
     "welcome-list1": "Basics",
     "welcome-list1": "Basics",
     "welcome-list2": "Advanced",
     "welcome-list2": "Advanced",
+    "templates-board": "Templates Board",
+    "card-templates-swimlane": "Card Templates Swimlane",
+    "list-templates-swimlane": "List Templates Swimlane",
+    "board-templates-swimlane": "Board Templates Swimlane",
     "what-to-do": "What do you want to do?",
     "what-to-do": "What do you want to do?",
     "wipLimitErrorPopup-title": "Invalid WIP Limit",
     "wipLimitErrorPopup-title": "Invalid WIP Limit",
     "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.",
     "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.",

+ 10 - 0
models/boards.js

@@ -304,6 +304,13 @@ Boards.attachSchema(new SimpleSchema({
     defaultValue: false,
     defaultValue: false,
     optional: true,
     optional: true,
   },
   },
+  type: {
+    /**
+     * The type of board
+     */
+    type: String,
+    defaultValue: 'board',
+  },
 }));
 }));
 
 
 
 
@@ -559,6 +566,9 @@ Boards.helpers({
     });
     });
   },
   },
 
 
+  isTemplateBoard() {
+    return this.type === 'template-board';
+  },
 });
 });
 
 
 
 

+ 5 - 1
models/cards.js

@@ -246,7 +246,7 @@ Cards.attachSchema(new SimpleSchema({
      * type of the card
      * type of the card
      */
      */
     type: String,
     type: String,
-    defaultValue: '',
+    defaultValue: 'cardType-card',
   },
   },
   linkedId: {
   linkedId: {
     /**
     /**
@@ -930,6 +930,10 @@ Cards.helpers({
       return this.assignedBy;
       return this.assignedBy;
     }
     }
   },
   },
+
+  isTemplateCard() {
+    return this.type === 'template-card';
+  },
 });
 });
 
 
 Cards.mutations({
 Cards.mutations({

+ 11 - 0
models/lists.js

@@ -107,6 +107,13 @@ Lists.attachSchema(new SimpleSchema({
       'saddlebrown', 'paleturquoise', 'mistyrose', 'indigo',
       'saddlebrown', 'paleturquoise', 'mistyrose', 'indigo',
     ],
     ],
   },
   },
+  type: {
+    /**
+     * The type of list
+     */
+    type: String,
+    defaultValue: 'list',
+  },
 }));
 }));
 
 
 Lists.allow({
 Lists.allow({
@@ -169,6 +176,10 @@ Lists.helpers({
       return this.color;
       return this.color;
     return '';
     return '';
   },
   },
+
+  isTemplateList() {
+    return this.type === 'template-list';
+  },
 });
 });
 
 
 Lists.mutations({
 Lists.mutations({

+ 11 - 0
models/swimlanes.js

@@ -78,6 +78,13 @@ Swimlanes.attachSchema(new SimpleSchema({
       }
       }
     },
     },
   },
   },
+  type: {
+    /**
+     * The type of swimlane
+     */
+    type: String,
+    defaultValue: 'swimlane',
+  },
 }));
 }));
 
 
 Swimlanes.allow({
 Swimlanes.allow({
@@ -114,6 +121,10 @@ Swimlanes.helpers({
       return this.color;
       return this.color;
     return '';
     return '';
   },
   },
+
+  isTemplateSwimlane() {
+    return this.type === 'template-swimlane';
+  },
 });
 });
 
 
 Swimlanes.mutations({
 Swimlanes.mutations({

+ 48 - 0
models/users.js

@@ -159,6 +159,13 @@ Users.attachSchema(new SimpleSchema({
       'board-view-cal',
       'board-view-cal',
     ],
     ],
   },
   },
+  'profile.templatesBoardId': {
+    /**
+     * Reference to the templates board
+     */
+    type: String,
+    defaultValue: '',
+  },
   services: {
   services: {
     /**
     /**
      * services field of the user
      * services field of the user
@@ -328,6 +335,13 @@ Users.helpers({
     const profile = this.profile || {};
     const profile = this.profile || {};
     return profile.language || 'en';
     return profile.language || 'en';
   },
   },
+
+  getTemplatesBoard() {
+      return {
+          id: this.profile.templatesBoardId,
+          slug: Boards.findOne(this.profile.templatesBoardId).slug,
+      };
+  },
 });
 });
 
 
 Users.mutations({
 Users.mutations({
@@ -701,6 +715,40 @@ if (Meteor.isServer) {
             Lists.insert({title: TAPi18n.__(title), boardId, sort: titleIndex}, fakeUser);
             Lists.insert({title: TAPi18n.__(title), boardId, sort: titleIndex}, fakeUser);
           });
           });
         });
         });
+
+        Boards.insert({
+          title: TAPi18n.__('templates-board'),
+          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);
+
+            // Insert the list templates swimlane
+            Swimlanes.insert({
+                title: TAPi18n.__('list-templates-swimlane'),
+                boardId,
+                sort: 2,
+                type: 'template-container',
+            }, fakeUser);
+
+            // Insert the board templates swimlane
+            Swimlanes.insert({
+                title: TAPi18n.__('board-templates-swimlane'),
+                boardId,
+                sort: 3,
+                type: 'template-container',
+            }, fakeUser);
+        });
       });
       });
     });
     });
   }
   }

+ 1 - 0
server/publications/boards.js

@@ -32,6 +32,7 @@ Meteor.publish('boards', function() {
       color: 1,
       color: 1,
       members: 1,
       members: 1,
       permission: 1,
       permission: 1,
+      type: 1,
     },
     },
   });
   });
 });
 });