mirror of
https://github.com/wekan/wekan.git
synced 2026-01-05 17:18:49 +01:00
Modify Broken Cards to use new search functions and component
This commit is contained in:
parent
5f53c71b0c
commit
8f978c23b4
4 changed files with 184 additions and 220 deletions
|
|
@ -6,8 +6,12 @@ template(name="resultCard")
|
|||
ul.result-card-context-list
|
||||
li.result-card-context(title="{{_ 'board'}}")
|
||||
.result-card-block-wrapper
|
||||
+viewer
|
||||
= getBoard.title
|
||||
if boardId
|
||||
+viewer
|
||||
= getBoard.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if getBoard.archived
|
||||
i.fa.fa-archive
|
||||
li.result-card-context.result-card-context-separator
|
||||
|
|
@ -16,8 +20,12 @@ template(name="resultCard")
|
|||
= ' '
|
||||
li.result-card-context(title="{{_ 'swimlane'}}")
|
||||
.result-card-block-wrapper
|
||||
+viewer
|
||||
= getSwimlane.title
|
||||
if swimlaneId
|
||||
+viewer
|
||||
= getSwimlane.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if getSwimlane.archived
|
||||
i.fa.fa-archive
|
||||
li.result-card-context.result-card-context-separator
|
||||
|
|
@ -26,7 +34,11 @@ template(name="resultCard")
|
|||
= ' '
|
||||
li.result-card-context(title="{{_ 'list'}}")
|
||||
.result-card-block-wrapper
|
||||
+viewer
|
||||
= getList.title
|
||||
if listId
|
||||
+viewer
|
||||
= getList.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if getList.archived
|
||||
i.fa.fa-archive
|
||||
|
|
|
|||
|
|
@ -3,39 +3,15 @@ template(name="brokenCardsHeaderBar")
|
|||
| {{_ 'broken-cards'}}
|
||||
|
||||
template(name="brokenCards")
|
||||
.wrapper
|
||||
.broken-cards-wrapper
|
||||
each card in brokenCardsList
|
||||
.broken-cards-card-wrapper
|
||||
.broken-cards-card-title
|
||||
= card.title
|
||||
ul.broken-cards-context-list
|
||||
li.broken-cards-context(title="{{_ 'board'}}")
|
||||
if card.boardId
|
||||
+viewer
|
||||
= card.getBoard.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
li.broken-cards-context.broken-cards-context-separator
|
||||
= ' '
|
||||
| {{_ 'context-separator'}}
|
||||
= ' '
|
||||
li.broken-cards-context(title="{{_ 'swimlane'}}")
|
||||
if card.swimlaneId
|
||||
+viewer
|
||||
= card.getSwimlane.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
li.broken-cards-context
|
||||
= ' '
|
||||
| {{_ 'context-separator'}}
|
||||
= ' '
|
||||
li.broken-cards-context(title="{{_ 'list'}}")
|
||||
if card.listId
|
||||
+viewer
|
||||
= card.getList.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if currentUser
|
||||
if searching.get
|
||||
+spinner
|
||||
else if hasResults.get
|
||||
.global-search-results-list-wrapper
|
||||
if hasQueryErrors.get
|
||||
div
|
||||
each msg in errorMessages
|
||||
span.global-search-error-messages
|
||||
= msg
|
||||
else
|
||||
+resultsPaged(this)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { CardSearchPagedComponent } from "../../lib/cardSearch";
|
||||
|
||||
BlazeComponent.extendComponent({}).register('brokenCardsHeaderBar');
|
||||
|
||||
Template.brokenCards.helpers({
|
||||
|
|
@ -6,23 +8,11 @@ Template.brokenCards.helpers({
|
|||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
class BrokenCardsComponent extends CardSearchPagedComponent {
|
||||
onCreated() {
|
||||
Meteor.subscribe('setting');
|
||||
Meteor.subscribe('brokenCards');
|
||||
},
|
||||
super.onCreated();
|
||||
|
||||
brokenCardsList() {
|
||||
const selector = {
|
||||
$or: [
|
||||
{ boardId: { $in: [null, ''] } },
|
||||
{ swimlaneId: { $in: [null, ''] } },
|
||||
{ listId: { $in: [null, ''] } },
|
||||
{ permission: 'public' },
|
||||
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
|
||||
],
|
||||
};
|
||||
|
||||
return Cards.find(selector);
|
||||
},
|
||||
}).register('brokenCards');
|
||||
Meteor.subscribe('brokenCards', this.sessionId);
|
||||
}
|
||||
}
|
||||
BrokenCardsComponent.register('brokenCards');
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Meteor.publish('myCards', function(sessionId) {
|
|||
// sort: { name: 'dueAt', order: 'des' },
|
||||
};
|
||||
|
||||
return buildQuery(sessionId, queryParams);
|
||||
return findCards(sessionId, buildQuery(queryParams));
|
||||
});
|
||||
|
||||
// Meteor.publish('dueCards', function(sessionId, allUsers = false) {
|
||||
|
|
@ -44,93 +44,104 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
|||
// eslint-disable-next-line no-console
|
||||
// console.log('queryParams:', queryParams);
|
||||
|
||||
return buildQuery(sessionId, queryParams);
|
||||
return findCards(sessionId, buildQuery(queryParams));
|
||||
});
|
||||
|
||||
function buildQuery(sessionId, queryParams) {
|
||||
class QueryErrors {
|
||||
constructor() {
|
||||
this.notFound = {
|
||||
boards: [],
|
||||
swimlanes: [],
|
||||
lists: [],
|
||||
labels: [],
|
||||
users: [],
|
||||
members: [],
|
||||
assignees: [],
|
||||
status: [],
|
||||
comments: [],
|
||||
};
|
||||
|
||||
this.colorMap = Boards.colorMap();
|
||||
}
|
||||
|
||||
hasErrors() {
|
||||
for (const value of Object.values(this.notFound)) {
|
||||
if (value.length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
errorMessages() {
|
||||
const messages = [];
|
||||
|
||||
this.notFound.boards.forEach(board => {
|
||||
messages.push({ tag: 'board-title-not-found', value: board });
|
||||
});
|
||||
this.notFound.swimlanes.forEach(swim => {
|
||||
messages.push({ tag: 'swimlane-title-not-found', value: swim });
|
||||
});
|
||||
this.notFound.lists.forEach(list => {
|
||||
messages.push({ tag: 'list-title-not-found', value: list });
|
||||
});
|
||||
this.notFound.comments.forEach(comments => {
|
||||
comments.forEach(text => {
|
||||
messages.push({ tag: 'comment-not-found', value: text });
|
||||
});
|
||||
});
|
||||
this.notFound.labels.forEach(label => {
|
||||
if (Boards.labelColors().includes(label)) {
|
||||
messages.push({
|
||||
tag: 'label-color-not-found',
|
||||
value: label,
|
||||
color: true,
|
||||
});
|
||||
} else {
|
||||
messages.push({
|
||||
tag: 'label-not-found',
|
||||
value: label,
|
||||
color: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.notFound.users.forEach(user => {
|
||||
messages.push({ tag: 'user-username-not-found', value: user });
|
||||
});
|
||||
this.notFound.members.forEach(user => {
|
||||
messages.push({ tag: 'user-username-not-found', value: user });
|
||||
});
|
||||
this.notFound.assignees.forEach(user => {
|
||||
messages.push({ tag: 'user-username-not-found', value: user });
|
||||
});
|
||||
|
||||
return messages;
|
||||
}
|
||||
};
|
||||
|
||||
class Query {
|
||||
params = {};
|
||||
selector = {};
|
||||
projection = {};
|
||||
errors = new QueryErrors();
|
||||
|
||||
constructor(selector, projection) {
|
||||
if (selector) {
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
if (projection) {
|
||||
this.projection = projection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildSelector(queryParams) {
|
||||
const userId = Meteor.userId();
|
||||
|
||||
const errors = new (class {
|
||||
constructor() {
|
||||
this.notFound = {
|
||||
boards: [],
|
||||
swimlanes: [],
|
||||
lists: [],
|
||||
labels: [],
|
||||
users: [],
|
||||
members: [],
|
||||
assignees: [],
|
||||
status: [],
|
||||
comments: [],
|
||||
};
|
||||
|
||||
this.colorMap = Boards.colorMap();
|
||||
}
|
||||
|
||||
hasErrors() {
|
||||
for (const value of Object.values(this.notFound)) {
|
||||
if (value.length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
errorMessages() {
|
||||
const messages = [];
|
||||
|
||||
this.notFound.boards.forEach(board => {
|
||||
messages.push({ tag: 'board-title-not-found', value: board });
|
||||
});
|
||||
this.notFound.swimlanes.forEach(swim => {
|
||||
messages.push({ tag: 'swimlane-title-not-found', value: swim });
|
||||
});
|
||||
this.notFound.lists.forEach(list => {
|
||||
messages.push({ tag: 'list-title-not-found', value: list });
|
||||
});
|
||||
this.notFound.comments.forEach(comments => {
|
||||
comments.forEach(text => {
|
||||
messages.push({ tag: 'comment-not-found', value: text });
|
||||
});
|
||||
});
|
||||
this.notFound.labels.forEach(label => {
|
||||
if (Boards.labelColors().includes(label)) {
|
||||
messages.push({
|
||||
tag: 'label-color-not-found',
|
||||
value: label,
|
||||
color: true,
|
||||
});
|
||||
} else {
|
||||
messages.push({
|
||||
tag: 'label-not-found',
|
||||
value: label,
|
||||
color: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.notFound.users.forEach(user => {
|
||||
messages.push({ tag: 'user-username-not-found', value: user });
|
||||
});
|
||||
this.notFound.members.forEach(user => {
|
||||
messages.push({ tag: 'user-username-not-found', value: user });
|
||||
});
|
||||
this.notFound.assignees.forEach(user => {
|
||||
messages.push({ tag: 'user-username-not-found', value: user });
|
||||
});
|
||||
|
||||
return messages;
|
||||
}
|
||||
})();
|
||||
errors = new QueryErrors();
|
||||
|
||||
let selector = {};
|
||||
let skip = 0;
|
||||
if (queryParams.skip) {
|
||||
skip = queryParams.skip;
|
||||
}
|
||||
let limit = 25;
|
||||
if (queryParams.limit) {
|
||||
limit = queryParams.limit;
|
||||
}
|
||||
|
||||
if (queryParams.selector) {
|
||||
selector = queryParams.selector;
|
||||
|
|
@ -487,6 +498,25 @@ function buildQuery(sessionId, queryParams) {
|
|||
// eslint-disable-next-line no-console
|
||||
// console.log('selector.$and:', selector.$and);
|
||||
|
||||
const query = new Query();
|
||||
query.selector = selector;
|
||||
query.params = queryParams;
|
||||
query.errors = errors;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
function buildProjection(query) {
|
||||
|
||||
let skip = 0;
|
||||
if (query.params.skip) {
|
||||
skip = query.params.skip;
|
||||
}
|
||||
let limit = 25;
|
||||
if (query.params.limit) {
|
||||
limit = query.params.limit;
|
||||
}
|
||||
|
||||
const projection = {
|
||||
fields: {
|
||||
_id: 1,
|
||||
|
|
@ -516,9 +546,9 @@ function buildQuery(sessionId, queryParams) {
|
|||
limit,
|
||||
};
|
||||
|
||||
if (queryParams.sort) {
|
||||
const order = queryParams.sort.order === 'asc' ? 1 : -1;
|
||||
switch (queryParams.sort.name) {
|
||||
if (query.params.sort) {
|
||||
const order = query.params.sort.order === 'asc' ? 1 : -1;
|
||||
switch (query.params.sort.name) {
|
||||
case 'dueAt':
|
||||
projection.sort = {
|
||||
dueAt: order,
|
||||
|
|
@ -561,77 +591,33 @@ function buildQuery(sessionId, queryParams) {
|
|||
// eslint-disable-next-line no-console
|
||||
// console.log('projection:', projection);
|
||||
|
||||
return findCards(sessionId, selector, projection, errors);
|
||||
query.projection = projection;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
Meteor.publish('brokenCards', function() {
|
||||
const user = Users.findOne({ _id: this.userId });
|
||||
function buildQuery(queryParams) {
|
||||
const query = buildSelector(queryParams);
|
||||
|
||||
const permiitedBoards = [null];
|
||||
let selector = {};
|
||||
selector.$or = [
|
||||
{ permission: 'public' },
|
||||
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
|
||||
];
|
||||
return buildProjection(query);
|
||||
}
|
||||
|
||||
Boards.find(selector).forEach(board => {
|
||||
permiitedBoards.push(board._id);
|
||||
});
|
||||
Meteor.publish('brokenCards', function(sessionId) {
|
||||
|
||||
selector = {
|
||||
boardId: { $in: permiitedBoards },
|
||||
$or: [
|
||||
{ boardId: { $in: [null, ''] } },
|
||||
{ swimlaneId: { $in: [null, ''] } },
|
||||
{ listId: { $in: [null, ''] } },
|
||||
],
|
||||
const queryParams = {
|
||||
users: [Meteor.user().username],
|
||||
// limit: 25,
|
||||
skip: 0,
|
||||
// sort: { name: 'dueAt', order: 'des' },
|
||||
};
|
||||
|
||||
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 = [];
|
||||
const users = [];
|
||||
|
||||
cards.forEach(card => {
|
||||
if (card.boardId) boards.push(card.boardId);
|
||||
if (card.swimlaneId) swimlanes.push(card.swimlaneId);
|
||||
if (card.listId) lists.push(card.listId);
|
||||
if (card.members) {
|
||||
card.members.forEach(userId => {
|
||||
users.push(userId);
|
||||
});
|
||||
}
|
||||
if (card.assignees) {
|
||||
card.assignees.forEach(userId => {
|
||||
users.push(userId);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return [
|
||||
cards,
|
||||
Boards.find({ _id: { $in: boards } }),
|
||||
Swimlanes.find({ _id: { $in: swimlanes } }),
|
||||
Lists.find({ _id: { $in: lists } }),
|
||||
Users.find({ _id: { $in: users } }, { fields: Users.safeFields }),
|
||||
const query = buildQuery(queryParams);
|
||||
query.selector.$or = [
|
||||
{ boardId: { $in: [null, ''] } },
|
||||
{ swimlaneId: { $in: [null, ''] } },
|
||||
{ listId: { $in: [null, ''] } },
|
||||
];
|
||||
|
||||
return findCards(sessionId, query);
|
||||
});
|
||||
|
||||
Meteor.publish('nextPage', function(sessionId) {
|
||||
|
|
@ -641,7 +627,7 @@ Meteor.publish('nextPage', function(sessionId) {
|
|||
const projection = session.getProjection();
|
||||
projection.skip = session.lastHit;
|
||||
|
||||
return findCards(sessionId, session.getSelector(), projection);
|
||||
return findCards(sessionId, new Query(session.getSelector(), projection));
|
||||
});
|
||||
|
||||
Meteor.publish('previousPage', function(sessionId) {
|
||||
|
|
@ -651,20 +637,20 @@ Meteor.publish('previousPage', function(sessionId) {
|
|||
const projection = session.getProjection();
|
||||
projection.skip = session.lastHit - session.resultsCount - projection.limit;
|
||||
|
||||
return findCards(sessionId, session.getSelector(), projection);
|
||||
return findCards(sessionId, new Query(session.getSelector(), projection));
|
||||
});
|
||||
|
||||
function findCards(sessionId, selector, projection, errors = []) {
|
||||
function findCards(sessionId, query) {
|
||||
const userId = Meteor.userId();
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('selector:', selector);
|
||||
console.log('selector.$and:', selector.$and);
|
||||
console.log('selector:', query.selector);
|
||||
console.log('selector.$and:', query.selector.$and);
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('projection:', projection);
|
||||
let cards;
|
||||
if (!errors || !errors.hasErrors()) {
|
||||
cards = Cards.find(selector, projection);
|
||||
cards = Cards.find(query.selector, query.projection);
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('count:', cards.count());
|
||||
|
|
@ -675,9 +661,9 @@ function findCards(sessionId, selector, projection, errors = []) {
|
|||
lastHit: 0,
|
||||
resultsCount: 0,
|
||||
cards: [],
|
||||
selector: SessionData.pickle(selector),
|
||||
projection: SessionData.pickle(projection),
|
||||
errors: errors.errorMessages(),
|
||||
selector: SessionData.pickle(query.selector),
|
||||
projection: SessionData.pickle(query.projection),
|
||||
errors: query.errors.errorMessages(),
|
||||
},
|
||||
};
|
||||
// if (errors) {
|
||||
|
|
@ -687,8 +673,8 @@ function findCards(sessionId, selector, projection, errors = []) {
|
|||
if (cards) {
|
||||
update.$set.totalHits = cards.count();
|
||||
update.$set.lastHit =
|
||||
projection.skip + projection.limit < cards.count()
|
||||
? projection.skip + projection.limit
|
||||
query.projection.skip + query.projection.limit < cards.count()
|
||||
? query.projection.skip + query.projection.limit
|
||||
: cards.count();
|
||||
update.$set.cards = cards.map(card => {
|
||||
return card._id;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue