--- a/models/wekanCreator.js +++ b/models/wekanCreator.js @@ -323,11 +323,13 @@ class WekanCreator { // now add other members if (boardToImport.members) { - boardToImport.members.forEach(wekanMember => { - // is it defined and do we already have it in our list? - if ( - wekanMember.wekanId && - !boardToCreate.members.some( - member => member.wekanId === wekanMember.wekanId, - ) - ) - boardToCreate.members.push({ - ...wekanMember, - userId: wekanMember.wekanId, - }); - }); + // Build a Set of already-present wekanIds so dedup is O(1) per member + // instead of O(M) per member (was O(M^2) overall). + const seenWekanIds = new Set( + boardToCreate.members.map(m => m.wekanId).filter(Boolean), + ); + boardToImport.members.forEach(wekanMember => { + if (wekanMember.wekanId && !seenWekanIds.has(wekanMember.wekanId)) { + seenWekanIds.add(wekanMember.wekanId); + boardToCreate.members.push({ + ...wekanMember, + userId: wekanMember.wekanId, + }); + } + }); } @@ -410,18 +412,22 @@ class WekanCreator { // add members if (card.members) { - const wekanMembers = []; - // we can't just map, as some members may not have been mapped - 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)) { - wekanMembers.push(wekanId); - } - } - return true; - }); + // Use a Set for O(1) dedup instead of Array.find() O(M) per member. + const seenMemberIds = new Set(); + const wekanMembers = []; + card.members.forEach(sourceMemberId => { + if (this.members[sourceMemberId]) { + const wekanId = this.members[sourceMemberId]; + if (!seenMemberIds.has(wekanId)) { + seenMemberIds.add(wekanId); + wekanMembers.push(wekanId); + } + } + return true; + }); if (wekanMembers.length > 0) { cardToCreate.members = wekanMembers; } @@ -429,18 +435,22 @@ class WekanCreator { // add assignees if (card.assignees) { - const wekanAssignees = []; - // we can't just map, as some members may not have been mapped - card.assignees.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 (!wekanAssignees.find(wId => wId === wekanId)) { - wekanAssignees.push(wekanId); - } - } - return true; - }); + // Same Set-based dedup for assignees. + const seenAssigneeIds = new Set(); + const wekanAssignees = []; + card.assignees.forEach(sourceMemberId => { + if (this.members[sourceMemberId]) { + const wekanId = this.members[sourceMemberId]; + if (!seenAssigneeIds.has(wekanId)) { + seenAssigneeIds.add(wekanId); + wekanAssignees.push(wekanId); + } + } + return true; + }); if (wekanAssignees.length > 0) { cardToCreate.assignees = wekanAssignees; }