diff --git a/.eslintrc.json b/.eslintrc.json index 4c862c827..64818faae 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -97,7 +97,7 @@ "Avatar": true, "Avatars": true, "BlazeComponent": false, - "BlazeLayout": false, + "CollectionHooks": false, "DocHead": false, "ESSearchResults": false, diff --git a/.meteor/packages b/.meteor/packages index bb4c6b0d3..854f5d5dd 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -26,7 +26,6 @@ mquandalle:collection-mutations # Account system accounts-password@2.4.0 useraccounts:core -useraccounts:flow-routing useraccounts:unstyled simple:rest-accounts-password wekan-ldap @@ -91,5 +90,6 @@ logging@1.3.3 wekan-fullcalendar momentjs:moment@2.29.3 # wekan-fontawesome + +useraccounts:flow-routing-extra ostrio:flow-router-extra -pwix:blaze-layout diff --git a/.meteor/versions b/.meteor/versions index 27665dca0..8fa12d88e 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -54,7 +54,6 @@ idmontie:migrations@1.0.3 inter-process-messaging@0.1.1 jquery@3.0.0 kadira:dochead@1.5.0 -kadira:flow-router@2.12.1 konecty:mongo-counter@0.0.5_3 lmieulet:meteor-coverage@1.1.4 localstorage@1.2.0 @@ -101,7 +100,7 @@ ordered-dict@1.1.0 ostrio:cookies@2.7.2 ostrio:cstorage@4.0.1 ostrio:files@2.3.3 -ostrio:flow-router-extra@3.9.0 +ostrio:flow-router-extra@3.10.1 ostrio:i18n@3.2.1 pascoual:pdfkit@1.0.7 peerlibrary:assert@0.3.0 @@ -112,7 +111,6 @@ peerlibrary:data-lookup@0.3.0 peerlibrary:reactive-field@0.6.0 percolate:synced-cron@1.5.2 promise@0.12.2 -pwix:blaze-layout@2.3.3 raix:eventemitter@0.1.3 raix:handlebar-helpers@0.2.5 random@1.2.1 @@ -147,7 +145,7 @@ ui@1.0.13 underscore@1.0.13 url@1.3.2 useraccounts:core@1.16.2 -useraccounts:flow-routing@1.15.0 +useraccounts:flow-routing-extra@1.1.0 useraccounts:unstyled@1.14.2 webapp@1.13.6 webapp-hashing@1.1.1 @@ -160,4 +158,4 @@ wekan-ldap@0.0.2 wekan-markdown@1.0.9 wekan-oidc@1.0.12 yasaricli:slugify@0.0.7 -zodern:types@1.0.10 +zodern:types@1.0.13 diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js index 87525c1f7..c761bb69e 100644 --- a/client/components/boards/boardArchive.js +++ b/client/components/boards/boardArchive.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; BlazeComponent.extendComponent({ onCreated() { diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 74c1f25a9..2a88343a7 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import '../gantt/gantt.js'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { TAPi18n } from '/imports/i18n'; import dragscroll from '@wekanteam/dragscroll'; import { boardConverter } from '/client/lib/boardConverter'; diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 292a6b042..d9e1a99af 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import dragscroll from '@wekanteam/dragscroll'; /* diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index c3d973948..66adc5be2 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; const subManager = new SubsManager(); @@ -17,7 +18,7 @@ Template.boardList.helpers({ BoardMultiSelection() { return BoardMultiSelection; }, -}) +}); Template.boardListHeaderBar.events({ 'click .js-open-archived-board'() { @@ -25,8 +26,7 @@ Template.boardListHeaderBar.events({ }, }); -Template.boardList.events({ -}); +Template.boardList.events({}); Template.boardListHeaderBar.helpers({ title() { @@ -54,7 +54,7 @@ BlazeComponent.extendComponent({ let currUser = ReactiveCache.getCurrentUser(); let userLanguage; if (currUser && currUser.profile) { - userLanguage = currUser.profile.language + userLanguage = currUser.profile.language; } if (userLanguage) { TAPi18n.setLanguage(userLanguage); @@ -69,7 +69,7 @@ BlazeComponent.extendComponent({ reorderWorkspaces(draggedSpaceId, targetSpaceId) { const tree = this.workspacesTreeVar.get(); - + // Helper to remove a space from tree const removeSpace = (nodes, id) => { for (let i = 0; i < nodes.length; i++) { @@ -86,7 +86,7 @@ BlazeComponent.extendComponent({ } return { tree: nodes, removed: null }; }; - + // Helper to insert a space after target const insertAfter = (nodes, targetId, spaceToInsert) => { for (let i = 0; i < nodes.length; i++) { @@ -102,17 +102,20 @@ BlazeComponent.extendComponent({ } return false; }; - + // Clone the tree const newTree = EJSON.clone(tree); - + // Remove the dragged space - const { tree: treeAfterRemoval, removed } = removeSpace(newTree, draggedSpaceId); - + const { tree: treeAfterRemoval, removed } = removeSpace( + newTree, + draggedSpaceId, + ); + if (removed) { // Insert after target insertAfter(treeAfterRemoval, targetSpaceId, removed); - + // Save the new tree Meteor.call('setWorkspacesTree', treeAfterRemoval, (err) => { if (err) console.error(err); @@ -123,7 +126,6 @@ BlazeComponent.extendComponent({ onRendered() { // jQuery sortable is disabled in favor of HTML5 drag-and-drop for space management // The old sortable code has been removed to prevent conflicts - /* OLD SORTABLE CODE - DISABLED const itemsSelector = '.js-board:not(.placeholder)'; @@ -166,30 +168,28 @@ BlazeComponent.extendComponent({ */ }, userHasTeams() { - if (ReactiveCache.getCurrentUser()?.teams?.length > 0) - return true; - else - return false; + if (ReactiveCache.getCurrentUser()?.teams?.length > 0) return true; + else return false; }, teamsDatas() { - const teams = ReactiveCache.getCurrentUser()?.teams + const teams = ReactiveCache.getCurrentUser()?.teams; if (teams) - return teams.sort((a, b) => a.teamDisplayName.localeCompare(b.teamDisplayName)); - else - return []; + return teams.sort((a, b) => + a.teamDisplayName.localeCompare(b.teamDisplayName), + ); + else return []; }, userHasOrgs() { - if (ReactiveCache.getCurrentUser()?.orgs?.length > 0) - return true; - else - return false; + if (ReactiveCache.getCurrentUser()?.orgs?.length > 0) return true; + else return false; }, orgsDatas() { const orgs = ReactiveCache.getCurrentUser()?.orgs; if (orgs) - return orgs.sort((a, b) => a.orgDisplayName.localeCompare(b.orgDisplayName)); - else - return []; + return orgs.sort((a, b) => + a.orgDisplayName.localeCompare(b.orgDisplayName), + ); + else return []; }, userHasOrgsOrTeams() { const ret = this.userHasOrgs() || this.userHasTeams(); @@ -198,7 +198,7 @@ BlazeComponent.extendComponent({ currentMenuPath() { const sel = this.selectedMenu.get(); const currentUser = ReactiveCache.getCurrentUser(); - + // Helper to find space by id in tree const findSpaceById = (nodes, targetId, path = []) => { for (const node of nodes) { @@ -206,13 +206,16 @@ BlazeComponent.extendComponent({ return [...path, node]; } if (node.children && node.children.length > 0) { - const result = findSpaceById(node.children, targetId, [...path, node]); + const result = findSpaceById(node.children, targetId, [ + ...path, + node, + ]); if (result) return result; } } return null; }; - + if (sel === 'starred') { return { icon: '⭐', text: TAPi18n.__('allboards.starred') }; } else if (sel === 'templates') { @@ -224,8 +227,11 @@ BlazeComponent.extendComponent({ const tree = this.workspacesTreeVar.get(); const spacePath = findSpaceById(tree, sel); if (spacePath && spacePath.length > 0) { - const pathText = spacePath.map(s => s.name).join(' / '); - return { icon: '🗂️', text: `${TAPi18n.__('allboards.workspaces')} / ${pathText}` }; + const pathText = spacePath.map((s) => s.name).join(' / '); + return { + icon: '🗂️', + text: `${TAPi18n.__('allboards.workspaces') || 'Workspaces'} / ${pathText}`, + }; } return { icon: '🗂️', text: TAPi18n.__('allboards.workspaces') }; } @@ -235,18 +241,23 @@ BlazeComponent.extendComponent({ $and: [ { archived: false }, { type: { $in: ['board', 'template-container'] } }, - { title: { $not: { $regex: /^\^.*\^$/ } } } - ] + { title: { $not: { $regex: /^\^.*\^$/ } } }, + ], }; const membershipOrs = []; - let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly'); + let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne( + 'tableVisibilityMode-allowPrivateOnly', + ); if (FlowRouter.getRouteName() === 'home') { membershipOrs.push({ 'members.userId': Meteor.userId() }); - if (allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue) { - query.$and.push({ 'permission': 'private' }); + if ( + allowPrivateVisibilityOnly !== undefined && + allowPrivateVisibilityOnly.booleanValue + ) { + query.$and.push({ permission: 'private' }); } const currUser = ReactiveCache.getCurrentUser(); @@ -270,11 +281,13 @@ BlazeComponent.extendComponent({ //query.$and[2].$or.push({'teams': { $elemMatch : {teamId: teamsIds[0]}}}); membershipOrs.push({ 'teams.teamId': { $in: teamsIds } }); } - if (membershipOrs.length) { - query.$and.splice(2, 0, { $or: membershipOrs }); - } - } - else if (allowPrivateVisibilityOnly !== undefined && !allowPrivateVisibilityOnly.booleanValue) { + if (membershipOrs.length) { + query.$and.splice(2, 0, { $or: membershipOrs }); + } + } else if ( + allowPrivateVisibilityOnly !== undefined && + !allowPrivateVisibilityOnly.booleanValue + ) { query = { archived: false, //type: { $in: ['board','template-container'] }, @@ -288,28 +301,33 @@ BlazeComponent.extendComponent({ let list = boards; // Apply left menu filtering const sel = this.selectedMenu.get(); - const assignments = (currentUser && currentUser.profile && currentUser.profile.boardWorkspaceAssignments) || {}; + const assignments = + (currentUser && + currentUser.profile && + currentUser.profile.boardWorkspaceAssignments) || + {}; if (sel === 'starred') { - list = list.filter(b => currentUser && currentUser.hasStarred(b._id)); + list = list.filter((b) => currentUser && currentUser.hasStarred(b._id)); } else if (sel === 'templates') { - list = list.filter(b => b.type === 'template-container'); + list = list.filter((b) => b.type === 'template-container'); } else if (sel === 'remaining') { // Show boards not in any workspace AND not templates // Keep starred boards visible in Remaining too - list = list.filter(b => - !assignments[b._id] && - b.type !== 'template-container' + list = list.filter( + (b) => !assignments[b._id] && b.type !== 'template-container', ); } else { // assume sel is a workspaceId // Keep starred boards visible in their workspace too - list = list.filter(b => assignments[b._id] === sel); + list = list.filter((b) => assignments[b._id] === sel); } if (currentUser && typeof currentUser.sortBoardsForUser === 'function') { return currentUser.sortBoardsForUser(list); } - return list.slice().sort((a, b) => (a.title || '').localeCompare(b.title || '')); + return list + .slice() + .sort((a, b) => (a.title || '').localeCompare(b.title || '')); }, boardLists(boardId) { /* Bug Board icons random dance https://github.com/wekan/wekan/issues/4214 @@ -369,29 +387,35 @@ BlazeComponent.extendComponent({ }, 'click .js-add-workspace'(evt) { evt.preventDefault(); - const name = prompt(TAPi18n.__('allboards.add-workspace-prompt') || 'New Space name'); + const name = prompt( + TAPi18n.__('allboards.add-workspace-prompt') || 'New Space name', + ); if (name && name.trim()) { - Meteor.call('createWorkspace', { parentId: null, name: name.trim() }, (err, res) => { - if (err) console.error(err); - }); + Meteor.call( + 'createWorkspace', + { parentId: null, name: name.trim() }, + (err, res) => { + if (err) console.error(err); + }, + ); } }, 'click .js-add-board'(evt) { // Store the currently selected workspace/menu for board creation const selectedWorkspaceId = this.selectedWorkspaceIdVar.get(); const selectedMenu = this.selectedMenu.get(); - + if (selectedWorkspaceId) { Session.set('createBoardInWorkspace', selectedWorkspaceId); } else { Session.set('createBoardInWorkspace', null); } - - // Open different popup based on context - if (selectedMenu === 'templates') { - Popup.open('createTemplateContainer')(evt); - } else { - Popup.open('createBoard')(evt); + + // Open different popup based on context + if (selectedMenu === 'templates') { + Popup.open('createTemplateContainer')(evt); + } else { + Popup.open('createBoard')(evt); } }, 'click .js-star-board'(evt) { @@ -405,16 +429,27 @@ BlazeComponent.extendComponent({ // HTML5 DnD from boards to spaces 'dragstart .js-board'(evt) { const boardId = this.currentData()._id; - + // Support multi-drag - if (BoardMultiSelection.isActive() && BoardMultiSelection.isSelected(boardId)) { + if ( + BoardMultiSelection.isActive() && + BoardMultiSelection.isSelected(boardId) + ) { const selectedIds = BoardMultiSelection.getSelectedBoardIds(); - try { - evt.originalEvent.dataTransfer.setData('text/plain', JSON.stringify(selectedIds)); - evt.originalEvent.dataTransfer.setData('application/x-board-multi', 'true'); + try { + evt.originalEvent.dataTransfer.setData( + 'text/plain', + JSON.stringify(selectedIds), + ); + evt.originalEvent.dataTransfer.setData( + 'application/x-board-multi', + 'true', + ); } catch (e) {} } else { - try { evt.originalEvent.dataTransfer.setData('text/plain', boardId); } catch (e) {} + try { + evt.originalEvent.dataTransfer.setData('text/plain', boardId); + } catch (e) {} } }, 'click .js-clone-board'(evt) { @@ -487,8 +522,11 @@ BlazeComponent.extendComponent({ 'click .js-archive-selected-boards'(evt) { evt.preventDefault(); const selectedBoards = BoardMultiSelection.getSelectedBoardIds(); - if (selectedBoards.length > 0 && confirm(TAPi18n.__('archive-board-confirm'))) { - selectedBoards.forEach(boardId => { + if ( + selectedBoards.length > 0 && + confirm(TAPi18n.__('archive-board-confirm')) + ) { + selectedBoards.forEach((boardId) => { Meteor.call('archiveBoard', boardId); }); BoardMultiSelection.reset(); @@ -497,8 +535,11 @@ BlazeComponent.extendComponent({ 'click .js-duplicate-selected-boards'(evt) { evt.preventDefault(); const selectedBoards = BoardMultiSelection.getSelectedBoardIds(); - if (selectedBoards.length > 0 && confirm(TAPi18n.__('duplicate-board-confirm'))) { - selectedBoards.forEach(boardId => { + if ( + selectedBoards.length > 0 && + confirm(TAPi18n.__('duplicate-board-confirm')) + ) { + selectedBoards.forEach((boardId) => { const board = ReactiveCache.getBoard(boardId); if (board) { Meteor.call( @@ -511,7 +552,7 @@ BlazeComponent.extendComponent({ }, (err, res) => { if (err) console.error(err); - } + }, ); } }); @@ -519,35 +560,42 @@ BlazeComponent.extendComponent({ } }, 'click #resetBtn'(event) { - let allBoards = document.getElementsByClassName("js-board"); + let allBoards = document.getElementsByClassName('js-board'); let currBoard; for (let i = 0; i < allBoards.length; i++) { currBoard = allBoards[i]; - currBoard.style.display = "block"; + currBoard.style.display = 'block'; } }, 'click #filterBtn'(event) { event.preventDefault(); - let selectedTeams = document.querySelectorAll('#jsAllBoardTeams option:checked'); - let selectedTeamsValues = Array.from(selectedTeams).map(function (elt) { return elt.value }); - let index = selectedTeamsValues.indexOf("-1"); + let selectedTeams = document.querySelectorAll( + '#jsAllBoardTeams option:checked', + ); + let selectedTeamsValues = Array.from(selectedTeams).map( + function (elt) { + return elt.value; + }, + ); + let index = selectedTeamsValues.indexOf('-1'); if (index > -1) { selectedTeamsValues.splice(index, 1); } - let selectedOrgs = document.querySelectorAll('#jsAllBoardOrgs option:checked'); - let selectedOrgsValues = Array.from(selectedOrgs).map(function (elt) { return elt.value }); - index = selectedOrgsValues.indexOf("-1"); + let selectedOrgs = document.querySelectorAll( + '#jsAllBoardOrgs option:checked', + ); + let selectedOrgsValues = Array.from(selectedOrgs).map(function (elt) { + return elt.value; + }); + index = selectedOrgsValues.indexOf('-1'); if (index > -1) { selectedOrgsValues.splice(index, 1); } if (selectedTeamsValues.length > 0 || selectedOrgsValues.length > 0) { const query = { - $and: [ - { archived: false }, - { type: 'board' } - ] + $and: [{ archived: false }, { type: 'board' }], }; const ors = []; if (selectedTeamsValues.length > 0) { @@ -561,7 +609,7 @@ BlazeComponent.extendComponent({ } let filteredBoards = ReactiveCache.getBoards(query, {}); - let allBoards = document.getElementsByClassName("js-board"); + let allBoards = document.getElementsByClassName('js-board'); let currBoard; if (filteredBoards.length > 0) { let currBoardId; @@ -573,16 +621,13 @@ BlazeComponent.extendComponent({ return board._id == currBoardId; }); - if (found !== undefined) - currBoard.style.display = "block"; - else - currBoard.style.display = "none"; + if (found !== undefined) currBoard.style.display = 'block'; + else currBoard.style.display = 'none'; } - } - else { + } else { for (let i = 0; i < allBoards.length; i++) { currBoard = allBoards[i]; - currBoard.style.display = "none"; + currBoard.style.display = 'none'; } } } @@ -591,7 +636,7 @@ BlazeComponent.extendComponent({ evt.preventDefault(); evt.stopPropagation(); const workspaceId = evt.currentTarget.getAttribute('data-id'); - + // Find the space in the tree const findSpace = (nodes, id) => { for (const node of nodes) { @@ -603,33 +648,43 @@ BlazeComponent.extendComponent({ } return null; }; - + const tree = this.workspacesTreeVar.get(); const space = findSpace(tree, workspaceId); - + if (space) { - const newName = prompt(TAPi18n.__('allboards.edit-workspace-name') || 'Space name:', space.name); - const newIcon = prompt(TAPi18n.__('allboards.edit-workspace-icon') || 'Space icon (markdown):', space.icon || '📁'); - + const newName = prompt( + TAPi18n.__('allboards.edit-workspace-name') || 'Space name:', + space.name, + ); + const newIcon = prompt( + TAPi18n.__('allboards.edit-workspace-icon') || + 'Space icon (markdown):', + space.icon || '📁', + ); + if (newName !== null && newName.trim()) { // Update space in tree const updateSpaceInTree = (nodes, id, updates) => { - return nodes.map(node => { + return nodes.map((node) => { if (node.id === id) { return { ...node, ...updates }; } if (node.children) { - return { ...node, children: updateSpaceInTree(node.children, id, updates) }; + return { + ...node, + children: updateSpaceInTree(node.children, id, updates), + }; } return node; }); }; - - const updatedTree = updateSpaceInTree(tree, workspaceId, { - name: newName.trim(), - icon: newIcon || '📁' + + const updatedTree = updateSpaceInTree(tree, workspaceId, { + name: newName.trim(), + icon: newIcon || '📁', }); - + Meteor.call('setWorkspacesTree', updatedTree, (err) => { if (err) console.error(err); }); @@ -640,19 +695,29 @@ BlazeComponent.extendComponent({ evt.preventDefault(); evt.stopPropagation(); const parentId = evt.currentTarget.getAttribute('data-id'); - const name = prompt(TAPi18n.__('allboards.add-subworkspace-prompt') || 'Subspace name:'); - + const name = prompt( + TAPi18n.__('allboards.add-subworkspace-prompt') || 'Subspace name:', + ); + if (name && name.trim()) { - Meteor.call('createWorkspace', { parentId, name: name.trim() }, (err) => { - if (err) console.error(err); - }); + Meteor.call( + 'createWorkspace', + { parentId, name: name.trim() }, + (err) => { + if (err) console.error(err); + }, + ); } }, 'dragstart .workspace-node'(evt) { - const workspaceId = evt.currentTarget.getAttribute('data-workspace-id'); + const workspaceId = + evt.currentTarget.getAttribute('data-workspace-id'); evt.originalEvent.dataTransfer.effectAllowed = 'move'; - evt.originalEvent.dataTransfer.setData('application/x-workspace-id', workspaceId); - + evt.originalEvent.dataTransfer.setData( + 'application/x-workspace-id', + workspaceId, + ); + // Create a better drag image const dragImage = evt.currentTarget.cloneNode(true); dragImage.style.position = 'absolute'; @@ -661,25 +726,28 @@ BlazeComponent.extendComponent({ document.body.appendChild(dragImage); evt.originalEvent.dataTransfer.setDragImage(dragImage, 0, 0); setTimeout(() => document.body.removeChild(dragImage), 0); - + evt.currentTarget.classList.add('dragging'); }, 'dragend .workspace-node'(evt) { evt.currentTarget.classList.remove('dragging'); - document.querySelectorAll('.workspace-node').forEach(el => { + document.querySelectorAll('.workspace-node').forEach((el) => { el.classList.remove('drag-over'); }); }, 'dragover .workspace-node'(evt) { evt.preventDefault(); evt.stopPropagation(); - + const draggingEl = document.querySelector('.workspace-node.dragging'); const targetEl = evt.currentTarget; - + // Allow dropping boards on any space // Or allow dropping spaces on other spaces (but not on itself or descendants) - if (!draggingEl || (targetEl !== draggingEl && !draggingEl.contains(targetEl))) { + if ( + !draggingEl || + (targetEl !== draggingEl && !draggingEl.contains(targetEl)) + ) { evt.originalEvent.dataTransfer.dropEffect = 'move'; targetEl.classList.add('drag-over'); } @@ -690,19 +758,25 @@ BlazeComponent.extendComponent({ 'drop .workspace-node'(evt) { evt.preventDefault(); evt.stopPropagation(); - + const targetEl = evt.currentTarget; targetEl.classList.remove('drag-over'); - + // Check what's being dropped - board or workspace - const draggedWorkspaceId = evt.originalEvent.dataTransfer.getData('application/x-workspace-id'); - const isMultiBoard = evt.originalEvent.dataTransfer.getData('application/x-board-multi'); - const boardData = evt.originalEvent.dataTransfer.getData('text/plain'); - + const draggedWorkspaceId = evt.originalEvent.dataTransfer.getData( + 'application/x-workspace-id', + ); + const isMultiBoard = evt.originalEvent.dataTransfer.getData( + 'application/x-board-multi', + ); + const boardData = + evt.originalEvent.dataTransfer.getData('text/plain'); + if (draggedWorkspaceId && !boardData) { // This is a workspace reorder operation - const targetWorkspaceId = targetEl.getAttribute('data-workspace-id'); - + const targetWorkspaceId = + targetEl.getAttribute('data-workspace-id'); + if (draggedWorkspaceId !== targetWorkspaceId) { this.reorderWorkspaces(draggedWorkspaceId, targetWorkspaceId); } @@ -710,13 +784,13 @@ BlazeComponent.extendComponent({ // This is a board assignment operation // Get the workspace ID directly from the dropped workspace-node's data-workspace-id attribute const workspaceId = targetEl.getAttribute('data-workspace-id'); - + if (workspaceId) { if (isMultiBoard) { // Multi-board drag try { const boardIds = JSON.parse(boardData); - boardIds.forEach(boardId => { + boardIds.forEach((boardId) => { Meteor.call('assignBoardToWorkspace', boardId, workspaceId); }); } catch (e) { @@ -732,7 +806,7 @@ BlazeComponent.extendComponent({ 'dragover .js-select-menu'(evt) { evt.preventDefault(); evt.stopPropagation(); - + const menuType = evt.currentTarget.getAttribute('data-type'); // Only allow drop on "remaining" menu to unassign boards from spaces if (menuType === 'remaining') { @@ -746,22 +820,25 @@ BlazeComponent.extendComponent({ 'drop .js-select-menu'(evt) { evt.preventDefault(); evt.stopPropagation(); - + const menuType = evt.currentTarget.getAttribute('data-type'); evt.currentTarget.classList.remove('drag-over'); - + // Only handle drops on "remaining" menu if (menuType !== 'remaining') return; - - const isMultiBoard = evt.originalEvent.dataTransfer.getData('application/x-board-multi'); - const boardData = evt.originalEvent.dataTransfer.getData('text/plain'); - + + const isMultiBoard = evt.originalEvent.dataTransfer.getData( + 'application/x-board-multi', + ); + const boardData = + evt.originalEvent.dataTransfer.getData('text/plain'); + if (boardData) { if (isMultiBoard) { // Multi-board drag - unassign all from workspaces try { const boardIds = JSON.parse(boardData); - boardIds.forEach(boardId => { + boardIds.forEach((boardId) => { Meteor.call('unassignBoardFromWorkspace', boardId); }); } catch (e) { @@ -791,50 +868,59 @@ BlazeComponent.extendComponent({ }, menuItemCount(type) { const currentUser = ReactiveCache.getCurrentUser(); - const assignments = (currentUser && currentUser.profile && currentUser.profile.boardWorkspaceAssignments) || {}; - + const assignments = + (currentUser && + currentUser.profile && + currentUser.profile.boardWorkspaceAssignments) || + {}; + // Get all boards for counting let query = { $and: [ { archived: false }, { type: { $in: ['board', 'template-container'] } }, { $or: [{ 'members.userId': Meteor.userId() }] }, - { title: { $not: { $regex: /^\^.*\^$/ } } } - ] + { title: { $not: { $regex: /^\^.*\^$/ } } }, + ], }; const allBoards = ReactiveCache.getBoards(query, {}); - + if (type === 'starred') { - return allBoards.filter(b => currentUser && currentUser.hasStarred(b._id)).length; + return allBoards.filter( + (b) => currentUser && currentUser.hasStarred(b._id), + ).length; } else if (type === 'templates') { - return allBoards.filter(b => b.type === 'template-container').length; + return allBoards.filter((b) => b.type === 'template-container').length; } else if (type === 'remaining') { // Count boards not in any workspace AND not templates // Include starred boards (they appear in both Starred and Remaining) - return allBoards.filter(b => - !assignments[b._id] && - b.type !== 'template-container' + return allBoards.filter( + (b) => !assignments[b._id] && b.type !== 'template-container', ).length; } return 0; }, workspaceCount(workspaceId) { const currentUser = ReactiveCache.getCurrentUser(); - const assignments = (currentUser && currentUser.profile && currentUser.profile.boardWorkspaceAssignments) || {}; - + const assignments = + (currentUser && + currentUser.profile && + currentUser.profile.boardWorkspaceAssignments) || + {}; + // Get all boards for counting let query = { $and: [ { archived: false }, { type: { $in: ['board', 'template-container'] } }, { $or: [{ 'members.userId': Meteor.userId() }] }, - { title: { $not: { $regex: /^\^.*\^$/ } } } - ] + { title: { $not: { $regex: /^\^.*\^$/ } } }, + ], }; const allBoards = ReactiveCache.getBoards(query, {}); - + // Count boards directly assigned to this space (not including children) - return allBoards.filter(b => assignments[b._id] === workspaceId).length; + return allBoards.filter((b) => assignments[b._id] === workspaceId).length; }, canModifyBoards() { const currentUser = ReactiveCache.getCurrentUser(); diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 532fc641b..aff8b5e6a 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { DatePicker } from '/client/lib/datepicker'; import { formatDateTime, diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index d1c390883..4396890e5 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; BlazeComponent.extendComponent({ addSubtask(event) { diff --git a/client/components/gantt/gantt.js b/client/components/gantt/gantt.js index d10560dea..d4299abbd 100644 --- a/client/components/gantt/gantt.js +++ b/client/components/gantt/gantt.js @@ -1,3 +1,5 @@ +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; + // Add click handler to ganttView for card titles Template.ganttView.events({ 'click .js-gantt-card-title'(event, template) { diff --git a/client/components/import/import.js b/client/components/import/import.js index 757b55e41..b8f7fe66b 100644 --- a/client/components/import/import.js +++ b/client/components/import/import.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { trelloGetMembersToMap } from './trelloMembersMapper'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { wekanGetMembersToMap } from './wekanMembersMapper'; import { csvGetMembersToMap } from './csvMembersMapper'; diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index eeda23cb2..adc099321 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { Spinner } from '/client/lib/spinner'; const subManager = new SubsManager(); diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index b42bbfffa..2e57e694e 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import Lists from '../../../models/lists'; import { TAPi18n } from '/imports/i18n'; import dragscroll from '@wekanteam/dragscroll'; diff --git a/client/components/main/header.js b/client/components/main/header.js index 99c3aabc1..1b9d1deb9 100644 --- a/client/components/main/header.js +++ b/client/components/main/header.js @@ -1,10 +1,11 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; Meteor.subscribe('user-admin'); Meteor.subscribe('boards'); Meteor.subscribe('setting'); Meteor.subscribe('announcements'); -Template.header.onCreated(function(){ +Template.header.onCreated(function () { const templateInstance = this; templateInstance.currentSetting = new ReactiveVar(); templateInstance.isLoading = new ReactiveVar(false); @@ -13,10 +14,21 @@ Template.header.onCreated(function(){ onReady() { templateInstance.currentSetting.set(ReactiveCache.getCurrentSetting()); let currSetting = templateInstance.currentSetting.curValue; - if(currSetting && currSetting !== undefined && currSetting.customLoginLogoImageUrl !== undefined && document.getElementById("headerIsSettingDatabaseCallDone") != null) - document.getElementById("headerIsSettingDatabaseCallDone").style.display = 'none'; - else if(document.getElementById("headerIsSettingDatabaseCallDone") != null) - document.getElementById("headerIsSettingDatabaseCallDone").style.display = 'block'; + if ( + currSetting && + currSetting !== undefined && + currSetting.customLoginLogoImageUrl !== undefined && + document.getElementById('headerIsSettingDatabaseCallDone') != null + ) + document.getElementById( + 'headerIsSettingDatabaseCallDone', + ).style.display = 'none'; + else if ( + document.getElementById('headerIsSettingDatabaseCallDone') != null + ) + document.getElementById( + 'headerIsSettingDatabaseCallDone', + ).style.display = 'block'; return this.stop(); }, }); @@ -74,10 +86,15 @@ Template.header.events({ }, 'keypress .js-zoom-input'(evt) { - if (evt.which === 13) { // Enter key + if (evt.which === 13) { + // Enter key const newZoomPercent = parseInt(evt.target.value); - if (!isNaN(newZoomPercent) && newZoomPercent >= 50 && newZoomPercent <= 300) { + if ( + !isNaN(newZoomPercent) && + newZoomPercent >= 50 && + newZoomPercent <= 300 + ) { const newZoom = newZoomPercent / 100; Utils.setZoomLevel(newZoom); diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index d2d535207..8257ed41e 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -1,7 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; - -BlazeLayout.setRoot('body'); +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; let alreadyCheck = 1; let isCheckDone = false; @@ -47,7 +46,7 @@ Template.userFormsLayout.onCreated(function () { Template.userFormsLayout.onRendered(() => { Meteor.call('getAuthenticationsEnabled', (_, result) => { - let enabledAuthenticationMethods = [ 'password' ]; // we show/hide this based on isPasswordLoginEnabled + let enabledAuthenticationMethods = ['password']; // we show/hide this based on isPasswordLoginEnabled if (result) { Object.keys(result).forEach((m) => { @@ -88,16 +87,26 @@ Template.userFormsLayout.onRendered(() => { EscapeActions.executeAll(); // Add autocomplete attribute to login input for WCAG compliance - const loginInput = document.querySelector('input[type="text"], input[type="email"]'); - if (loginInput && loginInput.name && (loginInput.name.toLowerCase().includes('user') || loginInput.name.toLowerCase().includes('email'))) { + const loginInput = document.querySelector( + 'input[type="text"], input[type="email"]', + ); + if ( + loginInput && + loginInput.name && + (loginInput.name.toLowerCase().includes('user') || + loginInput.name.toLowerCase().includes('email')) + ) { loginInput.setAttribute('autocomplete', 'username email'); } // Add autocomplete attributes to password fields for WCAG compliance const passwordInputs = document.querySelectorAll('input[type="password"]'); - passwordInputs.forEach(input => { + passwordInputs.forEach((input) => { if (input.name && input.name.includes('password')) { - if (input.name.includes('password_again') || input.name.includes('new_password')) { + if ( + input.name.includes('password_again') || + input.name.includes('new_password') + ) { input.setAttribute('autocomplete', 'new-password'); } else { input.setAttribute('autocomplete', 'current-password'); @@ -111,18 +120,18 @@ Template.userFormsLayout.helpers({ isLegalNoticeLinkExist() { const currSet = Template.instance().currentSetting.get(); if (currSet && currSet !== undefined && currSet != null) { - return currSet.legalNotice !== undefined && currSet.legalNotice.trim() != ""; - } - else - return false; + return ( + currSet.legalNotice !== undefined && currSet.legalNotice.trim() != '' + ); + } else return false; }, getLegalNoticeWithWritTraduction() { - let spanLegalNoticeElt = $("#legalNoticeSpan"); + let spanLegalNoticeElt = $('#legalNoticeSpan'); if (spanLegalNoticeElt != null && spanLegalNoticeElt != undefined) { spanLegalNoticeElt.html(TAPi18n.__('acceptance_of_our_legalNotice', {})); } - let atLinkLegalNoticeElt = $("#legalNoticeAtLink"); + let atLinkLegalNoticeElt = $('#legalNoticeAtLink'); if (atLinkLegalNoticeElt != null && atLinkLegalNoticeElt != undefined) { atLinkLegalNoticeElt.html(TAPi18n.__('legalNotice', {})); } @@ -180,43 +189,52 @@ Template.userFormsLayout.events({ 'DOMSubtreeModified #at-oidc'(event) { if (alreadyCheck <= 2) { let currSetting = ReactiveCache.getCurrentSetting(); - let oidcBtnElt = $("#at-oidc"); - if (currSetting && currSetting !== undefined && currSetting.oidcBtnText !== undefined && oidcBtnElt != null && oidcBtnElt != undefined) { + let oidcBtnElt = $('#at-oidc'); + if ( + currSetting && + currSetting !== undefined && + currSetting.oidcBtnText !== undefined && + oidcBtnElt != null && + oidcBtnElt != undefined + ) { let htmlvalue = "" + currSetting.oidcBtnText; if (alreadyCheck == 1) { alreadyCheck++; - oidcBtnElt.html(""); - } - else { + oidcBtnElt.html(''); + } else { alreadyCheck++; oidcBtnElt.html(htmlvalue); } } - } - else { + } else { alreadyCheck = 1; } }, 'DOMSubtreeModified .at-form'(event) { if (alreadyCheck <= 2 && !isCheckDone) { - if (document.getElementById("at-oidc") != null) { + if (document.getElementById('at-oidc') != null) { let currSetting = ReactiveCache.getCurrentSetting(); - let oidcBtnElt = $("#at-oidc"); - if (currSetting && currSetting !== undefined && currSetting.oidcBtnText !== undefined && oidcBtnElt != null && oidcBtnElt != undefined) { - let htmlvalue = "" + currSetting.oidcBtnText; + let oidcBtnElt = $('#at-oidc'); + if ( + currSetting && + currSetting !== undefined && + currSetting.oidcBtnText !== undefined && + oidcBtnElt != null && + oidcBtnElt != undefined + ) { + let htmlvalue = + "" + currSetting.oidcBtnText; if (alreadyCheck == 1) { alreadyCheck++; - oidcBtnElt.html(""); - } - else { + oidcBtnElt.html(''); + } else { alreadyCheck++; isCheckDone = true; oidcBtnElt.html(htmlvalue); } } } - } - else { + } else { alreadyCheck = 1; } }, @@ -247,14 +265,14 @@ async function authentication(event, templateInstance) { switch (result) { case 'ldap': - return new Promise(resolve => { + return new Promise((resolve) => { Meteor.loginWithLDAP(match, password, function () { resolve(FlowRouter.go('/')); }); }); case 'saml': - return new Promise(resolve => { + return new Promise((resolve) => { const provider = Meteor.settings.public.SAML_PROVIDER; Meteor.loginWithSaml( { @@ -267,7 +285,7 @@ async function authentication(event, templateInstance) { }); case 'cas': - return new Promise(resolve => { + return new Promise((resolve) => { Meteor.loginWithCas(match, password, function () { resolve(FlowRouter.go('/')); }); @@ -279,9 +297,15 @@ async function authentication(event, templateInstance) { } function getAuthenticationMethod( - { displayAuthenticationMethod, defaultAuthenticationMethod }, + settings, match, ) { + if (!settings) { + return getUserAuthenticationMethod(undefined, match); + } + + const { displayAuthenticationMethod, defaultAuthenticationMethod } = settings; + if (displayAuthenticationMethod) { return $('.select-authentication').val(); } @@ -289,7 +313,7 @@ function getAuthenticationMethod( } function getUserAuthenticationMethod(defaultAuthenticationMethod, match) { - return new Promise(resolve => { + return new Promise((resolve) => { try { Meteor.subscribe('user-authenticationMethod', match, { onReady() { diff --git a/client/components/settings/peopleBody.js b/client/components/settings/peopleBody.js index 9abaf7ff3..2e3601f23 100644 --- a/client/components/settings/peopleBody.js +++ b/client/components/settings/peopleBody.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import LockoutSettings from '/models/lockoutSettings'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; const orgsPerPage = 25; const teamsPerPage = 25; diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index c61ff3996..7141e4a92 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; Sidebar = null; diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 29d21d685..45e3dae4b 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; Template.headerUserBar.events({ 'click .js-open-header-member-menu': Popup.open('memberMenu'), diff --git a/client/lib/keyboard.js b/client/lib/keyboard.js index f817e9aa3..e557cd186 100644 --- a/client/lib/keyboard.js +++ b/client/lib/keyboard.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; // XXX There is no reason to define these shortcuts globally, they should be // attached to a template (most of them will go in the `board` template). diff --git a/client/lib/modal.js b/client/lib/modal.js index 00b6fc4b7..08e1b380e 100644 --- a/client/lib/modal.js +++ b/client/lib/modal.js @@ -1,4 +1,5 @@ const closedValue = null; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; window.Modal = new (class { constructor() { diff --git a/client/lib/utils.js b/client/lib/utils.js index 26535b939..811e4f180 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; Utils = { setBackgroundImage(url) { diff --git a/config/accounts.js b/config/accounts.js index 247627e97..6ff1b83e9 100644 --- a/config/accounts.js +++ b/config/accounts.js @@ -1,4 +1,5 @@ import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; const passwordField = AccountsTemplates.removeField('password'); passwordField.autocomplete = 'current-password'; diff --git a/config/router.js b/config/router.js index 666e36dbc..64ca7066e 100644 --- a/config/router.js +++ b/config/router.js @@ -1,4 +1,5 @@ import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; let previousPath; FlowRouter.triggers.exit([ @@ -505,11 +506,11 @@ FlowRouter.route('/translation', { }, }); -FlowRouter.notFound = { +FlowRouter.route('*', { action() { this.render('defaultLayout', { content: 'notFound' }); }, -}; +}); // We maintain a list of redirections to ensure that we don't break old URLs // when we change our routing scheme. diff --git a/imports/reactiveCache.js b/imports/reactiveCache.js index 800904ded..a46b6d296 100644 --- a/imports/reactiveCache.js +++ b/imports/reactiveCache.js @@ -1,4 +1,5 @@ import { DataCache } from '@wekanteam/meteor-reactive-cache'; +import Settings from '../models/settings'; // Server isn't reactive, so search for the data always. ReactiveCacheServer = { @@ -106,7 +107,9 @@ ReactiveCacheServer = { let ret = Attachments.findOne(idOrFirstObjectSelector, options); if (!ret && typeof idOrFirstObjectSelector === 'string') { // Fall back to old structure for single attachment lookup - ret = Attachments.getAttachmentWithBackwardCompatibility(idOrFirstObjectSelector); + ret = Attachments.getAttachmentWithBackwardCompatibility( + idOrFirstObjectSelector, + ); } return ret; }, @@ -259,7 +262,7 @@ ReactiveCacheServer = { return ret; }, getCurrentUser() { - const ret = Meteor.user(); + const ret = Meteor.user(); return ret; }, getTranslation(idOrFirstObjectSelector = {}, options = {}) { @@ -272,19 +275,22 @@ ReactiveCacheServer = { ret = ret.fetch(); } return ret; - } -} + }, +}; // only the Client is reactive // saving the result has a big advantage if the query is big and often searched for the same data again and again // if the data is changed in the client, the data is saved to the server and depending code is reactive called again ReactiveCacheClient = { getBoard(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__board) { - this.__board = new DataCache(_idOrFirstObjectSelect => { + this.__board = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Boards.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Boards.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -292,9 +298,9 @@ ReactiveCacheClient = { return ret; }, getBoards(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__boards) { - this.__boards = new DataCache(_select => { + this.__boards = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Boards.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -307,11 +313,14 @@ ReactiveCacheClient = { return ret; }, getList(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__list) { - this.__list = new DataCache(_idOrFirstObjectSelect => { + this.__list = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Lists.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Lists.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -319,9 +328,9 @@ ReactiveCacheClient = { return ret; }, getLists(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__lists) { - this.__lists = new DataCache(_select => { + this.__lists = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Lists.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -334,11 +343,14 @@ ReactiveCacheClient = { return ret; }, getSwimlane(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__swimlane) { - this.__swimlane = new DataCache(_idOrFirstObjectSelect => { + this.__swimlane = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Swimlanes.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Swimlanes.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -346,9 +358,9 @@ ReactiveCacheClient = { return ret; }, getSwimlanes(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__swimlanes) { - this.__swimlanes = new DataCache(_select => { + this.__swimlanes = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Swimlanes.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -361,11 +373,14 @@ ReactiveCacheClient = { return ret; }, getChecklist(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__checklist) { - this.__checklist = new DataCache(_idOrFirstObjectSelect => { + this.__checklist = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Checklists.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Checklists.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -373,9 +388,9 @@ ReactiveCacheClient = { return ret; }, getChecklists(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__checklists) { - this.__checklists = new DataCache(_select => { + this.__checklists = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Checklists.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -388,21 +403,26 @@ ReactiveCacheClient = { return ret; }, getChecklistItem(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__checklistItem) { - this.__checklistItem = new DataCache(_idOrFirstObjectSelect => { + this.__checklistItem = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = ChecklistItems.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = ChecklistItems.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } - const ret = this.__checklistItem.get(EJSON.stringify(idOrFirstObjectSelect)); + const ret = this.__checklistItem.get( + EJSON.stringify(idOrFirstObjectSelect), + ); return ret; }, getChecklistItems(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__checklistItems) { - this.__checklistItems = new DataCache(_select => { + this.__checklistItems = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = ChecklistItems.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -415,11 +435,14 @@ ReactiveCacheClient = { return ret; }, getCard(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__card) { - this.__card = new DataCache(_idOrFirstObjectSelect => { + this.__card = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Cards.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Cards.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -427,9 +450,9 @@ ReactiveCacheClient = { return ret; }, getCards(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__cards) { - this.__cards = new DataCache(_select => { + this.__cards = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Cards.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -442,11 +465,14 @@ ReactiveCacheClient = { return ret; }, getCardComment(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__cardComment) { - this.__cardComment = new DataCache(_idOrFirstObjectSelect => { + this.__cardComment = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = CardComments.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = CardComments.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -454,9 +480,9 @@ ReactiveCacheClient = { return ret; }, getCardComments(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__cardComments) { - this.__cardComments = new DataCache(_select => { + this.__cardComments = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = CardComments.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -469,23 +495,31 @@ ReactiveCacheClient = { return ret; }, getCardCommentReaction(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__cardCommentReaction) { - this.__cardCommentReaction = new DataCache(_idOrFirstObjectSelect => { + this.__cardCommentReaction = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = CardCommentReactions.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = CardCommentReactions.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } - const ret = this.__cardCommentReaction.get(EJSON.stringify(idOrFirstObjectSelect)); + const ret = this.__cardCommentReaction.get( + EJSON.stringify(idOrFirstObjectSelect), + ); return ret; }, getCardCommentReactions(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__cardCommentReactions) { - this.__cardCommentReactions = new DataCache(_select => { + this.__cardCommentReactions = new DataCache((_select) => { const __select = EJSON.parse(_select); - let _ret = CardCommentReactions.find(__select.selector, __select.options); + let _ret = CardCommentReactions.find( + __select.selector, + __select.options, + ); if (__select.getQuery !== true) { _ret = _ret.fetch(); } @@ -496,11 +530,14 @@ ReactiveCacheClient = { return ret; }, getCustomField(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__customField) { - this.__customField = new DataCache(_idOrFirstObjectSelect => { + this.__customField = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = CustomFields.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = CustomFields.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -508,9 +545,9 @@ ReactiveCacheClient = { return ret; }, getCustomFields(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__customFields) { - this.__customFields = new DataCache(_select => { + this.__customFields = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = CustomFields.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -523,15 +560,20 @@ ReactiveCacheClient = { return ret; }, getAttachment(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__attachment) { - this.__attachment = new DataCache(_idOrFirstObjectSelect => { + this.__attachment = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); // Try new structure first - let _ret = Attachments.findOne(__select.idOrFirstObjectSelector, __select.options); + let _ret = Attachments.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); if (!_ret && typeof __select.idOrFirstObjectSelector === 'string') { // Fall back to old structure for single attachment lookup - _ret = Attachments.getAttachmentWithBackwardCompatibility(__select.idOrFirstObjectSelector); + _ret = Attachments.getAttachmentWithBackwardCompatibility( + __select.idOrFirstObjectSelector, + ); } return _ret; }); @@ -540,9 +582,9 @@ ReactiveCacheClient = { return ret; }, getAttachments(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__attachments) { - this.__attachments = new DataCache(_select => { + this.__attachments = new DataCache((_select) => { const __select = EJSON.parse(_select); // Try new structure first let _ret = Attachments.find(__select.selector, __select.options); @@ -550,7 +592,9 @@ ReactiveCacheClient = { _ret = _ret.fetch(); // If no results and we have a cardId selector, try old structure if (_ret.length === 0 && __select.selector['meta.cardId']) { - _ret = Attachments.getAttachmentsWithBackwardCompatibility(__select.selector); + _ret = Attachments.getAttachmentsWithBackwardCompatibility( + __select.selector, + ); } } return _ret; @@ -560,11 +604,14 @@ ReactiveCacheClient = { return ret; }, getAvatar(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__avatar) { - this.__avatar = new DataCache(_idOrFirstObjectSelect => { + this.__avatar = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Avatars.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Avatars.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -572,9 +619,9 @@ ReactiveCacheClient = { return ret; }, getAvatars(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__avatars) { - this.__avatars = new DataCache(_select => { + this.__avatars = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Avatars.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -587,11 +634,14 @@ ReactiveCacheClient = { return ret; }, getUser(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__user) { - this.__user = new DataCache(_idOrFirstObjectSelect => { + this.__user = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Users.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Users.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -599,9 +649,9 @@ ReactiveCacheClient = { return ret; }, getUsers(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__users) { - this.__users = new DataCache(_select => { + this.__users = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Users.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -614,11 +664,14 @@ ReactiveCacheClient = { return ret; }, getOrg(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__org) { - this.__org = new DataCache(_idOrFirstObjectSelect => { + this.__org = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Org.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Org.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -626,9 +679,9 @@ ReactiveCacheClient = { return ret; }, getOrgs(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__orgs) { - this.__orgs = new DataCache(_select => { + this.__orgs = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Org.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -641,11 +694,14 @@ ReactiveCacheClient = { return ret; }, getTeam(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__team) { - this.__team = new DataCache(_idOrFirstObjectSelect => { + this.__team = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Team.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Team.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -653,9 +709,9 @@ ReactiveCacheClient = { return ret; }, getTeams(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__teams) { - this.__teams = new DataCache(_select => { + this.__teams = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Team.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -668,11 +724,14 @@ ReactiveCacheClient = { return ret; }, getActivity(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__activity) { - this.__activity = new DataCache(_idOrFirstObjectSelect => { + this.__activity = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Activities.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Activities.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -680,9 +739,9 @@ ReactiveCacheClient = { return ret; }, getActivities(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__activities) { - this.__activities = new DataCache(_select => { + this.__activities = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Activities.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -695,11 +754,14 @@ ReactiveCacheClient = { return ret; }, getRule(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__rule) { - this.__rule = new DataCache(_idOrFirstObjectSelect => { + this.__rule = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Rules.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Rules.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -707,9 +769,9 @@ ReactiveCacheClient = { return ret; }, getRules(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__rules) { - this.__rules = new DataCache(_select => { + this.__rules = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Rules.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -722,11 +784,14 @@ ReactiveCacheClient = { return ret; }, getAction(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__action) { - this.__action = new DataCache(_idOrFirstObjectSelect => { + this.__action = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Actions.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Actions.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -734,9 +799,9 @@ ReactiveCacheClient = { return ret; }, getActions(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__actions) { - this.__actions = new DataCache(_select => { + this.__actions = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Actions.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -749,11 +814,14 @@ ReactiveCacheClient = { return ret; }, getTrigger(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__trigger) { - this.__trigger = new DataCache(_idOrFirstObjectSelect => { + this.__trigger = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Triggers.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Triggers.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -761,9 +829,9 @@ ReactiveCacheClient = { return ret; }, getTriggers(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__triggers) { - this.__triggers = new DataCache(_select => { + this.__triggers = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Triggers.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -776,21 +844,26 @@ ReactiveCacheClient = { return ret; }, getImpersonatedUser(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__impersonatedUser) { - this.__impersonatedUser = new DataCache(_idOrFirstObjectSelect => { + this.__impersonatedUser = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = ImpersonatedUsers.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = ImpersonatedUsers.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } - const ret = this.__impersonatedUser.get(EJSON.stringify(idOrFirstObjectSelect)); + const ret = this.__impersonatedUser.get( + EJSON.stringify(idOrFirstObjectSelect), + ); return ret; }, getImpersonatedUsers(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__impersonatedUsers) { - this.__impersonatedUsers = new DataCache(_select => { + this.__impersonatedUsers = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = ImpersonatedUsers.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -803,11 +876,14 @@ ReactiveCacheClient = { return ret; }, getIntegration(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__integration) { - this.__integration = new DataCache(_idOrFirstObjectSelect => { + this.__integration = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Integrations.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Integrations.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -815,9 +891,9 @@ ReactiveCacheClient = { return ret; }, getIntegrations(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__integrations) { - this.__integrations = new DataCache(_select => { + this.__integrations = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Integrations.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -830,21 +906,26 @@ ReactiveCacheClient = { return ret; }, getInvitationCode(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__invitationCode) { - this.__invitationCode = new DataCache(_idOrFirstObjectSelect => { + this.__invitationCode = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = InvitationCodes.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = InvitationCodes.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } - const ret = this.__invitationCode.get(EJSON.stringify(idOrFirstObjectSelect)); + const ret = this.__invitationCode.get( + EJSON.stringify(idOrFirstObjectSelect), + ); return ret; }, getInvitationCodes(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__invitationCodes) { - this.__invitationCodes = new DataCache(_select => { + this.__invitationCodes = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = InvitationCodes.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -877,11 +958,14 @@ ReactiveCacheClient = { return ret; }, getTranslation(idOrFirstObjectSelector = {}, options = {}) { - const idOrFirstObjectSelect = {idOrFirstObjectSelector, options} + const idOrFirstObjectSelect = { idOrFirstObjectSelector, options }; if (!this.__translation) { - this.__translation = new DataCache(_idOrFirstObjectSelect => { + this.__translation = new DataCache((_idOrFirstObjectSelect) => { const __select = EJSON.parse(_idOrFirstObjectSelect); - const _ret = Translation.findOne(__select.idOrFirstObjectSelector, __select.options); + const _ret = Translation.findOne( + __select.idOrFirstObjectSelector, + __select.options, + ); return _ret; }); } @@ -889,9 +973,9 @@ ReactiveCacheClient = { return ret; }, getTranslations(selector = {}, options = {}, getQuery = false) { - const select = {selector, options, getQuery} + const select = { selector, options, getQuery }; if (!this.__translations) { - this.__translations = new DataCache(_select => { + this.__translations = new DataCache((_select) => { const __select = EJSON.parse(_select); let _ret = Translation.find(__select.selector, __select.options); if (__select.getQuery !== true) { @@ -902,8 +986,8 @@ ReactiveCacheClient = { } const ret = this.__translations.get(EJSON.stringify(select)); return ret; - } -} + }, +}; // global Reactive Cache class to avoid big overhead while searching for the same data often again // This class calls 2 implementation, for server and client code @@ -987,9 +1071,15 @@ ReactiveCache = { getChecklistItem(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getChecklistItem(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getChecklistItem( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getChecklistItem(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getChecklistItem( + idOrFirstObjectSelector, + options, + ); } return ret; }, @@ -1023,9 +1113,15 @@ ReactiveCache = { getCardComment(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getCardComment(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getCardComment( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getCardComment(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getCardComment( + idOrFirstObjectSelector, + options, + ); } return ret; }, @@ -1041,27 +1137,47 @@ ReactiveCache = { getCardCommentReaction(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getCardCommentReaction(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getCardCommentReaction( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getCardCommentReaction(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getCardCommentReaction( + idOrFirstObjectSelector, + options, + ); } return ret; }, getCardCommentReactions(selector = {}, options = {}, getQuery = false) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getCardCommentReactions(selector, options, getQuery); + ret = ReactiveCacheServer.getCardCommentReactions( + selector, + options, + getQuery, + ); } else { - ret = ReactiveCacheClient.getCardCommentReactions(selector, options, getQuery); + ret = ReactiveCacheClient.getCardCommentReactions( + selector, + options, + getQuery, + ); } return ret; }, getCustomField(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getCustomField(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getCustomField( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getCustomField(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getCustomField( + idOrFirstObjectSelector, + options, + ); } return ret; }, @@ -1239,27 +1355,47 @@ ReactiveCache = { getImpersonatedUser(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getImpersonatedUser(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getImpersonatedUser( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getImpersonatedUser(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getImpersonatedUser( + idOrFirstObjectSelector, + options, + ); } return ret; }, getImpersonatedUsers(selector = {}, options = {}, getQuery = false) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getImpersonatedUsers(selector, options, getQuery); + ret = ReactiveCacheServer.getImpersonatedUsers( + selector, + options, + getQuery, + ); } else { - ret = ReactiveCacheClient.getImpersonatedUsers(selector, options, getQuery); + ret = ReactiveCacheClient.getImpersonatedUsers( + selector, + options, + getQuery, + ); } return ret; }, getIntegration(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getIntegration(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getIntegration( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getIntegration(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getIntegration( + idOrFirstObjectSelector, + options, + ); } return ret; }, @@ -1274,7 +1410,10 @@ ReactiveCache = { }, getSessionData(idOrFirstObjectSelector = {}, options = {}) { // no reactive cache, otherwise global search will not work anymore - let ret = ReactiveCacheServer.getSessionData(idOrFirstObjectSelector, options); + let ret = ReactiveCacheServer.getSessionData( + idOrFirstObjectSelector, + options, + ); return ret; }, getSessionDatas(selector = {}, options = {}, getQuery = false) { @@ -1285,9 +1424,15 @@ ReactiveCache = { getInvitationCode(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getInvitationCode(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getInvitationCode( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getInvitationCode(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getInvitationCode( + idOrFirstObjectSelector, + options, + ); } return ret; }, @@ -1321,9 +1466,15 @@ ReactiveCache = { getTranslation(idOrFirstObjectSelector = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveCacheServer.getTranslation(idOrFirstObjectSelector, options); + ret = ReactiveCacheServer.getTranslation( + idOrFirstObjectSelector, + options, + ); } else { - ret = ReactiveCacheClient.getTranslation(idOrFirstObjectSelector, options); + ret = ReactiveCacheClient.getTranslation( + idOrFirstObjectSelector, + options, + ); } return ret; }, @@ -1336,76 +1487,67 @@ ReactiveCache = { } return ret; }, -} +}; // Server isn't reactive, so search for the data always. ReactiveMiniMongoIndexServer = { getSubTasksWithParentId(parentId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (parentId) { - ret = ReactiveCache.getCards( - { parentId, - ...addSelect, - }, options); + ret = ReactiveCache.getCards({ parentId, ...addSelect }, options); } return ret; }, getChecklistsWithCardId(cardId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (cardId) { - ret = ReactiveCache.getChecklists( - { cardId, - ...addSelect, - }, options); + ret = ReactiveCache.getChecklists({ cardId, ...addSelect }, options); } return ret; }, getChecklistItemsWithChecklistId(checklistId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (checklistId) { ret = ReactiveCache.getChecklistItems( - { checklistId, - ...addSelect, - }, options); + { checklistId, ...addSelect }, + options, + ); } return ret; }, getCardCommentsWithCardId(cardId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (cardId) { - ret = ReactiveCache.getCardComments( - { cardId, - ...addSelect, - }, options); + ret = ReactiveCache.getCardComments({ cardId, ...addSelect }, options); } return ret; }, getActivityWithId(activityId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (activityId) { ret = ReactiveCache.getActivities( - { _id: activityId, - ...addSelect, - }, options); + { _id: activityId, ...addSelect }, + options, + ); } return ret; - } -} + }, +}; // Client side little MiniMongo DB "Index" ReactiveMiniMongoIndexClient = { getSubTasksWithParentId(parentId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (parentId) { - const select = {addSelect, options} + const select = { addSelect, options }; if (!this.__subTasksWithId) { - this.__subTasksWithId = new DataCache(_select => { + this.__subTasksWithId = new DataCache((_select) => { const __select = EJSON.parse(_select); const _subTasks = ReactiveCache.getCards( - { parentId: { $exists: true }, - ...__select.addSelect, - }, __select.options); - const _ret = _.groupBy(_subTasks, 'parentId') + { parentId: { $exists: true }, ...__select.addSelect }, + __select.options, + ); + const _ret = _.groupBy(_subTasks, 'parentId'); return _ret; }); } @@ -1417,17 +1559,17 @@ ReactiveMiniMongoIndexClient = { return ret; }, getChecklistsWithCardId(cardId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (cardId) { - const select = {addSelect, options} + const select = { addSelect, options }; if (!this.__checklistsWithId) { - this.__checklistsWithId = new DataCache(_select => { + this.__checklistsWithId = new DataCache((_select) => { const __select = EJSON.parse(_select); const _checklists = ReactiveCache.getChecklists( - { cardId: { $exists: true }, - ...__select.addSelect, - }, __select.options); - const _ret = _.groupBy(_checklists, 'cardId') + { cardId: { $exists: true }, ...__select.addSelect }, + __select.options, + ); + const _ret = _.groupBy(_checklists, 'cardId'); return _ret; }); } @@ -1439,17 +1581,17 @@ ReactiveMiniMongoIndexClient = { return ret; }, getChecklistItemsWithChecklistId(checklistId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (checklistId) { - const select = {addSelect, options} + const select = { addSelect, options }; if (!this.__checklistItemsWithId) { - this.__checklistItemsWithId = new DataCache(_select => { + this.__checklistItemsWithId = new DataCache((_select) => { const __select = EJSON.parse(_select); const _checklistItems = ReactiveCache.getChecklistItems( - { checklistId: { $exists: true }, - ...__select.addSelect, - }, __select.options); - const _ret = _.groupBy(_checklistItems, 'checklistId') + { checklistId: { $exists: true }, ...__select.addSelect }, + __select.options, + ); + const _ret = _.groupBy(_checklistItems, 'checklistId'); return _ret; }); } @@ -1457,9 +1599,9 @@ ReactiveMiniMongoIndexClient = { if (ret) { if (Meteor.isServer) { ret[checklistId] = ReactiveCache.getChecklistItems( - {checklistId: checklistId, - ...addSelect - }, options); + { checklistId: checklistId, ...addSelect }, + options, + ); } ret = ret[checklistId] || []; } @@ -1467,17 +1609,17 @@ ReactiveMiniMongoIndexClient = { return ret; }, getCardCommentsWithCardId(cardId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (cardId) { - const select = {addSelect, options} + const select = { addSelect, options }; if (!this.__cardCommentsWithId) { - this.__cardCommentsWithId = new DataCache(_select => { + this.__cardCommentsWithId = new DataCache((_select) => { const __select = EJSON.parse(_select); const _cardComments = ReactiveCache.getCardComments( - { cardId: { $exists: true }, - ...__select.addSelect, - }, __select.options); - const _ret = _.groupBy(_cardComments, 'cardId') + { cardId: { $exists: true }, ...__select.addSelect }, + __select.options, + ); + const _ret = _.groupBy(_cardComments, 'cardId'); return _ret; }); } @@ -1489,17 +1631,17 @@ ReactiveMiniMongoIndexClient = { return ret; }, getActivityWithId(activityId, addSelect = {}, options = {}) { - let ret = [] + let ret = []; if (activityId) { - const select = {addSelect, options} + const select = { addSelect, options }; if (!this.__activityWithId) { - this.__activityWithId = new DataCache(_select => { + this.__activityWithId = new DataCache((_select) => { const __select = EJSON.parse(_select); const _activities = ReactiveCache.getActivities( - { _id: { $exists: true }, - ...__select.addSelect, - }, __select.options); - const _ret = _.indexBy(_activities, '_id') + { _id: { $exists: true }, ...__select.addSelect }, + __select.options, + ); + const _ret = _.indexBy(_activities, '_id'); return _ret; }); } @@ -1509,8 +1651,8 @@ ReactiveMiniMongoIndexClient = { } } return ret; - } -} + }, +}; // global Reactive MiniMongo Index Cache class to avoid big overhead while searching for the same data often again // This class calls 2 implementation, for server and client code @@ -1522,48 +1664,88 @@ ReactiveMiniMongoIndex = { getSubTasksWithParentId(parentId, addSelect = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveMiniMongoIndexServer.getSubTasksWithParentId(parentId, addSelect, options); + ret = ReactiveMiniMongoIndexServer.getSubTasksWithParentId( + parentId, + addSelect, + options, + ); } else { - ret = ReactiveMiniMongoIndexClient.getSubTasksWithParentId(parentId, addSelect, options); + ret = ReactiveMiniMongoIndexClient.getSubTasksWithParentId( + parentId, + addSelect, + options, + ); } return ret; }, getChecklistsWithCardId(cardId, addSelect = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveMiniMongoIndexServer.getChecklistsWithCardId(cardId, addSelect, options); + ret = ReactiveMiniMongoIndexServer.getChecklistsWithCardId( + cardId, + addSelect, + options, + ); } else { - ret = ReactiveMiniMongoIndexClient.getChecklistsWithCardId(cardId, addSelect, options); + ret = ReactiveMiniMongoIndexClient.getChecklistsWithCardId( + cardId, + addSelect, + options, + ); } return ret; }, getChecklistItemsWithChecklistId(checklistId, addSelect = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveMiniMongoIndexServer.getChecklistItemsWithChecklistId(checklistId, addSelect, options); + ret = ReactiveMiniMongoIndexServer.getChecklistItemsWithChecklistId( + checklistId, + addSelect, + options, + ); } else { - ret = ReactiveMiniMongoIndexClient.getChecklistItemsWithChecklistId(checklistId, addSelect, options); + ret = ReactiveMiniMongoIndexClient.getChecklistItemsWithChecklistId( + checklistId, + addSelect, + options, + ); } return ret; }, getCardCommentsWithCardId(cardId, addSelect = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveMiniMongoIndexServer.getCardCommentsWithCardId(cardId, addSelect, options); + ret = ReactiveMiniMongoIndexServer.getCardCommentsWithCardId( + cardId, + addSelect, + options, + ); } else { - ret = ReactiveMiniMongoIndexClient.getCardCommentsWithCardId(cardId, addSelect, options); + ret = ReactiveMiniMongoIndexClient.getCardCommentsWithCardId( + cardId, + addSelect, + options, + ); } return ret; }, getActivityWithId(activityId, addSelect = {}, options = {}) { let ret; if (Meteor.isServer) { - ret = ReactiveMiniMongoIndexServer.getActivityWithId(activityId, addSelect, options); + ret = ReactiveMiniMongoIndexServer.getActivityWithId( + activityId, + addSelect, + options, + ); } else { - ret = ReactiveMiniMongoIndexClient.getActivityWithId(activityId, addSelect, options); + ret = ReactiveMiniMongoIndexClient.getActivityWithId( + activityId, + addSelect, + options, + ); } return ret; - } -} + }, +}; export { ReactiveCache, ReactiveMiniMongoIndex }; diff --git a/models/activities.js b/models/activities.js index 943fb9306..626656138 100644 --- a/models/activities.js +++ b/models/activities.js @@ -202,7 +202,7 @@ if (Meteor.isServer) { params.comment = comment.text; if (board) { const comment = params.comment; - const knownUsers = board.members.map(member => { + const knownUsers = board.members.map((member) => { const u = ReactiveCache.getUser(member.userId); if (u) { member.username = u.username; @@ -223,7 +223,7 @@ if (Meteor.isServer) { if (activity.boardId && username === 'board_members') { // mentions all board members - const knownUids = knownUsers.map(u => u.userId); + const knownUids = knownUsers.map((u) => u.userId); watchers = _.union(watchers, [...knownUids]); title = 'act-atUserComment'; } else if (activity.cardId && username === 'card_members') { @@ -243,7 +243,6 @@ if (Meteor.isServer) { title = 'act-atUserComment'; watchers = _.union(watchers, [uid]); } - } } params.commentId = comment._id; @@ -300,7 +299,7 @@ if (Meteor.isServer) { // due time reminder, if it doesn't have old value, it's a brand new set, need some differentiation title = activity.timeOldValue ? 'act-withDue' : 'act-newDue'; } - ['timeValue', 'timeOldValue'].forEach(key => { + ['timeValue', 'timeOldValue'].forEach((key) => { // copy time related keys & values to params const value = activity[key]; if (value) params[key] = value; @@ -313,7 +312,7 @@ if (Meteor.isServer) { if (new RegExp(BIGEVENTS).exec(atype)) { watchers = _.union( watchers, - board.activeMembers().map(member => member.userId), + board.activeMembers().map((member) => member.userId), ); // notify all active members for important events } } catch (e) { @@ -335,7 +334,7 @@ if (Meteor.isServer) { _.intersection(participants, trackingUsers), ); } - Notifications.getUsers(watchers).forEach(user => { + Notifications.getUsers(watchers).forEach((user) => { // don't notify a user of their own behavior if (user._id !== userId) { Notifications.notify(user, title, description, params); @@ -350,7 +349,7 @@ if (Meteor.isServer) { }); if (integrations.length > 0) { params.watchers = watchers; - integrations.forEach(integration => { + integrations.forEach((integration) => { Meteor.call( 'outgoingWebhooks', integration, diff --git a/models/boards.js b/models/boards.js index 8fe525843..0f99ef1fd 100644 --- a/models/boards.js +++ b/models/boards.js @@ -1,6 +1,7 @@ import { ReactiveCache } from '/imports/reactiveCache'; import escapeForRegex from 'escape-string-regexp'; import { TAPi18n } from '/imports/i18n'; +import { CustomFields } from './customFields'; import { ALLOWED_BOARD_COLORS, ALLOWED_COLORS, @@ -9,6 +10,7 @@ import { TYPE_TEMPLATE_CONTAINER, } from '/config/const'; import Users from "./users"; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import TableVisibilityModeSettings from "./tableVisibilityModeSettings"; // const escapeForRegex = require('escape-string-regexp'); diff --git a/models/cards.js b/models/cards.js index d5bbb8bec..fb97bd99e 100644 --- a/models/cards.js +++ b/models/cards.js @@ -1,4 +1,5 @@ import { ReactiveCache, ReactiveMiniMongoIndex } from '/imports/reactiveCache'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { formatDateTime, formatDate, diff --git a/models/exporter.js b/models/exporter.js index a42dc0f7a..f1f601540 100644 --- a/models/exporter.js +++ b/models/exporter.js @@ -1,6 +1,7 @@ import { ReactiveCache } from '/imports/reactiveCache'; const Papa = require('papaparse'); import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { formatDateTime, formatDate, diff --git a/models/server/ExporterExcel.js b/models/server/ExporterExcel.js index e9775baff..66684917e 100644 --- a/models/server/ExporterExcel.js +++ b/models/server/ExporterExcel.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { createWorkbook } from './createWorkbook'; import { formatDateTime, diff --git a/models/settings.js b/models/settings.js index 3a85e5013..8645e2117 100644 --- a/models/settings.js +++ b/models/settings.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; //var nodemailer = require('nodemailer'); // Sandstorm context is detected using the METEOR_SETTINGS environment variable diff --git a/models/trelloCreator.js b/models/trelloCreator.js index 5dde821c0..c0400b443 100644 --- a/models/trelloCreator.js +++ b/models/trelloCreator.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; +import { CustomFields } from './customFields'; import { formatDateTime, formatDate, diff --git a/models/users.js b/models/users.js index 54de4a94e..f83ecd3c2 100644 --- a/models/users.js +++ b/models/users.js @@ -2018,6 +2018,7 @@ Meteor.methods({ }, // Spaces: create a new space under parentId (or root when null) createWorkspace({ parentId = null, name }) { + check(parentId, Match.OneOf(String, null)); check(name, String); if (!this.userId) throw new Meteor.Error('not-logged-in'); const user = Users.findOne(this.userId) || {}; diff --git a/models/wekanCreator.js b/models/wekanCreator.js index 2bf142d50..503cba3fc 100644 --- a/models/wekanCreator.js +++ b/models/wekanCreator.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { CustomFields } from './customFields'; import { formatDateTime, formatDate, diff --git a/sandstorm.js b/sandstorm.js index b50922794..6539a1942 100644 --- a/sandstorm.js +++ b/sandstorm.js @@ -1,6 +1,7 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { Meteor } from 'meteor/meteor'; import { Picker } from 'meteor/communitypackages:picker'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; // Sandstorm context is detected using the METEOR_SETTINGS environment variable // in the package definition. diff --git a/server/publications/lockoutSettings.js b/server/publications/lockoutSettings.js index c94309c33..089083f2a 100644 --- a/server/publications/lockoutSettings.js +++ b/server/publications/lockoutSettings.js @@ -1,4 +1,5 @@ import LockoutSettings from '/models/lockoutSettings'; +import { Settings } from '../../models/settings'; Meteor.publish('lockoutSettings', function() { const ret = LockoutSettings.find(); diff --git a/server/publications/settings.js b/server/publications/settings.js index e2365d523..a8c073187 100644 --- a/server/publications/settings.js +++ b/server/publications/settings.js @@ -1,4 +1,5 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import { Settings } from '../../models/settings'; Meteor.publish('globalwebhooks', () => { const boardId = Integrations.Const.GLOBAL_WEBHOOK_ID; diff --git a/server/publications/tableVisibilityModeSettings.js b/server/publications/tableVisibilityModeSettings.js index 4326e59a6..9e04875c4 100644 --- a/server/publications/tableVisibilityModeSettings.js +++ b/server/publications/tableVisibilityModeSettings.js @@ -1,3 +1,5 @@ +import { Settings } from '../../models/settings'; + Meteor.publish('tableVisibilityModeSettings', function() { const ret = TableVisibilityModeSettings.find(); return ret; diff --git a/server/routes/attachmentApi.js b/server/routes/attachmentApi.js index ae10ca64b..490c54f7f 100644 --- a/server/routes/attachmentApi.js +++ b/server/routes/attachmentApi.js @@ -3,6 +3,7 @@ import { Accounts } from 'meteor/accounts-base'; import { WebApp } from 'meteor/webapp'; import { ReactiveCache } from '/imports/reactiveCache'; import { Attachments, fileStoreStrategyFactory } from '/models/attachments'; +import { Settings } from '../../models/settings'; import { moveToStorage } from '/models/lib/fileStoreStrategy'; import { STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS, STORAGE_NAME_S3 } from '/models/lib/fileStoreStrategy'; import AttachmentStorageSettings from '/models/attachmentStorageSettings';