From 40a3267615d34b011acbf19d6706a85d98e2e8fb Mon Sep 17 00:00:00 2001 From: Ole Langbehn Date: Sat, 16 Mar 2019 14:25:04 +0100 Subject: make emails for invitations all lowercase for compatibility with AccountsTemplates Email addresses for invitations are stored case sensitive in mongo, together with the invitation codes. When someone tries to sign up due to an invitation, in the sign up form, due to AccountsTemplates defaults, the email address is lowercased on blur of the textbox. When they then try to sign in, they get an error about the invitation code not existing. This makes it impossible to successfully invite people using non-lowercased email addresses. This patch lowercases the emails on the client side when inviting them. Other possibilities would be to lowercase them on the server side before storing them to mongodb, making a case insensitive search on mongodb, or making the email input field in the sign up form not lowercase the email string. This patch was chosen in favor of the other possibilities because of its simplicity. --- client/components/settings/settingBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index 2f58d551..8279a092 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -90,7 +90,7 @@ BlazeComponent.extendComponent({ }, inviteThroughEmail() { - const emails = $('#email-to-invite').val().trim().split('\n').join(',').split(','); + const emails = $('#email-to-invite').val().toLowerCase().trim().split('\n').join(',').split(','); const boardsToInvite = []; $('.js-toggle-board-choose .materialCheckBox.is-checked').each(function () { boardsToInvite.push($(this).data('id')); -- cgit v1.2.3-1-g7c22 From 4cd0d1c3971f001eccf023bb84f1bee113fed215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Fri, 8 Mar 2019 23:39:33 +0100 Subject: Migrate customFields --- client/components/sidebar/sidebarCustomFields.js | 5 +++-- models/cards.js | 2 +- models/customFields.js | 10 +++++----- models/export.js | 2 +- server/migrations.js | 13 +++++++++++++ server/publications/boards.js | 2 +- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/client/components/sidebar/sidebarCustomFields.js b/client/components/sidebar/sidebarCustomFields.js index ccc8ffb9..bdd8e7a0 100644 --- a/client/components/sidebar/sidebarCustomFields.js +++ b/client/components/sidebar/sidebarCustomFields.js @@ -2,7 +2,7 @@ BlazeComponent.extendComponent({ customFields() { return CustomFields.find({ - boardId: Session.get('currentBoard'), + boardIds: {$in: [Session.get('currentBoard')]}, }); }, @@ -103,7 +103,6 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ evt.preventDefault(); const data = { - boardId: Session.get('currentBoard'), name: this.find('.js-field-name').value.trim(), type: this.type.get(), settings: this.getSettings(), @@ -114,8 +113,10 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ // insert or update if (!this.data()._id) { + data.boardIds = [Session.get('currentBoard')]; CustomFields.insert(data); } else { + data.boardIds = {$in: [Session.get('currentBoard')]}; CustomFields.update(this.data()._id, {$set: data}); } diff --git a/models/cards.js b/models/cards.js index c3bae400..2caecb46 100644 --- a/models/cards.js +++ b/models/cards.js @@ -476,7 +476,7 @@ Cards.helpers({ // get all definitions const definitions = CustomFields.find({ - boardId: this.boardId, + boardIds: {$in: [this.boardId]}, }).fetch(); // match right definition to each field diff --git a/models/customFields.js b/models/customFields.js index b7ad5467..79f96708 100644 --- a/models/customFields.js +++ b/models/customFields.js @@ -4,11 +4,11 @@ CustomFields = new Mongo.Collection('customFields'); * A custom field on a card in the board */ CustomFields.attachSchema(new SimpleSchema({ - boardId: { + boardIds: { /** * the ID of the board */ - type: String, + type: [String], }, name: { /** @@ -135,7 +135,7 @@ if (Meteor.isServer) { const paramBoardId = req.params.boardId; JsonRoutes.sendResult(res, { code: 200, - data: CustomFields.find({ boardId: paramBoardId }).map(function (cf) { + data: CustomFields.find({ boardIds: {$in: [paramBoardId]} }).map(function (cf) { return { _id: cf._id, name: cf.name, @@ -159,7 +159,7 @@ if (Meteor.isServer) { const paramCustomFieldId = req.params.customFieldId; JsonRoutes.sendResult(res, { code: 200, - data: CustomFields.findOne({ _id: paramCustomFieldId, boardId: paramBoardId }), + data: CustomFields.findOne({ _id: paramCustomFieldId, boardIds: {$in: [paramBoardId]} }), }); }); @@ -189,7 +189,7 @@ if (Meteor.isServer) { boardId: paramBoardId, }); - const customField = CustomFields.findOne({_id: id, boardId: paramBoardId }); + const customField = CustomFields.findOne({_id: id, boardIds: {$in: [paramBoardId]} }); customFieldCreation(req.body.authorId, customField); JsonRoutes.sendResult(res, { diff --git a/models/export.js b/models/export.js index 76f2da06..f281b34a 100644 --- a/models/export.js +++ b/models/export.js @@ -75,7 +75,7 @@ class Exporter { result.lists = Lists.find(byBoard, noBoardId).fetch(); result.cards = Cards.find(byBoardNoLinked, noBoardId).fetch(); result.swimlanes = Swimlanes.find(byBoard, noBoardId).fetch(); - result.customFields = CustomFields.find(byBoard, noBoardId).fetch(); + result.customFields = CustomFields.find({boardIds: {$in: [this.boardId]}}, {fields: {boardId: 0}}).fetch(); result.comments = CardComments.find(byBoard, noBoardId).fetch(); result.activities = Activities.find(byBoard, noBoardId).fetch(); result.rules = Rules.find(byBoard, noBoardId).fetch(); diff --git a/server/migrations.js b/server/migrations.js index b8915fe9..ced67218 100644 --- a/server/migrations.js +++ b/server/migrations.js @@ -525,3 +525,16 @@ Migrations.add('fix-circular-reference_', () => { } }); }); + +Migrations.add('mutate-boardIds-in-customfields', () => { + CustomFields.find().forEach((cf) => { + CustomFields.update(cf, { + $set: { + boardIds: [cf.boardId], + }, + $unset: { + boardId: "", + }, + }, noValidateMulti); + }); +}); diff --git a/server/publications/boards.js b/server/publications/boards.js index 18c44d2b..6d9d2b9e 100644 --- a/server/publications/boards.js +++ b/server/publications/boards.js @@ -78,7 +78,7 @@ Meteor.publishRelations('board', function(boardId) { this.cursor(Lists.find({ boardId })); this.cursor(Swimlanes.find({ boardId })); this.cursor(Integrations.find({ boardId })); - this.cursor(CustomFields.find({ boardId }, { sort: { name: 1 } })); + this.cursor(CustomFields.find({ boardIds: {$in: [boardId]} }, { sort: { name: 1 } })); // Cards and cards comments // XXX Originally we were publishing the card documents as a child of the -- cgit v1.2.3-1-g7c22 From d01fccd9497120613bf2c0b986963e67e7f3d6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 16 Mar 2019 22:43:47 +0100 Subject: - Fix card copy & move between boards with customFields - Fix card copy & move between boards with labels with same name - Fix activities for labels when copying and moving card - Fix activities for customFields when copying and moving card --- client/components/activities/activities.jade | 9 +- client/components/activities/activities.js | 8 ++ client/components/cards/cardDetails.js | 8 +- client/components/lists/list.js | 4 +- client/components/sidebar/sidebarCustomFields.js | 13 ++- models/boards.js | 2 +- models/cards.js | 102 +++++++++++++++++++---- models/customFields.js | 61 +++++++++++--- server/lib/utils.js | 6 ++ 9 files changed, 179 insertions(+), 34 deletions(-) diff --git a/client/components/activities/activities.jade b/client/components/activities/activities.jade index 949400f6..54066da8 100644 --- a/client/components/activities/activities.jade +++ b/client/components/activities/activities.jade @@ -99,6 +99,9 @@ template(name="boardActivities") else | {{{_ 'activity-added' memberLink cardLink}}}. + if($eq activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. + if($eq activityType 'moveCard') | {{{_ 'activity-moved' cardLink oldList.title list.title}}}. @@ -135,7 +138,7 @@ template(name="cardActivities") p.activity-desc +memberName(user=user) if($eq activityType 'createCard') - | {{_ 'activity-added' cardLabel list.title}}. + | {{_ 'activity-added' cardLabel listName}}. if($eq activityType 'importCard') | {{{_ 'activity-imported' cardLabel list.title sourceLink}}}. if($eq activityType 'joinMember') @@ -176,6 +179,10 @@ template(name="cardActivities") | {{_ 'activity-sent' cardLabel boardLabel}}. if($eq activityType 'moveCard') | {{_ 'activity-moved' cardLabel oldList.title list.title}}. + + if($eq activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. + if($eq activityType 'addAttachment') | {{{_ 'activity-attached' attachmentLink cardLabel}}}. if attachment.isImage diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js index 81995221..cbdd776e 100644 --- a/client/components/activities/activities.js +++ b/client/components/activities/activities.js @@ -74,6 +74,8 @@ BlazeComponent.extendComponent({ lastLabel(){ const lastLabelId = this.currentData().labelId; + if (!lastLabelId) + return; const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById(lastLabelId); if(lastLabel.name === undefined || lastLabel.name === ''){ return lastLabel.color; @@ -84,11 +86,15 @@ BlazeComponent.extendComponent({ lastCustomField(){ const lastCustomField = CustomFields.findOne(this.currentData().customFieldId); + if (!lastCustomField) + return null; return lastCustomField.name; }, lastCustomFieldValue(){ const lastCustomField = CustomFields.findOne(this.currentData().customFieldId); + if (!lastCustomField) + return null; const value = this.currentData().value; if (lastCustomField.settings.dropdownItems && lastCustomField.settings.dropdownItems.length > 0) { const dropDownValue = _.find(lastCustomField.settings.dropdownItems, (item) => { @@ -135,6 +141,8 @@ BlazeComponent.extendComponent({ customField() { const customField = this.currentData().customField(); + if (!customField) + return null; return customField.name; }, diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index d27fe732..79e9e311 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -412,11 +412,13 @@ Template.moveCardPopup.events({ // XXX We should *not* get the currentCard from the global state, but // instead from a “component” state. const card = Cards.findOne(Session.get('currentCard')); + const bSelect = $('.js-select-boards')[0]; + const boardId = bSelect.options[bSelect.selectedIndex].value; const lSelect = $('.js-select-lists')[0]; - const newListId = lSelect.options[lSelect.selectedIndex].value; + const listId = lSelect.options[lSelect.selectedIndex].value; const slSelect = $('.js-select-swimlanes')[0]; - card.swimlaneId = slSelect.options[slSelect.selectedIndex].value; - card.move(card.swimlaneId, newListId, 0); + const swimlaneId = slSelect.options[slSelect.selectedIndex].value; + card.move(boardId, swimlaneId, listId, 0); Popup.close(); }, }); diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 868be2ce..cceae7b4 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -86,12 +86,12 @@ BlazeComponent.extendComponent({ if (MultiSelection.isActive()) { Cards.find(MultiSelection.getMongoSelector()).forEach((card, i) => { - card.move(swimlaneId, listId, sortIndex.base + i * sortIndex.increment); + card.move(currentBoard._id, swimlaneId, listId, sortIndex.base + i * sortIndex.increment); }); } else { const cardDomElement = ui.item.get(0); const card = Blaze.getData(cardDomElement); - card.move(swimlaneId, listId, sortIndex.base); + card.move(currentBoard._id, swimlaneId, listId, sortIndex.base); } boardComponent.setIsDragging(false); }, diff --git a/client/components/sidebar/sidebarCustomFields.js b/client/components/sidebar/sidebarCustomFields.js index bdd8e7a0..81147ce5 100644 --- a/client/components/sidebar/sidebarCustomFields.js +++ b/client/components/sidebar/sidebarCustomFields.js @@ -116,15 +116,22 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ data.boardIds = [Session.get('currentBoard')]; CustomFields.insert(data); } else { - data.boardIds = {$in: [Session.get('currentBoard')]}; CustomFields.update(this.data()._id, {$set: data}); } Popup.back(); }, 'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() { - const customFieldId = this._id; - CustomFields.remove(customFieldId); + const customField = CustomFields.findOne(this._id); + if (customField.boardIds.length > 1) { + CustomFields.update(customField._id, { + $pull: { + boardIds: Session.get('currentBoard') + } + }); + } else { + CustomFields.remove(customField._id); + } Popup.close(); }), }]; diff --git a/models/boards.js b/models/boards.js index 9a71ede8..99ac8e6e 100644 --- a/models/boards.js +++ b/models/boards.js @@ -466,7 +466,7 @@ Boards.helpers({ }, customFields() { - return CustomFields.find({ boardId: this._id }, { sort: { name: 1 } }); + return CustomFields.find({ boardIds: {$in: [this._id]} }, { sort: { name: 1 } }); }, // XXX currently mutations return no value so we have an issue when using addLabel in import diff --git a/models/cards.js b/models/cards.js index 2caecb46..c234ab37 100644 --- a/models/cards.js +++ b/models/cards.js @@ -289,9 +289,19 @@ Cards.helpers({ const oldId = this._id; const oldCard = Cards.findOne(oldId); + // Copy Custom Fields + if (oldBoard._id !== boardId) { + CustomFields.find({ + _id: {$in: oldCard.customFields.map((cf) => { return cf._id; })}, + }).forEach((cf) => { + if (!_.contains(cf.boardIds, boardId)) + cf.addBoard(boardId); + }); + } + delete this._id; delete this.labelIds; - this.labelIds= newCardLabels; + this.labelIds = newCardLabels; this.boardId = boardId; this.swimlaneId = swimlaneId; this.listId = listId; @@ -306,7 +316,6 @@ Cards.helpers({ // copy checklists Checklists.find({cardId: oldId}).forEach((ch) => { - // REMOVE verify copy with arguments ch.copy(_id); }); @@ -314,13 +323,11 @@ Cards.helpers({ Cards.find({parentId: oldId}).forEach((subtask) => { subtask.parentId = _id; subtask._id = null; - // REMOVE verify copy with arguments instead of insert? Cards.insert(subtask); }); // copy card comments CardComments.find({cardId: oldId}).forEach((cmt) => { - // REMOVE verify copy with arguments cmt.copy(_id); }); @@ -485,6 +492,9 @@ Cards.helpers({ const definition = definitions.find((definition) => { return definition._id === customField._id; }); + if (!definition) { + return {}; + } //search for "True Value" which is for DropDowns other then the Value (which is the id) let trueValue = customField.value; if (definition.settings.dropdownItems && definition.settings.dropdownItems.length > 0) { @@ -1054,18 +1064,41 @@ Cards.mutations({ }; }, - move(swimlaneId, listId, sortIndex) { - const list = Lists.findOne(listId); + move(boardId, swimlaneId, listId, sort) { + // Copy Custom Fields + if (this.boardId !== boardId) { + CustomFields.find({ + _id: {$in: this.customFields.map((cf) => { return cf._id; })}, + }).forEach((cf) => { + if (!_.contains(cf.boardIds, boardId)) + cf.addBoard(boardId); + }); + } + + // Get label names + const oldBoard = Boards.findOne(this.boardId); + const oldBoardLabels = oldBoard.labels; + const oldCardLabels = _.pluck(_.filter(oldBoardLabels, (label) => { + return _.contains(this.labelIds, label._id); + }), 'name'); + + const newBoard = Boards.findOne(boardId); + const newBoardLabels = newBoard.labels; + const newCardLabelIds = _.pluck(_.filter(newBoardLabels, (label) => { + return label.name && _.contains(oldCardLabels, label.name); + }), '_id'); + const mutatedFields = { + boardId, swimlaneId, listId, - boardId: list.boardId, - sort: sortIndex, + sort, + labelIds: newCardLabelIds, }; - return { + Cards.update(this._id, { $set: mutatedFields, - }; + }); }, addLabel(labelId) { @@ -1287,8 +1320,47 @@ Cards.mutations({ //FUNCTIONS FOR creation of Activities -function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId) { - if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) || +function updateActivities(doc, fieldNames, modifier) { + if (_.contains(fieldNames, 'labelIds') && _.contains(fieldNames, 'boardId')) { + Activities.find({ + activityType: 'addedLabel', + cardId: doc._id, + }).forEach((a) => { + const lidx = doc.labelIds.indexOf(a.labelId); + if (lidx !== -1 && modifier.$set.labelIds.length > lidx) { + Activities.update(a._id, { + $set: { + labelId: modifier.$set.labelIds[doc.labelIds.indexOf(a.labelId)], + boardId: modifier.$set.boardId, + } + }); + } else { + Activities.remove(a._id); + } + }); + } else if (_.contains(fieldNames, 'boardId')) { + Activities.remove({ + activityType: 'addedLabel', + cardId: doc._id, + }); + } +} + +function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId, oldBoardId) { + if (_.contains(fieldNames, 'boardId') && (doc.boardId !== oldBoardId)) { + Activities.insert({ + userId, + activityType: 'moveCardBoard', + boardName: Boards.findOne(doc.boardId).title, + boardId: doc.boardId, + oldBoardId, + oldBoardName: Boards.findOne(oldBoardId).title, + cardId: doc._id, + swimlaneName: Swimlanes.findOne(doc.swimlaneId).title, + swimlaneId: doc.swimlaneId, + oldSwimlaneId, + }); + } else if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) || (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){ Activities.insert({ userId, @@ -1435,7 +1507,7 @@ function cardCustomFields(userId, doc, fieldNames, modifier) { // only individual changes are registered if (dotNotation.length > 1) { - const customFieldId = doc.customFields[dot_notation[1]]._id; + const customFieldId = doc.customFields[dotNotation[1]]._id; const act = { userId, customFieldId, @@ -1508,12 +1580,14 @@ if (Meteor.isServer) { Cards.after.update(function(userId, doc, fieldNames) { const oldListId = this.previous.listId; const oldSwimlaneId = this.previous.swimlaneId; - cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId); + const oldBoardId = this.previous.boardId; + cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId, oldBoardId); }); // Add a new activity if we add or remove a member to the card Cards.before.update((userId, doc, fieldNames, modifier) => { cardMembers(userId, doc, fieldNames, modifier); + updateActivities(doc, fieldNames, modifier); }); // Add a new activity if we add or remove a label to the card diff --git a/models/customFields.js b/models/customFields.js index 79f96708..a67ddb7d 100644 --- a/models/customFields.js +++ b/models/customFields.js @@ -72,17 +72,37 @@ CustomFields.attachSchema(new SimpleSchema({ }, })); +CustomFields.mutations({ + addBoard(boardId) { + if (boardId) { + return { + $push: { + boardIds: boardId, + }, + }; + } else { + return null; + } + }, +}); + CustomFields.allow({ insert(userId, doc) { - return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + return allowIsAnyBoardMember(userId, Boards.find({ + _id: {$in: doc.boardIds}, + }).fetch()); }, update(userId, doc) { - return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + return allowIsAnyBoardMember(userId, Boards.find({ + _id: {$in: doc.boardIds}, + }).fetch()); }, remove(userId, doc) { - return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + return allowIsAnyBoardMember(userId, Boards.find({ + _id: {$in: doc.boardIds}, + }).fetch()); }, - fetch: ['userId', 'boardId'], + fetch: ['userId', 'boardIds'], }); // not sure if we need this? @@ -92,27 +112,48 @@ function customFieldCreation(userId, doc){ Activities.insert({ userId, activityType: 'createCustomField', - boardId: doc.boardId, + boardId: doc.boardIds[0], // We are creating a customField, it has only one boardId customFieldId: doc._id, }); } if (Meteor.isServer) { Meteor.startup(() => { - CustomFields._collection._ensureIndex({ boardId: 1 }); + CustomFields._collection._ensureIndex({ boardIds: 1 }); }); CustomFields.after.insert((userId, doc) => { customFieldCreation(userId, doc); }); - CustomFields.after.remove((userId, doc) => { + CustomFields.before.update((userId, doc, fieldNames, modifier) => { + if (_.contains(fieldNames, 'boardIds') && modifier.$pull) { + Cards.update( + {boardId: modifier.$pull.boardIds, 'customFields._id': doc._id}, + {$pull: {'customFields': {'_id': doc._id}}}, + {multi: true} + ); + Activities.remove({ + customFieldId: doc._id, + boardId: modifier.$pull.boardIds, + }); + } else if (_.contains(fieldNames, 'boardIds') && modifier.$push) { + Activities.insert({ + userId, + activityType: 'createCustomField', + boardId: modifier.$push.boardIds, + customFieldId: doc._id, + }); + } + }); + + CustomFields.before.remove((userId, doc) => { Activities.remove({ customFieldId: doc._id, }); Cards.update( - {'boardId': doc.boardId, 'customFields._id': doc._id}, + {boardId: {$in: doc.boardIds}, 'customFields._id': doc._id}, {$pull: {'customFields': {'_id': doc._id}}}, {multi: true} ); @@ -186,7 +227,7 @@ if (Meteor.isServer) { showOnCard: req.body.showOnCard, automaticallyOnCard: req.body.automaticallyOnCard, showLabelOnMiniCard: req.body.showLabelOnMiniCard, - boardId: paramBoardId, + boardIds: {$in: [paramBoardId]}, }); const customField = CustomFields.findOne({_id: id, boardIds: {$in: [paramBoardId]} }); @@ -214,7 +255,7 @@ if (Meteor.isServer) { Authentication.checkUserId( req.userId); const paramBoardId = req.params.boardId; const id = req.params.customFieldId; - CustomFields.remove({ _id: id, boardId: paramBoardId }); + CustomFields.remove({ _id: id, boardIds: {$in: [paramBoardId]} }); JsonRoutes.sendResult(res, { code: 200, data: { diff --git a/server/lib/utils.js b/server/lib/utils.js index ee925847..3b4412fe 100644 --- a/server/lib/utils.js +++ b/server/lib/utils.js @@ -6,6 +6,12 @@ allowIsBoardMember = function(userId, board) { return board && board.hasMember(userId); }; +allowIsAnyBoardMember = function(userId, boards) { + return _.some(boards, (board) => { + return board && board.hasMember(userId); + }); +}; + allowIsBoardMemberCommentOnly = function(userId, board) { return board && board.hasMember(userId) && !board.hasCommentOnly(userId); }; -- cgit v1.2.3-1-g7c22 From 777d9ac35320cbfdd8d90136b176d4a3e69e74be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 16 Mar 2019 23:15:30 +0100 Subject: Lint fix --- client/components/activities/activities.js | 2 +- client/components/sidebar/sidebarCustomFields.js | 4 ++-- models/cards.js | 2 +- server/migrations.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js index cbdd776e..0476897f 100644 --- a/client/components/activities/activities.js +++ b/client/components/activities/activities.js @@ -75,7 +75,7 @@ BlazeComponent.extendComponent({ lastLabel(){ const lastLabelId = this.currentData().labelId; if (!lastLabelId) - return; + return null; const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById(lastLabelId); if(lastLabel.name === undefined || lastLabel.name === ''){ return lastLabel.color; diff --git a/client/components/sidebar/sidebarCustomFields.js b/client/components/sidebar/sidebarCustomFields.js index 81147ce5..28af973b 100644 --- a/client/components/sidebar/sidebarCustomFields.js +++ b/client/components/sidebar/sidebarCustomFields.js @@ -126,8 +126,8 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ if (customField.boardIds.length > 1) { CustomFields.update(customField._id, { $pull: { - boardIds: Session.get('currentBoard') - } + boardIds: Session.get('currentBoard'), + }, }); } else { CustomFields.remove(customField._id); diff --git a/models/cards.js b/models/cards.js index c234ab37..2bf83825 100644 --- a/models/cards.js +++ b/models/cards.js @@ -1332,7 +1332,7 @@ function updateActivities(doc, fieldNames, modifier) { $set: { labelId: modifier.$set.labelIds[doc.labelIds.indexOf(a.labelId)], boardId: modifier.$set.boardId, - } + }, }); } else { Activities.remove(a._id); diff --git a/server/migrations.js b/server/migrations.js index ced67218..09852495 100644 --- a/server/migrations.js +++ b/server/migrations.js @@ -533,7 +533,7 @@ Migrations.add('mutate-boardIds-in-customfields', () => { boardIds: [cf.boardId], }, $unset: { - boardId: "", + boardId: '', }, }, noValidateMulti); }); -- cgit v1.2.3-1-g7c22 From a6e3c8984d76d56d0803c67c6e857d052e892aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sun, 17 Mar 2019 16:23:59 +0100 Subject: Fix dissapearing subtasks --- models/boards.js | 4 +--- server/publications/boards.js | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/models/boards.js b/models/boards.js index 9a71ede8..3c9d6da0 100644 --- a/models/boards.js +++ b/models/boards.js @@ -605,9 +605,7 @@ Boards.helpers({ title: TAPi18n.__('queue'), boardId: this._id, }); - Boards.update(this._id, {$set: { - subtasksDefaultListId: this.subtasksDefaultListId, - }}); + this.setSubtasksDefaultListId(this.subtasksDefaultListId); } return this.subtasksDefaultListId; }, diff --git a/server/publications/boards.js b/server/publications/boards.js index 18c44d2b..b6fc0b97 100644 --- a/server/publications/boards.js +++ b/server/publications/boards.js @@ -116,7 +116,7 @@ Meteor.publishRelations('board', function(boardId) { const boards = this.join(Boards); const subCards = this.join(Cards); - this.cursor(Cards.find({ boardId }), function(cardId, card) { + this.cursor(Cards.find({ boardId: {$in: [boardId, board.subtasksDefaultBoardId]}}), function(cardId, card) { if (card.type === 'cardType-linkedCard') { const impCardId = card.linkedId; subCards.push(impCardId); @@ -141,6 +141,7 @@ Meteor.publishRelations('board', function(boardId) { checklists.send(); checklistItems.send(); boards.send(); + parentCards.send(); if (board.members) { // Board members. This publication also includes former board members that -- cgit v1.2.3-1-g7c22 From 9651d62b967358f3eac6ae1c92ce5e03a0ddb7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Mon, 18 Mar 2019 22:55:56 +0100 Subject: Fix #2266 --- client/components/lists/list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 868be2ce..fb1c0128 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -70,7 +70,7 @@ BlazeComponent.extendComponent({ const currentBoard = Boards.findOne(Session.get('currentBoard')); let swimlaneId = ''; const boardView = Meteor.user().profile.boardView; - if (boardView === 'board-view-swimlanes') + if (boardView === 'board-view-swimlanes' || currentBoard.isTemplatesBoard()) swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id; else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal')) swimlaneId = currentBoard.getDefaultSwimline()._id; -- cgit v1.2.3-1-g7c22 From ec30665bc4c87b5d1aa36cf25cd7cdaa4ffc2634 Mon Sep 17 00:00:00 2001 From: justinr1234 Date: Mon, 18 Mar 2019 23:06:18 -0500 Subject: Don't swallow email errors Fixes #2246 --- server/rulesHelper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/rulesHelper.js b/server/rulesHelper.js index 163bd41e..34e1abc1 100644 --- a/server/rulesHelper.js +++ b/server/rulesHelper.js @@ -78,6 +78,7 @@ RulesHelper = { emailMsg, }); } catch (e) { + console.error(e); return; } } -- cgit v1.2.3-1-g7c22 From 7a6b4adcc11d05b2cb4f798643b82e4aae0c0b26 Mon Sep 17 00:00:00 2001 From: justinr1234 Date: Mon, 18 Mar 2019 23:50:15 -0500 Subject: Disable eslint for console error --- server/rulesHelper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/rulesHelper.js b/server/rulesHelper.js index 34e1abc1..453c586d 100644 --- a/server/rulesHelper.js +++ b/server/rulesHelper.js @@ -78,6 +78,7 @@ RulesHelper = { emailMsg, }); } catch (e) { + // eslint-disable-next-line no-console console.error(e); return; } -- cgit v1.2.3-1-g7c22 From e97656555029cb58be775e4be65843b634725d6f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 20 Mar 2019 19:25:28 +0200 Subject: Update changelog. --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dca4f793..6540c0e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# Upcoming Wekan release + +This release fixes the following bugs, thanks to GitHub user neurolabs: + +- [The invitation code doesn't exist - case-sensitive eMail](https://github.com/wekan/wekan/issues/1384). + # v2.48 2019-03-15 Wekan release This release fixes the following bugs, thanks to GitHub user xet7: -- cgit v1.2.3-1-g7c22 From 6f35d73fe817127f027bf9f3f918e5a76d904d22 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 20 Mar 2019 19:28:56 +0200 Subject: Update changelog. --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6540c0e7..ed4befe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # Upcoming Wekan release -This release fixes the following bugs, thanks to GitHub user neurolabs: +This release fixes the following bugs: -- [The invitation code doesn't exist - case-sensitive eMail](https://github.com/wekan/wekan/issues/1384). +- [The invitation code doesn't exist - case-sensitive eMail](https://github.com/wekan/wekan/issues/1384). Thanks to neurolabs. +- [Don't swallow email errors](https://github.com/wekan/wekan/pull/2272). Thanks to justinr1234. # v2.48 2019-03-15 Wekan release -- cgit v1.2.3-1-g7c22 From 5ca083105c6938130b5d0fdb696a49c0da5d3d1f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 20 Mar 2019 21:36:19 +0200 Subject: Update changelog. --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed4befe8..29e531a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ This release fixes the following bugs: - [The invitation code doesn't exist - case-sensitive eMail](https://github.com/wekan/wekan/issues/1384). Thanks to neurolabs. - [Don't swallow email errors](https://github.com/wekan/wekan/pull/2272). Thanks to justinr1234. +- [Migrate customFields model](https://github.com/wekan/wekan/pull/2264]. + Modifies the customFields model to keep an array of boardIds where the customField can be used. + Adds name matching for labels when copying/moving cards between boards. + This way, customFields are not lost when copying/moving a card. Particularly useful when templates have customFields or labels with specific names (not tested for templates yet). + Thanks to andresmanelli. + +Thanks to above GitHub users for their contributions and translators for their translations. # v2.48 2019-03-15 Wekan release -- cgit v1.2.3-1-g7c22 From 9f95a1059191be699e2581807704bd987f3843f9 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 20 Mar 2019 21:45:56 +0200 Subject: Update translations. --- i18n/hu.i18n.json | 42 +++++++------- i18n/oc.i18n.json | 10 ++-- i18n/sv.i18n.json | 160 +++++++++++++++++++++++++++--------------------------- 3 files changed, 106 insertions(+), 106 deletions(-) diff --git a/i18n/hu.i18n.json b/i18n/hu.i18n.json index 0f10daf1..cb500412 100644 --- a/i18n/hu.i18n.json +++ b/i18n/hu.i18n.json @@ -1,6 +1,6 @@ { "accept": "Elfogadás", - "act-activity-notify": "Activity Notification", + "act-activity-notify": "Tevékenység értesítés", "act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", "act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", "act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", @@ -626,7 +626,7 @@ "r-check": "Check", "r-uncheck": "Uncheck", "r-item": "item", - "r-of-checklist": "of checklist", + "r-of-checklist": "ellenőrzőlistából", "r-send-email": "Send an email", "r-to": "to", "r-subject": "subject", @@ -651,32 +651,32 @@ "r-d-remove-all-member": "Remove all member", "r-d-check-all": "Check all items of a list", "r-d-uncheck-all": "Uncheck all items of a list", - "r-d-check-one": "Check item", + "r-d-check-one": "Elem ellenőrzése", "r-d-uncheck-one": "Uncheck item", - "r-d-check-of-list": "of checklist", - "r-d-add-checklist": "Add checklist", - "r-d-remove-checklist": "Remove checklist", - "r-by": "by", - "r-add-checklist": "Add checklist", - "r-with-items": "with items", + "r-d-check-of-list": "ellenőrzőlistából", + "r-d-add-checklist": "Ellenőrzőlista hozzáadása", + "r-d-remove-checklist": "Ellenőrzőlista eltávolítása", + "r-by": "által", + "r-add-checklist": "Ellenőrzőlista hozzáadása", + "r-with-items": "elemekkel", "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-when-a-card-is-moved": "When a card is moved to another list", + "r-when-a-card-is-moved": "Amikor egy kártya másik listába kerül", "ldap": "LDAP", "oauth2": "OAuth2", "cas": "CAS", - "authentication-method": "Authentication method", - "authentication-type": "Authentication type", - "custom-product-name": "Custom Product Name", - "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" + "authentication-method": "Hitelesítési mód", + "authentication-type": "Hitelesítés típusa", + "custom-product-name": "Saját terméknév", + "layout": "Elrendezés", + "hide-logo": "Logo elrejtése", + "add-custom-html-after-body-start": "Egyedi HTML hozzáadása után", + "add-custom-html-before-body-end": "1", + "error-undefined": "Valami hiba történt", + "error-ldap-login": "Hiba történt bejelentkezés közben", + "display-authentication-method": "Hitelelesítési mód mutatása", + "default-authentication-method": "Alapértelmezett hitelesítési mód" } \ No newline at end of file diff --git a/i18n/oc.i18n.json b/i18n/oc.i18n.json index 89f68375..57389d44 100644 --- a/i18n/oc.i18n.json +++ b/i18n/oc.i18n.json @@ -76,7 +76,7 @@ "add-label": "Apondre una etiqueta", "add-list": "Apondre una tièra", "add-members": "Apondre un participant", - "added": "Apondut", + "added": "Apondut lo", "addMemberPopup-title": "Participants", "admin": "Administartor", "admin-desc": "As lo drech de legir e modificar las cartas, tirar de participants, e modificar las opcions del tablèu.", @@ -135,8 +135,8 @@ "card-delete-notice": "Un còp tirat, pas de posibilitat de tornar enrè", "card-delete-pop": "Totes las accions van èsser quitadas del seguit d'activitat e poiretz pas mai utilizar aquesta carta.", "card-delete-suggest-archive": "Podètz desplaçar una carta dins Archius per la quitar del tablèu e gardar las activitats.", - "card-due": "esperat", - "card-due-on": "esperat per", + "card-due": "Esperat", + "card-due-on": "Esperat lo", "card-spent": "Temps passat", "card-edit-attachments": "Cambiar las pèças jonchas", "card-edit-custom-fields": "Cambiar los camps personalizats", @@ -326,7 +326,7 @@ "import-user-select": "Pick your existing user you want to use as this member", "importMapMembersAddPopup-title": "Seleccionar un participant", "info": "Vesion", - "initials": "Data inicala", + "initials": "Iniciala", "invalid-date": "Data invalida", "invalid-time": "Temps invalid", "invalid-user": "Participant invalid", @@ -458,7 +458,7 @@ "username": "Username", "view-it": "View it", "warn-list-archived": "warning: this card is in an list at Archive", - "watch": "Agachar", + "watch": "Seguit", "watching": "Agachat", "watching-info": "You will be notified of any change in this board", "welcome-board": "Tablèu de benvenguda", diff --git a/i18n/sv.i18n.json b/i18n/sv.i18n.json index 34c35927..647c3c10 100644 --- a/i18n/sv.i18n.json +++ b/i18n/sv.i18n.json @@ -1,37 +1,37 @@ { "accept": "Acceptera", "act-activity-notify": "Aktivitetsnotifikation", - "act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-addLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-removeLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-addChecklist": "added checklist __checklist__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-addChecklistItem": "added checklist item __checklistItem__ to checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-removeChecklist": "removed checklist __checklist__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-removeChecklistItem": "removed checklist item __checklistItem__ from checklist __checkList__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-checkedItem": "checked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-uncheckedItem": "unchecked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-createBoard": "created board __board__", - "act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__", - "act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-createList": "added list __list__ to board __board__", - "act-addBoardMember": "added member __member__ to board __board__", - "act-archivedBoard": "Board __board__ moved to Archive", - "act-archivedCard": "Card __card__ at list __list__ at swimlane __swimlane__ at board __board__ moved to Archive", - "act-archivedList": "List __list__ at swimlane __swimlane__ at board __board__ moved to Archive", - "act-archivedSwimlane": "Swimlane __swimlane__ at board __board__ moved to Archive", - "act-importBoard": "imported board __board__", - "act-importCard": "imported card __card__ to list __list__ at swimlane __swimlane__ at board __board__", - "act-importList": "imported list __list__ to swimlane __swimlane__ at board __board__", - "act-joinMember": "added member __member__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", - "act-moveCard": "moved card __card__ from list __oldList__ at swimlane __oldSwimlane__ at board __oldBoard__ to list __list__ at swimlane __swimlane__ at board __board__", - "act-removeBoardMember": "removed member __member__ from board __board__", - "act-restoredCard": "restored card __card__ to list __list__ at swimlane __swimlane__ at board __board__", - "act-unjoinMember": "removed member __member__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__", + "act-addAttachment": "la till bifogad fil __attachment__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-deleteAttachment": "raderade bifogad fil __attachment__ från kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-addSubtask": "la till underaktivitet __subtask__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-addLabel": "la till etikett __label__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-removeLabel": "Tog bort etikett __label__ från kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-addChecklist": "la till checklista __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-addChecklistItem": "la till checklistobjekt __checklistItem__ till checklista __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-removeChecklist": "tag bort checklista __checklist__ från kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-removeChecklistItem": "tog bort checklistobjekt __checklistItem__ från __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-checkedItem": "bockade av __checklistItem__ från checklista __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-uncheckedItem": "avmarkerade __checklistItem__ från checklista __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-completeChecklist": "slutförde checklista __checklist__ i kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-uncompleteChecklist": "ofullbordade checklista __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-addComment": "kommenterade på kort __card__: __comment__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-createBoard": "skapade tavla __board__", + "act-createCard": "skapade kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-createCustomField": "skapade anpassat fält __customField__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-createList": "la till lista __list__ på tavla __board__", + "act-addBoardMember": "la till medlem __member__ på tavla __board__", + "act-archivedBoard": "Tavla__board__ flyttad till arkivet", + "act-archivedCard": "Kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__ flyttad till arkivet", + "act-archivedList": "Lista __list__ i simbana __swimlane__ på tavla __board__ flyttad till arkivet", + "act-archivedSwimlane": "Simbana __swimlane__ på tavla __board__ flyttad till arkivet", + "act-importBoard": "importerade board __board__", + "act-importCard": "importerade kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-importList": "importerade lista __list__ i simbana __swimlane__ på tavla __board__", + "act-joinMember": "la till medlem __member__ på kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", + "act-moveCard": "flyttade kort __card__ från lista __oldList__ i simbana __oldSwimlane__ på tavla __oldBoard__ till lista __list__ i simbana __swimlane__ på tavla __board__", + "act-removeBoardMember": "borttagen medlem __member__  från tavla __board__", + "act-restoredCard": "återställde kort __card__ till lista __lis__ i simbana __swimlane__ på tavla __board__", + "act-unjoinMember": "tog bort medlem __member__ från kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", "act-withBoardTitle": "_tavla_", "act-withCardTitle": "[__board__] __card__", "actions": "Åtgärder", @@ -56,14 +56,14 @@ "activity-unchecked-item": "okryssad %s i checklistan %s av %s", "activity-checklist-added": "lade kontrollista till %s", "activity-checklist-removed": "tog bort en checklista från %s", - "activity-checklist-completed": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", + "activity-checklist-completed": "slutförde checklista __checklist__ i kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", "activity-checklist-uncompleted": "inte slutfört checklistan %s av %s", "activity-checklist-item-added": "lade checklista objekt till '%s' i %s", "activity-checklist-item-removed": "tog bort en checklista objekt från \"%s\" i %s", "add": "Lägg till", "activity-checked-item-card": "kryssad %s i checklistan %s", "activity-unchecked-item-card": "okryssad %s i checklistan %s", - "activity-checklist-completed-card": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", + "activity-checklist-completed-card": "slutförde checklista __checklist__ i kort __card__ i lista __list__ i simbana __swimlane__ på tavla __board__", "activity-checklist-uncompleted-card": "icke slutfört checklistan %s", "add-attachment": "Lägg till bilaga", "add-board": "Lägg till anslagstavla", @@ -93,7 +93,7 @@ "archive-board": "Flytta Anslagstavla till Arkiv", "archive-card": "Flytta Kort till Arkiv", "archive-list": "Flytta Lista till Arkiv", - "archive-swimlane": "Move Swimlane to Archive", + "archive-swimlane": "Flytta simbanan till arkivet", "archive-selection": "Flytta markerade till Arkiv", "archiveBoardPopup-title": "Flytta Anslagstavla till Arkiv?", "archived-items": "Arkiv", @@ -121,7 +121,7 @@ "boardChangeTitlePopup-title": "Byt namn på anslagstavla", "boardChangeVisibilityPopup-title": "Ändra synlighet", "boardChangeWatchPopup-title": "Ändra bevaka", - "boardMenuPopup-title": "Board Settings", + "boardMenuPopup-title": "Tavlans inställningar", "boards": "Anslagstavlor", "board-view": "Anslagstavelsvy", "board-view-cal": "Kalender", @@ -181,7 +181,7 @@ "close-board-pop": "Du kommer att kunna återställa anslagstavlan genom att klicka på knappen \"Arkiv\" från hemrubriken.", "color-black": "svart", "color-blue": "blå", - "color-crimson": "crimson", + "color-crimson": "mörkröd", "color-darkgreen": "mörkgrön", "color-gold": "guld", "color-gray": "grå", @@ -189,22 +189,22 @@ "color-indigo": "indigo", "color-lime": "lime", "color-magenta": "magenta", - "color-mistyrose": "mistyrose", - "color-navy": "navy", + "color-mistyrose": "ljusrosa", + "color-navy": "marinblå", "color-orange": "orange", - "color-paleturquoise": "paleturquoise", - "color-peachpuff": "peachpuff", + "color-paleturquoise": "turkos", + "color-peachpuff": "ersika", "color-pink": "rosa", - "color-plum": "plum", + "color-plum": "lila", "color-purple": "lila", "color-red": "röd", "color-saddlebrown": "sadelbrun", "color-silver": "silver", "color-sky": "himmel", - "color-slateblue": "slateblue", + "color-slateblue": "skifferblå", "color-white": "vit", "color-yellow": "gul", - "unset-color": "Unset", + "unset-color": "Urkoppla", "comment": "Kommentera", "comment-placeholder": "Skriv kommentar", "comment-only": "Kommentera endast", @@ -312,7 +312,7 @@ "import-board-c": "Importera anslagstavla", "import-board-title-trello": "Importera anslagstavla från Trello", "import-board-title-wekan": "Importera anslagstavla från tidigare 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-sandstorm-backup-warning": "Ta inte bort data som du importerar från exporterad original-tavla eller Trello innan du kontrollerar att det här spannet stänger och öppnas igen, eller får du felmeddelandet Tavla hittades inte, det vill säga dataförlust.", "import-sandstorm-warning": "Importerad anslagstavla raderar all befintlig data på anslagstavla och ersätter den med importerat anslagstavla.", "from-trello": "Från Trello", "from-wekan": "Från tidigare export", @@ -323,7 +323,7 @@ "import-map-members": "Kartlägg medlemmar", "import-members-map": "Din importerade anslagstavla har några medlemmar. Vänligen kartlägg medlemmarna du vill importera till dina användare", "import-show-user-mapping": "Granska medlemskartläggning", - "import-user-select": "Pick your existing user you want to use as this member", + "import-user-select": "Välj din befintliga användare du vill använda som den här medlemmen", "importMapMembersAddPopup-title": "Välj medlem", "info": "Version", "initials": "Initialer ", @@ -350,7 +350,7 @@ "set-color-list": "Ange färg", "listActionPopup-title": "Liståtgärder", "swimlaneActionPopup-title": "Simbana-åtgärder", - "swimlaneAddPopup-title": "Add a Swimlane below", + "swimlaneAddPopup-title": "Lägg till en simbana nedan", "listImportCardPopup-title": "Importera ett Trello kort", "listMorePopup-title": "Mera", "link-list": "Länk till den här listan", @@ -377,7 +377,7 @@ "name": "Namn", "no-archived-cards": "Inga kort i Arkiv.", "no-archived-lists": "Inga listor i Arkiv.", - "no-archived-swimlanes": "No swimlanes in Archive.", + "no-archived-swimlanes": "Inga simbanor i arkivet.", "no-results": "Inga reslutat", "normal": "Normal", "normal-desc": "Kan se och redigera kort. Kan inte ändra inställningar.", @@ -465,9 +465,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", + "card-templates-swimlane": "Kortmallar", + "list-templates-swimlane": "Listmalla", + "board-templates-swimlane": "Tavelmallar", "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.", @@ -493,14 +493,14 @@ "send-smtp-test": "Skicka ett prov e-postmeddelande till dig själv", "invitation-code": "Inbjudningskod", "email-invite-register-subject": "__inviter__ skickade dig en inbjudan", - "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": "Kära__user__,\n\n__inviter__ bjuder in dig att samarbeta på kanban-tavlan.\n\nFölj länken nedan:\n__url__\n\nDin inbjudningskod är: __icode__\n\nTack!", + "email-smtp-test-subject": "SMTP test-email", "email-smtp-test-text": "Du har skickat ett e-postmeddelande", "error-invitation-code-not-exist": "Inbjudningskod finns inte", "error-notAuthorized": "Du är inte behörig att se den här sidan.", "outgoing-webhooks": "Utgående Webhookar", "outgoingWebhooksPopup-title": "Utgående Webhookar", - "boardCardTitlePopup-title": "Card Title Filter", + "boardCardTitlePopup-title": "Korttitelfiler", "new-outgoing-webhook": "Ny utgående webhook", "no-name": "(Okänd)", "Node_version": "Nodversion", @@ -552,25 +552,25 @@ "show-subtasks-field": "Kort kan ha deluppgifter", "deposit-subtasks-board": "Insättnings deluppgifter på denna anslagstavla:", "deposit-subtasks-list": "Landningslista för deluppgifter deponerade här:", - "show-parent-in-minicard": "Show parent in minicard:", + "show-parent-in-minicard": "Visa förälder i minikort:", "prefix-with-full-path": "Prefix med fullständig sökväg", - "prefix-with-parent": "Prefix with parent", + "prefix-with-parent": "Prefix med förälder", "subtext-with-full-path": "Undertext med fullständig sökväg", - "subtext-with-parent": "Subtext with parent", - "change-card-parent": "Change card's parent", - "parent-card": "Parent card", + "subtext-with-parent": "Undertext med förälder", + "change-card-parent": "Ändra kortets förälder", + "parent-card": "Föräldrakort", "source-board": "Källa för anslagstavla", - "no-parent": "Don't show parent", + "no-parent": "Visa inte förälder", "activity-added-label": "lade till etiketten '%s' till %s", "activity-removed-label": "tog bort etiketten '%s' från %s", "activity-delete-attach": "raderade en bilaga från %s", "activity-added-label-card": "lade till etiketten \"%s\"", "activity-removed-label-card": "tog bort etiketten \"%s\"", "activity-delete-attach-card": "tog bort en bilaga", - "activity-set-customfield": "set custom field '%s' to '%s' in %s", - "activity-unset-customfield": "unset custom field '%s' in %s", + "activity-set-customfield": "ställ in anpassat fält '%s' till '%s' i %s", + "activity-unset-customfield": "Koppla bort anpassat fält '%s' i %s", "r-rule": "Regel", - "r-add-trigger": "Add trigger", + "r-add-trigger": "Lägg till utlösare", "r-add-action": "Lägg till åtgärd", "r-board-rules": "Regler för anslagstavla", "r-add-rule": "Lägg till regel", @@ -601,15 +601,15 @@ "r-when-a-checklist": "När en checklista är", "r-when-the-checklist": "När checklistan", "r-completed": "Avslutad", - "r-made-incomplete": "Made incomplete", - "r-when-a-item": "When a checklist item is", - "r-when-the-item": "When the checklist item", + "r-made-incomplete": "Gjord ofullständig", + "r-when-a-item": "När ett checklistobjekt ä", + "r-when-the-item": "När checklistans objekt", "r-checked": "Kryssad", "r-unchecked": "Okryssad", "r-move-card-to": "Flytta kort till", "r-top-of": "Överst på", "r-bottom-of": "Nederst av", - "r-its-list": "its list", + "r-its-list": "sin lista", "r-archive": "Flytta till Arkiv", "r-unarchive": "Återställ från Arkiv", "r-card": "kort", @@ -631,10 +631,10 @@ "r-to": "till", "r-subject": "änme", "r-rule-details": "Regeldetaljer", - "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-d-move-to-bottom-gen": "Move card to bottom of its list", - "r-d-move-to-bottom-spec": "Move card to bottom of list", + "r-d-move-to-top-gen": "Flytta kort till toppen av sin lista", + "r-d-move-to-top-spec": "Flytta kort till toppen av listan", + "r-d-move-to-bottom-gen": "Flytta kort till botten av sin lista", + "r-d-move-to-bottom-spec": "Flytta kort till botten av listan", "r-d-send-email": "Skicka e-post", "r-d-send-email-to": "till", "r-d-send-email-subject": "ämne", @@ -645,7 +645,7 @@ "r-d-remove-label": "Ta bort etikett", "r-create-card": "Skapa nytt kort", "r-in-list": "i listan", - "r-in-swimlane": "in swimlane", + "r-in-swimlane": "i simbana", "r-d-add-member": "Lägg till medlem", "r-d-remove-member": "Ta bort medlem", "r-d-remove-all-member": "Ta bort alla medlemmar", @@ -658,13 +658,13 @@ "r-d-remove-checklist": "Ta bort checklista", "r-by": "av", "r-add-checklist": "Lägg till checklista", - "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-when-a-card-is-moved": "When a card is moved to another list", + "r-with-items": "med objekt", + "r-items-list": "objekt1,objekt2,objekt3", + "r-add-swimlane": "Lägg till simbana", + "r-swimlane-name": "Simbanans namn", + "r-board-note": "Notera: lämna ett fält tomt för att matcha alla möjliga värden.", + "r-checklist-note": "Notera: Objekt i en checklista måste skrivas som kommaseparerade objekt", + "r-when-a-card-is-moved": "När ett kort flyttas till en annan lista", "ldap": "LDAP", "oauth2": "OAuth2", "cas": "CAS", @@ -673,8 +673,8 @@ "custom-product-name": "Anpassat produktnamn", "layout": "Layout", "hide-logo": "Dölj logotypen", - "add-custom-html-after-body-start": "Add Custom HTML after start", - "add-custom-html-before-body-end": "Add Custom HTML before end", + "add-custom-html-after-body-start": "Lägg till anpassad HTML efter start", + "add-custom-html-before-body-end": "Lägg till anpassad HTML före slut", "error-undefined": "Något gick fel", "error-ldap-login": "Ett fel uppstod när du försökte logga in", "display-authentication-method": "Visa autentiseringsmetod", -- cgit v1.2.3-1-g7c22 From f083fc0d7b4998e87afa5ad2b3eeaa99690079e4 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 21 Mar 2019 00:13:31 +0200 Subject: Update changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29e531a0..af7f69cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This release fixes the following bugs: Adds name matching for labels when copying/moving cards between boards. This way, customFields are not lost when copying/moving a card. Particularly useful when templates have customFields or labels with specific names (not tested for templates yet). Thanks to andresmanelli. +- [Fix dissapearing subtasks](https://github.com/wekan/wekan/pull/2265). Thanks to andresmanelli. Thanks to above GitHub users for their contributions and translators for their translations. -- cgit v1.2.3-1-g7c22 From 1046976c08f54100aad600f9071f8b747c8e55f9 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 21 Mar 2019 00:23:35 +0200 Subject: [Fix Cards disappear when rearranged on template board](https://github.com/wekan/wekan/issues/2266). Thanks to andresmanelli ! Closes #2266 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af7f69cf..baa4c709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This release fixes the following bugs: This way, customFields are not lost when copying/moving a card. Particularly useful when templates have customFields or labels with specific names (not tested for templates yet). Thanks to andresmanelli. - [Fix dissapearing subtasks](https://github.com/wekan/wekan/pull/2265). Thanks to andresmanelli. +- [Cards disappear when rearranged on template board](https://github.com/wekan/wekan/issues/2266). Thanks to andresmanelli. Thanks to above GitHub users for their contributions and translators for their translations. -- cgit v1.2.3-1-g7c22 From da3edb35ccf8a29bd6568b8b0445fdc1d6113b19 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 21 Mar 2019 00:39:35 +0200 Subject: v2.49 --- CHANGELOG.md | 2 +- Stackerfile.yml | 2 +- package.json | 2 +- sandstorm-pkgdef.capnp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baa4c709..ac1624d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Upcoming Wekan release +# v2.49 2019-03-21 Wekan release This release fixes the following bugs: diff --git a/Stackerfile.yml b/Stackerfile.yml index 46037269..49ac8a7c 100644 --- a/Stackerfile.yml +++ b/Stackerfile.yml @@ -1,5 +1,5 @@ appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928 -appVersion: "v2.48.0" +appVersion: "v2.49.0" files: userUploads: - README.md diff --git a/package.json b/package.json index fc18b575..3195486e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wekan", - "version": "v2.48.0", + "version": "v2.49.0", "description": "Open-Source kanban", "private": true, "scripts": { diff --git a/sandstorm-pkgdef.capnp b/sandstorm-pkgdef.capnp index f9551eff..6d9798e0 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 = 250, + appVersion = 251, # Increment this for every release. - appMarketingVersion = (defaultText = "2.48.0~2019-03-15"), + appMarketingVersion = (defaultText = "2.49.0~2019-03-21"), # Human-readable presentation of the app version. minUpgradableAppVersion = 0, -- cgit v1.2.3-1-g7c22