From 0a53ee87b94232608b5131f47dd77d2fa4bbc5ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Fri, 22 Feb 2019 22:59:19 +0100 Subject: [PATCH 01/19] Add first draft of data model and user interface. No actions. --- client/components/boards/boardArchive.js | 6 --- client/components/boards/boardsList.jade | 3 ++ client/components/boards/boardsList.js | 16 ++++++++ client/components/cards/cardDetails.jade | 3 ++ client/components/cards/cardDetails.js | 3 ++ client/components/users/userHeader.jade | 3 ++ client/components/users/userHeader.js | 9 +++++ i18n/en.i18n.json | 6 +++ models/boards.js | 10 +++++ models/cards.js | 6 ++- models/lists.js | 11 ++++++ models/swimlanes.js | 11 ++++++ models/users.js | 48 ++++++++++++++++++++++++ server/publications/boards.js | 1 + 14 files changed, 129 insertions(+), 7 deletions(-) diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js index 8f4d54345..c8bbb3419 100644 --- a/client/components/boards/boardArchive.js +++ b/client/components/boards/boardArchive.js @@ -1,9 +1,3 @@ -Template.boardListHeaderBar.events({ - 'click .js-open-archived-board'() { - Modal.open('archivedBoards'); - }, -}); - BlazeComponent.extendComponent({ onCreated() { this.subscribe('archivedBoards'); diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index 89852570d..e36b8fc6e 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -36,3 +36,6 @@ template(name="boardListHeaderBar") a.board-header-btn.js-open-archived-board i.fa.fa-archive span {{_ 'archives'}} + a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") + i.fa.fa-clone + span {{_ 'templates'}} diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 1ed881467..70dd11438 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,5 +1,20 @@ 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({ onCreated() { Meteor.subscribe('setting'); @@ -9,6 +24,7 @@ BlazeComponent.extendComponent({ return Boards.find({ archived: false, 'members.userId': Meteor.userId(), + type: 'board', }, { sort: ['title'], }); diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 25316d043..4d9b2e083 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -247,6 +247,9 @@ template(name="cardDetailsActionsPopup") unless archived li: a.js-archive {{_ 'archive-card'}} li: a.js-more {{_ 'cardMorePopup-title'}} + hr + ul.pop-over-list + li: a.js-template-card {{_ 'cardTemplatePopup-title'}} template(name="moveCardPopup") +boardsAndLists diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index a571e21a1..489f28ae6 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -365,6 +365,9 @@ Template.cardDetailsActionsPopup.events({ if (!err && ret) Popup.close(); }); }, + 'click .js-template-card' () { + console.log('REMOVE Creating template card'); + }, }); Template.editCardTitleForm.onRendered(function () { diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index b6e10d8a5..a47049332 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -20,6 +20,9 @@ template(name="memberMenuPopup") if currentUser.isAdmin li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}} hr + ul.pop-over-list + li: a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") {{_ 'templates'}} + hr ul.pop-over-list li: a.js-logout {{_ 'log-out'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 63cbb14f4..0978ec751 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -3,6 +3,15 @@ Template.headerUserBar.events({ '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({ 'click .js-edit-profile': Popup.open('editProfile'), 'click .js-change-settings': Popup.open('changeSettings'), diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index d4e817ea0..4c3f59437 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -92,6 +92,7 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +144,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn" : "Sign In with CAS", @@ -453,6 +455,10 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "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?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/models/boards.js b/models/boards.js index 71831a630..a2f4c0a84 100644 --- a/models/boards.js +++ b/models/boards.js @@ -304,6 +304,13 @@ Boards.attachSchema(new SimpleSchema({ defaultValue: false, optional: true, }, + type: { + /** + * The type of board + */ + type: String, + defaultValue: 'board', + }, })); @@ -559,6 +566,9 @@ Boards.helpers({ }); }, + isTemplateBoard() { + return this.type === 'template-board'; + }, }); diff --git a/models/cards.js b/models/cards.js index ff19a9a0e..e9fc453ed 100644 --- a/models/cards.js +++ b/models/cards.js @@ -246,7 +246,7 @@ Cards.attachSchema(new SimpleSchema({ * type of the card */ type: String, - defaultValue: '', + defaultValue: 'cardType-card', }, linkedId: { /** @@ -930,6 +930,10 @@ Cards.helpers({ return this.assignedBy; } }, + + isTemplateCard() { + return this.type === 'template-card'; + }, }); Cards.mutations({ diff --git a/models/lists.js b/models/lists.js index 54e7d0373..e0040752b 100644 --- a/models/lists.js +++ b/models/lists.js @@ -107,6 +107,13 @@ Lists.attachSchema(new SimpleSchema({ 'saddlebrown', 'paleturquoise', 'mistyrose', 'indigo', ], }, + type: { + /** + * The type of list + */ + type: String, + defaultValue: 'list', + }, })); Lists.allow({ @@ -169,6 +176,10 @@ Lists.helpers({ return this.color; return ''; }, + + isTemplateList() { + return this.type === 'template-list'; + }, }); Lists.mutations({ diff --git a/models/swimlanes.js b/models/swimlanes.js index e2c3925c4..bdc9a6911 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -78,6 +78,13 @@ Swimlanes.attachSchema(new SimpleSchema({ } }, }, + type: { + /** + * The type of swimlane + */ + type: String, + defaultValue: 'swimlane', + }, })); Swimlanes.allow({ @@ -114,6 +121,10 @@ Swimlanes.helpers({ return this.color; return ''; }, + + isTemplateSwimlane() { + return this.type === 'template-swimlane'; + }, }); Swimlanes.mutations({ diff --git a/models/users.js b/models/users.js index 0fdf21a88..7bc9e5bfc 100644 --- a/models/users.js +++ b/models/users.js @@ -159,6 +159,13 @@ Users.attachSchema(new SimpleSchema({ 'board-view-cal', ], }, + 'profile.templatesBoardId': { + /** + * Reference to the templates board + */ + type: String, + defaultValue: '', + }, services: { /** * services field of the user @@ -328,6 +335,13 @@ Users.helpers({ const profile = this.profile || {}; return profile.language || 'en'; }, + + getTemplatesBoard() { + return { + id: this.profile.templatesBoardId, + slug: Boards.findOne(this.profile.templatesBoardId).slug, + }; + }, }); Users.mutations({ @@ -701,6 +715,40 @@ if (Meteor.isServer) { 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); + }); }); }); } diff --git a/server/publications/boards.js b/server/publications/boards.js index fb4c8c84c..71c53612d 100644 --- a/server/publications/boards.js +++ b/server/publications/boards.js @@ -32,6 +32,7 @@ Meteor.publish('boards', function() { color: 1, members: 1, permission: 1, + type: 1, }, }); }); From 64bf455b296a10369e8318183c2c6cd61a122869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Fri, 22 Feb 2019 23:48:23 +0100 Subject: [PATCH 02/19] Save template swimlanes in profile. Fix swimlane view for templates board. Avoid deleting template containers --- client/components/boards/boardBody.jade | 9 ++-- client/components/boards/boardHeader.jade | 12 +++-- client/components/boards/boardsList.js | 4 +- .../components/swimlanes/swimlaneHeader.jade | 7 +-- client/components/users/userHeader.js | 4 +- i18n/en.i18n.json | 6 +-- models/boards.js | 4 ++ models/swimlanes.js | 4 ++ models/users.js | 50 ++++++++++++++++--- 9 files changed, 74 insertions(+), 26 deletions(-) diff --git a/client/components/boards/boardBody.jade b/client/components/boards/boardBody.jade index 3a40921d0..e36058f65 100644 --- a/client/components/boards/boardBody.jade +++ b/client/components/boards/boardBody.jade @@ -20,12 +20,15 @@ template(name="boardBody") class="{{#if draggingActive.get}}is-dragging-active{{/if}}") if showOverlay.get .board-overlay - if isViewSwimlanes + if currentBoard.isTemplatesBoard each currentBoard.swimlanes +swimlane(this) - if isViewLists + else if isViewSwimlanes + each currentBoard.swimlanes + +swimlane(this) + else if isViewLists +listsGroup - if isViewCalendar + else if isViewCalendar +calendarView template(name="calendarView") diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 75b2f02b0..4c9d6e436 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -96,10 +96,11 @@ template(name="boardHeaderBar") i.fa.fa-search span {{_ 'search'}} - a.board-header-btn.js-toggle-board-view( - title="{{_ 'board-view'}}") - i.fa.fa-th-large - span {{_ currentUser.profile.boardView}} + unless currentBoard.isTemplatesBoard + a.board-header-btn.js-toggle-board-view( + title="{{_ 'board-view'}}") + i.fa.fa-th-large + span {{_ currentUser.profile.boardView}} if canModifyBoard a.board-header-btn.js-multiselection-activate( @@ -132,7 +133,8 @@ template(name="boardMenuPopup") hr ul.pop-over-list li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} - li: a.js-archive-board {{_ 'archive-board'}} + unless currentBoard.isTemplatesBoard + li: a.js-archive-board {{_ 'archive-board'}} li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} hr ul.pop-over-list diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 70dd11438..3fd2d8899 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -8,10 +8,10 @@ Template.boardListHeaderBar.events({ Template.boardListHeaderBar.helpers({ templatesBoardId() { - return Meteor.user().getTemplatesBoard().id; + return Meteor.user().getTemplatesBoardId(); }, templatesBoardSlug() { - return Meteor.user().getTemplatesBoard().slug; + return Meteor.user().getTemplatesBoardSlug(); }, }); diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 33eb5731f..ac4a03277 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -22,9 +22,10 @@ template(name="swimlaneActionPopup") unless currentUser.isCommentOnly ul.pop-over-list li: a.js-set-swimlane-color {{_ 'select-color'}} - hr - ul.pop-over-list - li: a.js-close-swimlane {{_ 'archive-swimlane'}} + unless this.isTemplateContainer + hr + ul.pop-over-list + li: a.js-close-swimlane {{_ 'archive-swimlane'}} template(name="swimlaneAddPopup") unless currentUser.isCommentOnly diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 0978ec751..29b295348 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -5,10 +5,10 @@ Template.headerUserBar.events({ Template.memberMenuPopup.helpers({ templatesBoardId() { - return Meteor.user().getTemplatesBoard().id; + return Meteor.user().getTemplatesBoardId(); }, templatesBoardSlug() { - return Meteor.user().getTemplatesBoard().slug; + return Meteor.user().getTemplatesBoardSlug(); }, }); diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 4c3f59437..5fbbebf51 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -456,9 +456,9 @@ "welcome-list1": "Basics", "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", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/models/boards.js b/models/boards.js index a2f4c0a84..7328899ed 100644 --- a/models/boards.js +++ b/models/boards.js @@ -569,6 +569,10 @@ Boards.helpers({ isTemplateBoard() { return this.type === 'template-board'; }, + + isTemplatesBoard() { + return this.type === 'template-container'; + }, }); diff --git a/models/swimlanes.js b/models/swimlanes.js index bdc9a6911..185422ce7 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -125,6 +125,10 @@ Swimlanes.helpers({ isTemplateSwimlane() { return this.type === 'template-swimlane'; }, + + isTemplateContainer() { + return this.type === 'template-container'; + }, }); Swimlanes.mutations({ diff --git a/models/users.js b/models/users.js index 7bc9e5bfc..1493aa0d3 100644 --- a/models/users.js +++ b/models/users.js @@ -166,6 +166,27 @@ Users.attachSchema(new SimpleSchema({ type: String, defaultValue: '', }, + 'profile.cardTemplatesSwimlaneId': { + /** + * Reference to the card templates swimlane Id + */ + type: String, + defaultValue: '', + }, + 'profile.listTemplatesSwimlaneId': { + /** + * Reference to the list templates swimlane Id + */ + type: String, + defaultValue: '', + }, + 'profile.boardTemplatesSwimlaneId': { + /** + * Reference to the board templates swimlane Id + */ + type: String, + defaultValue: '', + }, services: { /** * services field of the user @@ -336,11 +357,12 @@ Users.helpers({ return profile.language || 'en'; }, - getTemplatesBoard() { - return { - id: this.profile.templatesBoardId, - slug: Boards.findOne(this.profile.templatesBoardId).slug, - }; + getTemplatesBoardId() { + return this.profile.templatesBoardId; + }, + + getTemplatesBoardSlug() { + return Boards.findOne(this.profile.templatesBoardId).slug; }, }); @@ -731,7 +753,11 @@ if (Meteor.isServer) { boardId, sort: 1, type: 'template-container', - }, fakeUser); + }, fakeUser, (err, swimlaneId) => { + + // Insert the reference to out card templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.cardTemplatesSwimlaneId': swimlaneId}}); + }); // Insert the list templates swimlane Swimlanes.insert({ @@ -739,7 +765,11 @@ if (Meteor.isServer) { boardId, sort: 2, type: 'template-container', - }, fakeUser); + }, fakeUser, (err, swimlaneId) => { + + // Insert the reference to out list templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.listTemplatesSwimlaneId': swimlaneId}}); + }); // Insert the board templates swimlane Swimlanes.insert({ @@ -747,7 +777,11 @@ if (Meteor.isServer) { boardId, sort: 3, type: 'template-container', - }, fakeUser); + }, fakeUser, (err, swimlaneId) => { + + // Insert the reference to out board templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.boardTemplatesSwimlaneId': swimlaneId}}); + }); }); }); }); From cdf070189e11205eecd11641226ae62964cc03e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 01:40:11 +0100 Subject: [PATCH 03/19] Remove links from templates board for the moment Insert the correct template type in templates board Allow independant lists in templates board Add some helpers --- client/components/lists/listBody.jade | 15 +++++++------ client/components/lists/listBody.js | 11 +++++++--- client/components/swimlanes/swimlaneHeader.js | 2 ++ client/components/swimlanes/swimlanes.jade | 7 ++++++ client/components/swimlanes/swimlanes.js | 7 ++++++ models/lists.js | 7 ++++++ models/swimlanes.js | 22 +++++++++++++++++++ 7 files changed, 61 insertions(+), 10 deletions(-) diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index f030833ba..10d39d15a 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -45,13 +45,14 @@ template(name="addCardForm") .add-controls.clearfix button.primary.confirm(type="submit") {{_ 'add'}} unless isSandstorm - span.quiet - | {{_ 'or'}} - a.js-link {{_ 'link'}} - span.quiet - |   - | / - a.js-search {{_ 'search'}} + unless currentBoard.isTemplatesBoard + span.quiet + | {{_ 'or'}} + a.js-link {{_ 'link'}} + span.quiet + |   + | / + a.js-search {{_ 'search'}} template(name="autocompleteLabelLine") .minicard-label(class="card-label-{{colorName}}" title=labelName) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 0f5caac56..576bcd9f0 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -70,7 +70,11 @@ BlazeComponent.extendComponent({ const boardId = this.data().board(); let swimlaneId = ''; const boardView = Meteor.user().profile.boardView; - if (boardView === 'board-view-swimlanes') + let cardType = 'cardType-card'; + if (this.data().board().isTemplatesBoard()) { + swimlaneId = this.parentComponent().parentComponent().data()._id; // Always swimlanes view + cardType = (Swimlanes.findOne(swimlaneId).isCardTemplatesSwimlane())?'template-card':'cardType-card'; + } else if (boardView === 'board-view-swimlanes') swimlaneId = this.parentComponent().parentComponent().data()._id; else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal')) swimlaneId = boardId.getDefaultSwimline()._id; @@ -85,7 +89,7 @@ BlazeComponent.extendComponent({ boardId: boardId._id, sort: sortIndex, swimlaneId, - type: 'cardType-card', + type: cardType, }); // if the displayed card count is less than the total cards in the list, @@ -149,7 +153,8 @@ BlazeComponent.extendComponent({ idOrNull(swimlaneId) { const currentUser = Meteor.user(); - if (currentUser.profile.boardView === 'board-view-swimlanes') + if (currentUser.profile.boardView === 'board-view-swimlanes' + || this.data().board().isTemplatesBoard()) return swimlaneId; return undefined; }, diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index 1004cb254..b78bdc96e 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -47,12 +47,14 @@ BlazeComponent.extendComponent({ const titleInput = this.find('.swimlane-name-input'); const title = titleInput.value.trim(); const sortValue = calculateIndexData(this.currentSwimlane, nextSwimlane, 1); + const swimlaneType = (currentBoard.isTemplatesBoard())?'template-swimlane':'swimlane'; if (title) { Swimlanes.insert({ title, boardId: Session.get('currentBoard'), sort: sortValue.base, + type: swimlaneType, }); titleInput.value = ''; diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 34177a022..0e070a211 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -10,6 +10,13 @@ template(name="swimlane") +miniList(this) if currentUser.isBoardMember +addListForm + else if currentBoard.isTemplatesBoard + each lists + +list(this) + if currentCardIsInThisList _id ../_id + +cardDetails(currentCard) + if currentUser.isBoardMember + +addListForm else each currentBoard.lists +list(this) diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index ce327f54d..4dd84604d 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -153,6 +153,10 @@ BlazeComponent.extendComponent({ }).register('swimlane'); BlazeComponent.extendComponent({ + onCreated() { + this.currentSwimlane = this.currentData(); + }, + // Proxy open() { this.childComponents('inlinedForm')[0].open(); @@ -164,11 +168,14 @@ BlazeComponent.extendComponent({ evt.preventDefault(); const titleInput = this.find('.list-name-input'); const title = titleInput.value.trim(); + const listType = (this.currentSwimlane.isListTemplatesSwimlane())?'template-list':'list'; if (title) { Lists.insert({ title, boardId: Session.get('currentBoard'), sort: $('.list').length, + type: listType, + swimlaneId: this.currentSwimlane._id, }); titleInput.value = ''; diff --git a/models/lists.js b/models/lists.js index e0040752b..a0b882bcb 100644 --- a/models/lists.js +++ b/models/lists.js @@ -27,6 +27,13 @@ Lists.attachSchema(new SimpleSchema({ */ type: String, }, + swimlaneId: { + /** + * the swimalen associated to this list. Used for templates + */ + type: String, + defaultValue: '', + }, createdAt: { /** * creation date diff --git a/models/swimlanes.js b/models/swimlanes.js index 185422ce7..9d4e16de9 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -108,6 +108,13 @@ Swimlanes.helpers({ }), { sort: ['sort'] }); }, + lists() { + return Lists.find(Filter.mongoSelector({ + swimlaneId: this._id, + archived: false, + }), { sort: ['sort'] }); + }, + allCards() { return Cards.find({ swimlaneId: this._id }); }, @@ -129,6 +136,21 @@ Swimlanes.helpers({ isTemplateContainer() { return this.type === 'template-container'; }, + + isListTemplatesSwimlane() { + const user = Users.findOne(Meteor.userId()); + return user.profile.listTemplatesSwimlaneId === this._id; + }, + + isCardTemplatesSwimlane() { + const user = Users.findOne(Meteor.userId()); + return user.profile.cardTemplatesSwimlaneId === this._id; + }, + + isBoardTemplatesSwimlane() { + const user = Users.findOne(Meteor.userId()); + return user.profile.boardsTemplatesSwimlaneId === this._id; + }, }); Swimlanes.mutations({ From 1e72177991e3fe11a1837e3e294e4de5d728aa30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 12:14:37 +0100 Subject: [PATCH 04/19] Avoid links on a template-board Allow creation of template boards with a linked card Avoid changing the name of the template-container swimlanes --- client/components/lists/listBody.jade | 15 ++++---- client/components/lists/listBody.js | 38 ++++++++++++++----- .../components/swimlanes/swimlaneHeader.jade | 24 +++++++----- client/components/swimlanes/swimlanes.js | 2 +- i18n/en.i18n.json | 1 - models/swimlanes.js | 2 +- models/users.js | 2 +- 7 files changed, 54 insertions(+), 30 deletions(-) diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index 10d39d15a..bc1469a92 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -46,13 +46,14 @@ template(name="addCardForm") button.primary.confirm(type="submit") {{_ 'add'}} unless isSandstorm unless currentBoard.isTemplatesBoard - span.quiet - | {{_ 'or'}} - a.js-link {{_ 'link'}} - span.quiet - |   - | / - a.js-search {{_ 'search'}} + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-link {{_ 'link'}} + span.quiet + |   + | / + a.js-search {{_ 'search'}} template(name="autocompleteLabelLine") .minicard-label(class="card-label-{{colorName}}" title=labelName) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 576bcd9f0..eccef5525 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -67,29 +67,47 @@ BlazeComponent.extendComponent({ const labelIds = formComponent.labels.get(); const customFields = formComponent.customFields.get(); - const boardId = this.data().board(); + const board = this.data().board(); + let linkedId = ''; let swimlaneId = ''; const boardView = Meteor.user().profile.boardView; let cardType = 'cardType-card'; - if (this.data().board().isTemplatesBoard()) { - swimlaneId = this.parentComponent().parentComponent().data()._id; // Always swimlanes view - cardType = (Swimlanes.findOne(swimlaneId).isCardTemplatesSwimlane())?'template-card':'cardType-card'; - } else if (boardView === 'board-view-swimlanes') - swimlaneId = this.parentComponent().parentComponent().data()._id; - else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal')) - swimlaneId = boardId.getDefaultSwimline()._id; - if (title) { + if (board.isTemplatesBoard()) { + swimlaneId = this.parentComponent().parentComponent().data()._id; // Always swimlanes view + const swimlane = Swimlanes.findOne(swimlaneId); + // If this is the card templates swimlane, insert a card template + if (swimlane.isCardTemplatesSwimlane()) + cardType = 'template-card'; + // If this is the board templates swimlane, insert a board template and a linked card + else if (swimlane.isBoardTemplatesSwimlane()) { + linkedId = Boards.insert({ + title, + permission: 'private', + type: 'template-board', + }); + Swimlanes.insert({ + title: TAPi18n.__('default'), + boardId: linkedId, + }); + cardType = 'cardType-linkedBoard'; + } + } else if (boardView === 'board-view-swimlanes') + swimlaneId = this.parentComponent().parentComponent().data()._id; + else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal')) + swimlaneId = board.getDefaultSwimline()._id; + const _id = Cards.insert({ title, members, labelIds, customFields, listId: this.data()._id, - boardId: boardId._id, + boardId: board._id, sort: sortIndex, swimlaneId, type: cardType, + linkedId, }); // if the displayed card count is less than the total cards in the list, diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index ac4a03277..810dd57f0 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -1,15 +1,21 @@ template(name="swimlaneHeader") .swimlane-header-wrap.js-swimlane-header(class='{{#if colorClass}}swimlane-{{colorClass}}{{/if}}') - +inlinedForm - +editSwimlaneTitleForm + if this.isTemplateContainer + +swimlaneFixedHeader(this) else - .swimlane-header( - class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}") - = title - .swimlane-header-menu - unless currentUser.isCommentOnly - a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon - a.fa.fa-navicon.js-open-swimlane-menu + +inlinedForm + +editSwimlaneTitleForm + else + +swimlaneFixedHeader(this) + +template(name="swimlaneFixedHeader") + .swimlane-header( + class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}") + = title + .swimlane-header-menu + unless currentUser.isCommentOnly + a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon + a.fa.fa-navicon.js-open-swimlane-menu template(name="editSwimlaneTitleForm") .list-composer diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 4dd84604d..63266e5fb 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -168,8 +168,8 @@ BlazeComponent.extendComponent({ evt.preventDefault(); const titleInput = this.find('.list-name-input'); const title = titleInput.value.trim(); - const listType = (this.currentSwimlane.isListTemplatesSwimlane())?'template-list':'list'; if (title) { + const listType = (this.currentSwimlane.isListTemplatesSwimlane())?'template-list':'list'; Lists.insert({ title, boardId: Session.get('currentBoard'), diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 5fbbebf51..3c6effd68 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -455,7 +455,6 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", - "templates-board": "Templates Board", "card-templates-swimlane": "Card Templates", "list-templates-swimlane": "List Templates", "board-templates-swimlane": "Board Templates", diff --git a/models/swimlanes.js b/models/swimlanes.js index 9d4e16de9..be3f617cc 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -149,7 +149,7 @@ Swimlanes.helpers({ isBoardTemplatesSwimlane() { const user = Users.findOne(Meteor.userId()); - return user.profile.boardsTemplatesSwimlaneId === this._id; + return user.profile.boardTemplatesSwimlaneId === this._id; }, }); diff --git a/models/users.js b/models/users.js index 1493aa0d3..87f2b8602 100644 --- a/models/users.js +++ b/models/users.js @@ -739,7 +739,7 @@ if (Meteor.isServer) { }); Boards.insert({ - title: TAPi18n.__('templates-board'), + title: TAPi18n.__('templates'), permission: 'private', type: 'template-container' }, fakeUser, (err, boardId) => { From 7a6afb8aea2c3398ec0fe34d664398bd94cac90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 15:32:44 +0100 Subject: [PATCH 05/19] Add template search in Add Card menu Archive all cards in list when list is archived Remove default board in link popup Only list non-template boards in card link and search --- client/components/lists/listBody.jade | 27 +++++++++-------- client/components/lists/listBody.js | 43 +++++++++++++++------------ i18n/en.i18n.json | 1 + models/boards.js | 4 +++ models/lists.js | 13 ++++++++ 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index bc1469a92..4d7ec1589 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -54,6 +54,10 @@ template(name="addCardForm") |   | / a.js-search {{_ 'search'}} + span.quiet + |   + | / + a.js-search-template {{_ 'template'}} template(name="autocompleteLabelLine") .minicard-label(class="card-label-{{colorName}}" title=labelName) @@ -63,11 +67,9 @@ template(name="linkCardPopup") label {{_ 'boards'}}: .link-board-wrapper select.js-select-boards + option(value="") each boards - if $eq _id currentBoard._id - option(value="{{_id}}" selected) {{_ 'current'}} - else - option(value="{{_id}}") {{title}} + option(value="{{_id}}") {{title}} input.primary.confirm.js-link-board(type="button" value="{{_ 'link'}}") label {{_ 'swimlanes'}}: @@ -90,14 +92,15 @@ template(name="linkCardPopup") input.primary.confirm.js-done(type="button" value="{{_ 'link'}}") template(name="searchCardPopup") - label {{_ 'boards'}}: - .link-board-wrapper - select.js-select-boards - each boards - if $eq _id currentBoard._id - option(value="{{_id}}" selected) {{_ 'current'}} - else - option(value="{{_id}}") {{title}} + unless isTemplateSearch + label {{_ 'boards'}}: + .link-board-wrapper + select.js-select-boards + each boards + if $eq _id currentBoard._id + option(value="{{_id}}" selected) {{_ 'current'}} + else + option(value="{{_id}}") {{title}} form.js-search-term-form input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus) .list-body.js-perfect-scrollbar.search-card-results diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index eccef5525..66d056c46 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -316,6 +316,7 @@ BlazeComponent.extendComponent({ keydown: this.pressKey, 'click .js-link': Popup.open('linkCard'), 'click .js-search': Popup.open('searchCard'), + 'click .js-search-template': Popup.open('searchCard'), }]; }, @@ -390,17 +391,7 @@ BlazeComponent.extendComponent({ BlazeComponent.extendComponent({ onCreated() { - // Prefetch first non-current board id - const boardId = Boards.findOne({ - archived: false, - 'members.userId': Meteor.userId(), - _id: {$ne: Session.get('currentBoard')}, - }, { - sort: ['title'], - })._id; - // Subscribe to this board - subManager.subscribe('board', boardId); - this.selectedBoardId = new ReactiveVar(boardId); + this.selectedBoardId = new ReactiveVar(''); this.selectedSwimlaneId = new ReactiveVar(''); this.selectedListId = new ReactiveVar(''); @@ -426,6 +417,7 @@ BlazeComponent.extendComponent({ archived: false, 'members.userId': Meteor.userId(), _id: {$ne: Session.get('currentBoard')}, + type: 'board', }, { sort: ['title'], }); @@ -433,7 +425,7 @@ BlazeComponent.extendComponent({ }, swimlanes() { - if (!this.selectedBoardId) { + if (!this.selectedBoardId.get()) { return []; } const swimlanes = Swimlanes.find({boardId: this.selectedBoardId.get()}); @@ -443,7 +435,7 @@ BlazeComponent.extendComponent({ }, lists() { - if (!this.selectedBoardId) { + if (!this.selectedBoardId.get()) { return []; } const lists = Lists.find({boardId: this.selectedBoardId.get()}); @@ -531,12 +523,18 @@ BlazeComponent.extendComponent({ }, onCreated() { - // Prefetch first non-current board id - let board = Boards.findOne({ - archived: false, - 'members.userId': Meteor.userId(), - _id: {$ne: Session.get('currentBoard')}, - }); + const isTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-search-template'); + let board = {}; + if (isTemplateSearch) { + board = Boards.findOne(Meteor.user().profile.templatesBoardId); + } else { + // Prefetch first non-current board id + board = Boards.findOne({ + archived: false, + 'members.userId': Meteor.userId(), + _id: {$ne: Session.get('currentBoard')}, + }); + } if (!board) { Popup.close(); return; @@ -568,6 +566,7 @@ BlazeComponent.extendComponent({ archived: false, 'members.userId': Meteor.userId(), _id: {$ne: Session.get('currentBoard')}, + type: 'board', }, { sort: ['title'], }); @@ -610,3 +609,9 @@ BlazeComponent.extendComponent({ }]; }, }).register('searchCardPopup'); + +Template.searchCardPopup.helpers({ + isTemplateSearch() { + return $(Popup._getTopStack().openerElement).hasClass('js-search-template'); + }, +}); diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 3c6effd68..94666c16c 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -92,6 +92,7 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", "templates": "Templates", "assign-member": "Assign member", "attached": "attached", diff --git a/models/boards.js b/models/boards.js index 7328899ed..c17c73517 100644 --- a/models/boards.js +++ b/models/boards.js @@ -470,6 +470,10 @@ Boards.helpers({ if (excludeLinked) { query.linkedId = null; } + if (this.isTemplatesBoard()) { + query.type = 'template-card'; + query.archived = false; + } const projection = { limit: 10, sort: { createdAt: -1 } }; if (term) { diff --git a/models/lists.js b/models/lists.js index a0b882bcb..236432cc8 100644 --- a/models/lists.js +++ b/models/lists.js @@ -195,10 +195,23 @@ Lists.mutations({ }, archive() { + Cards.find({ + listId: this._id, + archived: false, + }).forEach((card) => { + return card.archive(); + }); return { $set: { archived: true } }; }, restore() { + cardsToRestore = Cards.find({ + listId: this._id, + archived: true, + }); + cardsToRestore.forEach((card) => { + card.restore(); + }); return { $set: { archived: false } }; }, From 0fec7115451ba3b49442965c8160df4911157601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 16:36:29 +0100 Subject: [PATCH 06/19] Prepare to create card from template --- client/components/cards/cardDetails.js | 58 +++----------------------- client/components/lists/listBody.jade | 6 +-- client/components/lists/listBody.js | 7 ++-- models/boards.js | 2 + models/cardComments.js | 6 +++ models/cards.js | 25 +++++++++++ models/checklists.js | 13 ++++++ 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 489f28ae6..1281356da 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -459,26 +459,9 @@ BlazeComponent.extendComponent({ }, }).register('boardsAndLists'); - -function cloneCheckList(_id, checklist) { - 'use strict'; - const checklistId = checklist._id; - checklist.cardId = _id; - checklist._id = null; - const newChecklistId = Checklists.insert(checklist); - ChecklistItems.find({checklistId}).forEach(function(item) { - item._id = null; - item.checklistId = newChecklistId; - item.cardId = _id; - ChecklistItems.insert(item); - }); -} - Template.copyCardPopup.events({ 'click .js-done'() { const card = Cards.findOne(Session.get('currentCard')); - const oldId = card._id; - card._id = null; const lSelect = $('.js-select-lists')[0]; card.listId = lSelect.options[lSelect.selectedIndex].value; const slSelect = $('.js-select-swimlanes')[0]; @@ -493,38 +476,13 @@ Template.copyCardPopup.events({ if (title) { card.title = title; card.coverId = ''; - const _id = Cards.insert(card); + const _id = card.copy(); // In case the filter is active we need to add the newly inserted card in // the list of exceptions -- cards that are not filtered. Otherwise the // card will disappear instantly. // See https://github.com/wekan/wekan/issues/80 Filter.addException(_id); - // copy checklists - let cursor = Checklists.find({cardId: oldId}); - cursor.forEach(function() { - cloneCheckList(_id, arguments[0]); - }); - - // copy subtasks - cursor = Cards.find({parentId: oldId}); - cursor.forEach(function() { - 'use strict'; - const subtask = arguments[0]; - subtask.parentId = _id; - subtask._id = null; - /* const newSubtaskId = */ Cards.insert(subtask); - }); - - // copy card comments - cursor = CardComments.find({cardId: oldId}); - cursor.forEach(function () { - 'use strict'; - const comment = arguments[0]; - comment.cardId = _id; - comment._id = null; - CardComments.insert(comment); - }); Popup.close(); } }, @@ -561,9 +519,8 @@ Template.copyChecklistToManyCardsPopup.events({ Filter.addException(_id); // copy checklists - let cursor = Checklists.find({cardId: oldId}); - cursor.forEach(function() { - cloneCheckList(_id, arguments[0]); + Checklists.find({cardId: oldId}).forEach((ch) => { + ch.copy(_id); }); // copy subtasks @@ -577,13 +534,8 @@ Template.copyChecklistToManyCardsPopup.events({ }); // copy card comments - cursor = CardComments.find({cardId: oldId}); - cursor.forEach(function () { - 'use strict'; - const comment = arguments[0]; - comment.cardId = _id; - comment._id = null; - CardComments.insert(comment); + CardComments.find({cardId: oldId}).forEach((cmt) => { + cmt.copy(_id); }); } Popup.close(); diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index 4d7ec1589..80ce70c08 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -96,11 +96,9 @@ template(name="searchCardPopup") label {{_ 'boards'}}: .link-board-wrapper select.js-select-boards + option(value="") each boards - if $eq _id currentBoard._id - option(value="{{_id}}" selected) {{_ 'current'}} - else - option(value="{{_id}}") {{title}} + option(value="{{_id}}") {{title}} form.js-search-term-form input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus) .list-body.js-perfect-scrollbar.search-card-results diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 66d056c46..e6849eb22 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -456,6 +456,7 @@ BlazeComponent.extendComponent({ archived: false, linkedId: {$nin: ownCardsIds}, _id: {$nin: ownCardsIds}, + type: {$nin: ['template-card']}, }); }, @@ -523,16 +524,16 @@ BlazeComponent.extendComponent({ }, onCreated() { - const isTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-search-template'); + this.isTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-search-template'); let board = {}; - if (isTemplateSearch) { + if (this.isTemplateSearch) { board = Boards.findOne(Meteor.user().profile.templatesBoardId); } else { // Prefetch first non-current board id board = Boards.findOne({ archived: false, 'members.userId': Meteor.userId(), - _id: {$ne: Session.get('currentBoard')}, + _id: {$nin: [Session.get('currentBoard'), Meteor.user().profile.templatesBoardId]}, }); } if (!board) { diff --git a/models/boards.js b/models/boards.js index c17c73517..25cf5e370 100644 --- a/models/boards.js +++ b/models/boards.js @@ -473,6 +473,8 @@ Boards.helpers({ if (this.isTemplatesBoard()) { query.type = 'template-card'; query.archived = false; + } else { + query.type = {$nin: ['template-card']}; } const projection = { limit: 10, sort: { createdAt: -1 } }; diff --git a/models/cardComments.js b/models/cardComments.js index 974c5ec93..f29366a56 100644 --- a/models/cardComments.js +++ b/models/cardComments.js @@ -67,6 +67,12 @@ CardComments.allow({ }); CardComments.helpers({ + copy(newCardId) { + this.cardId = newCardId; + this._id = null; + CardComments.insert(this); + }, + user() { return Users.findOne(this.userId); }, diff --git a/models/cards.js b/models/cards.js index e9fc453ed..c7b4a3667 100644 --- a/models/cards.js +++ b/models/cards.js @@ -272,6 +272,31 @@ Cards.allow({ }); Cards.helpers({ + copy() { + const oldId = this._id; + this._id = null; + const _id = Cards.insert(this); + + // copy checklists + Checklists.find({cardId: oldId}).forEach((ch) => { + ch.copy(_id); + }); + + // copy subtasks + Cards.find({parentId: oldId}).forEach((subtask) => { + subtask.parentId = _id; + subtask._id = null; + Cards.insert(subtask); + }); + + // copy card comments + CardComments.find({cardId: oldId}).forEach((cmt) => { + cmt.copy(_id); + }); + + return _id; + }, + list() { return Lists.findOne(this.listId); }, diff --git a/models/checklists.js b/models/checklists.js index a372fafa4..99e9f25e3 100644 --- a/models/checklists.js +++ b/models/checklists.js @@ -48,6 +48,19 @@ Checklists.attachSchema(new SimpleSchema({ })); Checklists.helpers({ + copy(newCardId) { + const oldChecklistId = this._id; + this._id = null; + this.cardId = newCardId; + const newChecklistId = Checklists.insert(this); + ChecklistItems.find({checklistId: oldChecklistId}).forEach((item) => { + item._id = null; + item.checklistId = newChecklistId; + item.cardId = newCardId; + ChecklistItems.insert(item); + }); + }, + itemCount() { return ChecklistItems.find({ checklistId: this._id }).count(); }, From 044126188d28a24b0df5d67cf69d081ce7790886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 19:00:52 +0100 Subject: [PATCH 07/19] Allow card creation from template --- client/components/lists/listBody.js | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index e6849eb22..e84874bb4 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -593,26 +593,27 @@ BlazeComponent.extendComponent({ this.term.set(evt.target.searchTerm.value); }, 'click .js-minicard'(evt) { - // LINK CARD - const card = Blaze.getData(evt.currentTarget); - const _id = Cards.insert({ - title: card.title, //dummy - listId: this.listId, - swimlaneId: this.swimlaneId, - boardId: this.boardId, - sort: Lists.findOne(this.listId).cards().count(), - type: 'cardType-linkedCard', - linkedId: card.linkedId || card._id, - }); + let card = Blaze.getData(evt.currentTarget); + let _id = ''; + // Common + card.listId = this.listId; + card.swimlaneId = this.swimlaneId; + card.boardId = this.boardId; + card.sort = Lists.findOne(this.listId).cards().count(); + // From template + if (this.isTemplateSearch) { + card.type = 'cardType-card'; + card.linkedId = ''; + _id = card.copy(); + } else { // Linked + card._id = null; + card.type = 'cardType-linkedCard'; + card.linkedId = card.linkedId || card._id; + _id = Cards.insert(card); + } Filter.addException(_id); Popup.close(); }, }]; }, }).register('searchCardPopup'); - -Template.searchCardPopup.helpers({ - isTemplateSearch() { - return $(Popup._getTopStack().openerElement).hasClass('js-search-template'); - }, -}); From f888cfd565b197903c24a07221f6a6a44e1b6223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 20:41:36 +0100 Subject: [PATCH 08/19] Allow list creation from template --- client/components/lists/listBody.jade | 13 +++- client/components/lists/listBody.js | 62 +++++++++++++------ client/components/lists/minilist.jade | 8 +++ client/components/swimlanes/miniswimlane.jade | 8 +++ client/components/swimlanes/swimlanes.jade | 6 +- client/components/swimlanes/swimlanes.js | 8 ++- models/boards.js | 24 +++++++ models/lists.js | 18 ++++++ 8 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 client/components/lists/minilist.jade create mode 100644 client/components/swimlanes/miniswimlane.jade diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index 80ce70c08..46f90f998 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -57,7 +57,7 @@ template(name="addCardForm") span.quiet |   | / - a.js-search-template {{_ 'template'}} + a.js-card-template {{_ 'template'}} template(name="autocompleteLabelLine") .minicard-label(class="card-label-{{colorName}}" title=labelName) @@ -104,5 +104,12 @@ template(name="searchCardPopup") .list-body.js-perfect-scrollbar.search-card-results .minicards.clearfix.js-minicards each results - a.minicard-wrapper.js-minicard - +minicard(this) + if isListTemplateSearch + a.minicard-wrapper.js-minicard + +minilist(this) + if isSwimlaneTemplateSearch + a.minicard-wrapper.js-minicard + +miniswimlane(this) + unless isTemplateSearch + a.minicard-wrapper.js-minicard + +minicard(this) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index e84874bb4..ad34efef9 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -524,7 +524,10 @@ BlazeComponent.extendComponent({ }, onCreated() { - this.isTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-search-template'); + this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template'); + this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template'); + this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-swimlane-template'); + this.isTemplateSearch = this.isCardTemplateSearch || this.isListTemplateSearch || this.isSwimlaneTemplateSearch; let board = {}; if (this.isTemplateSearch) { board = Boards.findOne(Meteor.user().profile.templatesBoardId); @@ -579,7 +582,15 @@ BlazeComponent.extendComponent({ return []; } const board = Boards.findOne(this.selectedBoardId.get()); - return board.searchCards(this.term.get(), false); + if (!this.isTemplateSearch || this.isCardTemplateSearch) { + return board.searchCards(this.term.get(), false); + } else if (this.isListTemplateSearch) { + return board.searchLists(this.term.get()); + } else if (this.isSwimlaneTemplateSearch) { + return board.searchSwimlanes(this.term.get()); + } else { + return []; + } }, events() { @@ -593,25 +604,38 @@ BlazeComponent.extendComponent({ this.term.set(evt.target.searchTerm.value); }, 'click .js-minicard'(evt) { - let card = Blaze.getData(evt.currentTarget); + // 0. Common + let element = Blaze.getData(evt.currentTarget); + console.log(element); + element.boardId = this.boardId; let _id = ''; - // Common - card.listId = this.listId; - card.swimlaneId = this.swimlaneId; - card.boardId = this.boardId; - card.sort = Lists.findOne(this.listId).cards().count(); - // From template - if (this.isTemplateSearch) { - card.type = 'cardType-card'; - card.linkedId = ''; - _id = card.copy(); - } else { // Linked - card._id = null; - card.type = 'cardType-linkedCard'; - card.linkedId = card.linkedId || card._id; - _id = Cards.insert(card); + if (!this.isTemplateSearch || this.isCardTemplateSearch) { + // Card insertion + // 1. Common + element.listId = this.listId; + element.swimlaneId = this.swimlaneId; + element.sort = Lists.findOne(this.listId).cards().count(); + // 1.A From template + if (this.isTemplateSearch) { + element.type = 'cardType-card'; + element.linkedId = ''; + _id = element.copy(); + // 1.B Linked card + } else { + element._id = null; + element.type = 'cardType-linkedCard'; + element.linkedId = element.linkedId || element._id; + _id = Cards.insert(element); + } + Filter.addException(_id); + // List insertion + } else if (this.isListTemplateSearch) { + element.swimlaneId = ''; + element.sort = Swimlanes.findOne(this.swimlaneId).lists().count(); + element.type = 'list'; + element.swimlaneId = this.swimlaneId; + _id = element.copy(); } - Filter.addException(_id); Popup.close(); }, }]; diff --git a/client/components/lists/minilist.jade b/client/components/lists/minilist.jade new file mode 100644 index 000000000..e34214c40 --- /dev/null +++ b/client/components/lists/minilist.jade @@ -0,0 +1,8 @@ +template(name="minilist") + .minicard( + class="minicard-{{colorClass}}") + .minicard-title + .handle + .fa.fa-arrows + +viewer + = title diff --git a/client/components/swimlanes/miniswimlane.jade b/client/components/swimlanes/miniswimlane.jade new file mode 100644 index 000000000..d4be85994 --- /dev/null +++ b/client/components/swimlanes/miniswimlane.jade @@ -0,0 +1,8 @@ +template(name="miniswimlane") + .minicard( + class="minicard-{{colorClass}}") + .minicard-title + .handle + .fa.fa-arrows + +viewer + = title diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 0e070a211..ba174cb55 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -51,7 +51,11 @@ template(name="addListForm") autocomplete="off" autofocus) .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-list-template {{_ 'template'}} else a.open-list-composer.js-open-inlined-form i.fa.fa-plus diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 63266e5fb..bdaed81d2 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -154,6 +154,8 @@ BlazeComponent.extendComponent({ BlazeComponent.extendComponent({ onCreated() { + currentBoard = Boards.findOne(Session.get('currentBoard')); + this.isListTemplatesSwimlane = currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane(); this.currentSwimlane = this.currentData(); }, @@ -169,19 +171,19 @@ BlazeComponent.extendComponent({ const titleInput = this.find('.list-name-input'); const title = titleInput.value.trim(); if (title) { - const listType = (this.currentSwimlane.isListTemplatesSwimlane())?'template-list':'list'; Lists.insert({ title, boardId: Session.get('currentBoard'), sort: $('.list').length, - type: listType, - swimlaneId: this.currentSwimlane._id, + type: (this.isListTemplatesSwimlane)?'template-list':'list', + swimlaneId: (this.isListTemplatesSwimlane)?this.currentSwimlane._id:'', }); titleInput.value = ''; titleInput.focus(); } }, + 'click .js-list-template': Popup.open('searchCard'), }]; }, }).register('addListForm'); diff --git a/models/boards.js b/models/boards.js index 25cf5e370..530a6f712 100644 --- a/models/boards.js +++ b/models/boards.js @@ -463,6 +463,30 @@ Boards.helpers({ return _id; }, + searchLists(term) { + check(term, Match.OneOf(String, null, undefined)); + + const query = { boardId: this._id }; + if (this.isTemplatesBoard()) { + query.type = 'template-list'; + query.archived = false; + } else { + query.type = {$nin: ['template-list']}; + } + const projection = { limit: 10, sort: { createdAt: -1 } }; + + if (term) { + const regex = new RegExp(term, 'i'); + + query.$or = [ + { title: regex }, + { description: regex }, + ]; + } + + return Lists.find(query, projection); + }, + searchCards(term, excludeLinked) { check(term, Match.OneOf(String, null, undefined)); diff --git a/models/lists.js b/models/lists.js index 236432cc8..e2ded36e8 100644 --- a/models/lists.js +++ b/models/lists.js @@ -137,6 +137,24 @@ Lists.allow({ }); Lists.helpers({ + copy() { + const oldId = this._id; + this._id = null; + const _id = Lists.insert(this); + + // Copy all cards in list + Cards.find({ + listId: oldId, + archived: false, + }).forEach((card) => { + card.type = 'cardType-card'; + card.listId = _id; + card.boardId = this.boardId; + card.swimlaneId = this.swimlaneId; + card.copy(); + }); + }, + cards(swimlaneId) { const selector = { listId: this._id, From 60be4df76e02afdf4dd62f8e03505d55c0ed119e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 23 Feb 2019 23:07:54 +0100 Subject: [PATCH 09/19] Allow swimlane creation from template Mix lists with same name to avoid duplicates --- client/components/cards/cardDetails.jade | 3 -- client/components/cards/cardDetails.js | 3 -- client/components/lists/listBody.jade | 5 ++- client/components/lists/listBody.js | 19 +++++----- .../components/swimlanes/swimlaneHeader.jade | 5 +++ client/components/swimlanes/swimlaneHeader.js | 1 + client/components/swimlanes/swimlanes.js | 8 ++--- models/boards.js | 24 +++++++++++++ models/lists.js | 36 +++++++++++-------- models/swimlanes.js | 31 ++++++++++++++++ 10 files changed, 100 insertions(+), 35 deletions(-) diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 4d9b2e083..25316d043 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -247,9 +247,6 @@ template(name="cardDetailsActionsPopup") unless archived li: a.js-archive {{_ 'archive-card'}} li: a.js-more {{_ 'cardMorePopup-title'}} - hr - ul.pop-over-list - li: a.js-template-card {{_ 'cardTemplatePopup-title'}} template(name="moveCardPopup") +boardsAndLists diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 1281356da..73a7a67d5 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -365,9 +365,6 @@ Template.cardDetailsActionsPopup.events({ if (!err && ret) Popup.close(); }); }, - 'click .js-template-card' () { - console.log('REMOVE Creating template card'); - }, }); Template.editCardTitleForm.onRendered(function () { diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index 46f90f998..fcc28777a 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -91,7 +91,7 @@ template(name="linkCardPopup") unless isSandstorm input.primary.confirm.js-done(type="button" value="{{_ 'link'}}") -template(name="searchCardPopup") +template(name="searchElementPopup") unless isTemplateSearch label {{_ 'boards'}}: .link-board-wrapper @@ -110,6 +110,9 @@ template(name="searchCardPopup") if isSwimlaneTemplateSearch a.minicard-wrapper.js-minicard +miniswimlane(this) + if isCardTemplateSearch + a.minicard-wrapper.js-minicard + +minicard(this) unless isTemplateSearch a.minicard-wrapper.js-minicard +minicard(this) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index ad34efef9..f8634c0b7 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -315,8 +315,8 @@ BlazeComponent.extendComponent({ return [{ keydown: this.pressKey, 'click .js-link': Popup.open('linkCard'), - 'click .js-search': Popup.open('searchCard'), - 'click .js-search-template': Popup.open('searchCard'), + 'click .js-search': Popup.open('searchElement'), + 'click .js-card-template': Popup.open('searchElement'), }]; }, @@ -526,7 +526,7 @@ BlazeComponent.extendComponent({ onCreated() { this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template'); this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template'); - this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-swimlane-template'); + this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-open-add-swimlane-menu'); this.isTemplateSearch = this.isCardTemplateSearch || this.isListTemplateSearch || this.isSwimlaneTemplateSearch; let board = {}; if (this.isTemplateSearch) { @@ -551,14 +551,13 @@ BlazeComponent.extendComponent({ this.boardId = Session.get('currentBoard'); // In order to get current board info subManager.subscribe('board', this.boardId); - board = Boards.findOne(this.boardId); // List where to insert card const list = $(Popup._getTopStack().openerElement).closest('.js-list'); this.listId = Blaze.getData(list[0])._id; // Swimlane where to insert card - const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane'); + const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane'); this.swimlaneId = ''; - if (board.view === 'board-view-swimlanes') + if (Meteor.user().profile.boardView === 'board-view-swimlanes') this.swimlaneId = Blaze.getData(swimlane[0])._id; else this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id; @@ -606,7 +605,6 @@ BlazeComponent.extendComponent({ 'click .js-minicard'(evt) { // 0. Common let element = Blaze.getData(evt.currentTarget); - console.log(element); element.boardId = this.boardId; let _id = ''; if (!this.isTemplateSearch || this.isCardTemplateSearch) { @@ -630,14 +628,17 @@ BlazeComponent.extendComponent({ Filter.addException(_id); // List insertion } else if (this.isListTemplateSearch) { - element.swimlaneId = ''; element.sort = Swimlanes.findOne(this.swimlaneId).lists().count(); element.type = 'list'; element.swimlaneId = this.swimlaneId; _id = element.copy(); + } else if (this.isSwimlaneTemplateSearch) { + element.sort = Boards.findOne(this.boardId).swimlanes().count(); + element.type = 'swimlalne'; + _id = element.copy(); } Popup.close(); }, }]; }, -}).register('searchCardPopup'); +}).register('searchElementPopup'); diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 810dd57f0..de9621d52 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -40,6 +40,11 @@ template(name="swimlaneAddPopup") autocomplete="off" autofocus) .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'add'}} + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-swimlane-template {{_ 'template'}} template(name="setSwimlaneColorPopup") form.edit-label diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index b78bdc96e..e7f3cc761 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -65,6 +65,7 @@ BlazeComponent.extendComponent({ // with a minimum of interactions Popup.close(); }, + 'click .js-swimlane-template': Popup.open('searchElement'), }]; }, }).register('swimlaneAddPopup'); diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index bdaed81d2..b4277d4fe 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -154,8 +154,8 @@ BlazeComponent.extendComponent({ BlazeComponent.extendComponent({ onCreated() { - currentBoard = Boards.findOne(Session.get('currentBoard')); - this.isListTemplatesSwimlane = currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane(); + this.currentBoard = Boards.findOne(Session.get('currentBoard')); + this.isListTemplatesSwimlane = this.currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane(); this.currentSwimlane = this.currentData(); }, @@ -176,14 +176,14 @@ BlazeComponent.extendComponent({ boardId: Session.get('currentBoard'), sort: $('.list').length, type: (this.isListTemplatesSwimlane)?'template-list':'list', - swimlaneId: (this.isListTemplatesSwimlane)?this.currentSwimlane._id:'', + swimlaneId: (this.currentBoard.isTemplatesBoard())?this.currentSwimlane._id:'', }); titleInput.value = ''; titleInput.focus(); } }, - 'click .js-list-template': Popup.open('searchCard'), + 'click .js-list-template': Popup.open('searchElement'), }]; }, }).register('addListForm'); diff --git a/models/boards.js b/models/boards.js index 530a6f712..d81ded15b 100644 --- a/models/boards.js +++ b/models/boards.js @@ -463,6 +463,30 @@ Boards.helpers({ return _id; }, + searchSwimlanes(term) { + check(term, Match.OneOf(String, null, undefined)); + + const query = { boardId: this._id }; + if (this.isTemplatesBoard()) { + query.type = 'template-swimlane'; + query.archived = false; + } else { + query.type = {$nin: ['template-swimlane']}; + } + const projection = { limit: 10, sort: { createdAt: -1 } }; + + if (term) { + const regex = new RegExp(term, 'i'); + + query.$or = [ + { title: regex }, + { description: regex }, + ]; + } + + return Swimlanes.find(query, projection); + }, + searchLists(term) { check(term, Match.OneOf(String, null, undefined)); diff --git a/models/lists.js b/models/lists.js index e2ded36e8..76708ffd4 100644 --- a/models/lists.js +++ b/models/lists.js @@ -139,8 +139,17 @@ Lists.allow({ Lists.helpers({ copy() { const oldId = this._id; - this._id = null; - const _id = Lists.insert(this); + let _id = null; + existingListWithSameName = Lists.findOne({ + boardId: this.boardId, + title: this.title, + }); + if (existingListWithSameName) { + _id = existingListWithSameName._id; + } else { + this._id = null; + _id = Lists.insert(this); + } // Copy all cards in list Cards.find({ @@ -213,23 +222,20 @@ Lists.mutations({ }, archive() { - Cards.find({ - listId: this._id, - archived: false, - }).forEach((card) => { - return card.archive(); - }); + if (this.isTemplateList()) { + this.cards().forEach((card) => { + return card.archive(); + }); + } return { $set: { archived: true } }; }, restore() { - cardsToRestore = Cards.find({ - listId: this._id, - archived: true, - }); - cardsToRestore.forEach((card) => { - card.restore(); - }); + if (this.isTemplateList()) { + this.allCards().forEach((card) => { + return card.restore(); + }); + } return { $set: { archived: false } }; }, diff --git a/models/swimlanes.js b/models/swimlanes.js index be3f617cc..205f1498b 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -101,6 +101,23 @@ Swimlanes.allow({ }); Swimlanes.helpers({ + copy() { + const oldId = this._id; + this._id = null; + const _id = Swimlanes.insert(this); + + // Copy all lists in swimlane + Lists.find({ + swimlaneId: oldId, + archived: false, + }).forEach((list) => { + list.type = 'list'; + list.swimlaneId = _id; + list.boardId = this.boardId; + list.copy(); + }); + }, + cards() { return Cards.find(Filter.mongoSelector({ swimlaneId: this._id, @@ -115,6 +132,10 @@ Swimlanes.helpers({ }), { sort: ['sort'] }); }, + allLists() { + return Lists.find({ swimlaneId: this._id }); + }, + allCards() { return Cards.find({ swimlaneId: this._id }); }, @@ -159,10 +180,20 @@ Swimlanes.mutations({ }, archive() { + if (this.isTemplateSwimlane()) { + this.lists().forEach((list) => { + return list.archive(); + }); + } return { $set: { archived: true } }; }, restore() { + if (this.isTemplateSwimlane()) { + this.allLists().forEach((list) => { + return list.restore(); + }); + } return { $set: { archived: false } }; }, From eb62c9ce6ad0fa0d5de7889ec087db8cdc579339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sun, 24 Feb 2019 00:13:35 +0100 Subject: [PATCH 10/19] Fix lint errors --- client/components/boards/boardsList.js | 4 +- client/components/lists/listBody.js | 80 +++++++++++++------------- client/components/users/userHeader.js | 4 +- models/boards.js | 12 ++-- models/cards.js | 38 ++++++------ models/checklists.js | 20 +++---- models/lists.js | 50 ++++++++-------- models/swimlanes.js | 48 ++++++++-------- models/users.js | 70 +++++++++++----------- 9 files changed, 163 insertions(+), 163 deletions(-) diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 3fd2d8899..df495bb14 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -8,10 +8,10 @@ Template.boardListHeaderBar.events({ Template.boardListHeaderBar.helpers({ templatesBoardId() { - return Meteor.user().getTemplatesBoardId(); + return Meteor.user().getTemplatesBoardId(); }, templatesBoardSlug() { - return Meteor.user().getTemplatesBoardSlug(); + return Meteor.user().getTemplatesBoardSlug(); }, }); diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index f8634c0b7..befcf72f6 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -81,16 +81,16 @@ BlazeComponent.extendComponent({ cardType = 'template-card'; // If this is the board templates swimlane, insert a board template and a linked card else if (swimlane.isBoardTemplatesSwimlane()) { - linkedId = Boards.insert({ - title, - permission: 'private', - type: 'template-board', - }); - Swimlanes.insert({ - title: TAPi18n.__('default'), - boardId: linkedId, - }); - cardType = 'cardType-linkedBoard'; + linkedId = Boards.insert({ + title, + permission: 'private', + type: 'template-board', + }); + Swimlanes.insert({ + title: TAPi18n.__('default'), + boardId: linkedId, + }); + cardType = 'cardType-linkedBoard'; } } else if (boardView === 'board-view-swimlanes') swimlaneId = this.parentComponent().parentComponent().data()._id; @@ -149,9 +149,9 @@ BlazeComponent.extendComponent({ const methodName = evt.shiftKey ? 'toggleRange' : 'toggle'; MultiSelection[methodName](this.currentData()._id); - // If the card is already selected, we want to de-select it. - // XXX We should probably modify the minicard href attribute instead of - // overwriting the event in case the card is already selected. + // If the card is already selected, we want to de-select it. + // XXX We should probably modify the minicard href attribute instead of + // overwriting the event in case the card is already selected. } else if (Session.equals('currentCard', this.currentData()._id)) { evt.stopImmediatePropagation(); evt.preventDefault(); @@ -171,8 +171,8 @@ BlazeComponent.extendComponent({ idOrNull(swimlaneId) { const currentUser = Meteor.user(); - if (currentUser.profile.boardView === 'board-view-swimlanes' - || this.data().board().isTemplatesBoard()) + if (currentUser.profile.boardView === 'board-view-swimlanes' || + this.data().board().isTemplatesBoard()) return swimlaneId; return undefined; }, @@ -292,8 +292,8 @@ BlazeComponent.extendComponent({ // work. $form.find('button[type=submit]').click(); - // Pressing Tab should open the form of the next column, and Maj+Tab go - // in the reverse order + // Pressing Tab should open the form of the next column, and Maj+Tab go + // in the reverse order } else if (evt.keyCode === 9) { evt.preventDefault(); const isReverse = evt.shiftKey; @@ -354,7 +354,7 @@ BlazeComponent.extendComponent({ const currentBoard = Boards.findOne(Session.get('currentBoard')); callback($.map(currentBoard.labels, (label) => { if (label.name.indexOf(term) > -1 || - label.color.indexOf(term) > -1) { + label.color.indexOf(term) > -1) { return label; } return null; @@ -530,7 +530,7 @@ BlazeComponent.extendComponent({ this.isTemplateSearch = this.isCardTemplateSearch || this.isListTemplateSearch || this.isSwimlaneTemplateSearch; let board = {}; if (this.isTemplateSearch) { - board = Boards.findOne(Meteor.user().profile.templatesBoardId); + board = Boards.findOne(Meteor.user().profile.templatesBoardId); } else { // Prefetch first non-current board id board = Boards.findOne({ @@ -582,13 +582,13 @@ BlazeComponent.extendComponent({ } const board = Boards.findOne(this.selectedBoardId.get()); if (!this.isTemplateSearch || this.isCardTemplateSearch) { - return board.searchCards(this.term.get(), false); + return board.searchCards(this.term.get(), false); } else if (this.isListTemplateSearch) { - return board.searchLists(this.term.get()); + return board.searchLists(this.term.get()); } else if (this.isSwimlaneTemplateSearch) { - return board.searchSwimlanes(this.term.get()); + return board.searchSwimlanes(this.term.get()); } else { - return []; + return []; } }, @@ -604,7 +604,7 @@ BlazeComponent.extendComponent({ }, 'click .js-minicard'(evt) { // 0. Common - let element = Blaze.getData(evt.currentTarget); + const element = Blaze.getData(evt.currentTarget); element.boardId = this.boardId; let _id = ''; if (!this.isTemplateSearch || this.isCardTemplateSearch) { @@ -615,27 +615,27 @@ BlazeComponent.extendComponent({ element.sort = Lists.findOne(this.listId).cards().count(); // 1.A From template if (this.isTemplateSearch) { - element.type = 'cardType-card'; - element.linkedId = ''; - _id = element.copy(); - // 1.B Linked card + element.type = 'cardType-card'; + element.linkedId = ''; + _id = element.copy(); + // 1.B Linked card } else { - element._id = null; - element.type = 'cardType-linkedCard'; - element.linkedId = element.linkedId || element._id; - _id = Cards.insert(element); + element._id = null; + element.type = 'cardType-linkedCard'; + element.linkedId = element.linkedId || element._id; + _id = Cards.insert(element); } Filter.addException(_id); - // List insertion + // List insertion } else if (this.isListTemplateSearch) { - element.sort = Swimlanes.findOne(this.swimlaneId).lists().count(); - element.type = 'list'; - element.swimlaneId = this.swimlaneId; - _id = element.copy(); + element.sort = Swimlanes.findOne(this.swimlaneId).lists().count(); + element.type = 'list'; + element.swimlaneId = this.swimlaneId; + _id = element.copy(); } else if (this.isSwimlaneTemplateSearch) { - element.sort = Boards.findOne(this.boardId).swimlanes().count(); - element.type = 'swimlalne'; - _id = element.copy(); + element.sort = Boards.findOne(this.boardId).swimlanes().count(); + element.type = 'swimlalne'; + _id = element.copy(); } Popup.close(); }, diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 29b295348..6a2397a4b 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -5,10 +5,10 @@ Template.headerUserBar.events({ Template.memberMenuPopup.helpers({ templatesBoardId() { - return Meteor.user().getTemplatesBoardId(); + return Meteor.user().getTemplatesBoardId(); }, templatesBoardSlug() { - return Meteor.user().getTemplatesBoardSlug(); + return Meteor.user().getTemplatesBoardSlug(); }, }); diff --git a/models/boards.js b/models/boards.js index d81ded15b..0d3213bc8 100644 --- a/models/boards.js +++ b/models/boards.js @@ -471,7 +471,7 @@ Boards.helpers({ query.type = 'template-swimlane'; query.archived = false; } else { - query.type = {$nin: ['template-swimlane']}; + query.type = {$nin: ['template-swimlane']}; } const projection = { limit: 10, sort: { createdAt: -1 } }; @@ -495,7 +495,7 @@ Boards.helpers({ query.type = 'template-list'; query.archived = false; } else { - query.type = {$nin: ['template-list']}; + query.type = {$nin: ['template-list']}; } const projection = { limit: 10, sort: { createdAt: -1 } }; @@ -522,7 +522,7 @@ Boards.helpers({ query.type = 'template-card'; query.archived = false; } else { - query.type = {$nin: ['template-card']}; + query.type = {$nin: ['template-card']}; } const projection = { limit: 10, sort: { createdAt: -1 } }; @@ -975,7 +975,7 @@ if (Meteor.isServer) { * @param {string} userId the ID of the user to retrieve the data * @return_type [{_id: string, title: string}] - */ + */ JsonRoutes.add('GET', '/api/users/:userId/boards', function (req, res) { try { Authentication.checkLoggedIn(req.userId); @@ -1012,7 +1012,7 @@ if (Meteor.isServer) { * * @return_type [{_id: string, title: string}] - */ + */ JsonRoutes.add('GET', '/api/boards', function (req, res) { try { Authentication.checkUserId(req.userId); @@ -1083,7 +1083,7 @@ if (Meteor.isServer) { * * @return_type {_id: string, defaultSwimlaneId: string} - */ + */ JsonRoutes.add('POST', '/api/boards', function (req, res) { try { Authentication.checkUserId(req.userId); diff --git a/models/cards.js b/models/cards.js index c7b4a3667..e91f0af50 100644 --- a/models/cards.js +++ b/models/cards.js @@ -273,28 +273,28 @@ Cards.allow({ Cards.helpers({ copy() { - const oldId = this._id; - this._id = null; - const _id = Cards.insert(this); + const oldId = this._id; + this._id = null; + const _id = Cards.insert(this); - // copy checklists - Checklists.find({cardId: oldId}).forEach((ch) => { - ch.copy(_id); - }); + // copy checklists + Checklists.find({cardId: oldId}).forEach((ch) => { + ch.copy(_id); + }); - // copy subtasks - Cards.find({parentId: oldId}).forEach((subtask) => { - subtask.parentId = _id; - subtask._id = null; - Cards.insert(subtask); - }); + // copy subtasks + Cards.find({parentId: oldId}).forEach((subtask) => { + subtask.parentId = _id; + subtask._id = null; + Cards.insert(subtask); + }); - // copy card comments - CardComments.find({cardId: oldId}).forEach((cmt) => { - cmt.copy(_id); - }); + // copy card comments + CardComments.find({cardId: oldId}).forEach((cmt) => { + cmt.copy(_id); + }); - return _id; + return _id; }, list() { @@ -1259,7 +1259,7 @@ Cards.mutations({ function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId) { if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) || - (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){ + (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){ Activities.insert({ userId, oldListId, diff --git a/models/checklists.js b/models/checklists.js index 99e9f25e3..9e763f1ad 100644 --- a/models/checklists.js +++ b/models/checklists.js @@ -49,16 +49,16 @@ Checklists.attachSchema(new SimpleSchema({ Checklists.helpers({ copy(newCardId) { - const oldChecklistId = this._id; - this._id = null; - this.cardId = newCardId; - const newChecklistId = Checklists.insert(this); - ChecklistItems.find({checklistId: oldChecklistId}).forEach((item) => { - item._id = null; - item.checklistId = newChecklistId; - item.cardId = newCardId; - ChecklistItems.insert(item); - }); + const oldChecklistId = this._id; + this._id = null; + this.cardId = newCardId; + const newChecklistId = Checklists.insert(this); + ChecklistItems.find({checklistId: oldChecklistId}).forEach((item) => { + item._id = null; + item.checklistId = newChecklistId; + item.cardId = newCardId; + ChecklistItems.insert(item); + }); }, itemCount() { diff --git a/models/lists.js b/models/lists.js index 76708ffd4..453e0be10 100644 --- a/models/lists.js +++ b/models/lists.js @@ -138,30 +138,30 @@ Lists.allow({ Lists.helpers({ copy() { - const oldId = this._id; - let _id = null; - existingListWithSameName = Lists.findOne({ - boardId: this.boardId, - title: this.title, - }); - if (existingListWithSameName) { - _id = existingListWithSameName._id; - } else { - this._id = null; - _id = Lists.insert(this); - } + const oldId = this._id; + let _id = null; + existingListWithSameName = Lists.findOne({ + boardId: this.boardId, + title: this.title, + }); + if (existingListWithSameName) { + _id = existingListWithSameName._id; + } else { + this._id = null; + _id = Lists.insert(this); + } - // Copy all cards in list - Cards.find({ - listId: oldId, - archived: false, - }).forEach((card) => { - card.type = 'cardType-card'; - card.listId = _id; - card.boardId = this.boardId; - card.swimlaneId = this.swimlaneId; - card.copy(); - }); + // Copy all cards in list + Cards.find({ + listId: oldId, + archived: false, + }).forEach((card) => { + card.type = 'cardType-card'; + card.listId = _id; + card.boardId = this.boardId; + card.swimlaneId = this.swimlaneId; + card.copy(); + }); }, cards(swimlaneId) { @@ -224,7 +224,7 @@ Lists.mutations({ archive() { if (this.isTemplateList()) { this.cards().forEach((card) => { - return card.archive(); + return card.archive(); }); } return { $set: { archived: true } }; @@ -233,7 +233,7 @@ Lists.mutations({ restore() { if (this.isTemplateList()) { this.allCards().forEach((card) => { - return card.restore(); + return card.restore(); }); } return { $set: { archived: false } }; diff --git a/models/swimlanes.js b/models/swimlanes.js index 205f1498b..6f679a8d3 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -102,20 +102,20 @@ Swimlanes.allow({ Swimlanes.helpers({ copy() { - const oldId = this._id; - this._id = null; - const _id = Swimlanes.insert(this); + const oldId = this._id; + this._id = null; + const _id = Swimlanes.insert(this); - // Copy all lists in swimlane - Lists.find({ - swimlaneId: oldId, - archived: false, - }).forEach((list) => { - list.type = 'list'; - list.swimlaneId = _id; - list.boardId = this.boardId; - list.copy(); - }); + // Copy all lists in swimlane + Lists.find({ + swimlaneId: oldId, + archived: false, + }).forEach((list) => { + list.type = 'list'; + list.swimlaneId = _id; + list.boardId = this.boardId; + list.copy(); + }); }, cards() { @@ -127,8 +127,8 @@ Swimlanes.helpers({ lists() { return Lists.find(Filter.mongoSelector({ - swimlaneId: this._id, - archived: false, + swimlaneId: this._id, + archived: false, }), { sort: ['sort'] }); }, @@ -155,22 +155,22 @@ Swimlanes.helpers({ }, isTemplateContainer() { - return this.type === 'template-container'; + return this.type === 'template-container'; }, isListTemplatesSwimlane() { - const user = Users.findOne(Meteor.userId()); - return user.profile.listTemplatesSwimlaneId === this._id; + const user = Users.findOne(Meteor.userId()); + return user.profile.listTemplatesSwimlaneId === this._id; }, isCardTemplatesSwimlane() { - const user = Users.findOne(Meteor.userId()); - return user.profile.cardTemplatesSwimlaneId === this._id; + const user = Users.findOne(Meteor.userId()); + return user.profile.cardTemplatesSwimlaneId === this._id; }, isBoardTemplatesSwimlane() { - const user = Users.findOne(Meteor.userId()); - return user.profile.boardTemplatesSwimlaneId === this._id; + const user = Users.findOne(Meteor.userId()); + return user.profile.boardTemplatesSwimlaneId === this._id; }, }); @@ -182,7 +182,7 @@ Swimlanes.mutations({ archive() { if (this.isTemplateSwimlane()) { this.lists().forEach((list) => { - return list.archive(); + return list.archive(); }); } return { $set: { archived: true } }; @@ -191,7 +191,7 @@ Swimlanes.mutations({ restore() { if (this.isTemplateSwimlane()) { this.allLists().forEach((list) => { - return list.restore(); + return list.restore(); }); } return { $set: { archived: false } }; diff --git a/models/users.js b/models/users.js index 87f2b8602..9bc4f175f 100644 --- a/models/users.js +++ b/models/users.js @@ -358,11 +358,11 @@ Users.helpers({ }, getTemplatesBoardId() { - return this.profile.templatesBoardId; + return this.profile.templatesBoardId; }, getTemplatesBoardSlug() { - return Boards.findOne(this.profile.templatesBoardId).slug; + return Boards.findOne(this.profile.templatesBoardId).slug; }, }); @@ -741,47 +741,47 @@ if (Meteor.isServer) { Boards.insert({ title: TAPi18n.__('templates'), permission: 'private', - type: 'template-container' + type: 'template-container', }, fakeUser, (err, boardId) => { - // Insert the reference to our templates board - Users.update(fakeUserId.get(), {$set: {'profile.templatesBoardId': 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, (err, swimlaneId) => { + // Insert the card templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('card-templates-swimlane'), + boardId, + sort: 1, + type: 'template-container', + }, fakeUser, (err, swimlaneId) => { - // Insert the reference to out card templates swimlane - Users.update(fakeUserId.get(), {$set: {'profile.cardTemplatesSwimlaneId': swimlaneId}}); - }); + // Insert the reference to out card templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.cardTemplatesSwimlaneId': swimlaneId}}); + }); - // Insert the list templates swimlane - Swimlanes.insert({ - title: TAPi18n.__('list-templates-swimlane'), - boardId, - sort: 2, - type: 'template-container', - }, fakeUser, (err, swimlaneId) => { + // Insert the list templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('list-templates-swimlane'), + boardId, + sort: 2, + type: 'template-container', + }, fakeUser, (err, swimlaneId) => { - // Insert the reference to out list templates swimlane - Users.update(fakeUserId.get(), {$set: {'profile.listTemplatesSwimlaneId': swimlaneId}}); - }); + // Insert the reference to out list templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.listTemplatesSwimlaneId': swimlaneId}}); + }); - // Insert the board templates swimlane - Swimlanes.insert({ - title: TAPi18n.__('board-templates-swimlane'), - boardId, - sort: 3, - type: 'template-container', - }, fakeUser, (err, swimlaneId) => { + // Insert the board templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('board-templates-swimlane'), + boardId, + sort: 3, + type: 'template-container', + }, fakeUser, (err, swimlaneId) => { - // Insert the reference to out board templates swimlane - Users.update(fakeUserId.get(), {$set: {'profile.boardTemplatesSwimlaneId': swimlaneId}}); - }); + // Insert the reference to out board templates swimlane + Users.update(fakeUserId.get(), {$set: {'profile.boardTemplatesSwimlaneId': swimlaneId}}); + }); }); }); }); From 775476f97c1dda92e856ca4650e6003ea1487d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sun, 24 Feb 2019 11:54:52 +0100 Subject: [PATCH 11/19] Fix miniscreen render --- client/components/lists/listBody.js | 4 ++-- client/components/swimlanes/swimlanes.jade | 19 ++++++------------- client/components/swimlanes/swimlanes.js | 9 +++++++++ models/lists.js | 6 +++--- models/swimlanes.js | 7 ++++--- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index befcf72f6..7b3dc6a6e 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -630,8 +630,8 @@ BlazeComponent.extendComponent({ } else if (this.isListTemplateSearch) { element.sort = Swimlanes.findOne(this.swimlaneId).lists().count(); element.type = 'list'; - element.swimlaneId = this.swimlaneId; - _id = element.copy(); + element.swimlaneId = ''; + _id = element.copy(this.swimlaneId); } else if (this.isSwimlaneTemplateSearch) { element.sort = Boards.findOne(this.boardId).swimlanes().count(); element.type = 'swimlalne'; diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index ba174cb55..c56834df4 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -3,22 +3,15 @@ template(name="swimlane") +swimlaneHeader .swimlane.js-lists.js-swimlane if isMiniScreen - if currentList + if currentListIsInThisSwimlane _id +list(currentList) - else - each currentBoard.lists + unless currentList + each lists +miniList(this) if currentUser.isBoardMember +addListForm - else if currentBoard.isTemplatesBoard - each lists - +list(this) - if currentCardIsInThisList _id ../_id - +cardDetails(currentCard) - if currentUser.isBoardMember - +addListForm else - each currentBoard.lists + each lists +list(this) if currentCardIsInThisList _id ../_id +cardDetails(currentCard) @@ -31,12 +24,12 @@ template(name="listsGroup") if currentList +list(currentList) else - each currentBoard.lists + each lists +miniList(this) if currentUser.isBoardMember +addListForm else - each currentBoard.lists + each lists +list(this) if currentCardIsInThisList _id null +cardDetails(currentCard) diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index b4277d4fe..519b00d2e 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -1,5 +1,10 @@ const { calculateIndex, enableClickOnTouch } = Utils; +function currentListIsInThisSwimlane(swimlaneId) { + const currentList = Lists.findOne(Session.get('currentList')); + return currentList && (currentList.swimlaneId === swimlaneId || currentList.swimlaneId === ''); +} + function currentCardIsInThisList(listId, swimlaneId) { const currentCard = Cards.findOne(Session.get('currentCard')); const currentUser = Meteor.user(); @@ -114,6 +119,10 @@ BlazeComponent.extendComponent({ return currentCardIsInThisList(listId, swimlaneId); }, + currentListIsInThisSwimlane(swimlaneId) { + return currentListIsInThisSwimlane(swimlaneId); + }, + events() { return [{ // Click-and-drag action diff --git a/models/lists.js b/models/lists.js index 453e0be10..bf2430ee9 100644 --- a/models/lists.js +++ b/models/lists.js @@ -29,7 +29,7 @@ Lists.attachSchema(new SimpleSchema({ }, swimlaneId: { /** - * the swimalen associated to this list. Used for templates + * the swimlane associated to this list. Used for templates */ type: String, defaultValue: '', @@ -137,7 +137,7 @@ Lists.allow({ }); Lists.helpers({ - copy() { + copy(swimlaneId) { const oldId = this._id; let _id = null; existingListWithSameName = Lists.findOne({ @@ -159,7 +159,7 @@ Lists.helpers({ card.type = 'cardType-card'; card.listId = _id; card.boardId = this.boardId; - card.swimlaneId = this.swimlaneId; + card.swimlaneId = swimlaneId; card.copy(); }); }, diff --git a/models/swimlanes.js b/models/swimlanes.js index 6f679a8d3..d35483297 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -112,9 +112,9 @@ Swimlanes.helpers({ archived: false, }).forEach((list) => { list.type = 'list'; - list.swimlaneId = _id; + list.swimlaneId = ''; list.boardId = this.boardId; - list.copy(); + list.copy(_id); }); }, @@ -127,7 +127,8 @@ Swimlanes.helpers({ lists() { return Lists.find(Filter.mongoSelector({ - swimlaneId: this._id, + boardId: this.boardId, + swimlaneId: {$in: [this._id, '']}, archived: false, }), { sort: ['sort'] }); }, From 7033315cd36530330af6f785716cce9342ef4a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sun, 24 Feb 2019 12:55:34 +0100 Subject: [PATCH 12/19] Add migrations --- server/migrations.js | 95 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/server/migrations.js b/server/migrations.js index 8dcd892ad..cb64b7e8a 100644 --- a/server/migrations.js +++ b/server/migrations.js @@ -422,3 +422,98 @@ Migrations.add('add-defaultAuthenticationMethod', () => { }, }, noValidateMulti); }); + +Migrations.add('add-templates', () => { + Boards.update({ + type: { + $exists: false, + }, + }, { + $set: { + type: 'board', + }, + }, noValidateMulti); + Swimlanes.update({ + type: { + $exists: false, + }, + }, { + $set: { + type: 'swimlane', + }, + }, noValidateMulti); + Lists.update({ + type: { + $exists: false, + }, + swimlaneId: { + $exists: false, + }, + }, { + $set: { + type: 'list', + swimlaneId: '', + }, + }, noValidateMulti); + Users.find({ + 'profile.templatesBoardId': { + $exists: false, + }, + }).forEach((user) => { + // Create board and swimlanes + Boards.insert({ + title: TAPi18n.__('templates'), + permission: 'private', + type: 'template-container', + members: [ + { + userId: user._id, + isAdmin: true, + isActive: true, + isNoComments: false, + isCommentOnly: false, + }, + ], + }, (err, boardId) => { + + // Insert the reference to our templates board + Users.update(user._id, {$set: {'profile.templatesBoardId': boardId}}); + + // Insert the card templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('card-templates-swimlane'), + boardId, + sort: 1, + type: 'template-container', + }, (err, swimlaneId) => { + + // Insert the reference to out card templates swimlane + Users.update(user._id, {$set: {'profile.cardTemplatesSwimlaneId': swimlaneId}}); + }); + + // Insert the list templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('list-templates-swimlane'), + boardId, + sort: 2, + type: 'template-container', + }, (err, swimlaneId) => { + + // Insert the reference to out list templates swimlane + Users.update(user._id, {$set: {'profile.listTemplatesSwimlaneId': swimlaneId}}); + }); + + // Insert the board templates swimlane + Swimlanes.insert({ + title: TAPi18n.__('board-templates-swimlane'), + boardId, + sort: 3, + type: 'template-container', + }, (err, swimlaneId) => { + + // Insert the reference to out board templates swimlane + Users.update(user._id, {$set: {'profile.boardTemplatesSwimlaneId': swimlaneId}}); + }); + }); + }); +}); From 13c2157e36f65be4138a85fae0379e0fe31f02bd Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 25 Feb 2019 06:14:43 +0200 Subject: [PATCH 13/19] Update translations. --- i18n/ar.i18n.json | 6 ++++++ i18n/bg.i18n.json | 6 ++++++ i18n/br.i18n.json | 6 ++++++ i18n/ca.i18n.json | 6 ++++++ i18n/cs.i18n.json | 6 ++++++ i18n/da.i18n.json | 6 ++++++ i18n/de.i18n.json | 6 ++++++ i18n/el.i18n.json | 6 ++++++ i18n/en-GB.i18n.json | 6 ++++++ i18n/eo.i18n.json | 6 ++++++ i18n/es-AR.i18n.json | 6 ++++++ i18n/es.i18n.json | 6 ++++++ i18n/eu.i18n.json | 6 ++++++ i18n/fa.i18n.json | 6 ++++++ i18n/fi.i18n.json | 6 ++++++ i18n/fr.i18n.json | 6 ++++++ i18n/gl.i18n.json | 6 ++++++ i18n/he.i18n.json | 6 ++++++ i18n/hi.i18n.json | 6 ++++++ i18n/hu.i18n.json | 6 ++++++ i18n/hy.i18n.json | 6 ++++++ i18n/id.i18n.json | 6 ++++++ i18n/ig.i18n.json | 6 ++++++ i18n/it.i18n.json | 6 ++++++ i18n/ja.i18n.json | 6 ++++++ i18n/ka.i18n.json | 6 ++++++ i18n/km.i18n.json | 6 ++++++ i18n/ko.i18n.json | 6 ++++++ i18n/lv.i18n.json | 6 ++++++ i18n/mk.i18n.json | 6 ++++++ i18n/mn.i18n.json | 6 ++++++ i18n/nb.i18n.json | 6 ++++++ i18n/nl.i18n.json | 6 ++++++ i18n/pl.i18n.json | 6 ++++++ i18n/pt-BR.i18n.json | 6 ++++++ i18n/pt.i18n.json | 6 ++++++ i18n/ro.i18n.json | 6 ++++++ i18n/ru.i18n.json | 6 ++++++ i18n/sr.i18n.json | 6 ++++++ i18n/sv.i18n.json | 6 ++++++ i18n/sw.i18n.json | 6 ++++++ i18n/ta.i18n.json | 6 ++++++ i18n/th.i18n.json | 6 ++++++ i18n/tr.i18n.json | 18 ++++++++++++------ i18n/uk.i18n.json | 6 ++++++ i18n/vi.i18n.json | 6 ++++++ i18n/zh-CN.i18n.json | 6 ++++++ i18n/zh-TW.i18n.json | 6 ++++++ 48 files changed, 294 insertions(+), 6 deletions(-) diff --git a/i18n/ar.i18n.json b/i18n/ar.i18n.json index 3a1b171f6..5f407569c 100644 --- a/i18n/ar.i18n.json +++ b/i18n/ar.i18n.json @@ -92,6 +92,8 @@ "restore-board": "استعادة اللوحة", "no-archived-boards": "لا توجد لوحات في الأرشيف.", "archives": "أرشيف", + "template": "Template", + "templates": "Templates", "assign-member": "تعيين عضو", "attached": "أُرفق)", "attachment": "مرفق", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "علامات", "cardMembersPopup-title": "أعضاء", "cardMorePopup-title": "المزيد", + "cardTemplatePopup-title": "Create template", "cards": "بطاقات", "cards-count": "بطاقات", "casSignIn": "تسجيل الدخول مع CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "المبادئ", "welcome-list2": "متقدم", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "ماذا تريد أن تنجز?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/bg.i18n.json b/i18n/bg.i18n.json index 96e0195dc..d776b9e32 100644 --- a/i18n/bg.i18n.json +++ b/i18n/bg.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Възстанови Таблото", "no-archived-boards": "Няма Табла в Архива.", "archives": "Архив", + "template": "Template", + "templates": "Templates", "assign-member": "Възложи на член от екипа", "attached": "прикачен", "attachment": "Прикаченн файл", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Етикети", "cardMembersPopup-title": "Членове", "cardMorePopup-title": "Още", + "cardTemplatePopup-title": "Create template", "cards": "Карти", "cards-count": "Карти", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Невалиден WIP лимит", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/br.i18n.json b/i18n/br.i18n.json index b6ffe2db0..e54f57b09 100644 --- a/i18n/br.i18n.json +++ b/i18n/br.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Izili", "cardMorePopup-title": "Muioc’h", + "cardTemplatePopup-title": "Create template", "cards": "Kartennoù", "cards-count": "Kartennoù", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ca.i18n.json b/i18n/ca.i18n.json index 3ec051815..9cc36323c 100644 --- a/i18n/ca.i18n.json +++ b/i18n/ca.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restaura Tauler", "no-archived-boards": "No hi han Taulers al Arxiu.", "archives": "Desa", + "template": "Template", + "templates": "Templates", "assign-member": "Assignar membre", "attached": "adjuntat", "attachment": "Adjunt", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiquetes", "cardMembersPopup-title": "Membres", "cardMorePopup-title": "Més", + "cardTemplatePopup-title": "Create template", "cards": "Fitxes", "cards-count": "Fitxes", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Objectiu 1", "welcome-list1": "Bàsics", "welcome-list2": "Avançades", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Què vols fer?", "wipLimitErrorPopup-title": "Límit de Treball en Progrès invàlid", "wipLimitErrorPopup-dialog-pt1": "El nombre de tasques en esta llista és superior al límit de Treball en Progrès que heu definit.", diff --git a/i18n/cs.i18n.json b/i18n/cs.i18n.json index 5f809eaa7..dbdf45511 100644 --- a/i18n/cs.i18n.json +++ b/i18n/cs.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Obnovit tablo", "no-archived-boards": "V archivu nejsou žádná tabla.", "archives": "Archiv", + "template": "Template", + "templates": "Templates", "assign-member": "Přiřadit člena", "attached": "přiloženo", "attachment": "Příloha", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Štítky", "cardMembersPopup-title": "Členové", "cardMorePopup-title": "Více", + "cardTemplatePopup-title": "Create template", "cards": "Karty", "cards-count": "Karty", "casSignIn": "Přihlásit pomocí CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milník 1", "welcome-list1": "Základní", "welcome-list2": "Pokročilé", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Co chcete dělat?", "wipLimitErrorPopup-title": "Neplatný WIP Limit", "wipLimitErrorPopup-dialog-pt1": "Počet úkolů v tomto sloupci je vyšší než definovaný WIP limit.", diff --git a/i18n/da.i18n.json b/i18n/da.i18n.json index 656de7295..b54634c5a 100644 --- a/i18n/da.i18n.json +++ b/i18n/da.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/de.i18n.json b/i18n/de.i18n.json index 841417316..e6a3d97e8 100644 --- a/i18n/de.i18n.json +++ b/i18n/de.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Board wiederherstellen", "no-archived-boards": "Keine Boards im Archiv.", "archives": "Archiv", + "template": "Template", + "templates": "Templates", "assign-member": "Mitglied zuweisen", "attached": "angehängt", "attachment": "Anhang", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Mitglieder", "cardMorePopup-title": "Mehr", + "cardTemplatePopup-title": "Create template", "cards": "Karten", "cards-count": "Karten", "casSignIn": "Mit CAS anmelden", @@ -453,6 +456,9 @@ "welcome-swimlane": "Meilenstein 1", "welcome-list1": "Grundlagen", "welcome-list2": "Fortgeschritten", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Was wollen Sie tun?", "wipLimitErrorPopup-title": "Ungültiges WIP-Limit", "wipLimitErrorPopup-dialog-pt1": "Die Anzahl von Aufgaben in dieser Liste ist größer als das von Ihnen definierte WIP-Limit.", diff --git a/i18n/el.i18n.json b/i18n/el.i18n.json index adfd19f2d..216b0c2d2 100644 --- a/i18n/el.i18n.json +++ b/i18n/el.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Ετικέτες", "cardMembersPopup-title": "Μέλοι", "cardMorePopup-title": "Περισσότερα", + "cardTemplatePopup-title": "Create template", "cards": "Κάρτες", "cards-count": "Κάρτες", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/en-GB.i18n.json b/i18n/en-GB.i18n.json index 04bb2bacf..c9b68793f 100644 --- a/i18n/en-GB.i18n.json +++ b/i18n/en-GB.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/eo.i18n.json b/i18n/eo.i18n.json index da1e9697f..1c84bbd49 100644 --- a/i18n/eo.i18n.json +++ b/i18n/eo.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Arkivi", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etikedoj", "cardMembersPopup-title": "Membroj", "cardMorePopup-title": "Pli", + "cardTemplatePopup-title": "Create template", "cards": "Kartoj", "cards-count": "Kartoj", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Kion vi volas fari?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/es-AR.i18n.json b/i18n/es-AR.i18n.json index 95c2f086a..2d6d65fee 100644 --- a/i18n/es-AR.i18n.json +++ b/i18n/es-AR.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restaurar Tablero", "no-archived-boards": "No Boards in Archive.", "archives": "Archivar", + "template": "Template", + "templates": "Templates", "assign-member": "Asignar miembro", "attached": "adjunto(s)", "attachment": "Adjunto", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Miembros", "cardMorePopup-title": "Mas", + "cardTemplatePopup-title": "Create template", "cards": "Tarjetas", "cards-count": "Tarjetas", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Hito 1", "welcome-list1": "Básicos", "welcome-list2": "Avanzado", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "¿Qué querés hacer?", "wipLimitErrorPopup-title": "Límite TEP Inválido", "wipLimitErrorPopup-dialog-pt1": " El número de tareas en esta lista es mayor que el límite TEP que definiste.", diff --git a/i18n/es.i18n.json b/i18n/es.i18n.json index dad03bf69..f17edd865 100644 --- a/i18n/es.i18n.json +++ b/i18n/es.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restaurar el tablero", "no-archived-boards": "No hay Tableros en el Archivo", "archives": "Archivar", + "template": "Template", + "templates": "Templates", "assign-member": "Asignar miembros", "attached": "adjuntado", "attachment": "Adjunto", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Miembros", "cardMorePopup-title": "Más", + "cardTemplatePopup-title": "Create template", "cards": "Tarjetas", "cards-count": "Tarjetas", "casSignIn": "Iniciar sesión con CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Hito 1", "welcome-list1": "Básicos", "welcome-list2": "Avanzados", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "¿Qué deseas hacer?", "wipLimitErrorPopup-title": "El límite del trabajo en proceso no es válido.", "wipLimitErrorPopup-dialog-pt1": "El número de tareas en esta lista es mayor que el límite del trabajo en proceso que has definido.", diff --git a/i18n/eu.i18n.json b/i18n/eu.i18n.json index 4d34b6ca5..ab54ba9e7 100644 --- a/i18n/eu.i18n.json +++ b/i18n/eu.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Berreskuratu arbela", "no-archived-boards": "No Boards in Archive.", "archives": "Artxibatu", + "template": "Template", + "templates": "Templates", "assign-member": "Esleitu kidea", "attached": "erantsita", "attachment": "Eranskina", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiketak", "cardMembersPopup-title": "Kideak", "cardMorePopup-title": "Gehiago", + "cardTemplatePopup-title": "Create template", "cards": "Txartelak", "cards-count": "Txartelak", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Oinarrizkoa", "welcome-list2": "Aurreratua", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Zer egin nahi duzu?", "wipLimitErrorPopup-title": "Baliogabeko WIP muga", "wipLimitErrorPopup-dialog-pt1": "Zerrenda honetako atazen muga, WIP-en ezarritakoa baina handiagoa da", diff --git a/i18n/fa.i18n.json b/i18n/fa.i18n.json index 90c515b7d..db8eefe46 100644 --- a/i18n/fa.i18n.json +++ b/i18n/fa.i18n.json @@ -92,6 +92,8 @@ "restore-board": "بازیابی تخته", "no-archived-boards": "هیچ بردی داخل آرشیو نیست", "archives": "بایگانی", + "template": "Template", + "templates": "Templates", "assign-member": "تعیین عضو", "attached": "ضمیمه شده", "attachment": "ضمیمه", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "برچسب ها", "cardMembersPopup-title": "اعضا", "cardMorePopup-title": "بیشتر", + "cardTemplatePopup-title": "Create template", "cards": "کارت‌ها", "cards-count": "کارت‌ها", "casSignIn": "ورود با استفاده از CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "پایه ای ها", "welcome-list2": "پیشرفته", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "چه کاری می خواهید انجام دهید؟", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/fi.i18n.json b/i18n/fi.i18n.json index 7e2c4d3b7..a4a115ec6 100644 --- a/i18n/fi.i18n.json +++ b/i18n/fi.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Palauta taulu", "no-archived-boards": "Ei tauluja Arkistossa", "archives": "Arkisto", + "template": "Malli", + "templates": "Mallit", "assign-member": "Valitse jäsen", "attached": "liitetty", "attachment": "Liitetiedosto", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Tunnisteet", "cardMembersPopup-title": "Jäsenet", "cardMorePopup-title": "Lisää", + "cardTemplatePopup-title": "Luo malli", "cards": "Kortit", "cards-count": "korttia", "casSignIn": "CAS kirjautuminen", @@ -453,6 +456,9 @@ "welcome-swimlane": "Merkkipaalu 1", "welcome-list1": "Perusasiat", "welcome-list2": "Edistynyt", + "card-templates-swimlane": "Kortti mallit", + "list-templates-swimlane": "Lista mallit", + "board-templates-swimlane": "Taulu mallit", "what-to-do": "Mitä haluat tehdä?", "wipLimitErrorPopup-title": "Virheellinen WIP-raja", "wipLimitErrorPopup-dialog-pt1": "Tässä listassa olevien tehtävien määrä on korkeampi kuin asettamasi WIP-raja.", diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json index ff4b2146c..aa20a1edc 100644 --- a/i18n/fr.i18n.json +++ b/i18n/fr.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restaurer le tableau", "no-archived-boards": "Aucun tableau archivé.", "archives": "Archiver", + "template": "Template", + "templates": "Templates", "assign-member": "Affecter un membre", "attached": "joint", "attachment": "Pièce jointe", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Étiquettes", "cardMembersPopup-title": "Membres", "cardMorePopup-title": "Plus", + "cardTemplatePopup-title": "Create template", "cards": "Cartes", "cards-count": "Cartes", "casSignIn": "Se connecter avec CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Jalon 1", "welcome-list1": "Basiques", "welcome-list2": "Avancés", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Que voulez-vous faire ?", "wipLimitErrorPopup-title": "Limite WIP invalide", "wipLimitErrorPopup-dialog-pt1": "Le nombre de cartes de cette liste est supérieur à la limite WIP que vous avez définie.", diff --git a/i18n/gl.i18n.json b/i18n/gl.i18n.json index 9c310c78b..617a213ab 100644 --- a/i18n/gl.i18n.json +++ b/i18n/gl.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restaurar taboleiro", "no-archived-boards": "No Boards in Archive.", "archives": "Arquivar", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Anexo", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Membros", "cardMorePopup-title": "Máis", + "cardTemplatePopup-title": "Create template", "cards": "Tarxetas", "cards-count": "Tarxetas", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Fundamentos", "welcome-list2": "Avanzado", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Que desexa facer?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/he.i18n.json b/i18n/he.i18n.json index 939f2002c..8d089d87b 100644 --- a/i18n/he.i18n.json +++ b/i18n/he.i18n.json @@ -92,6 +92,8 @@ "restore-board": "שחזור לוח", "no-archived-boards": "לא נשמרו לוחות בארכיון.", "archives": "להעביר לארכיון", + "template": "Template", + "templates": "Templates", "assign-member": "הקצאת חבר", "attached": "מצורף", "attachment": "קובץ מצורף", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "תוויות", "cardMembersPopup-title": "חברים", "cardMorePopup-title": "עוד", + "cardTemplatePopup-title": "Create template", "cards": "כרטיסים", "cards-count": "כרטיסים", "casSignIn": "כניסה עם CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "ציון דרך 1", "welcome-list1": "יסודות", "welcome-list2": "מתקדם", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "מה ברצונך לעשות?", "wipLimitErrorPopup-title": "מגבלת „בעבודה” שגויה", "wipLimitErrorPopup-dialog-pt1": "מספר המשימות ברשימה זו גדולה ממגבלת הפריטים „בעבודה” שהגדרת.", diff --git a/i18n/hi.i18n.json b/i18n/hi.i18n.json index 8f5028d6e..7586bf45f 100644 --- a/i18n/hi.i18n.json +++ b/i18n/hi.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore बोर्ड", "no-archived-boards": "No Boards in Archive.", "archives": "पुरालेख", + "template": "Template", + "templates": "Templates", "assign-member": "आवंटित सदस्य", "attached": "संलग्न", "attachment": "संलग्नक", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "नामपत्र", "cardMembersPopup-title": "सदस्य", "cardMorePopup-title": "अतिरिक्त", + "cardTemplatePopup-title": "Create template", "cards": "कार्ड्स", "cards-count": "कार्ड्स", "casSignIn": "सीएएस के साथ साइन इन करें", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want तक do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks अंदर में यह सूची is higher than the WIP limit you've defined.", diff --git a/i18n/hu.i18n.json b/i18n/hu.i18n.json index 18b5b0a12..8f8085c80 100644 --- a/i18n/hu.i18n.json +++ b/i18n/hu.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Tábla visszaállítása", "no-archived-boards": "No Boards in Archive.", "archives": "Archiválás", + "template": "Template", + "templates": "Templates", "assign-member": "Tag hozzárendelése", "attached": "csatolva", "attachment": "Melléklet", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Címkék", "cardMembersPopup-title": "Tagok", "cardMorePopup-title": "Több", + "cardTemplatePopup-title": "Create template", "cards": "Kártyák", "cards-count": "Kártyák", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "1. mérföldkő", "welcome-list1": "Alapok", "welcome-list2": "Speciális", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Mit szeretne tenni?", "wipLimitErrorPopup-title": "Érvénytelen WIP korlát", "wipLimitErrorPopup-dialog-pt1": "A listán lévő feladatok száma magasabb a meghatározott WIP korlátnál.", diff --git a/i18n/hy.i18n.json b/i18n/hy.i18n.json index fe53857bf..22f84286e 100644 --- a/i18n/hy.i18n.json +++ b/i18n/hy.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/id.i18n.json b/i18n/id.i18n.json index 2f363bb9b..8c308e099 100644 --- a/i18n/id.i18n.json +++ b/i18n/id.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Arsip", + "template": "Template", + "templates": "Templates", "assign-member": "Tugaskan anggota", "attached": "terlampir", "attachment": "Lampiran", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Daftar Label", "cardMembersPopup-title": "Daftar Anggota", "cardMorePopup-title": "Lainnya", + "cardTemplatePopup-title": "Create template", "cards": "Daftar Kartu", "cards-count": "Daftar Kartu", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Tingkat dasar", "welcome-list2": "Tingkat lanjut", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Apa yang mau Anda lakukan?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ig.i18n.json b/i18n/ig.i18n.json index 27cee9636..375444975 100644 --- a/i18n/ig.i18n.json +++ b/i18n/ig.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Aha", "cardMembersPopup-title": "Ndị otu", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/it.i18n.json b/i18n/it.i18n.json index 821877223..6a5e97730 100644 --- a/i18n/it.i18n.json +++ b/i18n/it.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Ripristina Bacheca", "no-archived-boards": "No Boards in Archive.", "archives": "Archivia", + "template": "Template", + "templates": "Templates", "assign-member": "Aggiungi membro", "attached": "allegato", "attachment": "Allegato", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etichette", "cardMembersPopup-title": "Membri", "cardMorePopup-title": "Altro", + "cardTemplatePopup-title": "Create template", "cards": "Schede", "cards-count": "Schede", "casSignIn": "Entra con CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Pietra miliare 1", "welcome-list1": "Basi", "welcome-list2": "Avanzate", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Cosa vuoi fare?", "wipLimitErrorPopup-title": "Limite work in progress non valido. ", "wipLimitErrorPopup-dialog-pt1": "Il numero di compiti in questa lista è maggiore del limite di work in progress che hai definito in precedenza. ", diff --git a/i18n/ja.i18n.json b/i18n/ja.i18n.json index 59db5a821..0a432b705 100644 --- a/i18n/ja.i18n.json +++ b/i18n/ja.i18n.json @@ -92,6 +92,8 @@ "restore-board": "ボードをリストア", "no-archived-boards": "No Boards in Archive.", "archives": "アーカイブ", + "template": "Template", + "templates": "Templates", "assign-member": "メンバーの割当", "attached": "添付されました", "attachment": "添付ファイル", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "ラベル", "cardMembersPopup-title": "メンバー", "cardMorePopup-title": "さらに見る", + "cardTemplatePopup-title": "Create template", "cards": "カード", "cards-count": "カード", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "基本", "welcome-list2": "高度", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "何をしたいですか?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ka.i18n.json b/i18n/ka.i18n.json index 76ee2ffef..f99663d4e 100644 --- a/i18n/ka.i18n.json +++ b/i18n/ka.i18n.json @@ -92,6 +92,8 @@ "restore-board": "ბარათის აღდგენა", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "უფლებამოსილი წევრი", "attached": "მიბმული", "attachment": "მიბმული ფიალი", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "ნიშნები", "cardMembersPopup-title": "წევრები", "cardMorePopup-title": "მეტი", + "cardTemplatePopup-title": "Create template", "cards": "ბარათები", "cards-count": "ბარათები", "casSignIn": "შესვლა CAS-ით", @@ -453,6 +456,9 @@ "welcome-swimlane": "ეტაპი 1 ", "welcome-list1": "ბაზისური ", "welcome-list2": "დაწინაურებული", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "რისი გაკეთება გსურთ? ", "wipLimitErrorPopup-title": "არასწორი WIP ლიმიტი", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/km.i18n.json b/i18n/km.i18n.json index 5f3b2dd49..35197573c 100644 --- a/i18n/km.i18n.json +++ b/i18n/km.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ko.i18n.json b/i18n/ko.i18n.json index 1f7066cb1..473a699b5 100644 --- a/i18n/ko.i18n.json +++ b/i18n/ko.i18n.json @@ -92,6 +92,8 @@ "restore-board": "보드 복구", "no-archived-boards": "No Boards in Archive.", "archives": "보관", + "template": "Template", + "templates": "Templates", "assign-member": "멤버 지정", "attached": "첨부됨", "attachment": "첨부 파일", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "라벨", "cardMembersPopup-title": "멤버", "cardMorePopup-title": "더보기", + "cardTemplatePopup-title": "Create template", "cards": "카드", "cards-count": "카드", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "신규", "welcome-list2": "진행", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "무엇을 하고 싶으신가요?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/lv.i18n.json b/i18n/lv.i18n.json index b5c62aae2..e0c5da5c5 100644 --- a/i18n/lv.i18n.json +++ b/i18n/lv.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/mk.i18n.json b/i18n/mk.i18n.json index 5481cc70d..2a6e6b035 100644 --- a/i18n/mk.i18n.json +++ b/i18n/mk.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Възстанови Таблото", "no-archived-boards": "Няма Табла в Архива.", "archives": "Архив", + "template": "Template", + "templates": "Templates", "assign-member": "Възложи на член от екипа", "attached": "прикачен", "attachment": "Прикаченн файл", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Етикети", "cardMembersPopup-title": "Членове", "cardMorePopup-title": "Още", + "cardTemplatePopup-title": "Create template", "cards": "Карти", "cards-count": "Карти", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Невалиден WIP лимит", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/mn.i18n.json b/i18n/mn.i18n.json index 012dea074..6c8a3e414 100644 --- a/i18n/mn.i18n.json +++ b/i18n/mn.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Гишүүд", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/nb.i18n.json b/i18n/nb.i18n.json index 1427e263b..b66150065 100644 --- a/i18n/nb.i18n.json +++ b/i18n/nb.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Arkiv", + "template": "Template", + "templates": "Templates", "assign-member": "Tildel medlem", "attached": "la ved", "attachment": "Vedlegg", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiketter", "cardMembersPopup-title": "Medlemmer", "cardMorePopup-title": "Mer", + "cardTemplatePopup-title": "Create template", "cards": "Kort", "cards-count": "Kort", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/nl.i18n.json b/i18n/nl.i18n.json index 24370c093..dcb354bb8 100644 --- a/i18n/nl.i18n.json +++ b/i18n/nl.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Herstel Bord", "no-archived-boards": "No Boards in Archive.", "archives": "Archiveren", + "template": "Template", + "templates": "Templates", "assign-member": "Wijs lid aan", "attached": "bijgevoegd", "attachment": "Bijlage", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Leden", "cardMorePopup-title": "Meer", + "cardTemplatePopup-title": "Create template", "cards": "Kaarten", "cards-count": "Kaarten", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Mijlpaal 1", "welcome-list1": "Basis", "welcome-list2": "Geadvanceerd", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Wat wil je doen?", "wipLimitErrorPopup-title": "Ongeldige WIP limiet", "wipLimitErrorPopup-dialog-pt1": "Het aantal taken in deze lijst is groter dan de gedefinieerde WIP limiet ", diff --git a/i18n/pl.i18n.json b/i18n/pl.i18n.json index 99a1af9f3..3ec021e53 100644 --- a/i18n/pl.i18n.json +++ b/i18n/pl.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Przywróć tablicę", "no-archived-boards": "Brak tablic w Archiwum.", "archives": "Zarchiwizuj", + "template": "Template", + "templates": "Templates", "assign-member": "Dodaj członka", "attached": "załączono", "attachment": "Załącznik", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etykiety", "cardMembersPopup-title": "Członkowie", "cardMorePopup-title": "Więcej", + "cardTemplatePopup-title": "Create template", "cards": "Karty", "cards-count": "Karty", "casSignIn": "Zaloguj się poprzez CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Kamień milowy 1", "welcome-list1": "Podstawy", "welcome-list2": "Zaawansowane", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Co chcesz zrobić?", "wipLimitErrorPopup-title": "Nieprawidłowy limit kart na liście", "wipLimitErrorPopup-dialog-pt1": "Aktualna ilość kart na tej liście jest większa niż aktualny zdefiniowany limit kart.", diff --git a/i18n/pt-BR.i18n.json b/i18n/pt-BR.i18n.json index 2fb9c4203..d15353e9f 100644 --- a/i18n/pt-BR.i18n.json +++ b/i18n/pt-BR.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restaurar Quadro", "no-archived-boards": "Sem Quadros no Arquivo-morto.", "archives": "Arquivos-morto", + "template": "Template", + "templates": "Templates", "assign-member": "Atribuir Membro", "attached": "anexado", "attachment": "Anexo", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Membros", "cardMorePopup-title": "Mais", + "cardTemplatePopup-title": "Create template", "cards": "Cartões", "cards-count": "Cartões", "casSignIn": "Entrar com CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Marco 1", "welcome-list1": "Básico", "welcome-list2": "Avançado", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "O que você gostaria de fazer?", "wipLimitErrorPopup-title": "Limite WIP Inválido", "wipLimitErrorPopup-dialog-pt1": "O número de tarefas nesta lista excede o limite WIP definido.", diff --git a/i18n/pt.i18n.json b/i18n/pt.i18n.json index b58709602..bd773954b 100644 --- a/i18n/pt.i18n.json +++ b/i18n/pt.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Membros", "cardMorePopup-title": "Mais", + "cardTemplatePopup-title": "Create template", "cards": "Cartões", "cards-count": "Cartões", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ro.i18n.json b/i18n/ro.i18n.json index dd3938d48..25b794b9b 100644 --- a/i18n/ro.i18n.json +++ b/i18n/ro.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Ataşament", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Ce ai vrea sa faci?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ru.i18n.json b/i18n/ru.i18n.json index 16bbb6e7d..6fde47f97 100644 --- a/i18n/ru.i18n.json +++ b/i18n/ru.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Востановить доску", "no-archived-boards": "Нет досок в архиве.", "archives": "Архив", + "template": "Template", + "templates": "Templates", "assign-member": "Назначить участника", "attached": "прикреплено", "attachment": "Вложение", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Метки", "cardMembersPopup-title": "Участники", "cardMorePopup-title": "Поделиться", + "cardTemplatePopup-title": "Create template", "cards": "Карточки", "cards-count": "Карточки", "casSignIn": "Войти через CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Этап 1", "welcome-list1": "Основы", "welcome-list2": "Расширенно", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Что вы хотите сделать?", "wipLimitErrorPopup-title": "Некорректный лимит на кол-во задач", "wipLimitErrorPopup-dialog-pt1": "Количество задач в этом списке превышает установленный вами лимит", diff --git a/i18n/sr.i18n.json b/i18n/sr.i18n.json index 83bdc3a60..77a1c55a7 100644 --- a/i18n/sr.i18n.json +++ b/i18n/sr.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Arhiviraj", + "template": "Template", + "templates": "Templates", "assign-member": "Dodeli člana", "attached": "Prikačeno", "attachment": "Prikačeni dokument", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Članovi", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Osnove", "welcome-list2": "Napredno", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Šta želiš da uradiš ?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/sv.i18n.json b/i18n/sv.i18n.json index a2c0c23e9..7cf6670cf 100644 --- a/i18n/sv.i18n.json +++ b/i18n/sv.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Återställ anslagstavla", "no-archived-boards": "Inga anslagstavlor i Arkiv.", "archives": "Arkiv", + "template": "Template", + "templates": "Templates", "assign-member": "Tilldela medlem", "attached": "bifogad", "attachment": "Bilaga", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiketter", "cardMembersPopup-title": "Medlemmar", "cardMorePopup-title": "Mera", + "cardTemplatePopup-title": "Create template", "cards": "Kort", "cards-count": "Kort", "casSignIn": "Logga in med CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milstolpe 1", "welcome-list1": "Grunderna", "welcome-list2": "Avancerad", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Vad vill du göra?", "wipLimitErrorPopup-title": "Ogiltig WIP-gräns", "wipLimitErrorPopup-dialog-pt1": "Antalet uppgifter i den här listan är högre än WIP-gränsen du har definierat.", diff --git a/i18n/sw.i18n.json b/i18n/sw.i18n.json index 1ffffddb4..f68b08e87 100644 --- a/i18n/sw.i18n.json +++ b/i18n/sw.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "Attachment", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/ta.i18n.json b/i18n/ta.i18n.json index 772fe092d..ef63da13f 100644 --- a/i18n/ta.i18n.json +++ b/i18n/ta.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "Archive", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "attached", "attachment": "இணைப்பு ", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Members", "cardMorePopup-title": "மேலும் ", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/th.i18n.json b/i18n/th.i18n.json index a748773e8..ceb4e7615 100644 --- a/i18n/th.i18n.json +++ b/i18n/th.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Restore Board", "no-archived-boards": "No Boards in Archive.", "archives": "เอกสารที่เก็บไว้", + "template": "Template", + "templates": "Templates", "assign-member": "กำหนดสมาชิก", "attached": "แนบมาด้วย", "attachment": "สิ่งที่แนบมา", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "ป้ายกำกับ", "cardMembersPopup-title": "สมาชิก", "cardMorePopup-title": "เพิ่มเติม", + "cardTemplatePopup-title": "Create template", "cards": "การ์ด", "cards-count": "การ์ด", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "พื้นฐาน", "welcome-list2": "ก้าวหน้า", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "ต้องการทำอะไร", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/tr.i18n.json b/i18n/tr.i18n.json index 5bac9e4f3..987a728a6 100644 --- a/i18n/tr.i18n.json +++ b/i18n/tr.i18n.json @@ -42,7 +42,7 @@ "activity-removed": "%s i %s ten kaldırdı", "activity-sent": "%s i %s e gönderdi", "activity-unjoined": "%s içinden ayrıldı", - "activity-subtask-added": "Alt-görev 1%s'e eklendi", + "activity-subtask-added": "Alt-görev %s'e eklendi", "activity-checked-item": "checked %s in checklist %s of %s", "activity-unchecked-item": "unchecked %s in checklist %s of %s", "activity-checklist-added": "%s içine yapılacak listesi ekledi", @@ -92,6 +92,8 @@ "restore-board": "Panoyu Geri Getir", "no-archived-boards": "Arşivde Pano Yok.", "archives": "Arşivle", + "template": "Template", + "templates": "Templates", "assign-member": "Üye ata", "attached": "dosya(sı) eklendi", "attachment": "Ek Dosya", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Etiketler", "cardMembersPopup-title": "Üyeler", "cardMorePopup-title": "Daha", + "cardTemplatePopup-title": "Create template", "cards": "Kartlar", "cards-count": "Kartlar", "casSignIn": "CAS ile giriş yapın", @@ -402,7 +405,7 @@ "save": "Kaydet", "search": "Arama", "rules": "Kurallar", - "search-cards": "Bu tahta da ki kart başlıkları ve açıklamalarında arama yap", + "search-cards": "Bu panoda kart başlıkları ve açıklamalarında arama yap", "search-example": "Aranılacak metin?", "select-color": "Renk Seç", "set-wip-limit-value": "Bu listedeki en fazla öğe sayısı için bir sınır belirleyin", @@ -453,6 +456,9 @@ "welcome-swimlane": "Kilometre taşı", "welcome-list1": "Temel", "welcome-list2": "Gelişmiş", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "Ne yapmak istiyorsunuz?", "wipLimitErrorPopup-title": "Geçersiz Devam Eden İş Sınırı", "wipLimitErrorPopup-dialog-pt1": "Bu listedeki iş sayısı belirlediğiniz sınırdan daha fazla.", @@ -519,10 +525,10 @@ "card-end-on": "Bitiş zamanı", "editCardReceivedDatePopup-title": "Giriş tarihini değiştir", "editCardEndDatePopup-title": "Bitiş tarihini değiştir", - "setCardColorPopup-title": "renk ayarla", - "setCardActionsColorPopup-title": "Choose a color", - "setSwimlaneColorPopup-title": "Choose a color", - "setListColorPopup-title": "Choose a color", + "setCardColorPopup-title": "Renk ayarla", + "setCardActionsColorPopup-title": "Renk seçimi yap", + "setSwimlaneColorPopup-title": "Renk seçimi yap", + "setListColorPopup-title": "Renk seçimi yap", "assigned-by": "Atamayı yapan", "requested-by": "Talep Eden", "board-delete-notice": "Silme kalıcıdır. Bu kartla ilişkili tüm listeleri, kartları ve işlemleri kaybedeceksiniz.", diff --git a/i18n/uk.i18n.json b/i18n/uk.i18n.json index a7a85d406..232acffea 100644 --- a/i18n/uk.i18n.json +++ b/i18n/uk.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Відновити дошку", "no-archived-boards": "Немає дошок в архіві", "archives": "Архів", + "template": "Template", + "templates": "Templates", "assign-member": "Assign member", "attached": "доданно", "attachment": "Додаток", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Користувачі", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Картки", "cards-count": "Картки", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "Кількість завдань у цьому списку перевищує встановлений вами ліміт", diff --git a/i18n/vi.i18n.json b/i18n/vi.i18n.json index 96223df82..f52bd3ced 100644 --- a/i18n/vi.i18n.json +++ b/i18n/vi.i18n.json @@ -92,6 +92,8 @@ "restore-board": "Khôi Phục Bảng", "no-archived-boards": "No Boards in Archive.", "archives": "Lưu Trữ", + "template": "Template", + "templates": "Templates", "assign-member": "Chỉ định thành viên", "attached": "đã đính kèm", "attachment": "Phần đính kèm", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Thành Viên", "cardMorePopup-title": "More", + "cardTemplatePopup-title": "Create template", "cards": "Cards", "cards-count": "Cards", "casSignIn": "Sign In with CAS", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", "welcome-list2": "Advanced", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "What do you want to do?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", diff --git a/i18n/zh-CN.i18n.json b/i18n/zh-CN.i18n.json index 71bb3ac38..7fd127df0 100644 --- a/i18n/zh-CN.i18n.json +++ b/i18n/zh-CN.i18n.json @@ -92,6 +92,8 @@ "restore-board": "还原看板", "no-archived-boards": "没有归档的看板。", "archives": "归档", + "template": "Template", + "templates": "Templates", "assign-member": "分配成员", "attached": "附加", "attachment": "附件", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "标签", "cardMembersPopup-title": "成员", "cardMorePopup-title": "更多", + "cardTemplatePopup-title": "Create template", "cards": "卡片", "cards-count": "卡片", "casSignIn": "用CAS登录", @@ -453,6 +456,9 @@ "welcome-swimlane": "里程碑 1", "welcome-list1": "基本", "welcome-list2": "高阶", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "要做什么?", "wipLimitErrorPopup-title": "无效的最大任务数", "wipLimitErrorPopup-dialog-pt1": "此列表中的任务数量已经超过了设置的最大任务数。", diff --git a/i18n/zh-TW.i18n.json b/i18n/zh-TW.i18n.json index 29f47c296..19c1374a0 100644 --- a/i18n/zh-TW.i18n.json +++ b/i18n/zh-TW.i18n.json @@ -92,6 +92,8 @@ "restore-board": "還原看板", "no-archived-boards": "封存中沒有看板。", "archives": "封存", + "template": "Template", + "templates": "Templates", "assign-member": "分配成員", "attached": "附加", "attachment": "附件", @@ -143,6 +145,7 @@ "cardLabelsPopup-title": "標籤", "cardMembersPopup-title": "成員", "cardMorePopup-title": "更多", + "cardTemplatePopup-title": "Create template", "cards": "卡片", "cards-count": "卡片", "casSignIn": "以 CAS 登入", @@ -453,6 +456,9 @@ "welcome-swimlane": "Milestone 1", "welcome-list1": "基本", "welcome-list2": "進階", + "card-templates-swimlane": "Card Templates", + "list-templates-swimlane": "List Templates", + "board-templates-swimlane": "Board Templates", "what-to-do": "要做什麼?", "wipLimitErrorPopup-title": "Invalid WIP Limit", "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.", From dc7286a0ef8111c0855129911492588ba8a384df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Mon, 25 Feb 2019 22:48:25 +0100 Subject: [PATCH 14/19] Fix list view issues. Allow creation of boards from templates --- client/components/boards/boardBody.jade | 2 +- client/components/boards/boardHeader.jade | 5 ++- client/components/boards/boardHeader.js | 1 + client/components/boards/miniboard.jade | 8 ++++ client/components/lists/listBody.jade | 17 ++++--- client/components/lists/listBody.js | 55 ++++++++++++++++------- client/components/main/editor.js | 4 +- models/boards.js | 36 +++++++++++++++ models/cardComments.js | 2 +- models/cards.js | 2 +- models/lists.js | 6 ++- models/swimlanes.js | 19 +++++--- 12 files changed, 122 insertions(+), 35 deletions(-) create mode 100644 client/components/boards/miniboard.jade diff --git a/client/components/boards/boardBody.jade b/client/components/boards/boardBody.jade index e36058f65..32f8629f3 100644 --- a/client/components/boards/boardBody.jade +++ b/client/components/boards/boardBody.jade @@ -27,7 +27,7 @@ template(name="boardBody") each currentBoard.swimlanes +swimlane(this) else if isViewLists - +listsGroup + +listsGroup(currentBoard) else if isViewCalendar +calendarView diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 4c9d6e436..1f6462bd9 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -277,7 +277,10 @@ template(name="createBoard") input.primary.wide(type="submit" value="{{_ 'create'}}") span.quiet | {{_ 'or'}} - a.js-import-board {{_ 'import-board'}} + a.js-import-board {{_ 'import'}} + span.quiet + | / + a.js-board-template {{_ 'template'}} template(name="chooseBoardSource") ul.pop-over-list diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 89f686ab4..492fda40d 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -304,6 +304,7 @@ const CreateBoard = BlazeComponent.extendComponent({ 'click .js-import': Popup.open('boardImportBoard'), submit: this.onSubmit, 'click .js-import-board': Popup.open('chooseBoardSource'), + 'click .js-board-template': Popup.open('searchElement'), }]; }, }).register('createBoardPopup'); diff --git a/client/components/boards/miniboard.jade b/client/components/boards/miniboard.jade new file mode 100644 index 000000000..d1fb0b075 --- /dev/null +++ b/client/components/boards/miniboard.jade @@ -0,0 +1,8 @@ +template(name="miniboard") + .minicard( + class="minicard-{{colorClass}}") + .minicard-title + .handle + .fa.fa-arrows + +viewer + = title diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index fcc28777a..b8e2adc71 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -103,16 +103,23 @@ template(name="searchElementPopup") input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus) .list-body.js-perfect-scrollbar.search-card-results .minicards.clearfix.js-minicards - each results - if isListTemplateSearch + if isBoardTemplateSearch + each results + a.minicard-wrapper.js-minicard + +miniboard(this) + if isListTemplateSearch + each results a.minicard-wrapper.js-minicard +minilist(this) - if isSwimlaneTemplateSearch + if isSwimlaneTemplateSearch + each results a.minicard-wrapper.js-minicard +miniswimlane(this) - if isCardTemplateSearch + if isCardTemplateSearch + each results a.minicard-wrapper.js-minicard +minicard(this) - unless isTemplateSearch + unless isTemplateSearch + each results a.minicard-wrapper.js-minicard +minicard(this) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 7b3dc6a6e..5a3862f3d 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -527,7 +527,11 @@ BlazeComponent.extendComponent({ this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template'); this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template'); this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-open-add-swimlane-menu'); - this.isTemplateSearch = this.isCardTemplateSearch || this.isListTemplateSearch || this.isSwimlaneTemplateSearch; + this.isBoardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-add-board'); + this.isTemplateSearch = this.isCardTemplateSearch || + this.isListTemplateSearch || + this.isSwimlaneTemplateSearch || + this.isBoardTemplateSearch; let board = {}; if (this.isTemplateSearch) { board = Boards.findOne(Meteor.user().profile.templatesBoardId); @@ -548,23 +552,26 @@ BlazeComponent.extendComponent({ subManager.subscribe('board', boardId); this.selectedBoardId = new ReactiveVar(boardId); - this.boardId = Session.get('currentBoard'); - // In order to get current board info - subManager.subscribe('board', this.boardId); - // List where to insert card - const list = $(Popup._getTopStack().openerElement).closest('.js-list'); - this.listId = Blaze.getData(list[0])._id; - // Swimlane where to insert card - const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane'); - this.swimlaneId = ''; - if (Meteor.user().profile.boardView === 'board-view-swimlanes') - this.swimlaneId = Blaze.getData(swimlane[0])._id; - else - this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id; + if (!this.isBoardTemplateSearch) { + this.boardId = Session.get('currentBoard'); + // In order to get current board info + subManager.subscribe('board', this.boardId); + this.swimlaneId = ''; + // Swimlane where to insert card + const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane'); + if (Meteor.user().profile.boardView === 'board-view-swimlanes') + this.swimlaneId = Blaze.getData(swimlane[0])._id; + else + this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id; + // List where to insert card + const list = $(Popup._getTopStack().openerElement).closest('.js-list'); + this.listId = Blaze.getData(list[0])._id; + } this.term = new ReactiveVar(''); }, boards() { + console.log('booom'); const boards = Boards.find({ archived: false, 'members.userId': Meteor.userId(), @@ -587,6 +594,12 @@ BlazeComponent.extendComponent({ return board.searchLists(this.term.get()); } else if (this.isSwimlaneTemplateSearch) { return board.searchSwimlanes(this.term.get()); + } else if (this.isBoardTemplateSearch) { + const boards = board.searchBoards(this.term.get()); + boards.forEach((board) => { + subManager.subscribe('board', board.linkedId); + }); + return boards; } else { return []; } @@ -605,11 +618,11 @@ BlazeComponent.extendComponent({ 'click .js-minicard'(evt) { // 0. Common const element = Blaze.getData(evt.currentTarget); - element.boardId = this.boardId; let _id = ''; if (!this.isTemplateSearch || this.isCardTemplateSearch) { // Card insertion // 1. Common + element.boardId = this.boardId; element.listId = this.listId; element.swimlaneId = this.swimlaneId; element.sort = Lists.findOne(this.listId).cards().count(); @@ -620,7 +633,7 @@ BlazeComponent.extendComponent({ _id = element.copy(); // 1.B Linked card } else { - element._id = null; + delete element._id; element.type = 'cardType-linkedCard'; element.linkedId = element.linkedId || element._id; _id = Cards.insert(element); @@ -628,14 +641,22 @@ BlazeComponent.extendComponent({ Filter.addException(_id); // List insertion } else if (this.isListTemplateSearch) { + element.boardId = this.boardId; element.sort = Swimlanes.findOne(this.swimlaneId).lists().count(); element.type = 'list'; - element.swimlaneId = ''; _id = element.copy(this.swimlaneId); } else if (this.isSwimlaneTemplateSearch) { + element.boardId = this.boardId; element.sort = Boards.findOne(this.boardId).swimlanes().count(); element.type = 'swimlalne'; _id = element.copy(); + } else if (this.isBoardTemplateSearch) { + board = Boards.findOne(element.linkedId); + board.sort = Boards.find({archived: false}).count(); + board.type = 'board'; + delete board.slug; + delete board.members; + _id = board.copy(); } Popup.close(); }, diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 20ece5622..88d8abf02 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -36,7 +36,10 @@ import sanitizeXss from 'xss'; const at = HTML.CharRef({html: '@', str: '@'}); Blaze.Template.registerHelper('mentions', new Template('mentions', function() { const view = this; + let content = Blaze.toHTML(view.templateContentBlock); const currentBoard = Boards.findOne(Session.get('currentBoard')); + if (!currentBoard) + return HTML.Raw(sanitizeXss(content)); const knowedUsers = currentBoard.members.map((member) => { const u = Users.findOne(member.userId); if(u){ @@ -45,7 +48,6 @@ Blaze.Template.registerHelper('mentions', new Template('mentions', function() { return member; }); const mentionRegex = /\B@([\w.]*)/gi; - let content = Blaze.toHTML(view.templateContentBlock); let currentMention; while ((currentMention = mentionRegex.exec(content)) !== null) { diff --git a/models/boards.js b/models/boards.js index 0d3213bc8..0db2e48e3 100644 --- a/models/boards.js +++ b/models/boards.js @@ -315,6 +315,21 @@ Boards.attachSchema(new SimpleSchema({ Boards.helpers({ + copy() { + const oldId = this._id; + delete this._id; + const _id = Boards.insert(this); + + // Copy all swimlanes in board + Swimlanes.find({ + boardId: oldId, + archived: false, + }).forEach((swimlane) => { + swimlane.type = 'swimlane'; + swimlane.boardId = _id; + swimlane.copy(oldId); + }); + }, /** * Is supplied user authorized to view this board? */ @@ -463,6 +478,27 @@ Boards.helpers({ return _id; }, + searchBoards(term) { + check(term, Match.OneOf(String, null, undefined)); + + const query = { boardId: this._id }; + query.type = 'cardType-linkedBoard'; + query.archived = false; + + const projection = { limit: 10, sort: { createdAt: -1 } }; + + if (term) { + const regex = new RegExp(term, 'i'); + + query.$or = [ + { title: regex }, + { description: regex }, + ]; + } + + return Cards.find(query, projection); + }, + searchSwimlanes(term) { check(term, Match.OneOf(String, null, undefined)); diff --git a/models/cardComments.js b/models/cardComments.js index f29366a56..fcb97104d 100644 --- a/models/cardComments.js +++ b/models/cardComments.js @@ -69,7 +69,7 @@ CardComments.allow({ CardComments.helpers({ copy(newCardId) { this.cardId = newCardId; - this._id = null; + delete this._id; CardComments.insert(this); }, diff --git a/models/cards.js b/models/cards.js index e91f0af50..c733c7f8b 100644 --- a/models/cards.js +++ b/models/cards.js @@ -274,7 +274,7 @@ Cards.allow({ Cards.helpers({ copy() { const oldId = this._id; - this._id = null; + delete this._id; const _id = Cards.insert(this); // copy checklists diff --git a/models/lists.js b/models/lists.js index bf2430ee9..d76c961c0 100644 --- a/models/lists.js +++ b/models/lists.js @@ -139,20 +139,24 @@ Lists.allow({ Lists.helpers({ copy(swimlaneId) { const oldId = this._id; + const oldSwimlaneId = this.swimlaneId || null; let _id = null; existingListWithSameName = Lists.findOne({ boardId: this.boardId, title: this.title, + archived: false, }); if (existingListWithSameName) { _id = existingListWithSameName._id; } else { - this._id = null; + delete this._id; + delete this.swimlaneId; _id = Lists.insert(this); } // Copy all cards in list Cards.find({ + swimlaneId: oldSwimlaneId, listId: oldId, archived: false, }).forEach((card) => { diff --git a/models/swimlanes.js b/models/swimlanes.js index d35483297..a3427fc62 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -101,18 +101,23 @@ Swimlanes.allow({ }); Swimlanes.helpers({ - copy() { + copy(oldBoardId) { const oldId = this._id; - this._id = null; + delete this._id; const _id = Swimlanes.insert(this); - // Copy all lists in swimlane - Lists.find({ - swimlaneId: oldId, + const query = { + swimlaneId: {$in: [oldId, '']}, archived: false, - }).forEach((list) => { + }; + if (oldBoardId) { + query.boardId = oldBoardId; + } + + // Copy all lists in swimlane + Lists.find(query).forEach((list) => { list.type = 'list'; - list.swimlaneId = ''; + list.swimlaneId = oldId; list.boardId = this.boardId; list.copy(_id); }); From 2f3138207cc3093acbcc6f04b0f2e1ee10d57307 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 26 Feb 2019 00:28:01 +0200 Subject: [PATCH 15/19] Update translations. --- i18n/cs.i18n.json | 14 +- i18n/de.i18n.json | 12 +- i18n/es.i18n.json | 12 +- i18n/fr.i18n.json | 12 +- i18n/he.i18n.json | 12 +- i18n/it.i18n.json | 304 +++++++++++++++++++++---------------------- i18n/pt-BR.i18n.json | 12 +- i18n/zh-CN.i18n.json | 12 +- 8 files changed, 195 insertions(+), 195 deletions(-) diff --git a/i18n/cs.i18n.json b/i18n/cs.i18n.json index dbdf45511..cad46ea92 100644 --- a/i18n/cs.i18n.json +++ b/i18n/cs.i18n.json @@ -92,8 +92,8 @@ "restore-board": "Obnovit tablo", "no-archived-boards": "V archivu nejsou žádná tabla.", "archives": "Archiv", - "template": "Template", - "templates": "Templates", + "template": "Šablona", + "templates": "Šablony", "assign-member": "Přiřadit člena", "attached": "přiloženo", "attachment": "Příloha", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Štítky", "cardMembersPopup-title": "Členové", "cardMorePopup-title": "Více", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Vytvořit šablonu", "cards": "Karty", "cards-count": "Karty", "casSignIn": "Přihlásit pomocí CAS", @@ -169,7 +169,7 @@ "clipboard": "Schránka nebo potáhnout a pustit", "close": "Zavřít", "close-board": "Zavřít tablo", - "close-board-pop": "You will be able to restore the board by clicking the “Archive” button from the home header.", + "close-board-pop": "Budete moci obnovit tablo kliknutím na tlačítko \"Archiv\" v hlavním menu.", "color-black": "černá", "color-blue": "modrá", "color-crimson": "crimson", @@ -195,7 +195,7 @@ "color-slateblue": "slateblue", "color-white": "bílá", "color-yellow": "žlutá", - "unset-color": "Unset", + "unset-color": "Nenastaveno", "comment": "Komentář", "comment-placeholder": "Text komentáře", "comment-only": "Pouze komentáře", @@ -335,7 +335,7 @@ "leaveBoardPopup-title": "Opustit tablo?", "link-card": "Odkázat na tuto kartu", "list-archive-cards": "Přesunout všechny karty v tomto seznamu do archivu.", - "list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Archive and bring them back to the board, click “Menu” > “Archive”.", + "list-archive-cards-pop": "Toto odstraní z tabla všechny karty z tohoto seznamu. Pro zobrazení karet v Archivu a jejich opětovné obnovení, klikni v \"Menu\" > \"Archiv\".", "list-move-cards": "Přesunout všechny karty v tomto sloupci", "list-select-cards": "Vybrat všechny karty v tomto sloupci", "set-color-list": "Nastavit barvu", @@ -660,7 +660,7 @@ "authentication-method": "Metoda autentizace", "authentication-type": "Typ autentizace", "custom-product-name": "Vlastní název produktu", - "layout": "uspořádání", + "layout": "Uspořádání", "hide-logo": "Skrýt logo", "add-custom-html-after-body-start": "Přidej vlastní HTML za ", "add-custom-html-before-body-end": "Přidej vlastní HTML před ", diff --git a/i18n/de.i18n.json b/i18n/de.i18n.json index e6a3d97e8..39188c0a5 100644 --- a/i18n/de.i18n.json +++ b/i18n/de.i18n.json @@ -92,8 +92,8 @@ "restore-board": "Board wiederherstellen", "no-archived-boards": "Keine Boards im Archiv.", "archives": "Archiv", - "template": "Template", - "templates": "Templates", + "template": "Vorlage", + "templates": "Vorlagen", "assign-member": "Mitglied zuweisen", "attached": "angehängt", "attachment": "Anhang", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Labels", "cardMembersPopup-title": "Mitglieder", "cardMorePopup-title": "Mehr", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Vorlage erstellen", "cards": "Karten", "cards-count": "Karten", "casSignIn": "Mit CAS anmelden", @@ -456,9 +456,9 @@ "welcome-swimlane": "Meilenstein 1", "welcome-list1": "Grundlagen", "welcome-list2": "Fortgeschritten", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "Kartenvorlagen", + "list-templates-swimlane": "Listenvorlagen", + "board-templates-swimlane": "Boardvorlagen", "what-to-do": "Was wollen Sie tun?", "wipLimitErrorPopup-title": "Ungültiges WIP-Limit", "wipLimitErrorPopup-dialog-pt1": "Die Anzahl von Aufgaben in dieser Liste ist größer als das von Ihnen definierte WIP-Limit.", diff --git a/i18n/es.i18n.json b/i18n/es.i18n.json index f17edd865..ac3fd36ef 100644 --- a/i18n/es.i18n.json +++ b/i18n/es.i18n.json @@ -92,8 +92,8 @@ "restore-board": "Restaurar el tablero", "no-archived-boards": "No hay Tableros en el Archivo", "archives": "Archivar", - "template": "Template", - "templates": "Templates", + "template": "Plantilla", + "templates": "Plantillas", "assign-member": "Asignar miembros", "attached": "adjuntado", "attachment": "Adjunto", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Miembros", "cardMorePopup-title": "Más", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Crear plantilla", "cards": "Tarjetas", "cards-count": "Tarjetas", "casSignIn": "Iniciar sesión con CAS", @@ -456,9 +456,9 @@ "welcome-swimlane": "Hito 1", "welcome-list1": "Básicos", "welcome-list2": "Avanzados", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "Plantilla de tarjeta", + "list-templates-swimlane": "Listar plantillas", + "board-templates-swimlane": "Plantilla de tablero", "what-to-do": "¿Qué deseas hacer?", "wipLimitErrorPopup-title": "El límite del trabajo en proceso no es válido.", "wipLimitErrorPopup-dialog-pt1": "El número de tareas en esta lista es mayor que el límite del trabajo en proceso que has definido.", diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json index aa20a1edc..5c38a222b 100644 --- a/i18n/fr.i18n.json +++ b/i18n/fr.i18n.json @@ -92,8 +92,8 @@ "restore-board": "Restaurer le tableau", "no-archived-boards": "Aucun tableau archivé.", "archives": "Archiver", - "template": "Template", - "templates": "Templates", + "template": "Modèle", + "templates": "Modèles", "assign-member": "Affecter un membre", "attached": "joint", "attachment": "Pièce jointe", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Étiquettes", "cardMembersPopup-title": "Membres", "cardMorePopup-title": "Plus", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Créer un modèle", "cards": "Cartes", "cards-count": "Cartes", "casSignIn": "Se connecter avec CAS", @@ -456,9 +456,9 @@ "welcome-swimlane": "Jalon 1", "welcome-list1": "Basiques", "welcome-list2": "Avancés", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "Modèles de cartes", + "list-templates-swimlane": "Modèles de listes", + "board-templates-swimlane": "Modèles de tableaux", "what-to-do": "Que voulez-vous faire ?", "wipLimitErrorPopup-title": "Limite WIP invalide", "wipLimitErrorPopup-dialog-pt1": "Le nombre de cartes de cette liste est supérieur à la limite WIP que vous avez définie.", diff --git a/i18n/he.i18n.json b/i18n/he.i18n.json index 8d089d87b..81cc6210a 100644 --- a/i18n/he.i18n.json +++ b/i18n/he.i18n.json @@ -92,8 +92,8 @@ "restore-board": "שחזור לוח", "no-archived-boards": "לא נשמרו לוחות בארכיון.", "archives": "להעביר לארכיון", - "template": "Template", - "templates": "Templates", + "template": "תבנית", + "templates": "תבניות", "assign-member": "הקצאת חבר", "attached": "מצורף", "attachment": "קובץ מצורף", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "תוויות", "cardMembersPopup-title": "חברים", "cardMorePopup-title": "עוד", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "יצירת תבנית", "cards": "כרטיסים", "cards-count": "כרטיסים", "casSignIn": "כניסה עם CAS", @@ -456,9 +456,9 @@ "welcome-swimlane": "ציון דרך 1", "welcome-list1": "יסודות", "welcome-list2": "מתקדם", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "תבניות כרטיסים", + "list-templates-swimlane": "תבניות רשימות", + "board-templates-swimlane": "תבניות לוחות", "what-to-do": "מה ברצונך לעשות?", "wipLimitErrorPopup-title": "מגבלת „בעבודה” שגויה", "wipLimitErrorPopup-dialog-pt1": "מספר המשימות ברשימה זו גדולה ממגבלת הפריטים „בעבודה” שהגדרת.", diff --git a/i18n/it.i18n.json b/i18n/it.i18n.json index 6a5e97730..1133a436c 100644 --- a/i18n/it.i18n.json +++ b/i18n/it.i18n.json @@ -32,7 +32,7 @@ "activity-archived": "%s spostato nell'archivio", "activity-attached": "allegato %s a %s", "activity-created": "creato %s", - "activity-customfield-created": "Campo personalizzato creato", + "activity-customfield-created": "%s creato come campo personalizzato", "activity-excluded": "escluso %s da %s", "activity-imported": "importato %s in %s da %s", "activity-imported-board": "importato %s da %s", @@ -47,19 +47,19 @@ "activity-unchecked-item": "disattivato %s nella checklist %s di %s", "activity-checklist-added": "aggiunta checklist a %s", "activity-checklist-removed": "È stata rimossa una checklist da%s", - "activity-checklist-completed": "completed the checklist %s of %s", - "activity-checklist-uncompleted": "uncompleted the checklist %s of %s", + "activity-checklist-completed": "Completata la checklist %s di %s", + "activity-checklist-uncompleted": "La checklist non è stata completata", "activity-checklist-item-added": "Aggiunto l'elemento checklist a '%s' in %s", - "activity-checklist-item-removed": "removed a checklist item from '%s' in %s", + "activity-checklist-item-removed": "è stato rimosso un elemento della checklist da '%s' in %s", "add": "Aggiungere", - "activity-checked-item-card": "checked %s in checklist %s", - "activity-unchecked-item-card": "unchecked %s in checklist %s", - "activity-checklist-completed-card": "completed the checklist %s", - "activity-checklist-uncompleted-card": "uncompleted the checklist %s", + "activity-checked-item-card": "%s è stato selezionato nella checklist %s", + "activity-unchecked-item-card": "%s è stato deselezionato nella checklist %s", + "activity-checklist-completed-card": "completata la checklist %s", + "activity-checklist-uncompleted-card": "La checklist %s non è completa", "add-attachment": "Aggiungi Allegato", "add-board": "Aggiungi Bacheca", "add-card": "Aggiungi Scheda", - "add-swimlane": "Aggiungi Corsia", + "add-swimlane": "Aggiungi Diagramma Swimlane", "add-subtask": "Aggiungi sotto-compito", "add-checklist": "Aggiungi Checklist", "add-checklist-item": "Aggiungi un elemento alla checklist", @@ -78,19 +78,19 @@ "and-n-other-card": "E __count__ altra scheda", "and-n-other-card_plural": "E __count__ altre schede", "apply": "Applica", - "app-is-offline": "Loading, please wait. Refreshing the page will cause data loss. If loading does not work, please check that server has not stopped.", - "archive": "Move to Archive", - "archive-all": "Move All to Archive", - "archive-board": "Move Board to Archive", - "archive-card": "Move Card to Archive", - "archive-list": "Move List to Archive", - "archive-swimlane": "Move Swimlane to Archive", - "archive-selection": "Move selection to Archive", - "archiveBoardPopup-title": "Move Board to Archive?", + "app-is-offline": "Caricamento, attendere prego. Aggiornare la pagina porterà ad una perdita dei dati. Se il caricamento non dovesse funzionare, per favore controlla che il server non sia stato fermato.", + "archive": "Sposta nell'Archivio", + "archive-all": "Sposta tutto nell'Archivio", + "archive-board": "Sposta la bacheca nell'Archivio", + "archive-card": "Sposta la scheda nell'Archivio", + "archive-list": "Sposta elenco nell'Archivio", + "archive-swimlane": "Sposta diagramma nell'Archivio", + "archive-selection": "Sposta la selezione nell'archivio", + "archiveBoardPopup-title": "Spostare al bacheca nell'archivio?", "archived-items": "Archivia", - "archived-boards": "Boards in Archive", + "archived-boards": "Bacheche nell'archivio", "restore-board": "Ripristina Bacheca", - "no-archived-boards": "No Boards in Archive.", + "no-archived-boards": "Nessuna bacheca presente nell'archivio", "archives": "Archivia", "template": "Template", "templates": "Templates", @@ -116,16 +116,16 @@ "boards": "Bacheche", "board-view": "Visualizza bacheca", "board-view-cal": "Calendario", - "board-view-swimlanes": "Corsie", + "board-view-swimlanes": "Diagramma Swimlane", "board-view-lists": "Liste", "bucket-example": "Per esempio come \"una lista di cose da fare\"", "cancel": "Cancella", - "card-archived": "This card is moved to Archive.", - "board-archived": "This board is moved to Archive.", + "card-archived": "Questa scheda è stata spostata nell'archivio", + "board-archived": "Questa bacheca è stata spostata nell'archivio", "card-comments-title": "Questa scheda ha %s commenti.", "card-delete-notice": "L'eliminazione è permanente. Tutte le azioni associate a questa scheda andranno perse.", "card-delete-pop": "Tutte le azioni saranno rimosse dal flusso attività e non sarai in grado di riaprire la scheda. Non potrai tornare indietro.", - "card-delete-suggest-archive": "You can move a card to Archive to remove it from the board and preserve the activity.", + "card-delete-suggest-archive": "Puoi spostare una scheda nell'archivio per rimuoverla dalla bacheca e mantenere la sua attività", "card-due": "Scadenza", "card-due-on": "Scade", "card-spent": "Tempo trascorso", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Etichette", "cardMembersPopup-title": "Membri", "cardMorePopup-title": "Altro", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Crea un template", "cards": "Schede", "cards-count": "Schede", "casSignIn": "Entra con CAS", @@ -169,33 +169,33 @@ "clipboard": "Clipboard o drag & drop", "close": "Chiudi", "close-board": "Chiudi bacheca", - "close-board-pop": "You will be able to restore the board by clicking the “Archive” button from the home header.", + "close-board-pop": "Potrai ripristinare la bacheca cliccando sul tasto \"Archivio\" presente nell'intestazione della home.", "color-black": "nero", "color-blue": "blu", - "color-crimson": "crimson", - "color-darkgreen": "darkgreen", - "color-gold": "gold", - "color-gray": "gray", + "color-crimson": "Rosso cremisi", + "color-darkgreen": "Verde scuro", + "color-gold": "Dorato", + "color-gray": "Grigio", "color-green": "verde", - "color-indigo": "indigo", + "color-indigo": "Indaco", "color-lime": "lime", - "color-magenta": "magenta", - "color-mistyrose": "mistyrose", - "color-navy": "navy", + "color-magenta": "Magenta", + "color-mistyrose": "Mistyrose", + "color-navy": "Navy", "color-orange": "arancione", - "color-paleturquoise": "paleturquoise", - "color-peachpuff": "peachpuff", + "color-paleturquoise": "Turchese chiaro", + "color-peachpuff": "Pesca", "color-pink": "rosa", - "color-plum": "plum", + "color-plum": "Prugna", "color-purple": "viola", "color-red": "rosso", - "color-saddlebrown": "saddlebrown", - "color-silver": "silver", + "color-saddlebrown": "Saddlebrown", + "color-silver": "Argento", "color-sky": "azzurro", - "color-slateblue": "slateblue", - "color-white": "white", + "color-slateblue": "Ardesia", + "color-white": "Bianco", "color-yellow": "giallo", - "unset-color": "Unset", + "unset-color": "Non impostato", "comment": "Commento", "comment-placeholder": "Scrivi Commento", "comment-only": "Solo commenti", @@ -223,7 +223,7 @@ "custom-field-checkbox": "Casella di scelta", "custom-field-date": "Data", "custom-field-dropdown": "Lista a discesa", - "custom-field-dropdown-none": "(nessun)", + "custom-field-dropdown-none": "(niente)", "custom-field-dropdown-options": "Lista opzioni", "custom-field-dropdown-options-placeholder": "Premi invio per aggiungere altre opzioni", "custom-field-dropdown-unknown": "(sconosciuto)", @@ -302,20 +302,20 @@ "import-board": "Importa bacheca", "import-board-c": "Importa bacheca", "import-board-title-trello": "Importa una bacheca da Trello", - "import-board-title-wekan": "Import board from previous export", - "import-sandstorm-backup-warning": "Do not delete data you import from original exported board or Trello before checking does this grain close and open again, or do you get Board not found error, that means data loss.", + "import-board-title-wekan": "Importa bacheca dall'esportazione precedente", + "import-sandstorm-backup-warning": "Non cancellare i dati che importi dalla bacheca esportata in origine o da Trello prima che il controllo finisca e si riapra ancora, altrimenti otterrai un messaggio di errore Bacheca non trovata, che significa che i dati sono perduti.", "import-sandstorm-warning": "La bacheca importata cancellerà tutti i dati esistenti su questa bacheca e li rimpiazzerà con quelli della bacheca importata.", "from-trello": "Da Trello", - "from-wekan": "From previous export", + "from-wekan": "Dall'esportazione precedente", "import-board-instruction-trello": "Nella tua bacheca Trello vai a 'Menu', poi 'Altro', 'Stampa ed esporta', 'Esporta JSON', e copia il testo che compare.", - "import-board-instruction-wekan": "In your board, go to 'Menu', then 'Export board', and copy the text in the downloaded file.", - "import-board-instruction-about-errors": "If you get errors when importing board, sometimes importing still works, and board is at All Boards page.", + "import-board-instruction-wekan": "Nella tua bacheca vai su \"Menu\", poi \"Esporta la bacheca\", e copia il testo nel file scaricato", + "import-board-instruction-about-errors": "Se hai degli errori quando importi una bacheca, qualche volta l'importazione funziona comunque, e la bacheca si trova nella pagina \"Tutte le bacheche\"", "import-json-placeholder": "Incolla un JSON valido qui", "import-map-members": "Mappatura dei membri", - "import-members-map": "Your imported board has some members. Please map the members you want to import to your users", + "import-members-map": "La bacheca che hai importato contiene alcuni membri. Per favore scegli i membri che vuoi importare tra i tuoi utenti", "import-show-user-mapping": "Rivedi la mappatura dei membri", - "import-user-select": "Pick your existing user you want to use as this member", - "importMapMembersAddPopup-title": "Select member", + "import-user-select": "Scegli l'utente che vuoi venga utilizzato come questo membro", + "importMapMembersAddPopup-title": "Scegli membro", "info": "Versione", "initials": "Iniziali", "invalid-date": "Data non valida", @@ -334,21 +334,21 @@ "leave-board-pop": "Sei sicuro di voler abbandonare __boardTitle__? Sarai rimosso da tutte le schede in questa bacheca.", "leaveBoardPopup-title": "Abbandona Bacheca?", "link-card": "Link a questa scheda", - "list-archive-cards": "Move all cards in this list to Archive", - "list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Archive and bring them back to the board, click “Menu” > “Archive”.", + "list-archive-cards": "Sposta tutte le schede in questo elenco nell'Archivio", + "list-archive-cards-pop": "Questo rimuoverà tutte le schede nell'elenco dalla bacheca. Per vedere le schede nell'archivio e portarle dov'erano nella bacheca, clicca su \"Menu\" > \"Archivio\". ", "list-move-cards": "Sposta tutte le schede in questa lista", "list-select-cards": "Selezione tutte le schede in questa lista", - "set-color-list": "Set Color", + "set-color-list": "Imposta un colore", "listActionPopup-title": "Azioni disponibili", - "swimlaneActionPopup-title": "Azioni corsia", - "swimlaneAddPopup-title": "Add a Swimlane below", + "swimlaneActionPopup-title": "Azioni diagramma Swimlane", + "swimlaneAddPopup-title": "Aggiungi un diagramma Swimlane di seguito", "listImportCardPopup-title": "Importa una scheda di Trello", "listMorePopup-title": "Altro", "link-list": "Link a questa lista", "list-delete-pop": "Tutte le azioni saranno rimosse dal flusso attività e non sarai in grado di recuperare la lista. Non potrai tornare indietro.", - "list-delete-suggest-archive": "You can move a list to Archive to remove it from the board and preserve the activity.", + "list-delete-suggest-archive": "Puoi spostare un elenco nell'archivio per rimuoverlo dalla bacheca e mantentere la sua attività.", "lists": "Liste", - "swimlanes": "Corsie", + "swimlanes": "Diagramma Swimlane", "log-out": "Log Out", "log-in": "Log In", "loginPopup-title": "Log In", @@ -366,9 +366,9 @@ "muted-info": "Non sarai mai notificato delle modifiche in questa bacheca", "my-boards": "Le mie bacheche", "name": "Nome", - "no-archived-cards": "No cards in Archive.", - "no-archived-lists": "No lists in Archive.", - "no-archived-swimlanes": "No swimlanes in Archive.", + "no-archived-cards": "Non ci sono schede nell'archivio.", + "no-archived-lists": "Non ci sono elenchi nell'archivio.", + "no-archived-swimlanes": "Non ci sono diagrammi Swimlane nell'archivio.", "no-results": "Nessun risultato", "normal": "Normale", "normal-desc": "Può visionare e modificare le schede. Non può cambiare le impostazioni.", @@ -404,7 +404,7 @@ "restore": "Ripristina", "save": "Salva", "search": "Cerca", - "rules": "Rules", + "rules": "Regole", "search-cards": "Ricerca per titolo e descrizione scheda su questa bacheca", "search-example": "Testo da ricercare?", "select-color": "Seleziona Colore", @@ -448,7 +448,7 @@ "uploaded-avatar": "Avatar caricato", "username": "Username", "view-it": "Vedi", - "warn-list-archived": "warning: this card is in an list at Archive", + "warn-list-archived": "Attenzione:questa scheda si trova in un elenco dell'archivio", "watch": "Segui", "watching": "Stai seguendo", "watching-info": "Sarai notificato per tutte le modifiche in questa bacheca", @@ -456,9 +456,9 @@ "welcome-swimlane": "Pietra miliare 1", "welcome-list1": "Basi", "welcome-list2": "Avanzate", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "Template scheda", + "list-templates-swimlane": "Elenca i template", + "board-templates-swimlane": "Bacheca dei template", "what-to-do": "Cosa vuoi fare?", "wipLimitErrorPopup-title": "Limite work in progress non valido. ", "wipLimitErrorPopup-dialog-pt1": "Il numero di compiti in questa lista è maggiore del limite di work in progress che hai definito in precedenza. ", @@ -470,7 +470,7 @@ "disable-self-registration": "Disabilita Auto-registrazione", "invite": "Invita", "invite-people": "Invita persone", - "to-boards": "Alla(e) bacheche(a)", + "to-boards": "Alla(e) bacheca", "email-addresses": "Indirizzi email", "smtp-host-description": "L'indirizzo del server SMTP che gestisce le tue email.", "smtp-port-description": "La porta che il tuo server SMTP utilizza per le email in uscita.", @@ -484,14 +484,14 @@ "send-smtp-test": "Invia un'email di test a te stesso", "invitation-code": "Codice d'invito", "email-invite-register-subject": "__inviter__ ti ha inviato un invito", - "email-invite-register-text": "Dear __user__,\n\n__inviter__ invites you to kanban board for collaborations.\n\nPlease follow the link below:\n__url__\n\nAnd your invitation code is: __icode__\n\nThanks.", - "email-smtp-test-subject": "SMTP Test Email", + "email-invite-register-text": "Gentile __user__,\n\n__inviter__ ti ha invitato a partecipare a questa bacheca kanban per collaborare.\n\nPer favore segui il collegamento qui sotto:\n__url__\n\nIl tuo codice di invito è: __icode__\n\nGrazie.", + "email-smtp-test-subject": "E-Mail di prova SMTP", "email-smtp-test-text": "Hai inviato un'email con successo", "error-invitation-code-not-exist": "Il codice d'invito non esiste", "error-notAuthorized": "Non sei autorizzato ad accedere a questa pagina.", "outgoing-webhooks": "Server esterni", "outgoingWebhooksPopup-title": "Server esterni", - "boardCardTitlePopup-title": "Card Title Filter", + "boardCardTitlePopup-title": "Filtro per Titolo Scheda", "new-outgoing-webhook": "Nuovo webhook in uscita", "no-name": "(Sconosciuto)", "Node_version": "Versione di Node", @@ -504,13 +504,13 @@ "OS_Totalmem": "Memoria totale del sistema operativo ", "OS_Type": "Tipo di sistema operativo ", "OS_Uptime": "Tempo di attività del sistema operativo. ", - "days": "days", + "days": "giorni", "hours": "ore", "minutes": "minuti", "seconds": "secondi", "show-field-on-card": "Visualizza questo campo sulla scheda", - "automatically-field-on-card": "Auto create field to all cards", - "showLabel-field-on-card": "Show field label on minicard", + "automatically-field-on-card": "Crea automaticamente i campi per tutte le schede", + "showLabel-field-on-card": "Mostra l'etichetta di campo su minischeda", "yes": "Sì", "no": "No", "accounts": "Profili", @@ -525,10 +525,10 @@ "card-end-on": "Termina il", "editCardReceivedDatePopup-title": "Cambia data ricezione", "editCardEndDatePopup-title": "Cambia data finale", - "setCardColorPopup-title": "Set color", - "setCardActionsColorPopup-title": "Choose a color", - "setSwimlaneColorPopup-title": "Choose a color", - "setListColorPopup-title": "Choose a color", + "setCardColorPopup-title": "Imposta il colore", + "setCardActionsColorPopup-title": "Scegli un colore", + "setSwimlaneColorPopup-title": "Scegli un colore", + "setListColorPopup-title": "Scegli un colore", "assigned-by": "Assegnato da", "requested-by": "Richiesto da", "board-delete-notice": "L'eliminazione è permanente. Tutte le azioni, liste e schede associate a questa bacheca andranno perse.", @@ -552,89 +552,89 @@ "parent-card": "Scheda genitore", "source-board": "Bacheca d'origine", "no-parent": "Non mostrare i genitori", - "activity-added-label": "added label '%s' to %s", - "activity-removed-label": "removed label '%s' from %s", - "activity-delete-attach": "deleted an attachment from %s", + "activity-added-label": "L' etichetta '%s' è stata aggiunta a %s", + "activity-removed-label": "L'etichetta '%s' è stata rimossa da %s", + "activity-delete-attach": "Rimosso un allegato da %s", "activity-added-label-card": "aggiunta etichetta '%s'", - "activity-removed-label-card": "removed label '%s'", + "activity-removed-label-card": "L' etichetta '%s' è stata rimossa.", "activity-delete-attach-card": "Cancella un allegato", "r-rule": "Ruolo", "r-add-trigger": "Aggiungi trigger", "r-add-action": "Aggiungi azione", - "r-board-rules": "Regole del cruscotto", + "r-board-rules": "Regole della bacheca", "r-add-rule": "Aggiungi regola", "r-view-rule": "Visualizza regola", "r-delete-rule": "Cancella regola", "r-new-rule-name": "Titolo nuova regola", "r-no-rules": "Nessuna regola", - "r-when-a-card": "When a card", - "r-is": "is", - "r-is-moved": "is moved", - "r-added-to": "added to", + "r-when-a-card": "Quando una scheda", + "r-is": "è", + "r-is-moved": "viene spostata", + "r-added-to": "Aggiunto/a a ", "r-removed-from": "Rimosso da", - "r-the-board": "Il cruscotto", + "r-the-board": "La bacheca", "r-list": "lista", - "set-filter": "Set Filter", - "r-moved-to": "Moved to", - "r-moved-from": "Moved from", - "r-archived": "Moved to Archive", - "r-unarchived": "Restored from Archive", - "r-a-card": "a card", - "r-when-a-label-is": "When a label is", - "r-when-the-label-is": "When the label is", - "r-list-name": "list name", - "r-when-a-member": "When a member is", - "r-when-the-member": "When the member", - "r-name": "name", - "r-when-a-attach": "When an attachment", - "r-when-a-checklist": "When a checklist is", - "r-when-the-checklist": "When the checklist", - "r-completed": "Completed", - "r-made-incomplete": "Made incomplete", - "r-when-a-item": "When a checklist item is", - "r-when-the-item": "When the checklist item", - "r-checked": "Checked", - "r-unchecked": "Unchecked", - "r-move-card-to": "Move card to", - "r-top-of": "Top of", - "r-bottom-of": "Bottom of", - "r-its-list": "its list", - "r-archive": "Move to Archive", - "r-unarchive": "Restore from Archive", - "r-card": "card", + "set-filter": "Imposta un filtro", + "r-moved-to": "Spostato/a a ", + "r-moved-from": "Spostato/a da", + "r-archived": "Spostato/a nell'archivio", + "r-unarchived": "Ripristinato/a dall'archivio", + "r-a-card": "una scheda", + "r-when-a-label-is": "Quando un'etichetta viene", + "r-when-the-label-is": "Quando l'etichetta viene", + "r-list-name": "Nome dell'elenco", + "r-when-a-member": "Quando un membro viene", + "r-when-the-member": "Quando un membro viene", + "r-name": "nome", + "r-when-a-attach": "Quando un allegato", + "r-when-a-checklist": "Quando una checklist è", + "r-when-the-checklist": "Quando la checklist", + "r-completed": "Completato/a", + "r-made-incomplete": "Rendi incompleto", + "r-when-a-item": "Quando un elemento della checklist è", + "r-when-the-item": "Quando un elemento della checklist", + "r-checked": "Selezionato", + "r-unchecked": "Deselezionato", + "r-move-card-to": "Sposta scheda a", + "r-top-of": "Al di sopra di", + "r-bottom-of": "Al di sotto di", + "r-its-list": "il suo elenco", + "r-archive": "Sposta nell'Archivio", + "r-unarchive": "Ripristina dall'archivio", + "r-card": "scheda", "r-add": "Aggiungere", - "r-remove": "Remove", - "r-label": "label", - "r-member": "member", - "r-remove-all": "Remove all members from the card", - "r-set-color": "Set color to", + "r-remove": "Rimuovi", + "r-label": "etichetta", + "r-member": "membro", + "r-remove-all": "Rimuovi tutti i membri dalla scheda", + "r-set-color": "Imposta il colore a", "r-checklist": "checklist", - "r-check-all": "Check all", - "r-uncheck-all": "Uncheck all", - "r-items-check": "items of checklist", - "r-check": "Check", - "r-uncheck": "Uncheck", - "r-item": "item", + "r-check-all": "Spunta tutti", + "r-uncheck-all": "Togli la spunta a tutti", + "r-items-check": "Elementi della checklist", + "r-check": "Spunta", + "r-uncheck": "Togli la spunta", + "r-item": "elemento", "r-of-checklist": "della lista di cose da fare", - "r-send-email": "Send an email", - "r-to": "to", + "r-send-email": "Invia un e-mail", + "r-to": "a", "r-subject": "soggetto", - "r-rule-details": "Rule details", - "r-d-move-to-top-gen": "Move card to top of its list", - "r-d-move-to-top-spec": "Move card to top of list", + "r-rule-details": "Dettagli della regola", + "r-d-move-to-top-gen": "Sposta la scheda al di sopra del suo elenco", + "r-d-move-to-top-spec": "Sposta la scheda la di sopra dell'elenco", "r-d-move-to-bottom-gen": "Sposta la scheda in fondo alla sua lista", "r-d-move-to-bottom-spec": "Muovi la scheda in fondo alla lista", "r-d-send-email": "Spedisci email", - "r-d-send-email-to": "to", + "r-d-send-email-to": "a", "r-d-send-email-subject": "soggetto", "r-d-send-email-message": "Messaggio", - "r-d-archive": "Move card to Archive", - "r-d-unarchive": "Restore card from Archive", + "r-d-archive": "Sposta la scheda nell'archivio", + "r-d-unarchive": "Ripristina la scheda dall'archivio", "r-d-add-label": "Aggiungi etichetta", "r-d-remove-label": "Rimuovi Etichetta", - "r-create-card": "Create new card", - "r-in-list": "in list", - "r-in-swimlane": "in swimlane", + "r-create-card": "Crea una nuova scheda", + "r-in-list": "in elenco", + "r-in-swimlane": "nel diagramma swimlane", "r-d-add-member": "Aggiungi membro", "r-d-remove-member": "Rimuovi membro", "r-d-remove-all-member": "Rimouvi tutti i membri", @@ -645,27 +645,27 @@ "r-d-check-of-list": "della lista di cose da fare", "r-d-add-checklist": "Aggiungi lista di cose da fare", "r-d-remove-checklist": "Rimuovi check list", - "r-by": "by", + "r-by": "da", "r-add-checklist": "Aggiungi lista di cose da fare", - "r-with-items": "with items", - "r-items-list": "item1,item2,item3", - "r-add-swimlane": "Add swimlane", - "r-swimlane-name": "swimlane name", - "r-board-note": "Note: leave a field empty to match every possible value.", - "r-checklist-note": "Note: checklist's items have to be written as comma separated values.", + "r-with-items": "con elementi", + "r-items-list": "elemento1,elemento2,elemento3", + "r-add-swimlane": "Aggiungi un diagramma swimlane", + "r-swimlane-name": "Nome diagramma swimlane", + "r-board-note": "Nota: Lascia un campo vuoto per abbinare ogni possibile valore", + "r-checklist-note": "Nota: Gli elementi della checklist devono essere scritti come valori separati dalla virgola", "r-when-a-card-is-moved": "Quando una scheda viene spostata su un'altra lista", "ldap": "LDAP", "oauth2": "Oauth2", "cas": "CAS", "authentication-method": "Metodo di Autenticazione", "authentication-type": "Tipo Autenticazione", - "custom-product-name": "Custom Product Name", + "custom-product-name": "Personalizza il nome del prodotto", "layout": "Layout", - "hide-logo": "Hide Logo", - "add-custom-html-after-body-start": "Add Custom HTML after start", - "add-custom-html-before-body-end": "Add Custom HTML before end", - "error-undefined": "Something went wrong", - "error-ldap-login": "An error occurred while trying to login", - "display-authentication-method": "Display Authentication Method", - "default-authentication-method": "Default Authentication Method" + "hide-logo": "Nascondi il logo", + "add-custom-html-after-body-start": "Aggiungi codice HTML personalizzato dopo inzio", + "add-custom-html-before-body-end": "Aggiunti il codice HTML prima di fine", + "error-undefined": "Qualcosa è andato storto", + "error-ldap-login": "C'è stato un errore mentre provavi ad effettuare il login", + "display-authentication-method": "Mostra il metodo di autenticazione", + "default-authentication-method": "Metodo di autenticazione predefinito" } \ No newline at end of file diff --git a/i18n/pt-BR.i18n.json b/i18n/pt-BR.i18n.json index d15353e9f..5f677275d 100644 --- a/i18n/pt-BR.i18n.json +++ b/i18n/pt-BR.i18n.json @@ -92,8 +92,8 @@ "restore-board": "Restaurar Quadro", "no-archived-boards": "Sem Quadros no Arquivo-morto.", "archives": "Arquivos-morto", - "template": "Template", - "templates": "Templates", + "template": "Modelo", + "templates": "Modelos", "assign-member": "Atribuir Membro", "attached": "anexado", "attachment": "Anexo", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Etiquetas", "cardMembersPopup-title": "Membros", "cardMorePopup-title": "Mais", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Criar Modelo", "cards": "Cartões", "cards-count": "Cartões", "casSignIn": "Entrar com CAS", @@ -456,9 +456,9 @@ "welcome-swimlane": "Marco 1", "welcome-list1": "Básico", "welcome-list2": "Avançado", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "Modelos de cartão", + "list-templates-swimlane": "Modelos de lista", + "board-templates-swimlane": "Modelos de quadro", "what-to-do": "O que você gostaria de fazer?", "wipLimitErrorPopup-title": "Limite WIP Inválido", "wipLimitErrorPopup-dialog-pt1": "O número de tarefas nesta lista excede o limite WIP definido.", diff --git a/i18n/zh-CN.i18n.json b/i18n/zh-CN.i18n.json index 7fd127df0..7c68f2cc8 100644 --- a/i18n/zh-CN.i18n.json +++ b/i18n/zh-CN.i18n.json @@ -92,8 +92,8 @@ "restore-board": "还原看板", "no-archived-boards": "没有归档的看板。", "archives": "归档", - "template": "Template", - "templates": "Templates", + "template": "模板", + "templates": "模板", "assign-member": "分配成员", "attached": "附加", "attachment": "附件", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "标签", "cardMembersPopup-title": "成员", "cardMorePopup-title": "更多", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "新建模板", "cards": "卡片", "cards-count": "卡片", "casSignIn": "用CAS登录", @@ -456,9 +456,9 @@ "welcome-swimlane": "里程碑 1", "welcome-list1": "基本", "welcome-list2": "高阶", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "卡片模板", + "list-templates-swimlane": "列表模板", + "board-templates-swimlane": "看板模板", "what-to-do": "要做什么?", "wipLimitErrorPopup-title": "无效的最大任务数", "wipLimitErrorPopup-dialog-pt1": "此列表中的任务数量已经超过了设置的最大任务数。", From a7071291468f1b3b99d13691b6c088f00069896f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 26 Feb 2019 16:51:24 +0200 Subject: [PATCH 16/19] Removed console.log. --- client/components/lists/listBody.js | 1 - 1 file changed, 1 deletion(-) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 5a3862f3d..04c7eede8 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -571,7 +571,6 @@ BlazeComponent.extendComponent({ }, boards() { - console.log('booom'); const boards = Boards.find({ archived: false, 'members.userId': Meteor.userId(), From 6ee75fbdbaef7b3d465639060e34c48f7c275c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Wed, 27 Feb 2019 19:33:54 +0100 Subject: [PATCH 17/19] Fix templates board not found --- models/users.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/users.js b/models/users.js index 7152d133b..0dd9c1d67 100644 --- a/models/users.js +++ b/models/users.js @@ -711,7 +711,6 @@ if (Meteor.isServer) { CollectionHooks.getUserId = () => { return fakeUserId.get() || getUserId(); }; - /* if (!isSandstorm) { Users.after.insert((userId, doc) => { const fakeUser = { @@ -721,6 +720,7 @@ if (Meteor.isServer) { }; fakeUserId.withValue(doc._id, () => { + /* // Insert the Welcome Board Boards.insert({ title: TAPi18n.__('welcome-board'), @@ -737,6 +737,7 @@ if (Meteor.isServer) { Lists.insert({title: TAPi18n.__(title), boardId, sort: titleIndex}, fakeUser); }); }); + */ Boards.insert({ title: TAPi18n.__('templates'), @@ -786,7 +787,6 @@ if (Meteor.isServer) { }); }); } - */ Users.after.insert((userId, doc) => { From d21aa97219d00dae22cc3ffb23b13f0807c589b0 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 27 Feb 2019 20:39:56 +0200 Subject: [PATCH 18/19] Update translations. --- i18n/ru.i18n.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/i18n/ru.i18n.json b/i18n/ru.i18n.json index 6fde47f97..082cc0069 100644 --- a/i18n/ru.i18n.json +++ b/i18n/ru.i18n.json @@ -92,8 +92,8 @@ "restore-board": "Востановить доску", "no-archived-boards": "Нет досок в архиве.", "archives": "Архив", - "template": "Template", - "templates": "Templates", + "template": "Шаблон", + "templates": "Шаблоны", "assign-member": "Назначить участника", "attached": "прикреплено", "attachment": "Вложение", @@ -145,7 +145,7 @@ "cardLabelsPopup-title": "Метки", "cardMembersPopup-title": "Участники", "cardMorePopup-title": "Поделиться", - "cardTemplatePopup-title": "Create template", + "cardTemplatePopup-title": "Создать шаблон", "cards": "Карточки", "cards-count": "Карточки", "casSignIn": "Войти через CAS", @@ -456,9 +456,9 @@ "welcome-swimlane": "Этап 1", "welcome-list1": "Основы", "welcome-list2": "Расширенно", - "card-templates-swimlane": "Card Templates", - "list-templates-swimlane": "List Templates", - "board-templates-swimlane": "Board Templates", + "card-templates-swimlane": "Шаблоны карточек", + "list-templates-swimlane": "Шаблоны списков", + "board-templates-swimlane": "Шаблоны досок", "what-to-do": "Что вы хотите сделать?", "wipLimitErrorPopup-title": "Некорректный лимит на кол-во задач", "wipLimitErrorPopup-dialog-pt1": "Количество задач в этом списке превышает установленный вами лимит", From 904b5bf0f5f6e36131bf2d081a5d08fef408ac81 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 27 Feb 2019 21:01:32 +0200 Subject: [PATCH 19/19] v2.29 --- CHANGELOG.md | 7 +++++++ Stackerfile.yml | 2 +- package.json | 2 +- sandstorm-pkgdef.capnp | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f105915fa..f87199c19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v2.29 2019-02-27 Wekan release + +This release adds the following new features: + +- Swimlane/List/Board/Card templates. In Progress, please test and [add comment if you find not listed bugs](https://github.com/wekan/wekan/issues/2165). + Thanks to GitHub user andresmanelli. + # v2.28 2019-02-27 Wekan release This release adds the following new Sandstorm features and fixes: diff --git a/Stackerfile.yml b/Stackerfile.yml index 294bdb9a3..031953fef 100644 --- a/Stackerfile.yml +++ b/Stackerfile.yml @@ -1,5 +1,5 @@ appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928 -appVersion: "v2.28.0" +appVersion: "v2.29.0" files: userUploads: - README.md diff --git a/package.json b/package.json index 22b394a23..300a52a05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wekan", - "version": "v2.28.0", + "version": "v2.29.0", "description": "Open-Source kanban", "private": true, "scripts": { diff --git a/sandstorm-pkgdef.capnp b/sandstorm-pkgdef.capnp index 11cf0c31e..0d7064c5c 100644 --- a/sandstorm-pkgdef.capnp +++ b/sandstorm-pkgdef.capnp @@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = ( appTitle = (defaultText = "Wekan"), # The name of the app as it is displayed to the user. - appVersion = 230, + appVersion = 231, # Increment this for every release. - appMarketingVersion = (defaultText = "2.28.0~2019-02-27"), + appMarketingVersion = (defaultText = "2.29.0~2019-02-27"), # Human-readable presentation of the app version. minUpgradableAppVersion = 0,