mirror of
https://github.com/wekan/wekan.git
synced 2026-02-28 10:54:07 +01:00
Prettier & eslint project style update
This commit is contained in:
parent
a0a482aa8e
commit
3eb4d2c341
116 changed files with 6216 additions and 5240 deletions
|
|
@ -37,7 +37,7 @@ AccountSettings.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
AccountSettings.allow({
|
||||
|
|
@ -47,11 +47,6 @@ AccountSettings.allow({
|
|||
},
|
||||
});
|
||||
|
||||
AccountSettings.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
AccountSettings._collection._ensureIndex({ modifiedAt: -1 });
|
||||
|
|
@ -62,7 +57,7 @@ if (Meteor.isServer) {
|
|||
booleanValue: false,
|
||||
sort: 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
AccountSettings.upsert(
|
||||
{ _id: 'accounts-allowUserNameChange' },
|
||||
|
|
@ -71,7 +66,7 @@ if (Meteor.isServer) {
|
|||
booleanValue: false,
|
||||
sort: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,6 @@ Actions.helpers({
|
|||
},
|
||||
});
|
||||
|
||||
Actions.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
Actions._collection._ensureIndex({ modifiedAt: -1 });
|
||||
|
|
|
|||
|
|
@ -71,11 +71,6 @@ Activities.after.insert((userId, doc) => {
|
|||
RulesHelper.executeRules(activity);
|
||||
});
|
||||
|
||||
Activities.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// For efficiency create indexes on the date of creation, and on the date of
|
||||
// creation in conjunction with the card or board id, as corresponding views
|
||||
|
|
@ -87,15 +82,15 @@ if (Meteor.isServer) {
|
|||
Activities._collection._ensureIndex({ boardId: 1, createdAt: -1 });
|
||||
Activities._collection._ensureIndex(
|
||||
{ commentId: 1 },
|
||||
{ partialFilterExpression: { commentId: { $exists: true } } }
|
||||
{ partialFilterExpression: { commentId: { $exists: true } } },
|
||||
);
|
||||
Activities._collection._ensureIndex(
|
||||
{ attachmentId: 1 },
|
||||
{ partialFilterExpression: { attachmentId: { $exists: true } } }
|
||||
{ partialFilterExpression: { attachmentId: { $exists: true } } },
|
||||
);
|
||||
Activities._collection._ensureIndex(
|
||||
{ customFieldId: 1 },
|
||||
{ partialFilterExpression: { customFieldId: { $exists: true } } }
|
||||
{ partialFilterExpression: { customFieldId: { $exists: true } } },
|
||||
);
|
||||
// Label activity did not work yet, unable to edit labels when tried this.
|
||||
//Activities._collection._dropIndex({ labelId: 1 }, { "indexKey": -1 });
|
||||
|
|
@ -205,20 +200,20 @@ if (Meteor.isServer) {
|
|||
if (board) {
|
||||
const watchingUsers = _.pluck(
|
||||
_.where(board.watchers, { level: 'watching' }),
|
||||
'userId'
|
||||
'userId',
|
||||
);
|
||||
const trackingUsers = _.pluck(
|
||||
_.where(board.watchers, { level: 'tracking' }),
|
||||
'userId'
|
||||
'userId',
|
||||
);
|
||||
watchers = _.union(
|
||||
watchers,
|
||||
watchingUsers,
|
||||
_.intersection(participants, trackingUsers)
|
||||
_.intersection(participants, trackingUsers),
|
||||
);
|
||||
}
|
||||
|
||||
Notifications.getUsers(watchers).forEach((user) => {
|
||||
Notifications.getUsers(watchers).forEach(user => {
|
||||
Notifications.notify(user, title, description, params);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Announcements.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Announcements.allow({
|
||||
|
|
@ -52,11 +52,6 @@ Announcements.allow({
|
|||
},
|
||||
});
|
||||
|
||||
Announcements.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
Announcements._collection._ensureIndex({ modifiedAt: -1 });
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Attachments = new FS.Collection('attachments', {
|
|||
// XXX Should we use `beforeWrite` option of CollectionFS instead of
|
||||
// collection-hooks?
|
||||
// We should use `beforeWrite`.
|
||||
beforeWrite: (fileObj) => {
|
||||
beforeWrite: fileObj => {
|
||||
if (!fileObj.isImage()) {
|
||||
return {
|
||||
type: 'application/octet-stream',
|
||||
|
|
@ -84,7 +84,7 @@ if (Meteor.isServer) {
|
|||
$unset: {
|
||||
source: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ Boards.attachSchema(
|
|||
const colors = Boards.simpleSchema()._schema['labels.$.color']
|
||||
.allowedValues;
|
||||
const defaultLabelsColors = _.clone(colors).splice(0, 6);
|
||||
return defaultLabelsColors.map((color) => ({
|
||||
return defaultLabelsColors.map(color => ({
|
||||
color,
|
||||
_id: Random.id(6),
|
||||
name: '',
|
||||
|
|
@ -342,7 +342,7 @@ Boards.attachSchema(
|
|||
type: String,
|
||||
defaultValue: 'board',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Boards.helpers({
|
||||
|
|
@ -355,7 +355,7 @@ Boards.helpers({
|
|||
Swimlanes.find({
|
||||
boardId: oldId,
|
||||
archived: false,
|
||||
}).forEach((swimlane) => {
|
||||
}).forEach(swimlane => {
|
||||
swimlane.type = 'swimlane';
|
||||
swimlane.copy(_id);
|
||||
});
|
||||
|
|
@ -382,7 +382,7 @@ Boards.helpers({
|
|||
isActiveMember(userId) {
|
||||
if (userId) {
|
||||
return this.members.find(
|
||||
(member) => member.userId === userId && member.isActive
|
||||
member => member.userId === userId && member.isActive,
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
|
|
@ -396,14 +396,14 @@ Boards.helpers({
|
|||
cards() {
|
||||
return Cards.find(
|
||||
{ boardId: this._id, archived: false },
|
||||
{ sort: { title: 1 } }
|
||||
{ sort: { title: 1 } },
|
||||
);
|
||||
},
|
||||
|
||||
lists() {
|
||||
return Lists.find(
|
||||
{ boardId: this._id, archived: false },
|
||||
{ sort: { sort: 1 } }
|
||||
{ sort: { sort: 1 } },
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -418,7 +418,7 @@ Boards.helpers({
|
|||
swimlanes() {
|
||||
return Swimlanes.find(
|
||||
{ boardId: this._id, archived: false },
|
||||
{ sort: { sort: 1 } }
|
||||
{ sort: { sort: 1 } },
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -432,7 +432,7 @@ Boards.helpers({
|
|||
},
|
||||
{
|
||||
sort: { sort: 1 },
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -535,7 +535,7 @@ Boards.helpers({
|
|||
customFields() {
|
||||
return CustomFields.find(
|
||||
{ boardIds: { $in: [this._id] } },
|
||||
{ sort: { name: 1 } }
|
||||
{ sort: { name: 1 } },
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -848,7 +848,7 @@ Boards.mutations({
|
|||
isAdmin,
|
||||
isNoComments,
|
||||
isCommentOnly,
|
||||
currentUserId = Meteor.userId()
|
||||
currentUserId = Meteor.userId(),
|
||||
) {
|
||||
const memberIndex = this.memberIndex(memberId);
|
||||
// do not allow change permission of self
|
||||
|
|
@ -884,9 +884,9 @@ Boards.mutations({
|
|||
|
||||
function boardRemover(userId, doc) {
|
||||
[Cards, Lists, Swimlanes, Integrations, Rules, Activities].forEach(
|
||||
(element) => {
|
||||
element => {
|
||||
element.remove({ boardId: doc._id });
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -927,7 +927,7 @@ if (Meteor.isServer) {
|
|||
_.findWhere(doc.members, {
|
||||
userId: removedMemberId,
|
||||
isAdmin: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
fetch: ['members'],
|
||||
|
|
@ -973,7 +973,7 @@ if (Meteor.isServer) {
|
|||
_id: 1,
|
||||
'members.userId': 1,
|
||||
},
|
||||
{ unique: true }
|
||||
{ unique: true },
|
||||
);
|
||||
Boards._collection._ensureIndex({ 'members.userId': 1 });
|
||||
});
|
||||
|
|
@ -1009,12 +1009,12 @@ if (Meteor.isServer) {
|
|||
labelIds: removedLabelId,
|
||||
},
|
||||
},
|
||||
{ multi: true }
|
||||
{ multi: true },
|
||||
);
|
||||
});
|
||||
|
||||
const foreachRemovedMember = (doc, modifier, callback) => {
|
||||
Object.keys(modifier).forEach((set) => {
|
||||
Object.keys(modifier).forEach(set => {
|
||||
if (modifier[set] !== false) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1030,11 +1030,6 @@ if (Meteor.isServer) {
|
|||
});
|
||||
};
|
||||
|
||||
Boards.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
// Remove a member from all objects of the board before leaving the board
|
||||
Boards.before.update((userId, doc, fieldNames, modifier) => {
|
||||
if (!_.contains(fieldNames, 'members')) {
|
||||
|
|
@ -1043,7 +1038,7 @@ if (Meteor.isServer) {
|
|||
|
||||
if (modifier.$set) {
|
||||
const boardId = doc._id;
|
||||
foreachRemovedMember(doc, modifier.$set, (memberId) => {
|
||||
foreachRemovedMember(doc, modifier.$set, memberId => {
|
||||
Cards.update(
|
||||
{ boardId },
|
||||
{
|
||||
|
|
@ -1052,7 +1047,7 @@ if (Meteor.isServer) {
|
|||
watchers: memberId,
|
||||
},
|
||||
},
|
||||
{ multi: true }
|
||||
{ multi: true },
|
||||
);
|
||||
|
||||
Lists.update(
|
||||
|
|
@ -1062,7 +1057,7 @@ if (Meteor.isServer) {
|
|||
watchers: memberId,
|
||||
},
|
||||
},
|
||||
{ multi: true }
|
||||
{ multi: true },
|
||||
);
|
||||
|
||||
const board = Boards._transform(doc);
|
||||
|
|
@ -1112,7 +1107,7 @@ if (Meteor.isServer) {
|
|||
|
||||
// Say goodbye to the former member
|
||||
if (modifier.$set) {
|
||||
foreachRemovedMember(doc, modifier.$set, (memberId) => {
|
||||
foreachRemovedMember(doc, modifier.$set, memberId => {
|
||||
Activities.insert({
|
||||
userId,
|
||||
memberId,
|
||||
|
|
@ -1143,7 +1138,7 @@ if (Meteor.isServer) {
|
|||
// admins can access boards of any user
|
||||
Authentication.checkAdminOrCondition(
|
||||
req.userId,
|
||||
req.userId === paramUserId
|
||||
req.userId === paramUserId,
|
||||
);
|
||||
|
||||
const data = Boards.find(
|
||||
|
|
@ -1153,7 +1148,7 @@ if (Meteor.isServer) {
|
|||
},
|
||||
{
|
||||
sort: ['title'],
|
||||
}
|
||||
},
|
||||
).map(function(board) {
|
||||
return {
|
||||
_id: board._id,
|
||||
|
|
@ -1332,7 +1327,7 @@ if (Meteor.isServer) {
|
|||
if (!board.getLabel(name, color)) {
|
||||
Boards.direct.update(
|
||||
{ _id: id },
|
||||
{ $push: { labels: { _id: labelId, name, color } } }
|
||||
{ $push: { labels: { _id: labelId, name, color } } },
|
||||
);
|
||||
JsonRoutes.sendResult(res, {
|
||||
code: 200,
|
||||
|
|
@ -1364,7 +1359,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('POST', '/api/boards/:boardId/members/:memberId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const boardId = req.params.boardId;
|
||||
|
|
@ -1384,7 +1379,7 @@ if (Meteor.isServer) {
|
|||
isTrue(isAdmin),
|
||||
isTrue(isNoComments),
|
||||
isTrue(isCommentOnly),
|
||||
req.userId
|
||||
req.userId,
|
||||
);
|
||||
|
||||
JsonRoutes.sendResult(res, {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ CardComments.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
CardComments.allow({
|
||||
|
|
@ -107,11 +107,6 @@ function commentCreation(userId, doc) {
|
|||
});
|
||||
}
|
||||
|
||||
CardComments.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// Comments are often fetched within a card, so we create an index to make these
|
||||
// queries more efficient.
|
||||
|
|
@ -125,7 +120,6 @@ if (Meteor.isServer) {
|
|||
});
|
||||
|
||||
CardComments.after.update((userId, doc) => {
|
||||
const activity = Activities.findOne({ commentId: doc._id });
|
||||
const card = Cards.findOne(doc.cardId);
|
||||
Activities.insert({
|
||||
userId,
|
||||
|
|
@ -139,7 +133,6 @@ if (Meteor.isServer) {
|
|||
});
|
||||
|
||||
CardComments.before.remove((userId, doc) => {
|
||||
const activity = Activities.findOne({ commentId: doc._id });
|
||||
const card = Cards.findOne(doc.cardId);
|
||||
Activities.insert({
|
||||
userId,
|
||||
|
|
@ -174,7 +167,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/comments', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
Authentication.checkUserId(req.userId);
|
||||
|
|
@ -233,7 +226,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -280,7 +273,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -318,7 +311,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
1554
models/cards.js
1554
models/cards.js
File diff suppressed because it is too large
Load diff
|
|
@ -61,7 +61,7 @@ ChecklistItems.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
ChecklistItems.allow({
|
||||
|
|
@ -225,11 +225,6 @@ if (Meteor.isServer) {
|
|||
publishChekListUncompleted(userId, doc, fieldNames);
|
||||
});
|
||||
|
||||
ChecklistItems.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
ChecklistItems.after.insert((userId, doc) => {
|
||||
itemCreation(userId, doc);
|
||||
});
|
||||
|
|
@ -281,7 +276,7 @@ if (Meteor.isServer) {
|
|||
code: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -308,13 +303,13 @@ if (Meteor.isServer) {
|
|||
if (req.body.hasOwnProperty('isFinished')) {
|
||||
ChecklistItems.direct.update(
|
||||
{ _id: paramItemId },
|
||||
{ $set: { isFinished: req.body.isFinished } }
|
||||
{ $set: { isFinished: req.body.isFinished } },
|
||||
);
|
||||
}
|
||||
if (req.body.hasOwnProperty('title')) {
|
||||
ChecklistItems.direct.update(
|
||||
{ _id: paramItemId },
|
||||
{ $set: { title: req.body.title } }
|
||||
{ $set: { title: req.body.title } },
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +319,7 @@ if (Meteor.isServer) {
|
|||
_id: paramItemId,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -353,7 +348,7 @@ if (Meteor.isServer) {
|
|||
_id: paramItemId,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ Checklists.attachSchema(
|
|||
type: Number,
|
||||
decimal: true,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Checklists.helpers({
|
||||
|
|
@ -68,7 +68,7 @@ Checklists.helpers({
|
|||
this._id = null;
|
||||
this.cardId = newCardId;
|
||||
const newChecklistId = Checklists.insert(this);
|
||||
ChecklistItems.find({ checklistId: oldChecklistId }).forEach((item) => {
|
||||
ChecklistItems.find({ checklistId: oldChecklistId }).forEach(item => {
|
||||
item._id = null;
|
||||
item.checklistId = newChecklistId;
|
||||
item.cardId = newCardId;
|
||||
|
|
@ -84,7 +84,7 @@ Checklists.helpers({
|
|||
{
|
||||
checklistId: this._id,
|
||||
},
|
||||
{ sort: ['sort'] }
|
||||
{ sort: ['sort'] },
|
||||
);
|
||||
},
|
||||
finishedCount() {
|
||||
|
|
@ -160,16 +160,11 @@ if (Meteor.isServer) {
|
|||
});
|
||||
});
|
||||
|
||||
Checklists.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
Checklists.before.remove((userId, doc) => {
|
||||
const activities = Activities.find({ checklistId: doc._id });
|
||||
const card = Cards.findOne(doc.cardId);
|
||||
if (activities) {
|
||||
activities.forEach((activity) => {
|
||||
activities.forEach(activity => {
|
||||
Activities.remove(activity._id);
|
||||
});
|
||||
}
|
||||
|
|
@ -203,7 +198,7 @@ if (Meteor.isServer) {
|
|||
Authentication.checkUserId(req.userId);
|
||||
const paramCardId = req.params.cardId;
|
||||
const checklists = Checklists.find({ cardId: paramCardId }).map(function(
|
||||
doc
|
||||
doc,
|
||||
) {
|
||||
return {
|
||||
_id: doc._id,
|
||||
|
|
@ -220,7 +215,7 @@ if (Meteor.isServer) {
|
|||
code: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -269,7 +264,7 @@ if (Meteor.isServer) {
|
|||
code: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -313,7 +308,7 @@ if (Meteor.isServer) {
|
|||
code: 400,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -340,7 +335,7 @@ if (Meteor.isServer) {
|
|||
_id: paramChecklistId,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ CustomFields.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
CustomFields.mutations({
|
||||
|
|
@ -118,7 +118,7 @@ CustomFields.allow({
|
|||
userId,
|
||||
Boards.find({
|
||||
_id: { $in: doc.boardIds },
|
||||
}).fetch()
|
||||
}).fetch(),
|
||||
);
|
||||
},
|
||||
update(userId, doc) {
|
||||
|
|
@ -126,7 +126,7 @@ CustomFields.allow({
|
|||
userId,
|
||||
Boards.find({
|
||||
_id: { $in: doc.boardIds },
|
||||
}).fetch()
|
||||
}).fetch(),
|
||||
);
|
||||
},
|
||||
remove(userId, doc) {
|
||||
|
|
@ -134,7 +134,7 @@ CustomFields.allow({
|
|||
userId,
|
||||
Boards.find({
|
||||
_id: { $in: doc.boardIds },
|
||||
}).fetch()
|
||||
}).fetch(),
|
||||
);
|
||||
},
|
||||
fetch: ['userId', 'boardIds'],
|
||||
|
|
@ -152,7 +152,7 @@ function customFieldCreation(userId, doc) {
|
|||
});
|
||||
}
|
||||
|
||||
function customFieldDeletion(userId, doc){
|
||||
function customFieldDeletion(userId, doc) {
|
||||
Activities.insert({
|
||||
userId,
|
||||
activityType: 'deleteCustomField',
|
||||
|
|
@ -163,7 +163,7 @@ function customFieldDeletion(userId, doc){
|
|||
|
||||
// This has some bug, it does not show edited customField value at Outgoing Webhook,
|
||||
// instead it shows undefined, and no listId and swimlaneId.
|
||||
function customFieldEdit(userId, doc){
|
||||
function customFieldEdit(userId, doc) {
|
||||
const card = Cards.findOne(doc.cardId);
|
||||
Activities.insert({
|
||||
userId,
|
||||
|
|
@ -185,17 +185,12 @@ if (Meteor.isServer) {
|
|||
customFieldCreation(userId, doc);
|
||||
});
|
||||
|
||||
CustomFields.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
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 }
|
||||
{ multi: true },
|
||||
);
|
||||
customFieldEdit(userId, doc);
|
||||
Activities.remove({
|
||||
|
|
@ -223,7 +218,7 @@ if (Meteor.isServer) {
|
|||
Cards.update(
|
||||
{ boardId: { $in: doc.boardIds }, 'customFields._id': doc._id },
|
||||
{ $pull: { customFields: { _id: doc._id } } },
|
||||
{ multi: true }
|
||||
{ multi: true },
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
@ -241,7 +236,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/custom-fields', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
Authentication.checkUserId(req.userId);
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -254,7 +249,7 @@ if (Meteor.isServer) {
|
|||
name: cf.name,
|
||||
type: cf.type,
|
||||
};
|
||||
}
|
||||
},
|
||||
),
|
||||
});
|
||||
});
|
||||
|
|
@ -281,7 +276,7 @@ if (Meteor.isServer) {
|
|||
boardIds: { $in: [paramBoardId] },
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -299,7 +294,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('POST', '/api/boards/:boardId/custom-fields', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
Authentication.checkUserId(req.userId);
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -351,7 +346,7 @@ if (Meteor.isServer) {
|
|||
_id: id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
125
models/export.js
125
models/export.js
|
|
@ -57,7 +57,10 @@ export class Exporter {
|
|||
|
||||
build() {
|
||||
const byBoard = { boardId: this._boardId };
|
||||
const byBoardNoLinked = { boardId: this._boardId, linkedId: {$in: ['', null] } };
|
||||
const byBoardNoLinked = {
|
||||
boardId: this._boardId,
|
||||
linkedId: { $in: ['', null] },
|
||||
};
|
||||
// we do not want to retrieve boardId in related elements
|
||||
const noBoardId = {
|
||||
fields: {
|
||||
|
|
@ -67,15 +70,21 @@ export class Exporter {
|
|||
const result = {
|
||||
_format: 'wekan-board-1.0.0',
|
||||
};
|
||||
_.extend(result, Boards.findOne(this._boardId, {
|
||||
fields: {
|
||||
stars: 0,
|
||||
},
|
||||
}));
|
||||
_.extend(
|
||||
result,
|
||||
Boards.findOne(this._boardId, {
|
||||
fields: {
|
||||
stars: 0,
|
||||
},
|
||||
}),
|
||||
);
|
||||
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({boardIds: {$in: [this.boardId]}}, {fields: {boardId: 0}}).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();
|
||||
|
|
@ -84,24 +93,40 @@ export class Exporter {
|
|||
result.subtaskItems = [];
|
||||
result.triggers = [];
|
||||
result.actions = [];
|
||||
result.cards.forEach((card) => {
|
||||
result.checklists.push(...Checklists.find({
|
||||
cardId: card._id,
|
||||
}).fetch());
|
||||
result.checklistItems.push(...ChecklistItems.find({
|
||||
cardId: card._id,
|
||||
}).fetch());
|
||||
result.subtaskItems.push(...Cards.find({
|
||||
parentid: card._id,
|
||||
}).fetch());
|
||||
result.cards.forEach(card => {
|
||||
result.checklists.push(
|
||||
...Checklists.find({
|
||||
cardId: card._id,
|
||||
}).fetch(),
|
||||
);
|
||||
result.checklistItems.push(
|
||||
...ChecklistItems.find({
|
||||
cardId: card._id,
|
||||
}).fetch(),
|
||||
);
|
||||
result.subtaskItems.push(
|
||||
...Cards.find({
|
||||
parentid: card._id,
|
||||
}).fetch(),
|
||||
);
|
||||
});
|
||||
result.rules.forEach((rule) => {
|
||||
result.triggers.push(...Triggers.find({
|
||||
_id: rule.triggerId,
|
||||
}, noBoardId).fetch());
|
||||
result.actions.push(...Actions.find({
|
||||
_id: rule.actionId,
|
||||
}, noBoardId).fetch());
|
||||
result.rules.forEach(rule => {
|
||||
result.triggers.push(
|
||||
...Triggers.find(
|
||||
{
|
||||
_id: rule.triggerId,
|
||||
},
|
||||
noBoardId,
|
||||
).fetch(),
|
||||
);
|
||||
result.actions.push(
|
||||
...Actions.find(
|
||||
{
|
||||
_id: rule.actionId,
|
||||
},
|
||||
noBoardId,
|
||||
).fetch(),
|
||||
);
|
||||
});
|
||||
|
||||
// [Old] for attachments we only export IDs and absolute url to original doc
|
||||
|
|
@ -122,43 +147,45 @@ export class Exporter {
|
|||
});
|
||||
};
|
||||
const getBase64DataSync = Meteor.wrapAsync(getBase64Data);
|
||||
result.attachments = Attachments.find(byBoard).fetch().map((attachment) => {
|
||||
return {
|
||||
_id: attachment._id,
|
||||
cardId: attachment.cardId,
|
||||
// url: FlowRouter.url(attachment.url()),
|
||||
file: getBase64DataSync(attachment),
|
||||
name: attachment.original.name,
|
||||
type: attachment.original.type,
|
||||
};
|
||||
});
|
||||
result.attachments = Attachments.find(byBoard)
|
||||
.fetch()
|
||||
.map(attachment => {
|
||||
return {
|
||||
_id: attachment._id,
|
||||
cardId: attachment.cardId,
|
||||
// url: FlowRouter.url(attachment.url()),
|
||||
file: getBase64DataSync(attachment),
|
||||
name: attachment.original.name,
|
||||
type: attachment.original.type,
|
||||
};
|
||||
});
|
||||
|
||||
// we also have to export some user data - as the other elements only
|
||||
// include id but we have to be careful:
|
||||
// 1- only exports users that are linked somehow to that board
|
||||
// 2- do not export any sensitive information
|
||||
const users = {};
|
||||
result.members.forEach((member) => {
|
||||
result.members.forEach(member => {
|
||||
users[member.userId] = true;
|
||||
});
|
||||
result.lists.forEach((list) => {
|
||||
result.lists.forEach(list => {
|
||||
users[list.userId] = true;
|
||||
});
|
||||
result.cards.forEach((card) => {
|
||||
result.cards.forEach(card => {
|
||||
users[card.userId] = true;
|
||||
if (card.members) {
|
||||
card.members.forEach((memberId) => {
|
||||
card.members.forEach(memberId => {
|
||||
users[memberId] = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
result.comments.forEach((comment) => {
|
||||
result.comments.forEach(comment => {
|
||||
users[comment.userId] = true;
|
||||
});
|
||||
result.activities.forEach((activity) => {
|
||||
result.activities.forEach(activity => {
|
||||
users[activity.userId] = true;
|
||||
});
|
||||
result.checklists.forEach((checklist) => {
|
||||
result.checklists.forEach(checklist => {
|
||||
users[checklist.userId] = true;
|
||||
});
|
||||
const byUserIds = {
|
||||
|
|
@ -177,13 +204,15 @@ export class Exporter {
|
|||
'profile.avatarUrl': 1,
|
||||
},
|
||||
};
|
||||
result.users = Users.find(byUserIds, userFields).fetch().map((user) => {
|
||||
// user avatar is stored as a relative url, we export absolute
|
||||
if ((user.profile || {}).avatarUrl) {
|
||||
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
|
||||
}
|
||||
return user;
|
||||
});
|
||||
result.users = Users.find(byUserIds, userFields)
|
||||
.fetch()
|
||||
.map(user => {
|
||||
// user avatar is stored as a relative url, we export absolute
|
||||
if ((user.profile || {}).avatarUrl) {
|
||||
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
|
||||
}
|
||||
return user;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { TrelloCreator } from './trelloCreator';
|
||||
import { WekanCreator } from './wekanCreator';
|
||||
import {Exporter} from './export';
|
||||
import { Exporter } from './export';
|
||||
import wekanMembersMapper from './wekanmapper';
|
||||
|
||||
Meteor.methods({
|
||||
|
|
@ -11,12 +11,12 @@ Meteor.methods({
|
|||
check(currentBoard, Match.Maybe(String));
|
||||
let creator;
|
||||
switch (importSource) {
|
||||
case 'trello':
|
||||
creator = new TrelloCreator(data);
|
||||
break;
|
||||
case 'wekan':
|
||||
creator = new WekanCreator(data);
|
||||
break;
|
||||
case 'trello':
|
||||
creator = new TrelloCreator(data);
|
||||
break;
|
||||
case 'wekan':
|
||||
creator = new WekanCreator(data);
|
||||
break;
|
||||
}
|
||||
|
||||
// 1. check all parameters are ok from a syntax point of view
|
||||
|
|
@ -38,11 +38,9 @@ Meteor.methods({
|
|||
const data = exporter.build();
|
||||
const addData = {};
|
||||
addData.membersMapping = wekanMembersMapper.getMembersToMap(data);
|
||||
const creator = new WekanCreator(addData);
|
||||
const creator = new WekanCreator(addData);
|
||||
//data.title = `${data.title } - ${ TAPi18n.__('copy-tag')}`;
|
||||
data.title = `${data.title}`;
|
||||
return creator.create(data, currentBoardId);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -86,14 +86,9 @@ Integrations.attachSchema(
|
|||
*/
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Integrations.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
Integrations.allow({
|
||||
insert(userId, doc) {
|
||||
return allowIsBoardAdmin(userId, Boards.findOne(doc.boardId));
|
||||
|
|
@ -123,7 +118,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/integrations', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -131,7 +126,7 @@ if (Meteor.isServer) {
|
|||
|
||||
const data = Integrations.find(
|
||||
{ boardId: paramBoardId },
|
||||
{ fields: { token: 0 } }
|
||||
{ fields: { token: 0 } },
|
||||
).map(function(doc) {
|
||||
return doc;
|
||||
});
|
||||
|
|
@ -155,7 +150,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/integrations/:intId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -166,7 +161,7 @@ if (Meteor.isServer) {
|
|||
code: 200,
|
||||
data: Integrations.findOne(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ fields: { token: 0 } }
|
||||
{ fields: { token: 0 } },
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -187,7 +182,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('POST', '/api/boards/:boardId/integrations', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -228,7 +223,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('PUT', '/api/boards/:boardId/integrations/:intId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -239,35 +234,35 @@ if (Meteor.isServer) {
|
|||
const newEnabled = req.body.enabled;
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $set: { enabled: newEnabled } }
|
||||
{ $set: { enabled: newEnabled } },
|
||||
);
|
||||
}
|
||||
if (req.body.hasOwnProperty('title')) {
|
||||
const newTitle = req.body.title;
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $set: { title: newTitle } }
|
||||
{ $set: { title: newTitle } },
|
||||
);
|
||||
}
|
||||
if (req.body.hasOwnProperty('url')) {
|
||||
const newUrl = req.body.url;
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $set: { url: newUrl } }
|
||||
{ $set: { url: newUrl } },
|
||||
);
|
||||
}
|
||||
if (req.body.hasOwnProperty('token')) {
|
||||
const newToken = req.body.token;
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $set: { token: newToken } }
|
||||
{ $set: { token: newToken } },
|
||||
);
|
||||
}
|
||||
if (req.body.hasOwnProperty('activities')) {
|
||||
const newActivities = req.body.activities;
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $set: { activities: newActivities } }
|
||||
{ $set: { activities: newActivities } },
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -306,14 +301,14 @@ if (Meteor.isServer) {
|
|||
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $pullAll: { activities: newActivities } }
|
||||
{ $pullAll: { activities: newActivities } },
|
||||
);
|
||||
|
||||
JsonRoutes.sendResult(res, {
|
||||
code: 200,
|
||||
data: Integrations.findOne(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ fields: { _id: 1, activities: 1 } }
|
||||
{ fields: { _id: 1, activities: 1 } },
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -322,7 +317,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -346,14 +341,14 @@ if (Meteor.isServer) {
|
|||
|
||||
Integrations.direct.update(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ $addToSet: { activities: { $each: newActivities } } }
|
||||
{ $addToSet: { activities: { $each: newActivities } } },
|
||||
);
|
||||
|
||||
JsonRoutes.sendResult(res, {
|
||||
code: 200,
|
||||
data: Integrations.findOne(
|
||||
{ _id: paramIntId, boardId: paramBoardId },
|
||||
{ fields: { _id: 1, activities: 1 } }
|
||||
{ fields: { _id: 1, activities: 1 } },
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -362,7 +357,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -375,7 +370,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('DELETE', '/api/boards/:boardId/integrations/:intId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ InvitationCodes.attachSchema(
|
|||
type: Boolean,
|
||||
defaultValue: true,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
InvitationCodes.helpers({
|
||||
|
|
@ -56,11 +56,6 @@ InvitationCodes.helpers({
|
|||
},
|
||||
});
|
||||
|
||||
InvitationCodes.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
// InvitationCodes.before.insert((userId, doc) => {
|
||||
// doc.createdAt = new Date();
|
||||
// doc.authorId = userId;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ Lists.attachSchema(
|
|||
type: String,
|
||||
defaultValue: 'list',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Lists.allow({
|
||||
|
|
@ -198,7 +198,7 @@ Lists.helpers({
|
|||
swimlaneId: oldSwimlaneId,
|
||||
listId: oldId,
|
||||
archived: false,
|
||||
}).forEach((card) => {
|
||||
}).forEach(card => {
|
||||
card.copy(boardId, swimlaneId, _id);
|
||||
});
|
||||
},
|
||||
|
|
@ -262,7 +262,7 @@ Lists.mutations({
|
|||
|
||||
archive() {
|
||||
if (this.isTemplateList()) {
|
||||
this.cards().forEach((card) => {
|
||||
this.cards().forEach(card => {
|
||||
return card.archive();
|
||||
});
|
||||
}
|
||||
|
|
@ -271,7 +271,7 @@ Lists.mutations({
|
|||
|
||||
restore() {
|
||||
if (this.isTemplateList()) {
|
||||
this.allCards().forEach((card) => {
|
||||
this.allCards().forEach(card => {
|
||||
return card.restore();
|
||||
});
|
||||
}
|
||||
|
|
@ -346,15 +346,10 @@ if (Meteor.isServer) {
|
|||
});
|
||||
});
|
||||
|
||||
Lists.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
Lists.before.remove((userId, doc) => {
|
||||
const cards = Cards.find({ listId: doc._id });
|
||||
if (cards) {
|
||||
cards.forEach((card) => {
|
||||
cards.forEach(card => {
|
||||
Cards.remove(card._id);
|
||||
});
|
||||
}
|
||||
|
|
@ -404,7 +399,7 @@ if (Meteor.isServer) {
|
|||
_id: doc._id,
|
||||
title: doc.title,
|
||||
};
|
||||
}
|
||||
},
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -425,7 +420,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -492,7 +487,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
Authentication.checkUserId(req.userId);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Rules.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Rules.mutations({
|
||||
|
|
@ -74,11 +74,6 @@ Rules.allow({
|
|||
},
|
||||
});
|
||||
|
||||
Rules.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
Rules._collection._ensureIndex({ modifiedAt: -1 });
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ Settings.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
Settings.helpers({
|
||||
mailUrl() {
|
||||
|
|
@ -88,7 +88,7 @@ Settings.helpers({
|
|||
return `${protocol}${this.mailServer.host}:${this.mailServer.port}/`;
|
||||
}
|
||||
return `${protocol}${this.mailServer.username}:${encodeURIComponent(
|
||||
this.mailServer.password
|
||||
this.mailServer.password,
|
||||
)}@${this.mailServer.host}:${this.mailServer.port}/`;
|
||||
},
|
||||
});
|
||||
|
|
@ -99,11 +99,6 @@ Settings.allow({
|
|||
},
|
||||
});
|
||||
|
||||
Settings.before.update((userId, doc, fieldNames, modifier) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = new Date();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
Settings._collection._ensureIndex({ modifiedAt: -1 });
|
||||
|
|
@ -111,7 +106,7 @@ if (Meteor.isServer) {
|
|||
if (!setting) {
|
||||
const now = new Date();
|
||||
const domain = process.env.ROOT_URL.match(
|
||||
/\/\/(?:www\.)?(.*)?(?:\/)?/
|
||||
/\/\/(?:www\.)?(.*)?(?:\/)?/,
|
||||
)[1];
|
||||
const from = `Boards Support <support@${domain}>`;
|
||||
const defaultSetting = {
|
||||
|
|
@ -143,9 +138,7 @@ if (Meteor.isServer) {
|
|||
if (_.contains(fieldNames, 'mailServer') && doc.mailServer.host) {
|
||||
const protocol = doc.mailServer.enableTLS ? 'smtps://' : 'smtp://';
|
||||
if (!doc.mailServer.username && !doc.mailServer.password) {
|
||||
process.env.MAIL_URL = `${protocol}${doc.mailServer.host}:${
|
||||
doc.mailServer.port
|
||||
}/`;
|
||||
process.env.MAIL_URL = `${protocol}${doc.mailServer.host}:${doc.mailServer.port}/`;
|
||||
} else {
|
||||
process.env.MAIL_URL = `${protocol}${
|
||||
doc.mailServer.username
|
||||
|
|
@ -220,14 +213,14 @@ if (Meteor.isServer) {
|
|||
if (!user.isAdmin) {
|
||||
throw new Meteor.Error('not-allowed');
|
||||
}
|
||||
emails.forEach((email) => {
|
||||
emails.forEach(email => {
|
||||
if (email && SimpleSchema.RegEx.Email.test(email)) {
|
||||
// Checks if the email is already link to an account.
|
||||
const userExist = Users.findOne({ email });
|
||||
if (userExist) {
|
||||
throw new Meteor.Error(
|
||||
'user-exist',
|
||||
`The user with the email ${email} has already an account.`
|
||||
`The user with the email ${email} has already an account.`,
|
||||
);
|
||||
}
|
||||
// Checks if the email is already link to an invitation.
|
||||
|
|
@ -253,10 +246,10 @@ if (Meteor.isServer) {
|
|||
} else {
|
||||
throw new Meteor.Error(
|
||||
'invitation-generated-fail',
|
||||
err.message
|
||||
err.message,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -284,7 +277,7 @@ if (Meteor.isServer) {
|
|||
throw new Meteor.Error(
|
||||
'email-fail',
|
||||
`${TAPi18n.__('email-fail-text', { lng: lang })}: ${message}`,
|
||||
message
|
||||
message,
|
||||
);
|
||||
}
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ Swimlanes.attachSchema(
|
|||
type: String,
|
||||
defaultValue: 'swimlane',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Swimlanes.allow({
|
||||
|
|
@ -153,7 +153,7 @@ Swimlanes.helpers({
|
|||
}
|
||||
|
||||
// Copy all lists in swimlane
|
||||
Lists.find(query).forEach((list) => {
|
||||
Lists.find(query).forEach(list => {
|
||||
list.type = 'list';
|
||||
list.swimlaneId = oldId;
|
||||
list.boardId = boardId;
|
||||
|
|
@ -167,7 +167,7 @@ Swimlanes.helpers({
|
|||
swimlaneId: this._id,
|
||||
archived: false,
|
||||
}),
|
||||
{ sort: ['sort'] }
|
||||
{ sort: ['sort'] },
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -178,7 +178,7 @@ Swimlanes.helpers({
|
|||
swimlaneId: { $in: [this._id, ''] },
|
||||
archived: false,
|
||||
},
|
||||
{ sort: ['sort'] }
|
||||
{ sort: ['sort'] },
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ Swimlanes.mutations({
|
|||
|
||||
archive() {
|
||||
if (this.isTemplateSwimlane()) {
|
||||
this.myLists().forEach((list) => {
|
||||
this.myLists().forEach(list => {
|
||||
return list.archive();
|
||||
});
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ Swimlanes.mutations({
|
|||
|
||||
restore() {
|
||||
if (this.isTemplateSwimlane()) {
|
||||
this.myLists().forEach((list) => {
|
||||
this.myLists().forEach(list => {
|
||||
return list.restore();
|
||||
});
|
||||
}
|
||||
|
|
@ -262,11 +262,6 @@ Swimlanes.mutations({
|
|||
},
|
||||
});
|
||||
|
||||
Swimlanes.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
Swimlanes.hookOptions.after.update = { fetchPrevious: false };
|
||||
|
||||
if (Meteor.isServer) {
|
||||
|
|
@ -292,11 +287,11 @@ if (Meteor.isServer) {
|
|||
swimlaneId: { $in: [doc._id, ''] },
|
||||
archived: false,
|
||||
},
|
||||
{ sort: ['sort'] }
|
||||
{ sort: ['sort'] },
|
||||
);
|
||||
|
||||
if (lists.count() < 2) {
|
||||
lists.forEach((list) => {
|
||||
lists.forEach(list => {
|
||||
list.remove();
|
||||
});
|
||||
} else {
|
||||
|
|
@ -350,7 +345,7 @@ if (Meteor.isServer) {
|
|||
_id: doc._id,
|
||||
title: doc.title,
|
||||
};
|
||||
}
|
||||
},
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -372,7 +367,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/swimlanes/:swimlaneId', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
const paramBoardId = req.params.boardId;
|
||||
|
|
@ -459,7 +454,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const DateString = Match.Where(function (dateAsString) {
|
||||
const DateString = Match.Where(function(dateAsString) {
|
||||
check(dateAsString, String);
|
||||
return moment(dateAsString, moment.ISO_8601).isValid();
|
||||
});
|
||||
|
|
@ -52,10 +52,10 @@ export class TrelloCreator {
|
|||
* @param {String} dateString a properly formatted Date
|
||||
*/
|
||||
_now(dateString) {
|
||||
if(dateString) {
|
||||
if (dateString) {
|
||||
return new Date(dateString);
|
||||
}
|
||||
if(!this._nowDate) {
|
||||
if (!this._nowDate) {
|
||||
this._nowDate = new Date();
|
||||
}
|
||||
return this._nowDate;
|
||||
|
|
@ -67,75 +67,90 @@ export class TrelloCreator {
|
|||
* Otherwise return current logged user.
|
||||
* @param trelloUserId
|
||||
* @private
|
||||
*/
|
||||
*/
|
||||
_user(trelloUserId) {
|
||||
if(trelloUserId && this.members[trelloUserId]) {
|
||||
if (trelloUserId && this.members[trelloUserId]) {
|
||||
return this.members[trelloUserId];
|
||||
}
|
||||
return Meteor.userId();
|
||||
}
|
||||
|
||||
checkActions(trelloActions) {
|
||||
check(trelloActions, [Match.ObjectIncluding({
|
||||
data: Object,
|
||||
date: DateString,
|
||||
type: String,
|
||||
})]);
|
||||
check(trelloActions, [
|
||||
Match.ObjectIncluding({
|
||||
data: Object,
|
||||
date: DateString,
|
||||
type: String,
|
||||
}),
|
||||
]);
|
||||
// XXX we could perform more thorough checks based on action type
|
||||
}
|
||||
|
||||
checkBoard(trelloBoard) {
|
||||
check(trelloBoard, Match.ObjectIncluding({
|
||||
closed: Boolean,
|
||||
name: String,
|
||||
prefs: Match.ObjectIncluding({
|
||||
// XXX refine control by validating 'background' against a list of
|
||||
// allowed values (is it worth the maintenance?)
|
||||
background: String,
|
||||
permissionLevel: Match.Where((value) => {
|
||||
return ['org', 'private', 'public'].indexOf(value)>= 0;
|
||||
check(
|
||||
trelloBoard,
|
||||
Match.ObjectIncluding({
|
||||
closed: Boolean,
|
||||
name: String,
|
||||
prefs: Match.ObjectIncluding({
|
||||
// XXX refine control by validating 'background' against a list of
|
||||
// allowed values (is it worth the maintenance?)
|
||||
background: String,
|
||||
permissionLevel: Match.Where(value => {
|
||||
return ['org', 'private', 'public'].indexOf(value) >= 0;
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
);
|
||||
}
|
||||
|
||||
checkCards(trelloCards) {
|
||||
check(trelloCards, [Match.ObjectIncluding({
|
||||
closed: Boolean,
|
||||
dateLastActivity: DateString,
|
||||
desc: String,
|
||||
idLabels: [String],
|
||||
idMembers: [String],
|
||||
name: String,
|
||||
pos: Number,
|
||||
})]);
|
||||
check(trelloCards, [
|
||||
Match.ObjectIncluding({
|
||||
closed: Boolean,
|
||||
dateLastActivity: DateString,
|
||||
desc: String,
|
||||
idLabels: [String],
|
||||
idMembers: [String],
|
||||
name: String,
|
||||
pos: Number,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkLabels(trelloLabels) {
|
||||
check(trelloLabels, [Match.ObjectIncluding({
|
||||
// XXX refine control by validating 'color' against a list of allowed
|
||||
// values (is it worth the maintenance?)
|
||||
name: String,
|
||||
})]);
|
||||
check(trelloLabels, [
|
||||
Match.ObjectIncluding({
|
||||
// XXX refine control by validating 'color' against a list of allowed
|
||||
// values (is it worth the maintenance?)
|
||||
name: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkLists(trelloLists) {
|
||||
check(trelloLists, [Match.ObjectIncluding({
|
||||
closed: Boolean,
|
||||
name: String,
|
||||
})]);
|
||||
check(trelloLists, [
|
||||
Match.ObjectIncluding({
|
||||
closed: Boolean,
|
||||
name: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkChecklists(trelloChecklists) {
|
||||
check(trelloChecklists, [Match.ObjectIncluding({
|
||||
idBoard: String,
|
||||
idCard: String,
|
||||
name: String,
|
||||
checkItems: [Match.ObjectIncluding({
|
||||
state: String,
|
||||
check(trelloChecklists, [
|
||||
Match.ObjectIncluding({
|
||||
idBoard: String,
|
||||
idCard: String,
|
||||
name: String,
|
||||
})],
|
||||
})]);
|
||||
checkItems: [
|
||||
Match.ObjectIncluding({
|
||||
state: String,
|
||||
name: String,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
// You must call parseActions before calling this one.
|
||||
|
|
@ -146,31 +161,35 @@ export class TrelloCreator {
|
|||
// very old boards won't have a creation activity so no creation date
|
||||
createdAt: this._now(this.createdAt.board),
|
||||
labels: [],
|
||||
members: [{
|
||||
userId: Meteor.userId(),
|
||||
isAdmin: true,
|
||||
isActive: true,
|
||||
isNoComments: false,
|
||||
isCommentOnly: false,
|
||||
swimlaneId: false,
|
||||
}],
|
||||
members: [
|
||||
{
|
||||
userId: Meteor.userId(),
|
||||
isAdmin: true,
|
||||
isActive: true,
|
||||
isNoComments: false,
|
||||
isCommentOnly: false,
|
||||
swimlaneId: false,
|
||||
},
|
||||
],
|
||||
permission: this.getPermission(trelloBoard.prefs.permissionLevel),
|
||||
slug: getSlug(trelloBoard.name) || 'board',
|
||||
stars: 0,
|
||||
title: trelloBoard.name,
|
||||
};
|
||||
// now add other members
|
||||
if(trelloBoard.memberships) {
|
||||
trelloBoard.memberships.forEach((trelloMembership) => {
|
||||
if (trelloBoard.memberships) {
|
||||
trelloBoard.memberships.forEach(trelloMembership => {
|
||||
const trelloId = trelloMembership.idMember;
|
||||
// do we have a mapping?
|
||||
if(this.members[trelloId]) {
|
||||
if (this.members[trelloId]) {
|
||||
const wekanId = this.members[trelloId];
|
||||
// do we already have it in our list?
|
||||
const wekanMember = boardToCreate.members.find((wekanMember) => wekanMember.userId === wekanId);
|
||||
if(wekanMember) {
|
||||
const wekanMember = boardToCreate.members.find(
|
||||
wekanMember => wekanMember.userId === wekanId,
|
||||
);
|
||||
if (wekanMember) {
|
||||
// we're already mapped, but maybe with lower rights
|
||||
if(!wekanMember.isAdmin) {
|
||||
if (!wekanMember.isAdmin) {
|
||||
wekanMember.isAdmin = this.getAdmin(trelloMembership.memberType);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -186,7 +205,7 @@ export class TrelloCreator {
|
|||
}
|
||||
});
|
||||
}
|
||||
trelloBoard.labels.forEach((label) => {
|
||||
trelloBoard.labels.forEach(label => {
|
||||
const labelToCreate = {
|
||||
_id: Random.id(6),
|
||||
color: label.color ? label.color : 'black',
|
||||
|
|
@ -198,7 +217,7 @@ export class TrelloCreator {
|
|||
boardToCreate.labels.push(labelToCreate);
|
||||
});
|
||||
const boardId = Boards.direct.insert(boardToCreate);
|
||||
Boards.direct.update(boardId, {$set: {modifiedAt: this._now()}});
|
||||
Boards.direct.update(boardId, { $set: { modifiedAt: this._now() } });
|
||||
// log activity
|
||||
Activities.direct.insert({
|
||||
activityType: 'importBoard',
|
||||
|
|
@ -225,7 +244,7 @@ export class TrelloCreator {
|
|||
*/
|
||||
createCards(trelloCards, boardId) {
|
||||
const result = [];
|
||||
trelloCards.forEach((card) => {
|
||||
trelloCards.forEach(card => {
|
||||
const cardToCreate = {
|
||||
archived: card.closed,
|
||||
boardId,
|
||||
|
|
@ -243,26 +262,26 @@ export class TrelloCreator {
|
|||
};
|
||||
// add labels
|
||||
if (card.idLabels) {
|
||||
cardToCreate.labelIds = card.idLabels.map((trelloId) => {
|
||||
cardToCreate.labelIds = card.idLabels.map(trelloId => {
|
||||
return this.labels[trelloId];
|
||||
});
|
||||
}
|
||||
// add members {
|
||||
if(card.idMembers) {
|
||||
if (card.idMembers) {
|
||||
const wekanMembers = [];
|
||||
// we can't just map, as some members may not have been mapped
|
||||
card.idMembers.forEach((trelloId) => {
|
||||
if(this.members[trelloId]) {
|
||||
card.idMembers.forEach(trelloId => {
|
||||
if (this.members[trelloId]) {
|
||||
const wekanId = this.members[trelloId];
|
||||
// we may map multiple Trello members to the same wekan user
|
||||
// in which case we risk adding the same user multiple times
|
||||
if(!wekanMembers.find((wId) => wId === wekanId)){
|
||||
if (!wekanMembers.find(wId => wId === wekanId)) {
|
||||
wekanMembers.push(wekanId);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if(wekanMembers.length>0) {
|
||||
if (wekanMembers.length > 0) {
|
||||
cardToCreate.members = wekanMembers;
|
||||
}
|
||||
}
|
||||
|
|
@ -289,7 +308,7 @@ export class TrelloCreator {
|
|||
// add comments
|
||||
const comments = this.comments[card.id];
|
||||
if (comments) {
|
||||
comments.forEach((comment) => {
|
||||
comments.forEach(comment => {
|
||||
const commentToCreate = {
|
||||
boardId,
|
||||
cardId,
|
||||
|
|
@ -318,15 +337,15 @@ export class TrelloCreator {
|
|||
const attachments = this.attachments[card.id];
|
||||
const trelloCoverId = card.idAttachmentCover;
|
||||
if (attachments) {
|
||||
attachments.forEach((att) => {
|
||||
attachments.forEach(att => {
|
||||
const file = new FS.File();
|
||||
// Simulating file.attachData on the client generates multiple errors
|
||||
// - HEAD returns null, which causes exception down the line
|
||||
// - the template then tries to display the url to the attachment which causes other errors
|
||||
// so we make it server only, and let UI catch up once it is done, forget about latency comp.
|
||||
const self = this;
|
||||
if(Meteor.isServer) {
|
||||
file.attachData(att.url, function (error) {
|
||||
if (Meteor.isServer) {
|
||||
file.attachData(att.url, function(error) {
|
||||
file.boardId = boardId;
|
||||
file.cardId = cardId;
|
||||
file.userId = self._user(att.idMemberCreator);
|
||||
|
|
@ -334,15 +353,17 @@ export class TrelloCreator {
|
|||
// attachments' related activities automatically
|
||||
file.source = 'import';
|
||||
if (error) {
|
||||
throw(error);
|
||||
throw error;
|
||||
} else {
|
||||
const wekanAtt = Attachments.insert(file, () => {
|
||||
// we do nothing
|
||||
});
|
||||
self.attachmentIds[att.id] = wekanAtt._id;
|
||||
//
|
||||
if(trelloCoverId === att.id) {
|
||||
Cards.direct.update(cardId, { $set: {coverId: wekanAtt._id}});
|
||||
if (trelloCoverId === att.id) {
|
||||
Cards.direct.update(cardId, {
|
||||
$set: { coverId: wekanAtt._id },
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -357,7 +378,7 @@ export class TrelloCreator {
|
|||
|
||||
// Create labels if they do not exist and load this.labels.
|
||||
createLabels(trelloLabels, board) {
|
||||
trelloLabels.forEach((label) => {
|
||||
trelloLabels.forEach(label => {
|
||||
const color = label.color;
|
||||
const name = label.name;
|
||||
const existingLabel = board.getLabel(name, color);
|
||||
|
|
@ -371,7 +392,7 @@ export class TrelloCreator {
|
|||
}
|
||||
|
||||
createLists(trelloLists, boardId) {
|
||||
trelloLists.forEach((list) => {
|
||||
trelloLists.forEach(list => {
|
||||
const listToCreate = {
|
||||
archived: list.closed,
|
||||
boardId,
|
||||
|
|
@ -384,7 +405,7 @@ export class TrelloCreator {
|
|||
sort: list.pos,
|
||||
};
|
||||
const listId = Lists.direct.insert(listToCreate);
|
||||
Lists.direct.update(listId, {$set: {'updatedAt': this._now()}});
|
||||
Lists.direct.update(listId, { $set: { updatedAt: this._now() } });
|
||||
this.lists[list.id] = listId;
|
||||
// log activity
|
||||
// Activities.direct.insert({
|
||||
|
|
@ -416,12 +437,12 @@ export class TrelloCreator {
|
|||
sort: 1,
|
||||
};
|
||||
const swimlaneId = Swimlanes.direct.insert(swimlaneToCreate);
|
||||
Swimlanes.direct.update(swimlaneId, {$set: {'updatedAt': this._now()}});
|
||||
Swimlanes.direct.update(swimlaneId, { $set: { updatedAt: this._now() } });
|
||||
this.swimlane = swimlaneId;
|
||||
}
|
||||
|
||||
createChecklists(trelloChecklists) {
|
||||
trelloChecklists.forEach((checklist) => {
|
||||
trelloChecklists.forEach(checklist => {
|
||||
if (this.cards[checklist.idCard]) {
|
||||
// Create the checklist
|
||||
const checklistToCreate = {
|
||||
|
|
@ -435,7 +456,7 @@ export class TrelloCreator {
|
|||
this.checklists[checklist.id] = checklistId;
|
||||
// Now add the items to the checklistItems
|
||||
let counter = 0;
|
||||
checklist.checkItems.forEach((item) => {
|
||||
checklist.checkItems.forEach(item => {
|
||||
counter++;
|
||||
const checklistItemTocreate = {
|
||||
_id: checklistId + counter,
|
||||
|
|
@ -458,15 +479,15 @@ export class TrelloCreator {
|
|||
getColor(trelloColorCode) {
|
||||
// trello color name => wekan color
|
||||
const mapColors = {
|
||||
'blue': 'belize',
|
||||
'orange': 'pumpkin',
|
||||
'green': 'nephritis',
|
||||
'red': 'pomegranate',
|
||||
'purple': 'wisteria',
|
||||
'pink': 'pomegranate',
|
||||
'lime': 'nephritis',
|
||||
'sky': 'belize',
|
||||
'grey': 'midnight',
|
||||
blue: 'belize',
|
||||
orange: 'pumpkin',
|
||||
green: 'nephritis',
|
||||
red: 'pomegranate',
|
||||
purple: 'wisteria',
|
||||
pink: 'pomegranate',
|
||||
lime: 'nephritis',
|
||||
sky: 'belize',
|
||||
grey: 'midnight',
|
||||
};
|
||||
const wekanColor = mapColors[trelloColorCode];
|
||||
return wekanColor || Boards.simpleSchema()._schema.color.allowedValues[0];
|
||||
|
|
@ -482,7 +503,7 @@ export class TrelloCreator {
|
|||
}
|
||||
|
||||
parseActions(trelloActions) {
|
||||
trelloActions.forEach((action) => {
|
||||
trelloActions.forEach(action => {
|
||||
if (action.type === 'addAttachmentToCard') {
|
||||
// We have to be cautious, because the attachment could have been removed later.
|
||||
// In that case Trello still reports its addition, but removes its 'url' field.
|
||||
|
|
@ -490,11 +511,11 @@ export class TrelloCreator {
|
|||
const trelloAttachment = action.data.attachment;
|
||||
// We need the idMemberCreator
|
||||
trelloAttachment.idMemberCreator = action.idMemberCreator;
|
||||
if(trelloAttachment.url) {
|
||||
if (trelloAttachment.url) {
|
||||
// we cannot actually create the Wekan attachment, because we don't yet
|
||||
// have the cards to attach it to, so we store it in the instance variable.
|
||||
const trelloCardId = action.data.card.id;
|
||||
if(!this.attachments[trelloCardId]) {
|
||||
if (!this.attachments[trelloCardId]) {
|
||||
this.attachments[trelloCardId] = [];
|
||||
}
|
||||
this.attachments[trelloCardId].push(trelloAttachment);
|
||||
|
|
@ -520,88 +541,89 @@ export class TrelloCreator {
|
|||
}
|
||||
|
||||
importActions(actions, boardId) {
|
||||
actions.forEach((action) => {
|
||||
actions.forEach(action => {
|
||||
switch (action.type) {
|
||||
// Board related actions
|
||||
// TODO: addBoardMember, removeBoardMember
|
||||
case 'createBoard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
type: 'board',
|
||||
activityTypeId: boardId,
|
||||
activityType: 'createBoard',
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// List related activities
|
||||
// TODO: removeList, archivedList
|
||||
case 'createList': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
type: 'list',
|
||||
activityType: 'createList',
|
||||
listId: this.lists[action.data.list.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Card related activities
|
||||
// TODO: archivedCard, restoredCard, joinMember, unjoinMember
|
||||
case 'createCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
activityType: 'createCard',
|
||||
listId: this.lists[action.data.list.id],
|
||||
cardId: this.cards[action.data.card.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'updateCard': {
|
||||
if (action.data.old.idList) {
|
||||
// Board related actions
|
||||
// TODO: addBoardMember, removeBoardMember
|
||||
case 'createBoard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
oldListId: this.lists[action.data.old.idList],
|
||||
activityType: 'moveCard',
|
||||
listId: this.lists[action.data.listAfter.id],
|
||||
type: 'board',
|
||||
activityTypeId: boardId,
|
||||
activityType: 'createBoard',
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// List related activities
|
||||
// TODO: removeList, archivedList
|
||||
case 'createList': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
type: 'list',
|
||||
activityType: 'createList',
|
||||
listId: this.lists[action.data.list.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Card related activities
|
||||
// TODO: archivedCard, restoredCard, joinMember, unjoinMember
|
||||
case 'createCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
activityType: 'createCard',
|
||||
listId: this.lists[action.data.list.id],
|
||||
cardId: this.cards[action.data.card.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'updateCard': {
|
||||
if (action.data.old.idList) {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
oldListId: this.lists[action.data.old.idList],
|
||||
activityType: 'moveCard',
|
||||
listId: this.lists[action.data.listAfter.id],
|
||||
cardId: this.cards[action.data.card.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Comment related activities
|
||||
// Trello doesn't export the comment id
|
||||
// Attachment related activities
|
||||
case 'addAttachmentToCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
type: 'card',
|
||||
activityType: 'addAttachment',
|
||||
attachmentId: this.attachmentIds[action.data.attachment.id],
|
||||
cardId: this.cards[action.data.card.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Checklist related activities
|
||||
case 'addChecklistToCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
activityType: 'addChecklist',
|
||||
cardId: this.cards[action.data.card.id],
|
||||
checklistId: this.checklists[action.data.checklist.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Comment related activities
|
||||
// Trello doesn't export the comment id
|
||||
// Attachment related activities
|
||||
case 'addAttachmentToCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
type: 'card',
|
||||
activityType: 'addAttachment',
|
||||
attachmentId: this.attachmentIds[action.data.attachment.id],
|
||||
cardId: this.cards[action.data.card.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Checklist related activities
|
||||
case 'addChecklistToCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(action.idMemberCreator),
|
||||
activityType: 'addChecklist',
|
||||
cardId: this.cards[action.data.card.id],
|
||||
checklistId: this.checklists[action.data.checklist.id],
|
||||
boardId,
|
||||
createdAt: this._now(action.date),
|
||||
});
|
||||
break;
|
||||
}}
|
||||
// Trello doesn't have an add checklist item action
|
||||
});
|
||||
}
|
||||
|
|
@ -624,7 +646,9 @@ export class TrelloCreator {
|
|||
|
||||
create(board, currentBoardId) {
|
||||
// TODO : Make isSandstorm variable global
|
||||
const isSandstorm = Meteor.settings && Meteor.settings.public &&
|
||||
const isSandstorm =
|
||||
Meteor.settings &&
|
||||
Meteor.settings.public &&
|
||||
Meteor.settings.public.sandstorm;
|
||||
if (isSandstorm && currentBoardId) {
|
||||
const currentBoard = Boards.findOne(currentBoardId);
|
||||
|
|
|
|||
|
|
@ -51,18 +51,13 @@ Triggers.helpers({
|
|||
|
||||
labels() {
|
||||
const boardLabels = this.board().labels;
|
||||
const cardLabels = _.filter(boardLabels, (label) => {
|
||||
const cardLabels = _.filter(boardLabels, label => {
|
||||
return _.contains(this.labelIds, label._id);
|
||||
});
|
||||
return cardLabels;
|
||||
},
|
||||
});
|
||||
|
||||
Triggers.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
Triggers._collection._ensureIndex({ modifiedAt: -1 });
|
||||
|
|
|
|||
|
|
@ -46,14 +46,7 @@ UnsavedEditCollection.attachSchema(
|
|||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
UnsavedEditCollection.before.update(
|
||||
(userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
if (Meteor.isServer) {
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ Users.attachSchema(
|
|||
optional: false,
|
||||
defaultValue: 'password',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
Users.allow({
|
||||
|
|
@ -259,7 +259,7 @@ Users.allow({
|
|||
const adminsNumber = Users.find({ isAdmin: true }).count();
|
||||
const { isAdmin } = Users.findOne(
|
||||
{ _id: userId },
|
||||
{ fields: { isAdmin: 1 } }
|
||||
{ fields: { isAdmin: 1 } },
|
||||
);
|
||||
|
||||
// Prevents remove of the only one administrator
|
||||
|
|
@ -533,7 +533,7 @@ Meteor.methods({
|
|||
check(email, String);
|
||||
const existingUser = Users.findOne(
|
||||
{ 'emails.address': email },
|
||||
{ fields: { _id: 1 } }
|
||||
{ fields: { _id: 1 } },
|
||||
);
|
||||
if (existingUser) {
|
||||
throw new Meteor.Error('email-already-taken');
|
||||
|
|
@ -700,7 +700,7 @@ if (Meteor.isServer) {
|
|||
if (!options || !options.profile) {
|
||||
throw new Meteor.Error(
|
||||
'error-invitation-code-blank',
|
||||
'The invitation code is required'
|
||||
'The invitation code is required',
|
||||
);
|
||||
}
|
||||
const invitationCode = InvitationCodes.findOne({
|
||||
|
|
@ -711,7 +711,8 @@ if (Meteor.isServer) {
|
|||
if (!invitationCode) {
|
||||
throw new Meteor.Error(
|
||||
'error-invitation-code-not-exist',
|
||||
'The invitation code doesn\'t exist'
|
||||
// eslint-disable-next-line quotes
|
||||
"The invitation code doesn't exist",
|
||||
);
|
||||
} else {
|
||||
user.profile = { icode: options.profile.invitationcode };
|
||||
|
|
@ -722,18 +723,13 @@ if (Meteor.isServer) {
|
|||
Meteor.bindEnvironment(() => {
|
||||
InvitationCodes.remove({ _id: invitationCode._id });
|
||||
}),
|
||||
200
|
||||
200,
|
||||
);
|
||||
return user;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Users.before.update((userId, doc, fieldNames, modifier, options) => {
|
||||
modifier.$set = modifier.$set || {};
|
||||
modifier.$set.modifiedAt = Date.now();
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// Let mongoDB ensure username unicity
|
||||
Meteor.startup(() => {
|
||||
|
|
@ -742,7 +738,7 @@ if (Meteor.isServer) {
|
|||
{
|
||||
username: 1,
|
||||
},
|
||||
{ unique: true }
|
||||
{ unique: true },
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -786,7 +782,7 @@ if (Meteor.isServer) {
|
|||
// b. We use it to find deleted and newly inserted ids by using it in one
|
||||
// direction and then in the other.
|
||||
function incrementBoards(boardsIds, inc) {
|
||||
boardsIds.forEach((boardId) => {
|
||||
boardsIds.forEach(boardId => {
|
||||
Boards.update(boardId, { $inc: { stars: inc } });
|
||||
});
|
||||
}
|
||||
|
|
@ -855,7 +851,7 @@ if (Meteor.isServer) {
|
|||
Users.update(fakeUserId.get(), {
|
||||
$set: { 'profile.cardTemplatesSwimlaneId': swimlaneId },
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Insert the list templates swimlane
|
||||
|
|
@ -872,7 +868,7 @@ if (Meteor.isServer) {
|
|||
Users.update(fakeUserId.get(), {
|
||||
$set: { 'profile.listTemplatesSwimlaneId': swimlaneId },
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Insert the board templates swimlane
|
||||
|
|
@ -889,9 +885,9 @@ if (Meteor.isServer) {
|
|||
Users.update(fakeUserId.get(), {
|
||||
$set: { 'profile.boardTemplatesSwimlaneId': swimlaneId },
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -921,7 +917,7 @@ if (Meteor.isServer) {
|
|||
if (!invitationCode) {
|
||||
throw new Meteor.Error('error-invitation-code-not-exist');
|
||||
} else {
|
||||
invitationCode.boardsToBeInvited.forEach((boardId) => {
|
||||
invitationCode.boardsToBeInvited.forEach(boardId => {
|
||||
const board = Boards.findOne(boardId);
|
||||
board.addMember(doc._id);
|
||||
});
|
||||
|
|
@ -1071,7 +1067,7 @@ if (Meteor.isServer) {
|
|||
loginDisabled: true,
|
||||
'services.resume.loginTokens': '',
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} else if (action === 'enableLogin') {
|
||||
Users.update({ _id: id }, { $set: { loginDisabled: '' } });
|
||||
|
|
@ -1112,7 +1108,7 @@ if (Meteor.isServer) {
|
|||
*/
|
||||
JsonRoutes.add('POST', '/api/boards/:boardId/members/:userId/add', function(
|
||||
req,
|
||||
res
|
||||
res,
|
||||
) {
|
||||
try {
|
||||
Authentication.checkUserId(req.userId);
|
||||
|
|
@ -1136,7 +1132,7 @@ if (Meteor.isServer) {
|
|||
isTrue(isAdmin),
|
||||
isTrue(isNoComments),
|
||||
isTrue(isCommentOnly),
|
||||
userId
|
||||
userId,
|
||||
);
|
||||
}
|
||||
return {
|
||||
|
|
@ -1207,7 +1203,7 @@ if (Meteor.isServer) {
|
|||
data: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// simple version, only toggle watch / unwatch
|
||||
const simpleWatchable = (collection) => {
|
||||
const simpleWatchable = collection => {
|
||||
collection.attachSchema({
|
||||
watchers: {
|
||||
type: [String],
|
||||
|
|
@ -24,8 +24,8 @@ const simpleWatchable = (collection) => {
|
|||
collection.mutations({
|
||||
setWatcher(userId, level) {
|
||||
// if level undefined or null or false, then remove
|
||||
if (!level) return { $pull: { watchers: userId }};
|
||||
return { $addToSet: { watchers: userId }};
|
||||
if (!level) return { $pull: { watchers: userId } };
|
||||
return { $addToSet: { watchers: userId } };
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -34,7 +34,7 @@ const simpleWatchable = (collection) => {
|
|||
const complexWatchOptions = ['watching', 'tracking', 'muted'];
|
||||
const complexWatchDefault = 'muted';
|
||||
|
||||
const complexWatchable = (collection) => {
|
||||
const complexWatchable = collection => {
|
||||
collection.attachSchema({
|
||||
'watchers.$.userId': {
|
||||
type: String,
|
||||
|
|
@ -72,9 +72,9 @@ const complexWatchable = (collection) => {
|
|||
setWatcher(userId, level) {
|
||||
// if level undefined or null or false, then remove
|
||||
if (level === complexWatchDefault) level = null;
|
||||
if (!level) return { $pull: { watchers: { userId }}};
|
||||
if (!level) return { $pull: { watchers: { userId } } };
|
||||
const index = this.watcherIndex(userId);
|
||||
if (index<0) return { $push: { watchers: { userId, level }}};
|
||||
if (index < 0) return { $push: { watchers: { userId, level } } };
|
||||
return {
|
||||
$set: {
|
||||
[`watchers.${index}.level`]: level,
|
||||
|
|
|
|||
|
|
@ -87,99 +87,120 @@ export class WekanCreator {
|
|||
}
|
||||
|
||||
checkActivities(wekanActivities) {
|
||||
check(wekanActivities, [Match.ObjectIncluding({
|
||||
activityType: String,
|
||||
createdAt: DateString,
|
||||
})]);
|
||||
check(wekanActivities, [
|
||||
Match.ObjectIncluding({
|
||||
activityType: String,
|
||||
createdAt: DateString,
|
||||
}),
|
||||
]);
|
||||
// XXX we could perform more thorough checks based on action type
|
||||
}
|
||||
|
||||
checkBoard(wekanBoard) {
|
||||
check(wekanBoard, Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
title: String,
|
||||
// XXX refine control by validating 'color' against a list of
|
||||
// allowed values (is it worth the maintenance?)
|
||||
color: String,
|
||||
permission: Match.Where((value) => {
|
||||
return ['private', 'public'].indexOf(value) >= 0;
|
||||
check(
|
||||
wekanBoard,
|
||||
Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
title: String,
|
||||
// XXX refine control by validating 'color' against a list of
|
||||
// allowed values (is it worth the maintenance?)
|
||||
color: String,
|
||||
permission: Match.Where(value => {
|
||||
return ['private', 'public'].indexOf(value) >= 0;
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
);
|
||||
}
|
||||
|
||||
checkCards(wekanCards) {
|
||||
check(wekanCards, [Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
dateLastActivity: DateString,
|
||||
labelIds: [String],
|
||||
title: String,
|
||||
sort: Number,
|
||||
})]);
|
||||
check(wekanCards, [
|
||||
Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
dateLastActivity: DateString,
|
||||
labelIds: [String],
|
||||
title: String,
|
||||
sort: Number,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkLabels(wekanLabels) {
|
||||
check(wekanLabels, [Match.ObjectIncluding({
|
||||
// XXX refine control by validating 'color' against a list of allowed
|
||||
// values (is it worth the maintenance?)
|
||||
color: String,
|
||||
})]);
|
||||
check(wekanLabels, [
|
||||
Match.ObjectIncluding({
|
||||
// XXX refine control by validating 'color' against a list of allowed
|
||||
// values (is it worth the maintenance?)
|
||||
color: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkLists(wekanLists) {
|
||||
check(wekanLists, [Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
title: String,
|
||||
})]);
|
||||
check(wekanLists, [
|
||||
Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
title: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkSwimlanes(wekanSwimlanes) {
|
||||
check(wekanSwimlanes, [Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
title: String,
|
||||
})]);
|
||||
check(wekanSwimlanes, [
|
||||
Match.ObjectIncluding({
|
||||
archived: Boolean,
|
||||
title: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkChecklists(wekanChecklists) {
|
||||
check(wekanChecklists, [Match.ObjectIncluding({
|
||||
cardId: String,
|
||||
title: String,
|
||||
})]);
|
||||
check(wekanChecklists, [
|
||||
Match.ObjectIncluding({
|
||||
cardId: String,
|
||||
title: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkChecklistItems(wekanChecklistItems) {
|
||||
check(wekanChecklistItems, [Match.ObjectIncluding({
|
||||
cardId: String,
|
||||
title: String,
|
||||
})]);
|
||||
check(wekanChecklistItems, [
|
||||
Match.ObjectIncluding({
|
||||
cardId: String,
|
||||
title: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkRules(wekanRules) {
|
||||
check(wekanRules, [Match.ObjectIncluding({
|
||||
triggerId: String,
|
||||
actionId: String,
|
||||
title: String,
|
||||
})]);
|
||||
check(wekanRules, [
|
||||
Match.ObjectIncluding({
|
||||
triggerId: String,
|
||||
actionId: String,
|
||||
title: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
checkTriggers(wekanTriggers) {
|
||||
// XXX More check based on trigger type
|
||||
check(wekanTriggers, [Match.ObjectIncluding({
|
||||
activityType: String,
|
||||
desc: String,
|
||||
})]);
|
||||
check(wekanTriggers, [
|
||||
Match.ObjectIncluding({
|
||||
activityType: String,
|
||||
desc: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
getMembersToMap(data) {
|
||||
// we will work on the list itself (an ordered array of objects) when a
|
||||
// mapping is done, we add a 'wekan' field to the object representing the
|
||||
// imported member
|
||||
// we will work on the list itself (an ordered array of objects) when a
|
||||
// mapping is done, we add a 'wekan' field to the object representing the
|
||||
// imported member
|
||||
const membersToMap = data.members;
|
||||
const users = data.users;
|
||||
// auto-map based on username
|
||||
membersToMap.forEach((importedMember) => {
|
||||
membersToMap.forEach(importedMember => {
|
||||
importedMember.id = importedMember.userId;
|
||||
delete importedMember.userId;
|
||||
const user = users.filter((user) => {
|
||||
const user = users.filter(user => {
|
||||
return user._id === importedMember.id;
|
||||
})[0];
|
||||
if (user.profile && user.profile.fullname) {
|
||||
|
|
@ -196,10 +217,12 @@ export class WekanCreator {
|
|||
|
||||
checkActions(wekanActions) {
|
||||
// XXX More check based on action type
|
||||
check(wekanActions, [Match.ObjectIncluding({
|
||||
actionType: String,
|
||||
desc: String,
|
||||
})]);
|
||||
check(wekanActions, [
|
||||
Match.ObjectIncluding({
|
||||
actionType: String,
|
||||
desc: String,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
// You must call parseActions before calling this one.
|
||||
|
|
@ -210,15 +233,17 @@ export class WekanCreator {
|
|||
// very old boards won't have a creation activity so no creation date
|
||||
createdAt: this._now(boardToImport.createdAt),
|
||||
labels: [],
|
||||
members: [{
|
||||
userId: Meteor.userId(),
|
||||
wekanId: Meteor.userId(),
|
||||
isActive: true,
|
||||
isAdmin: true,
|
||||
isNoComments: false,
|
||||
isCommentOnly: false,
|
||||
swimlaneId: false,
|
||||
}],
|
||||
members: [
|
||||
{
|
||||
userId: Meteor.userId(),
|
||||
wekanId: Meteor.userId(),
|
||||
isActive: true,
|
||||
isAdmin: true,
|
||||
isNoComments: false,
|
||||
isCommentOnly: false,
|
||||
swimlaneId: false,
|
||||
},
|
||||
],
|
||||
// Standalone Export has modifiedAt missing, adding modifiedAt to fix it
|
||||
modifiedAt: this._now(boardToImport.modifiedAt),
|
||||
permission: boardToImport.permission,
|
||||
|
|
@ -228,16 +253,20 @@ export class WekanCreator {
|
|||
};
|
||||
// now add other members
|
||||
if (boardToImport.members) {
|
||||
boardToImport.members.forEach((wekanMember) => {
|
||||
boardToImport.members.forEach(wekanMember => {
|
||||
// do we already have it in our list?
|
||||
if (!boardToCreate.members.some((member) => member.wekanId === wekanMember.wekanId))
|
||||
if (
|
||||
!boardToCreate.members.some(
|
||||
member => member.wekanId === wekanMember.wekanId,
|
||||
)
|
||||
)
|
||||
boardToCreate.members.push({
|
||||
...wekanMember,
|
||||
userId: wekanMember.wekanId,
|
||||
});
|
||||
});
|
||||
}
|
||||
boardToImport.labels.forEach((label) => {
|
||||
boardToImport.labels.forEach(label => {
|
||||
const labelToCreate = {
|
||||
_id: Random.id(6),
|
||||
color: label.color,
|
||||
|
|
@ -279,7 +308,7 @@ export class WekanCreator {
|
|||
*/
|
||||
createCards(wekanCards, boardId) {
|
||||
const result = [];
|
||||
wekanCards.forEach((card) => {
|
||||
wekanCards.forEach(card => {
|
||||
const cardToCreate = {
|
||||
archived: card.archived,
|
||||
boardId,
|
||||
|
|
@ -300,7 +329,7 @@ export class WekanCreator {
|
|||
};
|
||||
// add labels
|
||||
if (card.labelIds) {
|
||||
cardToCreate.labelIds = card.labelIds.map((wekanId) => {
|
||||
cardToCreate.labelIds = card.labelIds.map(wekanId => {
|
||||
return this.labels[wekanId];
|
||||
});
|
||||
}
|
||||
|
|
@ -308,12 +337,12 @@ export class WekanCreator {
|
|||
if (card.members) {
|
||||
const wekanMembers = [];
|
||||
// we can't just map, as some members may not have been mapped
|
||||
card.members.forEach((sourceMemberId) => {
|
||||
card.members.forEach(sourceMemberId => {
|
||||
if (this.members[sourceMemberId]) {
|
||||
const wekanId = this.members[sourceMemberId];
|
||||
// we may map multiple Wekan members to the same wekan user
|
||||
// in which case we risk adding the same user multiple times
|
||||
if (!wekanMembers.find((wId) => wId === wekanId)) {
|
||||
if (!wekanMembers.find(wId => wId === wekanId)) {
|
||||
wekanMembers.push(wekanId);
|
||||
}
|
||||
}
|
||||
|
|
@ -349,7 +378,7 @@ export class WekanCreator {
|
|||
// add comments
|
||||
const comments = this.comments[card._id];
|
||||
if (comments) {
|
||||
comments.forEach((comment) => {
|
||||
comments.forEach(comment => {
|
||||
const commentToCreate = {
|
||||
boardId,
|
||||
cardId,
|
||||
|
|
@ -377,7 +406,7 @@ export class WekanCreator {
|
|||
const attachments = this.attachments[card._id];
|
||||
const wekanCoverId = card.coverId;
|
||||
if (attachments) {
|
||||
attachments.forEach((att) => {
|
||||
attachments.forEach(att => {
|
||||
const file = new FS.File();
|
||||
// Simulating file.attachData on the client generates multiple errors
|
||||
// - HEAD returns null, which causes exception down the line
|
||||
|
|
@ -394,7 +423,7 @@ export class WekanCreator {
|
|||
// attachments' related activities automatically
|
||||
file.source = 'import';
|
||||
if (error) {
|
||||
throw (error);
|
||||
throw error;
|
||||
} else {
|
||||
const wekanAtt = Attachments.insert(file, () => {
|
||||
// we do nothing
|
||||
|
|
@ -411,33 +440,37 @@ export class WekanCreator {
|
|||
}
|
||||
});
|
||||
} else if (att.file) {
|
||||
file.attachData(new Buffer(att.file, 'base64'), {
|
||||
type: att.type,
|
||||
}, (error) => {
|
||||
file.name(att.name);
|
||||
file.boardId = boardId;
|
||||
file.cardId = cardId;
|
||||
file.userId = self._user(att.userId);
|
||||
// The field source will only be used to prevent adding
|
||||
// attachments' related activities automatically
|
||||
file.source = 'import';
|
||||
if (error) {
|
||||
throw (error);
|
||||
} else {
|
||||
const wekanAtt = Attachments.insert(file, () => {
|
||||
// we do nothing
|
||||
});
|
||||
this.attachmentIds[att._id] = wekanAtt._id;
|
||||
//
|
||||
if (wekanCoverId === att._id) {
|
||||
Cards.direct.update(cardId, {
|
||||
$set: {
|
||||
coverId: wekanAtt._id,
|
||||
},
|
||||
file.attachData(
|
||||
new Buffer(att.file, 'base64'),
|
||||
{
|
||||
type: att.type,
|
||||
},
|
||||
error => {
|
||||
file.name(att.name);
|
||||
file.boardId = boardId;
|
||||
file.cardId = cardId;
|
||||
file.userId = self._user(att.userId);
|
||||
// The field source will only be used to prevent adding
|
||||
// attachments' related activities automatically
|
||||
file.source = 'import';
|
||||
if (error) {
|
||||
throw error;
|
||||
} else {
|
||||
const wekanAtt = Attachments.insert(file, () => {
|
||||
// we do nothing
|
||||
});
|
||||
this.attachmentIds[att._id] = wekanAtt._id;
|
||||
//
|
||||
if (wekanCoverId === att._id) {
|
||||
Cards.direct.update(cardId, {
|
||||
$set: {
|
||||
coverId: wekanAtt._id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
// todo XXX set cover - if need be
|
||||
|
|
@ -450,7 +483,7 @@ export class WekanCreator {
|
|||
|
||||
// Create labels if they do not exist and load this.labels.
|
||||
createLabels(wekanLabels, board) {
|
||||
wekanLabels.forEach((label) => {
|
||||
wekanLabels.forEach(label => {
|
||||
const color = label.color;
|
||||
const name = label.name;
|
||||
const existingLabel = board.getLabel(name, color);
|
||||
|
|
@ -479,7 +512,7 @@ export class WekanCreator {
|
|||
const listId = Lists.direct.insert(listToCreate);
|
||||
Lists.direct.update(listId, {
|
||||
$set: {
|
||||
'updatedAt': this._now(),
|
||||
updatedAt: this._now(),
|
||||
},
|
||||
});
|
||||
this.lists[list._id] = listId;
|
||||
|
|
@ -520,7 +553,7 @@ export class WekanCreator {
|
|||
const swimlaneId = Swimlanes.direct.insert(swimlaneToCreate);
|
||||
Swimlanes.direct.update(swimlaneId, {
|
||||
$set: {
|
||||
'updatedAt': this._now(),
|
||||
updatedAt: this._now(),
|
||||
},
|
||||
});
|
||||
this.swimlanes[swimlane._id] = swimlaneId;
|
||||
|
|
@ -545,7 +578,7 @@ export class WekanCreator {
|
|||
}
|
||||
|
||||
createTriggers(wekanTriggers, boardId) {
|
||||
wekanTriggers.forEach((trigger) => {
|
||||
wekanTriggers.forEach(trigger => {
|
||||
if (trigger.hasOwnProperty('labelId')) {
|
||||
trigger.labelId = this.labels[trigger.labelId];
|
||||
}
|
||||
|
|
@ -560,7 +593,7 @@ export class WekanCreator {
|
|||
}
|
||||
|
||||
createActions(wekanActions, boardId) {
|
||||
wekanActions.forEach((action) => {
|
||||
wekanActions.forEach(action => {
|
||||
if (action.hasOwnProperty('labelId')) {
|
||||
action.labelId = this.labels[action.labelId];
|
||||
}
|
||||
|
|
@ -575,7 +608,7 @@ export class WekanCreator {
|
|||
}
|
||||
|
||||
createRules(wekanRules, boardId) {
|
||||
wekanRules.forEach((rule) => {
|
||||
wekanRules.forEach(rule => {
|
||||
// Create the rule
|
||||
rule.boardId = boardId;
|
||||
rule.triggerId = this.triggers[rule.triggerId];
|
||||
|
|
@ -595,189 +628,178 @@ export class WekanCreator {
|
|||
sort: checklistitem.sort ? checklistitem.sort : checklistitemIndex,
|
||||
isFinished: checklistitem.isFinished,
|
||||
};
|
||||
const checklistItemId = ChecklistItems.direct.insert(checklistItemTocreate);
|
||||
const checklistItemId = ChecklistItems.direct.insert(
|
||||
checklistItemTocreate,
|
||||
);
|
||||
this.checklistItems[checklistitem._id] = checklistItemId;
|
||||
});
|
||||
}
|
||||
|
||||
parseActivities(wekanBoard) {
|
||||
wekanBoard.activities.forEach((activity) => {
|
||||
wekanBoard.activities.forEach(activity => {
|
||||
switch (activity.activityType) {
|
||||
case 'addAttachment':
|
||||
{
|
||||
// We have to be cautious, because the attachment could have been removed later.
|
||||
// In that case Wekan still reports its addition, but removes its 'url' field.
|
||||
// So we test for that
|
||||
const wekanAttachment = wekanBoard.attachments.filter((attachment) => {
|
||||
return attachment._id === activity.attachmentId;
|
||||
})[0];
|
||||
case 'addAttachment': {
|
||||
// We have to be cautious, because the attachment could have been removed later.
|
||||
// In that case Wekan still reports its addition, but removes its 'url' field.
|
||||
// So we test for that
|
||||
const wekanAttachment = wekanBoard.attachments.filter(attachment => {
|
||||
return attachment._id === activity.attachmentId;
|
||||
})[0];
|
||||
|
||||
if (typeof wekanAttachment !== 'undefined' && wekanAttachment) {
|
||||
if (wekanAttachment.url || wekanAttachment.file) {
|
||||
// we cannot actually create the Wekan attachment, because we don't yet
|
||||
// have the cards to attach it to, so we store it in the instance variable.
|
||||
const wekanCardId = activity.cardId;
|
||||
if (!this.attachments[wekanCardId]) {
|
||||
this.attachments[wekanCardId] = [];
|
||||
if (typeof wekanAttachment !== 'undefined' && wekanAttachment) {
|
||||
if (wekanAttachment.url || wekanAttachment.file) {
|
||||
// we cannot actually create the Wekan attachment, because we don't yet
|
||||
// have the cards to attach it to, so we store it in the instance variable.
|
||||
const wekanCardId = activity.cardId;
|
||||
if (!this.attachments[wekanCardId]) {
|
||||
this.attachments[wekanCardId] = [];
|
||||
}
|
||||
this.attachments[wekanCardId].push(wekanAttachment);
|
||||
}
|
||||
this.attachments[wekanCardId].push(wekanAttachment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'addComment':
|
||||
{
|
||||
const wekanComment = wekanBoard.comments.filter((comment) => {
|
||||
return comment._id === activity.commentId;
|
||||
})[0];
|
||||
const id = activity.cardId;
|
||||
if (!this.comments[id]) {
|
||||
this.comments[id] = [];
|
||||
case 'addComment': {
|
||||
const wekanComment = wekanBoard.comments.filter(comment => {
|
||||
return comment._id === activity.commentId;
|
||||
})[0];
|
||||
const id = activity.cardId;
|
||||
if (!this.comments[id]) {
|
||||
this.comments[id] = [];
|
||||
}
|
||||
this.comments[id].push(wekanComment);
|
||||
break;
|
||||
}
|
||||
case 'createBoard': {
|
||||
this.createdAt.board = activity.createdAt;
|
||||
break;
|
||||
}
|
||||
case 'createCard': {
|
||||
const cardId = activity.cardId;
|
||||
this.createdAt.cards[cardId] = activity.createdAt;
|
||||
this.createdBy.cards[cardId] = activity.userId;
|
||||
break;
|
||||
}
|
||||
case 'createList': {
|
||||
const listId = activity.listId;
|
||||
this.createdAt.lists[listId] = activity.createdAt;
|
||||
break;
|
||||
}
|
||||
case 'createSwimlane': {
|
||||
const swimlaneId = activity.swimlaneId;
|
||||
this.createdAt.swimlanes[swimlaneId] = activity.createdAt;
|
||||
break;
|
||||
}
|
||||
this.comments[id].push(wekanComment);
|
||||
break;
|
||||
}
|
||||
case 'createBoard':
|
||||
{
|
||||
this.createdAt.board = activity.createdAt;
|
||||
break;
|
||||
}
|
||||
case 'createCard':
|
||||
{
|
||||
const cardId = activity.cardId;
|
||||
this.createdAt.cards[cardId] = activity.createdAt;
|
||||
this.createdBy.cards[cardId] = activity.userId;
|
||||
break;
|
||||
}
|
||||
case 'createList':
|
||||
{
|
||||
const listId = activity.listId;
|
||||
this.createdAt.lists[listId] = activity.createdAt;
|
||||
break;
|
||||
}
|
||||
case 'createSwimlane':
|
||||
{
|
||||
const swimlaneId = activity.swimlaneId;
|
||||
this.createdAt.swimlanes[swimlaneId] = activity.createdAt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
importActivities(activities, boardId) {
|
||||
activities.forEach((activity) => {
|
||||
activities.forEach(activity => {
|
||||
switch (activity.activityType) {
|
||||
// Board related activities
|
||||
// TODO: addBoardMember, removeBoardMember
|
||||
case 'createBoard':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
type: 'board',
|
||||
activityTypeId: boardId,
|
||||
activityType: activity.activityType,
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// List related activities
|
||||
// TODO: removeList, archivedList
|
||||
case 'createList':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
type: 'list',
|
||||
activityType: activity.activityType,
|
||||
listId: this.lists[activity.listId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Card related activities
|
||||
// TODO: archivedCard, restoredCard, joinMember, unjoinMember
|
||||
case 'createCard':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
listId: this.lists[activity.listId],
|
||||
cardId: this.cards[activity.cardId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'moveCard':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
oldListId: this.lists[activity.oldListId],
|
||||
activityType: activity.activityType,
|
||||
listId: this.lists[activity.listId],
|
||||
cardId: this.cards[activity.cardId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Comment related activities
|
||||
case 'addComment':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
cardId: this.cards[activity.cardId],
|
||||
commentId: this.commentIds[activity.commentId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Attachment related activities
|
||||
case 'addAttachment':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
type: 'card',
|
||||
activityType: activity.activityType,
|
||||
attachmentId: this.attachmentIds[activity.attachmentId],
|
||||
cardId: this.cards[activity.cardId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Checklist related activities
|
||||
case 'addChecklist':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
cardId: this.cards[activity.cardId],
|
||||
checklistId: this.checklists[activity.checklistId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'addChecklistItem':
|
||||
{
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
cardId: this.cards[activity.cardId],
|
||||
checklistId: this.checklists[activity.checklistId],
|
||||
checklistItemId: activity.checklistItemId.replace(
|
||||
activity.checklistId,
|
||||
this.checklists[activity.checklistId]),
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Board related activities
|
||||
// TODO: addBoardMember, removeBoardMember
|
||||
case 'createBoard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
type: 'board',
|
||||
activityTypeId: boardId,
|
||||
activityType: activity.activityType,
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// List related activities
|
||||
// TODO: removeList, archivedList
|
||||
case 'createList': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
type: 'list',
|
||||
activityType: activity.activityType,
|
||||
listId: this.lists[activity.listId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Card related activities
|
||||
// TODO: archivedCard, restoredCard, joinMember, unjoinMember
|
||||
case 'createCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
listId: this.lists[activity.listId],
|
||||
cardId: this.cards[activity.cardId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'moveCard': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
oldListId: this.lists[activity.oldListId],
|
||||
activityType: activity.activityType,
|
||||
listId: this.lists[activity.listId],
|
||||
cardId: this.cards[activity.cardId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Comment related activities
|
||||
case 'addComment': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
cardId: this.cards[activity.cardId],
|
||||
commentId: this.commentIds[activity.commentId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Attachment related activities
|
||||
case 'addAttachment': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
type: 'card',
|
||||
activityType: activity.activityType,
|
||||
attachmentId: this.attachmentIds[activity.attachmentId],
|
||||
cardId: this.cards[activity.cardId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
// Checklist related activities
|
||||
case 'addChecklist': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
cardId: this.cards[activity.cardId],
|
||||
checklistId: this.checklists[activity.checklistId],
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'addChecklistItem': {
|
||||
Activities.direct.insert({
|
||||
userId: this._user(activity.userId),
|
||||
activityType: activity.activityType,
|
||||
cardId: this.cards[activity.cardId],
|
||||
checklistId: this.checklists[activity.checklistId],
|
||||
checklistItemId: activity.checklistItemId.replace(
|
||||
activity.checklistId,
|
||||
this.checklists[activity.checklistId],
|
||||
),
|
||||
boardId,
|
||||
createdAt: this._now(activity.createdAt),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -788,7 +810,6 @@ export class WekanCreator {
|
|||
// check(data, {
|
||||
// membersMapping: Match.Optional(Object),
|
||||
// });
|
||||
|
||||
// this.checkActivities(board.activities);
|
||||
// this.checkBoard(board);
|
||||
// this.checkLabels(board.labels);
|
||||
|
|
@ -807,7 +828,9 @@ export class WekanCreator {
|
|||
|
||||
create(board, currentBoardId) {
|
||||
// TODO : Make isSandstorm variable global
|
||||
const isSandstorm = Meteor.settings && Meteor.settings.public &&
|
||||
const isSandstorm =
|
||||
Meteor.settings &&
|
||||
Meteor.settings.public &&
|
||||
Meteor.settings.public.sandstorm;
|
||||
if (isSandstorm && currentBoardId) {
|
||||
const currentBoard = Boards.findOne(currentBoardId);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ export function getMembersToMap(data) {
|
|||
const membersToMap = data.members;
|
||||
const users = data.users;
|
||||
// auto-map based on username
|
||||
membersToMap.forEach((importedMember) => {
|
||||
membersToMap.forEach(importedMember => {
|
||||
importedMember.id = importedMember.userId;
|
||||
delete importedMember.userId;
|
||||
const user = users.filter((user) => {
|
||||
const user = users.filter(user => {
|
||||
return user._id === importedMember.id;
|
||||
})[0];
|
||||
if (user.profile && user.profile.fullname) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue