mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
Fixed #2338 -> Slow opening of big boards with too many archived items
This commit is contained in:
parent
b983479476
commit
ab4fec0f3c
8 changed files with 92 additions and 64 deletions
|
|
@ -14,7 +14,7 @@ BlazeComponent.extendComponent({
|
||||||
const currentBoardId = Session.get('currentBoard');
|
const currentBoardId = Session.get('currentBoard');
|
||||||
if (!currentBoardId)
|
if (!currentBoardId)
|
||||||
return;
|
return;
|
||||||
const handle = subManager.subscribe('board', currentBoardId);
|
const handle = subManager.subscribe('board', currentBoardId, false);
|
||||||
Tracker.nonreactive(() => {
|
Tracker.nonreactive(() => {
|
||||||
Tracker.autorun(() => {
|
Tracker.autorun(() => {
|
||||||
this.isBoardReady.set(handle.ready());
|
this.isBoardReady.set(handle.ready());
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,12 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
hasOvertimeCards() {
|
hasOvertimeCards() {
|
||||||
subManager.subscribe('board', this.currentData()._id);
|
subManager.subscribe('board', this.currentData()._id, false);
|
||||||
return this.currentData().hasOvertimeCards();
|
return this.currentData().hasOvertimeCards();
|
||||||
},
|
},
|
||||||
|
|
||||||
hasSpentTimeCards() {
|
hasSpentTimeCards() {
|
||||||
subManager.subscribe('board', this.currentData()._id);
|
subManager.subscribe('board', this.currentData()._id, false);
|
||||||
return this.currentData().hasSpentTimeCards();
|
return this.currentData().hasSpentTimeCards();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ Template.moveCardPopup.events({
|
||||||
});
|
});
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
onCreated() {
|
onCreated() {
|
||||||
subManager.subscribe('board', Session.get('currentBoard'));
|
subManager.subscribe('board', Session.get('currentBoard'), false);
|
||||||
this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
|
this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -453,7 +453,7 @@ BlazeComponent.extendComponent({
|
||||||
return [{
|
return [{
|
||||||
'change .js-select-boards'(evt) {
|
'change .js-select-boards'(evt) {
|
||||||
this.selectedBoardId.set($(evt.currentTarget).val());
|
this.selectedBoardId.set($(evt.currentTarget).val());
|
||||||
subManager.subscribe('board', this.selectedBoardId.get());
|
subManager.subscribe('board', this.selectedBoardId.get(), false);
|
||||||
},
|
},
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
|
|
@ -676,7 +676,7 @@ BlazeComponent.extendComponent({
|
||||||
if (selection === 'none') {
|
if (selection === 'none') {
|
||||||
this.parentBoard.set(null);
|
this.parentBoard.set(null);
|
||||||
} else {
|
} else {
|
||||||
subManager.subscribe('board', $(evt.currentTarget).val());
|
subManager.subscribe('board', $(evt.currentTarget).val(), false);
|
||||||
this.parentBoard.set(selection);
|
this.parentBoard.set(selection);
|
||||||
list.prop('disabled', false);
|
list.prop('disabled', false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -348,7 +348,7 @@ BlazeComponent.extendComponent({
|
||||||
|
|
||||||
this.boardId = Session.get('currentBoard');
|
this.boardId = Session.get('currentBoard');
|
||||||
// In order to get current board info
|
// In order to get current board info
|
||||||
subManager.subscribe('board', this.boardId);
|
subManager.subscribe('board', this.boardId, false);
|
||||||
this.board = Boards.findOne(this.boardId);
|
this.board = Boards.findOne(this.boardId);
|
||||||
// List where to insert card
|
// List where to insert card
|
||||||
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
|
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
|
||||||
|
|
@ -414,7 +414,7 @@ BlazeComponent.extendComponent({
|
||||||
events() {
|
events() {
|
||||||
return [{
|
return [{
|
||||||
'change .js-select-boards'(evt) {
|
'change .js-select-boards'(evt) {
|
||||||
subManager.subscribe('board', $(evt.currentTarget).val());
|
subManager.subscribe('board', $(evt.currentTarget).val(), false);
|
||||||
this.selectedBoardId.set($(evt.currentTarget).val());
|
this.selectedBoardId.set($(evt.currentTarget).val());
|
||||||
},
|
},
|
||||||
'change .js-select-swimlanes'(evt) {
|
'change .js-select-swimlanes'(evt) {
|
||||||
|
|
@ -500,13 +500,13 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
const boardId = board._id;
|
const boardId = board._id;
|
||||||
// Subscribe to this board
|
// Subscribe to this board
|
||||||
subManager.subscribe('board', boardId);
|
subManager.subscribe('board', boardId, false);
|
||||||
this.selectedBoardId = new ReactiveVar(boardId);
|
this.selectedBoardId = new ReactiveVar(boardId);
|
||||||
|
|
||||||
if (!this.isBoardTemplateSearch) {
|
if (!this.isBoardTemplateSearch) {
|
||||||
this.boardId = Session.get('currentBoard');
|
this.boardId = Session.get('currentBoard');
|
||||||
// In order to get current board info
|
// In order to get current board info
|
||||||
subManager.subscribe('board', this.boardId);
|
subManager.subscribe('board', this.boardId, false);
|
||||||
this.swimlaneId = '';
|
this.swimlaneId = '';
|
||||||
// Swimlane where to insert card
|
// Swimlane where to insert card
|
||||||
const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane');
|
const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane');
|
||||||
|
|
@ -547,7 +547,7 @@ BlazeComponent.extendComponent({
|
||||||
} else if (this.isBoardTemplateSearch) {
|
} else if (this.isBoardTemplateSearch) {
|
||||||
const boards = board.searchBoards(this.term.get());
|
const boards = board.searchBoards(this.term.get());
|
||||||
boards.forEach((board) => {
|
boards.forEach((board) => {
|
||||||
subManager.subscribe('board', board.linkedId);
|
subManager.subscribe('board', board.linkedId, false);
|
||||||
});
|
});
|
||||||
return boards;
|
return boards;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -558,7 +558,7 @@ BlazeComponent.extendComponent({
|
||||||
events() {
|
events() {
|
||||||
return [{
|
return [{
|
||||||
'change .js-select-boards'(evt) {
|
'change .js-select-boards'(evt) {
|
||||||
subManager.subscribe('board', $(evt.currentTarget).val());
|
subManager.subscribe('board', $(evt.currentTarget).val(), false);
|
||||||
this.selectedBoardId.set($(evt.currentTarget).val());
|
this.selectedBoardId.set($(evt.currentTarget).val());
|
||||||
},
|
},
|
||||||
'submit .js-search-term-form'(evt) {
|
'submit .js-search-term-form'(evt) {
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,56 @@
|
||||||
template(name="archivesSidebar")
|
template(name="archivesSidebar")
|
||||||
+basicTabs(tabs=tabs)
|
if isArchiveReady.get
|
||||||
|
+basicTabs(tabs=tabs)
|
||||||
+tabContent(slug="cards")
|
+tabContent(slug="cards")
|
||||||
p.quiet
|
|
||||||
a.js-restore-all-cards {{_ 'restore-all'}}
|
|
||||||
| -
|
|
||||||
a.js-delete-all-cards {{_ 'delete-all'}}
|
|
||||||
each archivedCards
|
|
||||||
.minicard-wrapper.js-minicard
|
|
||||||
+minicard(this)
|
|
||||||
if currentUser.isBoardMember
|
|
||||||
p.quiet
|
p.quiet
|
||||||
a.js-restore-card {{_ 'restore'}}
|
a.js-restore-all-cards {{_ 'restore-all'}}
|
||||||
| -
|
| -
|
||||||
a.js-delete-card {{_ 'delete'}}
|
a.js-delete-all-cards {{_ 'delete-all'}}
|
||||||
if cardIsInArchivedList
|
each archivedCards
|
||||||
p.quiet.small ({{_ 'warn-list-archived'}})
|
.minicard-wrapper.js-minicard
|
||||||
else
|
+minicard(this)
|
||||||
p.no-items-message {{_ 'no-archived-cards'}}
|
|
||||||
|
|
||||||
+tabContent(slug="lists")
|
|
||||||
p.quiet
|
|
||||||
a.js-restore-all-lists {{_ 'restore-all'}}
|
|
||||||
| -
|
|
||||||
a.js-delete-all-lists {{_ 'delete-all'}}
|
|
||||||
ul.archived-lists
|
|
||||||
each archivedLists
|
|
||||||
li.archived-lists-item
|
|
||||||
= title
|
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
p.quiet
|
p.quiet
|
||||||
a.js-restore-list {{_ 'restore'}}
|
a.js-restore-card {{_ 'restore'}}
|
||||||
| -
|
| -
|
||||||
a.js-delete-list {{_ 'delete'}}
|
a.js-delete-card {{_ 'delete'}}
|
||||||
else
|
if cardIsInArchivedList
|
||||||
li.no-items-message {{_ 'no-archived-lists'}}
|
p.quiet.small ({{_ 'warn-list-archived'}})
|
||||||
|
else
|
||||||
|
p.no-items-message {{_ 'no-archived-cards'}}
|
||||||
|
|
||||||
+tabContent(slug="swimlanes")
|
+tabContent(slug="lists")
|
||||||
p.quiet
|
p.quiet
|
||||||
a.js-restore-all-swimlanes {{_ 'restore-all'}}
|
a.js-restore-all-lists {{_ 'restore-all'}}
|
||||||
| -
|
| -
|
||||||
a.js-delete-all-swimlanes {{_ 'delete-all'}}
|
a.js-delete-all-lists {{_ 'delete-all'}}
|
||||||
ul.archived-lists
|
ul.archived-lists
|
||||||
each archivedSwimlanes
|
each archivedLists
|
||||||
li.archived-lists-item
|
li.archived-lists-item
|
||||||
= title
|
= title
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
p.quiet
|
p.quiet
|
||||||
a.js-restore-swimlane {{_ 'restore'}}
|
a.js-restore-list {{_ 'restore'}}
|
||||||
| -
|
| -
|
||||||
a.js-delete-swimlane {{_ 'delete'}}
|
a.js-delete-list {{_ 'delete'}}
|
||||||
else
|
else
|
||||||
li.no-items-message {{_ 'no-archived-swimlanes'}}
|
li.no-items-message {{_ 'no-archived-lists'}}
|
||||||
|
|
||||||
|
+tabContent(slug="swimlanes")
|
||||||
|
p.quiet
|
||||||
|
a.js-restore-all-swimlanes {{_ 'restore-all'}}
|
||||||
|
| -
|
||||||
|
a.js-delete-all-swimlanes {{_ 'delete-all'}}
|
||||||
|
ul.archived-lists
|
||||||
|
each archivedSwimlanes
|
||||||
|
li.archived-lists-item
|
||||||
|
= title
|
||||||
|
if currentUser.isBoardMember
|
||||||
|
p.quiet
|
||||||
|
a.js-restore-swimlane {{_ 'restore'}}
|
||||||
|
| -
|
||||||
|
a.js-delete-swimlane {{_ 'delete'}}
|
||||||
|
else
|
||||||
|
li.no-items-message {{_ 'no-archived-swimlanes'}}
|
||||||
|
else
|
||||||
|
+spinner
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,26 @@
|
||||||
|
const subManager = new SubsManager();
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
|
onCreated() {
|
||||||
|
this.isArchiveReady = new ReactiveVar(false);
|
||||||
|
|
||||||
|
// The pattern we use to manually handle data loading is described here:
|
||||||
|
// https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
|
||||||
|
// XXX The boardId should be readed from some sort the component "props",
|
||||||
|
// unfortunatly, Blaze doesn't have this notion.
|
||||||
|
this.autorun(() => {
|
||||||
|
const currentBoardId = Session.get('currentBoard');
|
||||||
|
if (!currentBoardId)
|
||||||
|
return;
|
||||||
|
const handle = subManager.subscribe('board', currentBoardId, true);
|
||||||
|
Tracker.nonreactive(() => {
|
||||||
|
Tracker.autorun(() => {
|
||||||
|
this.isArchiveReady.set( handle.ready() );
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
tabs() {
|
tabs() {
|
||||||
return [
|
return [
|
||||||
{ name: TAPi18n.__('cards'), slug: 'cards' },
|
{ name: TAPi18n.__('cards'), slug: 'cards' },
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,12 @@ Meteor.publish('archivedBoards', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Meteor.publishRelations('board', function(boardId) {
|
// If isArchived = false, this will only return board elements which are not archived.
|
||||||
|
// If isArchived = true, this will only return board elements which are archived.
|
||||||
|
Meteor.publishRelations('board', function(boardId, isArchived) {
|
||||||
this.unblock();
|
this.unblock();
|
||||||
check(boardId, String);
|
check(boardId, String);
|
||||||
|
check(isArchived, Boolean);
|
||||||
const thisUserId = this.userId;
|
const thisUserId = this.userId;
|
||||||
|
|
||||||
this.cursor(Boards.find({
|
this.cursor(Boards.find({
|
||||||
|
|
@ -75,8 +78,8 @@ Meteor.publishRelations('board', function(boardId) {
|
||||||
],
|
],
|
||||||
// Sort required to ensure oplog usage
|
// Sort required to ensure oplog usage
|
||||||
}, { limit: 1, sort: { _id: 1 } }), function(boardId, board) {
|
}, { limit: 1, sort: { _id: 1 } }), function(boardId, board) {
|
||||||
this.cursor(Lists.find({ boardId }));
|
this.cursor(Lists.find({ boardId: boardId, archived: isArchived }));
|
||||||
this.cursor(Swimlanes.find({ boardId }));
|
this.cursor(Swimlanes.find({ boardId: boardId, archived: isArchived }));
|
||||||
this.cursor(Integrations.find({ boardId }));
|
this.cursor(Integrations.find({ boardId }));
|
||||||
this.cursor(CustomFields.find({ boardIds: {$in: [boardId]} }, { sort: { name: 1 } }));
|
this.cursor(CustomFields.find({ boardIds: {$in: [boardId]} }, { sort: { name: 1 } }));
|
||||||
|
|
||||||
|
|
@ -115,8 +118,9 @@ Meteor.publishRelations('board', function(boardId) {
|
||||||
parentCards.selector = (_ids) => ({ parentId: _ids });
|
parentCards.selector = (_ids) => ({ parentId: _ids });
|
||||||
const boards = this.join(Boards);
|
const boards = this.join(Boards);
|
||||||
const subCards = this.join(Cards);
|
const subCards = this.join(Cards);
|
||||||
|
subCards.selector = (_ids) => ({ archived: isArchived });
|
||||||
|
|
||||||
this.cursor(Cards.find({ boardId: {$in: [boardId, board.subtasksDefaultBoardId]}}), function(cardId, card) {
|
this.cursor(Cards.find({ boardId: {$in: [boardId, board.subtasksDefaultBoardId]}, archived: isArchived }), function(cardId, card) {
|
||||||
if (card.type === 'cardType-linkedCard') {
|
if (card.type === 'cardType-linkedCard') {
|
||||||
const impCardId = card.linkedId;
|
const impCardId = card.linkedId;
|
||||||
subCards.push(impCardId);
|
subCards.push(impCardId);
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,5 @@ FastRender.onAllRoutes(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
FastRender.route('/b/:id/:slug', function({ id }) {
|
FastRender.route('/b/:id/:slug', function({ id }) {
|
||||||
this.subscribe('board', id);
|
this.subscribe('board', id, false);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue