mirror of
https://github.com/wekan/wekan.git
synced 2025-12-19 17:00:13 +01:00
Merge branch 'master' of supplee.net:wekan
This commit is contained in:
commit
734c56a6b6
10 changed files with 479 additions and 34 deletions
64
client/components/main/dueCards.jade
Normal file
64
client/components/main/dueCards.jade
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
template(name="dueCardsHeaderBar")
|
||||||
|
h1
|
||||||
|
//a.back-btn(href="{{pathFor 'home'}}")
|
||||||
|
// i.fa.fa-chevron-left
|
||||||
|
| {{_ 'dueCards-title'}}
|
||||||
|
|
||||||
|
.board-header-btns.left
|
||||||
|
a.board-header-btn.js-due-cards-view-change(title="{{_ 'dueCardsViewChange-title'}}")
|
||||||
|
i.fa.fa-caret-down
|
||||||
|
if $eq dueCardsView 'me'
|
||||||
|
i.fa.fa-user
|
||||||
|
| {{_ 'dueCardsViewChange-choice-me'}}
|
||||||
|
if $eq dueCardsView 'all'
|
||||||
|
i.fa.fa-users
|
||||||
|
| {{_ 'dueCardsViewChange-choice-all'}}
|
||||||
|
|
||||||
|
template(name="dueCardsModalTitle")
|
||||||
|
h2
|
||||||
|
i.fa.fa-keyboard-o
|
||||||
|
| {{_ 'dueCards-title'}}
|
||||||
|
|
||||||
|
template(name="dueCards")
|
||||||
|
.wrapper
|
||||||
|
.due-cards-dueat-list-wrapper
|
||||||
|
each card in dueCardsList
|
||||||
|
.due-cards-card-wrapper
|
||||||
|
a.minicard-wrapper.card-title(href=card.absoluteUrl)
|
||||||
|
+minicard(card)
|
||||||
|
ul.due-cards-context-list
|
||||||
|
li.due-cards-context(title="{{_ 'board'}}")
|
||||||
|
+viewer
|
||||||
|
= card.getBoard.title
|
||||||
|
li.due-cards-context.due-cards-context-separator
|
||||||
|
= ' '
|
||||||
|
| {{_ 'context-separator'}}
|
||||||
|
= ' '
|
||||||
|
li.due-cards-context(title="{{_ 'swimlane'}}")
|
||||||
|
+viewer
|
||||||
|
= card.getSwimlane.title
|
||||||
|
li.due-cards-context
|
||||||
|
= ' '
|
||||||
|
| {{_ 'context-separator'}}
|
||||||
|
= ' '
|
||||||
|
li.due-cards-context(title="{{_ 'list'}}")
|
||||||
|
+viewer
|
||||||
|
= card.getList.title
|
||||||
|
|
||||||
|
|
||||||
|
template(name="dueCardsViewChangePopup")
|
||||||
|
ul.pop-over-list
|
||||||
|
li
|
||||||
|
with "dueCardsViewChange-choice-me"
|
||||||
|
a.js-due-cards-view-me
|
||||||
|
i.fa.fa-user.colorful
|
||||||
|
| {{_ 'dueCardsViewChange-choice-me'}}
|
||||||
|
if $eq Utils.dueCardsView "me"
|
||||||
|
i.fa.fa-check
|
||||||
|
li
|
||||||
|
with "dueCardsViewChange-choice-all"
|
||||||
|
a.js-due-cards-view-all
|
||||||
|
i.fa.fa-users.colorful
|
||||||
|
| {{_ 'dueCardsViewChange-choice-all'}}
|
||||||
|
if $eq Utils.dueCardsView "all"
|
||||||
|
i.fa.fa-check
|
||||||
140
client/components/main/dueCards.js
Normal file
140
client/components/main/dueCards.js
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
dueCardsView() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('sort:', Utils.dueCardsView());
|
||||||
|
return Utils.dueCardsView();
|
||||||
|
},
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'click .js-due-cards-view-change': Popup.open('dueCardsViewChange'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
}).register('dueCardsHeaderBar');
|
||||||
|
|
||||||
|
Template.dueCards.helpers({
|
||||||
|
userId() {
|
||||||
|
return Meteor.userId();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
events() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'click .js-due-cards-view-me'() {
|
||||||
|
Utils.setDueCardsView('me');
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
'click .js-due-cards-view-all'() {
|
||||||
|
Utils.setDueCardsView('all');
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
}).register('dueCardsViewChangePopup');
|
||||||
|
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
onCreated() {
|
||||||
|
Meteor.subscribe('setting');
|
||||||
|
Meteor.subscribe('dueCards', Utils.dueCardsView() === 'all');
|
||||||
|
},
|
||||||
|
|
||||||
|
dueCardsView() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('sort:', Utils.dueCardsView());
|
||||||
|
return Utils.dueCardsView();
|
||||||
|
},
|
||||||
|
|
||||||
|
sortByBoard() {
|
||||||
|
return this.dueCardsView() === 'board';
|
||||||
|
},
|
||||||
|
|
||||||
|
dueCardsList() {
|
||||||
|
const allUsers = Utils.dueCardsView() === 'all';
|
||||||
|
|
||||||
|
const user = Meteor.user();
|
||||||
|
|
||||||
|
const archivedBoards = [];
|
||||||
|
Boards.find({ archived: true }).forEach(board => {
|
||||||
|
archivedBoards.push(board._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const permiitedBoards = [];
|
||||||
|
let selector = {
|
||||||
|
archived: false,
|
||||||
|
};
|
||||||
|
// if user is not an admin allow her to see cards only from public boards
|
||||||
|
// or those where she is a member
|
||||||
|
if (!user.isAdmin) {
|
||||||
|
selector.$or = [
|
||||||
|
{ permission: 'public' },
|
||||||
|
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
Boards.find(selector).forEach(board => {
|
||||||
|
permiitedBoards.push(board._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const archivedSwimlanes = [];
|
||||||
|
Swimlanes.find({ archived: true }).forEach(swimlane => {
|
||||||
|
archivedSwimlanes.push(swimlane._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const archivedLists = [];
|
||||||
|
Lists.find({ archived: true }).forEach(list => {
|
||||||
|
archivedLists.push(list._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
selector = {
|
||||||
|
archived: false,
|
||||||
|
boardId: {
|
||||||
|
$nin: archivedBoards,
|
||||||
|
$in: permiitedBoards,
|
||||||
|
},
|
||||||
|
swimlaneId: { $nin: archivedSwimlanes },
|
||||||
|
listId: { $nin: archivedLists },
|
||||||
|
dueAt: { $ne: null },
|
||||||
|
endAt: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!allUsers) {
|
||||||
|
selector.$or = [{ members: user._id }, { assignees: user._id }];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cards = [];
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('cards selector:', selector);
|
||||||
|
Cards.find(selector).forEach(card => {
|
||||||
|
cards.push(card);
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log(
|
||||||
|
// 'board:',
|
||||||
|
// card.board(),
|
||||||
|
// 'swimlane:',
|
||||||
|
// card.swimlane(),
|
||||||
|
// 'list:',
|
||||||
|
// card.list(),
|
||||||
|
// );
|
||||||
|
});
|
||||||
|
|
||||||
|
cards.sort((a, b) => {
|
||||||
|
const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt;
|
||||||
|
const y = b.dueAt === null ? Date('2100-12-31') : b.dueAt;
|
||||||
|
|
||||||
|
if (x > y) return 1;
|
||||||
|
else if (x < y) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('cards:', cards);
|
||||||
|
return cards;
|
||||||
|
},
|
||||||
|
}).register('dueCards');
|
||||||
69
client/components/main/dueCards.styl
Normal file
69
client/components/main/dueCards.styl
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
.due-cards-board-wrapper
|
||||||
|
border-radius: 8px
|
||||||
|
//padding: 0.5rem
|
||||||
|
min-width: 400px
|
||||||
|
border-width: 8px
|
||||||
|
border-color: grey
|
||||||
|
border-style: solid
|
||||||
|
margin-bottom: 2rem
|
||||||
|
margin-right: auto
|
||||||
|
margin-left: auto
|
||||||
|
|
||||||
|
.due-cards-board-title
|
||||||
|
font-size: 1.4rem
|
||||||
|
font-weight: bold
|
||||||
|
padding: 0.5rem
|
||||||
|
background-color: grey
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.due-cards-swimlane-title
|
||||||
|
font-size: 1.1rem
|
||||||
|
font-weight: bold
|
||||||
|
padding: 0.5rem
|
||||||
|
padding-bottom: 0.4rem
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 0.5rem
|
||||||
|
//border-top: black 1px solid
|
||||||
|
//border-bottom: black 1px solid
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.swimlane-default-color
|
||||||
|
background-color: lightgrey
|
||||||
|
|
||||||
|
.due-cards-list-title
|
||||||
|
font-weight: bold
|
||||||
|
font-size: 1.1rem
|
||||||
|
//padding-bottom: 0
|
||||||
|
//margin-bottom: 0
|
||||||
|
text-align: center
|
||||||
|
margin-bottom: 0.7rem
|
||||||
|
|
||||||
|
.due-cards-list-wrapper
|
||||||
|
margin: 1rem
|
||||||
|
border-radius: 5px
|
||||||
|
padding: 1.5rem
|
||||||
|
padding-top: 0.75rem
|
||||||
|
display: inline-block
|
||||||
|
min-width: 250px
|
||||||
|
max-width: 350px
|
||||||
|
|
||||||
|
.due-cards-card-wrapper
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 10px
|
||||||
|
|
||||||
|
.due-cards-dueat-list-wrapper
|
||||||
|
max-width: 500px
|
||||||
|
margin-right: auto
|
||||||
|
margin-left: auto
|
||||||
|
|
||||||
|
.due-cards-field-name
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
.due-cards-context
|
||||||
|
display: inline-block
|
||||||
|
|
||||||
|
.due-cards-context-separator
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
.due-cards-context-list
|
||||||
|
margin-bottom: 0.7rem
|
||||||
|
|
@ -5,15 +5,14 @@ template(name="myCardsHeaderBar")
|
||||||
| {{_ 'my-cards'}}
|
| {{_ 'my-cards'}}
|
||||||
|
|
||||||
.board-header-btns.left
|
.board-header-btns.left
|
||||||
a.board-header-btn.js-toggle-my-cards-choose-sort(title="{{_ 'my-cards-sort'}}")
|
a.board-header-btn.js-toggle-my-cards-choose-sort(title="{{_ 'myCardsSortChange-title'}}")
|
||||||
//i.fa.fa-caret-down
|
i.fa.fa-caret-down
|
||||||
i.fa.fa-sort
|
|
||||||
if $eq myCardsSort 'board'
|
if $eq myCardsSort 'board'
|
||||||
i.fa.fa-th-large
|
i.fa.fa-th-large
|
||||||
| {{_ 'my-cards-sort-board'}}
|
| {{_ 'myCardsSortChange-choice-board'}}
|
||||||
if $eq myCardsSort 'dueAt'
|
if $eq myCardsSort 'dueAt'
|
||||||
i.fa.fa-calendar
|
i.fa.fa-calendar
|
||||||
| {{_ 'my-cards-sort-dueat'}}
|
| {{_ 'myCardsSortChange-choice-dueat'}}
|
||||||
|
|
||||||
template(name="myCardsModalTitle")
|
template(name="myCardsModalTitle")
|
||||||
h2
|
h2
|
||||||
|
|
@ -50,21 +49,21 @@ template(name="myCards")
|
||||||
ul.my-cards-context-list
|
ul.my-cards-context-list
|
||||||
li.my-cards-context(title="{{_ 'board'}}")
|
li.my-cards-context(title="{{_ 'board'}}")
|
||||||
+viewer
|
+viewer
|
||||||
= card.board.title
|
= card.getBoard.title
|
||||||
li.my-cards-context.my-cards-context-separator
|
li.my-cards-context.my-cards-context-separator
|
||||||
= ' '
|
= ' '
|
||||||
| {{_ 'context-separator'}}
|
| {{_ 'context-separator'}}
|
||||||
= ' '
|
= ' '
|
||||||
li.my-cards-context(title="{{_ 'swimlane'}}")
|
li.my-cards-context(title="{{_ 'swimlane'}}")
|
||||||
+viewer
|
+viewer
|
||||||
= card.swimlane.title
|
= card.getSwimlane.title
|
||||||
li.my-cards-context
|
li.my-cards-context
|
||||||
= ' '
|
= ' '
|
||||||
| {{_ 'context-separator'}}
|
| {{_ 'context-separator'}}
|
||||||
= ' '
|
= ' '
|
||||||
li.my-cards-context(title="{{_ 'list'}}")
|
li.my-cards-context(title="{{_ 'list'}}")
|
||||||
+viewer
|
+viewer
|
||||||
= card.list.title
|
= card.getList.title
|
||||||
|
|
||||||
|
|
||||||
template(name="myCardsSortChangePopup")
|
template(name="myCardsSortChangePopup")
|
||||||
|
|
@ -73,24 +72,13 @@ template(name="myCardsSortChangePopup")
|
||||||
with "my-cards-sort-board"
|
with "my-cards-sort-board"
|
||||||
a.js-my-cards-sort-board
|
a.js-my-cards-sort-board
|
||||||
i.fa.fa-th-large.colorful
|
i.fa.fa-th-large.colorful
|
||||||
| {{_ 'my-cards-sort-board'}}
|
| {{_ 'myCardsSortChange-choice-board'}}
|
||||||
if $eq Utils.myCardsSort "board"
|
if $eq Utils.myCardsSort "board"
|
||||||
i.fa.fa-check
|
i.fa.fa-check
|
||||||
li
|
li
|
||||||
with "my-cards-sort-dueat"
|
with "my-cards-sort-dueat"
|
||||||
a.js-my-cards-sort-dueat
|
a.js-my-cards-sort-dueat
|
||||||
i.fa.fa-calendar.colorful
|
i.fa.fa-calendar.colorful
|
||||||
| {{_ 'my-cards-sort-dueat'}}
|
| {{_ 'myCardsSortChange-choice-dueat'}}
|
||||||
if $eq Utils.myCardsSort "dueAt"
|
if $eq Utils.myCardsSort "dueAt"
|
||||||
i.fa.fa-check
|
i.fa.fa-check
|
||||||
|
|
||||||
//template(name="myCardsSortChangePopup")
|
|
||||||
// ul.pop-over-list
|
|
||||||
// li
|
|
||||||
// a.js-my-cards-sort-board
|
|
||||||
// i.fa.fa-th-large.colorful
|
|
||||||
// | {{_ 'my-cards-sort-board'}}
|
|
||||||
// li
|
|
||||||
// a.js-my-cards-sort-dueat
|
|
||||||
// i.fa.fa-calendar.colorful
|
|
||||||
// | {{_ 'my-cards-sort-dueat'}}
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,9 @@ BlazeComponent.extendComponent({
|
||||||
events() {
|
events() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'click .js-toggle-my-cards-choose-sort'() {
|
'click .js-toggle-my-cards-choose-sort': Popup.open(
|
||||||
// eslint-disable-next-line no-console
|
'myCardsSortChange',
|
||||||
// console.log('open sort');
|
),
|
||||||
// Popup.open('myCardsSortChange');
|
|
||||||
Utils.myCardsSortToggle();
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
@ -93,7 +90,7 @@ BlazeComponent.extendComponent({
|
||||||
if (list === null || card.listId !== list._id) {
|
if (list === null || card.listId !== list._id) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
// console.log('new list');
|
// console.log('new list');
|
||||||
list = card.list();
|
list = card.getList();
|
||||||
if (list.archived) {
|
if (list.archived) {
|
||||||
list = null;
|
list = null;
|
||||||
return;
|
return;
|
||||||
|
|
@ -104,7 +101,7 @@ BlazeComponent.extendComponent({
|
||||||
if (swimlane === null || card.swimlaneId !== swimlane._id) {
|
if (swimlane === null || card.swimlaneId !== swimlane._id) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
// console.log('new swimlane');
|
// console.log('new swimlane');
|
||||||
swimlane = card.swimlane();
|
swimlane = card.getSwimlane();
|
||||||
if (swimlane.archived) {
|
if (swimlane.archived) {
|
||||||
swimlane = null;
|
swimlane = null;
|
||||||
return;
|
return;
|
||||||
|
|
@ -115,7 +112,7 @@ BlazeComponent.extendComponent({
|
||||||
if (board === null || card.boardId !== board._id) {
|
if (board === null || card.boardId !== board._id) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
// console.log('new board');
|
// console.log('new board');
|
||||||
board = card.board();
|
board = card.getBoard();
|
||||||
if (board.archived) {
|
if (board.archived) {
|
||||||
board = null;
|
board = null;
|
||||||
return;
|
return;
|
||||||
|
|
@ -200,7 +197,13 @@ BlazeComponent.extendComponent({
|
||||||
|
|
||||||
const cards = [];
|
const cards = [];
|
||||||
cursor.forEach(card => {
|
cursor.forEach(card => {
|
||||||
|
if (
|
||||||
|
!card.getBoard().archived &&
|
||||||
|
!card.getSwimlane().archived &&
|
||||||
|
!card.getList().archived
|
||||||
|
) {
|
||||||
cards.push(card);
|
cards.push(card);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cards.sort((a, b) => {
|
cards.sort((a, b) => {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,31 @@ Utils = {
|
||||||
location.reload();
|
location.reload();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
archivedBoardIds() {
|
||||||
|
const archivedBoards = [];
|
||||||
|
Boards.find({ archived: false }).forEach(board => {
|
||||||
|
archivedBoards.push(board._id);
|
||||||
|
});
|
||||||
|
return archivedBoards;
|
||||||
|
},
|
||||||
|
|
||||||
|
dueCardsView() {
|
||||||
|
let view = window.localStorage.getItem('dueCardsView');
|
||||||
|
|
||||||
|
if (!view || !['me', 'all'].includes(view)) {
|
||||||
|
window.localStorage.setItem('dueCardsView', 'me');
|
||||||
|
location.reload();
|
||||||
|
view = 'me';
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
},
|
||||||
|
|
||||||
|
setDueCardsView(view) {
|
||||||
|
window.localStorage.setItem('dueCardsView', view);
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
|
||||||
// XXX We should remove these two methods
|
// XXX We should remove these two methods
|
||||||
goBoardId(_id) {
|
goBoardId(_id) {
|
||||||
const board = Boards.findOne(_id);
|
const board = Boards.findOne(_id);
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,32 @@ FlowRouter.route('/my-cards', {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
FlowRouter.route('/due-cards', {
|
||||||
|
name: 'due-cards',
|
||||||
|
action() {
|
||||||
|
const dueCardsTemplate = 'dueCards';
|
||||||
|
|
||||||
|
Filter.reset();
|
||||||
|
// EscapeActions.executeAll();
|
||||||
|
EscapeActions.executeUpTo('popup-close');
|
||||||
|
|
||||||
|
Utils.manageCustomUI();
|
||||||
|
Utils.manageMatomo();
|
||||||
|
|
||||||
|
// if (previousPath) {
|
||||||
|
// Modal.open(dueCardsTemplate, {
|
||||||
|
// header: 'dueCardsModalTitle',
|
||||||
|
// onCloseGoTo: previousPath,
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
BlazeLayout.render('defaultLayout', {
|
||||||
|
headerBar: 'dueCardsHeaderBar',
|
||||||
|
content: dueCardsTemplate,
|
||||||
|
});
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
FlowRouter.route('/import/:source', {
|
FlowRouter.route('/import/:source', {
|
||||||
name: 'import',
|
name: 'import',
|
||||||
triggersEnter: [AccountsTemplates.ensureSignedIn],
|
triggersEnter: [AccountsTemplates.ensureSignedIn],
|
||||||
|
|
|
||||||
|
|
@ -854,7 +854,11 @@
|
||||||
"list": "List",
|
"list": "List",
|
||||||
"board": "Board",
|
"board": "Board",
|
||||||
"context-separator": "/",
|
"context-separator": "/",
|
||||||
"my-cards-sort": "My Cards Sort",
|
"myCardsSortChange-title": "My Cards Sort",
|
||||||
"my-cards-sort-board": "By Board",
|
"myCardsSortChange-choice-board": "By Board",
|
||||||
"my-cards-sort-dueat": "By Due Date"
|
"myCardsSortChange-choice-dueat": "By Due Date",
|
||||||
|
"dueCards-title": "Due Cards",
|
||||||
|
"dueCardsViewChange-title": "Due Cards View",
|
||||||
|
"dueCardsViewChange-choice-me": "Me",
|
||||||
|
"dueCardsViewChange-choice-all": "All Users"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,45 @@ Cards.helpers({
|
||||||
return Boards.findOne(this.boardId);
|
return Boards.findOne(this.boardId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getList() {
|
||||||
|
const list = this.list();
|
||||||
|
if (!list) {
|
||||||
|
return {
|
||||||
|
_id: this.listId,
|
||||||
|
title: 'Undefined List',
|
||||||
|
archived: false,
|
||||||
|
colorClass: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSwimlane() {
|
||||||
|
const swimlane = this.swimlane();
|
||||||
|
if (!swimlane) {
|
||||||
|
return {
|
||||||
|
_id: this.swimlaneId,
|
||||||
|
title: 'Undefined Swimlane',
|
||||||
|
archived: false,
|
||||||
|
colorClass: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return swimlane;
|
||||||
|
},
|
||||||
|
|
||||||
|
getBoard() {
|
||||||
|
const board = this.board();
|
||||||
|
if (!board) {
|
||||||
|
return {
|
||||||
|
_id: this.boardId,
|
||||||
|
title: 'Undefined Board',
|
||||||
|
archived: false,
|
||||||
|
colorClass: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return board;
|
||||||
|
},
|
||||||
|
|
||||||
labels() {
|
labels() {
|
||||||
const boardLabels = this.board().labels;
|
const boardLabels = this.board().labels;
|
||||||
const cardLabels = _.filter(boardLabels, label => {
|
const cardLabels = _.filter(boardLabels, label => {
|
||||||
|
|
|
||||||
|
|
@ -32,3 +32,90 @@ Meteor.publish('myCards', function() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Meteor.publish('dueCards', function(allUsers = false) {
|
||||||
|
check(allUsers, Boolean);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('all users:', allUsers);
|
||||||
|
|
||||||
|
const user = Users.findOne(this.userId);
|
||||||
|
|
||||||
|
const archivedBoards = [];
|
||||||
|
Boards.find({ archived: true }).forEach(board => {
|
||||||
|
archivedBoards.push(board._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const permiitedBoards = [];
|
||||||
|
let selector = {
|
||||||
|
archived: false,
|
||||||
|
};
|
||||||
|
// if user is not an admin allow her to see cards only from boards where
|
||||||
|
// she is a member
|
||||||
|
if (!user.isAdmin) {
|
||||||
|
selector.$or = [
|
||||||
|
{ permission: 'public' },
|
||||||
|
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
Boards.find(selector).forEach(board => {
|
||||||
|
permiitedBoards.push(board._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const archivedSwimlanes = [];
|
||||||
|
Swimlanes.find({ archived: true }).forEach(swimlane => {
|
||||||
|
archivedSwimlanes.push(swimlane._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const archivedLists = [];
|
||||||
|
Lists.find({ archived: true }).forEach(list => {
|
||||||
|
archivedLists.push(list._id);
|
||||||
|
});
|
||||||
|
|
||||||
|
selector = {
|
||||||
|
archived: false,
|
||||||
|
boardId: { $nin: archivedBoards, $in: permiitedBoards },
|
||||||
|
swimlaneId: { $nin: archivedSwimlanes },
|
||||||
|
listId: { $nin: archivedLists },
|
||||||
|
dueAt: { $ne: null },
|
||||||
|
endAt: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!allUsers) {
|
||||||
|
selector.$or = [{ members: user._id }, { assignees: user._id }];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cards = Cards.find(selector, {
|
||||||
|
fields: {
|
||||||
|
_id: 1,
|
||||||
|
archived: 1,
|
||||||
|
boardId: 1,
|
||||||
|
swimlaneId: 1,
|
||||||
|
listId: 1,
|
||||||
|
title: 1,
|
||||||
|
type: 1,
|
||||||
|
sort: 1,
|
||||||
|
members: 1,
|
||||||
|
assignees: 1,
|
||||||
|
colors: 1,
|
||||||
|
dueAt: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const boards = [];
|
||||||
|
const swimlanes = [];
|
||||||
|
const lists = [];
|
||||||
|
|
||||||
|
cards.forEach(card => {
|
||||||
|
if (card.boardId) boards.push(card.boardId);
|
||||||
|
if (card.swimlaneId) swimlanes.push(card.swimlaneId);
|
||||||
|
if (card.listId) lists.push(card.listId);
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
cards,
|
||||||
|
Boards.find({ _id: { $in: boards } }),
|
||||||
|
Swimlanes.find({ _id: { $in: swimlanes } }),
|
||||||
|
Lists.find({ _id: { $in: lists } }),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue